Hibernate SVN: r15872 - core/branches/Branch_3_2/src/org/hibernate/hql/ast/tree.
by hibernate-commits@lists.jboss.org
Author: steve.ebersole(a)jboss.com
Date: 2009-02-03 15:49:00 -0500 (Tue, 03 Feb 2009)
New Revision: 15872
Removed:
core/branches/Branch_3_2/src/org/hibernate/hql/ast/tree/DisplayableNode.java
Log:
HHH-3751 : Antlr tree parser tracing
Deleted: core/branches/Branch_3_2/src/org/hibernate/hql/ast/tree/DisplayableNode.java
===================================================================
--- core/branches/Branch_3_2/src/org/hibernate/hql/ast/tree/DisplayableNode.java 2009-02-03 20:48:39 UTC (…
[View More]rev 15871)
+++ core/branches/Branch_3_2/src/org/hibernate/hql/ast/tree/DisplayableNode.java 2009-02-03 20:49:00 UTC (rev 15872)
@@ -1,16 +0,0 @@
-// $Id$
-package org.hibernate.hql.ast.tree;
-
-/**
- * Implementors will return additional display text, which will be used
- * by the ASTPrinter to display information (besides the node type and node
- * text).
- */
-public interface DisplayableNode {
- /**
- * Returns additional display text for the AST node.
- *
- * @return String - The additional display text.
- */
- String getDisplayText();
-}
[View Less]
16 years
Hibernate SVN: r15871 - in core/branches/Branch_3_2: src/org/hibernate/hql/ast and 3 other directories.
by hibernate-commits@lists.jboss.org
Author: steve.ebersole(a)jboss.com
Date: 2009-02-03 15:48:39 -0500 (Tue, 03 Feb 2009)
New Revision: 15871
Added:
core/branches/Branch_3_2/src/org/hibernate/hql/ast/util/DisplayableNode.java
Modified:
core/branches/Branch_3_2/build.xml
core/branches/Branch_3_2/src/org/hibernate/hql/ast/HqlSqlWalker.java
core/branches/Branch_3_2/src/org/hibernate/hql/ast/QueryTranslatorImpl.java
core/branches/Branch_3_2/src/org/hibernate/hql/ast/SqlGenerator.java
core/branches/Branch_3_2/src/…
[View More]org/hibernate/hql/ast/tree/AbstractStatement.java
core/branches/Branch_3_2/src/org/hibernate/hql/ast/tree/BinaryArithmeticOperatorNode.java
core/branches/Branch_3_2/src/org/hibernate/hql/ast/tree/CollectionFunction.java
core/branches/Branch_3_2/src/org/hibernate/hql/ast/tree/FromClause.java
core/branches/Branch_3_2/src/org/hibernate/hql/ast/tree/FromElement.java
core/branches/Branch_3_2/src/org/hibernate/hql/ast/tree/FromReferenceNode.java
core/branches/Branch_3_2/src/org/hibernate/hql/ast/tree/IntoClause.java
core/branches/Branch_3_2/src/org/hibernate/hql/ast/tree/ParameterNode.java
core/branches/Branch_3_2/src/org/hibernate/hql/ast/util/ASTPrinter.java
core/branches/Branch_3_2/src/org/hibernate/hql/ast/util/ASTUtil.java
core/branches/Branch_3_2/src/org/hibernate/util/StringHelper.java
Log:
HHH-3751 : Antlr tree parser tracing
Modified: core/branches/Branch_3_2/build.xml
===================================================================
--- core/branches/Branch_3_2/build.xml 2009-02-03 20:45:03 UTC (rev 15870)
+++ core/branches/Branch_3_2/build.xml 2009-02-03 20:48:39 UTC (rev 15871)
@@ -172,8 +172,8 @@
</taskdef>
<mkdir dir="${dir.out.antlr-package}" />
<antlrtask target="${dir.grammar}/hql.g" outputdirectory="${dir.out.antlr-package}" />
- <antlrtask target="${dir.grammar}/hql-sql.g" outputdirectory="${dir.out.antlr-package}" />
- <antlrtask target="${dir.grammar}/sql-gen.g" outputdirectory="${dir.out.antlr-package}" />
+ <antlrtask target="${dir.grammar}/hql-sql.g" outputdirectory="${dir.out.antlr-package}" tracetreewalker="true" />
+ <antlrtask target="${dir.grammar}/sql-gen.g" outputdirectory="${dir.out.antlr-package}" tracetreewalker="true" />
<touch file="${dir.out.antlr-package}/.antlr_run"/>
</target>
Modified: core/branches/Branch_3_2/src/org/hibernate/hql/ast/HqlSqlWalker.java
===================================================================
--- core/branches/Branch_3_2/src/org/hibernate/hql/ast/HqlSqlWalker.java 2009-02-03 20:45:03 UTC (rev 15870)
+++ core/branches/Branch_3_2/src/org/hibernate/hql/ast/HqlSqlWalker.java 2009-02-03 20:48:39 UTC (rev 15871)
@@ -71,6 +71,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;
@@ -147,6 +148,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
@@ -185,7 +220,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_2/src/org/hibernate/hql/ast/QueryTranslatorImpl.java
===================================================================
--- core/branches/Branch_3_2/src/org/hibernate/hql/ast/QueryTranslatorImpl.java 2009-02-03 20:45:03 UTC (rev 15870)
+++ core/branches/Branch_3_2/src/org/hibernate/hql/ast/QueryTranslatorImpl.java 2009-02-03 20:48:39 UTC (rev 15871)
@@ -264,8 +264,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_2/src/org/hibernate/hql/ast/SqlGenerator.java
===================================================================
--- core/branches/Branch_3_2/src/org/hibernate/hql/ast/SqlGenerator.java 2009-02-03 20:45:03 UTC (rev 15870)
+++ core/branches/Branch_3_2/src/org/hibernate/hql/ast/SqlGenerator.java 2009-02-03 20:48:39 UTC (rev 15871)
@@ -9,16 +9,22 @@
import antlr.RecognitionException;
import antlr.collections.AST;
import org.hibernate.QueryException;
+import org.hibernate.util.StringHelper;
import org.hibernate.param.ParameterSpecification;
import org.hibernate.dialect.function.SQLFunction;
import org.hibernate.engine.SessionFactoryImplementor;
import org.hibernate.hql.antlr.SqlGeneratorBase;
+import org.hibernate.hql.antlr.SqlTokenTypes;
import org.hibernate.hql.ast.tree.MethodNode;
import org.hibernate.hql.ast.tree.FromElement;
import org.hibernate.hql.ast.tree.Node;
import org.hibernate.hql.ast.tree.ParameterNode;
import org.hibernate.hql.ast.tree.ParameterContainer;
+import org.hibernate.hql.ast.util.ASTPrinter;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
/**
* Generates SQL by overriding callback methods in the base class, which does
* the actual SQL AST walking.
@@ -27,6 +33,9 @@
* @author Steve Ebersole
*/
public class SqlGenerator extends SqlGeneratorBase implements ErrorReporter {
+ private static final Log log = LogFactory.getLog( SqlGenerator.class );
+ private static final ASTPrinter printer = new ASTPrinter( SqlTokenTypes.class, true );
+
/**
* Handles parser errors.
*/
@@ -51,6 +60,45 @@
return collectedParameters;
}
+ public ASTPrinter getPrinter() {
+ return printer;
+ }
+
+
+ // 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 processing ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
protected void out(String s) {
writer.clause( s );
}
Modified: core/branches/Branch_3_2/src/org/hibernate/hql/ast/tree/AbstractStatement.java
===================================================================
--- core/branches/Branch_3_2/src/org/hibernate/hql/ast/tree/AbstractStatement.java 2009-02-03 20:45:03 UTC (rev 15870)
+++ core/branches/Branch_3_2/src/org/hibernate/hql/ast/tree/AbstractStatement.java 2009-02-03 20:48:39 UTC (rev 15871)
@@ -3,6 +3,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_2/src/org/hibernate/hql/ast/tree/BinaryArithmeticOperatorNode.java
===================================================================
--- core/branches/Branch_3_2/src/org/hibernate/hql/ast/tree/BinaryArithmeticOperatorNode.java 2009-02-03 20:45:03 UTC (rev 15870)
+++ core/branches/Branch_3_2/src/org/hibernate/hql/ast/tree/BinaryArithmeticOperatorNode.java 2009-02-03 20:48:39 UTC (rev 15871)
@@ -3,6 +3,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_2/src/org/hibernate/hql/ast/tree/CollectionFunction.java
===================================================================
--- core/branches/Branch_3_2/src/org/hibernate/hql/ast/tree/CollectionFunction.java 2009-02-03 20:45:03 UTC (rev 15870)
+++ core/branches/Branch_3_2/src/org/hibernate/hql/ast/tree/CollectionFunction.java 2009-02-03 20:48:39 UTC (rev 15871)
@@ -4,6 +4,8 @@
import antlr.SemanticException;
import antlr.collections.AST;
+import org.hibernate.hql.ast.util.DisplayableNode;
+
/**
* Represents 'elements()' or 'indices()'.
*
Modified: core/branches/Branch_3_2/src/org/hibernate/hql/ast/tree/FromClause.java
===================================================================
--- core/branches/Branch_3_2/src/org/hibernate/hql/ast/tree/FromClause.java 2009-02-03 20:45:03 UTC (rev 15870)
+++ core/branches/Branch_3_2/src/org/hibernate/hql/ast/tree/FromClause.java 2009-02-03 20:48:39 UTC (rev 15871)
@@ -14,6 +14,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_2/src/org/hibernate/hql/ast/tree/FromElement.java
===================================================================
--- core/branches/Branch_3_2/src/org/hibernate/hql/ast/tree/FromElement.java 2009-02-03 20:45:03 UTC (rev 15870)
+++ core/branches/Branch_3_2/src/org/hibernate/hql/ast/tree/FromElement.java 2009-02-03 20:48:39 UTC (rev 15871)
@@ -12,6 +12,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_2/src/org/hibernate/hql/ast/tree/FromReferenceNode.java
===================================================================
--- core/branches/Branch_3_2/src/org/hibernate/hql/ast/tree/FromReferenceNode.java 2009-02-03 20:45:03 UTC (rev 15870)
+++ core/branches/Branch_3_2/src/org/hibernate/hql/ast/tree/FromReferenceNode.java 2009-02-03 20:48:39 UTC (rev 15871)
@@ -7,6 +7,8 @@
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.hibernate.hql.ast.util.DisplayableNode;
+
/**
* Represents a reference to a FROM element, for example a class alias in a WHERE clause.
*
Modified: core/branches/Branch_3_2/src/org/hibernate/hql/ast/tree/IntoClause.java
===================================================================
--- core/branches/Branch_3_2/src/org/hibernate/hql/ast/tree/IntoClause.java 2009-02-03 20:45:03 UTC (rev 15870)
+++ core/branches/Branch_3_2/src/org/hibernate/hql/ast/tree/IntoClause.java 2009-02-03 20:48:39 UTC (rev 15871)
@@ -6,6 +6,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_2/src/org/hibernate/hql/ast/tree/ParameterNode.java
===================================================================
--- core/branches/Branch_3_2/src/org/hibernate/hql/ast/tree/ParameterNode.java 2009-02-03 20:45:03 UTC (rev 15870)
+++ core/branches/Branch_3_2/src/org/hibernate/hql/ast/tree/ParameterNode.java 2009-02-03 20:48:39 UTC (rev 15871)
@@ -4,6 +4,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_2/src/org/hibernate/hql/ast/util/ASTPrinter.java
===================================================================
--- core/branches/Branch_3_2/src/org/hibernate/hql/ast/util/ASTPrinter.java 2009-02-03 20:45:03 UTC (rev 15870)
+++ core/branches/Branch_3_2/src/org/hibernate/hql/ast/util/ASTPrinter.java 2009-02-03 20:48:39 UTC (rev 15871)
@@ -1,86 +1,95 @@
-// $Id$
+/*
+ * 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.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 (pgmjsd(a)sourceforge.net)
+ * @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) {
@@ -93,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();
}
/**
@@ -149,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) {
@@ -219,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( "] " );
@@ -229,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) {
@@ -253,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_2/src/org/hibernate/hql/ast/util/ASTUtil.java
===================================================================
--- core/branches/Branch_3_2/src/org/hibernate/hql/ast/util/ASTUtil.java 2009-02-03 20:45:03 UTC (rev 15870)
+++ core/branches/Branch_3_2/src/org/hibernate/hql/ast/util/ASTUtil.java 2009-02-03 20:48:39 UTC (rev 15871)
@@ -1,8 +1,34 @@
-// $Id$
+/*
+ * 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.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;
@@ -11,47 +37,63 @@
/**
* Provides utility methods for AST traversal and manipulation.
*
- * @author Joshua Davis (pgmjsd(a)sourceforge.net)
+ * @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 );
@@ -62,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) {
@@ -79,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) {
@@ -104,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) {
@@ -122,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) {
@@ -132,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) {
@@ -147,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) {
@@ -161,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) {
@@ -178,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 );
@@ -272,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 ) {
@@ -285,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.
*/
@@ -293,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);
@@ -309,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 );
}
@@ -348,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;
+ }
}
Copied: core/branches/Branch_3_2/src/org/hibernate/hql/ast/util/DisplayableNode.java (from rev 15787, core/branches/Branch_3_2/src/org/hibernate/hql/ast/tree/DisplayableNode.java)
===================================================================
--- core/branches/Branch_3_2/src/org/hibernate/hql/ast/util/DisplayableNode.java (rev 0)
+++ core/branches/Branch_3_2/src/org/hibernate/hql/ast/util/DisplayableNode.java 2009-02-03 20:48:39 UTC (rev 15871)
@@ -0,0 +1,15 @@
+// $Id$
+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();
+}
Property changes on: core/branches/Branch_3_2/src/org/hibernate/hql/ast/util/DisplayableNode.java
___________________________________________________________________
Name: svn:keywords
+ Author Date Id Revision
Name: svn:eol-style
+ native
Modified: core/branches/Branch_3_2/src/org/hibernate/util/StringHelper.java
===================================================================
--- core/branches/Branch_3_2/src/org/hibernate/util/StringHelper.java 2009-02-03 20:45:03 UTC (rev 15870)
+++ core/branches/Branch_3_2/src/org/hibernate/util/StringHelper.java 2009-02-03 20:48:39 UTC (rev 15871)
@@ -4,6 +4,7 @@
import java.util.Iterator;
import java.util.StringTokenizer;
import java.util.ArrayList;
+import java.util.Arrays;
public final class StringHelper {
@@ -62,7 +63,13 @@
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 );
}
[View Less]
16 years
Hibernate SVN: r15870 - in core/branches/Branch_3_3/core: src/main/java/org/hibernate/hql/ast and 1 other directory.
by hibernate-commits@lists.jboss.org
Author: steve.ebersole(a)jboss.com
Date: 2009-02-03 15:45:03 -0500 (Tue, 03 Feb 2009)
New Revision: 15870
Modified:
core/branches/Branch_3_3/core/pom.xml
core/branches/Branch_3_3/core/src/main/java/org/hibernate/hql/ast/SqlGenerator.java
Log:
HHH-3751 : Antlr tree parser tracing
Modified: core/branches/Branch_3_3/core/pom.xml
===================================================================
--- core/branches/Branch_3_3/core/pom.xml 2009-02-03 20:37:01 UTC (rev 15869)
+++ core/branches/…
[View More]Branch_3_3/core/pom.xml 2009-02-03 20:45:03 UTC (rev 15870)
@@ -77,6 +77,7 @@
<artifactId>antlr-maven-plugin</artifactId>
<version>${antlrPluginVersion}</version>
<configuration>
+ <traceTreeParser>true</traceTreeParser>
<grammars>hql.g,hql-sql.g,sql-gen.g</grammars>
</configuration>
<executions>
Modified: core/branches/Branch_3_3/core/src/main/java/org/hibernate/hql/ast/SqlGenerator.java
===================================================================
--- core/branches/Branch_3_3/core/src/main/java/org/hibernate/hql/ast/SqlGenerator.java 2009-02-03 20:37:01 UTC (rev 15869)
+++ core/branches/Branch_3_3/core/src/main/java/org/hibernate/hql/ast/SqlGenerator.java 2009-02-03 20:45:03 UTC (rev 15870)
@@ -32,16 +32,22 @@
import antlr.RecognitionException;
import antlr.collections.AST;
import org.hibernate.QueryException;
+import org.hibernate.util.StringHelper;
import org.hibernate.param.ParameterSpecification;
import org.hibernate.dialect.function.SQLFunction;
import org.hibernate.engine.SessionFactoryImplementor;
import org.hibernate.hql.antlr.SqlGeneratorBase;
+import org.hibernate.hql.antlr.SqlTokenTypes;
import org.hibernate.hql.ast.tree.MethodNode;
import org.hibernate.hql.ast.tree.FromElement;
import org.hibernate.hql.ast.tree.Node;
import org.hibernate.hql.ast.tree.ParameterNode;
import org.hibernate.hql.ast.tree.ParameterContainer;
+import org.hibernate.hql.ast.util.ASTPrinter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
/**
* Generates SQL by overriding callback methods in the base class, which does
* the actual SQL AST walking.
@@ -50,6 +56,9 @@
* @author Steve Ebersole
*/
public class SqlGenerator extends SqlGeneratorBase implements ErrorReporter {
+ private static final Logger log = LoggerFactory.getLogger( SqlGenerator.class );
+ private static final ASTPrinter printer = new ASTPrinter( SqlTokenTypes.class, true );
+
/**
* Handles parser errors.
*/
@@ -74,6 +83,45 @@
return collectedParameters;
}
+ public ASTPrinter getPrinter() {
+ return printer;
+ }
+
+
+ // 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 processing ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
protected void out(String s) {
writer.clause( s );
}
[View Less]
16 years
Hibernate SVN: r15869 - in core/branches/Branch_3_3/core/src/main/java/org/hibernate: hql/ast/tree and 2 other directories.
by hibernate-commits@lists.jboss.org
Author: steve.ebersole(a)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
…
[View More]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 );
[View Less]
16 years
Hibernate SVN: r15868 - in core/branches/envers-hibernate-3.3/src: main/java/org/hibernate/envers/entities and 6 other directories.
by hibernate-commits@lists.jboss.org
Author: adamw
Date: 2009-02-03 13:30:11 -0500 (Tue, 03 Feb 2009)
New Revision: 15868
Added:
core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/entities/components/relations/NotAuditedManyToOneComponent.java
core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/entities/components/relations/NotAuditedManyToOneComponentTestEntity.java
core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/accesstype/Country.…
[View More]java
core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/accesstype/ImmutableClassAccessType.java
core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/components/relations/NotAuditedManyToOneInComponent.java
Modified:
core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/configuration/metadata/ComponentMetadataGenerator.java
core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/entities/EntityInstantiator.java
core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/entities/mapper/SubclassPropertyMapper.java
core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/entities/mapper/id/SingleIdMapper.java
core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/event/AuditEventListener.java
Log:
svn merge -r 15828:15867 https://svn.jboss.org/repos/hibernate/core/trunk/envers .
Modified: core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/configuration/metadata/ComponentMetadataGenerator.java
===================================================================
--- core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/configuration/metadata/ComponentMetadataGenerator.java 2009-02-03 14:23:14 UTC (rev 15867)
+++ core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/configuration/metadata/ComponentMetadataGenerator.java 2009-02-03 18:30:11 UTC (rev 15868)
@@ -37,9 +37,14 @@
while (properties.hasNext()) {
Property property = properties.next();
- mainGenerator.addValue(parent, property.getValue(), componentMapper, entityName, xmlMappingData,
- componentAuditingData.getPropertyAuditingData(property.getName()),
- property.isInsertable(), firstPass);
+ PropertyAuditingData componentPropertyAuditingData =
+ componentAuditingData.getPropertyAuditingData(property.getName());
+
+ // Checking if that property is audited
+ if (componentPropertyAuditingData != null) {
+ mainGenerator.addValue(parent, property.getValue(), componentMapper, entityName, xmlMappingData,
+ componentPropertyAuditingData, property.isInsertable(), firstPass);
+ }
}
}
}
Modified: core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/entities/EntityInstantiator.java
===================================================================
--- core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/entities/EntityInstantiator.java 2009-02-03 14:23:14 UTC (rev 15867)
+++ core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/entities/EntityInstantiator.java 2009-02-03 18:30:11 UTC (rev 15868)
@@ -32,6 +32,7 @@
import org.hibernate.envers.exception.AuditException;
import org.hibernate.envers.reader.AuditReaderImplementor;
import org.hibernate.envers.tools.reflection.ReflectionTools;
+import org.hibernate.util.ReflectHelper;
/**
* @author Adam Warski (adam at warski dot org)
@@ -80,7 +81,7 @@
Object ret;
try {
Class<?> cls = ReflectionTools.loadClass(entityName);
- ret = cls.newInstance();
+ ret = ReflectHelper.getDefaultConstructor(cls).newInstance();
} catch (Exception e) {
throw new AuditException(e);
}
Modified: core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/entities/mapper/SubclassPropertyMapper.java
===================================================================
--- core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/entities/mapper/SubclassPropertyMapper.java 2009-02-03 14:23:14 UTC (rev 15867)
+++ core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/entities/mapper/SubclassPropertyMapper.java 2009-02-03 18:30:11 UTC (rev 15868)
@@ -79,7 +79,9 @@
if (parentCollectionChanges == null) {
return mainCollectionChanges;
} else {
- parentCollectionChanges.addAll(mainCollectionChanges);
+ if(mainCollectionChanges != null) {
+ parentCollectionChanges.addAll(mainCollectionChanges);
+ }
return parentCollectionChanges;
}
}
Modified: core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/entities/mapper/id/SingleIdMapper.java
===================================================================
--- core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/entities/mapper/id/SingleIdMapper.java 2009-02-03 14:23:14 UTC (rev 15867)
+++ core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/entities/mapper/id/SingleIdMapper.java 2009-02-03 18:30:11 UTC (rev 15868)
@@ -33,6 +33,7 @@
import org.hibernate.property.Getter;
import org.hibernate.property.Setter;
+import org.hibernate.proxy.HibernateProxy;
/**
* @author Adam Warski (adam at warski dot org)
@@ -77,8 +78,13 @@
return null;
}
- Getter getter = ReflectionTools.getGetter(data.getClass(), propertyData);
- return getter.get(data);
+ if(data instanceof HibernateProxy) {
+ HibernateProxy hibernateProxy = (HibernateProxy) data;
+ return hibernateProxy.getHibernateLazyInitializer().getIdentifier();
+ } else {
+ Getter getter = ReflectionTools.getGetter(data.getClass(), propertyData);
+ return getter.get(data);
+ }
}
public void mapToMapFromId(Map<String, Object> data, Object obj) {
@@ -91,8 +97,13 @@
if (obj == null) {
data.put(propertyData.getName(), null);
} else {
- Getter getter = ReflectionTools.getGetter(obj.getClass(), propertyData);
- data.put(propertyData.getName(), getter.get(obj));
+ if(obj instanceof HibernateProxy) {
+ HibernateProxy hibernateProxy = (HibernateProxy)obj;
+ data.put(propertyData.getName(), hibernateProxy.getHibernateLazyInitializer().getIdentifier());
+ } else {
+ Getter getter = ReflectionTools.getGetter(obj.getClass(), propertyData);
+ data.put(propertyData.getName(), getter.get(obj));
+ }
}
}
Modified: core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/event/AuditEventListener.java
===================================================================
--- core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/event/AuditEventListener.java 2009-02-03 14:23:14 UTC (rev 15867)
+++ core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/event/AuditEventListener.java 2009-02-03 18:30:11 UTC (rev 15868)
@@ -57,6 +57,7 @@
import org.hibernate.event.PreCollectionUpdateEvent;
import org.hibernate.event.PreCollectionUpdateEventListener;
import org.hibernate.persister.entity.EntityPersister;
+import org.hibernate.proxy.HibernateProxy;
/**
* @author Adam Warski (adam at warski dot org)
@@ -64,6 +65,8 @@
public class AuditEventListener implements PostInsertEventListener, PostUpdateEventListener,
PostDeleteEventListener, PreCollectionUpdateEventListener, PreCollectionRemoveEventListener,
PostCollectionRecreateEventListener, Initializable {
+ private static final long serialVersionUID = -2499904286323112715L;
+
private AuditConfiguration verCfg;
private void generateBidirectionalCollectionChangeWorkUnits(AuditSync verSync, EntityPersister entityPersister,
@@ -93,7 +96,14 @@
if (newValue != null) {
// relDesc.getToEntityName() doesn't always return the entity name of the value - in case
// of subclasses, this will be root class, no the actual class. So it can't be used here.
- String toEntityName = session.guessEntityName(newValue);
+ String toEntityName;
+ if(newValue instanceof HibernateProxy) {
+ HibernateProxy hibernateProxy = (HibernateProxy) newValue;
+ toEntityName = session.bestGuessEntityName(newValue);
+ newValue = hibernateProxy.getHibernateLazyInitializer().getImplementation();
+ } else {
+ toEntityName = session.guessEntityName(newValue);
+ }
IdMapper idMapper = verCfg.getEntCfg().get(toEntityName).getIdMapper();
@@ -102,8 +112,15 @@
}
if (oldValue != null) {
- String toEntityName = session.guessEntityName(oldValue);
-
+ String toEntityName;
+ if(oldValue instanceof HibernateProxy) {
+ HibernateProxy hibernateProxy = (HibernateProxy) oldValue;
+ toEntityName = session.bestGuessEntityName(oldValue);
+ oldValue = hibernateProxy.getHibernateLazyInitializer().getImplementation();
+ } else {
+ toEntityName = session.guessEntityName(oldValue);
+ }
+
IdMapper idMapper = verCfg.getEntCfg().get(toEntityName).getIdMapper();
Serializable id = (Serializable) idMapper.mapToIdFromEntity(oldValue);
Copied: core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/entities/components/relations/NotAuditedManyToOneComponent.java (from rev 15867, core/trunk/envers/src/test/java/org/hibernate/envers/test/entities/components/relations/NotAuditedManyToOneComponent.java)
===================================================================
--- core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/entities/components/relations/NotAuditedManyToOneComponent.java (rev 0)
+++ core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/entities/components/relations/NotAuditedManyToOneComponent.java 2009-02-03 18:30:11 UTC (rev 15868)
@@ -0,0 +1,90 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.envers.test.entities.components.relations;
+
+import org.hibernate.envers.test.entities.UnversionedStrTestEntity;
+import org.hibernate.envers.NotAudited;
+
+import javax.persistence.ManyToOne;
+import javax.persistence.Embeddable;
+
+/**
+ * @author Adam Warski (adam at warski dot org)
+ */
+@Embeddable
+public class NotAuditedManyToOneComponent {
+ @ManyToOne
+ @NotAudited
+ private UnversionedStrTestEntity entity;
+
+ private String data;
+
+ public NotAuditedManyToOneComponent(UnversionedStrTestEntity entity, String data) {
+ this.entity = entity;
+ this.data = data;
+ }
+
+ public NotAuditedManyToOneComponent() {
+ }
+
+ public String getData() {
+ return data;
+ }
+
+ public void setData(String data) {
+ this.data = data;
+ }
+
+ public UnversionedStrTestEntity getEntity() {
+ return entity;
+ }
+
+ public void setEntity(UnversionedStrTestEntity entity) {
+ this.entity = entity;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ NotAuditedManyToOneComponent that = (NotAuditedManyToOneComponent) o;
+
+ if (data != null ? !data.equals(that.data) : that.data != null) return false;
+ if (entity != null ? !entity.equals(that.entity) : that.entity != null) return false;
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = entity != null ? entity.hashCode() : 0;
+ result = 31 * result + (data != null ? data.hashCode() : 0);
+ return result;
+ }
+
+ public String toString() {
+ return "NotAuditedManyToOneComponent(str1 = " + data + ")";
+ }
+}
\ No newline at end of file
Copied: core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/entities/components/relations/NotAuditedManyToOneComponentTestEntity.java (from rev 15867, core/trunk/envers/src/test/java/org/hibernate/envers/test/entities/components/relations/NotAuditedManyToOneComponentTestEntity.java)
===================================================================
--- core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/entities/components/relations/NotAuditedManyToOneComponentTestEntity.java (rev 0)
+++ core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/entities/components/relations/NotAuditedManyToOneComponentTestEntity.java 2009-02-03 18:30:11 UTC (rev 15868)
@@ -0,0 +1,97 @@
+/*
+ * 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.envers.test.entities.components.relations;
+
+import javax.persistence.Embedded;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+
+import org.hibernate.envers.Audited;
+
+/**
+ * @author Adam Warski (adam at warski dot org)
+ */
+@Entity
+public class NotAuditedManyToOneComponentTestEntity {
+ @Id
+ @GeneratedValue
+ private Integer id;
+
+ @Embedded
+ @Audited
+ private NotAuditedManyToOneComponent comp1;
+
+ public NotAuditedManyToOneComponentTestEntity() {
+ }
+
+ public NotAuditedManyToOneComponentTestEntity(Integer id, NotAuditedManyToOneComponent comp1) {
+ this.id = id;
+ this.comp1 = comp1;
+ }
+
+ public NotAuditedManyToOneComponentTestEntity(NotAuditedManyToOneComponent comp1) {
+ this.comp1 = comp1;
+ }
+
+ public Integer getId() {
+ return id;
+ }
+
+ public void setId(Integer id) {
+ this.id = id;
+ }
+
+ public NotAuditedManyToOneComponent getComp1() {
+ return comp1;
+ }
+
+ public void setComp1(NotAuditedManyToOneComponent comp1) {
+ this.comp1 = comp1;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ NotAuditedManyToOneComponentTestEntity that = (NotAuditedManyToOneComponentTestEntity) o;
+
+ if (comp1 != null ? !comp1.equals(that.comp1) : that.comp1 != null) return false;
+ if (id != null ? !id.equals(that.id) : that.id != null) return false;
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = id != null ? id.hashCode() : 0;
+ result = 31 * result + (comp1 != null ? comp1.hashCode() : 0);
+ return result;
+ }
+
+ public String toString() {
+ return "NAMTOCTE(id = " + id + ", comp1 = " + comp1 + ")";
+ }
+}
\ No newline at end of file
Copied: core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/accesstype/Country.java (from rev 15867, core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/accesstype/Country.java)
===================================================================
--- core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/accesstype/Country.java (rev 0)
+++ core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/accesstype/Country.java 2009-02-03 18:30:11 UTC (rev 15868)
@@ -0,0 +1,72 @@
+package org.hibernate.envers.test.integration.accesstype;
+
+import org.hibernate.envers.Audited;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+
+@Entity
+@Audited
+public class Country {
+ @Id
+ @Column(length = 4)
+ private Integer code;
+
+ @Column(length = 40)
+ private String name;
+
+ /**
+ * Default constructor for persistence provider.
+ */
+ @SuppressWarnings({"UnusedDeclaration"})
+ private Country() { }
+
+ private Country(Integer code, String naam) {
+ this.code = code;
+ this.name = naam;
+ }
+
+ public Integer getCode() {
+ return code;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public static Country of(Integer code, String name) {
+ return new Country(code, name);
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((code == null) ? 0 : code.hashCode());
+ result = prime * result + ((name == null) ? 0 : name.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ Country other = (Country) obj;
+ if (code == null) {
+ if (other.code != null)
+ return false;
+ } else if (!code.equals(other.code))
+ return false;
+ if (name == null) {
+ if (other.name != null)
+ return false;
+ } else if (!name.equals(other.name))
+ return false;
+ return true;
+ }
+}
Copied: core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/accesstype/ImmutableClassAccessType.java (from rev 15867, core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/accesstype/ImmutableClassAccessType.java)
===================================================================
--- core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/accesstype/ImmutableClassAccessType.java (rev 0)
+++ core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/accesstype/ImmutableClassAccessType.java 2009-02-03 18:30:11 UTC (rev 15868)
@@ -0,0 +1,50 @@
+package org.hibernate.envers.test.integration.accesstype;
+
+import java.util.Arrays;
+
+import javax.persistence.EntityManager;
+
+import org.hibernate.ejb.Ejb3Configuration;
+import org.hibernate.envers.test.AbstractEntityTest;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+import static org.testng.Assert.assertEquals;
+
+public class ImmutableClassAccessType extends AbstractEntityTest {
+ private Country country;
+
+ public void configure(Ejb3Configuration cfg) {
+ cfg.addAnnotatedClass(Country.class);
+ }
+
+ @BeforeClass(dependsOnMethods = "init")
+ public void initData() {
+ EntityManager em = getEntityManager();
+
+ // Revision 1
+ em.getTransaction().begin();
+ country = Country.of(123, "Germany");
+ em.persist(country);
+ em.getTransaction().commit();
+
+ }
+
+ @Test
+ public void testRevisionsCounts() {
+ assert Arrays.asList(1)
+ .equals(
+ getAuditReader().getRevisions(Country.class,
+ country.getCode()));
+ }
+
+ @Test
+ public void testHistoryOfId1() {
+ Country country1 = getEntityManager().find(Country.class,
+ country.getCode());
+ assertEquals(country1, country);
+
+ Country history = getAuditReader().find(Country.class, country1.getCode(), 1);
+ assertEquals(country, history);
+ }
+
+}
\ No newline at end of file
Copied: core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/components/relations/NotAuditedManyToOneInComponent.java (from rev 15867, core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/components/relations/NotAuditedManyToOneInComponent.java)
===================================================================
--- core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/components/relations/NotAuditedManyToOneInComponent.java (rev 0)
+++ core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/components/relations/NotAuditedManyToOneInComponent.java 2009-02-03 18:30:11 UTC (rev 15868)
@@ -0,0 +1,113 @@
+/*
+ * 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.envers.test.integration.components.relations;
+
+import java.util.Arrays;
+import javax.persistence.EntityManager;
+
+import org.hibernate.envers.test.AbstractEntityTest;
+import org.hibernate.envers.test.entities.components.relations.NotAuditedManyToOneComponentTestEntity;
+import org.hibernate.envers.test.entities.components.relations.NotAuditedManyToOneComponent;
+import org.hibernate.envers.test.entities.UnversionedStrTestEntity;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import org.hibernate.ejb.Ejb3Configuration;
+
+/**
+ * @author Adam Warski (adam at warski dot org)
+ */
+public class NotAuditedManyToOneInComponent extends AbstractEntityTest {
+ private Integer mtocte_id1;
+
+ public void configure(Ejb3Configuration cfg) {
+ cfg.addAnnotatedClass(NotAuditedManyToOneComponentTestEntity.class);
+ cfg.addAnnotatedClass(UnversionedStrTestEntity.class);
+ }
+
+ @BeforeClass(dependsOnMethods = "init")
+ public void initData() {
+ // No revision
+ EntityManager em = getEntityManager();
+ em.getTransaction().begin();
+
+ UnversionedStrTestEntity ste1 = new UnversionedStrTestEntity();
+ ste1.setStr("str1");
+
+ UnversionedStrTestEntity ste2 = new UnversionedStrTestEntity();
+ ste2.setStr("str2");
+
+ em.persist(ste1);
+ em.persist(ste2);
+
+ em.getTransaction().commit();
+
+ // Revision 1
+ em = getEntityManager();
+ em.getTransaction().begin();
+
+ NotAuditedManyToOneComponentTestEntity mtocte1 = new NotAuditedManyToOneComponentTestEntity(
+ new NotAuditedManyToOneComponent(ste1, "data1"));
+
+ em.persist(mtocte1);
+
+ em.getTransaction().commit();
+
+ // No revision
+ em = getEntityManager();
+ em.getTransaction().begin();
+
+ mtocte1 = em.find(NotAuditedManyToOneComponentTestEntity.class, mtocte1.getId());
+ mtocte1.getComp1().setEntity(ste2);
+
+ em.getTransaction().commit();
+
+ // Revision 2
+ em = getEntityManager();
+ em.getTransaction().begin();
+
+ mtocte1 = em.find(NotAuditedManyToOneComponentTestEntity.class, mtocte1.getId());
+ mtocte1.getComp1().setData("data2");
+
+ em.getTransaction().commit();
+
+ mtocte_id1 = mtocte1.getId();
+ }
+
+ @Test
+ public void testRevisionsCounts() {
+ assert Arrays.asList(1, 2).equals(getAuditReader().getRevisions(NotAuditedManyToOneComponentTestEntity.class, mtocte_id1));
+ }
+
+ @Test
+ public void testHistoryOfId1() {
+ NotAuditedManyToOneComponentTestEntity ver1 = new NotAuditedManyToOneComponentTestEntity(mtocte_id1,
+ new NotAuditedManyToOneComponent(null, "data1"));
+ NotAuditedManyToOneComponentTestEntity ver2 = new NotAuditedManyToOneComponentTestEntity(mtocte_id1,
+ new NotAuditedManyToOneComponent(null, "data2"));
+
+ assert getAuditReader().find(NotAuditedManyToOneComponentTestEntity.class, mtocte_id1, 1).equals(ver1);
+ assert getAuditReader().find(NotAuditedManyToOneComponentTestEntity.class, mtocte_id1, 2).equals(ver2);
+ }
+}
\ No newline at end of file
[View Less]
16 years
Hibernate SVN: r15867 - core/branches/Branch_3_3/core/src/main/java/org/hibernate/hql/ast/tree.
by hibernate-commits@lists.jboss.org
Author: steve.ebersole(a)jboss.com
Date: 2009-02-03 09:23:14 -0500 (Tue, 03 Feb 2009)
New Revision: 15867
Modified:
core/branches/Branch_3_3/core/src/main/java/org/hibernate/hql/ast/tree/DotNode.java
Log:
HHH-3749 : limit FromElement reuse based on alias
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/…
[View More]DotNode.java 2009-02-03 14:22:51 UTC (rev 15866)
+++ core/branches/Branch_3_3/core/src/main/java/org/hibernate/hql/ast/tree/DotNode.java 2009-02-03 14:23:14 UTC (rev 15867)
@@ -434,7 +434,13 @@
//
///////////////////////////////////////////////////////////////////////////////
- if ( elem == null ) {
+ boolean found = elem != null;
+ // even though we might find a pre-existing element by join path, for FromElements originating in a from-clause
+ // we should only ever use the found element if the aliases match (null != null here). Implied joins are
+ // always (?) ok to reuse.
+ boolean useFoundFromElement = found && ( elem.isImplied() || areSame( classAlias, elem.getClassAlias() ) );
+
+ if ( ! useFoundFromElement ) {
// If this is an implied join in a from element, then use the impled join type which is part of the
// tree parser's state (set by the gramamar actions).
JoinSequence joinSequence = getSessionFactoryHelper()
@@ -458,13 +464,19 @@
);
}
else {
- currentFromClause.addDuplicateAlias(classAlias, elem);
+ // NOTE : addDuplicateAlias() already performs nullness checks on the alias.
+ currentFromClause.addDuplicateAlias( classAlias, elem );
}
setImpliedJoin( elem );
getWalker().addQuerySpaces( elem.getEntityPersister().getQuerySpaces() );
setFromElement( elem ); // This 'dot' expression now refers to the resulting from element.
}
+ private boolean areSame(String alias1, String alias2) {
+ // again, null != null here
+ return !StringHelper.isEmpty( alias1 ) && !StringHelper.isEmpty( alias2 ) && alias1.equals( alias2 );
+ }
+
private void setImpliedJoin(FromElement elem) {
this.impliedJoin = elem;
if ( getFirstChild().getType() == SqlTokenTypes.DOT ) {
[View Less]
16 years
Hibernate SVN: r15866 - core/trunk/core/src/main/java/org/hibernate/hql/ast/tree.
by hibernate-commits@lists.jboss.org
Author: steve.ebersole(a)jboss.com
Date: 2009-02-03 09:22:51 -0500 (Tue, 03 Feb 2009)
New Revision: 15866
Modified:
core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/DotNode.java
Log:
HHH-3749 : limit FromElement reuse based on alias
Modified: core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/DotNode.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/DotNode.java 2009-02-03 14:20:50 UTC (rev …
[View More]15865)
+++ core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/DotNode.java 2009-02-03 14:22:51 UTC (rev 15866)
@@ -434,7 +434,13 @@
//
///////////////////////////////////////////////////////////////////////////////
- if ( elem == null ) {
+ boolean found = elem != null;
+ // even though we might find a pre-existing element by join path, for FromElements originating in a from-clause
+ // we should only ever use the found element if the aliases match (null != null here). Implied joins are
+ // always (?) ok to reuse.
+ boolean useFoundFromElement = found && ( elem.isImplied() || areSame( classAlias, elem.getClassAlias() ) );
+
+ if ( ! useFoundFromElement ) {
// If this is an implied join in a from element, then use the impled join type which is part of the
// tree parser's state (set by the gramamar actions).
JoinSequence joinSequence = getSessionFactoryHelper()
@@ -458,13 +464,19 @@
);
}
else {
- currentFromClause.addDuplicateAlias(classAlias, elem);
+ // NOTE : addDuplicateAlias() already performs nullness checks on the alias.
+ currentFromClause.addDuplicateAlias( classAlias, elem );
}
setImpliedJoin( elem );
getWalker().addQuerySpaces( elem.getEntityPersister().getQuerySpaces() );
setFromElement( elem ); // This 'dot' expression now refers to the resulting from element.
}
+ private boolean areSame(String alias1, String alias2) {
+ // again, null != null here
+ return !StringHelper.isEmpty( alias1 ) && !StringHelper.isEmpty( alias2 ) && alias1.equals( alias2 );
+ }
+
private void setImpliedJoin(FromElement elem) {
this.impliedJoin = elem;
if ( getFirstChild().getType() == SqlTokenTypes.DOT ) {
[View Less]
16 years
Hibernate SVN: r15865 - core/branches/Branch_3_2/src/org/hibernate/hql/ast/tree.
by hibernate-commits@lists.jboss.org
Author: steve.ebersole(a)jboss.com
Date: 2009-02-03 09:20:50 -0500 (Tue, 03 Feb 2009)
New Revision: 15865
Modified:
core/branches/Branch_3_2/src/org/hibernate/hql/ast/tree/DotNode.java
Log:
HHH-3749 : limit FromElement reuse based on alias
Modified: core/branches/Branch_3_2/src/org/hibernate/hql/ast/tree/DotNode.java
===================================================================
--- core/branches/Branch_3_2/src/org/hibernate/hql/ast/tree/DotNode.java 2009-02-03 01:16:57 UTC (rev 15864)…
[View More]
+++ core/branches/Branch_3_2/src/org/hibernate/hql/ast/tree/DotNode.java 2009-02-03 14:20:50 UTC (rev 15865)
@@ -411,7 +411,13 @@
//
///////////////////////////////////////////////////////////////////////////////
- if ( elem == null ) {
+ boolean found = elem != null;
+ // even though we might find a pre-existing element by join path, for FromElements originating in a from-clause
+ // we should only ever use the found element if the aliases match (null != null here). Implied joins are
+ // always (?) ok to reuse.
+ boolean useFoundFromElement = found && ( elem.isImplied() || areSame( classAlias, elem.getClassAlias() ) );
+
+ if ( ! useFoundFromElement ) {
// If this is an implied join in a from element, then use the impled join type which is part of the
// tree parser's state (set by the gramamar actions).
JoinSequence joinSequence = getSessionFactoryHelper()
@@ -435,13 +441,19 @@
);
}
else {
- currentFromClause.addDuplicateAlias(classAlias, elem);
+ // NOTE : addDuplicateAlias() already performs nullness checks on the alias.
+ currentFromClause.addDuplicateAlias( classAlias, elem );
}
setImpliedJoin( elem );
getWalker().addQuerySpaces( elem.getEntityPersister().getQuerySpaces() );
setFromElement( elem ); // This 'dot' expression now refers to the resulting from element.
}
+ private boolean areSame(String alias1, String alias2) {
+ // again, null != null here
+ return !StringHelper.isEmpty( alias1 ) && !StringHelper.isEmpty( alias2 ) && alias1.equals( alias2 );
+ }
+
private void setImpliedJoin(FromElement elem) {
this.impliedJoin = elem;
if ( getFirstChild().getType() == SqlTokenTypes.DOT ) {
[View Less]
16 years
Hibernate SVN: r15864 - in core/branches/Branch_3_2/src/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:16:57 -0500 (Mon, 02 Feb 2009)
New Revision: 15864
Modified:
core/branches/Branch_3_2/src/org/hibernate/engine/StatefulPersistenceContext.java
core/branches/Branch_3_2/src/org/hibernate/event/def/DefaultEvictEventListener.java
core/branches/Branch_3_2/src/org/hibernate/proxy/AbstractLazyInitializer.java
core/branches/Branch_3_2/src/org/hibernate/proxy/LazyInitializer.java
Log:
HHH-3357 : clear() performance
Modified: core/…
[View More]branches/Branch_3_2/src/org/hibernate/engine/StatefulPersistenceContext.java
===================================================================
--- core/branches/Branch_3_2/src/org/hibernate/engine/StatefulPersistenceContext.java 2009-02-03 01:15:58 UTC (rev 15863)
+++ core/branches/Branch_3_2/src/org/hibernate/engine/StatefulPersistenceContext.java 2009-02-03 01:16:57 UTC (rev 15864)
@@ -181,7 +181,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_2/src/org/hibernate/event/def/DefaultEvictEventListener.java
===================================================================
--- core/branches/Branch_3_2/src/org/hibernate/event/def/DefaultEvictEventListener.java 2009-02-03 01:15:58 UTC (rev 15863)
+++ core/branches/Branch_3_2/src/org/hibernate/event/def/DefaultEvictEventListener.java 2009-02-03 01:16:57 UTC (rev 15864)
@@ -58,7 +58,7 @@
doEvict( entity, key, e.getPersister(), event.getSession() );
}
}
- li.setSession( null );
+ li.unsetSession();
}
else {
EntityEntry e = persistenceContext.removeEntry( object );
Modified: core/branches/Branch_3_2/src/org/hibernate/proxy/AbstractLazyInitializer.java
===================================================================
--- core/branches/Branch_3_2/src/org/hibernate/proxy/AbstractLazyInitializer.java 2009-02-03 01:15:58 UTC (rev 15863)
+++ core/branches/Branch_3_2/src/org/hibernate/proxy/AbstractLazyInitializer.java 2009-02-03 01:16:57 UTC (rev 15864)
@@ -4,59 +4,104 @@
import org.hibernate.HibernateException;
import org.hibernate.LazyInitializationException;
-import org.hibernate.ObjectNotFoundException;
import org.hibernate.engine.EntityKey;
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 ) {
@@ -87,28 +132,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() &&
session.getPersistenceContext().containsProxy(this);
}
-
- public final void setImplementation(Object target) {
- this.target = target;
- initialized = true;
- }
/**
* Return the underlying persistent object, initializing if necessary
@@ -117,6 +150,14 @@
initialize();
return target;
}
+
+ /**
+ * {@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,
@@ -127,18 +168,31 @@
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_2/src/org/hibernate/proxy/LazyInitializer.java
===================================================================
--- core/branches/Branch_3_2/src/org/hibernate/proxy/LazyInitializer.java 2009-02-03 01:15:58 UTC (rev 15863)
+++ core/branches/Branch_3_2/src/org/hibernate/proxy/LazyInitializer.java 2009-02-03 01:16:57 UTC (rev 15864)
@@ -8,67 +8,108 @@
/**
* 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();
[View Less]
16 years
Hibernate SVN: r15863 - in core/trunk/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:15:58 -0500 (Mon, 02 Feb 2009)
New Revision: 15863
Modified:
core/trunk/core/src/main/java/org/hibernate/engine/StatefulPersistenceContext.java
core/trunk/core/src/main/java/org/hibernate/event/def/DefaultEvictEventListener.java
core/trunk/core/src/main/java/org/hibernate/proxy/AbstractLazyInitializer.java
core/trunk/core/src/main/java/org/hibernate/proxy/LazyInitializer.java
Log:
HHH-3357 : clear() performance
Modified: core/…
[View More]trunk/core/src/main/java/org/hibernate/engine/StatefulPersistenceContext.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/engine/StatefulPersistenceContext.java 2009-02-03 01:14:53 UTC (rev 15862)
+++ core/trunk/core/src/main/java/org/hibernate/engine/StatefulPersistenceContext.java 2009-02-03 01:15:58 UTC (rev 15863)
@@ -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/trunk/core/src/main/java/org/hibernate/event/def/DefaultEvictEventListener.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/event/def/DefaultEvictEventListener.java 2009-02-03 01:14:53 UTC (rev 15862)
+++ core/trunk/core/src/main/java/org/hibernate/event/def/DefaultEvictEventListener.java 2009-02-03 01:15:58 UTC (rev 15863)
@@ -83,7 +83,7 @@
doEvict( entity, key, e.getPersister(), event.getSession() );
}
}
- li.setSession( null );
+ li.unsetSession();
}
else {
EntityEntry e = persistenceContext.removeEntry( object );
Modified: core/trunk/core/src/main/java/org/hibernate/proxy/AbstractLazyInitializer.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/proxy/AbstractLazyInitializer.java 2009-02-03 01:14:53 UTC (rev 15862)
+++ core/trunk/core/src/main/java/org/hibernate/proxy/AbstractLazyInitializer.java 2009-02-03 01:15:58 UTC (rev 15863)
@@ -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/trunk/core/src/main/java/org/hibernate/proxy/LazyInitializer.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/proxy/LazyInitializer.java 2009-02-03 01:14:53 UTC (rev 15862)
+++ core/trunk/core/src/main/java/org/hibernate/proxy/LazyInitializer.java 2009-02-03 01:15:58 UTC (rev 15863)
@@ -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