Package org.objectweb.speedo.query.jdo

Source Code of org.objectweb.speedo.query.jdo.JDOAbstractCompiledQuery

/**
* Copyright (C) 2001-2006 France Telecom R&D
*/
package org.objectweb.speedo.query.jdo;

import org.objectweb.jorm.api.PMapper;
import org.objectweb.jorm.lib.JormPathHelper;
import org.objectweb.jorm.type.api.PType;
import org.objectweb.medor.api.EvaluationException;
import org.objectweb.medor.api.MedorException;
import org.objectweb.medor.eval.prefetch.api.PrefetchBufferFactory;
import org.objectweb.medor.expression.api.ExpressionException;
import org.objectweb.medor.expression.api.ParameterOperand;
import org.objectweb.medor.expression.lib.BasicParameterOperand;
import org.objectweb.medor.optim.api.QueryTransformer;
import org.objectweb.medor.optim.jorm.Jorm2Rdb;
import org.objectweb.medor.optim.lib.BasicQueryRewriter;
import org.objectweb.medor.optim.lib.FlattenQueryTreeRule;
import org.objectweb.medor.optim.lib.IndexesGenerator;
import org.objectweb.medor.optim.lib.PushNotInExpressionRule;
import org.objectweb.medor.optim.rdb.Like2SQL;
import org.objectweb.medor.query.api.QueryTree;
import org.objectweb.medor.query.jorm.lib.JormQueryTreeHelper;
import org.objectweb.medor.query.lib.QueryTreePrinter;
import org.objectweb.medor.type.lib.PTypeSpaceMedor;
import org.objectweb.medor.type.lib.QType;
import org.objectweb.perseus.persistence.api.PersistenceException;
import org.objectweb.speedo.api.SpeedoException;
import org.objectweb.speedo.lib.Personality;
import org.objectweb.speedo.mapper.api.JormFactory;
import org.objectweb.speedo.mapper.lib.DelegatePMapper;
import org.objectweb.speedo.mim.api.PersistentObjectItf;
import org.objectweb.speedo.pm.api.POManagerItf;
import org.objectweb.speedo.pm.jdo.api.JDOPOManagerItf;
import org.objectweb.speedo.query.api.QueryDefinition;
import org.objectweb.speedo.query.lib.AbstractCompiledQuery;
import org.objectweb.speedo.workingset.jdo.api.JDOTransactionItf;
import org.objectweb.util.monolog.api.BasicLevel;
import org.objectweb.util.monolog.api.Logger;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.StringTokenizer;

import javax.jdo.JDOException;
import javax.jdo.JDOUserException;

public abstract class JDOAbstractCompiledQuery extends AbstractCompiledQuery {

    /**
     * Fields from javax.jdo.Query
     */
    protected JDOQueryDefinitionImpl qd = null;

    /**
     * vparams, hparams and hvars are internal objects to manipulate the list of
     * parameters, and the list of variables.
     */
    protected Map hparams = null;

    protected Map paramName2paramClass = null;

    protected Map hvars = null;

    protected Logger varParserlogger = null;

    protected Logger filterParserLogger = null;
   
    protected abstract Object executeQT(JDOPOManagerItf pm,
            ParameterOperand[] pos,
            QueryDefinition userqd)
    throws EvaluationException, MedorException, SpeedoException ;

    public void init(Logger l, Logger logParserVar, Logger logParserFil,
            PMapper m, PrefetchBufferFactory pbf, JormFactory _jf) {
        init(l, m, pbf, _jf);
        varParserlogger = logParserVar;
        filterParserLogger = logParserFil;
    }

    public void setMapper(PMapper m) {
        mapper = new DelegatePMapper(m, Personality.JDO);
        if (jf != null) {
            mapper.setJormFactory(jf);
        }
    }

    public boolean isPrefetchResult() {
        return qd.withPrefetch;
    }

    public void defineQuery(JDOQueryDefinitionImpl _qd) {
        this.qd = new JDOQueryDefinitionImpl(_qd);
        classLoader = _qd.getCandidateClass().getClassLoader();
        if (classLoader == null) {
            classLoader = getClass().getClassLoader();
            if (classLoader == null) {
                classLoader = ClassLoader.getSystemClassLoader();
                logger.log(BasicLevel.DEBUG, "The system classLoader of the "
                        + "class is assigned to the query: " + classLoader);
            } else {
                logger.log(BasicLevel.DEBUG, "The classLoader of Speedo is"
                        + " assigned the query: " + classLoader);
            }
        } else {
            logger.log(BasicLevel.DEBUG, "The classLoader of the class is "
                    + "assigned to the query: " + classLoader);
        }
        mapper.setClassLoader(classLoader);
        status = DEFINED;
    }

