private String getWholeAssociationPath(CriteriaImpl.Subcriteria subcriteria) {
    String path = subcriteria.getPath();

    // some messy, complex stuff here, since createCriteria() can take an
    // aliased path, or a path rooted at the creating criteria instance
    Criteria parent = null;
    if (path.indexOf('.') > 0) {
      // if it is a compound path
      String testAlias = StringHelper.root(path);
      if (!testAlias.equals(subcriteria.getAlias())) {
        // and the qualifier is not the alias of this criteria
        //      -> check to see if we belong to some criteria other
        //          than the one that created us
        parent = aliasCriteriaMap.get(testAlias);
      }
    }
    if (parent == null) {
      // otherwise assume the parent is the the criteria that created us
      parent = subcriteria.getParent();
    } else {
      path = StringHelper.unroot(path);
    }

    if (parent.equals(rootCriteria)) {
      // if its the root criteria, we are done
      return path;
    } else {
      // otherwise, recurse
      return getWholeAssociationPath((CriteriaImpl.Subcriteria) parent) + '.' + path;
    }
  }
  public QueryParameters getQueryParameters() {
    LockOptions lockOptions = new LockOptions();
    RowSelection selection = new RowSelection();
    selection.setFirstRow(rootCriteria.getFirstResult());
    selection.setMaxRows(rootCriteria.getMaxResults());
    selection.setTimeout(rootCriteria.getTimeout());
    selection.setFetchSize(rootCriteria.getFetchSize());
    final Map<String, LockMode> lockModeMap = rootCriteria.getLockModes();
    for (final String key : lockModeMap.keySet()) {
      final Criteria subcriteria = getAliasedCriteria(key);
      lockOptions.setAliasSpecificLockMode(getSQLAlias(subcriteria), lockModeMap.get(key));
    }
    final List<Object> values = new ArrayList<Object>();
    final List<Type> types = new ArrayList<Type>();
    final Iterator<CriteriaImpl.Subcriteria> subcriteriaIterator =
        rootCriteria.iterateSubcriteria();
    while (subcriteriaIterator.hasNext()) {
      CriteriaImpl.Subcriteria subcriteria = subcriteriaIterator.next();
      LockMode lm = subcriteria.getLockMode();
      if (lm != null) {
        lockOptions.setAliasSpecificLockMode(getSQLAlias(subcriteria), lm);
      }
      if (subcriteria.getWithClause() != null) {
        TypedValue[] tv = subcriteria.getWithClause().getTypedValues(subcriteria, this);
        for (TypedValue aTv : tv) {
          values.add(aTv.getValue());
          types.add(aTv.getType());
        }
      }
    }

    // Type and value gathering for the WHERE clause needs to come AFTER lock mode gathering,
    // because the lock mode gathering loop now contains join clauses which can contain
    // parameter bindings (as in the HQL WITH clause).
    Iterator<CriteriaImpl.CriterionEntry> iter = rootCriteria.iterateExpressionEntries();
    while (iter.hasNext()) {
      CriteriaImpl.CriterionEntry ce = iter.next();
      TypedValue[] tv = ce.getCriterion().getTypedValues(ce.getCriteria(), this);
      for (TypedValue aTv : tv) {
        values.add(aTv.getValue());
        types.add(aTv.getType());
      }
    }

    Object[] valueArray = values.toArray();
    Type[] typeArray = ArrayHelper.toTypeArray(types);
    return new QueryParameters(
        typeArray,
        valueArray,
        lockOptions,
        selection,
        rootCriteria.isReadOnlyInitialized(),
        (rootCriteria.isReadOnlyInitialized() && rootCriteria.isReadOnly()),
        rootCriteria.getCacheable(),
        rootCriteria.getCacheRegion(),
        rootCriteria.getComment(),
        rootCriteria.getQueryHints(),
        rootCriteria.isLookupByNaturalKey(),
        rootCriteria.getResultTransformer());
  }
 private void createAssociationPathCriteriaMap() {
   final Iterator<CriteriaImpl.Subcriteria> iter = rootCriteria.iterateSubcriteria();
   while (iter.hasNext()) {
     CriteriaImpl.Subcriteria crit = iter.next();
     String wholeAssociationPath = getWholeAssociationPath(crit);
     Object old = associationPathCriteriaMap.put(wholeAssociationPath, crit);
     if (old != null) {
       throw new QueryException("duplicate association path: " + wholeAssociationPath);
     }
     JoinType joinType = crit.getJoinType();
     old = associationPathJoinTypesMap.put(wholeAssociationPath, joinType);
     if (old != null) {
       // TODO : not so sure this is needed...
       throw new QueryException("duplicate association path: " + wholeAssociationPath);
     }
     if (crit.getWithClause() != null) {
       this.withClauseMap.put(wholeAssociationPath, crit.getWithClause());
     }
   }
 }
 public boolean hasRestriction(String path) {
   final CriteriaImpl.Subcriteria crit = (CriteriaImpl.Subcriteria) getCriteria(path);
   return crit != null && crit.hasRestriction();
 }