KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > hibernate > hql > ast > util > SyntheticAndFactory


1 // $Id: SyntheticAndFactory.java,v 1.1 2005/07/12 20:27:22 steveebersole Exp $
2
package org.hibernate.hql.ast.util;
3
4 import java.util.Map JavaDoc;
5
6 import org.hibernate.hql.antlr.HqlSqlTokenTypes;
7 import org.hibernate.hql.ast.tree.FromElement;
8 import org.hibernate.hql.ast.tree.QueryNode;
9 import org.hibernate.hql.ast.tree.RestrictableStatement;
10 import org.hibernate.hql.ast.tree.SqlFragment;
11 import org.hibernate.persister.entity.Queryable;
12 import org.hibernate.sql.JoinFragment;
13 import org.hibernate.util.StringHelper;
14
15 import antlr.ASTFactory;
16 import antlr.collections.AST;
17
18 import org.apache.commons.logging.Log;
19 import org.apache.commons.logging.LogFactory;
20
21 /**
22  * Creates synthetic and nodes based on the where fragment part of a JoinSequence.
23  *
24  * @author josh Dec 5, 2004 12:25:20 PM
25  */

26 public class SyntheticAndFactory implements HqlSqlTokenTypes {
27     private static final Log log = LogFactory.getLog( SyntheticAndFactory.class );
28
29     private ASTFactory astFactory;
30     private AST thetaJoins;
31     private AST filters;
32
33     public SyntheticAndFactory(ASTFactory astFactory) {
34         this.astFactory = astFactory;
35     }
36
37     public void addWhereFragment(JoinFragment joinFragment, String JavaDoc whereFragment, QueryNode query, FromElement fromElement) {
38
39         if ( whereFragment != null ) {
40             whereFragment = whereFragment.trim();
41         }
42         if ( StringHelper.isEmpty( whereFragment ) ) {
43             return;
44         }
45         else if ( !fromElement.useWhereFragment() && !joinFragment.hasThetaJoins() ) {
46             return;
47         }
48
49         // Forcefully remove leading ands from where fragments; the grammar will
50
// handle adding them
51
if ( whereFragment.startsWith( "and" ) ) {
52             whereFragment = whereFragment.substring( 4 );
53         }
54
55         if ( log.isDebugEnabled() ) log.debug( "Using WHERE fragment [" + whereFragment + "]" );
56
57         SqlFragment fragment = ( SqlFragment ) ASTUtil.create( astFactory, SQL_TOKEN, whereFragment );
58         fragment.setJoinFragment( joinFragment );
59         fragment.setFromElement( fromElement );
60
61         // Filter conditions need to be inserted before the HQL where condition and the
62
// theta join node. This is because org.hibernate.loader.Loader binds the filter parameters first,
63
// then it binds all the HQL query parameters, see org.hibernate.loader.Loader.processFilterParameters().
64
if ( fragment.getFromElement().isFilter() || fragment.hasFilterCondition() ) {
65             if ( filters == null ) {
66                 // Find or create the WHERE clause
67
AST where = query.getWhereClause();
68                 // Create a new FILTERS node as a parent of all filters
69
filters = astFactory.create( FILTERS, "{filter conditions}" );
70                 // Put the FILTERS node before the HQL condition and theta joins
71
ASTUtil.insertChild( where, filters );
72             }
73             
74             // add the current fragment to the FILTERS node
75
filters.addChild( fragment );
76         }
77         else {
78             if ( thetaJoins == null ) {
79                 // Find or create the WHERE clause
80
AST where = query.getWhereClause();
81                 // Create a new THETA_JOINS node as a parent of all filters
82
thetaJoins = astFactory.create( THETA_JOINS, "{theta joins}" );
83                 // Put the THETA_JOINS node before the HQL condition, after the filters.
84
if (filters==null) {
85                     ASTUtil.insertChild( where, thetaJoins );
86                 }
87                 else {
88                     ASTUtil.insertSibling( where, thetaJoins );
89                 }
90             }
91             
92             // add the current fragment to the THETA_JOINS node
93
thetaJoins.addChild(fragment);
94         }
95
96     }
97
98     public void addDiscriminatorWhereFragment(RestrictableStatement statement, Queryable persister, Map JavaDoc enabledFilters, String JavaDoc alias) {
99         String JavaDoc whereFragment = persister.filterFragment( alias, enabledFilters ).trim();
100         if ( "".equals( whereFragment ) ) {
101             return;
102         }
103         if ( whereFragment.startsWith( "and" ) ) {
104             whereFragment = whereFragment.substring( 4 );
105         }
106
107         // Need to parse off the column qualifiers; this is assuming (which is true as of now)
108
// that this is only used from update and delete HQL statement parsing
109
whereFragment = StringHelper.replace( whereFragment, alias + ".", "" );
110
111 // Simply creating the SQL_TOKEN directly breaks the sql-gen phase; however,
112
// manually building the "eq fragment to subtree" will (in all likelihood) break
113
// if a discriminator is needed *and* a where attribute has been specified.
114
//
115
// The only real solution is to parse the resulting where Fragment using a
116
// "real" SQL grammar/parser into our SQL AST representation
117

118 // AST discrimNode = astFactory.create( SQL_TOKEN, whereFragment );
119
AST discrimNode = parseEqFragmentToSubtree( whereFragment );
120
121         if ( statement.getWhereClause().getNumberOfChildren() == 0 ) {
122             statement.getWhereClause().setFirstChild( discrimNode );
123         }
124         else {
125             AST and = astFactory.create( AND, "{and}" );
126             AST currentFirstChild = statement.getWhereClause().getFirstChild();
127             and.setFirstChild( discrimNode );
128             and.addChild( currentFirstChild );
129             statement.getWhereClause().setFirstChild( and );
130         }
131     }
132
133     private AST parseEqFragmentToSubtree(String JavaDoc whereFragment) {
134         int chunkPos = whereFragment.lastIndexOf( "=" );
135         String JavaDoc check = whereFragment.substring( 0, chunkPos ).trim();
136         String JavaDoc test = whereFragment.substring( chunkPos + 1 ).trim();
137         AST eq = astFactory.create( EQ, "{discriminator}" );
138         eq.setFirstChild( astFactory.create( IDENT, check ) );
139         eq.addChild( astFactory.create( SQL_TOKEN, test ) );
140         return eq;
141     }
142 }
143
Popular Tags