Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: nectar/data/Query.java


1   /*
2        Copyright (C) 2003  Kai Schutte
3    
4       This program is free software; you can redistribute it and/or modify
5       it under the terms of the GNU General Public License as published by
6       the Free Software Foundation; either version 2 of the License, or
7       (at your option) any later version.
8    
9       This program is distributed in the hope that it will be useful,
10      but WITHOUT ANY WARRANTY; without even the implied warranty of
11      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12      GNU General Public License for more details.
13   
14      You should have received a copy of the GNU General Public License
15      along with this program; if not, write to the Free Software
16      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17   
18   * Query.java
19   *
20   * Created on March 31, 2003, 7:53 PM
21   */
22  
23  package nectar.data;
24  
25  import java.util.Collection;
26  import java.util.Vector;
27  import nectar.record.Record;
28  import nectar.record.RecordDescriptor;
29  
30  /** Query objects are used to define the criteria for a query to the DataSource. It
31   * is essentially an object oriented analogy to SQL's SELECT statement. With this
32   * analogy, the variables that a Query is defined by could be described as:
33   * SELECT (list of fieldnames) FROM (list of tables) WHERE (dataConditions tree)
34   * (list of postElements).
35   *
36   * @author Kai Schutte skander@skander.com
37   */
38  public class Query {
39      private Vector fields = null;
40      private Vector extraFields = new Vector();
41      private Vector tables = null;
42      private DataConditions dcs = null;
43      private MatchConditions mcs = null;
44      private PostElements pes = null;
45      /** Creates a new empty instance of Query */
46      public Query() {
47          fields = new Vector();
48          tables = new Vector();
49      }
50      
51      /** Create a new instance of a Query object based on the criteria determined in the
52       * RecordDescriptor object.
53       * @param rd The RecordDescriptor defining a Record's general criteria.
54       */
55      public Query(RecordDescriptor rd) {
56          fields = new Vector();
57          tables = new Vector();
58          redefine(rd);
59      }
60      
61      /** reset this Query object so that it looks like a new object created with the
62       * empty constructor.
63       */    
64      public void reset() {
65          fields.clear();
66          extraFields.clear();
67          tables.clear();
68          dcs = null;
69          mcs = null;
70          pes = null;
71      }
72      
73      /** reset, then set all values according to the criteria defined in the given
74       * RecordDescriptor.
75       * @param rd The RecordDescriptor defining the query criteria.
76       */    
77      public void redefine(RecordDescriptor rd) {
78          reset();
79          String type = rd.getType();
80          addTable(Record.TABLE);
81          addTable(type);
82          addField(Record.FIELD_RECORD_ID);
83          addDataCondition(DataConditions.AND, new OperatorCondition(new FieldElement(Record.TABLE, Record.FIELD_RECORD_ID), OperatorCondition.EQUAL, new FieldElement(type, Record.FIELD_CHILD_ID)));
84          addDataCondition(DataConditions.AND, new OperatorCondition(new FieldElement(Record.TABLE, Record.FIELD_TYPE), OperatorCondition.EQUAL, new ValueElement(type)));
85          
86          Long owner = rd.getOwner();
87          if (owner == null) {
88              addDataCondition(DataConditions.AND, new FunctionCondition(FunctionCondition.ISNULL, new FieldElement(Record.TABLE, Record.FIELD_OWNER)));
89          } else if (owner.longValue() >= 0) {
90              addDataCondition(DataConditions.AND, new OperatorCondition(new FieldElement(Record.TABLE, Record.FIELD_OWNER), OperatorCondition.EQUAL, new ValueElement(owner.toString())));
91          }
92          
93          Long project = rd.getProject();
94          DataConditions projectDcs = new DataConditions();
95          projectDcs.append(DataConditions.OR, new FunctionCondition(FunctionCondition.ISNULL, new FieldElement(Record.TABLE, Record.FIELD_PROJECT)));
96          projectDcs.append(DataConditions.OR, new OperatorCondition(new FieldElement(Record.TABLE, Record.FIELD_PROJECT), OperatorCondition.EQUAL, new ValueElement(project.toString())));
97          addDataCondition(DataConditions.AND, projectDcs);
98          
99          String status = rd.getStatus();
100         if (status != null)
101             addDataCondition(DataConditions.AND, new OperatorCondition(new FieldElement(Record.TABLE, Record.FIELD_STATUS), OperatorCondition.EQUAL, new ValueElement(status)));
102     }
103     
104     /** Creates a new Query instance, with a shorthand to set the fields and tables from a Collection of field Strings and a Collection
105      * of table Strings.
106      * @param f Collection of field name strings.
107      * @param t Collection of table name strings.
108      */
109     public Query(Collection f, Collection t) {
110         this.fields = new Vector(f);
111         this.tables = new Vector(t);
112     }
113     
114     /** Creates a new instance of Query with field names, table names, DataConditions
115      * and PostElements set.
116      * @param f Collection of field names.
117      * @param t Collection of table names.
118      * @param d DataConditions construct to use in this Query.
119      * @param p PostElements construct to use in this Query.
120      *
121      */
122     public Query(Collection f, Collection t, DataConditions d, PostElements p) {
123         this.fields = new Vector(f);
124         this.tables = new Vector(t);
125         this.dcs = d;
126         this.pes = p;
127     }
128     
129     /** create a deep copy of this Query. As Query objects in their entirety may be
130      * rather complex, this method may put a pretty heavy load on the system if used
131      * frequently.
132      * @return a deep/recursive copy of this instance.
133      */
134     public Object clone() {
135         Query clone = new Query();
136         clone.fields = new Vector(this.fields);
137         clone.tables = new Vector(this.tables);
138         if (dcs != null)
139             clone.dcs = (DataConditions)dcs.clone();
140         if (pes != null)
141             clone.pes = (PostElements)pes.clone();
142         if (mcs != null)
143             clone.mcs = (MatchConditions)mcs.clone();
144         clone.extraFields = new Vector(this.extraFields);
145         return clone;
146     }
147     
148     /** get the Collection of field names defined in this query.
149      * @return the Collection of field name Strings.
150      */
151     public Collection getFields() { return fields; }
152     
153     /** Set the Collection of field names for this Query.
154      *
155      * Calling <CODE>setFields(null)</CODE> is equivalent to
156      * <CODE>clearFields()</CODE>.
157      * @param fields Collection of field name strings.
158      */
159     public void setFields(Collection fields) {
160         if (fields == null)
161             this.fields.clear();
162         else
163             this.fields = new Vector(fields);
164     }
165     
166     /** Clears the internal list of field names. */
167     public void clearFields() {
168         this.fields.clear();
169     }
170     /** append a field name to this Query.
171      * @param field the name of the field to add.
172      */
173     public void addField(String field) {
174         fields.add(field);
175     }
176     /** Returns a collection of extra field names. Extra field names are ones with have
177      * not been specified through setFields() or addField() but are necessary for this
178      * Query to work correctly. For example, adding a MatchCondition to a query will
179      * add an extra field to contain the score of a match.
180      * @return the Collection of extra field names.
181      */
182     public Collection getExtraFields() { return extraFields; }
183     
184     /** Return the collection of table name strings used in this Query.
185      * @return the collection of tables for this Query.
186      */
187     public Collection getTables() { return tables; }
188     /** Set the list of tables this Query uses.
189      *
190      * Calling <CODE>getTables(null)</CODE> is equivalent to
191      * <CODE>clearTables()</CODE>.
192      * @param tables the Collection of table names.
193      */
194     public void setTables(Collection tables) {
195         if (tables == null)
196             this.tables.clear();
197         else
198             this.tables = new Vector(tables);
199     }
200     
201     /** Clears the internal list of table names. */    
202     public void clearTables() {
203         this.tables.clear();
204     }
205     
206     /** add's a table name to the internal list in this Query.
207      * @param table Add a table name to this Query.
208      */
209     public void addTable(String table) {
210         if (tables == null)
211             tables = new Vector();
212         tables.add(table);
213     }
214     
215     /** returns the DataConditions for this Query.
216      * @return the dataConditions.
217      */
218     public DataConditions getDataConditions() { return dcs; }
219     /** Sets the DataConditions for this Query.
220      * @param dcs the DataConditions.
221      */
222     public void setDataConditions(DataConditions dcs) { this.dcs = dcs; }
223 
224     /** remove all data conditions from this Query. */    
225         public void clearDataConditions() {
226         this.dcs = null;
227     }
228 
229     
230     /** Append a DataCondition to the top level DataConditions object in this Query.
231      * @param operator AND/OR/NOT -- see {@link DataConditions}.
232      * @param dc The DataCondition to add.
233      */
234     public void addDataCondition(byte operator, DataCondition dc) {
235         if (dcs == null) dcs = new DataConditions(dc);
236         else dcs.append(operator, dc);
237     }
238     /** Append a DataConditions to the top level DataConditions object in this Query.
239      * @param operator AND/OR/NOT -- see {@link DataConditions}.
240      * @param dc The DataConditions to add.
241      */
242     public void addDataCondition(byte operator, DataConditions dc) {
243         if (dcs == null) dcs = new DataConditions(dc);
244         else dcs.append(operator, dc);
245     }
246     
247     /** Set the MatchConditions object for this Query.
248      * @param mcs the MatchConditions for this Query.
249      */
250     public void setMatchConditions(MatchConditions mcs) {
251         this.mcs = mcs;
252         extraFields.add(mcs.getReturnField());
253     }
254     
255     /** Returns the MatchConditions defined in this Query.
256      * @return the matchConditions object or null if it's undefined.
257      */
258     public MatchConditions getMatchConditions() {
259         return mcs;
260     }
261     
262     /** Returns the PostElements object for this Query.
263      * @return the PostElements object or null if undefined.
264      */
265     public PostElements getPostElements() { return pes; }
266     /** Sets the PostElements object for this Query.
267      * @param pes The PostElements object to set.
268      */
269     public void setPostElements(PostElements pes) { this.pes = pes; }
270     /** Append a PostElement to this Query's PostElements object.
271      * @param pe the PostElement to add.
272      */
273     public void addPostElement(PostElement pe) {
274         if (pes == null) { pes = new PostElements(); }
275         pes.set(pe);
276     }
277 }