HHH-12511 Make ASTPrinter threadsafe and have code reuse their instances
This commit is contained in:
parent
782f023a5a
commit
0546eaac3b
|
@ -20,6 +20,7 @@ import org.hibernate.hql.internal.antlr.HqlBaseParser;
|
|||
import org.hibernate.hql.internal.antlr.HqlTokenTypes;
|
||||
import org.hibernate.hql.internal.ast.util.ASTPrinter;
|
||||
import org.hibernate.hql.internal.ast.util.ASTUtil;
|
||||
import org.hibernate.hql.internal.ast.util.TokenPrinters;
|
||||
import org.hibernate.internal.CoreLogging;
|
||||
import org.hibernate.internal.CoreMessageLogger;
|
||||
import org.hibernate.internal.util.StringHelper;
|
||||
|
@ -41,11 +42,6 @@ public final class HqlParser extends HqlBaseParser {
|
|||
private static final CoreMessageLogger LOG = CoreLogging.messageLogger( HqlParser.class );
|
||||
|
||||
private final ParseErrorHandler parseErrorHandler;
|
||||
private final ASTPrinter printer = getASTPrinter();
|
||||
|
||||
private static ASTPrinter getASTPrinter() {
|
||||
return new ASTPrinter( org.hibernate.hql.internal.antlr.HqlTokenTypes.class );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a HqlParser instance for the given HQL string.
|
||||
|
@ -362,7 +358,7 @@ public final class HqlParser extends HqlBaseParser {
|
|||
}
|
||||
|
||||
private void showAst(AST ast, PrintWriter pw) {
|
||||
printer.showAst( ast, pw );
|
||||
TokenPrinters.HQL_TOKEN_PRINTER.showAst( ast, pw );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -65,6 +65,7 @@ import org.hibernate.hql.internal.ast.util.LiteralProcessor;
|
|||
import org.hibernate.hql.internal.ast.util.NodeTraverser;
|
||||
import org.hibernate.hql.internal.ast.util.SessionFactoryHelper;
|
||||
import org.hibernate.hql.internal.ast.util.SyntheticAndFactory;
|
||||
import org.hibernate.hql.internal.ast.util.TokenPrinters;
|
||||
import org.hibernate.hql.spi.QueryTranslator;
|
||||
import org.hibernate.id.BulkInsertionCapableIdentifierGenerator;
|
||||
import org.hibernate.id.IdentifierGenerator;
|
||||
|
@ -118,7 +119,6 @@ public class HqlSqlWalker extends HqlSqlBaseWalker implements ErrorReporter, Par
|
|||
private final AliasGenerator aliasGenerator = new AliasGenerator();
|
||||
private final LiteralProcessor literalProcessor;
|
||||
private final ParseErrorHandler parseErrorHandler;
|
||||
private final ASTPrinter printer;
|
||||
private final String collectionFilterRole;
|
||||
|
||||
private FromClause currentFromClause;
|
||||
|
@ -171,7 +171,6 @@ public class HqlSqlWalker extends HqlSqlBaseWalker implements ErrorReporter, Par
|
|||
this.tokenReplacements = tokenReplacements;
|
||||
this.collectionFilterRole = collectionRole;
|
||||
this.hqlParser = parser;
|
||||
this.printer = new ASTPrinter( SqlTokenTypes.class );
|
||||
}
|
||||
|
||||
// handle trace logging ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
@ -194,7 +193,7 @@ public class HqlSqlWalker extends HqlSqlBaseWalker implements ErrorReporter, Par
|
|||
private String buildTraceNodeName(AST tree) {
|
||||
return tree == null
|
||||
? "???"
|
||||
: tree.getText() + " [" + printer.getTokenTypeName( tree.getType() ) + "]";
|
||||
: tree.getText() + " [" + TokenPrinters.SQL_TOKEN_PRINTER.getTokenTypeName( tree.getType() ) + "]";
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1337,7 +1336,7 @@ public class HqlSqlWalker extends HqlSqlBaseWalker implements ErrorReporter, Par
|
|||
}
|
||||
|
||||
public ASTPrinter getASTPrinter() {
|
||||
return printer;
|
||||
return TokenPrinters.SQL_TOKEN_PRINTER;
|
||||
}
|
||||
|
||||
public ArrayList<ParameterSpecification> getParameterSpecs() {
|
||||
|
|
|
@ -42,6 +42,7 @@ import org.hibernate.hql.internal.ast.tree.UpdateStatement;
|
|||
import org.hibernate.hql.internal.ast.util.ASTPrinter;
|
||||
import org.hibernate.hql.internal.ast.util.ASTUtil;
|
||||
import org.hibernate.hql.internal.ast.util.NodeTraverser;
|
||||
import org.hibernate.hql.internal.ast.util.TokenPrinters;
|
||||
import org.hibernate.hql.spi.FilterTranslator;
|
||||
import org.hibernate.hql.spi.ParameterTranslations;
|
||||
import org.hibernate.internal.CoreMessageLogger;
|
||||
|
@ -262,8 +263,6 @@ public class QueryTranslatorImpl implements FilterTranslator {
|
|||
}
|
||||
}
|
||||
|
||||
private static final ASTPrinter SQL_TOKEN_PRINTER = new ASTPrinter( SqlTokenTypes.class );
|
||||
|
||||
private HqlSqlWalker analyze(HqlParser parser, String collectionRole) throws QueryException, RecognitionException {
|
||||
final HqlSqlWalker w = new HqlSqlWalker( this, factory, parser, tokenReplacements, collectionRole );
|
||||
final AST hqlAst = parser.getAST();
|
||||
|
@ -272,7 +271,7 @@ public class QueryTranslatorImpl implements FilterTranslator {
|
|||
w.statement( hqlAst );
|
||||
|
||||
if ( LOG.isDebugEnabled() ) {
|
||||
LOG.debug( SQL_TOKEN_PRINTER.showAsString( w.getAST(), "--- SQL AST ---" ) );
|
||||
LOG.debug( TokenPrinters.SQL_TOKEN_PRINTER.showAsString( w.getAST(), "--- SQL AST ---" ) );
|
||||
}
|
||||
|
||||
w.getParseErrorHandler().throwQueryException();
|
||||
|
@ -304,11 +303,9 @@ public class QueryTranslatorImpl implements FilterTranslator {
|
|||
return parser;
|
||||
}
|
||||
|
||||
private static final ASTPrinter HQL_TOKEN_PRINTER = new ASTPrinter( HqlTokenTypes.class );
|
||||
|
||||
void showHqlAst(AST hqlAst) {
|
||||
if ( LOG.isDebugEnabled() ) {
|
||||
LOG.debug( HQL_TOKEN_PRINTER.showAsString( hqlAst, "--- HQL AST ---" ) );
|
||||
LOG.debug( TokenPrinters.HQL_TOKEN_PRINTER.showAsString( hqlAst, "--- HQL AST ---" ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@ import org.hibernate.hql.internal.ast.tree.Node;
|
|||
import org.hibernate.hql.internal.ast.tree.ParameterContainer;
|
||||
import org.hibernate.hql.internal.ast.tree.ParameterNode;
|
||||
import org.hibernate.hql.internal.ast.util.ASTPrinter;
|
||||
import org.hibernate.hql.internal.ast.util.TokenPrinters;
|
||||
import org.hibernate.internal.CoreLogging;
|
||||
import org.hibernate.internal.CoreMessageLogger;
|
||||
import org.hibernate.internal.util.StringHelper;
|
||||
|
@ -57,7 +58,6 @@ public class SqlGenerator extends SqlGeneratorBase implements ErrorReporter {
|
|||
private ParseErrorHandler parseErrorHandler;
|
||||
private SessionFactoryImplementor sessionFactory;
|
||||
private LinkedList<SqlWriter> outputStack = new LinkedList<SqlWriter>();
|
||||
private final ASTPrinter printer = new ASTPrinter( SqlTokenTypes.class );
|
||||
private List<ParameterSpecification> collectedParameters = new ArrayList<ParameterSpecification>();
|
||||
|
||||
|
||||
|
@ -81,7 +81,7 @@ public class SqlGenerator extends SqlGeneratorBase implements ErrorReporter {
|
|||
private String buildTraceNodeName(AST tree) {
|
||||
return tree == null
|
||||
? "???"
|
||||
: tree.getText() + " [" + printer.getTokenTypeName( tree.getType() ) + "]";
|
||||
: tree.getText() + " [" + TokenPrinters.SQL_TOKEN_PRINTER.getTokenTypeName( tree.getType() ) + "]";
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -16,6 +16,7 @@ import org.hibernate.hql.internal.antlr.SqlTokenTypes;
|
|||
import org.hibernate.hql.internal.ast.util.ASTAppender;
|
||||
import org.hibernate.hql.internal.ast.util.ASTIterator;
|
||||
import org.hibernate.hql.internal.ast.util.ASTPrinter;
|
||||
import org.hibernate.hql.internal.ast.util.TokenPrinters;
|
||||
import org.hibernate.type.Type;
|
||||
|
||||
import antlr.SemanticException;
|
||||
|
@ -157,7 +158,7 @@ public class SelectClause extends SelectExpressionList {
|
|||
if ( type == null ) {
|
||||
throw new QueryException(
|
||||
"No data type for node: " + selectExpression.getClass().getName() + " "
|
||||
+ new ASTPrinter( SqlTokenTypes.class ).showAsString( (AST) selectExpression, "" )
|
||||
+ TokenPrinters.SQL_TOKEN_PRINTER.showAsString( (AST) selectExpression, "" )
|
||||
);
|
||||
}
|
||||
//sqlResultTypeList.add( type );
|
||||
|
|
|
@ -11,6 +11,7 @@ import java.util.List;
|
|||
|
||||
import org.hibernate.hql.internal.antlr.SqlTokenTypes;
|
||||
import org.hibernate.hql.internal.ast.util.ASTPrinter;
|
||||
import org.hibernate.hql.internal.ast.util.TokenPrinters;
|
||||
|
||||
import antlr.collections.AST;
|
||||
|
||||
|
@ -44,7 +45,7 @@ public abstract class SelectExpressionList extends HqlSqlWalkerNode {
|
|||
else {
|
||||
throw new IllegalStateException(
|
||||
"Unexpected AST: " + n.getClass().getName() + " "
|
||||
+ new ASTPrinter( SqlTokenTypes.class ).showAsString( n, "" )
|
||||
+ TokenPrinters.SQL_TOKEN_PRINTER.showAsString( n, "" )
|
||||
);
|
||||
}
|
||||
p++;
|
||||
|
|
|
@ -20,52 +20,24 @@ import antlr.collections.AST;
|
|||
/**
|
||||
* Utility for generating pretty "ASCII art" representations of syntax trees.
|
||||
*
|
||||
* This class is threadsafe: reuse instances as needed.
|
||||
*
|
||||
* @author Joshua Davis
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class ASTPrinter {
|
||||
|
||||
private final Map<Integer,String> tokenTypeNameCache;
|
||||
private final boolean showClassNames;
|
||||
|
||||
/**
|
||||
* Constructs a printer.
|
||||
* <p/>
|
||||
* Delegates to {@link #ASTPrinter(Class, boolean)} with {@link #isShowClassNames showClassNames} as <tt>true</tt>
|
||||
* Constructs a printer. Package protected: use the constants from {TokenPrinters}
|
||||
* @see TokenPrinters
|
||||
*
|
||||
* @param tokenTypeConstants The token types to use during printing; typically the {vocabulary}TokenTypes.java
|
||||
* interface generated by ANTLR.
|
||||
*/
|
||||
public ASTPrinter(Class tokenTypeConstants) {
|
||||
this( ASTUtil.generateTokenNameCache( tokenTypeConstants ), true );
|
||||
}
|
||||
|
||||
public ASTPrinter(boolean showClassNames) {
|
||||
this( (Map) null, showClassNames );
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a printer.
|
||||
*
|
||||
* @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 ASTPrinter(Class tokenTypeConstants, boolean showClassNames) {
|
||||
this( ASTUtil.generateTokenNameCache( tokenTypeConstants ), showClassNames );
|
||||
}
|
||||
|
||||
private ASTPrinter(Map<Integer,String> tokenTypeNameCache, boolean showClassNames) {
|
||||
this.tokenTypeNameCache = tokenTypeNameCache;
|
||||
this.showClassNames = showClassNames;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for property 'showClassNames'.
|
||||
*
|
||||
* @return Value for property 'showClassNames'.
|
||||
*/
|
||||
public boolean isShowClassNames() {
|
||||
return showClassNames;
|
||||
ASTPrinter(Class tokenTypeConstants) {
|
||||
this.tokenTypeNameCache = ASTUtil.generateTokenNameCache( tokenTypeConstants );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -117,10 +89,7 @@ public class ASTPrinter {
|
|||
*/
|
||||
public String getTokenTypeName(int type) {
|
||||
final Integer typeInteger = type;
|
||||
String value = null;
|
||||
if ( tokenTypeNameCache != null ) {
|
||||
value = tokenTypeNameCache.get( typeInteger );
|
||||
}
|
||||
String value = tokenTypeNameCache.get( typeInteger );
|
||||
if ( value == null ) {
|
||||
value = typeInteger.toString();
|
||||
}
|
||||
|
@ -161,19 +130,17 @@ public class ASTPrinter {
|
|||
}
|
||||
|
||||
private void showNode(PrintWriter pw, AST ast) {
|
||||
String s = nodeToString( ast, isShowClassNames() );
|
||||
String s = nodeToString( ast );
|
||||
pw.println( s );
|
||||
}
|
||||
|
||||
public String nodeToString(AST ast, boolean showClassName) {
|
||||
public String nodeToString(AST ast) {
|
||||
if ( ast == null ) {
|
||||
return "{node:null}";
|
||||
}
|
||||
StringBuilder buf = new StringBuilder();
|
||||
buf.append( "[" ).append( getTokenTypeName( ast.getType() ) ).append( "] " );
|
||||
if ( showClassName ) {
|
||||
buf.append( StringHelper.unqualify( ast.getClass().getName() ) ).append( ": " );
|
||||
}
|
||||
buf.append( StringHelper.unqualify( ast.getClass().getName() ) ).append( ": " );
|
||||
|
||||
buf.append( "'" );
|
||||
String text = ast.getText();
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
package org.hibernate.hql.internal.ast.util;
|
||||
|
||||
import org.hibernate.hql.internal.antlr.HqlTokenTypes;
|
||||
import org.hibernate.hql.internal.antlr.SqlTokenTypes;
|
||||
import org.hibernate.sql.ordering.antlr.GeneratedOrderByFragmentRendererTokenTypes;
|
||||
|
||||
/**
|
||||
* Commonly used token printers expressed as constants.
|
||||
*/
|
||||
public interface TokenPrinters {
|
||||
|
||||
ASTPrinter HQL_TOKEN_PRINTER = new ASTPrinter( HqlTokenTypes.class );
|
||||
|
||||
ASTPrinter SQL_TOKEN_PRINTER = new ASTPrinter( SqlTokenTypes.class );
|
||||
|
||||
ASTPrinter ORDERBY_FRAGMENT_PRINTER = new ASTPrinter( GeneratedOrderByFragmentRendererTokenTypes.class );
|
||||
|
||||
}
|
|
@ -9,6 +9,7 @@ package org.hibernate.sql.ordering.antlr;
|
|||
import org.hibernate.NullPrecedence;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.hql.internal.ast.util.ASTPrinter;
|
||||
import org.hibernate.hql.internal.ast.util.TokenPrinters;
|
||||
import org.hibernate.internal.util.StringHelper;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
@ -25,7 +26,6 @@ import antlr.collections.AST;
|
|||
public class OrderByFragmentRenderer extends GeneratedOrderByFragmentRenderer {
|
||||
|
||||
private static final Logger LOG = Logger.getLogger( OrderByFragmentRenderer.class.getName() );
|
||||
private static final ASTPrinter printer = new ASTPrinter( GeneratedOrderByFragmentRendererTokenTypes.class );
|
||||
|
||||
private final SessionFactoryImplementor sessionFactory;
|
||||
|
||||
|
@ -56,7 +56,7 @@ public class OrderByFragmentRenderer extends GeneratedOrderByFragmentRenderer {
|
|||
private String buildTraceNodeName(AST tree) {
|
||||
return tree == null
|
||||
? "???"
|
||||
: tree.getText() + " [" + printer.getTokenTypeName( tree.getType() ) + "]";
|
||||
: tree.getText() + " [" + TokenPrinters.ORDERBY_FRAGMENT_PRINTER.getTokenTypeName( tree.getType() ) + "]";
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -11,6 +11,7 @@ import java.util.Set;
|
|||
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.hql.internal.ast.util.ASTPrinter;
|
||||
import org.hibernate.hql.internal.ast.util.TokenPrinters;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
|
@ -55,8 +56,7 @@ public class OrderByFragmentTranslator {
|
|||
}
|
||||
|
||||
if ( LOG.isTraceEnabled() ) {
|
||||
ASTPrinter printer = new ASTPrinter( OrderByTemplateTokenTypes.class );
|
||||
LOG.trace( printer.showAsString( parser.getAST(), "--- {order-by fragment} ---" ) );
|
||||
LOG.trace( TokenPrinters.ORDERBY_FRAGMENT_PRINTER.showAsString( parser.getAST(), "--- {order-by fragment} ---" ) );
|
||||
}
|
||||
|
||||
// Render the parsed tree to text.
|
||||
|
|
|
@ -18,6 +18,8 @@ import org.hibernate.hql.internal.ast.util.ASTIterator;
|
|||
import org.hibernate.hql.internal.ast.util.ASTParentsFirstIterator;
|
||||
import org.hibernate.hql.internal.ast.util.ASTPrinter;
|
||||
import org.hibernate.hql.internal.ast.util.ASTUtil;
|
||||
import org.hibernate.hql.internal.ast.util.TokenPrinters;
|
||||
|
||||
import org.hibernate.testing.junit4.BaseUnitTestCase;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
@ -36,7 +38,7 @@ public class ASTIteratorTest extends BaseUnitTestCase {
|
|||
HqlParser parser = HqlParser.getInstance( input );
|
||||
parser.statement();
|
||||
AST ast = parser.getAST();
|
||||
ASTPrinter printer = new ASTPrinter( HqlTokenTypes.class );
|
||||
ASTPrinter printer = TokenPrinters.HQL_TOKEN_PRINTER;
|
||||
printer.showAst( ast, new PrintWriter( System.out ) );
|
||||
ASTIterator iterator = new ASTIterator( ast );
|
||||
int count = 0;
|
||||
|
|
Loading…
Reference in New Issue