1 package org.apache.torque.sql.whereclausebuilder;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import org.apache.torque.TorqueException;
23 import org.apache.torque.adapter.Adapter;
24 import org.apache.torque.criteria.PreparedStatementPart;
25 import org.apache.torque.criteria.SqlEnum;
26 import org.apache.torque.sql.WhereClauseExpression;
27
28
29
30
31
32
33
34 public class LikeBuilder extends AbstractWhereClausePsPartBuilder
35 {
36
37 private static final char BACKSLASH = '\\';
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59 public PreparedStatementPart buildPs(
60 WhereClauseExpression whereClausePart,
61 boolean ignoreCase,
62 Adapter adapter)
63 throws TorqueException
64 {
65 if (!(whereClausePart.getRValue() instanceof String))
66 {
67 throw new TorqueException(
68 "rValue must be a String for the operator "
69 + whereClausePart.getOperator());
70 }
71 String value = (String) whereClausePart.getRValue();
72
73
74
75
76
77
78
79
80 int position = 0;
81 StringBuffer sb = new StringBuffer();
82 boolean replaceWithEquals = true;
83 while (position < value.length())
84 {
85 char checkWildcard = value.charAt(position);
86
87 switch (checkWildcard)
88 {
89 case BACKSLASH:
90 if (position + 1 >= value.length())
91 {
92
93 break;
94 }
95 position++;
96 char escapedChar = value.charAt(position);
97 if (escapedChar != '*' && escapedChar != '?')
98 {
99 sb.append(checkWildcard);
100 }
101
102 checkWildcard = escapedChar;
103 break;
104 case '%':
105 case '_':
106 replaceWithEquals = false;
107 break;
108 case '*':
109 replaceWithEquals = false;
110 checkWildcard = '%';
111 break;
112 case '?':
113 replaceWithEquals = false;
114 checkWildcard = '_';
115 break;
116 default:
117 break;
118 }
119
120 sb.append(checkWildcard);
121 position++;
122 }
123 value = sb.toString();
124
125 PreparedStatementPart result;
126 if (ignoreCase)
127 {
128 if (adapter.useIlike() && !replaceWithEquals)
129 {
130 if (SqlEnum.LIKE.equals(whereClausePart.getOperator()))
131 {
132 whereClausePart.setOperator(SqlEnum.ILIKE);
133 }
134 else if (SqlEnum.NOT_LIKE.equals(whereClausePart.getOperator()))
135 {
136 whereClausePart.setOperator(SqlEnum.NOT_ILIKE);
137 }
138 result = getObjectOrColumnPsPartBuilder().buildPs(
139 whereClausePart.getLValue(), false, adapter);
140 }
141 else
142 {
143
144
145
146 result = getObjectOrColumnPsPartBuilder().buildPs(
147 whereClausePart.getLValue(), true, adapter);
148 }
149 }
150 else
151 {
152 result = getObjectOrColumnPsPartBuilder().buildPs(
153 whereClausePart.getLValue(), ignoreCase, adapter);
154 }
155
156 if (replaceWithEquals)
157 {
158 if (whereClausePart.getOperator().equals(SqlEnum.NOT_LIKE)
159 || whereClausePart.getOperator().equals(SqlEnum.NOT_ILIKE))
160 {
161 result.getSql().append(SqlEnum.NOT_EQUAL);
162 }
163 else
164 {
165 result.getSql().append(SqlEnum.EQUAL);
166 }
167
168
169 position = 0;
170 sb = new StringBuffer();
171 while (position < value.length())
172 {
173 char checkWildcard = value.charAt(position);
174
175 if (checkWildcard == BACKSLASH
176 && position + 1 < value.length())
177 {
178 position++;
179
180 checkWildcard = value.charAt(position);
181 }
182 sb.append(checkWildcard);
183 position++;
184 }
185 value = sb.toString();
186 }
187 else
188 {
189 result.getSql().append(whereClausePart.getOperator());
190 }
191
192 String rValueSql = "?";
193
194 if (ignoreCase && (!(adapter.useIlike()) || replaceWithEquals))
195 {
196 rValueSql = adapter.ignoreCase(rValueSql);
197 }
198
199 if (!replaceWithEquals && adapter.useEscapeClauseForLike())
200 {
201 rValueSql = rValueSql + SqlEnum.ESCAPE + "'\\'";
202 }
203
204 result.getPreparedStatementReplacements().add(value);
205 result.getSql().append(rValueSql);
206 return result;
207 }
208
209
210
211
212 public boolean isApplicable(
213 WhereClauseExpression whereClauseExpression,
214 Adapter adapter)
215 {
216 if (whereClauseExpression.getOperator().equals(SqlEnum.LIKE)
217 || whereClauseExpression.getOperator().equals(SqlEnum.NOT_LIKE)
218 || whereClauseExpression.getOperator().equals(SqlEnum.ILIKE)
219 || whereClauseExpression.getOperator().equals(SqlEnum.NOT_ILIKE))
220 {
221 return true;
222 }
223 return false;
224 }
225 }