    // IMPLEMENTATION OF ReplaceableCacheEntry INTERFACE //
    // ---------------------------------------------------//
    public Object getCeIdentifier() {
        return qd;
    }

    // IMPLEMENTATION OF CompiledQuery INTERFACE //
    // -------------------------------------------//
    public synchronized QueryDefinition getDefinition() {
        switch (status) {
        case DEFINED:
        case COMPILED:
            return qd;
        case UNDEFINED:
        default:
            return null;
        }
    }

    protected QueryTree optimize(QueryTree qt, boolean debug)
            throws MedorException, ExpressionException {
        ArrayList rules = new ArrayList();
        rules.add(new PushNotInExpressionRule());
        if (mapper.getMapperName().startsWith("rdb")) {
            rules.add(new FlattenQueryTreeRule());
            rules.add(new Jorm2Rdb());
            rules.add(new Like2SQL());
        } else {

        }
        QueryTree optimizedQT = qt;
        QueryTransformer queryTransformer = new BasicQueryRewriter(rules);
        IndexesGenerator indexesGenerator = new IndexesGenerator();
        try {
            optimizedQT = queryTransformer.transform(optimizedQT);
            if (debug) {
                logger.log(BasicLevel.DEBUG, "Query optimized");
                QueryTreePrinter.printQueryTree(optimizedQT, logger);
            }
            optimizedQT = indexesGenerator.transform(optimizedQT);
        } catch (Exception e) {
            throw new MedorException("Impossible to optimize the query", e);
        }

        pncParams = JormQueryTreeHelper.getRequiredPNameManagers(optimizedQT);
        for (Iterator it = pncParams.iterator(); it.hasNext();) {
            ParameterOperand po = (ParameterOperand) it.next();
            String name = po.getName();
            if (debug) {
                logger.log(BasicLevel.DEBUG, "ParameterOperand " + name
                        + " is expected.");
            }
            po.setValue(JormPathHelper.getPNameCoder(name, mapper));
        }
        return optimizedQT;
    }
    /**
     * evaluate the query with a single parameter which is a array of object
     * parameters.
     * @param pm    the persistence manager object
     * @param a    the array parameter of the query
     * @return  a Collection of result objects
     * @throws org.objectweb.medor.api.EvaluationException
     * @throws org.objectweb.medor.api.MedorException
     */
    public Object execute(Object[] a, POManagerItf  pm, QueryDefinition userqd)
            throws SpeedoException, MedorException, ExpressionException {
        if (status != COMPILED)
            throw new EvaluationException(
                    "Impossible to execute a query if it has not been defined and compiled before");
        ParameterOperand[] pos = null;
        if (a != null) {
            pos = new ParameterOperand[a.length + pncParams.size()];
            for(Iterator it = hparams.values().iterator(); it.hasNext();) {
                Object[] o = (Object[]) it.next();
                int idx = ((Integer) o[0]).intValue();
                pos[idx] = new BasicParameterOperand(
                    (BasicParameterOperand) o[1]);
                treatParameter(pos[idx], a[idx]);
            }
        } else {
            pos = new ParameterOperand[pncParams.size()];
        }
        if (pncParams.size() >0) {
            int i = (a == null ? 0 : a.length);
            for (Iterator it = pncParams.iterator(); it.hasNext(); i++) {
                pos[i++] = (ParameterOperand) it.next();
            }
        }
        return executeQT((JDOPOManagerItf) pm, pos, userqd);
    }


    /**
     * evaluate the query with a single parameter which is a Map of object parameters.
     * @param pm    the persistence manager object
     * @param m    the map parameter of the query
     * @return  a Collection of result objects
     * @throws org.objectweb.medor.api.EvaluationException
     * @throws org.objectweb.medor.api.MedorException
     */
    public Object execute(Map m, POManagerItf  pm, QueryDefinition userqd)
            throws SpeedoException, MedorException, ExpressionException {
        if (status != COMPILED)
            throw new EvaluationException(
                    "Impossible to execute a query if it has not been defined and compiled before");
        ParameterOperand[] pos =
                new BasicParameterOperand[m.size() + pncParams.size()];
        for(Iterator it = hparams.values().iterator(); it.hasNext();) {
            Object[] o = (Object[]) it.next();
            int idx = ((Integer) o[0]).intValue();
            pos[idx] = new BasicParameterOperand(
                (BasicParameterOperand) o[1]);
            treatParameter(pos[idx], m.get(pos[idx].getName()));
            }
        if (pncParams.size() >0) {
            int i = (m == null ? 0 : m.size());
            for (Iterator it = pncParams.iterator(); it.hasNext(); i++) {
                pos[i++] = (ParameterOperand) it.next();
            }
        }
        return executeQT((JDOPOManagerItf) pm, pos, userqd);
    }

