JPA persistence.xml 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/dd56eb85 Tree: http://git-wip-us.apache.org/repos/asf/karaf-boot/tree/dd56eb85 Diff: http://git-wip-us.apache.org/repos/asf/karaf-boot/diff/dd56eb85
Branch: refs/heads/master Commit: dd56eb8539118c462e55564becf8f1a647cf53d6 Parents: d68761c Author: Guillaume Nodet <[email protected]> Authored: Thu Apr 14 20:35:17 2016 +0200 Committer: Guillaume Nodet <[email protected]> Committed: Thu Apr 14 20:37:55 2016 +0200 ---------------------------------------------------------------------- .../karaf-boot-starter-jpa/pom.xml | 57 ++++++++ .../org/apache/karaf/boot/jpa/EclipseLink.java | 4 + .../org/apache/karaf/boot/jpa/Hibernate.java | 93 ++++++++++++ .../java/org/apache/karaf/boot/jpa/OpenJpa.java | 38 +++++ .../apache/karaf/boot/jpa/PersistentUnit.java | 36 +++++ .../org/apache/karaf/boot/jpa/Property.java | 13 ++ .../org/apache/karaf/boot/jpa/Provider.java | 10 ++ .../apache/karaf/boot/jpa/TransactionType.java | 6 + .../karaf/boot/jpa/impl/JpaProcessor.java | 140 +++++++++++++++++++ .../javax.annotation.processing.Processor | 1 + karaf-boot-starters/pom.xml | 1 + 11 files changed, 399 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/karaf-boot/blob/dd56eb85/karaf-boot-starters/karaf-boot-starter-jpa/pom.xml ---------------------------------------------------------------------- diff --git a/karaf-boot-starters/karaf-boot-starter-jpa/pom.xml b/karaf-boot-starters/karaf-boot-starter-jpa/pom.xml new file mode 100644 index 0000000..c0ce5b8 --- /dev/null +++ b/karaf-boot-starters/karaf-boot-starter-jpa/pom.xml @@ -0,0 +1,57 @@ +<?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. + --> + + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.apache.karaf.boot</groupId> + <artifactId>karaf-boot-starters</artifactId> + <version>1.0.0-SNAPSHOT</version> + <relativePath>../pom.xml</relativePath> + </parent> + + <artifactId>karaf-boot-starter-jpa</artifactId> + + <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> + </dependencies> + + <build> + <plugins> + <plugin> + <artifactId>maven-compiler-plugin</artifactId> + <configuration> + <compilerArgument>-proc:none</compilerArgument> + </configuration> + </plugin> + </plugins> + </build> + +</project> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/karaf-boot/blob/dd56eb85/karaf-boot-starters/karaf-boot-starter-jpa/src/main/java/org/apache/karaf/boot/jpa/EclipseLink.java ---------------------------------------------------------------------- diff --git a/karaf-boot-starters/karaf-boot-starter-jpa/src/main/java/org/apache/karaf/boot/jpa/EclipseLink.java b/karaf-boot-starters/karaf-boot-starter-jpa/src/main/java/org/apache/karaf/boot/jpa/EclipseLink.java new file mode 100644 index 0000000..f1cba0d --- /dev/null +++ b/karaf-boot-starters/karaf-boot-starter-jpa/src/main/java/org/apache/karaf/boot/jpa/EclipseLink.java @@ -0,0 +1,4 @@ +package org.apache.karaf.boot.jpa; + +public interface EclipseLink { +} http://git-wip-us.apache.org/repos/asf/karaf-boot/blob/dd56eb85/karaf-boot-starters/karaf-boot-starter-jpa/src/main/java/org/apache/karaf/boot/jpa/Hibernate.java ---------------------------------------------------------------------- diff --git a/karaf-boot-starters/karaf-boot-starter-jpa/src/main/java/org/apache/karaf/boot/jpa/Hibernate.java b/karaf-boot-starters/karaf-boot-starter-jpa/src/main/java/org/apache/karaf/boot/jpa/Hibernate.java new file mode 100644 index 0000000..06361d4 --- /dev/null +++ b/karaf-boot-starters/karaf-boot-starter-jpa/src/main/java/org/apache/karaf/boot/jpa/Hibernate.java @@ -0,0 +1,93 @@ +package org.apache.karaf.boot.jpa; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import org.apache.karaf.boot.jpa.PersistentUnit.ProviderProperty; + +public interface Hibernate { + + @ProviderProperty("hibernate.query.substitutions") + @Target(ElementType.TYPE) + @Retention(RetentionPolicy.SOURCE) + @interface QuerySubstitutions { + String value(); + } + + @ProviderProperty("hibernate.hbm2ddl.auto") + @Target(ElementType.TYPE) + @Retention(RetentionPolicy.SOURCE) + @interface Hbm2DdlAuto { + Hbm2DdlAutoType value(); + } + + @ProviderProperty("hibernate.dialect") + @Target(ElementType.TYPE) + @Retention(RetentionPolicy.SOURCE) + @interface Dialect { + DialectType value(); + } + + enum DialectType { + Cache71, + DataDirectOracle9, + DB2390, + DB2400, + DB2, + Derby, + Firebird, + FrontBase, + H2, + HSQL, + Informix, + Ingres10, + Ingres9, + Ingres, + Interbase, + JDataStore, + Mckoi, + MimerSQL, + MySQL5, + MySQL5InnoDB, + MySQL, + MySQLInnoDB, + MySQLMyISAM, + Oracle10g, + Oracle8i, + Oracle9, + Oracle9i, + Oracle, + Pointbase, + PostgresPlus, + PostgreSQL, + Progress, + RDMSOS2200, + SAPDB, + SQLServer2008, + SQLServer, + Sybase11, + SybaseAnywhere, + SybaseASE15, + Sybase, + Teradata, + TimesTen; + + public String toString() { + return "org.hibernate.dialect." + super.toString() + "Dialect"; + } + } + + enum Hbm2DdlAutoType { + Validate, + Update, + Create, + CreateDrop; + + public String toString() { + return super.toString().toLowerCase(); + } + } + +} http://git-wip-us.apache.org/repos/asf/karaf-boot/blob/dd56eb85/karaf-boot-starters/karaf-boot-starter-jpa/src/main/java/org/apache/karaf/boot/jpa/OpenJpa.java ---------------------------------------------------------------------- diff --git a/karaf-boot-starters/karaf-boot-starter-jpa/src/main/java/org/apache/karaf/boot/jpa/OpenJpa.java b/karaf-boot-starters/karaf-boot-starter-jpa/src/main/java/org/apache/karaf/boot/jpa/OpenJpa.java new file mode 100644 index 0000000..01186fc --- /dev/null +++ b/karaf-boot-starters/karaf-boot-starter-jpa/src/main/java/org/apache/karaf/boot/jpa/OpenJpa.java @@ -0,0 +1,38 @@ +package org.apache.karaf.boot.jpa; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import org.apache.karaf.boot.jpa.PersistentUnit.ProviderProperty; + +public interface OpenJpa { + + @ProviderProperty("openjpa.AutoClear") + @Target(ElementType.TYPE) + @Retention(RetentionPolicy.SOURCE) + @interface AutoClear { + Value value(); + enum Value { + Datastore, All; + public String toString() { + return super.toString().toLowerCase(); + } + } + } + + @ProviderProperty("openjpa.AutoDetach") + @Target(ElementType.TYPE) + @Retention(RetentionPolicy.SOURCE) + @interface AutoDetach { + Value value(); + enum Value { + Close, Commit, Nontx_Read; + public String toString() { + return super.toString().toLowerCase().replace('_', '-'); + } + } + } + +} http://git-wip-us.apache.org/repos/asf/karaf-boot/blob/dd56eb85/karaf-boot-starters/karaf-boot-starter-jpa/src/main/java/org/apache/karaf/boot/jpa/PersistentUnit.java ---------------------------------------------------------------------- diff --git a/karaf-boot-starters/karaf-boot-starter-jpa/src/main/java/org/apache/karaf/boot/jpa/PersistentUnit.java b/karaf-boot-starters/karaf-boot-starter-jpa/src/main/java/org/apache/karaf/boot/jpa/PersistentUnit.java new file mode 100644 index 0000000..ada2ef3 --- /dev/null +++ b/karaf-boot-starters/karaf-boot-starter-jpa/src/main/java/org/apache/karaf/boot/jpa/PersistentUnit.java @@ -0,0 +1,36 @@ +package org.apache.karaf.boot.jpa; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.SOURCE) +public @interface PersistentUnit { + + String name(); + + String description() default ""; + + TransactionType transactionType() default TransactionType.RESOURCE_LOCAL; + + Provider provider() default Provider.Default; + + String providerName() default ""; + + String jtaDataSource() default ""; + + String nonJtaDataSource() default ""; + + // TODO: mapping-file, jar-file, class, exclude-unlisted-classes, shared-cache-mode, validation-mode + + Property[] properties() default {}; + + + @Target(ElementType.ANNOTATION_TYPE) + @interface ProviderProperty { + String value(); + } + +} http://git-wip-us.apache.org/repos/asf/karaf-boot/blob/dd56eb85/karaf-boot-starters/karaf-boot-starter-jpa/src/main/java/org/apache/karaf/boot/jpa/Property.java ---------------------------------------------------------------------- diff --git a/karaf-boot-starters/karaf-boot-starter-jpa/src/main/java/org/apache/karaf/boot/jpa/Property.java b/karaf-boot-starters/karaf-boot-starter-jpa/src/main/java/org/apache/karaf/boot/jpa/Property.java new file mode 100644 index 0000000..5cce58c --- /dev/null +++ b/karaf-boot-starters/karaf-boot-starter-jpa/src/main/java/org/apache/karaf/boot/jpa/Property.java @@ -0,0 +1,13 @@ +package org.apache.karaf.boot.jpa; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +@Retention(RetentionPolicy.SOURCE) +public @interface Property { + + String name(); + + String value(); + +} http://git-wip-us.apache.org/repos/asf/karaf-boot/blob/dd56eb85/karaf-boot-starters/karaf-boot-starter-jpa/src/main/java/org/apache/karaf/boot/jpa/Provider.java ---------------------------------------------------------------------- diff --git a/karaf-boot-starters/karaf-boot-starter-jpa/src/main/java/org/apache/karaf/boot/jpa/Provider.java b/karaf-boot-starters/karaf-boot-starter-jpa/src/main/java/org/apache/karaf/boot/jpa/Provider.java new file mode 100644 index 0000000..13a62d4 --- /dev/null +++ b/karaf-boot-starters/karaf-boot-starter-jpa/src/main/java/org/apache/karaf/boot/jpa/Provider.java @@ -0,0 +1,10 @@ +package org.apache.karaf.boot.jpa; + +public enum Provider { + + Default, + Hibernate, + OpenJpa, + EclipseLink; + +} http://git-wip-us.apache.org/repos/asf/karaf-boot/blob/dd56eb85/karaf-boot-starters/karaf-boot-starter-jpa/src/main/java/org/apache/karaf/boot/jpa/TransactionType.java ---------------------------------------------------------------------- diff --git a/karaf-boot-starters/karaf-boot-starter-jpa/src/main/java/org/apache/karaf/boot/jpa/TransactionType.java b/karaf-boot-starters/karaf-boot-starter-jpa/src/main/java/org/apache/karaf/boot/jpa/TransactionType.java new file mode 100644 index 0000000..53e76d2 --- /dev/null +++ b/karaf-boot-starters/karaf-boot-starter-jpa/src/main/java/org/apache/karaf/boot/jpa/TransactionType.java @@ -0,0 +1,6 @@ +package org.apache.karaf.boot.jpa; + +public enum TransactionType { + RESOURCE_LOCAL, + JTA +} http://git-wip-us.apache.org/repos/asf/karaf-boot/blob/dd56eb85/karaf-boot-starters/karaf-boot-starter-jpa/src/main/java/org/apache/karaf/boot/jpa/impl/JpaProcessor.java ---------------------------------------------------------------------- diff --git a/karaf-boot-starters/karaf-boot-starter-jpa/src/main/java/org/apache/karaf/boot/jpa/impl/JpaProcessor.java b/karaf-boot-starters/karaf-boot-starter-jpa/src/main/java/org/apache/karaf/boot/jpa/impl/JpaProcessor.java new file mode 100644 index 0000000..4becbc2 --- /dev/null +++ b/karaf-boot-starters/karaf-boot-starter-jpa/src/main/java/org/apache/karaf/boot/jpa/impl/JpaProcessor.java @@ -0,0 +1,140 @@ +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; + } + +} http://git-wip-us.apache.org/repos/asf/karaf-boot/blob/dd56eb85/karaf-boot-starters/karaf-boot-starter-jpa/src/main/resources/META-INF/services/javax.annotation.processing.Processor ---------------------------------------------------------------------- diff --git a/karaf-boot-starters/karaf-boot-starter-jpa/src/main/resources/META-INF/services/javax.annotation.processing.Processor b/karaf-boot-starters/karaf-boot-starter-jpa/src/main/resources/META-INF/services/javax.annotation.processing.Processor new file mode 100644 index 0000000..eb83448 --- /dev/null +++ b/karaf-boot-starters/karaf-boot-starter-jpa/src/main/resources/META-INF/services/javax.annotation.processing.Processor @@ -0,0 +1 @@ +org.apache.karaf.boot.jpa.impl.JpaProcessor http://git-wip-us.apache.org/repos/asf/karaf-boot/blob/dd56eb85/karaf-boot-starters/pom.xml ---------------------------------------------------------------------- diff --git a/karaf-boot-starters/pom.xml b/karaf-boot-starters/pom.xml index caa5d44..8a22ae1 100644 --- a/karaf-boot-starters/pom.xml +++ b/karaf-boot-starters/pom.xml @@ -36,6 +36,7 @@ <module>karaf-boot-starter-ds</module> <module>karaf-boot-starter-shell</module> <module>karaf-boot-starter-web</module> + <module>karaf-boot-starter-jpa</module> </modules> </project> \ No newline at end of file
