KickJava   Java API By Example, From Geeks To Geeks.

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


1 // $Id: FromElement.java,v 1.1 2005/07/12 20:27:16 steveebersole Exp $
2
package org.hibernate.hql.ast.tree;
3
4 import java.util.LinkedList JavaDoc;
5 import java.util.List JavaDoc;
6
7 import org.hibernate.QueryException;
8 import org.hibernate.engine.JoinSequence;
9 import org.hibernate.hql.QueryTranslator;
10 import org.hibernate.hql.antlr.SqlTokenTypes;
11 import org.hibernate.hql.ast.util.ASTUtil;
12 import org.hibernate.persister.collection.QueryableCollection;
13 import org.hibernate.persister.entity.EntityPersister;
14 import org.hibernate.persister.entity.PropertyMapping;
15 import org.hibernate.persister.entity.Queryable;
16 import org.hibernate.type.EntityType;
17 import org.hibernate.type.Type;
18 import org.hibernate.util.StringHelper;
19
20 import org.apache.commons.logging.Log;
21 import org.apache.commons.logging.LogFactory;
22
23 /**
24  * Represents a single mapped class mentioned in an HQL FROM clause. Each
25  * class reference will have the following symbols:
26  * <ul>
27  * <li>A class name - This is the name of the Java class that is mapped by Hibernate.</li>
28  * <li>[optional] an HQL alias for the mapped class.</li>
29  * <li>A table name - The name of the table that is mapped to the Java class.</li>
30  * <li>A table alias - The alias for the table that will be used in the resulting SQL.</li>
31  * </ul>
32  * <br>
33  * User: josh<br>
34  * Date: Dec 6, 2003<br>
35  * Time: 10:28:17 AM<br>
36  */

