You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@karaf.apache.org by cs...@apache.org on 2016/05/09 14:48:49 UTC
[30/35] karaf-boot git commit: Use stax for file generation
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 <ch...@die-schneider.net>
Authored: Mon Apr 25 18:30:19 2016 +0200
Committer: Christian Schneider <ch...@die-schneider.net>
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 @@
<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-
- <!--
-
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+ <!-- Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with this
+ work for additional information regarding copyright ownership. The ASF licenses
+ this file to You under the Apache License, Version 2.0 (the "License"); you
+ may not use this file except in compliance with the License. You may obtain
+ a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless
+ required by applicable law or agreed to in writing, software distributed
+ under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES
+ OR CONDITIONS OF ANY KIND, either express or implied. See the License for
+ the specific language governing permissions and limitations under the License. -->
<modelVersion>4.0.0</modelVersion>
@@ -41,6 +35,7 @@
<version>${project.version}</version>
<extensions>true</extensions>
</plugin>
+
</plugins>
</build>
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 @@
<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <!--
-
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- -->
+ <!-- Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with this
+ work for additional information regarding copyright ownership. The ASF licenses
+ this file to You under the Apache License, Version 2.0 (the "License"); you
+ may not use this file except in compliance with the License. You may obtain
+ a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless
+ required by applicable law or agreed to in writing, software distributed
+ under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES
+ OR CONDITIONS OF ANY KIND, either express or implied. See the License for
+ the specific language governing permissions and limitations under the License. -->
<modelVersion>4.0.0</modelVersion>
@@ -32,15 +26,36 @@
<dependencies>
<dependency>
- <groupId>org.osgi</groupId>
- <artifactId>osgi.cmpn</artifactId>
- <version>${osgi.version}</version>
- </dependency>
- <dependency>
<groupId>org.apache.geronimo.specs</groupId>
<artifactId>geronimo-jpa_2.0_spec</artifactId>
<version>1.1</version>
</dependency>
+ <!--
+ <dependency>
+ <groupId>net.java.dev.stax-utils</groupId>
+ <artifactId>stax-utils</artifactId>
+ <version>20070216</version>
+ <exclusions>
+ <exclusion>
+ <artifactId>jsr173-ri</artifactId>
+ <groupId>com.bea.xml</groupId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ -->
+
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.12</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-core</artifactId>
+ <version>1.10.19</version>
+ <scope>test</scope>
+ </dependency>
</dependencies>
<build>
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<? 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() + "\"/>");
- }
+ "", "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<PersistentUnit, List<? extends AnnotationMirror>> units) throws Exception {
+ Set<String> puNames = new HashSet<String>();
+ 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("<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.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(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<String, String> 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<? extends AnnotationMirror> annotations, Map<String, String> 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(" <property name=\"" + name + "\" value=\"" + value + "\"/>");
- }
+ 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(" </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());
+ 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<PersistentUnit, List<? extends AnnotationMirror>> 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 @@
+<?xml version="1.0" ?>
+<persistence verson="2.0">
+ <persistence-unit name="test-pu" transaction-type="JTA">
+ <description>Some description</description>
+ <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
+ <jta-data-source>myds</jta-data-source>
+ <properties>
+ <property name="hibernate.dialect" value="org.hibernate.dialect.DerbyDialect"/>
+ </properties>
+ </persistence-unit>
+</persistence>