KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > genimen > djeneric > repository > DjQueryByExample


1 /*
2  * Copyright (c) 2001-2005 by Genimen BV (www.genimen.com) All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without modification, is permitted
5  * provided that the following conditions are met:
6  * - Redistributions of source code must retain the above copyright notice, this list of conditions
7  * and the following disclaimer.
8  * - Redistributions in binary form must reproduce the above copyright notice, this list of
9  * conditions and the following disclaimer in the documentation and/or other materials
10  * provided with the distribution.
11  * - All advertising materials mentioning features or use of this software must display the
12  * following acknowledgment: "This product includes Djeneric."
13  * - Products derived from this software may not be called "Djeneric" nor may
14  * "Djeneric" appear in their names without prior written permission of Genimen BV.
15  * - Redistributions of any form whatsoever must retain the following acknowledgment: "This
16  * product includes Djeneric."
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS "AS IS"
19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED. IN NO EVENT SHALL GENIMEN BV, DJENERIC.ORG,
22  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */

30 package com.genimen.djeneric.repository;
31
32 import java.math.BigDecimal JavaDoc;
33 import java.util.ArrayList JavaDoc;
34 import java.util.Date JavaDoc;
35 import java.util.HashMap JavaDoc;
36
37 import com.genimen.djeneric.language.Messages;
38 import com.genimen.djeneric.repository.exceptions.DjenericException;
39 import com.genimen.djeneric.repository.exceptions.ObjectNotDefinedException;
40 import com.genimen.djeneric.repository.exceptions.PropertyFormatException;
41 import com.genimen.djeneric.repository.exceptions.QbeFilterException;
42 import com.genimen.djeneric.util.DjLikeComparator;
43
44 /**
45  * Description of the Class
46  *
47  *@author Wido Riezebos
48  *@created November 5, 2001
49  */