37 public class FromElement extends HqlSqlWalkerNode implements DisplayableNode {
38     private static final Log log = LogFactory.getLog( FromElement.class );
39
40     private String JavaDoc className;
41     private String JavaDoc classAlias;
42     private String JavaDoc tableAlias;
43     private String JavaDoc collectionTableAlias;
44     private FromClause fromClause;
45     private boolean includeSubclasses = true;
46     private boolean collectionJoin = false;
47     private FromElement origin;
48     private String JavaDoc[] columns;
49     private String JavaDoc role;
50     private boolean fetch;
51     private boolean isAllPropertyFetch;
52     private boolean filter = false;
53     private int sequence = -1;
54     private boolean useFromFragment = false;
55     private boolean initialized = false;
56     private FromElementType elementType;
57     private boolean useWhereFragment = true;
58     private List JavaDoc destinations = new LinkedList JavaDoc();
59     private boolean manyToMany = false;
60     private String JavaDoc adHocOnClauseFragment = null;
61
62     public FromElement() {
63     }
64
65     public String JavaDoc getCollectionSuffix() {
66         return elementType.getCollectionSuffix();
67     }
68
69     public void setCollectionSuffix(String JavaDoc suffix) {
70         elementType.setCollectionSuffix(suffix);
71     }
72
73     public void initializeCollection(FromClause fromClause, String JavaDoc classAlias, String JavaDoc tableAlias) {
74         doInitialize( fromClause, tableAlias, null, classAlias, null, null );
75         initialized = true;
76     }
77
78     public void initializeEntity(
79             FromClause fromClause,
80             String JavaDoc className,
81             EntityPersister persister,
82             EntityType type,
83             String JavaDoc classAlias,
84             String JavaDoc tableAlias) {
85         doInitialize( fromClause, tableAlias, className, classAlias, persister, type );
86         this.sequence = fromClause.nextFromElementCounter();
87         initialized = true;
88     }
89
90     private void doInitialize(FromClause fromClause, String JavaDoc tableAlias, String JavaDoc className, String JavaDoc classAlias,
91                               EntityPersister persister, EntityType type) {
92         if ( initialized ) {
93             throw new IllegalStateException JavaDoc( "Already initialized!!" );
94         }
95         this.fromClause = fromClause;
96         this.tableAlias = tableAlias;
97         this.className = className;
98         this.classAlias = classAlias;
99         this.elementType = new FromElementType( this, persister, type );
100         // Register the FromElement with the FROM clause, now that we have the names and aliases.
101
fromClause.registerFromElement( this );
102         if ( log.isDebugEnabled() ) {
103             log.debug( fromClause + " : " + className + " ("
104                     + ( classAlias == null ? "no alias" : classAlias ) + ") -> " + tableAlias );
105         }
106     }
107
108     public EntityPersister getEntityPersister() {
109         return elementType.getEntityPersister();
110     }
111
112     public Type getDataType() {
113         return elementType.getDataType();
114     }
115
116     public Type getSelectType() {
117         return elementType.getSelectType();
118     }
119
120     public Queryable getQueryable() {
121         return elementType.getQueryable();
122     }
123
124     public String JavaDoc getClassName() {
125         return className;
126     }
127
128     public String JavaDoc getClassAlias() {
129         return classAlias;
130         //return classAlias == null ? className : classAlias;
131
}
132
133     private String JavaDoc getTableName() {
134         Queryable queryable = getQueryable();
135         return ( queryable != null ) ? queryable.getTableName() : "{none}";
136     }
137
138     public String JavaDoc getTableAlias() {
139         return tableAlias;
140     }
141
142     /**
143      * Render the identifier select, but in a 'scalar' context (i.e. generate the column alias).
144      *
145      * @param i the sequence of the returned type
146      * @return the identifier select with the column alias.
147      */

148     String JavaDoc renderScalarIdentifierSelect(int i) {
149         return elementType.renderScalarIdentifierSelect( i );
150     }
151
152     void checkInitialized() {
153         if ( !initialized ) {
154             throw new IllegalStateException JavaDoc( "FromElement has not been initialized!" );
155         }
156     }
157
158     /**
159      * Returns the identifier select SQL fragment.
160      *
161      * @param size The total number of returned types.
162      * @param k The sequence of the current returned type.
163      * @return the identifier select SQL fragment.
164      */

165     String JavaDoc renderIdentifierSelect(int size, int k) {
166         return elementType.renderIdentifierSelect( size, k );
167     }
168
169     /**
170      * Returns the property select SQL fragment.
171      *
172      * @param size The total number of returned types.
173      * @param k The sequence of the current returned type.
174      * @return the property select SQL fragment.
175      */

176     String JavaDoc renderPropertySelect(int size, int k) {
177         return elementType.renderPropertySelect( size, k, isAllPropertyFetch );
178     }
179
180     String JavaDoc renderCollectionSelectFragment(int size, int k) {
181         return elementType.renderCollectionSelectFragment( size, k );
182     }
183
184     String JavaDoc renderValueCollectionSelectFragment(int size, int k) {
185         return elementType.renderValueCollectionSelectFragment( size, k );
186     }
187
188     public FromClause getFromClause() {
189         return fromClause;
190     }
191
192     /**
193      * Returns true if this FromElement was implied by a path, or false if this FROM element is explicitly declared in
194      * the FROM clause.
195      *
196      * @return true if this FromElement was implied by a path, or false if this FROM element is explicitly declared
197      */

198     public boolean isImplied() {
199         return false; // This is an explicit FROM element.
200
}
201
202     /**
203      * Returns additional display text for the AST node.
204      *
205      * @return String - The additional display text.
206      */

207     public String JavaDoc getDisplayText() {
208         StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
209         buf.append( "FromElement{" );
210         appendDisplayText( buf );
211         buf.append( "}" );
212         return buf.toString();
213     }
214
215     protected void appendDisplayText(StringBuffer JavaDoc buf) {
216         buf.append( isImplied() ? (
217                 isImpliedInFromClause() ? "implied in FROM clause" : "implied" )
218                 : "explicit" );
219         buf.append( "," ).append( isCollectionJoin() ? "collection join" : "not a collection join" );
220         buf.append( "," ).append( fetch ? "fetch join" : "not a fetch join" );
221         buf.append( "," ).append( isAllPropertyFetch ? "fetch all properties" : "fetch non-lazy properties" );
222         buf.append( ",classAlias=" ).append( getClassAlias() );
223         buf.append( ",role=" ).append( role );
224         buf.append( ",tableName=" ).append( getTableName() );
225         buf.append( ",tableAlias=" ).append( getTableAlias() );
226         buf.append( ",colums={" );
227         if ( columns != null ) {
228             for ( int i = 0; i < columns.length; i++ ) {
229                 buf.append( columns[i] );
230                 if ( i < columns.length ) {
231                     buf.append( " " );
232                 }
233             }
234         }
235         buf.append( ",className=" ).append( className );
236         buf.append( "}" );
237     }
238
239     public int hashCode() {
240         return super.hashCode();
241     }
242
243     public boolean equals(Object JavaDoc obj) {
244         return super.equals( obj );
245     }
246
247
248     public void setJoinSequence(JoinSequence joinSequence) {
249         elementType.setJoinSequence( joinSequence );
250     }
251
252     public JoinSequence getJoinSequence() {
253         return elementType.getJoinSequence();
254     }
255
256     public void setIncludeSubclasses(boolean includeSubclasses) {
257         this.includeSubclasses = includeSubclasses;
258     }
259
260     public boolean isIncludeSubclasses() {
261         return includeSubclasses;
262     }
263
264     public String JavaDoc getIdentityColumn() {
265         checkInitialized();
266         String JavaDoc table = getTableAlias();
267         if ( table == null ) {
268             throw new IllegalStateException JavaDoc( "No table alias for node " + this );
269         }
270         String JavaDoc[] cols = getPropertyMapping( EntityPersister.ENTITY_ID ).toColumns( table, EntityPersister.ENTITY_ID );
271         String JavaDoc result = StringHelper.join( ", ", cols );
272         return cols.length == 1 ? result : "(" + result + ")";
273     }
274
275     public void setCollectionJoin(boolean collectionJoin) {
276         this.collectionJoin = collectionJoin;
277     }
278
279     public boolean isCollectionJoin() {
280         return collectionJoin;
281     }
282
283     public void setRole(String JavaDoc role) {
284         this.role = role;
285     }
286
287     public void setQueryableCollection(QueryableCollection queryableCollection) {
288         elementType.setQueryableCollection( queryableCollection );
289     }
290
291     public QueryableCollection getQueryableCollection() {
292         return elementType.getQueryableCollection();
293     }
294
295     public void setColumns(String JavaDoc[] columns) {
296         this.columns = columns;
297     }
298
299     public void setOrigin(FromElement origin, boolean manyToMany) {
300         this.origin = origin;
301         this.manyToMany = manyToMany;
302         origin.addDestination( this );
303         if ( origin.getFromClause() == this.getFromClause() ) {
304             // TODO: Figure out a better way to get the FROM elements in a proper tree structure.
305
// If this is not the destination of a many-to-many, add it as a child of the origin.
306
if ( manyToMany ) {
307                 ASTUtil.appendSibling( origin, this );
308             }
309             else {
310                 if ( !getWalker().isInFrom() && !getWalker().isInSelect() ) {
311                     getFromClause().addChild( this );
312                 }
313                 else {
314                     origin.addChild( this );
315                 }
316             }
317         }
318         else if ( !getWalker().isInFrom() ) {
319             // HHH-276 : implied joins in a subselect where clause - The destination needs to be added
320
// to the destination's from clause.
321
getFromClause().addChild( this ); // Not sure if this is will fix everything, but it works.
322
}
323         else {
324             // Otherwise, the destination node was implied by the FROM clause and the FROM clause processor
325
// will automatically add it in the right place.
326
}
327     }
328
329     public boolean isManyToMany() {
330         return manyToMany;
331     }
332
333     private void addDestination(FromElement fromElement) {
334         destinations.add( fromElement );
335     }
336
337     public List JavaDoc getDestinations() {
338         return destinations;
339     }
340
341     public FromElement getOrigin() {
342         return origin;
343     }
344
345     /**
346      * Returns the type of a property, given it's name (the last part) and the full path.
347      *
348      * @param propertyName The last part of the full path to the property.
349      * @return The type.
350      * @0param propertyPath The full property path.
351      */

352     public Type getPropertyType(String JavaDoc propertyName, String JavaDoc propertyPath) {
353         return elementType.getPropertyType( propertyName, propertyPath );
354     }
355
356     public String JavaDoc[] toColumns(String JavaDoc tableAlias, String JavaDoc path, boolean inSelect) {
357         return elementType.toColumns( tableAlias, path, inSelect );
358     }
359
360     public PropertyMapping getPropertyMapping(String JavaDoc propertyName) {
361         return elementType.getPropertyMapping( propertyName );
362     }
363
364     public void setFetch(boolean fetch) {
365         this.fetch = fetch;
366         // Fetch can't be used with scroll() or iterate().
367
if ( fetch && getWalker().isShallowQuery() ) {
368             throw new QueryException( QueryTranslator.ERROR_CANNOT_FETCH_WITH_ITERATE );
369         }
370     }
371
372     public boolean isFetch() {
373         return fetch;
374     }
375
376     public int getSequence() {
377         return sequence;
378     }
379
380     public void setFilter(boolean b) {
381         filter = b;
382     }
383
384     public boolean isFilter() {
385         return filter;
386     }
387
388     /**
389      * Returns true if the from fragment should be included in the from clause.
390      */

391     public boolean useFromFragment() {
392         checkInitialized();
393         // If it's not implied or it is implied and it's a many to many join where the target wasn't found.
394
return !isImplied() || this.useFromFragment;
395     }
396
397     public void setUseFromFragment(boolean useFromFragment) {
398         this.useFromFragment = useFromFragment;
399     }
400
401     public boolean useWhereFragment() {
402         return useWhereFragment;
403     }
404
405     public void setUseWhereFragment(boolean b) {
406         useWhereFragment = b;
407     }
408
409
410     public void setCollectionTableAlias(String JavaDoc collectionTableAlias) {
411         this.collectionTableAlias = collectionTableAlias;
412     }
413
414     public String JavaDoc getCollectionTableAlias() {
415         return collectionTableAlias;
416     }
417
418     public boolean isCollectionOfValuesOrComponents() {
419         return elementType.isCollectionOfValuesOrComponents();
420     }
421
422     public boolean isEntity() {
423         return elementType.isEntity();
424     }
425
426     public void setImpliedInFromClause(boolean flag) {
427         throw new UnsupportedOperationException JavaDoc( "Explicit FROM elements can't be implied in the FROM clause!" );
428     }
429
430     public boolean isImpliedInFromClause() {
431         return false; // Since this is an explicit FROM element, it can't be implied in the FROM clause.
432
}
433
434     public void setInProjectionList(boolean inProjectionList) {
435         // Do nothing, eplicit from elements are *always* in the projection list.
436
}
437
438     /**
439      * Returns true if this element should be in the projection list.
440      *
441      * @return
442      */

443     public boolean inProjectionList() {
444         return !isImplied() && isFromOrJoinFragment();
445     }
446
447     public boolean isFromOrJoinFragment() {
448         return getType() == SqlTokenTypes.FROM_FRAGMENT || getType() == SqlTokenTypes.JOIN_FRAGMENT;
449     }
450     
451     public boolean isAllPropertyFetch() {
452         return isAllPropertyFetch;
453     }
454     
455     public void setAllPropertyFetch(boolean fetch) {
456         isAllPropertyFetch = fetch;
457     }
458
459     public String JavaDoc getAdHocOnClauseFragment() {
460         return adHocOnClauseFragment;
461     }
462
463     public void setAdHocOnClauseFragment(String JavaDoc adHocOnClauseFragment) {
464         this.adHocOnClauseFragment = adHocOnClauseFragment;
465     }
466
467     public boolean hasCacheablePersister() {
468         if ( getQueryableCollection() != null ) {
469             return getQueryableCollection().hasCache();
470         }
471         else {
472             return getQueryable().hasCache();
473         }
474     }
475 }
476
Popular Tags