001: /**
002: * Speedo: an implementation of JDO compliant personality on top of JORM generic
003: * I/O sub-system. Copyright (C) 2001-2006 France Telecom
004: *
005: * This library is free software; you can redistribute it and/or modify it under
006: * the terms of the GNU Lesser General Public License as published by the Free
007: * Software Foundation; either version 2 of the License, or (at your option) any
008: * later version.
009: *
010: * This library is distributed in the hope that it will be useful, but WITHOUT
011: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
012: * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
013: * details.
014: *
015: * You should have received a copy of the GNU Lesser General Public License
016: * along with this library; if not, write to the Free Software Foundation, Inc.,
017: * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
018: *
019: * Contact: speedo@objectweb.org
020: *
021: * Authors: S.Chassande-Barrioz.
022: */package org.objectweb.speedo.query.ejb;
023:
024: import org.objectweb.jorm.api.PMapper;
025: import org.objectweb.jorm.metainfo.api.Manager;
026: import org.objectweb.medor.api.MedorException;
027: import org.objectweb.medor.expression.api.ExpressionException;
028: import org.objectweb.medor.query.lib.SelectProject;
029: import org.objectweb.speedo.api.SpeedoException;
030: import org.objectweb.speedo.lib.Personality;
031: import org.objectweb.speedo.mapper.lib.DelegatePMapper;
032: import org.objectweb.speedo.pm.api.POManagerItf;
033: import org.objectweb.speedo.query.api.QueryDefinition;
034: import org.objectweb.speedo.query.ejb.parser.EJBQL;
035: import org.objectweb.speedo.query.ejb.parser.EJBQLVariableVisitor;
036: import org.objectweb.speedo.query.ejb.parser.ParseException;
037: import org.objectweb.speedo.query.ejb.parser.SimpleNode;
038: import org.objectweb.speedo.query.lib.AbstractCompiledQuery;
039: import org.objectweb.util.monolog.api.BasicLevel;
040:
041: import java.io.CharArrayReader;
042: import java.util.Map;
043:
044: public class EJBCompiledQuery extends AbstractCompiledQuery {
045:
046: EJBQueryDefinitionImpl qd;
047:
048: public void setMapper(PMapper m) {
049: mapper = new DelegatePMapper(m, Personality.EJB);
050: if (jf != null) {
051: mapper.setJormFactory(jf);
052: }
053: }
054:
055: public Object getCeIdentifier() {
056: return qd;
057: }
058:
059: public synchronized QueryDefinition getDefinition() {
060: switch (status) {
061: case DEFINED:
062: case COMPILED:
063: return qd;
064: case UNDEFINED:
065: default:
066: return null;
067: }
068: }
069:
070: public void defineQuery(EJBQueryDefinitionImpl _qd) {
071: this .qd = new EJBQueryDefinitionImpl(_qd);
072: }
073:
074: public void compile() throws SpeedoException, MedorException,
075: ExpressionException {
076: if (status == UNDEFINED)
077: throw new SpeedoException(
078: "Impossible to compile an undefined query");
079: if (status == COMPILED)
080: return;
081: long timeToCompile = System.currentTimeMillis();
082: boolean debug = logger.isLoggable(BasicLevel.DEBUG);
083: // create a speedoQL object with a filter string
084: String query = qd.query;
085:
086: // create representations of the parameters list and the variable list
087: /*
088: toHashtableParams(qd.parameters, ";,");
089: toHashtableVars(qd.variables, ";,");
090: */
091: Manager miManager = mapper.getMetaInfoManager();
092: if (miManager == null)
093: throw new SpeedoException(
094: "A non null Meta information manager is needed");
095: SimpleNode node = null;
096: try {
097: node = new EJBQL(new CharArrayReader(query.toCharArray()))
098: .EJBQL();
099: } catch (ParseException e) {
100: throw new SpeedoException(
101: "Impossible to parse the query and to create AST",
102: e);
103: }
104:
105: EJBQLVariableVisitor eqvv = new EJBQLVariableVisitor(node);
106: Map fields = eqvv.getFields();
107:
108: SelectProject sp = new SelectProject("");
109: /*
110: // Begin PREFETCHING CODE (by Seb)
111: if (mDesc.getPrefetch() && (mapper != null)) {
112: // Find the QueryTree of the ClassExtend of the bean of the current finder method
113: // WARNING: This only works for finder methods, and not for ejbSelect methods!!!
114: // (Indeed the result type of the query must be the bean type in which
115: // the method is defined)
116: ClassExtent ce = null;
117: QueryTree qt = null;
118: String jormClassName = ((EntityCmp2Desc) mDesc.getBeanDesc()).getJormClassName();
119: Iterator itFields = fields.values().iterator();
120: boolean found = false;
121: while (itFields.hasNext() && !found) {
122: QueryTree cqt = ((QueryTreeField) itFields.next()).getQueryTree();
123: Collection extents = JormQueryTreeHelper.getJormExtents(cqt);
124: for (Iterator it = extents.iterator(); it.hasNext() && !found;) {
125: JormExtent je = (JormExtent) it.next();
126: if (jormClassName.equals(je.getJormName())) {
127: found = true;
128: ce = (ClassExtent) je;
129: qt = cqt;
130: }
131: }
132: }
133: if ((ce == null) && (qt == null)) {
134: throw new Error("EjbqlQueryTreeHolder: cannot do the prefetch !!!");
135: }
136: setMapper(qt, mapper);
137: // Add fields of the class which the values must be prefetched, at
138: // the begin of the the TupleCollection
139: JormQueryTreeHelper.addPrefetchFields(ce, qt, sp);
140: prefetchIdentifierIndex = sp.getTupleStructure().getSize() + 1;
141: }
142: // End PREFETCHING CODE
143: */
144:
145: // create SelectProject (visit the SELECT clause)
146: /*
147: EJBQLSelectVisitor eqsv = new EJBQLSelectVisitor(node, fields, sp);
148: */
149:
150: /* TODO
151: SpeedoQLVariableVisitor sqvv = new SpeedoQLVariableVisitor(node,
152: miManager, varParserlogger, hparams, hvars, qd.order,
153: qd.candidateClass.getName(), qd.includeSubClasses);
154: // start the variable visitor to catch all variables an build a
155: // first tree of them without collection navigation
156: Map fields = sqvv.getFields();
157: QueryBuilder qb = sqvv.getQueryBuilder();
158: QueryTree qt = sqvv.getQueryTree();
159:
160: SelectProject sp = new SelectProject("");
161: if (!query.equals("(true)") && !query.equals("true")) {
162: //Ther is a filter and potentialy collection navigation
163: if (debug) {
164: logger.log(BasicLevel.DEBUG, "Query = " + qd.query);
165: }
166: // start the query filter visitor, to build and expression tree of
167: // the filter expression
168: SpeedoQLQueryFilterVisitor sqfv = new SpeedoQLQueryFilterVisitor(
169: fields, sp, (ASTSpeedoQL) node, filterParserLogger,
170: hparams, hvars, qd.candidateClass, qb, jf);
171: sp.setQueryFilter(sqfv.getQueryFilter());
172: }
173: assignMapper(sp);
174: assignMapper(qt);
175:
176: JDOQueryEvalContext qec = new JDOQueryEvalContext(sp, this);
177:
178: SelectGroupByVisitor sgv = new SelectGroupByVisitor(sp, qt, mapper,
179: sqvv, qd, qec, classLoader);
180:
181: sgv.visit(qd);
182: selectedFieldTypes = sgv.getSelectFieldTypes();
183: assignMapper(qec.query);
184:
185: //Specify the ordering
186: if (qd.order != null && qd.order.size() > 0) {
187: OrderField[] ofs = new OrderField[qd.order.size()];
188: for (int i = 0; i < ofs.length; i++) {
189: String o = (String) qd.order.get(i);
190: int idx = o.indexOf(' ');
191: boolean desc = false;
192: if (idx != -1) {
193: desc = o.substring(idx + 1).trim().equals("descending");
194: o = o.substring(0, idx);
195: }
196: o = "this." + o;
197: ofs[i] = new BasicOrderField((QueryTreeField) qt
198: .getTupleStructure().getField(o), desc);
199: }
200: sp.setOrderBy(ofs);
201: }
202:
203: logger.log(BasicLevel.INFO, "QueryTree built");
204: if (debug) {
205: QueryTreePrinter.printQueryTree(qec.query, logger);
206: }
207: //check for the use of the userCache
208: if (qd.result == null && qd.variables == null) {
209: //no variable used and the result is the candidate class
210: Map field2value = new HashMap();
211: if (getFieldComparaison(sp.getQueryFilter(), field2value)) {
212: HomeItf sh = null;
213: try {
214: sh = (HomeItf) jf.getPClassMapping(qd.candidateClass
215: .getName(), classLoader);
216: } catch (PException e) {
217: //never happen
218: }
219: userCache = sh.getUserCache(field2value.keySet());
220: if (userCache != null) {
221: userCacheIndexes = new Operand[field2value.size()];
222: String[] ifs = userCache.getIndexFieldNames();
223: for (int i = 0; i < ifs.length; i++) {
224: userCacheIndexes[i] = (Operand) field2value.get(ifs[i]);
225: }
226: }
227: }
228:
229: }
230:
231: // Optimize the queryTree
232: optimize(qec, debug);
233:
234: // Creates an evaluator associated to the QueryTree
235: qec.evaluator = new MedorEvaluator(qec.query, 0);
236:
237: qecs = new JDOQueryEvalContext[] { qec };
238: */
239: timeToCompile = System.currentTimeMillis() - timeToCompile;
240: status = COMPILED;
241: logger.log(BasicLevel.INFO, "Query compiled in "
242: + timeToCompile + "ms");
243: // TODO Auto-generated method stub
244:
245: }
246:
247: public Object execute(Object[] parameters, POManagerItf pm,
248: QueryDefinition qd) throws SpeedoException, MedorException,
249: ExpressionException {
250: // TODO Auto-generated method stub
251: return null;
252: }
253:
254: public Object execute(Map parameters, POManagerItf pm,
255: QueryDefinition qd) throws SpeedoException, MedorException,
256: ExpressionException {
257: // TODO Auto-generated method stub
258: return null;
259: }
260:
261: }
|