KickJava   Java API By Example, From Geeks To Geeks.

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


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.Map JavaDoc;
18 import java.util.TreeMap JavaDoc;
19 import java.util.LinkedHashMap JavaDoc;
20 import java.util.List JavaDoc;
21 import java.util.Iterator JavaDoc;
22
23 import java.lang.reflect.Constructor JavaDoc;
24
25 import org.josql.internal.Setter;
26 import org.josql.internal.Utilities;
27
28 import org.josql.Query;
29 import org.josql.QueryParseException;
30 import org.josql.QueryExecutionException;
31
32 public class NewObjectExpression extends ValueExpression
33 {
34
35     private String JavaDoc cn = null;
36     private Class JavaDoc clazz = null;
37     private List JavaDoc constructorArgs = null;
38     private Map JavaDoc intoExps = null;
39     private Constructor JavaDoc constructor = null;
40     private Object JavaDoc[] conParms = null;
41     private int argsSize = -1;
42
43     public void addIntoExpression (Expression exp,
44                    String JavaDoc setter)
45     {
46
47     if (this.intoExps == null)
48     {
49
50         this.intoExps = new LinkedHashMap JavaDoc ();
51
52     }
53
54     this.intoExps.put (exp,
55                setter);
56
57     }
58
59     public void setConstructorArgs (List JavaDoc exps)
60     {
61
62     this.constructorArgs = exps;
63
64     this.argsSize = exps.size () - 1;
65
66     }
67
68     public void setClassName (String JavaDoc c)
69     {
70
71     this.cn = c;
72
73     }
74
75     public boolean hasFixedResult (Query q)
76     {
77
78     return false;
79
80     }
81
82     public Class JavaDoc getExpectedReturnType (Query q)
83                                     throws QueryParseException
84     {
85
86     return this.clazz;
87
88     }
89
90     public void init (Query q)
91                   throws QueryParseException
92     {
93
94     // Load the class.
95
try
96     {
97
98         // Load via the custom (if present) classloader.
99
this.clazz = q.getClassLoader ().loadClass (this.cn);
100
101     } catch (Exception JavaDoc e) {
102
103         throw new QueryParseException ("Unable to load class: " +
104                        this.cn,
105                        e);
106
107     }
108
109     Class JavaDoc[] conTypes = null;
110
111     // Init all the constructor arg expressions, if provided.
112
if (this.constructorArgs != null)
113     {
114
115         conTypes = new Class JavaDoc [this.constructorArgs.size ()];
116
117         this.conParms = new Object JavaDoc[this.constructorArgs.size ()];
118
119         for (int i = 0; i < this.constructorArgs.size (); i++)
120         {
121
122         Expression exp = (Expression) this.constructorArgs.get (i);
123
124         exp.init (q);
125
126         conTypes[i] = exp.getExpectedReturnType (q);
127
128         }
129
130     }
131
132     TreeMap JavaDoc tm = new TreeMap JavaDoc ();
133
134     Constructor JavaDoc[] cons = this.clazz.getConstructors ();
135
136     for (int i = 0; i < cons.length; i++)
137     {
138
139         int score = Utilities.matchMethodArgs (cons[i].getParameterTypes (),
140                            conTypes);
141
142         if (score > 0)
143         {
144
145         tm.put (new Integer JavaDoc (score),
146             cons[i]);
147
148         }
149
150     }
151
152     if (tm.size () > 0)
153     {
154
155         this.constructor = (Constructor JavaDoc) tm.get (tm.lastKey ());
156
157     }
158
159     // Now try and find the constructor.
160
if (this.constructor == null)
161     {
162
163         throw new QueryParseException ("Unable to find constructor: " +
164                        Utilities.formatSignature (this.clazz.getName (),
165                                       conTypes));
166
167     }
168
169     // Now init any setters.
170
if (this.intoExps != null)
171     {
172
173         Iterator JavaDoc iter = this.intoExps.keySet ().iterator ();
174
175         Class JavaDoc[] pts = new Class JavaDoc[1];
176
177         while (iter.hasNext ())
178         {
179
180         Expression exp = (Expression) iter.next ();
181
182         String JavaDoc setName = (String JavaDoc) this.intoExps.get (exp);
183
184         exp.init (q);
185
186         pts[0] = exp.getExpectedReturnType (q);
187
188         // Create the Setter.
189
Setter set = null;
190
191         try
192         {
193
194             set = new Setter (setName,
195                       this.clazz,
196                       pts);
197
198         } catch (Exception JavaDoc e) {
199
200             throw new QueryParseException ("Unable to create setter for: " +
201                            setName,
202                            e);
203
204         }
205
206         this.intoExps.put (exp,
207                    set);
208
209         }
210
211     }
212
213     }
214
215     /**
216      * Always return <code>true</code> because a new object is being created and thus
217      * will be unequal to null.
218      *
219      * @param o The object currently in "scope".
220      * @param q The Query object.
221      * @return <code>true</code> always.
222      */

223     public boolean isTrue (Object JavaDoc o,
224                Query q)
225     {
226
227     return true;
228
229     }
230
231     public Object JavaDoc evaluate (Object JavaDoc o,
232                 Query q)
233                         throws QueryExecutionException
234     {
235
236     return this.getValue (o,
237                   q);
238
239     }
240
241     public Object JavaDoc getValue (Object JavaDoc o,
242                 Query q)
243                         throws QueryExecutionException
244     {
245
246     // Need to create a new object.
247
if (this.constructorArgs != null)
248     {
249
250         for (int i = this.argsSize; i > -1; i--)
251         {
252
253         Expression exp = (Expression) this.constructorArgs.get (i);
254
255         try
256         {
257
258             this.conParms[i] = exp.getValue (o,
259                              q);
260
261         } catch (Exception JavaDoc e) {
262
263             throw new QueryExecutionException ("Unable to evaluate constructor argument expression: " +
264                                exp,
265                                e);
266
267         }
268
269         }
270
271     }
272
273     // Execute the constructor.
274
Object JavaDoc obj = null;
275
276     try
277     {
278
279         obj = this.constructor.newInstance (Utilities.convertArgs (this.conParms,
280                                        this.constructor.getParameterTypes ()));
281
282     } catch (Exception JavaDoc e) {
283
284         throw new QueryExecutionException ("Unable to create new instance of: " +
285                            this.clazz.getName () +
286                            " using constructor: " +
287                            this.constructor +
288                            ", passing parameters: " +
289                            this.conParms,
290                            e);
291
292     }
293
294     // See if we have any setters.
295
if (this.intoExps != null)
296     {
297
298         Iterator JavaDoc iter = this.intoExps.keySet ().iterator ();
299
300         while (iter.hasNext ())
301         {
302
303         Expression exp = (Expression) iter.next ();
304
305         Setter set = (Setter) this.intoExps.get (exp);
306
307         Object JavaDoc so = null;
308
309         // Eval the expression.
310
try
311         {
312
313             so = exp.getValue (o,
314                        q);
315
316         } catch (Exception JavaDoc e) {
317
318             throw new QueryExecutionException ("Unable to evaluate expression: " +
319                                exp +
320                                " for setter: " +
321                                set +
322                                " on class: " +
323                                this.clazz.getName (),
324                                e);
325
326         }
327
328         try
329         {
330
331             set.setValue (obj,
332                   so);
333
334         } catch (Exception JavaDoc e) {
335
336             String JavaDoc cn = null + "";
337
338             if (so != null)
339             {
340
341             cn = so.getClass ().getName ();
342
343             }
344
345             throw new QueryExecutionException ("Unable to set value of type: " +
346                                cn +
347                                " in object of type: " +
348                                this.clazz.getName () +
349                                " using setter: " +
350                                set +
351                                " (value is result of expression: " +
352                                exp +
353                                ")",
354                                e);
355
356         }
357
358         }
359
360     }
361
362     return obj;
363
364     }
365
366     public String JavaDoc toString ()
367     {
368
369     StringBuffer JavaDoc b = new StringBuffer JavaDoc ("new ");
370     b.append (this.clazz.getName ());
371     b.append (" (");
372     
373     if (this.constructorArgs != null)
374     {
375
376         for (int i = 0; i < this.constructorArgs.size (); i++)
377         {
378
379         Expression exp = (Expression) this.constructorArgs.get (i);
380
381         b.append (exp);
382
383         if (i < this.constructorArgs.size () - 1)
384         {
385
386             b.append (", ");
387
388         }
389
390         }
391
392     }
393
394     b.append (")");
395
396     if (this.intoExps != null)
397     {
398
399         b.append (" {");
400
401         Iterator JavaDoc iter = this.intoExps.keySet ().iterator ();
402
403         while (iter.hasNext ())
404         {
405
406         Expression exp = (Expression) iter.next ();
407
408         b.append (exp);
409
410         b.append (" -> ");
411
412         Object JavaDoc obj = this.intoExps.get (exp);
413
414         if (obj instanceof Setter)
415         {
416
417             Setter set = (Setter) obj;
418
419             b.append (set);
420
421         }
422
423         if (obj instanceof String JavaDoc)
424         {
425
426             b.append ((String JavaDoc) obj);
427
428         }
429
430         if (iter.hasNext ())
431         {
432
433             b.append (", ");
434
435         }
436
437         }
438
439         b.append ("}");
440
441     }
442
443     return b.toString ();
444
445     }
446
447 }
448
Popular Tags