Author: steve.ebersole(a)jboss.com
Date: 2009-02-09 14:32:49 -0500 (Mon, 09 Feb 2009)
New Revision: 15919
Added:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/persister/MappedTableMetadata.java
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/Dot.java
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/IndexCollectionElementReference.java
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/IndexedCollectionElementAccessPersisterReference.java
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/PersisterJoin.java
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/PropertyJoin.java
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/PropertyJoinBuilder.java
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/PropertyPathTerminus.java
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/StatementStack.java
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/path/impl/AbstractPathNormalizationStrategy.java
core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/resolve/
core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/resolve/ResolverTest.java
Removed:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/path/AbstractPathNormalizationStrategy.java
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/util/ErrorCounter.java
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/util/ErrorReporter.java
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/util/ParseErrorHandler.java
Modified:
core/branches/SQL_GEN_REDESIGN/pom.xml
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/persister/entity/Queryable.java
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/ASTFactoryImpl.java
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/AbstractPersisterReference.java
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/CollectionPersisterReference.java
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/EntityPersisterReference.java
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/HqlNormalizer.java
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/Join.java
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/NormalizationContext.java
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/NormalizationContextAwareNode.java
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/PersisterAliasReference.java
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/PersisterReference.java
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/PersisterReferenceBuilder.java
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/PersisterReferenceContext.java
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/PropertyReference.java
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/RootPersisterReferenceContext.java
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/path/PathNormalizationStrategy.java
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/path/PathedPropertyReferenceSource.java
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/path/impl/BasicPathNormalizationStrategySupport.java
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/path/impl/FromClausePathNormalizationStrategy.java
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/path/impl/SelectClausePathNormalizationStrategy.java
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/path/impl/WithFragmentPathNormalizationStrategy.java
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/parse/HqlParser.java
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/parse/PathCollector.java
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/util/ASTPrinter.java
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/util/ASTUtil.java
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/util/ErrorHandlerDelegateImpl.java
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/util/PathHelper.java
core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/normalize/NormalizerTest.java
core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/parse/ParserTest.java
Log:
HHH-2407 : HQL translation rework ->
HHH-3687 : parse (phase1)
HHH-3688 : normalize (phase2)
Modified: core/branches/SQL_GEN_REDESIGN/pom.xml
===================================================================
--- core/branches/SQL_GEN_REDESIGN/pom.xml 2009-02-09 19:27:30 UTC (rev 15918)
+++ core/branches/SQL_GEN_REDESIGN/pom.xml 2009-02-09 19:32:49 UTC (rev 15919)
@@ -197,6 +197,9 @@
<name>hql/normalize.g</name>
</grammar>
<grammar>
+ <name>hql/resolve.g</name>
+ </grammar>
+ <grammar>
<name>order/parse.g</name>
</grammar>
<grammar>
Added:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/persister/MappedTableMetadata.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/persister/MappedTableMetadata.java
(rev 0)
+++
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/persister/MappedTableMetadata.java 2009-02-09
19:32:49 UTC (rev 15919)
@@ -0,0 +1,108 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.persister;
+
+/**
+ * Provides access to information about the tables used to persist a collection or
entity.
+ * <p/>
+ * Note that this includes all inheritence tables and secondary tables. The
"main" table is called the
+ * {@link #getDrivingTableName() driving} table. This is the table from which all {@link
#getJoinedTables joins}
+ * originate.
+ *
+ * @author Steve Ebersole
+ */
+public interface MappedTableMetadata {
+ /**
+ * Provides information about a secondary or inheritence table to which we must join to
define the entire
+ * table space for this thing being persisted.
+ */
+ public static class JoinedTable {
+ private final String name;
+ private final String[] keyColumns;
+ private final boolean useInnerJoin;
+
+ /**
+ * Create a JoinedTable definition. By default we are saying to not use inner joins.
+ *
+ * @param name The table name.
+ * @param keyColumns The columns which make up the key to the {@link
MappedTableMetadata#getDrivingTableName driving}
+ * table.
+ */
+ public JoinedTable(String name, String[] keyColumns) {
+ this( name, keyColumns, false );
+ }
+
+ /**
+ * Create a JoinedTable definition.
+ *
+ * @param name The table name.
+ * @param keyColumns The columns which make up the key to the {@link
MappedTableMetadata#getDrivingTableName driving}
+ * table.
+ * @param useInnerJoin Should we use an inner join (faster, but restrictive) as the
join type?
+ */
+ public JoinedTable(String name, String[] keyColumns, boolean useInnerJoin) {
+ this.name = name;
+ this.keyColumns = keyColumns;
+ this.useInnerJoin = useInnerJoin;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public String[] getKeyColumns() {
+ return keyColumns;
+ }
+
+ public boolean useInnerJoin() {
+ return useInnerJoin;
+ }
+ }
+
+
+ public String getSqlAliasRootBase();
+
+ /**
+ * Get the name of the driving table.
+ *
+ * @return
+ */
+ public String getDrivingTableName();
+
+ /**
+ * Get the names of the identifier columns from the driving table. The entity
persisters
+ * assume that all <i>key</i> mappings refer to the driving table's PK
(this is true for both <i>join</i> and
+ * <i>joined-subclass</i> mappings).
+ *
+ * @return The driving table columns used in all {@link #getJoinedTables joins}
+ */
+ public String[] getIdentifierColumnNames();
+
+ /**
+ * Tables to which we must join to provide the complete "table space" for the
given persister.
+ *
+ * @return The joined table definitions.
+ */
+ public JoinedTable[] getJoinedTables();
+}
Modified:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java 2009-02-09
19:27:30 UTC (rev 15918)
+++
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java 2009-02-09
19:32:49 UTC (rev 15919)
@@ -36,6 +36,7 @@
import java.util.Map;
import java.util.Set;
import java.util.Comparator;
+import java.util.LinkedHashMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -48,6 +49,7 @@
import org.hibernate.QueryException;
import org.hibernate.StaleObjectStateException;
import org.hibernate.StaleStateException;
+import org.hibernate.persister.MappedTableMetadata;
import org.hibernate.jdbc.Expectation;
import org.hibernate.jdbc.Expectations;
import org.hibernate.jdbc.TooManyRowsAffectedException;
@@ -2838,6 +2840,63 @@
return false;
}
+
+ public class MappedTableMetadataImpl implements MappedTableMetadata {
+ private final JoinedTable[] joinedTables;
+
+ public MappedTableMetadataImpl() {
+ LinkedHashMap joinedTableMap = new LinkedHashMap();
+
+ int sublassTableCount = getSubclassTableSpan();
+ for ( int i = 1; i < sublassTableCount; i++ ) {
+ final String tableName = getSubclassTableName( i );
+ JoinedTable joinedTable = ( JoinedTable ) joinedTableMap.get( tableName );
+ if ( joinedTable == null && !getTableName().equals( tableName ) ) {
+ joinedTable = new JoinedTable( tableName, getSubclassTableKeyColumns( i ),
isClassOrSuperclassTable( i ) );
+ joinedTableMap.put( tableName, joinedTable );
+ }
+ }
+
+ int tableCount = getTableSpan();
+ for ( int i = 1; i < tableCount; i++ ) {
+ final String tableName = getTableName( i );
+ JoinedTable joinedTable = ( JoinedTable ) joinedTableMap.get( tableName );
+ if ( joinedTable == null && !getTableName().equals( tableName ) ) {
+ joinedTable = new JoinedTable( tableName, getKeyColumns( i ) );
+ joinedTableMap.put( tableName, joinedTable );
+ }
+ }
+
+ this.joinedTables = ( JoinedTable[] ) joinedTableMap.values().toArray( new
JoinedTable[ joinedTableMap.size() ] );
+ }
+
+ public String getSqlAliasRootBase() {
+ return StringHelper.unqualifyEntityName( entityMetamodel.getName() ).toLowerCase();
+ }
+
+ public String getDrivingTableName() {
+ return getTableName();
+ }
+
+ public String[] getIdentifierColumnNames() {
+ return AbstractEntityPersister.this.getIdentifierColumnNames();
+ }
+
+ public JoinedTable[] getJoinedTables() {
+ return joinedTables;
+ }
+ }
+
+
+ private MappedTableMetadata mappedTableMetadata;
+
+ public MappedTableMetadata getMappedTableMetadata() {
+ if ( mappedTableMetadata == null) {
+ mappedTableMetadata = new MappedTableMetadataImpl();
+ }
+ return mappedTableMetadata;
+ }
+
protected JoinFragment createJoin(String name, boolean innerJoin, boolean
includeSubclasses) {
final String[] idCols = StringHelper.qualify( name, getIdentifierColumnNames() ); //all
joins join to the pk of the driving table
final JoinFragment join = getFactory().getDialect().createOuterJoinFragment();
Modified:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/persister/entity/Queryable.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/persister/entity/Queryable.java 2009-02-09
19:27:30 UTC (rev 15918)
+++
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/persister/entity/Queryable.java 2009-02-09
19:32:49 UTC (rev 15919)
@@ -24,6 +24,8 @@
*/
package org.hibernate.persister.entity;
+import org.hibernate.persister.MappedTableMetadata;
+
/**
* Extends the generic <tt>EntityPersister</tt> contract to add
* operations required by the Hibernate Query Language
@@ -174,4 +176,11 @@
return name;
}
}
+
+ /**
+ * Get access to the persister's mapped table metadata.
+ *
+ * @return The mapped table metadata
+ */
+ public MappedTableMetadata getMappedTableMetadata();
}
Modified:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/ASTFactoryImpl.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/ASTFactoryImpl.java 2009-02-09
19:27:30 UTC (rev 15918)
+++
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/ASTFactoryImpl.java 2009-02-09
19:32:49 UTC (rev 15919)
@@ -44,16 +44,24 @@
switch ( tokenType ) {
case IDENT :
return Ident.class;
+ case DOT :
+ return Dot.class;
case ENTITY_PERSISTER_REF :
return EntityPersisterReference.class;
case COLLECTION_PERSISTER_REF :
return CollectionPersisterReference.class;
- case JOIN :
- return Join.class;
+ case INDEXED_COLLECTION_ACCESS_PERSISTER_REF :
+ return IndexedCollectionElementAccessPersisterReference.class;
+ case PROPERTY_JOIN :
+ return PropertyJoin.class;
+ case PERSISTER_JOIN :
+ return PersisterJoin.class;
case ALIAS_REF :
return PersisterAliasReference.class;
case PROPERTY_REF :
return PropertyReference.class;
+ case INDEXED_COLLECTION_ELEMENT_REF :
+ return IndexCollectionElementReference.class;
case INSERT :
return InsertStatement.class;
case UPDATE :
@@ -97,7 +105,7 @@
*/
protected void initialize(AST ast) {
if ( ast instanceof NormalizationContextAwareNode ) {
- ( ( NormalizationContextAwareNode ) ast ).injectResolutionContext( resolutionContext
);
+ ( ( NormalizationContextAwareNode ) ast ).injectNormalizationContext(
resolutionContext );
}
}
}
Modified:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/AbstractPersisterReference.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/AbstractPersisterReference.java 2009-02-09
19:27:30 UTC (rev 15918)
+++
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/AbstractPersisterReference.java 2009-02-09
19:32:49 UTC (rev 15919)
@@ -30,11 +30,12 @@
/**
* Base class for {@link PersisterReference} implementations. Mainly it centralizes
handling
- * of reusable proerty joins.
+ * of reusable property joins.
*
* @author Steve Ebersole
*/
-public abstract class AbstractPersisterReference extends Node implements
PersisterReference {
+public abstract class AbstractPersisterReference extends Node implements
PersisterReference, NormalizationContextAwareNode {
+ private NormalizationContext normalizationContext;
private Map reusablePropertyJoins = new HashMap();
/**
@@ -57,4 +58,31 @@
public PersisterReference locatePersisterReference() {
return this;
}
+
+ /**
+ * Getter for property 'aliasNode'.
+ *
+ * @return Value for property 'aliasNode'.
+ */
+ protected Node getAliasNode() {
+ return ( Node ) getFirstChild().getNextSibling();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getAlias() {
+ return getAliasNode().getText();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void injectNormalizationContext(NormalizationContext normalizationContext) {
+ this.normalizationContext = normalizationContext;
+ }
+
+ protected NormalizationContext normalizationContext() {
+ return normalizationContext;
+ }
}
Modified:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/CollectionPersisterReference.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/CollectionPersisterReference.java 2009-02-09
19:27:30 UTC (rev 15918)
+++
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/CollectionPersisterReference.java 2009-02-09
19:32:49 UTC (rev 15919)
@@ -38,8 +38,7 @@
*
* @author Steve Ebersole
*/
-public class CollectionPersisterReference extends AbstractPersisterReference implements
PersisterReference, NormalizationContextAwareNode, DisplayableNode {
- private NormalizationContext resolutionContext;
+public class CollectionPersisterReference extends AbstractPersisterReference implements
DisplayableNode {
private transient QueryableCollection persister;
/**
@@ -113,18 +112,11 @@
return getPropertyType( propertyName ) != null;
}
- /**
- * {@inheritDoc}
- */
- public void injectResolutionContext(NormalizationContext resolutionContext) {
- this.resolutionContext = resolutionContext;
- }
-
private SessionFactoryImplementor getSessionFactory() {
- if ( resolutionContext == null ) {
+ if ( normalizationContext() == null ) {
throw new AssertionFailure( "resolution context was null on attempt to retrieve
session factory reference" );
}
- return resolutionContext.getSessionFactoryImplementor();
+ return normalizationContext().getSessionFactoryImplementor();
}
/**
Added:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/Dot.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/Dot.java
(rev 0)
+++
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/Dot.java 2009-02-09
19:32:49 UTC (rev 15919)
@@ -0,0 +1,37 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.sql.ast.phase.hql.normalize;
+
+import org.hibernate.sql.ast.common.Node;
+
+/**
+ * TODO : javadoc
+ *
+ * @author Steve Ebersole
+ */
+public class Dot extends Node {
+ public String getText() {
+ return getFirstChild().getText() + '.' +
getFirstChild().getNextSibling().getText();
+ }
+}
Modified:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/EntityPersisterReference.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/EntityPersisterReference.java 2009-02-09
19:27:30 UTC (rev 15918)
+++
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/EntityPersisterReference.java 2009-02-09
19:32:49 UTC (rev 15919)
@@ -41,9 +41,7 @@
*
* @author Steve Ebersole
*/
-public class EntityPersisterReference extends AbstractPersisterReference
- implements NormalizationContextAwareNode, DisplayableNode {
- private NormalizationContext resolutionContext;
+public class EntityPersisterReference extends AbstractPersisterReference implements
DisplayableNode {
private transient Queryable persister;
/**
@@ -111,18 +109,11 @@
return getPropertyType( propertyName ) != null;
}
- /**
- * {@inheritDoc}
- */
- public void injectResolutionContext(NormalizationContext resolutionContext) {
- this.resolutionContext = resolutionContext;
- }
-
private SessionFactoryImplementor getSessionFactory() {
- if ( resolutionContext == null ) {
- throw new AssertionFailure( "resolution context was null on attempt to retrieve
session factory reference" );
+ if ( normalizationContext() == null ) {
+ throw new AssertionFailure( "normalizatioon context was null on attempt to
retrieve session factory reference" );
}
- return resolutionContext.getSessionFactoryImplementor();
+ return normalizationContext().getSessionFactoryImplementor();
}
/**
Modified:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/HqlNormalizer.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/HqlNormalizer.java 2009-02-09
19:27:30 UTC (rev 15918)
+++
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/HqlNormalizer.java 2009-02-09
19:32:49 UTC (rev 15919)
@@ -25,14 +25,18 @@
import java.io.PrintStream;
import java.io.PrintWriter;
+import java.util.List;
+import java.util.Iterator;
+import java.util.ArrayList;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.hibernate.sql.ast.util.ParseErrorHandler;
-import org.hibernate.sql.ast.util.ErrorCounter;
+import org.hibernate.sql.ast.util.ErrorHandlerDelegate;
+import org.hibernate.sql.ast.util.ErrorHandlerDelegateImpl;
import org.hibernate.sql.ast.util.ASTPrinter;
import org.hibernate.sql.ast.common.JoinType;
+import org.hibernate.sql.ast.common.Node;
import
org.hibernate.sql.ast.phase.hql.normalize.path.impl.FromClausePathNormalizationStrategy;
import
org.hibernate.sql.ast.phase.hql.normalize.path.impl.BasicPathNormalizationStrategySupport;
import
org.hibernate.sql.ast.phase.hql.normalize.path.impl.SelectClausePathNormalizationStrategy;
@@ -40,8 +44,13 @@
import
org.hibernate.sql.ast.phase.hql.normalize.path.impl.WithFragmentPathNormalizationStrategy;
import org.hibernate.QueryException;
import org.hibernate.MappingException;
+import org.hibernate.persister.collection.QueryableCollection;
+import org.hibernate.type.Type;
import org.hibernate.sql.ast.phase.hql.normalize.path.PathNormalizationStrategyStack;
import org.hibernate.sql.ast.phase.hql.normalize.path.PathedPropertyReferenceSource;
+import org.hibernate.sql.ast.phase.hql.normalize.path.PathNormalizationStrategy;
+import org.hibernate.sql.ast.DetailedSemanticException;
+import org.hibernate.sql.ast.alias.ImplicitAliasGenerator;
import org.hibernate.engine.SessionFactoryImplementor;
import org.hibernate.util.StringHelper;
@@ -60,9 +69,11 @@
private final SessionFactoryImplementor sessionFactory;
private final PersisterReferenceBuilder persisterReferenceBuilder;
- private final ParseErrorHandler parseErrorHandler = new ErrorCounter();
+ private final PropertyJoinBuilder propertyJoinBuilder;
+ private final ErrorHandlerDelegate parseErrorHandler = new ErrorHandlerDelegateImpl();
private final ASTPrinter printer = new ASTPrinter( HqlNormalizeTokenTypes.class );
- private final AliasBuilder aliasBuilder = new AliasBuilder();
+ private final ImplicitAliasGenerator aliasBuilder = new ImplicitAliasGenerator();
+ private final StatementStack statementStack = new StatementStack();
private final PathNormalizationStrategyStack pathNormalizationStrategyStack = new
PathNormalizationStrategyStack();
private int traceDepth = 0;
@@ -71,6 +82,7 @@
super();
this.sessionFactory = sessionFactory;
this.persisterReferenceBuilder = new PersisterReferenceBuilder( this );
+ this.propertyJoinBuilder = new PropertyJoinBuilder( this );
super.setASTFactory( new ASTFactoryImpl( this ) );
}
@@ -79,6 +91,37 @@
}
+ // handle trace logging
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ 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) {
+ System.out.println( msg );
+// log.trace( msg );
+ }
+
+
// overrides of Antlr infastructure methods
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
public void reportError(RecognitionException e) {
@@ -93,7 +136,7 @@
getParseErrorHandler().reportWarning( s );
}
- public ParseErrorHandler getParseErrorHandler() {
+ public ErrorHandlerDelegate getParseErrorHandler() {
return parseErrorHandler;
}
@@ -107,7 +150,7 @@
}
- // Resolution state
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ // Normalization context
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
private PersisterReferenceContext currentPersisterReferenceContext;
@@ -115,6 +158,10 @@
return currentPersisterReferenceContext;
}
+ public PathNormalizationStrategy getCurrentPathNormalizationStrategy() {
+ return pathNormalizationStrategyStack.getCurrent();
+ }
+
protected void pushStatement(AST statementNode) {
if ( currentPersisterReferenceContext == null ) {
currentPersisterReferenceContext = new RootPersisterReferenceContext();
@@ -124,9 +171,11 @@
}
pathNormalizationStrategyStack.push( new BasicPathNormalizationStrategySupport( this )
);
+ statementStack.push( ( Statement ) statementNode );
}
protected void popStatement() {
+ statementStack.pop();
pathNormalizationStrategyStack.pop();
if ( currentPersisterReferenceContext instanceof HierarchicalPersisterReferenceContext
) {
currentPersisterReferenceContext = ( ( HierarchicalPersisterReferenceContext )
currentPersisterReferenceContext ).getParent();
@@ -136,10 +185,7 @@
}
}
-
- // ResolutionContext impl
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- public AliasBuilder getAliasBuilder() {
+ public ImplicitAliasGenerator getAliasBuilder() {
return aliasBuilder;
}
@@ -155,64 +201,74 @@
return persisterReferenceBuilder;
}
+ public PropertyJoinBuilder getPropertyJoinBuilder() {
+ return propertyJoinBuilder;
+ }
- // handle trace logging
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- 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 );
+ public void registerAssociationFetch(Join join) {
+ // todo : implement
}
- private String buildTraceNodeName(AST tree) {
- return tree == null
- ? "???"
- : tree.getText() + " [" + printer.getTokenTypeName( tree.getType() ) +
"]";
+ public void registerPropertyFetch(PersisterReference persisterReference) {
+ // todo : implement
}
- public void traceOut(String ruleName, AST tree) {
- if ( inputState.guessing > 0 ) {
+
+ // semantic action overrides
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ protected void applyCollectionFilter(AST querySpecIn) {
+ if ( isSubquery() ) {
return;
}
- String prefix = "<-" + StringHelper.repeat( '-', (--traceDepth *
2) ) + " ";
- trace( prefix + ruleName );
- }
- private void trace(String msg) {
- System.out.println( msg );
-// log.trace( msg );
- }
+ AST potentialFilterRole = querySpecIn.getFirstChild();
+ if ( potentialFilterRole == null || potentialFilterRole.getType() != FILTER ) {
+ return;
+ }
+ final String collectionRole = potentialFilterRole.getText();
+ trace( "applying collection filter for role [" + collectionRole +
"]" );
- // AST output methods
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ // Remove the FILTER node from the tree as we are about to expand it...
+ querySpecIn.setFirstChild( potentialFilterRole.getNextSibling() );
- public void dumpAst(AST ast) {
- dumpAst( ast, "DUMP" );
- }
+ QueryableCollection persister = ( QueryableCollection )
getSessionFactoryImplementor().getCollectionPersister( collectionRole );
- public void dumpAst(AST ast, String header) {
- log.info( printer.showAsString( ast, header ) );
- }
+ if ( !persister.getElementType().isEntityType() ) {
+ throw new QueryException( "cannot filter collection of values" );
+ }
- public void showAst(AST ast, PrintStream out) {
- showAst( ast, new PrintWriter( out ) );
- }
+ String collectionElementEntityName = persister.getElementPersister().getEntityName();
- private void showAst(AST ast, PrintWriter pw) {
- printer.showAst( ast, pw );
- }
+ AST persisterSpace = astFactory.create( PERSISTER_SPACE,
"filter-persister-space" );
+ AST persisterRef = astFactory.create( ENTITY_PERSISTER_REF,
"filter-persister-ref" );
+ persisterSpace.setFirstChild( persisterRef );
+ persisterRef.addChild( astFactory.create( ENTITY_NAME, collectionElementEntityName )
);
+ persisterRef.addChild( astFactory.create( ALIAS, "this" ) );
+ persisterRef.addChild( astFactory.create( FILTER, collectionRole ) );
+ registerPersisterReference( persisterRef );
- private String textOrNull(AST ast) {
- return ast == null ? null : ast.getText();
+ AST selectFromNode = querySpecIn.getFirstChild();
+ assert selectFromNode.getType() == SELECT_FROM : "mis-structured AST";
+
+ AST fromClauseNode = selectFromNode.getFirstChild();
+ if ( fromClauseNode == null ) {
+ fromClauseNode = astFactory.create( FROM, "from" );
+ selectFromNode.setFirstChild( fromClauseNode );
+ }
+ else if ( fromClauseNode.getType() == SELECT ) {
+ AST tmp = astFactory.create( FROM, "from" );
+ tmp.setFirstChild( fromClauseNode ); // really the SELECT clause
+ fromClauseNode = tmp;
+ selectFromNode.setFirstChild( fromClauseNode );
+ }
+
+ assert fromClauseNode.getType() == FROM : "mis-structured AST";
+ fromClauseNode.addChild( persisterSpace ); // make it the first child???
}
- // function processing
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
private boolean processingFunction;
protected void startingFunction() {
@@ -227,10 +283,7 @@
return processingFunction;
}
-
- // persister-related semntic action overrides
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- protected AST normalizeEntityName(AST node) throws SemanticException {
+ protected AST normalizeEntityName(AST node) throws SemanticException {
String entityName = node.getText();
if ( !isEntityName( entityName ) ) {
final String importedName = getSessionFactoryImplementor().getImportedClassName(
entityName );
@@ -265,8 +318,6 @@
}
- // property-related semntic action overrides
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
protected String locateOwningPersisterAlias(AST property) {
PersisterReference persisterReference = getCurrentPersisterReferenceContext()
.locatePersisterReferenceExposingProperty( property.getText() );
@@ -274,8 +325,6 @@
}
- // path normalization
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
protected AST normalizeQualifiedRoot(AST alias) {
log.debug( "normalizing path expression root as alias [" + alias.getText() +
"]" );
return pathNormalizationStrategyStack.getCurrent().handleRoot(
getCurrentPersisterReferenceContext().locatePersisterReferenceByAlias( alias.getText() )
);
@@ -287,6 +336,10 @@
return root.handleIntermediatePathPart( ( Ident ) propertyName );
}
+ protected AST normalizeUnqualifiedPropertyReferenceSource(AST propertyName) {
+ return pathNormalizationStrategyStack.getCurrent().handleRoot(
getCurrentPersisterReferenceContext().locatePersisterReferenceExposingProperty(
propertyName.getText() ) );
+ }
+
protected AST normalizePropertyPathIntermediary(AST source, AST propertyNameNode) {
log.trace( "normalizing intermediate path expression [" + textOrNull(
propertyNameNode ) + "]" );
return pathNormalizationStrategyStack.getCurrent().handleIntermediatePathPart( (
PathedPropertyReferenceSource ) source, ( Ident ) propertyNameNode );
@@ -297,9 +350,45 @@
return pathNormalizationStrategyStack.getCurrent().handleTerminalPathPart( (
PathedPropertyReferenceSource ) source, ( Ident ) propertyNameNode );
}
+ protected AST normalizeIntermediateIndexOperation(AST collectionPath, AST selector)
throws SemanticException {
+ log.trace( "normalizing intermediate index access [" + textOrNull(
collectionPath ) + "]" );
+ PathedPropertyReferenceSource collectionSource = ( PathedPropertyReferenceSource )
collectionPath.getFirstChild();
+ Ident collectionProperty = ( Ident ) collectionSource.getNextSibling();
+ return pathNormalizationStrategyStack.getCurrent().handleIntermediateIndexAccess(
collectionSource, collectionProperty, ( Node ) selector );
+ }
- // property path normalization strategies
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ protected AST normalizeTerminalIndexOperation(AST collectionPath, AST selector)
throws SemanticException {
+ log.trace( "normalizing terminal index access [" + textOrNull( collectionPath
) + "]" );
+ PathedPropertyReferenceSource collectionSource = ( PathedPropertyReferenceSource )
collectionPath.getFirstChild();
+ Ident collectionProperty = ( Ident ) collectionSource.getNextSibling();
+ return pathNormalizationStrategyStack.getCurrent().handleTerminalIndexAccess(
collectionSource, collectionProperty, ( Node ) selector );
+ }
+ protected AST normalizeIndexOperation(AST collectionPropertyReference, AST selector)
throws SemanticException {
+ PropertyReference propertyReference = ( PropertyReference )
collectionPropertyReference;
+ Type type = propertyReference.getSource().getPropertyType(
propertyReference.getPropertyName() );
+ if ( !type.isCollectionType() ) {
+ throw new DetailedSemanticException( "Not a collection property reference",
collectionPropertyReference );
+ }
+
+ // todo : validate the selector type against the indexed collection's key type?
+
+ Join join = getPropertyJoinBuilder().buildIndexOperationJoin(
+ propertyReference.getSource().locatePersisterReference(),
+ propertyReference.getPropertyName(),
+ null,
+ ( Node ) getASTFactory().create( INNER, "inner" ),
+ ( Node ) selector
+ );
+
+ return join.locateRhs();
+ }
+
+ protected AST normalizeIndexedRoot(AST root) {
+// return super.normalizeIndexedRoot( alias );
+ return root;
+ }
+
protected void pushFromClausePropertyPathContext(AST joinTypeNode, AST fetch, AST alias,
AST propertyFetch) {
pathNormalizationStrategyStack.push(
new FromClausePathNormalizationStrategy(
@@ -332,8 +421,8 @@
popPathNormalizationContext();
}
- private void popPathNormalizationContext() {
- pathNormalizationStrategyStack.pop();
+ private PathNormalizationStrategy popPathNormalizationContext() {
+ return pathNormalizationStrategyStack.pop();
}
protected void pushSelectClausePropertyPathContext() {
@@ -350,8 +439,9 @@
);
}
- protected void popOnFragmentPropertyPathContext() {
- popPathNormalizationContext();
+ protected AST popOnFragmentPropertyPathContext() {
+ OnFragmentPathNormalizationStrategy strategy = ( OnFragmentPathNormalizationStrategy )
popPathNormalizationContext();
+ return strategy.getDiscoveredLHS();
}
protected void pushWithFragmentPropertyPathContext(AST rhsPropertyReference) {
@@ -371,4 +461,115 @@
protected void applyWithFragment(AST withFragment) {
( ( WithFragmentPathNormalizationStrategy ) pathNormalizationStrategyStack.getCurrent()
).applyWithFragment( withFragment );
}
+
+ protected void postProcessQuery(AST querySpec) {
+ AST selectFrom = querySpec.getFirstChild();
+ assert selectFrom.getType() == SELECT_FROM;
+
+ AST fromClause = selectFrom.getFirstChild();
+ assert fromClause.getType() == FROM;
+
+ AST selectClause = fromClause.getNextSibling();
+ assert selectClause == null || selectClause.getType() == SELECT;
+
+ if ( selectClause == null || selectClause.getNumberOfChildren() == 0 ) {
+ selectClause = generateDerivedSelectClause( fromClause );
+ fromClause.setNextSibling( selectClause );
+ }
+
+ if ( propertyFetchAliases != null && !propertyFetchAliases.isEmpty() ) {
+ AST fetches = astFactory.create( FETCH, "fetch-aliases" );
+ Iterator aliases = propertyFetchAliases.iterator();
+ while ( aliases.hasNext() ) {
+ final String alias = ( String ) aliases.next();
+ fetches.addChild( astFactory.create( ALIAS_REF, alias ) );
+ }
+ selectClause.addChild( fetches );
+ propertyFetchAliases.clear();
+ }
+
+ // todo : attach mapping-defined order-by fragments
+ // an issue here is that order-by fragments are attached "above" the
"query spec" level according to ANSI SQL
+ // for example, an order by is a function of the combined result in the case of a
UNION, INTERSECT, etc...
+
+ }
+
+ private AST generateDerivedSelectClause(AST fromClause) {
+ AST selectClause = astFactory.create( SELECT, "derived-select-clause" );
+ AST selectList = astFactory.create( SELECT_LIST, "derived-select-list" );
+ selectClause.setFirstChild( selectList );
+
+ List implicitlySelectedPersisterReferenceAliases =
+ getCurrentPersisterReferenceContext().getPersisterReferencesImplicitInDerivedSelectClause();
+ assert implicitlySelectedPersisterReferenceAliases != null : "Found no registered
implied select references";
+
+
+ Iterator itr = implicitlySelectedPersisterReferenceAliases.iterator();
+ while ( itr.hasNext() ) {
+ final PersisterReference persisterReference = ( PersisterReference ) itr.next();
+ final String alias = persisterReference.getAlias();
+ AST aliasReference = astFactory.create( ALIAS_REF, alias );
+ AST selectItem = astFactory.create( SELECT_ITEM, "derived-select-item" );
+ selectItem.setFirstChild( aliasReference );
+ selectList.addChild( selectItem );
+ }
+
+ return selectClause;
+ }
+
+ protected void registerSelectItem(AST selectItem) {
+ // todo : this was intended to allow for reusing select elements in other clauses, like
say an order by
+ trace( "registering select item" );
+ }
+
+ protected AST buildRootEntityPersisterReference(AST persisterReferenceNode, AST
entityName, AST alias, AST filter, AST propertyFetch) {
+ PersisterReference ref = ( PersisterReference )
super.buildRootEntityPersisterReference(
+ persisterReferenceNode,
+ entityName,
+ alias,
+ filter,
+ propertyFetch
+ );
+
+ if ( filter != null ) {
+ log.trace( "applying filter [" + filter.getText() + ", " +
entityName + "]" );
+ }
+
+ getCurrentPersisterReferenceContext().registerPersisterReferenceImplicitInDerivedSelectClause(
ref );
+
+ return ref;
+ }
+
+ private List propertyFetchAliases;
+
+ protected void registerPropertyFetchNode(AST persisterReference) {
+ if ( propertyFetchAliases == null ) {
+ propertyFetchAliases = new ArrayList();
+ }
+ propertyFetchAliases.add( ( ( PersisterReference ) persisterReference ).getAlias() );
+ }
+
+
+ // AST output methods
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ public void dumpAst(AST ast) {
+ dumpAst( ast, "DUMP" );
+ }
+
+ public void dumpAst(AST ast, String header) {
+ log.info( printer.showAsString( ast, header ) );
+ }
+
+ public void showAst(AST ast, PrintStream out) {
+ showAst( ast, new PrintWriter( out ) );
+ }
+
+ private void showAst(AST ast, PrintWriter pw) {
+ printer.showAst( ast, pw );
+ }
+
+
+ private String textOrNull(AST ast) {
+ return ast == null ? null : ast.getText();
+ }
}
Added:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/IndexCollectionElementReference.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/IndexCollectionElementReference.java
(rev 0)
+++
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/IndexCollectionElementReference.java 2009-02-09
19:32:49 UTC (rev 15919)
@@ -0,0 +1,34 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.sql.ast.phase.hql.normalize;
+
+import org.hibernate.sql.ast.common.Node;
+
+/**
+ * Models the terminal reference to an index operator.
+ *
+ * @author Steve Ebersole
+ */
+public class IndexCollectionElementReference extends Node implements PropertyPathTerminus
{
+}
Added:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/IndexedCollectionElementAccessPersisterReference.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/IndexedCollectionElementAccessPersisterReference.java
(rev 0)
+++
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/IndexedCollectionElementAccessPersisterReference.java 2009-02-09
19:32:49 UTC (rev 15919)
@@ -0,0 +1,101 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.sql.ast.phase.hql.normalize;
+
+import org.hibernate.type.AssociationType;
+import org.hibernate.type.Type;
+import org.hibernate.persister.collection.QueryableCollection;
+import org.hibernate.persister.entity.Queryable;
+import org.hibernate.AssertionFailure;
+
+/**
+ * Models the concept of a reference to the element persister of an indexed collection
(map, list) which has been
+ * accessed or restricted by an index operation.
+ *
+ * @author Steve Ebersole
+ */
+public class IndexedCollectionElementAccessPersisterReference extends
AbstractPersisterReference {
+ private transient QueryableCollection collectionPersister;
+ private transient Queryable elementPersister;
+
+ /**
+ * Retrieve the collection "role" identifying the underlying {@link
org.hibernate.persister.collection.CollectionPersister}
+ *
+ * @return The collection role
+ */
+ public String getCollectionRole() {
+ return getFirstChild().getText();
+ }
+
+ public String getName() {
+ return getCollectionRole() + "[]";
+ }
+
+ public boolean isCollection() {
+ return false;
+ }
+
+ public AssociationType getPersisterType() {
+ return elementPersister() == null
+ ? null
+ : ( AssociationType ) elementPersister().getType();
+ }
+
+ public QueryableCollection collectionPersister() {
+ if ( collectionPersister == null ) {
+ collectionPersister = ( QueryableCollection )
normalizationContext().getSessionFactoryImplementor()
+ .getCollectionPersister( getCollectionRole() );
+ }
+ return collectionPersister;
+ }
+
+ public Queryable elementPersister() {
+ if ( elementPersister == null ) {
+ try {
+ elementPersister = ( Queryable ) collectionPersister().getElementPersister();
+ }
+ catch ( AssertionFailure ignore ) {
+ // leave it null
+ }
+ }
+ return elementPersister;
+ }
+
+ public Type getPropertyType(String propertyName) {
+ try {
+ return elementPersister().getPropertyType( propertyName );
+ }
+ catch( Throwable ignore ) {
+ return null;
+ }
+ }
+
+ public boolean containsProperty(String propertyName) {
+ return getPropertyType( propertyName ) != null;
+ }
+
+ public Type getCollectionIndexType() {
+ return collectionPersister().getIndexType();
+ }
+}
Modified:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/Join.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/Join.java 2009-02-09
19:27:30 UTC (rev 15918)
+++
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/Join.java 2009-02-09
19:32:49 UTC (rev 15919)
@@ -33,26 +33,12 @@
*
* @author Steve Ebersole
*/
-public class Join extends Node {
- private boolean forced = false;
+public interface Join extends AST {
+ public Node locateJoinType();
- public void force() {
- forced = true;
- }
+ public JoinType getEnumeratedJoinType();
- public boolean isForced() {
- return forced;
- }
+ public Node locateJoinedProperty();
- public Node getJoinType() {
- return ( Node ) getFirstChild();
- }
-
- public JoinType getEnumeratedJoinType() {
- return JoinType.resolve( getJoinType() );
- }
-
- public PersisterReference getRhs() {
- return ( PersisterReference ) getFirstChild().getNextSibling();
- }
+ public PersisterReference locateRhs();
}
Modified:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/NormalizationContext.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/NormalizationContext.java 2009-02-09
19:27:30 UTC (rev 15918)
+++
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/NormalizationContext.java 2009-02-09
19:32:49 UTC (rev 15919)
@@ -27,6 +27,8 @@
import org.hibernate.engine.SessionFactoryImplementor;
import org.hibernate.sql.ast.util.ASTPrinter;
+import org.hibernate.sql.ast.phase.hql.normalize.path.PathNormalizationStrategy;
+import org.hibernate.sql.ast.alias.ImplicitAliasGenerator;
/**
* Defines the environment or context in which normalization is occuring, more
specifically
@@ -54,7 +56,7 @@
*
* @return The alias builder.
*/
- public AliasBuilder getAliasBuilder();
+ public ImplicitAliasGenerator getAliasBuilder();
/**
* The current {@link PersisterReferenceContext} for this context. The {@link
PersisterReferenceContext}
@@ -72,6 +74,13 @@
public PersisterReferenceBuilder getPersisterReferenceBuilder();
/**
+ * The builder of {@link Join} instances pertaining to property joins for this context.
+ *
+ * @return The property {@link Join} builder.
+ */
+ public PropertyJoinBuilder getPropertyJoinBuilder();
+
+ /**
* The AST printer available for this context.
*
* @return The AST printer.
@@ -84,4 +93,10 @@
* @return True or false.
*/
public boolean isCurrentlyProcessingFunction();
+
+ public PathNormalizationStrategy getCurrentPathNormalizationStrategy();
+
+ public void registerAssociationFetch(Join join);
+
+ public void registerPropertyFetch(PersisterReference persisterReference);
}
Modified:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/NormalizationContextAwareNode.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/NormalizationContextAwareNode.java 2009-02-09
19:27:30 UTC (rev 15918)
+++
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/NormalizationContextAwareNode.java 2009-02-09
19:32:49 UTC (rev 15919)
@@ -35,5 +35,5 @@
*
* @param resolutionContext The resolution context.
*/
- public void injectResolutionContext(NormalizationContext resolutionContext);
+ public void injectNormalizationContext(NormalizationContext resolutionContext);
}
Modified:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/PersisterAliasReference.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/PersisterAliasReference.java 2009-02-09
19:27:30 UTC (rev 15918)
+++
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/PersisterAliasReference.java 2009-02-09
19:32:49 UTC (rev 15919)
@@ -27,26 +27,40 @@
import org.hibernate.type.Type;
/**
- * TODO : javadoc
+ * Represents a reference to a persister-reference alias.
*
* @author Steve Ebersole
*/
public class PersisterAliasReference extends Node implements PropertyReferenceSource,
NormalizationContextAwareNode {
private NormalizationContext resolutionContext;
+ /**
+ * Retrieves the alias.
+ *
+ * @return The alias.
+ */
public String getPersisterAlias() {
return getText();
}
+ /**
+ * {@inheritDoc}
+ */
public PersisterReference locatePersisterReference() {
return resolutionContext.getCurrentPersisterReferenceContext()
.locatePersisterReferenceByAlias( getPersisterAlias() );
}
- public void injectResolutionContext(NormalizationContext resolutionContext) {
+ /**
+ * {@inheritDoc}
+ */
+ public void injectNormalizationContext(NormalizationContext resolutionContext) {
this.resolutionContext = resolutionContext;
}
+ /**
+ * {@inheritDoc}
+ */
public Type getPropertyType(String property) {
return locatePersisterReference().getPropertyType( property );
}
Added:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/PersisterJoin.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/PersisterJoin.java
(rev 0)
+++
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/PersisterJoin.java 2009-02-09
19:32:49 UTC (rev 15919)
@@ -0,0 +1,50 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.sql.ast.phase.hql.normalize;
+
+import org.hibernate.sql.ast.common.Node;
+import org.hibernate.sql.ast.common.JoinType;
+
+/**
+ * TODO : javadoc
+ *
+ * @author Steve Ebersole
+ */
+public class PersisterJoin extends Node implements Join {
+ public Node locateJoinType() {
+ return ( Node ) getFirstChild();
+ }
+
+ public JoinType getEnumeratedJoinType() {
+ return JoinType.resolve( locateJoinType() );
+ }
+
+ public Node locateJoinedProperty() {
+ return null;
+ }
+
+ public PersisterReference locateRhs() {
+ return ( PersisterReference ) locateJoinType().getNextSibling();
+ }
+}
Modified:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/PersisterReference.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/PersisterReference.java 2009-02-09
19:27:30 UTC (rev 15918)
+++
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/PersisterReference.java 2009-02-09
19:32:49 UTC (rev 15919)
@@ -36,14 +36,15 @@
public interface PersisterReference extends AST, PropertyReferenceSource {
/**
* Get the alias assigned to this persister reference. May be explcitly defined by the
query author or
- * supplied by {@link AliasBuilder#buildUniqueImplicitAlias()}, but all persister
references will have an alias.
+ * supplied by {@link
org.hibernate.sql.ast.alias.ImplicitAliasGenerator#buildUniqueImplicitAlias()}, but all
persister references will have an alias.
*
* @return This persister reference's alias.
*/
public String getAlias();
/**
- * Get the name of this persister reference.
+ * Get the name of this persister reference. This is just some descriptive text.
+ *
* @return The name.
*/
public String getName();
Modified:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/PersisterReferenceBuilder.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/PersisterReferenceBuilder.java 2009-02-09
19:27:30 UTC (rev 15918)
+++
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/PersisterReferenceBuilder.java 2009-02-09
19:32:49 UTC (rev 15919)
@@ -23,23 +23,23 @@
*/
package org.hibernate.sql.ast.phase.hql.normalize;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import antlr.ASTFactory;
+import antlr.collections.AST;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
-import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.MappingException;
import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.persister.entity.EntityPersister;
+import org.hibernate.sql.ast.alias.ImplicitAliasGenerator;
-import antlr.collections.AST;
-import antlr.ASTFactory;
-
/**
* Centralization of code needed to build a {@link PersisterReference}
*
* @author Steve Ebersole
*/
public class PersisterReferenceBuilder implements HqlNormalizeTokenTypes {
- public static final Log log = LogFactory.getLog( PersisterReferenceBuilder.class );
+ private static final Logger log = LoggerFactory.getLogger(
PersisterReferenceBuilder.class );
private final NormalizationContext normalizationContext;
@@ -55,7 +55,7 @@
return normalizationContext.getCurrentPersisterReferenceContext();
}
- private AliasBuilder aliasBuilder() {
+ private ImplicitAliasGenerator aliasBuilder() {
return normalizationContext.getAliasBuilder();
}
@@ -70,13 +70,11 @@
*
* @param entityName The entity name to which to build a PersisterReference.
* @param alias The alias (or null) to apply to the built PersisterReference.
- * @param propertyFetching Whether lazy property fetching should be enabled.
* @return The built PersisterReference
*/
public EntityPersisterReference buildEntityPersisterReference(
String entityName,
- String alias,
- boolean propertyFetching) {
+ String alias) {
EntityPersister persister = lookupEntityPersister( entityName );
String aliasText = determineAlias( alias );
@@ -85,9 +83,6 @@
AST persisterReference = astFactory().create( ENTITY_PERSISTER_REF );
persisterReference.setFirstChild( entityNameNode );
persisterReference.addChild( aliasNode );
- if ( propertyFetching ) {
- persisterReference.addChild( astFactory().create( PROP_FETCH ) );
- }
EntityPersisterReference entityPersisterReference = ( EntityPersisterReference )
persisterReference;
persisterReferenceContext().registerPersisterReference( entityPersisterReference );
@@ -100,13 +95,11 @@
* @param collectionRole The {@link
org.hibernate.persister.collection.CollectionPersister#getRole() collection role}
* for which to build a PersisterReference.
* @param alias The alias (or null) to apply to the built PersisterReference.
- * @param propertyFetching Whether lazy property fetching should be enabled.
* @return The built PersisterReference
*/
public CollectionPersisterReference buildCollectionPersisterReference(
String collectionRole,
- String alias,
- boolean propertyFetching) {
+ String alias) {
// todo : is this the structure we want here?
String aliasText = determineAlias( alias );
@@ -115,16 +108,35 @@
AST persisterReference = astFactory().create( COLLECTION_PERSISTER_REF );
persisterReference.setFirstChild( collectionRoleNode );
persisterReference.addChild( aliasNode );
- if ( propertyFetching ) {
- persisterReference.addChild( astFactory().create( PROP_FETCH ) );
- }
-
CollectionPersisterReference collectionPersisterReference = (
CollectionPersisterReference ) persisterReference;
persisterReferenceContext().registerPersisterReference( collectionPersisterReference
);
return collectionPersisterReference;
}
+ public IndexedCollectionElementAccessPersisterReference
buildIndexedCollectionElementAccessPersisterReference(
+ String collectionRole,
+ String alias,
+ AST selector) {
+ String aliasText = determineAlias( alias );
+
+ AST collectionRoleNode = astFactory().create( COLLECTION_ROLE, collectionRole );
+ AST aliasNode = astFactory().create( ALIAS, aliasText );
+
+ AST indexValueCondition = astFactory().create( INDEX_VALUE_CORRELATION,
"index-correlation" );
+ indexValueCondition.addChild( selector );
+
+ AST persisterReference = astFactory().create( INDEXED_COLLECTION_ACCESS_PERSISTER_REF
);
+ persisterReference.setFirstChild( collectionRoleNode );
+ persisterReference.addChild( aliasNode );
+ persisterReference.addChild( indexValueCondition );
+
+ IndexedCollectionElementAccessPersisterReference pr = (
IndexedCollectionElementAccessPersisterReference ) persisterReference;
+ persisterReferenceContext().registerPersisterReference( pr );
+
+ return pr;
+ }
+
private EntityPersister lookupEntityPersister(String name) {
// NOTE : the parser should have already normalized the entity name...
try {
@@ -156,7 +168,7 @@
}
public static boolean isImplicitAlias(String alias) {
- return AliasBuilder.isImplicitAlias( alias );
+ return ImplicitAliasGenerator.isImplicitAlias( alias );
}
}
Modified:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/PersisterReferenceContext.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/PersisterReferenceContext.java 2009-02-09
19:27:30 UTC (rev 15918)
+++
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/PersisterReferenceContext.java 2009-02-09
19:32:49 UTC (rev 15919)
@@ -23,6 +23,8 @@
*/
package org.hibernate.sql.ast.phase.hql.normalize;
+import java.util.List;
+
/**
* TODO : javadoc
*
@@ -78,4 +80,8 @@
*/
public void registerPersisterReference(PersisterReference persisterReference);
+ public void registerPersisterReferenceImplicitInDerivedSelectClause(PersisterReference
persisterReference);
+
+ public List getPersisterReferencesImplicitInDerivedSelectClause();
+
}
Added:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/PropertyJoin.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/PropertyJoin.java
(rev 0)
+++
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/PropertyJoin.java 2009-02-09
19:32:49 UTC (rev 15919)
@@ -0,0 +1,50 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.sql.ast.phase.hql.normalize;
+
+import org.hibernate.sql.ast.common.Node;
+import org.hibernate.sql.ast.common.JoinType;
+
+/**
+ * TODO : javadoc
+ *
+ * @author Steve Ebersole
+ */
+public class PropertyJoin extends Node implements Join {
+ public Node locateJoinType() {
+ return ( Node ) getFirstChild();
+ }
+
+ public JoinType getEnumeratedJoinType() {
+ return JoinType.resolve( locateJoinType() );
+ }
+
+ public Node locateJoinedProperty() {
+ return ( Node ) locateJoinType().getNextSibling();
+ }
+
+ public PersisterReference locateRhs() {
+ return ( PersisterReference ) locateJoinedProperty().getNextSibling();
+ }
+}
Added:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/PropertyJoinBuilder.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/PropertyJoinBuilder.java
(rev 0)
+++
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/PropertyJoinBuilder.java 2009-02-09
19:32:49 UTC (rev 15919)
@@ -0,0 +1,217 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.sql.ast.phase.hql.normalize;
+
+import org.hibernate.type.Type;
+import org.hibernate.type.CollectionType;
+import org.hibernate.type.EntityType;
+import org.hibernate.HibernateException;
+import org.hibernate.sql.ast.util.ASTPrinter;
+import org.hibernate.sql.ast.common.Node;
+import org.hibernate.sql.ast.alias.ImplicitAliasGenerator;
+import org.hibernate.engine.SessionFactoryImplementor;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * TODO : javadoc
+ *
+ * @author Steve Ebersole
+ */
+public class PropertyJoinBuilder implements HqlNormalizeTokenTypes {
+ private static final Logger log = LoggerFactory.getLogger( PropertyJoinBuilder.class );
+
+ private final NormalizationContext normalizationContext;
+
+ public PropertyJoinBuilder(NormalizationContext normalizationContext) {
+ this.normalizationContext = normalizationContext;
+ }
+
+ /**
+ * Build a property join node.
+ *
+ * @param lhs The join's left-hand-side persister-reference
+ * @param propertyName The property name.
+ * @param alias The alias to apply to the rhs of the join
+ * @param joinType The type of join (INNER, etc) to produce.
+ * @param propertyFetching should property fetching be applied to the joined persister?
+ * @param associationFetching Should the association making up the property join also be
fetched?
+ *
+ * @return The right-hand-side persister-reference.
+ */
+ public Join buildPropertyJoin(
+ PersisterReference lhs,
+ String propertyName,
+ String alias,
+ Node joinType,
+ boolean propertyFetching,
+ boolean associationFetching) {
+ PersisterReference rhs;
+ final Type associationType = lhs.getPropertyType( propertyName );
+ if ( associationType.isCollectionType() ) {
+ CollectionType collectionType = ( CollectionType ) associationType;
+ rhs = persisterReferenceBuilder().buildCollectionPersisterReference(
+ collectionType.getRole(),
+ alias
+ );
+ }
+ else if ( associationType.isEntityType() ) {
+ EntityType entityType = ( EntityType ) associationType;
+ String entityName = entityType.getAssociatedEntityName( sessionFactoryImplementor()
);
+ rhs = persisterReferenceBuilder().buildEntityPersisterReference( entityName, alias );
+ }
+ else {
+ throw new HibernateException(
+ "cannot create join on non-association [root=" + lhs.getAlias()
+ + ", name=" + propertyName
+ + ", type=" + associationType.getName() + "]"
+ );
+ }
+
+ if ( propertyFetching ) {
+ normalizationContext.registerPropertyFetch( rhs );
+ }
+
+ Join joinNode = buildJoinNode( lhs, rhs, propertyName, joinType, associationFetching
);
+
+
+ if ( log.isTraceEnabled() ) {
+ log.trace(
+ printer().showAsString(
+ joinNode,
+ "implicit join : " + lhs.getAlias() + "." + propertyName
+ )
+ );
+ }
+
+ return joinNode;
+ }
+
+ public Join buildIndexOperationJoin(
+ PersisterReference lhs,
+ String collectionPropertyName,
+ String alias,
+ Node joinType,
+ Node selector) {
+ final Type associationType = lhs.getPropertyType( collectionPropertyName );
+ if ( !associationType.isCollectionType() ) {
+ throw new HibernateException(
+ "Cannot process index operation against a non-collection property [root="
+ lhs.getAlias() +
+ ", name=" + collectionPropertyName +
+ ", type=" + associationType.getName()
+ );
+ }
+
+ CollectionType collectionType = ( CollectionType ) associationType;
+ IndexedCollectionElementAccessPersisterReference rhs =
persisterReferenceBuilder().buildIndexedCollectionElementAccessPersisterReference(
+ collectionType.getRole(),
+ alias,
+ selector
+ );
+ if ( rhs.getCollectionIndexType() == null ) {
+ throw new HibernateException(
+ "Cannot process index operation against a non-indexed collection property
[root=" + lhs.getAlias() +
+ ", name=" + collectionPropertyName +
+ ", type=" + associationType.getName()
+ );
+ }
+
+ Join joinNode = buildJoinNode( lhs, rhs, collectionPropertyName, joinType, false );
+
+ if ( log.isTraceEnabled() ) {
+ log.trace(
+ printer().showAsString(
+ joinNode,
+ "implicit join : " + lhs.getAlias() + "." +
collectionPropertyName + "[]"
+ )
+ );
+ }
+
+ return joinNode;
+ }
+
+
+ private Join buildJoinNode(
+ PersisterReference lhs,
+ PersisterReference rhs,
+ String propertyName,
+ Node joinType,
+ boolean associationFetching) {
+ Join joinNode = ( Join ) createNode( PROPERTY_JOIN, "join" );
+ joinNode.setFirstChild( joinType );
+ joinNode.addChild( createNode( ASSOCIATION_NAME, propertyName ) );
+ joinNode.addChild( rhs );
+
+ if ( associationFetching ) {
+ normalizationContext.registerAssociationFetch( joinNode );
+ }
+
+ lhs.addChild( joinNode );
+
+ return joinNode;
+ }
+
+ // normalization context
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ protected final Node createNode(int type, String text) {
+ return ( Node ) normalizationContext.getASTFactory().create( type, text );
+ }
+
+ /**
+ * Getter for property 'aliasBuilder'.
+ *
+ * @return Value for property 'aliasBuilder'.
+ */
+ protected final ImplicitAliasGenerator aliasBuilder() {
+ return normalizationContext.getAliasBuilder();
+ }
+
+ /**
+ * Getter for property 'persisterReferenceBuilder'.
+ *
+ * @return Value for property 'persisterReferenceBuilder'.
+ */
+ protected final PersisterReferenceBuilder persisterReferenceBuilder() {
+ return normalizationContext.getPersisterReferenceBuilder();
+ }
+
+ /**
+ * Getter for property 'sessionFactoryImplementor'.
+ *
+ * @return Value for property 'sessionFactoryImplementor'.
+ */
+ protected final SessionFactoryImplementor sessionFactoryImplementor() {
+ return normalizationContext.getSessionFactoryImplementor();
+ }
+
+ /**
+ * Getter for property 'ASTPrinter'.
+ *
+ * @return Value for property 'ASTPrinter'.
+ */
+ protected final ASTPrinter printer() {
+ return normalizationContext.getPrinter();
+ }
+}
Added:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/PropertyPathTerminus.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/PropertyPathTerminus.java
(rev 0)
+++
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/PropertyPathTerminus.java 2009-02-09
19:32:49 UTC (rev 15919)
@@ -0,0 +1,34 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.sql.ast.phase.hql.normalize;
+
+import antlr.collections.AST;
+
+/**
+ * Represents the terminal part of a property path.
+ *
+ * @author Steve Ebersole
+ */
+public interface PropertyPathTerminus extends AST {
+}
Modified:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/PropertyReference.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/PropertyReference.java 2009-02-09
19:27:30 UTC (rev 15918)
+++
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/PropertyReference.java 2009-02-09
19:32:49 UTC (rev 15919)
@@ -31,7 +31,7 @@
*
* @author Steve Ebersole
*/
-public class PropertyReference extends Node {
+public class PropertyReference extends Node implements PropertyPathTerminus {
private String originalPath;
public String getOriginalPath() {
Modified:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/RootPersisterReferenceContext.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/RootPersisterReferenceContext.java 2009-02-09
19:27:30 UTC (rev 15918)
+++
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/RootPersisterReferenceContext.java 2009-02-09
19:32:49 UTC (rev 15919)
@@ -47,6 +47,7 @@
private static final Logger log = LoggerFactory.getLogger(
RootPersisterReferenceContext.class );
private List persisterReferences = new ArrayList();
+ private List persisterReferencesImplicitInDerivedSelectClause;
private Map aliasXref = new HashMap();
/**
@@ -63,6 +64,23 @@
/**
* {@inheritDoc}
*/
+ public void registerPersisterReferenceImplicitInDerivedSelectClause(PersisterReference
persisterReference) {
+ if ( persisterReferencesImplicitInDerivedSelectClause == null ) {
+ persisterReferencesImplicitInDerivedSelectClause = new ArrayList();
+ }
+ persisterReferencesImplicitInDerivedSelectClause.add( persisterReference );
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public List getPersisterReferencesImplicitInDerivedSelectClause() {
+ return persisterReferencesImplicitInDerivedSelectClause;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
public boolean isContainedAlias(String alias) {
return aliasXref.containsKey( alias );
}
Added:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/StatementStack.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/StatementStack.java
(rev 0)
+++
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/StatementStack.java 2009-02-09
19:32:49 UTC (rev 15919)
@@ -0,0 +1,47 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.sql.ast.phase.hql.normalize;
+
+import java.util.LinkedList;
+
+/**
+ * Provides a stack of {@link Statement} nodes
+ *
+ * @author Steve Ebersole
+ */
+public class StatementStack {
+ private LinkedList stack = new LinkedList();
+
+ public void push(Statement statement) {
+ stack.addFirst( statement );
+ }
+
+ public Statement pop() {
+ return ( Statement ) stack.removeFirst();
+ }
+
+ public Statement getCurrent() {
+ return ( Statement ) stack.getFirst();
+ }
+}
Deleted:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/path/AbstractPathNormalizationStrategy.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/path/AbstractPathNormalizationStrategy.java 2009-02-09
19:27:30 UTC (rev 15918)
+++
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/path/AbstractPathNormalizationStrategy.java 2009-02-09
19:32:49 UTC (rev 15919)
@@ -1,422 +0,0 @@
-/*
- * Hibernate, Relational Persistence for Idiomatic Java
- *
- * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
- * indicated by the @author tags or express copyright attribution
- * statements applied by the authors. All third-party contributions are
- * distributed under license by Red Hat Middleware LLC.
- *
- * This copyrighted material is made available to anyone wishing to use, modify,
- * copy, or redistribute it subject to the terms and conditions of the GNU
- * Lesser General Public License, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
- * for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this distribution; if not, write to:
- * Free Software Foundation, Inc.
- * 51 Franklin Street, Fifth Floor
- * Boston, MA 02110-1301 USA
- */
-package org.hibernate.sql.ast.phase.hql.normalize.path;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.hibernate.sql.ast.phase.hql.normalize.PropertyReference;
-import org.hibernate.sql.ast.phase.hql.normalize.Ident;
-import org.hibernate.sql.ast.phase.hql.normalize.NormalizationContext;
-import org.hibernate.sql.ast.phase.hql.normalize.AliasBuilder;
-import org.hibernate.sql.ast.phase.hql.normalize.PersisterReferenceBuilder;
-import org.hibernate.sql.ast.phase.hql.normalize.PersisterReference;
-import org.hibernate.sql.ast.phase.hql.normalize.HqlNormalizeTokenTypes;
-import org.hibernate.sql.ast.phase.hql.normalize.Join;
-import org.hibernate.sql.ast.phase.hql.normalize.DuplicateAliasException;
-import org.hibernate.sql.ast.util.ASTPrinter;
-import org.hibernate.sql.ast.util.DisplayableNode;
-import org.hibernate.type.ComponentType;
-import org.hibernate.type.Type;
-import org.hibernate.type.CollectionType;
-import org.hibernate.type.EntityType;
-import org.hibernate.QueryException;
-import org.hibernate.HibernateException;
-import org.hibernate.engine.SessionFactoryImplementor;
-
-import antlr.collections.AST;
-import antlr.CommonAST;
-import antlr.Token;
-
-/**
- * Abstract implementation of {@link PathNormalizationStrategy} providing convenience
methods to actual
- * {@link PathNormalizationStrategy} implementors.
- *
- * @author Steve Ebersole
- */
-public abstract class AbstractPathNormalizationStrategy implements
PathNormalizationStrategy, HqlNormalizeTokenTypes {
- private static final Logger log = LoggerFactory.getLogger(
AbstractPathNormalizationStrategy.class );
-
- protected final NormalizationContext normalizationContext;
- private PersisterReference root; // todo whether we need this depends on how we deciode
to structure the prop-joins...
- private String pathThusFar = null;
-
- protected AbstractPathNormalizationStrategy(NormalizationContext normalizationContext)
{
- this.normalizationContext = normalizationContext;
- }
-
- /**
- * Getter for property 'root'.
- *
- * @return Value for property 'root'.
- */
- protected PersisterReference getRoot() {
- return root;
- }
-
-
- // normalization context
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- /**
- * Getter for property 'normalizationContext'.
- *
- * @return Value for property 'normalizationContext'.
- */
- protected NormalizationContext getNormalizationContext() {
- return normalizationContext;
- }
-
- protected final AST createNode(int type, String text) {
- return getNormalizationContext().getASTFactory().create( type, text );
- }
-
- /**
- * Getter for property 'aliasBuilder'.
- *
- * @return Value for property 'aliasBuilder'.
- */
- protected final AliasBuilder getAliasBuilder() {
- return getNormalizationContext().getAliasBuilder();
- }
-
- /**
- * Getter for property 'persisterReferenceBuilder'.
- *
- * @return Value for property 'persisterReferenceBuilder'.
- */
- protected final PersisterReferenceBuilder getPersisterReferenceBuilder() {
- return getNormalizationContext().getPersisterReferenceBuilder();
- }
-
- /**
- * Getter for property 'sessionFactoryImplementor'.
- *
- * @return Value for property 'sessionFactoryImplementor'.
- */
- protected final SessionFactoryImplementor getSessionFactoryImplementor() {
- return getNormalizationContext().getSessionFactoryImplementor();
- }
-
- /**
- * Getter for property 'ASTPrinter'.
- *
- * @return Value for property 'ASTPrinter'.
- */
- protected final ASTPrinter getASTPrinter() {
- return getNormalizationContext().getPrinter();
- }
-
-
- // path
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- protected void initializePathSoFar(String root) {
- pathThusFar = root;
- }
-
- /**
- * Getter for property 'pathThusFar'.
- *
- * @return Value for property 'pathThusFar'.
- */
- public String getPathThusFar() {
- return pathThusFar;
- }
-
- /**
- * {@inheritDoc}
- */
- public final PathedPropertyReferenceSource handleRoot(PersisterReference
persisterReference) {
- initializePathSoFar( persisterReference.getAlias() );
- root = persisterReference;
- log.trace( "handling root path source [" + pathThusFar + "]" );
- return internalHandleRoot( persisterReference );
- }
-
- /**
- * Hook for subclasses to process the path root.
- *
- * @param persisterReference The persister defining the source root.
- * @return The appropriate property path source implementation.
- */
- protected abstract PathedPropertyReferenceSource internalHandleRoot(PersisterReference
persisterReference);
-
- /**
- * {@inheritDoc}
- */
- public final PathedPropertyReferenceSource
handleIntermediatePathPart(PathedPropertyReferenceSource source, Ident pathPart) {
- pathThusFar = ( pathThusFar == null ) ? pathPart.getText() : pathThusFar +
"." + pathPart.getText();
- log.trace( "handling intermediate path source [" + pathThusFar +
"]" );
- return internalResolveIntermediatePathPart( source, pathPart );
- }
-
- /**
- * Hook for subclasses to process an intermediate part of the path.
- *
- * @param source The source from which pathPart originates.
- * @param pathPart The name of the path part to be processed.
- * @return The appropriate property path source implementation.
- */
- protected PathedPropertyReferenceSource
internalResolveIntermediatePathPart(PathedPropertyReferenceSource source, Ident pathPart)
{
- return source.handleIntermediatePathPart( pathPart );
- }
-
- /**
- * {@inheritDoc}
- */
- public final PropertyReference handleTerminalPathPart(PathedPropertyReferenceSource
source, Ident pathPart) {
- pathThusFar = ( pathThusFar == null ) ? pathPart.getText() : pathThusFar +
"." + pathPart.getText();
- log.trace( "handling terminal path part [" + pathThusFar + "]" );
- try {
- return internalResolveTerminalPathPart( source, pathPart );
- }
- finally {
- pathThusFar = null;
- }
- }
-
- /**
- * Hook for subclasses to process the terminal (or ending) part of a path.
- *
- * @param source The source from which pathPart originates.
- * @param pathPart The name of the path part to be processed.
- * @return a {@link #PROPERTY_REF} node representing the normalized property path.
- */
- protected PropertyReference
internalResolveTerminalPathPart(PathedPropertyReferenceSource source, Ident pathPart) {
- return source.handleTerminalPathPart( pathPart );
- }
-
- /**
- * Convenience method to locate the index of a component sub-property. The returned
index is relative to
- * {@link ComponentType#getPropertyNames}.
- *
- * @param componentType The component type mapping.
- * @param subPropertyName The sub-property name.
- * @return The index.
- */
- protected final int locateComponentPropertyIndex(ComponentType componentType, Ident
subPropertyName) {
- return locateComponentPropertyIndex( componentType, subPropertyName.getText() );
- }
-
- /**
- * Convenience method to locate the index of a component sub-property. The returned
index is relative to
- * {@link ComponentType#getPropertyNames}.
- *
- * @param componentType The component type mapping.
- * @param subPropertyName The sub-property name.
- * @return The index.
- */
- protected static int locateComponentPropertyIndex(ComponentType componentType, String
subPropertyName) {
- String[] componentPropertyNames = componentType.getPropertyNames();
- for ( int i = 0; i < componentPropertyNames.length; i++ ) {
- if ( componentPropertyNames[i].equals( subPropertyName ) ) {
- return i;
- }
- }
- throw new QueryException( "could not locate component property [" +
subPropertyName + "]" );
- }
-
- /**
- * Generate a {@link #PROPERTY_REF} node.
- *
- * @param origin The persister from which the property originates.
- * @param propertyName The name of the property being referenced.
- * @return The {@link #PROPERTY_REF} node.
- */
- protected final PropertyReference generatePropertyReference(PersisterReference origin,
String propertyName) {
- AST propertyReference = createNode( PROPERTY_REF, "property-reference" );
- propertyReference.addChild( createNode( ALIAS_REF, origin.getAlias() ) );
- propertyReference.addChild( createNode( IDENT, propertyName ) );
- return ( PropertyReference ) propertyReference;
- }
-
- /**
- * Locate (if property joins are reusable) or build an appropriate join.
- *
- * @param lhs The join lhs, which is the origin of the property.
- * @param propertyName The name of the property
- * @param alias The alias, if any, to apply to the generated RHS persister reference.
- * @param propertyFetching Should property fetching be applied to the generated RHS?
- * @param associationFetch Did this property join specify association fetching (join
fetch)?
- * @return The appropriate join.
- */
- protected final Join locateOrBuildPropertyJoin(
- PersisterReference lhs,
- String propertyName,
- String alias,
- boolean propertyFetching,
- boolean associationFetch) {
- Join join = null;
-
- if ( areJoinsReusable() ) {
- join = lhs.locateReusablePropertyJoin( propertyName );
- }
-
- if ( join == null ) {
- join = buildPropertyJoin( lhs, propertyName, alias, propertyFetching, associationFetch
);
- if ( areJoinsReusable() ) {
- lhs.registerReusablePropertyJoin( propertyName, join );
- }
- }
-
- return join;
- }
-
- /**
- * Build a property join node.
- *
- * @param lhs The join's left-hand-side persister-reference
- * @param propertyName The property name.
- * @param alias The alias to apply to the rhs of the join
- * @param propertyFetching should property fetching be applied to the joined persister?
- * @param associationFetch Should the association making up the property join also be
fetched?
- *
- * @return The right-hand-side persister-reference.
- */
- protected Join buildPropertyJoin(
- PersisterReference lhs,
- String propertyName,
- String alias,
- boolean propertyFetching,
- boolean associationFetch) {
- validateJoinCreation( lhs, propertyName );
-
- PersisterReference rhs = null;
- final Type associationType = lhs.getPropertyType( propertyName );
- if ( associationType.isCollectionType() ) {
- CollectionType collectionType = ( CollectionType ) associationType;
- rhs = getPersisterReferenceBuilder().buildCollectionPersisterReference(
- collectionType.getRole(),
- alias,
- propertyFetching
- );
- }
- else if ( associationType.isEntityType() ) {
- EntityType entityType = ( EntityType ) associationType;
- String entityName = entityType.getAssociatedEntityName( getSessionFactoryImplementor()
);
- rhs = getPersisterReferenceBuilder().buildEntityPersisterReference( entityName, alias,
propertyFetching );
- }
- else {
- throw new HibernateException( "cannot create join on non-association [name="
+ propertyName + ", type=" + associationType + "]" );
- }
-
- Join propertyJoinNode = ( Join ) createNode( JOIN, "join" );
- propertyJoinNode.setFirstChild( buildJoinTypeNode() );
- propertyJoinNode.addChild( rhs );
-
- // todo : handle mapped join conditions, adding them to the tree
-
- if ( associationFetch ) {
- registerAssociationFetch( propertyJoinNode );
- }
-
- if ( log.isTraceEnabled() ) {
- log.trace(
- getASTPrinter().showAsString(
- propertyJoinNode,
- "implicit join [" + lhs.getAlias() + "." + propertyName +
"]"
- )
- );
- }
-
- lhs.addChild( propertyJoinNode );
-
- return propertyJoinNode;
- }
-
- /**
- * Hook to allow subclasses to disallow implicit join.
- *
- * @param origin The persister-reference which is the origin of the property
- * @param property The property resulting in a join.
- */
- protected void validateJoinCreation(PersisterReference origin, String property) {
- log.debug( "creating path expression implied join [" + origin.getAlias() +
"].[" + property + "]" );
- }
-
- private void registerAssociationFetch(Join propertyJoinNode) {
- // todo : implement
- }
-
- /**
- * Hook to allow subclasses to define the type of join to use for an implciit join.
- * <p/>
- * The default is to use an {@link #INNER} join.
- *
- * @return The join type node.
- */
- protected AST buildJoinTypeNode() {
- return createNode( INNER, "inner" );
- }
-
- /**
- * Does this strategy allows property joins to be reused?
- *
- * @return True/false.
- */
- protected boolean areJoinsReusable() {
- return true;
- }
-
-
- // source impl support
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- public abstract class AbstractPathedPropertyReferenceSource extends CommonAST
- implements PathedPropertyReferenceSource, DisplayableNode {
- private final String originationPath;
-
- /**
- * Constructs a new AbstractPathedPropertyReferenceSource.
- */
- protected AbstractPathedPropertyReferenceSource() {
- this( getPathThusFar() );
- }
-
- protected AbstractPathedPropertyReferenceSource(Token token) {
- this( token, getPathThusFar() );
- }
-
- protected AbstractPathedPropertyReferenceSource(String originationPath) {
- this.originationPath = originationPath;
- }
-
- protected AbstractPathedPropertyReferenceSource(Token token, String originationPath) {
- super( token );
- this.originationPath = originationPath;
- }
-
- /**
- * {@inheritDoc}
- */
- public String getOriginationPath() {
- return originationPath;
- }
-
- /**
- * {@inheritDoc}
- */
- public final String getDisplayText() {
- return " ADPATER : SHOULD NEVER END UP IN TREE!";
- }
- }
-}
Modified:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/path/PathNormalizationStrategy.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/path/PathNormalizationStrategy.java 2009-02-09
19:27:30 UTC (rev 15918)
+++
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/path/PathNormalizationStrategy.java 2009-02-09
19:32:49 UTC (rev 15919)
@@ -24,12 +24,13 @@
package org.hibernate.sql.ast.phase.hql.normalize.path;
import org.hibernate.sql.ast.phase.hql.normalize.PersisterReference;
-import org.hibernate.sql.ast.phase.hql.normalize.PropertyReference;
import org.hibernate.sql.ast.phase.hql.normalize.Ident;
+import org.hibernate.sql.ast.phase.hql.normalize.PropertyPathTerminus;
+import org.hibernate.sql.ast.common.Node;
/**
* Applies a strategy pattern to the manner in which path expressions are normalized,
allowing contextual pluggability
- * of the implicit-join handling rules...
+ * of the implicit-join and index-access handling rules...
*
* @author Steve Ebersole
*/
@@ -61,5 +62,9 @@
*
* @return The terminal property reference indicated by the overall path.
*/
- public PropertyReference handleTerminalPathPart(PathedPropertyReferenceSource source,
Ident pathPart);
+ public PropertyPathTerminus handleTerminalPathPart(PathedPropertyReferenceSource source,
Ident pathPart);
+
+ public PathedPropertyReferenceSource
handleIntermediateIndexAccess(PathedPropertyReferenceSource source, Ident name, Node
selector);
+
+ public PropertyPathTerminus handleTerminalIndexAccess(PathedPropertyReferenceSource
source, Ident name, Node selector);
}
Modified:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/path/PathedPropertyReferenceSource.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/path/PathedPropertyReferenceSource.java 2009-02-09
19:27:30 UTC (rev 15918)
+++
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/path/PathedPropertyReferenceSource.java 2009-02-09
19:32:49 UTC (rev 15919)
@@ -25,8 +25,9 @@
import antlr.collections.AST;
-import org.hibernate.sql.ast.phase.hql.normalize.PropertyReference;
import org.hibernate.sql.ast.phase.hql.normalize.Ident;
+import org.hibernate.sql.ast.phase.hql.normalize.PropertyPathTerminus;
+import org.hibernate.sql.ast.common.Node;
/**
* The contract for representing the non-terminal parts of a property path expression
@@ -60,5 +61,9 @@
*
* @return The property reference.
*/
- public PropertyReference handleTerminalPathPart(Ident name);
+ public PropertyPathTerminus handleTerminalPathPart(Ident name);
+
+ public PathedPropertyReferenceSource handleIntermediateIndexAccess(Ident name, Node
selector);
+
+ public PropertyPathTerminus handleTerminalIndexAccess(Ident name, Node selector);
}
Copied:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/path/impl/AbstractPathNormalizationStrategy.java
(from rev 15747,
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/path/AbstractPathNormalizationStrategy.java)
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/path/impl/AbstractPathNormalizationStrategy.java
(rev 0)
+++
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/path/impl/AbstractPathNormalizationStrategy.java 2009-02-09
19:32:49 UTC (rev 15919)
@@ -0,0 +1,448 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.sql.ast.phase.hql.normalize.path.impl;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.hibernate.sql.ast.phase.hql.normalize.PropertyReference;
+import org.hibernate.sql.ast.phase.hql.normalize.Ident;
+import org.hibernate.sql.ast.phase.hql.normalize.NormalizationContext;
+import org.hibernate.sql.ast.alias.ImplicitAliasGenerator;
+import org.hibernate.sql.ast.phase.hql.normalize.PersisterReferenceBuilder;
+import org.hibernate.sql.ast.phase.hql.normalize.PersisterReference;
+import org.hibernate.sql.ast.phase.hql.normalize.HqlNormalizeTokenTypes;
+import org.hibernate.sql.ast.phase.hql.normalize.Join;
+import org.hibernate.sql.ast.phase.hql.normalize.PropertyPathTerminus;
+import org.hibernate.sql.ast.phase.hql.normalize.path.PathNormalizationStrategy;
+import org.hibernate.sql.ast.phase.hql.normalize.path.PathedPropertyReferenceSource;
+import org.hibernate.sql.ast.util.ASTPrinter;
+import org.hibernate.sql.ast.util.DisplayableNode;
+import org.hibernate.sql.ast.common.Node;
+import org.hibernate.type.ComponentType;
+import org.hibernate.QueryException;
+import org.hibernate.engine.SessionFactoryImplementor;
+
+import antlr.collections.AST;
+import antlr.CommonAST;
+import antlr.Token;
+
+/**
+ * Abstract implementation of {@link
org.hibernate.sql.ast.phase.hql.normalize.path.PathNormalizationStrategy} providing
convenience methods to actual
+ * {@link org.hibernate.sql.ast.phase.hql.normalize.path.PathNormalizationStrategy}
implementors.
+ *
+ * @author Steve Ebersole
+ */
+public abstract class AbstractPathNormalizationStrategy implements
PathNormalizationStrategy, HqlNormalizeTokenTypes {
+ private static final Logger log = LoggerFactory.getLogger(
AbstractPathNormalizationStrategy.class );
+
+ private final NormalizationContext normalizationContext;
+ private PersisterReference root; // todo whether we need this depends on how we deciode
to structure the prop-joins...
+ private String pathThusFar = null;
+
+ protected AbstractPathNormalizationStrategy(NormalizationContext normalizationContext)
{
+ this.normalizationContext = normalizationContext;
+ }
+
+ /**
+ * Getter for property 'root'.
+ *
+ * @return Value for property 'root'.
+ */
+ protected PersisterReference getRoot() {
+ return root;
+ }
+
+
+ // normalization context
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ /**
+ * Getter for property 'normalizationContext'.
+ *
+ * @return Value for property 'normalizationContext'.
+ */
+ protected NormalizationContext normalizationContext() {
+ return normalizationContext;
+ }
+
+ protected final Node createNode(int type, String text) {
+ return ( Node ) normalizationContext().getASTFactory().create( type, text );
+ }
+
+ /**
+ * Getter for property 'aliasBuilder'.
+ *
+ * @return Value for property 'aliasBuilder'.
+ */
+ protected final ImplicitAliasGenerator getAliasBuilder() {
+ return normalizationContext().getAliasBuilder();
+ }
+
+ /**
+ * Getter for property 'persisterReferenceBuilder'.
+ *
+ * @return Value for property 'persisterReferenceBuilder'.
+ */
+ protected final PersisterReferenceBuilder getPersisterReferenceBuilder() {
+ return normalizationContext().getPersisterReferenceBuilder();
+ }
+
+ /**
+ * Getter for property 'sessionFactoryImplementor'.
+ *
+ * @return Value for property 'sessionFactoryImplementor'.
+ */
+ protected final SessionFactoryImplementor getSessionFactoryImplementor() {
+ return normalizationContext().getSessionFactoryImplementor();
+ }
+
+ /**
+ * Getter for property 'ASTPrinter'.
+ *
+ * @return Value for property 'ASTPrinter'.
+ */
+ protected final ASTPrinter getASTPrinter() {
+ return normalizationContext().getPrinter();
+ }
+
+
+ // path
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ protected void initializePathSoFar(String root) {
+ pathThusFar = root;
+ }
+
+ /**
+ * Getter for property 'pathThusFar'.
+ *
+ * @return Value for property 'pathThusFar'.
+ */
+ public String getPathThusFar() {
+ return pathThusFar;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public final PathedPropertyReferenceSource handleRoot(PersisterReference
persisterReference) {
+ initializePathSoFar( persisterReference.getAlias() );
+ root = persisterReference;
+ log.trace( "handling root path source [" + pathThusFar + "]" );
+ return internalHandleRoot( persisterReference );
+ }
+
+ /**
+ * Hook for subclasses to process the path root.
+ *
+ * @param persisterReference The persister defining the source root.
+ * @return The appropriate property path source implementation.
+ */
+ protected abstract PathedPropertyReferenceSource internalHandleRoot(PersisterReference
persisterReference);
+
+ /**
+ * {@inheritDoc}
+ */
+ public final PathedPropertyReferenceSource
handleIntermediatePathPart(PathedPropertyReferenceSource source, Ident pathPart) {
+ pathThusFar = ( pathThusFar == null ) ? pathPart.getText() : pathThusFar +
"." + pathPart.getText();
+ log.trace( "handling intermediate path source [" + pathThusFar +
"]" );
+ return internalResolveIntermediatePathPart( source, pathPart );
+ }
+
+ /**
+ * Hook for subclasses to process an intermediate part of the path.
+ *
+ * @param source The source from which pathPart originates.
+ * @param pathPart The name of the path part to be processed.
+ * @return The appropriate property path source implementation.
+ */
+ protected PathedPropertyReferenceSource
internalResolveIntermediatePathPart(PathedPropertyReferenceSource source, Ident pathPart)
{
+ return source.handleIntermediatePathPart( pathPart );
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public final PropertyPathTerminus handleTerminalPathPart(PathedPropertyReferenceSource
source, Ident pathPart) {
+ pathThusFar = ( pathThusFar == null ) ? pathPart.getText() : pathThusFar +
"." + pathPart.getText();
+ log.trace( "handling terminal path part [" + pathThusFar + "]" );
+ try {
+ return internalResolveTerminalPathPart( source, pathPart );
+ }
+ finally {
+ pathThusFar = null;
+ }
+ }
+
+ /**
+ * Hook for subclasses to process the terminal (or ending) part of a path.
+ *
+ * @param source The source from which pathPart originates.
+ * @param pathPart The name of the path part to be processed.
+ * @return a node representing the normalized property path.
+ */
+ protected PropertyPathTerminus
internalResolveTerminalPathPart(PathedPropertyReferenceSource source, Ident pathPart) {
+ return source.handleTerminalPathPart( pathPart );
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public final PathedPropertyReferenceSource
handleIntermediateIndexAccess(PathedPropertyReferenceSource source, Ident pathPart, Node
selector) {
+ pathThusFar = ( ( pathThusFar == null ) ? pathPart.getText() : pathThusFar +
"." + pathPart.getText() ) + "[]";
+ log.trace( "handling intermediate index access [" + pathThusFar +
"]" );
+ try {
+ return internalHandleIntermediateIndexAccess( source, pathPart, selector );
+ }
+ finally {
+ pathThusFar = null;
+ }
+ }
+
+ /**
+ * Hook for subclasses to process an index access as an intermediate property path.
+ *
+ * @param source The source from which pathPart originates.
+ * @param pathPart The name of the path part to be processed.
+ * @param selector The index selector to be appliedto the indexed collection
+ *
+ * @return The appropriate property path source implementation.
+ */
+ protected PathedPropertyReferenceSource
internalHandleIntermediateIndexAccess(PathedPropertyReferenceSource source, Ident
pathPart, Node selector) {
+ return source.handleIntermediateIndexAccess( pathPart, selector );
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public final PropertyPathTerminus
handleTerminalIndexAccess(PathedPropertyReferenceSource source, Ident pathPart, Node
selector) {
+ pathThusFar = ( ( pathThusFar == null ) ? pathPart.getText() : pathThusFar +
"." + pathPart.getText() ) + "[]";
+ log.trace( "handling terminal index access [" + pathThusFar + "]"
);
+ try {
+ return internalHandleTerminalIndexAccess( source, pathPart, selector );
+ }
+ finally {
+ pathThusFar = null;
+ }
+ }
+
+ /**
+ * Hook for subclasses to process an index access as the terminus of a property path.
+ *
+ * @param source The source from which pathPart originates.
+ * @param pathPart The name of the path part to be processed.
+ * @param selector The index selector to be appliedto the indexed collection
+ *
+ * @return a node representing the normalized property path.
+ */
+ protected PropertyPathTerminus
internalHandleTerminalIndexAccess(PathedPropertyReferenceSource source, Ident pathPart,
Node selector) {
+ return source.handleTerminalIndexAccess( pathPart, selector );
+ }
+
+ /**
+ * Convenience method to locate the index of a component sub-property. The returned
index is relative to
+ * {@link ComponentType#getPropertyNames}.
+ *
+ * @param componentType The component type mapping.
+ * @param subPropertyName The sub-property name.
+ * @return The index.
+ */
+ protected final int locateComponentPropertyIndex(ComponentType componentType, Ident
subPropertyName) {
+ return locateComponentPropertyIndex( componentType, subPropertyName.getText() );
+ }
+
+ /**
+ * Convenience method to locate the index of a component sub-property. The returned
index is relative to
+ * {@link ComponentType#getPropertyNames}.
+ *
+ * @param componentType The component type mapping.
+ * @param subPropertyName The sub-property name.
+ * @return The index.
+ */
+ protected static int locateComponentPropertyIndex(ComponentType componentType, String
subPropertyName) {
+ String[] componentPropertyNames = componentType.getPropertyNames();
+ for ( int i = 0; i < componentPropertyNames.length; i++ ) {
+ if ( componentPropertyNames[i].equals( subPropertyName ) ) {
+ return i;
+ }
+ }
+ throw new QueryException( "could not locate component property [" +
subPropertyName + "]" );
+ }
+
+ /**
+ * Generate a {@link #PROPERTY_REF} node.
+ *
+ * @param origin The persister from which the property originates.
+ * @param propertyName The name of the property being referenced.
+ * @return The {@link #PROPERTY_REF} node.
+ */
+ protected final PropertyReference generatePropertyReference(PersisterReference origin,
String propertyName) {
+ AST propertyReference = createNode( PROPERTY_REF, "property-reference" );
+ propertyReference.addChild( createNode( ALIAS_REF, origin.getAlias() ) );
+ propertyReference.addChild( createNode( IDENT, propertyName ) );
+ return ( PropertyReference ) propertyReference;
+ }
+
+ /**
+ * Locate (if property joins are reusable) or build an appropriate join.
+ *
+ * @param lhs The join lhs, which is the origin of the property.
+ * @param propertyName The name of the property
+ * @param alias The alias, if any, to apply to the generated RHS persister reference.
+ * @param propertyFetching Should property fetching be applied to the generated RHS?
+ * @param associationFetching Did this property join specify association fetching (join
fetch)?
+ * @return The appropriate join.
+ */
+ protected final Join locateOrBuildPropertyJoin(
+ PersisterReference lhs,
+ String propertyName,
+ String alias,
+ boolean propertyFetching,
+ boolean associationFetching) {
+ Join join = null;
+
+ if ( areJoinsReusable() ) {
+ join = lhs.locateReusablePropertyJoin( propertyName );
+ }
+
+ if ( join == null ) {
+ join = buildPropertyJoin( lhs, propertyName, alias, propertyFetching,
associationFetching );
+ if ( areJoinsReusable() ) {
+ lhs.registerReusablePropertyJoin( propertyName, join );
+ }
+ }
+
+ return join;
+ }
+
+ /**
+ * Build a property join node.
+ *
+ * @param lhs The join's left-hand-side persister-reference
+ * @param propertyName The property name.
+ * @param alias The alias to apply to the rhs of the join
+ * @param propertyFetching should property fetching be applied to the joined persister?
+ * @param associationFetching Should the association making up the property join also be
fetched?
+ *
+ * @return The right-hand-side persister-reference.
+ */
+ protected Join buildPropertyJoin(
+ PersisterReference lhs,
+ String propertyName,
+ String alias,
+ boolean propertyFetching,
+ boolean associationFetching) {
+ validateJoinCreation( lhs, propertyName );
+ return normalizationContext().getPropertyJoinBuilder().buildPropertyJoin(
+ lhs,
+ propertyName,
+ alias,
+ buildJoinTypeNode(),
+ propertyFetching,
+ associationFetching
+ );
+ }
+
+ /**
+ * Hook to allow subclasses to disallow implicit join.
+ *
+ * @param origin The persister-reference which is the origin of the property
+ * @param property The property resulting in a join.
+ */
+ protected void validateJoinCreation(PersisterReference origin, String property) {
+ log.debug( "creating path expression implied join [" + origin.getAlias() +
"].[" + property + "]" );
+ }
+
+ /**
+ * Hook to allow subclasses to define the type of join to use for an implciit join.
+ * <p/>
+ * The default is to use an {@link #INNER} join.
+ *
+ * @return The join type node.
+ */
+ protected Node buildJoinTypeNode() {
+ return createNode( INNER, "inner" );
+ }
+
+ /**
+ * Does this strategy allows property joins to be reused?
+ *
+ * @return True/false.
+ */
+ protected boolean areJoinsReusable() {
+ return true;
+ }
+
+
+ // source impl support
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ public abstract class AbstractPathedPropertyReferenceSource extends CommonAST
+ implements PathedPropertyReferenceSource, DisplayableNode {
+ private final String originationPath;
+
+ /**
+ * Constructs a new AbstractPathedPropertyReferenceSource.
+ */
+ protected AbstractPathedPropertyReferenceSource() {
+ this( getPathThusFar() );
+ }
+
+ protected AbstractPathedPropertyReferenceSource(Token token) {
+ this( token, getPathThusFar() );
+ }
+
+ protected AbstractPathedPropertyReferenceSource(String originationPath) {
+ this.originationPath = originationPath;
+ }
+
+ protected AbstractPathedPropertyReferenceSource(Token token, String originationPath) {
+ super( token );
+ this.originationPath = originationPath;
+ }
+
+ public PropertyPathTerminus handleTerminalIndexAccess(PersisterReference lhs, Ident
name, Node selector) {
+ Join join = normalizationContext().getPropertyJoinBuilder().buildIndexOperationJoin(
+ lhs,
+ name.getText(),
+ null,
+ buildJoinTypeNode(),
+ selector
+ );
+ return ( PropertyPathTerminus ) createNode( INDEXED_COLLECTION_ELEMENT_REF,
join.locateRhs().getAlias() );
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getOriginationPath() {
+ return originationPath;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public final String getDisplayText() {
+ return " ADPATER : SHOULD NEVER END UP IN TREE!";
+ }
+ }
+}
Modified:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/path/impl/BasicPathNormalizationStrategySupport.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/path/impl/BasicPathNormalizationStrategySupport.java 2009-02-09
19:27:30 UTC (rev 15918)
+++
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/path/impl/BasicPathNormalizationStrategySupport.java 2009-02-09
19:32:49 UTC (rev 15919)
@@ -29,10 +29,12 @@
import org.hibernate.sql.ast.phase.hql.normalize.PersisterReference;
import org.hibernate.sql.ast.phase.hql.normalize.NormalizationContext;
import org.hibernate.sql.ast.phase.hql.normalize.Ident;
-import org.hibernate.sql.ast.phase.hql.normalize.PropertyReference;
import org.hibernate.sql.ast.phase.hql.normalize.Join;
-import org.hibernate.sql.ast.phase.hql.normalize.path.AbstractPathNormalizationStrategy;
+import
org.hibernate.sql.ast.phase.hql.normalize.IndexedCollectionElementAccessPersisterReference;
+import org.hibernate.sql.ast.phase.hql.normalize.PropertyPathTerminus;
+import
org.hibernate.sql.ast.phase.hql.normalize.path.impl.AbstractPathNormalizationStrategy;
import org.hibernate.sql.ast.phase.hql.normalize.path.PathedPropertyReferenceSource;
+import org.hibernate.sql.ast.common.Node;
import org.hibernate.type.Type;
import org.hibernate.type.ComponentType;
import org.hibernate.type.EntityType;
@@ -128,7 +130,7 @@
return determineAppropriateIntermediateSourceType( lhs, name );
}
- public PropertyReference handleTerminalPathPart(Ident name) {
+ public PropertyPathTerminus handleTerminalPathPart(Ident name) {
final String nameText = name.getText();
if ( lhs.getPropertyType( nameText ).isEntityType() ) {
if ( shouldTerminalEntityPropertyForceJoin() ) {
@@ -138,6 +140,21 @@
return generatePropertyReference( lhs, name.getText() );
}
+ public PathedPropertyReferenceSource handleIntermediateIndexAccess(Ident name, Node
selector) {
+ Join join = normalizationContext().getPropertyJoinBuilder().buildIndexOperationJoin(
+ lhs,
+ name.getText(),
+ null,
+ buildJoinTypeNode(),
+ selector
+ );
+ return new IndexAccessIntermediatePathSource( join.locateRhs() );
+ }
+
+ public PropertyPathTerminus handleTerminalIndexAccess(Ident name, Node selector) {
+ return super.handleTerminalIndexAccess( lhs, name, selector );
+ }
+
public String getText() {
return "root-source {" + lhs.getAlias() + "}";
}
@@ -148,9 +165,17 @@
throw new HibernateException( "cannot dereference simple value as part of path
expression" );
}
- public PropertyReference handleTerminalPathPart(Ident name) {
+ public PropertyPathTerminus handleTerminalPathPart(Ident name) {
throw new HibernateException( "cannot dereference simple value as part of path
expression" );
}
+
+ public PathedPropertyReferenceSource handleIntermediateIndexAccess(Ident name, Node
selector) {
+ throw new HibernateException( "cannot apply index operation to simple value"
);
+ }
+
+ public PropertyPathTerminus handleTerminalIndexAccess(Ident name, Node selector) {
+ throw new HibernateException( "cannot apply index operation to simple value"
);
+ }
}
private class ComponentIntermediatePathSource extends
AbstractPathedPropertyReferenceSource {
@@ -184,10 +209,18 @@
}
}
- public PropertyReference handleTerminalPathPart(Ident name) {
+ public PropertyPathTerminus handleTerminalPathPart(Ident name) {
return generatePropertyReference( lhs, buildComponentDereferencePath( name.getText() )
);
}
+ public PathedPropertyReferenceSource handleIntermediateIndexAccess(Ident name, Node
selector) {
+ throw new HibernateException( "cannot apply index operation to component
value" );
+ }
+
+ public PropertyPathTerminus handleTerminalIndexAccess(Ident name, Node selector) {
+ throw new HibernateException( "cannot apply index operation to component
value" );
+ }
+
private String buildComponentDereferencePath(String subPropertyName) {
return propertyPath + "." + subPropertyName;
}
@@ -204,10 +237,10 @@
public PathedPropertyReferenceSource handleIntermediatePathPart(Ident name) {
Join join = locateOrBuildPropertyJoin( lhs, lhsPropertyName, null, false, false );
- return determineAppropriateIntermediateSourceType( join.getRhs(), name );
+ return determineAppropriateIntermediateSourceType( join.locateRhs(), name );
}
- public PropertyReference handleTerminalPathPart(Ident name) {
+ public PropertyPathTerminus handleTerminalPathPart(Ident name) {
final EntityType type = ( EntityType ) lhs.getPropertyType( lhsPropertyName );
if ( isReferenceToPrimaryKey( type, lhsPropertyName ) ) {
return generatePropertyReference( lhs, lhsPropertyName + "." +
name.getText() );
@@ -217,12 +250,27 @@
final String propertyName = name.getText();
if ( type.isEntityType() ) {
if ( shouldTerminalEntityPropertyForceJoin() ) {
- locateOrBuildPropertyJoin( join.getRhs(), propertyName, null, false, false );
+ locateOrBuildPropertyJoin( join.locateRhs(), propertyName, null, false, false );
}
}
- return generatePropertyReference( join.getRhs(), propertyName );
+ return generatePropertyReference( join.locateRhs(), propertyName );
}
}
+
+ public PathedPropertyReferenceSource handleIntermediateIndexAccess(Ident name, Node
selector) {
+ Join join = normalizationContext().getPropertyJoinBuilder().buildIndexOperationJoin(
+ lhs,
+ name.getText(),
+ null,
+ buildJoinTypeNode(),
+ selector
+ );
+ return new IndexAccessIntermediatePathSource( join.locateRhs() );
+ }
+
+ public PropertyPathTerminus handleTerminalIndexAccess(Ident name, Node selector) {
+ return super.handleTerminalIndexAccess( lhs, name, selector );
+ }
}
protected boolean shouldTerminalEntityPropertyForceJoin() {
@@ -242,14 +290,51 @@
throw new HibernateException( "cannot implicit join across a collection
association" );
}
- public PropertyReference handleTerminalPathPart(Ident name) {
+ public PropertyPathTerminus handleTerminalPathPart(Ident name) {
// TODO : what are the circusmstances under which we need to *join* to the collection,
as opposed to say munge it into a subquery???
final String nameText = name.getText();
if ( CollectionProperties.isAnyCollectionProperty( nameText ) ) {
Join join = locateOrBuildPropertyJoin( lhs, propertyName, null, false, false );
- return generatePropertyReference( join.getRhs(), nameText );
+ return generatePropertyReference( join.locateRhs(), nameText );
}
throw new HibernateException( "cannot implicit join across a collection
association" );
}
+
+ public PathedPropertyReferenceSource handleIntermediateIndexAccess(Ident name, Node
selector) {
+ throw new HibernateException( "cannot implicit join across a collection
association" );
+ }
+
+ public PropertyPathTerminus handleTerminalIndexAccess(Ident name, Node selector) {
+ throw new HibernateException( "cannot implicit join across a collection
association" );
+ }
}
+
+ protected class IndexAccessIntermediatePathSource extends
AbstractPathedPropertyReferenceSource {
+ private final IndexedCollectionElementAccessPersisterReference persisterReference;
+
+ public IndexAccessIntermediatePathSource(PersisterReference persisterReference) {
+ if ( persisterReference instanceof IndexedCollectionElementAccessPersisterReference )
{
+ this.persisterReference = ( IndexedCollectionElementAccessPersisterReference )
persisterReference;
+ }
+ else {
+ throw new HibernateException( "Expecting
IndexedCollectionElementAccessPersisterReference, found " +
persisterReference.getClass().getName() );
+ }
+ }
+
+ public PathedPropertyReferenceSource handleIntermediatePathPart(Ident name) {
+ return determineAppropriateIntermediateSourceType( persisterReference, name );
+ }
+
+ public PropertyPathTerminus handleTerminalPathPart(Ident name) {
+ return generatePropertyReference( persisterReference, name.getText() );
+ }
+
+ public PathedPropertyReferenceSource handleIntermediateIndexAccess(Ident name, Node
selector) {
+ throw new IllegalStateException( "doubled up index operators" );
+ }
+
+ public PropertyPathTerminus handleTerminalIndexAccess(Ident name, Node selector) {
+ throw new IllegalStateException( "doubled up index operators" );
+ }
+ }
}
\ No newline at end of file
Modified:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/path/impl/FromClausePathNormalizationStrategy.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/path/impl/FromClausePathNormalizationStrategy.java 2009-02-09
19:27:30 UTC (rev 15918)
+++
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/path/impl/FromClausePathNormalizationStrategy.java 2009-02-09
19:32:49 UTC (rev 15919)
@@ -23,17 +23,18 @@
*/
package org.hibernate.sql.ast.phase.hql.normalize.path.impl;
-import antlr.collections.AST;
-
import org.hibernate.sql.ast.phase.hql.normalize.PersisterReference;
import org.hibernate.sql.ast.phase.hql.normalize.PropertyReference;
import org.hibernate.sql.ast.phase.hql.normalize.Ident;
import org.hibernate.sql.ast.phase.hql.normalize.NormalizationContext;
import org.hibernate.sql.ast.phase.hql.normalize.HqlNormalizeTokenTypes;
-import org.hibernate.sql.ast.phase.hql.normalize.path.AbstractPathNormalizationStrategy;
+import org.hibernate.sql.ast.phase.hql.normalize.PropertyPathTerminus;
+import org.hibernate.sql.ast.phase.hql.normalize.Join;
+import
org.hibernate.sql.ast.phase.hql.normalize.path.impl.AbstractPathNormalizationStrategy;
import org.hibernate.sql.ast.phase.hql.normalize.path.PathNormalizationStrategy;
import org.hibernate.sql.ast.phase.hql.normalize.path.PathedPropertyReferenceSource;
import org.hibernate.sql.ast.common.JoinType;
+import org.hibernate.sql.ast.common.Node;
import org.hibernate.type.Type;
import org.hibernate.HibernateException;
import org.hibernate.QueryException;
@@ -80,6 +81,18 @@
return new SourceImpl( persisterReference );
}
+ protected Join buildPropertyJoin(
+ PersisterReference lhs,
+ String propertyName,
+ String alias,
+ boolean propertyFetching,
+ boolean associationFetching) {
+ Join join = super.buildPropertyJoin( lhs, propertyName, alias, propertyFetching,
associationFetching );
+ normalizationContext().getCurrentPersisterReferenceContext()
+ .registerPersisterReferenceImplicitInDerivedSelectClause( join.locateRhs() );
+ return join;
+ }
+
private class SourceImpl extends AbstractPathedPropertyReferenceSource {
private final PersisterReference lhs;
@@ -89,10 +102,10 @@
public PathedPropertyReferenceSource handleIntermediatePathPart(Ident name) {
// TODO : still need to account for paths including component dereferences...
- return new SourceImpl( locateOrBuildPropertyJoin( lhs, name.getText(), null, false,
associationFetch ).getRhs() );
+ return new SourceImpl( locateOrBuildPropertyJoin( lhs, name.getText(), null, false,
associationFetch ).locateRhs() );
}
- public PropertyReference handleTerminalPathPart(Ident name) {
+ public PropertyPathTerminus handleTerminalPathPart(Ident name) {
final String propertyName = name.getText();
Type terminalPropertyType = lhs.getPropertyType( propertyName );
if ( !terminalPropertyType.isAssociationType() ) {
@@ -106,9 +119,17 @@
return propertyReference;
}
+
+ public PathedPropertyReferenceSource handleIntermediateIndexAccess(Ident name, Node
selector) {
+ throw new UnsupportedOperationException( "index operation not supported in from
clause" );
+ }
+
+ public PropertyPathTerminus handleTerminalIndexAccess(Ident name, Node selector) {
+ throw new UnsupportedOperationException( "index operation not supported in from
clause" );
+ }
}
- protected AST buildJoinTypeNode() {
+ protected Node buildJoinTypeNode() {
if ( joinType == JoinType.INNER ) {
return createNode( INNER, "inner" );
}
Modified:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/path/impl/SelectClausePathNormalizationStrategy.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/path/impl/SelectClausePathNormalizationStrategy.java 2009-02-09
19:27:30 UTC (rev 15918)
+++
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/path/impl/SelectClausePathNormalizationStrategy.java 2009-02-09
19:32:49 UTC (rev 15919)
@@ -41,6 +41,6 @@
protected boolean shouldTerminalEntityPropertyForceJoin() {
// here we should *as long as* we are not part of a function processing
- return ! getNormalizationContext().isCurrentlyProcessingFunction();
+ return ! normalizationContext().isCurrentlyProcessingFunction();
}
}
Modified:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/path/impl/WithFragmentPathNormalizationStrategy.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/path/impl/WithFragmentPathNormalizationStrategy.java 2009-02-09
19:27:30 UTC (rev 15918)
+++
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/path/impl/WithFragmentPathNormalizationStrategy.java 2009-02-09
19:32:49 UTC (rev 15919)
@@ -23,9 +23,6 @@
*/
package org.hibernate.sql.ast.phase.hql.normalize.path.impl;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
import org.hibernate.sql.ast.phase.hql.normalize.PersisterReference;
import org.hibernate.sql.ast.phase.hql.normalize.NormalizationContext;
import org.hibernate.sql.ast.phase.hql.normalize.Join;
@@ -33,6 +30,8 @@
import org.hibernate.QueryException;
import antlr.collections.AST;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
* {@link org.hibernate.sql.ast.phase.hql.normalize.path.PathNormalizationStrategy} for
dealing with <tt>WITH</tt>
@@ -41,7 +40,7 @@
* @author Steve Ebersole
*/
public class WithFragmentPathNormalizationStrategy extends
BasicPathNormalizationStrategySupport {
- public static final Log log = LogFactory.getLog(
WithFragmentPathNormalizationStrategy.class );
+ private static final Logger log = LoggerFactory.getLogger(
WithFragmentPathNormalizationStrategy.class );
private final PersisterReference lhs;
@@ -57,7 +56,7 @@
AST nextPossible = lhs.getFirstChild();
while ( nextPossible != null ) {
if ( nextPossible instanceof Join ) {
- if ( ( ( Join ) nextPossible ).getRhs() == rhs ) {
+ if ( ( ( Join ) nextPossible ).locateRhs() == rhs ) {
join = ( Join ) nextPossible;
break;
}
Modified:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/parse/HqlParser.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/parse/HqlParser.java 2009-02-09
19:27:30 UTC (rev 15918)
+++
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/parse/HqlParser.java 2009-02-09
19:32:49 UTC (rev 15919)
@@ -25,8 +25,8 @@
import org.hibernate.sql.ast.util.ASTUtil;
import org.hibernate.sql.ast.util.ASTPrinter;
-import org.hibernate.sql.ast.util.ErrorCounter;
-import org.hibernate.sql.ast.util.ParseErrorHandler;
+import org.hibernate.sql.ast.util.ErrorHandlerDelegateImpl;
+import org.hibernate.sql.ast.util.ErrorHandlerDelegate;
import org.hibernate.QueryException;
import org.hibernate.MappingException;
import org.hibernate.persister.entity.EntityPersister;
@@ -65,7 +65,7 @@
private static final Logger log = LoggerFactory.getLogger( HqlParser.class );
private final Context context;
- private final ParseErrorHandler parseErrorHandler = new ErrorCounter();
+ private final ErrorHandlerDelegate parseErrorHandler = new ErrorHandlerDelegateImpl();
private final ASTPrinter printer = new ASTPrinter( HqlParseTokenTypes.class );
private int traceDepth = 0;
@@ -93,7 +93,7 @@
parseErrorHandler.reportWarning( s );
}
- public ParseErrorHandler getParseErrorHandler() {
+ public ErrorHandlerDelegate getParseErrorHandler() {
return parseErrorHandler;
}
Modified:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/parse/PathCollector.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/parse/PathCollector.java 2009-02-09
19:27:30 UTC (rev 15918)
+++
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/parse/PathCollector.java 2009-02-09
19:32:49 UTC (rev 15919)
@@ -40,22 +40,23 @@
}
public static String getPath(AST dotStructure) {
- if ( dotStructure.getType() == IDENT ) {
+ if ( dotStructure.getType() == DOT ) {
+ return extractText( dotStructure );
+ }
+ else {
return dotStructure.getText();
}
-
- return extractText( dotStructure );
}
private static String extractText(AST node) {
AST lhs = node.getFirstChild();
AST rhs = lhs.getNextSibling();
- if ( lhs.getType() == IDENT ) {
- return lhs.getText() + node.getText() + rhs.getText();
+ if ( lhs.getType() == DOT ) {
+ return extractText( lhs ) + node.getText() + rhs.getText();
}
else {
- return extractText( lhs ) + node.getText() + rhs.getText();
+ return lhs.getText() + node.getText() + rhs.getText();
}
}
}
Modified:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/util/ASTPrinter.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/util/ASTPrinter.java 2009-02-09
19:27:30 UTC (rev 15918)
+++
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/util/ASTPrinter.java 2009-02-09
19:32:49 UTC (rev 15919)
@@ -131,10 +131,15 @@
* or just the integer as a string if none exists.
*/
public String getTokenTypeName(int type) {
- if ( tokenTypeNameCache == null ) {
- return Integer.toString( type );
+ final Integer typeInteger = new Integer( type );
+ String value = null;
+ if ( tokenTypeNameCache != null ) {
+ value = ( String ) tokenTypeNameCache.get( typeInteger );
}
- return ( String ) tokenTypeNameCache.get( new Integer( type ) );
+ if ( value == null ) {
+ value = typeInteger.toString();
+ }
+ return value;
}
private void showAst(ArrayList parents, PrintWriter pw, AST ast) {
Modified:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/util/ASTUtil.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/util/ASTUtil.java 2009-02-09
19:27:30 UTC (rev 15918)
+++
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/util/ASTUtil.java 2009-02-09
19:32:49 UTC (rev 15919)
@@ -383,14 +383,31 @@
* @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) {
- String tokenTypeName = Integer.toString( value );
- if ( owner != null ) {
- Field[] fields = owner.getFields();
+ 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() == value ) {
+ if ( fieldValue != null && fieldValue.intValue() == tokenType ) {
tokenTypeName = fields[i].getName();
break;
}
@@ -419,17 +436,4 @@
}
return rtn;
}
-
- /**
- * Just a friendly renaming of {@link #getConstantName}; in fact this method just simply
delegates to that one.
- *
- * @param tokenTypeInterface The *TokenTypes interface (or one of its implementors).
- * @param tokenType The token type value.
- * @return The corresponding name.
- *
- * @see #getConstantName
- */
- public static String getTokenTypeName(Class tokenTypeInterface, int tokenType) {
- return getConstantName( tokenTypeInterface, tokenType );
- }
}
Deleted:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/util/ErrorCounter.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/util/ErrorCounter.java 2009-02-09
19:27:30 UTC (rev 15918)
+++
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/util/ErrorCounter.java 2009-02-09
19:32:49 UTC (rev 15919)
@@ -1,95 +0,0 @@
-/*
- * Hibernate, Relational Persistence for Idiomatic Java
- *
- * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
- * indicated by the @author tags or express copyright attribution
- * statements applied by the authors. All third-party contributions are
- * distributed under license by Red Hat Middleware LLC.
- *
- * This copyrighted material is made available to anyone wishing to use, modify,
- * copy, or redistribute it subject to the terms and conditions of the GNU
- * Lesser General Public License, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
- * for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this distribution; if not, write to:
- * Free Software Foundation, Inc.
- * 51 Franklin Street, Fifth Floor
- * Boston, MA 02110-1301 USA
- */
-package org.hibernate.sql.ast.util;
-
-import antlr.RecognitionException;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.hibernate.QueryException;
-import org.hibernate.sql.ast.QuerySyntaxException;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-/**
- * An error handler that counts parsing errors and warnings.
- */
-public class ErrorCounter implements ParseErrorHandler {
- private Log log = LogFactory.getLog( ErrorCounter.class );
-
- private List errorList = new ArrayList();
- private List warningList = new ArrayList();
- private List recognitionExceptions = new ArrayList();
-
- public void reportError(RecognitionException e) {
- String msg = e.toString();
- reportError( msg );
- recognitionExceptions.add( e );
- if ( log.isTraceEnabled() ) {
- log.trace( msg, e );
- }
- }
-
- public void reportError(String message) {
- log.error( message );
- errorList.add( message );
- }
-
- public void reportWarning(String message) {
- log.debug( message );
- warningList.add( message );
- }
-
- public int getErrorCount() {
- return errorList.size();
- }
-
- private String getErrorString() {
- StringBuffer buf = new StringBuffer();
- for ( Iterator iterator = errorList.iterator(); iterator.hasNext(); ) {
- buf.append( ( String ) iterator.next() );
- if ( iterator.hasNext() ) buf.append( "\n" );
-
- }
- return buf.toString();
- }
-
- public void throwQueryException() throws QueryException {
- if ( getErrorCount() > 0 ) {
- if ( recognitionExceptions.size() > 0 ) {
- throw QuerySyntaxException.convert( ( RecognitionException )
recognitionExceptions.get( 0 ) );
- }
- else {
- throw new QueryException( getErrorString() );
- }
- }
- else {
- // all clear
- if ( log.isDebugEnabled() ) {
- log.debug( "throwQueryException() : no errors" );
- }
- }
- }
-}
\ No newline at end of file
Modified:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/util/ErrorHandlerDelegateImpl.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/util/ErrorHandlerDelegateImpl.java 2009-02-09
19:27:30 UTC (rev 15918)
+++
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/util/ErrorHandlerDelegateImpl.java 2009-02-09
19:32:49 UTC (rev 15919)
@@ -23,16 +23,17 @@
*/
package org.hibernate.sql.ast.util;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
import antlr.RecognitionException;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
import org.hibernate.QueryException;
import org.hibernate.sql.ast.QuerySyntaxException;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
/**
* An implementation of the {@link ErrorHandlerDelegate} contract.
*
@@ -40,7 +41,7 @@
* @author Steve Ebersole
*/
public class ErrorHandlerDelegateImpl implements ErrorHandlerDelegate {
- private static final Log log = LogFactory.getLog( ErrorHandlerDelegateImpl.class );
+ private static final Logger log = LoggerFactory.getLogger(
ErrorHandlerDelegateImpl.class );
private List errorList = new ArrayList();
private List recognitionExceptions = new ArrayList();
Deleted:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/util/ErrorReporter.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/util/ErrorReporter.java 2009-02-09
19:27:30 UTC (rev 15918)
+++
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/util/ErrorReporter.java 2009-02-09
19:32:49 UTC (rev 15919)
@@ -1,39 +0,0 @@
-/*
- * Hibernate, Relational Persistence for Idiomatic Java
- *
- * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
- * indicated by the @author tags or express copyright attribution
- * statements applied by the authors. All third-party contributions are
- * distributed under license by Red Hat Middleware LLC.
- *
- * This copyrighted material is made available to anyone wishing to use, modify,
- * copy, or redistribute it subject to the terms and conditions of the GNU
- * Lesser General Public License, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
- * for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this distribution; if not, write to:
- * Free Software Foundation, Inc.
- * 51 Franklin Street, Fifth Floor
- * Boston, MA 02110-1301 USA
- */
-package org.hibernate.sql.ast.util;
-
-import antlr.RecognitionException;
-
-/**
- * Implementations will report or handle errors invoked by an ANTLR base parser.
- *
- * @author Joshua Davis
- */
-public interface ErrorReporter {
- void reportError(RecognitionException e);
-
- void reportError(String s);
-
- void reportWarning(String s);
-}
\ No newline at end of file
Deleted:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/util/ParseErrorHandler.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/util/ParseErrorHandler.java 2009-02-09
19:27:30 UTC (rev 15918)
+++
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/util/ParseErrorHandler.java 2009-02-09
19:32:49 UTC (rev 15919)
@@ -1,39 +0,0 @@
-/*
- * Hibernate, Relational Persistence for Idiomatic Java
- *
- * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
- * indicated by the @author tags or express copyright attribution
- * statements applied by the authors. All third-party contributions are
- * distributed under license by Red Hat Middleware LLC.
- *
- * This copyrighted material is made available to anyone wishing to use, modify,
- * copy, or redistribute it subject to the terms and conditions of the GNU
- * Lesser General Public License, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
- * for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this distribution; if not, write to:
- * Free Software Foundation, Inc.
- * 51 Franklin Street, Fifth Floor
- * Boston, MA 02110-1301 USA
- */
-package org.hibernate.sql.ast.util;
-
-import org.hibernate.QueryException;
-
-
-/**
- * Defines the behavior of an error handler for the Hibernate parsers.
- *
- * @author Joshua Davis
- */
-public interface ParseErrorHandler extends ErrorReporter {
-
- int getErrorCount();
-
- void throwQueryException() throws QueryException;
-}
\ No newline at end of file
Modified:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/util/PathHelper.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/util/PathHelper.java 2009-02-09
19:27:30 UTC (rev 15918)
+++
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/util/PathHelper.java 2009-02-09
19:32:49 UTC (rev 15919)
@@ -28,10 +28,9 @@
import antlr.ASTFactory;
import antlr.collections.AST;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
/**
* Provides utility methods for dealing with path expressions.
* <p/>
@@ -41,7 +40,7 @@
* @author Steve Ebersole
*/
public final class PathHelper implements Sql92TokenTypes {
- private static final Log log = LogFactory.getLog( PathHelper.class );
+ private static final Logger log = LoggerFactory.getLogger( PathHelper.class );
/**
* Direct instantiation of PathHelper disallowed.
Modified:
core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/normalize/NormalizerTest.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/normalize/NormalizerTest.java 2009-02-09
19:27:30 UTC (rev 15918)
+++
core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/normalize/NormalizerTest.java 2009-02-09
19:32:49 UTC (rev 15919)
@@ -34,10 +34,6 @@
import org.hibernate.cfg.Environment;
import org.hibernate.dialect.HSQLDialect;
import org.hibernate.sql.ast.util.NodeTraverser;
-import org.hibernate.sql.ast.phase.hql.normalize.HqlNormalizer;
-import org.hibernate.sql.ast.phase.hql.normalize.QuerySpec;
-import org.hibernate.sql.ast.phase.hql.normalize.SelectItem;
-import org.hibernate.sql.ast.phase.hql.normalize.SelectStatement;
import org.hibernate.sql.ast.phase.hql.parse.ParserTest;
import org.hibernate.sql.ast.phase.hql.domain.Animal;
import org.hibernate.sql.ast.common.JoinType;
@@ -72,7 +68,7 @@
}
public void testBasicStructure() throws Throwable {
- AST query = resolve( "select a from Animal a order by a.name" );
+ AST query = normalize( "select a from Animal a order by a.name" );
assertEquals( query.getType(), QUERY );
AST querySpec = query.getFirstChild();
@@ -99,26 +95,26 @@
public void testSimpleHql() throws Exception {
// First, get an AST by parsing some HQL text.
- AST ast = resolve( "from Animal" );
+ AST ast = normalize( "from Animal" );
// Assert:
assertEquals( ast.getType(), QUERY );
}
public void testSimpleExplicitJoins() throws Throwable {
- AST ast = resolve( "from Animal as a inner join a.mother as m" );
+ AST ast = normalize( "from Animal as a inner join a.mother as m" );
JoinCounter.assertJoinCount( 1, ast );
- ast = resolve( "from Animal as a inner join a.offspring as c inner join a.mother
as m" );
+ ast = normalize( "from Animal as a inner join a.offspring as c inner join a.mother
as m" );
JoinCounter.assertJoinCount( 2, ast );
}
public void testPathedExplicitJoins() throws Throwable {
- AST ast = resolve( "from Animal as a inner join a.mother.father.offspring as
auntsanduncles" );
+ AST ast = normalize( "from Animal as a inner join a.mother.father.offspring as
auntsanduncles" );
JoinCounter.assertJoinCount( 3, ast );
}
public void testSelectPersisterReference() throws Throwable {
- AST query = resolve( "select a from Animal a" );
+ AST query = normalize( "select a from Animal a" );
JoinCounter.assertJoinCount( 0, query );
SelectItemCounter.assertSelectItemCount( 1, query );
@@ -135,7 +131,7 @@
public void testSelectAssociationPropertyReference() throws Throwable {
// todo : implicit joins...
- AST query = resolve( "select a.mother as m from Animal as a" );
+ AST query = normalize( "select a.mother as m from Animal as a" );
JoinCounter.assertJoinCount( 1, query );
assertTrue( query instanceof SelectStatement );
@@ -148,7 +144,7 @@
Join join = ( Join ) itr.next();
assertFalse( itr.hasNext() );
assertEquals( JoinType.INNER, join.getEnumeratedJoinType() );
- PersisterReference rhs = join.getRhs();
+ PersisterReference rhs = join.locateRhs();
assertEquals( Animal.class.getName(), rhs.getName() );
// this should work since there is only one non-explicit persister alias...
assertEquals( "<gen:0>", rhs.getAlias() );
@@ -166,7 +162,7 @@
}
public void testSimpleSimplePropertyReference() throws Throwable {
- AST query = resolve( "select a.name as m from Animal as a" );
+ AST query = normalize( "select a.name as m from Animal as a" );
JoinCounter.assertJoinCount( 0, query );
SelectItemCounter.assertSelectItemCount( 1, query );
assertTrue( query instanceof SelectStatement );
@@ -187,7 +183,7 @@
}
public void testSelectPropertyRefCount() throws Throwable {
- AST query = resolve( "select count(a.mother) from Animal as a" );
+ AST query = normalize( "select count(a.mother) from Animal as a" );
JoinCounter.assertJoinCount( 0, query );
SelectItemCounter.assertSelectItemCount( 1, query );
assertTrue( query instanceof SelectStatement );
@@ -206,110 +202,135 @@
}
public void testExplicitImplicitJoin() throws Exception {
- AST ast = resolve( "from Animal a left join fetch a.mother.mother.mother as ggm
where ggm.name like '%weeble%'" );
+ AST ast = normalize( "from Animal a left join fetch a.mother.mother.mother as ggm
where ggm.name like '%weeble%'" );
assertTrue( ast instanceof SelectStatement );
JoinCounter.assertJoinCount( 3, ast );
- ast = resolve( "from Animal as a inner join a.mother.mother as gm" );
+ ast = normalize( "from Animal as a inner join a.mother.mother as gm" );
JoinCounter.assertJoinCount( 2, ast );
- ast = resolve( "from Animal as a inner join a.mother.father as gf" );
+ ast = normalize( "from Animal as a inner join a.mother.father as gf" );
JoinCounter.assertJoinCount( 2, ast );
- ast = resolve( "from Animal as a inner join a.offspring as c inner join
a.mother.father as mgf inner join fetch a.father" );
+ ast = normalize( "from Animal as a inner join a.offspring as c inner join
a.mother.father as mgf inner join fetch a.father" );
JoinCounter.assertJoinCount( 4, ast );
}
public void testExplicitCollectionJoin() throws Throwable {
- AST ast = resolve( "from Animal as a inner join a.offspring as o where o.name like
'%boots%'" );
+ normalize( "from Animal as a inner join a.offspring as o where o.name like
'%boots%'" );
}
public void testSimpleImplicitJoin() throws Exception {
- AST ast = resolve( "from Animal a where a.mother.name like '%mary%'"
);
+ AST ast = normalize( "from Animal a where a.mother.name like
'%mary%'" );
assertTrue( ast instanceof SelectStatement );
JoinCounter.assertJoinCount( 1, ast );
- ast = resolve( "from Animal a where a.mother.father.name like
'%weeble%'" );
+ ast = normalize( "from Animal a where a.mother.father.name like
'%weeble%'" );
assertTrue( ast instanceof SelectStatement );
JoinCounter.assertJoinCount( 2, ast );
- ast = resolve( "from Animal a where a.mother.mother.name like
'%weeble%'" );
+ ast = normalize( "from Animal a where a.mother.mother.name like
'%weeble%'" );
assertTrue( ast instanceof SelectStatement );
JoinCounter.assertJoinCount( 2, ast );
- ast = resolve( "from Animal a where a.mother.mother = ?" );
+ ast = normalize( "from Animal a where a.mother.mother = ?" );
assertTrue( ast instanceof SelectStatement );
JoinCounter.assertJoinCount( 1, ast );
}
public void testWithClause() throws Throwable {
- resolve( "from Zoo z inner join z.mammals as m with m.name = ?" );
+ normalize( "from Zoo z inner join z.mammals as m with m.name = ?" );
}
public void testUnqualifiedPropertyReference() throws Exception {
- AST ast = resolve( "from Animal where name like '%mary%'" );
+ AST ast = normalize( "from Animal where name like '%mary%'" );
assertTrue( ast instanceof SelectStatement );
JoinCounter.assertJoinCount( 0, ast );
- ast = resolve( "from Animal where mother.name like '%mary%'" );
+ ast = normalize( "from Animal where mother.name like '%mary%'" );
assertTrue( ast instanceof SelectStatement );
JoinCounter.assertJoinCount( 1, ast );
}
public void testThetaJoins() throws Exception {
- AST ast = resolve( "from Animal a, Animal b where a.mother.id = b.id and b.name
like '%mary%'" );
+ AST ast = normalize( "from Animal a, Animal b where a.mother.id = b.id and b.name
like '%mary%'" );
assertTrue( ast instanceof SelectStatement );
// JoinCounter.assertJoinCount( 1, ast );
- ast = resolve( "from Animal a, Animal b inner join b.mother as c where a.mother.id
= b.id and b.name like '%mary%'" );
+ ast = normalize( "from Animal a, Animal b inner join b.mother as c where
a.mother.id = b.id and b.name like '%mary%'" );
assertTrue( ast instanceof SelectStatement );
// JoinCounter.assertJoinCount( 2, ast );
}
public void testAdHocJoins() throws Exception {
- resolve( "from Animal a inner join Zoo z on a.id = z.id" );
- resolve( "from Animal a inner join Zoo z on a.id = z.id inner join z.mammals as m
with m.name = ?" );
+ normalize( "from Animal a inner join Zoo z on a.id = z.id" );
+ normalize( "from Animal a inner join Zoo z on a.id = z.id inner join z.mammals as
m with m.name = ?" );
}
public void testReusingImplcitJoins() throws Throwable {
- AST ast = resolve( "from Animal a where a.mother.father.name = 'abc' and
a.mother.father.description = 'xyz'" );
+ AST ast = normalize( "from Animal a where a.mother.father.name = 'abc' and
a.mother.father.description = 'xyz'" );
assertTrue( ast instanceof SelectStatement );
JoinCounter.assertJoinCount( 2, ast );
}
- public void testIndexOperations() throws Throwable {
-// resolve( "select o from IndexedCollectionOwner as o where
o.simpleMap['test'] = 'xyz'" );
- resolve( "select o from IndexedCollectionOwner as o inner join o.simpleMap as s
where o.simpleMap[ index(s) ] = 'xyz'" );
- }
+// these entities were not copied over...
+// public void testIndexOperations() throws Throwable {
+// normalize( "select o from IndexedCollectionOwner as o where
o.simpleMap['test'] = 'xyz'" );
+// normalize( "select o from IndexedCollectionOwner as o inner join o.simpleMap as
s where o.simpleMap[ index(s) ] = 'xyz'" );
+// }
public void testIndexOperations2() throws Throwable {
- resolve( "from Zoo zoo join zoo.animals an where zoo.mammals[ index(an) ] =
an" );
- resolve( "from Zoo where mammals['dog'] = ?" );
- resolve( "from Zoo zoo where zoo.mammals['dog'].father.description like
'%black%'" );
+ normalize( "select zoo from Zoo as zoo where zoo.mammals['dog'] =
maxelement(zoo.mammals)" );
+ normalize( "select zoo from Zoo as zoo where
zoo.mammals['dog'].description = 'abc'" );
+ normalize( "from Zoo zoo join zoo.animals an where zoo.mammals[ index(an) ] =
an" );
+ normalize( "from Zoo where mammals['dog'] = ?" );
+ normalize( "from Zoo zoo where zoo.mammals['dog'].father.description like
'%black%'" );
}
+ public void testFilters() throws Exception {
+ String role = Animal.class.getName() + ".offspring";
+ normalizeFilter( "", role );
+ normalizeFilter( "order by this.id", role );
+ normalizeFilter( "where this.name = ?", role );
+ }
+
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- private AST resolve(String hql) throws RecognitionException, TokenStreamException {
- // to be completely accurate, the incoming hql string should be run through
- // QuerySplitter as that is what happens prior to translation and results in
- // a different string to actually translate...
- String[] queries = QuerySplitter.concreteQueries( hql, getSessionFactoryImplementor()
);
- assertEquals( "polymorhpic queries not allowed here", 1, queries.length );
- hql = queries[0];
+ private AST normalize(String hql) throws RecognitionException, TokenStreamException {
+ return normalize( hql, getSessionFactoryImplementor() );
+ }
- AST hqlAst = ParserTest.doParse( hql, false );
+ private AST normalizeFilter(String hql, String role) throws RecognitionException,
TokenStreamException {
+ return normalizeFilter( hql, role, getSessionFactoryImplementor() );
+ }
- // Now, pass it though the resolver phase, which yeilds
- // a processed HQL AST.
- HqlNormalizer resolver = new HqlNormalizer( sessionFactory );
- resolver.statement( hqlAst );
- AST resolvedHql = resolver.getAST();
- System.out.println( resolver.getPrinter().showAsString( resolvedHql, "Resolved AST
: " + resolvedHql.toStringTree() + "" ) );
- return resolvedHql;
+ public static AST normalize(String hql, SessionFactoryImplementor sessionFactory) throws
TokenStreamException, RecognitionException {
+ AST hqlAst = ParserTest.parse( splitQuery( hql, sessionFactory ) );
+
+ HqlNormalizer normalizer = new HqlNormalizer( sessionFactory );
+ normalizer.statement( hqlAst );
+ AST normalizedAST = normalizer.getAST();
+ System.out.println( normalizer.getPrinter().showAsString( normalizedAST,
"Normalized query AST" ) );
+ return normalizedAST;
}
+ public static AST normalizeFilter(String hql, String role, SessionFactoryImplementor
sessionFactory) throws TokenStreamException, RecognitionException {
+ AST hqlAst = ParserTest.parseFilter( splitQuery( hql, sessionFactory ), role );
+
+ HqlNormalizer normalizer = new HqlNormalizer( sessionFactory );
+ normalizer.statement( hqlAst );
+ AST normalizedAST = normalizer.getAST();
+ System.out.println( normalizer.getPrinter().showAsString( normalizedAST,
"Normalized filter AST" ) );
+ return normalizedAST;
+ }
+
+ private static String splitQuery(String hql, SessionFactoryImplementor sessionFactory)
{
+ String[] queries = QuerySplitter.concreteQueries( hql, sessionFactory );
+ assertEquals( "polymorhpic queries not allowed here", 1, queries.length );
+ return queries[0];
+ }
+
protected SessionFactoryImplementor getSessionFactoryImplementor() {
return sessionFactory;
}
Modified:
core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/parse/ParserTest.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/parse/ParserTest.java 2009-02-09
19:27:30 UTC (rev 15918)
+++
core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/parse/ParserTest.java 2009-02-09
19:32:49 UTC (rev 15919)
@@ -4,7 +4,6 @@
import org.hibernate.sql.ast.util.ASTIterator;
import org.hibernate.sql.ast.common.Node;
import org.hibernate.sql.ast.util.ASTPrinter;
-import org.hibernate.sql.ast.phase.hql.parse.HqlParser;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -1013,15 +1012,15 @@
}
public void testEmptyFilter() throws Exception {
- parseFilter( "" ); // Blank is a legitimate filter.
+ parseFilter( "", "Owner.collection" ); // Blank is a legitimate
filter.
}
public void testOrderByFilter() throws Exception {
- parseFilter( "order by this.id" );
+ parseFilter( "order by this.id", "Owner.collection" );
}
public void testRestrictionFilter() throws Exception {
- parseFilter( "where this.name = ?" );
+ parseFilter( "where this.name = ?", "Owner.collection" );
}
public void testNoFrom() throws Exception {
@@ -1099,7 +1098,7 @@
parse("select distinct user.party from
com.itf.iceclaims.domain.party.user.UserImpl user inner join user.party.$RelatedWorkgroups
relatedWorkgroups where relatedWorkgroups.workgroup.id = :workgroup and
relatedWorkgroups.effectiveTime.start <= :datesnow and
relatedWorkgroups.effectiveTime.end > :dateenow ");
}
public void testLineAndColumnNumber() throws Exception {
- AST ast = doParse("from Foo f\nwhere f.name = 'fred'",false);
+ AST ast = parse("from Foo f\nwhere f.name = 'fred'" );
// Find some of the nodes and check line and column values.
ASTIterator iter = new ASTIterator(ast);
boolean foundFoo = false;
@@ -1131,30 +1130,27 @@
}
- private void parse(String input) throws RecognitionException, TokenStreamException {
- doParse( input, false );
+ public static AST parse(String input) throws RecognitionException, TokenStreamException
{
+ HqlParser parser = buildHqlParser( input );
+ parser.statement();
+ return extractAST( parser );
}
- private void parseFilter(String input) throws TokenStreamException, RecognitionException
{
- doParse( input, true );
+ public static AST parseFilter(String input, String collectionRole) throws
TokenStreamException, RecognitionException {
+ HqlParser parser = buildHqlParser( input );
+ parser.filterStatement( collectionRole );
+ return extractAST( parser );
}
- public static AST doParse(String input, boolean isFilter) throws RecognitionException,
TokenStreamException {
- System.out.println( "input: ->" + ASTPrinter.escapeMultibyteChars(input) +
"<-" );
- HqlParser parser = buildHqlParser( input );
- if ( isFilter ) {
- parser.filterStatement();
- }
- else {
- parser.statement();
- }
+ private static AST extractAST(HqlParser parser) {
AST ast = parser.getAST();
- show( ast, "AST [" + ast.toStringTree() + "]" );
+ show( ast, "Parsed AST" );
assertEquals( "At least one error occurred during parsing!", 0,
parser.getParseErrorHandler().getErrorCount() );
return ast;
}
private static HqlParser buildHqlParser(String hql) {
+ System.out.println( "input: ->" + ASTPrinter.escapeMultibyteChars( hql ) +
"<-" );
return new HqlParser(
hql,
new HqlParser.Context() {
Added:
core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/resolve/ResolverTest.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/resolve/ResolverTest.java
(rev 0)
+++
core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/resolve/ResolverTest.java 2009-02-09
19:32:49 UTC (rev 15919)
@@ -0,0 +1,117 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.sql.ast.phase.hql.resolve;
+
+import junit.framework.TestCase;
+
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.cfg.Configuration;
+import org.hibernate.cfg.Environment;
+import org.hibernate.dialect.HSQLDialect;
+import org.hibernate.sql.ast.util.ASTPrinter;
+import org.hibernate.sql.ast.util.NodeDeepCopier;
+import org.hibernate.sql.ast.phase.hql.domain.Animal;
+import org.hibernate.sql.ast.phase.hql.domain.Human;
+import org.hibernate.sql.ast.phase.hql.normalize.NormalizerTest;
+import org.hibernate.persister.entity.AbstractEntityPersister;
+
+import antlr.ASTFactory;
+import antlr.TokenStreamException;
+import antlr.RecognitionException;
+import antlr.collections.AST;
+
+/**
+ * TODO : javadoc
+ *
+ * @author Steve Ebersole
+ */
+public class ResolverTest extends TestCase {
+ private static ASTPrinter printer = new ASTPrinter( HqlResolveTokenTypes.class );
+ private SessionFactoryImplementor sessionFactory;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ sessionFactory = ( SessionFactoryImplementor ) new Configuration()
+ .setProperty( Environment.HBM2DDL_AUTO, "none" )
+ .setProperty( Environment.DIALECT, HSQLDialect.class.getName() )
+ .addResource( "org/hibernate/sql/ast/phase/hql/domain/Mappings.hbm.xml" )
+ .buildSessionFactory();
+ }
+
+ protected void tearDown() throws Exception {
+ if ( sessionFactory != null ) {
+ sessionFactory.close();
+ }
+ super.tearDown();
+ }
+
+ public void testResolve() throws Throwable {
+// resolve( "from Animal a" );
+// resolve( "select a.description from Animal a" );
+ resolve( "select a from Animal a" );
+ }
+
+ public void testFilters() throws Exception {
+ String role = Animal.class.getName() + ".offspring";
+ AST ast = resolveFilter( "", role );
+ resolveFilter( "order by this.id", role );
+ resolveFilter( "where this.name = ?", role );
+ }
+
+ public void testPropertyJoins() throws Throwable {
+ resolve( "from Animal a inner join a.father as f" );
+ }
+
+ public void testPersisterJoins() throws Throwable {
+// resolve( "from Animal a, Animal b" );
+ resolve( "from Animal a cross join Animal b" );
+// resolve( "from Animal a inner join Animal b on a.mother = b.father" );
+ }
+
+ private AST resolve(String hql) throws TokenStreamException, RecognitionException {
+ return resolve( hql, sessionFactory );
+ }
+
+ private AST resolveFilter(String hql, String role) throws TokenStreamException,
RecognitionException {
+ return resolveFilter( hql, role, sessionFactory );
+ }
+
+ public static AST resolve(String hql, SessionFactoryImplementor sessionFactory) throws
TokenStreamException, RecognitionException {
+ AST normalizedAST = NormalizerTest.normalize( hql, sessionFactory );
+ return resolve( normalizedAST, sessionFactory );
+ }
+
+ public static AST resolveFilter(String hql, String role, SessionFactoryImplementor
sessionFactory) throws TokenStreamException, RecognitionException {
+ AST normalizedAST = NormalizerTest.normalizeFilter( hql, role, sessionFactory );
+ return resolve( normalizedAST, sessionFactory );
+ }
+
+ private static AST resolve(AST normalizedAST, SessionFactoryImplementor sessionFactory)
throws RecognitionException {
+ HqlResolver resolver = new HqlResolver( sessionFactory );
+ resolver.statement( normalizedAST );
+ AST resolvedAST = resolver.getAST();
+ System.out.println( printer.showAsString( resolvedAST, "Resolved AST" ) );
+ return resolvedAST;
+ }
+}