KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > josql > expressions > LikeExpression


1 /*
2  * Copyright 2004-2005 Gary Bentley
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License"); you may
5  * not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */

15 package org.josql.expressions;
16
17 import java.util.List JavaDoc;
18 import java.util.ArrayList JavaDoc;
19 import java.util.StringTokenizer JavaDoc;
20
21 import org.josql.Query;
22 import org.josql.QueryExecutionException;
23 import org.josql.QueryParseException;
24
25 import org.josql.internal.Utilities;
26
27 /**
28  * Represents a LHS [ NOT ] [ $ ] LIKE RHS expression.
29  * It should be noted that unlike "normal" SQL the "." character is not supported since in
30  * practice it tends to be redundant.
31  * <p>
32  * It is possible to use: $ in front of the "LIKE" to indicate that a case insensitive
33  * comparison should be performed, for example:
34  * <pre>
35  * SELECT *
36  * FROM java.lang.String
37  * WHERE toString $LIKE '%value'
38  * </pre>
39  * <p>
40  * Also, the LHS or RHS can be built up using the "+" operator to concatenate a string, thus:
41  * <pre>
42  * SELECT *
43  * FROM java.lang.String
44  * WHREE toString $LIKE '%' + :myValue
45  * </pre>
46  * <p>
47  * In this way (using the {@link BindVariable named bind variable}) you don't have to provide
48  * the wildcard.
49  * <p>
50  * It is also possible to specify your own "wildcard" character in the Query object using:
51  * {@link Query#setWildcardCharacter(char)}.
52  * <p>
53  * Note: the implementation is a modified version of that provided by: Kevin Stannard
54  * (http://www.jzoo.com/java/wildcardfilter/).
55  * <p>
56  * Last Modified By: $Author: barrygently $<br />
57  * Last Modified On: $Date: 2005/04/28 05:48:59 $<br />
58  * Current Revision: $Revision: 1.5 $<br />
59  */

60 public class LikeExpression extends BinaryExpression
61 {
62
63     private boolean not = false;
64     private boolean ignoreCase = false;
65     private List JavaDoc pattern = null;
66
67     public boolean isIgnoreCase ()
68     {
69
70     return this.ignoreCase;
71
72     }
73
74     /**
75      * Init the expression, we over-ride here so that if the RHS is fixed we can
76      * init the pattern that will be used to match the expression.
77      *
78      * @param q The Query object.
79      * @throws QueryParseException If the LHS and/or RHS cannot be inited.
80      */

81     public void init (Query q)
82                   throws QueryParseException
83     {
84
85     // Call our parent first.
86
super.init (q);
87
88     if (this.right.hasFixedResult (q))
89     {
90
91         // It does have a fixed result so get the value and init the pattern.
92
Object JavaDoc r = null;
93
94         try
95         {
96
97         r = this.right.getValue (null,
98                      q);
99
100         } catch (Exception JavaDoc e) {
101
102         throw new QueryParseException ("Unable to get RHS value from: \"" +
103                            this.right +
104                            "\", expected to RHS to have fixed result.",
105                            e);
106
107         }
108
109         if (r == null)
110         {
111
112         // Return since we can't do anything useful now.
113
return;
114
115         }
116
117         String JavaDoc rs = r.toString ();
118
119         if (this.ignoreCase)
120         {
121
122         rs = rs.toLowerCase ();
123
124         }
125
126         char wc = q.getWildcardCharacter ();
127
128         this.pattern = Utilities.getLikePattern (rs,
129                              String.valueOf (wc));
130
131     }
132
133     }
134
135     public void setIgnoreCase (boolean v)
136     {
137
138     this.ignoreCase = v;
139
140     }
141
142     public boolean isNot ()
143     {
144
145     return this.not;
146
147     }
148
149     public void setNot (boolean v)
150     {
151
152     this.not = v;
153
154     }
155
156     /**
157      * Returns whether the LHS is "LIKE" the RHS.
158      * A special case here is that if the LHS and RHS are both <code>null</code> then <code>true</code>
159      * is returned. Also, if either the LHS or RHS is not null and one is null then <code>false</code>
160      * is returned.
161      *
162      * @param o The object to evaluate the expression on.
163      * @param q The Query object.
164      * @return <code>true</code> if the LHS is "LIKE" the RHS, <code>false</code> if not. And using
165      * "NOT" will invert the result.
166      * @throws QueryExecutionException If the expression cannot be evaluated.
167      */

168     public boolean isTrue (Object JavaDoc o,
169                Query q)
170                        throws QueryExecutionException
171     {
172
173     // Get the left...
174
Object JavaDoc l = this.left.getValue (o,
175                        q);
176
177     if (this.pattern != null)
178     {
179
180         return Utilities.matchLikePattern (this.pattern,
181                            l,
182                            this.not,
183                            this.ignoreCase);
184
185     }
186
187     Object JavaDoc r = this.right.getValue (o,
188                     q);
189
190     if ((l == null)
191         &&
192         (r == null)
193        )
194     {
195
196         // Special case...
197
if (this.not)
198         {
199
200         return false;
201
202         }
203
204         return true;
205
206     }
207
208     if ((l == null)
209         ||
210         (r == null)
211        )
212     {
213
214         if (this.not)
215         {
216
217         return true;
218
219         }
220
221         return false;
222
223     }
224
225     // Convert RHS to a string.
226
String JavaDoc rs = r.toString ();
227
228     if (this.ignoreCase)
229     {
230
231         rs = rs.toLowerCase ();
232
233     }
234
235     // Now see if rs contains the wildcard character.
236
char wc = q.getWildcardCharacter ();
237
238     List JavaDoc pat = Utilities.getLikePattern (rs,
239                          String.valueOf (wc));
240
241     return Utilities.matchLikePattern (pat,
242                        l,
243                        this.not,
244                        this.ignoreCase);
245
246     }
247
248     /**
249      * Returns a string version of the expression.
250      * Returns in the form:
251      * <pre>
252      * {@link Expression#toString() Expression} [ NOT ] [ $ ]LIKE {@link Expression#toString() Expression}
253      * </pre>
254      *
255      * @return A string representation of the expression.
256      */

257     public String JavaDoc toString ()
258     {
259
260     StringBuffer JavaDoc buf = new StringBuffer JavaDoc (this.left.toString ());
261
262     if (this.isNot ())
263     {
264
265         buf.append (" NOT");
266
267     }
268
269     buf.append (" ");
270
271     if (this.ignoreCase)
272     {
273
274         buf.append ("$");
275
276     }
277
278     buf.append ("LIKE ");
279
280     buf.append (this.right);
281
282     if (this.isBracketed ())
283     {
284
285         buf.insert (0,
286             "(");
287         buf.append (")");
288
289     }
290
291     return buf.toString ();
292
293     }
294
295 }
296
Popular Tags