Open Source Repository

Home /hibernate/hibernate-3.2.7.ga | Repository Home



org/hibernate/engine/QueryParameters.java
//$Id: QueryParameters.java 15240 2008-10-01 19:32:11Z [email protected] $
package org.hibernate.engine;

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

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.hibernate.HibernateException;
import org.hibernate.QueryException;
import org.hibernate.ScrollMode;
import org.hibernate.impl.FilterImpl;
import org.hibernate.dialect.Dialect;
import org.hibernate.hql.classic.ParserHelper;
import org.hibernate.pretty.Printer;
import org.hibernate.transform.ResultTransformer;
import org.hibernate.type.Type;
import org.hibernate.util.ArrayHelper;

/**
 @author Gavin King
 */
public final class QueryParameters {
  private static final Log log = LogFactory.getLog(QueryParameters.class);

  private Type[] positionalParameterTypes;
  private Object[] positionalParameterValues;
  private Map namedParameters;
  private Map lockModes;
  private RowSelection rowSelection;
  private boolean cacheable;
  private String cacheRegion;
  private String comment;
  private ScrollMode scrollMode;
  private Serializable[] collectionKeys;
  private Object optionalObject;
  private String optionalEntityName;
  private Serializable optionalId;
  private boolean readOnly;
  private boolean callable = false;
  private boolean autodiscovertypes = false;
  private boolean isNaturalKeyLookup;

  private final ResultTransformer resultTransformer; // why is all others non final ?

  private String processedSQL;
  private Type[] processedPositionalParameterTypes;
  private Object[] processedPositionalParameterValues;

