KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > medor > query > rdb > lib > MedorExpression2WhereClause


1 /**
2  * MEDOR: Middleware Enabling Distributed Object Requests
3  *
4  * Copyright (C) 2001-2004 France Telecom R&D
5  * Contact: alexandre.lefebvre@rd.francetelecom.com
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20  *
21  * Initial developers: M. Alia, S. Chassande-Barrioz, A. Lefebvre
22  */

23 package org.objectweb.medor.query.rdb.lib;
24
25 import org.objectweb.jorm.mapper.rdb.adapter.api.RdbAdapter;
26 import org.objectweb.jorm.type.api.PType;
27 import org.objectweb.jorm.type.api.PTypeSpace;
28 import org.objectweb.medor.api.MedorException;
29 import org.objectweb.medor.expression.api.Expression;
30 import org.objectweb.medor.expression.api.ExpressionException;
31 import org.objectweb.medor.expression.api.Operand;
32 import org.objectweb.medor.expression.api.Operator;
33 import org.objectweb.medor.expression.api.ParameterOperand;
34 import org.objectweb.medor.expression.api.UnaryOperator;
35 import org.objectweb.medor.expression.converter.rdb.Expression2WhereClauseImpl;
36 import org.objectweb.medor.expression.lib.BasicOperand;
37 import org.objectweb.medor.filter.api.FieldOperand;
38 import org.objectweb.medor.filter.jorm.lib.IsNullPName;
39 import org.objectweb.medor.filter.lib.InCollection;
40 import org.objectweb.medor.filter.lib.IsEmpty;
41 import org.objectweb.medor.filter.lib.IsNull;
42 import org.objectweb.medor.filter.lib.MemberOf;
43 import org.objectweb.medor.query.api.QueryTreeField;
44 import org.objectweb.medor.query.rdb.api.RdbExpField;
45
46 import java.util.Collection JavaDoc;
47 import java.util.Iterator JavaDoc;
48
49 /**
50  * This class overrides Expression2WhereClauseImpl for MEDOR-specific operators.
51  * <p>It is meant to be used for a particular QueryLeaf.<p>
52  *
53  * @author A. Lefebvre
54  */

