001: /*
002: * Copyright 2004 Clinton Begin
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016: package com.ibatis.sqlmap.engine.mapping.sql.dynamic.elements;
017:
018: import com.ibatis.common.beans.Probe;
019: import com.ibatis.common.beans.ProbeFactory;
020: import com.ibatis.sqlmap.engine.type.SimpleDateFormatter;
021:
022: import java.math.BigDecimal;
023: import java.math.BigInteger;
024: import java.util.Date;
025:
026: public abstract class ConditionalTagHandler extends BaseTagHandler {
027:
028: private static final Probe PROBE = ProbeFactory.getProbe();
029:
030: public static final long NOT_COMPARABLE = Long.MIN_VALUE;
031: private static final String DATE_MASK = "yyyy/MM/dd hh:mm:ss";
032:
033: private static final String START_INDEX = "[";
034:
035: public abstract boolean isCondition(SqlTagContext ctx, SqlTag tag,
036: Object parameterObject);
037:
038: public int doStartFragment(SqlTagContext ctx, SqlTag tag,
039: Object parameterObject) {
040:
041: ctx.pushRemoveFirstPrependMarker(tag);
042:
043: if (isCondition(ctx, tag, parameterObject)) {
044: return SqlTagHandler.INCLUDE_BODY;
045: } else {
046: return SqlTagHandler.SKIP_BODY;
047: }
048: }
049:
050: public int doEndFragment(SqlTagContext ctx, SqlTag tag,
051: Object parameterObject, StringBuffer bodyContent) {
052:
053: IterateContext iterate = ctx.peekIterateContext();
054:
055: if (null != iterate && iterate.isAllowNext()) {
056: iterate.next();
057: iterate.setAllowNext(false);
058: if (!iterate.hasNext()) {
059: iterate.setFinal(true);
060: }
061: }
062:
063: //iteratePropertyReplace(bodyContent,ctx.peekIterateContext());
064:
065: return super .doEndFragment(ctx, tag, parameterObject,
066: bodyContent);
067: }
068:
069: protected long compare(SqlTagContext ctx, SqlTag tag,
070: Object parameterObject) {
071: String comparePropertyName = tag.getComparePropertyAttr();
072: String compareValue = tag.getCompareValueAttr();
073:
074: String prop = getResolvedProperty(ctx, tag);
075: Object value1;
076: Class type;
077:
078: if (prop != null) {
079: value1 = PROBE.getObject(parameterObject, prop);
080: type = PROBE
081: .getPropertyTypeForGetter(parameterObject, prop);
082: } else {
083: value1 = parameterObject;
084: if (value1 != null) {
085: type = parameterObject.getClass();
086: } else {
087: type = Object.class;
088: }
089: }
090: if (comparePropertyName != null) {
091: Object value2 = PROBE.getObject(parameterObject,
092: comparePropertyName);
093: return compareValues(type, value1, value2);
094: } else if (compareValue != null) {
095: return compareValues(type, value1, compareValue);
096: } else {
097: throw new RuntimeException(
098: "Error comparing in conditional fragment. Uknown 'compare to' values.");
099: }
100: }
101:
102: protected long compareValues(Class type, Object value1,
103: Object value2) {
104: long result = NOT_COMPARABLE;
105:
106: if (value1 == null || value2 == null) {
107: result = value1 == value2 ? 0 : NOT_COMPARABLE;
108: } else {
109: if (value2.getClass() != type) {
110: value2 = convertValue(type, value2.toString());
111: }
112: if (value2 instanceof String && type != String.class) {
113: value1 = value1.toString();
114: }
115: if (!(value1 instanceof Comparable && value2 instanceof Comparable)) {
116: value1 = value1.toString();
117: value2 = value2.toString();
118: }
119: result = ((Comparable) value1).compareTo(value2);
120: }
121:
122: return result;
123: }
124:
125: protected Object convertValue(Class type, String value) {
126: if (type == String.class) {
127: return value;
128: } else if (type == Byte.class || type == byte.class) {
129: return Byte.valueOf(value);
130: } else if (type == Short.class || type == short.class) {
131: return Short.valueOf(value);
132: } else if (type == Character.class || type == char.class) {
133: return new Character(value.charAt(0));
134: } else if (type == Integer.class || type == int.class) {
135: return Integer.valueOf(value);
136: } else if (type == Long.class || type == long.class) {
137: return Long.valueOf(value);
138: } else if (type == Float.class || type == float.class) {
139: return Float.valueOf(value);
140: } else if (type == Double.class || type == double.class) {
141: return Double.valueOf(value);
142: } else if (type == Boolean.class || type == boolean.class) {
143: return Boolean.valueOf(value);
144: } else if (type == Date.class) {
145: return SimpleDateFormatter.format(DATE_MASK, value);
146: } else if (type == BigInteger.class) {
147: return new BigInteger(value);
148: } else if (type == BigDecimal.class) {
149: return new BigDecimal(value);
150: } else {
151: return value;
152: }
153:
154: }
155:
156: /**
157: * This method will add the proper index values to an indexed property
158: * string if we are inside an iterate tag
159: *
160: * @param ctx
161: * @param tag
162: */
163: protected String getResolvedProperty(SqlTagContext ctx, SqlTag tag) {
164: String prop = tag.getPropertyAttr();
165: IterateContext itCtx = ctx.peekIterateContext();
166:
167: if (prop != null) {
168:
169: if (null != itCtx && itCtx.isAllowNext()) {
170: itCtx.next();
171: itCtx.setAllowNext(false);
172: if (!itCtx.hasNext()) {
173: itCtx.setFinal(true);
174: }
175: }
176:
177: if (prop.indexOf(START_INDEX) > -1) {
178: if (itCtx != null) {
179: prop = itCtx.addIndexToTagProperty(prop);
180: }
181: }
182: }
183:
184: return prop;
185: }
186: }
|