50 public class DjQueryByExample extends DjObject implements DjObjectMatcher
51 {
52   HashMap JavaDoc _operators = new HashMap JavaDoc();
53   final static String JavaDoc[] _supportedOps = {"==", "!=", "<", ">", "<=", ">=", "like"};
54
55   /**
56    * Constructor for the DjQueryByExample object
57    *
58    *@param session Description of the Parameter
59    *@param extent Description of the Parameter
60    *@exception DjenericException Description of the Exception
61    */

62   protected DjQueryByExample(DjSession session, DjExtent extent) throws DjenericException
63   {
64     super(session, extent);
65     // Make sure this object is not cached and does not take part in queries/transactions
66
setTemporary(true);
67     setTransient(true);
68   }
69
70   /**
71    * Constructor for the DjQueryByExample object
72    *
73    *@param session Description of the Parameter
74    *@param objectType Description of the Parameter
75    *@exception DjenericException Description of the Exception
76    */

77   protected DjQueryByExample(DjSession session, String JavaDoc objectType) throws DjenericException
78   {
79     super(session, objectType);
80     setTransient(true);
81   }
82
83   public static String JavaDoc[] getSupportedOperators()
84   {
85     return _supportedOps;
86   }
87
88   protected void initializeDefaultValues()
89   { // Deliberate override to avoid default values messing up the query
90
}
91
92   /**
93    * Sets the operator to be used for comparison of the property identified by
94    * property index. Supported operators are ==, <> !=, <, >, <=, >=
95    *
96    *@param propertyIndex The new operator value
97    *@param operator The new operator value
98    *@exception DjenericException Description of the Exception
99    */

100   public void setOperator(int propertyIndex, String JavaDoc operator) throws ObjectNotDefinedException, QbeFilterException
101   {
102     setOperator(getPropertyName(propertyIndex), operator);
103   }
104
105   /**
106    * Sets the operator to be used for comparison of the property identified by
107    * propertyName. Supported operators are ==, <> !=, <, >, <=, >=
108    *
109    *@param propertyName The new operator value
110    *@param operator The new operator value
111    *@exception DjenericException Description of the Exception
112    */

113   public void setOperator(String JavaDoc propertyName, String JavaDoc operator) throws ObjectNotDefinedException, QbeFilterException
114   {
115     if (operator.equals("<>")) operator = "!=";
116
117     // first make sure the property is valid by forcing an exception if invalid:
118
getProperty(propertyName);
119     // Now check the validity of the operator
120
isValidOperator(operator);
121
122     _operators.put(propertyName, operator);
123   }
124
125   public static void isValidOperator(String JavaDoc operator) throws QbeFilterException
126   {
127     boolean valid = false;
128     for (int i = 0; !valid && i < _supportedOps.length; i++)
129       valid |= operator.equals(_supportedOps[i]);
130
131     if (!valid) throw new QbeFilterException(Messages.getString("DjQueryByExample.UnsupportedOperator", operator));
132   }
133
134   /**
135    * Returns the operator to be used during comparison of the provided property
136    *
137    *@param propertyName Name of the property to find the operator for
138    *@return The operator
139    *@exception DjenericException Description of the Exception
140    */

141   public String JavaDoc getOperator(String JavaDoc propertyName) throws DjenericException
142   {
143     // first make sure the property is valid by forcing an exception if invalid:
144
getProperty(propertyName);
145
146     String JavaDoc result = (String JavaDoc) _operators.get(propertyName);
147     if (result == null) result = "==";
148
149     return result;
150   }
151
152   public boolean hasOperatorFor(String JavaDoc propertyName)
153   {
154     String JavaDoc result = (String JavaDoc) _operators.get(propertyName);
155     return result != null;
156   }
157
158   public boolean hasOperatorFor(int propertyIndex)
159   {
160     return hasOperatorFor(getPropertyName(propertyIndex));
161   }
162
163   public void removeOperatorFor(String JavaDoc propertyName)
164   {
165     _operators.remove(propertyName);
166   }
167
168   public void removeOperatorFor(int propertyIndex)
169   {
170     _operators.remove(getPropertyName(propertyIndex));
171   }
172
173   /**
174    * Returns the operator to be used during comparison of the provided property
175    *
176    *@param propertyIndex Index of the property to find the operator for
177    *@return The operator
178    *@exception DjenericException Description of the Exception
179    */

180   public String JavaDoc getOperator(int propertyIndex) throws DjenericException
181   {
182     return getOperator(getPropertyName(propertyIndex));
183   }
184
185   /**
186    * Returns the extent of the DjQueryByExample object
187    *
188    *@return The extent value
189    */

190   public DjExtent getExtent()
191   {
192     return super.getExtent();
193   }
194
195   /**
196    * Description of the Method
197    *
198    *@exception DjenericException Description of the Exception
199    */

200   protected void update()
201   {
202     // deliberately do nothing, do not persist QBE's
203
}
204
205   /**
206    * Description of the Method
207    *
208    *@exception DjenericException Description of the Exception
209    */

210   protected void insert()
211   {
212     // deliberately do nothing, do not persist QBE's
213
}
214
215   /**
216    * Description of the Method
217    *
218    *@exception DjenericException Description of the Exception
219    */

220   protected void delete()
221   {
222     // deliberately do nothing, do not persist QBE's
223
}
224
225   /**
226    * Description of the Method
227    *
228    *@exception DjenericException Description of the Exception
229    */

230   public void reload()
231   {
232     // deliberately do nothing, do not persist QBE's
233
}
234
235   public boolean match(DjObject po) throws DjenericException
236   {
237     // Do not match deleted objects:
238
if (po.isMarkedForDelete()) return false;
239
240     for (int j = 0; j < getPropertyCount(); j++)
241     {
242       if (!isNull(j))
243       {
244         DjProperty prop = getProperty(j);
245         String JavaDoc oper = getOperator(j);
246
247         if (oper.equals("=="))
248         {
249           if (!get(j).equals(po.get(prop.getName())))
250           {
251             return false;
252           }
253         }
254         else if (oper.equals("!="))
255         {
256           if (get(j).equals(po.get(prop.getName())))
257           {
258             return false;
259           }
260         }
261         else
262         {
263           Object JavaDoc o1 = get(j);
264           Object JavaDoc o2 = po.get(prop.getName());
265
266           if (oper.equals("<"))
267           {
268             if (o1 instanceof String JavaDoc) return o1.toString().compareTo(o2.toString()) < 0;
269             if (o1 instanceof BigDecimal JavaDoc) return ((BigDecimal JavaDoc) o1).compareTo((BigDecimal JavaDoc) o1) < 0;
270             if (o1 instanceof Date JavaDoc) return ((Date JavaDoc) o1).compareTo((Date JavaDoc) o1) < 0;
271             if (o1 instanceof Integer JavaDoc) return ((Integer JavaDoc) o1).compareTo((Integer JavaDoc) o1) < 0;
272             if (o1 instanceof Long JavaDoc) return ((Long JavaDoc) o1).compareTo((Long JavaDoc) o1) < 0;
273             throw new DjenericException(Messages.getString("DjQueryByExample.CanNotMatch", o1.getClass().getName()));
274           }
275
276           if (oper.equals("<="))
277           {
278             if (o1 instanceof String JavaDoc) return o1.toString().compareTo(o2.toString()) <= 0;
279             if (o1 instanceof BigDecimal JavaDoc) return ((BigDecimal JavaDoc) o1).compareTo((BigDecimal JavaDoc) o1) <= 0;
280             if (o1 instanceof Date JavaDoc) return ((Date JavaDoc) o1).compareTo((Date JavaDoc) o1) <= 0;
281             if (o1 instanceof Integer JavaDoc) return ((Integer JavaDoc) o1).compareTo((Integer JavaDoc) o1) <= 0;
282             if (o1 instanceof Long JavaDoc) return ((Long JavaDoc) o1).compareTo((Long JavaDoc) o1) <= 0;
283             throw new DjenericException(Messages.getString("DjQueryByExample.CanNotMatch", o1.getClass().getName()));
284           }
285
286           if (oper.equals(">"))
287           {
288             if (o1 instanceof String JavaDoc) return o1.toString().compareTo(o2.toString()) > 0;
289             if (o1 instanceof BigDecimal JavaDoc) return ((BigDecimal JavaDoc) o1).compareTo((BigDecimal JavaDoc) o1) > 0;
290             if (o1 instanceof Date JavaDoc) return ((Date JavaDoc) o1).compareTo((Date JavaDoc) o1) > 0;
291             if (o1 instanceof Integer JavaDoc) return ((Integer JavaDoc) o1).compareTo((Integer JavaDoc) o1) > 0;
292             if (o1 instanceof Long JavaDoc) return ((Long JavaDoc) o1).compareTo((Long JavaDoc) o1) > 0;
293             throw new DjenericException(Messages.getString("DjQueryByExample.CanNotMatch", o1.getClass().getName()));
294           }
295
296           if (oper.equals(">="))
297           {
298             if (o1 instanceof String JavaDoc) return o1.toString().compareTo(o2.toString()) >= 0;
299             if (o1 instanceof BigDecimal JavaDoc) return ((BigDecimal JavaDoc) o1).compareTo((BigDecimal JavaDoc) o1) >= 0;
300             if (o1 instanceof Date JavaDoc) return ((Date JavaDoc) o1).compareTo((Date JavaDoc) o1) >= 0;
301             if (o1 instanceof Integer JavaDoc) return ((Integer JavaDoc) o1).compareTo((Integer JavaDoc) o1) >= 0;
302             if (o1 instanceof Long JavaDoc) return ((Long JavaDoc) o1).compareTo((Long JavaDoc) o1) >= 0;
303             throw new DjenericException(Messages.getString("DjQueryByExample.CanNotMatch", o1.getClass().getName()));
304           }
305
306           if (oper.equals("like"))
307           {
308             String JavaDoc s1 = getString(j);
309             String JavaDoc s2 = po.getString(prop.getName());
310
311             if (s1 == null || s2 == null) return false;
312
313             DjLikeComparator like = new DjLikeComparator(s2, '\\', false);
314             return like.compare(s1);
315           }
316         }
317       }
318     }
319     return true;
320   }
321
322   public void setExpressionValue(String JavaDoc propertyName, Object JavaDoc value) throws PropertyFormatException,
323       ObjectNotDefinedException, DjenericException
324   {
325     set(propertyName, translateConstant(value));
326   }
327
328   public void setExpressionValue(int propertyIdx, Object JavaDoc value) throws PropertyFormatException,
329       ObjectNotDefinedException, DjenericException
330   {
331     set(propertyIdx, translateConstant(value));
332   }
333
334   public static Object JavaDoc translateConstant(Object JavaDoc someValue) throws QbeFilterException
335   {
336     if (someValue instanceof String JavaDoc)
337     {
338       String JavaDoc value = (String JavaDoc) someValue;
339       if ((value.startsWith("\"") && value.endsWith("\"")) || (value.startsWith("'") && value.endsWith("'")))
340       {
341         value = value.substring(1);
342         if (value.length() > 0) value = value.substring(0, value.length() - 1);
343         else throw new QbeFilterException(Messages.getString("DjQueryByExample.UnterminatedString", someValue));
344         someValue = value;
345       }
346       else
347       {
348         try
349         { // Is it a valid numeric value then?
350
someValue = new BigDecimal JavaDoc(value);
351         }
352         catch (Exception JavaDoc x)
353         {
354           // Not a number: then try for some predefined constants
355
if (value.equalsIgnoreCase("null")) someValue = null;
356           else if (value.equalsIgnoreCase("timestamp")) someValue = new Date JavaDoc();
357           else throw new QbeFilterException(Messages.getString("DjQueryByExample.InvalidQBEConstant", value));
358         }
359       }
360     }
361     return someValue;
362   }
363
364   public String JavaDoc[] getPropertiesWithFilter() throws DjenericException
365   {
366     String JavaDoc propertyNames[] = getPropertyNames();
367     ArrayList JavaDoc result = new ArrayList JavaDoc();
368
369     for (int i = 0; i < propertyNames.length; i++)
370     {
371       if (hasOperatorFor(propertyNames[i]) || !isNull(propertyNames[i]))
372       {
373         result.add(propertyNames[i]);
374       }
375     }
376     return (String JavaDoc[]) result.toArray(new String JavaDoc[0]);
377   }
378
379   public boolean isResultUnique()
380   {
381     // The resultset of a QBE does never contain the same instance multiple times.
382
return true;
383   }
384
385   /**
386    * Copies all properties that are NOT part of a relation (master or detail)
387    * Furthermore only properties that not null are copied UNLESS the parameter
388    * includeNulls is true; in that case properties that are null on the given
389    * object are also set.
390    * Note that the ID property is NOT copied.
391    * @param obj
392    * @throws DjenericException
393    */

394   public void acceptSimpleProperties(DjObject obj, boolean includeNulls) throws DjenericException
395   {
396     for (int i = 0; i < getPropertyCount(); i++)
397     {
398       DjProperty prop = getProperty(i);
399       if (prop.getType() instanceof DjDomain && obj.hasProperty(prop.getName()))
400       {
401         if (obj.getExtent().getIdProperty().getName().equals(prop.getName())) continue;
402
403         if (!obj.isNull(prop.getName())) set(prop.getName(), obj.get(prop.getName()));
404         else if (includeNulls) setNull(prop.getName());
405       }
406     }
407   }
408
409   public String JavaDoc toString()
410   {
411     StringBuffer JavaDoc sb = new StringBuffer JavaDoc(100);
412     DjExtent extent = getExtent();
413     sb.append("Qbe(" + extent.getName() + ")\n{\n");
414     for (int i = 0; i < extent.getPropertyCount(); i++)
415     {
416       if (!isNull(i))
417       {
418         sb.append(" " + extent.getProperty(i).getName() + "=\"" + getString(i) + "\"\n");
419       }
420     }
421     sb.append("}");
422     return sb.toString();
423   }
424 }
Popular Tags