001: /*
002: * Created on 31-Jan-2006
003: *
004: * TODO To change the template for this generated file go to
005: * Window - Preferences - Java - Code Style - Code Templates
006: */
007: package com.jofti.parser;
008:
009: import java.util.Collection;
010: import java.util.Iterator;
011: import java.util.Map;
012:
013: import com.jofti.exception.JoftiException;
014: import com.jofti.introspect.ClassIntrospector;
015: import com.jofti.introspect.ClassUtils;
016: import com.jofti.util.ReflectionUtil;
017:
018: /**
019: * @author xenephon
020: *
021: * TODO To change the template for this generated type comment go to
022: * Window - Preferences - Java - Code Style - Code Templates
023: */
024: public class AttributeValueParser {
025:
026: /**
027: *
028: */
029:
030: private ClassUtils utils = new ClassUtils();
031:
032: //special value for primitive types
033: public static final String VALUE = "VALUE";
034:
035: public AttributeValueParser() {
036:
037: }
038:
039: public Comparable[] constructArrayValue(Object unParsedValues,
040: ClassIntrospector introspector, Class name,
041: String attribute, Map parameters) throws JoftiException {
042:
043: // we can either have a string that is a key to a named attribute or a list
044: boolean fromObject = false;
045: Collection values = null;
046:
047: if (unParsedValues.getClass() == String.class) {
048: if (isParam((String) unParsedValues)) {
049:
050: Object obj = constructFromParameters(
051: (String) unParsedValues, parameters);
052:
053: if (obj == null) {
054:
055: throw new JoftiException(
056: "Value NULL is not valid for use with IN operator "
057: + parameters);
058: }
059:
060: if (!(obj instanceof Collection)) {
061: throw new JoftiException("Parameter "
062: + unParsedValues
063: + " must be an instance of a Collection");
064: }
065: values = (Collection) obj;
066:
067: fromObject = true;
068: }
069: } else {
070: values = (Collection) unParsedValues;
071: }
072: // construct the value
073: Comparable[] returnValues = null;
074: try {
075: if (values != null && values.size() != 0) {
076: Class clazz = introspector.getClassForAttribute(name,
077: attribute);
078: int size = values.size();
079: returnValues = new Comparable[size];
080: if (clazz.isArray()) {
081: clazz = clazz.getComponentType();
082: }
083: Iterator it = values.iterator();
084: for (int i = 0; i < size; i++) {
085: Object obj = it.next();
086: if (fromObject) {
087: if (checkType(clazz, obj)) {
088: returnValues[i] = (Comparable) obj;
089: } else {
090: throw new JoftiException(
091: "Type for parameter "
092: + obj
093: + " does not match required type "
094: + clazz + " in parameter "
095: + unParsedValues);
096: }
097: } else {
098: returnValues[i] = changeValueType(clazz,
099: (String) obj);
100:
101: }
102: }
103:
104: } else {
105: // return an empyt array if values is empty
106: returnValues = new Comparable[1];
107: }
108:
109: } catch (Exception e) {
110: throw new JoftiException(e);
111: }
112: return returnValues;
113: }
114:
115: public Comparable changeValueType(Class className, String value)
116: throws JoftiException {
117:
118: return (Comparable) ReflectionUtil.constructObjectValue(
119: className, value);
120: }
121:
122: public Comparable constructForIsNot(String unParsedValue,
123: Map namedParameters) throws JoftiException {
124: //this only allows nulls
125: Object value = (Comparable) constructFromParameters(
126: unParsedValue, namedParameters);
127: // check value is null
128: try {
129: if (value == null
130: || ("null".equalsIgnoreCase((String) value))) {
131: return null;
132: }
133: } catch (ClassCastException e) {
134: //we can ignore this here
135: }
136: throw new JoftiException(
137: "only NULL can be used with operator IS or NOT");
138:
139: }
140:
141: public Comparable constructValue(String unParsedValue,
142: ClassIntrospector introspector, Class name,
143: String attribute, Map namedParameters)
144: throws JoftiException {
145: // construct the value
146: Object value = null;
147: Class clazz = null;
148: try {
149: if (unParsedValue != null) {
150:
151: // see if it is a named or positional query first
152:
153: if (isParam(unParsedValue)) {
154: value = constructFromParameters(unParsedValue,
155: namedParameters);
156: if (value == null) {
157: throw new JoftiException(
158: "Value null is only allowed with IS or NOT operators "
159: + namedParameters);
160: }
161: clazz = introspector.getClassForAttribute(name,
162: attribute);
163: if (!checkType(clazz, value)) {
164: throw new JoftiException("Parameter type "
165: + value.getClass()
166: + " is not valid for parameter '"
167: + unParsedValue
168: + "' requires assignable type of "
169: + clazz);
170: }
171:
172: } else {
173: // string attribute check from unparsed value
174: clazz = introspector.getClassForAttribute(name,
175: attribute);
176: if (clazz.isArray()) {
177: value = changeValueType(clazz
178: .getComponentType(), unParsedValue);
179: } else {
180: value = changeValueType(clazz, unParsedValue);
181: }
182: }
183:
184: }
185: } catch (Exception e) {
186: throw new JoftiException(e);
187: }
188: return (Comparable) value;
189: }
190:
191: public Object constructFromParameters(String unParsedValue,
192: Map parameters) throws JoftiException {
193:
194: Object value = null;
195: // get the char at pos 0
196: char tempChar = unParsedValue.charAt(0);
197:
198: // see if starts with allowed value
199: if (tempChar == ':' || tempChar == '?') {
200: value = parameters.get(unParsedValue.substring(1));
201: if (value == null) {
202: if (parameters.containsKey(unParsedValue.substring(1))) {
203: return null;
204: }
205: throw new JoftiException("Parameter " + unParsedValue
206: + " is not in parameter set " + parameters);
207: } else {
208: // check return type compatability here
209:
210: value = utils.wrapObject(value);
211: }
212: }
213: //return null if we do not have matching prefix
214: // or value from map (which could also be null)
215:
216: return value;
217: }
218:
219: protected boolean isParam(String value) {
220: if (value == null) {
221: return false;
222: } else {
223: char tempChar = value.charAt(0);
224: if (tempChar == ':' || tempChar == '?') {
225: return true;
226: } else {
227: return false;
228: }
229: }
230: }
231:
232: protected boolean checkType(Class clazz, Object value) {
233: return clazz.isAssignableFrom(value.getClass())
234: && Comparable.class.isAssignableFrom(clazz);
235: }
236:
237: public Comparable[] processVals(String val, Map namedParameters)
238: throws JoftiException {
239: String value = (String) constructFromParameters(val,
240: namedParameters);
241:
242: if (value == null) {
243: value = val;
244: }
245: Comparable[] comp = new Comparable[2];
246: comp[0] = value.substring(0, value.length() - 1);
247: comp[1] = ((String) comp[0]) + Character.MAX_VALUE;
248: return comp;
249:
250: }
251: }
|