KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > amber > expr > MemberExpr


1 /*
2  * Copyright (c) 1998-2006 Caucho Technology -- all rights reserved
3  *
4  * This file is part of Resin(R) Open Source
5  *
6  * Each copy or derived work must preserve the copyright notice and this
7  * notice unmodified.
8  *
9  * Resin Open Source is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * Resin Open Source is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
17  * of NON-INFRINGEMENT. See the GNU General Public License for more
18  * details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with Resin Open Source; if not, write to the
22  * Free Software Foundation, Inc.
23  * 59 Temple Place, Suite 330
24  * Boston, MA 02111-1307 USA
25  *
26  * @author Scott Ferguson
27  */

28
29 package com.caucho.amber.expr;
30
31 import com.caucho.amber.query.FromItem;
32 import com.caucho.amber.query.QueryParser;
33 import com.caucho.amber.table.Column;
34 import com.caucho.amber.table.ForeignColumn;
35 import com.caucho.amber.table.LinkColumns;
36 import com.caucho.amber.table.Table;
37 import com.caucho.util.CharBuffer;
38
39 import java.util.ArrayList JavaDoc;
40
41 /**
42  * Represents a member query expression
43  */

44 public class MemberExpr extends AbstractAmberExpr {
45   private boolean _isNot;
46
47   // PathExpr or ArgExpr (jpa/10c8)
48
private AmberExpr _itemExpr;
49
50   private AmberExpr _collectionExpr;
51
52   private MemberExpr(AmberExpr itemExpr,
53                      AmberExpr collectionExpr, boolean isNot)
54   {
55     _itemExpr = itemExpr;
56     _collectionExpr = collectionExpr;
57     _isNot = isNot;
58   }
59
60   public static AmberExpr create(QueryParser parser,
61                                  AmberExpr itemExpr,
62                                  AmberExpr collectionExpr,
63                                  boolean isNot)
64   {
65     if (collectionExpr instanceof IdExpr)
66       collectionExpr = ((CollectionIdExpr) collectionExpr).getPath();
67
68     /* commented out: jpa/10c8-jpa/10ca
69     if (itemExpr instanceof ArgExpr) {
70     }
71     else if (collectionExpr instanceof OneToManyExpr) {
72       OneToManyExpr oneToMany = (OneToManyExpr) collectionExpr;
73       PathExpr parent = oneToMany.getParent();
74
75       FromItem childFromItem = ((PathExpr) itemExpr).getChildFromItem();
76
77       AmberExpr expr;
78
79       expr = new ManyToOneJoinExpr(oneToMany.getLinkColumns(),
80                                    childFromItem,
81                                    parent.getChildFromItem());
82
83       if (isNot)
84         return new UnaryExpr(QueryParser.NOT, expr);
85       else
86         return expr;
87     }
88     */

89
90     return new MemberExpr(itemExpr, collectionExpr, isNot);
91   }
92
93   /**
94    * Binds the expression as a select item.
95    */

96   public AmberExpr bindSelect(QueryParser parser)
97   {
98     return this;
99   }
100
101   /**
102    * Returns true for a boolean expression.
103    */

104   public boolean isBoolean()
105   {
106     return true;
107   }
108
109   /**
110    * Returns true if the expression uses the from item.
111    */

112   public boolean usesFrom(FromItem from, int type, boolean isNot)
113   {
114     if (! (_itemExpr instanceof PathExpr))
115       return false;
116
117     return (_collectionExpr.usesFrom(from, type) ||
118             ((PathExpr) _itemExpr).usesFrom(from, type));
119   }
120
121   /**
122    * Returns true if the expression uses the from item.
123    */

124   public AmberExpr replaceJoin(JoinExpr join)
125   {
126     if (_itemExpr instanceof PathExpr) {
127       _collectionExpr = _collectionExpr.replaceJoin(join);
128       _itemExpr = (PathExpr) _itemExpr.replaceJoin(join);
129     }
130
131     return this;
132   }
133
134   /**
135    * Generates the where expression.
136    */

137   public void generateWhere(CharBuffer cb)
138   {
139     generateInternalWhere(cb, true);
140   }
141
142   /**
143    * Generates the (update) where expression.
144    */

145   public void generateUpdateWhere(CharBuffer cb)
146   {
147     generateInternalWhere(cb, false);
148   }
149
150   /**
151    * Generates the having expression.
152    */

153   public void generateHaving(CharBuffer cb)
154   {
155     generateWhere(cb);
156   }
157
158   //
159
// private
160

161   private void generateInternalWhere(CharBuffer cb,
162                                      boolean select)
163   {
164     OneToManyExpr oneToMany = null;
165
166     // ManyToMany is implemented as a
167
// ManyToOne[embeddeding OneToMany]
168
if (_collectionExpr instanceof ManyToOneExpr) {
169       PathExpr expr = ((ManyToOneExpr) _collectionExpr).getParent();
170       if (expr instanceof OneToManyExpr)
171         oneToMany = (OneToManyExpr) expr;
172
173     } else if (_collectionExpr instanceof OneToManyExpr) {
174       oneToMany = (OneToManyExpr) _collectionExpr;
175     }
176     else
177       throw new UnsupportedOperationException JavaDoc();
178
179     LinkColumns join = oneToMany.getLinkColumns();
180
181     if (_isNot)
182       cb.append("NOT ");
183
184     // jpa/10ca
185
// XXX: needs to handle compound PK.
186
ForeignColumn fk = (ForeignColumn) join.getColumns().get(0);
187     cb.append(oneToMany.getParent().getChildFromItem().getName());
188     cb.append('.');
189     cb.append(fk.getTargetColumn().getName());
190
191     // changed to IN for jpa/10ca cb.append("EXISTS (SELECT *");
192
cb.append(" IN (SELECT "); // SELECT *");
193
cb.append(fk.getName());
194     Table table = join.getSourceTable();
195     cb.append(" FROM " + table.getName() + " caucho");
196     cb.append(" WHERE ");
197
198     String JavaDoc targetTable = oneToMany.getParent().getChildFromItem().getName();
199
200     cb.append(join.generateJoin("caucho", targetTable));
201
202     if (_itemExpr instanceof ArgExpr) {
203
204       cb.append(" AND caucho.");
205
206       if (_collectionExpr instanceof ManyToOneExpr) {
207         join = ((ManyToOneExpr) _collectionExpr).getLinkColumns();
208
209         String JavaDoc name = join.getColumns().get(0).getName();
210
211         cb.append(name);
212       }
213       else {
214         // XXX: needs to handle compound PK.
215
ArrayList JavaDoc<Column> idColumns =
216           join.getSourceTable().getIdColumns();
217
218         cb.append(idColumns.get(0).getName());
219       }
220
221       cb.append(" = ?");
222     }
223     else if (_collectionExpr instanceof ManyToOneExpr) {
224       join = ((ManyToOneExpr) _collectionExpr).getLinkColumns();
225
226       String JavaDoc itemWhere;
227       boolean isArg = false;
228
229       String JavaDoc where;
230
231       if (_itemExpr instanceof ManyToOneExpr) {
232         LinkColumns manyToOneJoin = ((ManyToOneExpr) _itemExpr).getLinkColumns();
233
234         itemWhere = ((ManyToOneExpr) _itemExpr).getParent().getChildFromItem().getName();
235
236         where = join.generateJoin(manyToOneJoin, "caucho", itemWhere);
237       }
238       else {
239
240         if (_itemExpr instanceof PathExpr) {
241           itemWhere = ((PathExpr) _itemExpr).getChildFromItem().getName();
242         }
243         else {
244           isArg = true;
245           itemWhere = "?";
246         }
247
248         where = join.generateJoin("caucho", itemWhere, isArg);
249       }
250
251       cb.append(" AND " + where);
252     }
253     else if (_collectionExpr instanceof OneToManyExpr) {
254       if (_itemExpr instanceof ManyToOneExpr) {
255
256         join = ((ManyToOneExpr) _itemExpr).getLinkColumns();
257
258         String JavaDoc itemWhere = ((ManyToOneExpr) _itemExpr).getParent().getChildFromItem().getName();
259
260         String JavaDoc where = join.generateJoin(itemWhere, "caucho");
261
262         cb.append(" AND " + where);
263       }
264       else {
265         // XXX: needs to handle compound PK.
266
ArrayList JavaDoc<Column> idColumns =
267           join.getSourceTable().getIdColumns();
268
269         String JavaDoc id = idColumns.get(0).getName();
270
271         cb.append(" AND (caucho." + id + " = ");
272
273         FromItem childFromItem = ((PathExpr) _itemExpr).getChildFromItem();
274
275         if (childFromItem != null) {
276           cb.append(childFromItem.getName() + ".");
277
278           // XXX: needs to handle compound PK.
279
idColumns = childFromItem.getTable().getIdColumns();
280
281           cb.append(idColumns.get(0).getName() + ")");
282         }
283       }
284     }
285
286     cb.append(')');
287   }
288 }
289
Popular Tags