55 public class MedorExpression2WhereClause extends Expression2WhereClauseImpl {
56
57     /**
58      * The QueryLeaf associated to this instance of MedorExpression2WhereClause.
59      */

60     private BasicRdbExpQueryLeaf queryLeaf;
61
62     /**
63      * ParameterOperands associated to a particular conversion.
64      */

65     private ParameterOperand[] pos;
66
67     public String JavaDoc convertExp2WhereClause(Expression exp,
68                                          RdbAdapter rdbAdapter,
69                                          BasicRdbExpQueryLeaf ql,
70                                          ParameterOperand[] pos)
71     throws ExpressionException {
72         this.queryLeaf = ql;
73         this.pos = pos;
74         return convertExp2WhereClause(exp, rdbAdapter);
75     }
76
77     public void convertExp2WhereClause(Expression exp,
78                                        RdbAdapter rdbAdapter,
79                                        StringBuffer JavaDoc sb)
80             throws ExpressionException {
81         if (exp instanceof FieldOperand) {
82             sb.append(BasicRdbExpQueryLeaf.getQualifiedFieldName(
83                     ((RdbExpField) ((FieldOperand) exp).getField())));
84         } else if (exp instanceof IsNullPName) {
85             sb.append("(? = ");
86             convertExp2WhereClause(new BasicOperand(true), rdbAdapter, sb);
87             sb.append(")");
88         } else if (exp instanceof InCollection) {
89             InCollection bo = (InCollection) exp;
90             sb.append("(");
91             convertExp2WhereClause(bo.getExpression(0), rdbAdapter, sb);
92             sb.append(" ");
93             sb.append(toSqlOperator(bo.getOperatorString()));
94             sb.append(" ");
95             getSQLEnumeration(bo.getExpression(1),
96                             bo.getElemType(),
97                             pos, sb);
98             sb.append(")");
99         } else if (exp instanceof MemberOf) {
100             MemberOf mo = (MemberOf) exp;
101             int size = mo.getOperandNumber() / 2;
102             sb.append("(");
103             for (int i = 0; i < size; i++) {
104                 convertExp2WhereClause(mo.getExpression(i), rdbAdapter, sb);
105                 sb.append(i < (size - 1) ? ", " : "");
106             }
107             sb.append(" IN (");
108             FieldOperand fop = (FieldOperand) mo.getExpression(size);
109             appendSubquery(fop, rdbAdapter, sb);
110             sb.append("))");
111         } else if (exp instanceof IsEmpty) {
112             IsEmpty ie = (IsEmpty) exp;
113             sb.append(" NOT EXISTS (");
114             Expression e = ie.getExpression(0);
115             if (e instanceof FieldOperand) {
116                 appendSubquery((FieldOperand) e, rdbAdapter, sb);
117             } else {
118                 throw new IllegalStateException JavaDoc
119                     ("can't handle operand type: " + e);
120             }
121             sb.append(")");
122                 }
123         //TODO: in the case of NOT xyz, it may sometimes be better to
124
//produce something else, e.g. NOT (toto IS NULL) -> toto IS NOT NULL
125
else if (exp instanceof IsNull) { //specific MEDOR
126
convertExp2WhereClause(((UnaryOperator) exp).getExpression(0), rdbAdapter, sb);
127             sb.append(" ");
128             sb.append(toSqlOperator(((Operator) exp).getOperatorString()));
129         } else
130             super.convertExp2WhereClause(exp, rdbAdapter, sb);
131     }
132
133     private void appendSubquery(FieldOperand fop, RdbAdapter rdbAdapter,
134                     StringBuffer JavaDoc sb)
135         throws ExpressionException {
136         QueryTreeField qtf = (QueryTreeField) fop.getField();
137         BasicRdbExpQueryLeaf leaf = (BasicRdbExpQueryLeaf) qtf.getQueryTree();
138         if (leaf == queryLeaf) {
139             throw new ExpressionException
140                 ("can't append self as a subquery " + qtf.getName());
141         }
142         leaf.setRdbAdapter(rdbAdapter);
143         try {
144             sb.append(leaf.getSqlRequest(null, false, false));
145         } catch (MedorException e) {
146             throw new ExpressionException(e);
147         }
148     }
149
150     private void getSQLEnumeration(
151             Expression e,
152             PType elemType,
153             ParameterOperand[] pos,
154             StringBuffer JavaDoc sb)
155             throws ExpressionException {
156         Collection c = null;
157         sb.append("(");
158         if (e instanceof ParameterOperand) {
159             String JavaDoc pn = ((ParameterOperand) e).getName();
160             if (pos == null || pos.length == 0)
161                 throw new ExpressionException("No Parameter");
162             int i = 0;
163             while (i < pos.length && !pn.equals(pos[i].getName()))
164                 i++;
165             if (i < pos.length)
166                 c = (Collection) pos[i].getObject();
167             else
168                 throw new ExpressionException("Parameter " + pn + " not found");
169         } else
170             c = (Collection) ((Operand) e).getObject();
171         Iterator JavaDoc it = c.iterator();
172         if (!it.hasNext()) {
173             throw new ExpressionException("Empty collection for InCollection operator");
174         }
175         while (it.hasNext()) {
176             Object JavaDoc nextit = it.next();
177             //case of ParameterOperand
178
if (nextit instanceof ParameterOperand) {
179                 sb.append("?");
180             } else if (elemType.equals(PTypeSpace.STRING)) {
181                 sb.append("'");
182                 sb.append(nextit);
183                 sb.append("'");
184             } else {
185                 sb.append(nextit);
186             }
187             if (it.hasNext()) {
188                 sb.append(", ");
189             }
190         }
191         sb.append(")");
192     }
193
194     public void convertExp2WhereClauseBuilder(Expression exp,
195                                               String JavaDoc rdbAdapterVarName,
196                                               StringBuffer JavaDoc sb)
197         throws ExpressionException {
198         if (exp instanceof FieldOperand) {
199             sb.append(BasicRdbExpQueryLeaf.getQualifiedFieldName(
200                     ((RdbExpField) ((FieldOperand) exp).getField())));
201         } else if (exp instanceof IsNullPName) {
202             sb.append("(? = ");
203             convertExp2WhereClauseBuilder(new BasicOperand(true), rdbAdapterVarName, sb);
204             sb.append(")");
205         } else if (exp instanceof InCollection) {
206             InCollection bo = (InCollection) exp;
207             sb.append("(");
208             convertExp2WhereClauseBuilder(bo.getExpression(0), rdbAdapterVarName, sb);
209             sb.append(" ");
210             sb.append(toSqlOperator(bo.getOperatorString()));
211             sb.append(" ");
212             getSQLEnumeration(bo.getExpression(1),
213                             bo.getElemType(),
214                             pos, sb);
215             sb.append(")");
216         } else if (exp instanceof MemberOf) {
217             throw new ExpressionException("MemberOf Operator not yet supported at generation time");
218         } else if (exp instanceof IsNull) { //specific MEDOR
219
convertExp2WhereClauseBuilder(((Operator) exp).getExpression(0), rdbAdapterVarName, sb);
220             sb.append(" ");
221             sb.append(toSqlOperator(((Operator) exp).getOperatorString()));
222         } else
223             super.convertExp2WhereClauseBuilder(exp, rdbAdapterVarName, sb);
224     }
225 }
226
Popular Tags