/**
* Speedo: an implementation of JDO compliant personality on top of JORM generic
* I/O sub-system. Copyright (C) 2001-2006 France Telecom
*
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option) any
* later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Contact: speedo@objectweb.org
*
* Authors: S.Chassande-Barrioz.
*/
package org.objectweb.speedo.query.ejb;
import org.objectweb.jorm.api.PMapper;
import org.objectweb.jorm.metainfo.api.Manager;
import org.objectweb.medor.api.MedorException;
import org.objectweb.medor.expression.api.ExpressionException;
import org.objectweb.medor.query.lib.SelectProject;
import org.objectweb.speedo.api.SpeedoException;
import org.objectweb.speedo.lib.Personality;
import org.objectweb.speedo.mapper.lib.DelegatePMapper;
import org.objectweb.speedo.pm.api.POManagerItf;
import org.objectweb.speedo.query.api.QueryDefinition;
import org.objectweb.speedo.query.ejb.parser.EJBQL;
import org.objectweb.speedo.query.ejb.parser.EJBQLVariableVisitor;
import org.objectweb.speedo.query.ejb.parser.ParseException;
import org.objectweb.speedo.query.ejb.parser.SimpleNode;
import org.objectweb.speedo.query.lib.AbstractCompiledQuery;
import org.objectweb.util.monolog.api.BasicLevel;
import java.io.CharArrayReader;
import java.util.Map;
public class EJBCompiledQuery extends AbstractCompiledQuery {
EJBQueryDefinitionImpl qd;
public void setMapper(PMapper m) {
mapper = new DelegatePMapper(m, Personality.EJB);
if (jf != null) {
mapper.setJormFactory(jf);
}
}
public Object getCeIdentifier() {
return qd;
}
public synchronized QueryDefinition getDefinition() {
switch (status) {
case DEFINED:
case COMPILED:
return qd;
case UNDEFINED:
default:
return null;
}
}
public void defineQuery(EJBQueryDefinitionImpl _qd) {
this.qd = new EJBQueryDefinitionImpl(_qd);
}
public void compile() throws SpeedoException, MedorException,
ExpressionException {
if (status == UNDEFINED)
throw new SpeedoException(
"Impossible to compile an undefined query");
if (status == COMPILED)
return;
long timeToCompile = System.currentTimeMillis();
boolean debug = logger.isLoggable(BasicLevel.DEBUG);
// create a speedoQL object with a filter string
String query = qd.query;
// create representations of the parameters list and the variable list
/*
toHashtableParams(qd.parameters, ";,");
toHashtableVars(qd.variables, ";,");
*/
Manager miManager = mapper.getMetaInfoManager();
if (miManager == null)
throw new SpeedoException(
"A non null Meta information manager is needed");
SimpleNode node = null;
try {
node = new EJBQL(new CharArrayReader(query.toCharArray()))
.EJBQL();
} catch (ParseException e) {
throw new SpeedoException(
"Impossible to parse the query and to create AST", e);
}
EJBQLVariableVisitor eqvv = new EJBQLVariableVisitor(node);
Map fields = eqvv.getFields();
SelectProject sp = new SelectProject("");
/*
// Begin PREFETCHING CODE (by Seb)
if (mDesc.getPrefetch() && (mapper != null)) {
// Find the QueryTree of the ClassExtend of the bean of the current finder method
// WARNING: This only works for finder methods, and not for ejbSelect methods!!!
// (Indeed the result type of the query must be the bean type in which
// the method is defined)
ClassExtent ce = null;
QueryTree qt = null;
String jormClassName = ((EntityCmp2Desc) mDesc.getBeanDesc()).getJormClassName();
Iterator itFields = fields.values().iterator();
boolean found = false;
while (itFields.hasNext() && !found) {
QueryTree cqt = ((QueryTreeField) itFields.next()).getQueryTree();
Collection extents = JormQueryTreeHelper.getJormExtents(cqt);
for (Iterator it = extents.iterator(); it.hasNext() && !found;) {
JormExtent je = (JormExtent) it.next();
if (jormClassName.equals(je.getJormName())) {
found = true;
ce = (ClassExtent) je;
qt = cqt;
}
}
}
if ((ce == null) && (qt == null)) {
throw new Error("EjbqlQueryTreeHolder: cannot do the prefetch !!!");
}
setMapper(qt, mapper);
// Add fields of the class which the values must be prefetched, at
// the begin of the the TupleCollection
JormQueryTreeHelper.addPrefetchFields(ce, qt, sp);
prefetchIdentifierIndex = sp.getTupleStructure().getSize() + 1;
}
// End PREFETCHING CODE
*/
// create SelectProject (visit the SELECT clause)
/*
EJBQLSelectVisitor eqsv = new EJBQLSelectVisitor(node, fields, sp);
*/
/* TODO
SpeedoQLVariableVisitor sqvv = new SpeedoQLVariableVisitor(node,
miManager, varParserlogger, hparams, hvars, qd.order,
qd.candidateClass.getName(), qd.includeSubClasses);
// start the variable visitor to catch all variables an build a
// first tree of them without collection navigation
Map fields = sqvv.getFields();
QueryBuilder qb = sqvv.getQueryBuilder();
QueryTree qt = sqvv.getQueryTree();
SelectProject sp = new SelectProject("");
if (!query.equals("(true)") && !query.equals("true")) {
//Ther is a filter and potentialy collection navigation
if (debug) {
logger.log(BasicLevel.DEBUG, "Query = " + qd.query);
}
// start the query filter visitor, to build and expression tree of
// the filter expression
SpeedoQLQueryFilterVisitor sqfv = new SpeedoQLQueryFilterVisitor(
fields, sp, (ASTSpeedoQL) node, filterParserLogger,
hparams, hvars, qd.candidateClass, qb, jf);
sp.setQueryFilter(sqfv.getQueryFilter());
}
assignMapper(sp);
assignMapper(qt);
JDOQueryEvalContext qec = new JDOQueryEvalContext(sp, this);
SelectGroupByVisitor sgv = new SelectGroupByVisitor(sp, qt, mapper,
sqvv, qd, qec, classLoader);
sgv.visit(qd);
selectedFieldTypes = sgv.getSelectFieldTypes();
assignMapper(qec.query);
//Specify the ordering
if (qd.order != null && qd.order.size() > 0) {
OrderField[] ofs = new OrderField[qd.order.size()];
for (int i = 0; i < ofs.length; i++) {
String o = (String) qd.order.get(i);
int idx = o.indexOf(' ');
boolean desc = false;
if (idx != -1) {
desc = o.substring(idx + 1).trim().equals("descending");
o = o.substring(0, idx);
}
o = "this." + o;
ofs[i] = new BasicOrderField((QueryTreeField) qt
.getTupleStructure().getField(o), desc);
}
sp.setOrderBy(ofs);
}
logger.log(BasicLevel.INFO, "QueryTree built");
if (debug) {
QueryTreePrinter.printQueryTree(qec.query, logger);
}
//check for the use of the userCache
if (qd.result == null && qd.variables == null) {
//no variable used and the result is the candidate class
Map field2value = new HashMap();
if (getFieldComparaison(sp.getQueryFilter(), field2value)) {
HomeItf sh = null;
try {
sh = (HomeItf) jf.getPClassMapping(qd.candidateClass
.getName(), classLoader);
} catch (PException e) {
//never happen
}
userCache = sh.getUserCache(field2value.keySet());
if (userCache != null) {
userCacheIndexes = new Operand[field2value.size()];
String[] ifs = userCache.getIndexFieldNames();
for (int i = 0; i < ifs.length; i++) {
userCacheIndexes[i] = (Operand) field2value.get(ifs[i]);
}
}
}
}
// Optimize the queryTree
optimize(qec, debug);
// Creates an evaluator associated to the QueryTree
qec.evaluator = new MedorEvaluator(qec.query, 0);
qecs = new JDOQueryEvalContext[] { qec };
*/
timeToCompile = System.currentTimeMillis() - timeToCompile;
status = COMPILED;
logger
.log(BasicLevel.INFO, "Query compiled in " + timeToCompile
+ "ms");
// TODO Auto-generated method stub
}
public Object execute(Object[] parameters, POManagerItf pm,
QueryDefinition qd) throws SpeedoException, MedorException,
ExpressionException {
// TODO Auto-generated method stub
return null;
}
public Object execute(Map parameters, POManagerItf pm, QueryDefinition qd)
throws SpeedoException, MedorException, ExpressionException {
// TODO Auto-generated method stub
return null;
}
}