KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > hibernate > hql > ast > tree > IndexNode


1 // $Id: IndexNode.java,v 1.1 2005/07/12 20:27:16 steveebersole Exp $
2
package org.hibernate.hql.ast.tree;
3
4 import org.hibernate.QueryException;
5 import org.hibernate.engine.JoinSequence;
6 import org.hibernate.hql.ast.SqlGenerator;
7 import org.hibernate.hql.ast.util.SessionFactoryHelper;
8 import org.hibernate.persister.collection.QueryableCollection;
9 import org.hibernate.type.CollectionType;
10 import org.hibernate.type.Type;
11
12 import antlr.RecognitionException;
13 import antlr.SemanticException;
14 import antlr.collections.AST;
15
16 import org.apache.commons.logging.Log;
17 import org.apache.commons.logging.LogFactory;
18
19 /**
20  * Represents the [] operator and provides it's semantics.
21  *
22  * @author josh Aug 14, 2004 7:07:10 AM
23  */

24 public class IndexNode extends FromReferenceNode {
25
26     private static final Log log = LogFactory.getLog( IndexNode.class );
27
28     public void setScalarColumnText(int i) throws SemanticException {
29         throw new UnsupportedOperationException JavaDoc( "An IndexNode cannot generate column text!" );
30     }
31
32     public void prepareForDot(String JavaDoc propertyName) throws SemanticException {
33         FromElement fromElement = getFromElement();
34         if ( fromElement == null ) {
35             throw new IllegalStateException JavaDoc( "No FROM element for index operator!" );
36         }
37         QueryableCollection queryableCollection = fromElement.getQueryableCollection();
38         if ( queryableCollection != null && !queryableCollection.isOneToMany() ) {
39
40             FromReferenceNode collectionNode = ( FromReferenceNode ) getFirstChild();
41             String JavaDoc path = collectionNode.getPath() + "[]." + propertyName;
42             if ( log.isDebugEnabled() ) {
43                 log.debug( "Creating join for many-to-many elements for " + path );
44             }
45             FromElementFactory factory = new FromElementFactory( fromElement.getFromClause(), fromElement, path );
46             // This will add the new from element to the origin.
47
FromElement elementJoin = factory.createElementJoin( queryableCollection );
48             setFromElement( elementJoin );
49         }
50     }
51
52     public void resolveIndex(AST parent) throws SemanticException {
53         throw new UnsupportedOperationException JavaDoc();
54     }
55
56     public void resolve(boolean generateJoin, boolean implicitJoin, String JavaDoc classAlias, AST parent)
57     throws SemanticException {
58         if ( isResolved() ) {
59             return;
60         }
61         FromReferenceNode collectionNode = ( FromReferenceNode ) getFirstChild();
62         SessionFactoryHelper sessionFactoryHelper = getSessionFactoryHelper();
63         collectionNode.resolveIndex( this ); // Fully resolve the map reference, create implicit joins.
64

65         Type type = collectionNode.getDataType();
66         if ( !type.isCollectionType() ) {
67             throw new SemanticException( "The [] operator cannot be applied to type " + type.toString() );
68         }
69         String JavaDoc collectionRole = ( ( CollectionType ) type ).getRole();
70         QueryableCollection queryableCollection = sessionFactoryHelper.requireQueryableCollection( collectionRole );
71         if ( !queryableCollection.hasIndex() ) {
72             throw new QueryException( "unindexed fromElement before []: " + collectionNode.getPath() );
73         }
74
75         // Generate the inner join -- The elements need to be joined to the collection they are in.
76
FromElement fromElement = collectionNode.getFromElement();
77         String JavaDoc elementTable = fromElement.getTableAlias();
78         FromClause fromClause = fromElement.getFromClause();
79         String JavaDoc path = collectionNode.getPath();
80
81         FromElement elem = fromClause.findCollectionJoin( path );
82         if ( elem == null ) {
83             FromElementFactory factory = new FromElementFactory( fromClause, fromElement, path );
84             elem = factory.createCollectionElementsJoin( queryableCollection, elementTable );
85             if ( log.isDebugEnabled() ) {
86                 log.debug( "No FROM element found for the elements of collection join path " + path
87                         + ", created " + elem );
88             }
89         }
90         else {
91             if ( log.isDebugEnabled() ) {
92                 log.debug( "FROM element found for collection join path " + path );
93             }
94         }
95
96         // Add the condition to the join sequence that qualifies the indexed element.
97
AST index = collectionNode.getNextSibling(); // The index should be a constant, which will have been processed already.
98
if ( index == null ) {
99             throw new QueryException( "No index value!" );
100         }
101
102         setFromElement( fromElement ); // The 'from element' that represents the elements of the collection.
103

104         // Sometimes use the element table alias, sometimes use the... umm... collection table alias (many to many)
105
String JavaDoc collectionTableAlias = elementTable;
106         if ( elem.getCollectionTableAlias() != null ) {
107             collectionTableAlias = elem.getCollectionTableAlias();
108         }
109
110         // TODO: get SQL rendering out of here, create an AST for the join expressions.
111
// Use the SQL generator grammar to generate the SQL text for the index expression.
112
JoinSequence joinSequence = fromElement.getJoinSequence();
113         String JavaDoc[] indexCols = queryableCollection.getIndexColumnNames();
114         if ( indexCols.length != 1 ) {
115             throw new QueryException( "composite-index appears in []: " + collectionNode.getPath() );
116         }
117         SqlGenerator gen = new SqlGenerator( getSessionFactoryHelper().getFactory() );
118         try {
119             gen.simpleExpr( index ); //TODO: used to be exprNoParens! was this needed?
120
}
121         catch ( RecognitionException e ) {
122             throw new QueryException( e.getMessage(), e );
123         }
124         String JavaDoc expression = gen.getSQL();
125         joinSequence.addCondition( collectionTableAlias + '.' + indexCols[0] + " = " + expression );
126
127         // Now, set the text for this node. It should be the element columns.
128
String JavaDoc[] elementColumns = queryableCollection.getElementColumnNames( elementTable );
129         setText( elementColumns[0] );
130         setResolved();
131     }
132
133
134 }
135
Popular Tags