Return-Path: X-Original-To: archive-asf-public-internal@cust-asf2.ponee.io Delivered-To: archive-asf-public-internal@cust-asf2.ponee.io Received: from cust-asf.ponee.io (cust-asf.ponee.io [163.172.22.183]) by cust-asf2.ponee.io (Postfix) with ESMTP id 92F74200AC0 for ; Mon, 9 May 2016 16:48:25 +0200 (CEST) Received: by cust-asf.ponee.io (Postfix) id 921171609A8; Mon, 9 May 2016 14:48:25 +0000 (UTC) Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by cust-asf.ponee.io (Postfix) with SMTP id 0712F160A2D for ; Mon, 9 May 2016 16:48:22 +0200 (CEST) Received: (qmail 80568 invoked by uid 500); 9 May 2016 14:48:22 -0000 Mailing-List: contact commits-help@karaf.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@karaf.apache.org Delivered-To: mailing list commits@karaf.apache.org Received: (qmail 80371 invoked by uid 99); 9 May 2016 14:48:22 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 09 May 2016 14:48:22 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id 01687E108B; Mon, 9 May 2016 14:48:22 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: cschneider@apache.org To: commits@karaf.apache.org Date: Mon, 09 May 2016 14:48:49 -0000 Message-Id: In-Reply-To: <1e3eeb57e42d4f938950e5b22b1cb7f9@git.apache.org> References: <1e3eeb57e42d4f938950e5b22b1cb7f9@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: [30/35] karaf-boot git commit: Use stax for file generation archived-at: Mon, 09 May 2016 14:48:25 -0000 Use stax for file generation Project: http://git-wip-us.apache.org/repos/asf/karaf-boot/repo Commit: http://git-wip-us.apache.org/repos/asf/karaf-boot/commit/af6327ca Tree: http://git-wip-us.apache.org/repos/asf/karaf-boot/tree/af6327ca Diff: http://git-wip-us.apache.org/repos/asf/karaf-boot/diff/af6327ca Branch: refs/heads/master Commit: af6327ca53b12afc27e573aab9dce0ddc76d9a27 Parents: 5e0846f Author: Christian Schneider Authored: Mon Apr 25 18:30:19 2016 +0200 Committer: Christian Schneider Committed: Mon Apr 25 18:30:19 2016 +0200 ---------------------------------------------------------------------- samples/jpa/pom.xml | 33 ++-- starters/karaf-boot-starter-jpa/pom.xml | 61 +++--- .../karaf/boot/jpa/impl/JpaProcessor.java | 198 +++++++++++-------- .../karaf/boot/jpa/impl/JpaProcessorTest.java | 64 ++++++ .../src/test/resources/expected_persistence.xml | 11 ++ 5 files changed, 241 insertions(+), 126 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/karaf-boot/blob/af6327ca/samples/jpa/pom.xml ---------------------------------------------------------------------- diff --git a/samples/jpa/pom.xml b/samples/jpa/pom.xml index 032396f..1c51404 100644 --- a/samples/jpa/pom.xml +++ b/samples/jpa/pom.xml @@ -1,23 +1,17 @@ - - - + + + 4.0.0 @@ -41,6 +35,7 @@ ${project.version} true + http://git-wip-us.apache.org/repos/asf/karaf-boot/blob/af6327ca/starters/karaf-boot-starter-jpa/pom.xml ---------------------------------------------------------------------- diff --git a/starters/karaf-boot-starter-jpa/pom.xml b/starters/karaf-boot-starter-jpa/pom.xml index c0ce5b8..734714b 100644 --- a/starters/karaf-boot-starter-jpa/pom.xml +++ b/starters/karaf-boot-starter-jpa/pom.xml @@ -1,23 +1,17 @@ - + - + 4.0.0 @@ -32,15 +26,36 @@ - org.osgi - osgi.cmpn - ${osgi.version} - - org.apache.geronimo.specs geronimo-jpa_2.0_spec 1.1 + + + + junit + junit + 4.12 + test + + + org.mockito + mockito-core + 1.10.19 + test + http://git-wip-us.apache.org/repos/asf/karaf-boot/blob/af6327ca/starters/karaf-boot-starter-jpa/src/main/java/org/apache/karaf/boot/jpa/impl/JpaProcessor.java ---------------------------------------------------------------------- diff --git a/starters/karaf-boot-starter-jpa/src/main/java/org/apache/karaf/boot/jpa/impl/JpaProcessor.java b/starters/karaf-boot-starter-jpa/src/main/java/org/apache/karaf/boot/jpa/impl/JpaProcessor.java index 4becbc2..ed52850 100644 --- a/starters/karaf-boot-starter-jpa/src/main/java/org/apache/karaf/boot/jpa/impl/JpaProcessor.java +++ b/starters/karaf-boot-starter-jpa/src/main/java/org/apache/karaf/boot/jpa/impl/JpaProcessor.java @@ -1,27 +1,26 @@ 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 javax.annotation.processing.AbstractProcessor; +import javax.annotation.processing.RoundEnvironment; +import javax.lang.model.element.AnnotationMirror; +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 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; @@ -41,76 +40,93 @@ public class JpaProcessor extends AbstractProcessor { @Override public boolean process(Set annotations, RoundEnvironment roundEnv) { Map> units = new HashMap>(); - - for (Element elem : roundEnv.getElementsAnnotatedWith(PersistentUnit.class)) { PersistentUnit pu = elem.getAnnotation(PersistentUnit.class); units.put(pu, elem.getAnnotationMirrors()); } if (!units.isEmpty()) { try { - Set puNames = new HashSet(); FileObject o = processingEnv.getFiler().createResource(StandardLocation.CLASS_OUTPUT, - "", "META-INF/persistence.xml"); - PrintWriter w = new PrintWriter(o.openWriter()); - w.println(""); - w.println(""); - 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(" "); - if (!pu.description().isEmpty()) { - w.println(" " + pu.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(" " + name + ""); - } - if (!pu.jtaDataSource().isEmpty()) { - w.println(" " + pu.jtaDataSource() + ""); - } - if (!pu.nonJtaDataSource().isEmpty()) { - w.println(" " + pu.nonJtaDataSource() + ""); - } - if (pu.properties().length > 0) { - w.println(" "); - for (Property property : pu.properties()) { - w.println(" "); - } + "", "META-INF/persistence.xml"); + process(o.openWriter(), units); + processingEnv.getMessager().printMessage(Kind.NOTE, "Generated META-INF/persistence.xml"); + } catch (Exception e) { + processingEnv.getMessager().printMessage(Kind.ERROR, "Error: " + e.getMessage()); + } + } + return true; + } + + public void process(Writer writer, Map> units) throws Exception { + Set puNames = new HashSet(); + XMLOutputFactory xof = XMLOutputFactory.newInstance(); + //XMLStreamWriter w = new IndentingXMLStreamWriter(xof.createXMLStreamWriter(writer)); + XMLStreamWriter w = xof.createXMLStreamWriter(writer); + w.setDefaultNamespace("http://java.sun.com/xml/ns/persistence"); + w.writeStartDocument(); + w.writeStartElement("persistence"); + w.writeAttribute("verson", "2.0"); + + //w.println(""); + 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.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 props = new HashMap<>(); + addProperties(pu, props); + addAnnProperties(units.get(pu), 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 props) { + if (pu.properties() == null) { + return; + } + for (Property property : pu.properties()) { + props.put(property.name(), property.value()); + } + } - for (AnnotationMirror annMirror : units.get(pu)) { + private void addAnnProperties(List annotations, Map props) + throws XMLStreamException { + for (AnnotationMirror annMirror : annotations) { - 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(" "); - } + 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(); + 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()); @@ -121,20 +137,34 @@ public class JpaProcessor extends AbstractProcessor { // } else { // processingEnv.getMessager().printMessage(Kind.MANDATORY_WARNING, "Annotation nok"); // } - } + } + } - w.println(" "); - } - w.println(" "); - } - w.println(""); - w.close(); - processingEnv.getMessager().printMessage(Kind.NOTE, "Generated META-INF/persistence.xml"); - } catch (IOException e) { - processingEnv.getMessager().printMessage(Kind.ERROR, "Error: " + e.getMessage()); + 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: + 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; } - return true; } } http://git-wip-us.apache.org/repos/asf/karaf-boot/blob/af6327ca/starters/karaf-boot-starter-jpa/src/test/java/org/apache/karaf/boot/jpa/impl/JpaProcessorTest.java ---------------------------------------------------------------------- diff --git a/starters/karaf-boot-starter-jpa/src/test/java/org/apache/karaf/boot/jpa/impl/JpaProcessorTest.java b/starters/karaf-boot-starter-jpa/src/test/java/org/apache/karaf/boot/jpa/impl/JpaProcessorTest.java new file mode 100644 index 0000000..d3e683a --- /dev/null +++ b/starters/karaf-boot-starter-jpa/src/test/java/org/apache/karaf/boot/jpa/impl/JpaProcessorTest.java @@ -0,0 +1,64 @@ +package org.apache.karaf.boot.jpa.impl; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.io.File; +import java.io.StringWriter; +import java.net.URL; +import java.nio.charset.Charset; +import java.nio.file.Files; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.lang.model.element.AnnotationMirror; + +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.jpa.TransactionType; +import org.junit.Assert; +import org.junit.Ignore; +import org.junit.Test; + +public class JpaProcessorTest { + + @Ignore + @Test + public void testProcess() throws Exception { + JpaProcessor processor = new JpaProcessor(); + Map> units = new HashMap<>(); + PersistentUnit pu = getTestPersitentUnit(); + units.put(pu, Collections.emptyList()); + URL url = this.getClass().getResource("/expected_persistence.xml"); + byte[] encoded = Files.readAllBytes(new File(url.toURI()).toPath()); + String expected = new String(encoded, Charset.forName("utf-8")); + StringWriter writer = new StringWriter(); + processor.process(writer, units); + Assert.assertEquals(expected, writer.getBuffer().toString()); + } + + private PersistentUnit getTestPersitentUnit() { + PersistentUnit pu = mock(PersistentUnit.class); + when(pu.name()).thenReturn("test-pu"); + when(pu.provider()).thenReturn(Provider.Hibernate); + when(pu.transactionType()).thenReturn(TransactionType.JTA); + when(pu.description()).thenReturn("Some description"); + when(pu.jtaDataSource()).thenReturn("myds"); + Property dialect = prop("hibernate.dialect", "org.hibernate.dialect.DerbyDialect"); + Property[] props = new Property[] { dialect }; + when(pu.properties()).thenReturn(props); + return pu; + } + + private Property prop(String name, String value) { + Property dialect = mock(Property.class); + when(dialect.name()).thenReturn(name); + when(dialect.value()).thenReturn(value); + return dialect; + } + + +} http://git-wip-us.apache.org/repos/asf/karaf-boot/blob/af6327ca/starters/karaf-boot-starter-jpa/src/test/resources/expected_persistence.xml ---------------------------------------------------------------------- diff --git a/starters/karaf-boot-starter-jpa/src/test/resources/expected_persistence.xml b/starters/karaf-boot-starter-jpa/src/test/resources/expected_persistence.xml new file mode 100644 index 0000000..8002eba --- /dev/null +++ b/starters/karaf-boot-starter-jpa/src/test/resources/expected_persistence.xml @@ -0,0 +1,11 @@ + + + + Some description + org.hibernate.jpa.HibernatePersistenceProvider + myds + + + + +