blob: 465992d4f0d00a913efc01dbeafcfcc9dd07aaa2 [file] [log] [blame]
package org.apache.karaf.boot.jpa.impl;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.lang.annotation.Annotation;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;
import org.apache.karaf.boot.jpa.PersistentUnit;
import org.apache.karaf.boot.jpa.Property;
import org.apache.karaf.boot.jpa.Provider;
import org.apache.karaf.boot.plugin.api.BootPlugin;
import org.apache.karaf.boot.plugin.api.StreamFactory;
import javanet.staxutils.IndentingXMLStreamWriter;
public class JpaProcessor implements BootPlugin {
private boolean useHibernate;
public JpaProcessor() {
}
@Override
public Map<String, List<String>> enhance(List<Class<?>> annotatedList, File generatedDir,
StreamFactory streamFactory) {
try {
File persistenceFile = new File(generatedDir, "META-INF/persistence.xml");
OutputStream os = streamFactory.create(persistenceFile);
process(new OutputStreamWriter(os), annotatedList);
// System.out.println(Kind.NOTE, "Generated META-INF/persistence.xml");
} catch (Exception e) {
throw new RuntimeException(e);
// processingEnv.getMessager().printMessage(Kind.ERROR, "Error: " + e.getMessage());
}
Map<String, List<String>> headers = new HashMap<>();
headers.put("Meta-Persistence", Arrays.asList("META-INF/persistence.xml"));
if (useHibernate) {
headers.put("Import-Package", Arrays.asList("org.hibernate.proxy", "javassist.util.proxy"));
}
return headers;
}
public void process(Writer writer, List<Class<?>> annotatedList) throws Exception {
Set<String> puNames = new HashSet<String>();
XMLOutputFactory xof = XMLOutputFactory.newInstance();
XMLStreamWriter w = new IndentingXMLStreamWriter(xof.createXMLStreamWriter(writer));
w.setDefaultNamespace("http://java.sun.com/xml/ns/persistence");
w.writeStartDocument();
w.writeStartElement("persistence");
w.writeAttribute("verson", "2.0");
// 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 (Class<?> annotated : annotatedList) {
PersistentUnit pu = annotated.getAnnotation(PersistentUnit.class);
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.writeStartElement("persistence-unit");
w.writeAttribute("name", pu.name());
w.writeAttribute("transaction-type", pu.transactionType().toString());
writeElement(w, "description", pu.description());
String providerName = getProvider(pu);
writeElement(w, "provider", providerName);
writeElement(w, "jta-data-source", pu.jtaDataSource());
writeElement(w, "non-jta-data-source", pu.nonJtaDataSource());
Map<String, String> props = new HashMap<>();
addProperties(pu, props);
addAnnProperties(annotated, props);
if (props.size() > 0) {
w.writeStartElement("properties");
for (String key : props.keySet()) {
w.writeEmptyElement("property");
w.writeAttribute("name", key);
w.writeAttribute("value", props.get(key));
}
w.writeEndElement();
}
w.writeEndElement();
}
w.writeEndElement();
w.writeEndDocument();
w.flush();
w.close();
}
private void addProperties(PersistentUnit pu, Map<String, String> props) {
if (pu.properties() == null) {
return;
}
for (Property property : pu.properties()) {
props.put(property.name(), property.value());
}
}
private void addAnnProperties(Class<?> annotated, Map<String, String> props) throws XMLStreamException {
for (Annotation annotation : annotated.getAnnotations()) {
String name = null;
/*
* for (Annotation a : annotated.getAnnotations()) { 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(); props.put(name,
* 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");
// }
}
}
private void writeElement(XMLStreamWriter w, String localName, String content) throws XMLStreamException {
if (content != null && !content.isEmpty()) {
w.writeStartElement(localName);
w.writeCharacters(content);
w.writeEndElement();
}
}
private String getProvider(PersistentUnit pu) throws IOException {
if (pu.provider() != Provider.Default && pu.providerName() != null && !pu.providerName().isEmpty()) {
throw new IOException("At most one of provider and providerName can be used");
}
if (pu.provider() != null) {
switch (pu.provider()) {
case Hibernate:
useHibernate = true;
return "org.hibernate.jpa.HibernatePersistenceProvider";
default:
// TODO
throw new IOException("Unsupported provider: " + pu.provider());
}
} else if (pu.providerName() != null) {
return pu.providerName();
} else {
return null;
}
}
@Override
public Class<? extends Annotation> getAnnotation() {
return PersistentUnit.class;
}
}