Package org.xorm.query

Source Code of org.xorm.query.QueryImpl

/*
    $Header: /cvsroot/xorm/xorm/src/org/xorm/query/QueryImpl.java,v 1.29 2003/08/29 16:42:31 wbiggs Exp $

    This file is part of XORM.

    XORM is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    XORM 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 General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with XORM; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/
package org.xorm.query;

import java.io.StringReader;
import java.util.HashMap;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.ArrayList;
import java.util.StringTokenizer;

import javax.jdo.Query;
import javax.jdo.Extent;
import javax.jdo.PersistenceManager;
import javax.jdo.JDOUserException;

import org.xorm.ClassMapping;
import org.xorm.CollectionProxy;
import org.xorm.FetchGroupManager;
import org.xorm.InterfaceManagerFactory;
import org.xorm.I15d;
import org.xorm.XORM;
import org.xorm.query.jdoql.JDOQL;

/**
* Implementation of JDO query interface.  This is a wrapper around
* a QueryLanguage object, which returns an Expression.
*/
public class QueryImpl implements Query, I15d {
    private static HashMap knownClasses = new HashMap();
    static {
        knownClasses.put("Character", Character.class);
        knownClasses.put("char", Character.TYPE);
        knownClasses.put("Integer", Integer.class);
        knownClasses.put("int", Integer.TYPE);
        knownClasses.put("Long", Long.class);
        knownClasses.put("long", Long.TYPE);
        knownClasses.put("Float", Float.class);
        knownClasses.put("float", Float.TYPE);
        knownClasses.put("Double", Double.class);
        knownClasses.put("double", Double.TYPE);
        knownClasses.put("Boolean", Boolean.class);
        knownClasses.put("boolean", Boolean.TYPE);
        knownClasses.put("Short", Short.class);
        knownClasses.put("short", Short.TYPE);
        knownClasses.put("String", String.class);

        // This one's not in the spec, but it's rather convenient.
        knownClasses.put("Collection", Collection.class);
    }

    // Instance variables
    protected PersistenceManager mgr;
    protected QueryLanguage query;

    protected boolean compiled;
    private List imports;
    private List openResults = new ArrayList();

    public QueryImpl(PersistenceManager mgr) {
        this.mgr = mgr;
        query = new JDOQL();
    }

    public QueryImpl(PersistenceManager mgr, QueryLanguage query) {
        this.mgr = mgr;
        this.query = query;
    }

    // TODO FIXME
    public QueryImpl(PersistenceManager mgr, QueryImpl other) {
        this(mgr);
        /*
          NEED query = (QueryLanguage) other.query.clone()
          this.compiled = other.compiled;
        */
        if (other.imports != null) {
            this.imports = new ArrayList(other.imports);
        }
    }

    public PersistenceManager getPersistenceManager() {
        return mgr;
    }

    public void setClass(Class clazz) {
        if (query instanceof AbstractQueryLanguage) {
            ((AbstractQueryLanguage) query).setClass(clazz);
        }
    }

    public Class getCandidateClass() {
        return query.getCandidateClass();
    }

    public void setFilter(String filter) {
        if (query instanceof AbstractQueryLanguage) {
            ((AbstractQueryLanguage) query).setFilter(filter);
        }
    }

    // Needed by ExpressionValidator
    Class getParameterType(String name) {
        if (query instanceof AbstractQueryLanguage) {
            return ((AbstractQueryLanguage) query).getParameterType(name);
        }
        return null;
    }
    Class getVariableType(String name) {
        if (query instanceof AbstractQueryLanguage) {
            return ((AbstractQueryLanguage) query).getVariableType(name);
        }
        return null;
    }

    public void declareVariables(String variables) {
        if (query instanceof AbstractQueryLanguage) {
            declareImpl(variables, ((AbstractQueryLanguage) query).varNameToType, ";");
        } else {
            throw new UnsupportedOperationException();
        }
    }

    public void declareParameters(String parameters) {
        if (query instanceof AbstractQueryLanguage) {
            declareImpl(parameters, ((AbstractQueryLanguage) query).paramNameToType, ",");
        } else {
            throw new UnsupportedOperationException();
        }
    }

    // Shared code for variables and parameters
    // TODO more sanity checking
    private void declareImpl(String input, HashMap nameMap, String token) {
        StringTokenizer toke = new StringTokenizer(input, token);
        while (toke.hasMoreTokens()) {
            String var = toke.nextToken().trim();
            int pos = var.indexOf(' ');
            String typeName = var.substring(0,pos);
            String varName = var.substring(pos+1);
            Class typeClass = typeNameToClass(typeName);
            if (typeClass == null) {
                throw new JDOUserException(I18N.msg("E_query_class", typeName));
            }
            nameMap.put(varName, typeClass);
        } // for each parameter
    }

    public void compile() {
        if (!compiled) {
            try {
                query.compile();
                compiled = true;
            } catch (QuerySyntaxException e) {
                throw new JDOUserException(I18N.msg("E_parse_query"), e);
            }
            ExpressionValidator ev = new ExpressionValidator(this);
            if (!ev.isValid()) {
                throw new JDOUserException(I18N.msg("E_parse_query"));
            }
        }
    }

    Expression getExpression() {
        return query.getExpression();
    }

