METAGEN Start of JPA metamodel processor project

This commit is contained in:
Hardy Ferentschik 2009-07-07 09:04:46 +00:00 committed by Strong Liu
parent 1e39c4b07f
commit 31901374fc
62 changed files with 6142 additions and 0 deletions

View File

@ -0,0 +1,19 @@
- Find host for project
- Implement XML overriding of annotation metadata
- Implement access Type rules for XML metadata
- Investigate why it is not possible to use the Filer API to load non class resources, eg
/META-INF/orm.xml. The API throws a FilerException with the message "Illegal name /META-INF".
The call is processingEnv.getFiler().getResource((StandardLocation.CLASS_OUTPUT, "/META-INF", "orm.xml" )
Currently we work around this by using Class.getResourceAsStream()
- Optimize XML parsing by only processing XML files if they have changed since last run (maybe write
a tmp file against which to compare the last modified time stamp)
- Reduce the amount of logging and make logging configurable using the possibility to pass arguments to
the processor using -Akey[=value]
- Write IDE specific plugins which allow to cache processing steps

View File

@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed 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.

View File

@ -0,0 +1,323 @@
<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-jpamodelgen</artifactId>
<version>1.0.0-SNAPSHOT</version>
<name>JPA 2 Static-Metamodel Generator</name>
<description>Annotation Processor to generate JPA 2 static metamodel classes</description>
<inceptionYear>2009</inceptionYear>
<dependencies>
<dependency>
<groupId>org.hibernate.java-persistence</groupId>
<artifactId>jpa-api</artifactId>
<version>2.0-cr-1</version>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>5.8</version>
<classifier>jdk15</classifier>
<scope>test</scope>
</dependency>
</dependencies>
<licenses>
<license>
<name>Apache License, Version 2.0</name>
<url>license.txt</url>
</license>
</licenses>
<scm>
<connection>scm:svn:https://svn.jboss.org/repos/hibernate/jpamodelgen/trunk</connection>
<url>http://fisheye.jboss.org/browse/Hibernate/jpamodelgen/trunk</url>
</scm>
<developers>
<developer>
<id>epbernard</id>
<name>Emmanuel Bernard</name>
<email>emmanuel@hibernate.org</email>
<url>http://in.relation.to/Bloggers/Emmanuel</url>
</developer>
<developer>
<id>hardy.ferentschik</id>
<name>Hardy Ferentschik</name>
<email>hferents@redhat.com</email>
<organization>JBoss, a division of Red Hat</organization>
<url>http://in.relation.to/Bloggers/Hardy</url>
</developer>
<developer>
<id>max.andersen@jboss.com</id>
<name>Max Andersen</name>
<email>max.andersen@redhat.com</email>
<url>http://in.relation.to/Bloggers/Max</url>
</developer>
</developers>
<build>
<defaultGoal>test</defaultGoal>
<resources>
<resource>
<directory>src/main/resources</directory>
</resource>
<resource>
<directory>src/main/xsd</directory>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.0.2</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
<compilerArgument>-proc:none</compilerArgument>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<id>process_annotations</id>
<phase>process-test-resources</phase>
<configuration>
<tasks>
<property name="build.compiler" value="extJavac"/>
<property name="target.dir" value="${project.build.directory}/generated-src/jpamodelgen"/>
<mkdir dir="${target.dir}"/>
<javac srcdir="${project.build.testSourceDirectory}"
destdir="${target.dir}"
failonerror="false"
excludes="test/**">
<compilerarg value="-proc:only"/>
<classpath>
<path refid="maven.test.classpath"/>
</classpath>
</javac>
</tasks>
<testSourceRoot>${project.build.directory}/generated-src/jpamodelgen</testSourceRoot>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jaxb2-maven-plugin</artifactId>
<version>1.2</version>
<executions>
<execution>
<goals>
<goal>xjc</goal>
</goals>
</execution>
</executions>
<configuration>
<packageName>org.hibernate.jpamodelgen.xml.jaxb</packageName>
<outputDirectory>${basedir}/target/generated-sources</outputDirectory>
<extension>true</extension>
</configuration>
</plugin>
<plugin>
<inherited>true</inherited>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<suiteXmlFiles>
<suiteXmlFile>${basedir}/src/test/suite/unit-tests.xml</suiteXmlFile>
</suiteXmlFiles>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-report-plugin</artifactId>
<executions>
<execution>
<id>generate-test-report</id>
<phase>test</phase>
<goals>
<goal>report-only</goal>
</goals>
</execution>
</executions>
<configuration>
<outputDirectory>${project.build.directory}/surefire-reports</outputDirectory>
<outputName>test-report</outputName>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.2</version>
<configuration>
<archive>
<manifestEntries>
<Implementation-Title>${pom.artifactId}</Implementation-Title>
<Implementation-Version>${pom.version}</Implementation-Version>
<Implementation-Vendor>${pom.groupId}</Implementation-Vendor>
<Implementation-Vendor-Id>${pom.groupId}</Implementation-Vendor-Id>
<Implementation-URL>${pom.url}</Implementation-URL>
<Specification-Title>JPA2 Model Generator</Specification-Title>
</manifestEntries>
</archive>
</configuration>
</plugin>
<plugin>
<artifactId>maven-source-plugin</artifactId>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptors>
<descriptor>src/main/assembly/dist.xml</descriptor>
</descriptors>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>site</phase>
<goals>
<goal>assembly</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-release-plugin</artifactId>
<version>2.0-beta-9</version>
<configuration>
<autoVersionSubmodules>true</autoVersionSubmodules>
<allowTimestampedSnapshots>true</allowTimestampedSnapshots>
<remoteTagging>true</remoteTagging>
<goals>package deploy</goals>
</configuration>
</plugin>
</plugins>
<extensions>
<!-- scm based deployments (jboss release repo) -->
<extension>
<groupId>org.apache.maven.wagon</groupId>
<artifactId>wagon-scm</artifactId>
<version>1.0-beta-6</version>
</extension>
<extension>
<groupId>org.apache.maven.scm</groupId>
<artifactId>maven-scm-manager-plexus</artifactId>
<version>1.0</version>
</extension>
<extension>
<groupId>org.apache.maven.scm</groupId>
<artifactId>maven-scm-provider-svnexe</artifactId>
<version>1.0</version>
</extension>
</extensions>
</build>
<distributionManagement>
<repository>
<id>repository.jboss.org</id>
<name>JBoss Release Repository</name>
<url>scm:svn:https://svn.jboss.org/repos/repository.jboss.org/maven2</url>
</repository>
<snapshotRepository>
<id>snapshots.jboss.org</id>
<name>JBoss Snapshot Repository</name>
<url>dav:https://snapshots.jboss.org/maven2</url>
</snapshotRepository>
</distributionManagement>
<reporting>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-project-info-reports-plugin</artifactId>
<version>2.0.1</version>
</plugin>
<plugin>
<artifactId>maven-javadoc-plugin</artifactId>
<reportSets>
<reportSet>
<id>html</id>
<configuration>
<tags>
<tag>
<name>todo</name>
<placement>a</placement>
<head>ToDo:</head>
</tag>
</tags>
</configuration>
<reports>
<report>javadoc</report>
</reports>
</reportSet>
</reportSets>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jxr-maven-plugin</artifactId>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
</plugin>
<plugin>
<artifactId>maven-clover-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-pmd-plugin</artifactId>
<configuration>
<targetJdk>1.5</targetJdk>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>taglist-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>changelog-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>changes-maven-plugin</artifactId>
</plugin>
</plugins>
</reporting>
</project>

View File

@ -0,0 +1,65 @@
JPA Model Generator
What is it?
-----------
This is a Java 6 annotation processor generating meta model classes for the JPA 2 criteria queries.
The processor (JPAMetaModelEntityProcessor) processes all classes annotated with @Entity, as well as
entities mapped in /META-INF/orm.xml and mapping files specified in persistence.xml.
Status
------
This is an alpha release of the annotation processor. The implemented functionality includes:
- full support for annotations honoring the access type (v2.0)
- support for persistence.xml, orm.xml and <mapping-file>
- tests (both via compilation failure and regular assertion failure)
System Requirements
-------------------
JDK 1.6 or above.
Issues
------
See issues.txt
Using JPA Model Generator
-------------------------
- Copy jpamodelgen-*.jar together will all jar files from lib into the classpath of your application.
The jpamodelgen jar file contains a service file (/META-INF/services/javax.annotation.processing.Processor)
so that the annotation processor will automatically be executed during compilation.
You can also explicitly specify the processor using the -processor flag:
> javac -cp <myclasspath> -d <target> -sourcepath <sources> -processor org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor
* Maven
This distribution contains a pom.xml file showing one of three possible ways to integrate the processor in a maven project.
You can just add <processor>org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor</processor> to the maven-compiler-plugin.
This approach has, however, the shortcoming that messages from the annotation processor are not displayed. This is a known
issue. See also - http://weblogs.java.net/blog/ss141213/archive/2007/11/my_maven_experi.html
The second alternative is the maven-annotation-plugin (http://code.google.com/p/maven-annotation-plugin/). This approach
hasn't been tested yet.
Last but not least, you can use the maven-antrun-plugin to just run the annotation processor and ignore the processor in
in the maven-compiler-plugin via '-proc:none'. This is the approach chosen in the POM for this project.
* Ant
Make sure the annotation processor and its dependencies are in the classpath. Due the service file the processor will be
automatically executed when the javac task executes.
If not try adding <compilerarg value="-processor org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor"/>
* Idea
Again, if in the classpath the JPAMetaModelEntityProcessor should execute automatically. If not add the following under
'Compiler->Java Compiler': -target 1.6 -processor org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor
You can also turn of annotation processing via: -target 1.6 -proc:none

View File

@ -0,0 +1,81 @@
<?xml version='1.0' encoding='UTF-8'?>
<!--
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.
-->
<assembly>
<id>dist</id>
<formats>
<format>tar.gz</format>
<format>tar.bz2</format>
<format>zip</format>
</formats>
<dependencySets>
<dependencySet>
<useProjectArtifact>false</useProjectArtifact>
<outputDirectory>lib</outputDirectory>
<scope>runtime</scope>
</dependencySet>
</dependencySets>
<files>
<file>
<source>readme.txt</source>
<outputDirectory>/</outputDirectory>
<filtered>true</filtered>
</file>
<file>
<source>license.txt</source>
<outputDirectory>/</outputDirectory>
</file>
<file>
<source>issues.txt</source>
<outputDirectory>/</outputDirectory>
</file>
</files>
<fileSets>
<fileSet>
<directory>target</directory>
<outputDirectory/>
<excludes>
<exclude>*-javadoc.jar</exclude>
<exclude>*-sources.jar</exclude>
</excludes>
<includes>
<include>jpamodelgen-*.jar</include>
</includes>
</fileSet>
<fileSet>
<directory>target/site/apidocs</directory>
<outputDirectory>docs/api</outputDirectory>
</fileSet>
<fileSet>
<directory>.</directory>
<outputDirectory/>
<useDefaultExcludes>true</useDefaultExcludes>
<excludes>
<exclude>*.txt</exclude>
<exclude>**/target/**</exclude>
<exclude>*.iml</exclude>
</excludes>
</fileSet>
</fileSets>
</assembly>

View File

@ -0,0 +1,140 @@
// $Id$
/*
* JBoss, Home of Professional Open Source
* Copyright 2008, Red Hat Middleware LLC, and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* Licensed 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.
*/
package org.hibernate.jpamodelgen;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.IOException;
import java.io.StringWriter;
import java.util.List;
import javax.annotation.processing.ProcessingEnvironment;
import javax.annotation.processing.FilerException;
import javax.annotation.Generated;
import javax.tools.FileObject;
import javax.tools.Diagnostic;
import javax.lang.model.type.TypeMirror;
import javax.lang.model.type.TypeKind;
import javax.lang.model.type.DeclaredType;
import javax.lang.model.element.Element;
import javax.lang.model.element.TypeElement;
/**
* @author Emmanuel Bernard
*/
public class ClassWriter {
public static void writeFile(IMetaEntity entity, ProcessingEnvironment processingEnv, Context context) {
try {
String metaModelPackage = entity.getPackageName();
StringBuffer body = generateBody( entity, context );
FileObject fo = processingEnv.getFiler().createSourceFile(
metaModelPackage + "." + entity.getSimpleName() + "_"
);
OutputStream os = fo.openOutputStream();
PrintWriter pw = new PrintWriter( os );
pw.println( "package " + metaModelPackage + ";" );
pw.println();
pw.println( entity.generateImports() );
pw.println( body );
pw.flush();
pw.close();
}
catch ( FilerException filerEx ) {
processingEnv.getMessager().printMessage(
Diagnostic.Kind.ERROR,
"Problem with Processing Environment Filer: "
+ filerEx.getMessage()
);
}
catch ( IOException ioEx ) {
processingEnv.getMessager().printMessage(
Diagnostic.Kind.ERROR,
"Problem opening file to write MetaModel for " + entity.getSimpleName()
+ ioEx.getMessage()
);
}
}
/**
* Generate everything after import statements.
*
* @param entity The meta entity for which to write the body
*
* @return body content
*/
private static StringBuffer generateBody(IMetaEntity entity, Context context) {
StringWriter sw = new StringWriter();
PrintWriter pw = null;
try {
pw = new PrintWriter( sw );
//pw.println( "@" + entity.importType( Generated.class.getName() ) + "(\"JPA MetaModel for " + entity.getQualifiedName() + "\")" );
pw.println( "@" + entity.importType( "javax.persistence.metamodel.StaticMetamodel" ) + "(" + entity.getSimpleName() + ".class)" );
printClassDeclaration( entity, pw, context );
pw.println();
List<IMetaAttribute> members = entity.getMembers();
for ( IMetaAttribute metaMember : members ) {
pw.println( " " + metaMember.getDeclarationString() );
}
pw.println();
pw.println( "}" );
return sw.getBuffer();
}
finally {
if ( pw != null ) {
pw.close();
}
}
}
private static void printClassDeclaration(IMetaEntity entity, PrintWriter pw, Context context) {
pw.print( "public abstract class " + entity.getSimpleName() + "_" );
final TypeMirror superClass = entity.getTypeElement().getSuperclass();
//superclass of Object is of NoType which returns some other kind
String superclassDeclaration = "";
if (superClass.getKind() == TypeKind.DECLARED ) {
//F..king Ch...t Have those people used their horrible APIs even once?
final Element superClassElement = ( ( DeclaredType ) superClass ).asElement();
String superClassName = ( ( TypeElement ) superClassElement ).getQualifiedName().toString();
if ( context.getMetaEntitiesToProcess().containsKey( superClassName )
|| context.getMetaSuperclassAndEmbeddableToProcess().containsKey( superClassName ) ) {
pw.print( " extends " + superClassName + "_" );
}
}
pw.println( " {" );
}
}

View File

@ -0,0 +1,104 @@
// $Id$
/*
* JBoss, Home of Professional Open Source
* Copyright 2008, Red Hat Middleware LLC, and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* Licensed 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.
*/
package org.hibernate.jpamodelgen;
import java.util.Map;
import java.util.HashMap;
import java.util.Set;
import java.util.HashSet;
import javax.lang.model.element.TypeElement;
import javax.persistence.AccessType;
import javax.annotation.processing.ProcessingEnvironment;
import javax.tools.Diagnostic;
import org.hibernate.jpamodelgen.annotation.MetaEntity;
/**
* @author Max Andersen
* @author Hardy Ferentschik
* @author Emmanuel Bernard
*/
public class Context {
//used to cache access types
private Map<TypeElement, AccessTypeHolder> accessTypes = new HashMap<TypeElement, AccessTypeHolder>();
private Set<String> elementsAlreadyProcessed = new HashSet<String>();
private ProcessingEnvironment pe;
private final Map<String, IMetaEntity> metaEntitiesToProcess = new HashMap<String, IMetaEntity>();
private final Map<String, IMetaEntity> metaSuperclassAndEmbeddableToProcess = new HashMap<String, IMetaEntity>();
private static class AccessTypeHolder {
public AccessType elementAccessType;
public AccessType hierarchyAccessType;
}
public Context(ProcessingEnvironment pe) {
this.pe = pe;
}
public Map<String, IMetaEntity> getMetaEntitiesToProcess() {
return metaEntitiesToProcess;
}
public Map<String, IMetaEntity> getMetaSuperclassAndEmbeddableToProcess() {
return metaSuperclassAndEmbeddableToProcess;
}
public void addAccessType(TypeElement element, AccessType accessType) {
AccessTypeHolder typeHolder = accessTypes.get( element );
if ( typeHolder == null ) {
typeHolder = new AccessTypeHolder();
accessTypes.put( element, typeHolder );
}
typeHolder.elementAccessType = accessType;
}
public void addAccessTypeForHierarchy(TypeElement element, AccessType accessType) {
AccessTypeHolder typeHolder = accessTypes.get( element );
if ( typeHolder == null ) {
typeHolder = new AccessTypeHolder();
accessTypes.put( element, typeHolder );
}
typeHolder.hierarchyAccessType = accessType;
}
public AccessType getAccessType(TypeElement element) {
final AccessTypeHolder typeHolder = accessTypes.get( element );
return typeHolder != null ? typeHolder.elementAccessType : null;
}
public AccessType getDefaultAccessTypeForHerarchy(TypeElement element) {
final AccessTypeHolder typeHolder = accessTypes.get( element );
return typeHolder != null ? typeHolder.hierarchyAccessType : null;
}
public Set<String> getElementsAlreadyProcessed() {
return elementsAlreadyProcessed;
}
//only process Embeddable or Superclass
//does not work for Entity (risk of circularity)
public void processElement(TypeElement element, AccessType defaultAccessTypeForHierarchy) {
if ( elementsAlreadyProcessed.contains( element.getQualifiedName().toString() ) ) {
pe.getMessager().printMessage( Diagnostic.Kind.WARNING, "Element already processed (ignoring): " + element );
return;
}
ClassWriter.writeFile( new MetaEntity( pe, element, this, defaultAccessTypeForHierarchy ), pe, this );
elementsAlreadyProcessed.add( element.getQualifiedName().toString() );
}
}

View File

@ -0,0 +1,31 @@
// $Id$
/*
* JBoss, Home of Professional Open Source
* Copyright 2008, Red Hat Middleware LLC, and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* Licensed 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.
*/
package org.hibernate.jpamodelgen;
/**
* @author Hardy Ferentschik
*/
public interface IMetaAttribute {
String getDeclarationString();
String getMetaType();
String getPropertyName();
String getTypeDeclaration();
}

View File

@ -0,0 +1,26 @@
// $Id$
/*
* JBoss, Home of Professional Open Source
* Copyright 2008, Red Hat Middleware LLC, and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* Licensed 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.
*/
package org.hibernate.jpamodelgen;
import org.hibernate.jpamodelgen.IMetaAttribute;
/**
* @author Hardy Ferentschik
*/
public interface IMetaCollection extends IMetaAttribute {
}

View File

@ -0,0 +1,45 @@
// $Id$
/*
* JBoss, Home of Professional Open Source
* Copyright 2008, Red Hat Middleware LLC, and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* Licensed 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.
*/
package org.hibernate.jpamodelgen;
import javax.lang.model.element.Name;
import javax.lang.model.element.TypeElement;
import java.util.List;
/**
* @author Hardy Ferentschik
*/
public interface IMetaEntity extends ImportContext {
String getSimpleName();
String getQualifiedName();
String getPackageName();
List<IMetaAttribute> getMembers();
String generateImports();
String importType(String fqcn);
String staticImport(String fqcn, String member);
String importType(Name qualifiedName);
TypeElement getTypeElement();
}

View File

@ -0,0 +1,24 @@
// $Id$
/*
* JBoss, Home of Professional Open Source
* Copyright 2008, Red Hat Middleware LLC, and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* Licensed 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.
*/
package org.hibernate.jpamodelgen;
/**
* @author Hardy Ferentschik
*/
public interface IMetaSingleAttribute extends IMetaAttribute {
}

View File

@ -0,0 +1,46 @@
// $Id$
/*
* JBoss, Home of Professional Open Source
* Copyright 2008, Red Hat Middleware LLC, and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* Licensed 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.
*/
package org.hibernate.jpamodelgen;
/**
*
* @author Max Andersen
* @author Hardy Ferentschik
* @author Emmanuel Bernard
*/
public interface ImportContext {
/**
* Add fqcn to the import list. Returns fqcn as needed in source code.
* Attempts to handle fqcn with array and generics references.
* <p/>
* e.g.
* java.util.Collection<org.marvel.Hulk> imports java.util.Collection and returns Collection
* org.marvel.Hulk[] imports org.marvel.Hulk and returns Hulk
*
* @param fqcn Fully qualified class name of the type to import.
*
* @return import string
*/
public abstract String importType(String fqcn);
public abstract String staticImport(String fqcn, String member);
public abstract String generateImports();
}

View File

@ -0,0 +1,184 @@
// $Id$
/*
* JBoss, Home of Professional Open Source
* Copyright 2008, Red Hat Middleware LLC, and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* Licensed 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.
*/
package org.hibernate.jpamodelgen;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
/**
*
* @author Max Andersen
* @author Hardy Ferentschik
* @author Emmanuel Bernard
*/
public class ImportContextImpl implements ImportContext {
Set<String> imports = new TreeSet<String>();
Set<String> staticImports = new TreeSet<String>();
Map<String, String> simpleNames = new HashMap<String, String>();
String basePackage = "";
private static final Map<String, String> PRIMITIVES = new HashMap<String, String>();
static {
PRIMITIVES.put( "char", "Character" );
PRIMITIVES.put( "byte", "Byte" );
PRIMITIVES.put( "short", "Short" );
PRIMITIVES.put( "int", "Integer" );
PRIMITIVES.put( "long", "Long" );
PRIMITIVES.put( "boolean", "Boolean" );
PRIMITIVES.put( "float", "Float" );
PRIMITIVES.put( "double", "Double" );
}
public ImportContextImpl(String basePackage) {
this.basePackage = basePackage;
}
/**
* Add fqcn to the import list. Returns fqcn as needed in source code.
* Attempts to handle fqcn with array and generics references.
*
* e.g.
* java.util.Collection<org.marvel.Hulk> imports java.util.Collection and returns Collection
* org.marvel.Hulk[] imports org.marvel.Hulk and returns Hulk
*
*
* @param fqcn
* @return import string
*/
public String importType(String fqcn) {
String result = fqcn;
//if(fqcn==null) return "/** (null) **/";
String additionalTypePart = null;
if(fqcn.indexOf('<')>=0) {
additionalTypePart = result.substring(fqcn.indexOf('<'));
result = result.substring(0,fqcn.indexOf('<'));
fqcn = result;
} else if(fqcn.indexOf('[')>=0) {
additionalTypePart = result.substring(fqcn.indexOf('['));
result = result.substring(0,fqcn.indexOf('['));
fqcn = result;
}
String pureFqcn = fqcn.replace( '$', '.' );
boolean canBeSimple = true;
String simpleName = unqualify(fqcn);
if(simpleNames.containsKey(simpleName)) {
String existingFqcn = simpleNames.get(simpleName);
if(existingFqcn.equals(pureFqcn)) {
canBeSimple = true;
} else {
canBeSimple = false;
}
} else {
canBeSimple = true;
simpleNames.put(simpleName, pureFqcn);
imports.add( pureFqcn );
}
if ( inSamePackage(fqcn) || (imports.contains( pureFqcn ) && canBeSimple) ) {
result = unqualify( result ); // dequalify
} else if ( inJavaLang( fqcn ) ) {
result = result.substring( "java.lang.".length() );
}
if(additionalTypePart!=null) {
result = result + additionalTypePart;
}
result = result.replace( '$', '.' );
return result;
}
public String staticImport(String fqcn, String member) {
String local = fqcn + "." + member;
imports.add(local);
staticImports.add(local);
if(member.equals("*")) {
return "";
} else {
return member;
}
}
private boolean inDefaultPackage(String className) {
return className.indexOf( "." ) < 0;
}
private boolean isPrimitive(String className) {
return PRIMITIVES.containsKey( className );
}
private boolean inSamePackage(String className) {
String other = qualifier( className );
return other == basePackage
|| (other != null && other.equals( basePackage ) );
}
private boolean inJavaLang(String className) {
return "java.lang".equals( qualifier( className ) );
}
public String generateImports() {
StringBuffer buf = new StringBuffer();
for ( Iterator<String> imps = imports.iterator(); imps.hasNext(); ) {
String next = imps.next();
if(isPrimitive(next) || inDefaultPackage(next) || inJavaLang(next) || inSamePackage(next)) {
// dont add automatically "imported" stuff
} else {
if(staticImports.contains(next)) {
buf.append("import static " + next + ";\r\n");
} else {
buf.append("import " + next + ";\r\n");
}
}
}
if(buf.indexOf( "$" )>=0) {
return buf.toString();
}
return buf.toString();
}
public static String unqualify(String qualifiedName) {
int loc = qualifiedName.lastIndexOf(".");
return ( loc < 0 ) ? qualifiedName : qualifiedName.substring( qualifiedName.lastIndexOf(".") + 1 );
}
public static String qualifier(String qualifiedName) {
int loc = qualifiedName.lastIndexOf(".");
return ( loc < 0 ) ? "" : qualifiedName.substring( 0, loc );
}
}

View File

@ -0,0 +1,443 @@
// $Id$
/*
* JBoss, Home of Professional Open Source
* Copyright 2008, Red Hat Middleware LLC, and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* Licensed 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.
*/
package org.hibernate.jpamodelgen;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Collection;
import java.util.List;
import java.util.Set;
import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.ProcessingEnvironment;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.annotation.processing.SupportedSourceVersion;
import static javax.lang.model.SourceVersion.RELEASE_6;
import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.TypeElement;
import javax.lang.model.util.Elements;
import javax.persistence.AccessType;
import javax.persistence.Embeddable;
import javax.persistence.MappedSuperclass;
import javax.tools.Diagnostic;
import javax.tools.FileObject;
import javax.tools.StandardLocation;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import org.xml.sax.SAXException;
import org.hibernate.jpamodelgen.annotation.MetaEntity;
import org.hibernate.jpamodelgen.xml.XmlMetaEntity;
import org.hibernate.jpamodelgen.xml.jaxb.Entity;
import org.hibernate.jpamodelgen.xml.jaxb.EntityMappings;
import org.hibernate.jpamodelgen.xml.jaxb.ObjectFactory;
import org.hibernate.jpamodelgen.xml.jaxb.Persistence;
import org.hibernate.jpamodelgen.xml.jaxb.PersistenceUnitDefaults;
import org.hibernate.jpamodelgen.xml.jaxb.PersistenceUnitMetadata;
/**
* Main annotation processor.
*
* @author Max Andersen
* @author Hardy Ferentschik
* @author Emmanuel Bernard
*/
//@SupportedAnnotationTypes("javax.persistence.Entity")
@SupportedAnnotationTypes("*")
@SupportedSourceVersion(RELEASE_6)
// TODO Extract all the XML parsing into a separate class
public class JPAMetaModelEntityProcessor extends AbstractProcessor {
private static final String PATH_SEPARATOR = "/";
private static final String PERSISTENCE_XML = "/META-INF/persistence.xml";
private static final String ORM_XML = "/META-INF/orm.xml";
private static final Boolean ALLOW_OTHER_PROCESSORS_TO_CLAIM_ANNOTATIONS = Boolean.FALSE;
private static final String ENTITY_ANN = javax.persistence.Entity.class.getName();
private static final String MAPPED_SUPERCLASS_ANN = MappedSuperclass.class.getName();
private static final String EMBEDDABLE_ANN = Embeddable.class.getName();
private static final AccessType DEFAULT_XML_ACCESS_TYPE = AccessType.PROPERTY;
private static final String PERSISTENCE_XML_XSD = "persistence_2_0.xsd";
private static final String ORM_XSD = "orm_2_0.xsd";
private boolean xmlProcessed = false;
private Context context;
public void init(ProcessingEnvironment env) {
super.init( env );
context = new Context( env );
processingEnv.getMessager().printMessage( Diagnostic.Kind.NOTE, "Init Processor " + this );
}
@Override
public boolean process(final Set<? extends TypeElement> annotations,
final RoundEnvironment roundEnvironment) {
if ( roundEnvironment.processingOver() ) {
processingEnv.getMessager()
.printMessage( Diagnostic.Kind.NOTE, "Last processing round." );
createMetaModelClasses();
processingEnv.getMessager()
.printMessage( Diagnostic.Kind.NOTE, "Finished processing" );
return ALLOW_OTHER_PROCESSORS_TO_CLAIM_ANNOTATIONS;
}
if ( !xmlProcessed ) {
parsePersistenceXml();
}
if ( !hostJPAAnnotations( annotations ) ) {
processingEnv.getMessager()
.printMessage( Diagnostic.Kind.NOTE, "Current processing round does not contain entities" );
return ALLOW_OTHER_PROCESSORS_TO_CLAIM_ANNOTATIONS;
}
Set<? extends Element> elements = roundEnvironment.getRootElements();
for ( Element element : elements ) {
processingEnv.getMessager().printMessage( Diagnostic.Kind.NOTE, "Processing " + element.toString() );
handleRootElementAnnotationMirrors( element );
}
return ALLOW_OTHER_PROCESSORS_TO_CLAIM_ANNOTATIONS;
}
private void createMetaModelClasses() {
for ( IMetaEntity entity : context.getMetaEntitiesToProcess().values() ) {
processingEnv.getMessager()
.printMessage( Diagnostic.Kind.NOTE, "Writing meta model for " + entity );
ClassWriter.writeFile( entity, processingEnv, context );
}
//process left over, in most cases is empty
for ( String className : context.getElementsAlreadyProcessed() ) {
context.getMetaSuperclassAndEmbeddableToProcess().remove( className );
}
for ( IMetaEntity entity : context.getMetaSuperclassAndEmbeddableToProcess().values() ) {
processingEnv.getMessager()
.printMessage( Diagnostic.Kind.NOTE, "Writing meta model for " + entity );
ClassWriter.writeFile( entity, processingEnv, context );
}
}
private boolean hostJPAAnnotations(Set<? extends TypeElement> annotations) {
for ( TypeElement type : annotations ) {
final String typeName = type.getQualifiedName().toString();
if ( typeName.equals( ENTITY_ANN ) ) {
return true;
}
else if ( typeName.equals( EMBEDDABLE_ANN ) ) {
return true;
}
else if ( typeName.equals( MAPPED_SUPERCLASS_ANN ) ) {
return true;
}
}
return false;
}
private void parsePersistenceXml() {
Persistence persistence = parseXml( PERSISTENCE_XML, Persistence.class, PERSISTENCE_XML_XSD );
if ( persistence != null )
{
List<Persistence.PersistenceUnit> persistenceUnits = persistence.getPersistenceUnit();
for ( Persistence.PersistenceUnit unit : persistenceUnits ) {
List<String> mappingFiles = unit.getMappingFile();
for ( String mappingFile : mappingFiles ) {
parsingOrmXml( mappingFile );
}
}
}
parsingOrmXml( ORM_XML ); // /META-INF/orm.xml is implicit
xmlProcessed = true;
}
private void parsingOrmXml(String resource) {
EntityMappings mappings = parseXml( resource, EntityMappings.class, ORM_XSD );
if ( mappings == null ) {
return;
}
AccessType accessType = determineGlobalAccessType( mappings );
parseEntities( mappings, accessType );
parseEmbeddable( mappings, accessType );
parseMappedSuperClass( mappings, accessType );
}
private AccessType determineGlobalAccessType(EntityMappings mappings) {
AccessType accessType = DEFAULT_XML_ACCESS_TYPE;
if ( mappings.getAccess() != null ) {
accessType = mapXmlAccessTypeToJpaAccessType( mappings.getAccess() );
return accessType; // no need to check persistence unit default
}
PersistenceUnitMetadata meta = mappings.getPersistenceUnitMetadata();
if ( meta != null ) {
PersistenceUnitDefaults persistenceUnitDefaults = meta.getPersistenceUnitDefaults();
if ( persistenceUnitDefaults != null ) {
org.hibernate.jpamodelgen.xml.jaxb.AccessType xmlAccessType = persistenceUnitDefaults.getAccess();
if ( xmlAccessType != null ) {
accessType = mapXmlAccessTypeToJpaAccessType( xmlAccessType );
}
}
}
return accessType;
}
private AccessType mapXmlAccessTypeToJpaAccessType(org.hibernate.jpamodelgen.xml.jaxb.AccessType xmlAccessType) {
switch ( xmlAccessType ) {
case FIELD: {
return AccessType.FIELD;
}
case PROPERTY: {
return AccessType.PROPERTY;
}
}
return null;
}
private void parseEntities(EntityMappings mappings, AccessType accessType) {
String packageName = mappings.getPackage();
Collection<Entity> entities = mappings.getEntity();
for ( Entity entity : entities ) {
String fullyQualifiedClassName = packageName + "." + entity.getClazz();
if ( !xmlMappedTypeExists( fullyQualifiedClassName ) ) {
processingEnv.getMessager().printMessage(
Diagnostic.Kind.WARNING,
fullyQualifiedClassName + " is mapped in xml, but class does not exists. Skipping meta model generation."
);
continue;
}
XmlMetaEntity metaEntity = new XmlMetaEntity(
entity, packageName, getXmlMappedType( fullyQualifiedClassName )
);
if ( context.getMetaEntitiesToProcess().containsKey( fullyQualifiedClassName ) ) {
processingEnv.getMessager().printMessage(
Diagnostic.Kind.WARNING,
fullyQualifiedClassName + " was already processed once. Skipping second occurance."
);
}
context.getMetaEntitiesToProcess().put( fullyQualifiedClassName, metaEntity );
}
}
private boolean xmlMappedTypeExists(String fullyQualifiedClassName) {
Elements utils = processingEnv.getElementUtils();
return utils.getTypeElement( fullyQualifiedClassName ) != null;
}
private TypeElement getXmlMappedType(String fullyQualifiedClassName) {
Elements utils = processingEnv.getElementUtils();
return utils.getTypeElement( fullyQualifiedClassName );
}
private void parseEmbeddable(EntityMappings mappings, AccessType accessType) {
String packageName = mappings.getPackage();
Collection<org.hibernate.jpamodelgen.xml.jaxb.Embeddable> embeddables = mappings.getEmbeddable();
for ( org.hibernate.jpamodelgen.xml.jaxb.Embeddable embeddable : embeddables ) {
String fullyQualifiedClassName = packageName + "." + embeddable.getClazz();
if ( !xmlMappedTypeExists( fullyQualifiedClassName ) ) {
processingEnv.getMessager().printMessage(
Diagnostic.Kind.WARNING,
fullyQualifiedClassName + " is mapped in xml, but class does not exists. Skipping meta model generation."
);
continue;
}
XmlMetaEntity metaEntity = new XmlMetaEntity(
embeddable, packageName, getXmlMappedType( fullyQualifiedClassName )
);
if ( context.getMetaSuperclassAndEmbeddableToProcess().containsKey( fullyQualifiedClassName ) ) {
processingEnv.getMessager().printMessage(
Diagnostic.Kind.WARNING,
fullyQualifiedClassName + " was already processed once. Skipping second occurance."
);
}
context.getMetaSuperclassAndEmbeddableToProcess().put( fullyQualifiedClassName, metaEntity );
}
}
private void parseMappedSuperClass(EntityMappings mappings, AccessType accessType) {
String packageName = mappings.getPackage();
Collection<org.hibernate.jpamodelgen.xml.jaxb.MappedSuperclass> mappedSuperClasses = mappings.getMappedSuperclass();
for ( org.hibernate.jpamodelgen.xml.jaxb.MappedSuperclass mappedSuperClass : mappedSuperClasses ) {
String fullyQualifiedClassName = packageName + "." + mappedSuperClass.getClazz();
if ( !xmlMappedTypeExists( fullyQualifiedClassName ) ) {
processingEnv.getMessager().printMessage(
Diagnostic.Kind.WARNING,
fullyQualifiedClassName + " is mapped in xml, but class does not exists. Skipping meta model generation."
);
continue;
}
XmlMetaEntity metaEntity = new XmlMetaEntity(
mappedSuperClass, packageName, getXmlMappedType( fullyQualifiedClassName )
);
if ( context.getMetaSuperclassAndEmbeddableToProcess().containsKey( fullyQualifiedClassName ) ) {
processingEnv.getMessager().printMessage(
Diagnostic.Kind.WARNING,
fullyQualifiedClassName + " was already processed once. Skipping second occurance."
);
}
context.getMetaSuperclassAndEmbeddableToProcess().put( fullyQualifiedClassName, metaEntity );
}
}
private void handleRootElementAnnotationMirrors(final Element element) {
List<? extends AnnotationMirror> annotationMirrors = element
.getAnnotationMirrors();
for ( AnnotationMirror mirror : annotationMirrors ) {
final String annotationType = mirror.getAnnotationType().toString();
if ( element.getKind() == ElementKind.CLASS ) {
if ( annotationType.equals( ENTITY_ANN ) ) {
MetaEntity metaEntity = new MetaEntity( processingEnv, ( TypeElement ) element, context );
// TODO instead of just adding the entity we have to do some merging.
context.getMetaEntitiesToProcess().put( metaEntity.getQualifiedName(), metaEntity );
}
else if ( annotationType.equals( MAPPED_SUPERCLASS_ANN )
|| annotationType.equals( EMBEDDABLE_ANN ) ) {
MetaEntity metaEntity = new MetaEntity( processingEnv, ( TypeElement ) element, context );
// TODO instead of just adding the entity we have to do some merging.
context.getMetaSuperclassAndEmbeddableToProcess().put( metaEntity.getQualifiedName(), metaEntity );
}
}
}
}
private InputStream getInputStreamForResource(String resource) {
String pkg = getPackage( resource );
String name = getRelativeName( resource );
processingEnv.getMessager()
.printMessage( Diagnostic.Kind.NOTE, "Reading resource " + resource );
InputStream ormStream;
try {
FileObject fileObject = processingEnv.getFiler().getResource( StandardLocation.CLASS_OUTPUT, pkg, name );
ormStream = fileObject.openInputStream();
}
catch ( IOException e1 ) {
processingEnv.getMessager()
.printMessage(
Diagnostic.Kind.WARNING,
"Could not load " + resource + " using processingEnv.getFiler().getResource(). Using classpath..."
);
// TODO
// unfortunately, the Filer.getResource API seems not to be able to load from /META-INF. One gets a
// FilerException with the message with "Illegal name /META-INF". This means that we have to revert to
// using the classpath. This might mean that we find a persistence.xml which is 'part of another jar.
// Not sure what else we can do here
ormStream = this.getClass().getResourceAsStream( resource );
}
return ormStream;
}
/**
* Tries to open the specified xml file and return an instance of the specified class using JAXB.
*
* @param resource the xml file name
* @param clazz The type of jaxb node to return
* @param schemaName The schema to validate against (can be {@code null});
*
* @return The top level jaxb instance contained in the xml file or {@code null} in case the file could not be found.
*/
private <T> T parseXml(String resource, Class<T> clazz, String schemaName) {
InputStream stream = getInputStreamForResource( resource );
if ( stream == null ) {
processingEnv.getMessager().printMessage( Diagnostic.Kind.NOTE, resource + " not found." );
return null;
}
try {
JAXBContext jc = JAXBContext.newInstance( ObjectFactory.class );
Unmarshaller unmarshaller = jc.createUnmarshaller();
if ( schemaName != null ) {
unmarshaller.setSchema( getSchema( schemaName ) );
}
return clazz.cast( unmarshaller.unmarshal( stream ) );
}
catch ( JAXBException e ) {
String message = "Error unmarshalling " + resource + " with exception :\n " + e;
processingEnv.getMessager().printMessage( Diagnostic.Kind.WARNING, message );
return null;
}
catch ( Exception e ) {
String message = "Error reading " + resource + " with exception :\n " + e;
processingEnv.getMessager().printMessage( Diagnostic.Kind.WARNING, message );
return null;
}
}
private String getPackage(String resourceName) {
if ( !resourceName.contains( PATH_SEPARATOR ) ) {
return "";
}
else {
return resourceName.substring( 0, resourceName.lastIndexOf( PATH_SEPARATOR ) );
}
}
private String getRelativeName(String resourceName) {
if ( !resourceName.contains( PATH_SEPARATOR ) ) {
return resourceName;
}
else {
return resourceName.substring( resourceName.lastIndexOf( PATH_SEPARATOR ) + 1 );
}
}
private Schema getSchema(String schemaName) {
Schema schema = null;
URL schemaUrl = this.getClass().getClassLoader().getResource( schemaName );
if ( schemaUrl == null ) {
return schema;
}
SchemaFactory sf = SchemaFactory.newInstance( javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI );
try {
schema = sf.newSchema( schemaUrl );
}
catch ( SAXException e ) {
processingEnv.getMessager().printMessage(
Diagnostic.Kind.WARNING, "Unable to create schema for " + schemaName + ": " + e.getMessage()
);
}
return schema;
}
}

View File

@ -0,0 +1,75 @@
// $Id$
/*
* JBoss, Home of Professional Open Source
* Copyright 2008, Red Hat Middleware LLC, and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* Licensed 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.
*/
package org.hibernate.jpamodelgen;
import java.util.HashMap;
import java.util.Map;
import javax.lang.model.type.TypeMirror;
import javax.lang.model.type.TypeKind;
import javax.lang.model.type.DeclaredType;
import javax.lang.model.element.TypeElement;
import javax.lang.model.element.Element;
/**
* Utility class.
*
* @author Max Andersen
* @author Hardy Ferentschik
* @author Emmanuel Bernard
*/
public class TypeUtils {
private static final Map<String, String> PRIMITIVES = new HashMap<String, String>();
static {
PRIMITIVES.put( "char", "Character" );
PRIMITIVES.put( "byte", "Byte" );
PRIMITIVES.put( "short", "Short" );
PRIMITIVES.put( "int", "Integer" );
PRIMITIVES.put( "long", "Long" );
PRIMITIVES.put( "boolean", "Boolean" );
PRIMITIVES.put( "float", "Float" );
PRIMITIVES.put( "double", "Double" );
}
static public String toTypeString(TypeMirror type) {
if(type.getKind().isPrimitive()) {
return PRIMITIVES.get(type.toString());
}
return type.toString();
}
static public TypeElement getSuperclass(TypeElement element) {
final TypeMirror superClass = element.getSuperclass();
//superclass of Object is of NoType which returns some other kind
String superclassDeclaration = "";
if (superClass.getKind() == TypeKind.DECLARED ) {
//F..king Ch...t Have those people used their horrible APIs even once?
final Element superClassElement = ( ( DeclaredType ) superClass ).asElement();
return ( TypeElement ) superClassElement;
}
else {
return null;
}
}
}

View File

@ -0,0 +1,74 @@
// $Id$
/*
* JBoss, Home of Professional Open Source
* Copyright 2008, Red Hat Middleware LLC, and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* Licensed 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.
*/
package org.hibernate.jpamodelgen.annotation;
import org.hibernate.jpamodelgen.IMetaAttribute;
import java.beans.Introspector;
import javax.annotation.processing.ProcessingEnvironment;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
/**
*
* @author Max Andersen
* @author Hardy Ferentschik
* @author Emmanuel Bernard
*/
public abstract class MetaAttribute implements IMetaAttribute {
final protected Element element;
final protected MetaEntity parent;
final protected ProcessingEnvironment pe;
private final String type;
public MetaAttribute(MetaEntity parent, Element element, String type) {
this.element = element;
this.parent = parent;
this.type = type;
this.pe = parent.pe;
}
public String getDeclarationString() {
return "public static volatile " + parent.importType(getMetaType()) + "<" + parent.importType(parent.getQualifiedName()) + ", " + parent.importType(getTypeDeclaration()) + "> " + getPropertyName() + ";";
}
public String getPropertyName() {
if(element.getKind()==ElementKind.FIELD) {
return element.getSimpleName().toString();
} else if (element.getKind()==ElementKind.METHOD) {
String name = element.getSimpleName().toString();
if(name.startsWith("get")) {
return pe.getElementUtils().getName(Introspector.decapitalize(name.substring("get".length()))).toString();
} else if(name.startsWith("is")) {
return (pe.getElementUtils().getName(Introspector.decapitalize(name.substring("is".length())))).toString();
}
return pe.getElementUtils().getName(Introspector.decapitalize(name)).toString();
} else {
return pe.getElementUtils().getName(element.getSimpleName() + "/* " + element.getKind() + " */").toString();
}
}
abstract public String getMetaType();
public String getTypeDeclaration() {
return type;
}
}

View File

@ -0,0 +1,46 @@
// $Id$
/*
* JBoss, Home of Professional Open Source
* Copyright 2008, Red Hat Middleware LLC, and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* Licensed 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.
*/
package org.hibernate.jpamodelgen.annotation;
import org.hibernate.jpamodelgen.IMetaCollection;
import javax.lang.model.element.Element;
/**
*
* @author Max Andersen
* @author Hardy Ferentschik
* @author Emmanuel Bernard
*/
public class MetaCollection extends MetaAttribute implements IMetaCollection {
private String collectionType;
public MetaCollection(MetaEntity parent, Element element, String collectionType, String elementType) {
super(parent, element, elementType);
this.collectionType = collectionType;
}
@Override
public String getMetaType() {
return collectionType;
}
}

View File

@ -0,0 +1,433 @@
// $Id$
/*
* JBoss, Home of Professional Open Source
* Copyright 2008, Red Hat Middleware LLC, and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* Licensed 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.
*/
package org.hibernate.jpamodelgen.annotation;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.annotation.processing.ProcessingEnvironment;
import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.Name;
import javax.lang.model.element.PackageElement;
import javax.lang.model.element.TypeElement;
import javax.lang.model.element.Modifier;
import javax.lang.model.type.DeclaredType;
import javax.lang.model.type.ExecutableType;
import javax.lang.model.type.PrimitiveType;
import javax.lang.model.type.TypeMirror;
import javax.lang.model.util.ElementFilter;
import javax.lang.model.util.SimpleTypeVisitor6;
import javax.persistence.EmbeddedId;
import javax.persistence.Id;
import javax.persistence.AccessType;
import javax.persistence.Entity;
import javax.persistence.MappedSuperclass;
import javax.persistence.Transient;
import javax.persistence.Embedded;
import javax.persistence.Embeddable;
import javax.persistence.Access;
import javax.persistence.ElementCollection;
import javax.tools.Diagnostic.Kind;
import javax.tools.Diagnostic;
import org.hibernate.jpamodelgen.IMetaEntity;
import org.hibernate.jpamodelgen.IMetaAttribute;
import org.hibernate.jpamodelgen.ImportContext;
import org.hibernate.jpamodelgen.ImportContextImpl;
import org.hibernate.jpamodelgen.TypeUtils;
import org.hibernate.jpamodelgen.Context;
/**
*
* @author Max Andersen
* @author Hardy Ferentschik
* @author Emmanuel Bernard
*/
public class MetaEntity implements IMetaEntity {
final TypeElement element;
final protected ProcessingEnvironment pe;
final ImportContext importContext;
private Context context;
//used to propagate the access type of the root entity over to subclasses, superclasses and embeddable
private AccessType defaultAccessTypeForHierarchy;
private AccessType defaultAccessTypeForElement;
public MetaEntity(ProcessingEnvironment pe, TypeElement element, Context context) {
this.element = element;
this.pe = pe;
importContext = new ImportContextImpl( getPackageName() );
this.context = context;
}
public MetaEntity(ProcessingEnvironment pe, TypeElement element, Context context, AccessType accessType) {
this(pe, element, context);
this.defaultAccessTypeForHierarchy = accessType;
}
public String getSimpleName() {
return element.getSimpleName().toString();
}
public Element getOriginalElement() {
return element;
}
public String getQualifiedName() {
return element.getQualifiedName().toString();
}
public String getPackageName() {
PackageElement packageOf = pe.getElementUtils().getPackageOf( element );
return pe.getElementUtils().getName( packageOf.getQualifiedName() ).toString();
}
public List<IMetaAttribute> getMembers() {
List<IMetaAttribute> membersFound = new ArrayList<IMetaAttribute>();
final AccessType elementAccessType = getAccessTypeForElement();
List<? extends Element> fieldsOfClass = ElementFilter.fieldsIn( element.getEnclosedElements() );
addPersistentMembers( membersFound, elementAccessType, fieldsOfClass, AccessType.FIELD );
List<? extends Element> methodsOfClass = ElementFilter.methodsIn( element.getEnclosedElements() );
addPersistentMembers( membersFound, elementAccessType, methodsOfClass, AccessType.PROPERTY );
//process superclasses
for(TypeElement superclass = TypeUtils.getSuperclass(element) ;
superclass != null ;
superclass = TypeUtils.getSuperclass( superclass ) ) {
if ( superclass.getAnnotation( Entity.class ) != null ) {
break; //will be handled or has been handled already
}
else if ( superclass.getAnnotation( MappedSuperclass.class ) != null ) {
//FIXME use the class defalut access type
context.processElement( superclass, defaultAccessTypeForHierarchy );
}
}
//this is valid to not have properties (ie subentities)
// if ( membersFound.size() == 0 ) {
// pe.getMessager().printMessage( Kind.WARNING, "No properties found on " + element, element );
// }
return membersFound;
}
private void addPersistentMembers(
List<IMetaAttribute> membersFound,
AccessType elementAccessType,
List<? extends Element> membersOfClass,
AccessType membersKind) {
pe.getMessager()
.printMessage( Kind.NOTE, "Scanning " + membersOfClass.size() + " " + membersKind + " for " + element.toString() );
AccessType explicitAccessType;
if (elementAccessType == membersKind) {
//all membersKind considered
explicitAccessType = null;
}
else {
//use membersKind only if marked with @Access(membersKind)
explicitAccessType = membersKind;
}
for ( Element memberOfClass : membersOfClass ) {
MetaAttribute result = memberOfClass.asType().accept( new TypeVisitor( this, explicitAccessType ),
memberOfClass
);
if ( result != null ) {
membersFound.add( result );
}
//EBE not sure why?
// else {
// pe.getMessager().printMessage( Kind.WARNING, "Could not find valid info for JPA property", mymember );
// }
}
}
private AccessType getAccessTypeForElement() {
//get local strategy
AccessType accessType = getAccessTypeForClass(element);
if (accessType == null) {
accessType = this.defaultAccessTypeForHierarchy;
}
if (accessType == null) {
//we dont' know
//if an enity go up
//
//superclasses alre always treated after their entities
//and their access type are discovered
//FIXME is it really true if only the superclass is changed
TypeElement superClass = element;
do {
superClass = TypeUtils.getSuperclass( superClass );
if (superClass != null) {
if ( superClass.getAnnotation( Entity.class ) != null
|| superClass.getAnnotation( MappedSuperclass.class ) != null ) {
//FIXME make it work for XML
AccessType superClassAccessType = getAccessTypeForClass(superClass);
//we've reach the root entity and resolved Ids
if ( superClassAccessType != null && defaultAccessTypeForHierarchy != null) {
break; //we've found it
}
}
else {
break; //neither @Entity nor @MappedSuperclass
}
}
}
while ( superClass != null );
}
if ( accessType == null ) {
accessType = AccessType.PROPERTY; //default to property
this.defaultAccessTypeForElement = accessType;
}
//this is a subclass so caching is OK
//this.defaultAccessTypeForHierarchy = accessType;
context.addAccessType( this.element, accessType );
this.defaultAccessTypeForElement = accessType;
return accessType;
}
private AccessType getAccessTypeForClass(TypeElement searchedElement) {
pe.getMessager().printMessage( Diagnostic.Kind.NOTE, "check class" + searchedElement );
AccessType accessType = context.getAccessType( searchedElement );
if (defaultAccessTypeForHierarchy == null) {
this.defaultAccessTypeForHierarchy = context.getDefaultAccessTypeForHerarchy( searchedElement );
}
if ( accessType != null ) {
pe.getMessager().printMessage( Diagnostic.Kind.NOTE, "Found in cache" + searchedElement + ":" + accessType );
return accessType;
}
/**
* when forcing access type, we can only override the defaultAccessTypeForHierarchy
* if we are the entity root (identified by having @Id or @EmbeddedId
*/
final Access accessAnn = searchedElement.getAnnotation( Access.class );
AccessType forcedAccessType = accessAnn != null ? accessAnn.value() : null;
if ( forcedAccessType != null) {
pe.getMessager().printMessage( Diagnostic.Kind.NOTE, "access type " + searchedElement + ":" + forcedAccessType );
context.addAccessType( searchedElement, forcedAccessType );
}
//continue nevertheless to check if we are root and if defaultAccessTypeForHierarchy
//should be overridden
if ( forcedAccessType == null || defaultAccessTypeForHierarchy == null) {
List<? extends Element> myMembers = searchedElement.getEnclosedElements();
for ( Element subElement : myMembers ) {
List<? extends AnnotationMirror> entityAnnotations =
pe.getElementUtils().getAllAnnotationMirrors( subElement );
for ( Object entityAnnotation : entityAnnotations ) {
AnnotationMirror annotationMirror = ( AnnotationMirror ) entityAnnotation;
final String annotationType = annotationMirror.getAnnotationType().toString();
//FIXME consider XML
if ( annotationType.equals( Id.class.getName() )
|| annotationType.equals( EmbeddedId.class.getName() ) ) {
pe.getMessager().printMessage( Diagnostic.Kind.NOTE, "Found id on" + searchedElement );
final ElementKind kind = subElement.getKind();
if ( kind == ElementKind.FIELD || kind == ElementKind.METHOD ) {
accessType = kind == ElementKind.FIELD ? AccessType.FIELD : AccessType.PROPERTY;
//FIXME enlever in niveau
if (defaultAccessTypeForHierarchy == null) {
this.defaultAccessTypeForHierarchy = context.getDefaultAccessTypeForHerarchy( searchedElement );
//we've discovered the class hierarchy, let's cache it
if ( defaultAccessTypeForHierarchy == null ) {
this.defaultAccessTypeForHierarchy = accessType;
context.addAccessTypeForHierarchy( searchedElement, defaultAccessTypeForHierarchy );
//FIXME should we add
//context.addAccessTypeForHierarchy( element, defaultAccessTypeForHierarchy );
}
}
if ( forcedAccessType == null) {
context.addAccessType( searchedElement, accessType );
pe.getMessager().printMessage( Diagnostic.Kind.NOTE, "access type " + searchedElement + ":" + accessType );
return accessType;
}
else {
return forcedAccessType;
}
}
}
}
}
}
return forcedAccessType;
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder();
sb.append( "MetaEntity" );
sb.append( "{element=" ).append( element );
sb.append( '}' );
return sb.toString();
}
static Map<String, String> COLLECTIONS = new HashMap<String, String>();
static {
COLLECTIONS.put( "java.util.Collection", "javax.persistence.metamodel.CollectionAttribute" );
COLLECTIONS.put( "java.util.Set", "javax.persistence.metamodel.SetAttribute" );
COLLECTIONS.put( "java.util.List", "javax.persistence.metamodel.ListAttribute" );
COLLECTIONS.put( "java.util.Map", "javax.persistence.metamodel.MapAttribute" );
}
class TypeVisitor extends SimpleTypeVisitor6<MetaAttribute, Element> {
MetaEntity parent;
//if null, process all members as implicit
//if not null, only process members marked as @Access(explicitAccessType)
private AccessType explicitAccessType;
TypeVisitor(MetaEntity parent, AccessType explicitAccessType) {
this.parent = parent;
this.explicitAccessType = explicitAccessType;
}
@Override
protected MetaAttribute defaultAction(TypeMirror e, Element p) {
return super.defaultAction( e, p );
}
@Override
public MetaAttribute visitPrimitive(PrimitiveType t, Element element) {
if ( isPersistent( element ) ) {
return new MetaSingleAttribute( parent, element, TypeUtils.toTypeString( t ) );
}
else {
return null;
}
}
private boolean isPersistent(Element element) {
//FIXME consider XML
boolean correctAccessType = false;
if (this.explicitAccessType == null) {
correctAccessType = true;
}
else {
final Access accessAnn = element.getAnnotation( Access.class );
if ( accessAnn != null && explicitAccessType.equals( accessAnn.value() ) ) {
correctAccessType = true;
}
}
return correctAccessType
&& element.getAnnotation( Transient.class ) == null
&& !element.getModifiers().contains( Modifier.TRANSIENT )
&& !element.getModifiers().contains( Modifier.STATIC );
}
@Override
public MetaAttribute visitDeclared(DeclaredType t, Element element) {
//FIXME consider XML
if ( isPersistent( element ) ) {
TypeElement returnedElement = ( TypeElement ) pe.getTypeUtils().asElement( t );
String collection = COLLECTIONS.get( returnedElement.getQualifiedName().toString() ); // WARNING: .toString() is necessary here since Name equals does not compare to String
if ( collection != null ) {
//collection of element
if ( element.getAnnotation( ElementCollection.class ) != null ) {
final TypeMirror collectionType = t.getTypeArguments().get( 0 );
final TypeElement collectionElement = ( TypeElement ) pe.getTypeUtils().asElement( collectionType );
this.parent.context.processElement( collectionElement,
this.parent.defaultAccessTypeForElement );
}
if ( collection.equals( "javax.persistence.metamodel.MapAttribute" ) ) {
return new MetaMap( parent, element, collection, getKeyType( t ), getElementType( t ) );
}
else {
return new MetaCollection( parent, element, collection, getElementType( t ) );
}
}
else {
//FIXME Consider XML
if ( element.getAnnotation( Embedded.class ) != null
|| returnedElement.getAnnotation( Embeddable.class ) != null ) {
this.parent.context.processElement( returnedElement,
this.parent.defaultAccessTypeForElement );
}
return new MetaSingleAttribute( parent, element, returnedElement.getQualifiedName().toString() );
}
}
else {
return null;
}
}
@Override
public MetaAttribute visitExecutable(ExecutableType t, Element p) {
String string = p.getSimpleName().toString();
// TODO: implement proper property get/is/boolean detection
if ( string.startsWith( "get" ) || string.startsWith( "is" ) ) {
TypeMirror returnType = t.getReturnType();
return returnType.accept( this, p );
}
else {
return null;
}
}
}
public String generateImports() {
return importContext.generateImports();
}
public String importType(String fqcn) {
return importContext.importType( fqcn );
}
public String staticImport(String fqcn, String member) {
return importContext.staticImport( fqcn, member );
}
public String importType(Name qualifiedName) {
return importType( qualifiedName.toString() );
}
public TypeElement getTypeElement() {
return element;
}
private String getKeyType(DeclaredType t) {
return t.getTypeArguments().get( 0 ).toString();
}
private String getElementType(DeclaredType declaredType) {
if ( declaredType.getTypeArguments().size() == 1 ) {
return declaredType.getTypeArguments().get( 0 ).toString();
}
else {
return declaredType.getTypeArguments().get( 1 ).toString();
}
}
}

View File

@ -0,0 +1,42 @@
// $Id$
/*
* JBoss, Home of Professional Open Source
* Copyright 2008, Red Hat Middleware LLC, and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* Licensed 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.
*/
package org.hibernate.jpamodelgen.annotation;
import javax.lang.model.element.Element;
/**
*
* @author Max Andersen
* @author Hardy Ferentschik
* @author Emmanuel Bernard
*/
public class MetaMap extends MetaCollection {
private final String keyType;
public MetaMap(MetaEntity parent, Element element, String collectionType,
String keyType, String elementType) {
super(parent, element, collectionType, elementType);
this.keyType = keyType;
}
public String getDeclarationString() {
return "public static volatile " + parent.importType(getMetaType()) + "<" + parent.importType(parent.getQualifiedName()) + ", " + parent.importType(keyType) + ", " + parent.importType(getTypeDeclaration()) + "> " + getPropertyName() + ";";
}
}

View File

@ -0,0 +1,41 @@
// $Id$
/*
* JBoss, Home of Professional Open Source
* Copyright 2008, Red Hat Middleware LLC, and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* Licensed 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.
*/
package org.hibernate.jpamodelgen.annotation;
import org.hibernate.jpamodelgen.IMetaSingleAttribute;
import javax.lang.model.element.Element;
/**
*
* @author Max Andersen
* @author Hardy Ferentschik
* @author Emmanuel Bernard
*/
public class MetaSingleAttribute extends MetaAttribute implements IMetaSingleAttribute {
public MetaSingleAttribute(MetaEntity parent, Element element, String type) {
super(parent, element, type);
}
@Override
public String getMetaType() {
return "javax.persistence.metamodel.SingularAttribute";
}
}

View File

@ -0,0 +1,56 @@
// $Id$
/*
* JBoss, Home of Professional Open Source
* Copyright 2008, Red Hat Middleware LLC, and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* Licensed 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.
*/
package org.hibernate.jpamodelgen.xml;
import org.hibernate.jpamodelgen.IMetaAttribute;
/**
* @author Hardy Ferentschik
*/
public abstract class XmlMetaAttribute implements IMetaAttribute {
private XmlMetaEntity parentEntity;
private String propertyName;
private String type;
XmlMetaAttribute(XmlMetaEntity parent, String propertyName, String type) {
this.parentEntity = parent;
this.propertyName = propertyName;
this.type = type;
}
@Override
public String getDeclarationString() {
return "public static volatile " + parentEntity.importType(getMetaType()) + "<" + parentEntity.importType(parentEntity.getQualifiedName()) + ", " + parentEntity.importType(getTypeDeclaration()) + "> " + getPropertyName() + ";";
}
public String getPropertyName() {
return propertyName;
}
public String getTypeDeclaration() {
return type;
}
@Override
abstract public String getMetaType();
}

View File

@ -0,0 +1,38 @@
// $Id$
/*
* JBoss, Home of Professional Open Source
* Copyright 2008, Red Hat Middleware LLC, and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* Licensed 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.
*/
package org.hibernate.jpamodelgen.xml;
import org.hibernate.jpamodelgen.IMetaCollection;
/**
* @author Hardy Ferentschik
*/
public class XmlMetaCollection extends XmlMetaAttribute implements IMetaCollection {
String collectionType;
public XmlMetaCollection(XmlMetaEntity parent, String propertyName, String type, String collectionType) {
super(parent, propertyName, type);
this.collectionType = collectionType;
}
@Override
public String getMetaType() {
return collectionType;
}
}

View File

@ -0,0 +1,255 @@
// $Id$
/*
* JBoss, Home of Professional Open Source
* Copyright 2008, Red Hat Middleware LLC, and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* Licensed 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.
*/
package org.hibernate.jpamodelgen.xml;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.lang.model.element.Element;
import javax.lang.model.element.Name;
import javax.lang.model.element.TypeElement;
import javax.lang.model.type.DeclaredType;
import org.hibernate.jpamodelgen.IMetaAttribute;
import org.hibernate.jpamodelgen.ImportContextImpl;
import org.hibernate.jpamodelgen.IMetaEntity;
import org.hibernate.jpamodelgen.ImportContext;
import org.hibernate.jpamodelgen.xml.jaxb.Attributes;
import org.hibernate.jpamodelgen.xml.jaxb.Basic;
import org.hibernate.jpamodelgen.xml.jaxb.ElementCollection;
import org.hibernate.jpamodelgen.xml.jaxb.Embeddable;
import org.hibernate.jpamodelgen.xml.jaxb.EmbeddableAttributes;
import org.hibernate.jpamodelgen.xml.jaxb.Entity;
import org.hibernate.jpamodelgen.xml.jaxb.Id;
import org.hibernate.jpamodelgen.xml.jaxb.ManyToOne;
import org.hibernate.jpamodelgen.xml.jaxb.MappedSuperclass;
import org.hibernate.jpamodelgen.xml.jaxb.OneToMany;
import org.hibernate.jpamodelgen.xml.jaxb.OneToOne;
/**
* @author Hardy Ferentschik
*/
public class XmlMetaEntity implements IMetaEntity {
static Map<String, String> COLLECTIONS = new HashMap<String, String>();
static {
COLLECTIONS.put( "java.util.Collection", "javax.persistence.metamodel.CollectionAttribute" );
COLLECTIONS.put( "java.util.Set", "javax.persistence.metamodel.SetAttribute" );
COLLECTIONS.put( "java.util.List", "javax.persistence.metamodel.ListAttribute" );
COLLECTIONS.put( "java.util.Map", "javax.persistence.metamodel.MapAttribute" );
}
final private String clazzName;
final private String packageName;
final private ImportContext importContext;
final private List<IMetaAttribute> members = new ArrayList<IMetaAttribute>();
private TypeElement element;
public XmlMetaEntity(Entity ormEntity, String packageName, TypeElement element) {
this.clazzName = ormEntity.getClazz();
this.packageName = packageName;
importContext = new ImportContextImpl( getPackageName() );
this.element = element;
Attributes attributes = ormEntity.getAttributes();
parseAttributes( attributes );
}
public XmlMetaEntity(MappedSuperclass mappedSuperclass, String packageName, TypeElement element) {
this.clazzName = mappedSuperclass.getClazz();
this.packageName = packageName;
importContext = new ImportContextImpl( getPackageName() );
this.element = element;
Attributes attributes = mappedSuperclass.getAttributes();
parseAttributes( attributes );
}
public XmlMetaEntity(Embeddable embeddable, String packageName, TypeElement element) {
this.clazzName = embeddable.getClazz();
this.packageName = packageName;
importContext = new ImportContextImpl( getPackageName() );
this.element = element;
EmbeddableAttributes attributes = embeddable.getAttributes();
XmlMetaSingleAttribute attribute;
for ( Basic basic : attributes.getBasic() ) {
attribute = new XmlMetaSingleAttribute( this, basic.getName(), getType( basic.getName() ) );
members.add( attribute );
}
for ( ManyToOne manyToOne : attributes.getManyToOne() ) {
attribute = new XmlMetaSingleAttribute( this, manyToOne.getName(), getType( manyToOne.getName() ) );
members.add( attribute );
}
for ( OneToOne oneToOne : attributes.getOneToOne() ) {
attribute = new XmlMetaSingleAttribute( this, oneToOne.getName(), getType( oneToOne.getName() ) );
members.add( attribute );
}
XmlMetaCollection metaCollection;
for ( OneToMany oneToMany : attributes.getOneToMany() ) {
String[] types = getCollectionType( oneToMany.getName() );
metaCollection = new XmlMetaCollection( this, oneToMany.getName(), types[0], types[1] );
members.add( metaCollection );
}
for ( ElementCollection collection : attributes.getElementCollection() ) {
String[] types = getCollectionType( collection.getName() );
metaCollection = new XmlMetaCollection( this, collection.getName(), types[0], types[1] );
members.add( metaCollection );
}
}
public String getSimpleName() {
return clazzName;
}
public String getQualifiedName() {
return packageName + "." + getSimpleName();
}
public String getPackageName() {
return packageName;
}
public List<IMetaAttribute> getMembers() {
return members;
}
public String generateImports() {
return importContext.generateImports();
}
public String importType(String fqcn) {
return importContext.importType( fqcn );
}
public String staticImport(String fqcn, String member) {
return importContext.staticImport( fqcn, member );
}
public String importType(Name qualifiedName) {
return importType( qualifiedName.toString() );
}
public TypeElement getTypeElement() {
return element;
}
private String[] getCollectionType(String propertyName) {
String types[] = new String[2];
for ( Element elem : element.getEnclosedElements() ) {
if ( elem.getSimpleName().toString().equals( propertyName ) ) {
DeclaredType type = ( ( DeclaredType ) elem.asType() );
types[0] = type.getTypeArguments().get( 0 ).toString();
types[1] = COLLECTIONS.get( type.asElement().toString() );
}
}
return types;
}
private String getType(String propertyName) {
String typeName = null;
for ( Element elem : element.getEnclosedElements() ) {
if ( elem.getSimpleName().toString().equals( propertyName ) ) {
switch ( elem.asType().getKind() ) {
case INT: {
typeName = "java.lang.Integer";
break;
}
case LONG: {
typeName = "java.lang.Long";
break;
}
case BOOLEAN: {
typeName = "java.lang.Boolean";
break;
}
case DECLARED: {
typeName = elem.asType().toString();
break;
}
case TYPEVAR: {
typeName = elem.asType().toString();
break;
}
}
break;
}
}
return typeName;
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder();
sb.append( "XmlMetaEntity" );
sb.append( "{type=" ).append( element );
sb.append( '}' );
return sb.toString();
}
private void parseAttributes(Attributes attributes) {
XmlMetaSingleAttribute attribute;
if ( !attributes.getId().isEmpty() ) {
// TODO what do we do if there are more than one id nodes?
Id id = attributes.getId().get( 0 );
attribute = new XmlMetaSingleAttribute(
this, id.getName(), getType( id.getName() )
);
members.add( attribute );
}
for ( Basic basic : attributes.getBasic() ) {
attribute = new XmlMetaSingleAttribute( this, basic.getName(), getType( basic.getName() ) );
members.add( attribute );
}
for ( ManyToOne manyToOne : attributes.getManyToOne() ) {
attribute = new XmlMetaSingleAttribute( this, manyToOne.getName(), getType( manyToOne.getName() ) );
members.add( attribute );
}
for ( OneToOne oneToOne : attributes.getOneToOne() ) {
attribute = new XmlMetaSingleAttribute( this, oneToOne.getName(), getType( oneToOne.getName() ) );
members.add( attribute );
}
XmlMetaCollection metaCollection;
for ( OneToMany oneToMany : attributes.getOneToMany() ) {
String[] types = getCollectionType( oneToMany.getName() );
metaCollection = new XmlMetaCollection( this, oneToMany.getName(), types[0], types[1] );
members.add( metaCollection );
}
for ( ElementCollection collection : attributes.getElementCollection() ) {
String[] types = getCollectionType( collection.getName() );
metaCollection = new XmlMetaCollection( this, collection.getName(), types[0], types[1] );
members.add( metaCollection );
}
}
}

View File

@ -0,0 +1,35 @@
// $Id$
/*
* JBoss, Home of Professional Open Source
* Copyright 2008, Red Hat Middleware LLC, and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* Licensed 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.
*/
package org.hibernate.jpamodelgen.xml;
import org.hibernate.jpamodelgen.IMetaSingleAttribute;
/**
* @author Hardy Ferentschik
*/
public class XmlMetaSingleAttribute extends XmlMetaAttribute implements IMetaSingleAttribute {
public XmlMetaSingleAttribute(XmlMetaEntity parent, String propertyName, String type) {
super(parent, propertyName, type);
}
@Override
public String getMetaType() {
return "javax.persistence.metamodel.SingularAttribute";
}
}

View File

@ -0,0 +1 @@
org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,247 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- persistence.xml schema -->
<xsd:schema targetNamespace="http://java.sun.com/xml/ns/persistence"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:persistence="http://java.sun.com/xml/ns/persistence"
elementFormDefault="qualified"
attributeFormDefault="unqualified"
version="2.0">
<xsd:annotation>
<xsd:documentation>
@(#)persistence_2_0.xsd 1.0 August 27 2008
</xsd:documentation>
</xsd:annotation>
<xsd:annotation>
<xsd:documentation><![CDATA[
This is the XML Schema for the persistence configuration file.
The file must be named "META-INF/persistence.xml" in the
persistence archive.
Persistence configuration files must indicate
the persistence schema by using the persistence namespace:
http://java.sun.com/xml/ns/persistence
and indicate the version of the schema by
using the version element as shown below:
<persistence 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"
version="2.0">
...
</persistence>
]]></xsd:documentation>
</xsd:annotation>
<xsd:simpleType name="versionType">
<xsd:restriction base="xsd:token">
<xsd:pattern value="[0-9]+(\.[0-9]+)*"/>
</xsd:restriction>
</xsd:simpleType>
<!-- **************************************************** -->
<xsd:element name="persistence">
<xsd:complexType>
<xsd:sequence>
<!-- **************************************************** -->
<xsd:element name="persistence-unit"
minOccurs="1" maxOccurs="unbounded">
<xsd:complexType>
<xsd:annotation>
<xsd:documentation>Configuration of a persistence unit.
</xsd:documentation>
</xsd:annotation>
<xsd:sequence>
<!-- **************************************************** -->
<xsd:element name="description" type="xsd:string"
minOccurs="0">
<xsd:annotation>
<xsd:documentation>
Description of this persistence unit.
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<!-- **************************************************** -->
<xsd:element name="provider" type="xsd:string"
minOccurs="0">
<xsd:annotation>
<xsd:documentation>
Provider class that supplies EntityManagers for this
persistence unit.
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<!-- **************************************************** -->
<xsd:element name="jta-data-source" type="xsd:string"
minOccurs="0">
<xsd:annotation>
<xsd:documentation>
The container-specific name of the JTA datasource to use.
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<!-- **************************************************** -->
<xsd:element name="non-jta-data-source" type="xsd:string"
minOccurs="0">
<xsd:annotation>
<xsd:documentation>
The container-specific name of a non-JTA datasource to use.
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<!-- **************************************************** -->
<xsd:element name="mapping-file" type="xsd:string"
minOccurs="0" maxOccurs="unbounded">
<xsd:annotation>
<xsd:documentation>File containing mapping information. Loaded as a resource
by the persistence provider.
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<!-- **************************************************** -->
<xsd:element name="jar-file" type="xsd:string"
minOccurs="0" maxOccurs="unbounded">
<xsd:annotation>
<xsd:documentation>
Jar file that should be scanned for entities.
Not applicable to Java SE persistence units.
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<!-- **************************************************** -->
<xsd:element name="class" type="xsd:string"
minOccurs="0" maxOccurs="unbounded">
<xsd:annotation>
<xsd:documentation>
Class to scan for annotations. It should be annotated
with either @Entity, @Embeddable or @MappedSuperclass.
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<!-- **************************************************** -->
<xsd:element name="exclude-unlisted-classes" type="xsd:boolean"
default="false" minOccurs="0">
<xsd:annotation>
<xsd:documentation>
When set to true then only listed classes and jars will
be scanned for persistent classes, otherwise the enclosing
jar or directory will also be scanned. Not applicable to
Java SE persistence units.
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<!-- **************************************************** -->
<xsd:element name="caching"
type="persistence:persistence-unit-caching-type"
minOccurs="0">
<xsd:annotation>
<xsd:documentation>
Defines whether caching is enabled for the
persistence unit if caching is supported by the
persistence provider. When set to ALL, all entities
will be cached. When set to NONE, no entities will
be cached. When set to ENABLE_SELECTIVE, only entities
specified as cacheable will be cached. When set toDISABLE_SELECTIVE, entities specified as not cacheable
will not be cached.
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<!-- **************************************************** -->
<xsd:element
name="validation-mode"
type="persistence:persistence-unit-validation-mode-type"
minOccurs="0">
<xsd:annotation>
<xsd:documentation>
Specifies the validation mode to be used for the
persistence unit.
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<!-- **************************************************** -->
<xsd:element name="properties" minOccurs="0">
<xsd:annotation>
<xsd:documentation>
A list of vendor-specific properties.
</xsd:documentation>
</xsd:annotation>
<xsd:complexType>
<xsd:sequence>
<xsd:element name="property"
minOccurs="0" maxOccurs="unbounded">
<xsd:annotation>
<xsd:documentation>
A name-value pair.
</xsd:documentation>
</xsd:annotation>
<xsd:complexType>
<xsd:attribute name="name" type="xsd:string"
use="required"/>
<xsd:attribute name="value" type="xsd:string"
use="required"/>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
<!-- **************************************************** -->
<xsd:attribute name="name" type="xsd:string" use="required">
<xsd:annotation>
<xsd:documentation>
Name used in code to reference this persistence unit.
</xsd:documentation>
</xsd:annotation></xsd:attribute>
<!-- **************************************************** -->
<xsd:attribute name="transaction-type"
type="persistence:persistence-unit-transaction-type">
<xsd:annotation>
<xsd:documentation>
Type of transactions used by EntityManagers from this
persistence unit.
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
<xsd:attribute name="version" type="persistence:versionType"
fixed="2.0" use="required"/>
</xsd:complexType>
</xsd:element>
<!-- **************************************************** -->
<xsd:simpleType name="persistence-unit-transaction-type">
<xsd:annotation>
<xsd:documentation>
public enum TransactionType { JTA, RESOURCE_LOCAL };
</xsd:documentation>
</xsd:annotation>
<xsd:restriction base="xsd:token">
<xsd:enumeration value="JTA"/>
<xsd:enumeration value="RESOURCE_LOCAL"/>
</xsd:restriction>
</xsd:simpleType>
<!-- **************************************************** -->
<xsd:simpleType name="persistence-unit-caching-type">
<xsd:annotation>
<xsd:documentation>
public enum CachingType { ALL, NONE, ENABLE_SELECTIVE,
DISABLE_SELECTIVE};
</xsd:documentation>
</xsd:annotation>
<xsd:restriction base="xsd:token">
<xsd:enumeration value="ALL"/>
<xsd:enumeration value="NONE"/>
<xsd:enumeration value="ENABLE_SELECTIVE"/>
<xsd:enumeration value="DISABLE_SELECTIVE"/>
</xsd:restriction>
</xsd:simpleType>
<!-- **************************************************** -->
<xsd:simpleType name="persistence-unit-validation-mode-type">
<xsd:annotation>
<xsd:documentation>public enum ValidationMode { AUTO, CALLBACK, NONE};
</xsd:documentation>
</xsd:annotation>
<xsd:restriction base="xsd:token">
<xsd:enumeration value="AUTO"/>
<xsd:enumeration value="CALLBACK"/>
<xsd:enumeration value="NONE"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:schema>

View File

@ -0,0 +1,71 @@
// $Id$
/*
* JBoss, Home of Professional Open Source
* Copyright 2008, Red Hat Middleware LLC, and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* Licensed 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.
*/
package model;
import java.util.Set;
import javax.persistence.Embeddable;
import javax.persistence.Access;
import javax.persistence.AccessType;
import javax.persistence.ElementCollection;
import javax.persistence.CollectionTable;
/**
* @author Emmanuel Bernard
*/
@Embeddable
@Access(javax.persistence.AccessType.PROPERTY)
public class Address {
private String street1;
private String city;
private Country country;
private Set<Inhabitant> inhabitants;
public String getStreet1() {
return street1;
}
public void setStreet1(String street1) {
this.street1 = street1;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public Country getCountry() {
return country;
}
public void setCountry(Country country) {
this.country = country;
}
@ElementCollection
@CollectionTable(name = "Add_Inh")
public Set<Inhabitant> getInhabitants() {
return inhabitants;
}
public void setInhabitants(Set<Inhabitant> inhabitants) {
this.inhabitants = inhabitants;
}
}

View File

@ -0,0 +1,59 @@
// $Id$
/*
* JBoss, Home of Professional Open Source
* Copyright 2008, Red Hat Middleware LLC, and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* Licensed 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.
*/
package model;
import javax.persistence.MappedSuperclass;
/**
* @author Emmanuel Bernard
*/
@MappedSuperclass
public class Area {
private int length;
private int width;
private int height;
//should not be persistent
public int getVolume() {
return length*width*height;
}
public int getLength() {
return length;
}
public void setLength(int length) {
this.length = length;
}
public int getWidth() {
return width;
}
public void setWidth(int width) {
this.width = width;
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
}

View File

@ -0,0 +1,36 @@
// $Id$
/*
* JBoss, Home of Professional Open Source
* Copyright 2008, Red Hat Middleware LLC, and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* Licensed 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.
*/
package model;
import javax.persistence.MappedSuperclass;
/**
* @author Emmanuel Bernard
*/
@MappedSuperclass
public class Building extends Area {
private Address address;
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
}

View File

@ -0,0 +1,46 @@
// $Id$
/*
* JBoss, Home of Professional Open Source
* Copyright 2008, Red Hat Middleware LLC, and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* Licensed 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.
*/
package model;
import javax.persistence.Embeddable;
/**
* @author Emmanuel Bernard
*/
@Embeddable
public class Country {
String name;
String iso2Code;
String nonPersistent;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getIso2Code() {
return iso2Code;
}
public void setIso2Code(String iso2Code) {
this.iso2Code = iso2Code;
}
}

View File

@ -0,0 +1,45 @@
// $Id$
/*
* JBoss, Home of Professional Open Source
* Copyright 2008, Red Hat Middleware LLC, and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* Licensed 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.
*/
package model;
import java.util.Set;
import javax.persistence.Entity;
import javax.persistence.OneToMany;
import javax.persistence.Access;
import javax.persistence.AccessType;
/**
* @author Emmanuel Bernard
*/
@Entity
public class Customer extends User {
private Set<Order> orders;
private String nonPersistent;
@Access(AccessType.FIELD)
boolean goodPayer;
public Set<Order> getOrders() {
return orders;
}
@OneToMany
public void setOrders(Set<Order> orders) {
this.orders = orders;
}
}

View File

@ -0,0 +1,55 @@
// $Id$
/*
* JBoss, Home of Professional Open Source
* Copyright 2008, Red Hat Middleware LLC, and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* Licensed 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.
*/
package model;
import javax.persistence.Embeddable;
/**
* @author Emmanuel Bernard
*/
@Embeddable
public class Detail {
Integer length;
Integer width;
Integer height;
Integer nonPersistent;
public Integer getLength() {
return length;
}
public void setLength(Integer length) {
this.length = length;
}
public Integer getWidth() {
return width;
}
public void setWidth(Integer width) {
this.width = width;
}
public Integer getHeight() {
return height;
}
public void setHeight(Integer height) {
this.height = height;
}
}

View File

@ -0,0 +1,43 @@
// $Id$
/*
* JBoss, Home of Professional Open Source
* Copyright 2008, Red Hat Middleware LLC, and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* Licensed 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.
*/
package model;
import javax.persistence.Entity;
import javax.persistence.Access;
import javax.persistence.AccessType;
/**
* @author Emmanuel Bernard
*/
@Entity
@Access(javax.persistence.AccessType.FIELD)
public class Hominidae extends Mammals {
private int intelligence;
public int getIntelligence() {
return intelligence;
}
public void setIntelligence(int intelligence) {
this.intelligence = intelligence;
}
public int getNonPersistent() {
return 0;
}
}

View File

@ -0,0 +1,38 @@
// $Id$
/*
* JBoss, Home of Professional Open Source
* Copyright 2008, Red Hat Middleware LLC, and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* Licensed 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.
*/
package model;
import javax.persistence.Id;
import javax.persistence.Entity;
/**
* @author Emmanuel Bernard
*/
@Entity
public class House extends Building {
@Id
private Long id;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
}

View File

@ -0,0 +1,37 @@
// $Id$
/*
* JBoss, Home of Professional Open Source
* Copyright 2008, Red Hat Middleware LLC, and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* Licensed 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.
*/
package model;
import javax.persistence.Entity;
/**
* @author Emmanuel Bernard
*/
@Entity
public class Human extends Hominidae {
private int nonPersistent;
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}

View File

@ -0,0 +1,43 @@
// $Id$
/*
* JBoss, Home of Professional Open Source
* Copyright 2008, Red Hat Middleware LLC, and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* Licensed 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.
*/
package model;
import java.util.Set;
import javax.persistence.Embeddable;
import javax.persistence.Access;
import javax.persistence.AccessType;
import javax.persistence.ElementCollection;
/**
* @author Emmanuel Bernard
*/
@Embeddable
@Access(javax.persistence.AccessType.FIELD)
public class Inhabitant {
private String name;
@ElementCollection
private Set<Pet> pets;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}

View File

@ -0,0 +1,94 @@
// $Id$
/*
* JBoss, Home of Professional Open Source
* Copyright 2008, Red Hat Middleware LLC, and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* Licensed 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.
*/
package model;
import java.util.Map;
import java.util.Set;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
/**
*
* @author Max Andersen
* @author Hardy Ferentschik
* @author Emmanuel Bernard
*/
@Entity
public class Item {
long _id;
int _quantity;
Product _product;
Order _order;
Detail detail;
@Id
public long getId() {
return _id;
}
public void setId(long id) {
this._id = id;
}
public int getQuantity() {
return _quantity;
}
public void setQuantity(int quantity) {
this._quantity = quantity;
}
@ManyToOne
public Product getProduct() {
return _product;
}
public void setProduct(Product product) {
this._product = product;
}
@ManyToOne
public Order getOrder() {
return _order;
}
public void setOrder(Order order) {
this._order = order;
}
@OneToMany
public Map<String, Order> getNamedOrders() {
return null;
}
public Detail getDetail() {
return detail;
}
public void setDetail(Detail detail) {
this.detail = detail;
}
}

View File

@ -0,0 +1,43 @@
// $Id$
/*
* JBoss, Home of Professional Open Source
* Copyright 2008, Red Hat Middleware LLC, and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* Licensed 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.
*/
package model;
import javax.persistence.MappedSuperclass;
import javax.persistence.Access;
import javax.persistence.AccessType;
/**
* @author Emmanuel Bernard
*/
@MappedSuperclass
@Access(javax.persistence.AccessType.FIELD)
public class LivingBeing {
boolean isReallyAlive;
public boolean isReallyAlive() {
return isReallyAlive;
}
public void setReallyAlive(boolean reallyAlive) {
isReallyAlive = reallyAlive;
}
public int nonPersistent() {
return 0;
}
}

View File

@ -0,0 +1,47 @@
// $Id$
/*
* JBoss, Home of Professional Open Source
* Copyright 2008, Red Hat Middleware LLC, and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* Licensed 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.
*/
package model;
import javax.persistence.Entity;
import javax.persistence.Id;
/**
* @author Emmanuel Bernard
*/
@Entity
public class Mammals extends LivingBeing {
private String id;
private String nbrOfMammals;
@Id
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getNbrOfMammals() {
return nbrOfMammals;
}
public void setNbrOfMammals(String nbrOfMammals) {
this.nbrOfMammals = nbrOfMammals;
}
}

View File

@ -0,0 +1,47 @@
// $Id$
/*
* JBoss, Home of Professional Open Source
* Copyright 2008, Red Hat Middleware LLC, and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* Licensed 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.
*/
package model;
import java.util.Date;
import java.util.List;
import java.util.Set;
/**
*
* @author Max Andersen
* @author Hardy Ferentschik
* @author Emmanuel Bernard
*/
//@Entity
public class Order {
//@Id
long id;
//@OneToMany
Set<Item> items;
boolean filled;
Date date;
//@OneToMany
List<String> notes;
//@ManyToOne
Shop shop;
}

View File

@ -0,0 +1,40 @@
// $Id$
/*
* JBoss, Home of Professional Open Source
* Copyright 2008, Red Hat Middleware LLC, and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* Licensed 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.
*/
package model;
import javax.persistence.Embeddable;
/**
* @author Emmanuel Bernard
*/
@Embeddable
public class Pet {
String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getNonPersistent() {
return null;
}
}

View File

@ -0,0 +1,53 @@
// $Id$
/*
* JBoss, Home of Professional Open Source
* Copyright 2008, Red Hat Middleware LLC, and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* Licensed 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.
*/
package model;
import java.math.BigDecimal;
import java.util.Set;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
/**
*
* @author Max Andersen
* @author Hardy Ferentschik
* @author Emmanuel Bernard
*/
@Entity
public class Product {
transient String nonPersistent;
static String nonPersistent2;
@Id
long id;
int test;
String description;
BigDecimal price;
@ManyToOne
Shop shop;
@OneToMany
Set<Item> items;
}

View File

@ -0,0 +1,35 @@
// $Id$
/*
* JBoss, Home of Professional Open Source
* Copyright 2008, Red Hat Middleware LLC, and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* Licensed 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.
*/
package model;
import javax.persistence.Entity;
import javax.persistence.Id;
/**
*
* @author Max Andersen
* @author Hardy Ferentschik
* @author Emmanuel Bernard
*/
@Entity
public class Shop {
@Id
long id;
String name;
}

View File

@ -0,0 +1,58 @@
// $Id$
/*
* JBoss, Home of Professional Open Source
* Copyright 2008, Red Hat Middleware LLC, and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* Licensed 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.
*/
package model;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Transient;
/**
* @author Emmanuel Bernard
*/
@Entity
public class User {
private Long id;
private String nonPersistent;
private String name;
@Id
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
@Transient
public String getNonPersistent() {
return nonPersistent;
}
public void setNonPersistent(String nonPersistent) {
this.nonPersistent = nonPersistent;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}

View File

@ -0,0 +1,51 @@
// $Id$
/*
* JBoss, Home of Professional Open Source
* Copyright 2008, Red Hat Middleware LLC, and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* Licensed 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.
*/
package model.xmlmapped;
/**
* @author Hardy Ferentschik
*/
public class Address {
private String street1;
private String city;
private String country;
public String getStreet1() {
return street1;
}
public void setStreet1(String street1) {
this.street1 = street1;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
}

View File

@ -0,0 +1,36 @@
// $Id$
/*
* JBoss, Home of Professional Open Source
* Copyright 2008, Red Hat Middleware LLC, and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* Licensed 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.
*/
package model.xmlmapped;
import model.Address;
import model.Area;
/**
* @author Hardy Ferentschik
*/
public class Building extends Area {
private Address address;
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
}

View File

@ -0,0 +1,37 @@
// $Id$
/*
* JBoss, Home of Professional Open Source
* Copyright 2008, Red Hat Middleware LLC, and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* Licensed 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.
*/
package model.xmlmapped;
/**
* @author Hardy Ferentschik
*/
public class LivingBeing {
boolean isReallyAlive;
public boolean isReallyAlive() {
return isReallyAlive;
}
public void setReallyAlive(boolean reallyAlive) {
isReallyAlive = reallyAlive;
}
public int nonPersistent() {
return 0;
}
}

View File

@ -0,0 +1,42 @@
// $Id$
/*
* JBoss, Home of Professional Open Source
* Copyright 2008, Red Hat Middleware LLC, and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* Licensed 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.
*/
package model.xmlmapped;
/**
* @author Hardy Ferentschik
*/
public class Mammal extends LivingBeing {
private String id;
private String subclass;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getSubclass() {
return subclass;
}
public void setSubclass(String subclass) {
this.subclass = subclass;
}
}

View File

@ -0,0 +1,94 @@
// $Id$
/*
* JBoss, Home of Professional Open Source
* Copyright 2008, Red Hat Middleware LLC, and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* Licensed 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.
*/
package test;
import org.testng.annotations.Test;
import org.testng.Assert;
/**
* @author Emmanuel Bernard
*/
@Test
public class AccessTypeTest {
@Test
public void testExcludeTransientFieldAndStatic() throws Exception{
absenceOfField( "model.Product_", "nonPersistent" );
absenceOfField( "model.Product_", "nonPersistent2" );
}
@Test
public void testDefaultAccessTypeOnEntity() throws Exception{
absenceOfField( "model.User_", "nonPersistent" );
}
@Test
public void testDefaultAccessTypeForSubclassOfEntity() throws Exception{
absenceOfField( "model.Customer_", "nonPersistent" );
}
@Test
public void testDefaultAccessTypeForEmbeddable() throws Exception{
absenceOfField( "model.Detail_", "nonPersistent" );
}
@Test
public void testInheritedAccessTypeForEmbeddable() throws Exception{
absenceOfField( "model.Country_", "nonPersistent" );
absenceOfField( "model.Pet_", "nonPersistent", "Colleciton of membeddable not taken care of" );
}
@Test
public void testDefaultAccessTypeForMappedSuperclass() throws Exception{
absenceOfField( "model.Detail_", "volume" );
}
@Test
public void testExplicitAccessTypeAndDefaultFromRootEntity() throws Exception{
absenceOfField( "model.LivingBeing_", "nonPersistent", "eplicit access type on mapped superclass" );
absenceOfField( "model.Hominidae_", "nonPersistent", "eplicit access type on entity" );
absenceOfField( "model.Human_", "nonPersistent", "proper inheritance from root entity access type" );
}
@Test
public void testMemberAccessType() throws Exception{
presenceOfField( "model.Customer_", "goodPayer", "access type overriding" );
}
private void absenceOfField(String className, String fieldName) throws ClassNotFoundException {
absenceOfField( className, fieldName, "field should not be persistent" );
}
private void absenceOfField(String className, String fieldName, String errorString) throws ClassNotFoundException {
Assert.assertFalse( isFieldHere(className, fieldName), errorString );
}
private void presenceOfField(String className, String fieldName, String errorString) throws ClassNotFoundException {
Assert.assertTrue( isFieldHere(className, fieldName), errorString );
}
private boolean isFieldHere(String className, String fieldName) throws ClassNotFoundException {
Class<?> user_ = Class.forName( className );
try {
user_.getField( fieldName );
return true;
}
catch (NoSuchFieldException e) {
return false;
}
}
}

View File

@ -0,0 +1,46 @@
// $Id$
/*
* JBoss, Home of Professional Open Source
* Copyright 2008, Red Hat Middleware LLC, and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* Licensed 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.
*/
package test;
import org.testng.annotations.Test;
import org.testng.Assert;
import model.Customer_;
import model.User_;
import model.House_;
import model.Building_;
import model.Area_;
/**
* @author Emmanuel Bernard
*/
@Test
public class InheritanceTest {
@Test
public void testSuperEntity() throws Exception {
Assert.assertEquals( Customer_.class.getSuperclass(), User_.class,
"Entity with super entity should inherit at the metamodel level");
}
@Test
public void testMappedSuperclass() throws Exception {
Assert.assertEquals( House_.class.getSuperclass(), Building_.class,
"Entity with mapped superclass should inherit at the metamodel level");
Assert.assertEquals( Building_.class.getSuperclass(), Area_.class,
"mapped superclass with mapped superclass should inherit at the metamodel level");
}
}

View File

@ -0,0 +1,166 @@
// $Id$
/*
* JBoss, Home of Professional Open Source
* Copyright 2008, Red Hat Middleware LLC, and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* Licensed 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.
*/
package test;
import java.math.BigDecimal;
import java.util.Date;
import java.util.Set;
import javax.persistence.Tuple;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Expression;
import javax.persistence.criteria.Join;
import static javax.persistence.criteria.JoinType.INNER;
import javax.persistence.criteria.ListJoin;
import javax.persistence.criteria.Path;
import javax.persistence.criteria.Root;
import model.Item;
import model.Item_;
import model.Order;
import model.Order_;
import model.Product;
import model.Product_;
import model.Shop_;
/**
* Writing queries involves passing typesafe, statically cached, metamodel
* objects to the query builder in order to create the various parts of
* the query. The typesafe metamodel objects were validated at init time,
* so it is impossible to build invalid queries in the application code.
*
* @author Max Andersen
* @author Hardy Ferentschik
* @author Emmanuel Bernard
*/
public class QueryTest {
CriteriaBuilder qb;
public void test() {
CriteriaQuery<Tuple> q = qb.createTupleQuery();
Root<Order> order = q.from( Order.class );
Join<Item, Product> product = order.join( Order_.items )
.join( Item_.product );
Path<BigDecimal> price = product.get( Product_.price );
Path<Boolean> filled = order.get( Order_.filled );
Path<Date> date = order.get( Order_.date );
q.select( qb.tuple( order, product ) )
.where( qb.and( qb.gt( price, 100.00 ), qb.not( filled ) ) )
.orderBy( qb.asc( price ), qb.desc( date ) );
}
public void testUntypesafe() {
CriteriaQuery<Tuple> q = qb.createTupleQuery();
Root<Order> order = q.from( Order.class );
Join<Item, Product> product = order.join( "items" )
.join( "product" );
Path<BigDecimal> price = product.get( "price" );
Path<Boolean> filled = order.get( "filled" );
Path<Date> date = order.get( "date" );
q.select( qb.tuple( order, product ) )
.where( qb.and( qb.gt( price, 100.00 ), qb.not( filled ) ) )
.orderBy( qb.asc( price ), qb.desc( date ) );
}
/**
* Navigation by joining
*/
public void test2() {
CriteriaQuery<Product> q = qb.createQuery( Product.class );
Root<Product> product = q.from( Product.class );
Join<Item, Order> order = product.join( Product_.items )
.join( Item_.order );
q.select( product )
.where( qb.equal( order.get( Order_.id ), 12345l ) );
}
public void testMap() {
CriteriaQuery<Item> q = qb.createQuery( Item.class );
Root<Item> item = q.from( Item.class );
item.join( Item_.namedOrders );
}
/**
* Navigation by compound Path
*/
public void test3() {
CriteriaQuery<Item> q = qb.createQuery( Item.class );
Root<Item> item = q.from( Item.class );
Path<String> shopName = item.get( Item_.order )
.get( Order_.shop )
.get( Shop_.name );
q.select( item )
.where( qb.equal( shopName, "amazon.com" ) );
}
// public void test4() {
// CriteriaQuery q = qb.create();
//
// Root<Order> order = q.from(Order.class);
// ListJoin<Order, String> note = order.join(Order_.notes);
// Expression<Set<Item>> items = order.get(Order_.items);
// order.fetch(Order_.items, JoinType.INNER);
//
// q.select(note)
// .where( qb.and( qb.lt(note.index(), 10), qb.isNotEmpty(items) ) );
// }
public void test4Untypesafe() {
CriteriaQuery<String> q = qb.createQuery( String.class );
Root<Order> order = q.from( Order.class );
ListJoin<Order, String> note = order.joinList( "notes" );
Expression<Set<Item>> items = order.get( "items" );
order.fetch( "items", INNER );
q.select( note )
.where( qb.and( qb.lt( note.index(), 10 ), qb.isNotEmpty( items ) ) );
}
/*public void test5() {
Expression<Long> l= null;
Expression<Integer> i= null;
Expression<Float> x= null;
Expression<Float> y= null;
Expression<Number> n;
Expression<Float> f;
Expression<String> s = null;
n = qb.quot(l, i);
f = qb.sum(x, y);
n = qb.quot(x, y);
javax.jpamodelgen.criteria.Order o = qb.asc(n);
javax.jpamodelgen.criteria.Order p = qb.ascending(s);
}*/
}

View File

@ -0,0 +1,55 @@
// $Id$
/*
* JBoss, Home of Professional Open Source
* Copyright 2008, Red Hat Middleware LLC, and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* Licensed 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.
*/
package test;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertTrue;
import org.testng.annotations.Test;
/**
* @author Hardy Ferentschik
*/
public class XmlMappingTest {
@Test
public void testXmlConfiguredEmbeddedClassGenerated() throws Exception {
assertNotNull( Class.forName( "model.xmlmapped.Address_" ) );
}
@Test
public void testXmlConfiguredMappedSuperclassGenerated() throws Exception {
Class<?> building = Class.forName( "model.xmlmapped.Building_" );
assertNotNull( building );
assertNotNull( building.getField( "address" ) );
}
@Test
public void testClassHierarchy() throws Exception {
Class<?> mammal = Class.forName( "model.xmlmapped.Mammal_" );
assertNotNull( mammal );
Class<?> being = Class.forName( "model.xmlmapped.LivingBeing_" );
assertNotNull( being );
assertTrue( mammal.getSuperclass().equals( being ) );
}
@Test(expectedExceptions = ClassNotFoundException.class)
public void testNonExistentMappedClassesGetIgnored() throws Exception {
Class.forName( "model.Dummy_" );
}
}

View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm orm_2_0.xsd"
version="2.0"
>
<package>model</package>
<entity class="Dummy" access="FIELD" metadata-complete="true"> <!-- Class does not exist -->
<attributes>
<id name="id"/>
</attributes>
</entity>
</entity-mappings>

View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm orm_1_0.xsd"
version="1.0"
>
<package>model</package>
<entity class="Airplane" metadata-complete="true" access="PROPERTY">
<attributes>
<id name="serialNumber"/>
</attributes>
</entity>
</entity-mappings>

View File

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm orm_2_0.xsd"
version="2.0"
>
<package>model</package>
<entity class="Dummy" access="FIELD" metadata-complete="true"> <!-- Class does not exist -->
<attributes>
<id name="id"/>
</entity>
</entity-mappings>

View File

@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm orm_2_0.xsd"
version="2.0"
>
<package>model</package>
<!-- default package -->
<entity class="Order" access="FIELD" metadata-complete="true"> <!--means ignore annotations-->
<attributes>
<id name="id">
<column name="fld_id"/>
</id>
<basic name="filled"/>
<basic name="date"/>
<many-to-one name="shop"/>
<one-to-many name="items"
target-entity="Item"
fetch="EAGER"> <!-- target-entity optional guess the type from the geenric-->
<cascade>
<cascade-persist/>
</cascade>
</one-to-many>
<element-collection name="notes"/>
<!-- new in JPA 2 -->
</attributes>
</entity>
</entity-mappings>

View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<persistence 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 persistence.xsd" version="2.0">
<persistence-unit name="annotation-processor" transaction-type="JTA">
<description>Test persistence unit</description>
<mapping-file>/META-INF/dummy.xml</mapping-file>
<mapping-file>/META-INF/malformed-mapping-xml.xml</mapping-file>
<mapping-file>/META-INF/jpa1-orm.xml</mapping-file>
<mapping-file>/model/xmlmapped/address.xml</mapping-file>
<mapping-file>/model/xmlmapped/building.xml</mapping-file>
<mapping-file>/model/xmlmapped/mammal.xml</mapping-file>
</persistence-unit>
</persistence>

View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm orm_2_0.xsd"
version="2.0"
>
<package>model.xmlmapped</package> <!-- default package -->
<embeddable class="Address" access="FIELD" metadata-complete="true"> <!--means ignore annotations-->
<attributes>
<basic name="street1"/>
<basic name="city"/>
<basic name="country"/>
</attributes>
</embeddable>
</entity-mappings>

View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm orm_2_0.xsd"
version="2.0"
>
<package>model.xmlmapped</package>
<mapped-superclass class="Building" access="FIELD" metadata-complete="true"> <!--means ignore annotations-->
<attributes>
<one-to-one name="address" fetch="LAZY"/>
</attributes>
</mapped-superclass>
</entity-mappings>

View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm orm_2_0.xsd"
version="2.0"
>
<package>model.xmlmapped</package>
<entity class="LivingBeing" access="FIELD" metadata-complete="true">
<attributes>
<basic name="isReallyAlive"/>
</attributes>
</entity>
<entity class="Mammal" access="FIELD" metadata-complete="true">
<attributes>
<id name="id"/>
<basic name="subclass"/>
</attributes>
</entity>
</entity-mappings>

View File

@ -0,0 +1,9 @@
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<suite name="Hibernate Model Generator Tests" verbose="1">
<test name="Unit tests">
<packages>
<package name="test"/>
</packages>
</test>
</suite>