alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Glassfish example source code file (QueryImpl.java)

This example Glassfish source code file (QueryImpl.java) is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Java - Glassfish tags/keywords

class, collection, jdoexception, jqlc, noi18n, noi18n, object, object, parametertable, queryimpl, queryimpl, string, string, stringbuffer, util

The Glassfish QueryImpl.java source code

/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
 *
 * The contents of this file are subject to the terms of either the GNU
 * General Public License Version 2 only ("GPL") or the Common Development
 * and Distribution License("CDDL") (collectively, the "License").  You
 * may not use this file except in compliance with the License.  You can
 * obtain a copy of the License at
 * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
 * or packager/legal/LICENSE.txt.  See the License for the specific
 * language governing permissions and limitations under the License.
 *
 * When distributing the software, include this License Header Notice in each
 * file and include the License file at packager/legal/LICENSE.txt.
 *
 * GPL Classpath Exception:
 * Oracle designates this particular file as subject to the "Classpath"
 * exception as provided by Oracle in the GPL Version 2 section of the License
 * file that accompanied this code.
 *
 * Modifications:
 * If applicable, add the following below the License Header, with the fields
 * enclosed by brackets [] replaced by your own identifying information:
 * "Portions Copyright [year] [name of copyright owner]"
 *
 * Contributor(s):
 * If you wish your version of this file to be governed by only the CDDL or
 * only the GPL Version 2, indicate your decision by adding "[Contributor]
 * elects to include this software in this distribution under the [CDDL or GPL
 * Version 2] license."  If you don't indicate a single choice of license, a
 * recipient has the option to distribute your version of this file under
 * either the CDDL, the GPL Version 2 or to extend the choice of license to
 * its licensees as provided above.  However, if you add GPL Version 2 code
 * and therefore, elected the GPL Version 2 license, then the option applies
 * only if the new code is made subject to such option by the copyright
 * holder.
 */

/*
 * QueryImpl.java
 *
 * Created on March 8, 2000
 */

package com.sun.jdo.spi.persistence.support.sqlstore.query;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Map;
import java.util.ResourceBundle;

import com.sun.jdo.api.persistence.support.Query;
import com.sun.jdo.api.persistence.support.Transaction;
import com.sun.jdo.api.persistence.support.JDOException;
import com.sun.jdo.api.persistence.support.JDOQueryException;
import com.sun.jdo.api.persistence.support.JDOUnsupportedOptionException;
import com.sun.jdo.spi.persistence.support.sqlstore.PersistenceManager;
import com.sun.jdo.spi.persistence.support.sqlstore.RetrieveDesc;
import com.sun.jdo.spi.persistence.utility.logging.Logger;
import com.sun.jdo.spi.persistence.support.sqlstore.query.jqlc.JQLC;
import com.sun.jdo.spi.persistence.support.sqlstore.query.jqlc.ParameterTable;
import com.sun.jdo.spi.persistence.support.sqlstore.ValueFetcher;
import org.glassfish.persistence.common.I18NHelper;

/**
 *
 * @author  Michael Bouschen
 * @version 0.1
 */