    private Object getCollectionProxy(BoundExpression bound) {
        FetchGroupManager fgm = XORM.getFetchGroupManager(mgr);
        ClassMapping mapping = XORM.getModelMapping(mgr).getClassMapping(query.getCandidateClass());
        Selector selector = bound.getSelector();
        selector.require(fgm.getDataFetchGroup(mapping));
        CollectionProxy cp = new CollectionProxy(mgr, mapping, selector);
        openResults.add(cp);
        return cp;
    }

    public BoundExpression getBoundExpression() {
        if (!compiled) {
            compile();
        }
        return new BoundExpression(query, mgr);
    }

    public Object execute() {
        return getCollectionProxy(getBoundExpression());
    }

    public Object execute(Object param) {
        BoundExpression bound = getBoundExpression();
        bound.bindParameter(0, param);
        return getCollectionProxy(bound);
    }
    public Object execute(Object param0, Object param1) {
        BoundExpression bound = getBoundExpression();
        bound.bindParameter(0, param0);
        bound.bindParameter(1, param1);
        return getCollectionProxy(bound);
    }
    public Object execute(Object param0, Object param1, Object param2) {
        BoundExpression bound = getBoundExpression();
        bound.bindParameter(0, param0);
        bound.bindParameter(1, param1);
        bound.bindParameter(2, param2);
        return getCollectionProxy(bound);
    }

    public Object executeWithMap(Map map) {
        BoundExpression bound = getBoundExpression();
        bound.setMap(map);
        return getCollectionProxy(bound);
    }

    public Object executeWithArray(Object[] array) {
        BoundExpression bound = getBoundExpression();
        for (int i = 0; i < array.length; i++) {
            bound.bindParameter(i, array[i]);
        }
        return getCollectionProxy(bound);
    }

    public void setCandidates(Extent extent) {
        // TODO this does not account for subclasses = false,
        // but at present subclasses are not supported anyway.
        if (query instanceof AbstractQueryLanguage) {
            ((AbstractQueryLanguage) query).setClass(extent.getCandidateClass());
        }
    }

    public void setCandidates(Collection collection) {
        throw new UnsupportedOperationException();
    }

    public void declareImports(String imports) {
        this.imports = new ArrayList();

        StringTokenizer toke = new StringTokenizer(imports, ";");
        while (toke.hasMoreTokens()) {
            String var = toke.nextToken().trim();
            int pos = var.indexOf(' ');
            String importStr = var.substring(0,pos);
            if (!"import".equals(importStr)) {
                throw new JDOUserException("Bad syntax for import");
            }
            String target = var.substring(pos+1);
            this.imports.add(target);
        }
    }

    // TODO: Check spec on the order in which we check these things
    private Class typeNameToClass(String typeName) {
        if (typeName.indexOf('.') != -1) {
            // Fully specified name.
            try {
                return Class.forName(typeName);
            } catch (ClassNotFoundException e2) {
                // silently ignore
            }
        } else {
            // Might be a well known java.lang class
            Class typeClass = (Class) knownClasses.get(typeName);
            if (typeClass != null) return typeClass;
        }
 
        // Not fully specified or java.lang; try imports
        if (imports != null) {
            String dotName = "." + typeName;
            Iterator i = imports.iterator();
            while (i.hasNext()) {
                String importStr = (String) i.next();
                if (importStr.endsWith(dotName)) {
                    try {
                        return Class.forName(importStr);
                    } catch (ClassNotFoundException e) {
                        // silently ignore
                    }
                } else if (importStr.endsWith("*")) {
                    try {
                        return Class.forName(importStr.substring(0, importStr.length() - 1) + typeName);
                    } catch (ClassNotFoundException e) {
                        // silently ignore
                    }
                }
            } // for each import
        // if there are imports
 
        // Assume same package as the thing we're selecting
        try {
            return Class.forName(query.getCandidateClass().getPackage().getName() + "." + typeName);
        } catch (ClassNotFoundException e) {
            // silently ignore
        }
        return null;
    }

    public void setOrdering(String ordering) {
        if (query instanceof AbstractQueryLanguage) {
            StringTokenizer toke = new StringTokenizer(ordering, ",");
            while (toke.hasMoreTokens()) {
                String var = toke.nextToken().trim();
                int pos = var.indexOf(' ');
                if (pos < 0) {
                    throw new JDOUserException(I18N.msg("E_query_ordering"));
                }
                String field = var.substring(0,pos);
                String orderStr = var.substring(pos+1);
                int order;
                if ("ascending".equalsIgnoreCase(orderStr)) {
                    order = QueryOrdering.ASCENDING;
                } else if ("descending".equalsIgnoreCase(orderStr)) {
                    order = QueryOrdering.DESCENDING;
                } else {
                    throw new JDOUserException(I18N.msg("E_query_ordering"));
                }
                ((AbstractQueryLanguage) query)
                    .addOrdering(new QueryOrdering(field, order));
            }
        }
    }

    public QueryOrdering[] getOrdering() {
        return query.getOrdering();
    }

    public void setIgnoreCache(boolean ignoreCache) {
        throw new UnsupportedOperationException();
    }
    public boolean getIgnoreCache() {
        throw new UnsupportedOperationException();
    }
    public void close(Object object) {
        if (openResults.contains(object)) {
            ((CollectionProxy) object).close();
            openResults.remove(object);
        }
    }
    public void closeAll() {
        Iterator it = openResults.iterator();
        while (it.hasNext()) {
            ((CollectionProxy) it.next()).close();
        }
        openResults.clear();
    }

    public String toString() {
        return getExpression().toString();
    }
}
TOP

Related Classes of org.xorm.query.QueryImpl

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.