KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > db4o > query > Predicate


1 /* Copyright (C) 2004 - 2006 db4objects Inc. http://www.db4o.com
2
3 This file is part of the db4o open source object database.
4
5 db4o is free software; you can redistribute it and/or modify it under
6 the terms of version 2 of the GNU General Public License as published
7 by the Free Software Foundation and as clarified by db4objects' GPL
8 interpretation policy, available at
9 http://www.db4o.com/about/company/legalpolicies/gplinterpretation/
10 Alternatively you can write to db4objects, Inc., 1900 S Norfolk Street,
11 Suite 350, San Mateo, CA 94403, USA.
12
13 db4o is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 for more details.
17
18 You should have received a copy of the GNU General Public License along
19 with this program; if not, write to the Free Software Foundation, Inc.,
20 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */

21 package com.db4o.query;
22
23 import java.io.*;
24 import java.lang.reflect.*;
25
26 import com.db4o.*;
27
28 /**
29  * Base class for native queries.
30  * <br><br>Native Queries allow typesafe, compile-time checked and refactorable
31  * querying, following object-oriented principles. Native Queries expressions
32  * are written as if one or more lines of code would be run against all
33  * instances of a class. A Native Query expression should return true to mark
34  * specific instances as part of the result set.
35  * db4o will attempt to optimize native query expressions and execute them
36  * against indexes and without instantiating actual objects, where this is
37  * possible.<br><br>
38  * The syntax of the enclosing object for the native query expression varies,
39  * depending on the language version used. Here are some examples,
40  * how a simple native query will look like in some of the programming languages
41  * and dialects that db4o supports:<br><br>
42  *
43  * <code>
44  * <b>// C# .NET 2.0</b><br>
45  * IList &lt;Cat&gt; cats = db.Query &lt;Cat&gt; (delegate(Cat cat) {<br>
46  * &#160;&#160;&#160;return cat.Name == "Occam";<br>
47  * });<br>
48  * <br>
49  *<br>
50  * <b>// Java JDK 5</b><br>
51  * List &lt;Cat&gt; cats = db.query(new Predicate&lt;Cat&gt;() {<br>
52  * &#160;&#160;&#160;public boolean match(Cat cat) {<br>
53  * &#160;&#160;&#160;&#160;&#160;&#160;return cat.getName().equals("Occam");<br>
54  * &#160;&#160;&#160;}<br>
55  * });<br>
56  * <br>
57  * <br>
58  * <b>// Java JDK 1.2 to 1.4</b><br>
59  * List cats = db.query(new Predicate() {<br>
60  * &#160;&#160;&#160;public boolean match(Cat cat) {<br>
61  * &#160;&#160;&#160;&#160;&#160;&#160;return cat.getName().equals("Occam");<br>
62  * &#160;&#160;&#160;}<br>
63  * });<br>
64  * <br>
65  * <br>
66  * <b>// Java JDK 1.1</b><br>
67  * ObjectSet cats = db.query(new CatOccam());<br>
68  * <br>
69  * public static class CatOccam extends Predicate {<br>
70  * &#160;&#160;&#160;public boolean match(Cat cat) {<br>
71  * &#160;&#160;&#160;&#160;&#160;&#160;return cat.getName().equals("Occam");<br>
72  * &#160;&#160;&#160;}<br>
73  * });<br>
74  * <br>
75  * <br>
76  * <b>// C# .NET 1.1</b><br>
77  * IList cats = db.Query(new CatOccam());<br>
78  * <br>
79  * public class CatOccam : Predicate {<br>
80  * &#160;&#160;&#160;public boolean Match(Cat cat) {<br>
81  * &#160;&#160;&#160;&#160;&#160;&#160;return cat.Name == "Occam";<br>
82  * &#160;&#160;&#160;}<br>
83  * });<br>
84  * </code>
85  * <br>
86  * Summing up the above:<br>
87  * In order to run a Native Query, you can<br>
88  * - use the delegate notation for .NET 2.0.<br>
89  * - extend the Predicate class for all other language dialects<br><br>
90  * A class that extends Predicate is required to
91  * implement the #match() / #Match() method, following the native query
92  * conventions:<br>
93  * - The name of the method is "#match()" (Java) / "#Match()" (.NET).<br>
94  * - The method must be public public.<br>
95  * - The method returns a boolean.<br>
96  * - The method takes one parameter.<br>
97  * - The Type (.NET) / Class (Java) of the parameter specifies the extent.<br>
98  * - For all instances of the extent that are to be included into the
99  * resultset of the query, the match method should return true. For all
100  * instances that are not to be included, the match method should return
101  * false.<br><br>
102  */

103 public abstract class Predicate implements Serializable {
104     
105     /**
106      * public for implementation reasons, please ignore.
107      */

108     public final static String JavaDoc PREDICATEMETHOD_NAME="match";
109     
110     static final Class JavaDoc OBJECT_CLASS = Object JavaDoc.class;
111     
112     private Class JavaDoc _extentType;
113     private transient Method cachedFilterMethod=null;
114     
115     public Predicate() {
116         this(null);
117     }
118
119     public Predicate(Class JavaDoc extentType) {
120         _extentType=extentType;
121     }
122
123     // IMPORTANT: must have package visibility because it is used as
124
// internal on the .net side
125
Method getFilterMethod() {
126         if(cachedFilterMethod!=null) {
127             return cachedFilterMethod;
128         }
129         Method[] methods=getClass().getMethods();
130         Method untypedMethod=null;
131         for (int methodIdx = 0; methodIdx < methods.length; methodIdx++) {
132             Method method=methods[methodIdx];
133             if (isFilterMethod(method)) {
134                 if (!OBJECT_CLASS.equals(method.getParameterTypes()[0])) {
135                     cachedFilterMethod=method;
136                     return method;
137                 }
138                 untypedMethod=method;
139             }
140         }
141         if(untypedMethod!=null) {
142             cachedFilterMethod=untypedMethod;
143             return untypedMethod;
144         }
145         throw new IllegalArgumentException JavaDoc("Invalid predicate.");
146     }
147
148     private boolean isFilterMethod(Method method) {
149         if (method.getParameterTypes().length != 1) {
150             return false;
151         }
152         if (Deploy.csharp) {
153             return method.getName().equalsIgnoreCase(PREDICATEMETHOD_NAME);
154         }
155         return method.getName().equals(PREDICATEMETHOD_NAME);
156     }
157
158     /**
159      * public for implementation reasons, please ignore.
160      */

161     public Class JavaDoc extentType() {
162         return (_extentType!=null ? _extentType : getFilterMethod().getParameterTypes()[0]);
163     }
164
165     /**
166      * public for implementation reasons, please ignore.
167      */

168     public boolean appliesTo(Object JavaDoc candidate) {
169         try {
170             Method filterMethod=getFilterMethod();
171             Platform4.setAccessible(filterMethod);
172             Object JavaDoc ret=filterMethod.invoke(this,new Object JavaDoc[]{candidate});
173             return ((Boolean JavaDoc)ret).booleanValue();
174         } catch (Exception JavaDoc e) {
175             
176             // FIXME: Exceptions should be logged for app developers,
177
// but we can't print them out here.
178

179             // e.printStackTrace();
180

181             
182             return false;
183         }
184     }
185 }
186
Popular Tags