001: package org.hibernate.hql.ast;
002:
003: import org.hibernate.hql.ParameterTranslations;
004: import org.hibernate.type.Type;
005: import org.hibernate.param.ParameterSpecification;
006: import org.hibernate.param.PositionalParameterSpecification;
007: import org.hibernate.param.NamedParameterSpecification;
008: import org.hibernate.util.ArrayHelper;
009:
010: import java.util.Map;
011: import java.util.Set;
012: import java.util.List;
013: import java.util.ArrayList;
014: import java.util.HashMap;
015: import java.util.Iterator;
016: import java.io.Serializable;
017:
018: /**
019: * Defines the information available for parameters encountered during
020: * query translation through the antlr-based parser.
021: *
022: * @author Steve Ebersole
023: */
024: public class ParameterTranslationsImpl implements ParameterTranslations {
025:
026: private final Map namedParameters;
027: private final ParameterInfo[] ordinalParameters;
028:
029: public boolean supportsOrdinalParameterMetadata() {
030: return true;
031: }
032:
033: public int getOrdinalParameterCount() {
034: return ordinalParameters.length;
035: }
036:
037: public ParameterInfo getOrdinalParameterInfo(int ordinalPosition) {
038: // remember that ordinal parameters numbers are 1-based!!!
039: return ordinalParameters[ordinalPosition - 1];
040: }
041:
042: public int getOrdinalParameterSqlLocation(int ordinalPosition) {
043: return getOrdinalParameterInfo(ordinalPosition)
044: .getSqlLocations()[0];
045: }
046:
047: public Type getOrdinalParameterExpectedType(int ordinalPosition) {
048: return getOrdinalParameterInfo(ordinalPosition)
049: .getExpectedType();
050: }
051:
052: public Set getNamedParameterNames() {
053: return namedParameters.keySet();
054: }
055:
056: public ParameterInfo getNamedParameterInfo(String name) {
057: return (ParameterInfo) namedParameters.get(name);
058: }
059:
060: public int[] getNamedParameterSqlLocations(String name) {
061: return getNamedParameterInfo(name).getSqlLocations();
062: }
063:
064: public Type getNamedParameterExpectedType(String name) {
065: return getNamedParameterInfo(name).getExpectedType();
066: }
067:
068: /**
069: * Constructs a parameter metadata object given a list of parameter
070: * specifications.
071: * </p>
072: * Note: the order in the incoming list denotes the parameter's
073: * psudeo-position within the resulting sql statement.
074: *
075: * @param parameterSpecifications
076: */
077: public ParameterTranslationsImpl(List parameterSpecifications) {
078:
079: class NamedParamTempHolder {
080: String name;
081: Type type;
082: List positions = new ArrayList();
083: }
084:
085: int size = parameterSpecifications.size();
086: List ordinalParameterList = new ArrayList();
087: Map namedParameterMap = new HashMap();
088: for (int i = 0; i < size; i++) {
089: final ParameterSpecification spec = (ParameterSpecification) parameterSpecifications
090: .get(i);
091: if (PositionalParameterSpecification.class
092: .isAssignableFrom(spec.getClass())) {
093: PositionalParameterSpecification ordinalSpec = (PositionalParameterSpecification) spec;
094: ordinalParameterList.add(new ParameterInfo(i,
095: ordinalSpec.getExpectedType()));
096: } else if (NamedParameterSpecification.class
097: .isAssignableFrom(spec.getClass())) {
098: NamedParameterSpecification namedSpec = (NamedParameterSpecification) spec;
099: NamedParamTempHolder paramHolder = (NamedParamTempHolder) namedParameterMap
100: .get(namedSpec.getName());
101: if (paramHolder == null) {
102: paramHolder = new NamedParamTempHolder();
103: paramHolder.name = namedSpec.getName();
104: paramHolder.type = namedSpec.getExpectedType();
105: namedParameterMap.put(namedSpec.getName(),
106: paramHolder);
107: }
108: paramHolder.positions.add(new Integer(i));
109: } else {
110: // don't care about other param types here, just those explicitly user-defined...
111: }
112: }
113:
114: ordinalParameters = (ParameterInfo[]) ordinalParameterList
115: .toArray(new ParameterInfo[ordinalParameterList.size()]);
116:
117: if (namedParameterMap.isEmpty()) {
118: namedParameters = java.util.Collections.EMPTY_MAP;
119: } else {
120: Map namedParametersBacking = new HashMap(namedParameterMap
121: .size());
122: Iterator itr = namedParameterMap.values().iterator();
123: while (itr.hasNext()) {
124: final NamedParamTempHolder holder = (NamedParamTempHolder) itr
125: .next();
126: namedParametersBacking.put(holder.name,
127: new ParameterInfo(ArrayHelper
128: .toIntArray(holder.positions),
129: holder.type));
130: }
131: namedParameters = java.util.Collections
132: .unmodifiableMap(namedParametersBacking);
133: }
134: }
135:
136: public static class ParameterInfo implements Serializable {
137: private final int[] sqlLocations;
138: private final Type expectedType;
139:
140: public ParameterInfo(int[] sqlPositions, Type expectedType) {
141: this .sqlLocations = sqlPositions;
142: this .expectedType = expectedType;
143: }
144:
145: public ParameterInfo(int sqlPosition, Type expectedType) {
146: this .sqlLocations = new int[] { sqlPosition };
147: this .expectedType = expectedType;
148: }
149:
150: public int[] getSqlLocations() {
151: return sqlLocations;
152: }
153:
154: public Type getExpectedType() {
155: return expectedType;
156: }
157: }
158: }
|