[hibernate-commits] Hibernate SVN: r15869 - in core/branches/Branch_3_3/core/src/main/java/org/hibernate: hql/ast/tree and 2 other directories.

hibernate-commits at lists.jboss.org hibernate-commits at lists.jboss.org
Tue Feb 3 15:37:02 EST 2009


Author: steve.ebersole at jboss.com
Date: 2009-02-03 15:37:01 -0500 (Tue, 03 Feb 2009)
New Revision: 15869

Added:
   core/branches/Branch_3_3/core/src/main/java/org/hibernate/hql/ast/util/DisplayableNode.java
Modified:
   core/branches/Branch_3_3/core/src/main/java/org/hibernate/hql/ast/HqlSqlWalker.java
   core/branches/Branch_3_3/core/src/main/java/org/hibernate/hql/ast/QueryTranslatorImpl.java
   core/branches/Branch_3_3/core/src/main/java/org/hibernate/hql/ast/tree/AbstractStatement.java
   core/branches/Branch_3_3/core/src/main/java/org/hibernate/hql/ast/tree/BinaryArithmeticOperatorNode.java
   core/branches/Branch_3_3/core/src/main/java/org/hibernate/hql/ast/tree/CollectionFunction.java
   core/branches/Branch_3_3/core/src/main/java/org/hibernate/hql/ast/tree/DotNode.java
   core/branches/Branch_3_3/core/src/main/java/org/hibernate/hql/ast/tree/FromClause.java
   core/branches/Branch_3_3/core/src/main/java/org/hibernate/hql/ast/tree/FromElement.java
   core/branches/Branch_3_3/core/src/main/java/org/hibernate/hql/ast/tree/IntoClause.java
   core/branches/Branch_3_3/core/src/main/java/org/hibernate/hql/ast/tree/ParameterNode.java
   core/branches/Branch_3_3/core/src/main/java/org/hibernate/hql/ast/util/ASTPrinter.java
   core/branches/Branch_3_3/core/src/main/java/org/hibernate/hql/ast/util/ASTUtil.java
   core/branches/Branch_3_3/core/src/main/java/org/hibernate/util/StringHelper.java
Log:
HHH-3751 : Antlr tree parser tracing

Modified: core/branches/Branch_3_3/core/src/main/java/org/hibernate/hql/ast/HqlSqlWalker.java
===================================================================
--- core/branches/Branch_3_3/core/src/main/java/org/hibernate/hql/ast/HqlSqlWalker.java	2009-02-03 18:30:11 UTC (rev 15868)
+++ core/branches/Branch_3_3/core/src/main/java/org/hibernate/hql/ast/HqlSqlWalker.java	2009-02-03 20:37:01 UTC (rev 15869)
@@ -94,6 +94,7 @@
 import org.hibernate.type.DbTimestampType;
 import org.hibernate.usertype.UserVersionType;
 import org.hibernate.util.ArrayHelper;
+import org.hibernate.util.StringHelper;
 
 import antlr.ASTFactory;
 import antlr.RecognitionException;
@@ -169,6 +170,40 @@
 	}
 
 
