001: /*
002: * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved
003: *
004: * This file is part of Resin(R) Open Source
005: *
006: * Each copy or derived work must preserve the copyright notice and this
007: * notice unmodified.
008: *
009: * Resin Open Source is free software; you can redistribute it and/or modify
010: * it under the terms of the GNU General Public License as published by
011: * the Free Software Foundation; either version 2 of the License, or
012: * (at your option) any later version.
013: *
014: * Resin Open Source is distributed in the hope that it will be useful,
015: * but WITHOUT ANY WARRANTY; without even the implied warranty of
016: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
017: * of NON-INFRINGEMENT. See the GNU General Public License for more
018: * details.
019: *
020: * You should have received a copy of the GNU General Public License
021: * along with Resin Open Source; if not, write to the
022: * Free Software Foundation, Inc.
023: * 59 Temple Place, Suite 330
024: * Boston, MA 02111-1307 USA
025: *
026: * @author Scott Ferguson
027: */
028:
029: package com.caucho.amber.expr;
030:
031: import com.caucho.amber.query.FromItem;
032: import com.caucho.amber.query.QueryParseException;
033: import com.caucho.amber.query.QueryParser;
034: import com.caucho.util.CharBuffer;
035:
036: import java.util.ArrayList;
037:
038: /**
039: * A conjunction.
040: */
041: public class AndExpr extends AbstractAmberExpr {
042: private ArrayList<AmberExpr> _components = new ArrayList<AmberExpr>();
043:
044: /**
045: * Creates the and.
046: */
047: public static AmberExpr create(AmberExpr left, AmberExpr right)
048: throws QueryParseException {
049: if (left == null && right == null)
050: return null;
051: else if (left == null)
052: return right.createBoolean();
053: else if (right == null)
054: return left.createBoolean();
055: else if (left instanceof AndExpr) {
056: AndExpr and = (AndExpr) left;
057: and.add(right.createBoolean());
058: return and;
059: } else if (right instanceof AndExpr) {
060: AndExpr and = (AndExpr) right;
061: and.add(left.createBoolean());
062: return and;
063: } else {
064: AndExpr and = new AndExpr();
065: and.add(left.createBoolean());
066: and.add(right.createBoolean());
067:
068: return and;
069: }
070: }
071:
072: /**
073: * Returns true for a boolean expression.
074: */
075: public boolean isBoolean() {
076: return true;
077: }
078:
079: /**
080: * Adds a new component.
081: */
082: public void add(AmberExpr expr) {
083: _components.add(expr);
084: }
085:
086: /**
087: * Returns the components.
088: */
089: public ArrayList<AmberExpr> getComponents() {
090: return _components;
091: }
092:
093: /**
094: * Binds the expression as a select item.
095: */
096: public AmberExpr bindSelect(QueryParser parser) {
097: for (int i = 0; i < _components.size(); i++) {
098: AmberExpr expr = _components.get(i);
099:
100: expr = expr.bindSelect(parser);
101:
102: _components.set(i, expr);
103: }
104:
105: return this ;
106: }
107:
108: /**
109: * Returns a single expression.
110: */
111: public AmberExpr getSingle() {
112: if (_components.size() == 0)
113: return null;
114: else if (_components.size() == 1)
115: return _components.get(0);
116: else
117: return this ;
118: }
119:
120: /**
121: * Returns true if the expression uses the from item.
122: */
123: public boolean usesFrom(FromItem from, int type, boolean isNot) {
124: if (type == IS_INNER_JOIN) {
125: // returns true if the from item is used in any term of the conjunction
126: for (int i = 0; i < _components.size(); i++) {
127: AmberExpr expr = _components.get(i);
128:
129: if (!isNot && expr.usesFrom(from, type, isNot))
130: return true;
131: else if (isNot && !expr.usesFrom(from, type, isNot))
132: return false;
133: }
134:
135: return false;
136: } else {
137: for (int i = 0; i < _components.size(); i++) {
138: AmberExpr expr = _components.get(i);
139:
140: if (expr.usesFrom(from, type))
141: return true;
142: }
143:
144: return false;
145: }
146: }
147:
148: /**
149: * Returns true if the from item is used in the expression
150: */
151: @Override
152: public boolean exists(FromItem from) {
153: for (int i = 0; i < _components.size(); i++) {
154: if (_components.get(i).exists(from))
155: return true;
156: }
157:
158: return false;
159: }
160:
161: /**
162: * Returns true if the expression uses the from item.
163: */
164: public AmberExpr replaceJoin(JoinExpr join) {
165: for (int i = 0; i < _components.size(); i++) {
166: AmberExpr expr = _components.get(i);
167:
168: expr = expr.replaceJoin(join);
169:
170: _components.set(i, expr);
171: }
172:
173: return this ;
174: }
175:
176: /**
177: * Generates the where expression.
178: */
179: public void generateWhere(CharBuffer cb) {
180: generateInternalWhere(cb, true);
181: }
182:
183: /**
184: * Generates the (update) where expression.
185: */
186: public void generateUpdateWhere(CharBuffer cb) {
187: generateInternalWhere(cb, false);
188: }
189:
190: /**
191: * Generates the having expression.
192: */
193: public void generateHaving(CharBuffer cb) {
194: generateWhere(cb);
195: }
196:
197: /**
198: * Generates the join expression.
199: */
200: public void generateJoin(CharBuffer cb) {
201: cb.append('(');
202:
203: for (int i = 0; i < _components.size(); i++) {
204: if (i != 0)
205: cb.append(" and ");
206:
207: AmberExpr expr = _components.get(i);
208:
209: expr.generateJoin(cb);
210: }
211:
212: cb.append(')');
213: }
214:
215: /**
216: * Binds the argument type based on another expr.
217: */
218: public void setInternalArgType(AmberExpr other) {
219: for (int i = 0; i < _components.size(); i++)
220: _components.get(i).setInternalArgType(other);
221: }
222:
223: //
224: // private
225:
226: private void generateInternalWhere(CharBuffer cb, boolean select) {
227: cb.append('(');
228:
229: for (int i = 0; i < _components.size(); i++) {
230: if (i != 0)
231: cb.append(" and ");
232:
233: AmberExpr expr = _components.get(i);
234:
235: if (select)
236: expr.generateWhere(cb);
237: else
238: expr.generateUpdateWhere(cb);
239: }
240:
241: cb.append(')');
242: }
243: }
|