FileDocCategorySizeDatePackage
ParameterTable.javaAPI DocGlassfish v2 API15082Fri May 04 22:35:06 BST 2007com.sun.jdo.spi.persistence.support.sqlstore.query.jqlc

ParameterTable

public class ParameterTable extends Object
The query parameter table
author
Michael Bouschen
version
0.1

Fields Summary
List
names
Query parameter names
List
types
Query parameter types
transient List
values
Query Parameter values
private static final String
NULL_
null key
private static final String
TRUE_
true key
private static final String
FALSE_
false key
private static final String
OTHER_
other key
private static final String
NOPARAMS_
noparams key
private static final char
PARAMKEY_SEPARATOR
key parameter separator
static final Unbound
unbound
Singleton representing the value for an unbound query parameter
protected static final ResourceBundle
messages
I18N support
Constructors Summary
public ParameterTable()


         
     
    
public ParameterTable(ParameterTable other)
Copy constructor.

param
other the ParameterTable to be copied

        this.names = other.names;
        this.types = other.types;
        this.values = other.values;
    
Methods Summary
public voidadd(java.lang.String name, com.sun.jdo.spi.persistence.support.sqlstore.query.util.type.Type type)
Adds a new query parameter with the specified type to the query parameter table.

        names.add(name);
        types.add(type);
    
public voidcheckUnboundParams()
Checks whether all parameters have an actual value.

        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)));
            }
        }
    
private voiddefineValueByIndex(int index, java.lang.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);
    
private voiddefineValueByName(java.lang.String name, java.lang.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);
    
public java.lang.IntegergetIndexForParamName(java.lang.String paramName)
Returns the parameter index for the specified parameter name.

deprecated

        return new Integer(names.indexOf(paramName));
    
public java.lang.StringgetKeyForRetrieveDescCache()
Calculates and returns the key for the RetrieveDesc cache based, on the actual parameter values. A null return means, the RetrieveDesc should not be cached. Note, this method needs to be in sync with method inline.

        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();
    
public com.sun.jdo.spi.persistence.utility.ParameterInfogetParameterInfoForParamName(java.lang.String paramName)
Returns the parameter info for the specified parameter name.

param
paramName
return
corresponding parameterInfo

        return getParameterInfoForParamName(paramName, null);
    
public com.sun.jdo.spi.persistence.utility.ParameterInfogetParameterInfoForParamName(java.lang.String paramName, java.lang.String associatedField)
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

        int index = names.indexOf(paramName);
        Type type = (Type)types.get(index);
        return new ParameterInfo(index, type.getEnumType(), associatedField);
    
public java.lang.ObjectgetValueByIndex(int index)
Returns the value of the parameter with the specified 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);
    
public java.lang.ObjectgetValueByName(java.lang.String name)
Returns the value of the parameter with the specified name.

        int index = names.indexOf(name);
        if (index == -1)
            throw new JDOFatalInternalException(I18NHelper.getMessage(
                messages,
                "jqlc.parametertable.getvaluebyname.undefined", //NOI18N
                name));

        return getValueByIndex(index);
    
public com.sun.jdo.spi.persistence.support.sqlstore.ValueFetchergetValueFetcher()
Wraps the actual parameter array into a ValueFetcher instnace.

return

        return new QueryValueFetcher(values.toArray(new Object[values.size()]));
    
public java.util.ListgetValues()
Returns the list of parameter values.

        return values;
    
public voidinit()
Initializes the parameter declarations (names and types list). Needs to be called prior to any add call.

        this.names = new ArrayList();
        this.types = new ArrayList();
    
public voidinitValueHandling()
Initializes the parameter values. This methods sets the values for all declared parameters to unbound.

        values = new ArrayList(names.size());
        final int size = names.size();
        for (int i = 0; i < size; i++) {
            values.add(unbound);
        }
    
public booleaninline(java.lang.String paramName)
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.

        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;
    
private booleanisCompatibleValue(java.lang.Class formalType, java.lang.Object 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
true if the type of the value is compatible with the formal type; false otherwise.

        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;
    
private booleanisInlineType(java.lang.Object type)
Returns 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.

 
        // 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;
    
public voidsetValues(java.lang.Object[] actualParams)
Check actual query parameters specified as array and return the ValueFetcher for the inputparameters.

param
actualParams
return
the parameters wrapped in the ValueFetcher

        if (actualParams != null)
        {
            for (int i = 0; i < actualParams.length; i++)
            {
                Object value = actualParams[i];
                defineValueByIndex(i, value);
            }
        }
    
public voidsetValues(java.util.Map actualParams)
Check actual query parameters specified as map and return the ValueFetcher for the inputparameters.

param
actualParams
return
the parameters wrapped in the ValueFetcher

        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);
            }
        }