+	// handle trace logging ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+    private int traceDepth = 0;
+
+	public 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 );
+	}
+
+	private String buildTraceNodeName(AST tree) {
+		return tree == null
+				? "???"
+				: tree.getText() + " [" + printer.getTokenTypeName( tree.getType() ) + "]";
+	}
+
+	public void traceOut(String ruleName, AST tree) {
+		if ( inputState.guessing > 0 ) {
+			return;
+		}
+		String prefix = "<-" + StringHelper.repeat( '-', (--traceDepth * 2) ) + " ";
+		trace( prefix + ruleName );
+	}
+
+	private void trace(String msg) {
+		log.trace( msg );
+	}
+
+
+	// semantic action handling ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
 	protected void prepareFromClauseInputTree(AST fromClauseInput) {
 		if ( !isSubQuery() ) {
 //			// inject param specifications to account for dynamic filter param values
@@ -207,7 +242,7 @@
 
 				String collectionElementEntityName = persister.getElementPersister().getEntityName();
 				ASTFactory inputAstFactory = hqlParser.getASTFactory();
-				AST fromElement = ASTUtil.create( inputAstFactory, HqlTokenTypes.FILTER_ENTITY, collectionElementEntityName );
+				AST fromElement = inputAstFactory.create( FILTER_ENTITY, collectionElementEntityName );
 				ASTUtil.createSibling( inputAstFactory, HqlTokenTypes.ALIAS, "this", fromElement );
 				fromClauseInput.addChild( fromElement );
 				// Show the modified AST.

Modified: core/branches/Branch_3_3/core/src/main/java/org/hibernate/hql/ast/QueryTranslatorImpl.java
===================================================================
--- core/branches/Branch_3_3/core/src/main/java/org/hibernate/hql/ast/QueryTranslatorImpl.java	2009-02-03 18:30:11 UTC (rev 15868)
+++ core/branches/Branch_3_3/core/src/main/java/org/hibernate/hql/ast/QueryTranslatorImpl.java	2009-02-03 20:37:01 UTC (rev 15869)
@@ -287,8 +287,7 @@
 
 	void showHqlAst(AST hqlAst) {
 		if ( AST_LOG.isDebugEnabled() ) {
-			ASTPrinter printer = new ASTPrinter( HqlTokenTypes.class );
-			printer.setShowClassNames( false ); // The class names aren't interesting in the first tree.
+			ASTPrinter printer = new ASTPrinter( HqlTokenTypes.class, false );
 			AST_LOG.debug( printer.showAsString( hqlAst, "--- HQL AST ---" ) );
 		}
 	}

Modified: core/branches/Branch_3_3/core/src/main/java/org/hibernate/hql/ast/tree/AbstractStatement.java
===================================================================
--- core/branches/Branch_3_3/core/src/main/java/org/hibernate/hql/ast/tree/AbstractStatement.java	2009-02-03 18:30:11 UTC (rev 15868)
+++ core/branches/Branch_3_3/core/src/main/java/org/hibernate/hql/ast/tree/AbstractStatement.java	2009-02-03 20:37:01 UTC (rev 15869)
@@ -26,6 +26,8 @@
 
 import java.util.Iterator;
 
+import org.hibernate.hql.ast.util.DisplayableNode;
+
 /**
  * Convenience implementation of Statement to centralize common functionality.
  *

Modified: core/branches/Branch_3_3/core/src/main/java/org/hibernate/hql/ast/tree/BinaryArithmeticOperatorNode.java
===================================================================
--- core/branches/Branch_3_3/core/src/main/java/org/hibernate/hql/ast/tree/BinaryArithmeticOperatorNode.java	2009-02-03 18:30:11 UTC (rev 15868)
+++ core/branches/Branch_3_3/core/src/main/java/org/hibernate/hql/ast/tree/BinaryArithmeticOperatorNode.java	2009-02-03 20:37:01 UTC (rev 15869)
@@ -26,6 +26,7 @@
 
 import org.hibernate.Hibernate;
 import org.hibernate.hql.ast.util.ColumnHelper;
+import org.hibernate.hql.ast.util.DisplayableNode;
 import org.hibernate.hql.antlr.HqlSqlTokenTypes;
 import org.hibernate.type.Type;
 

Modified: core/branches/Branch_3_3/core/src/main/java/org/hibernate/hql/ast/tree/CollectionFunction.java
===================================================================
--- core/branches/Branch_3_3/core/src/main/java/org/hibernate/hql/ast/tree/CollectionFunction.java	2009-02-03 18:30:11 UTC (rev 15868)
+++ core/branches/Branch_3_3/core/src/main/java/org/hibernate/hql/ast/tree/CollectionFunction.java	2009-02-03 20:37:01 UTC (rev 15869)
@@ -27,6 +27,8 @@
 import antlr.SemanticException;
 import antlr.collections.AST;
 
+import org.hibernate.hql.ast.util.DisplayableNode;
+
 /**
  * Represents 'elements()' or 'indices()'.
  *

Modified: core/branches/Branch_3_3/core/src/main/java/org/hibernate/hql/ast/tree/DotNode.java
===================================================================
--- core/branches/Branch_3_3/core/src/main/java/org/hibernate/hql/ast/tree/DotNode.java	2009-02-03 18:30:11 UTC (rev 15868)
+++ core/branches/Branch_3_3/core/src/main/java/org/hibernate/hql/ast/tree/DotNode.java	2009-02-03 20:37:01 UTC (rev 15869)
@@ -140,7 +140,7 @@
 		StringBuffer buf = new StringBuffer();
 		FromElement fromElement = getFromElement();
 		buf.append( "{propertyName=" ).append( propertyName );
-		buf.append( ",dereferenceType=" ).append( ASTPrinter.getConstantName( getClass(), dereferenceType ) );
+		buf.append( ",dereferenceType=" ).append( getWalker().getASTPrinter().getTokenTypeName( dereferenceType ) );
 		buf.append( ",propertyPath=" ).append( propertyPath );
 		buf.append( ",path=" ).append( getPath() );
 		if ( fromElement != null ) {

Modified: core/branches/Branch_3_3/core/src/main/java/org/hibernate/hql/ast/tree/FromClause.java
===================================================================
--- core/branches/Branch_3_3/core/src/main/java/org/hibernate/hql/ast/tree/FromClause.java	2009-02-03 18:30:11 UTC (rev 15868)
+++ core/branches/Branch_3_3/core/src/main/java/org/hibernate/hql/ast/tree/FromClause.java	2009-02-03 20:37:01 UTC (rev 15869)
@@ -37,6 +37,7 @@
 import org.hibernate.hql.antlr.HqlSqlTokenTypes;
 import org.hibernate.hql.ast.util.ASTIterator;
 import org.hibernate.hql.ast.util.ASTUtil;
+import org.hibernate.hql.ast.util.DisplayableNode;
 
 import antlr.SemanticException;
 import antlr.collections.AST;

Modified: core/branches/Branch_3_3/core/src/main/java/org/hibernate/hql/ast/tree/FromElement.java
===================================================================
--- core/branches/Branch_3_3/core/src/main/java/org/hibernate/hql/ast/tree/FromElement.java	2009-02-03 18:30:11 UTC (rev 15868)
+++ core/branches/Branch_3_3/core/src/main/java/org/hibernate/hql/ast/tree/FromElement.java	2009-02-03 20:37:01 UTC (rev 15869)
@@ -35,6 +35,7 @@
 import org.hibernate.hql.CollectionProperties;
 import org.hibernate.hql.antlr.SqlTokenTypes;
 import org.hibernate.hql.ast.util.ASTUtil;
+import org.hibernate.hql.ast.util.DisplayableNode;
 import org.hibernate.hql.ast.HqlSqlWalker;
 import org.hibernate.persister.collection.QueryableCollection;
 import org.hibernate.persister.entity.EntityPersister;

Modified: core/branches/Branch_3_3/core/src/main/java/org/hibernate/hql/ast/tree/IntoClause.java
===================================================================
--- core/branches/Branch_3_3/core/src/main/java/org/hibernate/hql/ast/tree/IntoClause.java	2009-02-03 18:30:11 UTC (rev 15868)
+++ core/branches/Branch_3_3/core/src/main/java/org/hibernate/hql/ast/tree/IntoClause.java	2009-02-03 20:37:01 UTC (rev 15869)
@@ -29,6 +29,7 @@
 import java.sql.Types;
 
 import org.hibernate.QueryException;
+import org.hibernate.hql.ast.util.DisplayableNode;
 import org.hibernate.persister.entity.Queryable;
 import org.hibernate.type.Type;
 import org.hibernate.util.ArrayHelper;

Modified: core/branches/Branch_3_3/core/src/main/java/org/hibernate/hql/ast/tree/ParameterNode.java
===================================================================
--- core/branches/Branch_3_3/core/src/main/java/org/hibernate/hql/ast/tree/ParameterNode.java	2009-02-03 18:30:11 UTC (rev 15868)
+++ core/branches/Branch_3_3/core/src/main/java/org/hibernate/hql/ast/tree/ParameterNode.java	2009-02-03 20:37:01 UTC (rev 15869)
@@ -27,6 +27,7 @@
 import org.hibernate.param.ParameterSpecification;
 import org.hibernate.type.Type;
 import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.hql.ast.util.DisplayableNode;
 
 /**
  * Implementation of ParameterNode.

Modified: core/branches/Branch_3_3/core/src/main/java/org/hibernate/hql/ast/util/ASTPrinter.java
===================================================================
--- core/branches/Branch_3_3/core/src/main/java/org/hibernate/hql/ast/util/ASTPrinter.java	2009-02-03 18:30:11 UTC (rev 15868)
+++ core/branches/Branch_3_3/core/src/main/java/org/hibernate/hql/ast/util/ASTPrinter.java	2009-02-03 20:37:01 UTC (rev 15869)
@@ -20,90 +20,76 @@
  * Free Software Foundation, Inc.
  * 51 Franklin Street, Fifth Floor
  * Boston, MA  02110-1301  USA
- *
  */
 package org.hibernate.hql.ast.util;
 
 import java.io.ByteArrayOutputStream;
 import java.io.PrintStream;
 import java.io.PrintWriter;
-import java.lang.reflect.Field;
-import java.lang.reflect.Modifier;
 import java.util.ArrayList;
-import java.util.HashMap;
 import java.util.Map;
 
-import org.hibernate.hql.ast.tree.DisplayableNode;
 import org.hibernate.util.StringHelper;
 
 import antlr.collections.AST;
 
 /**
- * An 'ASCII art' AST printer for debugging ANTLR grammars.
+ * Utility for generating pretty "ASCII art" representations of syntax trees.
  *
  * @author Joshua Davis
+ * @author Steve Ebersole
  */
 public class ASTPrinter {
-	private Map tokenTypeNamesByTokenType;
-	private Class tokenTypeConstants;
-	private boolean showClassNames = true;
+	private final Map tokenTypeNameCache;
+	private final boolean showClassNames;
 
 	/**
-	 * Constructs an org.hibernate.hql.antlr.ASTPrinter, given the class that contains the token type
-	 * constants (typically the '{grammar}TokenTypes' interface generated by
-	 * ANTLR).
+	 * Constructs a printer.
+	 * <p/>
+	 * Delegates to {@link #ASTPrinter(Class, boolean)} with {@link #isShowClassNames showClassNames} as <tt>true</tt>
 	 *
-	 * @param tokenTypeConstants The class with token type constants in it.
+	 * @param tokenTypeConstants The token types to use during printing; typically the {vocabulary}TokenTypes.java
+	 * interface generated by ANTLR.
 	 */
 	public ASTPrinter(Class tokenTypeConstants) {
-		this.tokenTypeConstants = tokenTypeConstants;
+		this( ASTUtil.generateTokenNameCache( tokenTypeConstants ), true );
 	}
 
-	/**
-	 * Returns true if the node class names will be displayed.
-	 *
-	 * @return true if the node class names will be displayed.
-	 */
-	public boolean isShowClassNames() {
-		return showClassNames;
+	public ASTPrinter(boolean showClassNames) {
+		this( ( Map ) null, showClassNames );
 	}
 
 	/**
-	 * Enables or disables AST node class name display.
+	 * Constructs a printer.
 	 *
-	 * @param showClassNames true to enable class name display, false to disable
+	 * @param tokenTypeConstants The token types to use during printing; typically the {vocabulary}TokenTypes.java
+	 * interface generated by ANTLR.
+	 * @param showClassNames Should the AST class names be shown.
 	 */
-	public void setShowClassNames(boolean showClassNames) {
-		this.showClassNames = showClassNames;
+	public ASTPrinter(Class tokenTypeConstants, boolean showClassNames) {
+		this( ASTUtil.generateTokenNameCache( tokenTypeConstants ), showClassNames );
 	}
 
-	/**
-	 * Prints the AST in 'ASCII art' tree form to the specified print stream.
-	 *
-	 * @param ast The AST to print.
-	 * @param out The print stream.
-	 */
-	private void showAst(AST ast, PrintStream out) {
-		showAst( ast, new PrintWriter( out ) );
+	private ASTPrinter(Map tokenTypeNameCache, boolean showClassNames) {
+		this.tokenTypeNameCache = tokenTypeNameCache;
+		this.showClassNames = showClassNames;
 	}
 
 	/**
-	 * Prints the AST in 'ASCII art' tree form to the specified print writer.
+	 * Getter for property 'showClassNames'.
 	 *
-	 * @param ast The AST to print.
-	 * @param pw  The print writer.
+	 * @return Value for property 'showClassNames'.
 	 */
-	public void showAst(AST ast, PrintWriter pw) {
-		ArrayList parents = new ArrayList();
-		showAst( parents, pw, ast );
-		pw.flush();
+	public boolean isShowClassNames() {
+		return showClassNames;
 	}
 
 	/**
-	 * Prints the AST in 'ASCII art' tree form into a string.
+	 * Renders the AST into 'ASCII art' form and returns that string representation.
 	 *
-	 * @param ast    The AST to display.
+	 * @param ast The AST to display.
 	 * @param header The header for the display.
+	 *
 	 * @return The AST in 'ASCII art' form, as a string.
 	 */
 	public String showAsString(AST ast, String header) {
@@ -116,53 +102,25 @@
 	}
 
 	/**
-	 * Get a single token type name in the specified set of token type constants (interface).
+	 * Prints the AST in 'ASCII art' form to the specified print stream.
 	 *
-	 * @param tokenTypeConstants Token type constants interface (e.g. HqlSqlTokenTypes.class).
-	 * @param type               The token type ( typically from ast.getType() ).
-	 * @return The token type name, *or* the integer value if the name could not be found for some reason.
+	 * @param ast The AST to print.
+	 * @param out The print stream to which the AST should be printed.
 	 */
-	public static String getConstantName(Class tokenTypeConstants, int type) {
-		String tokenTypeName = null;
-		if ( tokenTypeConstants != null ) {
-			Field[] fields = tokenTypeConstants.getFields();
-			for ( int i = 0; i < fields.length; i++ ) {
-				Field field = fields[i];
-				tokenTypeName = getTokenTypeName( field, type, true );
-				if ( tokenTypeName != null ) {
-					break;	// Stop if found.
-				}
-			} // for
-		} // if type constants were provided
-
-		// Use the integer value if no token type name was found
-		if ( tokenTypeName == null ) {
-			tokenTypeName = Integer.toString( type );
-		}
-
-		return tokenTypeName;
+	public void showAst(AST ast, PrintStream out) {
+		showAst( ast, new PrintWriter( out ) );
 	}
 
-	private static String getTokenTypeName(Field field, int type, boolean checkType) {
-		if ( Modifier.isStatic( field.getModifiers() ) ) {
-			try {
-				Object value = field.get( null );
-				if ( !checkType ) {
-					return field.getName();
-				}
-				else if ( value instanceof Integer ) {
-					Integer integer = ( Integer ) value;
-					if ( integer.intValue() == type ) {
-						return field.getName();
-					}
-				} // if value is an integer
-			} // try
-			catch ( IllegalArgumentException ignore ) {
-			}
-			catch ( IllegalAccessException ignore ) {
-			}
-		} // if the field is static
-		return null;
+	/**
+	 * Prints the AST in 'ASCII art' tree form to the specified print writer.
+	 *
+	 * @param ast The AST to print.
+	 * @param pw The print writer to which the AST should be written.
+	 */
+	public void showAst(AST ast, PrintWriter pw) {
+		ArrayList parents = new ArrayList();
+		showAst( parents, pw, ast );
+		pw.flush();
 	}
 
 	/**
@@ -172,33 +130,16 @@
 	 * @return String - The token type name from the token type constant class,
 	 *         or just the integer as a string if none exists.
 	 */
-	private String getTokenTypeName(int type) {
-		// If the class with the constants in it was not supplied, just
-		// use the integer token type as the token type name.
-		if ( tokenTypeConstants == null ) {
-			return Integer.toString( type );
+	public String getTokenTypeName(int type) {
+		final Integer typeInteger = new Integer( type );
+		String value = null;
+		if ( tokenTypeNameCache != null ) {
+			value = ( String ) tokenTypeNameCache.get( typeInteger );
 		}
-
-		// Otherwise, create a type id -> name map from the class if it
-		// hasn't already been created.
-		if ( tokenTypeNamesByTokenType == null ) {
-			Field[] fields = tokenTypeConstants.getFields();
-			tokenTypeNamesByTokenType = new HashMap();
-			String tokenTypeName = null;
-			for ( int i = 0; i < fields.length; i++ ) {
-				Field field = fields[i];
-				tokenTypeName = getTokenTypeName( field, type, false );
-				if ( tokenTypeName != null ) {
-					try {
-						tokenTypeNamesByTokenType.put( field.get( null ), field.getName() );
-					}
-					catch ( IllegalAccessException ignore ) {
-					}
-				}
-			} // for
-		} // if the map hasn't been created.
-
-		return ( String ) tokenTypeNamesByTokenType.get( new Integer( type ) );
+		if ( value == null ) {
+			value = typeInteger.toString();
+		}
+		return value;
 	}
 
 	private void showAst(ArrayList parents, PrintWriter pw, AST ast) {
@@ -242,7 +183,7 @@
 
 	public String nodeToString(AST ast, boolean showClassName) {
 		if ( ast == null ) {
-			return "{null}";
+			return "{node:null}";
 		}
 		StringBuffer buf = new StringBuffer();
 		buf.append( "[" ).append( getTokenTypeName( ast.getType() ) ).append( "] " );
@@ -252,15 +193,17 @@
 
         buf.append( "'" );
         String text = ast.getText();
-        appendEscapedMultibyteChars(text, buf);
+		if ( text == null ) {
+			text = "{text:null}";
+		}
+		appendEscapedMultibyteChars(text, buf);
         buf.append( "'" );
 		if ( ast instanceof DisplayableNode ) {
 			DisplayableNode displayableNode = ( DisplayableNode ) ast;
 			// Add a space before the display text.
 			buf.append( " " ).append( displayableNode.getDisplayText() );
 		}
-		String s = buf.toString();
-		return s;
+		return buf.toString();
 	}
 
     public static void appendEscapedMultibyteChars(String text, StringBuffer buf) {
@@ -276,10 +219,9 @@
         }
     }
 
-    public static String escapeMultibyteChars(String text)
-    {
+    public static String escapeMultibyteChars(String text) {
         StringBuffer buf = new StringBuffer();
         appendEscapedMultibyteChars(text,buf);
         return buf.toString();
     }
-}
+}
\ No newline at end of file

Modified: core/branches/Branch_3_3/core/src/main/java/org/hibernate/hql/ast/util/ASTUtil.java
===================================================================
--- core/branches/Branch_3_3/core/src/main/java/org/hibernate/hql/ast/util/ASTUtil.java	2009-02-03 18:30:11 UTC (rev 15868)
+++ core/branches/Branch_3_3/core/src/main/java/org/hibernate/hql/ast/util/ASTUtil.java	2009-02-03 20:37:01 UTC (rev 15869)
@@ -20,12 +20,15 @@
  * Free Software Foundation, Inc.
  * 51 Franklin Street, Fifth Floor
  * Boston, MA  02110-1301  USA
- *
  */
 package org.hibernate.hql.ast.util;
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Map;
+import java.util.HashMap;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
 
 import antlr.ASTFactory;
 import antlr.collections.AST;
@@ -35,46 +38,62 @@
  * Provides utility methods for AST traversal and manipulation.
  *
  * @author Joshua Davis
+ * @author Steve Ebersole
  */
 public final class ASTUtil {
 	/**
-	 * Private empty constructor.
-	 * (or else checkstyle says: 'warning: Utility classes should not have a public or default constructor.')
+	 * Disallow instantiation.
 	 *
-	 * @deprecated (tell clover to ignore this)
+	 * @deprecated (tellclovertoignorethis)
 	 */
 	private ASTUtil() {
 	}
 
 	/**
 	 * Creates a single node AST.
+	 * <p/>
+	 * TODO : this is silly, remove it...
 	 *
 	 * @param astFactory The factory.
-	 * @param type       The node type.
-	 * @param text       The node text.
+	 * @param type The node type.
+	 * @param text The node text.
+	 *
 	 * @return AST - A single node tree.
+	 *
+	 * @deprecated silly
 	 */
 	public static AST create(ASTFactory astFactory, int type, String text) {
-		AST node = astFactory.create( type, text );
-		return node;
+		return astFactory.create( type, text );
 	}
 
 	/**
-	 * Creates a single node AST as a sibling.
+	 * Creates a single node AST as a sibling of the passed prevSibling,
+	 * taking care to reorganize the tree correctly to account for this
+	 * newly created node.
 	 *
-	 * @param astFactory  The factory.
-	 * @param type        The node type.
-	 * @param text        The node text.
+	 * @param astFactory The factory.
+	 * @param type The node type.
+	 * @param text The node text.
 	 * @param prevSibling The previous sibling.
-	 * @return AST - A single node tree.
+	 *
+	 * @return The created AST node.
 	 */
 	public static AST createSibling(ASTFactory astFactory, int type, String text, AST prevSibling) {
 		AST node = astFactory.create( type, text );
-		node.setNextSibling( prevSibling.getNextSibling() );
-		prevSibling.setNextSibling( node );
-		return node;
+		return insertSibling( node, prevSibling );
 	}
 
+	/**
+	 * Inserts a node into a child subtree as a particularly positioned
+	 * sibling taking care to properly reorganize the tree to account for this
+	 * new addition.
+	 *
+	 * @param node The node to insert
+	 * @param prevSibling The previous node at the sibling position
+	 * where we want this node inserted.
+	 *
+	 * @return The return is the same as the node parameter passed in.
+	 */
 	public static AST insertSibling(AST node, AST prevSibling) {
 		node.setNextSibling( prevSibling.getNextSibling() );
 		prevSibling.setNextSibling( node );
@@ -85,11 +104,12 @@
 	 * Creates a 'binary operator' subtree, given the information about the
 	 * parent and the two child nodex.
 	 *
-	 * @param factory    The AST factory.
+	 * @param factory The AST factory.
 	 * @param parentType The type of the parent node.
 	 * @param parentText The text of the parent node.
-	 * @param child1     The first child.
-	 * @param child2     The second child.
+	 * @param child1 The first child.
+	 * @param child2 The second child.
+	 *
 	 * @return AST - A new sub-tree of the form "(parent child1 child2)"
 	 */
 	public static AST createBinarySubtree(ASTFactory factory, int parentType, String parentText, AST child1, AST child2) {
@@ -102,10 +122,11 @@
 	 * Creates a single parent of the specified child (i.e. a 'unary operator'
 	 * subtree).
 	 *
-	 * @param factory    The AST factory.
+	 * @param factory The AST factory.
 	 * @param parentType The type of the parent node.
 	 * @param parentText The text of the parent node.
-	 * @param child      The child.
+	 * @param child The child.
+	 *
 	 * @return AST - A new sub-tree of the form "(parent child)"
 	 */
 	public static AST createParent(ASTFactory factory, int parentType, String parentText, AST child) {
@@ -127,10 +148,33 @@
 	}
 
 	/**
+	 * Determine if a given node (test) is contained anywhere in the subtree
+	 * of another given node (fixture).
+	 *
+	 * @param fixture The node against which to testto be checked for children.
+	 * @param test The node to be tested as being a subtree child of the parent.
+	 * @return True if child is contained in the parent's collection of children.
+	 */
+	public static boolean isSubtreeChild(AST fixture, AST test) {
+		AST n = fixture.getFirstChild();
+		while ( n != null ) {
+			if ( n == test ) {
+				return true;
+			}
+			if ( n.getFirstChild() != null && isSubtreeChild( n, test ) ) {
+				return true;
+			}
+			n = n.getNextSibling();
+		}
+		return false;
+	}
+
+	/**
 	 * Finds the first node of the specified type in the chain of children.
 	 *
 	 * @param parent The parent
-	 * @param type   The type to find.
+	 * @param type The type to find.
+	 *
 	 * @return The first node of the specified type, or null if not found.
 	 */
 	public static AST findTypeInChildren(AST parent, int type) {
@@ -145,6 +189,7 @@
 	 * Returns the last direct child of 'n'.
 	 *
 	 * @param n The parent
+	 *
 	 * @return The last direct child of 'n'.
 	 */
 	public static AST getLastChild(AST n) {
@@ -155,6 +200,7 @@
 	 * Returns the last sibling of 'a'.
 	 *
 	 * @param a The sibling.
+	 *
 	 * @return The last sibling of 'a'.
 	 */
 	private static AST getLastSibling(AST a) {
@@ -170,6 +216,7 @@
 	 * Returns the 'list' representation with some brackets around it for debugging.
 	 *
 	 * @param n The tree.
+	 *
 	 * @return The list representation of the tree.
 	 */
 	public static String getDebugString(AST n) {
@@ -184,7 +231,8 @@
 	 * Find the previous sibling in the parent for the given child.
 	 *
 	 * @param parent the parent node
-	 * @param child  the child to find the previous sibling of
+	 * @param child the child to find the previous sibling of
+	 *
 	 * @return the previous sibling of the child
 	 */
 	public static AST findPreviousSibling(AST parent, AST child) {
@@ -201,52 +249,10 @@
 	}
 
 	/**
-	 * Determine if a given node (test) is a direct (throtle to one level down)
-	 * child of another given node (fixture).
-	 *
-	 * @param fixture The node against which to testto be checked for children.
-	 * @param test The node to be tested as being a child of the parent.
-	 * @return True if test is contained in the fixtures's direct children;
-	 * false otherwise.
-	 */
-	public static boolean isDirectChild(AST fixture, AST test) {
-		AST n = fixture.getFirstChild();
-		while ( n != null ) {
-			if ( n == test ) {
-				return true;
-			}
-			n = n.getNextSibling();
-		}
-		return false;
-	}
-
-	/**
-	 * Determine if a given node (test) is contained anywhere in the subtree
-	 * of another given node (fixture).
-	 *
-	 * @param fixture The node against which to testto be checked for children.
-	 * @param test The node to be tested as being a subtree child of the parent.
-	 * @return True if child is contained in the parent's collection of children.
-	 */
-	public static boolean isSubtreeChild(AST fixture, AST test) {
-		AST n = fixture.getFirstChild();
-		while ( n != null ) {
-			if ( n == test ) {
-				return true;
-			}
-			if ( n.getFirstChild() != null && isSubtreeChild( n, test ) ) {
-				return true;
-			}
-			n = n.getNextSibling();
-		}
-		return false;
-	}
-
-	/**
 	 * Makes the child node a sibling of the parent, reconnecting all siblings.
 	 *
 	 * @param parent the parent
-	 * @param child  the child
+	 * @param child the child
 	 */
 	public static void makeSiblingOfParent(AST parent, AST child) {
 		AST prev = findPreviousSibling( parent, child );
@@ -295,7 +301,7 @@
 	 * Inserts the child as the first child of the parent, all other children are shifted over to the 'right'.
 	 *
 	 * @param parent the parent
-	 * @param child  the new first child
+	 * @param child the new first child
 	 */
 	public static void insertChild(AST parent, AST child) {
 		if ( parent.getFirstChild() == null ) {
@@ -308,6 +314,13 @@
 		}
 	}
 
+	private static ASTArray createAstArray(ASTFactory factory, int size, int parentType, String parentText, AST child1) {
+		ASTArray array = new ASTArray( size );
+		array.add( factory.create( parentType, parentText ) );
+		array.add( child1 );
+		return array;
+	}
+
 	/**
 	 * Filters nodes out of a tree.
 	 */
@@ -316,6 +329,7 @@
 		 * Returns true if the node should be filtered out.
 		 *
 		 * @param n The node.
+		 *
 		 * @return true if the node should be filtered out, false to keep the node.
 		 */
 		boolean exclude(AST n);
@@ -332,17 +346,7 @@
 		public abstract boolean include(AST node);
 	}
 
-	private static ASTArray createAstArray(ASTFactory factory, int size, int parentType, String parentText, AST child1) {
-		ASTArray array = new ASTArray( size );
-		array.add( factory.create( parentType, parentText ) );
-		array.add( child1 );
-		return array;
-	}
-
 	public static List collectChildren(AST root, FilterPredicate predicate) {
-//		List children = new ArrayList();
-//		collectChildren( children, root, predicate );
-//		return children;
 		return new CollectingNodeVisitor( predicate ).collect( root );
 	}
 
@@ -371,13 +375,89 @@
 		}
 	}
 
-	private static void collectChildren(List children, AST root, FilterPredicate predicate) {
-		for ( AST n = root.getFirstChild(); n != null; n = n.getNextSibling() ) {
-			if ( predicate == null || !predicate.exclude( n ) ) {
-				children.add( n );
+	/**
+	 * Method to generate a map of token type names, keyed by their token type values.
+	 *
+	 * @param tokenTypeInterface The *TokenTypes interface (or implementor of said interface).
+	 * @return The generated map.
+	 */
+	public static Map generateTokenNameCache(Class tokenTypeInterface) {
+		final Field[] fields = tokenTypeInterface.getFields();
+		Map cache = new HashMap( (int)( fields.length * .75 ) + 1 );
+		for ( int i = 0; i < fields.length; i++ ) {
+			final Field field = fields[i];
+			if ( Modifier.isStatic( field.getModifiers() ) ) {
+				try {
+					cache.put( field.get( null ), field.getName() );
+				}
+				catch ( Throwable ignore ) {
+				}
 			}
-			collectChildren( children, n, predicate );
 		}
+		return cache;
 	}
 
+	/**
+	 * Get the name of a constant defined on the given class which has the given value.
+	 * <p/>
+	 * Note, if multiple constants have this value, the first will be returned which is known to be different
+	 * on different JVM implementations.
+	 *
+	 * @param owner The class which defines the constant
+	 * @param value The value of the constant.
+	 *
+	 * @return The token type name, *or* the integer value if the name could not be found.
+	 *
+	 * @deprecated Use #getTokenTypeName instead
+	 */
+	public static String getConstantName(Class owner, int value) {
+		return getTokenTypeName( owner, value );
+	}
+
+	/**
+	 * Intended to retrieve the name of an AST token type based on the token type interface.  However, this
+	 * method can be used to look up the name of any constant defined on a class/interface based on the constant value.
+	 * Note that if multiple constants have this value, the first will be returned which is known to be different
+	 * on different JVM implementations.
+	 *
+	 * @param tokenTypeInterface The *TokenTypes interface (or one of its implementors).
+	 * @param tokenType The token type value.
+	 *
+	 * @return The corresponding name.
+	 */
+	public static String getTokenTypeName(Class tokenTypeInterface, int tokenType) {
+		String tokenTypeName = Integer.toString( tokenType );
+		if ( tokenTypeInterface != null ) {
+			Field[] fields = tokenTypeInterface.getFields();
+			for ( int i = 0; i < fields.length; i++ ) {
+				final Integer fieldValue = extractIntegerValue( fields[i] );
+				if ( fieldValue != null && fieldValue.intValue() == tokenType ) {
+					tokenTypeName = fields[i].getName();
+					break;
+				}
+			}
+		}
+		return tokenTypeName;
+	}
+
+	private static Integer extractIntegerValue(Field field) {
+		Integer rtn = null;
+		try {
+			Object value = field.get( null );
+			if ( value instanceof Integer ) {
+				rtn = ( Integer ) value;
+			}
+			else if ( value instanceof Short ) {
+				rtn = new Integer( ( ( Short ) value ).intValue() );
+			}
+			else if ( value instanceof Long ) {
+				if ( ( ( Long ) value ).longValue() <= Integer.MAX_VALUE ) {
+					rtn = new Integer( ( ( Long ) value ).intValue() );
+				}
+			}
+		}
+		catch ( IllegalAccessException ignore ) {
+		}
+		return rtn;
+	}
 }

Added: core/branches/Branch_3_3/core/src/main/java/org/hibernate/hql/ast/util/DisplayableNode.java
===================================================================
--- core/branches/Branch_3_3/core/src/main/java/org/hibernate/hql/ast/util/DisplayableNode.java	                        (rev 0)
+++ core/branches/Branch_3_3/core/src/main/java/org/hibernate/hql/ast/util/DisplayableNode.java	2009-02-03 20:37:01 UTC (rev 15869)
@@ -0,0 +1,15 @@
+// $Id: DisplayableNode.java 7460 2005-07-12 20:27:29Z steveebersole $
+package org.hibernate.hql.ast.util;
+
+/**
+ * Marker interface for nodes (AST impls) wanting to display extra information during {@link ASTPrinter} processing.  The
+ * extra display text is output in addition to the node type and text.
+ */
+public interface DisplayableNode {
+	/**
+	 * Returns additional display text for the AST node.
+	 *
+	 * @return The additional display text.
+	 */
+	public String getDisplayText();
+}

Modified: core/branches/Branch_3_3/core/src/main/java/org/hibernate/util/StringHelper.java
===================================================================
--- core/branches/Branch_3_3/core/src/main/java/org/hibernate/util/StringHelper.java	2009-02-03 18:30:11 UTC (rev 15868)
+++ core/branches/Branch_3_3/core/src/main/java/org/hibernate/util/StringHelper.java	2009-02-03 20:37:01 UTC (rev 15869)
@@ -27,6 +27,7 @@
 import java.util.Iterator;
 import java.util.StringTokenizer;
 import java.util.ArrayList;
+import java.util.Arrays;
 
 public final class StringHelper {
 
@@ -85,6 +86,11 @@
 		return buf.toString();
 	}
 
+	public static String repeat(char character, int times) {
+		char[] buffer = new char[times];
+		Arrays.fill( buffer, character );
+		return new String( buffer );
+	}
 
 	public static String replace(String template, String placeholder, String replacement) {
 		return replace( template, placeholder, replacement, false );




More information about the hibernate-commits mailing list