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

Glassfish example source code file (ParameterTable.java)

This example Glassfish source code file (ParameterTable.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

arraylist, jdoqueryexception, list, list, noi18n, noi18n, object, object, parameterinfo, parametertable, string, string, type, unbound, util

The Glassfish ParameterTable.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.
 */

/*
 * ParameterTable.java
 *
 * Created on April 12, 2000
 */

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

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.ResourceBundle;

import com.sun.jdo.api.persistence.support.JDOQueryException;
import com.sun.jdo.api.persistence.support.JDOFatalInternalException;
import com.sun.jdo.spi.persistence.support.sqlstore.query.util.type.Type;
import com.sun.jdo.spi.persistence.support.sqlstore.query.util.type.StringType;
import com.sun.jdo.spi.persistence.support.sqlstore.query.util.type.PrimitiveType;
import com.sun.jdo.spi.persistence.support.sqlstore.query.util.type.WrapperClassType;
import com.sun.jdo.spi.persistence.support.sqlstore.query.util.type.MathType;
import com.sun.jdo.spi.persistence.support.sqlstore.query.util.type.DateType;

import org.glassfish.persistence.common.I18NHelper;
import com.sun.jdo.spi.persistence.support.sqlstore.ValueFetcher;
import com.sun.jdo.spi.persistence.utility.JavaTypeHelper;
import com.sun.jdo.spi.persistence.utility.ParameterInfo;

/**
 * The query parameter table
 *
 * @author  Michael Bouschen
 * @version 0.1
 */
public class ParameterTable
{
    /** Query parameter names */
    List names = null;

    /** Query parameter types */
    List types = null;

    /** Query Parameter values */
    transient List values = null;
    
    /** null key */
    private static final String NULL_ = "null"; //NOI18N

    /** true key */
    private static final String TRUE_ = "true"; //NOI18N

    /** false key */
    private static final String FALSE_ = "false"; //NOI18N

    /** other key */
    private static final String OTHER_ = "other"; //NOI18N

    /** noparams key */
    private static final String NOPARAMS_ = "noparams"; //NOI18N
    
    /** key parameter separator */
    private static final char PARAMKEY_SEPARATOR = '/';

    /**
     * Objects of this class represent the value for an unbound query parameter
     */
    static class Unbound { }

    /**
     * Singleton representing the value for an unbound query parameter
     */
    static final Unbound unbound = new Unbound();

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

    /**
     *
     */
    public ParameterTable()
    {}

    /**
     * Copy constructor.
     * @param other the ParameterTable to be copied
     */
    public ParameterTable(ParameterTable other)
    {
        this.names = other.names;
        this.types = other.types;
        this.values = other.values;
    }

    /**
     * Adds a new query parameter with the specified type to the query 
     * parameter table. 
     */
    public void add(String name, Type type)
    {
        names.add(name);
        types.add(type);
    }

    /**
     * Initializes the parameter declarations (names and types list). 
     * Needs to be called prior to any add call.
     */
    public void init()
    {
        this.names = new ArrayList();
        this.types = new ArrayList();
    }

    /**
     * Initializes the parameter values. This methods sets the values for all 
     * declared parameters to unbound.
     */
    public void initValueHandling()
    {
        values = new ArrayList(names.size());
        final int size = names.size();
        for (int i = 0; i < size; i++) {
            values.add(unbound);
        }
    }
    
    /**
     * Check actual query parameters specified as array and return the
     * ValueFetcher for the inputparameters.
     * @param actualParams
     */
    public void setValues(Object[] actualParams)
    {
        if (actualParams != null)
        {
            for (int i = 0; i < actualParams.length; i++)
            {
                Object value = actualParams[i];
                defineValueByIndex(i, value);
            }
        }
    }

    /**
     * Checks whether all parameters have an actual value.
     */
    public void checkUnboundParams()
    {
        final int size = values.size();
        for (int i = 0; i < size; i++)
        {
            if (values.get(i) == unbound)
            {
                throw new JDOQueryException(
                    I18NHelper.getMessage(messages, "jqlc.parametertable.checkunboundparams.unboundparam",  //NOI18N
                                          names.get(i)));
            }
        }
    }

    /**
     * Check actual query parameters specified as map and return the
     * ValueFetcher for the inputparameters.
     * @param actualParams
     */
    public void setValues(Map actualParams)
    {
        if (actualParams != null)
        {
            for (Iterator i = actualParams.entrySet().iterator(); i.hasNext();)
            {
                Map.Entry actualParam = (Map.Entry)i.next();
                String name = (String)actualParam.getKey();
                Object value = actualParam.getValue();
                defineValueByName(name, value);
            }
        }
    }

    /**
     * Returns the value of the parameter with the specified name.
     */
    public Object getValueByName(String name)
    {
        int index = names.indexOf(name);
        if (index == -1)
            throw new JDOFatalInternalException(I18NHelper.getMessage(
                messages,
                "jqlc.parametertable.getvaluebyname.undefined", //NOI18N
                name));

        return getValueByIndex(index);
    }

    /**
     * Returns the value of the parameter with the specified index.
     */
    public Object getValueByIndex(int index)
    {
        if ((index < 0) || (index >= values.size()))
            throw new JDOFatalInternalException(I18NHelper.getMessage(
                messages,
                "jqlc.parametertable.getvaluebyindex.wrongindex", //NOI18N
                String.valueOf(index)));

        return values.get(index);
    }

    /** Returns the list of parameter values. */
    public List getValues()
    {
        return values;
    }

    /**
     * Wraps the actual parameter array into a ValueFetcher instnace.
     * @return Instance of ValueFetcher
     */
    public ValueFetcher getValueFetcher()
    {
        return new QueryValueFetcher(values.toArray(new Object[values.size()]));
    }

    /**
     * Calculates and returns the key for the RetrieveDesc cache based,
     * on the actual parameter values.
     * A <code>null return means, the RetrieveDesc should not be
     * cached. 
     * Note, this method needs to be in sync with method inline.
     */
    public String getKeyForRetrieveDescCache()
    {
        StringBuffer key = new StringBuffer();
        final int size = values.size();
        for (int i = 0; i < size; i++) {
            // Do not cache RetrieveDesc if the parameter type is pc class
            // or java.lang.Object => return null
            if (isInlineType(types.get(i)))
                return null;

            Object item = values.get(i);
            if (item == null) {
                key.append(ParameterTable.NULL_);
            }
            else if (item instanceof Boolean) {
                if (((Boolean)item).booleanValue()) {
                    key.append(ParameterTable.TRUE_);
                } else {
                    key.append(ParameterTable.FALSE_);
                }
            } else {
                key.append(ParameterTable.OTHER_);
            }
            key.append(ParameterTable.PARAMKEY_SEPARATOR);
        }

        // If the key is 0 in length, the Query does not use any parameters.
        // But nevertheless we want cache the RD, thus we return a key for
        // no-parameter-queries
        if (key.length() == 0) {
            key.append(ParameterTable.NOPARAMS_);
        }

        return key.toString();
    }

    /**
     * Returns true if the parameter with the specified index should be inlined
     * by the optimizer.
     * Note, this method needs to be in sync with method
     * getKeyForRetrieveDescCache. 
     * @param paramName the parameter
     * @return true if the specified parameter should be inlined.
     */
    public boolean inline(String paramName)
    {
        int index = names.indexOf(paramName);
        Object value = values.get(index);

        if (isInlineType(types.get(index))) return true;

        if (value == null) return true;

        if (value instanceof Boolean) return true;

        return false;
    }

    /**
     * Returns <code>true if the specified parameter denotes a type
     * whose values should be inlined by the query optimizer if a query 
     * parameter s is declared with such a type.
     */
    private boolean isInlineType(Object type)
    { 
        // Check for types that are supported by JDBC, such that the
        // parameter can be mapped to a JDBC parameter, these are:
        // - String
        // - primitive types (int, float, etc.)
        // - wrapper class types (Integer, Float, etc.)
        // - BigDecimal, BigInteger
        // - Date class types
        // All other types including pc classes, java.lang.Object, etc.
        // should be inlined.
        if ((type instanceof StringType) ||
            (type instanceof PrimitiveType) ||
            (type instanceof WrapperClassType) ||
            (type instanceof MathType) ||
            (type instanceof DateType))
            return false;
        return true;
    }

    /**
     * Returns the parameter index for the specified parameter name.
     * @deprecated
     */
    public Integer getIndexForParamName(String paramName)
    {
        return new Integer(names.indexOf(paramName));
    }

    /**
     * Returns the parameter info for the specified parameter name.
     * @param paramName
     * @return corresponding parameterInfo
     */
    public ParameterInfo getParameterInfoForParamName(String paramName)
    {
        return getParameterInfoForParamName(paramName, null);
    }

    /**
     * Returns the parameter info for the specified parameter name
     * and associated field.
     * If the associated field is not known, then null is used as
     * input parameter.
     * @param paramName
     * @param associatedField
     * @return corresponding parameterInfo
     */
    public ParameterInfo getParameterInfoForParamName(String paramName,
            String associatedField)
    {
        int index = names.indexOf(paramName);
        Type type = (Type)types.get(index);
        return new ParameterInfo(index, type.getEnumType(), associatedField);
    }

    /**
     *
     */
    private void defineValueByName(String name, Object value)
    {
        int index = names.indexOf(name);
        if (index == -1)
            throw new JDOQueryException(
                I18NHelper.getMessage(messages, "jqlc.parametertable.definevaluebyname.undefinedparam", name)); //NOI18N
        defineValueByIndex(index, value);
    }

    /**
     *
     */
    private void defineValueByIndex(int index, Object value)
    {
        // index < 0 => implementation error
        if (index < 0)
            throw new JDOFatalInternalException(I18NHelper.getMessage(
                messages,
                "jqlc.parametertable.definevaluebyindex.wrongindex", //NOI18N
                String.valueOf(index)));          

        // index > type.size => too many actual parameters
        if (index >= types.size())
            throw new JDOQueryException(
                I18NHelper.getMessage(messages, "jqlc.parametertable.definevaluebyindex.wrongnumberofargs")); //NOI18N

        // check type compatibility of actual and formal parameter
        Class formalType = ((Type)types.get(index)).getJavaClass();
        if (!isCompatibleValue(formalType, value))
        {
            String actualTypeName = ((value==null) ? "<type of null>" : value.getClass().getName());
            throw new JDOQueryException(
                I18NHelper.getMessage(messages, "jqlc.parametertable.definevaluebyindex.typemismatch",  //NOI18N
                                      actualTypeName, formalType.getName()));
        }

        // everything is ok => set the actual parameters's value
        values.set(index, value);
    }

    /**
     * Checks whether the type of the specified value is compatible with the
     * specified formal type.
     * @param name the formal type.
     * @param the value to be checked
     * @return <code>true if the type of the value is compatible with the
     * formal type; <code>false otherwise.
     */
    private boolean isCompatibleValue(Class formalType, Object value)
    {
        boolean isCompatible = true;

        // handle value == null
        if (value == null) {
            isCompatible = !formalType.isPrimitive();
        }
        else {
            Class actualType = value.getClass();
            if (formalType.isPrimitive())
                formalType = JavaTypeHelper.getWrapperClass(formalType);

            isCompatible = formalType.isAssignableFrom(actualType);
        }
        return isCompatible;
    }

}

Other Glassfish examples (source code examples)

Here is a short list of links related to this Glassfish ParameterTable.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.