Hibernate SVN: r17313 - core/trunk/commons-annotations and 1 other directory.
by hibernate-commits@lists.jboss.org
Author: steve.ebersole(a)jboss.com
Date: 2009-08-15 13:28:12 -0400 (Sat, 15 Aug 2009)
New Revision: 17313
Added:
commons-annotations/trunk/readme.txt
Removed:
core/trunk/commons-annotations/readme.txt
Log:
break hibernate-commons-annotations back out into separate project
Copied: commons-annotations/trunk/readme.txt (from rev 17312, core/trunk/commons-annotations/readme.txt)
===================================================================
--- commons-annotations/trunk/readme.txt (rev 0)
+++ commons-annotations/trunk/readme.txt 2009-08-15 17:28:12 UTC (rev 17313)
@@ -0,0 +1,45 @@
+Hibernate Commons Annotations
+==================================================
+Version: @version@, @releasedate@
+
+Description
+-----------
+
+Hibernate Commons Annotations is a utility project used by annotations based
+Hibernate sub-projects.
+It's first scope is to support Java Generics type discovery.
+It's second scope is to support Java Annotations overriding through XML files
+(mainly but not conceptually limited to)
+
+
+Instructions
+------------
+
+TODO: Do something here
+
+
+Contact
+------------
+
+Latest Documentation:
+
+This project has no documentation per se, because of it's internal use focus.
+Please ask questions to the technical support forum.
+
+Bug Reports:
+
+ Hibernate JIRA (preferred)
+ hibernate-devel(a)lists.sourceforge.net
+
+Free Technical Support:
+
+ http://forum.hibernate.org (http://forum.hibernate.org/viewforum.php?f=9)
+
+
+Notes
+-----------
+
+If you want to contribute, go to http://www.hibernate.org/
+
+This software and its documentation are distributed under the terms of the
+FSF Lesser Gnu Public License (see lgpl.txt).
\ No newline at end of file
Deleted: core/trunk/commons-annotations/readme.txt
===================================================================
--- core/trunk/commons-annotations/readme.txt 2009-08-15 17:27:19 UTC (rev 17312)
+++ core/trunk/commons-annotations/readme.txt 2009-08-15 17:28:12 UTC (rev 17313)
@@ -1,45 +0,0 @@
-Hibernate Commons Annotations
-==================================================
-Version: @version@, @releasedate@
-
-Description
------------
-
-Hibernate Commons Annotations is a utility project used by annotations based
-Hibernate sub-projects.
-It's first scope is to support Java Generics type discovery.
-It's second scope is to support Java Annotations overriding through XML files
-(mainly but not conceptually limited to)
-
-
-Instructions
-------------
-
-TODO: Do something here
-
-
-Contact
-------------
-
-Latest Documentation:
-
-This project has no documentation per se, because of it's internal use focus.
-Please ask questions to the technical support forum.
-
-Bug Reports:
-
- Hibernate JIRA (preferred)
- hibernate-devel(a)lists.sourceforge.net
-
-Free Technical Support:
-
- http://forum.hibernate.org (http://forum.hibernate.org/viewforum.php?f=9)
-
-
-Notes
------------
-
-If you want to contribute, go to http://www.hibernate.org/
-
-This software and its documentation are distributed under the terms of the
-FSF Lesser Gnu Public License (see lgpl.txt).
\ No newline at end of file
15 years, 3 months
Hibernate SVN: r17312 - core/trunk/commons-annotations and 1 other directory.
by hibernate-commits@lists.jboss.org
Author: steve.ebersole(a)jboss.com
Date: 2009-08-15 13:27:19 -0400 (Sat, 15 Aug 2009)
New Revision: 17312
Added:
commons-annotations/trunk/pom.xml
Removed:
core/trunk/commons-annotations/pom.xml
Log:
break hibernate-commons-annotations back out into separate project
Copied: commons-annotations/trunk/pom.xml (from rev 17311, core/trunk/commons-annotations/pom.xml)
===================================================================
--- commons-annotations/trunk/pom.xml (rev 0)
+++ commons-annotations/trunk/pom.xml 2009-08-15 17:27:19 UTC (rev 17312)
@@ -0,0 +1,189 @@
+<?xml version="1.0"?>
+<!--
+ ~ Hibernate, Relational Persistence for Idiomatic Java
+ ~
+ ~ Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ ~ indicated by the @author tags or express copyright attribution
+ ~ statements applied by the authors. All third-party contributions are
+ ~ distributed under license by Red Hat Middleware LLC.
+ ~
+ ~ This copyrighted material is made available to anyone wishing to use, modify,
+ ~ copy, or redistribute it subject to the terms and conditions of the GNU
+ ~ Lesser General Public License, as published by the Free Software Foundation.
+ ~
+ ~ This program is distributed in the hope that it will be useful,
+ ~ but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ ~ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ ~ for more details.
+ ~
+ ~ You should have received a copy of the GNU Lesser General Public License
+ ~ along with this distribution; if not, write to:
+ ~ Free Software Foundation, Inc.
+ ~ 51 Franklin Street, Fifth Floor
+ ~ Boston, MA 02110-1301 USA
+ -->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.hibernate</groupId>
+ <artifactId>hibernate-commons-annotations</artifactId>
+ <packaging>jar</packaging>
+ <version>3.2.0-SNAPSHOT</version>
+
+ <name>Hibernate Commons Annotations</name>
+ <description>Common reflection code used in support of annotation processing</description>
+ <url>http://hibernate.org</url>
+ <inceptionYear>2005</inceptionYear>
+
+ <organization>
+ <name>Hibernate.org</name>
+ <url>http://hibernate.org</url>
+ </organization>
+
+ <licenses>
+ <license>
+ <name>GNU LESSER GENERAL PUBLIC LICENSE</name>
+ <url>http://www.gnu.org/licenses/lgpl.txt</url>
+ </license>
+ </licenses>
+
+ <developers>
+ <developer>
+ <id>epbernard</id>
+ <name>Emmanuel Bernard</name>
+ <email>emmanuel(a)hibernate.org</email>
+ <organization>JBoss, a division of Red Hat</organization>
+ <url>http://in.relation.to/Bloggers/Emmanuel</url>
+ </developer>
+ </developers>
+
+ <mailingLists>
+ <mailingList>
+ <name>Hibernate Announcements</name>
+ <post>hibernate-announce(a)lists.jboss.org</post>
+ <subscribe>https://lists.jboss.org/mailman/listinfo/hibernate-announce</subscribe>
+ <unsubscribe>https://lists.jboss.org/mailman/listinfo/hibernate-announce</unsubscribe>
+ <archive>http://lists.jboss.org/pipermail/hibernate-dev/</archive>
+ </mailingList>
+ <mailingList>
+ <name>Hibernate Commit Notificatons</name>
+ <post>hibernate-commits(a)lists.jboss.org</post>
+ <subscribe>https://lists.jboss.org/mailman/listinfo/hibernate-commits</subscribe>
+ <unsubscribe>https://lists.jboss.org/mailman/listinfo/hibernate-commits</unsubscribe>
+ <archive>http://lists.jboss.org/pipermail/hibernate-commits/</archive>
+ </mailingList>
+ <mailingList>
+ <name>Hibernate Developers</name>
+ <post>hibernate-dev(a)lists.jboss.org</post>
+ <subscribe>https://lists.jboss.org/mailman/listinfo/hibernate-dev</subscribe>
+ <unsubscribe>https://lists.jboss.org/mailman/listinfo/hibernate-dev</unsubscribe>
+ <archive>http://lists.jboss.org/pipermail/hibernate-dev/</archive>
+ <otherArchives>
+ <otherArchive>http://www.mail-archive.com/hibernate-dev%40lists.jboss.org/index.html</otherArchive>
+ </otherArchives>
+ </mailingList>
+ <mailingList>
+ <name>Hibernate Issue Notifications</name>
+ <post>hibernate-issues(a)lists.jboss.org</post>
+ <subscribe>https://lists.jboss.org/mailman/listinfo/hibernate-issues</subscribe>
+ <unsubscribe>https://lists.jboss.org/mailman/listinfo/hibernate-issues</unsubscribe>
+ <archive>http://lists.jboss.org/pipermail/hibernate-issues/</archive>
+ </mailingList>
+ </mailingLists>
+
+ <issueManagement>
+ <system>jira</system>
+ <url>http://opensource.atlassian.com/projects/hibernate/browse/HCANN</url>
+ </issueManagement>
+
+ <scm>
+ <connection>scm:svn:https://svn.jboss.org/repos/hibernate/commons-annotations/trunk</connection>
+ <developerConnection>scm:svn:https://svn.jboss.org/repos/hibernate/commons-annotations/trunk</developerConnection>
+ <url>https://svn.jboss.org/repos/hibernate/commons-annotations/trunk</url>
+ </scm>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ </dependency>
+ <!-- test-scoped dependencies for common testing dependencies -->
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>3.8.1</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>jcl-over-slf4j</artifactId>
+ <version>${slf4jVersion}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-log4j12</artifactId>
+ <version>${slf4jVersion}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>commons-logging</groupId>
+ <artifactId>commons-logging</artifactId>
+ <version>99.0-does-not-exist</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>commons-logging</groupId>
+ <artifactId>commons-logging-api</artifactId>
+ <version>99.0-does-not-exist</version>
+ <scope>test</scope>
+ </dependency>
+ <!-- / test-scoped dependencies for common testing dependencies -->
+ </dependencies>
+
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ <version>${slf4jVersion}</version>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+
+ <distributionManagement>
+ <repository>
+ <!-- Copy the dist to the local checkout of the JBoss maven2 repo ${maven.repository.root} -->
+ <!-- It is anticipated that ${maven.repository.root} be set in user's settings.xml -->
+ <!-- todo : replace this with direct svn access once the svnkit providers are available -->
+ <id>repository.jboss.org</id>
+ <url>file://${maven.repository.root}</url>
+ </repository>
+ <snapshotRepository>
+ <id>snapshots.jboss.org</id>
+ <name>JBoss Snapshot Repository</name>
+ <url>dav:https://snapshots.jboss.org/maven2</url>
+ </snapshotRepository>
+ </distributionManagement>
+
+ <properties>
+ <slf4jVersion>1.5.8</slf4jVersion>
+ </properties>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <source>1.5</source>
+ <target>1.5</target>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
Deleted: core/trunk/commons-annotations/pom.xml
===================================================================
--- core/trunk/commons-annotations/pom.xml 2009-08-15 17:26:18 UTC (rev 17311)
+++ core/trunk/commons-annotations/pom.xml 2009-08-15 17:27:19 UTC (rev 17312)
@@ -1,189 +0,0 @@
-<?xml version="1.0"?>
-<!--
- ~ Hibernate, Relational Persistence for Idiomatic Java
- ~
- ~ Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
- ~ indicated by the @author tags or express copyright attribution
- ~ statements applied by the authors. All third-party contributions are
- ~ distributed under license by Red Hat Middleware LLC.
- ~
- ~ This copyrighted material is made available to anyone wishing to use, modify,
- ~ copy, or redistribute it subject to the terms and conditions of the GNU
- ~ Lesser General Public License, as published by the Free Software Foundation.
- ~
- ~ This program is distributed in the hope that it will be useful,
- ~ but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- ~ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
- ~ for more details.
- ~
- ~ You should have received a copy of the GNU Lesser General Public License
- ~ along with this distribution; if not, write to:
- ~ Free Software Foundation, Inc.
- ~ 51 Franklin Street, Fifth Floor
- ~ Boston, MA 02110-1301 USA
- -->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-
- <modelVersion>4.0.0</modelVersion>
-
- <groupId>org.hibernate</groupId>
- <artifactId>hibernate-commons-annotations</artifactId>
- <packaging>jar</packaging>
- <version>3.2.0-SNAPSHOT</version>
-
- <name>Hibernate Commons Annotations</name>
- <description>Common reflection code used in support of annotation processing</description>
- <url>http://hibernate.org</url>
- <inceptionYear>2005</inceptionYear>
-
- <organization>
- <name>Hibernate.org</name>
- <url>http://hibernate.org</url>
- </organization>
-
- <licenses>
- <license>
- <name>GNU LESSER GENERAL PUBLIC LICENSE</name>
- <url>http://www.gnu.org/licenses/lgpl.txt</url>
- </license>
- </licenses>
-
- <developers>
- <developer>
- <id>epbernard</id>
- <name>Emmanuel Bernard</name>
- <email>emmanuel(a)hibernate.org</email>
- <organization>JBoss, a division of Red Hat</organization>
- <url>http://in.relation.to/Bloggers/Emmanuel</url>
- </developer>
- </developers>
-
- <mailingLists>
- <mailingList>
- <name>Hibernate Announcements</name>
- <post>hibernate-announce(a)lists.jboss.org</post>
- <subscribe>https://lists.jboss.org/mailman/listinfo/hibernate-announce</subscribe>
- <unsubscribe>https://lists.jboss.org/mailman/listinfo/hibernate-announce</unsubscribe>
- <archive>http://lists.jboss.org/pipermail/hibernate-dev/</archive>
- </mailingList>
- <mailingList>
- <name>Hibernate Commit Notificatons</name>
- <post>hibernate-commits(a)lists.jboss.org</post>
- <subscribe>https://lists.jboss.org/mailman/listinfo/hibernate-commits</subscribe>
- <unsubscribe>https://lists.jboss.org/mailman/listinfo/hibernate-commits</unsubscribe>
- <archive>http://lists.jboss.org/pipermail/hibernate-commits/</archive>
- </mailingList>
- <mailingList>
- <name>Hibernate Developers</name>
- <post>hibernate-dev(a)lists.jboss.org</post>
- <subscribe>https://lists.jboss.org/mailman/listinfo/hibernate-dev</subscribe>
- <unsubscribe>https://lists.jboss.org/mailman/listinfo/hibernate-dev</unsubscribe>
- <archive>http://lists.jboss.org/pipermail/hibernate-dev/</archive>
- <otherArchives>
- <otherArchive>http://www.mail-archive.com/hibernate-dev%40lists.jboss.org/index.html</otherArchive>
- </otherArchives>
- </mailingList>
- <mailingList>
- <name>Hibernate Issue Notifications</name>
- <post>hibernate-issues(a)lists.jboss.org</post>
- <subscribe>https://lists.jboss.org/mailman/listinfo/hibernate-issues</subscribe>
- <unsubscribe>https://lists.jboss.org/mailman/listinfo/hibernate-issues</unsubscribe>
- <archive>http://lists.jboss.org/pipermail/hibernate-issues/</archive>
- </mailingList>
- </mailingLists>
-
- <issueManagement>
- <system>jira</system>
- <url>http://opensource.atlassian.com/projects/hibernate/browse/HCANN</url>
- </issueManagement>
-
- <scm>
- <connection>scm:svn:https://svn.jboss.org/repos/hibernate/commons-annotations/trunk</connection>
- <developerConnection>scm:svn:https://svn.jboss.org/repos/hibernate/commons-annotations/trunk</developerConnection>
- <url>https://svn.jboss.org/repos/hibernate/commons-annotations/trunk</url>
- </scm>
-
- <dependencies>
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-api</artifactId>
- </dependency>
- <!-- test-scoped dependencies for common testing dependencies -->
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- <version>3.8.1</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>jcl-over-slf4j</artifactId>
- <version>${slf4jVersion}</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-log4j12</artifactId>
- <version>${slf4jVersion}</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>commons-logging</groupId>
- <artifactId>commons-logging</artifactId>
- <version>99.0-does-not-exist</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>commons-logging</groupId>
- <artifactId>commons-logging-api</artifactId>
- <version>99.0-does-not-exist</version>
- <scope>test</scope>
- </dependency>
- <!-- / test-scoped dependencies for common testing dependencies -->
- </dependencies>
-
- <dependencyManagement>
- <dependencies>
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-api</artifactId>
- <version>${slf4jVersion}</version>
- </dependency>
- </dependencies>
- </dependencyManagement>
-
- <distributionManagement>
- <repository>
- <!-- Copy the dist to the local checkout of the JBoss maven2 repo ${maven.repository.root} -->
- <!-- It is anticipated that ${maven.repository.root} be set in user's settings.xml -->
- <!-- todo : replace this with direct svn access once the svnkit providers are available -->
- <id>repository.jboss.org</id>
- <url>file://${maven.repository.root}</url>
- </repository>
- <snapshotRepository>
- <id>snapshots.jboss.org</id>
- <name>JBoss Snapshot Repository</name>
- <url>dav:https://snapshots.jboss.org/maven2</url>
- </snapshotRepository>
- </distributionManagement>
-
- <properties>
- <slf4jVersion>1.5.8</slf4jVersion>
- </properties>
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-compiler-plugin</artifactId>
- <configuration>
- <source>1.5</source>
- <target>1.5</target>
- </configuration>
- </plugin>
- </plugins>
- </build>
-
-</project>
15 years, 3 months
Hibernate SVN: r17311 - core/trunk/commons-annotations and 1 other directory.
by hibernate-commits@lists.jboss.org
Author: steve.ebersole(a)jboss.com
Date: 2009-08-15 13:26:18 -0400 (Sat, 15 Aug 2009)
New Revision: 17311
Added:
commons-annotations/trunk/changelog.txt
Removed:
core/trunk/commons-annotations/changelog.txt
Log:
break hibernate-commons-annotations back out into separate project
Copied: commons-annotations/trunk/changelog.txt (from rev 17310, core/trunk/commons-annotations/changelog.txt)
===================================================================
--- commons-annotations/trunk/changelog.txt (rev 0)
+++ commons-annotations/trunk/changelog.txt 2009-08-15 17:26:18 UTC (rev 17311)
@@ -0,0 +1,25 @@
+Hibernate Annotations Changelog
+===============================
+
+3.1.0.GA (20-08-2008)
+----------------------
+
+3.1.0.CR2 (23-07-2008)
+----------------------
+
+** Bug
+ * [HCANN-4] - NullPointerException in JavaXCollectionType
+
+
+3.1.0.CR1 (27-05-2008)
+----------------------
+
+** New Feature
+ * [HCANN-1] - Move to slf4j
+ * [HCANN-2] - Add POM
+ * [HCANN-3] - Make build independent of Hibernate Core structure
+
+3.0.0.GA (19-03-2007)
+---------------------
+
+Initial release as a standalone product (see Hibernate Annotations changelog for previous informations)
\ No newline at end of file
Deleted: core/trunk/commons-annotations/changelog.txt
===================================================================
--- core/trunk/commons-annotations/changelog.txt 2009-08-15 17:25:34 UTC (rev 17310)
+++ core/trunk/commons-annotations/changelog.txt 2009-08-15 17:26:18 UTC (rev 17311)
@@ -1,25 +0,0 @@
-Hibernate Annotations Changelog
-===============================
-
-3.1.0.GA (20-08-2008)
-----------------------
-
-3.1.0.CR2 (23-07-2008)
-----------------------
-
-** Bug
- * [HCANN-4] - NullPointerException in JavaXCollectionType
-
-
-3.1.0.CR1 (27-05-2008)
-----------------------
-
-** New Feature
- * [HCANN-1] - Move to slf4j
- * [HCANN-2] - Add POM
- * [HCANN-3] - Make build independent of Hibernate Core structure
-
-3.0.0.GA (19-03-2007)
----------------------
-
-Initial release as a standalone product (see Hibernate Annotations changelog for previous informations)
\ No newline at end of file
15 years, 3 months
Hibernate SVN: r17310 - core/trunk/commons-annotations and 1 other directory.
by hibernate-commits@lists.jboss.org
Author: steve.ebersole(a)jboss.com
Date: 2009-08-15 13:25:34 -0400 (Sat, 15 Aug 2009)
New Revision: 17310
Added:
commons-annotations/trunk/src/
Removed:
core/trunk/commons-annotations/src/
Log:
break hibernate-commons-annotations back out into separate project
Copied: commons-annotations/trunk/src (from rev 17309, core/trunk/commons-annotations/src)
15 years, 3 months
Hibernate SVN: r17309 - commons-annotations.
by hibernate-commits@lists.jboss.org
Author: steve.ebersole(a)jboss.com
Date: 2009-08-15 13:21:58 -0400 (Sat, 15 Aug 2009)
New Revision: 17309
Added:
commons-annotations/trunk/
Log:
break hibernate-commons-annotations back out into separate project
15 years, 3 months
Hibernate SVN: r17308 - core/trunk/commons-annotations and 3 other directories.
by hibernate-commits@lists.jboss.org
Author: epbernard
Date: 2009-08-15 12:31:51 -0400 (Sat, 15 Aug 2009)
New Revision: 17308
Modified:
core/trunk/annotations/pom.xml
core/trunk/commons-annotations/pom.xml
core/trunk/entitymanager/pom.xml
search/trunk/pom.xml
search/trunk/src/main/java/org/hibernate/search/jpa/impl/FullTextEntityManagerImpl.java
search/trunk/src/main/java/org/hibernate/search/jpa/impl/FullTextQueryImpl.java
Log:
Make commons annotation independent from core.
Modified: core/trunk/annotations/pom.xml
===================================================================
--- core/trunk/annotations/pom.xml 2009-08-15 16:24:27 UTC (rev 17307)
+++ core/trunk/annotations/pom.xml 2009-08-15 16:31:51 UTC (rev 17308)
@@ -42,7 +42,6 @@
<name>Hibernate Annotations</name>
<description>Annotations metadata for Hibernate</description>
- <!-- Annotations and Commons-Annotations both use the ANN JIRA key -->
<issueManagement>
<system>jira</system>
<url>http://opensource.atlassian.com/projects/hibernate/browse/ANN</url>
@@ -57,7 +56,7 @@
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-commons-annotations</artifactId>
- <version>${version}</version>
+ <version>3.2.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.hibernate.java-persistence</groupId>
Modified: core/trunk/commons-annotations/pom.xml
===================================================================
--- core/trunk/commons-annotations/pom.xml 2009-08-15 16:24:27 UTC (rev 17307)
+++ core/trunk/commons-annotations/pom.xml 2009-08-15 16:31:51 UTC (rev 17308)
@@ -28,43 +28,151 @@
<modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.hibernate</groupId>
- <artifactId>hibernate-parent</artifactId>
- <version>3.5.0-SNAPSHOT</version>
- <relativePath>../parent/pom.xml</relativePath>
- </parent>
-
<groupId>org.hibernate</groupId>
<artifactId>hibernate-commons-annotations</artifactId>
<packaging>jar</packaging>
+ <version>3.2.0-SNAPSHOT</version>
<name>Hibernate Commons Annotations</name>
<description>Common reflection code used in support of annotation processing</description>
+ <url>http://hibernate.org</url>
+ <inceptionYear>2005</inceptionYear>
- <!-- Annotations and Commons-Annotations both use the ANN JIRA key -->
+ <organization>
+ <name>Hibernate.org</name>
+ <url>http://hibernate.org</url>
+ </organization>
+
+ <licenses>
+ <license>
+ <name>GNU LESSER GENERAL PUBLIC LICENSE</name>
+ <url>http://www.gnu.org/licenses/lgpl.txt</url>
+ </license>
+ </licenses>
+
+ <developers>
+ <developer>
+ <id>epbernard</id>
+ <name>Emmanuel Bernard</name>
+ <email>emmanuel(a)hibernate.org</email>
+ <organization>JBoss, a division of Red Hat</organization>
+ <url>http://in.relation.to/Bloggers/Emmanuel</url>
+ </developer>
+ </developers>
+
+ <mailingLists>
+ <mailingList>
+ <name>Hibernate Announcements</name>
+ <post>hibernate-announce(a)lists.jboss.org</post>
+ <subscribe>https://lists.jboss.org/mailman/listinfo/hibernate-announce</subscribe>
+ <unsubscribe>https://lists.jboss.org/mailman/listinfo/hibernate-announce</unsubscribe>
+ <archive>http://lists.jboss.org/pipermail/hibernate-dev/</archive>
+ </mailingList>
+ <mailingList>
+ <name>Hibernate Commit Notificatons</name>
+ <post>hibernate-commits(a)lists.jboss.org</post>
+ <subscribe>https://lists.jboss.org/mailman/listinfo/hibernate-commits</subscribe>
+ <unsubscribe>https://lists.jboss.org/mailman/listinfo/hibernate-commits</unsubscribe>
+ <archive>http://lists.jboss.org/pipermail/hibernate-commits/</archive>
+ </mailingList>
+ <mailingList>
+ <name>Hibernate Developers</name>
+ <post>hibernate-dev(a)lists.jboss.org</post>
+ <subscribe>https://lists.jboss.org/mailman/listinfo/hibernate-dev</subscribe>
+ <unsubscribe>https://lists.jboss.org/mailman/listinfo/hibernate-dev</unsubscribe>
+ <archive>http://lists.jboss.org/pipermail/hibernate-dev/</archive>
+ <otherArchives>
+ <otherArchive>http://www.mail-archive.com/hibernate-dev%40lists.jboss.org/index.html</otherArchive>
+ </otherArchives>
+ </mailingList>
+ <mailingList>
+ <name>Hibernate Issue Notifications</name>
+ <post>hibernate-issues(a)lists.jboss.org</post>
+ <subscribe>https://lists.jboss.org/mailman/listinfo/hibernate-issues</subscribe>
+ <unsubscribe>https://lists.jboss.org/mailman/listinfo/hibernate-issues</unsubscribe>
+ <archive>http://lists.jboss.org/pipermail/hibernate-issues/</archive>
+ </mailingList>
+ </mailingLists>
+
<issueManagement>
<system>jira</system>
- <url>http://opensource.atlassian.com/projects/hibernate/browse/ANN</url>
+ <url>http://opensource.atlassian.com/projects/hibernate/browse/HCANN</url>
</issueManagement>
+ <scm>
+ <connection>scm:svn:https://svn.jboss.org/repos/hibernate/commons-annotations/trunk</connection>
+ <developerConnection>scm:svn:https://svn.jboss.org/repos/hibernate/commons-annotations/trunk</developerConnection>
+ <url>https://svn.jboss.org/repos/hibernate/commons-annotations/trunk</url>
+ </scm>
+
<dependencies>
<dependency>
- <groupId>org.hibernate</groupId>
- <artifactId>hibernate-core</artifactId>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
</dependency>
+ <!-- test-scoped dependencies for common testing dependencies -->
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>3.8.1</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>jcl-over-slf4j</artifactId>
+ <version>${slf4jVersion}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-log4j12</artifactId>
+ <version>${slf4jVersion}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>commons-logging</groupId>
+ <artifactId>commons-logging</artifactId>
+ <version>99.0-does-not-exist</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>commons-logging</groupId>
+ <artifactId>commons-logging-api</artifactId>
+ <version>99.0-does-not-exist</version>
+ <scope>test</scope>
+ </dependency>
+ <!-- / test-scoped dependencies for common testing dependencies -->
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
- <groupId>org.hibernate</groupId>
- <artifactId>hibernate-core</artifactId>
- <version>${version}</version>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ <version>${slf4jVersion}</version>
</dependency>
</dependencies>
</dependencyManagement>
+ <distributionManagement>
+ <repository>
+ <!-- Copy the dist to the local checkout of the JBoss maven2 repo ${maven.repository.root} -->
+ <!-- It is anticipated that ${maven.repository.root} be set in user's settings.xml -->
+ <!-- todo : replace this with direct svn access once the svnkit providers are available -->
+ <id>repository.jboss.org</id>
+ <url>file://${maven.repository.root}</url>
+ </repository>
+ <snapshotRepository>
+ <id>snapshots.jboss.org</id>
+ <name>JBoss Snapshot Repository</name>
+ <url>dav:https://snapshots.jboss.org/maven2</url>
+ </snapshotRepository>
+ </distributionManagement>
+
+ <properties>
+ <slf4jVersion>1.5.8</slf4jVersion>
+ </properties>
+
<build>
<plugins>
<plugin>
Modified: core/trunk/entitymanager/pom.xml
===================================================================
--- core/trunk/entitymanager/pom.xml 2009-08-15 16:24:27 UTC (rev 17307)
+++ core/trunk/entitymanager/pom.xml 2009-08-15 16:31:51 UTC (rev 17308)
@@ -85,7 +85,7 @@
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-commons-annotations</artifactId>
- <version>${version}</version>
+ <version>3.2.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
Modified: search/trunk/pom.xml
===================================================================
--- search/trunk/pom.xml 2009-08-15 16:24:27 UTC (rev 17307)
+++ search/trunk/pom.xml 2009-08-15 16:31:51 UTC (rev 17308)
@@ -54,6 +54,7 @@
<slf4jVersion>1.5.6</slf4jVersion>
<luceneVersion>2.4.1</luceneVersion>
<hibernateVersion>3.5.0-SNAPSHOT</hibernateVersion>
+ <hibernateCommonsAnnotationVersion>3.2.0-SNAPSHOT</hibernateCommonsAnnotationVersion>
</properties>
<dependencies>
@@ -68,7 +69,7 @@
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-commons-annotations</artifactId>
- <version>${hibernateVersion}</version>
+ <version>${hibernateCommonsAnnotationVersion}</version>
</dependency>
<!-- dependency>
<groupId>org.hibernate</groupId>
Modified: search/trunk/src/main/java/org/hibernate/search/jpa/impl/FullTextEntityManagerImpl.java
===================================================================
--- search/trunk/src/main/java/org/hibernate/search/jpa/impl/FullTextEntityManagerImpl.java 2009-08-15 16:24:27 UTC (rev 17307)
+++ search/trunk/src/main/java/org/hibernate/search/jpa/impl/FullTextEntityManagerImpl.java 2009-08-15 16:31:51 UTC (rev 17308)
@@ -10,6 +10,7 @@
import javax.persistence.Query;
import javax.persistence.EntityTransaction;
import javax.persistence.EntityManagerFactory;
+import javax.persistence.TypedQuery;
import javax.persistence.metamodel.Metamodel;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.QueryBuilder;
@@ -196,14 +197,22 @@
return em.createQuery( ejbqlString );
}
- public Query createQuery(CriteriaQuery criteriaQuery) {
- return null; //To change body of implemented methods use File | Settings | File Templates.
+ public <T> TypedQuery<T> createQuery(CriteriaQuery<T> criteriaQuery) {
+ return em.createQuery( criteriaQuery );
}
+ public <T> TypedQuery<T> createQuery(String qlString, Class<T> resultClass) {
+ return em.createQuery( qlString, resultClass );
+ }
+
public Query createNamedQuery(String name) {
return em.createNamedQuery( name );
}
+ public <T> TypedQuery<T> createNamedQuery(String name, Class<T> resultClass) {
+ return em.createNamedQuery( name, resultClass );
+ }
+
public Query createNativeQuery(String sqlString) {
return em.createNativeQuery( sqlString );
}
Modified: search/trunk/src/main/java/org/hibernate/search/jpa/impl/FullTextQueryImpl.java
===================================================================
--- search/trunk/src/main/java/org/hibernate/search/jpa/impl/FullTextQueryImpl.java 2009-08-15 16:24:27 UTC (rev 17307)
+++ search/trunk/src/main/java/org/hibernate/search/jpa/impl/FullTextQueryImpl.java 2009-08-15 16:31:51 UTC (rev 17308)
@@ -18,6 +18,7 @@
import javax.persistence.Query;
import javax.persistence.TemporalType;
import javax.persistence.LockModeType;
+import javax.persistence.Parameter;
import org.apache.lucene.search.Filter;
import org.apache.lucene.search.Sort;
@@ -282,14 +283,61 @@
throw new UnsupportedOperationException( "parameters not supported in fullText queries");
}
+ //FIXME remove old JPA 2 contract
public Map<String, Object> getNamedParameters() {
return null; //To change body of implemented methods use File | Settings | File Templates.
}
+ //FIXME remove old JPA 2 contract
public List getPositionalParameters() {
return null; //To change body of implemented methods use File | Settings | File Templates.
}
+ //FIXME
+ public Set<Parameter<?>> getParameters() {
+ return null; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ //FIXME
+ public Parameter<?> getParameter(String name) {
+ return null; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ //FIXME
+ public Parameter<?> getParameter(int position) {
+ return null; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ //FIXME
+ public <T> Parameter<T> getParameter(String name, Class<T> type) {
+ return null; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ //FIXME
+ public <T> Parameter<T> getParameter(int position, Class<T> type) {
+ return null; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ //FIXME
+ public boolean isBound(Parameter<?> param) {
+ return false; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ //FIXME
+ public <T> T getParameterValue(Parameter<T> param) {
+ return null; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ //FIXME
+ public Object getParameterValue(String name) {
+ return null; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ //FIXME
+ public Object getParameterValue(int position) {
+ return null; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
public Query setFlushMode(FlushModeType flushMode) {
if ( flushMode == FlushModeType.AUTO ) {
query.setFlushMode( FlushMode.AUTO );
15 years, 3 months
Hibernate SVN: r17307 - core/trunk/commons-annotations/src/main/java/org/hibernate/annotations/common/util.
by hibernate-commits@lists.jboss.org
Author: epbernard
Date: 2009-08-15 12:24:27 -0400 (Sat, 15 Aug 2009)
New Revision: 17307
Modified:
core/trunk/commons-annotations/src/main/java/org/hibernate/annotations/common/util/ReflectHelper.java
core/trunk/commons-annotations/src/main/java/org/hibernate/annotations/common/util/StringHelper.java
Log:
Remove dependency on core
Modified: core/trunk/commons-annotations/src/main/java/org/hibernate/annotations/common/util/ReflectHelper.java
===================================================================
--- core/trunk/commons-annotations/src/main/java/org/hibernate/annotations/common/util/ReflectHelper.java 2009-08-14 22:53:34 UTC (rev 17306)
+++ core/trunk/commons-annotations/src/main/java/org/hibernate/annotations/common/util/ReflectHelper.java 2009-08-15 16:24:27 UTC (rev 17307)
@@ -27,8 +27,7 @@
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
-import org.hibernate.AssertionFailure;
-import org.hibernate.util.StringHelper;
+import org.hibernate.annotations.common.AssertionFailure;
/**
* Complete duplication of {@link org.hibernate.util.ReflectHelper}.
@@ -186,7 +185,7 @@
public static Object getConstantValue(String name) {
Class clazz;
try {
- clazz = classForName( org.hibernate.util.StringHelper.qualifier( name ) );
+ clazz = classForName( StringHelper.qualifier( name ) );
}
catch ( Throwable t ) {
return null;
Modified: core/trunk/commons-annotations/src/main/java/org/hibernate/annotations/common/util/StringHelper.java
===================================================================
--- core/trunk/commons-annotations/src/main/java/org/hibernate/annotations/common/util/StringHelper.java 2009-08-14 22:53:34 UTC (rev 17306)
+++ core/trunk/commons-annotations/src/main/java/org/hibernate/annotations/common/util/StringHelper.java 2009-08-15 16:24:27 UTC (rev 17307)
@@ -23,176 +23,494 @@
*/
package org.hibernate.annotations.common.util;
+import java.util.Arrays;
import java.util.Iterator;
-import java.util.Collection;
+import java.util.StringTokenizer;
+
/**
* Complete duplication of {@link org.hibernate.util.StringHelper}.
*
* @author Emmanuel Bernard
- * @deprecated Use {@link org.hibernate.util.StringHelper} instead.
*/
public final class StringHelper {
private static final int ALIAS_TRUNCATE_LENGTH = 10;
public static final String WHITESPACE = " \n\r\f\t";
- private StringHelper() {
+ private StringHelper() { /* static methods only - hide constructor */
}
+ /*public static boolean containsDigits(String string) {
+ for ( int i=0; i<string.length(); i++ ) {
+ if ( Character.isDigit( string.charAt(i) ) ) return true;
+ }
+ return false;
+ }*/
+
public static int lastIndexOfLetter(String string) {
- return org.hibernate.util.StringHelper.lastIndexOfLetter( string );
+ for ( int i=0; i<string.length(); i++ ) {
+ char character = string.charAt(i);
+ if ( !Character.isLetter(character) /*&& !('_'==character)*/ ) return i-1;
+ }
+ return string.length()-1;
}
public static String join(String seperator, String[] strings) {
- return org.hibernate.util.StringHelper.join( seperator, strings );
+ int length = strings.length;
+ if ( length == 0 ) return "";
+ StringBuffer buf = new StringBuffer( length * strings[0].length() )
+ .append( strings[0] );
+ for ( int i = 1; i < length; i++ ) {
+ buf.append( seperator ).append( strings[i] );
+ }
+ return buf.toString();
}
public static String join(String seperator, Iterator objects) {
- return org.hibernate.util.StringHelper.join( seperator, objects );
+ StringBuffer buf = new StringBuffer();
+ if ( objects.hasNext() ) buf.append( objects.next() );
+ while ( objects.hasNext() ) {
+ buf.append( seperator ).append( objects.next() );
+ }
+ return buf.toString();
}
public static String[] add(String[] x, String sep, String[] y) {
- return org.hibernate.util.StringHelper.add( x, sep, y );
+ String[] result = new String[x.length];
+ for ( int i = 0; i < x.length; i++ ) {
+ result[i] = x[i] + sep + y[i];
+ }
+ return result;
}
public static String repeat(String string, int times) {
- return org.hibernate.util.StringHelper.repeat( string, times );
+ StringBuffer buf = new StringBuffer( string.length() * times );
+ for ( int i = 0; i < times; i++ ) buf.append( string );
+ return buf.toString();
}
+ public static String repeat(char character, int times) {
+ char[] buffer = new char[times];
+ Arrays.fill( buffer, character );
+ return new String( buffer );
+ }
+
+
public static String replace(String template, String placeholder, String replacement) {
- return org.hibernate.util.StringHelper.replace( template, placeholder, replacement );
+ return replace( template, placeholder, replacement, false );
}
public static String[] replace(String templates[], String placeholder, String replacement) {
- return org.hibernate.util.StringHelper.replace( templates, placeholder, replacement );
+ String[] result = new String[templates.length];
+ for ( int i =0; i<templates.length; i++ ) {
+ result[i] = replace( templates[i], placeholder, replacement );
+ }
+ return result;
}
public static String replace(String template, String placeholder, String replacement, boolean wholeWords) {
- return org.hibernate.util.StringHelper.replace( template, placeholder, replacement, wholeWords );
+ if ( template == null ) {
+ return template;
+ }
+ int loc = template.indexOf( placeholder );
+ if ( loc < 0 ) {
+ return template;
+ }
+ else {
+ final boolean actuallyReplace = !wholeWords ||
+ loc + placeholder.length() == template.length() ||
+ !Character.isJavaIdentifierPart( template.charAt( loc + placeholder.length() ) );
+ String actualReplacement = actuallyReplace ? replacement : placeholder;
+ return new StringBuffer( template.substring( 0, loc ) )
+ .append( actualReplacement )
+ .append( replace( template.substring( loc + placeholder.length() ),
+ placeholder,
+ replacement,
+ wholeWords ) ).toString();
+ }
}
+
public static String replaceOnce(String template, String placeholder, String replacement) {
- return org.hibernate.util.StringHelper.replaceOnce( template, placeholder, replacement );
+ if ( template == null ) {
+ return template; // returnign null!
+ }
+ int loc = template.indexOf( placeholder );
+ if ( loc < 0 ) {
+ return template;
+ }
+ else {
+ return new StringBuffer( template.substring( 0, loc ) )
+ .append( replacement )
+ .append( template.substring( loc + placeholder.length() ) )
+ .toString();
+ }
}
+
public static String[] split(String seperators, String list) {
- return org.hibernate.util.StringHelper.split( seperators, list );
+ return split( seperators, list, false );
}
public static String[] split(String seperators, String list, boolean include) {
- return org.hibernate.util.StringHelper.split( seperators, list, include );
+ StringTokenizer tokens = new StringTokenizer( list, seperators, include );
+ String[] result = new String[ tokens.countTokens() ];
+ int i = 0;
+ while ( tokens.hasMoreTokens() ) {
+ result[i++] = tokens.nextToken();
+ }
+ return result;
}
public static String unqualify(String qualifiedName) {
- return org.hibernate.util.StringHelper.unqualify( qualifiedName );
+ int loc = qualifiedName.lastIndexOf(".");
+ return ( loc < 0 ) ? qualifiedName : qualifiedName.substring( qualifiedName.lastIndexOf(".") + 1 );
}
- public static String qualify(String prefix, String name) {
- return org.hibernate.util.StringHelper.qualify( prefix, name );
+ public static String qualifier(String qualifiedName) {
+ int loc = qualifiedName.lastIndexOf(".");
+ return ( loc < 0 ) ? "" : qualifiedName.substring( 0, loc );
}
- public static String[] qualify(String prefix, String[] names) {
- return org.hibernate.util.StringHelper.qualify( prefix, names );
+ /**
+ * Collapses a name. Mainly intended for use with classnames, where an example might serve best to explain.
+ * Imagine you have a class named <samp>'org.hibernate.util.StringHelper'</samp>; calling collapse on that
+ * classname will result in <samp>'o.h.u.StringHelper'<samp>.
+ *
+ * @param name The name to collapse.
+ * @return The collapsed name.
+ */
+ public static String collapse(String name) {
+ if ( name == null ) {
+ return null;
+ }
+ int breakPoint = name.lastIndexOf( '.' );
+ if ( breakPoint < 0 ) {
+ return name;
+ }
+ return collapseQualifier( name.substring( 0, breakPoint ), true ) + name.substring( breakPoint ); // includes last '.'
}
- public static String qualifier(String qualifiedName) {
- return org.hibernate.util.StringHelper.qualifier( qualifiedName );
+ /**
+ * Given a qualifier, collapse it.
+ *
+ * @param qualifier The qualifier to collapse.
+ * @param includeDots Should we include the dots in the collapsed form?
+ *
+ * @return The collapsed form.
+ */
+ public static String collapseQualifier(String qualifier, boolean includeDots) {
+ StringTokenizer tokenizer = new StringTokenizer( qualifier, "." );
+ String collapsed = Character.toString( tokenizer.nextToken().charAt( 0 ) );
+ while ( tokenizer.hasMoreTokens() ) {
+ if ( includeDots ) {
+ collapsed += '.';
+ }
+ collapsed += tokenizer.nextToken().charAt( 0 );
+ }
+ return collapsed;
}
+ /**
+ * Partially unqualifies a qualified name. For example, with a base of 'org.hibernate' the name
+ * 'org.hibernate.util.StringHelper' would become 'util.StringHelper'.
+ *
+ * @param name The (potentially) qualified name.
+ * @param qualifierBase The qualifier base.
+ *
+ * @return The name itself, or the partially unqualified form if it begins with the qualifier base.
+ */
+ public static String partiallyUnqualify(String name, String qualifierBase) {
+ if ( name == null || ! name.startsWith( qualifierBase ) ) {
+ return name;
+ }
+ return name.substring( qualifierBase.length() + 1 ); // +1 to start after the following '.'
+ }
+
+ /**
+ * Cross between {@link #collapse} and {@link #partiallyUnqualify}. Functions much like {@link #collapse}
+ * except that only the qualifierBase is collapsed. For example, with a base of 'org.hibernate' the name
+ * 'org.hibernate.util.StringHelper' would become 'o.h.util.StringHelper'.
+ *
+ * @param name The (potentially) qualified name.
+ * @param qualifierBase The qualifier base.
+ *
+ * @return The name itself if it does not begin with the qualifierBase, or the properly collapsed form otherwise.
+ */
+ public static String collapseQualifierBase(String name, String qualifierBase) {
+ if ( name == null || ! name.startsWith( qualifierBase ) ) {
+ return collapse( name );
+ }
+ return collapseQualifier( qualifierBase, true ) + name.substring( qualifierBase.length() );
+ }
+
public static String[] suffix(String[] columns, String suffix) {
- return org.hibernate.util.StringHelper.suffix( columns, suffix );
+ if ( suffix == null ) return columns;
+ String[] qualified = new String[columns.length];
+ for ( int i = 0; i < columns.length; i++ ) {
+ qualified[i] = suffix( columns[i], suffix );
+ }
+ return qualified;
}
+ private static String suffix(String name, String suffix) {
+ return ( suffix == null ) ? name : name + suffix;
+ }
+
public static String root(String qualifiedName) {
- return org.hibernate.util.StringHelper.root( qualifiedName );
+ int loc = qualifiedName.indexOf( "." );
+ return ( loc < 0 ) ? qualifiedName : qualifiedName.substring( 0, loc );
}
public static String unroot(String qualifiedName) {
- return org.hibernate.util.StringHelper.unroot( qualifiedName );
+ int loc = qualifiedName.indexOf( "." );
+ return ( loc < 0 ) ? qualifiedName : qualifiedName.substring( loc+1, qualifiedName.length() );
}
public static boolean booleanValue(String tfString) {
- return org.hibernate.util.StringHelper.booleanValue( tfString );
+ String trimmed = tfString.trim().toLowerCase();
+ return trimmed.equals( "true" ) || trimmed.equals( "t" );
}
public static String toString(Object[] array) {
- return org.hibernate.util.StringHelper.toString( array );
+ int len = array.length;
+ if ( len == 0 ) return "";
+ StringBuffer buf = new StringBuffer( len * 12 );
+ for ( int i = 0; i < len - 1; i++ ) {
+ buf.append( array[i] ).append(", ");
+ }
+ return buf.append( array[len - 1] ).toString();
}
public static String[] multiply(String string, Iterator placeholders, Iterator replacements) {
- return org.hibernate.util.StringHelper.multiply( string, placeholders, replacements );
+ String[] result = new String[]{string};
+ while ( placeholders.hasNext() ) {
+ result = multiply( result, ( String ) placeholders.next(), ( String[] ) replacements.next() );
+ }
+ return result;
}
- public static int countUnquoted(String string, char character) {
- return org.hibernate.util.StringHelper.countUnquoted( string, character );
+ private static String[] multiply(String[] strings, String placeholder, String[] replacements) {
+ String[] results = new String[replacements.length * strings.length];
+ int n = 0;
+ for ( int i = 0; i < replacements.length; i++ ) {
+ for ( int j = 0; j < strings.length; j++ ) {
+ results[n++] = replaceOnce( strings[j], placeholder, replacements[i] );
+ }
+ }
+ return results;
}
- public static int[] locateUnquoted(String string, char character) {
- return org.hibernate.util.StringHelper.locateUnquoted( string, character );
+ public static int countUnquoted(String string, char character) {
+ if ( '\'' == character ) {
+ throw new IllegalArgumentException( "Unquoted count of quotes is invalid" );
+ }
+ if (string == null)
+ return 0;
+ // Impl note: takes advantage of the fact that an escpaed single quote
+ // embedded within a quote-block can really be handled as two seperate
+ // quote-blocks for the purposes of this method...
+ int count = 0;
+ int stringLength = string.length();
+ boolean inQuote = false;
+ for ( int indx = 0; indx < stringLength; indx++ ) {
+ char c = string.charAt( indx );
+ if ( inQuote ) {
+ if ( '\'' == c ) {
+ inQuote = false;
+ }
+ }
+ else if ( '\'' == c ) {
+ inQuote = true;
+ }
+ else if ( c == character ) {
+ count++;
+ }
+ }
+ return count;
}
public static boolean isNotEmpty(String string) {
- return org.hibernate.util.StringHelper.isNotEmpty( string );
+ return string != null && string.length() > 0;
}
public static boolean isEmpty(String string) {
- return org.hibernate.util.StringHelper.isEmpty( string );
+ return string == null || string.length() == 0;
}
+ public static String qualify(String prefix, String name) {
+ if ( name == null || prefix == null ) {
+ throw new NullPointerException();
+ }
+ return new StringBuffer( prefix.length() + name.length() + 1 )
+ .append(prefix)
+ .append('.')
+ .append(name)
+ .toString();
+ }
+
+ public static String[] qualify(String prefix, String[] names) {
+ if ( prefix == null ) return names;
+ int len = names.length;
+ String[] qualified = new String[len];
+ for ( int i = 0; i < len; i++ ) {
+ qualified[i] = qualify( prefix, names[i] );
+ }
+ return qualified;
+ }
+
public static int firstIndexOfChar(String sqlString, String string, int startindex) {
- return org.hibernate.util.StringHelper.firstIndexOfChar( sqlString, string, startindex );
+ int matchAt = -1;
+ for ( int i = 0; i < string.length(); i++ ) {
+ int curMatch = sqlString.indexOf( string.charAt( i ), startindex );
+ if ( curMatch >= 0 ) {
+ if ( matchAt == -1 ) { // first time we find match!
+ matchAt = curMatch;
+ }
+ else {
+ matchAt = Math.min( matchAt, curMatch );
+ }
+ }
+ }
+ return matchAt;
}
public static String truncate(String string, int length) {
- return org.hibernate.util.StringHelper.truncate( string, length );
+ if ( string.length() <= length ) {
+ return string;
+ }
+ else {
+ return string.substring( 0, length );
+ }
}
public static String generateAlias(String description) {
- return org.hibernate.util.StringHelper.generateAlias( description );
+ return generateAliasRoot(description) + '_';
}
+ /**
+ * Generate a nice alias for the given class name or collection role name and unique integer. Subclasses of
+ * Loader do <em>not</em> have to use aliases of this form.
+ *
+ * @param description The base name (usually an entity-name or collection-role)
+ * @param unique A uniquing value
+ *
+ * @return an alias of the form <samp>foo1_</samp>
+ */
public static String generateAlias(String description, int unique) {
- return org.hibernate.util.StringHelper.generateAlias( description, unique );
+ return generateAliasRoot(description) +
+ Integer.toString(unique) +
+ '_';
}
+ /**
+ * Generates a root alias by truncating the "root name" defined by
+ * the incoming decription and removing/modifying any non-valid
+ * alias characters.
+ *
+ * @param description The root name from which to generate a root alias.
+ * @return The generated root alias.
+ */
+ private static String generateAliasRoot(String description) {
+ String result = truncate( unqualifyEntityName(description), ALIAS_TRUNCATE_LENGTH )
+ .toLowerCase()
+ .replace( '/', '_' ) // entityNames may now include slashes for the representations
+ .replace( '$', '_' ); //classname may be an inner class
+ result = cleanAlias( result );
+ if ( Character.isDigit( result.charAt(result.length()-1) ) ) {
+ return result + "x"; //ick!
+ }
+ else {
+ return result;
+ }
+ }
+
+ /**
+ * Clean the generated alias by removing any non-alpha characters from the
+ * beginning.
+ *
+ * @param alias The generated alias to be cleaned.
+ * @return The cleaned alias, stripped of any leading non-alpha characters.
+ */
+ private static String cleanAlias(String alias) {
+ char[] chars = alias.toCharArray();
+ // short cut check...
+ if ( !Character.isLetter( chars[0] ) ) {
+ for ( int i = 1; i < chars.length; i++ ) {
+ // as soon as we encounter our first letter, return the substring
+ // from that position
+ if ( Character.isLetter( chars[i] ) ) {
+ return alias.substring( i );
+ }
+ }
+ }
+ return alias;
+ }
+
public static String unqualifyEntityName(String entityName) {
- return org.hibernate.util.StringHelper.unqualifyEntityName( entityName );
+ String result = unqualify(entityName);
+ int slashPos = result.indexOf( '/' );
+ if ( slashPos > 0 ) {
+ result = result.substring( 0, slashPos - 1 );
+ }
+ return result;
}
public static String toUpperCase(String str) {
- return org.hibernate.util.StringHelper.toUpperCase( str );
+ return str==null ? null : str.toUpperCase();
}
public static String toLowerCase(String str) {
- return org.hibernate.util.StringHelper.toLowerCase( str );
+ return str==null ? null : str.toLowerCase();
}
public static String moveAndToBeginning(String filter) {
- return org.hibernate.util.StringHelper.moveAndToBeginning( filter );
+ if ( filter.trim().length()>0 ){
+ filter += " and ";
+ if ( filter.startsWith(" and ") ) filter = filter.substring(4);
+ }
+ return filter;
}
/**
- * Not a direct copy from {@link org.hibernate.util.StringHelper}, this is instead directly copied
- * from {@link org.hibernate.util.ArrayHelper}.
+ * Determine if the given string is quoted (wrapped by '`' characters at beginning and end).
*
- * @param coll the collection
- * @return The int array
- * @deprecated Use {@link org.hibernate.util.ArrayHelper#toIntArray} instead.
+ * @param name The name to check.
+ * @return True if the given string starts and ends with '`'; false otherwise.
*/
- public static int[] toIntArray(Collection coll) {
- return org.hibernate.util.ArrayHelper.toIntArray( coll );
- }
-
public static boolean isQuoted(String name) {
- return org.hibernate.util.StringHelper.isQuoted( name );
+ return name != null && name.length() != 0 && name.charAt( 0 ) == '`' && name.charAt( name.length() - 1 ) == '`';
}
+ /**
+ * Return a representation of the given name ensuring quoting (wrapped with '`' characters). If already wrapped
+ * return name.
+ *
+ * @param name The name to quote.
+ * @return The quoted version.
+ */
public static String quote(String name) {
- return org.hibernate.util.StringHelper.quote( name );
+ if ( name == null || name.length() == 0 || isQuoted( name ) ) {
+ return name;
+ }
+ else {
+ return new StringBuffer( name.length() + 2 ).append('`').append( name ).append( '`' ).toString();
+ }
}
+ /**
+ * Return the unquoted version of name (stripping the start and end '`' characters if present).
+ *
+ * @param name The name to be unquoted.
+ * @return The unquoted version.
+ */
public static String unquote(String name) {
- return org.hibernate.util.StringHelper.unquote( name );
+ if ( isQuoted( name ) ) {
+ return name.substring( 1, name.length() - 1 );
+ }
+ else {
+ return name;
+ }
}
}
\ No newline at end of file
15 years, 3 months
Hibernate SVN: r17306 - in search/trunk: src/main/java/org/hibernate/search/backend/impl and 7 other directories.
by hibernate-commits@lists.jboss.org
Author: sannegrinovero
Date: 2009-08-14 18:53:34 -0400 (Fri, 14 Aug 2009)
New Revision: 17306
Added:
search/trunk/src/main/java/org/hibernate/search/backend/impl/jgroups/
search/trunk/src/main/java/org/hibernate/search/backend/impl/jgroups/JGroupsBackendQueueProcessor.java
search/trunk/src/main/java/org/hibernate/search/backend/impl/jgroups/JGroupsBackendQueueProcessorFactory.java
search/trunk/src/main/java/org/hibernate/search/backend/impl/jgroups/JGroupsMasterMessageListener.java
search/trunk/src/main/java/org/hibernate/search/backend/impl/jgroups/MasterJGroupsBackendQueueProcessorFactory.java
search/trunk/src/main/java/org/hibernate/search/backend/impl/jgroups/SlaveJGroupsBackendQueueProcessorFactory.java
search/trunk/src/main/java/org/hibernate/search/util/XMLHelper.java
search/trunk/src/test/java/org/hibernate/search/test/jgroups/
search/trunk/src/test/java/org/hibernate/search/test/jgroups/common/
search/trunk/src/test/java/org/hibernate/search/test/jgroups/common/JGroupsCommonTest.java
search/trunk/src/test/java/org/hibernate/search/test/jgroups/common/MultipleSessionsSearchTestCase.java
search/trunk/src/test/java/org/hibernate/search/test/jgroups/master/
search/trunk/src/test/java/org/hibernate/search/test/jgroups/master/JGroupsMasterTest.java
search/trunk/src/test/java/org/hibernate/search/test/jgroups/master/TShirt.java
search/trunk/src/test/java/org/hibernate/search/test/jgroups/slave/
search/trunk/src/test/java/org/hibernate/search/test/jgroups/slave/JGroupsReceiver.java
search/trunk/src/test/java/org/hibernate/search/test/jgroups/slave/JGroupsSlaveTest.java
search/trunk/src/test/java/org/hibernate/search/test/jgroups/slave/TShirt.java
Modified:
search/trunk/pom.xml
search/trunk/src/main/java/org/hibernate/search/backend/impl/BatchedQueueingProcessor.java
search/trunk/src/test/java/org/hibernate/search/test/SearchTestCase.java
Log:
HSEARCH-392 committing the patch provided by ?\197?\129ukasz More?\197?\132; adding svn keywords substitution as only change.
Modified: search/trunk/pom.xml
===================================================================
--- search/trunk/pom.xml 2009-08-14 18:29:45 UTC (rev 17305)
+++ search/trunk/pom.xml 2009-08-14 22:53:34 UTC (rev 17306)
@@ -162,6 +162,24 @@
<name>build.dir</name>
<value>${basedir}/target</value>
</property>
+ <!--
+ Following is the default jgroups mcast address. If you find the testsuite runs very slowly,
+ there may be problems with multicast on the interface JGroups uses by default on
+ your machine. You can try to resolve setting 'jgroups.bind_addr' as a system-property
+ to the jvm launching maven and setting the value to an interface where you know multicast works
+ -->
+ <property>
+ <name>jgroups.bind_addr</name>
+ <value>127.0.0.1</value>
+ </property>
+ <!-- There are problems with multicast and IPv6 on some OS/JDK combos, so we tell Java
+ to use IPv4. If you have problems with multicast when running the tests you can
+ try setting this to 'false', although typically that won't be helpful.
+ -->
+ <property>
+ <name>java.net.preferIPv4Stack</name>
+ <value>true</value>
+ </property>
</systemProperties>
<excludes>
<exclude>**/*.java</exclude>
@@ -665,6 +683,12 @@
<optional>true</optional>
</dependency>
<dependency>
+ <groupId>jgroups</groupId>
+ <artifactId>jgroups</artifactId>
+ <version>2.6.7.GA</version>
+ <optional>true</optional>
+ </dependency>
+ <dependency>
<groupId>javax.annotation</groupId>
<artifactId>jsr250-api</artifactId>
<version>1.0</version>
Modified: search/trunk/src/main/java/org/hibernate/search/backend/impl/BatchedQueueingProcessor.java
===================================================================
--- search/trunk/src/main/java/org/hibernate/search/backend/impl/BatchedQueueingProcessor.java 2009-08-14 18:29:45 UTC (rev 17305)
+++ search/trunk/src/main/java/org/hibernate/search/backend/impl/BatchedQueueingProcessor.java 2009-08-14 22:53:34 UTC (rev 17306)
@@ -22,6 +22,8 @@
import org.hibernate.search.backend.WorkType;
import org.hibernate.search.backend.configuration.ConfigurationParseHelper;
import org.hibernate.search.backend.impl.blackhole.BlackHoleBackendQueueProcessorFactory;
+import org.hibernate.search.backend.impl.jgroups.MasterJGroupsBackendQueueProcessorFactory;
+import org.hibernate.search.backend.impl.jgroups.SlaveJGroupsBackendQueueProcessorFactory;
import org.hibernate.search.backend.impl.jms.JMSBackendQueueProcessorFactory;
import org.hibernate.search.backend.impl.lucene.LuceneBackendQueueProcessorFactory;
import org.hibernate.search.engine.DocumentBuilderIndexedEntity;
@@ -86,6 +88,12 @@
else if ( "blackhole".equalsIgnoreCase( backend ) ) {
backendQueueProcessorFactory = new BlackHoleBackendQueueProcessorFactory();
}
+ else if ( "jgroupsMaster".equals( backend ) ) {
+ backendQueueProcessorFactory = new MasterJGroupsBackendQueueProcessorFactory();
+ }
+ else if ( "jgroupsSlave".equals( backend ) ) {
+ backendQueueProcessorFactory = new SlaveJGroupsBackendQueueProcessorFactory();
+ }
else {
backendQueueProcessorFactory = PluginLoader.instanceFromName( BackendQueueProcessorFactory.class,
backend, BatchedQueueingProcessor.class, "processor" );
@@ -105,7 +113,6 @@
}
}
-
public void prepareWorks(WorkQueue workQueue) {
List<Work> queue = workQueue.getQueue();
int initialSize = queue.size();
Added: search/trunk/src/main/java/org/hibernate/search/backend/impl/jgroups/JGroupsBackendQueueProcessor.java
===================================================================
--- search/trunk/src/main/java/org/hibernate/search/backend/impl/jgroups/JGroupsBackendQueueProcessor.java (rev 0)
+++ search/trunk/src/main/java/org/hibernate/search/backend/impl/jgroups/JGroupsBackendQueueProcessor.java 2009-08-14 22:53:34 UTC (rev 17306)
@@ -0,0 +1,78 @@
+// $Id$
+package org.hibernate.search.backend.impl.jgroups;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.jgroups.ChannelClosedException;
+import org.jgroups.ChannelNotConnectedException;
+import org.jgroups.Message;
+import org.slf4j.Logger;
+
+import org.hibernate.search.SearchException;
+import org.hibernate.search.backend.LuceneWork;
+import org.hibernate.search.backend.OptimizeLuceneWork;
+import org.hibernate.search.util.LoggerFactory;
+
+/**
+ * Responsible for sending Lucene works from slave nodes to master node
+ *
+ * @author Lukasz Moren
+ */
+public class JGroupsBackendQueueProcessor implements Runnable {
+
+ protected static final Logger log = LoggerFactory.make();
+
+ private final JGroupsBackendQueueProcessorFactory factory;
+ private final List<LuceneWork> queue;
+
+ public JGroupsBackendQueueProcessor(List<LuceneWork> queue, JGroupsBackendQueueProcessorFactory factory) {
+ this.factory = factory;
+ this.queue = queue;
+ }
+
+ @SuppressWarnings("unchecked")
+ public void run() {
+ List<LuceneWork> filteredQueue = new ArrayList<LuceneWork>( queue );
+ log.trace( "Preparing {} Lucene works to be sent to master node.", filteredQueue.size() );
+
+ for ( LuceneWork work : queue ) {
+ if ( work instanceof OptimizeLuceneWork ) {
+ //we don't want optimization to be propagated
+ filteredQueue.remove( work );
+ }
+ }
+ log.trace(
+ "Filtering: optimized Lucene works are not going to be sent to master node. There is {} Lucene works after filtering.",
+ filteredQueue.size()
+ );
+ if ( filteredQueue.size() == 0 ) {
+ log.trace(
+ "Nothing to send. Propagating works to a cluster has been skipped."
+ );
+ return;
+ }
+
+ /* Creates and send message with lucene works to master.
+ * As long as message destination address is null, Lucene works will be received by all listeners that implements
+ * org.jgroups.MessageListener interface, multiple master nodes in cluster are allowed. */
+ try {
+ Message message = new Message( null, factory.getAddress(), ( Serializable ) filteredQueue );
+ factory.getChannel().send( message );
+ log.trace(
+ "Lucene works have been sent from slave {} to master node.", factory.getAddress()
+ );
+ }
+ catch ( ChannelNotConnectedException e ) {
+ throw new SearchException(
+ "Unable to send Lucene work. Channel is not connected to: "
+ + factory.getClusterName()
+ );
+ }
+ catch ( ChannelClosedException e ) {
+ throw new SearchException( "Unable to send Lucene work. Attempt to send message on closed JGroups channel" );
+ }
+
+ }
+}
Property changes on: search/trunk/src/main/java/org/hibernate/search/backend/impl/jgroups/JGroupsBackendQueueProcessor.java
___________________________________________________________________
Name: svn:keywords
+ Id
Added: search/trunk/src/main/java/org/hibernate/search/backend/impl/jgroups/JGroupsBackendQueueProcessorFactory.java
===================================================================
--- search/trunk/src/main/java/org/hibernate/search/backend/impl/jgroups/JGroupsBackendQueueProcessorFactory.java (rev 0)
+++ search/trunk/src/main/java/org/hibernate/search/backend/impl/jgroups/JGroupsBackendQueueProcessorFactory.java 2009-08-14 22:53:34 UTC (rev 17306)
@@ -0,0 +1,182 @@
+// $Id$
+package org.hibernate.search.backend.impl.jgroups;
+
+import java.net.URL;
+import java.util.List;
+import java.util.Properties;
+
+import org.jgroups.Address;
+import org.jgroups.Channel;
+import org.jgroups.ChannelException;
+import org.jgroups.JChannel;
+import org.slf4j.Logger;
+
+import org.hibernate.search.Environment;
+import org.hibernate.search.SearchException;
+import org.hibernate.search.backend.BackendQueueProcessorFactory;
+import org.hibernate.search.backend.LuceneWork;
+import org.hibernate.search.engine.SearchFactoryImplementor;
+import org.hibernate.search.util.LoggerFactory;
+import org.hibernate.search.util.XMLHelper;
+import org.hibernate.util.ConfigHelper;
+
+
+/**
+ * Common base class for Master and Slave BackendQueueProcessorFactories
+ *
+ * @author Lukasz Moren
+ */
+public abstract class JGroupsBackendQueueProcessorFactory implements BackendQueueProcessorFactory {
+
+ protected static final Logger log = LoggerFactory.make();
+
+ public static final String JGROUPS_PREFIX = Environment.WORKER_BACKEND + ".jgroups.";
+
+ public static final String CONFIGURATION_STRING = JGROUPS_PREFIX + "configurationString";
+ public static final String CONFIGURATION_XML = JGROUPS_PREFIX + "configurationXml";
+ public static final String CONFIGURATION_FILE = JGROUPS_PREFIX + "configurationFile";
+ private static final String DEFAULT_JGROUPS_CONFIGURATION_FILE = "flush-udp.xml";
+
+ public static final String JG_CLUSTER_NAME = JGROUPS_PREFIX + "clusterName";
+
+ protected String clusterName = "HSearchCluster";
+ protected SearchFactoryImplementor searchFactory;
+ protected Channel channel = null;
+ protected Address address;
+
+ public void initialize(Properties props, SearchFactoryImplementor searchFactory) {
+ this.searchFactory = searchFactory;
+
+ if ( props.containsKey( JG_CLUSTER_NAME ) ) {
+ setClusterName( props.getProperty( JG_CLUSTER_NAME ) );
+ }
+
+ prepareJGroupsChannel( props );
+ }
+
+ private void prepareJGroupsChannel(Properties props) {
+ log.info( "Starting JGroups Channel" );
+ try {
+ buildChannel( props );
+ channel.setOpt( Channel.AUTO_RECONNECT, Boolean.TRUE );
+ channel.connect( clusterName );
+ }
+ catch ( ChannelException e ) {
+ throw new SearchException( "Unable to connect to: [" + clusterName + "] JGroups channel" );
+ }
+ log.info( "Connected to cluster [ {} ]. The node address is {}", clusterName, getAddress() );
+
+ if ( !channel.flushSupported() ) {
+ log.warn(
+ "FLUSH is not present in your JGroups stack! FLUSH is needed to ensure messages are not dropped while new nodes join the cluster. Will proceed, but inconsistencies may arise!"
+ );
+ }
+ }
+
+ /**
+ * Reads congiguration and builds channnel with its base.
+ * In order of preference - we first look for an external JGroups file, then a set of XML properties, and
+ * finally the legacy JGroups String properties.
+ *
+ * @param props configuratuion file
+ */
+ private void buildChannel(Properties props) {
+ String cfg;
+ if ( props != null ) {
+ if ( props.containsKey( CONFIGURATION_FILE ) ) {
+ cfg = props.getProperty( CONFIGURATION_FILE );
+ try {
+ channel = new JChannel( ConfigHelper.locateConfig( cfg ) );
+ }
+ catch ( Exception e ) {
+ log.error( "Error while trying to create a channel using config files: {}", cfg );
+ throw new SearchException( e );
+ }
+ }
+
+ if ( props.containsKey( CONFIGURATION_XML ) ) {
+ cfg = props.getProperty( CONFIGURATION_XML );
+ try {
+ channel = new JChannel( XMLHelper.elementFromString( cfg ) );
+ }
+ catch ( Exception e ) {
+ log.error( "Error while trying to create a channel using config XML: {}", cfg );
+ throw new SearchException( e );
+ }
+ }
+
+ if ( props.containsKey( CONFIGURATION_STRING ) ) {
+ cfg = props.getProperty( CONFIGURATION_STRING );
+ try {
+ channel = new JChannel( cfg );
+ }
+ catch ( Exception e ) {
+ log.error( "Error while trying to create a channel using config string: {}", cfg );
+ throw new SearchException( e );
+ }
+ }
+ }
+
+ if ( channel == null ) {
+ log.info(
+ "Unable to use any JGroups configuration mechanisms provided in properties {}. Using default JGroups configuration file!",
+ props
+ );
+ try {
+ URL fileUrl = ConfigHelper.locateConfig( DEFAULT_JGROUPS_CONFIGURATION_FILE );
+ if ( fileUrl != null ) {
+ channel = new JChannel( fileUrl );
+ }
+ else {
+ log.warn(
+ "Default JGroups configuration file was not found. Attempt to start JGroups channel with default configuration!"
+ );
+ channel = new JChannel();
+ }
+ }
+ catch ( ChannelException e ) {
+ throw new SearchException( "Unable to start JGroups channel", e );
+ }
+ }
+ }
+
+ public abstract Runnable getProcessor(List<LuceneWork> queue);
+
+ public void close() {
+ try {
+ if ( channel != null && channel.isOpen() ) {
+ log.info( "Disconnecting and closing JGroups Channel" );
+ channel.disconnect();
+ channel.close();
+ }
+ }
+ catch ( Exception toLog ) {
+ log.error( "Problem closing channel; setting it to null", toLog );
+ channel = null;
+ }
+ }
+
+ public Channel getChannel() {
+ return channel;
+ }
+
+ public void setClusterName(String clusterName) {
+ this.clusterName = clusterName;
+ }
+
+ public String getClusterName() {
+ return clusterName;
+ }
+
+ /**
+ * Cluster's node address
+ *
+ * @return Address
+ */
+ public Address getAddress() {
+ if ( address == null && channel != null ) {
+ address = channel.getLocalAddress();
+ }
+ return address;
+ }
+}
Property changes on: search/trunk/src/main/java/org/hibernate/search/backend/impl/jgroups/JGroupsBackendQueueProcessorFactory.java
___________________________________________________________________
Name: svn:keywords
+ Id
Added: search/trunk/src/main/java/org/hibernate/search/backend/impl/jgroups/JGroupsMasterMessageListener.java
===================================================================
--- search/trunk/src/main/java/org/hibernate/search/backend/impl/jgroups/JGroupsMasterMessageListener.java (rev 0)
+++ search/trunk/src/main/java/org/hibernate/search/backend/impl/jgroups/JGroupsMasterMessageListener.java 2009-08-14 22:53:34 UTC (rev 17306)
@@ -0,0 +1,88 @@
+// $Id$
+package org.hibernate.search.backend.impl.jgroups;
+
+import java.util.List;
+
+import org.jgroups.Address;
+import org.jgroups.Message;
+import org.jgroups.Receiver;
+import org.jgroups.View;
+import org.slf4j.Logger;
+
+import org.hibernate.search.backend.LuceneWork;
+import org.hibernate.search.engine.SearchFactoryImplementor;
+import org.hibernate.search.util.LoggerFactory;
+
+/**
+ * Listen for messages from slave nodes and apply them into <code>LuceneBackendQueueProcessor</code>
+ *
+ * @author Lukasz Moren
+ * @see org.hibernate.search.backend.impl.lucene.LuceneBackendQueueProcessorFactory
+ * @see org.hibernate.search.backend.impl.lucene.LuceneBackendQueueProcessor
+ * @see org.jgroups.Receiver
+ */
+public class JGroupsMasterMessageListener implements Receiver {
+
+ private static final Logger log = LoggerFactory.make();
+
+ private SearchFactoryImplementor searchFactory;
+
+ public JGroupsMasterMessageListener(SearchFactoryImplementor searchFactory) {
+ this.searchFactory = searchFactory;
+ }
+
+ @SuppressWarnings("unchecked")
+ public void receive(Message message) {
+ List<LuceneWork> queue;
+ try {
+ queue = ( List<LuceneWork> ) message.getObject();
+ }
+ catch ( ClassCastException e ) {
+ log.error( "Illegal object retrieved from message.", e );
+ return;
+ }
+
+ if ( queue != null && !queue.isEmpty() ) {
+ log.debug(
+ "There are {} Lucene docs received from slave node {} to be processed by master",
+ queue.size(),
+ message.getSrc()
+ );
+ Runnable worker = getWorker( queue );
+ worker.run();
+ }
+ else {
+ log.warn( "Received null or empty Lucene works list in message." );
+ }
+ }
+
+ private Runnable getWorker(List<LuceneWork> queue) {
+ Runnable processor;
+ processor = searchFactory.getBackendQueueProcessorFactory().getProcessor( queue );
+ return processor;
+ }
+
+ // ------------------------------------------------------------------------------------------------------------------
+ // Implementations of JGroups interfaces
+ // ------------------------------------------------------------------------------------------------------------------
+
+ public byte[] getState() {
+ return null;
+ }
+
+ public void setState(byte[] state) {
+ //no-op
+ }
+
+ public void viewAccepted(View view) {
+ log.info( "Received new cluster view: {}", view );
+ }
+
+ public void suspect(Address suspected_mbr) {
+ //no-op
+ }
+
+ public void block() {
+ //no-op
+ }
+}
Property changes on: search/trunk/src/main/java/org/hibernate/search/backend/impl/jgroups/JGroupsMasterMessageListener.java
___________________________________________________________________
Name: svn:keywords
+ Id
Added: search/trunk/src/main/java/org/hibernate/search/backend/impl/jgroups/MasterJGroupsBackendQueueProcessorFactory.java
===================================================================
--- search/trunk/src/main/java/org/hibernate/search/backend/impl/jgroups/MasterJGroupsBackendQueueProcessorFactory.java (rev 0)
+++ search/trunk/src/main/java/org/hibernate/search/backend/impl/jgroups/MasterJGroupsBackendQueueProcessorFactory.java 2009-08-14 22:53:34 UTC (rev 17306)
@@ -0,0 +1,59 @@
+// $Id$
+package org.hibernate.search.backend.impl.jgroups;
+
+import java.util.List;
+import java.util.Properties;
+
+import org.jgroups.Receiver;
+
+import org.hibernate.search.backend.LuceneWork;
+import org.hibernate.search.backend.impl.lucene.LuceneBackendQueueProcessorFactory;
+import org.hibernate.search.engine.SearchFactoryImplementor;
+
+/**
+ * Backend factory used in JGroups clustering mode in master node.
+ * Wraps {@link LuceneBackendQueueProcessorFactory} with providing extra
+ * functionality to receive Lucene works from slave nodes.
+ *
+ * @author Lukasz Moren
+ * @see org.hibernate.search.backend.impl.lucene.LuceneBackendQueueProcessorFactory
+ * @see org.hibernate.search.backend.impl.jgroups.SlaveJGroupsBackendQueueProcessorFactory
+ */
+public class MasterJGroupsBackendQueueProcessorFactory extends JGroupsBackendQueueProcessorFactory {
+
+ private LuceneBackendQueueProcessorFactory luceneBackendQueueProcessorFactory;
+ private Receiver masterListener;
+
+ @Override
+ public void initialize(Properties props, SearchFactoryImplementor searchFactory) {
+ super.initialize( props, searchFactory );
+ initLuceneBackendQueueProcessorFactory( props, searchFactory );
+
+ registerMasterListener();
+ }
+
+ public Runnable getProcessor(List<LuceneWork> queue) {
+ return luceneBackendQueueProcessorFactory.getProcessor( queue );
+ }
+
+ private void registerMasterListener() {
+ //register JGroups receiver in master node to get Lucene docs from slave nodes
+ masterListener = new JGroupsMasterMessageListener( searchFactory );
+ channel.setReceiver( masterListener );
+ }
+
+ private void initLuceneBackendQueueProcessorFactory(Properties props, SearchFactoryImplementor searchFactory) {
+ luceneBackendQueueProcessorFactory = new LuceneBackendQueueProcessorFactory();
+ luceneBackendQueueProcessorFactory.initialize( props, searchFactory );
+ }
+
+ public Receiver getMasterListener() {
+ return masterListener;
+ }
+
+ @Override
+ public void close() {
+ super.close();
+ luceneBackendQueueProcessorFactory.close();
+ }
+}
Property changes on: search/trunk/src/main/java/org/hibernate/search/backend/impl/jgroups/MasterJGroupsBackendQueueProcessorFactory.java
___________________________________________________________________
Name: svn:keywords
+ Id
Added: search/trunk/src/main/java/org/hibernate/search/backend/impl/jgroups/SlaveJGroupsBackendQueueProcessorFactory.java
===================================================================
--- search/trunk/src/main/java/org/hibernate/search/backend/impl/jgroups/SlaveJGroupsBackendQueueProcessorFactory.java (rev 0)
+++ search/trunk/src/main/java/org/hibernate/search/backend/impl/jgroups/SlaveJGroupsBackendQueueProcessorFactory.java 2009-08-14 22:53:34 UTC (rev 17306)
@@ -0,0 +1,16 @@
+// $Id$
+package org.hibernate.search.backend.impl.jgroups;
+
+import java.util.List;
+
+import org.hibernate.search.backend.LuceneWork;
+
+/**
+ * @author Lukasz Moren
+ */
+public class SlaveJGroupsBackendQueueProcessorFactory extends JGroupsBackendQueueProcessorFactory {
+
+ public Runnable getProcessor(List<LuceneWork> queue) {
+ return new JGroupsBackendQueueProcessor( queue, this );
+ }
+}
Property changes on: search/trunk/src/main/java/org/hibernate/search/backend/impl/jgroups/SlaveJGroupsBackendQueueProcessorFactory.java
___________________________________________________________________
Name: svn:keywords
+ Id
Added: search/trunk/src/main/java/org/hibernate/search/util/XMLHelper.java
===================================================================
--- search/trunk/src/main/java/org/hibernate/search/util/XMLHelper.java (rev 0)
+++ search/trunk/src/main/java/org/hibernate/search/util/XMLHelper.java 2009-08-14 22:53:34 UTC (rev 17306)
@@ -0,0 +1,35 @@
+package org.hibernate.search.util;
+
+import java.io.ByteArrayInputStream;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+/**
+ * A utility class to help with xml parsing
+ *
+ * @author Lukasz Moren
+ */
+public class XMLHelper {
+
+
+ /**
+ * Converts a String representing an XML snippet into an {@link org.w3c.dom.Element}.
+ *
+ * @param xml snippet as a string
+ *
+ * @return a DOM Element
+ *
+ * @throws Exception if unable to parse the String or if it doesn't contain valid XML.
+ */
+ public static Element elementFromString(String xml) throws Exception {
+ ByteArrayInputStream bais = new ByteArrayInputStream( xml.getBytes( "UTF-8" ) );
+ DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+ DocumentBuilder builder = factory.newDocumentBuilder();
+ Document document = builder.parse( bais );
+ bais.close();
+ return document.getDocumentElement();
+ }
+}
Property changes on: search/trunk/src/main/java/org/hibernate/search/util/XMLHelper.java
___________________________________________________________________
Name: svn:keywords
+ Id
Modified: search/trunk/src/test/java/org/hibernate/search/test/SearchTestCase.java
===================================================================
--- search/trunk/src/test/java/org/hibernate/search/test/SearchTestCase.java 2009-08-14 18:29:45 UTC (rev 17305)
+++ search/trunk/src/test/java/org/hibernate/search/test/SearchTestCase.java 2009-08-14 22:53:34 UTC (rev 17306)
@@ -153,4 +153,8 @@
protected String[] getAnnotatedPackages() {
return new String[] { };
}
+
+ protected static File getIndexDir() {
+ return indexDir;
+ }
}
Added: search/trunk/src/test/java/org/hibernate/search/test/jgroups/common/JGroupsCommonTest.java
===================================================================
--- search/trunk/src/test/java/org/hibernate/search/test/jgroups/common/JGroupsCommonTest.java (rev 0)
+++ search/trunk/src/test/java/org/hibernate/search/test/jgroups/common/JGroupsCommonTest.java 2009-08-14 22:53:34 UTC (rev 17306)
@@ -0,0 +1,129 @@
+// $Id$
+package org.hibernate.search.test.jgroups.common;
+
+import java.util.List;
+
+import org.apache.lucene.analysis.StopAnalyzer;
+import org.apache.lucene.queryParser.QueryParser;
+import org.apache.lucene.search.Query;
+
+import org.hibernate.HibernateException;
+import org.hibernate.Session;
+import org.hibernate.Transaction;
+import org.hibernate.cfg.Configuration;
+import org.hibernate.search.Environment;
+import org.hibernate.search.FullTextSession;
+import org.hibernate.search.Search;
+import org.hibernate.search.backend.impl.jgroups.JGroupsBackendQueueProcessorFactory;
+import org.hibernate.search.test.jgroups.master.TShirt;
+
+/**
+ * In case of running test outside Hibernate Search Maven configuration set following VM configuration:
+ * <br><br>
+ * <code>
+ * -Djava.net.preferIPv4Stack=true -Djgroups.bind_addr=127.0.0.1
+ * </code>
+ * @author Lukasz Moren
+ */
+
+public class JGroupsCommonTest extends MultipleSessionsSearchTestCase {
+
+ public static final String CHANNEL_NAME = "jgroups_test_channel";
+ private static final String DEFAULT_JGROUPS_CONFIGURATION_FILE = "flush-udp.xml";
+
+ public void testJGroupsBackend() throws Exception {
+
+ //get slave session
+ Session s = getSlaveSession();
+ Transaction tx = s.beginTransaction();
+ TShirt ts = new TShirt();
+ ts.setLogo( "Boston" );
+ ts.setSize( "XXL" );
+ TShirt ts2 = new TShirt();
+ ts2.setLogo( "Mapple leaves" );
+ ts2.setSize( "L" );
+ s.persist( ts );
+ s.persist( ts2 );
+ tx.commit();
+
+ Thread.sleep( 3000 );
+
+ FullTextSession ftSess = Search.getFullTextSession( openSession() );
+ ftSess.getTransaction().begin();
+ QueryParser parser = new QueryParser( "id", new StopAnalyzer() );
+ Query luceneQuery = parser.parse( "logo:Boston or logo:Mapple leaves" );
+ org.hibernate.Query query = ftSess.createFullTextQuery( luceneQuery );
+ List result = query.list();
+
+ assertEquals( 2, result.size() );
+
+ s = getSlaveSession();
+ tx = s.beginTransaction();
+ ts = ( TShirt ) s.get( TShirt.class, ts.getId() );
+ ts.setLogo( "Peter pan" );
+ tx.commit();
+
+ //need to sleep for the message consumption
+ Thread.sleep( 3000 );
+
+ parser = new QueryParser( "id", new StopAnalyzer() );
+ luceneQuery = parser.parse( "logo:Peter pan" );
+ query = ftSess.createFullTextQuery( luceneQuery );
+ result = query.list();
+ assertEquals( 1, result.size() );
+
+ s = getSlaveSession();
+ tx = s.beginTransaction();
+ s.delete( s.get( TShirt.class, ts.getId() ) );
+ s.delete( s.get( TShirt.class, ts2.getId() ) );
+ tx.commit();
+
+ //Need to sleep for the message consumption
+ Thread.sleep( 3000 );
+
+ parser = new QueryParser( "id", new StopAnalyzer() );
+ luceneQuery = parser.parse( "logo:Boston or logo:Mapple leaves" );
+ query = ftSess.createFullTextQuery( luceneQuery );
+ result = query.list();
+ assertEquals( 0, result.size() );
+
+ ftSess.close();
+ s.close();
+
+ }
+
+ @Override
+ protected void configure(Configuration cfg) {
+ //master jgroups configuration
+ super.configure( cfg );
+ cfg.setProperty( Environment.WORKER_BACKEND, "jgroupsMaster" );
+ cfg.setProperty( JGroupsBackendQueueProcessorFactory.CONFIGURATION_FILE, DEFAULT_JGROUPS_CONFIGURATION_FILE );
+ }
+
+ @Override
+ protected void commonConfigure(Configuration cfg) {
+ //slave jgroups configuration
+ super.commonConfigure( cfg );
+ cfg.setProperty( Environment.WORKER_BACKEND, "jgroupsSlave" );
+ cfg.setProperty( JGroupsBackendQueueProcessorFactory.CONFIGURATION_FILE, DEFAULT_JGROUPS_CONFIGURATION_FILE );
+ }
+
+ public static Session getSession() throws HibernateException {
+ return sessions.openSession();
+ }
+
+ @Override
+ protected Class<?>[] getMappings() {
+ return new Class[] {
+ TShirt.class
+ };
+ }
+
+ protected Class<?>[] getCommonMappings() {
+ return new Class[] {
+ TShirt.class
+ };
+ }
+
+
+}
Property changes on: search/trunk/src/test/java/org/hibernate/search/test/jgroups/common/JGroupsCommonTest.java
___________________________________________________________________
Name: svn:keywords
+ Id
Added: search/trunk/src/test/java/org/hibernate/search/test/jgroups/common/MultipleSessionsSearchTestCase.java
===================================================================
--- search/trunk/src/test/java/org/hibernate/search/test/jgroups/common/MultipleSessionsSearchTestCase.java (rev 0)
+++ search/trunk/src/test/java/org/hibernate/search/test/jgroups/common/MultipleSessionsSearchTestCase.java 2009-08-14 22:53:34 UTC (rev 17306)
@@ -0,0 +1,151 @@
+// $Id$
+package org.hibernate.search.test.jgroups.common;
+
+import java.io.InputStream;
+
+import org.slf4j.Logger;
+
+import org.hibernate.SessionFactory;
+import org.hibernate.cfg.AnnotationConfiguration;
+import org.hibernate.cfg.Configuration;
+import org.hibernate.classic.Session;
+import org.hibernate.dialect.Dialect;
+import org.hibernate.search.test.SearchTestCase;
+import org.hibernate.search.util.FileHelper;
+
+/**
+ * Test class to simulate clustered environment (one master, and one slave node)
+ *
+ * @author Lukasz Moren
+ */
+public abstract class MultipleSessionsSearchTestCase extends SearchTestCase {
+
+ private static final Logger log = org.hibernate.search.util.LoggerFactory.make();
+
+ private String masterCopy = "/master/copy";
+
+ /**
+ * The lucene index directory which is specific to the master node.
+ */
+ private String masterMain = "/master/main";
+
+ /**
+ * The lucene index directory which is specific to the slave node.
+ */
+ private String slave = "/slave";
+
+
+ protected static SessionFactory slaveSessionFactory;
+
+ /**
+ * Common configuration for all slave nodes
+ */
+ private Configuration commonCfg;
+
+ @Override
+ protected void configure(Configuration cfg) {
+ super.configure( cfg );
+
+ //master
+ cfg.setProperty( "hibernate.search.default.sourceBase", getIndexDir().getAbsolutePath() + masterCopy );
+ cfg.setProperty( "hibernate.search.default.indexBase", getIndexDir().getAbsolutePath() + masterMain );
+ cfg.setProperty( "hibernate.search.default.refresh", "1" );
+ cfg.setProperty(
+ "hibernate.search.default.directory_provider", "org.hibernate.search.store.FSMasterDirectoryProvider"
+ );
+ }
+
+ protected void commonConfigure(Configuration cfg) {
+ super.configure( cfg );
+
+ //slave(s)
+ cfg.setProperty( "hibernate.search.default.sourceBase", getIndexDir().getAbsolutePath() + masterCopy );
+ cfg.setProperty( "hibernate.search.default.indexBase", getIndexDir().getAbsolutePath() + slave );
+ cfg.setProperty( "hibernate.search.default.refresh", "1" );
+ cfg.setProperty(
+ "hibernate.search.default.directory_provider", "org.hibernate.search.store.FSSlaveDirectoryProvider"
+ );
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ if ( getIndexDir().exists() ) {
+ FileHelper.delete( getIndexDir() );
+ }
+ super.setUp();
+ buildCommonSessionFactory( getCommonMappings(), getCommonAnnotatedPackages(), getCommonXmlFiles() );
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ super.tearDown();
+
+ //close session factories and clean index files
+ if ( slaveSessionFactory != null ) {
+ slaveSessionFactory.close();
+ }
+ if ( getSessions() != null ) {
+ getSessions().close();
+ }
+ log.info( "Deleting test directory {} ", getIndexDir().getAbsolutePath() );
+ FileHelper.delete( getIndexDir() );
+ }
+
+ private void buildCommonSessionFactory(Class<?>[] classes, String[] packages, String[] xmlFiles) throws Exception {
+ try {
+ if ( getSlaveSessionFactory() != null ) {
+ getSlaveSessionFactory().close();
+ }
+
+ setCommonCfg( new AnnotationConfiguration() );
+ commonConfigure( commonCfg );
+ if ( recreateSchema() ) {
+ commonCfg.setProperty( org.hibernate.cfg.Environment.HBM2DDL_AUTO, "create-drop" );
+ }
+ for ( String aPackage : packages ) {
+ ( ( AnnotationConfiguration ) getCommonConfiguration() ).addPackage( aPackage );
+ }
+ for ( Class<?> aClass : classes ) {
+ ( ( AnnotationConfiguration ) getCommonConfiguration() ).addAnnotatedClass( aClass );
+ }
+ for ( String xmlFile : xmlFiles ) {
+ InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream( xmlFile );
+ getCommonConfiguration().addInputStream( is );
+ }
+ setDialect( Dialect.getDialect() );
+ slaveSessionFactory = getCommonConfiguration().buildSessionFactory();
+ }
+ catch ( Exception e ) {
+ e.printStackTrace();
+ throw e;
+ }
+ }
+
+ private void setCommonCfg(Configuration configuration) {
+ this.commonCfg = configuration;
+ }
+
+ protected Configuration getCommonConfiguration() {
+ return commonCfg;
+ }
+
+ protected Session getSlaveSession() {
+ return slaveSessionFactory.openSession();
+ }
+
+ protected static SessionFactory getSlaveSessionFactory() {
+ return slaveSessionFactory;
+ }
+
+ private String[] getCommonAnnotatedPackages() {
+ return new String[] { };
+ }
+
+ private String[] getCommonXmlFiles() {
+ return new String[] { };
+ }
+
+ protected abstract Class<?>[] getMappings();
+
+ protected abstract Class<?>[] getCommonMappings();
+}
Property changes on: search/trunk/src/test/java/org/hibernate/search/test/jgroups/common/MultipleSessionsSearchTestCase.java
___________________________________________________________________
Name: svn:keywords
+ Id
Added: search/trunk/src/test/java/org/hibernate/search/test/jgroups/master/JGroupsMasterTest.java
===================================================================
--- search/trunk/src/test/java/org/hibernate/search/test/jgroups/master/JGroupsMasterTest.java (rev 0)
+++ search/trunk/src/test/java/org/hibernate/search/test/jgroups/master/JGroupsMasterTest.java 2009-08-14 22:53:34 UTC (rev 17306)
@@ -0,0 +1,171 @@
+// $Id$
+package org.hibernate.search.test.jgroups.master;
+
+import java.io.Serializable;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.lucene.analysis.StopAnalyzer;
+import org.apache.lucene.document.Document;
+import org.apache.lucene.document.Field;
+import org.apache.lucene.queryParser.QueryParser;
+import org.apache.lucene.search.Query;
+import org.jgroups.JChannel;
+import org.jgroups.Message;
+
+import org.hibernate.HibernateException;
+import org.hibernate.Session;
+import org.hibernate.cfg.Configuration;
+import org.hibernate.search.Environment;
+import org.hibernate.search.FullTextSession;
+import org.hibernate.search.Search;
+import org.hibernate.search.backend.AddLuceneWork;
+import org.hibernate.search.backend.LuceneWork;
+import org.hibernate.search.backend.impl.jgroups.JGroupsBackendQueueProcessorFactory;
+import org.hibernate.search.engine.DocumentBuilder;
+import org.hibernate.search.test.SearchTestCase;
+import org.hibernate.search.test.jms.master.TShirt;
+
+/**
+ * Tests that the Master node in a JGroups cluster can properly process messages received from channel.
+ * <p/>
+ * In case of running test outside Hibernate Search Maven configuration set following VM configuration:
+ * <br><br>
+ * <code>
+ * -Djava.net.preferIPv4Stack=true -Djgroups.bind_addr=127.0.0.1
+ * </code>
+ *
+ * @author Lukasz Moren
+ */
+public class JGroupsMasterTest extends SearchTestCase {
+
+ /**
+ * Name of the JGroups channel used in test
+ */
+ public static final String CHANNEL_NAME = "jgroups_test_channel";
+
+ private JChannel channel;
+
+ public void testMessageSending() throws Exception {
+
+ TShirt shirt = createObjectWithSQL();
+ List<LuceneWork> queue = createDocumentAndWorkQueue( shirt );
+
+ sendMessage( queue );
+
+ Thread.sleep( 3000 );
+
+ FullTextSession ftSess = Search.getFullTextSession( openSession() );
+ ftSess.getTransaction().begin();
+ QueryParser parser = new QueryParser( "id", new StopAnalyzer() );
+ Query luceneQuery = parser.parse( "logo:jboss" );
+ org.hibernate.Query query = ftSess.createFullTextQuery( luceneQuery );
+ List result = query.list();
+ assertEquals( 1, result.size() );
+ ftSess.delete( result.get( 0 ) );
+ ftSess.getTransaction().commit();
+ ftSess.close();
+ }
+
+ private void prepareJGroupsChannel() throws Exception {
+ channel = new JChannel( prepareJGroupsCongigurationString() );
+ channel.connect( CHANNEL_NAME );
+ }
+
+ private void sendMessage(List<LuceneWork> queue) throws Exception {
+ //send message to all listeners
+ Message message = new Message( null, null, ( Serializable ) queue );
+ channel.send( message );
+ }
+
+ /**
+ * Manually create the work queue. This lists gets send by the Slaves to the Master for indexing.
+ *
+ * @param shirt The shirt to index
+ *
+ * @return A manually create <code>LuceneWork</code> list.
+ */
+ private List<LuceneWork> createDocumentAndWorkQueue(TShirt shirt) {
+ Document doc = new Document();
+ Field field = new Field(
+ DocumentBuilder.CLASS_FIELDNAME, shirt.getClass().getName(), Field.Store.YES, Field.Index.NOT_ANALYZED
+ );
+ doc.add( field );
+ field = new Field( "id", "1", Field.Store.YES, Field.Index.NOT_ANALYZED );
+ doc.add( field );
+ field = new Field( "logo", shirt.getLogo(), Field.Store.NO, Field.Index.ANALYZED );
+ doc.add( field );
+ LuceneWork luceneWork = new AddLuceneWork(
+ shirt.getId(), String.valueOf( shirt.getId() ), shirt.getClass(), doc
+ );
+ List<LuceneWork> queue = new ArrayList<LuceneWork>();
+ queue.add( luceneWork );
+ return queue;
+ }
+
+ /**
+ * Create a test object without trigggering indexing. Use SQL directly.
+ *
+ * @return a <code>TShirt</code> test object.
+ *
+ * @throws java.sql.SQLException in case the inset fails.
+ */
+ @SuppressWarnings({ "deprecation" })
+ private TShirt createObjectWithSQL() throws SQLException {
+ Session s = openSession();
+ s.getTransaction().begin();
+ Statement statement = s.connection().createStatement();
+ statement.executeUpdate(
+ "insert into TShirt_Master(id, logo, size) values( '1', 'JBoss balls', 'large')"
+ );
+ statement.close();
+ TShirt ts = ( TShirt ) s.get( TShirt.class, 1 );
+ s.getTransaction().commit();
+ s.close();
+ return ts;
+ }
+
+ public static Session getSession() throws HibernateException {
+ return sessions.openSession();
+ }
+
+ protected void setUp() throws Exception {
+ prepareJGroupsChannel();
+ super.setUp();
+ }
+
+ protected void tearDown() throws Exception {
+ channel.close();
+ super.tearDown();
+ }
+
+ protected void configure(Configuration cfg) {
+ super.configure( cfg );
+ // JGroups configuration for master node
+ cfg.setProperty( Environment.WORKER_BACKEND, "jgroupsMaster" );
+ cfg.setProperty( JGroupsBackendQueueProcessorFactory.JG_CLUSTER_NAME, CHANNEL_NAME );
+ cfg.setProperty(
+ JGroupsBackendQueueProcessorFactory.CONFIGURATION_STRING, prepareJGroupsCongigurationString()
+ );
+ }
+
+ private String prepareJGroupsCongigurationString() {
+ return "UDP(mcast_addr=228.1.2.3;mcast_port=45566;ip_ttl=32):" +
+ "PING(timeout=3000;num_initial_members=6):" +
+ "FD(timeout=5000):" +
+ "VERIFY_SUSPECT(timeout=1500):" +
+ "pbcast.NAKACK(gc_lag=10;retransmit_timeout=3000):" +
+ "UNICAST(timeout=5000):" +
+ "FRAG:" +
+ "pbcast.GMS(join_timeout=3000;" +
+ "shun=false;print_local_addr=true)";
+ }
+
+ protected Class[] getMappings() {
+ return new Class[] {
+ TShirt.class
+ };
+ }
+}
\ No newline at end of file
Property changes on: search/trunk/src/test/java/org/hibernate/search/test/jgroups/master/JGroupsMasterTest.java
___________________________________________________________________
Name: svn:keywords
+ Id
Added: search/trunk/src/test/java/org/hibernate/search/test/jgroups/master/TShirt.java
===================================================================
--- search/trunk/src/test/java/org/hibernate/search/test/jgroups/master/TShirt.java (rev 0)
+++ search/trunk/src/test/java/org/hibernate/search/test/jgroups/master/TShirt.java 2009-08-14 22:53:34 UTC (rev 17306)
@@ -0,0 +1,50 @@
+//$Id$
+package org.hibernate.search.test.jgroups.master;
+
+import org.hibernate.search.annotations.DocumentId;
+import org.hibernate.search.annotations.Field;
+import org.hibernate.search.annotations.Index;
+import org.hibernate.search.annotations.Indexed;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+
+/**
+ * @author Emmanuel Bernard
+ */
+@Entity
+@Indexed
+public class TShirt {
+ @Id
+ @GeneratedValue
+ @DocumentId
+ private int id;
+ @Field(index= Index.TOKENIZED)
+ private String logo;
+ private String size;
+
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ public String getLogo() {
+ return logo;
+ }
+
+ public void setLogo(String logo) {
+ this.logo = logo;
+ }
+
+ public String getSize() {
+ return size;
+ }
+
+ public void setSize(String size) {
+ this.size = size;
+ }
+}
\ No newline at end of file
Property changes on: search/trunk/src/test/java/org/hibernate/search/test/jgroups/master/TShirt.java
___________________________________________________________________
Name: svn:keywords
+ Id
Added: search/trunk/src/test/java/org/hibernate/search/test/jgroups/slave/JGroupsReceiver.java
===================================================================
--- search/trunk/src/test/java/org/hibernate/search/test/jgroups/slave/JGroupsReceiver.java (rev 0)
+++ search/trunk/src/test/java/org/hibernate/search/test/jgroups/slave/JGroupsReceiver.java 2009-08-14 22:53:34 UTC (rev 17306)
@@ -0,0 +1,40 @@
+// $Id$
+package org.hibernate.search.test.jgroups.slave;
+
+import java.util.List;
+
+import org.jgroups.Message;
+import org.jgroups.ReceiverAdapter;
+
+import org.hibernate.search.backend.LuceneWork;
+
+/**
+ * @author Lukasz Moren
+ */
+
+public class JGroupsReceiver extends ReceiverAdapter {
+
+ public static int queues;
+ public static int works;
+
+ public static void reset() {
+ queues = 0;
+ works = 0;
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public void receive(Message message) {
+
+ List<LuceneWork> queue;
+ try {
+ queue = ( List<LuceneWork> ) message.getObject();
+ }
+
+ catch ( ClassCastException e ) {
+ return;
+ }
+ queues++;
+ works += queue.size();
+ }
+}
Property changes on: search/trunk/src/test/java/org/hibernate/search/test/jgroups/slave/JGroupsReceiver.java
___________________________________________________________________
Name: svn:keywords
+ Id
Added: search/trunk/src/test/java/org/hibernate/search/test/jgroups/slave/JGroupsSlaveTest.java
===================================================================
--- search/trunk/src/test/java/org/hibernate/search/test/jgroups/slave/JGroupsSlaveTest.java (rev 0)
+++ search/trunk/src/test/java/org/hibernate/search/test/jgroups/slave/JGroupsSlaveTest.java 2009-08-14 22:53:34 UTC (rev 17306)
@@ -0,0 +1,165 @@
+// $Id$
+package org.hibernate.search.test.jgroups.slave;
+
+import org.jgroups.Channel;
+import org.jgroups.JChannel;
+
+import org.hibernate.Session;
+import org.hibernate.Transaction;
+import org.hibernate.cfg.Configuration;
+import org.hibernate.search.Environment;
+import org.hibernate.search.backend.impl.jgroups.JGroupsBackendQueueProcessorFactory;
+import org.hibernate.search.test.SearchTestCase;
+import org.hibernate.search.util.XMLHelper;
+
+/**
+ * Tests that the Slave node in a JGroups cluster can properly send messages to the channel.
+ * <p/>
+ * In case of running test outside Hibernate Search Maven configuration set following VM configuration:
+ * <br><br>
+ * <code>
+ * -Djava.net.preferIPv4Stack=true -Djgroups.bind_addr=127.0.0.1
+ * </code>
+ *
+ * @author Lukasz Moren
+ */
+
+public class JGroupsSlaveTest extends SearchTestCase {
+
+ public static final String CHANNEL_NAME = "HSearchCluster";
+
+ private Channel channel;
+
+ public void testMessageSend() throws Exception {
+
+ JGroupsReceiver.reset();
+
+ Session s = openSession();
+ Transaction tx = s.beginTransaction();
+ TShirt ts = new TShirt();
+ ts.setLogo( "Boston" );
+ ts.setSize( "XXL" );
+ TShirt ts2 = new TShirt();
+ ts2.setLogo( "Mapple leaves" );
+ ts2.setSize( "L" );
+ s.persist( ts );
+ s.persist( ts2 );
+ tx.commit();
+
+ //need to sleep for the message consumption
+ Thread.sleep( 500 );
+
+ assertEquals( 1, JGroupsReceiver.queues );
+ assertEquals( 2, JGroupsReceiver.works );
+
+ JGroupsReceiver.reset();
+ s = openSession();
+ tx = s.beginTransaction();
+ ts = ( TShirt ) s.get( TShirt.class, ts.getId() );
+ ts.setLogo( "Peter pan" );
+ tx.commit();
+
+ //need to sleep for the message consumption
+ Thread.sleep( 500 );
+
+ assertEquals( 1, JGroupsReceiver.queues );
+ assertEquals( 2, JGroupsReceiver.works );
+
+ JGroupsReceiver.reset();
+ s = openSession();
+ tx = s.beginTransaction();
+ s.delete( s.get( TShirt.class, ts.getId() ) );
+ tx.commit();
+
+ //Need to sleep for the message consumption
+ Thread.sleep( 500 );
+
+ assertEquals( 1, JGroupsReceiver.queues );
+ assertEquals( 1, JGroupsReceiver.works );
+ s.close();
+ }
+
+ private void prepareJGroupsChannel() throws Exception {
+ channel = new JChannel( XMLHelper.elementFromString( prepareXmlJGroupsConfiguration() ) );
+ channel.connect( CHANNEL_NAME );
+ channel.setReceiver( new JGroupsReceiver() );
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ prepareJGroupsChannel();
+ }
+
+ protected void tearDown() throws Exception {
+ channel.close();
+ super.tearDown();
+ }
+
+ protected Class[] getMappings() {
+ return new Class[] {
+ TShirt.class
+ };
+ }
+
+ protected void configure(Configuration cfg) {
+ super.configure( cfg );
+ cfg.setProperty( Environment.WORKER_BACKEND, "jgroupsSlave" );
+ cfg.setProperty( JGroupsBackendQueueProcessorFactory.CONFIGURATION_XML, prepareXmlJGroupsConfiguration() );
+ }
+
+ private String prepareXmlJGroupsConfiguration() {
+ return "<config>" +
+ "<UDP" +
+ " mcast_addr=\"${jgroups.udp.mcast_addr:228.10.10.10}\"" +
+ " mcast_port=\"${jgroups.udp.mcast_port:45588}\"" +
+ " tos=\"8\"" +
+ " ucast_recv_buf_size=\"20000000\"" +
+ " ucast_send_buf_size=\"640000\"" +
+ " mcast_recv_buf_size=\"25000000\"" +
+ " mcast_send_buf_size=\"640000\"" +
+ " loopback=\"false\"\n" +
+ " discard_incompatible_packets=\"true\"" +
+ " max_bundle_size=\"64000\"" +
+ " max_bundle_timeout=\"30\"" +
+ " use_incoming_packet_handler=\"true\"" +
+ " ip_ttl=\"${jgroups.udp.ip_ttl:2}\"" +
+ " enable_bundling=\"true\"" +
+ " enable_diagnostics=\"true\"" +
+ " use_concurrent_stack=\"true\"" +
+ " thread_naming_pattern=\"pl\"" +
+ " thread_pool.enabled=\"true\"" +
+ " thread_pool.min_threads=\"1\"" +
+ " thread_pool.max_threads=\"25\"" +
+ " thread_pool.keep_alive_time=\"5000\"" +
+ " thread_pool.queue_enabled=\"false\"" +
+ " thread_pool.queue_max_size=\"100\"" +
+ " thread_pool.rejection_policy=\"Run\"" +
+ " oob_thread_pool.enabled=\"true\"" +
+ " oob_thread_pool.min_threads=\"1\"" +
+ " oob_thread_pool.max_threads=\"8\"" +
+ " oob_thread_pool.keep_alive_time=\"5000\"" +
+ " oob_thread_pool.queue_enabled=\"false\"" +
+ " oob_thread_pool.queue_max_size=\"100\"" +
+ " oob_thread_pool.rejection_policy=\"Run\"/>" +
+ "<PING timeout=\"2000\" num_initial_members=\"3\"/>" +
+ "<MERGE2 max_interval=\"30000\" min_interval=\"10000\"/>" +
+ "<FD_SOCK/>" +
+ "<FD timeout=\"10000\" max_tries=\"5\" shun=\"true\"/>" +
+ "<VERIFY_SUSPECT timeout=\"1500\"/>" +
+ "<pbcast.NAKACK " +
+ " use_mcast_xmit=\"false\" gc_lag=\"0\"" +
+ " retransmit_timeout=\"300,600,1200,2400,4800\"" +
+ " discard_delivered_msgs=\"false\"/>" +
+ "<UNICAST timeout=\"300,600,1200,2400,3600\"/>" +
+ "<pbcast.STABLE stability_delay=\"1000\" desired_avg_gossip=\"50000\"" +
+ " max_bytes=\"400000\"/> " +
+ "<pbcast.GMS print_local_addr=\"true\" join_timeout=\"3000\"" +
+ " shun=\"false\"" +
+ " view_bundling=\"true\"/>" +
+ "<FC max_credits=\"20000000\" min_threshold=\"0.10\"/>" +
+ "<FRAG2 frag_size=\"60000\"/>" +
+ "<pbcast.STREAMING_STATE_TRANSFER />" +
+ "<pbcast.FLUSH timeout=\"0\"/>" +
+ "</config>";
+ }
+}
Property changes on: search/trunk/src/test/java/org/hibernate/search/test/jgroups/slave/JGroupsSlaveTest.java
___________________________________________________________________
Name: svn:keywords
+ Id
Added: search/trunk/src/test/java/org/hibernate/search/test/jgroups/slave/TShirt.java
===================================================================
--- search/trunk/src/test/java/org/hibernate/search/test/jgroups/slave/TShirt.java (rev 0)
+++ search/trunk/src/test/java/org/hibernate/search/test/jgroups/slave/TShirt.java 2009-08-14 22:53:34 UTC (rev 17306)
@@ -0,0 +1,50 @@
+// $Id$
+package org.hibernate.search.test.jgroups.slave;
+
+import org.hibernate.search.annotations.DocumentId;
+import org.hibernate.search.annotations.Field;
+import org.hibernate.search.annotations.Index;
+import org.hibernate.search.annotations.Indexed;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+
+/**
+ * @author Emmanuel Bernard
+ */
+@Entity
+@Indexed
+public class TShirt {
+ @Id
+ @GeneratedValue
+ @DocumentId
+ private int id;
+ @Field(index= Index.TOKENIZED)
+ private String logo;
+ private String size;
+
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ public String getLogo() {
+ return logo;
+ }
+
+ public void setLogo(String logo) {
+ this.logo = logo;
+ }
+
+ public String getSize() {
+ return size;
+ }
+
+ public void setSize(String size) {
+ this.size = size;
+ }
+}
\ No newline at end of file
Property changes on: search/trunk/src/test/java/org/hibernate/search/test/jgroups/slave/TShirt.java
___________________________________________________________________
Name: svn:keywords
+ Id
15 years, 3 months
Hibernate SVN: r17305 - core/trunk/entitymanager/src/main/java/org/hibernate/ejb/util and 1 other directories.
by hibernate-commits@lists.jboss.org
Author: epbernard
Date: 2009-08-14 14:29:45 -0400 (Fri, 14 Aug 2009)
New Revision: 17305
Added:
core/trunk/entitymanager/src/main/java/org/hibernate/ejb/util/PersistenceUtilHelper.java
jpa-api/trunk/src/main/java/javax/persistence/CacheRetrieveMode.java
jpa-api/trunk/src/main/java/javax/persistence/CacheStoreMode.java
jpa-api/trunk/src/main/java/javax/persistence/PersistenceUnitUtil.java
jpa-api/trunk/src/main/java/javax/persistence/PessimisticLockScope.java
jpa-api/trunk/src/main/java/javax/persistence/TypedQuery.java
Modified:
core/trunk/entitymanager/src/main/java/org/hibernate/ejb/AbstractEntityManagerImpl.java
core/trunk/entitymanager/src/main/java/org/hibernate/ejb/CurrentEntityManagerImpl.java
core/trunk/entitymanager/src/main/java/org/hibernate/ejb/EntityManagerFactoryImpl.java
core/trunk/entitymanager/src/main/java/org/hibernate/ejb/HibernatePersistence.java
core/trunk/entitymanager/src/main/java/org/hibernate/ejb/QueryImpl.java
jpa-api/trunk/src/main/java/javax/persistence/EntityManager.java
jpa-api/trunk/src/main/java/javax/persistence/EntityManagerFactory.java
jpa-api/trunk/src/main/java/javax/persistence/Parameter.java
jpa-api/trunk/src/main/java/javax/persistence/Query.java
Log:
Add support for the new JPA 2 API from July 23 2009 (only the top level package. Subpackages have not been updated. Also partially implement PersistenceUnitUtil
Modified: core/trunk/entitymanager/src/main/java/org/hibernate/ejb/AbstractEntityManagerImpl.java
===================================================================
--- core/trunk/entitymanager/src/main/java/org/hibernate/ejb/AbstractEntityManagerImpl.java 2009-08-14 17:26:52 UTC (rev 17304)
+++ core/trunk/entitymanager/src/main/java/org/hibernate/ejb/AbstractEntityManagerImpl.java 2009-08-14 18:29:45 UTC (rev 17305)
@@ -38,6 +38,7 @@
import javax.persistence.PersistenceException;
import javax.persistence.Query;
import javax.persistence.TransactionRequiredException;
+import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.QueryBuilder;
import javax.persistence.metamodel.Metamodel;
@@ -125,7 +126,11 @@
}
}
- public Query createQuery(CriteriaQuery criteriaQuery) {
+ public <T> TypedQuery<T> createQuery(String qlString, Class<T> resultClass) {
+ throw new UnsupportedOperationException( "Not yet implemented" );
+ }
+
+ public <T> TypedQuery<T> createQuery(CriteriaQuery<T> criteriaQuery) {
// TODO-STEVE : here is the interpretation/compilation portion.
// One option is to build on top of the existing
// org.hibernate.loader.custom.CustomQuery infastructure
@@ -142,6 +147,23 @@
throw new UnsupportedOperationException( "Not yet implemented!" );
}
+ public <T> TypedQuery<T> createQuery(CriteriaQuery<T> criteriaQuery, Class<T> resultClass) {
+ // TODO-STEVE : here is the interpretation/compilation portion.
+ // One option is to build on top of the existing
+ // org.hibernate.loader.custom.CustomQuery infastructure
+ // (which is how native sql queries are implemented e.g.).
+ // If so, then here we could interpret the criteria into
+ // a CustomQuery instance which is passed into the
+ // Query instance returned here. We would then call into
+ // the various SessionImplementor methods for execution
+ // such as #listCustomQuery and #scrollCustomQuery.
+ //
+ // The drawback to this (^^) approach is that CustomQuery +
+ // SessionImplementor combo does not support #executeUpdate
+ // processing...
+ throw new UnsupportedOperationException( "Not yet implemented!" );
+ }
+
public Query createNamedQuery(String name) {
//adjustFlushMode();
org.hibernate.Query namedQuery;
@@ -160,6 +182,11 @@
}
}
+ public <T> TypedQuery<T> createNamedQuery(String name, Class<T> resultClass) {
+ throw new UnsupportedOperationException( "Not yet implemented" );
+ }
+
+
public Query createNativeQuery(String sqlString) {
//adjustFlushMode();
try {
Modified: core/trunk/entitymanager/src/main/java/org/hibernate/ejb/CurrentEntityManagerImpl.java
===================================================================
--- core/trunk/entitymanager/src/main/java/org/hibernate/ejb/CurrentEntityManagerImpl.java 2009-08-14 17:26:52 UTC (rev 17304)
+++ core/trunk/entitymanager/src/main/java/org/hibernate/ejb/CurrentEntityManagerImpl.java 2009-08-14 18:29:45 UTC (rev 17305)
@@ -23,6 +23,7 @@
import java.util.Map;
import javax.persistence.PersistenceContextType;
+import javax.persistence.TypedQuery;
import javax.persistence.spi.PersistenceUnitTransactionType;
import org.hibernate.Session;
Modified: core/trunk/entitymanager/src/main/java/org/hibernate/ejb/EntityManagerFactoryImpl.java
===================================================================
--- core/trunk/entitymanager/src/main/java/org/hibernate/ejb/EntityManagerFactoryImpl.java 2009-08-14 17:26:52 UTC (rev 17304)
+++ core/trunk/entitymanager/src/main/java/org/hibernate/ejb/EntityManagerFactoryImpl.java 2009-08-14 18:29:45 UTC (rev 17305)
@@ -28,15 +28,19 @@
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContextType;
import javax.persistence.Cache;
+import javax.persistence.PersistenceUnitUtil;
import javax.persistence.metamodel.Metamodel;
import javax.persistence.criteria.QueryBuilder;
import javax.persistence.spi.PersistenceUnitTransactionType;
+import javax.persistence.spi.LoadState;
import org.hibernate.SessionFactory;
+import org.hibernate.Hibernate;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.cfg.Configuration;
import org.hibernate.ejb.criteria.QueryBuilderImpl;
import org.hibernate.ejb.metamodel.MetamodelImpl;
+import org.hibernate.ejb.util.PersistenceUtilHelper;
/**
* Actual Hiberate implementation of {@link javax.persistence.EntityManagerFactory}.
@@ -52,6 +56,7 @@
private final Class sessionInterceptorClass;
private final QueryBuilderImpl criteriaQueryBuilder;
private final Metamodel metamodel;
+ private final HibernatePersistenceUnitUtil util;
public EntityManagerFactoryImpl(
SessionFactory sessionFactory,
@@ -73,6 +78,7 @@
this.metamodel = null;
}
this.criteriaQueryBuilder = new QueryBuilderImpl( this );
+ this.util = new HibernatePersistenceUnitUtil( this );
}
public EntityManager createEntityManager() {
@@ -114,6 +120,10 @@
return new JPACache( sessionFactory );
}
+ public PersistenceUnitUtil getPersistenceUnitUtil() {
+ return null; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
public boolean isOpen() {
return ! sessionFactory.isClosed();
}
@@ -148,4 +158,35 @@
// sessionFactory.getCache().evictQueryRegions();
}
}
+
+ private static class HibernatePersistenceUnitUtil implements PersistenceUnitUtil, Serializable {
+ private final EntityManagerFactoryImpl emf;
+
+ private HibernatePersistenceUnitUtil(EntityManagerFactoryImpl emf) {
+ this.emf = emf;
+ }
+
+ public boolean isLoaded(Object entity, String attributeName) {
+ LoadState state = PersistenceUtilHelper.isLoadedWithoutReference( entity, attributeName );
+ if (state == LoadState.LOADED) {
+ return true;
+ }
+ else if (state == LoadState.NOT_LOADED ) {
+ return false;
+ }
+ else {
+ return PersistenceUtilHelper.isLoadedWithReference( entity, attributeName ) != LoadState.NOT_LOADED;
+ }
+
+
+ }
+
+ public boolean isLoaded(Object entity) {
+ return PersistenceUtilHelper.isLoaded( entity ) != LoadState.NOT_LOADED;
+ }
+
+ public Object getIdentifier(Object entity) {
+ throw new UnsupportedOperationException( "Not yet implemented" );
+ }
+ }
}
Modified: core/trunk/entitymanager/src/main/java/org/hibernate/ejb/HibernatePersistence.java
===================================================================
--- core/trunk/entitymanager/src/main/java/org/hibernate/ejb/HibernatePersistence.java 2009-08-14 17:26:52 UTC (rev 17304)
+++ core/trunk/entitymanager/src/main/java/org/hibernate/ejb/HibernatePersistence.java 2009-08-14 18:29:45 UTC (rev 17305)
@@ -36,6 +36,7 @@
import javax.persistence.spi.LoadState;
import org.hibernate.Hibernate;
+import org.hibernate.ejb.util.PersistenceUtilHelper;
import org.hibernate.intercept.FieldInterceptionHelper;
import org.hibernate.intercept.FieldInterceptor;
import org.hibernate.collection.PersistentCollection;
@@ -170,140 +171,15 @@
}
public LoadState isLoadedWithoutReference(Object proxy, String property) {
- Object entity;
- boolean sureFromUs = false;
- if ( proxy instanceof HibernateProxy ) {
- LazyInitializer li = ( ( HibernateProxy ) proxy ).getHibernateLazyInitializer();
- if ( li.isUninitialized() ) {
- return LoadState.NOT_LOADED;
- }
- else {
- entity = li.getImplementation();
- }
- sureFromUs = true;
- }
- else {
- entity = proxy;
- }
-
- //we are instrumenting but we can't assume we are the only ones
- if ( FieldInterceptionHelper.isInstrumented( entity ) ) {
- FieldInterceptor interceptor = FieldInterceptionHelper.extractFieldInterceptor( entity );
- final boolean isInitialized = interceptor == null || interceptor.isInitialized( property );
- LoadState state;
- if (isInitialized && interceptor != null) {
- //property is loaded according to bytecode enhancement, but is it loaded as far as association?
- //it's ours, we can read
- state = isLoaded( get( entity, property ) );
- //it's ours so we know it's loaded
- if (state == LoadState.UNKNOWN) state = LoadState.LOADED;
- }
- else if ( interceptor != null && (! isInitialized)) {
- state = LoadState.NOT_LOADED;
- }
- else if ( sureFromUs ) { //interceptor == null
- //property is loaded according to bytecode enhancement, but is it loaded as far as association?
- //it's ours, we can read
- state = isLoaded( get( entity, property ) );
- //it's ours so we know it's loaded
- if (state == LoadState.UNKNOWN) state = LoadState.LOADED;
- }
- else {
- state = LoadState.UNKNOWN;
- }
-
- return state;
- }
- else {
- //can't do sureFromUs ? LoadState.LOADED : LoadState.UNKNOWN;
- //is that an association?
- return LoadState.UNKNOWN;
- }
+ return PersistenceUtilHelper.isLoadedWithoutReference( proxy, property );
}
public LoadState isLoadedWithReference(Object proxy, String property) {
- //for sure we don't instrument and for sure it's not a lazy proxy
- Object object = get(proxy, property);
- return isLoaded( object );
+ return PersistenceUtilHelper.isLoadedWithReference( proxy, property );
}
- private Object get(Object proxy, String property) {
- final Class<?> clazz = proxy.getClass();
- try {
- try {
- final Field field = clazz.getField( property );
- setAccessibility( field );
- return field.get( proxy );
- }
- catch ( NoSuchFieldException e ) {
- final Method method = getMethod( clazz, property );
- if (method != null) {
- setAccessibility( method );
- return method.invoke( proxy );
- }
- else {
- throw new PersistenceException( "Unable to find field or method: "
- + clazz + "#"
- + property);
- }
- }
- }
- catch ( IllegalAccessException e ) {
- throw new PersistenceException( "Unable to access field or method: "
- + clazz + "#"
- + property, e);
- }
- catch ( InvocationTargetException e ) {
- throw new PersistenceException( "Unable to access field or method: "
- + clazz + "#"
- + property, e);
- }
- }
-
- /**
- * Returns the method with the specified name or <code>null</code> if it does not exist.
- *
- * @param clazz The class to check.
- * @param methodName The method name.
- *
- * @return Returns the method with the specified name or <code>null</code> if it does not exist.
- */
- public static Method getMethod(Class<?> clazz, String methodName) {
- try {
- char string[] = methodName.toCharArray();
- string[0] = Character.toUpperCase( string[0] );
- methodName = new String( string );
- try {
- return clazz.getMethod( "get" + methodName );
- }
- catch ( NoSuchMethodException e ) {
- return clazz.getMethod( "is" + methodName );
- }
- }
- catch ( NoSuchMethodException e ) {
- return null;
- }
- }
-
- public static void setAccessibility(Member member) {
- if ( !Modifier.isPublic( member.getModifiers() ) ) {
- //Sun's ease of use, sigh...
- ( ( AccessibleObject ) member ).setAccessible( true );
- }
- }
-
public LoadState isLoaded(Object o) {
- if ( o instanceof HibernateProxy ) {
- final boolean isInitialized = !( ( HibernateProxy ) o ).getHibernateLazyInitializer().isUninitialized();
- return isInitialized ? LoadState.LOADED : LoadState.NOT_LOADED;
- }
- else if ( o instanceof PersistentCollection ) {
- final boolean isInitialized = ( ( PersistentCollection ) o ).wasInitialized();
- return isInitialized ? LoadState.LOADED : LoadState.NOT_LOADED;
- }
- else {
- return LoadState.UNKNOWN;
- }
+ return PersistenceUtilHelper.isLoaded(o);
}
/**
Modified: core/trunk/entitymanager/src/main/java/org/hibernate/ejb/QueryImpl.java
===================================================================
--- core/trunk/entitymanager/src/main/java/org/hibernate/ejb/QueryImpl.java 2009-08-14 17:26:52 UTC (rev 17304)
+++ core/trunk/entitymanager/src/main/java/org/hibernate/ejb/QueryImpl.java 2009-08-14 18:29:45 UTC (rev 17305)
@@ -38,6 +38,7 @@
import static javax.persistence.TemporalType.*;
import javax.persistence.TransactionRequiredException;
import javax.persistence.LockModeType;
+import javax.persistence.Parameter;
import org.hibernate.FlushMode;
import org.hibernate.HibernateException;
@@ -395,16 +396,51 @@
}
}
- public Map<String, Object> getNamedParameters() {
- //FIXME
+ //FIXME
+ public Set<Parameter<?>> getParameters() {
return null; //To change body of implemented methods use File | Settings | File Templates.
}
- public List getPositionalParameters() {
- //FIXME
+ //FIXME
+ public Parameter<?> getParameter(String name) {
return null; //To change body of implemented methods use File | Settings | File Templates.
}
+ //FIXME
+ public Parameter<?> getParameter(int position) {
+ return null; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ //FIXME
+ public <T> Parameter<T> getParameter(String name, Class<T> type) {
+ return null; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ //FIXME
+ public <T> Parameter<T> getParameter(int position, Class<T> type) {
+ return null; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ //FIXME
+ public boolean isBound(Parameter<?> param) {
+ return false; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ //FIXME
+ public <T> T getParameterValue(Parameter<T> param) {
+ return null; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ //FIXME
+ public Object getParameterValue(String name) {
+ return null; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ //FIXME
+ public Object getParameterValue(int position) {
+ return null; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
public Query setFlushMode(FlushModeType flushMode) {
if ( flushMode == FlushModeType.AUTO ) {
query.setFlushMode( FlushMode.AUTO );
Added: core/trunk/entitymanager/src/main/java/org/hibernate/ejb/util/PersistenceUtilHelper.java
===================================================================
--- core/trunk/entitymanager/src/main/java/org/hibernate/ejb/util/PersistenceUtilHelper.java (rev 0)
+++ core/trunk/entitymanager/src/main/java/org/hibernate/ejb/util/PersistenceUtilHelper.java 2009-08-14 18:29:45 UTC (rev 17305)
@@ -0,0 +1,159 @@
+package org.hibernate.ejb.util;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Member;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.AccessibleObject;
+import javax.persistence.spi.LoadState;
+import javax.persistence.PersistenceException;
+
+import org.hibernate.proxy.HibernateProxy;
+import org.hibernate.proxy.LazyInitializer;
+import org.hibernate.intercept.FieldInterceptionHelper;
+import org.hibernate.intercept.FieldInterceptor;
+import org.hibernate.collection.PersistentCollection;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class PersistenceUtilHelper {
+ public static LoadState isLoadedWithoutReference(Object proxy, String property) {
+ Object entity;
+ boolean sureFromUs = false;
+ if ( proxy instanceof HibernateProxy ) {
+ LazyInitializer li = ( ( HibernateProxy ) proxy ).getHibernateLazyInitializer();
+ if ( li.isUninitialized() ) {
+ return LoadState.NOT_LOADED;
+ }
+ else {
+ entity = li.getImplementation();
+ }
+ sureFromUs = true;
+ }
+ else {
+ entity = proxy;
+ }
+
+ //we are instrumenting but we can't assume we are the only ones
+ if ( FieldInterceptionHelper.isInstrumented( entity ) ) {
+ FieldInterceptor interceptor = FieldInterceptionHelper.extractFieldInterceptor( entity );
+ final boolean isInitialized = interceptor == null || interceptor.isInitialized( property );
+ LoadState state;
+ if (isInitialized && interceptor != null) {
+ //property is loaded according to bytecode enhancement, but is it loaded as far as association?
+ //it's ours, we can read
+ state = isLoaded( get( entity, property ) );
+ //it's ours so we know it's loaded
+ if (state == LoadState.UNKNOWN) state = LoadState.LOADED;
+ }
+ else if ( interceptor != null && (! isInitialized)) {
+ state = LoadState.NOT_LOADED;
+ }
+ else if ( sureFromUs ) { //interceptor == null
+ //property is loaded according to bytecode enhancement, but is it loaded as far as association?
+ //it's ours, we can read
+ state = isLoaded( get( entity, property ) );
+ //it's ours so we know it's loaded
+ if (state == LoadState.UNKNOWN) state = LoadState.LOADED;
+ }
+ else {
+ state = LoadState.UNKNOWN;
+ }
+
+ return state;
+ }
+ else {
+ //can't do sureFromUs ? LoadState.LOADED : LoadState.UNKNOWN;
+ //is that an association?
+ return LoadState.UNKNOWN;
+ }
+ }
+
+ public static LoadState isLoadedWithReference(Object proxy, String property) {
+ //for sure we don't instrument and for sure it's not a lazy proxy
+ Object object = get(proxy, property);
+ return isLoaded( object );
+ }
+
+ private static Object get(Object proxy, String property) {
+ final Class<?> clazz = proxy.getClass();
+ try {
+ try {
+ final Field field = clazz.getField( property );
+ setAccessibility( field );
+ return field.get( proxy );
+ }
+ catch ( NoSuchFieldException e ) {
+ final Method method = getMethod( clazz, property );
+ if (method != null) {
+ setAccessibility( method );
+ return method.invoke( proxy );
+ }
+ else {
+ throw new PersistenceException( "Unable to find field or method: "
+ + clazz + "#"
+ + property);
+ }
+ }
+ }
+ catch ( IllegalAccessException e ) {
+ throw new PersistenceException( "Unable to access field or method: "
+ + clazz + "#"
+ + property, e);
+ }
+ catch ( InvocationTargetException e ) {
+ throw new PersistenceException( "Unable to access field or method: "
+ + clazz + "#"
+ + property, e);
+ }
+ }
+
+ /**
+ * Returns the method with the specified name or <code>null</code> if it does not exist.
+ *
+ * @param clazz The class to check.
+ * @param methodName The method name.
+ *
+ * @return Returns the method with the specified name or <code>null</code> if it does not exist.
+ */
+ private static Method getMethod(Class<?> clazz, String methodName) {
+ try {
+ char string[] = methodName.toCharArray();
+ string[0] = Character.toUpperCase( string[0] );
+ methodName = new String( string );
+ try {
+ return clazz.getMethod( "get" + methodName );
+ }
+ catch ( NoSuchMethodException e ) {
+ return clazz.getMethod( "is" + methodName );
+ }
+ }
+ catch ( NoSuchMethodException e ) {
+ return null;
+ }
+ }
+
+ private static void setAccessibility(Member member) {
+ if ( !Modifier.isPublic( member.getModifiers() ) ) {
+ //Sun's ease of use, sigh...
+ ( ( AccessibleObject ) member ).setAccessible( true );
+ }
+ }
+
+ public static LoadState isLoaded(Object o) {
+ if ( o instanceof HibernateProxy ) {
+ final boolean isInitialized = !( ( HibernateProxy ) o ).getHibernateLazyInitializer().isUninitialized();
+ return isInitialized ? LoadState.LOADED : LoadState.NOT_LOADED;
+ }
+ else if ( o instanceof PersistentCollection ) {
+ final boolean isInitialized = ( ( PersistentCollection ) o ).wasInitialized();
+ return isInitialized ? LoadState.LOADED : LoadState.NOT_LOADED;
+ }
+ else {
+ return LoadState.UNKNOWN;
+ }
+ }
+
+}
Added: jpa-api/trunk/src/main/java/javax/persistence/CacheRetrieveMode.java
===================================================================
--- jpa-api/trunk/src/main/java/javax/persistence/CacheRetrieveMode.java (rev 0)
+++ jpa-api/trunk/src/main/java/javax/persistence/CacheRetrieveMode.java 2009-08-14 18:29:45 UTC (rev 17305)
@@ -0,0 +1,18 @@
+// $Id: Cache.java 16130 2009-03-10 14:28:07Z hardy.ferentschik $
+// EJB3 Specification Copyright 2004-2009 Sun Microsystems, Inc.
+package javax.persistence;
+
+public enum CacheRetrieveMode {
+
+ /**
+ * Read entity data from the cache: this is
+ * the default behavior.
+ */
+ USE,
+
+ /**
+ * Bypass the cache: get data directly from
+ * the database.
+ */
+ BYPASS
+}
Added: jpa-api/trunk/src/main/java/javax/persistence/CacheStoreMode.java
===================================================================
--- jpa-api/trunk/src/main/java/javax/persistence/CacheStoreMode.java (rev 0)
+++ jpa-api/trunk/src/main/java/javax/persistence/CacheStoreMode.java 2009-08-14 18:29:45 UTC (rev 17305)
@@ -0,0 +1,26 @@
+// $Id: Cache.java 16130 2009-03-10 14:28:07Z hardy.ferentschik $
+// EJB3 Specification Copyright 2004-2009 Sun Microsystems, Inc.
+package javax.persistence;
+
+public enum CacheStoreMode {
+
+ /**
+ * Insert/update entity data into cache when read
+ * from database and when committed into database:
+ * this is the default behavior. Does not force refresh
+ * of already cached items when reading from database.
+ */
+ USE,
+
+ /**
+ * Don't insert into cache.
+ */
+ BYPASS,
+
+ /**
+ * Insert/update entity data into cache when read
+ * from database and when committed into database.
+ * Forces refresh of cache for items read from database.
+ */
+ REFRESH
+}
Modified: jpa-api/trunk/src/main/java/javax/persistence/EntityManager.java
===================================================================
--- jpa-api/trunk/src/main/java/javax/persistence/EntityManager.java 2009-08-14 17:26:52 UTC (rev 17304)
+++ jpa-api/trunk/src/main/java/javax/persistence/EntityManager.java 2009-08-14 18:29:45 UTC (rev 17305)
@@ -540,19 +540,31 @@
public Query createQuery(String qlString);
/**
- * Create an instance of Query for executing a
+ * Create an instance of TypedQuery for executing a
* criteria query.
- *
- * @param criteriaQuery a Criteria API query definition object
- *
+ * @param criteriaQuery a criteria query object
* @return the new query instance
- *
* @throws IllegalArgumentException if the query definition is
- * found to be invalid
+ * found to be invalid
*/
- public Query createQuery(CriteriaQuery criteriaQuery);
+ public <T> TypedQuery<T> createQuery(CriteriaQuery<T> criteriaQuery);
/**
+ * Create an instance of TypedQuery for executing a
+ * Java Persistence query language statement.
+ * The select list of the query must contain only a single
+ * item, which must be assignable to the type specified by
+ * the resultClass argument.
+ * @param qlString a Java Persistence query string
+ * @param resultClass the type of the query result
+ * @return the new query instance
+ * @throws IllegalArgumentException if the query string is found
+ * to be invalid or if the query result is found to
+ * not be assignable to the specified type.
+ */
+ public <T> TypedQuery<T> createQuery(String qlString, Class<T> resultClass);
+
+ /**
* Create an instance of Query for executing a
* named query (in the Java Persistence query language
* or in native SQL).
@@ -568,6 +580,23 @@
public Query createNamedQuery(String name);
/**
+ * Create an instance of TypedQuery for executing a
+ * named query (in the Java Persistence query language
+ * or in native SQL).
+ * The select list of the query must contain only a single
+ * item, which must be assignable to the type specified by
+ * the resultClass argument.
+ * @param name the name of a query defined in metadata
+ * @param resultClass the type of the query result
+ * @return the new query instance
+ * @throws IllegalArgumentException if a query has not been
+ * defined with the given name or if the query string is
+ * found to be invalid or if the query result is found to
+ * not be assignable to the specified type.
+ */
+ public <T> TypedQuery<T> createNamedQuery(String name, Class<T> resultClass);
+
+ /**
* Create an instance of Query for executing
* a native SQL statement, e.g., for update or delete.
*
Modified: jpa-api/trunk/src/main/java/javax/persistence/EntityManagerFactory.java
===================================================================
--- jpa-api/trunk/src/main/java/javax/persistence/EntityManagerFactory.java 2009-08-14 17:26:52 UTC (rev 17304)
+++ jpa-api/trunk/src/main/java/javax/persistence/EntityManagerFactory.java 2009-08-14 18:29:45 UTC (rev 17305)
@@ -1,110 +1,119 @@
// $Id$
// EJB3 Specification Copyright 2004-2009 Sun Microsystems, Inc.
-package javax.persistence;
-
-import java.util.Map;
-import java.util.Set;
-import javax.persistence.criteria.QueryBuilder;
-import javax.persistence.metamodel.Metamodel;
-
-/**
- * Interface used to interact with the entity manager factory * for the persistence unit.
- */
-public interface EntityManagerFactory {
- /**
- * Create a new EntityManager.
- * This method returns a new EntityManager instance each time
- * it is invoked.
- * The isOpen method will return true on the returned instance.
- *
- * @throws IllegalStateException if the entity manager factory
- * has been closed.
- */
- public EntityManager createEntityManager();
-
- /**
- * Create a new EntityManager with the specified Map of
- * properties.
- * This method returns a new EntityManager instance each time
- * it is invoked.
- * The isOpen method will return true on the returned instance.
- *
- * @throws IllegalStateException if the entity manager factory
- * has been closed.
- */
- public EntityManager createEntityManager(Map map);
-
- /**
- * Return an instance of QueryBuilder for the creation of
- * Criteria API objects.
- *
- * @return QueryBuilder instance
- *
- * @throws IllegalStateException if the entity manager factory
- * has been closed.
- */
- public QueryBuilder getQueryBuilder();
-
- /**
- * Return an instance of Metamodel interface for access to the
- * metamodel of the persistence unit.
- *
- * @return Metamodel instance
- *
- * @throws IllegalStateException if the entity manager has
- * been closed.
- */
- public Metamodel getMetamodel();
-
- /**
- * Indicates whether the factory is open. Returns true
- * until the factory has been closed.
- */
- public boolean isOpen();
-
- /**
- * Close the factory, releasing any resources that it holds.
- * After a factory instance is closed, all methods invoked on
- * it will throw an IllegalStateException, except for isOpen,
- * which will return false. Once an EntityManagerFactory has
- * been closed, all its entity managers are considered to be
- * in the closed state.
- *
- * @throws IllegalStateException if the entity manager factory
- * has been closed.
- */
- public void close();
-
- /**
- * Get the properties and associated values that are in effect
- * for the entity manager factory. Changing the contents of the
- * map does not change the configuration in effect.
- *
- * @return properties
- */
- public Map<String, Object> getProperties();
-
- /**
- * Get the names of the properties that are supported for use
- * with the entity manager factory. These correspond to
- * properties that may be passed to the methods of the
- * EntityManagerFactory interface that take a properties
- * argument. These include all standard properties as well as
- * vendor-specific properties supported by the provider. These
- * properties may or may not currently be in effect.
- *
- * @return properties and hints
- */
- public Set<String> getSupportedProperties();
-
- /**
- * Access the cache that is associated with the entity manager
- * factory (the "second level cache").
- *
- * @return instance of the Cache interface
- *
- * @throws IllegalStateException if the entity manager factory
- * has been closed.
- */
- public Cache getCache();
+package javax.persistence;
+
+import java.util.Map;
+import java.util.Set;
+import javax.persistence.criteria.QueryBuilder;
+import javax.persistence.metamodel.Metamodel;
+
+/**
+ * Interface used to interact with the entity manager factory * for the persistence unit.
+ */
+public interface EntityManagerFactory {
+ /**
+ * Create a new EntityManager.
+ * This method returns a new EntityManager instance each time
+ * it is invoked.
+ * The isOpen method will return true on the returned instance.
+ *
+ * @throws IllegalStateException if the entity manager factory
+ * has been closed.
+ */
+ public EntityManager createEntityManager();
+
+ /**
+ * Create a new EntityManager with the specified Map of
+ * properties.
+ * This method returns a new EntityManager instance each time
+ * it is invoked.
+ * The isOpen method will return true on the returned instance.
+ *
+ * @throws IllegalStateException if the entity manager factory
+ * has been closed.
+ */
+ public EntityManager createEntityManager(Map map);
+
+ /**
+ * Return an instance of QueryBuilder for the creation of
+ * Criteria API objects.
+ *
+ * @return QueryBuilder instance
+ *
+ * @throws IllegalStateException if the entity manager factory
+ * has been closed.
+ */
+ public QueryBuilder getQueryBuilder();
+
+ /**
+ * Return an instance of Metamodel interface for access to the
+ * metamodel of the persistence unit.
+ *
+ * @return Metamodel instance
+ *
+ * @throws IllegalStateException if the entity manager has
+ * been closed.
+ */
+ public Metamodel getMetamodel();
+
+ /**
+ * Indicates whether the factory is open. Returns true
+ * until the factory has been closed.
+ */
+ public boolean isOpen();
+
+ /**
+ * Close the factory, releasing any resources that it holds.
+ * After a factory instance is closed, all methods invoked on
+ * it will throw an IllegalStateException, except for isOpen,
+ * which will return false. Once an EntityManagerFactory has
+ * been closed, all its entity managers are considered to be
+ * in the closed state.
+ *
+ * @throws IllegalStateException if the entity manager factory
+ * has been closed.
+ */
+ public void close();
+
+ /**
+ * Get the properties and associated values that are in effect
+ * for the entity manager factory. Changing the contents of the
+ * map does not change the configuration in effect.
+ *
+ * @return properties
+ */
+ public Map<String, Object> getProperties();
+
+ /**
+ * Get the names of the properties that are supported for use
+ * with the entity manager factory. These correspond to
+ * properties that may be passed to the methods of the
+ * EntityManagerFactory interface that take a properties
+ * argument. These include all standard properties as well as
+ * vendor-specific properties supported by the provider. These
+ * properties may or may not currently be in effect.
+ *
+ * @return properties and hints
+ */
+ public Set<String> getSupportedProperties();
+
+ /**
+ * Access the cache that is associated with the entity manager
+ * factory (the "second level cache").
+ *
+ * @return instance of the Cache interface
+ *
+ * @throws IllegalStateException if the entity manager factory
+ * has been closed.
+ */
+ public Cache getCache();
+
+ /**
+ * Return interface providing access to utility methods
+ * for the persistence unit.
+ * @return PersistenceUnitUtil interface
+ * @throws IllegalStateException if the entity manager factory
+ * has been closed.
+ */
+ public PersistenceUnitUtil getPersistenceUnitUtil();
}
Modified: jpa-api/trunk/src/main/java/javax/persistence/Parameter.java
===================================================================
--- jpa-api/trunk/src/main/java/javax/persistence/Parameter.java 2009-08-14 17:26:52 UTC (rev 17304)
+++ jpa-api/trunk/src/main/java/javax/persistence/Parameter.java 2009-08-14 18:29:45 UTC (rev 17305)
@@ -21,5 +21,19 @@
* @return position of parameter
*/
Integer getPosition();
+
+ /**
+ * Return the Java type of the parameter. Values bound to the
+ * parameter must be assignable to this type.
+ * This method is required to be supported for criteria queries
+ * only. Applications that use this method for Java Persistence
+ * query language queries and native queries will not be portable.
+ * @return the Java type of the parameter
+ * @throws IllegalStateException if invoked on a parameter
+ * obtained from a Java persistence query language query or
+ * native query when the implementation does not support this
+ * use.
+ */
+ Class<T> getJavaType();
}
Added: jpa-api/trunk/src/main/java/javax/persistence/PersistenceUnitUtil.java
===================================================================
--- jpa-api/trunk/src/main/java/javax/persistence/PersistenceUnitUtil.java (rev 0)
+++ jpa-api/trunk/src/main/java/javax/persistence/PersistenceUnitUtil.java 2009-08-14 18:29:45 UTC (rev 17305)
@@ -0,0 +1,52 @@
+// $Id: PersistenceUtil.java 17036 2009-07-08 09:09:38Z epbernard $
+// EJB3 Specification Copyright 2004-2009 Sun Microsystems, Inc.
+package javax.persistence;
+
+/**
+ * Utility interface between the application and the persistence
+ * provider managing the persistence unit.
+ *
+ * The methods of this interface should only be invoked on entity
+ * instances obtained from or managed by entity managers for this
+ * persistence unit or on new entity instances.
+ */
+public interface PersistenceUnitUtil extends PersistenceUtil {
+
+ /**
+ * Determine the load state of a given persistent attribute
+ * of an entity belonging to the persistence unit.
+ * @param entity containing the attribute
+ * @param attributeName name of attribute whose load state is
+ * to be determined
+ * @return false if entity's state has not been loaded or
+ * if the attribute state has not been loaded, otherwise true
+ */
+ public boolean isLoaded(Object entity, String attributeName);
+
+ /**
+ * Determine the load state of an entity belonging to the
+ * persistence unit.
+ * This method can be used to determine the load state
+ * of an entity passed as a reference. An entity is
+ * considered loaded if all attributes for which FetchType
+ * EAGER has been specified have been loaded.
+ * The isLoaded(Object, String) method should be used to
+ * determine the load state of an attribute.
+ * Not doing so might lead to unintended loading of state.
+ * @param entity whose load state is to be determined
+ * @return false if the entity has not been loaded, else true.
+ */
+ public boolean isLoaded(Object entity);
+
+ /**
+ * Returns the id of the entity.
+ * A generated id is not guaranteed to be available until after
+ * the database insert has occurred.
+ * Returns null if the entity does not yet have an id
+ * @param entity
+ * @return id of the entity
+ * @throws IllegalStateException if the entity is found not to be
+ * an entity.
+ */
+ public Object getIdentifier(Object entity);
+}
Added: jpa-api/trunk/src/main/java/javax/persistence/PessimisticLockScope.java
===================================================================
--- jpa-api/trunk/src/main/java/javax/persistence/PessimisticLockScope.java (rev 0)
+++ jpa-api/trunk/src/main/java/javax/persistence/PessimisticLockScope.java 2009-08-14 18:29:45 UTC (rev 17305)
@@ -0,0 +1,8 @@
+// $Id:$
+// EJB3 Specification Copyright 2004-2009 Sun Microsystems, Inc.
+package javax.persistence;
+
+public enum PessimisticLockScope {
+ NORMAL,
+ EXTENDED
+}
Modified: jpa-api/trunk/src/main/java/javax/persistence/Query.java
===================================================================
--- jpa-api/trunk/src/main/java/javax/persistence/Query.java 2009-08-14 17:26:52 UTC (rev 17304)
+++ jpa-api/trunk/src/main/java/javax/persistence/Query.java 2009-08-14 18:29:45 UTC (rev 17305)
@@ -1,5 +1,5 @@
-// $Id$
-// EJB3 Specification Copyright 2004-2009 Sun Microsystems, Inc.
+// $Id$
+// EJB3 Specification Copyright 2004-2009 Sun Microsystems, Inc.
package javax.persistence;
import java.util.Calendar;
@@ -237,26 +237,119 @@
TemporalType temporalType);
/**
- * Get the parameters names and associated values of the
- * parameters that are bound for the query instance.
- * Returns empty map if no parameters have been bound
- * or if the query does not use named parameters.
- *
- * @return named parameters
- */
- public Map<String, Object> getNamedParameters();
+ * Get the parameter objects corresponding to the declared
+ * parameters of the query.
+ * Returns empty set if the query has no parameters.
+ * This method is not required to be supported for native
+ * queries.
+ * @return set of the parameter objects
+ * @throws IllegalStateException if invoked on a native
+ * query when the implementation does not support
+ * this use
+ */
+ Set<Parameter<?>> getParameters();
- /**
- * Get the values of the positional parameters
- * that are bound for the query instance.
- * Positional parameters are listed in order of position.
- * Returns empty list if no parameters have been bound
- * or if the query does not use positional parameters.
- *
- * @return positional parameters
- */
- public List getPositionalParameters();
+ /**
+ * Get the parameter object corresponding to the declared
+ * parameter of the given name.
+ * This method is not required to be supported for native
+ * queries.
+ * @param name
+ * @return parameter object
+ * @throws IllegalArgumentException if the parameter of the
+ * specified name does not exist
+ * @throws IllegalStateException if invoked on a native
+ * query when the implementation does not support
+ * this use
+ */
+ Parameter<?> getParameter(String name);
+ /**
+ * Get the parameter object corresponding to the declared
+ * positional parameter with the given position.
+ * This method is not required to be supported for native
+ * queries.
+ * @param position
+ * @return parameter object
+ * @throws IllegalArgumentException if the parameter with the
+ * specified position does not exist
+ * @throws IllegalStateException if invoked on a native
+ * query when the implementation does not support
+ * this use
+ */
+ Parameter<?> getParameter(int position);
+
+ /**
+ * Get the parameter of the given name and type.
+ * This method is required to be supported for criteria queries
+ * only.
+ * @param name
+ * @param type
+ * @return parameter object
+ * @throws IllegalArgumentException if the parameter of the
+ * specified name does not exist or is not assignable
+ * to the type
+ * @throws IllegalStateException if invoked on a native
+ * query or Java Persistence query language query when
+ * the implementation does not support this use
+ */
+ <T> Parameter<T> getParameter(String name, Class<T> type);
+
+ /**
+ * Get the positional parameter with the given position and type.
+ * This method is required to be supported for criteria queries
+ * only.
+ * @param position
+ * @param type
+ * @return parameter object
+ * @throws IllegalArgumentException if the parameter with the
+ * specified position does not exist or is not assignable
+ * to the type
+ * @throws IllegalStateException if invoked on a native
+ * query or Java Persistence query language query when
+ * the implementation does not support this use
+ */
+ <T> Parameter<T> getParameter(int position, Class<T> type);
+
+ /**
+ * Return a boolean indicating whether a value has been bound
+ * to the parameter.
+ * @param param parameter object
+ * @return boolean indicating whether parameter has been bound
+ */
+ boolean isBound(Parameter<?> param);
+
+ /**
+ * Return the value bound to the parameter.
+ * @param param parameter object
+ * @return parameter value
+ * @throws IllegalStateException if the parameter has not been
+ * been bound
+ */
+ <T> T getParameterValue(Parameter<T> param);
+
+ /**
+ * Return the value bound to the named parameter.
+ * @param name
+ * @return parameter value
+ * @throws IllegalStateException if the parameter has not been
+ * been bound
+ * @throws IllegalArgumentException if the parameter of the
+ * specified name does not exist
+ */
+ Object getParameterValue(String name);
+
+ /**
+ * Return the value bound to the positional parameter.
+ * @param position
+ * @return parameter value
+ * @throws IllegalStateException if the parameter has not been
+ * been bound
+ * @throws IllegalArgumentException if the parameter with the
+ * specified position does not exist
+ */
+ Object getParameterValue(int position);
+
/**
* Set the flush mode type to be used for the query execution.
* The flush mode type applies to the query regardless of the
Added: jpa-api/trunk/src/main/java/javax/persistence/TypedQuery.java
===================================================================
--- jpa-api/trunk/src/main/java/javax/persistence/TypedQuery.java (rev 0)
+++ jpa-api/trunk/src/main/java/javax/persistence/TypedQuery.java 2009-08-14 18:29:45 UTC (rev 17305)
@@ -0,0 +1,203 @@
+// $Id:$
+// EJB3 Specification Copyright 2004-2009 Sun Microsystems, Inc.
+package javax.persistence;
+
+import java.util.List;
+import java.util.Date;
+import java.util.Calendar;
+
+/**
+ * Interface used to control the execution of typed queries.
+ * @param <X> query result type
+ */
+public interface TypedQuery<X> extends Query {
+
+ /**
+ * Execute a SELECT query and return the query results
+ * as a typed List.
+ * @return a list of the results
+ * @throws IllegalStateException if called for a Java
+ * Persistence query language UPDATE or DELETE statement
+ * @throws QueryTimeoutException if the query execution exceeds
+ * the query timeout value set
+ * @throws TransactionRequiredException if a lock mode has
+ * been set and there is no transaction
+ * @throws PessimisticLockException if pessimistic locking
+ * fails and the transaction is rolled back
+ * @throws LockTimeoutException if pessimistic locking
+ * fails and only the statement is rolled back
+ */
+ List<X> getResultList();
+
+ /**
+ * Execute a SELECT query that returns a single result.
+ * @return the result
+ * @throws NoResultException if there is no result
+ * @throws NonUniqueResultException if more than one result
+ * @throws IllegalStateException if called for a Java
+ * Persistence query language UPDATE or DELETE statement
+ * @throws QueryTimeoutException if the query execution exceeds
+ * the query timeout value set
+ * @throws TransactionRequiredException if a lock mode has
+ * been set and there is no transaction
+ * @throws PessimisticLockException if pessimistic locking
+ * fails and the transaction is rolled back
+ * @throws LockTimeoutException if pessimistic locking
+ * fails and only the statement is rolled back
+ */
+ X getSingleResult();
+
+ /**
+ * Set the maximum number of results to retrieve.
+ * @param maxResult
+ * @return the same query instance
+ * @throws IllegalArgumentException if argument is negative
+ */
+ TypedQuery<X> setMaxResults(int maxResult);
+
+ /**
+ * Set the position of the first result to retrieve.
+ * @param startPosition position of the first result,
+ * numbered from 0
+ * @return the same query instance
+ * @throws IllegalArgumentException if argument is negative
+ */
+ TypedQuery<X> setFirstResult(int startPosition);
+
+ /**
+ * Set a query hint.
+ * If a vendor-specific hint is not recognized, it is silently
+ * ignored.
+ * Portable applications should not rely on the standard timeout
+ * hint. Depending on the database in use and the locking
+ * mechanisms used by the provider, the hint may or may not
+ * be observed.
+ * @param hintName
+ * @param value
+ * @return the same query instance
+ * @throws IllegalArgumentException if the second argument is not
+ * valid for the implementation
+ */
+ TypedQuery<X> setHint(String hintName, Object value);
+
+ /**
+ * Bind the value of a Parameter object.
+ * @param param parameter object
+ * @param value parameter value
+ * @return the same query instance
+ * @throws IllegalArgumentException if parameter
+ * does not correspond to a parameter of the
+ * query
+ */
+ <T> TypedQuery<X> setParameter(Parameter<T> param, T value);
+
+ /**
+ * Bind an instance of java.util.Date to a Parameter object.
+ * @param parameter object
+ * @param value
+ * @param temporalType
+ * @return the same query instance
+ * @throws IllegalArgumentException if position does not
+ * correspond to a parameter of the query
+ */
+ TypedQuery<X> setParameter(Parameter<Date> param, Date value, TemporalType temporalType);
+
+
+ /**
+ * Bind an instance of java.util.Calendar to a Parameter object.
+ * @param parameter
+ * @param value
+ * @param temporalType
+ * @return the same query instance
+ * @throws IllegalArgumentException if position does not
+ * correspond to a parameter of the query
+ */
+ TypedQuery<X> setParameter(Parameter<Calendar> param, Calendar value, TemporalType temporalType);
+
+ /**
+ * Bind an argument to a named parameter.
+ * @param name the parameter name
+ * @param value
+ * @return the same query instance
+ * @throws IllegalArgumentException if parameter name does not
+ * correspond to a parameter of the query or if
+ * the argument is of incorrect type
+ */
+ TypedQuery<X> setParameter(String name, Object value);
+
+ /**
+ * Bind an instance of java.util.Date to a named parameter.
+ * @param name
+ * @param value
+ * @param temporalType
+ * @return the same query instance
+ * @throws IllegalArgumentException if parameter name does not
+ * correspond to a parameter of the query
+ */
+ TypedQuery<X> setParameter(String name, Date value, TemporalType temporalType);
+
+ /**
+ * Bind an instance of java.util.Calendar to a named parameter.
+ * @param name
+ * @param value
+ * @param temporalType
+ * @return the same query instance
+ * @throws IllegalArgumentException if parameter name does not
+ * correspond to a parameter of the query
+ */
+ TypedQuery<X> setParameter(String name, Calendar value, TemporalType temporalType);
+
+ /**
+ * Bind an argument to a positional parameter.
+ * @param position
+ * @param value
+ * @return the same query instance
+ * @throws IllegalArgumentException if position does not
+ * correspond to a positional parameter of the
+ * query or if the argument is of incorrect type
+ */
+ TypedQuery<X> setParameter(int position, Object value);
+
+ /**
+ * Bind an instance of java.util.Date to a positional parameter.
+ * @param position
+ * @param value
+ * @param temporalType
+ * @return the same query instance
+ * @throws IllegalArgumentException if position does not
+ * correspond to a positional parameter of the query
+ */
+ TypedQuery<X> setParameter(int position, Date value, TemporalType temporalType);
+
+ /**
+ * Bind an instance of java.util.Calendar to a positional
+ * parameter.
+ * @param position
+ * @param value
+ * @param temporalType
+ * @return the same query instance
+ * @throws IllegalArgumentException if position does not
+ * correspond to a positional parameter of the query
+ */
+ TypedQuery<X> setParameter(int position, Calendar value, TemporalType temporalType);
+
+ /**
+ * Set the flush mode type to be used for the query execution.
+ * The flush mode type applies to the query regardless of the
+ * flush mode type in use for the entity manager.
+ * @return the same query instance
+ * @param flushMode
+ */
+ TypedQuery<X> setFlushMode(FlushModeType flushMode);
+
+ /**
+ * Set the lock mode type to be used for the query execution.
+ * @param lockMode
+ * @return the same query instance
+ * @throws IllegalStateException if the query is found not to
+ * be a Java Persistence query language SELECT query
+ * or a Criteria API query
+ */
+ TypedQuery<X> setLockMode(LockModeType lockMode);
+
+}
15 years, 3 months