public class QueryImpl
    implements Query
{
    /**
     *
     */
    private Class candidateClass;

    /**
     *
     */
    private String filterExpression;

    /**
     *
     */
    private String importDeclarations;

    /**
     *
     */
    private String parameterDeclarations;

    /**
     *
     */
    private String variableDeclarations;

    /**
     *
     */
    private String orderingSpecification;

    /**
     *
     */
    private String resultExpression;

    /**
     *
     */
    private boolean compiled = false;

    /**
     *
     */
    private transient PersistenceManager pm;

    /**
     *
     */
    private transient Collection candidateCollection;

    /**
     *
     */
    private transient boolean ignoreCache;

    /**
     * Enable relationship fields prefetch for this query.
     */
    private transient boolean prefetchEnabled = true;

    /**
     *
     */
    private transient JQLC jqlc;

    /**
     *
     */
    private transient ParameterTable paramtab;

    /**
     * Flag indicating whtehr this instance was created by serialization.
     */
    private transient boolean createdBySerialization = false;

    /**
     * I18N support
     */
    protected final static ResourceBundle messages =
        I18NHelper.loadBundle(QueryImpl.class);

    /** The logger */
    private static Logger logger = LogHelperQueryExecute.getLogger();

    /**
     * Create an empty query instance with no elements.
     */
    public QueryImpl(PersistenceManager pm)
    {
        if (logger.isLoggable(Logger.FINER))
            logger.finer("LOG_CreateNewQuery", identity()); //NOI18N
        this.pm = pm;
        this.paramtab = new ParameterTable();
        this.ignoreCache = pm.getPersistenceManagerFactory().getIgnoreCache();
    }

    /**
     * Create a new Query using elements from another Query.  The other Query
     * must have been created by the same JDO implementation.  It might be active
     * in a different PersistenceManager or might have been serialized and restored.
     * @param compiled another Query from the same JDO implementation
     */
    public QueryImpl (PersistenceManager pm, Object compiled)
    {
        if (logger.isLoggable(Logger.FINER))
            logger.finer("LOG_CreateNewQueryFromCompiled", identity(), compiled); //NOI18N
        this.pm = pm;
        if (compiled == null)
        {
            JDOException ex = new JDOQueryException(I18NHelper.getMessage(
                messages, "query.queryimpl.init.compiledquery.isnull")); //NOI18N
            logger.throwing("query.QueryImpl", "<init>", ex); //NOI18N
            throw ex;
        }

        if (!(compiled instanceof QueryImpl))
        {
            JDOException ex = new JDOQueryException(I18NHelper.getMessage(
                messages, "query.queryimpl.init.compiledquery.invalidtype", //NOI18N
                compiled.getClass().getName()));
            logger.throwing("query.QueryImpl", "<init>", ex); //NOI18N
            throw ex;
        }

        QueryImpl other = (QueryImpl)compiled;
        this.candidateClass = other.candidateClass;
        this.filterExpression = other.filterExpression;
        this.importDeclarations = other.importDeclarations;
        this.parameterDeclarations = other.parameterDeclarations;
        this.variableDeclarations = other.variableDeclarations;
        this.orderingSpecification = other.orderingSpecification;
        this.resultExpression = other.resultExpression;
        this.ignoreCache = other.ignoreCache;
        this.prefetchEnabled = other.prefetchEnabled;
        this.candidateCollection = null;

        // initialize paramtab, jqlc and compiled
        if (other.paramtab != null)
        {
            this.jqlc = other.jqlc;
            this.paramtab = new ParameterTable(other.paramtab);
            this.compiled = other.compiled;
        } 
        else
        {
            // other.paramtab == null means deserialized query =>
            // - parameter table
            // - set compiled = false
            this.jqlc = null;
            this.paramtab = new ParameterTable();
            this.compiled = false;
        }
    }

    /**
     * Create a query instance with the candidate class specified.
     * @param candidateClass the Class of the candidate instances.
     */
    public QueryImpl(PersistenceManager pm, Class candidateClass)
    {
        this(pm);
        setClass(candidateClass);
    }

    /**
     * Create a query instance with the candidate class and
     * candidate collection specified.
     * @param candidateClass the Class of the candidate instances.
     * @param candidateCollection the Collection of candidate instances.
     */
    public QueryImpl(PersistenceManager pm, Class candidateClass, Collection candidateCollection)
    {
        this(pm);
        setClass(candidateClass);
        setCandidates(candidateCollection);
    }

    /**
     * Create a query instance with the candidate class and
     * filter specified.
     * @param candidateClass the Class of the candidate instances.
     * @param filter the Filter for candidate instances.
     */
    public QueryImpl(PersistenceManager pm, Class candidateClass, String filter)
    {
        this(pm);
        setClass(candidateClass);
        setFilter(filter);
    }

    /**
     * Create a query instance with the candidate class,
     * the candidate collection, and filter specified.
     * @param candidateClass the Class of the candidate instances.
     * @param candidateCollection the Collection of candidate instances.
     * @param filter the Filter for candidate instances
     */
    public QueryImpl(PersistenceManager pm, Class candidateClass, Collection candidateCollection, String filter)
    {
        this(pm);
        setClass(candidateClass);
        setCandidates(candidateCollection);
        setFilter(filter);
    }

    /**
     * Bind the candidate class to the query instance.
     *
     * The class is used to scope the names in the query filter.
     * All of the candidate instances will be of this class or subclass.
     *
     * @param candidateClass the Class of the candidate instances.
     */
    public void setClass(Class candidateClass)
    {
        synchronized (this.paramtab)
        {
            this.candidateClass = candidateClass;
            this.compiled = false;
        }
    }

    /**
     * Bind the candidate Collection to the query instance.
     *
     * @param candidateCollection the Candidate collection.
     */
    public void setCandidates(Collection candidateCollection)
    {
        synchronized (this.paramtab)
        {
            this.candidateCollection = candidateCollection;
            // candidateCollection is not part of query compilation =>
            // do not change compiled flag
        }
    }

    /**
     * Bind the query filter to the query instance.
     *
     * The query filter is a Java boolean expression, which tells whether
     * instances in the candidate collection are to be returned in the result.
     *
     * @param filter the query filter.
     */
    public void setFilter(String filter)
    {
        synchronized (this.paramtab)
        {
            this.filterExpression = filter;
            this.compiled = false;
        }
    }

    /**
     * Bind the import statements to the query instance.
     * All imports must be declared in the same method call,
     * and the imports must be separated by semicolons.
     * The syntax is the same as in the Java language import statement.
     *
     * Parameters and unbound variables might come from a different class
     * from the candidate class, and the names might need to be declared in an
     * import statement to eliminate ambiguity.
     *
     * @param imports import statements separated by semicolons.
     */
    public void declareImports(String imports)
    {
        synchronized (this.paramtab)
        {
            this.importDeclarations = imports;
            this.compiled = false;
        }
    }

    /**
     * Bind the parameter statements to the query instance.
     * This method defines the parameter types and names
     * which will be used by a subsequent execute method.
     *
     * The parameter declaration is a String containing one or
     * more query parameter declarations separated with commas.
     * It follows the syntax for formal parameters in the Java language.
     * Each parameter named in the parameter declaration must be bound
     * to a value when the query is executed.
     *
     * @param parameters the list of parameters separated by commas.
     */
    public void declareParameters(String parameters)
    {
        synchronized (this.paramtab)
        {
            this.parameterDeclarations = parameters;
            this.compiled = false;
        }
    }

    /**
     * Bind the unbound variable statements to the query instance.
     * This method defines the types and names of variables that will be used
     * in the filter but not provided as values by the execute method.
     *
     * Variables might be used in the filter, and these variables must be
     * declared with their type. The unbound variable declaration is a
     * String containing one or more unbound variable declarations separated with
     * semicolons. It follows the syntax for local variables in the Java language.
     *
     * @param variables the variables separated by semicolons.
     */
    public void declareVariables(String variables)
    {
        synchronized (this.paramtab)
        {
            this.variableDeclarations = variables;
            this.compiled = false;
        }
    }

    /**
     * Bind the ordering statements to the query instance.
     *
     * The ordering specification includes a list of expressions
     * with the ascending/descending indicator.
     */
    public void setOrdering(String ordering)
    {
        synchronized (this.paramtab)
        {
            this.orderingSpecification = ordering;
            this.compiled = false;
        }
    }

    /**
     * Set the result of the query.
     * <p>
     * The query result is an optional keyword distinct followed by a Java
     * expression, which tells what values are to be returned by the JDO query.
     * If the result is not specified, then it defaults to "distinct this",
     * which has the effect of returning the elements of the candidates
     * that match the filter.
     */
    public void setResult(String result)
    {
        synchronized (this.paramtab)
        {
            this.resultExpression = result;
            this.compiled = false;
        }
    }

    /**
     * Set the ignoreCache option.
     *
     * The ignoreCache option setting specifies whether the query should execute
     * entirely in the back end, instead of in the cache.
     * @param ignoreCache the setting of the ignoreCache option.
     */
    public void setIgnoreCache(boolean ignoreCache)
    {
        synchronized (this.paramtab)
        {
            this.ignoreCache = ignoreCache;
        }
    }

    /**
     * Get the ignoreCache option setting.
     * @return the ignoreCache option setting.
     * @see #setIgnoreCache
     */
    public boolean getIgnoreCache()
    {
        return ignoreCache;
    }

    /** Sets the prefetchEnabled option.
     *   
     * The prefetchEnabled option specifies whether prefetch of relationship
     * fields should be enabled for this query. The prefetch is enabled by
     * default if such fields are part of DFG. A user needs to explicitely
     * disable prefetch for any particular query if the related instances
     * will not be used in this transaction.
     *
     * @param prefetchEnabled the setting of the prefetchEnabled option.
     */  
    public void setPrefetchEnabled(boolean prefetchEnabled) 
    {
        synchronized (this.paramtab)
        {
            this.prefetchEnabled = prefetchEnabled;
            this.compiled = false;
        }
    }

    /**
     * Verify the elements of the query and provide a hint to the query to
     * prepare and optimize an execution plan.
     */
    public void compile()
    {
        synchronized (this.paramtab)
        {
            if (!this.compiled)
            {
                if (logger.isLoggable(Logger.FINER))
                    logger.finer("LOG_CompileQuery", this); //NOI18N
                // create new query compiler instance
                jqlc = new JQLC();
                // define the query parts including syntax checks
                jqlc.setClass(candidateClass);
                jqlc.declareImports(importDeclarations);
                jqlc.declareParameters(parameterDeclarations);
                jqlc.declareVariables(variableDeclarations);
                jqlc.setOrdering(orderingSpecification);
                jqlc.setResult(resultExpression);
                jqlc.setFilter(filterExpression);
                jqlc.setPrefetchEnabled(prefetchEnabled);

                // semantic analysis
                jqlc.semanticCheck(paramtab);
                this.compiled = true;
            }
        }
    }

    /**
     * Execute the query and return the filtered Collection.
     * @return the filtered Collection.
     * @see #executeWithArray (Object[] parameters)
     */
    public Object execute()
    {
        synchronized (this.paramtab)
        {
            compile();
            ParameterTable params = new ParameterTable(paramtab);
            params.initValueHandling();
            params.checkUnboundParams();
            return doExecute(params);
        }
    }

    /**
     *  Execute the query and return the filtered Collection.
     * @return the filtered Collection.
     * @see #executeWithArray (Object[] parameters)
     * @param p1 the value of the first parameter declared.
     */
    public Object execute(Object p1)
    {
        Object [] params = new Object[1];
        params[0] = p1;
        return executeWithArray(params);
    }

    /**
     * Execute the query and return the filtered Collection.
     * @return the filtered Collection.
     * @see #executeWithArray (Object[] parameters)
     * @param p1 the value of the first parameter declared.
     * @param p2 the value of the second parameter declared.
     */
    public Object execute(Object p1, Object p2)
    {
        Object [] params = new Object[2];
        params[0] = p1;
        params[1] = p2;
        return executeWithArray(params);
    }

    /**
     * Execute the query and return the filtered Collection.
     * @return the filtered Collection.
     * @see #executeWithArray (Object[] parameters)
     * @param p1 the value of the first parameter declared.
     * @param p2 the value of the second parameter declared.
     * @param p3 the value of the third parameter declared.
     */
    public Object execute(Object p1, Object p2, Object p3)
    {
        Object [] params = new Object[3];
        params[0] = p1;
        params[1] = p2;
        params[2] = p3;
        return executeWithArray(params);
    }

    /**
     * Execute the query and return the filtered Collection.
     * @return the filtered Collection.
     * @see #executeWithArray (Object[] parameters)
     * @param parameters the Map containing all of the parameters.
     */
    public Object executeWithMap (Map parameters)
    {
        synchronized (this.paramtab)
        {
            compile();
            ParameterTable params = new ParameterTable(paramtab);
            params.initValueHandling();
            params.setValues(parameters);
            params.checkUnboundParams();
            return doExecute(params);
        }
    }

    /**
     * Execute the query and return the filtered Collection.
     *
     * <P>The execution of the query obtains the values of the parameters and
     * matches them against the declared parameters in order.  The type of
     * the declared parameters must match the type of the passed parameters,
     * except that the passed parameters might need to be unwrapped to get
     * their primitive values.
     *
     * <P>The filter, import, declared parameters, declared variables, and
     * ordering statements are verified for consistency.
     *
     * <P>Each element in the candidate Collection is examined to see that it
     * is assignment compatible to the Class of the query.  It is then evaluated
     * by the boolean expression of the filter.  The element passes the filter
     * if there exist unique values for all variables for which the filter
     * expression evaluates to true.
     * @return the filtered Collection.
     * @param parameters the Object array with all of the parameters.
     */
    public Object executeWithArray (Object[] parameters)
    {
        synchronized (this.paramtab)
        {
            compile();
            ParameterTable params = new ParameterTable(paramtab);
            params.initValueHandling();
            params.setValues(parameters);
            params.checkUnboundParams();
            return doExecute(params);
        }

    }

    /**
     * Get the PersistenceManager associated with this Query.
     *
     * <P>If this Query has no PersistenceManager return null.
     * @return the PersistenceManager associated with this Query.
     */
    public com.sun.jdo.api.persistence.support.PersistenceManager getPersistenceManager()
    {
        return (pm == null)? null : pm.getCurrentWrapper();
    }
    
    /**
     * This method clears the PersistenceManager and the candidateCollection fields. 
     * Then this query instance cannot be executed anymore, but it might be used to 
     * create a new equivalent query instance by passing this query instance to 
     * PersistenceManager newQuery method taking a compiled query.  
     * <p>
     * This method effectively disconnects the PersistenceManager allowing it to be 
     * garbage collected.
     */
    public void clearPersistenceManager()
    {
        this.pm = null;
        this.candidateCollection = null;
    }
    
    /**
     * Internal method called by execute, executeWithArray, executeWithMap.
     * - calls the code generation of the query compiler
     * - flushes updates
     * - executes the RetrieveDesc returned by the code generation
     * - resets the compiler
     */
    private Object doExecute(ParameterTable params)
    {
        Object result = null;
        RetrieveDesc rd = null;

        try
        {
            // We need to make sure that no parallel thread closes the pm =>
            // try to get a shared lock for the pm. Today, the pm impl does
            // not allow to promote a shared lock into a exclusive lock. Thus
            // we need to get an exclusive lock here. Otherwise pm.internalFlush
            // runs into a deadlock, because it tries to get a exclusive lock.
            // This code need to be changed to get a ahared lock as soon as 

            // The next line might result in a NPE, if pm is closed or if the
            // query instance was deserialized. Please note, I cannot check the
            // pm and then get the lock, because the pm might be closed in 
            // parallel. Then subsequent uses of pm in doexecute would fail.
            pm.acquireExclusiveLock();
        }
        catch (NullPointerException npe)
        {
            // NPE means pm is closed or query instance was serialized.
            String key = (createdBySerialization ? 
                          "query.queryimpl.doexecute.notboundtopm" : //NOI18N
                          "query.queryimpl.doexecute.pmclosed"); //NOI18N
            JDOException ex = new JDOQueryException(
                I18NHelper.getMessage(messages, key));
            logger.throwing("query.QueryImpl", "compile", ex); //NOI18N
            throw ex;
        }

        try
        {
            checkCandidates();
            // call the code generation
            rd = jqlc.codeGen(pm, params);
            // flush changes (inserts, updates, deletes) to the datastore
            flush();
            if (logger.isLoggable(Logger.FINER))
                logger.finer("LOG_ExecuteQuery", this, params.getValues()); //NOI18N
            // Note, the RetrieveDesc returned by the code generation is null
            // in the case of a query having a false filter =>
            // do not go to the datastore, but return an emtpy collection
            result = (rd != null) ?  pm.retrieve(rd, params.getValueFetcher()) : new ArrayList();
        }
        finally
        {
            // Note, the following stmt needs to be replaced by 
            // pm.releaseSharedLock, as soon as the pm supports promoting a 
            // shared lock into an exclusive lock.
            pm.releaseExclusiveLock();
        }

        return result;
    }

    /**
     * This method checks a valid candidates setting for this query. 
     */
    private void checkCandidates()
    {
        if ((candidateCollection == null) && (candidateClass != null)) 
        {
            // Set candidateCollection to the extent of the candidate class, if
            // candidateCollection is not specified. Note, the JDO spec defines 
            // subclasses=true as the default, but since this is not supported 
            // right now, I set it to subclasses=false.
            candidateCollection = pm.getExtent(candidateClass, false);
        }
        else {
            jqlc.checkCandidates(candidateClass, candidateCollection);
        }
    }

    /**
     *
     */
    private void flush()
    {
        Transaction tx = pm.currentTransaction();
        // flush updates to the database,
        // - if the is a transaction active and
        // - if transaction is not optimistic
        // - if ignoreCache is false
        if ((tx != null) && tx.isActive() && 
            !tx.getOptimistic() && !this.ignoreCache)
        {
            pm.internalFlush();
        }
    }

    /**  Returns a string representation of the object. */
    public String toString()
    {
        StringBuffer repr = new StringBuffer();
        repr.append("QueryImpl("); //NOI18N
        repr.append("candidateClass: "); //NOI18N
        repr.append(candidateClass);
        if (importDeclarations != null) {
            repr.append(", imports: "); //NOI18N
            repr.append(importDeclarations);
        } 
        if (parameterDeclarations != null) {
            repr.append(", parameters: "); //NOI18N
            repr.append(parameterDeclarations);
        }
        if (variableDeclarations != null) {
            repr.append(", variables: "); //NOI18N
            repr.append(variableDeclarations);
        }
        if (filterExpression != null) {
            repr.append(", filter: "); //NOI18N
            repr.append(filterExpression);
        }
        if (orderingSpecification != null) {
            repr.append(", ordering: "); //NOI18N
            repr.append(orderingSpecification);
        }
        if (resultExpression != null) {
            repr.append(", result: "); //NOI18N
            repr.append(resultExpression);
        }
        repr.append(", prefetchEnabled: "); //NOI18N
        repr.append(prefetchEnabled);
        repr.append(", identity: "); //NOI18N
        repr.append(identity());
        repr.append(")"); //NOI18N
        return repr.toString();
    }

    /** */
    private String identity()
    {
        return "QueryImpl@" + System.identityHashCode(this); //NOI18N
    }
    

    /**
     * Define readObject to initialize the transient field paramtab after deserialization.
     * This object is used for synchronization, thus it cannot be null.
     */
    private void readObject(java.io.ObjectInputStream in)
        throws java.io.IOException, ClassNotFoundException
    {
        in.defaultReadObject();
        this.paramtab = new ParameterTable();
        this.createdBySerialization = true;
    }

}

Other Glassfish examples (source code examples)

Here is a short list of links related to this Glassfish QueryImpl.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.