    protected void treatParameter(ParameterOperand po, Object value)
        throws SpeedoException, ExpressionException {
        Object val = value;
        if (po.getType().getTypeCode() == QType.TYPECODE_PNAME) {
            //Assign the pname of the parameter
            if (val == null) {
                try {
                    val =
                        jf.getPClassMapping(
                        (Class) paramName2paramClass.get(po.getName()))
                        .getPBinder().getNull();
                } catch (Exception e) {
                    throw new SpeedoException(
                        "Impossible to find the null PName of the parameter (name= "
                        + po.getName()
                        + " / type= " + po.getType().getJormName(),
                        e);
                }
            } else if (val instanceof PersistentObjectItf) {
                val = ((PersistentObjectItf) value).getPName();
            } else {
                throw new JDOUserException("The parameter '"
                    + po.getName()
                    + "' must be a persistent object: " + val);
            }
        }
        po.setValue(val);
    }

    // Private Methods //
    //-----------------//

    /**
     * Hash a String, and compute a Hashtable
     * example:
     *   ("String name, Float salary, Employee boss", ",")
     *   keys     | values
     *   ---------------------
     *   "name"   | "String"
     *   "salary" | "Float"
     *   "boss"   | "Employee"
     *
     * @param stringToHash  the String to hash
     * @param separator     the separator to tokenize
     */
    protected void toHashtableParams(String stringToHash, String separator) {
        hparams = new HashMap();
        paramName2paramClass = new HashMap();
        if (stringToHash != null) {
            StringTokenizer tok = new StringTokenizer(stringToHash, separator);
            int idx = 0;
            while (tok.hasMoreTokens()) {
                String tuple = tok.nextToken().trim();
                int i = tuple.indexOf(' ');
                String name = tuple.substring(i + 1, tuple.length());
                String paramType = tuple.substring(0, i).trim();
                PType type = getPType(paramType);
                hparams.put(name, new Object[]{
                    new Integer(idx),
                    new BasicParameterOperand(type, name)});
                idx ++;
                if (type == PTypeSpaceMedor.PNAME) {
                    paramName2paramClass.put(name, getClass(paramType));
                }
            }
        }
    }

    protected void toHashtableVars(String stringToHash, String separator) {
        hvars = new HashMap();
        if (stringToHash != null) {
            StringTokenizer tok = new StringTokenizer(stringToHash, separator);
            while (tok.hasMoreTokens()) {
                String tuple = tok.nextToken().trim();
                int i = tuple.indexOf(' ');
                String type = tuple.substring(0, i);
                hvars.put(tuple.substring(i + 1, tuple.length()), type);
            }
        }
    }

    protected Class getClass(String classname) {
        if (classLoader != null) {
            try {
                return classLoader.loadClass(classname);
            } catch (ClassNotFoundException e) {
                try {
                    return classLoader.loadClass(
                            qd.candidateClass.getPackage().getName() + "." + classname);
                } catch (ClassNotFoundException e2) {
                    return null;
                }
            }
        } else {
            return null;
        }
    }
   
    protected void flushCache(JDOPOManagerItf pm) {
        if (!qd.ignoreCache || !pm.getIgnoreCache()) {
            if (logger.isLoggable(BasicLevel.DEBUG)) {
                logger.log(BasicLevel.DEBUG,
                    "Flush dirty instances of the working set ...");
            }
            try {
                pm.getTransactionalPersistenceManager()
                        .flush((JDOTransactionItf) pm.currentTransaction(), this);
            } catch (PersistenceException e) {
                throw new JDOException("Impossible to use the cache into a " +
                        "query: Error during the flushing of data on the support", e);
            }
        }
    }

}
TOP

Related Classes of org.objectweb.speedo.query.jdo.JDOAbstractCompiledQuery

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.