Hibernate SVN: r15367 - core/trunk/core/src/main/java/org/hibernate/id.
by hibernate-commits@lists.jboss.org
Author: steve.ebersole(a)jboss.com
Date: 2008-10-21 15:11:13 -0400 (Tue, 21 Oct 2008)
New Revision: 15367
Removed:
core/trunk/core/src/main/java/org/hibernate/id/IdentifierGeneratorFactory.java
Log:
HHH-3512 : id generator short-naming
Deleted: core/trunk/core/src/main/java/org/hibernate/id/IdentifierGeneratorFactory.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/id/IdentifierGeneratorFactory.java 2008-10-21 19:10:17 UTC (rev 15366)
+++ core/trunk/core/src/main/java/org/hibernate/id/IdentifierGeneratorFactory.java 2008-10-21 19:11:13 UTC (rev 15367)
@@ -1,177 +0,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
- *
- */
-package org.hibernate.id;
-
-import java.io.Serializable;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.HashMap;
-import java.util.Properties;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.hibernate.HibernateException;
-import org.hibernate.MappingException;
-import org.hibernate.dialect.Dialect;
-import org.hibernate.type.Type;
-import org.hibernate.util.ReflectHelper;
-
-/**
- * Factory and helper methods for <tt>IdentifierGenerator</tt> framework.
- *
- * @author Gavin King
- */
-public final class IdentifierGeneratorFactory {
-
- private static final Logger log = LoggerFactory.getLogger( IdentifierGeneratorFactory.class );
-
- private static final HashMap GENERATORS = new HashMap();
- static {
- GENERATORS.put( "uuid", UUIDHexGenerator.class );
- GENERATORS.put( "hilo", TableHiLoGenerator.class );
- GENERATORS.put( "assigned", Assigned.class );
- GENERATORS.put( "identity", IdentityGenerator.class );
- GENERATORS.put( "select", SelectGenerator.class );
- GENERATORS.put( "sequence", SequenceGenerator.class );
- GENERATORS.put( "seqhilo", SequenceHiLoGenerator.class );
- GENERATORS.put( "increment", IncrementGenerator.class );
- GENERATORS.put( "foreign", ForeignGenerator.class );
- GENERATORS.put( "guid", GUIDGenerator.class );
- GENERATORS.put( "uuid.hex", UUIDHexGenerator.class ); // uuid.hex is deprecated
- GENERATORS.put( "sequence-identity", SequenceIdentityGenerator.class );
- }
-
- public static final Serializable SHORT_CIRCUIT_INDICATOR = new Serializable() {
- public String toString() {
- return "SHORT_CIRCUIT_INDICATOR";
- }
- };
-
- public static final Serializable POST_INSERT_INDICATOR = new Serializable() {
- public String toString() {
- return "POST_INSERT_INDICATOR";
- }
- };
-
- /**
- * Get the generated identifier when using identity columns
- *
- * @param rs The result set from which to extract the the generated identity.
- * @param type The expected type mapping for the identity value.
- * @return The generated identity value
- * @throws SQLException Can be thrown while accessing the result set
- * @throws HibernateException Indicates a problem reading back a generated identity value.
- */
- public static Serializable getGeneratedIdentity(ResultSet rs, Type type) throws SQLException, HibernateException {
- if ( !rs.next() ) {
- throw new HibernateException( "The database returned no natively generated identity value" );
- }
- final Serializable id = IdentifierGeneratorFactory.get( rs, type );
-
- if ( log.isDebugEnabled() ) {
- log.debug( "Natively generated identity: " + id );
- }
- return id;
- }
-
- // unhappy about this being public ... is there a better way?
- public static Serializable get(ResultSet rs, Type type) throws SQLException, IdentifierGenerationException {
- Class clazz = type.getReturnedClass();
- if ( clazz == Long.class ) {
- return new Long( rs.getLong( 1 ) );
- }
- else if ( clazz == Integer.class ) {
- return new Integer( rs.getInt( 1 ) );
- }
- else if ( clazz == Short.class ) {
- return new Short( rs.getShort( 1 ) );
- }
- else if ( clazz == String.class ) {
- return rs.getString( 1 );
- }
- else {
- throw new IdentifierGenerationException( "this id generator generates long, integer, short or string" );
- }
-
- }
-
- public static IdentifierGenerator create(String strategy, Type type, Properties params, Dialect dialect)
- throws MappingException {
- try {
- Class clazz = getIdentifierGeneratorClass( strategy, dialect );
- IdentifierGenerator idgen = ( IdentifierGenerator ) clazz.newInstance();
- if ( idgen instanceof Configurable ) {
- ( ( Configurable ) idgen ).configure( type, params, dialect );
- }
- return idgen;
- }
- catch ( Exception e ) {
- throw new MappingException(
- "could not instantiate id generator [entity-name=" + params.get(
- IdentifierGenerator.ENTITY_NAME
- ) + "]", e
- );
- }
- }
-
- public static Class getIdentifierGeneratorClass(String strategy, Dialect dialect) {
- Class clazz = ( Class ) GENERATORS.get( strategy );
- if ( "native".equals( strategy ) ) {
- clazz = dialect.getNativeIdentifierGeneratorClass();
- }
- try {
- if ( clazz == null ) {
- clazz = ReflectHelper.classForName( strategy );
- }
- }
- catch ( ClassNotFoundException e ) {
- throw new MappingException( "could not interpret id generator strategy: " + strategy );
- }
- return clazz;
- }
-
- public static Number createNumber(long value, Class clazz) throws IdentifierGenerationException {
- if ( clazz == Long.class ) {
- return new Long( value );
- }
- else if ( clazz == Integer.class ) {
- return new Integer( ( int ) value );
- }
- else if ( clazz == Short.class ) {
- return new Short( ( short ) value );
- }
- else {
- throw new IdentifierGenerationException( "this id generator generates long, integer, short" );
- }
- }
-
- /**
- * Disallow instantiation.
- */
- private IdentifierGeneratorFactory() {
- }
-
-}
16 years, 11 months
Hibernate SVN: r15366 - in core/trunk/core/src/main/java/org/hibernate: event/def and 4 other directories.
by hibernate-commits@lists.jboss.org
Author: steve.ebersole(a)jboss.com
Date: 2008-10-21 15:10:17 -0400 (Tue, 21 Oct 2008)
New Revision: 15366
Added:
core/trunk/core/src/main/java/org/hibernate/id/IdentifierGeneratorHelper.java
Modified:
core/trunk/core/src/main/java/org/hibernate/engine/VersionValue.java
core/trunk/core/src/main/java/org/hibernate/event/def/AbstractSaveEventListener.java
core/trunk/core/src/main/java/org/hibernate/id/AbstractPostInsertGenerator.java
core/trunk/core/src/main/java/org/hibernate/id/ForeignGenerator.java
core/trunk/core/src/main/java/org/hibernate/id/IdentityGenerator.java
core/trunk/core/src/main/java/org/hibernate/id/IncrementGenerator.java
core/trunk/core/src/main/java/org/hibernate/id/MultipleHiLoPerTableGenerator.java
core/trunk/core/src/main/java/org/hibernate/id/SequenceGenerator.java
core/trunk/core/src/main/java/org/hibernate/id/SequenceHiLoGenerator.java
core/trunk/core/src/main/java/org/hibernate/id/SequenceIdentityGenerator.java
core/trunk/core/src/main/java/org/hibernate/id/TableHiLoGenerator.java
core/trunk/core/src/main/java/org/hibernate/id/enhanced/OptimizerFactory.java
core/trunk/core/src/main/java/org/hibernate/id/factory/IdentifierGeneratorFactory.java
core/trunk/core/src/main/java/org/hibernate/impl/StatelessSessionImpl.java
Log:
HHH-3512 : id generator short-naming
Modified: core/trunk/core/src/main/java/org/hibernate/engine/VersionValue.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/engine/VersionValue.java 2008-10-21 18:46:51 UTC (rev 15365)
+++ core/trunk/core/src/main/java/org/hibernate/engine/VersionValue.java 2008-10-21 19:10:17 UTC (rev 15366)
@@ -27,7 +27,7 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.hibernate.MappingException;
-import org.hibernate.id.IdentifierGeneratorFactory;
+import org.hibernate.id.IdentifierGeneratorHelper;
/**
* A strategy for determining if a version value is an version of
@@ -91,7 +91,7 @@
}
}
public Object getDefaultValue(Object currentValue) {
- return IdentifierGeneratorFactory.createNumber( -1l, currentValue.getClass() );
+ return IdentifierGeneratorHelper.createNumber( -1l, currentValue.getClass() );
}
public String toString() {
return "VERSION_NEGATIVE";
Modified: core/trunk/core/src/main/java/org/hibernate/event/def/AbstractSaveEventListener.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/event/def/AbstractSaveEventListener.java 2008-10-21 18:46:51 UTC (rev 15365)
+++ core/trunk/core/src/main/java/org/hibernate/event/def/AbstractSaveEventListener.java 2008-10-21 19:10:17 UTC (rev 15366)
@@ -47,7 +47,7 @@
import org.hibernate.engine.Versioning;
import org.hibernate.event.EventSource;
import org.hibernate.id.IdentifierGenerationException;
-import org.hibernate.id.IdentifierGeneratorFactory;
+import org.hibernate.id.IdentifierGeneratorHelper;
import org.hibernate.intercept.FieldInterceptionHelper;
import org.hibernate.intercept.FieldInterceptor;
import org.hibernate.persister.entity.EntityPersister;
@@ -123,10 +123,10 @@
if ( generatedId == null ) {
throw new IdentifierGenerationException( "null id generated for:" + entity.getClass() );
}
- else if ( generatedId == IdentifierGeneratorFactory.SHORT_CIRCUIT_INDICATOR ) {
+ else if ( generatedId == IdentifierGeneratorHelper.SHORT_CIRCUIT_INDICATOR ) {
return source.getIdentifier( entity );
}
- else if ( generatedId == IdentifierGeneratorFactory.POST_INSERT_INDICATOR ) {
+ else if ( generatedId == IdentifierGeneratorHelper.POST_INSERT_INDICATOR ) {
return performSave( entity, null, persister, true, anything, source, requiresImmediateIdAccess );
}
else {
Modified: core/trunk/core/src/main/java/org/hibernate/id/AbstractPostInsertGenerator.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/id/AbstractPostInsertGenerator.java 2008-10-21 18:46:51 UTC (rev 15365)
+++ core/trunk/core/src/main/java/org/hibernate/id/AbstractPostInsertGenerator.java 2008-10-21 19:10:17 UTC (rev 15366)
@@ -39,6 +39,6 @@
* {@inheritDoc}
*/
public Serializable generate(SessionImplementor s, Object obj) {
- return IdentifierGeneratorFactory.POST_INSERT_INDICATOR;
+ return IdentifierGeneratorHelper.POST_INSERT_INDICATOR;
}
}
Modified: core/trunk/core/src/main/java/org/hibernate/id/ForeignGenerator.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/id/ForeignGenerator.java 2008-10-21 18:46:51 UTC (rev 15365)
+++ core/trunk/core/src/main/java/org/hibernate/id/ForeignGenerator.java 2008-10-21 19:10:17 UTC (rev 15366)
@@ -27,7 +27,6 @@
import java.io.Serializable;
import java.util.Properties;
-import org.hibernate.HibernateException;
import org.hibernate.MappingException;
import org.hibernate.Session;
import org.hibernate.TransientObjectException;
@@ -48,27 +47,61 @@
* @author Gavin King
*/
public class ForeignGenerator implements IdentifierGenerator, Configurable {
-
+ private String entityName;
private String propertyName;
- private String entityName;
/**
- * @see org.hibernate.id.IdentifierGenerator#generate(org.hibernate.engine.SessionImplementor, java.lang.Object)
+ * Getter for property 'entityName'.
+ *
+ * @return Value for property 'entityName'.
*/
- public Serializable generate(SessionImplementor sessionImplementor, Object object)
- throws HibernateException {
-
- Session session = (Session) sessionImplementor;
+ public String getEntityName() {
+ return entityName;
+ }
+ /**
+ * Getter for property 'propertyName'.
+ *
+ * @return Value for property 'propertyName'.
+ */
+ public String getPropertyName() {
+ return propertyName;
+ }
+
+ /**
+ * Getter for property 'role'. Role is the {@link #getPropertyName property name} qualified by the
+ * {@link #getEntityName entity name}.
+ *
+ * @return Value for property 'role'.
+ */
+ public String getRole() {
+ return getEntityName() + '.' + getPropertyName();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void configure(Type type, Properties params, Dialect d) {
+ propertyName = params.getProperty( "property" );
+ entityName = params.getProperty( ENTITY_NAME );
+ if ( propertyName==null ) {
+ throw new MappingException( "param named \"property\" is required for foreign id generation strategy" );
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Serializable generate(SessionImplementor sessionImplementor, Object object) {
+ Session session = ( Session ) sessionImplementor;
+
Object associatedObject = sessionImplementor.getFactory()
- .getClassMetadata( entityName )
+ .getClassMetadata( entityName )
.getPropertyValue( object, propertyName, session.getEntityMode() );
-
if ( associatedObject == null ) {
throw new IdentifierGenerationException(
- "attempted to assign id from null one-to-one property: " +
- propertyName
- );
+ "attempted to assign id from null one-to-one property [" + getRole() + "]"
+ );
}
EntityType type = (EntityType) sessionImplementor.getFactory()
@@ -81,7 +114,7 @@
type.getAssociatedEntityName(),
associatedObject,
sessionImplementor
- );
+ );
}
catch (TransientObjectException toe) {
id = session.save( type.getAssociatedEntityName(), associatedObject );
@@ -89,23 +122,9 @@
if ( session.contains(object) ) {
//abort the save (the object is already saved by a circular cascade)
- return IdentifierGeneratorFactory.SHORT_CIRCUIT_INDICATOR;
+ return IdentifierGeneratorHelper.SHORT_CIRCUIT_INDICATOR;
//throw new IdentifierGenerationException("save associated object first, or disable cascade for inverse association");
}
return id;
}
-
- /**
- * @see org.hibernate.id.Configurable#configure(org.hibernate.type.Type, java.util.Properties, org.hibernate.dialect.Dialect)
- */
- public void configure(Type type, Properties params, Dialect d)
- throws MappingException {
-
- propertyName = params.getProperty("property");
- entityName = params.getProperty(ENTITY_NAME);
- if (propertyName==null) throw new MappingException(
- "param named \"property\" is required for foreign id generation strategy"
- );
- }
-
}
Copied: core/trunk/core/src/main/java/org/hibernate/id/IdentifierGeneratorHelper.java (from rev 15266, core/trunk/core/src/main/java/org/hibernate/id/IdentifierGeneratorFactory.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/id/IdentifierGeneratorHelper.java (rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/id/IdentifierGeneratorHelper.java 2008-10-21 19:10:17 UTC (rev 15366)
@@ -0,0 +1,145 @@
+/*
+ * 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
+ *
+ */
+package org.hibernate.id;
+
+import java.io.Serializable;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.hibernate.HibernateException;
+import org.hibernate.type.Type;
+
+/**
+ * Factory and helper methods for <tt>IdentifierGenerator</tt> framework.
+ *
+ * @author Gavin King
+ */
+public final class IdentifierGeneratorHelper {
+ private static final Logger log = LoggerFactory.getLogger( IdentifierGeneratorHelper.class );
+
+ /**
+ * Marker object returned from {@link IdentifierGenerator#generate} to indicate that we should short-circuit any
+ * continued generated id checking. Currently this is only used in the case of the
+ * {@link org.hibernate.id.ForeignGenerator foreign} generator as a way to signal that we should use the associated
+ * entity's id value.
+ */
+ public static final Serializable SHORT_CIRCUIT_INDICATOR = new Serializable() {
+ public String toString() {
+ return "SHORT_CIRCUIT_INDICATOR";
+ }
+ };
+
+ /**
+ * Marker object returned from {@link IdentifierGenerator#generate} to indicate that the entity's identifier will
+ * be generated as part of the datbase insertion.
+ */
+ public static final Serializable POST_INSERT_INDICATOR = new Serializable() {
+ public String toString() {
+ return "POST_INSERT_INDICATOR";
+ }
+ };
+
+
+ /**
+ * Get the generated identifier when using identity columns
+ *
+ * @param rs The result set from which to extract the the generated identity.
+ * @param type The expected type mapping for the identity value.
+ * @return The generated identity value
+ * @throws SQLException Can be thrown while accessing the result set
+ * @throws HibernateException Indicates a problem reading back a generated identity value.
+ */
+ public static Serializable getGeneratedIdentity(ResultSet rs, Type type) throws SQLException, HibernateException {
+ if ( !rs.next() ) {
+ throw new HibernateException( "The database returned no natively generated identity value" );
+ }
+ final Serializable id = IdentifierGeneratorHelper.get( rs, type );
+ log.debug( "Natively generated identity: " + id );
+ return id;
+ }
+
+ /**
+ * Extract the value from the result set (which is assumed to already have been positioned to the apopriate row)
+ * and wrp it in the appropriate Java numeric type.
+ *
+ * @param rs The result set from which to extract the value.
+ * @param type The expected type of the value.
+ * @return The extracted value.
+ * @throws SQLException Indicates problems access the result set
+ * @throws IdentifierGenerationException Indicates an unknown type.
+ */
+ public static Serializable get(ResultSet rs, Type type) throws SQLException, IdentifierGenerationException {
+ Class clazz = type.getReturnedClass();
+ if ( clazz == Long.class ) {
+ return new Long( rs.getLong( 1 ) );
+ }
+ else if ( clazz == Integer.class ) {
+ return new Integer( rs.getInt( 1 ) );
+ }
+ else if ( clazz == Short.class ) {
+ return new Short( rs.getShort( 1 ) );
+ }
+ else if ( clazz == String.class ) {
+ return rs.getString( 1 );
+ }
+ else {
+ throw new IdentifierGenerationException( "this id generator generates long, integer, short or string" );
+ }
+
+ }
+
+ /**
+ * Wrap the given value in the given Java numeric class.
+ *
+ * @param value The primitive value to wrap.
+ * @param clazz The Java numeric type in which to wrap the value.
+ * @return The wrapped type.
+ * @throws IdentifierGenerationException Indicates an unhandled 'clazz'.
+ */
+ public static Number createNumber(long value, Class clazz) throws IdentifierGenerationException {
+ if ( clazz == Long.class ) {
+ return new Long( value );
+ }
+ else if ( clazz == Integer.class ) {
+ return new Integer( ( int ) value );
+ }
+ else if ( clazz == Short.class ) {
+ return new Short( ( short ) value );
+ }
+ else {
+ throw new IdentifierGenerationException( "this id generator generates long, integer, short" );
+ }
+ }
+
+ /**
+ * Disallow instantiation of IdentifierGeneratorHelper.
+ */
+ private IdentifierGeneratorHelper() {
+ }
+
+}
Modified: core/trunk/core/src/main/java/org/hibernate/id/IdentityGenerator.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/id/IdentityGenerator.java 2008-10-21 18:46:51 UTC (rev 15365)
+++ core/trunk/core/src/main/java/org/hibernate/id/IdentityGenerator.java 2008-10-21 19:10:17 UTC (rev 15366)
@@ -95,7 +95,7 @@
ResultSet rs = null;
try {
rs = insert.getGeneratedKeys();
- return IdentifierGeneratorFactory.getGeneratedIdentity(
+ return IdentifierGeneratorHelper.getGeneratedIdentity(
rs,
persister.getIdentifierType()
);
@@ -142,7 +142,7 @@
}
ResultSet rs = insert.getResultSet();
try {
- return IdentifierGeneratorFactory.getGeneratedIdentity( rs, persister.getIdentifierType() );
+ return IdentifierGeneratorHelper.getGeneratedIdentity( rs, persister.getIdentifierType() );
}
finally {
rs.close();
@@ -184,7 +184,7 @@
SessionImplementor session,
ResultSet rs,
Object object) throws SQLException {
- return IdentifierGeneratorFactory.getGeneratedIdentity( rs, persister.getIdentifierType() );
+ return IdentifierGeneratorHelper.getGeneratedIdentity( rs, persister.getIdentifierType() );
}
}
Modified: core/trunk/core/src/main/java/org/hibernate/id/IncrementGenerator.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/id/IncrementGenerator.java 2008-10-21 18:46:51 UTC (rev 15365)
+++ core/trunk/core/src/main/java/org/hibernate/id/IncrementGenerator.java 2008-10-21 19:10:17 UTC (rev 15366)
@@ -67,7 +67,7 @@
if (sql!=null) {
getNext( session );
}
- return IdentifierGeneratorFactory.createNumber(next++, returnClass);
+ return IdentifierGeneratorHelper.createNumber(next++, returnClass);
}
public void configure(Type type, Properties params, Dialect dialect)
Modified: core/trunk/core/src/main/java/org/hibernate/id/MultipleHiLoPerTableGenerator.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/id/MultipleHiLoPerTableGenerator.java 2008-10-21 18:46:51 UTC (rev 15365)
+++ core/trunk/core/src/main/java/org/hibernate/id/MultipleHiLoPerTableGenerator.java 2008-10-21 19:10:17 UTC (rev 15366)
@@ -209,7 +209,7 @@
//keep the behavior consistent even for boundary usages
int val = ( (Integer) doWorkInNewTransaction(session) ).intValue();
if (val == 0) val = ( (Integer) doWorkInNewTransaction(session) ).intValue();
- return IdentifierGeneratorFactory.createNumber( val, returnClass );
+ return IdentifierGeneratorHelper.createNumber( val, returnClass );
}
if (lo>maxLo) {
int hival = ( (Integer) doWorkInNewTransaction(session) ).intValue();
@@ -217,7 +217,7 @@
hi = hival * (maxLo+1);
log.debug("new hi value: " + hival);
}
- return IdentifierGeneratorFactory.createNumber( hi + lo++, returnClass );
+ return IdentifierGeneratorHelper.createNumber( hi + lo++, returnClass );
}
public void configure(Type type, Properties params, Dialect dialect) throws MappingException {
Modified: core/trunk/core/src/main/java/org/hibernate/id/SequenceGenerator.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/id/SequenceGenerator.java 2008-10-21 18:46:51 UTC (rev 15365)
+++ core/trunk/core/src/main/java/org/hibernate/id/SequenceGenerator.java 2008-10-21 19:10:17 UTC (rev 15366)
@@ -98,7 +98,7 @@
ResultSet rs = st.executeQuery();
try {
rs.next();
- Serializable result = IdentifierGeneratorFactory.get(
+ Serializable result = IdentifierGeneratorHelper.get(
rs, identifierType
);
if ( log.isDebugEnabled() ) {
Modified: core/trunk/core/src/main/java/org/hibernate/id/SequenceHiLoGenerator.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/id/SequenceHiLoGenerator.java 2008-10-21 18:46:51 UTC (rev 15365)
+++ core/trunk/core/src/main/java/org/hibernate/id/SequenceHiLoGenerator.java 2008-10-21 19:10:17 UTC (rev 15366)
@@ -75,7 +75,7 @@
//keep the behavior consistent even for boundary usages
long val = ( (Number) super.generate(session, obj) ).longValue();
if (val == 0) val = ( (Number) super.generate(session, obj) ).longValue();
- return IdentifierGeneratorFactory.createNumber( val, returnClass );
+ return IdentifierGeneratorHelper.createNumber( val, returnClass );
}
if ( lo>maxLo ) {
long hival = ( (Number) super.generate(session, obj) ).longValue();
@@ -85,7 +85,7 @@
log.debug("new hi value: " + hival);
}
- return IdentifierGeneratorFactory.createNumber( hi + lo++, returnClass );
+ return IdentifierGeneratorHelper.createNumber( hi + lo++, returnClass );
}
}
Modified: core/trunk/core/src/main/java/org/hibernate/id/SequenceIdentityGenerator.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/id/SequenceIdentityGenerator.java 2008-10-21 18:46:51 UTC (rev 15365)
+++ core/trunk/core/src/main/java/org/hibernate/id/SequenceIdentityGenerator.java 2008-10-21 19:10:17 UTC (rev 15366)
@@ -60,7 +60,7 @@
private static final Logger log = LoggerFactory.getLogger( SequenceIdentityGenerator.class );
public Serializable generate(SessionImplementor s, Object obj) {
- return IdentifierGeneratorFactory.POST_INSERT_INDICATOR;
+ return IdentifierGeneratorHelper.POST_INSERT_INDICATOR;
}
public InsertGeneratedIdentifierDelegate getInsertGeneratedIdentifierDelegate(
@@ -101,7 +101,7 @@
protected Serializable executeAndExtract(PreparedStatement insert) throws SQLException {
insert.executeUpdate();
- return IdentifierGeneratorFactory.getGeneratedIdentity(
+ return IdentifierGeneratorHelper.getGeneratedIdentity(
insert.getGeneratedKeys(),
getPersister().getIdentifierType()
);
Modified: core/trunk/core/src/main/java/org/hibernate/id/TableHiLoGenerator.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/id/TableHiLoGenerator.java 2008-10-21 18:46:51 UTC (rev 15365)
+++ core/trunk/core/src/main/java/org/hibernate/id/TableHiLoGenerator.java 2008-10-21 19:10:17 UTC (rev 15366)
@@ -78,7 +78,7 @@
//keep the behavior consistent even for boundary usages
long val = ( (Number) super.generate(session, obj) ).longValue();
if (val == 0) val = ( (Number) super.generate(session, obj) ).longValue();
- return IdentifierGeneratorFactory.createNumber( val, returnClass );
+ return IdentifierGeneratorHelper.createNumber( val, returnClass );
}
if (lo>maxLo) {
long hival = ( (Number) super.generate(session, obj) ).longValue();
@@ -87,7 +87,7 @@
log.debug("new hi value: " + hival);
}
- return IdentifierGeneratorFactory.createNumber( hi + lo++, returnClass );
+ return IdentifierGeneratorHelper.createNumber( hi + lo++, returnClass );
}
Modified: core/trunk/core/src/main/java/org/hibernate/id/enhanced/OptimizerFactory.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/id/enhanced/OptimizerFactory.java 2008-10-21 18:46:51 UTC (rev 15365)
+++ core/trunk/core/src/main/java/org/hibernate/id/enhanced/OptimizerFactory.java 2008-10-21 19:10:17 UTC (rev 15366)
@@ -32,7 +32,7 @@
import org.hibernate.HibernateException;
import org.hibernate.util.ReflectHelper;
-import org.hibernate.id.IdentifierGeneratorFactory;
+import org.hibernate.id.IdentifierGeneratorHelper;
/**
* Factory for {@link Optimizer} instances.
@@ -105,7 +105,7 @@
* @return The wrapped value.
*/
protected final Serializable make(long value) {
- return IdentifierGeneratorFactory.createNumber( value, returnClass );
+ return IdentifierGeneratorHelper.createNumber( value, returnClass );
}
/**
Modified: core/trunk/core/src/main/java/org/hibernate/id/factory/IdentifierGeneratorFactory.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/id/factory/IdentifierGeneratorFactory.java 2008-10-21 18:46:51 UTC (rev 15365)
+++ core/trunk/core/src/main/java/org/hibernate/id/factory/IdentifierGeneratorFactory.java 2008-10-21 19:10:17 UTC (rev 15366)
@@ -39,28 +39,6 @@
public interface IdentifierGeneratorFactory {
/**
- * Marker object returned from {@link IdentifierGenerator#generate} to indicate that we should short-circuit any
- * continued generated id checking. Currently this is only used in the case of the
- * {@link org.hibernate.id.ForeignGenerator foreign} generator as a way to signal that we should use the associated
- * entity's id value.
- */
- public static final Serializable SHORT_CIRCUIT_INDICATOR = new Serializable() {
- public String toString() {
- return "SHORT_CIRCUIT_INDICATOR";
- }
- };
-
- /**
- * Marker object returned from {@link IdentifierGenerator#generate} to indicate that the entity's identifier will
- * be generated as part of the datbase insertion.
- */
- public static final Serializable POST_INSERT_INDICATOR = new Serializable() {
- public String toString() {
- return "POST_INSERT_INDICATOR";
- }
- };
-
- /**
* Allow injection of the dialect to use.
*
* @param dialect The dialect
Modified: core/trunk/core/src/main/java/org/hibernate/impl/StatelessSessionImpl.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/impl/StatelessSessionImpl.java 2008-10-21 18:46:51 UTC (rev 15365)
+++ core/trunk/core/src/main/java/org/hibernate/impl/StatelessSessionImpl.java 2008-10-21 19:10:17 UTC (rev 15366)
@@ -62,7 +62,7 @@
import org.hibernate.engine.query.NativeSQLQueryPlan;
import org.hibernate.engine.query.sql.NativeSQLQuerySpecification;
import org.hibernate.event.EventListeners;
-import org.hibernate.id.IdentifierGeneratorFactory;
+import org.hibernate.id.IdentifierGeneratorHelper;
import org.hibernate.jdbc.Batcher;
import org.hibernate.jdbc.JDBCContext;
import org.hibernate.loader.criteria.CriteriaLoader;
@@ -110,7 +110,7 @@
persister.setPropertyValues( entity, state, EntityMode.POJO );
}
}
- if ( id == IdentifierGeneratorFactory.POST_INSERT_INDICATOR ) {
+ if ( id == IdentifierGeneratorHelper.POST_INSERT_INDICATOR ) {
id = persister.insert(state, entity, this);
}
else {
16 years, 11 months
Hibernate SVN: r15365 - in core/trunk: core/src/main/java/org/hibernate/engine and 7 other directories.
by hibernate-commits@lists.jboss.org
Author: steve.ebersole(a)jboss.com
Date: 2008-10-21 14:46:51 -0400 (Tue, 21 Oct 2008)
New Revision: 15365
Added:
core/trunk/core/src/main/java/org/hibernate/id/factory/
core/trunk/core/src/main/java/org/hibernate/id/factory/DefaultIdentifierGeneratorFactory.java
core/trunk/core/src/main/java/org/hibernate/id/factory/IdentifierGeneratorFactory.java
Modified:
core/trunk/core/src/main/java/org/hibernate/cfg/Configuration.java
core/trunk/core/src/main/java/org/hibernate/cfg/HbmBinder.java
core/trunk/core/src/main/java/org/hibernate/cfg/Mappings.java
core/trunk/core/src/main/java/org/hibernate/engine/Mapping.java
core/trunk/core/src/main/java/org/hibernate/impl/SessionFactoryImpl.java
core/trunk/core/src/main/java/org/hibernate/mapping/KeyValue.java
core/trunk/core/src/main/java/org/hibernate/mapping/SimpleValue.java
core/trunk/core/src/main/java/org/hibernate/mapping/Table.java
core/trunk/core/src/main/java/org/hibernate/persister/collection/AbstractCollectionPersister.java
core/trunk/core/src/main/resources/org/hibernate/hibernate-mapping-3.0.dtd
core/trunk/testsuite/src/test/java/org/hibernate/test/idgen/enhanced/table/Basic.hbm.xml
core/trunk/testsuite/src/test/java/org/hibernate/test/idgen/enhanced/table/HiLo.hbm.xml
Log:
HHH-3512 : id generator short-naming
Modified: core/trunk/core/src/main/java/org/hibernate/cfg/Configuration.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cfg/Configuration.java 2008-10-21 16:26:57 UTC (rev 15364)
+++ core/trunk/core/src/main/java/org/hibernate/cfg/Configuration.java 2008-10-21 18:46:51 UTC (rev 15365)
@@ -108,6 +108,8 @@
import org.hibernate.event.SaveOrUpdateEventListener;
import org.hibernate.id.IdentifierGenerator;
import org.hibernate.id.PersistentIdentifierGenerator;
+import org.hibernate.id.factory.IdentifierGeneratorFactory;
+import org.hibernate.id.factory.DefaultIdentifierGeneratorFactory;
import org.hibernate.impl.SessionFactoryImpl;
import org.hibernate.mapping.AuxiliaryDatabaseObject;
import org.hibernate.mapping.Collection;
@@ -202,6 +204,8 @@
private transient Mapping mapping = buildMapping();
+ private DefaultIdentifierGeneratorFactory identifierGeneratorFactory;
+
protected Configuration(SettingsFactory settingsFactory) {
this.settingsFactory = settingsFactory;
reset();
@@ -245,6 +249,8 @@
entityTuplizerFactory = new EntityTuplizerFactory();
// componentTuplizerFactory = new ComponentTuplizerFactory();
+
+ identifierGeneratorFactory = new DefaultIdentifierGeneratorFactory();
}
public EntityTuplizerFactory getEntityTuplizerFactory() {
@@ -750,43 +756,37 @@
Iterator iter = classes.values().iterator();
while ( iter.hasNext() ) {
- PersistentClass pc = (PersistentClass) iter.next();
-
+ PersistentClass pc = ( PersistentClass ) iter.next();
if ( !pc.isInherited() ) {
+ IdentifierGenerator ig = pc.getIdentifier().createIdentifierGenerator(
+ getIdentifierGeneratorFactory(),
+ dialect,
+ defaultCatalog,
+ defaultSchema,
+ (RootClass) pc
+ );
- IdentifierGenerator ig = pc.getIdentifier()
- .createIdentifierGenerator(
- dialect,
- defaultCatalog,
- defaultSchema,
- (RootClass) pc
- );
-
if ( ig instanceof PersistentIdentifierGenerator ) {
generators.put( ( (PersistentIdentifierGenerator) ig ).generatorKey(), ig );
}
-
}
}
iter = collections.values().iterator();
while ( iter.hasNext() ) {
- Collection collection = (Collection) iter.next();
-
+ Collection collection = ( Collection ) iter.next();
if ( collection.isIdentified() ) {
+ IdentifierGenerator ig = ( ( IdentifierCollection ) collection ).getIdentifier().createIdentifierGenerator(
+ getIdentifierGeneratorFactory(),
+ dialect,
+ defaultCatalog,
+ defaultSchema,
+ null
+ );
- IdentifierGenerator ig = ( (IdentifierCollection) collection ).getIdentifier()
- .createIdentifierGenerator(
- dialect,
- defaultCatalog,
- defaultSchema,
- null
- );
-
if ( ig instanceof PersistentIdentifierGenerator ) {
generators.put( ( (PersistentIdentifierGenerator) ig ).generatorKey(), ig );
}
-
}
}
@@ -2147,8 +2147,21 @@
return this;
}
+ /**
+ * Retrieve the IdentifierGeneratorFactory in effect for this configuration.
+ *
+ * @return This configuration's IdentifierGeneratorFactory.
+ */
+ public DefaultIdentifierGeneratorFactory getIdentifierGeneratorFactory() {
+ return identifierGeneratorFactory;
+ }
+
public Mapping buildMapping() {
return new Mapping() {
+ public IdentifierGeneratorFactory getIdentifierGeneratorFactory() {
+ return identifierGeneratorFactory;
+ }
+
/**
* Returns the identifier type of a mapped class
*/
@@ -2718,5 +2731,8 @@
extendsQueue.put( entry, null );
}
+ public DefaultIdentifierGeneratorFactory getIdentifierGeneratorFactory() {
+ return identifierGeneratorFactory;
+ }
}
}
Modified: core/trunk/core/src/main/java/org/hibernate/cfg/HbmBinder.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cfg/HbmBinder.java 2008-10-21 16:26:57 UTC (rev 15364)
+++ core/trunk/core/src/main/java/org/hibernate/cfg/HbmBinder.java 2008-10-21 18:46:51 UTC (rev 15365)
@@ -162,6 +162,9 @@
else if ( "fetch-profile".equals( elementName ) ) {
parseFetchProfile( element, mappings, null );
}
+ else if ( "identifier-generator".equals( elementName ) ) {
+ parseIdentifierGeneratorRegistration( element, mappings );
+ }
else if ( "typedef".equals( elementName ) ) {
bindTypeDef( element, mappings );
}
@@ -200,6 +203,26 @@
}
}
+ private static void parseIdentifierGeneratorRegistration(Element element, Mappings mappings) {
+ String strategy = element.attributeValue( "name" );
+ if ( StringHelper.isEmpty( strategy ) ) {
+ throw new MappingException( "'name' attribute expected for identifier-generator elements" );
+ }
+ String generatorClassName = element.attributeValue( "class" );
+ if ( StringHelper.isEmpty( generatorClassName ) ) {
+ throw new MappingException( "'class' attribute expected for identifier-generator [identifier-generator@name=" + strategy + "]" );
+ }
+
+ try {
+ Class generatorClass = ReflectHelper.classForName( generatorClassName );
+ mappings.getIdentifierGeneratorFactory().register( strategy, generatorClass );
+ }
+ catch ( ClassNotFoundException e ) {
+ throw new MappingException( "Unable to locate identifier-generator class [name=" + strategy + ", class=" + generatorClassName + "]" );
+ }
+
+ }
+
private static void bindImport(Element importNode, Mappings mappings) {
String className = getClassName( importNode.attribute( "class" ), mappings );
Attribute renameNode = importNode.attribute( "rename" );
Modified: core/trunk/core/src/main/java/org/hibernate/cfg/Mappings.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cfg/Mappings.java 2008-10-21 16:26:57 UTC (rev 15364)
+++ core/trunk/core/src/main/java/org/hibernate/cfg/Mappings.java 2008-10-21 18:46:51 UTC (rev 15365)
@@ -32,6 +32,7 @@
import org.hibernate.DuplicateMappingException;
import org.hibernate.MappingException;
+import org.hibernate.id.factory.DefaultIdentifierGeneratorFactory;
import org.hibernate.engine.FilterDefinition;
import org.hibernate.engine.NamedQueryDefinition;
import org.hibernate.engine.NamedSQLQueryDefinition;
@@ -518,4 +519,11 @@
* @param entry The entry to add.
*/
public void addToExtendsQueue(ExtendsQueueEntry entry);
+
+ /**
+ * Retrieve the IdentifierGeneratorFactory in effect for this mapping.
+ *
+ * @return The IdentifierGeneratorFactory
+ */
+ public DefaultIdentifierGeneratorFactory getIdentifierGeneratorFactory();
}
\ No newline at end of file
Modified: core/trunk/core/src/main/java/org/hibernate/engine/Mapping.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/engine/Mapping.java 2008-10-21 16:26:57 UTC (rev 15364)
+++ core/trunk/core/src/main/java/org/hibernate/engine/Mapping.java 2008-10-21 18:46:51 UTC (rev 15365)
@@ -25,6 +25,7 @@
package org.hibernate.engine;
import org.hibernate.MappingException;
+import org.hibernate.id.factory.IdentifierGeneratorFactory;
import org.hibernate.type.Type;
/**
@@ -38,6 +39,12 @@
* @author Gavin King
*/
public interface Mapping {
+ /**
+ * Allow access to the id generator factory, though this is only needed/allowed from configuration.
+ * @return
+ * @deprecated temporary solution
+ */
+ public IdentifierGeneratorFactory getIdentifierGeneratorFactory();
public Type getIdentifierType(String className) throws MappingException;
public String getIdentifierPropertyName(String className) throws MappingException;
public Type getReferencedPropertyType(String className, String propertyName) throws MappingException;
Added: core/trunk/core/src/main/java/org/hibernate/id/factory/DefaultIdentifierGeneratorFactory.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/id/factory/DefaultIdentifierGeneratorFactory.java (rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/id/factory/DefaultIdentifierGeneratorFactory.java 2008-10-21 18:46:51 UTC (rev 15365)
@@ -0,0 +1,139 @@
+/*
+ * 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
+ *
+ */
+package org.hibernate.id.factory;
+
+import java.util.Properties;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.hibernate.id.IdentifierGenerator;
+import org.hibernate.id.UUIDHexGenerator;
+import org.hibernate.id.TableHiLoGenerator;
+import org.hibernate.id.Assigned;
+import org.hibernate.id.IdentityGenerator;
+import org.hibernate.id.SelectGenerator;
+import org.hibernate.id.SequenceGenerator;
+import org.hibernate.id.SequenceHiLoGenerator;
+import org.hibernate.id.IncrementGenerator;
+import org.hibernate.id.ForeignGenerator;
+import org.hibernate.id.GUIDGenerator;
+import org.hibernate.id.SequenceIdentityGenerator;
+import org.hibernate.id.Configurable;
+import org.hibernate.id.enhanced.SequenceStyleGenerator;
+import org.hibernate.id.enhanced.TableGenerator;
+import org.hibernate.type.Type;
+import org.hibernate.util.FastHashMap;
+import org.hibernate.util.ReflectHelper;
+import org.hibernate.dialect.Dialect;
+import org.hibernate.MappingException;
+
+/**
+ * Basic <tt>templated</tt> support for {@link IdentifierGeneratorFactory} implementations.
+ *
+ * @author Steve Ebersole
+ */
+public class DefaultIdentifierGeneratorFactory implements IdentifierGeneratorFactory {
+ private static final Logger log = LoggerFactory.getLogger( DefaultIdentifierGeneratorFactory.class );
+
+ private Dialect dialect;
+ private FastHashMap generatorStrategyToClassNameMap = new FastHashMap();
+
+ /**
+ * Constructs a new DefaultIdentifierGeneratorFactory.
+ */
+ public DefaultIdentifierGeneratorFactory() {
+ register( "uuid", UUIDHexGenerator.class );
+ register( "hilo", TableHiLoGenerator.class );
+ register( "assigned", Assigned.class );
+ register( "identity", IdentityGenerator.class );
+ register( "select", SelectGenerator.class );
+ register( "sequence", SequenceGenerator.class );
+ register( "seqhilo", SequenceHiLoGenerator.class );
+ register( "increment", IncrementGenerator.class );
+ register( "foreign", ForeignGenerator.class );
+ register( "guid", GUIDGenerator.class );
+ register( "uuid.hex", UUIDHexGenerator.class ); // uuid.hex is deprecated
+ register( "sequence-identity", SequenceIdentityGenerator.class );
+ register( "enhanced-sequence", SequenceStyleGenerator.class );
+ register( "enhanced-table", TableGenerator.class );
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void setDialect(Dialect dialect) {
+ log.debug( "Setting dialect [" + dialect + "]" );
+ this.dialect = dialect;
+ }
+
+ public void register(String strategy, Class generatorClass) {
+ String msg = "Registering IdentifierGenerator strategy [" + strategy + "] -> [" + generatorClass + "]";
+ Object old = generatorStrategyToClassNameMap.put( strategy, generatorClass );
+ if ( old != null ) {
+ msg += ", overriding [" + old + "]";
+ }
+ log.debug( msg );
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public IdentifierGenerator createIdentifierGenerator(String strategy, Type type, Properties config) {
+ try {
+ Class clazz = getIdentifierGeneratorClass( strategy );
+ IdentifierGenerator idgen = ( IdentifierGenerator ) clazz.newInstance();
+ if ( idgen instanceof Configurable ) {
+ ( ( Configurable ) idgen ).configure( type, config, dialect );
+ }
+ return idgen;
+ }
+ catch ( Exception e ) {
+ String msg = "Could not instantiate id generator [entity-name="
+ + config.get( IdentifierGenerator.ENTITY_NAME ) + "]";
+ throw new MappingException( msg, e );
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Class getIdentifierGeneratorClass(String strategy) {
+ if ( "native".equals( strategy ) ) {
+ return dialect.getNativeIdentifierGeneratorClass();
+ }
+
+ Class generatorClass = ( Class ) generatorStrategyToClassNameMap.get( strategy );
+ try {
+ if ( generatorClass == null ) {
+ generatorClass = ReflectHelper.classForName( strategy );
+ }
+ }
+ catch ( ClassNotFoundException e ) {
+ throw new MappingException( "Could not interpret id generator strategy [" + strategy + "]" );
+ }
+ return generatorClass;
+ }
+}
Added: core/trunk/core/src/main/java/org/hibernate/id/factory/IdentifierGeneratorFactory.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/id/factory/IdentifierGeneratorFactory.java (rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/id/factory/IdentifierGeneratorFactory.java 2008-10-21 18:46:51 UTC (rev 15365)
@@ -0,0 +1,90 @@
+/*
+ * 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
+ *
+ */
+package org.hibernate.id.factory;
+
+import java.util.Properties;
+import java.io.Serializable;
+
+import org.hibernate.id.IdentifierGenerator;
+import org.hibernate.type.Type;
+import org.hibernate.dialect.Dialect;
+
+/**
+ * Contract for a <tt>factory</tt> of {@link IdentifierGenerator} instances.
+ *
+ * @author Steve Ebersole
+ */
+public interface IdentifierGeneratorFactory {
+
+ /**
+ * Marker object returned from {@link IdentifierGenerator#generate} to indicate that we should short-circuit any
+ * continued generated id checking. Currently this is only used in the case of the
+ * {@link org.hibernate.id.ForeignGenerator foreign} generator as a way to signal that we should use the associated
+ * entity's id value.
+ */
+ public static final Serializable SHORT_CIRCUIT_INDICATOR = new Serializable() {
+ public String toString() {
+ return "SHORT_CIRCUIT_INDICATOR";
+ }
+ };
+
+ /**
+ * Marker object returned from {@link IdentifierGenerator#generate} to indicate that the entity's identifier will
+ * be generated as part of the datbase insertion.
+ */
+ public static final Serializable POST_INSERT_INDICATOR = new Serializable() {
+ public String toString() {
+ return "POST_INSERT_INDICATOR";
+ }
+ };
+
+ /**
+ * Allow injection of the dialect to use.
+ *
+ * @param dialect The dialect
+ * @deprecated The intention is that Dialect should be required to be specified up-front and it would then get
+ * ctor injected.
+ */
+ public void setDialect(Dialect dialect);
+
+ /**
+ * Given a strategy, retrieve the appropriate identifier generator instance.
+ *
+ * @param strategy The generation strategy.
+ * @param type The mapping type for the identifier values.
+ * @param config Any configuraion properties given in the generator mapping.
+ *
+ * @return The appropriate generator instance.
+ */
+ public IdentifierGenerator createIdentifierGenerator(String strategy, Type type, Properties config);
+
+ /**
+ * Retrieve the class that will be used as the {@link IdentifierGenerator} for the given strategy.
+ *
+ * @param strategy The strategy
+ * @return The generator class.
+ */
+ public Class getIdentifierGeneratorClass(String strategy);
+}
Modified: core/trunk/core/src/main/java/org/hibernate/impl/SessionFactoryImpl.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/impl/SessionFactoryImpl.java 2008-10-21 16:26:57 UTC (rev 15364)
+++ core/trunk/core/src/main/java/org/hibernate/impl/SessionFactoryImpl.java 2008-10-21 18:46:51 UTC (rev 15365)
@@ -96,6 +96,7 @@
import org.hibernate.exception.SQLExceptionConverter;
import org.hibernate.id.IdentifierGenerator;
import org.hibernate.id.UUIDHexGenerator;
+import org.hibernate.id.factory.IdentifierGeneratorFactory;
import org.hibernate.jdbc.BatcherFactory;
import org.hibernate.mapping.Collection;
import org.hibernate.mapping.PersistentClass;
@@ -233,11 +234,12 @@
PersistentClass model = (PersistentClass) classes.next();
if ( !model.isInherited() ) {
IdentifierGenerator generator = model.getIdentifier().createIdentifierGenerator(
+ cfg.getIdentifierGeneratorFactory(),
settings.getDialect(),
settings.getDefaultCatalogName(),
settings.getDefaultSchemaName(),
(RootClass) model
- );
+ );
identifierGenerators.put( model.getEntityName(), generator );
}
}
@@ -467,6 +469,10 @@
this.observer.sessionFactoryCreated( this );
}
+ public IdentifierGeneratorFactory getIdentifierGeneratorFactory() {
+ return null;
+ }
+
private void registerEntityNameResolvers(EntityPersister persister) {
if ( persister.getEntityMetamodel() == null || persister.getEntityMetamodel().getTuplizerMapping() == null ) {
return;
Modified: core/trunk/core/src/main/java/org/hibernate/mapping/KeyValue.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/mapping/KeyValue.java 2008-10-21 16:26:57 UTC (rev 15364)
+++ core/trunk/core/src/main/java/org/hibernate/mapping/KeyValue.java 2008-10-21 18:46:51 UTC (rev 15365)
@@ -27,6 +27,7 @@
import org.hibernate.MappingException;
import org.hibernate.dialect.Dialect;
import org.hibernate.id.IdentifierGenerator;
+import org.hibernate.id.factory.IdentifierGeneratorFactory;
/**
* Represents an identifying key of a table: the value for primary key
@@ -35,20 +36,21 @@
* @author Gavin King
*/
public interface KeyValue extends Value {
+
+ public IdentifierGenerator createIdentifierGenerator(
+ IdentifierGeneratorFactory identifierGeneratorFactory,
+ Dialect dialect,
+ String defaultCatalog,
+ String defaultSchema,
+ RootClass rootClass) throws MappingException;
+
+ public boolean isIdentityColumn(IdentifierGeneratorFactory identifierGeneratorFactory, Dialect dialect);
public void createForeignKeyOfEntity(String entityName);
public boolean isCascadeDeleteEnabled();
- public boolean isIdentityColumn(Dialect dialect);
-
public String getNullValue();
public boolean isUpdateable();
-
- public IdentifierGenerator createIdentifierGenerator(
- Dialect dialect,
- String defaultCatalog,
- String defaultSchema,
- RootClass rootClass) throws MappingException;
}
Modified: core/trunk/core/src/main/java/org/hibernate/mapping/SimpleValue.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/mapping/SimpleValue.java 2008-10-21 16:26:57 UTC (rev 15364)
+++ core/trunk/core/src/main/java/org/hibernate/mapping/SimpleValue.java 2008-10-21 18:46:51 UTC (rev 15365)
@@ -34,9 +34,9 @@
import org.hibernate.dialect.Dialect;
import org.hibernate.engine.Mapping;
import org.hibernate.id.IdentifierGenerator;
-import org.hibernate.id.IdentifierGeneratorFactory;
import org.hibernate.id.IdentityGenerator;
import org.hibernate.id.PersistentIdentifierGenerator;
+import org.hibernate.id.factory.IdentifierGeneratorFactory;
import org.hibernate.type.Type;
import org.hibernate.type.TypeFactory;
import org.hibernate.util.ReflectHelper;
@@ -120,6 +120,7 @@
}
public IdentifierGenerator createIdentifierGenerator(
+ IdentifierGeneratorFactory identifierGeneratorFactory,
Dialect dialect,
String defaultCatalog,
String defaultSchema,
@@ -171,14 +172,10 @@
if (identifierGeneratorProperties!=null) {
params.putAll(identifierGeneratorProperties);
}
+
+ identifierGeneratorFactory.setDialect( dialect );
+ return identifierGeneratorFactory.createIdentifierGenerator( identifierGeneratorStrategy, getType(), params );
- return IdentifierGeneratorFactory.create(
- identifierGeneratorStrategy,
- getType(),
- params,
- dialect
- );
-
}
public boolean isUpdateable() {
@@ -210,9 +207,10 @@
return identifierGeneratorStrategy;
}
- public boolean isIdentityColumn(Dialect dialect) {
- return IdentifierGeneratorFactory.getIdentifierGeneratorClass(identifierGeneratorStrategy, dialect)
- .equals(IdentityGenerator.class);
+ public boolean isIdentityColumn(IdentifierGeneratorFactory identifierGeneratorFactory, Dialect dialect) {
+ identifierGeneratorFactory.setDialect( dialect );
+ return identifierGeneratorFactory.getIdentifierGeneratorClass( identifierGeneratorStrategy )
+ .equals( IdentityGenerator.class );
}
/**
Modified: core/trunk/core/src/main/java/org/hibernate/mapping/Table.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/mapping/Table.java 2008-10-21 16:26:57 UTC (rev 15364)
+++ core/trunk/core/src/main/java/org/hibernate/mapping/Table.java 2008-10-21 18:46:51 UTC (rev 15365)
@@ -392,7 +392,7 @@
.append( getQualifiedName( dialect, defaultCatalog, defaultSchema ) )
.append( " (" );
- boolean identityColumn = idValue != null && idValue.isIdentityColumn( dialect );
+ boolean identityColumn = idValue != null && idValue.isIdentityColumn( p.getIdentifierGeneratorFactory(), dialect );
// Try to find out the name of the primary key to create it as identity if the IdentityGenerator is used
String pkname = null;
Modified: core/trunk/core/src/main/java/org/hibernate/persister/collection/AbstractCollectionPersister.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/persister/collection/AbstractCollectionPersister.java 2008-10-21 16:26:57 UTC (rev 15364)
+++ core/trunk/core/src/main/java/org/hibernate/persister/collection/AbstractCollectionPersister.java 2008-10-21 18:46:51 UTC (rev 15365)
@@ -421,12 +421,13 @@
identifierColumnName = col.getQuotedName(dialect);
identifierColumnAlias = col.getAlias(dialect);
//unquotedIdentifierColumnName = identifierColumnAlias;
- identifierGenerator = idColl.getIdentifier().createIdentifierGenerator(
+ identifierGenerator = idColl.getIdentifier().createIdentifierGenerator(
+ cfg.getIdentifierGeneratorFactory(),
factory.getDialect(),
factory.getSettings().getDefaultCatalogName(),
factory.getSettings().getDefaultSchemaName(),
null
- );
+ );
}
else {
identifierType = null;
Modified: core/trunk/core/src/main/resources/org/hibernate/hibernate-mapping-3.0.dtd
===================================================================
--- core/trunk/core/src/main/resources/org/hibernate/hibernate-mapping-3.0.dtd 2008-10-21 16:26:57 UTC (rev 15364)
+++ core/trunk/core/src/main/resources/org/hibernate/hibernate-mapping-3.0.dtd 2008-10-21 18:46:51 UTC (rev 15365)
@@ -17,8 +17,10 @@
-->
<!ELEMENT hibernate-mapping (
- meta*,
- typedef*,
+ meta*,
+ identifier-generator*,
+ typedef*,
+ filter-def*,
import*,
(class|subclass|joined-subclass|union-subclass)*,
resultset*,
@@ -36,7 +38,7 @@
<!ATTLIST hibernate-mapping package CDATA #IMPLIED> <!-- default: none -->
<!--
- META element definition; used to assign meta-level attributes to a class
+ <meta.../> is used to assign meta-level attributes to a class
or property. Is currently used by codegenerator as a placeholder for
values that is not directly related to OR mappings.
-->
@@ -45,7 +47,14 @@
<!ATTLIST meta inherit (true|false) "true">
<!--
- TYPEDEF element definition; defines a new name for a Hibernate type. May
+ <identifier-generator.../> allows customized short-naming of IdentifierGenerator implementations.
+-->
+<!ELEMENT identifier-generator EMPTY>
+ <!ATTLIST identifier-generator name CDATA #REQUIRED>
+ <!ATTLIST identifier-generator class CDATA #REQUIRED>
+
+<!--
+ <typedef.../> allows defining a customized type mapping for a Hibernate type. May
contain parameters for parameterizable types.
-->
<!ELEMENT typedef (param*)>
Modified: core/trunk/testsuite/src/test/java/org/hibernate/test/idgen/enhanced/table/Basic.hbm.xml
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/idgen/enhanced/table/Basic.hbm.xml 2008-10-21 16:26:57 UTC (rev 15364)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/idgen/enhanced/table/Basic.hbm.xml 2008-10-21 18:46:51 UTC (rev 15365)
@@ -5,9 +5,11 @@
<hibernate-mapping package="org.hibernate.test.idgen.enhanced.table">
+ <identifier-generator name="table" class="org.hibernate.id.enhanced.TableGenerator"/>
+
<class name="Entity" table="ID_TBL_BSC_ENTITY">
<id name="id" column="ID" type="long">
- <generator class="org.hibernate.id.enhanced.TableGenerator">
+ <generator class="table">
<param name="table_name">ID_TBL_BSC_TBL</param>
<param name="segment_value">test</param>
<param name="initial_value">1</param>
Modified: core/trunk/testsuite/src/test/java/org/hibernate/test/idgen/enhanced/table/HiLo.hbm.xml
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/idgen/enhanced/table/HiLo.hbm.xml 2008-10-21 16:26:57 UTC (rev 15364)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/idgen/enhanced/table/HiLo.hbm.xml 2008-10-21 18:46:51 UTC (rev 15365)
@@ -5,9 +5,11 @@
<hibernate-mapping package="org.hibernate.test.idgen.enhanced.table">
+ <identifier-generator name="table" class="org.hibernate.id.enhanced.TableGenerator"/>
+
<class name="Entity" table="ID_TBL_HILO_ENTITY">
<id name="id" column="ID" type="long">
- <generator class="org.hibernate.id.enhanced.TableGenerator">
+ <generator class="table">
<param name="table_name">ID_TBL_HILO_TBL</param>
<param name="segment_value">test</param>
<param name="initial_value">1</param>
16 years, 11 months
Hibernate SVN: r15364 - search/trunk/src/java/org/hibernate/search/backend/impl/lucene/works.
by hibernate-commits@lists.jboss.org
Author: sannegrinovero
Date: 2008-10-21 12:26:57 -0400 (Tue, 21 Oct 2008)
New Revision: 15364
Modified:
search/trunk/src/java/org/hibernate/search/backend/impl/lucene/works/DeleteWorkDelegate.java
search/trunk/src/java/org/hibernate/search/backend/impl/lucene/works/PurgeAllWorkDelegate.java
Log:
improvements to DeleteWorkDelegate and PurgeAllWorkDelegate
Modified: search/trunk/src/java/org/hibernate/search/backend/impl/lucene/works/DeleteWorkDelegate.java
===================================================================
--- search/trunk/src/java/org/hibernate/search/backend/impl/lucene/works/DeleteWorkDelegate.java 2008-10-21 16:22:47 UTC (rev 15363)
+++ search/trunk/src/java/org/hibernate/search/backend/impl/lucene/works/DeleteWorkDelegate.java 2008-10-21 16:26:57 UTC (rev 15364)
@@ -38,24 +38,24 @@
}
public IndexInteractionType getIndexInteractionType() {
- return IndexInteractionType.NEEDS_INDEXWRITER;
+ return IndexInteractionType.PREFER_INDEXWRITER;
}
public void performWork(LuceneWork work, IndexWriter writer) {
log.trace( "Removing {}#{} by query.", work.getEntityClass(), work.getId() );
DocumentBuilder builder = workspace.getDocumentBuilder( work.getEntityClass() );
- BooleanQuery entityDeltionQuery = new BooleanQuery();
+ BooleanQuery entityDeletionQuery = new BooleanQuery();
TermQuery idQueryTerm = new TermQuery( builder.getTerm( work.getId() ) );
- entityDeltionQuery.add(idQueryTerm, BooleanClause.Occur.MUST);
+ entityDeletionQuery.add( idQueryTerm, BooleanClause.Occur.MUST );
- Term classNameQueryTerm = new Term(DocumentBuilder.CLASS_FIELDNAME, work.getEntityClass().getName());
- TermQuery classNameQuery = new TermQuery( classNameQueryTerm);
- entityDeltionQuery.add(classNameQuery, BooleanClause.Occur.MUST);
+ Term classNameQueryTerm = new Term( DocumentBuilder.CLASS_FIELDNAME, work.getEntityClass().getName() );
+ TermQuery classNameQuery = new TermQuery( classNameQueryTerm );
+ entityDeletionQuery.add( classNameQuery, BooleanClause.Occur.MUST );
try {
- writer.deleteDocuments( entityDeltionQuery );
+ writer.deleteDocuments( entityDeletionQuery );
}
catch ( Exception e ) {
String message = "Unable to remove " + work.getEntityClass() + "#" + work.getId() + " from index.";
Modified: search/trunk/src/java/org/hibernate/search/backend/impl/lucene/works/PurgeAllWorkDelegate.java
===================================================================
--- search/trunk/src/java/org/hibernate/search/backend/impl/lucene/works/PurgeAllWorkDelegate.java 2008-10-21 16:22:47 UTC (rev 15363)
+++ search/trunk/src/java/org/hibernate/search/backend/impl/lucene/works/PurgeAllWorkDelegate.java 2008-10-21 16:26:57 UTC (rev 15364)
@@ -28,15 +28,22 @@
}
public IndexInteractionType getIndexInteractionType() {
- return IndexInteractionType.NEEDS_INDEXREADER;
+ return IndexInteractionType.PREFER_INDEXREADER;
}
public void performWork(LuceneWork work, IndexWriter writer) {
- throw new UnsupportedOperationException();
+ log.trace( "purgeAll Lucene index using IndexWriter for type: {}", work.getEntityClass() );
+ try {
+ Term term = new Term( DocumentBuilder.CLASS_FIELDNAME, work.getEntityClass().getName() );
+ writer.deleteDocuments( term );
+ }
+ catch (Exception e) {
+ throw new SearchException( "Unable to purge all from Lucene index: " + work.getEntityClass(), e );
+ }
}
public void performWork(LuceneWork work, IndexReader reader) {
- log.trace( "purgeAll Lucene index using IndexReader: {}", work.getEntityClass() );
+ log.trace( "purgeAll Lucene index using IndexReader for type: {}", work.getEntityClass() );
try {
Term term = new Term( DocumentBuilder.CLASS_FIELDNAME, work.getEntityClass().getName() );
reader.deleteDocuments( term );
16 years, 11 months
Hibernate SVN: r15363 - search/trunk/src/java/org/hibernate/search/backend.
by hibernate-commits@lists.jboss.org
Author: sannegrinovero
Date: 2008-10-21 12:22:47 -0400 (Tue, 21 Oct 2008)
New Revision: 15363
Modified:
search/trunk/src/java/org/hibernate/search/backend/Workspace.java
Log:
sorry, this is part of previous commit: "HSEARCH-225 resolved"
Modified: search/trunk/src/java/org/hibernate/search/backend/Workspace.java
===================================================================
--- search/trunk/src/java/org/hibernate/search/backend/Workspace.java 2008-10-21 16:20:59 UTC (rev 15362)
+++ search/trunk/src/java/org/hibernate/search/backend/Workspace.java 2008-10-21 16:22:47 UTC (rev 15363)
@@ -2,6 +2,7 @@
package org.hibernate.search.backend;
import java.io.IOException;
+import java.util.Set;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.locks.ReentrantLock;
@@ -48,7 +49,7 @@
private final DirectoryProvider directoryProvider;
private final OptimizerStrategy optimizerStrategy;
private final ReentrantLock lock;
- private final boolean singleEntityInDirectory;
+ private final Set<Class> entitiesInDirectory;
private final LuceneIndexingParameters indexingParams;
// variable state:
@@ -72,7 +73,7 @@
this.searchFactoryImplementor = searchFactoryImplementor;
this.directoryProvider = provider;
this.optimizerStrategy = searchFactoryImplementor.getOptimizerStrategy( directoryProvider );
- this.singleEntityInDirectory = searchFactoryImplementor.getClassesInDirectoryProvider( provider ).size() == 1;
+ this.entitiesInDirectory = searchFactoryImplementor.getClassesInDirectoryProvider( provider );
this.indexingParams = searchFactoryImplementor.getIndexingParameters( directoryProvider );
this.lock = searchFactoryImplementor.getDirectoryProviderLock( provider );
}
@@ -216,12 +217,11 @@
}
/**
- * Some optimizations can be enabled only when the same Directory is not shared
- * among more entities.
- * @return true iff only one entity type is using this Directory.
+ * @return The unmodifiable set of entity types being indexed
+ * in the underlying Lucene Directory backing this Workspace.
*/
- public boolean isSingleEntityInDirectory() {
- return singleEntityInDirectory;
+ public Set<Class> getEntitiesInDirectory() {
+ return entitiesInDirectory;
}
/**
16 years, 11 months
Hibernate SVN: r15362 - search/trunk/src/java/org/hibernate/search/backend/impl/lucene/works.
by hibernate-commits@lists.jboss.org
Author: sannegrinovero
Date: 2008-10-21 12:20:59 -0400 (Tue, 21 Oct 2008)
New Revision: 15362
Added:
search/trunk/src/java/org/hibernate/search/backend/impl/lucene/works/DeleteExtWorkDelegate.java
Modified:
search/trunk/src/java/org/hibernate/search/backend/impl/lucene/works/LuceneWorkVisitor.java
Log:
HSEARCH-225 resolved
Added: search/trunk/src/java/org/hibernate/search/backend/impl/lucene/works/DeleteExtWorkDelegate.java
===================================================================
--- search/trunk/src/java/org/hibernate/search/backend/impl/lucene/works/DeleteExtWorkDelegate.java (rev 0)
+++ search/trunk/src/java/org/hibernate/search/backend/impl/lucene/works/DeleteExtWorkDelegate.java 2008-10-21 16:20:59 UTC (rev 15362)
@@ -0,0 +1,84 @@
+package org.hibernate.search.backend.impl.lucene.works;
+
+import java.io.Serializable;
+
+import org.apache.lucene.index.IndexReader;
+import org.apache.lucene.index.IndexWriter;
+import org.apache.lucene.index.Term;
+import org.hibernate.annotations.common.AssertionFailure;
+import org.hibernate.search.SearchException;
+import org.hibernate.search.backend.LuceneWork;
+import org.hibernate.search.backend.Workspace;
+import org.hibernate.search.backend.impl.lucene.IndexInteractionType;
+import org.hibernate.search.engine.DocumentBuilder;
+import org.hibernate.search.util.LoggerFactory;
+import org.slf4j.Logger;
+
+/**
+ * Stateless extension of <code>DeleteLuceneWork</code>,
+ * performing the same LuceneWork in an optimal way in case
+ * the index is NOT shared across different entities
+ * (which is the default).
+ *
+ * @author Sanne Grinovero
+ * @see DeleteWorkDelegate
+ */
+public class DeleteExtWorkDelegate extends DeleteWorkDelegate {
+
+ private final Class managedType;
+ private final DocumentBuilder builder;
+ private final Logger log = LoggerFactory.make();
+
+ DeleteExtWorkDelegate(Workspace workspace) {
+ super( workspace );
+ if ( workspace.getEntitiesInDirectory().size() != 1 ) {
+ throw new AssertionFailure( "Can't use this delegate on shared indexes" );
+ }
+ managedType = workspace.getEntitiesInDirectory().iterator().next();
+ builder = workspace.getDocumentBuilder( managedType );
+ }
+
+ @Override
+ public IndexInteractionType getIndexInteractionType() {
+ // no particular reason to prefer Reader, just it's possibly more tested
+ // as using the writer is an option of latest Lucene version only (2.4).
+ return IndexInteractionType.PREFER_INDEXREADER;
+ }
+
+ @Override
+ public void performWork(LuceneWork work, IndexWriter writer) {
+ checkType( work );
+ Serializable id = work.getId();
+ log.trace( "Removing {}#{} by id using an IndexWriter.", managedType, id );
+ Term idTerm = builder.getTerm( id );
+ try {
+ writer.deleteDocuments( idTerm );
+ }
+ catch ( Exception e ) {
+ String message = "Unable to remove " + managedType + "#" + id + " from index.";
+ throw new SearchException( message, e );
+ }
+ }
+
+ @Override
+ public void performWork(LuceneWork work, IndexReader reader) {
+ checkType( work );
+ Serializable id = work.getId();
+ log.trace( "Removing {}#{} by id using an IndexReader.", managedType, id );
+ Term idTerm = builder.getTerm( id );
+ try {
+ reader.deleteDocuments( idTerm );
+ }
+ catch ( Exception e ) {
+ String message = "Unable to remove " + managedType + "#" + id + " from index.";
+ throw new SearchException( message, e );
+ }
+ }
+
+ private void checkType(final LuceneWork work) {
+ if ( work.getEntityClass() != managedType ) {
+ throw new AssertionFailure( "Unexpected type" );
+ }
+ }
+
+}
Property changes on: search/trunk/src/java/org/hibernate/search/backend/impl/lucene/works/DeleteExtWorkDelegate.java
___________________________________________________________________
Name: svn:executable
+ *
Modified: search/trunk/src/java/org/hibernate/search/backend/impl/lucene/works/LuceneWorkVisitor.java
===================================================================
--- search/trunk/src/java/org/hibernate/search/backend/impl/lucene/works/LuceneWorkVisitor.java 2008-10-21 16:18:08 UTC (rev 15361)
+++ search/trunk/src/java/org/hibernate/search/backend/impl/lucene/works/LuceneWorkVisitor.java 2008-10-21 16:20:59 UTC (rev 15362)
@@ -25,10 +25,15 @@
private final Workspace linkedWorkspace;
public LuceneWorkVisitor(Workspace workspace) {
+ if ( workspace.getEntitiesInDirectory().size() == 1 ) {
+ this.deleteDelegate = new DeleteExtWorkDelegate( workspace );
+ }
+ else {
+ this.deleteDelegate = new DeleteWorkDelegate( workspace );
+ }
+ this.purgeAllDelegate = new PurgeAllWorkDelegate();
this.addDelegate = new AddWorkDelegate( workspace );
- this.deleteDelegate = new DeleteWorkDelegate( workspace );
this.optimizeDelegate = new OptimizeWorkDelegate( workspace );
- this.purgeAllDelegate = new PurgeAllWorkDelegate();
this.linkedWorkspace = workspace;
}
16 years, 11 months
Hibernate SVN: r15361 - search/trunk/src/java/org/hibernate/search/backend/impl/lucene.
by hibernate-commits@lists.jboss.org
Author: sannegrinovero
Date: 2008-10-21 12:18:08 -0400 (Tue, 21 Oct 2008)
New Revision: 15361
Modified:
search/trunk/src/java/org/hibernate/search/backend/impl/lucene/PerDPQueueProcessor.java
Log:
late fix for HSEARCH-272
Modified: search/trunk/src/java/org/hibernate/search/backend/impl/lucene/PerDPQueueProcessor.java
===================================================================
--- search/trunk/src/java/org/hibernate/search/backend/impl/lucene/PerDPQueueProcessor.java 2008-10-21 10:32:12 UTC (rev 15360)
+++ search/trunk/src/java/org/hibernate/search/backend/impl/lucene/PerDPQueueProcessor.java 2008-10-21 16:18:08 UTC (rev 15361)
@@ -152,7 +152,8 @@
*/
private void useWriterOnly() {
log.debug( "Skipping usage of an IndexReader for updates" );
- workOnWriter.addAll( workOnReader );
+ //position 0 needed to maintain correct ordering of Work: delete operations first.
+ workOnWriter.addAll( 0, workOnReader );
workOnReader.clear();
}
16 years, 11 months
Hibernate SVN: r15360 - in search/trunk: lib and 1 other directory.
by hibernate-commits@lists.jboss.org
Author: hardy.ferentschik
Date: 2008-10-21 06:32:12 -0400 (Tue, 21 Oct 2008)
New Revision: 15360
Modified:
search/trunk/doc/reference/en/modules/configuration.xml
search/trunk/doc/reference/en/modules/mapping.xml
search/trunk/lib/README.txt
Log:
HSEARCH-252 - reviewed and modified existing documentation. Also updated README.txt
Modified: search/trunk/doc/reference/en/modules/configuration.xml
===================================================================
--- search/trunk/doc/reference/en/modules/configuration.xml 2008-10-20 17:57:44 UTC (rev 15359)
+++ search/trunk/doc/reference/en/modules/configuration.xml 2008-10-21 10:32:12 UTC (rev 15360)
@@ -557,13 +557,13 @@
</listitem>
<listitem>
- <para><filename>lucene-core-*.jar</filename>: Lucene core
+ <para><filename>lucene-core.jar</filename>: Lucene core
engine</para>
</listitem>
<listitem>
- <para><filename>solr-*.jar</filename>: Additional analyzer
- infrastructure</para>
+ <para><filename>solr-core.jar</filename>, solr-common.jar:
+ Additional analyzer infrastructure</para>
</listitem>
</itemizedlist>
</section>
Modified: search/trunk/doc/reference/en/modules/mapping.xml
===================================================================
--- search/trunk/doc/reference/en/modules/mapping.xml 2008-10-20 17:57:44 UTC (rev 15359)
+++ search/trunk/doc/reference/en/modules/mapping.xml 2008-10-21 10:32:12 UTC (rev 15360)
@@ -261,7 +261,7 @@
</section>
<section id="search-mapping-associated">
- <title>Embedded and associated objects </title>
+ <title>Embedded and associated objects</title>
<para>Associated objects as well as embedded objects can be indexed as
part of the root entity index. It is necessary if you expect to search a
@@ -526,15 +526,14 @@
<section id="analyzer">
<title>Analyzer</title>
- <para>The default analyzer class used to index the elements is
+ <para>The default analyzer class used to index tokenized fields is
configurable through the <literal>hibernate.search.analyzer</literal>
- property. If none is defined,
- <classname>org.apache.lucene.analysis.standard.StandardAnalyzer</classname>
- is used as the default.</para>
+ property. The default value for this property is
+ <classname>org.apache.lucene.analysis.standard.StandardAnalyzer</classname>.</para>
- <para>You can also define the analyzer class per entity, per property
- and even per @Field (useful when multiple fields are indexed from a
- single property).</para>
+ <para>You can also define the analyzer class per entity, property and
+ even per @Field (useful when multiple fields are indexed from a single
+ property).</para>
<programlisting>@Entity
@Indexed
@@ -558,8 +557,8 @@
...
}</programlisting>
- <para>In this example, <classname>EntityAnalyzer</classname> is used
- index all tokenized properties (eg. <literal>name</literal>), except for
+ <para>In this example, <classname>EntityAnalyzer</classname> is used to
+ index all tokenized properties (eg. <literal>name</literal>), except
<literal>summary</literal> and <literal>body</literal> which are indexed
with <classname>PropertyAnalyzer</classname> and
<classname>FieldAnalyzer</classname> respectively.</para>
@@ -569,17 +568,18 @@
time a bad practice. It makes query building more complex and results
less predictable (for the novice), especially if you are using a
QueryParser (which uses the same analyzer for the whole query). As a
- thumb rule, the same analyzer should be used for both the indexing and
- the query for a given field.</para>
+ rule of thumb, for any given field the same analyzer should be used
+ for indexing and querying.</para>
</caution>
<section>
<title>Analyzer definitions</title>
- <para>Analyzers can become quite complex to deal with. Hibernate
- Search introduces the notion of analyzer definition. An analyzer
- definition can be reused by many <classname>@Analyzer</classname>
- declarations. An analyzer definition is composed of:</para>
+ <para>Analyzers can become quite complex to deal with for which reason
+ Hibernate Search introduces the notion of analyzer definitions. An
+ analyzer definition can be reused by many
+ <classname>@Analyzer</classname> declarations. An analyzer definition
+ is composed of:</para>
<itemizedlist>
<listitem>
@@ -588,25 +588,31 @@
</listitem>
<listitem>
- <para>a tokenizer: a piece of code used to chunk the sentence into
- individual words</para>
+ <para>a tokenizer: responsible for tokenizing the input stream
+ into individual words</para>
</listitem>
<listitem>
- <para>a list of filters: each filter is responsible to remove
- words, modify words and sometimes add words into the stream
- provided by the tokenizer</para>
+ <para>a list of filters: each filter is responsible to remove,
+ modify or sometimes even add words into the stream provided by the
+ tokenizer</para>
</listitem>
</itemizedlist>
- <para>This separation of tasks (tokenizer, list of filters) allows
- reuse of each individual component and let you build your ideal
- analyzer ns a very flexible way (just like a lego). This
- infrastructure is supported by the Solr analyzer framework. Make sure
- to add <filename>solr-*.jar</filename> to your classpath to use
- analyzer definitions: this jar is distributed with your distribution
- of Hibernate Search and is a striped down version of the Solr
- jar.</para>
+ <para>This separation of tasks - a tokenizer followed by a list of
+ filters - allows easy reuse of each individual component and let you
+ build your customized analyzer in a very flexible way (just like
+ lego). Generally speaking the <classname>Tokenizer</classname> starts
+ the analysis process by turning the character input into tokens which
+ are then further processed by the <classname>TokenFilter</classname>s.
+ Hibernate Search supports this infrastructure by utilizing the Solr
+ analyzer framework. Make sure to add<filename> solr-core.jar and
+ </filename><filename>solr-common.jar</filename> to your classpath to
+ use analyzer definitions. In case you also want to utilizing a
+ snowball stemmer also include the
+ <filename>solr-lucene-snowball.jar.</filename> Your distribution of
+ Hibernate Search provides these dependecies in its
+ <filename>lib</filename> directory.</para>
<programlisting>@AnalyzerDef(name="customanalyzer",
tokenizer = @TokenizerDef(factory = StandardTokenizerFactory.class),
Modified: search/trunk/lib/README.txt
===================================================================
--- search/trunk/lib/README.txt 2008-10-20 17:57:44 UTC (rev 15359)
+++ search/trunk/lib/README.txt 2008-10-21 10:32:12 UTC (rev 15360)
@@ -4,16 +4,17 @@
Core
====
hibernate-commons-annotations.jar: required
-hibernate-core.jar: required
-hibernate core dependencies: required (see Hibernate Core for more information)
-lucene-core-*.jar: required (used version 2.3.2)
-jta.jar: required
-jms.jar: optional (needed for JMS based clustering strategy, usually available with your application server)
-jsr-250-api.jar: optional (needed for JMS based clustering strategy, usually available with your application server)
-apache-solr-analyzer.jar: optional (used version 1.2.0), needed if @AnalyzerDef is used
-slf4j-api: required (a slf4j-[impl].ar is required too - eg. slf4j-log4j12.jar)
+hibernate-core.jar: required + hibernate core dependencies - see Hibernate Core for more information
+lucene-core.jar: required (used version 2.4.0)
+jta.jar: required
+slf4j-api: required together with a slf4j-[impl].jar eg slf4j-log4j12.jar
+jms.jar: optional, needed for JMS based clustering strategy, usually available with your application server
+jsr-250-api.jar: optional, needed for JMS based clustering strategy, usually available with your application server
+solr-core.jar, solr-common.jar: optional (used version 1.3.0), needed if @AnalyzerDef is used
+solr-lucenen-snowball.jar: optional, needed if snowball stemmer is used
+
Test
====
hibernate-annotations.jar: required
-hibernate-entitymanager.jar: required
\ No newline at end of file
+hibernate-entitymanager.jar: required
16 years, 11 months
Hibernate SVN: r15359 - in core/trunk/core: src/main/antlr and 7 other directories.
by hibernate-commits@lists.jboss.org
Author: steve.ebersole(a)jboss.com
Date: 2008-10-20 13:57:44 -0400 (Mon, 20 Oct 2008)
New Revision: 15359
Added:
core/trunk/core/src/main/antlr/order-by-render.g
core/trunk/core/src/main/antlr/order-by.g
core/trunk/core/src/main/java/org/hibernate/sql/ordering/
core/trunk/core/src/main/java/org/hibernate/sql/ordering/antlr/
core/trunk/core/src/main/java/org/hibernate/sql/ordering/antlr/CollationSpecification.java
core/trunk/core/src/main/java/org/hibernate/sql/ordering/antlr/ColumnMapper.java
core/trunk/core/src/main/java/org/hibernate/sql/ordering/antlr/Factory.java
core/trunk/core/src/main/java/org/hibernate/sql/ordering/antlr/Node.java
core/trunk/core/src/main/java/org/hibernate/sql/ordering/antlr/NodeSupport.java
core/trunk/core/src/main/java/org/hibernate/sql/ordering/antlr/OrderByFragment.java
core/trunk/core/src/main/java/org/hibernate/sql/ordering/antlr/OrderByFragmentParser.java
core/trunk/core/src/main/java/org/hibernate/sql/ordering/antlr/OrderByFragmentRenderer.java
core/trunk/core/src/main/java/org/hibernate/sql/ordering/antlr/OrderByFragmentTranslator.java
core/trunk/core/src/main/java/org/hibernate/sql/ordering/antlr/OrderingSpecification.java
core/trunk/core/src/main/java/org/hibernate/sql/ordering/antlr/SortKey.java
core/trunk/core/src/main/java/org/hibernate/sql/ordering/antlr/SortSpecification.java
core/trunk/core/src/main/java/org/hibernate/sql/ordering/antlr/TranslationContext.java
core/trunk/core/src/test/java/org/hibernate/sql/
core/trunk/core/src/test/java/org/hibernate/sql/TemplateTest.java
Modified:
core/trunk/core/pom.xml
core/trunk/core/src/main/java/org/hibernate/persister/collection/AbstractCollectionPersister.java
core/trunk/core/src/main/java/org/hibernate/sql/Template.java
core/trunk/core/src/test/resources/log4j.properties
Log:
HHH-2802 : order-by mapping -> support for property names
Modified: core/trunk/core/pom.xml
===================================================================
--- core/trunk/core/pom.xml 2008-10-20 17:13:25 UTC (rev 15358)
+++ core/trunk/core/pom.xml 2008-10-20 17:57:44 UTC (rev 15359)
@@ -77,7 +77,7 @@
<artifactId>antlr-maven-plugin</artifactId>
<version>${antlrPluginVersion}</version>
<configuration>
- <grammars>hql.g,hql-sql.g,sql-gen.g</grammars>
+ <grammars>hql.g,hql-sql.g,sql-gen.g,order-by.g,order-by-render.g</grammars>
</configuration>
<executions>
<execution>
Added: core/trunk/core/src/main/antlr/order-by-render.g
===================================================================
--- core/trunk/core/src/main/antlr/order-by-render.g (rev 0)
+++ core/trunk/core/src/main/antlr/order-by-render.g 2008-10-20 17:57:44 UTC (rev 15359)
@@ -0,0 +1,92 @@
+header
+{
+/*
+ * 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
+ *
+ */
+package org.hibernate.sql.ordering.antlr;
+}
+/**
+ * Antlr grammar for rendering <tt>ORDER_BY</tt> trees as described by the {@link OrderByFragmentParser}
+
+ * @author Steve Ebersole
+ */
+class GeneratedOrderByFragmentRenderer extends TreeParser;
+
+options {
+ importVocab=OrderByTemplate;
+ buildAST=false;
+}
+
+{
+ // the buffer to which we write the resulting SQL.
+ private StringBuffer buffer = new StringBuffer();
+
+ protected void out(String text) {
+ buffer.append( text );
+ }
+
+ protected void out(AST ast) {
+ buffer.append( ast.getText() );
+ }
+
+ /*package*/ String getRenderedFragment() {
+ return buffer.toString();
+ }
+}
+
+orderByFragment
+ : #(
+ ORDER_BY sortSpecification ( {out(", ");} sortSpecification)*
+ )
+ ;
+
+sortSpecification
+ : #(
+ SORT_SPEC sortKeySpecification (collationSpecification)? (orderingSpecification)?
+ )
+ ;
+
+sortKeySpecification
+ : #(SORT_KEY sortKey)
+ ;
+
+sortKey
+ : i:IDENT {
+ out( #i );
+ }
+ ;
+
+collationSpecification
+ : c:COLLATE {
+ out( " collate " );
+ out( c );
+ }
+ ;
+
+orderingSpecification
+ : o:ORDER_SPEC {
+ out( " " );
+ out( #o );
+ }
+ ;
\ No newline at end of file
Added: core/trunk/core/src/main/antlr/order-by.g
===================================================================
--- core/trunk/core/src/main/antlr/order-by.g (rev 0)
+++ core/trunk/core/src/main/antlr/order-by.g 2008-10-20 17:57:44 UTC (rev 15359)
@@ -0,0 +1,440 @@
+header
+{
+/*
+ * 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
+ *
+ */
+package org.hibernate.sql.ordering.antlr;
+}
+/**
+ * Antlr grammar for dealing with <tt>order-by</tt> mapping fragments.
+
+ * @author Steve Ebersole
+ */
+class GeneratedOrderByFragmentParser extends Parser;
+
+options
+{
+ exportVocab=OrderByTemplate;
+ buildAST=true;
+ k=3;
+}
+
+tokens
+{
+ // synthetic tokens
+ ORDER_BY;
+ SORT_SPEC;
+ ORDER_SPEC;
+ SORT_KEY;
+ EXPR_LIST;
+ DOT;
+ IDENT_LIST;
+ COLUMN_REF;
+
+ COLLATE="collate";
+ ASCENDING="asc";
+ DESCENDING="desc";
+}
+
+
+{
+ /**
+ * Method for logging execution trace information.
+ *
+ * @param msg The trace message.
+ */
+ protected void trace(String msg) {
+ System.out.println( msg );
+ }
+
+ /**
+ * Extract a node's text.
+ *
+ * @param ast The node
+ *
+ * @return The text.
+ */
+ protected final String extractText(AST ast) {
+ // for some reason, within AST creation blocks "[]" I am somtimes unable to refer to the AST.getText() method
+ // using #var (the #var is not interpreted as the rule's output AST).
+ return ast.getText();
+ }
+
+ /**
+ * Process the given node as a quote identifier. These need to be quoted in the dialect-specific way.
+ *
+ * @param ident The quoted-identifier node.
+ *
+ * @return The processed node.
+ *
+ * @see org.hibernate.dialect.Dialect#quote
+ */
+ protected AST quotedIdentifier(AST ident) {
+ return ident;
+ }
+
+ /**
+ * Process the given node as a quote string.
+ *
+ * @param ident The quoted string. This is used from within function param recognition, and represents a
+ * SQL-quoted string.
+ *
+ * @return The processed node.
+ */
+ protected AST quotedString(AST ident) {
+ return ident;
+ }
+
+ /**
+ * A check to see if the text of the given node represents a known function name.
+ *
+ * @param ast The node whose text we want to check.
+ *
+ * @return True if the node's text is a known function name, false otherwise.
+ *
+ * @see org.hibernate.dialect.function.SQLFunctionRegistry
+ */
+ protected boolean isFunctionName(AST ast) {
+ return false;
+ }
+
+ /**
+ * Process the given node as a function.
+ *
+ * @param The node representing the function invocation (including parameters as subtree components).
+ *
+ * @return The processed node.
+ */
+ protected AST resolveFunction(AST ast) {
+ return ast;
+ }
+
+ /**
+ * Process the given node as an IDENT. May represent either a column reference or a property reference.
+ *
+ * @param ident The node whose text represents either a column or property reference.
+ *
+ * @return The processed node.
+ */
+ protected AST resolveIdent(AST ident) {
+ return ident;
+ }
+
+ /**
+ * Allow post processing of each <tt>sort specification</tt>
+ *
+ * @param The grammar-built sort specification subtree.
+ *
+ * @return The processed sort specification subtree.
+ */
+ protected AST postProcessSortSpecification(AST sortSpec) {
+ return sortSpec;
+ }
+
+}
+
+/**
+ * Main recognition rule for this grammar
+ */
+orderByFragment { trace("orderByFragment"); }
+ : sortSpecification ( COMMA! sortSpecification )* {
+ #orderByFragment = #( [ORDER_BY, "order-by"], #orderByFragment );
+ }
+ ;
+
+/**
+ * Reconition rule for what ANSI SQL terms the <tt>sort specification</tt>, which is essentially each thing upon which
+ * the results should be sorted.
+ */
+sortSpecification { trace("sortSpecification"); }
+ : sortKey (collationSpecification)? (orderingSpecification)? {
+ #sortSpecification = #( [SORT_SPEC, "{sort specification}"], #sortSpecification );
+ #sortSpecification = postProcessSortSpecification( #sortSpecification );
+ }
+ ;
+
+/**
+ * Reconition rule for what ANSI SQL terms the <tt>sort key</tt> which is the expression (column, function, etc) upon
+ * which to base the sorting.
+ */
+sortKey! { trace("sortKey"); }
+ : e:expression {
+ #sortKey = #( [SORT_KEY, "sort key"], #e );
+ }
+ ;
+
+/**
+ * Reconition rule what this grammar recognizes as valid <tt>sort key</tt>.
+ */
+expression! { trace("expression"); }
+ : HARD_QUOTE qi:IDENT HARD_QUOTE {
+ #expression = quotedIdentifier( #qi );
+ }
+ | ( IDENT (DOT IDENT)* OPEN_PAREN ) => f:functionCall {
+ #expression = #f;
+ }
+ | p:simplePropertyPath {
+ #expression = resolveIdent( #p );
+ }
+ | i:IDENT {
+ if ( isFunctionName( #i ) ) {
+ #expression = resolveFunction( #i );
+ }
+ else {
+ #expression = resolveIdent( #i );
+ }
+ }
+ ;
+
+/**
+ * Intended for use as a syntactic predicate to determine whether an IDENT represents a known SQL function name.
+ */
+functionCallCheck! { trace("functionCallCheck"); }
+ : IDENT (DOT IDENT)* OPEN_PAREN { true }?
+ ;
+
+/**
+ * Recognition rule for a function call
+ */
+functionCall! { trace("functionCall"); }
+ : fn:functionName OPEN_PAREN pl:functionParameterList CLOSE_PAREN {
+ #functionCall = #( [IDENT, extractText( #fn )], #pl );
+ #functionCall = resolveFunction( #functionCall );
+ }
+ ;
+
+/**
+ * A function-name is an IDENT followed by zero or more (DOT IDENT) sequences
+ */
+functionName {
+ trace("functionName");
+ StringBuffer buffer = new StringBuffer();
+ }
+ : i:IDENT { buffer.append( i.getText() ); }
+ ( DOT i2:IDENT { buffer.append( '.').append( i2.getText() ); } )* {
+ #functionName = #( [IDENT,buffer.toString()] );
+ }
+ ;
+
+/**
+ * Recognition rule used to "wrap" all function parameters into an EXPR_LIST node
+ */
+functionParameterList { trace("functionParameterList"); }
+ : functionParameter ( COMMA! functionParameter )* {
+ #functionParameterList = #( [EXPR_LIST, "{param list}"], #functionParameterList );
+ }
+ ;
+
+/**
+ * Recognized function parameters.
+ */
+functionParameter { trace("functionParameter"); }
+ : expression
+ | NUM_DOUBLE
+ | NUM_FLOAT
+ | NUM_INT
+ | NUM_LONG
+ | QUOTED_STRING {
+ #functionParameter = quotedString( #functionParameter );
+ }
+ ;
+
+/**
+ * Reconition rule for what ANSI SQL terms the <tt>collation specification</tt> used to allow specifying that sorting for
+ * the given {@link #sortSpecification} be treated within a specific character-set.
+ */
+collationSpecification! { trace("collationSpecification"); }
+ : c:COLLATE cn:collationName {
+ #collationSpecification = #( [COLLATE, extractText( #cn )] );
+ }
+ ;
+
+/**
+ * The collation name wrt {@link #collationSpecification}. Namely, the character-set.
+ */
+collationName { trace("collationSpecification"); }
+ : IDENT
+ ;
+
+/**
+ * Reconition rule for what ANSI SQL terms the <tt>ordering specification</tt>; <tt>ASCENDING</tt> or
+ * <tt>DESCENDING</tt>.
+ */
+orderingSpecification! { trace("orderingSpecification"); }
+ : ( "asc" | "ascending" ) {
+ #orderingSpecification = #( [ORDER_SPEC, "asc"] );
+ }
+ | ( "desc" | "descending") {
+ #orderingSpecification = #( [ORDER_SPEC, "desc"] );
+ }
+ ;
+
+/**
+ * A simple-property-path is an IDENT followed by one or more (DOT IDENT) sequences
+ */
+simplePropertyPath {
+ trace("simplePropertyPath");
+ StringBuffer buffer = new StringBuffer();
+ }
+ : i:IDENT { buffer.append( i.getText() ); }
+ ( DOT i2:IDENT { buffer.append( '.').append( i2.getText() ); } )+ {
+ #simplePropertyPath = #( [IDENT,buffer.toString()] );
+ }
+ ;
+
+
+// **** LEXER ******************************************************************
+
+/**
+ * Lexer for the <tt>order-by</tt> fragment parser
+
+ * @author Steve Ebersole
+ * @author Joshua Davis
+ */
+class GeneratedOrderByLexer extends Lexer;
+
+options {
+ exportVocab=OrderByTemplate;
+ testLiterals = false;
+ k=2;
+ charVocabulary='\u0000'..'\uFFFE'; // Allow any char but \uFFFF (16 bit -1, ANTLR's EOF character)
+ caseSensitive = false;
+ caseSensitiveLiterals = false;
+}
+
+// -- Keywords --
+
+OPEN_PAREN: '(';
+CLOSE_PAREN: ')';
+
+COMMA: ',';
+
+HARD_QUOTE: '`';
+
+IDENT options { testLiterals=true; }
+ : ID_START_LETTER ( ID_LETTER )*
+ ;
+
+protected
+ID_START_LETTER
+ : '_'
+ | '$'
+ | 'a'..'z'
+ | '\u0080'..'\ufffe' // HHH-558 : Allow unicode chars in identifiers
+ ;
+
+protected
+ID_LETTER
+ : ID_START_LETTER
+ | '0'..'9'
+ ;
+
+QUOTED_STRING
+ : '\'' ( (ESCqs)=> ESCqs | ~'\'' )* '\''
+ ;
+
+protected
+ESCqs
+ :
+ '\'' '\''
+ ;
+
+//--- From the Java example grammar ---
+// a numeric literal
+NUM_INT
+ {boolean isDecimal=false; Token t=null;}
+ : '.' {_ttype = DOT;}
+ ( ('0'..'9')+ (EXPONENT)? (f1:FLOAT_SUFFIX {t=f1;})?
+ {
+ if (t != null && t.getText().toUpperCase().indexOf('F')>=0)
+ {
+ _ttype = NUM_FLOAT;
+ }
+ else
+ {
+ _ttype = NUM_DOUBLE; // assume double
+ }
+ }
+ )?
+ | ( '0' {isDecimal = true;} // special case for just '0'
+ ( ('x')
+ ( // hex
+ // the 'e'|'E' and float suffix stuff look
+ // like hex digits, hence the (...)+ doesn't
+ // know when to stop: ambig. ANTLR resolves
+ // it correctly by matching immediately. It
+ // is therefore ok to hush warning.
+ options { warnWhenFollowAmbig=false; }
+ : HEX_DIGIT
+ )+
+ | ('0'..'7')+ // octal
+ )?
+ | ('1'..'9') ('0'..'9')* {isDecimal=true;} // non-zero decimal
+ )
+ ( ('l') { _ttype = NUM_LONG; }
+
+ // only check to see if it's a float if looks like decimal so far
+ | {isDecimal}?
+ ( '.' ('0'..'9')* (EXPONENT)? (f2:FLOAT_SUFFIX {t=f2;})?
+ | EXPONENT (f3:FLOAT_SUFFIX {t=f3;})?
+ | f4:FLOAT_SUFFIX {t=f4;}
+ )
+ {
+ if (t != null && t.getText().toUpperCase() .indexOf('F') >= 0)
+ {
+ _ttype = NUM_FLOAT;
+ }
+ else
+ {
+ _ttype = NUM_DOUBLE; // assume double
+ }
+ }
+ )?
+ ;
+
+// hexadecimal digit (again, note it's protected!)
+protected
+HEX_DIGIT
+ : ('0'..'9'|'a'..'f')
+ ;
+
+// a couple protected methods to assist in matching floating point numbers
+protected
+EXPONENT
+ : ('e') ('+'|'-')? ('0'..'9')+
+ ;
+
+protected
+FLOAT_SUFFIX
+ : 'f'|'d'
+ ;
+
+WS : ( ' '
+ | '\t'
+ | '\r' '\n' { newline(); }
+ | '\n' { newline(); }
+ | '\r' { newline(); }
+ )
+ {$setType(Token.SKIP);} //ignore this token
+ ;
Modified: core/trunk/core/src/main/java/org/hibernate/persister/collection/AbstractCollectionPersister.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/persister/collection/AbstractCollectionPersister.java 2008-10-20 17:13:25 UTC (rev 15358)
+++ core/trunk/core/src/main/java/org/hibernate/persister/collection/AbstractCollectionPersister.java 2008-10-20 17:57:44 UTC (rev 15359)
@@ -80,12 +80,12 @@
import org.hibernate.sql.SelectFragment;
import org.hibernate.sql.SimpleSelect;
import org.hibernate.sql.Template;
+import org.hibernate.sql.ordering.antlr.ColumnMapper;
import org.hibernate.type.AbstractComponentType;
import org.hibernate.type.CollectionType;
import org.hibernate.type.EntityType;
import org.hibernate.type.Type;
import org.hibernate.util.ArrayHelper;
-import org.hibernate.util.CollectionHelper;
import org.hibernate.util.FilterHelper;
import org.hibernate.util.StringHelper;
@@ -113,7 +113,6 @@
private final String sqlDetectRowByIndexString;
private final String sqlDetectRowByElementString;
- private final String sqlOrderByString;
protected final String sqlWhereString;
private final String sqlOrderByStringTemplate;
private final String sqlWhereStringTemplate;
@@ -197,7 +196,7 @@
private final String manyToManyWhereString;
private final String manyToManyWhereTemplate;
- private final String manyToManyOrderByString;
+ private final boolean hasManyToManyOrder;
private final String manyToManyOrderByTemplate;
// custom sql
@@ -266,12 +265,7 @@
for ( int i = 1; i < spacesSize; i++ ) {
spaces[i] = (String) iter.next();
}
-
- sqlOrderByString = collection.getOrderBy();
- hasOrder = sqlOrderByString != null;
- sqlOrderByStringTemplate = hasOrder ?
- Template.renderOrderByStringTemplate(sqlOrderByString, dialect, factory.getSqlFunctionRegistry()) :
- null;
+
sqlWhereString = StringHelper.isNotEmpty( collection.getWhere() ) ? "( " + collection.getWhere() + ") " : null;
hasWhere = sqlWhereString != null;
sqlWhereStringTemplate = hasWhere ?
@@ -540,7 +534,26 @@
);
}
}
-
+
+ hasOrder = collection.getOrderBy() != null;
+ if ( hasOrder ) {
+ ColumnMapper mapper = new ColumnMapper() {
+ public String[] map(String reference) {
+ return elementPropertyMapping.toColumns( reference );
+ }
+ };
+ sqlOrderByStringTemplate = Template.renderOrderByStringTemplate(
+ collection.getOrderBy(),
+ mapper,
+ factory,
+ dialect,
+ factory.getSqlFunctionRegistry()
+ );
+ }
+ else {
+ sqlOrderByStringTemplate = null;
+ }
+
// Handle any filters applied to this collection
filterHelper = new FilterHelper( collection.getFilterMap(), dialect, factory.getSqlFunctionRegistry() );
@@ -552,11 +565,26 @@
manyToManyWhereTemplate = manyToManyWhereString == null ?
null :
Template.renderWhereStringTemplate( manyToManyWhereString, factory.getDialect(), factory.getSqlFunctionRegistry() );
- manyToManyOrderByString = collection.getManyToManyOrdering();
- manyToManyOrderByTemplate = manyToManyOrderByString == null
- ? null
- : Template.renderOrderByStringTemplate( manyToManyOrderByString, factory.getDialect(), factory.getSqlFunctionRegistry() );
+ hasManyToManyOrder = collection.getManyToManyOrdering() != null;
+ if ( hasManyToManyOrder ) {
+ ColumnMapper mapper = new ColumnMapper() {
+ public String[] map(String reference) {
+ return elementPropertyMapping.toColumns( reference );
+ }
+ };
+ manyToManyOrderByTemplate = Template.renderOrderByStringTemplate(
+ collection.getManyToManyOrdering(),
+ mapper,
+ factory,
+ dialect,
+ factory.getSqlFunctionRegistry()
+ );
+ }
+ else {
+ manyToManyOrderByTemplate = null;
+ }
+
initCollectionPropertyMap();
}
@@ -658,17 +686,15 @@
}
public String getSQLOrderByString(String alias) {
- return hasOrdering() ?
- StringHelper.replace( sqlOrderByStringTemplate, Template.TEMPLATE, alias ) : "";
+ return hasOrdering()
+ ? StringHelper.replace( sqlOrderByStringTemplate, Template.TEMPLATE, alias )
+ : "";
}
public String getManyToManyOrderByString(String alias) {
- if ( isManyToMany() && manyToManyOrderByString != null ) {
- return StringHelper.replace( manyToManyOrderByTemplate, Template.TEMPLATE, alias );
- }
- else {
- return "";
- }
+ return hasManyToManyOrdering()
+ ? StringHelper.replace( manyToManyOrderByTemplate, Template.TEMPLATE, alias )
+ : "";
}
public FetchMode getFetchMode() {
return fetchMode;
@@ -679,7 +705,7 @@
}
public boolean hasManyToManyOrdering() {
- return isManyToMany() && manyToManyOrderByTemplate != null;
+ return isManyToMany() && hasManyToManyOrder;
}
public boolean hasWhere() {
Modified: core/trunk/core/src/main/java/org/hibernate/sql/Template.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/sql/Template.java 2008-10-20 17:13:25 UTC (rev 15358)
+++ core/trunk/core/src/main/java/org/hibernate/sql/Template.java 2008-10-20 17:57:44 UTC (rev 15359)
@@ -30,6 +30,10 @@
import org.hibernate.dialect.Dialect;
import org.hibernate.dialect.function.SQLFunctionRegistry;
import org.hibernate.util.StringHelper;
+import org.hibernate.sql.ordering.antlr.ColumnMapper;
+import org.hibernate.sql.ordering.antlr.TranslationContext;
+import org.hibernate.sql.ordering.antlr.OrderByFragmentTranslator;
+import org.hibernate.engine.SessionFactoryImplementor;
/**
* Parses SQL fragments specified in mapping documents
@@ -233,93 +237,79 @@
return result.toString();
}
+ public static class NoOpColumnMapper implements ColumnMapper {
+ public static final NoOpColumnMapper INSTANCE = new NoOpColumnMapper();
+ public String[] map(String reference) {
+ return new String[] { reference };
+ }
+ }
+
/**
- * Takes order by clause provided in the mapping attribute and interpolates the alias.
- * Handles asc, desc, SQL functions, quoted identifiers.
+ * Performs order-by template rendering without {@link ColumnMapper column mapping}. An <tt>ORDER BY</tt> template
+ * has all column references "qualified" with a placeholder identified by {@link Template#TEMPLATE}
+ *
+ * @param orderByFragment The order-by fragment to render.
+ * @param dialect The SQL dialect being used.
+ * @param functionRegistry The SQL function registry
+ *
+ * @return The rendered <tt>ORDER BY</tt> template.
+ *
+ * @see #renderOrderByStringTemplate(String,ColumnMapper,SessionFactoryImplementor,Dialect,SQLFunctionRegistry)
*/
- public static String renderOrderByStringTemplate(String sqlOrderByString, Dialect dialect, SQLFunctionRegistry functionRegistry) {
- //TODO: make this a bit nicer
- String symbols = new StringBuffer()
- .append("=><!+-*/()',|&`")
- .append(StringHelper.WHITESPACE)
- .append( dialect.openQuote() )
- .append( dialect.closeQuote() )
- .toString();
- StringTokenizer tokens = new StringTokenizer(sqlOrderByString, symbols, true);
-
- StringBuffer result = new StringBuffer();
- boolean quoted = false;
- boolean quotedIdentifier = false;
-
- boolean hasMore = tokens.hasMoreTokens();
- String nextToken = hasMore ? tokens.nextToken() : null;
- while (hasMore) {
- String token = nextToken;
- String lcToken = token.toLowerCase();
- hasMore = tokens.hasMoreTokens();
- nextToken = hasMore ? tokens.nextToken() : null;
-
- boolean isQuoteCharacter = false;
-
- if ( !quotedIdentifier && "'".equals(token) ) {
- quoted = !quoted;
- isQuoteCharacter = true;
+ public static String renderOrderByStringTemplate(
+ String orderByFragment,
+ Dialect dialect,
+ SQLFunctionRegistry functionRegistry) {
+ return renderOrderByStringTemplate(
+ orderByFragment,
+ NoOpColumnMapper.INSTANCE,
+ null,
+ dialect,
+ functionRegistry
+ );
+ }
+
+ /**
+ * Performs order-by template rendering allowing {@link ColumnMapper column mapping}. An <tt>ORDER BY</tt> template
+ * has all column references "qualified" with a placeholder identified by {@link Template#TEMPLATE} which can later
+ * be used to easily inject the SQL alias.
+ *
+ * @param orderByFragment The order-by fragment to render.
+ * @param columnMapper The column mapping strategy to use.
+ * @param sessionFactory The session factory.
+ * @param dialect The SQL dialect being used.
+ * @param functionRegistry The SQL function registry
+ *
+ * @return The rendered <tt>ORDER BY</tt> template.
+ */
+ public static String renderOrderByStringTemplate(
+ String orderByFragment,
+ final ColumnMapper columnMapper,
+ final SessionFactoryImplementor sessionFactory,
+ final Dialect dialect,
+ final SQLFunctionRegistry functionRegistry) {
+ TranslationContext context = new TranslationContext() {
+ public SessionFactoryImplementor getSessionFactory() {
+ return sessionFactory;
}
-
- if ( !quoted ) {
-
- boolean isOpenQuote;
- if ( "`".equals(token) ) {
- isOpenQuote = !quotedIdentifier;
- token = lcToken = isOpenQuote ?
- new Character( dialect.openQuote() ).toString() :
- new Character( dialect.closeQuote() ).toString();
- quotedIdentifier = isOpenQuote;
- isQuoteCharacter = true;
- }
- else if ( !quotedIdentifier && ( dialect.openQuote()==token.charAt(0) ) ) {
- isOpenQuote = true;
- quotedIdentifier = true;
- isQuoteCharacter = true;
- }
- else if ( quotedIdentifier && ( dialect.closeQuote()==token.charAt(0) ) ) {
- quotedIdentifier = false;
- isQuoteCharacter = true;
- isOpenQuote = false;
- }
- else {
- isOpenQuote = false;
- }
-
- if (isOpenQuote) {
- result.append(TEMPLATE).append('.');
- }
-
+
+ public Dialect getDialect() {
+ return dialect;
}
-
- boolean quotedOrWhitespace = quoted ||
- quotedIdentifier ||
- isQuoteCharacter ||
- Character.isWhitespace( token.charAt(0) );
-
- if (quotedOrWhitespace) {
- result.append(token);
+
+ public SQLFunctionRegistry getSqlFunctionRegistry() {
+ return functionRegistry;
}
- else if (
- isIdentifier(token, dialect) &&
- !isFunctionOrKeyword(lcToken, nextToken, dialect, functionRegistry)
- ) {
- result.append(TEMPLATE)
- .append('.')
- .append( dialect.quote(token) );
+
+ public ColumnMapper getColumnMapper() {
+ return columnMapper;
}
- else {
- result.append(token);
- }
- }
- return result.toString();
+ };
+
+ OrderByFragmentTranslator translator = new OrderByFragmentTranslator( context );
+ return translator.render( orderByFragment );
}
-
+
private static boolean isNamedParameter(String token) {
return token.startsWith(":");
}
Added: core/trunk/core/src/main/java/org/hibernate/sql/ordering/antlr/CollationSpecification.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/sql/ordering/antlr/CollationSpecification.java (rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/sql/ordering/antlr/CollationSpecification.java 2008-10-20 17:57:44 UTC (rev 15359)
@@ -0,0 +1,34 @@
+/*
+ * 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
+ *
+ */
+package org.hibernate.sql.ordering.antlr;
+
+/**
+ * Models a collation specification (<tt>COLLATE</tt> using a specific character-set) within a
+ * {@link SortSpecification}.
+ *
+ * @author Steve Ebersole
+ */
+public class CollationSpecification extends NodeSupport {
+}
Added: core/trunk/core/src/main/java/org/hibernate/sql/ordering/antlr/ColumnMapper.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/sql/ordering/antlr/ColumnMapper.java (rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/sql/ordering/antlr/ColumnMapper.java 2008-10-20 17:57:44 UTC (rev 15359)
@@ -0,0 +1,46 @@
+/*
+ * 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
+ *
+ */
+package org.hibernate.sql.ordering.antlr;
+
+import org.hibernate.HibernateException;
+
+/**
+ * Contract for mapping a (an assumed) property reference to its columns.
+ *
+ * @author Steve Ebersole
+ */
+public interface ColumnMapper {
+ /**
+ * Resolve the property reference to its underlying columns.
+ *
+ * @param reference The property reference name.
+ *
+ * @return The underlying columns, or null if the property reference is unknown.
+ *
+ * @throws HibernateException Generally indicates that the property reference is unkown; interpretation is the
+ * same as a null return.
+ */
+ public String[] map(String reference) throws HibernateException;
+}
Added: core/trunk/core/src/main/java/org/hibernate/sql/ordering/antlr/Factory.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/sql/ordering/antlr/Factory.java (rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/sql/ordering/antlr/Factory.java 2008-10-20 17:57:44 UTC (rev 15359)
@@ -0,0 +1,54 @@
+/*
+ * 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
+ *
+ */
+package org.hibernate.sql.ordering.antlr;
+
+import antlr.ASTFactory;
+
+/**
+ * Acts as a {@link ASTFactory} for injecting our specific AST node classes into the Antlr generated trees.
+ *
+ * @author Steve Ebersole
+ */
+public class Factory extends ASTFactory implements OrderByTemplateTokenTypes {
+ /**
+ * {@inheritDoc}
+ */
+ public Class getASTNodeType(int i) {
+ switch ( i ) {
+ case ORDER_BY:
+ return OrderByFragment.class;
+ case SORT_SPEC:
+ return SortSpecification.class;
+ case ORDER_SPEC:
+ return OrderingSpecification.class;
+ case COLLATE:
+ return CollationSpecification.class;
+ case SORT_KEY:
+ return SortKey.class;
+ default:
+ return NodeSupport.class;
+ }
+ }
+}
Added: core/trunk/core/src/main/java/org/hibernate/sql/ordering/antlr/Node.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/sql/ordering/antlr/Node.java (rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/sql/ordering/antlr/Node.java 2008-10-20 17:57:44 UTC (rev 15359)
@@ -0,0 +1,53 @@
+/*
+ * 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
+ *
+ */
+package org.hibernate.sql.ordering.antlr;
+
+/**
+ * General contract for AST nodes.
+ *
+ * @author Steve Ebersole
+ */
+public interface Node {
+ /**
+ * Get the intrinsic text of this node.
+ *
+ * @return The node's text.
+ */
+ public String getText();
+
+ /**
+ * Get a string representation of this node usable for debug logging or similar.
+ *
+ * @return The node's debugging text.
+ */
+ public String getDebugText();
+
+ /**
+ * Build the node's representation for use in the resulting rendering.
+ *
+ * @return The renderable text.
+ */
+ public String getRenderableText();
+}
Added: core/trunk/core/src/main/java/org/hibernate/sql/ordering/antlr/NodeSupport.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/sql/ordering/antlr/NodeSupport.java (rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/sql/ordering/antlr/NodeSupport.java 2008-10-20 17:57:44 UTC (rev 15359)
@@ -0,0 +1,48 @@
+/*
+ * 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
+ *
+ */
+package org.hibernate.sql.ordering.antlr;
+
+import antlr.CommonAST;
+
+/**
+ * Basic implementation of a {@link Node}.
+ *
+ * @author Steve Ebersole
+ */
+public class NodeSupport extends CommonAST implements Node {
+ /**
+ * {@inheritDoc}
+ */
+ public String getDebugText() {
+ return getText();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getRenderableText() {
+ return getText();
+ }
+}
Added: core/trunk/core/src/main/java/org/hibernate/sql/ordering/antlr/OrderByFragment.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/sql/ordering/antlr/OrderByFragment.java (rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/sql/ordering/antlr/OrderByFragment.java 2008-10-20 17:57:44 UTC (rev 15359)
@@ -0,0 +1,33 @@
+/*
+ * 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
+ *
+ */
+package org.hibernate.sql.ordering.antlr;
+
+/**
+ * Represents a parsed <tt>order-by</tt> mapping fragment. This holds the tree of all {@link SortSpecification}s.
+ *
+ * @author Steve Ebersole
+ */
+public class OrderByFragment extends NodeSupport {
+}
Added: core/trunk/core/src/main/java/org/hibernate/sql/ordering/antlr/OrderByFragmentParser.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/sql/ordering/antlr/OrderByFragmentParser.java (rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/sql/ordering/antlr/OrderByFragmentParser.java 2008-10-20 17:57:44 UTC (rev 15359)
@@ -0,0 +1,194 @@
+/*
+ * 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
+ *
+ */
+package org.hibernate.sql.ordering.antlr;
+
+import java.util.ArrayList;
+
+import antlr.TokenStream;
+import antlr.CommonAST;
+import antlr.collections.AST;
+
+import org.hibernate.sql.Template;
+import org.hibernate.dialect.function.SQLFunction;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Extension of the Antlr-generated parser for the purpose of adding our custom parsing behavior.
+ *
+ * @author Steve Ebersole
+ */
+public class OrderByFragmentParser extends GeneratedOrderByFragmentParser {
+ private static final Logger log = LoggerFactory.getLogger( OrderByFragmentParser.class );
+
+ private final TranslationContext context;
+
+ public OrderByFragmentParser(TokenStream lexer, TranslationContext context) {
+ super( lexer );
+ super.setASTFactory( new Factory() );
+ this.context = context;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected void trace(String msg) {
+ log.trace( msg );
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected AST quotedIdentifier(AST ident) {
+ return getASTFactory().create(
+ OrderByTemplateTokenTypes.IDENT,
+ Template.TEMPLATE + "." + context.getDialect().quote( '`' + ident.getText() + '`' )
+ );
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected AST quotedString(AST ident) {
+ return getASTFactory().create( OrderByTemplateTokenTypes.IDENT, context.getDialect().quote( ident.getText() ) );
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected boolean isFunctionName(AST ast) {
+ return context.getSqlFunctionRegistry().hasFunction( ast.getText() );
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected AST resolveFunction(AST ast) {
+ AST child = ast.getFirstChild();
+ assert "{param list}".equals( child.getText() );
+ child = child.getFirstChild();
+
+ final String functionName = ast.getText();
+ final SQLFunction function = context.getSqlFunctionRegistry().findSQLFunction( functionName );
+ if ( function == null ) {
+ String text = functionName;
+ if ( child != null ) {
+ text += '(';
+ while ( child != null ) {
+ text += child.getText();
+ child = child.getNextSibling();
+ if ( child != null ) {
+ text += ", ";
+ }
+ }
+ text += ')';
+ }
+ return getASTFactory().create( OrderByTemplateTokenTypes.IDENT, text );
+ }
+ else {
+ ArrayList expressions = new ArrayList();
+ while ( child != null ) {
+ expressions.add( child.getText() );
+ child = child.getNextSibling();
+ }
+ final String text = function.render( expressions, context.getSessionFactory() );
+ return getASTFactory().create( OrderByTemplateTokenTypes.IDENT, text );
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected AST resolveIdent(AST ident) {
+ String text = ident.getText();
+ String[] replacements;
+ try {
+ replacements = context.getColumnMapper().map( text );
+ }
+ catch( Throwable t ) {
+ replacements = null;
+ }
+
+ if ( replacements == null || replacements.length == 0 ) {
+ return getASTFactory().create( OrderByTemplateTokenTypes.IDENT, Template.TEMPLATE + "." + ident );
+ }
+ else if ( replacements.length == 1 ) {
+ return getASTFactory().create( OrderByTemplateTokenTypes.IDENT, Template.TEMPLATE + "." + replacements[0] );
+ }
+ else {
+ final AST root = getASTFactory().create( OrderByTemplateTokenTypes.IDENT_LIST, "{ident list}" );
+ for ( int i = 0; i < replacements.length; i++ ) {
+ final String identText = Template.TEMPLATE + '.' + replacements[i];
+ root.addChild( getASTFactory().create( OrderByTemplateTokenTypes.IDENT, identText ) );
+ }
+ return root;
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected AST postProcessSortSpecification(AST sortSpec) {
+ assert SORT_SPEC == sortSpec.getType();
+ SortSpecification sortSpecification = ( SortSpecification ) sortSpec;
+ AST sortKey = sortSpecification.getSortKey();
+ if ( IDENT_LIST == sortKey.getFirstChild().getType() ) {
+ AST identList = sortKey.getFirstChild();
+ AST ident = identList.getFirstChild();
+ AST holder = new CommonAST();
+ do {
+ holder.addChild(
+ createSortSpecification(
+ ident,
+ sortSpecification.getCollation(),
+ sortSpecification.getOrdering()
+ )
+ );
+ ident = ident.getNextSibling();
+ } while ( ident != null );
+ sortSpec = holder.getFirstChild();
+ }
+ return sortSpec;
+ }
+
+ private SortSpecification createSortSpecification(
+ AST ident,
+ CollationSpecification collationSpecification,
+ OrderingSpecification orderingSpecification) {
+ AST sortSpecification = getASTFactory().create( SORT_SPEC, "{{sort specification}}" );
+ AST sortKey = getASTFactory().create( SORT_KEY, "{{sort key}}" );
+ AST newIdent = getASTFactory().create( ident.getType(), ident.getText() );
+ sortKey.setFirstChild( newIdent );
+ sortSpecification.setFirstChild( sortKey );
+ if ( collationSpecification != null ) {
+ sortSpecification.addChild( collationSpecification );
+ }
+ if ( orderingSpecification != null ) {
+ sortSpecification.addChild( orderingSpecification );
+ }
+ return ( SortSpecification ) sortSpecification;
+ }
+}
Added: core/trunk/core/src/main/java/org/hibernate/sql/ordering/antlr/OrderByFragmentRenderer.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/sql/ordering/antlr/OrderByFragmentRenderer.java (rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/sql/ordering/antlr/OrderByFragmentRenderer.java 2008-10-20 17:57:44 UTC (rev 15359)
@@ -0,0 +1,38 @@
+/*
+ * 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
+ *
+ */
+package org.hibernate.sql.ordering.antlr;
+
+import antlr.collections.AST;
+
+/**
+ * TODO : javadoc
+ *
+ * @author Steve Ebersole
+ */
+public class OrderByFragmentRenderer extends GeneratedOrderByFragmentRenderer {
+ protected void out(AST ast) {
+ out( ( ( Node ) ast ).getRenderableText() );
+ }
+}
Added: core/trunk/core/src/main/java/org/hibernate/sql/ordering/antlr/OrderByFragmentTranslator.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/sql/ordering/antlr/OrderByFragmentTranslator.java (rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/sql/ordering/antlr/OrderByFragmentTranslator.java 2008-10-20 17:57:44 UTC (rev 15359)
@@ -0,0 +1,87 @@
+/*
+ * 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
+ *
+ */
+package org.hibernate.sql.ordering.antlr;
+
+import java.io.StringReader;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.hibernate.HibernateException;
+import org.hibernate.hql.ast.util.ASTPrinter;
+
+/**
+ * A translator which coordinates translation of an <tt>order-by</tt> mapping.
+ *
+ * @author Steve Ebersole
+ */
+public class OrderByFragmentTranslator {
+ private static final Logger log = LoggerFactory.getLogger( OrderByFragmentTranslator.class );
+
+ public final TranslationContext context;
+
+ public OrderByFragmentTranslator(TranslationContext context) {
+ this.context = context;
+ }
+
+ /**
+ * The main contract, performing the transaction.
+ *
+ * @param fragment The <tt>order-by</tt> mapping fragment to be translated.
+ *
+ * @return The translated fragment.
+ */
+ public String render(String fragment) {
+ GeneratedOrderByLexer lexer = new GeneratedOrderByLexer( new StringReader( fragment ) );
+ OrderByFragmentParser parser = new OrderByFragmentParser( lexer, context );
+ try {
+ parser.orderByFragment();
+ }
+ catch ( HibernateException e ) {
+ throw e;
+ }
+ catch ( Throwable t ) {
+ throw new HibernateException( "Unable to parse order-by fragment", t );
+ }
+
+ if ( log.isTraceEnabled() ) {
+ ASTPrinter printer = new ASTPrinter( OrderByTemplateTokenTypes.class );
+ log.trace( printer.showAsString( parser.getAST(), "--- {order-by fragment} ---" ) );
+ }
+
+ GeneratedOrderByFragmentRenderer renderer = new GeneratedOrderByFragmentRenderer();
+ try {
+ renderer.orderByFragment( parser.getAST() );
+ }
+ catch ( HibernateException e ) {
+ throw e;
+ }
+ catch ( Throwable t ) {
+ throw new HibernateException( "Unable to render parsed order-by fragment", t );
+ }
+
+ return renderer.getRenderedFragment();
+ }
+}
Added: core/trunk/core/src/main/java/org/hibernate/sql/ordering/antlr/OrderingSpecification.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/sql/ordering/antlr/OrderingSpecification.java (rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/sql/ordering/antlr/OrderingSpecification.java 2008-10-20 17:57:44 UTC (rev 15359)
@@ -0,0 +1,70 @@
+/*
+ * 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
+ *
+ */
+package org.hibernate.sql.ordering.antlr;
+
+/**
+ * Models an ordering specification (<tt>ASCENDING</tt> or <tt>DESCENDING</tt>) within a {@link SortSpecification}.
+ *
+ * @author Steve Ebersole
+ */
+public class OrderingSpecification extends NodeSupport {
+ public static class Ordering {
+ public static final Ordering ASCENDING = new Ordering( "asc" );
+ public static final Ordering DESCENDING = new Ordering( "desc" );
+
+ private final String name;
+
+ private Ordering(String name) {
+ this.name = name;
+ }
+ }
+
+ private boolean resolved;
+ private Ordering ordering;
+
+ public Ordering getOrdering() {
+ if ( !resolved ) {
+ ordering = resolve( getText() );
+ resolved = true;
+ }
+ return ordering;
+ }
+
+ private static Ordering resolve(String text) {
+ if ( Ordering.ASCENDING.name.equals( text ) ) {
+ return Ordering.ASCENDING;
+ }
+ else if ( Ordering.DESCENDING.name.equals( text ) ) {
+ return Ordering.DESCENDING;
+ }
+ else {
+ throw new IllegalStateException( "Unknown ordering [" + text + "]" );
+ }
+ }
+
+ public String getRenderableText() {
+ return getOrdering().name;
+ }
+}
Added: core/trunk/core/src/main/java/org/hibernate/sql/ordering/antlr/SortKey.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/sql/ordering/antlr/SortKey.java (rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/sql/ordering/antlr/SortKey.java 2008-10-20 17:57:44 UTC (rev 15359)
@@ -0,0 +1,34 @@
+/*
+ * 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
+ *
+ */
+package org.hibernate.sql.ordering.antlr;
+
+/**
+ * Models the container node for the <tt>sort key</tt>, which is the term given by the ANSI SQL specification to the
+ * expression upon which to sort for each {@link SortSpecification}
+ *
+ * @author Steve Ebersole
+ */
+public class SortKey extends NodeSupport {
+}
Added: core/trunk/core/src/main/java/org/hibernate/sql/ordering/antlr/SortSpecification.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/sql/ordering/antlr/SortSpecification.java (rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/sql/ordering/antlr/SortSpecification.java 2008-10-20 17:57:44 UTC (rev 15359)
@@ -0,0 +1,80 @@
+/*
+ * 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
+ *
+ */
+package org.hibernate.sql.ordering.antlr;
+
+import antlr.collections.AST;
+
+/**
+ * Models each sorting exprersion.
+ *
+ * @author Steve Ebersole
+ */
+public class SortSpecification extends NodeSupport {
+ /**
+ * Locate the specified {@link SortKey}.
+ *
+ * @return The sort key.
+ */
+ public SortKey getSortKey() {
+ return ( SortKey ) getFirstChild();
+ }
+
+ /**
+ * Locate the specified <tt>collation specification</tt>, if one.
+ *
+ * @return The <tt>collation specification</tt>, or null if none was specified.
+ */
+ public CollationSpecification getCollation() {
+ AST possible = getSortKey().getNextSibling();
+ return possible != null && OrderByTemplateTokenTypes.COLLATE == possible.getType()
+ ? ( CollationSpecification ) possible
+ : null;
+ }
+
+ /**
+ * Locate the specified <tt>ordering specification</tt>, if one.
+ *
+ * @return The <tt>ordering specification</tt>, or null if none was specified.
+ */
+ public OrderingSpecification getOrdering() {
+ // IMPL NOTE : the ordering-spec would be either the 2nd or 3rd child (of the overall sort-spec), if it existed,
+ // depending on whether a collation-spec was specified.
+
+ AST possible = getSortKey().getNextSibling();
+ if ( possible == null ) {
+ // There was no sort-spec parts specified other then the sort-key so there can be no ordering-spec...
+ return null;
+ }
+
+ if ( OrderByTemplateTokenTypes.COLLATE == possible.getType() ) {
+ // the 2nd child was a collation-spec, so we need to check the 3rd child instead.
+ possible = possible.getNextSibling();
+ }
+
+ return possible != null && OrderByTemplateTokenTypes.ORDER_SPEC == possible.getType()
+ ? ( OrderingSpecification ) possible
+ : null;
+ }
+}
Added: core/trunk/core/src/main/java/org/hibernate/sql/ordering/antlr/TranslationContext.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/sql/ordering/antlr/TranslationContext.java (rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/sql/ordering/antlr/TranslationContext.java 2008-10-20 17:57:44 UTC (rev 15359)
@@ -0,0 +1,64 @@
+/*
+ * 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
+ *
+ */
+package org.hibernate.sql.ordering.antlr;
+
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.dialect.Dialect;
+import org.hibernate.dialect.function.SQLFunctionRegistry;
+
+/**
+ * Contract for contextual information required to perform translation.
+*
+* @author Steve Ebersole
+*/
+public interface TranslationContext {
+ /**
+ * Retrieves the <tt>session factory</tt> for this context.
+ *
+ * @return The <tt>session factory</tt>
+ */
+ public SessionFactoryImplementor getSessionFactory();
+
+ /**
+ * Retrieves the <tt>dialect</tt> for this context.
+ *
+ * @return The <tt>dialect</tt>
+ */
+ public Dialect getDialect();
+
+ /**
+ * Retrieves the <tt>SQL function registry/tt> for this context.
+ *
+ * @return The SQL function registry.
+ */
+ public SQLFunctionRegistry getSqlFunctionRegistry();
+
+ /**
+ * Retrieves the <tt>column mapper</tt> for this context.
+ *
+ * @return The <tt>column mapper</tt>
+ */
+ public ColumnMapper getColumnMapper();
+}
Added: core/trunk/core/src/test/java/org/hibernate/sql/TemplateTest.java
===================================================================
--- core/trunk/core/src/test/java/org/hibernate/sql/TemplateTest.java (rev 0)
+++ core/trunk/core/src/test/java/org/hibernate/sql/TemplateTest.java 2008-10-20 17:57:44 UTC (rev 15359)
@@ -0,0 +1,184 @@
+/*
+ * 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
+ *
+ */
+package org.hibernate.sql;
+
+import java.util.Collections;
+
+import junit.framework.TestCase;
+
+import org.hibernate.persister.entity.PropertyMapping;
+import org.hibernate.type.Type;
+import org.hibernate.QueryException;
+import org.hibernate.sql.ordering.antlr.ColumnMapper;
+import org.hibernate.dialect.Dialect;
+import org.hibernate.dialect.HSQLDialect;
+import org.hibernate.dialect.function.SQLFunctionRegistry;
+
+/**
+ * TODO : javadoc
+ *
+ * @author Steve Ebersole
+ */
+public class TemplateTest extends TestCase {
+ private static final PropertyMapping PROPERTY_MAPPING = new PropertyMapping() {
+ public String[] toColumns(String propertyName) throws QueryException, UnsupportedOperationException {
+ if ( "sql".equals( propertyName ) ) {
+ return new String[] { "sql" };
+ }
+ else if ( "component".equals( propertyName ) ) {
+ return new String[] { "comp_1", "comp_2" };
+ }
+ else if ( "component.prop1".equals( propertyName ) ) {
+ return new String[] { "comp_1" };
+ }
+ else if ( "component.prop2".equals( propertyName ) ) {
+ return new String[] { "comp_2" };
+ }
+ else if ( "property".equals( propertyName ) ) {
+ return new String[] { "prop" };
+ }
+ throw new QueryException( "could not resolve property: " + propertyName );
+ }
+
+ public Type toType(String propertyName) throws QueryException {
+ return null;
+ }
+
+ public String[] toColumns(String alias, String propertyName) throws QueryException {
+ return new String[0];
+ }
+
+ public Type getType() {
+ return null;
+ }
+ };
+
+ private static final ColumnMapper MAPPER = new ColumnMapper() {
+ public String[] map(String reference) {
+ return PROPERTY_MAPPING.toColumns( reference );
+ }
+ };
+
+ private static final Dialect DIALECT = new HSQLDialect();
+
+ private static final SQLFunctionRegistry FUNCTION_REGISTRY = new SQLFunctionRegistry( DIALECT, Collections.EMPTY_MAP );
+
+ public void testSQLReferences() {
+ String fragment = "sql asc, sql desc";
+ String template = doStandardRendering( fragment );
+
+ assertEquals( Template.TEMPLATE + ".sql asc, " + Template.TEMPLATE + ".sql desc", template );
+ }
+
+ public void testQuotedSQLReferences() {
+ String fragment = "`sql` asc, `sql` desc";
+ String template = doStandardRendering( fragment );
+
+ assertEquals( Template.TEMPLATE + ".\"sql\" asc, " + Template.TEMPLATE + ".\"sql\" desc", template );
+ }
+
+ public void testPropertyReference() {
+ String fragment = "property asc, property desc";
+ String template = doStandardRendering( fragment );
+
+ assertEquals( Template.TEMPLATE + ".prop asc, " + Template.TEMPLATE + ".prop desc", template );
+ }
+
+ public void testFunctionReference() {
+ String fragment = "upper(sql) asc, lower(sql) desc";
+ String template = doStandardRendering( fragment );
+
+ assertEquals( "upper(" + Template.TEMPLATE + ".sql) asc, lower(" + Template.TEMPLATE + ".sql) desc", template );
+ }
+
+ public void testQualifiedFunctionReference() {
+ String fragment = "qual.upper(property) asc, qual.lower(property) desc";
+ String template = doStandardRendering( fragment );
+
+ assertEquals( "qual.upper(" + Template.TEMPLATE + ".prop) asc, qual.lower(" + Template.TEMPLATE + ".prop) desc", template );
+ }
+
+ public void testDoubleQualifiedFunctionReference() {
+ String fragment = "qual1.qual2.upper(property) asc, qual1.qual2.lower(property) desc";
+ String template = doStandardRendering( fragment );
+
+ assertEquals( "qual1.qual2.upper(" + Template.TEMPLATE + ".prop) asc, qual1.qual2.lower(" + Template.TEMPLATE + ".prop) desc", template );
+ }
+
+ public void testFunctionWithPropertyReferenceAsParam() {
+ String fragment = "upper(property) asc, lower(property) desc";
+ String template = doStandardRendering( fragment );
+
+ assertEquals( "upper(" + Template.TEMPLATE + ".prop) asc, lower(" + Template.TEMPLATE + ".prop) desc", template );
+ }
+
+ public void testNestedFunctionReferences() {
+ String fragment = "upper(lower(sql)) asc, lower(upper(sql)) desc";
+ String template = doStandardRendering( fragment );
+
+ assertEquals( "upper(lower(" + Template.TEMPLATE + ".sql)) asc, lower(upper(" + Template.TEMPLATE + ".sql)) desc", template );
+ }
+
+ public void testComplexNestedFunctionReferences() {
+ String fragment = "mod(mod(sql,2),3) asc";
+ String template = doStandardRendering( fragment );
+
+ assertEquals( "mod(mod(" + Template.TEMPLATE + ".sql, 2), 3) asc", template );
+ }
+
+ public void testCollation() {
+ String fragment = "`sql` COLLATE my_collation, `sql` COLLATE your_collation";
+ String template = doStandardRendering( fragment );
+
+ assertEquals( Template.TEMPLATE + ".\"sql\" collate my_collation, " + Template.TEMPLATE + ".\"sql\" collate your_collation", template );
+ }
+
+ public void testCollationAndOrdering() {
+ String fragment = "sql COLLATE my_collation, upper(prop) COLLATE your_collation asc, `sql` desc";
+ String template = doStandardRendering( fragment );
+
+ assertEquals( Template.TEMPLATE + ".sql collate my_collation, upper(" + Template.TEMPLATE + ".prop) collate your_collation asc, " + Template.TEMPLATE + ".\"sql\" desc", template );
+
+ }
+
+ public void testComponentReferences() {
+ String fragment = "component asc";
+ String template = doStandardRendering( fragment );
+
+ assertEquals( Template.TEMPLATE + ".comp_1 asc, " + Template.TEMPLATE + ".comp_2 asc", template );
+
+ }
+
+ public void testComponentDerefReferences() {
+ String fragment = "component.prop1 asc";
+ String template = doStandardRendering( fragment );
+
+ assertEquals( Template.TEMPLATE + ".comp_1 asc", template );
+ }
+
+ public String doStandardRendering(String fragment) {
+ return Template.renderOrderByStringTemplate( fragment, MAPPER, null, DIALECT, FUNCTION_REGISTRY );
+ }
+}
\ No newline at end of file
Modified: core/trunk/core/src/test/resources/log4j.properties
===================================================================
--- core/trunk/core/src/test/resources/log4j.properties 2008-10-20 17:13:25 UTC (rev 15358)
+++ core/trunk/core/src/test/resources/log4j.properties 2008-10-20 17:57:44 UTC (rev 15359)
@@ -21,7 +21,6 @@
# 51 Franklin Street, Fifth Floor
# Boston, MA 02110-1301 USA
#
-#
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
@@ -31,3 +30,4 @@
log4j.logger.org.hibernate.test=info
log4j.logger.org.hibernate.tool.hbm2ddl=debug
+log4j.logger.org.hibernate.sql.ordering.antlr.OrderByFragmentTranslator=trace
\ No newline at end of file
16 years, 11 months
Hibernate SVN: r15358 - search/trunk/src/java/org/hibernate/search/bridge.
by hibernate-commits@lists.jboss.org
Author: epbernard
Date: 2008-10-20 13:13:25 -0400 (Mon, 20 Oct 2008)
New Revision: 15358
Modified:
search/trunk/src/java/org/hibernate/search/bridge/TwoWayFieldBridge.java
Log:
Remove experimental warning on objectToString()
Modified: search/trunk/src/java/org/hibernate/search/bridge/TwoWayFieldBridge.java
===================================================================
--- search/trunk/src/java/org/hibernate/search/bridge/TwoWayFieldBridge.java 2008-10-20 14:45:15 UTC (rev 15357)
+++ search/trunk/src/java/org/hibernate/search/bridge/TwoWayFieldBridge.java 2008-10-20 17:13:25 UTC (rev 15358)
@@ -26,7 +26,6 @@
/**
* convert the object representation to a String
* The return String must not be null, it can be empty though
- * EXPERIMENTAL API subject to change in the future
*/
String objectToString(Object object);
}
16 years, 11 months