  public QueryParameters() {
    thisArrayHelper.EMPTY_TYPE_ARRAY, ArrayHelper.EMPTY_OBJECT_ARRAY );
  }

  public QueryParameters(Type type, Object value) {
    thisnew Type[] { type }new Object[] { value } );
  }

  public QueryParameters(
      final Type[] positionalParameterTypes,
      final Object[] postionalParameterValues,
      final Object optionalObject,
      final String optionalEntityName,
      final Serializable optionalObjectId) {
    thispositionalParameterTypes, postionalParameterValues );
    this.optionalObject = optionalObject;
    this.optionalId = optionalObjectId;
    this.optionalEntityName = optionalEntityName;

  }

  public QueryParameters(
      final Type[] positionalParameterTypes,
      final Object[] postionalParameterValues) {
    thispositionalParameterTypes, postionalParameterValues, null, null, false, null, null, false, null );
  }

  public QueryParameters(
      final Type[] positionalParameterTypes,
      final Object[] postionalParameterValues,
      final Serializable[] collectionKeys) {
    thispositionalParameterTypes, postionalParameterValues, null, collectionKeys );
  }

  public QueryParameters(
      final Type[] positionalParameterTypes,
      final Object[] postionalParameterValues,
      final Map namedParameters,
      final Serializable[] collectionKeys) {
    this(
        positionalParameterTypes,
        postionalParameterValues,
        namedParameters,
        null,
        null,
        false,
        false,
        null,
        null,
        collectionKeys,
        null
    );
  }

  public QueryParameters(
      final Type[] positionalParameterTypes,
      final Object[] positionalParameterValues,
      final Map lockModes,
      final RowSelection rowSelection,
      final boolean cacheable,
      final String cacheRegion,
      //final boolean forceCacheRefresh,
      final String comment,
      final boolean isLookupByNaturalKey,
      final ResultTransformer transformer) {
    this(
        positionalParameterTypes,
        positionalParameterValues,
        null,
        lockModes,
        rowSelection,
        false,
        cacheable,
        cacheRegion,
        comment,
        null,
        transformer
    );
    isNaturalKeyLookup = isLookupByNaturalKey;
  }

  public QueryParameters(
      final Type[] positionalParameterTypes,
      final Object[] positionalParameterValues,
      final Map namedParameters,
      final Map lockModes,
      final RowSelection rowSelection,
      final boolean readOnly,
      final boolean cacheable,
      final String cacheRegion,
      //final boolean forceCacheRefresh,
      final String comment,
      final Serializable[] collectionKeys,
      ResultTransformer transformer) {
    this.positionalParameterTypes = positionalParameterTypes;
    this.positionalParameterValues = positionalParameterValues;
    this.namedParameters = namedParameters;
    this.lockModes = lockModes;
    this.rowSelection = rowSelection;
    this.cacheable = cacheable;
    this.cacheRegion = cacheRegion;
    //this.forceCacheRefresh = forceCacheRefresh;
    this.comment = comment;
    this.collectionKeys = collectionKeys;
    this.readOnly = readOnly;
    this.resultTransformer = transformer;
  }

  public QueryParameters(
      final Type[] positionalParameterTypes,
      final Object[] positionalParameterValues,
      final Map namedParameters,
      final Map lockModes,
      final RowSelection rowSelection,
      final boolean readOnly,
      final boolean cacheable,
      final String cacheRegion,
      //final boolean forceCacheRefresh,
      final String comment,
      final Serializable[] collectionKeys,
      final Object optionalObject,
      final String optionalEntityName,
      final Serializable optionalId,
      final ResultTransformer transformer) {
    this(
        positionalParameterTypes,
        positionalParameterValues,
        namedParameters,
        lockModes,
        rowSelection,
        readOnly,
        cacheable,
        cacheRegion,
        comment,
        collectionKeys,
        transformer
    );
    this.optionalEntityName = optionalEntityName;
    this.optionalId = optionalId;
    this.optionalObject = optionalObject;
  }

  public boolean hasRowSelection() {
    return rowSelection != null;
  }

  public Map getNamedParameters() {
    return namedParameters;
  }

  public Type[] getPositionalParameterTypes() {
    return positionalParameterTypes;
  }

  public Object[] getPositionalParameterValues() {
    return positionalParameterValues;
  }

  public RowSelection getRowSelection() {
    return rowSelection;
  }

  public ResultTransformer getResultTransformer() {
    return resultTransformer;
  }

  public void setNamedParameters(Map map) {
    namedParameters = map;
  }

  public void setPositionalParameterTypes(Type[] types) {
    positionalParameterTypes = types;
  }

  public void setPositionalParameterValues(Object[] objects) {
    positionalParameterValues = objects;
  }

  public void setRowSelection(RowSelection selection) {
    rowSelection = selection;
  }

  public Map getLockModes() {
    return lockModes;
  }

  public void setLockModes(Map map) {
    lockModes = map;
  }

  public void traceParameters(SessionFactoryImplementor factorythrows HibernateException {
    Printer print = new Printerfactory );
    if positionalParameterValues.length != ) {
      log.trace(
          "parameters: " +
              print.toStringpositionalParameterTypes, positionalParameterValues )
      );
    }
    if namedParameters != null ) {
      log.trace"named parameters: " + print.toStringnamedParameters ) );
    }
  }

  public boolean isCacheable() {
    return cacheable;
  }

  public void setCacheable(boolean b) {
    cacheable = b;
  }

  public String getCacheRegion() {
    return cacheRegion;
  }

  public void setCacheRegion(String cacheRegion) {
    this.cacheRegion = cacheRegion;
  }

  public void validateParameters() throws QueryException {
    int types = positionalParameterTypes == null : positionalParameterTypes.length;
    int values = positionalParameterValues == null : positionalParameterValues.length;
    if types != values ) {
      throw new QueryException(
          "Number of positional parameter types:" + types +
              " does not match number of positional parameters: " + values
      );
    }
  }

  public String getComment() {
    return comment;
  }

  public void setComment(String comment) {
    this.comment = comment;
  }

  public ScrollMode getScrollMode() {
    return scrollMode;
  }

  public void setScrollMode(ScrollMode scrollMode) {
    this.scrollMode = scrollMode;
  }

  public Serializable[] getCollectionKeys() {
    return collectionKeys;
  }

  public void setCollectionKeys(Serializable[] collectionKeys) {
    this.collectionKeys = collectionKeys;
  }

  public String getOptionalEntityName() {
    return optionalEntityName;
  }

  public void setOptionalEntityName(String optionalEntityName) {
    this.optionalEntityName = optionalEntityName;
  }

  public Serializable getOptionalId() {
    return optionalId;
  }

  public void setOptionalId(Serializable optionalId) {
    this.optionalId = optionalId;
  }

  public Object getOptionalObject() {
    return optionalObject;
  }

  public void setOptionalObject(Object optionalObject) {
    this.optionalObject = optionalObject;
  }

  public boolean isReadOnly() {
    return readOnly;
  }

  public void setReadOnly(boolean readOnly) {
    this.readOnly = readOnly;
  }

  public void setCallable(boolean callable) {
    this.callable = callable;
  }

  public boolean isCallable() {
    return callable;
  }

  public boolean hasAutoDiscoverScalarTypes() {
    return autodiscovertypes;
  }

  public void processFilters(String sql, SessionImplementor session) {
    processFilterssql, session.getEnabledFilters(), session.getFactory() );
  }

  public void processFilters(String sql, Map filters, SessionFactoryImplementor factory) {
    if filters.size() == || sql.indexOfParserHelper.HQL_VARIABLE_PREFIX ) {
      // HELLA IMPORTANT OPTIMIZATION!!!
      processedPositionalParameterValues = getPositionalParameterValues();
      processedPositionalParameterTypes = getPositionalParameterTypes();
      processedSQL = sql;
    }
    else {
      final Dialect dialect = factory.getDialect();
      String symbols = new StringBuffer().appendParserHelper.HQL_SEPARATORS )
          .appenddialect.openQuote() )
          .appenddialect.closeQuote() )
          .toString();
      StringTokenizer tokens = new StringTokenizersql, symbols, true );
      StringBuffer result = new StringBuffer();

      List parameters = new ArrayList();
      List parameterTypes = new ArrayList();

      int positionalIndex = 0;
      while tokens.hasMoreTokens() ) {
        final String token = tokens.nextToken();
        if token.startsWithParserHelper.HQL_VARIABLE_PREFIX ) ) {
          final String filterParameterName = token.substring);
          final String[] parts = parseFilterParameterNamefilterParameterName );
          final FilterImpl filter = FilterImpl filters.getparts[0] );
          final Object value = filter.getParameterparts[1] );
          final Type type = filter.getFilterDefinition().getParameterTypeparts[1] );
          if value != null && Collection.class.isAssignableFromvalue.getClass() ) ) {
            Iterator itr = ( ( Collection value ).iterator();
            while itr.hasNext() ) {
              Object elementValue = itr.next();
              result.append'?' );
              parameters.addelementValue );
              parameterTypes.addtype );
              if itr.hasNext() ) {
                result.append", " );
              }
            }
          }
          else {
            result.append'?' );
            parameters.addvalue );
            parameterTypes.addtype );
          }
        }
        else {
          if "?".equalstoken && positionalIndex < getPositionalParameterValues().length ) {
            parameters.addgetPositionalParameterValues()[positionalIndex] );
            parameterTypes.addgetPositionalParameterTypes()[positionalIndex] );
            positionalIndex++;
          }
          result.appendtoken );
        }
      }
      processedPositionalParameterValues = parameters.toArray();
      processedPositionalParameterTypes = Type[] ) parameterTypes.toArraynew Type[parameterTypes.size()] );
      processedSQL = result.toString();
    }
  }

  public String getFilteredSQL() {
    return processedSQL;
  }

  public Object[] getFilteredPositionalParameterValues() {
    return processedPositionalParameterValues;
  }

  public Type[] getFilteredPositionalParameterTypes() {
    return processedPositionalParameterTypes;
  }

  public boolean isNaturalKeyLookup() {
    return isNaturalKeyLookup;
  }

  public void setNaturalKeyLookup(boolean isNaturalKeyLookup) {
    this.isNaturalKeyLookup = isNaturalKeyLookup;
  }

  public void setAutoDiscoverScalarTypes(boolean autodiscovertypes) {
    this.autodiscovertypes = autodiscovertypes;
  }

  public QueryParameters createCopyUsing(RowSelection selection) {
    QueryParameters copy = new QueryParameters(
        this.positionalParameterTypes,
        this.positionalParameterValues,
        this.namedParameters,
        this.lockModes,
        selection,
        this.readOnly,
        this.cacheable,
        this.cacheRegion,
        this.comment,
        this.collectionKeys,
        this.optionalObject,
        this.optionalEntityName,
        this.optionalId,
        this.resultTransformer
    );
    copy.processedSQL = this.processedSQL;
    copy.processedPositionalParameterTypes = this.processedPositionalParameterTypes;
    copy.processedPositionalParameterValues = this.processedPositionalParameterValues;
    return copy;
  }

  public static String[] parseFilterParameterName(String filterParameterName) {
    int dot = filterParameterName.indexOf'.' );
    if dot <= ) {
      throw new IllegalArgumentException"Invalid filter-parameter name format" );
    }
    String filterName = filterParameterName.substring0, dot );
    String parameterName = filterParameterName.substringdot + );
    return new String[] { filterName, parameterName };
  }
}