blob: 4becbc2966f23dc2de1e848751cfceb426fc66c7 [file] [log] [blame]
package org.apache.karaf.boot.jpa.impl;
import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.Messager;
import javax.annotation.processing.RoundEnvironment;
import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.AnnotationValue;
import javax.lang.model.element.Element;
import javax.lang.model.element.TypeElement;
import javax.tools.Diagnostic.Kind;
import javax.tools.FileObject;
import javax.tools.StandardLocation;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.karaf.boot.jpa.PersistentUnit;
import org.apache.karaf.boot.jpa.Property;
import org.apache.karaf.boot.jpa.Provider;
public class JpaProcessor extends AbstractProcessor {
public JpaProcessor() {
}
@Override
public Set<String> getSupportedAnnotationTypes() {
return new HashSet<String>(Arrays.asList(
PersistentUnit.class.getName()
));
}
@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
Map<PersistentUnit, List<? extends AnnotationMirror>> units = new HashMap<PersistentUnit, List<? extends AnnotationMirror>>();
for (Element elem : roundEnv.getElementsAnnotatedWith(PersistentUnit.class)) {
PersistentUnit pu = elem.getAnnotation(PersistentUnit.class);
units.put(pu, elem.getAnnotationMirrors());
}
if (!units.isEmpty()) {
try {
Set<String> puNames = new HashSet<String>();
FileObject o = processingEnv.getFiler().createResource(StandardLocation.CLASS_OUTPUT,
"", "META-INF/persistence.xml");
PrintWriter w = new PrintWriter(o.openWriter());
w.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
w.println("<persistence version=\"2.0\" xmlns=\"http://java.sun.com/xml/ns/persistence\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd\">");
for (PersistentUnit pu : units.keySet()) {
if (pu.name() == null || pu.name().isEmpty()) {
throw new IOException("Missing persistent unit name");
}
if (!puNames.add(pu.name())) {
throw new IOException("Duplicate persistent unit name: " + pu.name());
}
w.println(" <persistence-unit name=\"" + pu.name() + "\" transaction-type=\"" + pu.transactionType().toString() + "\">");
if (!pu.description().isEmpty()) {
w.println(" <description>" + pu.description() + "</description>");
}
if (pu.provider() != Provider.Default || !pu.providerName().isEmpty()) {
if (pu.provider() != Provider.Default && !pu.providerName().isEmpty()) {
throw new IOException("At most one of provider and providerName can be used");
}
String name;
if (!pu.providerName().isEmpty()) {
name = pu.providerName();
} else {
switch (pu.provider()) {
case Hibernate:
name = "org.hibernate.jpa.HibernatePersistenceProvider";
break;
default:
// TODO
throw new IOException("Unsupported provider: " + pu.provider());
}
}
w.println(" <provider>" + name + "</provider>");
}
if (!pu.jtaDataSource().isEmpty()) {
w.println(" <jta-data-source>" + pu.jtaDataSource() + "</jta-data-source>");
}
if (!pu.nonJtaDataSource().isEmpty()) {
w.println(" <non-jta-data-source>" + pu.nonJtaDataSource() + "</non-jta-data-source>");
}
if (pu.properties().length > 0) {
w.println(" <properties>");
for (Property property : pu.properties()) {
w.println(" <property name=\"" + property.name() + "\" value=\"" + property.value() + "\"/>");
}
for (AnnotationMirror annMirror : units.get(pu)) {
String name = null;
for (AnnotationMirror a : processingEnv.getElementUtils().getAllAnnotationMirrors(annMirror.getAnnotationType().asElement())) {
if (a.toString().startsWith("@org.apache.karaf.boot.jpa.PersistentUnit.ProviderProperty")) {
name = a.getElementValues().values().iterator().next().getValue().toString();
break;
}
}
if (name != null) {
String value = annMirror.getElementValues().values().iterator().next().getValue().toString();
w.println(" <property name=\"" + name + "\" value=\"" + value + "\"/>");
}
// processingEnv.getMessager().printMessage(Kind.MANDATORY_WARNING, "Annotation: " + annMirror);
// processingEnv.getMessager().printMessage(Kind.MANDATORY_WARNING, "Annotation type: " + annMirror.getAnnotationType());
// processingEnv.getMessager().printMessage(Kind.MANDATORY_WARNING, "Annotation annot: " + annMirror.getAnnotationType().getAnnotationMirrors());
// processingEnv.getMessager().printMessage(Kind.MANDATORY_WARNING, "Annotation annot: " + processingEnv.getElementUtils().getAllAnnotationMirrors(annMirror.getAnnotationType().asElement()));
// processingEnv.getMessager().printMessage(Kind.MANDATORY_WARNING, "Annotation values: " + annMirror.getElementValues());
// if (annMirror.getAnnotationType().getAnnotation(PersistentUnit.ProviderProperty.class) != null) {
// processingEnv.getMessager().printMessage(Kind.MANDATORY_WARNING, "Annotation ok");
// } else {
// processingEnv.getMessager().printMessage(Kind.MANDATORY_WARNING, "Annotation nok");
// }
}
w.println(" </properties>");
}
w.println(" </persistence-unit>");
}
w.println("</persistence>");
w.close();
processingEnv.getMessager().printMessage(Kind.NOTE, "Generated META-INF/persistence.xml");
} catch (IOException e) {
processingEnv.getMessager().printMessage(Kind.ERROR, "Error: " + e.getMessage());
}
}
return true;
}
}