Hibernate SVN: r15862 - in core/branches/Branch_3_3/core/src/main/java/org/hibernate: event/def and 1 other directories.
by hibernate-commits@lists.jboss.org
Author: steve.ebersole(a)jboss.com
Date: 2009-02-02 20:14:53 -0500 (Mon, 02 Feb 2009)
New Revision: 15862
Modified:
core/branches/Branch_3_3/core/src/main/java/org/hibernate/engine/StatefulPersistenceContext.java
core/branches/Branch_3_3/core/src/main/java/org/hibernate/event/def/DefaultEvictEventListener.java
core/branches/Branch_3_3/core/src/main/java/org/hibernate/proxy/AbstractLazyInitializer.java
core/branches/Branch_3_3/core/src/main/java/org/hibernate/proxy/LazyInitializer.…
[View More]java
Log:
HHH-3357 : clear() performance
Modified: core/branches/Branch_3_3/core/src/main/java/org/hibernate/engine/StatefulPersistenceContext.java
===================================================================
--- core/branches/Branch_3_3/core/src/main/java/org/hibernate/engine/StatefulPersistenceContext.java 2009-02-03 00:47:57 UTC (rev 15861)
+++ core/branches/Branch_3_3/core/src/main/java/org/hibernate/engine/StatefulPersistenceContext.java 2009-02-03 01:14:53 UTC (rev 15862)
@@ -204,7 +204,7 @@
Iterator itr = proxiesByKey.values().iterator();
while ( itr.hasNext() ) {
final LazyInitializer li = ( ( HibernateProxy ) itr.next() ).getHibernateLazyInitializer();
- li.setSession( null );
+ li.unsetSession();
}
Map.Entry[] collectionEntryArray = IdentityMap.concurrentEntries( collectionEntries );
for ( int i = 0; i < collectionEntryArray.length; i++ ) {
Modified: core/branches/Branch_3_3/core/src/main/java/org/hibernate/event/def/DefaultEvictEventListener.java
===================================================================
--- core/branches/Branch_3_3/core/src/main/java/org/hibernate/event/def/DefaultEvictEventListener.java 2009-02-03 00:47:57 UTC (rev 15861)
+++ core/branches/Branch_3_3/core/src/main/java/org/hibernate/event/def/DefaultEvictEventListener.java 2009-02-03 01:14:53 UTC (rev 15862)
@@ -83,7 +83,7 @@
doEvict( entity, key, e.getPersister(), event.getSession() );
}
}
- li.setSession( null );
+ li.unsetSession();
}
else {
EntityEntry e = persistenceContext.removeEntry( object );
Modified: core/branches/Branch_3_3/core/src/main/java/org/hibernate/proxy/AbstractLazyInitializer.java
===================================================================
--- core/branches/Branch_3_3/core/src/main/java/org/hibernate/proxy/AbstractLazyInitializer.java 2009-02-03 00:47:57 UTC (rev 15861)
+++ core/branches/Branch_3_3/core/src/main/java/org/hibernate/proxy/AbstractLazyInitializer.java 2009-02-03 01:14:53 UTC (rev 15862)
@@ -32,54 +32,100 @@
import org.hibernate.engine.SessionImplementor;
/**
- * Convenience base class for lazy initialization handlers. Centralizes the
- * basic plumbing of doing lazy initialization freeing subclasses to
- * acts as essentially adapters to their intended entity mode and/or
+ * Convenience base class for lazy initialization handlers. Centralizes the basic plumbing of doing lazy
+ * initialization freeing subclasses to acts as essentially adapters to their intended entity mode and/or
* proxy generation strategy.
*
* @author Gavin King
*/
public abstract class AbstractLazyInitializer implements LazyInitializer {
-
+ private String entityName;
+ private Serializable id;
private Object target;
private boolean initialized;
- private String entityName;
- private Serializable id;
- private transient SessionImplementor session;
private boolean unwrap;
+ private transient SessionImplementor session;
+
/**
* For serialization from the non-pojo initializers (HHH-3309)
*/
protected AbstractLazyInitializer() {
}
-
+
+ /**
+ * Main constructor.
+ *
+ * @param entityName The name of the entity being proxied.
+ * @param id The identifier of the entity being proxied.
+ * @param session The session owning the proxy.
+ */
protected AbstractLazyInitializer(String entityName, Serializable id, SessionImplementor session) {
+ this.entityName = entityName;
this.id = id;
this.session = session;
- this.entityName = entityName;
}
+ /**
+ * {@inheritDoc}
+ */
+ public final String getEntityName() {
+ return entityName;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
public final Serializable getIdentifier() {
return id;
}
+ /**
+ * {@inheritDoc}
+ */
public final void setIdentifier(Serializable id) {
this.id = id;
}
- public final String getEntityName() {
- return entityName;
- }
-
+ /**
+ * {@inheritDoc}
+ */
public final boolean isUninitialized() {
return !initialized;
}
+ /**
+ * {@inheritDoc}
+ */
public final SessionImplementor getSession() {
return session;
}
+ /**
+ * {@inheritDoc}
+ */
+ public final void setSession(SessionImplementor s) throws HibernateException {
+ if ( s != session ) {
+ if ( isConnectedToSession() ) {
+ //TODO: perhaps this should be some other RuntimeException...
+ throw new HibernateException("illegally attempted to associate a proxy with two open Sessions");
+ }
+ else {
+ session = s;
+ }
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void unsetSession() {
+ session = null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
public final void initialize() throws HibernateException {
if (!initialized) {
if ( session==null ) {
@@ -110,28 +156,16 @@
}
}
- public final void setSession(SessionImplementor s) throws HibernateException {
- if (s!=session) {
- if ( isConnectedToSession() ) {
- //TODO: perhaps this should be some other RuntimeException...
- throw new HibernateException("illegally attempted to associate a proxy with two open Sessions");
- }
- else {
- session = s;
- }
- }
- }
-
+ /**
+ * Getter for property 'connectedToSession'.
+ *
+ * @return Value for property 'connectedToSession'.
+ */
protected final boolean isConnectedToSession() {
- return session!=null &&
- session.isOpen() &&
+ return session!=null &&
+ session.isOpen() &&
session.getPersistenceContext().containsProxy(this);
}
-
- public final void setImplementation(Object target) {
- this.target = target;
- initialized = true;
- }
/**
* Return the underlying persistent object, initializing if necessary
@@ -142,6 +176,14 @@
}
/**
+ * {@inheritDoc}
+ */
+ public final void setImplementation(Object target) {
+ this.target = target;
+ initialized = true;
+ }
+
+ /**
* Return the underlying persistent object in the given <tt>Session</tt>, or null,
* do not initialize the proxy
*/
@@ -150,20 +192,32 @@
getIdentifier(),
s.getFactory().getEntityPersister( getEntityName() ),
s.getEntityMode()
- );
+ );
return s.getPersistenceContext().getEntity( entityKey );
}
+ /**
+ * Getter for property 'target'.
+ * <p/>
+ * Same as {@link #getImplementation()} except that this method will not force initialization.
+ *
+ * @return Value for property 'target'.
+ */
protected final Object getTarget() {
return target;
}
+ /**
+ * {@inheritDoc}
+ */
public boolean isUnwrap() {
return unwrap;
}
+ /**
+ * {@inheritDoc}
+ */
public void setUnwrap(boolean unwrap) {
this.unwrap = unwrap;
}
-
}
Modified: core/branches/Branch_3_3/core/src/main/java/org/hibernate/proxy/LazyInitializer.java
===================================================================
--- core/branches/Branch_3_3/core/src/main/java/org/hibernate/proxy/LazyInitializer.java 2009-02-03 00:47:57 UTC (rev 15861)
+++ core/branches/Branch_3_3/core/src/main/java/org/hibernate/proxy/LazyInitializer.java 2009-02-03 01:14:53 UTC (rev 15862)
@@ -31,68 +31,109 @@
/**
* Handles fetching of the underlying entity for a proxy
+ *
* @author Gavin King
+ * @author Steve Ebersole
*/
public interface LazyInitializer {
-
/**
- * Initialize the proxy, fetching the target
- * entity if necessary
+ * Initialize the proxy, fetching the target entity if necessary.
+ *
+ * @throws HibernateException Indicates a problem initializing the proxy.
*/
- public abstract void initialize() throws HibernateException;
-
+ public void initialize() throws HibernateException;
+
/**
- * Get the identifier held by the proxy
+ * Retrieve the identifier value for the enity our owning proxy represents.
+ *
+ * @return The identifier value.
*/
- public abstract Serializable getIdentifier();
+ public Serializable getIdentifier();
/**
- * Set the identifier property of the proxy
+ * Set the identifier value for the enity our owning proxy represents.
+ *
+ * @param id The identifier value.
*/
- public abstract void setIdentifier(Serializable id);
-
+ public void setIdentifier(Serializable id);
+
/**
- * Get the entity name
+ * The entity-name of the entity our owning proxy represents.
+ *
+ * @return The entity-name.
*/
- public abstract String getEntityName();
-
+ public String getEntityName();
+
/**
- * Get the actual class of the entity (don't
- * use this, use the entityName)
+ * Get the actual class of the entity. Generally, {@link #getEntityName()} should be used instead.
+ *
+ * @return The actual entity class.
*/
- public abstract Class getPersistentClass();
-
+ public Class getPersistentClass();
+
/**
* Is the proxy uninitialzed?
+ *
+ * @return True if uninitialized; false otherwise.
*/
- public abstract boolean isUninitialized();
-
+ public boolean isUninitialized();
+
/**
- * Initialize the proxy manually
+ * Return the underlying persistent object, initializing if necessary
+ *
+ * @return The underlying target entity.
*/
- public abstract void setImplementation(Object target);
-
+ public Object getImplementation();
+
/**
- * Get the session, if this proxy is attached
+ * Return the underlying persistent object in the given session, or null if not contained in this session's
+ * persistence context.
+ *
+ * @param session The session to check
+ *
+ * @return The target, or null.
+ *
+ * @throws HibernateException Indicates problem locating the target.
*/
- public abstract SessionImplementor getSession();
-
+ public abstract Object getImplementation(SessionImplementor session) throws HibernateException;
+
/**
- * Attach the proxy to a session
+ * Initialize the proxy manually by injecting its target.
+ *
+ * @param target The proxy target (the actual entity being proxied).
*/
- public abstract void setSession(SessionImplementor s) throws HibernateException;
+ public void setImplementation(Object target);
/**
- * Return the underlying persistent object, initializing if necessary
+ * Get the session to which this proxy is associated, or null if it is not attached.
+ *
+ * @return The associated session.
*/
- public abstract Object getImplementation();
+ public SessionImplementor getSession();
/**
- * Return the underlying persistent object in the given <tt>Session</tt>, or null
+ * Associate the proxy with the given session.
+ * <p/>
+ * Care should be given to make certain that the proxy is added to the session's persistence context as well
+ * to maintain the symetry of the association. That must be done seperately as this method simply sets an
+ * internal reference. We do also check that if there is already an associated session that the proxy
+ * reference was removed from that previous session's persistence contet.
+ *
+ * @param session The session
+ * @throws HibernateException Indicates that the proxy was still contained in the persistence context of the
+ * "previous session".
*/
- public abstract Object getImplementation(SessionImplementor s)
- throws HibernateException;
+ public void setSession(SessionImplementor session) throws HibernateException;
+
+ /**
+ * Unset this initializer's reference to session. It is assumed that the caller is also taking care or
+ * cleaning up the owning proxy's reference in the persistence context.
+ * <p/>
+ * Generally speaking this is intended to be called only during {@link org.hibernate.Session#evict} and
+ * {@link org.hibernate.Session#clear} processing; most other use-cases should call {@link #setSession} instead.
+ */
+ public void unsetSession();
public void setUnwrap(boolean unwrap);
public boolean isUnwrap();
-}
\ No newline at end of file
+}
[View Less]
16 years
Hibernate SVN: r15861 - in core/branches/Branch_3_2: test/org/hibernate/test/dialect and 1 other directories.
by hibernate-commits@lists.jboss.org
Author: steve.ebersole(a)jboss.com
Date: 2009-02-02 19:47:57 -0500 (Mon, 02 Feb 2009)
New Revision: 15861
Added:
core/branches/Branch_3_2/src/org/hibernate/dialect/function/AbstractAnsiTrimEmulationFunction.java
core/branches/Branch_3_2/test/org/hibernate/test/dialect/function/
core/branches/Branch_3_2/test/org/hibernate/test/dialect/function/AnsiTrimEmulationFunctionTest.java
Modified:
core/branches/Branch_3_2/src/org/hibernate/dialect/function/AnsiTrimEmulationFunction.java
Log:
…
[View More]HHH-3701 : trim function emulation for sybase
Copied: core/branches/Branch_3_2/src/org/hibernate/dialect/function/AbstractAnsiTrimEmulationFunction.java (from rev 15840, core/branches/Branch_3_2/src/org/hibernate/dialect/function/AnsiTrimEmulationFunction.java)
===================================================================
--- core/branches/Branch_3_2/src/org/hibernate/dialect/function/AbstractAnsiTrimEmulationFunction.java (rev 0)
+++ core/branches/Branch_3_2/src/org/hibernate/dialect/function/AbstractAnsiTrimEmulationFunction.java 2009-02-03 00:47:57 UTC (rev 15861)
@@ -0,0 +1,227 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009, 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.dialect.function;
+
+import org.hibernate.Hibernate;
+import org.hibernate.QueryException;
+import org.hibernate.engine.Mapping;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.type.Type;
+
+import java.util.List;
+import java.util.ArrayList;
+
+/**
+ * A {@link org.hibernate.dialect.function.SQLFunction} providing support for implementing TRIM functionality
+ * (as defined by both the ANSI SQL and JPA specs) in cases where the dialect may not support the full <tt>trim</tt>
+ * function itself.
+ * <p/>
+ * Follows the <a href="http://en.wikipedia.org/wiki/Template_method_pattern">template</a> pattern in order to implement
+ * the {@link #render} method.
+ *
+ * @author Steve Ebersole
+ */
+public abstract class AbstractAnsiTrimEmulationFunction implements SQLFunction {
+ /**
+ * {@inheritDoc}
+ */
+ public final Type getReturnType(Type columnType, Mapping mapping) throws QueryException {
+ return Hibernate.STRING;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public final boolean hasArguments() {
+ return true;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public final boolean hasParenthesesIfNoArguments() {
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public final String render(List args, SessionFactoryImplementor factory) throws QueryException {
+ // According to both the ANSI-SQL and JPA specs, trim takes a variable number of parameters between 1 and 4.
+ // at least one paramer (trimSource) is required. From the SQL spec:
+ //
+ // <trim function> ::=
+ // TRIM <left paren> <trim operands> <right paren>
+ //
+ // <trim operands> ::=
+ // [ [ <trim specification> ] [ <trim character> ] FROM ] <trim source>
+ //
+ // <trim specification> ::=
+ // LEADING
+ // | TRAILING
+ // | BOTH
+ //
+ // If <trim specification> is omitted, BOTH is assumed.
+ // If <trim character> is omitted, space is assumed
+ if ( args.size() == 1 ) {
+ // we have the form: trim(trimSource)
+ // so we trim leading and trailing spaces
+ return resolveBothSpaceTrimFunction().render( args, factory ); // EARLY EXIT!!!!
+ }
+ else if ( "from".equalsIgnoreCase( ( String ) args.get( 0 ) ) ) {
+ // we have the form: trim(from trimSource).
+ // This is functionally equivalent to trim(trimSource)
+ return resolveBothSpaceTrimFromFunction().render( args, factory ); // EARLY EXIT!!!!
+ }
+ else {
+ // otherwise, a trim-specification and/or a trim-character
+ // have been specified; we need to decide which options
+ // are present and "do the right thing"
+ boolean leading = true; // should leading trim-characters be trimmed?
+ boolean trailing = true; // should trailing trim-characters be trimmed?
+ String trimCharacter; // the trim-character (what is to be trimmed off?)
+ String trimSource; // the trim-source (from where should it be trimmed?)
+
+ // potentialTrimCharacterArgIndex = 1 assumes that a
+ // trim-specification has been specified. we handle the
+ // exception to that explicitly
+ int potentialTrimCharacterArgIndex = 1;
+ String firstArg = ( String ) args.get( 0 );
+ if ( "leading".equalsIgnoreCase( firstArg ) ) {
+ trailing = false;
+ }
+ else if ( "trailing".equalsIgnoreCase( firstArg ) ) {
+ leading = false;
+ }
+ else if ( "both".equalsIgnoreCase( firstArg ) ) {
+ }
+ else {
+ potentialTrimCharacterArgIndex = 0;
+ }
+
+ String potentialTrimCharacter = ( String ) args.get( potentialTrimCharacterArgIndex );
+ if ( "from".equalsIgnoreCase( potentialTrimCharacter ) ) {
+ trimCharacter = "' '";
+ trimSource = ( String ) args.get( potentialTrimCharacterArgIndex + 1 );
+ }
+ else if ( potentialTrimCharacterArgIndex + 1 >= args.size() ) {
+ trimCharacter = "' '";
+ trimSource = potentialTrimCharacter;
+ }
+ else {
+ trimCharacter = potentialTrimCharacter;
+ if ( "from".equalsIgnoreCase( ( String ) args.get( potentialTrimCharacterArgIndex + 1 ) ) ) {
+ trimSource = ( String ) args.get( potentialTrimCharacterArgIndex + 2 );
+ }
+ else {
+ trimSource = ( String ) args.get( potentialTrimCharacterArgIndex + 1 );
+ }
+ }
+
+ List argsToUse = new ArrayList();
+ argsToUse.add( trimSource );
+ argsToUse.add( trimCharacter );
+
+ if ( trimCharacter.equals( "' '" ) ) {
+ if ( leading && trailing ) {
+ return resolveBothSpaceTrimFunction().render( argsToUse, factory );
+ }
+ else if ( leading ) {
+ return resolveLeadingSpaceTrimFunction().render( argsToUse, factory );
+ }
+ else {
+ return resolveTrailingSpaceTrimFunction().render( argsToUse, factory );
+ }
+ }
+ else {
+ if ( leading && trailing ) {
+ return resolveBothTrimFunction().render( argsToUse, factory );
+ }
+ else if ( leading ) {
+ return resolveLeadingTrimFunction().render( argsToUse, factory );
+ }
+ else {
+ return resolveTrailingTrimFunction().render( argsToUse, factory );
+ }
+ }
+ }
+ }
+
+ /**
+ * Resolve the function definition which should be used to trim both leading and trailing spaces.
+ * <p/>
+ * In this form, the imput arguments is missing the <tt>FROM</tt> keyword.
+ *
+ * @return The sql function
+ */
+ protected abstract SQLFunction resolveBothSpaceTrimFunction();
+
+ /**
+ * Resolve the function definition which should be used to trim both leading and trailing spaces.
+ * <p/>
+ * The same as {#link resolveBothSpaceTrimFunction} except that here the<tt>FROM</tt> is included and
+ * will need to be accounted for during {@link SQLFunction#render} processing.
+ *
+ * @return The sql function
+ */
+ protected abstract SQLFunction resolveBothSpaceTrimFromFunction();
+
+ /**
+ * Resolve the function definition which should be used to trim leading spaces.
+ *
+ * @return The sql function
+ */
+ protected abstract SQLFunction resolveLeadingSpaceTrimFunction();
+
+ /**
+ * Resolve the function definition which should be used to trim trailing spaces.
+ *
+ * @return The sql function
+ */
+ protected abstract SQLFunction resolveTrailingSpaceTrimFunction();
+
+ /**
+ * Resolve the function definition which should be used to trim the specified character from both the
+ * beginning (leading) and end (trailing) of the trim source.
+ *
+ * @return The sql function
+ */
+ protected abstract SQLFunction resolveBothTrimFunction();
+
+ /**
+ * Resolve the function definition which should be used to trim the specified character from the
+ * beginning (leading) of the trim source.
+ *
+ * @return The sql function
+ */
+ protected abstract SQLFunction resolveLeadingTrimFunction();
+
+ /**
+ * Resolve the function definition which should be used to trim the specified character from the
+ * end (trailing) of the trim source.
+ *
+ * @return The sql function
+ */
+ protected abstract SQLFunction resolveTrailingTrimFunction();
+}
\ No newline at end of file
Modified: core/branches/Branch_3_2/src/org/hibernate/dialect/function/AnsiTrimEmulationFunction.java
===================================================================
--- core/branches/Branch_3_2/src/org/hibernate/dialect/function/AnsiTrimEmulationFunction.java 2009-02-03 00:47:23 UTC (rev 15860)
+++ core/branches/Branch_3_2/src/org/hibernate/dialect/function/AnsiTrimEmulationFunction.java 2009-02-03 00:47:57 UTC (rev 15861)
@@ -1,14 +1,7 @@
package org.hibernate.dialect.function;
import org.hibernate.Hibernate;
-import org.hibernate.QueryException;
-import org.hibernate.engine.Mapping;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.type.Type;
-import java.util.List;
-import java.util.ArrayList;
-
/**
* A {@link SQLFunction} implementation that emulates the ANSI SQL trim function
* on dialects which do not support the full definition. However, this function
@@ -18,129 +11,222 @@
*
* @author Steve Ebersole
*/
-public class AnsiTrimEmulationFunction implements SQLFunction {
+public class AnsiTrimEmulationFunction extends AbstractAnsiTrimEmulationFunction {
+ public static final String LTRIM = "ltrim";
+ public static final String RTRIM = "rtrim";
+ public static final String REPLACE = "replace";
+ public static final String SPACE_PLACEHOLDER = "${space}$";
- private static final SQLFunction LEADING_SPACE_TRIM = new SQLFunctionTemplate( Hibernate.STRING, "ltrim( ?1 )");
- private static final SQLFunction TRAILING_SPACE_TRIM = new SQLFunctionTemplate( Hibernate.STRING, "rtrim( ?1 )");
- private static final SQLFunction BOTH_SPACE_TRIM = new SQLFunctionTemplate( Hibernate.STRING, "ltrim( rtrim( ?1 ) )");
- private static final SQLFunction BOTH_SPACE_TRIM_FROM = new SQLFunctionTemplate( Hibernate.STRING, "ltrim( rtrim( ?2 ) )");
+ public static final String LEADING_SPACE_TRIM_TEMPLATE = LTRIM + "(?1)";
+ public static final String TRAILING_SPACE_TRIM_TEMPLATE = RTRIM + "(?1)";
+ public static final String BOTH_SPACE_TRIM_TEMPLATE = LTRIM + "(" + RTRIM + "(?1))";
+ public static final String BOTH_SPACE_TRIM_FROM_TEMPLATE = LTRIM + "(" + RTRIM + "(?2))"; //skip the FROM keyword in params
- private static final SQLFunction LEADING_TRIM = new SQLFunctionTemplate( Hibernate.STRING, "replace( replace( rtrim( replace( replace( ?1, ' ', '${space}$' ), ?2, ' ' ) ), ' ', ?2 ), '${space}$', ' ' )" );
- private static final SQLFunction TRAILING_TRIM = new SQLFunctionTemplate( Hibernate.STRING, "replace( replace( ltrim( replace( replace( ?1, ' ', '${space}$' ), ?2, ' ' ) ), ' ', ?2 ), '${space}$', ' ' )" );
- private static final SQLFunction BOTH_TRIM = new SQLFunctionTemplate( Hibernate.STRING, "replace( replace( ltrim( rtrim( replace( replace( ?1, ' ', '${space}$' ), ?2, ' ' ) ) ), ' ', ?2 ), '${space}$', ' ' )" );
+ /**
+ * A template for the series of calls required to trim non-space chars from the beginning of text.
+ * <p/>
+ * NOTE : essentially we:</ol>
+ * <li>replace all space chars with the text '${space}$'</li>
+ * <li>replace all the actual replacement chars with space chars</li>
+ * <li>perform left-trimming (that removes any of the space chars we just added which occur at the beginning of the text)</li>
+ * <li>replace all space chars with the replacement char</li>
+ * <li>replace all the '${space}$' text with space chars</li>
+ * </ol>
+ */
+ public static final String LEADING_TRIM_TEMPLATE =
+ REPLACE + "(" +
+ REPLACE + "(" +
+ LTRIM + "(" +
+ REPLACE + "(" +
+ REPLACE + "(" +
+ "?1," +
+ "' '," +
+ "'" + SPACE_PLACEHOLDER + "'" +
+ ")," +
+ "?2," +
+ "' '" +
+ ")" +
+ ")," +
+ "' '," +
+ "?2" +
+ ")," +
+ "'" + SPACE_PLACEHOLDER + "'," +
+ "' '" +
+ ")";
- public Type getReturnType(Type columnType, Mapping mapping) throws QueryException {
- return Hibernate.STRING;
+ /**
+ * A template for the series of calls required to trim non-space chars from the end of text.
+ * <p/>
+ * NOTE: essentially the same series of calls as outlined in {@link #LEADING_TRIM_TEMPLATE} except that here,
+ * instead of left-trimming the added spaces, we right-trim them to remove them from the end of the text.
+ */
+ public static final String TRAILING_TRIM_TEMPLATE =
+ REPLACE + "(" +
+ REPLACE + "(" +
+ RTRIM + "(" +
+ REPLACE + "(" +
+ REPLACE + "(" +
+ "?1," +
+ "' '," +
+ "'" + SPACE_PLACEHOLDER + "'" +
+ ")," +
+ "?2," +
+ "' '" +
+ ")" +
+ ")," +
+ "' '," +
+ "?2" +
+ ")," +
+ "'" + SPACE_PLACEHOLDER + "'," +
+ "' '" +
+ ")";
+
+ /**
+ * A template for the series of calls required to trim non-space chars from both the beginning and the end of text.
+ * <p/>
+ * NOTE: again, we have a series of calls that is essentially the same as outlined in {@link #LEADING_TRIM_TEMPLATE}
+ * except that here we perform both left (leading) and right (trailing) trimming.
+ */
+ public static final String BOTH_TRIM_TEMPLATE =
+ REPLACE + "(" +
+ REPLACE + "(" +
+ LTRIM + "(" +
+ RTRIM + "(" +
+ REPLACE + "(" +
+ REPLACE + "(" +
+ "?1," +
+ "' '," +
+ "'" + SPACE_PLACEHOLDER + "'" +
+ ")," +
+ "?2," +
+ "' '" +
+ ")" +
+ ")" +
+ ")," +
+ "' '," +
+ "?2" +
+ ")," +
+ "'" + SPACE_PLACEHOLDER + "'," +
+ "' '" +
+ ")";
+
+ private final SQLFunction leadingSpaceTrim;
+ private final SQLFunction trailingSpaceTrim;
+ private final SQLFunction bothSpaceTrim;
+ private final SQLFunction bothSpaceTrimFrom;
+
+ private final SQLFunction leadingTrim;
+ private final SQLFunction trailingTrim;
+ private final SQLFunction bothTrim;
+
+ /**
+ * Constructs a new AnsiTrimEmulationFunction using {@link #LTRIM}, {@link #RTRIM}, and {@link #REPLACE}
+ * respectively.
+ *
+ * @see #AnsiTrimEmulationFunction(String,String,String)
+ */
+ public AnsiTrimEmulationFunction() {
+ this( LTRIM, RTRIM, REPLACE );
}
- public boolean hasArguments() {
- return true;
+ /**
+ * Constructs a <tt>trim()</tt> emulation function definition using the specified function calls.
+ *
+ * @param ltrimFunctionName The <tt>left trim</tt> function to use.
+ * @param rtrimFunctionName The <tt>right trim</tt> function to use.
+ * @param replaceFunctionName The <tt>replace</tt> function to use.
+ */
+ public AnsiTrimEmulationFunction(String ltrimFunctionName, String rtrimFunctionName, String replaceFunctionName) {
+ leadingSpaceTrim = new SQLFunctionTemplate(
+ Hibernate.STRING,
+ LEADING_SPACE_TRIM_TEMPLATE.replaceAll( LTRIM, ltrimFunctionName )
+ );
+
+ trailingSpaceTrim = new SQLFunctionTemplate(
+ Hibernate.STRING,
+ TRAILING_SPACE_TRIM_TEMPLATE.replaceAll( RTRIM, rtrimFunctionName )
+ );
+
+ bothSpaceTrim = new SQLFunctionTemplate(
+ Hibernate.STRING,
+ BOTH_SPACE_TRIM_TEMPLATE.replaceAll( LTRIM, ltrimFunctionName )
+ .replaceAll( RTRIM, rtrimFunctionName )
+ );
+
+ bothSpaceTrimFrom = new SQLFunctionTemplate(
+ Hibernate.STRING,
+ BOTH_SPACE_TRIM_FROM_TEMPLATE.replaceAll( LTRIM, ltrimFunctionName )
+ .replaceAll( RTRIM, rtrimFunctionName )
+ );
+
+ leadingTrim = new SQLFunctionTemplate(
+ Hibernate.STRING,
+ LEADING_TRIM_TEMPLATE.replaceAll( LTRIM, ltrimFunctionName )
+ .replaceAll( RTRIM, rtrimFunctionName )
+ .replaceAll( REPLACE,replaceFunctionName )
+ );
+
+ trailingTrim = new SQLFunctionTemplate(
+ Hibernate.STRING,
+ TRAILING_TRIM_TEMPLATE.replaceAll( LTRIM, ltrimFunctionName )
+ .replaceAll( RTRIM, rtrimFunctionName )
+ .replaceAll( REPLACE,replaceFunctionName )
+ );
+
+ bothTrim = new SQLFunctionTemplate(
+ Hibernate.STRING,
+ BOTH_TRIM_TEMPLATE.replaceAll( LTRIM, ltrimFunctionName )
+ .replaceAll( RTRIM, rtrimFunctionName )
+ .replaceAll( REPLACE,replaceFunctionName )
+ );
}
- public boolean hasParenthesesIfNoArguments() {
- return false;
+ /**
+ * {@inheritDoc}
+ */
+ protected SQLFunction resolveBothSpaceTrimFunction() {
+ return bothSpaceTrim;
}
- public String render(List args, SessionFactoryImplementor factory) throws QueryException {
- // according to both the ANSI-SQL and EJB3 specs, trim can either take
- // exactly one parameter or a variable number of parameters between 1 and 4.
- // from the SQL spec:
- //
- // <trim function> ::=
- // TRIM <left paren> <trim operands> <right paren>
- //
- // <trim operands> ::=
- // [ [ <trim specification> ] [ <trim character> ] FROM ] <trim source>
- //
- // <trim specification> ::=
- // LEADING
- // | TRAILING
- // | BOTH
- //
- // If only <trim specification> is omitted, BOTH is assumed;
- // if <trim character> is omitted, space is assumed
- if ( args.size() == 1 ) {
- // we have the form: trim(trimSource)
- // so we trim leading and trailing spaces
- return BOTH_SPACE_TRIM.render( args, factory );
- }
- else if ( "from".equalsIgnoreCase( ( String ) args.get( 0 ) ) ) {
- // we have the form: trim(from trimSource).
- // This is functionally equivalent to trim(trimSource)
- return BOTH_SPACE_TRIM_FROM.render( args, factory );
- }
- else {
- // otherwise, a trim-specification and/or a trim-character
- // have been specified; we need to decide which options
- // are present and "do the right thing"
- boolean leading = true; // should leading trim-characters be trimmed?
- boolean trailing = true; // should trailing trim-characters be trimmed?
- String trimCharacter = null; // the trim-character
- String trimSource = null; // the trim-source
+ /**
+ * {@inheritDoc}
+ */
+ protected SQLFunction resolveBothSpaceTrimFromFunction() {
+ return bothSpaceTrimFrom;
+ }
- // potentialTrimCharacterArgIndex = 1 assumes that a
- // trim-specification has been specified. we handle the
- // exception to that explicitly
- int potentialTrimCharacterArgIndex = 1;
- String firstArg = ( String ) args.get( 0 );
- if ( "leading".equalsIgnoreCase( firstArg ) ) {
- trailing = false;
- }
- else if ( "trailing".equalsIgnoreCase( firstArg ) ) {
- leading = false;
- }
- else if ( "both".equalsIgnoreCase( firstArg ) ) {
- }
- else {
- potentialTrimCharacterArgIndex = 0;
- }
+ /**
+ * {@inheritDoc}
+ */
+ protected SQLFunction resolveLeadingSpaceTrimFunction() {
+ return leadingSpaceTrim;
+ }
- String potentialTrimCharacter = ( String ) args.get( potentialTrimCharacterArgIndex );
- if ( "from".equalsIgnoreCase( potentialTrimCharacter ) ) {
- trimCharacter = "' '";
- trimSource = ( String ) args.get( potentialTrimCharacterArgIndex + 1 );
- }
- else if ( potentialTrimCharacterArgIndex + 1 >= args.size() ) {
- trimCharacter = "' '";
- trimSource = potentialTrimCharacter;
- }
- else {
- trimCharacter = potentialTrimCharacter;
- if ( "from".equalsIgnoreCase( ( String ) args.get( potentialTrimCharacterArgIndex + 1 ) ) ) {
- trimSource = ( String ) args.get( potentialTrimCharacterArgIndex + 2 );
- }
- else {
- trimSource = ( String ) args.get( potentialTrimCharacterArgIndex + 1 );
- }
- }
+ /**
+ * {@inheritDoc}
+ */
+ protected SQLFunction resolveTrailingSpaceTrimFunction() {
+ return trailingSpaceTrim;
+ }
- List argsToUse = null;
- argsToUse = new ArrayList();
- argsToUse.add( trimSource );
- argsToUse.add( trimCharacter );
+ /**
+ * {@inheritDoc}
+ */
+ protected SQLFunction resolveBothTrimFunction() {
+ return bothTrim;
+ }
- if ( trimCharacter.equals( "' '" ) ) {
- if ( leading && trailing ) {
- return BOTH_SPACE_TRIM.render( argsToUse, factory );
- }
- else if ( leading ) {
- return LEADING_SPACE_TRIM.render( argsToUse, factory );
- }
- else {
- return TRAILING_SPACE_TRIM.render( argsToUse, factory );
- }
- }
- else {
- if ( leading && trailing ) {
- return BOTH_TRIM.render( argsToUse, factory );
- }
- else if ( leading ) {
- return LEADING_TRIM.render( argsToUse, factory );
- }
- else {
- return TRAILING_TRIM.render( argsToUse, factory );
- }
- }
- }
+ /**
+ * {@inheritDoc}
+ */
+ protected SQLFunction resolveLeadingTrimFunction() {
+ return leadingTrim;
}
+
+ /**
+ * {@inheritDoc}
+ */
+ protected SQLFunction resolveTrailingTrimFunction() {
+ return trailingTrim;
+ }
}
Added: core/branches/Branch_3_2/test/org/hibernate/test/dialect/function/AnsiTrimEmulationFunctionTest.java
===================================================================
--- core/branches/Branch_3_2/test/org/hibernate/test/dialect/function/AnsiTrimEmulationFunctionTest.java (rev 0)
+++ core/branches/Branch_3_2/test/org/hibernate/test/dialect/function/AnsiTrimEmulationFunctionTest.java 2009-02-03 00:47:57 UTC (rev 15861)
@@ -0,0 +1,169 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009, 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.test.dialect.function;
+
+import java.util.List;
+import java.util.ArrayList;
+
+import junit.framework.TestCase;
+
+import org.hibernate.dialect.function.AnsiTrimEmulationFunction;
+
+/**
+ * TODO : javadoc
+ *
+ * @author Steve Ebersole
+ */
+public class AnsiTrimEmulationFunctionTest extends TestCase {
+ private static final String trimSource = "a.column";
+
+ public void testBasicSqlServerProcessing() {
+ AnsiTrimEmulationFunction function = new AnsiTrimEmulationFunction();
+
+ performBasicSpaceTrimmingTests( function );
+
+ final String expectedTrimPrep = "replace(replace(a.column,' ','${space}$'),'-',' ')";
+ final String expectedPostTrimPrefix = "replace(replace(";
+ final String expectedPostTrimSuffix = ",' ','-'),'${space}$',' ')";
+
+ // -> trim(LEADING '-' FROM a.column)
+ String rendered = function.render( argList( "LEADING", "'-'", "FROM", trimSource ), null );
+ String expected = expectedPostTrimPrefix + "ltrim(" + expectedTrimPrep + ")" + expectedPostTrimSuffix;
+ assertEquals( expected, rendered );
+
+ // -> trim(TRAILING '-' FROM a.column)
+ rendered = function.render( argList( "TRAILING", "'-'", "FROM", trimSource ), null );
+ expected = expectedPostTrimPrefix + "rtrim(" + expectedTrimPrep + ")" + expectedPostTrimSuffix;
+ assertEquals( expected, rendered );
+
+ // -> trim(BOTH '-' FROM a.column)
+ rendered = function.render( argList( "BOTH", "'-'", "FROM", trimSource ), null );
+ expected = expectedPostTrimPrefix + "ltrim(rtrim(" + expectedTrimPrep + "))" + expectedPostTrimSuffix;
+ assertEquals( expected, rendered );
+
+ // -> trim('-' FROM a.column)
+ rendered = function.render( argList( "'-'", "FROM", trimSource ), null );
+ expected = expectedPostTrimPrefix + "ltrim(rtrim(" + expectedTrimPrep + "))" + expectedPostTrimSuffix;
+ assertEquals( expected, rendered );
+ }
+
+ public void testBasicSybaseProcessing() {
+ AnsiTrimEmulationFunction function = new AnsiTrimEmulationFunction(
+ AnsiTrimEmulationFunction.LTRIM,
+ AnsiTrimEmulationFunction.RTRIM,
+ "str_replace"
+ );
+
+ performBasicSpaceTrimmingTests( function );
+
+ final String expectedTrimPrep = "str_replace(str_replace(a.column,' ','${space}$'),'-',' ')";
+ final String expectedPostTrimPrefix = "str_replace(str_replace(";
+ final String expectedPostTrimSuffix = ",' ','-'),'${space}$',' ')";
+
+ // -> trim(LEADING '-' FROM a.column)
+ String rendered = function.render( argList( "LEADING", "'-'", "FROM", trimSource ), null );
+ String expected = expectedPostTrimPrefix + "ltrim(" + expectedTrimPrep + ")" + expectedPostTrimSuffix;
+ assertEquals( expected, rendered );
+
+ // -> trim(TRAILING '-' FROM a.column)
+ rendered = function.render( argList( "TRAILING", "'-'", "FROM", trimSource ), null );
+ expected = expectedPostTrimPrefix + "rtrim(" + expectedTrimPrep + ")" + expectedPostTrimSuffix;
+ assertEquals( expected, rendered );
+
+ // -> trim(BOTH '-' FROM a.column)
+ rendered = function.render( argList( "BOTH", "'-'", "FROM", trimSource ), null );
+ expected = expectedPostTrimPrefix + "ltrim(rtrim(" + expectedTrimPrep + "))" + expectedPostTrimSuffix;
+ assertEquals( expected, rendered );
+
+ // -> trim('-' FROM a.column)
+ rendered = function.render( argList( "'-'", "FROM", trimSource ), null );
+ expected = expectedPostTrimPrefix + "ltrim(rtrim(" + expectedTrimPrep + "))" + expectedPostTrimSuffix;
+ assertEquals( expected, rendered );
+ }
+
+ private void performBasicSpaceTrimmingTests(AnsiTrimEmulationFunction function) {
+ // -> trim(a.column)
+ String rendered = function.render( argList( trimSource ), null );
+ assertEquals( "ltrim(rtrim(a.column))", rendered );
+
+ // -> trim(FROM a.column)
+ rendered = function.render( argList( "FROM", trimSource ), null );
+ assertEquals( "ltrim(rtrim(a.column))", rendered );
+
+ // -> trim(BOTH FROM a.column)
+ rendered = function.render( argList( "BOTH", "FROM", trimSource ), null );
+ assertEquals( "ltrim(rtrim(a.column))", rendered );
+
+ // -> trim(BOTH ' ' FROM a.column)
+ rendered = function.render( argList( "BOTH", "' '", "FROM", trimSource ), null );
+ assertEquals( "ltrim(rtrim(a.column))", rendered );
+
+ // -> trim(LEADING FROM a.column)
+ rendered = function.render( argList( "LEADING", "FROM", trimSource ), null );
+ assertEquals( "ltrim(a.column)", rendered );
+
+ // -> trim(LEADING ' ' FROM a.column)
+ rendered = function.render( argList( "LEADING", "' '", "FROM", trimSource ), null );
+ assertEquals( "ltrim(a.column)", rendered );
+
+ // -> trim(TRAILING FROM a.column)
+ rendered = function.render( argList( "TRAILING", "FROM", trimSource ), null );
+ assertEquals( "rtrim(a.column)", rendered );
+
+ // -> trim(TRAILING ' ' FROM a.column)
+ rendered = function.render( argList( "TRAILING", "' '", "FROM", trimSource ), null );
+ assertEquals( "rtrim(a.column)", rendered );
+ }
+
+ private List argList(String arg) {
+ ArrayList args = new ArrayList();
+ args.add( arg );
+ return args;
+ }
+
+ private List argList(String arg1, String arg2) {
+ ArrayList args = new ArrayList();
+ args.add( arg1 );
+ args.add( arg2 );
+ return args;
+ }
+
+ private List argList(String arg1, String arg2, String arg3) {
+ ArrayList args = new ArrayList();
+ args.add( arg1 );
+ args.add( arg2 );
+ args.add( arg3 );
+ return args;
+ }
+
+ private List argList(String arg1, String arg2, String arg3, String arg4) {
+ ArrayList args = new ArrayList();
+ args.add( arg1 );
+ args.add( arg2 );
+ args.add( arg3 );
+ args.add( arg4 );
+ return args;
+ }
+
+}
[View Less]
16 years
Hibernate SVN: r15860 - in core/trunk: testsuite/src/test/java/org/hibernate/test/dialect and 1 other directories.
by hibernate-commits@lists.jboss.org
Author: steve.ebersole(a)jboss.com
Date: 2009-02-02 19:47:23 -0500 (Mon, 02 Feb 2009)
New Revision: 15860
Added:
core/trunk/core/src/main/java/org/hibernate/dialect/function/AbstractAnsiTrimEmulationFunction.java
core/trunk/testsuite/src/test/java/org/hibernate/test/dialect/function/
core/trunk/testsuite/src/test/java/org/hibernate/test/dialect/function/AnsiTrimEmulationFunctionTest.java
Modified:
core/trunk/core/src/main/java/org/hibernate/dialect/function/…
[View More]AnsiTrimEmulationFunction.java
Log:
HHH-3701 : trim function emulation for sybase
Added: core/trunk/core/src/main/java/org/hibernate/dialect/function/AbstractAnsiTrimEmulationFunction.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/dialect/function/AbstractAnsiTrimEmulationFunction.java (rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/dialect/function/AbstractAnsiTrimEmulationFunction.java 2009-02-03 00:47:23 UTC (rev 15860)
@@ -0,0 +1,227 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009, 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.dialect.function;
+
+import org.hibernate.Hibernate;
+import org.hibernate.QueryException;
+import org.hibernate.engine.Mapping;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.type.Type;
+
+import java.util.List;
+import java.util.ArrayList;
+
+/**
+ * A {@link org.hibernate.dialect.function.SQLFunction} providing support for implementing TRIM functionality
+ * (as defined by both the ANSI SQL and JPA specs) in cases where the dialect may not support the full <tt>trim</tt>
+ * function itself.
+ * <p/>
+ * Follows the <a href="http://en.wikipedia.org/wiki/Template_method_pattern">template</a> pattern in order to implement
+ * the {@link #render} method.
+ *
+ * @author Steve Ebersole
+ */
+public abstract class AbstractAnsiTrimEmulationFunction implements SQLFunction {
+ /**
+ * {@inheritDoc}
+ */
+ public final Type getReturnType(Type columnType, Mapping mapping) throws QueryException {
+ return Hibernate.STRING;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public final boolean hasArguments() {
+ return true;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public final boolean hasParenthesesIfNoArguments() {
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public final String render(List args, SessionFactoryImplementor factory) throws QueryException {
+ // According to both the ANSI-SQL and JPA specs, trim takes a variable number of parameters between 1 and 4.
+ // at least one paramer (trimSource) is required. From the SQL spec:
+ //
+ // <trim function> ::=
+ // TRIM <left paren> <trim operands> <right paren>
+ //
+ // <trim operands> ::=
+ // [ [ <trim specification> ] [ <trim character> ] FROM ] <trim source>
+ //
+ // <trim specification> ::=
+ // LEADING
+ // | TRAILING
+ // | BOTH
+ //
+ // If <trim specification> is omitted, BOTH is assumed.
+ // If <trim character> is omitted, space is assumed
+ if ( args.size() == 1 ) {
+ // we have the form: trim(trimSource)
+ // so we trim leading and trailing spaces
+ return resolveBothSpaceTrimFunction().render( args, factory ); // EARLY EXIT!!!!
+ }
+ else if ( "from".equalsIgnoreCase( ( String ) args.get( 0 ) ) ) {
+ // we have the form: trim(from trimSource).
+ // This is functionally equivalent to trim(trimSource)
+ return resolveBothSpaceTrimFromFunction().render( args, factory ); // EARLY EXIT!!!!
+ }
+ else {
+ // otherwise, a trim-specification and/or a trim-character
+ // have been specified; we need to decide which options
+ // are present and "do the right thing"
+ boolean leading = true; // should leading trim-characters be trimmed?
+ boolean trailing = true; // should trailing trim-characters be trimmed?
+ String trimCharacter; // the trim-character (what is to be trimmed off?)
+ String trimSource; // the trim-source (from where should it be trimmed?)
+
+ // potentialTrimCharacterArgIndex = 1 assumes that a
+ // trim-specification has been specified. we handle the
+ // exception to that explicitly
+ int potentialTrimCharacterArgIndex = 1;
+ String firstArg = ( String ) args.get( 0 );
+ if ( "leading".equalsIgnoreCase( firstArg ) ) {
+ trailing = false;
+ }
+ else if ( "trailing".equalsIgnoreCase( firstArg ) ) {
+ leading = false;
+ }
+ else if ( "both".equalsIgnoreCase( firstArg ) ) {
+ }
+ else {
+ potentialTrimCharacterArgIndex = 0;
+ }
+
+ String potentialTrimCharacter = ( String ) args.get( potentialTrimCharacterArgIndex );
+ if ( "from".equalsIgnoreCase( potentialTrimCharacter ) ) {
+ trimCharacter = "' '";
+ trimSource = ( String ) args.get( potentialTrimCharacterArgIndex + 1 );
+ }
+ else if ( potentialTrimCharacterArgIndex + 1 >= args.size() ) {
+ trimCharacter = "' '";
+ trimSource = potentialTrimCharacter;
+ }
+ else {
+ trimCharacter = potentialTrimCharacter;
+ if ( "from".equalsIgnoreCase( ( String ) args.get( potentialTrimCharacterArgIndex + 1 ) ) ) {
+ trimSource = ( String ) args.get( potentialTrimCharacterArgIndex + 2 );
+ }
+ else {
+ trimSource = ( String ) args.get( potentialTrimCharacterArgIndex + 1 );
+ }
+ }
+
+ List argsToUse = new ArrayList();
+ argsToUse.add( trimSource );
+ argsToUse.add( trimCharacter );
+
+ if ( trimCharacter.equals( "' '" ) ) {
+ if ( leading && trailing ) {
+ return resolveBothSpaceTrimFunction().render( argsToUse, factory );
+ }
+ else if ( leading ) {
+ return resolveLeadingSpaceTrimFunction().render( argsToUse, factory );
+ }
+ else {
+ return resolveTrailingSpaceTrimFunction().render( argsToUse, factory );
+ }
+ }
+ else {
+ if ( leading && trailing ) {
+ return resolveBothTrimFunction().render( argsToUse, factory );
+ }
+ else if ( leading ) {
+ return resolveLeadingTrimFunction().render( argsToUse, factory );
+ }
+ else {
+ return resolveTrailingTrimFunction().render( argsToUse, factory );
+ }
+ }
+ }
+ }
+
+ /**
+ * Resolve the function definition which should be used to trim both leading and trailing spaces.
+ * <p/>
+ * In this form, the imput arguments is missing the <tt>FROM</tt> keyword.
+ *
+ * @return The sql function
+ */
+ protected abstract SQLFunction resolveBothSpaceTrimFunction();
+
+ /**
+ * Resolve the function definition which should be used to trim both leading and trailing spaces.
+ * <p/>
+ * The same as {#link resolveBothSpaceTrimFunction} except that here the<tt>FROM</tt> is included and
+ * will need to be accounted for during {@link SQLFunction#render} processing.
+ *
+ * @return The sql function
+ */
+ protected abstract SQLFunction resolveBothSpaceTrimFromFunction();
+
+ /**
+ * Resolve the function definition which should be used to trim leading spaces.
+ *
+ * @return The sql function
+ */
+ protected abstract SQLFunction resolveLeadingSpaceTrimFunction();
+
+ /**
+ * Resolve the function definition which should be used to trim trailing spaces.
+ *
+ * @return The sql function
+ */
+ protected abstract SQLFunction resolveTrailingSpaceTrimFunction();
+
+ /**
+ * Resolve the function definition which should be used to trim the specified character from both the
+ * beginning (leading) and end (trailing) of the trim source.
+ *
+ * @return The sql function
+ */
+ protected abstract SQLFunction resolveBothTrimFunction();
+
+ /**
+ * Resolve the function definition which should be used to trim the specified character from the
+ * beginning (leading) of the trim source.
+ *
+ * @return The sql function
+ */
+ protected abstract SQLFunction resolveLeadingTrimFunction();
+
+ /**
+ * Resolve the function definition which should be used to trim the specified character from the
+ * end (trailing) of the trim source.
+ *
+ * @return The sql function
+ */
+ protected abstract SQLFunction resolveTrailingTrimFunction();
+}
Modified: core/trunk/core/src/main/java/org/hibernate/dialect/function/AnsiTrimEmulationFunction.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/dialect/function/AnsiTrimEmulationFunction.java 2009-02-03 00:44:42 UTC (rev 15859)
+++ core/trunk/core/src/main/java/org/hibernate/dialect/function/AnsiTrimEmulationFunction.java 2009-02-03 00:47:23 UTC (rev 15860)
@@ -25,14 +25,7 @@
package org.hibernate.dialect.function;
import org.hibernate.Hibernate;
-import org.hibernate.QueryException;
-import org.hibernate.engine.Mapping;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.type.Type;
-import java.util.List;
-import java.util.ArrayList;
-
/**
* A {@link SQLFunction} implementation that emulates the ANSI SQL trim function
* on dialects which do not support the full definition. However, this function
@@ -42,129 +35,222 @@
*
* @author Steve Ebersole
*/
-public class AnsiTrimEmulationFunction implements SQLFunction {
+public class AnsiTrimEmulationFunction extends AbstractAnsiTrimEmulationFunction {
+ public static final String LTRIM = "ltrim";
+ public static final String RTRIM = "rtrim";
+ public static final String REPLACE = "replace";
+ public static final String SPACE_PLACEHOLDER = "${space}$";
- private static final SQLFunction LEADING_SPACE_TRIM = new SQLFunctionTemplate( Hibernate.STRING, "ltrim( ?1 )");
- private static final SQLFunction TRAILING_SPACE_TRIM = new SQLFunctionTemplate( Hibernate.STRING, "rtrim( ?1 )");
- private static final SQLFunction BOTH_SPACE_TRIM = new SQLFunctionTemplate( Hibernate.STRING, "ltrim( rtrim( ?1 ) )");
- private static final SQLFunction BOTH_SPACE_TRIM_FROM = new SQLFunctionTemplate( Hibernate.STRING, "ltrim( rtrim( ?2 ) )");
+ public static final String LEADING_SPACE_TRIM_TEMPLATE = LTRIM + "(?1)";
+ public static final String TRAILING_SPACE_TRIM_TEMPLATE = RTRIM + "(?1)";
+ public static final String BOTH_SPACE_TRIM_TEMPLATE = LTRIM + "(" + RTRIM + "(?1))";
+ public static final String BOTH_SPACE_TRIM_FROM_TEMPLATE = LTRIM + "(" + RTRIM + "(?2))"; //skip the FROM keyword in params
- private static final SQLFunction LEADING_TRIM = new SQLFunctionTemplate( Hibernate.STRING, "replace( replace( rtrim( replace( replace( ?1, ' ', '${space}$' ), ?2, ' ' ) ), ' ', ?2 ), '${space}$', ' ' )" );
- private static final SQLFunction TRAILING_TRIM = new SQLFunctionTemplate( Hibernate.STRING, "replace( replace( ltrim( replace( replace( ?1, ' ', '${space}$' ), ?2, ' ' ) ), ' ', ?2 ), '${space}$', ' ' )" );
- private static final SQLFunction BOTH_TRIM = new SQLFunctionTemplate( Hibernate.STRING, "replace( replace( ltrim( rtrim( replace( replace( ?1, ' ', '${space}$' ), ?2, ' ' ) ) ), ' ', ?2 ), '${space}$', ' ' )" );
+ /**
+ * A template for the series of calls required to trim non-space chars from the beginning of text.
+ * <p/>
+ * NOTE : essentially we:</ol>
+ * <li>replace all space chars with the text '${space}$'</li>
+ * <li>replace all the actual replacement chars with space chars</li>
+ * <li>perform left-trimming (that removes any of the space chars we just added which occur at the beginning of the text)</li>
+ * <li>replace all space chars with the replacement char</li>
+ * <li>replace all the '${space}$' text with space chars</li>
+ * </ol>
+ */
+ public static final String LEADING_TRIM_TEMPLATE =
+ REPLACE + "(" +
+ REPLACE + "(" +
+ LTRIM + "(" +
+ REPLACE + "(" +
+ REPLACE + "(" +
+ "?1," +
+ "' '," +
+ "'" + SPACE_PLACEHOLDER + "'" +
+ ")," +
+ "?2," +
+ "' '" +
+ ")" +
+ ")," +
+ "' '," +
+ "?2" +
+ ")," +
+ "'" + SPACE_PLACEHOLDER + "'," +
+ "' '" +
+ ")";
- public Type getReturnType(Type columnType, Mapping mapping) throws QueryException {
- return Hibernate.STRING;
+ /**
+ * A template for the series of calls required to trim non-space chars from the end of text.
+ * <p/>
+ * NOTE: essentially the same series of calls as outlined in {@link #LEADING_TRIM_TEMPLATE} except that here,
+ * instead of left-trimming the added spaces, we right-trim them to remove them from the end of the text.
+ */
+ public static final String TRAILING_TRIM_TEMPLATE =
+ REPLACE + "(" +
+ REPLACE + "(" +
+ RTRIM + "(" +
+ REPLACE + "(" +
+ REPLACE + "(" +
+ "?1," +
+ "' '," +
+ "'" + SPACE_PLACEHOLDER + "'" +
+ ")," +
+ "?2," +
+ "' '" +
+ ")" +
+ ")," +
+ "' '," +
+ "?2" +
+ ")," +
+ "'" + SPACE_PLACEHOLDER + "'," +
+ "' '" +
+ ")";
+
+ /**
+ * A template for the series of calls required to trim non-space chars from both the beginning and the end of text.
+ * <p/>
+ * NOTE: again, we have a series of calls that is essentially the same as outlined in {@link #LEADING_TRIM_TEMPLATE}
+ * except that here we perform both left (leading) and right (trailing) trimming.
+ */
+ public static final String BOTH_TRIM_TEMPLATE =
+ REPLACE + "(" +
+ REPLACE + "(" +
+ LTRIM + "(" +
+ RTRIM + "(" +
+ REPLACE + "(" +
+ REPLACE + "(" +
+ "?1," +
+ "' '," +
+ "'" + SPACE_PLACEHOLDER + "'" +
+ ")," +
+ "?2," +
+ "' '" +
+ ")" +
+ ")" +
+ ")," +
+ "' '," +
+ "?2" +
+ ")," +
+ "'" + SPACE_PLACEHOLDER + "'," +
+ "' '" +
+ ")";
+
+ private final SQLFunction leadingSpaceTrim;
+ private final SQLFunction trailingSpaceTrim;
+ private final SQLFunction bothSpaceTrim;
+ private final SQLFunction bothSpaceTrimFrom;
+
+ private final SQLFunction leadingTrim;
+ private final SQLFunction trailingTrim;
+ private final SQLFunction bothTrim;
+
+ /**
+ * Constructs a new AnsiTrimEmulationFunction using {@link #LTRIM}, {@link #RTRIM}, and {@link #REPLACE}
+ * respectively.
+ *
+ * @see #AnsiTrimEmulationFunction(String,String,String)
+ */
+ public AnsiTrimEmulationFunction() {
+ this( LTRIM, RTRIM, REPLACE );
}
- public boolean hasArguments() {
- return true;
+ /**
+ * Constructs a <tt>trim()</tt> emulation function definition using the specified function calls.
+ *
+ * @param ltrimFunctionName The <tt>left trim</tt> function to use.
+ * @param rtrimFunctionName The <tt>right trim</tt> function to use.
+ * @param replaceFunctionName The <tt>replace</tt> function to use.
+ */
+ public AnsiTrimEmulationFunction(String ltrimFunctionName, String rtrimFunctionName, String replaceFunctionName) {
+ leadingSpaceTrim = new SQLFunctionTemplate(
+ Hibernate.STRING,
+ LEADING_SPACE_TRIM_TEMPLATE.replaceAll( LTRIM, ltrimFunctionName )
+ );
+
+ trailingSpaceTrim = new SQLFunctionTemplate(
+ Hibernate.STRING,
+ TRAILING_SPACE_TRIM_TEMPLATE.replaceAll( RTRIM, rtrimFunctionName )
+ );
+
+ bothSpaceTrim = new SQLFunctionTemplate(
+ Hibernate.STRING,
+ BOTH_SPACE_TRIM_TEMPLATE.replaceAll( LTRIM, ltrimFunctionName )
+ .replaceAll( RTRIM, rtrimFunctionName )
+ );
+
+ bothSpaceTrimFrom = new SQLFunctionTemplate(
+ Hibernate.STRING,
+ BOTH_SPACE_TRIM_FROM_TEMPLATE.replaceAll( LTRIM, ltrimFunctionName )
+ .replaceAll( RTRIM, rtrimFunctionName )
+ );
+
+ leadingTrim = new SQLFunctionTemplate(
+ Hibernate.STRING,
+ LEADING_TRIM_TEMPLATE.replaceAll( LTRIM, ltrimFunctionName )
+ .replaceAll( RTRIM, rtrimFunctionName )
+ .replaceAll( REPLACE,replaceFunctionName )
+ );
+
+ trailingTrim = new SQLFunctionTemplate(
+ Hibernate.STRING,
+ TRAILING_TRIM_TEMPLATE.replaceAll( LTRIM, ltrimFunctionName )
+ .replaceAll( RTRIM, rtrimFunctionName )
+ .replaceAll( REPLACE,replaceFunctionName )
+ );
+
+ bothTrim = new SQLFunctionTemplate(
+ Hibernate.STRING,
+ BOTH_TRIM_TEMPLATE.replaceAll( LTRIM, ltrimFunctionName )
+ .replaceAll( RTRIM, rtrimFunctionName )
+ .replaceAll( REPLACE,replaceFunctionName )
+ );
}
- public boolean hasParenthesesIfNoArguments() {
- return false;
+ /**
+ * {@inheritDoc}
+ */
+ protected SQLFunction resolveBothSpaceTrimFunction() {
+ return bothSpaceTrim;
}
- public String render(List args, SessionFactoryImplementor factory) throws QueryException {
- // according to both the ANSI-SQL and EJB3 specs, trim can either take
- // exactly one parameter or a variable number of parameters between 1 and 4.
- // from the SQL spec:
- //
- // <trim function> ::=
- // TRIM <left paren> <trim operands> <right paren>
- //
- // <trim operands> ::=
- // [ [ <trim specification> ] [ <trim character> ] FROM ] <trim source>
- //
- // <trim specification> ::=
- // LEADING
- // | TRAILING
- // | BOTH
- //
- // If only <trim specification> is omitted, BOTH is assumed;
- // if <trim character> is omitted, space is assumed
- if ( args.size() == 1 ) {
- // we have the form: trim(trimSource)
- // so we trim leading and trailing spaces
- return BOTH_SPACE_TRIM.render( args, factory );
- }
- else if ( "from".equalsIgnoreCase( ( String ) args.get( 0 ) ) ) {
- // we have the form: trim(from trimSource).
- // This is functionally equivalent to trim(trimSource)
- return BOTH_SPACE_TRIM_FROM.render( args, factory );
- }
- else {
- // otherwise, a trim-specification and/or a trim-character
- // have been specified; we need to decide which options
- // are present and "do the right thing"
- boolean leading = true; // should leading trim-characters be trimmed?
- boolean trailing = true; // should trailing trim-characters be trimmed?
- String trimCharacter = null; // the trim-character
- String trimSource = null; // the trim-source
+ /**
+ * {@inheritDoc}
+ */
+ protected SQLFunction resolveBothSpaceTrimFromFunction() {
+ return bothSpaceTrimFrom;
+ }
- // potentialTrimCharacterArgIndex = 1 assumes that a
- // trim-specification has been specified. we handle the
- // exception to that explicitly
- int potentialTrimCharacterArgIndex = 1;
- String firstArg = ( String ) args.get( 0 );
- if ( "leading".equalsIgnoreCase( firstArg ) ) {
- trailing = false;
- }
- else if ( "trailing".equalsIgnoreCase( firstArg ) ) {
- leading = false;
- }
- else if ( "both".equalsIgnoreCase( firstArg ) ) {
- }
- else {
- potentialTrimCharacterArgIndex = 0;
- }
+ /**
+ * {@inheritDoc}
+ */
+ protected SQLFunction resolveLeadingSpaceTrimFunction() {
+ return leadingSpaceTrim;
+ }
- String potentialTrimCharacter = ( String ) args.get( potentialTrimCharacterArgIndex );
- if ( "from".equalsIgnoreCase( potentialTrimCharacter ) ) {
- trimCharacter = "' '";
- trimSource = ( String ) args.get( potentialTrimCharacterArgIndex + 1 );
- }
- else if ( potentialTrimCharacterArgIndex + 1 >= args.size() ) {
- trimCharacter = "' '";
- trimSource = potentialTrimCharacter;
- }
- else {
- trimCharacter = potentialTrimCharacter;
- if ( "from".equalsIgnoreCase( ( String ) args.get( potentialTrimCharacterArgIndex + 1 ) ) ) {
- trimSource = ( String ) args.get( potentialTrimCharacterArgIndex + 2 );
- }
- else {
- trimSource = ( String ) args.get( potentialTrimCharacterArgIndex + 1 );
- }
- }
+ /**
+ * {@inheritDoc}
+ */
+ protected SQLFunction resolveTrailingSpaceTrimFunction() {
+ return trailingSpaceTrim;
+ }
- List argsToUse = null;
- argsToUse = new ArrayList();
- argsToUse.add( trimSource );
- argsToUse.add( trimCharacter );
+ /**
+ * {@inheritDoc}
+ */
+ protected SQLFunction resolveBothTrimFunction() {
+ return bothTrim;
+ }
- if ( trimCharacter.equals( "' '" ) ) {
- if ( leading && trailing ) {
- return BOTH_SPACE_TRIM.render( argsToUse, factory );
- }
- else if ( leading ) {
- return LEADING_SPACE_TRIM.render( argsToUse, factory );
- }
- else {
- return TRAILING_SPACE_TRIM.render( argsToUse, factory );
- }
- }
- else {
- if ( leading && trailing ) {
- return BOTH_TRIM.render( argsToUse, factory );
- }
- else if ( leading ) {
- return LEADING_TRIM.render( argsToUse, factory );
- }
- else {
- return TRAILING_TRIM.render( argsToUse, factory );
- }
- }
- }
+ /**
+ * {@inheritDoc}
+ */
+ protected SQLFunction resolveLeadingTrimFunction() {
+ return leadingTrim;
}
+
+ /**
+ * {@inheritDoc}
+ */
+ protected SQLFunction resolveTrailingTrimFunction() {
+ return trailingTrim;
+ }
}
Added: core/trunk/testsuite/src/test/java/org/hibernate/test/dialect/function/AnsiTrimEmulationFunctionTest.java
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/dialect/function/AnsiTrimEmulationFunctionTest.java (rev 0)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/dialect/function/AnsiTrimEmulationFunctionTest.java 2009-02-03 00:47:23 UTC (rev 15860)
@@ -0,0 +1,169 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009, 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.test.dialect.function;
+
+import java.util.List;
+import java.util.ArrayList;
+
+import junit.framework.TestCase;
+
+import org.hibernate.dialect.function.AnsiTrimEmulationFunction;
+
+/**
+ * TODO : javadoc
+ *
+ * @author Steve Ebersole
+ */
+public class AnsiTrimEmulationFunctionTest extends TestCase {
+ private static final String trimSource = "a.column";
+
+ public void testBasicSqlServerProcessing() {
+ AnsiTrimEmulationFunction function = new AnsiTrimEmulationFunction();
+
+ performBasicSpaceTrimmingTests( function );
+
+ final String expectedTrimPrep = "replace(replace(a.column,' ','${space}$'),'-',' ')";
+ final String expectedPostTrimPrefix = "replace(replace(";
+ final String expectedPostTrimSuffix = ",' ','-'),'${space}$',' ')";
+
+ // -> trim(LEADING '-' FROM a.column)
+ String rendered = function.render( argList( "LEADING", "'-'", "FROM", trimSource ), null );
+ String expected = expectedPostTrimPrefix + "ltrim(" + expectedTrimPrep + ")" + expectedPostTrimSuffix;
+ assertEquals( expected, rendered );
+
+ // -> trim(TRAILING '-' FROM a.column)
+ rendered = function.render( argList( "TRAILING", "'-'", "FROM", trimSource ), null );
+ expected = expectedPostTrimPrefix + "rtrim(" + expectedTrimPrep + ")" + expectedPostTrimSuffix;
+ assertEquals( expected, rendered );
+
+ // -> trim(BOTH '-' FROM a.column)
+ rendered = function.render( argList( "BOTH", "'-'", "FROM", trimSource ), null );
+ expected = expectedPostTrimPrefix + "ltrim(rtrim(" + expectedTrimPrep + "))" + expectedPostTrimSuffix;
+ assertEquals( expected, rendered );
+
+ // -> trim('-' FROM a.column)
+ rendered = function.render( argList( "'-'", "FROM", trimSource ), null );
+ expected = expectedPostTrimPrefix + "ltrim(rtrim(" + expectedTrimPrep + "))" + expectedPostTrimSuffix;
+ assertEquals( expected, rendered );
+ }
+
+ public void testBasicSybaseProcessing() {
+ AnsiTrimEmulationFunction function = new AnsiTrimEmulationFunction(
+ AnsiTrimEmulationFunction.LTRIM,
+ AnsiTrimEmulationFunction.RTRIM,
+ "str_replace"
+ );
+
+ performBasicSpaceTrimmingTests( function );
+
+ final String expectedTrimPrep = "str_replace(str_replace(a.column,' ','${space}$'),'-',' ')";
+ final String expectedPostTrimPrefix = "str_replace(str_replace(";
+ final String expectedPostTrimSuffix = ",' ','-'),'${space}$',' ')";
+
+ // -> trim(LEADING '-' FROM a.column)
+ String rendered = function.render( argList( "LEADING", "'-'", "FROM", trimSource ), null );
+ String expected = expectedPostTrimPrefix + "ltrim(" + expectedTrimPrep + ")" + expectedPostTrimSuffix;
+ assertEquals( expected, rendered );
+
+ // -> trim(TRAILING '-' FROM a.column)
+ rendered = function.render( argList( "TRAILING", "'-'", "FROM", trimSource ), null );
+ expected = expectedPostTrimPrefix + "rtrim(" + expectedTrimPrep + ")" + expectedPostTrimSuffix;
+ assertEquals( expected, rendered );
+
+ // -> trim(BOTH '-' FROM a.column)
+ rendered = function.render( argList( "BOTH", "'-'", "FROM", trimSource ), null );
+ expected = expectedPostTrimPrefix + "ltrim(rtrim(" + expectedTrimPrep + "))" + expectedPostTrimSuffix;
+ assertEquals( expected, rendered );
+
+ // -> trim('-' FROM a.column)
+ rendered = function.render( argList( "'-'", "FROM", trimSource ), null );
+ expected = expectedPostTrimPrefix + "ltrim(rtrim(" + expectedTrimPrep + "))" + expectedPostTrimSuffix;
+ assertEquals( expected, rendered );
+ }
+
+ private void performBasicSpaceTrimmingTests(AnsiTrimEmulationFunction function) {
+ // -> trim(a.column)
+ String rendered = function.render( argList( trimSource ), null );
+ assertEquals( "ltrim(rtrim(a.column))", rendered );
+
+ // -> trim(FROM a.column)
+ rendered = function.render( argList( "FROM", trimSource ), null );
+ assertEquals( "ltrim(rtrim(a.column))", rendered );
+
+ // -> trim(BOTH FROM a.column)
+ rendered = function.render( argList( "BOTH", "FROM", trimSource ), null );
+ assertEquals( "ltrim(rtrim(a.column))", rendered );
+
+ // -> trim(BOTH ' ' FROM a.column)
+ rendered = function.render( argList( "BOTH", "' '", "FROM", trimSource ), null );
+ assertEquals( "ltrim(rtrim(a.column))", rendered );
+
+ // -> trim(LEADING FROM a.column)
+ rendered = function.render( argList( "LEADING", "FROM", trimSource ), null );
+ assertEquals( "ltrim(a.column)", rendered );
+
+ // -> trim(LEADING ' ' FROM a.column)
+ rendered = function.render( argList( "LEADING", "' '", "FROM", trimSource ), null );
+ assertEquals( "ltrim(a.column)", rendered );
+
+ // -> trim(TRAILING FROM a.column)
+ rendered = function.render( argList( "TRAILING", "FROM", trimSource ), null );
+ assertEquals( "rtrim(a.column)", rendered );
+
+ // -> trim(TRAILING ' ' FROM a.column)
+ rendered = function.render( argList( "TRAILING", "' '", "FROM", trimSource ), null );
+ assertEquals( "rtrim(a.column)", rendered );
+ }
+
+ private List argList(String arg) {
+ ArrayList args = new ArrayList();
+ args.add( arg );
+ return args;
+ }
+
+ private List argList(String arg1, String arg2) {
+ ArrayList args = new ArrayList();
+ args.add( arg1 );
+ args.add( arg2 );
+ return args;
+ }
+
+ private List argList(String arg1, String arg2, String arg3) {
+ ArrayList args = new ArrayList();
+ args.add( arg1 );
+ args.add( arg2 );
+ args.add( arg3 );
+ return args;
+ }
+
+ private List argList(String arg1, String arg2, String arg3, String arg4) {
+ ArrayList args = new ArrayList();
+ args.add( arg1 );
+ args.add( arg2 );
+ args.add( arg3 );
+ args.add( arg4 );
+ return args;
+ }
+
+}
[View Less]
16 years
Hibernate SVN: r15859 - in core/branches/Branch_3_3: testsuite/src/test/java/org/hibernate/test/dialect and 1 other directories.
by hibernate-commits@lists.jboss.org
Author: steve.ebersole(a)jboss.com
Date: 2009-02-02 19:44:42 -0500 (Mon, 02 Feb 2009)
New Revision: 15859
Added:
core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/function/AbstractAnsiTrimEmulationFunction.java
core/branches/Branch_3_3/testsuite/src/test/java/org/hibernate/test/dialect/function/
core/branches/Branch_3_3/testsuite/src/test/java/org/hibernate/test/dialect/function/AnsiTrimEmulationFunctionTest.java
Modified:
core/branches/Branch_3_3/core/src/main/java/…
[View More]org/hibernate/dialect/function/AnsiTrimEmulationFunction.java
Log:
HHH-3701 : trim function emulation for sybase
Added: core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/function/AbstractAnsiTrimEmulationFunction.java
===================================================================
--- core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/function/AbstractAnsiTrimEmulationFunction.java (rev 0)
+++ core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/function/AbstractAnsiTrimEmulationFunction.java 2009-02-03 00:44:42 UTC (rev 15859)
@@ -0,0 +1,227 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009, 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.dialect.function;
+
+import org.hibernate.Hibernate;
+import org.hibernate.QueryException;
+import org.hibernate.engine.Mapping;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.type.Type;
+
+import java.util.List;
+import java.util.ArrayList;
+
+/**
+ * A {@link org.hibernate.dialect.function.SQLFunction} providing support for implementing TRIM functionality
+ * (as defined by both the ANSI SQL and JPA specs) in cases where the dialect may not support the full <tt>trim</tt>
+ * function itself.
+ * <p/>
+ * Follows the <a href="http://en.wikipedia.org/wiki/Template_method_pattern">template</a> pattern in order to implement
+ * the {@link #render} method.
+ *
+ * @author Steve Ebersole
+ */
+public abstract class AbstractAnsiTrimEmulationFunction implements SQLFunction {
+ /**
+ * {@inheritDoc}
+ */
+ public final Type getReturnType(Type columnType, Mapping mapping) throws QueryException {
+ return Hibernate.STRING;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public final boolean hasArguments() {
+ return true;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public final boolean hasParenthesesIfNoArguments() {
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public final String render(List args, SessionFactoryImplementor factory) throws QueryException {
+ // According to both the ANSI-SQL and JPA specs, trim takes a variable number of parameters between 1 and 4.
+ // at least one paramer (trimSource) is required. From the SQL spec:
+ //
+ // <trim function> ::=
+ // TRIM <left paren> <trim operands> <right paren>
+ //
+ // <trim operands> ::=
+ // [ [ <trim specification> ] [ <trim character> ] FROM ] <trim source>
+ //
+ // <trim specification> ::=
+ // LEADING
+ // | TRAILING
+ // | BOTH
+ //
+ // If <trim specification> is omitted, BOTH is assumed.
+ // If <trim character> is omitted, space is assumed
+ if ( args.size() == 1 ) {
+ // we have the form: trim(trimSource)
+ // so we trim leading and trailing spaces
+ return resolveBothSpaceTrimFunction().render( args, factory ); // EARLY EXIT!!!!
+ }
+ else if ( "from".equalsIgnoreCase( ( String ) args.get( 0 ) ) ) {
+ // we have the form: trim(from trimSource).
+ // This is functionally equivalent to trim(trimSource)
+ return resolveBothSpaceTrimFromFunction().render( args, factory ); // EARLY EXIT!!!!
+ }
+ else {
+ // otherwise, a trim-specification and/or a trim-character
+ // have been specified; we need to decide which options
+ // are present and "do the right thing"
+ boolean leading = true; // should leading trim-characters be trimmed?
+ boolean trailing = true; // should trailing trim-characters be trimmed?
+ String trimCharacter; // the trim-character (what is to be trimmed off?)
+ String trimSource; // the trim-source (from where should it be trimmed?)
+
+ // potentialTrimCharacterArgIndex = 1 assumes that a
+ // trim-specification has been specified. we handle the
+ // exception to that explicitly
+ int potentialTrimCharacterArgIndex = 1;
+ String firstArg = ( String ) args.get( 0 );
+ if ( "leading".equalsIgnoreCase( firstArg ) ) {
+ trailing = false;
+ }
+ else if ( "trailing".equalsIgnoreCase( firstArg ) ) {
+ leading = false;
+ }
+ else if ( "both".equalsIgnoreCase( firstArg ) ) {
+ }
+ else {
+ potentialTrimCharacterArgIndex = 0;
+ }
+
+ String potentialTrimCharacter = ( String ) args.get( potentialTrimCharacterArgIndex );
+ if ( "from".equalsIgnoreCase( potentialTrimCharacter ) ) {
+ trimCharacter = "' '";
+ trimSource = ( String ) args.get( potentialTrimCharacterArgIndex + 1 );
+ }
+ else if ( potentialTrimCharacterArgIndex + 1 >= args.size() ) {
+ trimCharacter = "' '";
+ trimSource = potentialTrimCharacter;
+ }
+ else {
+ trimCharacter = potentialTrimCharacter;
+ if ( "from".equalsIgnoreCase( ( String ) args.get( potentialTrimCharacterArgIndex + 1 ) ) ) {
+ trimSource = ( String ) args.get( potentialTrimCharacterArgIndex + 2 );
+ }
+ else {
+ trimSource = ( String ) args.get( potentialTrimCharacterArgIndex + 1 );
+ }
+ }
+
+ List argsToUse = new ArrayList();
+ argsToUse.add( trimSource );
+ argsToUse.add( trimCharacter );
+
+ if ( trimCharacter.equals( "' '" ) ) {
+ if ( leading && trailing ) {
+ return resolveBothSpaceTrimFunction().render( argsToUse, factory );
+ }
+ else if ( leading ) {
+ return resolveLeadingSpaceTrimFunction().render( argsToUse, factory );
+ }
+ else {
+ return resolveTrailingSpaceTrimFunction().render( argsToUse, factory );
+ }
+ }
+ else {
+ if ( leading && trailing ) {
+ return resolveBothTrimFunction().render( argsToUse, factory );
+ }
+ else if ( leading ) {
+ return resolveLeadingTrimFunction().render( argsToUse, factory );
+ }
+ else {
+ return resolveTrailingTrimFunction().render( argsToUse, factory );
+ }
+ }
+ }
+ }
+
+ /**
+ * Resolve the function definition which should be used to trim both leading and trailing spaces.
+ * <p/>
+ * In this form, the imput arguments is missing the <tt>FROM</tt> keyword.
+ *
+ * @return The sql function
+ */
+ protected abstract SQLFunction resolveBothSpaceTrimFunction();
+
+ /**
+ * Resolve the function definition which should be used to trim both leading and trailing spaces.
+ * <p/>
+ * The same as {#link resolveBothSpaceTrimFunction} except that here the<tt>FROM</tt> is included and
+ * will need to be accounted for during {@link SQLFunction#render} processing.
+ *
+ * @return The sql function
+ */
+ protected abstract SQLFunction resolveBothSpaceTrimFromFunction();
+
+ /**
+ * Resolve the function definition which should be used to trim leading spaces.
+ *
+ * @return The sql function
+ */
+ protected abstract SQLFunction resolveLeadingSpaceTrimFunction();
+
+ /**
+ * Resolve the function definition which should be used to trim trailing spaces.
+ *
+ * @return The sql function
+ */
+ protected abstract SQLFunction resolveTrailingSpaceTrimFunction();
+
+ /**
+ * Resolve the function definition which should be used to trim the specified character from both the
+ * beginning (leading) and end (trailing) of the trim source.
+ *
+ * @return The sql function
+ */
+ protected abstract SQLFunction resolveBothTrimFunction();
+
+ /**
+ * Resolve the function definition which should be used to trim the specified character from the
+ * beginning (leading) of the trim source.
+ *
+ * @return The sql function
+ */
+ protected abstract SQLFunction resolveLeadingTrimFunction();
+
+ /**
+ * Resolve the function definition which should be used to trim the specified character from the
+ * end (trailing) of the trim source.
+ *
+ * @return The sql function
+ */
+ protected abstract SQLFunction resolveTrailingTrimFunction();
+}
Modified: core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/function/AnsiTrimEmulationFunction.java
===================================================================
--- core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/function/AnsiTrimEmulationFunction.java 2009-02-02 20:25:13 UTC (rev 15858)
+++ core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/function/AnsiTrimEmulationFunction.java 2009-02-03 00:44:42 UTC (rev 15859)
@@ -25,14 +25,7 @@
package org.hibernate.dialect.function;
import org.hibernate.Hibernate;
-import org.hibernate.QueryException;
-import org.hibernate.engine.Mapping;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.type.Type;
-import java.util.List;
-import java.util.ArrayList;
-
/**
* A {@link SQLFunction} implementation that emulates the ANSI SQL trim function
* on dialects which do not support the full definition. However, this function
@@ -42,129 +35,222 @@
*
* @author Steve Ebersole
*/
-public class AnsiTrimEmulationFunction implements SQLFunction {
+public class AnsiTrimEmulationFunction extends AbstractAnsiTrimEmulationFunction {
+ public static final String LTRIM = "ltrim";
+ public static final String RTRIM = "rtrim";
+ public static final String REPLACE = "replace";
+ public static final String SPACE_PLACEHOLDER = "${space}$";
- private static final SQLFunction LEADING_SPACE_TRIM = new SQLFunctionTemplate( Hibernate.STRING, "ltrim( ?1 )");
- private static final SQLFunction TRAILING_SPACE_TRIM = new SQLFunctionTemplate( Hibernate.STRING, "rtrim( ?1 )");
- private static final SQLFunction BOTH_SPACE_TRIM = new SQLFunctionTemplate( Hibernate.STRING, "ltrim( rtrim( ?1 ) )");
- private static final SQLFunction BOTH_SPACE_TRIM_FROM = new SQLFunctionTemplate( Hibernate.STRING, "ltrim( rtrim( ?2 ) )");
+ public static final String LEADING_SPACE_TRIM_TEMPLATE = LTRIM + "(?1)";
+ public static final String TRAILING_SPACE_TRIM_TEMPLATE = RTRIM + "(?1)";
+ public static final String BOTH_SPACE_TRIM_TEMPLATE = LTRIM + "(" + RTRIM + "(?1))";
+ public static final String BOTH_SPACE_TRIM_FROM_TEMPLATE = LTRIM + "(" + RTRIM + "(?2))"; //skip the FROM keyword in params
- private static final SQLFunction LEADING_TRIM = new SQLFunctionTemplate( Hibernate.STRING, "replace( replace( rtrim( replace( replace( ?1, ' ', '${space}$' ), ?2, ' ' ) ), ' ', ?2 ), '${space}$', ' ' )" );
- private static final SQLFunction TRAILING_TRIM = new SQLFunctionTemplate( Hibernate.STRING, "replace( replace( ltrim( replace( replace( ?1, ' ', '${space}$' ), ?2, ' ' ) ), ' ', ?2 ), '${space}$', ' ' )" );
- private static final SQLFunction BOTH_TRIM = new SQLFunctionTemplate( Hibernate.STRING, "replace( replace( ltrim( rtrim( replace( replace( ?1, ' ', '${space}$' ), ?2, ' ' ) ) ), ' ', ?2 ), '${space}$', ' ' )" );
+ /**
+ * A template for the series of calls required to trim non-space chars from the beginning of text.
+ * <p/>
+ * NOTE : essentially we:</ol>
+ * <li>replace all space chars with the text '${space}$'</li>
+ * <li>replace all the actual replacement chars with space chars</li>
+ * <li>perform left-trimming (that removes any of the space chars we just added which occur at the beginning of the text)</li>
+ * <li>replace all space chars with the replacement char</li>
+ * <li>replace all the '${space}$' text with space chars</li>
+ * </ol>
+ */
+ public static final String LEADING_TRIM_TEMPLATE =
+ REPLACE + "(" +
+ REPLACE + "(" +
+ LTRIM + "(" +
+ REPLACE + "(" +
+ REPLACE + "(" +
+ "?1," +
+ "' '," +
+ "'" + SPACE_PLACEHOLDER + "'" +
+ ")," +
+ "?2," +
+ "' '" +
+ ")" +
+ ")," +
+ "' '," +
+ "?2" +
+ ")," +
+ "'" + SPACE_PLACEHOLDER + "'," +
+ "' '" +
+ ")";
- public Type getReturnType(Type columnType, Mapping mapping) throws QueryException {
- return Hibernate.STRING;
+ /**
+ * A template for the series of calls required to trim non-space chars from the end of text.
+ * <p/>
+ * NOTE: essentially the same series of calls as outlined in {@link #LEADING_TRIM_TEMPLATE} except that here,
+ * instead of left-trimming the added spaces, we right-trim them to remove them from the end of the text.
+ */
+ public static final String TRAILING_TRIM_TEMPLATE =
+ REPLACE + "(" +
+ REPLACE + "(" +
+ RTRIM + "(" +
+ REPLACE + "(" +
+ REPLACE + "(" +
+ "?1," +
+ "' '," +
+ "'" + SPACE_PLACEHOLDER + "'" +
+ ")," +
+ "?2," +
+ "' '" +
+ ")" +
+ ")," +
+ "' '," +
+ "?2" +
+ ")," +
+ "'" + SPACE_PLACEHOLDER + "'," +
+ "' '" +
+ ")";
+
+ /**
+ * A template for the series of calls required to trim non-space chars from both the beginning and the end of text.
+ * <p/>
+ * NOTE: again, we have a series of calls that is essentially the same as outlined in {@link #LEADING_TRIM_TEMPLATE}
+ * except that here we perform both left (leading) and right (trailing) trimming.
+ */
+ public static final String BOTH_TRIM_TEMPLATE =
+ REPLACE + "(" +
+ REPLACE + "(" +
+ LTRIM + "(" +
+ RTRIM + "(" +
+ REPLACE + "(" +
+ REPLACE + "(" +
+ "?1," +
+ "' '," +
+ "'" + SPACE_PLACEHOLDER + "'" +
+ ")," +
+ "?2," +
+ "' '" +
+ ")" +
+ ")" +
+ ")," +
+ "' '," +
+ "?2" +
+ ")," +
+ "'" + SPACE_PLACEHOLDER + "'," +
+ "' '" +
+ ")";
+
+ private final SQLFunction leadingSpaceTrim;
+ private final SQLFunction trailingSpaceTrim;
+ private final SQLFunction bothSpaceTrim;
+ private final SQLFunction bothSpaceTrimFrom;
+
+ private final SQLFunction leadingTrim;
+ private final SQLFunction trailingTrim;
+ private final SQLFunction bothTrim;
+
+ /**
+ * Constructs a new AnsiTrimEmulationFunction using {@link #LTRIM}, {@link #RTRIM}, and {@link #REPLACE}
+ * respectively.
+ *
+ * @see #AnsiTrimEmulationFunction(String,String,String)
+ */
+ public AnsiTrimEmulationFunction() {
+ this( LTRIM, RTRIM, REPLACE );
}
- public boolean hasArguments() {
- return true;
+ /**
+ * Constructs a <tt>trim()</tt> emulation function definition using the specified function calls.
+ *
+ * @param ltrimFunctionName The <tt>left trim</tt> function to use.
+ * @param rtrimFunctionName The <tt>right trim</tt> function to use.
+ * @param replaceFunctionName The <tt>replace</tt> function to use.
+ */
+ public AnsiTrimEmulationFunction(String ltrimFunctionName, String rtrimFunctionName, String replaceFunctionName) {
+ leadingSpaceTrim = new SQLFunctionTemplate(
+ Hibernate.STRING,
+ LEADING_SPACE_TRIM_TEMPLATE.replaceAll( LTRIM, ltrimFunctionName )
+ );
+
+ trailingSpaceTrim = new SQLFunctionTemplate(
+ Hibernate.STRING,
+ TRAILING_SPACE_TRIM_TEMPLATE.replaceAll( RTRIM, rtrimFunctionName )
+ );
+
+ bothSpaceTrim = new SQLFunctionTemplate(
+ Hibernate.STRING,
+ BOTH_SPACE_TRIM_TEMPLATE.replaceAll( LTRIM, ltrimFunctionName )
+ .replaceAll( RTRIM, rtrimFunctionName )
+ );
+
+ bothSpaceTrimFrom = new SQLFunctionTemplate(
+ Hibernate.STRING,
+ BOTH_SPACE_TRIM_FROM_TEMPLATE.replaceAll( LTRIM, ltrimFunctionName )
+ .replaceAll( RTRIM, rtrimFunctionName )
+ );
+
+ leadingTrim = new SQLFunctionTemplate(
+ Hibernate.STRING,
+ LEADING_TRIM_TEMPLATE.replaceAll( LTRIM, ltrimFunctionName )
+ .replaceAll( RTRIM, rtrimFunctionName )
+ .replaceAll( REPLACE,replaceFunctionName )
+ );
+
+ trailingTrim = new SQLFunctionTemplate(
+ Hibernate.STRING,
+ TRAILING_TRIM_TEMPLATE.replaceAll( LTRIM, ltrimFunctionName )
+ .replaceAll( RTRIM, rtrimFunctionName )
+ .replaceAll( REPLACE,replaceFunctionName )
+ );
+
+ bothTrim = new SQLFunctionTemplate(
+ Hibernate.STRING,
+ BOTH_TRIM_TEMPLATE.replaceAll( LTRIM, ltrimFunctionName )
+ .replaceAll( RTRIM, rtrimFunctionName )
+ .replaceAll( REPLACE,replaceFunctionName )
+ );
}
- public boolean hasParenthesesIfNoArguments() {
- return false;
+ /**
+ * {@inheritDoc}
+ */
+ protected SQLFunction resolveBothSpaceTrimFunction() {
+ return bothSpaceTrim;
}
- public String render(List args, SessionFactoryImplementor factory) throws QueryException {
- // according to both the ANSI-SQL and EJB3 specs, trim can either take
- // exactly one parameter or a variable number of parameters between 1 and 4.
- // from the SQL spec:
- //
- // <trim function> ::=
- // TRIM <left paren> <trim operands> <right paren>
- //
- // <trim operands> ::=
- // [ [ <trim specification> ] [ <trim character> ] FROM ] <trim source>
- //
- // <trim specification> ::=
- // LEADING
- // | TRAILING
- // | BOTH
- //
- // If only <trim specification> is omitted, BOTH is assumed;
- // if <trim character> is omitted, space is assumed
- if ( args.size() == 1 ) {
- // we have the form: trim(trimSource)
- // so we trim leading and trailing spaces
- return BOTH_SPACE_TRIM.render( args, factory );
- }
- else if ( "from".equalsIgnoreCase( ( String ) args.get( 0 ) ) ) {
- // we have the form: trim(from trimSource).
- // This is functionally equivalent to trim(trimSource)
- return BOTH_SPACE_TRIM_FROM.render( args, factory );
- }
- else {
- // otherwise, a trim-specification and/or a trim-character
- // have been specified; we need to decide which options
- // are present and "do the right thing"
- boolean leading = true; // should leading trim-characters be trimmed?
- boolean trailing = true; // should trailing trim-characters be trimmed?
- String trimCharacter = null; // the trim-character
- String trimSource = null; // the trim-source
+ /**
+ * {@inheritDoc}
+ */
+ protected SQLFunction resolveBothSpaceTrimFromFunction() {
+ return bothSpaceTrimFrom;
+ }
- // potentialTrimCharacterArgIndex = 1 assumes that a
- // trim-specification has been specified. we handle the
- // exception to that explicitly
- int potentialTrimCharacterArgIndex = 1;
- String firstArg = ( String ) args.get( 0 );
- if ( "leading".equalsIgnoreCase( firstArg ) ) {
- trailing = false;
- }
- else if ( "trailing".equalsIgnoreCase( firstArg ) ) {
- leading = false;
- }
- else if ( "both".equalsIgnoreCase( firstArg ) ) {
- }
- else {
- potentialTrimCharacterArgIndex = 0;
- }
+ /**
+ * {@inheritDoc}
+ */
+ protected SQLFunction resolveLeadingSpaceTrimFunction() {
+ return leadingSpaceTrim;
+ }
- String potentialTrimCharacter = ( String ) args.get( potentialTrimCharacterArgIndex );
- if ( "from".equalsIgnoreCase( potentialTrimCharacter ) ) {
- trimCharacter = "' '";
- trimSource = ( String ) args.get( potentialTrimCharacterArgIndex + 1 );
- }
- else if ( potentialTrimCharacterArgIndex + 1 >= args.size() ) {
- trimCharacter = "' '";
- trimSource = potentialTrimCharacter;
- }
- else {
- trimCharacter = potentialTrimCharacter;
- if ( "from".equalsIgnoreCase( ( String ) args.get( potentialTrimCharacterArgIndex + 1 ) ) ) {
- trimSource = ( String ) args.get( potentialTrimCharacterArgIndex + 2 );
- }
- else {
- trimSource = ( String ) args.get( potentialTrimCharacterArgIndex + 1 );
- }
- }
+ /**
+ * {@inheritDoc}
+ */
+ protected SQLFunction resolveTrailingSpaceTrimFunction() {
+ return trailingSpaceTrim;
+ }
- List argsToUse = null;
- argsToUse = new ArrayList();
- argsToUse.add( trimSource );
- argsToUse.add( trimCharacter );
+ /**
+ * {@inheritDoc}
+ */
+ protected SQLFunction resolveBothTrimFunction() {
+ return bothTrim;
+ }
- if ( trimCharacter.equals( "' '" ) ) {
- if ( leading && trailing ) {
- return BOTH_SPACE_TRIM.render( argsToUse, factory );
- }
- else if ( leading ) {
- return LEADING_SPACE_TRIM.render( argsToUse, factory );
- }
- else {
- return TRAILING_SPACE_TRIM.render( argsToUse, factory );
- }
- }
- else {
- if ( leading && trailing ) {
- return BOTH_TRIM.render( argsToUse, factory );
- }
- else if ( leading ) {
- return LEADING_TRIM.render( argsToUse, factory );
- }
- else {
- return TRAILING_TRIM.render( argsToUse, factory );
- }
- }
- }
+ /**
+ * {@inheritDoc}
+ */
+ protected SQLFunction resolveLeadingTrimFunction() {
+ return leadingTrim;
}
+
+ /**
+ * {@inheritDoc}
+ */
+ protected SQLFunction resolveTrailingTrimFunction() {
+ return trailingTrim;
+ }
}
Added: core/branches/Branch_3_3/testsuite/src/test/java/org/hibernate/test/dialect/function/AnsiTrimEmulationFunctionTest.java
===================================================================
--- core/branches/Branch_3_3/testsuite/src/test/java/org/hibernate/test/dialect/function/AnsiTrimEmulationFunctionTest.java (rev 0)
+++ core/branches/Branch_3_3/testsuite/src/test/java/org/hibernate/test/dialect/function/AnsiTrimEmulationFunctionTest.java 2009-02-03 00:44:42 UTC (rev 15859)
@@ -0,0 +1,169 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009, 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.test.dialect.function;
+
+import java.util.List;
+import java.util.ArrayList;
+
+import junit.framework.TestCase;
+
+import org.hibernate.dialect.function.AnsiTrimEmulationFunction;
+
+/**
+ * TODO : javadoc
+ *
+ * @author Steve Ebersole
+ */
+public class AnsiTrimEmulationFunctionTest extends TestCase {
+ private static final String trimSource = "a.column";
+
+ public void testBasicSqlServerProcessing() {
+ AnsiTrimEmulationFunction function = new AnsiTrimEmulationFunction();
+
+ performBasicSpaceTrimmingTests( function );
+
+ final String expectedTrimPrep = "replace(replace(a.column,' ','${space}$'),'-',' ')";
+ final String expectedPostTrimPrefix = "replace(replace(";
+ final String expectedPostTrimSuffix = ",' ','-'),'${space}$',' ')";
+
+ // -> trim(LEADING '-' FROM a.column)
+ String rendered = function.render( argList( "LEADING", "'-'", "FROM", trimSource ), null );
+ String expected = expectedPostTrimPrefix + "ltrim(" + expectedTrimPrep + ")" + expectedPostTrimSuffix;
+ assertEquals( expected, rendered );
+
+ // -> trim(TRAILING '-' FROM a.column)
+ rendered = function.render( argList( "TRAILING", "'-'", "FROM", trimSource ), null );
+ expected = expectedPostTrimPrefix + "rtrim(" + expectedTrimPrep + ")" + expectedPostTrimSuffix;
+ assertEquals( expected, rendered );
+
+ // -> trim(BOTH '-' FROM a.column)
+ rendered = function.render( argList( "BOTH", "'-'", "FROM", trimSource ), null );
+ expected = expectedPostTrimPrefix + "ltrim(rtrim(" + expectedTrimPrep + "))" + expectedPostTrimSuffix;
+ assertEquals( expected, rendered );
+
+ // -> trim('-' FROM a.column)
+ rendered = function.render( argList( "'-'", "FROM", trimSource ), null );
+ expected = expectedPostTrimPrefix + "ltrim(rtrim(" + expectedTrimPrep + "))" + expectedPostTrimSuffix;
+ assertEquals( expected, rendered );
+ }
+
+ public void testBasicSybaseProcessing() {
+ AnsiTrimEmulationFunction function = new AnsiTrimEmulationFunction(
+ AnsiTrimEmulationFunction.LTRIM,
+ AnsiTrimEmulationFunction.RTRIM,
+ "str_replace"
+ );
+
+ performBasicSpaceTrimmingTests( function );
+
+ final String expectedTrimPrep = "str_replace(str_replace(a.column,' ','${space}$'),'-',' ')";
+ final String expectedPostTrimPrefix = "str_replace(str_replace(";
+ final String expectedPostTrimSuffix = ",' ','-'),'${space}$',' ')";
+
+ // -> trim(LEADING '-' FROM a.column)
+ String rendered = function.render( argList( "LEADING", "'-'", "FROM", trimSource ), null );
+ String expected = expectedPostTrimPrefix + "ltrim(" + expectedTrimPrep + ")" + expectedPostTrimSuffix;
+ assertEquals( expected, rendered );
+
+ // -> trim(TRAILING '-' FROM a.column)
+ rendered = function.render( argList( "TRAILING", "'-'", "FROM", trimSource ), null );
+ expected = expectedPostTrimPrefix + "rtrim(" + expectedTrimPrep + ")" + expectedPostTrimSuffix;
+ assertEquals( expected, rendered );
+
+ // -> trim(BOTH '-' FROM a.column)
+ rendered = function.render( argList( "BOTH", "'-'", "FROM", trimSource ), null );
+ expected = expectedPostTrimPrefix + "ltrim(rtrim(" + expectedTrimPrep + "))" + expectedPostTrimSuffix;
+ assertEquals( expected, rendered );
+
+ // -> trim('-' FROM a.column)
+ rendered = function.render( argList( "'-'", "FROM", trimSource ), null );
+ expected = expectedPostTrimPrefix + "ltrim(rtrim(" + expectedTrimPrep + "))" + expectedPostTrimSuffix;
+ assertEquals( expected, rendered );
+ }
+
+ private void performBasicSpaceTrimmingTests(AnsiTrimEmulationFunction function) {
+ // -> trim(a.column)
+ String rendered = function.render( argList( trimSource ), null );
+ assertEquals( "ltrim(rtrim(a.column))", rendered );
+
+ // -> trim(FROM a.column)
+ rendered = function.render( argList( "FROM", trimSource ), null );
+ assertEquals( "ltrim(rtrim(a.column))", rendered );
+
+ // -> trim(BOTH FROM a.column)
+ rendered = function.render( argList( "BOTH", "FROM", trimSource ), null );
+ assertEquals( "ltrim(rtrim(a.column))", rendered );
+
+ // -> trim(BOTH ' ' FROM a.column)
+ rendered = function.render( argList( "BOTH", "' '", "FROM", trimSource ), null );
+ assertEquals( "ltrim(rtrim(a.column))", rendered );
+
+ // -> trim(LEADING FROM a.column)
+ rendered = function.render( argList( "LEADING", "FROM", trimSource ), null );
+ assertEquals( "ltrim(a.column)", rendered );
+
+ // -> trim(LEADING ' ' FROM a.column)
+ rendered = function.render( argList( "LEADING", "' '", "FROM", trimSource ), null );
+ assertEquals( "ltrim(a.column)", rendered );
+
+ // -> trim(TRAILING FROM a.column)
+ rendered = function.render( argList( "TRAILING", "FROM", trimSource ), null );
+ assertEquals( "rtrim(a.column)", rendered );
+
+ // -> trim(TRAILING ' ' FROM a.column)
+ rendered = function.render( argList( "TRAILING", "' '", "FROM", trimSource ), null );
+ assertEquals( "rtrim(a.column)", rendered );
+ }
+
+ private List argList(String arg) {
+ ArrayList args = new ArrayList();
+ args.add( arg );
+ return args;
+ }
+
+ private List argList(String arg1, String arg2) {
+ ArrayList args = new ArrayList();
+ args.add( arg1 );
+ args.add( arg2 );
+ return args;
+ }
+
+ private List argList(String arg1, String arg2, String arg3) {
+ ArrayList args = new ArrayList();
+ args.add( arg1 );
+ args.add( arg2 );
+ args.add( arg3 );
+ return args;
+ }
+
+ private List argList(String arg1, String arg2, String arg3, String arg4) {
+ ArrayList args = new ArrayList();
+ args.add( arg1 );
+ args.add( arg2 );
+ args.add( arg3 );
+ args.add( arg4 );
+ return args;
+ }
+
+}
[View Less]
16 years
Hibernate SVN: r15858 - in core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast: ordering and 1 other directory.
by hibernate-commits@lists.jboss.org
Author: steve.ebersole(a)jboss.com
Date: 2009-02-02 15:25:13 -0500 (Mon, 02 Feb 2009)
New Revision: 15858
Modified:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/QuerySyntaxException.java
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/ordering/OrderByFragmentRenderer.java
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/ordering/OrderByFragmentTranslator.java
Log:
HHH-2407 : HQL translation rework (general cleanup)
Modified: …
[View More]core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/QuerySyntaxException.java
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/QuerySyntaxException.java 2009-02-02 20:24:25 UTC (rev 15857)
+++ core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/QuerySyntaxException.java 2009-02-02 20:25:13 UTC (rev 15858)
@@ -29,7 +29,8 @@
/**
* Exception thrown when there is a syntax error in the HQL.
*
- * @author josh
+ * @author Joshua Davis
+ * @author Steve Ebersole
*/
public class QuerySyntaxException extends QueryException {
public QuerySyntaxException(String message) {
@@ -41,15 +42,19 @@
setQueryString( hql );
}
- public static QuerySyntaxException convert(RecognitionException e) {
- return convert( e, null );
+ public QuerySyntaxException(RecognitionException e) {
+ super( extractMessage( e ) );
}
- public static QuerySyntaxException convert(RecognitionException e, String hql) {
+ public QuerySyntaxException(RecognitionException e, String query) {
+ this( e );
+ setQueryString( query );
+ }
+
+ public static String extractMessage(RecognitionException e) {
String positionInfo = e.getLine() > 0 && e.getColumn() > 0
? " near line " + e.getLine() + ", column " + e.getColumn()
: "";
- return new QuerySyntaxException( e.getMessage() + positionInfo, hql );
+ return e.getMessage() + positionInfo;
}
-
}
\ No newline at end of file
Modified: core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/ordering/OrderByFragmentRenderer.java
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/ordering/OrderByFragmentRenderer.java 2009-02-02 20:24:25 UTC (rev 15857)
+++ core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/ordering/OrderByFragmentRenderer.java 2009-02-02 20:25:13 UTC (rev 15858)
@@ -41,6 +41,9 @@
public class OrderByFragmentRenderer extends GeneratedOrderByFragmentRenderer {
private static final Logger log = LoggerFactory.getLogger( OrderByFragmentRenderer.class );
+ /**
+ * {@inheritDoc}
+ */
protected void out(AST ast) {
out( ( ( Node ) ast ).getRenderableText() );
}
@@ -50,30 +53,36 @@
private final ASTPrinter printer = new ASTPrinter( OrderByTemplateTokenTypes.class );
private int traceDepth = 0;
- public void traceIn(String ruleName, AST tree) {
+ /**
+ * {@inheritDoc}
+ */
+ public final void traceIn(String ruleName, AST tree) {
if ( inputState.guessing > 0 ) {
return;
}
String prefix = StringHelper.repeat( '-', (traceDepth++ * 2) ) + "-> ";
String traceText = ruleName + " (" + buildTraceNodeName(tree) + ")";
- trace( prefix + traceText );
+ traceExecution( prefix + traceText );
}
- private String buildTraceNodeName(AST tree) {
+ protected String buildTraceNodeName(AST tree) {
return tree == null
? "???"
: tree.getText() + " [" + printer.getTokenTypeName( tree.getType() ) + "]";
}
- public void traceOut(String ruleName, AST tree) {
+ /**
+ * {@inheritDoc}
+ */
+ public final void traceOut(String ruleName, AST tree) {
if ( inputState.guessing > 0 ) {
return;
}
String prefix = "<-" + StringHelper.repeat( '-', (--traceDepth * 2) ) + " ";
- trace( prefix + ruleName );
+ traceExecution( prefix + ruleName );
}
- private void trace(String msg) {
+ protected void traceExecution(String msg) {
log.trace( msg );
}
}
Modified: core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/ordering/OrderByFragmentTranslator.java
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/ordering/OrderByFragmentTranslator.java 2009-02-02 20:24:25 UTC (rev 15857)
+++ core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/ordering/OrderByFragmentTranslator.java 2009-02-02 20:25:13 UTC (rev 15858)
@@ -47,7 +47,7 @@
}
/**
- * The main contract, performing the transaction.
+ * The main contract, performing the translation.
*
* @param fragment The <tt>order-by</tt> mapping fragment to be translated.
*
@@ -71,7 +71,7 @@
log.trace( printer.showAsString( parser.getAST(), "--- {order-by fragment} ---" ) );
}
- GeneratedOrderByFragmentRenderer renderer = new GeneratedOrderByFragmentRenderer();
+ OrderByFragmentRenderer renderer = new OrderByFragmentRenderer();
try {
renderer.orderByFragment( parser.getAST() );
}
[View Less]
16 years
Hibernate SVN: r15857 - in core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast: alias and 1 other directories.
by hibernate-commits@lists.jboss.org
Author: steve.ebersole(a)jboss.com
Date: 2009-02-02 15:24:25 -0500 (Mon, 02 Feb 2009)
New Revision: 15857
Added:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/alias/
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/alias/AbstractTableAliasGeneratorTemplate.java
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/alias/DefaultTableAliasGenerator.java
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/alias/…
[View More]ImplicitAliasGenerator.java
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/alias/TableAliasGenerator.java
Removed:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/AliasBuilder.java
Log:
HHH-2407 : HQL translation rework ->
HHH-3687 : parse (phase1)
HHH-3688 : normalize (phase2)
Added: core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/alias/AbstractTableAliasGeneratorTemplate.java
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/alias/AbstractTableAliasGeneratorTemplate.java (rev 0)
+++ core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/alias/AbstractTableAliasGeneratorTemplate.java 2009-02-02 20:24:25 UTC (rev 15857)
@@ -0,0 +1,146 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009, 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.ast.alias;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.hibernate.persister.entity.Queryable;
+import org.hibernate.persister.collection.QueryableCollection;
+import org.hibernate.dialect.Dialect;
+import org.hibernate.util.StringHelper;
+
+/**
+ * Defines a termplated implementation of the {@link TableAliasGenerator} contract.
+ * <p/>
+ * The variance is in the subclass implementation of the {@link #truncateAliasBase} method.
+ *
+ * @author Steve Ebersole
+ */
+public abstract class AbstractTableAliasGeneratorTemplate implements TableAliasGenerator {
+ private static final Logger log = LoggerFactory.getLogger( TableAliasGenerator.class );
+
+ private final Dialect dialect;
+ private int uniqueingValue = 0;
+
+ protected AbstractTableAliasGeneratorTemplate(Dialect dialect) {
+ this.dialect = dialect;
+ }
+
+ /**
+ * Truncate down the base of the sql alias root to the 'totalAllowableSizeOfAliasBase'.
+ * <p/>
+ * This abstract method provides the variance in the templating routine; different implementations will
+ * define this extact behavior differently.
+ *
+ * @param base The base for the alias root.
+ * @param totalAllowableSizeOfAliasBase The total allowable size of the base after truncating.
+ *
+ * @return The appropriately truncated base.
+ */
+ protected abstract String truncateAliasBase(String base, int totalAllowableSizeOfAliasBase);
+
+ /**
+ * {@inheritDoc}
+ */
+ public final TableAliasRoot generateSqlAliasRoot(Queryable persister, String sourceAlias) {
+ log.trace( "Generating SQL alias root (entity) : " + sourceAlias );
+ String base = sourceAlias;
+ if ( ImplicitAliasGenerator.isImplicitAlias( sourceAlias ) ) {
+ base = persister.getMappedTableMetadata().getSqlAliasRootBase();
+ }
+ return generateSqlAliasRoot( base, determineMappedTableCount( persister ) );
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public final TableAliasRoot generateSqlAliasRoot(QueryableCollection persister, String sourceAlias) {
+ log.trace( "Generating SQL alias root (collection) : " + sourceAlias );
+ String base = sourceAlias;
+ if ( ImplicitAliasGenerator.isImplicitAlias( sourceAlias ) ) {
+ base = StringHelper.unqualify( persister.getName() ).toLowerCase();
+ }
+ return generateSqlAliasRoot( base, determineMappedTableCount( persister ) );
+ }
+
+ private int determineMappedTableCount(Queryable persister) {
+ return persister.getMappedTableMetadata().getJoinedTables().length + 1;
+ }
+
+ private int determineMappedTableCount(QueryableCollection persister) {
+ if ( !persister.getElementType().isAssociationType() ) {
+ return 1;
+ }
+ else {
+ return determineMappedTableCount( ( Queryable ) persister.getElementPersister() );
+ }
+ }
+
+ protected final TableAliasRoot generateSqlAliasRoot(String base, int tableCount) {
+ base = cleanBase( base );
+ base = ensureAliasCapacity( base, tableCount );
+ return new TableAliasRoot( base );
+ }
+
+ private String cleanBase(String base) {
+ base = base.toLowerCase()
+ .replace( '/', '_' )
+ .replace( '$', '_' );
+
+ char[] chars = base.toCharArray();
+ if ( !Character.isLetter( chars[0] ) ) {
+ for ( int i = 1; i < chars.length; i++ ) {
+ if ( Character.isLetter( chars[i] ) ) {
+ base = base.substring( i );
+ }
+ }
+ }
+
+ if ( Character.isDigit( base.charAt( base.length() - 1 ) ) ) {
+ base = base.substring( 0, base.length() - 1 ) + 'x';
+ }
+
+ return base;
+ }
+
+ private String ensureAliasCapacity(String base, int mappedTableCount) {
+ // we need to consider the max-alias-length reported by the dialect against the
+ // size of the incoming base + the number of mapped tables
+ int nextUniqueingValueSize = Integer.toString( uniqueingValue + 1 ).length();
+ int totalAllowableSizeOfAliasBase = dialect.getMaxAliasLength() - nextUniqueingValueSize;
+ if ( mappedTableCount > 1 ) {
+ totalAllowableSizeOfAliasBase-= Integer.toString( mappedTableCount ).length();
+ }
+ return buildUniqueAliasBase( truncateAliasBase( base, totalAllowableSizeOfAliasBase ) );
+ }
+
+ private String buildUniqueAliasBase(String base) {
+ return base + uniqueInteger() + '_';
+ }
+
+ private int uniqueInteger() {
+ return uniqueingValue++;
+ }
+}
Added: core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/alias/DefaultTableAliasGenerator.java
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/alias/DefaultTableAliasGenerator.java (rev 0)
+++ core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/alias/DefaultTableAliasGenerator.java 2009-02-02 20:24:25 UTC (rev 15857)
@@ -0,0 +1,47 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009, 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.ast.alias;
+
+import org.hibernate.dialect.Dialect;
+import org.hibernate.util.StringHelper;
+
+/**
+ * The default implementation of the templating provided by {@link AbstractTableAliasGeneratorTemplate}.
+ * <p/>
+ * Here we simply truncate the base down to the allowable size.
+ *
+ * @author Steve Ebersole
+ */
+public class DefaultTableAliasGenerator extends AbstractTableAliasGeneratorTemplate {
+ public DefaultTableAliasGenerator(Dialect dialect) {
+ super( dialect );
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected String truncateAliasBase(String base, int totalAllowableSizeOfAliasBase) {
+ return StringHelper.truncate( base, totalAllowableSizeOfAliasBase );
+ }
+}
\ No newline at end of file
Copied: core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/alias/ImplicitAliasGenerator.java (from rev 15747, core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/AliasBuilder.java)
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/alias/ImplicitAliasGenerator.java (rev 0)
+++ core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/alias/ImplicitAliasGenerator.java 2009-02-02 20:24:25 UTC (rev 15857)
@@ -0,0 +1,52 @@
+/*
+ * 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.ast.alias;
+
+/**
+ * Handles generating implicit (or synthetic) aliases.
+ *
+ * @author Steve Ebersole
+ */
+public class ImplicitAliasGenerator {
+ private int unaliasedCount = 0;
+
+ /**
+ * Builds a unique implicit alias.
+ *
+ * @return The generated alias.
+ */
+ public synchronized String buildUniqueImplicitAlias() {
+ return "<gen:" + unaliasedCount++ + ">";
+ }
+
+ /**
+ * Determine if the given alias is implicit.
+ *
+ * @param alias The alias to check
+ * @return True/false.
+ */
+ public static boolean isImplicitAlias(String alias) {
+ return alias == null || ( alias.startsWith( "<gen:" ) && alias.endsWith( ">" ) );
+ }
+}
Added: core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/alias/TableAliasGenerator.java
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/alias/TableAliasGenerator.java (rev 0)
+++ core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/alias/TableAliasGenerator.java 2009-02-02 20:24:25 UTC (rev 15857)
@@ -0,0 +1,111 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009, 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.ast.alias;
+
+import org.hibernate.persister.collection.QueryableCollection;
+import org.hibernate.persister.entity.Queryable;
+
+/**
+ * Contract for generating table alias roots. An alias root is the base used to create aliases for a whole series
+ * of related tables (e.g., for all the tables in a joined-subclass hierarchy).
+ *
+ * @author Steve Ebersole
+ */
+public interface TableAliasGenerator {
+ /**
+ * Encapsulation of the alias root.
+ */
+ public static class TableAliasRoot {
+ private final String base;
+
+ public TableAliasRoot(String base) {
+ this.base = base;
+ }
+
+ /**
+ * Generate the sql alias based on the given suffix which is the <i>subclass table number</i>.
+ *
+ * @param suffix The alias suffix.
+ *
+ * @return The generated alias.
+ */
+ public String generate(int suffix) {
+ return base + Integer.toString( suffix ) + '_';
+ }
+
+ /**
+ * Generate an alias for the <i>collection table</i>.
+ * <p/>
+ * For basic collections and many-to-many mappings the <i>collection table</i> is a distinct ERD entity, and we
+ * must generate a reference to that table (in contrast, the <i>collection table</i> for a one-to-many
+ * association is actually the entity table of the many side).
+ *
+ * @return The generated alias.
+ */
+ public String generateCollectionTableAlias() {
+ return base + "_";
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean equals(Object o) {
+ if ( this == o ) {
+ return true;
+ }
+ if ( o == null || getClass() != o.getClass() ) {
+ return false;
+ }
+ TableAliasRoot aliasRoot = ( TableAliasRoot ) o;
+ return base.equals( aliasRoot.base );
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public int hashCode() {
+ return base.hashCode();
+ }
+ }
+
+ /**
+ * Generate the alias root for the given persister reference.
+ *
+ * @param persister The entity persister.
+ * @param sourceAlias The alias attached to the persister in the source query.
+ *
+ * @return The alias root.
+ */
+ public TableAliasRoot generateSqlAliasRoot(Queryable persister, String sourceAlias);
+
+ /**
+ * Generate the alias root for the given persister reference.
+ *
+ * @param persister The collection persister
+ * @param sourceAlias The alias attached to the persister in the source query.
+ *
+ * @return The alias root.
+ */
+ public TableAliasRoot generateSqlAliasRoot(QueryableCollection persister, String sourceAlias);
+}
Deleted: core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/AliasBuilder.java
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/AliasBuilder.java 2009-02-02 17:15:35 UTC (rev 15856)
+++ core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/AliasBuilder.java 2009-02-02 20:24:25 UTC (rev 15857)
@@ -1,52 +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.sql.ast.phase.hql.normalize;
-
-/**
- * Handles generating synthetic or implicit aliases.
- *
- * @author Steve Ebersole
- */
-public class AliasBuilder {
- private int unaliasedCount = 0;
-
- /**
- * Builds a unique implicit alias.
- *
- * @return The generated alias.
- */
- public synchronized String buildUniqueImplicitAlias() {
- return "<gen:" + unaliasedCount++ + ">";
- }
-
- /**
- * Determine if the given alias is implicit.
- *
- * @param alias The alias to check
- * @return True/false.
- */
- public static boolean isImplicitAlias(String alias) {
- return alias == null || ( alias.startsWith( "<gen:" ) && alias.endsWith( ">" ) );
- }
-}
[View Less]
16 years
Hibernate SVN: r15856 - core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/util.
by hibernate-commits@lists.jboss.org
Author: steve.ebersole(a)jboss.com
Date: 2009-02-02 12:15:35 -0500 (Mon, 02 Feb 2009)
New Revision: 15856
Added:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/util/CopyableNode.java
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/util/ErrorHandler.java
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/util/ErrorHandlerDelegate.java
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/util/…
[View More]ErrorHandlerDelegateImpl.java
Modified:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/util/NodeDeepCopier.java
Log:
HHH-2407 : HQL translation rework ->
HHH-3687 : parse (phase1)
HHH-3688 : normalize (phase2)
Added: core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/util/CopyableNode.java
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/util/CopyableNode.java (rev 0)
+++ core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/util/CopyableNode.java 2009-02-02 17:15:35 UTC (rev 15856)
@@ -0,0 +1,38 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009, 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.ast.util;
+
+import antlr.collections.AST;
+
+/**
+ * Contract for nodes wishing to detail exactly how they should be shallow copied.
+ * <p/>
+ * Intended for use from {@link NodeDeepCopier#createShallowCopy} instead of the default shallow copy
+ * algorithm.
+ *
+ * @author Steve Ebersole
+ */
+public interface CopyableNode {
+ public AST createCopy();
+}
Copied: core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/util/ErrorHandler.java (from rev 15693, core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/util/ErrorReporter.java)
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/util/ErrorHandler.java (rev 0)
+++ core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/util/ErrorHandler.java 2009-02-02 17:15:35 UTC (rev 15856)
@@ -0,0 +1,56 @@
+/*
+ * 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.ast.util;
+
+import antlr.RecognitionException;
+
+/**
+ * Contract for handling error originating from the Antlr {@link antlr.TreeParser base} parser. In fact,
+ * these methods are all redefinitions of the error handling methods defined there.
+ *
+ * @author Joshua Davis
+ * @author Steve Ebersole
+ */
+public interface ErrorHandler {
+ /**
+ * Handle delegation of {@link antlr.TreeParser#reportError(antlr.RecognitionException)}
+ *
+ * @param recognitionException The Antlr recognition exception
+ */
+ public void reportError(RecognitionException recognitionException);
+
+ /**
+ * Handle delegation of {@link antlr.TreeParser#reportError(java.lang.String)}
+ *
+ * @param message The error message
+ */
+ public void reportError(String message);
+
+ /**
+ * Handle delegation of {@link antlr.TreeParser#reportWarning(String)}
+ *
+ * @param message The warning message
+ */
+ public void reportWarning(String message);
+}
\ No newline at end of file
Copied: core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/util/ErrorHandlerDelegate.java (from rev 15693, core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/util/ParseErrorHandler.java)
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/util/ErrorHandlerDelegate.java (rev 0)
+++ core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/util/ErrorHandlerDelegate.java 2009-02-02 17:15:35 UTC (rev 15856)
@@ -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.ast.util;
+
+import org.hibernate.QueryException;
+
+/**
+ * Additional contract for providing delegation of {@link ErrorHandler} functionality.
+ *
+ * @author Joshua Davis
+ * @author Steve Ebersole
+ */
+public interface ErrorHandlerDelegate extends ErrorHandler {
+ /**
+ * Get the number of errors current being tracked inside this delegate.
+ *
+ * @return The number of errors.
+ */
+ public int getErrorCount();
+
+ /**
+ * Construct and throw an appropriate query exception if required based on internal state.
+ *
+ * @throws QueryException If our internal states deems it necessary to generate a query exception
+ */
+ public void throwQueryException() throws QueryException;
+}
\ No newline at end of file
Copied: core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/util/ErrorHandlerDelegateImpl.java (from rev 15693, core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/util/ErrorCounter.java)
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/util/ErrorHandlerDelegateImpl.java (rev 0)
+++ core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/util/ErrorHandlerDelegateImpl.java 2009-02-02 17:15:35 UTC (rev 15856)
@@ -0,0 +1,110 @@
+/*
+ * 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.ast.util;
+
+import antlr.RecognitionException;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.hibernate.QueryException;
+import org.hibernate.sql.ast.QuerySyntaxException;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * An implementation of the {@link ErrorHandlerDelegate} contract.
+ *
+ * @author Joshua Davis
+ * @author Steve Ebersole
+ */
+public class ErrorHandlerDelegateImpl implements ErrorHandlerDelegate {
+ private static final Log log = LogFactory.getLog( ErrorHandlerDelegateImpl.class );
+
+ private List errorList = new ArrayList();
+ private List recognitionExceptions = new ArrayList();
+
+ /**
+ * {@inheritDoc}
+ */
+ public void reportError(RecognitionException e) {
+ final String msg = e.toString();
+ reportError( msg );
+ recognitionExceptions.add( e );
+ if ( log.isTraceEnabled() ) {
+ log.trace( msg, e );
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void reportError(String message) {
+ log.error( message );
+ errorList.add( message );
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void reportWarning(String message) {
+ log.debug( message );
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public int getErrorCount() {
+ return errorList.size();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void throwQueryException() throws QueryException {
+ if ( getErrorCount() > 0 ) {
+ if ( recognitionExceptions.size() > 0 ) {
+ throw new QuerySyntaxException( ( RecognitionException ) recognitionExceptions.get( 0 ) );
+ }
+ else {
+ throw new QueryException( generateErrorString() );
+ }
+ }
+ else {
+ // all clear
+ if ( log.isDebugEnabled() ) {
+ log.debug( "throwQueryException() : no errors" );
+ }
+ }
+ }
+ private String generateErrorString() {
+ StringBuffer buf = new StringBuffer();
+ for ( Iterator iterator = errorList.iterator(); iterator.hasNext(); ) {
+ buf.append( ( String ) iterator.next() );
+ if ( iterator.hasNext() ) buf.append( "\n" );
+
+ }
+ return buf.toString();
+ }
+}
\ No newline at end of file
Modified: core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/util/NodeDeepCopier.java
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/util/NodeDeepCopier.java 2009-02-02 15:50:32 UTC (rev 15855)
+++ core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/util/NodeDeepCopier.java 2009-02-02 17:15:35 UTC (rev 15856)
@@ -27,7 +27,7 @@
import antlr.ASTFactory;
/**
- * TODO : javadoc
+ * Strategy for creating copies of AST trees.
*
* @author Steve Ebersole
*/
@@ -39,18 +39,34 @@
}
public AST copy(AST node) {
+ // copy the root (incoming) node
AST newNode = createShallowCopy( node );
+ // track a running reference to the child node we are currently processing.
AST child = node.getFirstChild();
while ( child != null ) {
+ // create a deep copy of the current child and add it as a child to the copied root
newNode.addChild( copy( child ) );
+ // spin forward to the next child
child = child.getNextSibling();
}
return newNode;
}
+ /**
+ * Creates a shallow (non-linked) copy of an AST node.
+ *
+ * @param node The AST node to shallow copy.
+ *
+ * @return The shallow copy.
+ */
public AST createShallowCopy(AST node) {
- AST newNode = astFactory.create( node.getType(), node.getText() );
- newNode.initialize( node );
- return newNode;
+ if ( node instanceof CopyableNode ) {
+ return ( ( CopyableNode ) node ).createCopy();
+ }
+ else {
+ AST newNode = astFactory.create( node.getType(), node.getText() );
+ newNode.initialize( node );
+ return newNode;
+ }
}
}
[View Less]
16 years
Hibernate SVN: r15855 - in validator/trunk: hibernate-validator/src/main/java/org/hibernate/validation/util and 3 other directories.
by hibernate-commits@lists.jboss.org
Author: hardy.ferentschik
Date: 2009-02-02 10:50:32 -0500 (Mon, 02 Feb 2009)
New Revision: 15855
Added:
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/BuiltinConstraints.java
Removed:
validator/trunk/hibernate-validator/src/main/resources/org/hibernate/validation/BuiltinConstraintDefinitions.properties
Modified:
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/BeanMetaDataImpl.java
validator/trunk/hibernate-…
[View More]validator/src/main/java/org/hibernate/validation/engine/ConstraintDescriptorImpl.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ValidatorContextImpl.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ValidatorFactoryImpl.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ValidatorImpl.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/util/ReflectionHelper.java
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/ResourceBundleMessageInterpolatorTest.java
validator/trunk/validation-api/src/main/java/javax/validation/ConstraintDescriptor.java
Log:
Removed the properties files. Now a map is used to determine the builtin constraints. Also create the builtin constraints in ValidatorFactoryImpl and pass them along. This will allow to override the builtin constraints to be overridden in xml. However, I also had to pass the instance aound for quite a long time. I am wondering whether dependcy injection wouldn't be a good idea here (guice?)
Modified: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/BeanMetaDataImpl.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/BeanMetaDataImpl.java 2009-02-02 15:43:25 UTC (rev 15854)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/BeanMetaDataImpl.java 2009-02-02 15:50:32 UTC (rev 15855)
@@ -86,8 +86,11 @@
*/
private Map<Class<?>, List<Class<?>>> groupSequences = new HashMap<Class<?>, List<Class<?>>>();
- public BeanMetaDataImpl(Class<T> beanClass) {
+ private final BuiltinConstraints builtinConstraints;
+
+ public BeanMetaDataImpl(Class<T> beanClass, BuiltinConstraints builtinConstraints) {
this.beanClass = beanClass;
+ this.builtinConstraints = builtinConstraints;
createMetaData();
}
@@ -255,7 +258,7 @@
}
}
- return new ConstraintDescriptorImpl( annotation, groups );
+ return new ConstraintDescriptorImpl( annotation, groups, builtinConstraints );
}
/**
Added: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/BuiltinConstraints.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/BuiltinConstraints.java (rev 0)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/BuiltinConstraints.java 2009-02-02 15:50:32 UTC (rev 15855)
@@ -0,0 +1,113 @@
+// $Id:$
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, and individual contributors
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+* http://www.apache.org/licenses/LICENSE-2.0
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+package org.hibernate.validation.engine;
+
+import java.lang.annotation.Annotation;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import javax.validation.ConstraintValidator;
+import javax.validation.ValidationException;
+import javax.validation.constraints.AssertFalse;
+import javax.validation.constraints.AssertTrue;
+import javax.validation.constraints.Future;
+import javax.validation.constraints.Max;
+import javax.validation.constraints.Min;
+import javax.validation.constraints.NotNull;
+import javax.validation.constraints.Null;
+import javax.validation.constraints.Size;
+
+import org.hibernate.validation.constraints.AssertFalseValidator;
+import org.hibernate.validation.constraints.AssertTrueValidator;
+import org.hibernate.validation.constraints.FutureValidatorForCalendar;
+import org.hibernate.validation.constraints.FutureValidatorForDate;
+import org.hibernate.validation.constraints.MaxValidatorForNumber;
+import org.hibernate.validation.constraints.MaxValidatorForString;
+import org.hibernate.validation.constraints.MinValidatorForNumber;
+import org.hibernate.validation.constraints.MinValidatorForString;
+import org.hibernate.validation.constraints.NotNullValidator;
+import org.hibernate.validation.constraints.NullValidator;
+import org.hibernate.validation.constraints.PastValidatorForCalendar;
+import org.hibernate.validation.constraints.PastValidatorForDate;
+import org.hibernate.validation.constraints.SizeValidator;
+
+/**
+ * @author Hardy Ferentschik
+ */
+public class BuiltinConstraints {
+
+ private final Map<Class<? extends Annotation>, List<Class<? extends ConstraintValidator<?, ?>>>> builtinConstraints =
+ new HashMap<Class<? extends Annotation>, List<Class<? extends ConstraintValidator<?, ?>>>>();
+
+ public BuiltinConstraints() {
+
+ List<Class<? extends ConstraintValidator<?, ?>>> constraintList = new ArrayList<Class<? extends ConstraintValidator<?, ?>>>();
+ constraintList.add( AssertFalseValidator.class );
+ builtinConstraints.put( AssertFalse.class, constraintList );
+
+ constraintList = new ArrayList<Class<? extends ConstraintValidator<?, ?>>>();
+ constraintList.add( AssertTrueValidator.class );
+ builtinConstraints.put( AssertTrue.class, constraintList );
+
+ constraintList = new ArrayList<Class<? extends ConstraintValidator<?, ?>>>();
+ constraintList.add( FutureValidatorForCalendar.class );
+ constraintList.add( FutureValidatorForDate.class );
+ builtinConstraints.put( Future.class, constraintList );
+
+ constraintList = new ArrayList<Class<? extends ConstraintValidator<?, ?>>>();
+ constraintList.add( MaxValidatorForNumber.class );
+ constraintList.add( MaxValidatorForString.class );
+ builtinConstraints.put( Max.class, constraintList );
+
+ constraintList = new ArrayList<Class<? extends ConstraintValidator<?, ?>>>();
+ constraintList.add( MinValidatorForNumber.class );
+ constraintList.add( MinValidatorForString.class );
+ builtinConstraints.put( Min.class, constraintList );
+
+ constraintList = new ArrayList<Class<? extends ConstraintValidator<?, ?>>>();
+ constraintList.add( NotNullValidator.class );
+ builtinConstraints.put( NotNull.class, constraintList );
+
+ constraintList = new ArrayList<Class<? extends ConstraintValidator<?, ?>>>();
+ constraintList.add( NullValidator.class );
+ builtinConstraints.put( Null.class, constraintList );
+
+ constraintList = new ArrayList<Class<? extends ConstraintValidator<?, ?>>>();
+ constraintList.add( PastValidatorForCalendar.class );
+ constraintList.add( PastValidatorForDate.class );
+ builtinConstraints.put( Future.class, constraintList );
+
+ constraintList = new ArrayList<Class<? extends ConstraintValidator<?, ?>>>();
+ constraintList.add( SizeValidator.class );
+ builtinConstraints.put( Size.class, constraintList );
+
+
+ }
+
+ public List<Class<? extends ConstraintValidator<?, ?>>> getBuiltInConstraints(Annotation annotation) {
+ List<Class<? extends ConstraintValidator<?, ?>>> constraints = builtinConstraints.get( annotation.annotationType() );
+
+ if ( constraints == null ) {
+ throw new ValidationException( "Unable to find constraints for " + annotation.annotationType() );
+ }
+
+ return constraints;
+ }
+
+}
Property changes on: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/BuiltinConstraints.java
___________________________________________________________________
Name: svn:keywords
+ Id
Modified: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ConstraintDescriptorImpl.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ConstraintDescriptorImpl.java 2009-02-02 15:43:25 UTC (rev 15854)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ConstraintDescriptorImpl.java 2009-02-02 15:50:32 UTC (rev 15855)
@@ -20,6 +20,7 @@
import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
@@ -27,7 +28,6 @@
import java.util.List;
import java.util.Map;
import java.util.Set;
-import java.util.ArrayList;
import javax.validation.Constraint;
import javax.validation.ConstraintDescriptor;
import javax.validation.ConstraintValidator;
@@ -55,46 +55,80 @@
private static final Class<?>[] DEFAULT_GROUP = new Class<?>[] { Default.class };
private static final int OVERRIDES_PARAMETER_DEFAULT_INDEX = -1;
+ /**
+ * The actual constraint annotation.
+ */
private final U annotation;
- //TODO make it a list
- private final Class<? extends ConstraintValidator<U,?>>[] constraintClasses;
+
+ /**
+ * The set of classes implementing the validation for this constraint. See also
+ * <code>ConstraintValidator</code> resolution algorithm.
+ */
+ private final List<Class<? extends ConstraintValidator<?, ?>>> constraintClasses = new ArrayList<Class<? extends ConstraintValidator<?, ?>>>();
+
+ /**
+ * The groups for which to apply this constraint.
+ */
private final Set<Class<?>> groups;
+
+ /**
+ * The constraint parameters as map. The key is the paramter name and the value the
+ * parameter value as specified in the constraint.
+ */
private final Map<String, Object> parameters;
+
+ /**
+ * The composing constraints for this constraints.
+ */
private final Set<ConstraintDescriptor> composingConstraints = new HashSet<ConstraintDescriptor>();
+
+ /**
+ * Override paramter values used for composing constraints.
+ */
private final Map<ClassIndexWrapper, Map<String, Object>> overrideParameters = new HashMap<ClassIndexWrapper, Map<String, Object>>();
+
+ /**
+ * Flag indicating if in case of a composing constraint a single error or multiple errors should be raised.
+ */
private final boolean isReportAsSingleInvalidConstraint;
- public ConstraintDescriptorImpl(U annotation, Class<?>[] groups) {
- this( annotation, new HashSet<Class<?>>() );
+ /**
+ * Handle to the builtin constraint implementations.
+ */
+ private final BuiltinConstraints builtinConstraints;
+
+ public ConstraintDescriptorImpl(U annotation, Class<?>[] groups, BuiltinConstraints builtinConstraints) {
+ this( annotation, new HashSet<Class<?>>(), builtinConstraints );
if ( groups.length == 0 ) {
groups = DEFAULT_GROUP;
}
this.groups.addAll( Arrays.asList( groups ) );
}
- public ConstraintDescriptorImpl(U annotation, Set<Class<?>> groups) {
+ public ConstraintDescriptorImpl(U annotation, Set<Class<?>> groups, BuiltinConstraints builtinConstraints) {
this.annotation = annotation;
this.groups = groups;
this.parameters = getAnnotationParameters( annotation );
+ this.builtinConstraints = builtinConstraints;
this.isReportAsSingleInvalidConstraint = annotation.annotationType().isAnnotationPresent(
ReportAsViolationFromCompositeConstraint.class
);
+ findConstraintClasses();
+ parseOverrideParameters();
+ parseComposingConstraints();
+ }
+
+ private void findConstraintClasses() {
if ( ReflectionHelper.isBuiltInConstraintAnnotation( annotation ) ) {
- this.constraintClasses = (Class<? extends ConstraintValidator<U,?>>[])
- ReflectionHelper.getBuiltInConstraints( annotation );
+ constraintClasses.addAll( builtinConstraints.getBuiltInConstraints( annotation ) );
}
else {
- Constraint constraint = annotation.annotationType()
- .getAnnotation( Constraint.class );
- this.constraintClasses = (Class<? extends ConstraintValidator<U,?>>[])
- constraint.validatedBy();
+ Constraint constraint = annotation.annotationType().getAnnotation( Constraint.class );
+ constraintClasses.addAll( Arrays.asList( constraint.validatedBy() ) );
}
-
- parseOverrideParameters();
- parseComposingConstraints();
}
/**
@@ -114,11 +148,8 @@
/**
* {@inheritDoc}
*/
- public List<Class<? extends ConstraintValidator<?,?>>>
- getConstraintValidatorClasses() {
- return Collections.unmodifiableList(
- Arrays.asList((Class<? extends ConstraintValidator<?,?>>[]) constraintClasses)
- );
+ public List<Class<? extends ConstraintValidator<?, ?>>> getConstraintValidatorClasses() {
+ return Collections.unmodifiableList( constraintClasses );
}
/**
@@ -146,7 +177,7 @@
public String toString() {
return "ConstraintDescriptorImpl{" +
"annotation=" + annotation +
- ", constraintClasses=" + constraintClasses +
+ ", constraintClasses=" + constraintClasses.toString() +
", groups=" + groups +
", parameters=" + parameters +
", composingConstraints=" + composingConstraints +
@@ -172,7 +203,6 @@
}
private void addOverrideParameter(Map<ClassIndexWrapper, Map<String, Object>> overrideParameters, Object value, OverridesParameter... parameters) {
-
for ( OverridesParameter parameter : parameters ) {
ClassIndexWrapper wrapper = new ClassIndexWrapper( parameter.constraint(), parameter.index() );
Map<String, Object> map = overrideParameters.get( wrapper );
@@ -200,7 +230,6 @@
}
private void parseOverrideParameters() {
- // check for overrides
for ( Method m : annotation.annotationType().getMethods() ) {
if ( m.getAnnotation( OverridesParameter.class ) != null ) {
addOverrideParameter(
@@ -259,7 +288,7 @@
}
}
Annotation annotationProxy = AnnotationFactory.create( annotationDescriptor );
- return new ConstraintDescriptorImpl( annotationProxy, groups );
+ return new ConstraintDescriptorImpl( annotationProxy, groups, builtinConstraints );
}
private class ClassIndexWrapper {
Modified: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ValidatorContextImpl.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ValidatorContextImpl.java 2009-02-02 15:43:25 UTC (rev 15854)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ValidatorContextImpl.java 2009-02-02 15:50:32 UTC (rev 15855)
@@ -15,13 +15,16 @@
private final MessageInterpolator factoryMessageInterpolator;
private final TraversableResolver factoryTraversableResolver;
private final ConstraintValidatorFactory constraintValidatorFactory;
+ private final BuiltinConstraints builtinConstraints;
public ValidatorContextImpl(ConstraintValidatorFactory constraintValidatorFactory,
MessageInterpolator factoryMessageInterpolator,
- TraversableResolver factoryTraversableResolver) {
+ TraversableResolver factoryTraversableResolver,
+ BuiltinConstraints builtinConstraints) {
this.constraintValidatorFactory = constraintValidatorFactory;
this.factoryMessageInterpolator = factoryMessageInterpolator;
this.factoryTraversableResolver = factoryTraversableResolver;
+ this.builtinConstraints = builtinConstraints;
messageInterpolator( factoryMessageInterpolator );
traversableResolver( factoryTraversableResolver );
}
@@ -47,6 +50,6 @@
}
public Validator getValidator() {
- return new ValidatorImpl( constraintValidatorFactory, messageInterpolator );
+ return new ValidatorImpl( constraintValidatorFactory, messageInterpolator, builtinConstraints );
}
}
Modified: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ValidatorFactoryImpl.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ValidatorFactoryImpl.java 2009-02-02 15:43:25 UTC (rev 15854)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ValidatorFactoryImpl.java 2009-02-02 15:50:32 UTC (rev 15855)
@@ -34,6 +34,7 @@
private final MessageInterpolator messageInterpolator;
private final TraversableResolver traversableResolver;
private final ConstraintValidatorFactory constraintValidatorFactory;
+ private final BuiltinConstraints builtinConstraints = new BuiltinConstraints();
public ValidatorFactoryImpl(ConfigurationState configurationState) {
this.messageInterpolator = configurationState.getMessageInterpolator();
@@ -60,6 +61,6 @@
* {@inheritDoc}
*/
public ValidatorContext usingContext() {
- return new ValidatorContextImpl( constraintValidatorFactory, messageInterpolator, traversableResolver );
+ return new ValidatorContextImpl( constraintValidatorFactory, messageInterpolator, traversableResolver, builtinConstraints );
}
}
Modified: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ValidatorImpl.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ValidatorImpl.java 2009-02-02 15:43:25 UTC (rev 15854)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ValidatorImpl.java 2009-02-02 15:50:32 UTC (rev 15855)
@@ -65,10 +65,12 @@
private final ConstraintValidatorFactory constraintValidatorFactory;
private final MessageInterpolator messageInterpolator;
+ private final BuiltinConstraints builtinConstraints;
- public ValidatorImpl(ConstraintValidatorFactory constraintValidatorFactory, MessageInterpolator messageInterpolator) {
+ public ValidatorImpl(ConstraintValidatorFactory constraintValidatorFactory, MessageInterpolator messageInterpolator, BuiltinConstraints builtinConstraints) {
this.constraintValidatorFactory = constraintValidatorFactory;
this.messageInterpolator = messageInterpolator;
+ this.builtinConstraints = builtinConstraints;
}
/**
@@ -423,7 +425,7 @@
@SuppressWarnings("unchecked")
BeanMetaDataImpl<T> metadata = ( BeanMetaDataImpl<T> ) metadataProviders.get( beanClass );
if ( metadata == null ) {
- metadata = new BeanMetaDataImpl<T>( beanClass );
+ metadata = new BeanMetaDataImpl<T>( beanClass, builtinConstraints );
metadataProviders.put( beanClass, metadata );
}
return metadata;
Modified: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/util/ReflectionHelper.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/util/ReflectionHelper.java 2009-02-02 15:43:25 UTC (rev 15854)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/util/ReflectionHelper.java 2009-02-02 15:50:32 UTC (rev 15855)
@@ -18,7 +18,6 @@
package org.hibernate.validation.util;
import java.beans.Introspector;
-import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Field;
@@ -30,16 +29,13 @@
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.WildcardType;
-import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
-import java.util.Properties;
import javax.validation.Constraint;
-import javax.validation.ConstraintValidator;
import javax.validation.ValidationException;
import org.slf4j.Logger;
@@ -52,46 +48,14 @@
public class ReflectionHelper {
private static final Logger log = LoggerFactory.make();
- private static final Properties builtInConstraints = new Properties();
- static {
- URL url = ReflectionHelper.class.getResource( "/org/hibernate/validation/BuiltinConstraintDefinitions.properties" );
- try {
- builtInConstraints.load( url.openStream() );
- }
- catch ( IOException e ) {
- throw new ValidationException( "Unable to load defined builtin constraint definitions." );
- }
- }
-
/**
* Private constructor in order to avoid instantiation.
*/
private ReflectionHelper() {
}
- @SuppressWarnings( "unchecked")
- //FIXME do make it truely multivalidators
- //FIXME don't rely on properties files, what's the point
- public static Class<? extends ConstraintValidator<?,?>>[] getBuiltInConstraints(Annotation annotation) {
- Class constraint = null;
- String annotationType = annotation.annotationType().getName();
- if ( builtInConstraints.containsKey( annotationType ) ) {
- String constraintImplClassName = null;
- try {
- constraintImplClassName = builtInConstraints.getProperty( annotationType );
- constraint = Class.forName( constraintImplClassName );
- }
- catch ( ClassNotFoundException e ) {
- throw new ValidationException(
- "Unable to load " + constraintImplClassName + " as default implementation for " + annotationType
- );
- }
- }
- return new Class[] {constraint};
- }
-
/**
* Checks whether the given annotation is a builtin constraint annotation defined as defined by the specs.
*
Deleted: validator/trunk/hibernate-validator/src/main/resources/org/hibernate/validation/BuiltinConstraintDefinitions.properties
===================================================================
--- validator/trunk/hibernate-validator/src/main/resources/org/hibernate/validation/BuiltinConstraintDefinitions.properties 2009-02-02 15:43:25 UTC (rev 15854)
+++ validator/trunk/hibernate-validator/src/main/resources/org/hibernate/validation/BuiltinConstraintDefinitions.properties 2009-02-02 15:50:32 UTC (rev 15855)
@@ -1,3 +0,0 @@
-# $Id$
-javax.validation.constraints.NotNull=org.hibernate.validation.constraints.NotNullConstraintValidator
-javax.validation.constraints.Size=org.hibernate.validation.constraints.SizeConstraintValidator
\ No newline at end of file
Modified: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/ResourceBundleMessageInterpolatorTest.java
===================================================================
--- validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/ResourceBundleMessageInterpolatorTest.java 2009-02-02 15:43:25 UTC (rev 15854)
+++ validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/ResourceBundleMessageInterpolatorTest.java 2009-02-02 15:50:32 UTC (rev 15855)
@@ -32,8 +32,6 @@
import org.hibernate.validation.util.annotationfactory.AnnotationDescriptor;
import org.hibernate.validation.util.annotationfactory.AnnotationFactory;
-import org.hibernate.validation.engine.ResourceBundleMessageInterpolator;
-import org.hibernate.validation.engine.ConstraintDescriptorImpl;
/**
* Tests for message resolution.
@@ -59,55 +57,63 @@
@Test
public void testSuccessfulInterpolation() {
- ConstraintDescriptorImpl desciptor = new ConstraintDescriptorImpl( notNull, new Class<?>[] { } );
+ ConstraintDescriptorImpl descriptor = new ConstraintDescriptorImpl(
+ notNull, new Class<?>[] { }, new BuiltinConstraints()
+ );
String expected = "replacement worked";
- String actual = interpolator.interpolate( "{foo}", desciptor, null );
+ String actual = interpolator.interpolate( "{foo}", descriptor, null );
assertEquals( "Wrong substitution", expected, actual );
expected = "replacement worked replacement worked";
- actual = interpolator.interpolate( "{foo} {foo}", desciptor, null );
+ actual = interpolator.interpolate( "{foo} {foo}", descriptor, null );
assertEquals( "Wrong substitution", expected, actual );
expected = "This replacement worked just fine";
- actual = interpolator.interpolate( "This {foo} just fine", desciptor, null );
+ actual = interpolator.interpolate( "This {foo} just fine", descriptor, null );
assertEquals( "Wrong substitution", expected, actual );
expected = "{} { replacement worked }";
- actual = interpolator.interpolate( "{} { {foo} }", desciptor, null );
+ actual = interpolator.interpolate( "{} { {foo} }", descriptor, null );
assertEquals( "Wrong substitution", expected, actual );
}
@Test
public void testUnSuccessfulInterpolation() {
- ConstraintDescriptorImpl desciptor = new ConstraintDescriptorImpl( notNull, new Class<?>[] { } );
+ ConstraintDescriptorImpl descriptor = new ConstraintDescriptorImpl(
+ notNull, new Class<?>[] { }, new BuiltinConstraints()
+ );
String expected = "foo"; // missing {}
- String actual = interpolator.interpolate( "foo", desciptor, null );
+ String actual = interpolator.interpolate( "foo", descriptor, null );
assertEquals( "Wrong substitution", expected, actual );
expected = "#{foo {}";
- actual = interpolator.interpolate( "#{foo {}", desciptor, null );
+ actual = interpolator.interpolate( "#{foo {}", descriptor, null );
assertEquals( "Wrong substitution", expected, actual );
}
@Test
public void testUnkownTokenInterpolation() {
- ConstraintDescriptorImpl desciptor = new ConstraintDescriptorImpl( notNull, new Class<?>[] { } );
+ ConstraintDescriptorImpl descriptor = new ConstraintDescriptorImpl(
+ notNull, new Class<?>[] { }, new BuiltinConstraints()
+ );
String expected = "{bar}"; // unkown token {}
- String actual = interpolator.interpolate( "{bar}", desciptor, null );
+ String actual = interpolator.interpolate( "{bar}", descriptor, null );
assertEquals( "Wrong substitution", expected, actual );
}
@Test
public void testDefaultInterpolation() {
- ConstraintDescriptorImpl desciptor = new ConstraintDescriptorImpl( notNull, new Class<?>[] { } );
+ ConstraintDescriptorImpl descriptor = new ConstraintDescriptorImpl(
+ notNull, new Class<?>[] { }, new BuiltinConstraints()
+ );
String expected = "may not be null";
- String actual = interpolator.interpolate( notNull.message(), desciptor, null );
+ String actual = interpolator.interpolate( notNull.message(), descriptor, null );
assertEquals( "Wrong substitution", expected, actual );
- desciptor = new ConstraintDescriptorImpl( size, new Class<?>[] { } );
+ descriptor = new ConstraintDescriptorImpl( size, new Class<?>[] { }, new BuiltinConstraints() );
expected = "size must be between -2147483648 and 2147483647"; // unkown token {}
- actual = interpolator.interpolate( size.message(), desciptor, null );
+ actual = interpolator.interpolate( size.message(), descriptor, null );
assertEquals( "Wrong substitution", expected, actual );
}
Modified: validator/trunk/validation-api/src/main/java/javax/validation/ConstraintDescriptor.java
===================================================================
--- validator/trunk/validation-api/src/main/java/javax/validation/ConstraintDescriptor.java 2009-02-02 15:43:25 UTC (rev 15854)
+++ validator/trunk/validation-api/src/main/java/javax/validation/ConstraintDescriptor.java 2009-02-02 15:50:32 UTC (rev 15855)
@@ -18,63 +18,63 @@
package javax.validation;
import java.lang.annotation.Annotation;
+import java.util.List;
import java.util.Map;
import java.util.Set;
-import java.util.List;
+/**
+ * Describes a single constraint and its composing constraints.
+ *
+ * @author Emmanuel Bernard
+ * @author Hardy Ferentschik
+ */
+public interface ConstraintDescriptor {
/**
- * Describes a single constraint and its composing constraints.
+ * Returns the annotation describing the constraint declaration.
+ * If a composing constraint, parameter values are reflecting
+ * the overridden parameters from the main constraint
*
- * @author Emmanuel Bernard
- * @author Hardy Ferentschik
+ * @return The annotation for this constraint.
*/
- public interface ConstraintDescriptor {
- /**
- * Returns the annotation describing the constraint declaration.
- * If a composing constraint, parameter values are reflecting
- * the overridden parameters from the main constraint
- *
- * @return The annotation for this constraint.
- */
- Annotation getAnnotation();
+ Annotation getAnnotation();
- /**
- * @return The groups the constraint is applied on.
- */
- Set<Class<?>> getGroups();
+ /**
+ * @return The groups the constraint is applied on.
+ */
+ Set<Class<?>> getGroups();
- /**
- * list of the constraint validation implementation classes
- *
- * @return list of the constraint validation implementation classes
- */
- List<Class<? extends ConstraintValidator<?,?>>>
- getConstraintValidatorClasses();
+ /**
+ * Immutable list of the constraint validation implementation classes.
+ *
+ * @return list of the constraint validation implementation classes.
+ */
+ List<Class<? extends ConstraintValidator<?, ?>>>
+ getConstraintValidatorClasses();
- /**
- * Returns a map containing the annotation parameter names as keys and the
- * annotation parameter values as value.
- * If this constraint is used as part of a composed constraint, parameter
- * values are reflecting the overridden parameters from the main constraint.
- *
- * @return Returns a map containing the annotation paramter names as keys
- * and the annotation parameter values as value.
- */
- Map<String, Object> getParameters();
+ /**
+ * Returns a map containing the annotation parameter names as keys and the
+ * annotation parameter values as value.
+ * If this constraint is used as part of a composed constraint, parameter
+ * values are reflecting the overridden parameters from the main constraint.
+ *
+ * @return Returns a map containing the annotation paramter names as keys
+ * and the annotation parameter values as value.
+ */
+ Map<String, Object> getParameters();
- /**
- * Return a set of composing <code>ConstraintDescriptor</code>s where each
- * descriptor describes a composing constraint. <code>ConstraintDescriptor</code>
- * instances of composing constraints reflect overridden parameter values in
- * {@link #getParameters()} and {@link #getAnnotation()}.
- *
- * @return a set of <code>ConstraintDescriptor<code> objects or an empty set
- * in case there are no composing constraints.
- */
- Set<ConstraintDescriptor> getComposingConstraints();
+ /**
+ * Return a set of composing <code>ConstraintDescriptor</code>s where each
+ * descriptor describes a composing constraint. <code>ConstraintDescriptor</code>
+ * instances of composing constraints reflect overridden parameter values in
+ * {@link #getParameters()} and {@link #getAnnotation()}.
+ *
+ * @return a set of <code>ConstraintDescriptor<code> objects or an empty set
+ * in case there are no composing constraints.
+ */
+ Set<ConstraintDescriptor> getComposingConstraints();
- /**
- * @return true if the constraint is annotated with @ReportAsViolationFromCompositeConstraint
- */
- boolean isReportAsViolationFromCompositeConstraint();
- }
\ No newline at end of file
+ /**
+ * @return true if the constraint is annotated with @ReportAsViolationFromCompositeConstraint
+ */
+ boolean isReportAsViolationFromCompositeConstraint();
+}
\ No newline at end of file
[View Less]
16 years
Hibernate SVN: r15854 - in validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation: engine and 1 other directory.
by hibernate-commits@lists.jboss.org
Author: hardy.ferentschik
Date: 2009-02-02 10:43:25 -0500 (Mon, 02 Feb 2009)
New Revision: 15854
Modified:
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/bootstrap/ValidationTest.java
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/ConstraintCompositionTest.java
Log:
Changes due to renamed classes
Modified: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/bootstrap/ValidationTest.java
================…
[View More]===================================================
--- validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/bootstrap/ValidationTest.java 2009-02-02 15:42:10 UTC (rev 15853)
+++ validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/bootstrap/ValidationTest.java 2009-02-02 15:43:25 UTC (rev 15854)
@@ -44,7 +44,7 @@
import org.hibernate.validation.engine.HibernateValidatorConfiguration;
import org.hibernate.validation.engine.HibernateValidationProvider;
-import org.hibernate.validation.constraints.NotNullConstraintValidator;
+import org.hibernate.validation.constraints.NotNullValidator;
import org.hibernate.validation.eg.Customer;
import org.hibernate.validation.engine.ConfigurationImpl;
import org.hibernate.validation.engine.ConstraintValidatorFactoryImpl;
@@ -154,7 +154,7 @@
new ConstraintValidatorFactory() {
public <T extends ConstraintValidator<?, ?>> T getInstance(Class<T> key) {
- if ( key == NotNullConstraintValidator.class ) {
+ if ( key == NotNullValidator.class ) {
return ( T ) new BadlyBehavedNotNullConstraintValidator();
}
return new ConstraintValidatorFactoryImpl().getInstance( key );
@@ -245,7 +245,7 @@
assertTrue( factory instanceof ValidatorFactoryImpl );
}
- class BadlyBehavedNotNullConstraintValidator extends NotNullConstraintValidator {
+ class BadlyBehavedNotNullConstraintValidator extends NotNullValidator {
@Override
public boolean isValid(Object object, ConstraintValidatorContext constraintValidatorContext) {
return true;
Modified: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/ConstraintCompositionTest.java
===================================================================
--- validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/ConstraintCompositionTest.java 2009-02-02 15:42:10 UTC (rev 15853)
+++ validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/ConstraintCompositionTest.java 2009-02-02 15:43:25 UTC (rev 15854)
@@ -24,9 +24,9 @@
import static org.junit.Assert.fail;
import org.junit.Test;
-import org.hibernate.validation.constraints.NotNullConstraintValidator;
+import org.hibernate.validation.constraints.NotNullValidator;
import org.hibernate.validation.constraints.PatternValidator;
-import org.hibernate.validation.constraints.SizeConstraintValidator;
+import org.hibernate.validation.constraints.SizeValidator;
import org.hibernate.validation.constraints.composition.GermanZipcodeConstraintValidator;
import org.hibernate.validation.eg.FrenchAddress;
import org.hibernate.validation.eg.GermanAddress;
@@ -54,7 +54,7 @@
assertConstraintViolation(
constraintViolations.iterator().next(),
"may not be null",
- NotNullConstraintValidator.class,
+ NotNullValidator.class,
FrenchAddress.class,
null,
"zipCode"
@@ -69,7 +69,7 @@
assertConstraintViolation(
violation,
"A french zip code has a length of 5",
- SizeConstraintValidator.class,
+ SizeValidator.class,
FrenchAddress.class,
"abc",
"zipCode"
@@ -109,7 +109,7 @@
assertConstraintViolation(
violation,
"A french zip code has a length of 5",
- SizeConstraintValidator.class,
+ SizeValidator.class,
FrenchAddress.class,
"123",
"zipCode"
[View Less]
16 years
Hibernate SVN: r15853 - validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints.
by hibernate-commits@lists.jboss.org
Author: hardy.ferentschik
Date: 2009-02-02 10:42:10 -0500 (Mon, 02 Feb 2009)
New Revision: 15853
Added:
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/NotNullValidator.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/NullValidator.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/PastValidatorForCalendar.java
validator/trunk/hibernate-validator/src/main/java/…
[View More]org/hibernate/validation/constraints/PastValidatorForDate.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/SizeValidator.java
Removed:
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/NotNullConstraintValidator.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/NullConstraintValidator.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/PastConstraintCalendarValidator.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/PastConstraintDateValidator.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/SizeConstraintValidator.java
Log:
Renamed classes to have a consistent naming scheme
Deleted: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/NotNullConstraintValidator.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/NotNullConstraintValidator.java 2009-02-02 15:41:31 UTC (rev 15852)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/NotNullConstraintValidator.java 2009-02-02 15:42:10 UTC (rev 15853)
@@ -1,37 +0,0 @@
-// $Id$
-/*
-* JBoss, Home of Professional Open Source
-* Copyright 2008, Red Hat Middleware LLC, and individual contributors
-* by the @authors tag. See the copyright.txt in the distribution for a
-* full listing of individual contributors.
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-* http://www.apache.org/licenses/LICENSE-2.0
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-package org.hibernate.validation.constraints;
-
-import javax.validation.ConstraintValidator;
-import javax.validation.ConstraintValidatorContext;
-import javax.validation.constraints.NotNull;
-
-/**
- * Validate that the object is not <code>null</code>.
- *
- * @author Emmanuel Bernard
- */
-public class NotNullConstraintValidator implements ConstraintValidator<NotNull, Object> {
-
- public void initialize(NotNull parameters) {
- }
-
- public boolean isValid(Object object, ConstraintValidatorContext constraintValidatorContext) {
- return object != null;
- }
-}
Copied: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/NotNullValidator.java (from rev 15848, validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/NotNullConstraintValidator.java)
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/NotNullValidator.java (rev 0)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/NotNullValidator.java 2009-02-02 15:42:10 UTC (rev 15853)
@@ -0,0 +1,37 @@
+// $Id$
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, and individual contributors
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+* http://www.apache.org/licenses/LICENSE-2.0
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+package org.hibernate.validation.constraints;
+
+import javax.validation.ConstraintValidator;
+import javax.validation.ConstraintValidatorContext;
+import javax.validation.constraints.NotNull;
+
+/**
+ * Validate that the object is not <code>null</code>.
+ *
+ * @author Emmanuel Bernard
+ */
+public class NotNullValidator implements ConstraintValidator<NotNull, Object> {
+
+ public void initialize(NotNull parameters) {
+ }
+
+ public boolean isValid(Object object, ConstraintValidatorContext constraintValidatorContext) {
+ return object != null;
+ }
+}
Property changes on: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/NotNullValidator.java
___________________________________________________________________
Name: svn:keywords
+ Id
Deleted: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/NullConstraintValidator.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/NullConstraintValidator.java 2009-02-02 15:41:31 UTC (rev 15852)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/NullConstraintValidator.java 2009-02-02 15:42:10 UTC (rev 15853)
@@ -1,38 +0,0 @@
-// $Id
-/*
-* JBoss, Home of Professional Open Source
-* Copyright 2008, Red Hat Middleware LLC, and individual contributors
-* by the @authors tag. See the copyright.txt in the distribution for a
-* full listing of individual contributors.
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-* http://www.apache.org/licenses/LICENSE-2.0
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-package org.hibernate.validation.constraints;
-
-import javax.validation.ConstraintValidator;
-import javax.validation.ConstraintValidatorContext;
-import javax.validation.constraints.Null;
-
-/**
- * Validate that the object is <code>null</code>
- *
- * @author Alaa Nassef
- */
-public class NullConstraintValidator implements ConstraintValidator<Null, Object> {
-
- public void initialize(Null constraintAnnotation) {
- }
-
- public boolean isValid(Object object, ConstraintValidatorContext constraintValidatorContext) {
- return object == null;
- }
-
-}
Copied: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/NullValidator.java (from rev 15848, validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/NullConstraintValidator.java)
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/NullValidator.java (rev 0)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/NullValidator.java 2009-02-02 15:42:10 UTC (rev 15853)
@@ -0,0 +1,38 @@
+// $Id:$
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, and individual contributors
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+* http://www.apache.org/licenses/LICENSE-2.0
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+package org.hibernate.validation.constraints;
+
+import javax.validation.ConstraintValidator;
+import javax.validation.ConstraintValidatorContext;
+import javax.validation.constraints.Null;
+
+/**
+ * Validate that the object is <code>null</code>
+ *
+ * @author Alaa Nassef
+ */
+public class NullValidator implements ConstraintValidator<Null, Object> {
+
+ public void initialize(Null constraintAnnotation) {
+ }
+
+ public boolean isValid(Object object, ConstraintValidatorContext constraintValidatorContext) {
+ return object == null;
+ }
+
+}
Property changes on: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/NullValidator.java
___________________________________________________________________
Name: svn:keywords
+ Id
Name: svn:eol-style
+ native
Deleted: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/PastConstraintCalendarValidator.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/PastConstraintCalendarValidator.java 2009-02-02 15:41:31 UTC (rev 15852)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/PastConstraintCalendarValidator.java 2009-02-02 15:42:10 UTC (rev 15853)
@@ -1,43 +0,0 @@
-// $Id
-/*
-* JBoss, Home of Professional Open Source
-* Copyright 2008, Red Hat Middleware LLC, and individual contributors
-* by the @authors tag. See the copyright.txt in the distribution for a
-* full listing of individual contributors.
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-* http://www.apache.org/licenses/LICENSE-2.0
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-package org.hibernate.validation.constraints;
-
-import java.util.Calendar;
-import javax.validation.ConstraintValidator;
-import javax.validation.ConstraintValidatorContext;
-import javax.validation.constraints.Past;
-
-/**
- * Check that the <code>java.util.Calendar</code> passed to be validated is in the
- * past.
- *
- * @author Alaa Nassef
- */
-public class PastConstraintCalendarValidator implements ConstraintValidator<Past, Calendar> {
-
- public void initialize(Past constraintAnnotation) {
- }
-
- public boolean isValid(Calendar cal, ConstraintValidatorContext constraintValidatorContext) {
- //null values are valid
- if ( cal == null ) {
- return true;
- }
- return cal.before( Calendar.getInstance() );
- }
-}
Deleted: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/PastConstraintDateValidator.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/PastConstraintDateValidator.java 2009-02-02 15:41:31 UTC (rev 15852)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/PastConstraintDateValidator.java 2009-02-02 15:42:10 UTC (rev 15853)
@@ -1,43 +0,0 @@
-// $Id
-/*
-* JBoss, Home of Professional Open Source
-* Copyright 2008, Red Hat Middleware LLC, and individual contributors
-* by the @authors tag. See the copyright.txt in the distribution for a
-* full listing of individual contributors.
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-* http://www.apache.org/licenses/LICENSE-2.0
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-package org.hibernate.validation.constraints;
-
-import java.util.Date;
-import javax.validation.ConstraintValidator;
-import javax.validation.ConstraintValidatorContext;
-import javax.validation.constraints.Past;
-
-/**
- * Check that the <code>java.util.Date</code> passed to be validated is in the
- * past.
- *
- * @author Alaa Nassef
- */
-public class PastConstraintDateValidator implements ConstraintValidator<Past, Date> {
-
- public void initialize(Past constraintAnnotation) {
- }
-
- public boolean isValid(Date date, ConstraintValidatorContext constraintValidatorContext) {
- //null values are valid
- if ( date == null ) {
- return true;
- }
- return date.before( new Date() );
- }
-}
Copied: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/PastValidatorForCalendar.java (from rev 15848, validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/PastConstraintCalendarValidator.java)
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/PastValidatorForCalendar.java (rev 0)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/PastValidatorForCalendar.java 2009-02-02 15:42:10 UTC (rev 15853)
@@ -0,0 +1,43 @@
+// $Id:$
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, and individual contributors
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+* http://www.apache.org/licenses/LICENSE-2.0
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+package org.hibernate.validation.constraints;
+
+import java.util.Calendar;
+import javax.validation.ConstraintValidator;
+import javax.validation.ConstraintValidatorContext;
+import javax.validation.constraints.Past;
+
+/**
+ * Check that the <code>java.util.Calendar</code> passed to be validated is in the
+ * past.
+ *
+ * @author Alaa Nassef
+ */
+public class PastValidatorForCalendar implements ConstraintValidator<Past, Calendar> {
+
+ public void initialize(Past constraintAnnotation) {
+ }
+
+ public boolean isValid(Calendar cal, ConstraintValidatorContext constraintValidatorContext) {
+ //null values are valid
+ if ( cal == null ) {
+ return true;
+ }
+ return cal.before( Calendar.getInstance() );
+ }
+}
Property changes on: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/PastValidatorForCalendar.java
___________________________________________________________________
Name: svn:keywords
+ Id
Name: svn:eol-style
+ native
Copied: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/PastValidatorForDate.java (from rev 15848, validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/PastConstraintDateValidator.java)
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/PastValidatorForDate.java (rev 0)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/PastValidatorForDate.java 2009-02-02 15:42:10 UTC (rev 15853)
@@ -0,0 +1,43 @@
+// $Id:$
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, and individual contributors
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+* http://www.apache.org/licenses/LICENSE-2.0
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+package org.hibernate.validation.constraints;
+
+import java.util.Date;
+import javax.validation.ConstraintValidator;
+import javax.validation.ConstraintValidatorContext;
+import javax.validation.constraints.Past;
+
+/**
+ * Check that the <code>java.util.Date</code> passed to be validated is in the
+ * past.
+ *
+ * @author Alaa Nassef
+ */
+public class PastValidatorForDate implements ConstraintValidator<Past, Date> {
+
+ public void initialize(Past constraintAnnotation) {
+ }
+
+ public boolean isValid(Date date, ConstraintValidatorContext constraintValidatorContext) {
+ //null values are valid
+ if ( date == null ) {
+ return true;
+ }
+ return date.before( new Date() );
+ }
+}
Property changes on: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/PastValidatorForDate.java
___________________________________________________________________
Name: svn:keywords
+ Id
Name: svn:eol-style
+ native
Deleted: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/SizeConstraintValidator.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/SizeConstraintValidator.java 2009-02-02 15:41:31 UTC (rev 15852)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/SizeConstraintValidator.java 2009-02-02 15:42:10 UTC (rev 15853)
@@ -1,68 +0,0 @@
-// $Id$
-/*
-* JBoss, Home of Professional Open Source
-* Copyright 2008, Red Hat Middleware LLC, and individual contributors
-* by the @authors tag. See the copyright.txt in the distribution for a
-* full listing of individual contributors.
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-* http://www.apache.org/licenses/LICENSE-2.0
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-package org.hibernate.validation.constraints;
-
-import java.lang.reflect.Array;
-import java.util.Collection;
-import javax.validation.ConstraintValidator;
-import javax.validation.ConstraintValidatorContext;
-import javax.validation.constraints.Size;
-
-/**
- * Check that a string's length is between min and max.
- *
- * @author Emmanuel Bernard
- * @author Gavin King
- */
-//FIXME split into several type-safe validators
-public class SizeConstraintValidator implements ConstraintValidator<Size, Object> {
- private int min;
- private int max;
-
- public void initialize(Size parameters) {
- min = parameters.min();
- max = parameters.max();
- }
-
- /**
- * {@inheritDoc}
- */
- public boolean isValid(Object value, ConstraintValidatorContext constraintValidatorContext) {
- if ( value == null ) {
- return true;
- }
-
- int size;
- if ( value instanceof String ) {
- String string = ( String ) value;
- size = string.length();
-
- }
- else if ( value instanceof Collection ) {
- Collection collection = ( Collection ) value;
- size = collection.size();
- }
- else if ( value instanceof Array ) {
- size = Array.getLength( value );
- }
- else {
- throw new IllegalArgumentException( "Expected String type." );
- }
- return size >= min && size <= max;
- }
-}
Copied: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/SizeValidator.java (from rev 15848, validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/SizeConstraintValidator.java)
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/SizeValidator.java (rev 0)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/SizeValidator.java 2009-02-02 15:42:10 UTC (rev 15853)
@@ -0,0 +1,68 @@
+// $Id$
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, and individual contributors
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+* http://www.apache.org/licenses/LICENSE-2.0
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+package org.hibernate.validation.constraints;
+
+import java.lang.reflect.Array;
+import java.util.Collection;
+import javax.validation.ConstraintValidator;
+import javax.validation.ConstraintValidatorContext;
+import javax.validation.constraints.Size;
+
+/**
+ * Check that a string's length is between min and max.
+ *
+ * @author Emmanuel Bernard
+ * @author Gavin King
+ */
+//FIXME split into several type-safe validators
+public class SizeValidator implements ConstraintValidator<Size, Object> {
+ private int min;
+ private int max;
+
+ public void initialize(Size parameters) {
+ min = parameters.min();
+ max = parameters.max();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean isValid(Object value, ConstraintValidatorContext constraintValidatorContext) {
+ if ( value == null ) {
+ return true;
+ }
+
+ int size;
+ if ( value instanceof String ) {
+ String string = ( String ) value;
+ size = string.length();
+
+ }
+ else if ( value instanceof Collection ) {
+ Collection collection = ( Collection ) value;
+ size = collection.size();
+ }
+ else if ( value instanceof Array ) {
+ size = Array.getLength( value );
+ }
+ else {
+ throw new IllegalArgumentException( "Expected String type." );
+ }
+ return size >= min && size <= max;
+ }
+}
Property changes on: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/SizeValidator.java
___________________________________________________________________
Name: svn:keywords
+ Id
[View Less]
16 years