mirror of
https://github.com/scm-manager/scm-manager.git
synced 2025-11-09 15:05:44 +01:00
improve annotation processor
This commit is contained in:
@@ -47,7 +47,7 @@ import java.lang.annotation.Target;
|
||||
*/
|
||||
@Documented
|
||||
@Target({ ElementType.TYPE })
|
||||
@PluginAnnotation("extension-points")
|
||||
@PluginAnnotation("extension-point")
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface ExtensionPoint
|
||||
{
|
||||
|
||||
@@ -51,6 +51,6 @@ import java.lang.annotation.Target;
|
||||
*/
|
||||
@Documented
|
||||
@Target({ ElementType.TYPE })
|
||||
@PluginAnnotation("extensions")
|
||||
@PluginAnnotation("extension")
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface Extension {}
|
||||
|
||||
@@ -36,6 +36,11 @@ package sonia.scm.annotation;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Sebastian Sdorra
|
||||
@@ -55,7 +60,8 @@ public class ClassSetElement implements DescriptorElement
|
||||
* @param elementName
|
||||
* @param classes
|
||||
*/
|
||||
public ClassSetElement(String elementName, Iterable<String> classes)
|
||||
public ClassSetElement(String elementName,
|
||||
Iterable<ClassWithAttributes> classes)
|
||||
{
|
||||
this.elementName = elementName;
|
||||
this.classes = classes;
|
||||
@@ -73,23 +79,67 @@ public class ClassSetElement implements DescriptorElement
|
||||
@Override
|
||||
public void append(Document doc, Element root)
|
||||
{
|
||||
Element element = doc.createElement(elementName);
|
||||
|
||||
for (String c : classes)
|
||||
for (ClassWithAttributes c : classes)
|
||||
{
|
||||
Element element = doc.createElement(elementName);
|
||||
Element classEl = doc.createElement(EL_CLASS);
|
||||
|
||||
classEl.setTextContent(c);
|
||||
element.appendChild(classEl);
|
||||
classEl.setTextContent(c.className);
|
||||
|
||||
for (Entry<String, String> e : c.attributes.entrySet())
|
||||
{
|
||||
Element attr = doc.createElement(e.getKey());
|
||||
attr.setTextContent(e.getValue());
|
||||
element.appendChild(attr);
|
||||
}
|
||||
|
||||
element.appendChild(classEl);
|
||||
root.appendChild(element);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
//~--- inner classes --------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Class description
|
||||
*
|
||||
*
|
||||
* @version Enter version here..., 14/03/18
|
||||
* @author Enter your name here...
|
||||
*/
|
||||
public static class ClassWithAttributes
|
||||
{
|
||||
|
||||
/**
|
||||
* Constructs ...
|
||||
*
|
||||
*
|
||||
* @param className
|
||||
* @param attributes
|
||||
*/
|
||||
public ClassWithAttributes(String className, Map<String, String> attributes)
|
||||
{
|
||||
this.className = className;
|
||||
this.attributes = attributes;
|
||||
}
|
||||
|
||||
//~--- fields -------------------------------------------------------------
|
||||
|
||||
/** Field description */
|
||||
private final Map<String, String> attributes;
|
||||
|
||||
/** Field description */
|
||||
private final String className;
|
||||
}
|
||||
|
||||
|
||||
//~--- fields ---------------------------------------------------------------
|
||||
|
||||
/** Field description */
|
||||
private final Iterable<String> classes;
|
||||
private final Iterable<ClassWithAttributes> classes;
|
||||
|
||||
/** Field description */
|
||||
private final String elementName;
|
||||
|
||||
@@ -37,12 +37,14 @@ import com.github.legman.Subscribe;
|
||||
|
||||
import com.google.common.base.Throwables;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
import org.kohsuke.MetaInfServices;
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
|
||||
import sonia.scm.annotation.ClassSetElement.ClassWithAttributes;
|
||||
import sonia.scm.plugin.PluginAnnotation;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
@@ -58,6 +60,8 @@ import java.io.Writer;
|
||||
import java.lang.annotation.Annotation;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.annotation.processing.AbstractProcessor;
|
||||
@@ -68,6 +72,8 @@ import javax.annotation.processing.SupportedAnnotationTypes;
|
||||
import javax.annotation.processing.SupportedSourceVersion;
|
||||
|
||||
import javax.lang.model.SourceVersion;
|
||||
import javax.lang.model.element.AnnotationMirror;
|
||||
import javax.lang.model.element.AnnotationValue;
|
||||
import javax.lang.model.element.Element;
|
||||
import javax.lang.model.element.ElementKind;
|
||||
import javax.lang.model.element.ExecutableElement;
|
||||
@@ -115,8 +121,8 @@ public final class ScmAnnotationProcessor extends AbstractProcessor
|
||||
|
||||
/** Field description */
|
||||
private static final Set<ClassAnnotation> CLASS_ANNOTATIONS =
|
||||
ImmutableSet.of(new ClassAnnotation("jaxrs-resources", Path.class),
|
||||
new ClassAnnotation("jaxrs-providers", Provider.class));
|
||||
ImmutableSet.of(new ClassAnnotation("jaxrs-resource", Path.class),
|
||||
new ClassAnnotation("jaxrs-provider", Provider.class));
|
||||
|
||||
//~--- methods --------------------------------------------------------------
|
||||
|
||||
@@ -144,8 +150,7 @@ public final class ScmAnnotationProcessor extends AbstractProcessor
|
||||
|
||||
if (pa != null)
|
||||
{
|
||||
scanForClassAnnotations(descriptorElements, pa.value(),
|
||||
roundEnv.getElementsAnnotatedWith(e));
|
||||
scanForClassAnnotations(descriptorElements, roundEnv, e, pa.value());
|
||||
}
|
||||
|
||||
if (SUBSCRIBE_ANNOTATIONS.contains(e.getQualifiedName().toString()))
|
||||
@@ -156,8 +161,14 @@ public final class ScmAnnotationProcessor extends AbstractProcessor
|
||||
|
||||
for (ClassAnnotation ca : CLASS_ANNOTATIONS)
|
||||
{
|
||||
scanForClassAnnotations(descriptorElements, ca.elementName,
|
||||
roundEnv.getElementsAnnotatedWith(ca.annotationClass));
|
||||
TypeElement annotation = findAnnotation(annotations,
|
||||
ca.annotationClass);
|
||||
|
||||
if (annotation != null)
|
||||
{
|
||||
scanForClassAnnotations(descriptorElements, roundEnv, annotation,
|
||||
ca.elementName);
|
||||
}
|
||||
}
|
||||
|
||||
for (TypeElement annotation : subscriberAnnotations)
|
||||
@@ -193,6 +204,33 @@ public final class ScmAnnotationProcessor extends AbstractProcessor
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param annotations
|
||||
* @param annotationClass
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private TypeElement findAnnotation(Set<? extends TypeElement> annotations,
|
||||
Class<? extends Annotation> annotationClass)
|
||||
{
|
||||
TypeElement annotation = null;
|
||||
|
||||
for (TypeElement te : annotations)
|
||||
{
|
||||
if (te.getQualifiedName().toString().equals(annotationClass.getName()))
|
||||
{
|
||||
annotation = te;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return annotation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
@@ -283,24 +321,27 @@ public final class ScmAnnotationProcessor extends AbstractProcessor
|
||||
*
|
||||
*
|
||||
* @param descriptorElements
|
||||
* @param roundEnv
|
||||
* @param annotation
|
||||
* @param elementName
|
||||
* @param elements
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private void scanForClassAnnotations(
|
||||
Set<DescriptorElement> descriptorElements, String elementName,
|
||||
Set<? extends Element> elements)
|
||||
Set<DescriptorElement> descriptorElements, RoundEnvironment roundEnv,
|
||||
TypeElement annotation, String elementName)
|
||||
{
|
||||
Set<String> classes = Sets.newHashSet();
|
||||
Set<ClassWithAttributes> classes = Sets.newHashSet();
|
||||
|
||||
for (Element e : elements)
|
||||
for (Element e : roundEnv.getElementsAnnotatedWith(annotation))
|
||||
{
|
||||
if (e.getKind().isClass() || e.getKind().isInterface())
|
||||
{
|
||||
TypeElement type = (TypeElement) e;
|
||||
|
||||
classes.add(type.getQualifiedName().toString());
|
||||
classes.add(new ClassWithAttributes(type.getQualifiedName().toString(),
|
||||
getAttributesFromAnnotation(e, annotation)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -405,6 +446,40 @@ public final class ScmAnnotationProcessor extends AbstractProcessor
|
||||
}
|
||||
}
|
||||
|
||||
//~--- get methods ----------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param el
|
||||
* @param annotation
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private Map<String, String> getAttributesFromAnnotation(Element el,
|
||||
TypeElement annotation)
|
||||
{
|
||||
Map<String, String> attributes = Maps.newHashMap();
|
||||
|
||||
for (AnnotationMirror am : el.getAnnotationMirrors())
|
||||
{
|
||||
String qn = am.getAnnotationType().asElement().toString();
|
||||
|
||||
if (qn.equals(annotation.toString()))
|
||||
{
|
||||
for (Entry<? extends ExecutableElement,
|
||||
? extends AnnotationValue> entry : am.getElementValues().entrySet())
|
||||
{
|
||||
attributes.put(entry.getKey().getSimpleName().toString(),
|
||||
entry.getValue().getValue().toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return attributes;
|
||||
}
|
||||
|
||||
//~--- inner classes --------------------------------------------------------
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user