Source code: com/ibatis/sqlmap/engine/mapping/sql/dynamic/elements/ConditionalTagHandler.java
1 /*
2 * Copyright 2004 Clinton Begin
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 package com.ibatis.sqlmap.engine.mapping.sql.dynamic.elements;
17
18 import com.ibatis.common.beans.Probe;
19 import com.ibatis.common.beans.ProbeFactory;
20 import com.ibatis.common.exception.NestedRuntimeException;
21
22 import java.math.BigDecimal;
23 import java.math.BigInteger;
24 import java.text.DateFormat;
25 import java.text.ParseException;
26 import java.text.SimpleDateFormat;
27 import java.util.Date;
28
29 public abstract class ConditionalTagHandler extends BaseTagHandler {
30
31 private static final Probe PROBE = ProbeFactory.getProbe();
32
33 public static final long NOT_COMPARABLE = Long.MIN_VALUE;
34 private static final String DATE_MASK = "yyyy/MM/dd hh:mm:ss";
35 private static final DateFormat DATE_FORMAT = new SimpleDateFormat(DATE_MASK);
36
37 public abstract boolean isCondition(SqlTagContext ctx, SqlTag tag, Object parameterObject);
38
39 public int doStartFragment(SqlTagContext ctx, SqlTag tag, Object parameterObject) {
40
41 ctx.pushRemoveFirstPrependMarker(tag);
42
43 if (isCondition(ctx, tag, parameterObject)) {
44 return SqlTagHandler.INCLUDE_BODY;
45 } else {
46 return SqlTagHandler.SKIP_BODY;
47 }
48 }
49
50 public int doEndFragment(SqlTagContext ctx, SqlTag tag, Object parameterObject, StringBuffer bodyContent) {
51
52 IterateContext iterate = ctx.peekIterateContext();
53
54 if(null != iterate && iterate.isAllowNext()){
55 iterate.next();
56 iterate.setAllowNext(false);
57 }
58
59 iteratePropertyReplace(bodyContent,ctx.peekIterateContext());
60
61 return super.doEndFragment(ctx,tag,parameterObject,bodyContent);
62 }
63
64 protected long compare(SqlTagContext ctx, SqlTag tag, Object parameterObject) {
65 String propertyName = tag.getPropertyAttr();
66 String comparePropertyName = tag.getComparePropertyAttr();
67 String compareValue = tag.getCompareValueAttr();
68
69 String prop = tag.getPropertyAttr();
70 Object value1;
71 Class type;
72 if (prop != null) {
73 value1 = PROBE.getObject(parameterObject, propertyName);
74 type = PROBE.getPropertyTypeForGetter(parameterObject, propertyName);
75 } else {
76 value1 = parameterObject;
77 if (value1 != null) {
78 type = parameterObject.getClass();
79 } else {
80 type = Object.class;
81 }
82 }
83 if (comparePropertyName != null) {
84 Object value2 = PROBE.getObject(parameterObject, comparePropertyName);
85 return compareValues(type, value1, value2);
86 } else if (compareValue != null) {
87 return compareValues(type, value1, compareValue);
88 } else {
89 throw new NestedRuntimeException("Error comparing in conditional fragment. Uknown 'compare to' values.");
90 }
91 }
92
93 protected long compareValues(Class type, Object value1, Object value2) {
94 long result = NOT_COMPARABLE;
95
96 if (value1 == null || value2 == null) {
97 result = value1 == value2 ? 0 : NOT_COMPARABLE;
98 } else {
99 if (value2.getClass() != type) {
100 value2 = convertValue(type, value2.toString());
101 }
102 if (value2 instanceof String && type != String.class) {
103 value1 = value1.toString();
104 }
105 if (!(value1 instanceof Comparable && value2 instanceof Comparable)) {
106 value1 = value1.toString();
107 value2 = value2.toString();
108 }
109 result = ((Comparable) value1).compareTo(value2);
110 }
111
112 return result;
113 }
114
115 protected Object convertValue(Class type, String value) {
116 if (type == String.class) {
117 return value;
118 } else if (type == Byte.class || type == byte.class) {
119 return Byte.valueOf(value);
120 } else if (type == Short.class || type == short.class) {
121 return Short.valueOf(value);
122 } else if (type == Character.class || type == char.class) {
123 return new Character(value.charAt(0));
124 } else if (type == Integer.class || type == int.class) {
125 return Integer.valueOf(value);
126 } else if (type == Long.class || type == long.class) {
127 return Long.valueOf(value);
128 } else if (type == Float.class || type == float.class) {
129 return Float.valueOf(value);
130 } else if (type == Double.class || type == double.class) {
131 return Double.valueOf(value);
132 } else if (type == Boolean.class || type == boolean.class) {
133 return Boolean.valueOf(value);
134 } else if (type == Date.class) {
135 try {
136 return DATE_FORMAT.parse(value);
137 } catch (ParseException e) {
138 throw new NestedRuntimeException("Error parsing date. Cause: " + e, e);
139 }
140 } else if (type == BigInteger.class) {
141 return new BigInteger(value);
142 } else if (type == BigDecimal.class) {
143 return new BigDecimal(value);
144 } else {
145 return value;
146 }
147
148 }
149
150 }