KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > amber > field > EntityOneToManyField


1 /*
2  * Copyright (c) 1998-2006 Caucho Technology -- all rights reserved
3  *
4  * This file is part of Resin(R) Open Source
5  *
6  * Each copy or derived work must preserve the copyright notice and this
7  * notice unmodified.
8  *
9  * Resin Open Source is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * Resin Open Source is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
17  * of NON-INFRINGEMENT. See the GNU General Public License for more
18  * details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with Resin Open Source; if not, write to the
22  *
23  * Free Software Foundation, Inc.
24  * 59 Temple Place, Suite 330
25  * Boston, MA 02111-1307 USA
26  *
27  * @author Scott Ferguson
28  */

29
30 package com.caucho.amber.field;
31
32 import com.caucho.amber.expr.AmberExpr;
33 import com.caucho.amber.expr.OneToManyExpr;
34 import com.caucho.amber.expr.PathExpr;
35 import com.caucho.amber.query.QueryParser;
36 import com.caucho.amber.table.LinkColumns;
37 import com.caucho.amber.table.Table;
38 import com.caucho.amber.type.RelatedType;
39 import com.caucho.amber.type.Type;
40 import com.caucho.bytecode.JField;
41 import com.caucho.bytecode.JType;
42 import com.caucho.config.ConfigException;
43 import com.caucho.java.JavaWriter;
44 import com.caucho.log.Log;
45 import com.caucho.util.CharBuffer;
46 import com.caucho.util.L10N;
47
48 import javax.persistence.CascadeType;
49 import java.io.IOException JavaDoc;
50 import java.util.ArrayList JavaDoc;
51 import java.util.Map JavaDoc;
52 import java.util.Set JavaDoc;
53 import java.util.logging.Logger JavaDoc;
54
55 /**
56  * Represents a field to a collection of objects where the target
57  * hold a back-link to the source entity.
58  */

59 public class EntityOneToManyField extends CollectionField {
60   private static final L10N L = new L10N(EntityOneToManyField.class);
61   protected static final Logger JavaDoc log = Log.open(EntityOneToManyField.class);
62
63   private String JavaDoc _mapKey;
64
65   private ArrayList JavaDoc<String JavaDoc> _orderByFields;
66   private ArrayList JavaDoc<Boolean JavaDoc> _orderByAscending;
67
68   private EntityManyToOneField _sourceField;
69
70   public EntityOneToManyField(RelatedType entityType,
71                               String JavaDoc name,
72                               CascadeType[] cascadeTypes)
73     throws ConfigException
74   {
75     super(entityType, name, cascadeTypes);
76   }
77
78   public EntityOneToManyField(RelatedType entityType,
79                               String JavaDoc name)
80     throws ConfigException
81   {
82     this(entityType, name, null);
83   }
84
85   public EntityOneToManyField(RelatedType entityType)
86   {
87     super(entityType);
88   }
89
90   /**
91    * Sets the order by.
92    */

93   public void setOrderBy(ArrayList JavaDoc<String JavaDoc> orderByFields,
94                          ArrayList JavaDoc<Boolean JavaDoc> orderByAscending)
95   {
96     _orderByFields = orderByFields;
97     _orderByAscending = orderByAscending;
98   }
99
100   /**
101    * Returns the source type as
102    * entity or mapped-superclass.
103    */

104   public RelatedType getEntitySourceType()
105   {
106     return (RelatedType) getSourceType();
107   }
108
109   /**
110    * Returns the target type as
111    * entity or mapped-superclass.
112    */

113   public RelatedType getEntityTargetType()
114   {
115     return (RelatedType) getTargetType();
116   }
117
118   /**
119    * Returns the target type as entity.
120    */

121   public Type getTargetType()
122   {
123     return _sourceField.getSourceType();
124   }
125
126   /**
127    * Gets the source field.
128    */

129   public EntityManyToOneField getSourceField()
130   {
131     return _sourceField;
132   }
133
134   /**
135    * Sets the source field.
136    */

137   public void setSourceField(EntityManyToOneField sourceField)
138   {
139     _sourceField = sourceField;
140   }
141
142   /**
143    * Returns the link.
144    */

145   public LinkColumns getLinkColumns()
146   {
147     return _sourceField.getLinkColumns();
148   }
149
150   /**
151    * Gets the map key.
152    */

153   public String JavaDoc getMapKey()
154   {
155     return _mapKey;
156   }
157
158   /**
159    * Sets the map key.
160    */

161   public void setMapKey(String JavaDoc mapKey)
162   {
163     _mapKey = mapKey;
164   }
165
166   /**
167    * Initialize.
168    */

169   public void init()
170   {
171     if (_sourceField == null || getLinkColumns() == null)
172       throw new IllegalStateException JavaDoc();
173   }
174
175   /**
176    * Creates the expression for the field.
177    */

178   public AmberExpr createExpr(QueryParser parser, PathExpr parent)
179   {
180     return new OneToManyExpr(parser, parent, getLinkColumns());
181   }
182   /**
183    * Generates the (pre) cascade operation from
184    * parent to this child. This field will only
185    * be cascaded first if the operation can be
186    * performed with no risk to break FK constraints.
187    */

188   public void generatePreCascade(JavaWriter out,
189                                  String JavaDoc aConn,
190                                  CascadeType cascadeType)
191     throws IOException JavaDoc
192   {
193     if (cascadeType == CascadeType.PERSIST)
194       return;
195
196     generateInternalCascade(out, aConn, cascadeType);
197   }
198
199   /**
200    * Generates the (post) cascade operation from
201    * parent to this child. This field will only
202    * be cascaded first if the operation can be
203    * performed with no risk to break FK constraints.
204    */

205   public void generatePostCascade(JavaWriter out,
206                                   String JavaDoc aConn,
207                                   CascadeType cascadeType)
208     throws IOException JavaDoc
209   {
210     if (cascadeType != CascadeType.PERSIST)
211       return;
212
213     generateInternalCascade(out, aConn, cascadeType);
214   }
215
216   private void generateInternalCascade(JavaWriter out,
217                                        String JavaDoc aConn,
218                                        CascadeType cascadeType)
219     throws IOException JavaDoc
220   {
221     if (isCascade(cascadeType)) {
222
223       String JavaDoc getter = "_caucho_field_" + getGetterName(); // generateSuperGetter();
224

225       out.println("if (" + getter + " == null && " + generateSuperGetter() + " != null)");
226       out.pushDepth();
227       out.println(getSetterName() + "(" + generateSuperGetter() + ");");
228       out.popDepth();
229
230       out.println();
231       out.println("if (" + getter + " != null) {");
232       out.pushDepth();
233
234       out.println("for (Object o : " + getter + ") {");
235       out.pushDepth();
236
237       if (_sourceField != null) {
238         String JavaDoc typeName = getEntityTargetType().getJavaTypeName();
239         String JavaDoc setter = _sourceField.getSetterName();
240         out.println("((" + typeName + ") o)." + setter + "(this);");
241       }
242
243       out.print(aConn + ".");
244
245       switch (cascadeType) {
246       case PERSIST:
247         out.print("persistNoChecks");
248         break;
249
250       case MERGE:
251         out.print("merge");
252         break;
253
254       case REMOVE:
255         out.print("remove");
256         break;
257
258       case REFRESH:
259         out.print("refresh");
260         break;
261       }
262
263       out.println("(o);");
264
265       out.popDepth();
266       out.println("}");
267
268       out.popDepth();
269       out.println("}");
270     }
271   }
272
273   /**
274    * Generates the set clause.
275    */

276   public void generateSet(JavaWriter out, String JavaDoc pstmt,
277                           String JavaDoc obj, String JavaDoc index)
278     throws IOException JavaDoc
279   {
280   }
281
282   /**
283    * Generates the select clause.
284    */

285   public String JavaDoc generateLoadSelect(String JavaDoc id)
286   {
287     return null;
288   }
289
290   /**
291    * Updates from the cached copy.
292    */

293   public void generateCopyLoadObject(JavaWriter out,
294                                      String JavaDoc dst, String JavaDoc src,
295                                      int loadIndex)
296     throws IOException JavaDoc
297   {
298   }
299
300   /**
301    * Generates the target select.
302    */

303   public String JavaDoc generateTargetSelect(String JavaDoc id)
304   {
305     CharBuffer cb = CharBuffer.allocate();
306
307     Id key = getEntityTargetType().getId();
308
309     cb.append(key.generateSelect(id));
310
311     String JavaDoc value = getEntityTargetType().generateLoadSelect(id);
312
313     if (cb.length() > 0 && value.length() > 0)
314       cb.append(", ");
315
316     cb.append(value);
317
318     return cb.close();
319   }
320
321   /**
322    * Generates the set property.
323    */

324   public void generateGetProperty(JavaWriter out)
325     throws IOException JavaDoc
326   {
327     String JavaDoc var = "_caucho_field_" + getGetterName();
328
329     boolean isSet = getJavaType().isAssignableTo(Set JavaDoc.class);
330     boolean isMap = false;
331     if (!isSet) {
332       isMap = getJavaType().isAssignableTo(Map JavaDoc.class);
333     }
334
335     JType type = getJavaType();
336     JType []paramArgs = type.getActualTypeArguments();
337     JType param = paramArgs.length > 0 ? paramArgs[0] : null;
338     JType param2 = paramArgs.length > 1 ? paramArgs[1] : null;
339
340     out.print("private ");
341
342     String JavaDoc collectionImpl;
343
344     if (isSet)
345       collectionImpl = "com.caucho.amber.collection.SetImpl";
346     else if (isMap)
347       collectionImpl = "com.caucho.amber.collection.MapImpl";
348     else
349       collectionImpl = "com.caucho.amber.collection.CollectionImpl";
350
351     out.print(collectionImpl);
352
353     if (param != null) {
354       out.print("<");
355       out.print(param.getPrintName());
356       if (isMap) {
357         if (param2 != null) {
358           out.print(", ");
359           out.print(param2.getPrintName());
360         }
361       }
362       out.print(">");
363     }
364
365     out.println(" " + var + ";");
366
367     out.println();
368     out.println("public " + getJavaTypeName() + " " + getGetterName() + "()");
369     out.println("{");
370     out.pushDepth();
371
372     out.println("if (" + var + " != null) {");
373     out.pushDepth();
374     out.println(var + ".setSession(__caucho_session);");
375     out.println("return " + var + ";");
376     out.popDepth();
377     out.println("}");
378
379     out.println("if (__caucho_session == null) {");
380     if (! isAbstract()) {
381       out.println(" return super." + getGetterName() + "();");
382     }
383     out.println("}");
384
385     out.println("try {");
386     out.pushDepth();
387
388     out.print("String sql=\"");
389
390     out.print("SELECT c");
391     out.print(" FROM " + getEntitySourceType().getName() + " o,");
392     out.print(" o." + getName() + " c");
393     out.print(" WHERE ");
394     out.print(getEntitySourceType().getId().generateRawWhere("o"));
395
396     if (_orderByFields != null) {
397       out.print(" ORDER BY ");
398
399       for (int i = 0; i < _orderByFields.size(); i++) {
400         if (i != 0)
401           out.print(", ");
402
403         out.print("c." + _orderByFields.get(i));
404         if (Boolean.FALSE.equals(_orderByAscending.get(i)))
405           out.print(" DESC");
406       }
407     }
408
409     out.println("\";");
410     out.println("com.caucho.amber.AmberQuery query;");
411     out.println("query = __caucho_session.prepareQuery(sql);");
412
413     out.println("int index = 1;");
414     getEntitySourceType().getId().generateSet(out, "query", "index", "this");
415
416     // Ex: _caucho_getChildren = new com.caucho.amber.collection.CollectionImpl
417
out.print(var);
418     out.print(" = new ");
419     out.print(collectionImpl);
420
421     if (param != null) {
422       out.print("<");
423       out.print(param.getPrintName());
424       if (isMap) {
425         out.print(", ");
426         out.print(param2.getPrintName());
427       }
428       out.print(">");
429     }
430
431     out.print("(query");
432     if (isMap) {
433       out.println(",");
434       out.pushDepth();
435       out.print(getEntityTargetType().getBeanClass().getName());
436       out.print(".class.getDeclaredMethod(\"get");
437       String JavaDoc getterMapKey = getMapKey();
438       getterMapKey = Character.toUpperCase(getterMapKey.charAt(0)) + getterMapKey.substring(1);
439       out.print(getterMapKey); // "getId");
440
out.print("\", null)");
441       out.popDepth();
442     }
443     out.println(");");
444
445     /*
446       out.pushDepth();
447
448       //generateAdd(out);
449       //generateRemove(out);
450       //generateClear(out);
451       // generateSize(out);
452
453       out.popDepth();
454       out.println("};");
455     */

456
457     out.println();
458     out.println("return " + var + ";");
459
460     out.popDepth();
461     out.println("} catch (Exception e) {");
462     out.println(" throw com.caucho.amber.AmberRuntimeException.create(e);");
463     out.println("}");
464
465     out.popDepth();
466     out.println("}");
467   }
468
469   /**
470    * Generates the size method.
471    */

472   private void generateSize(JavaWriter out)
473     throws IOException JavaDoc
474   {
475     out.println("public int size()");
476     out.println("{");
477     out.pushDepth();
478
479     out.println("if (__caucho_session == null || isValid())");
480     out.println(" return super.size();");
481
482     out.println("try {");
483     out.pushDepth();
484
485     out.println("__caucho_session.flushNoChecks();");
486
487     out.print("String sql=\"");
488
489     out.print("SELECT count(*) FROM ");
490     out.print(getEntitySourceType().getName());
491     out.print(" AS o ");
492
493     out.print(" WHERE ");
494
495     // getKeyColumn().generateRawMatchArgWhere("o");
496

497     ArrayList JavaDoc<IdField> keys = getEntitySourceType().getId().getKeys();
498     for (int i = 0; i < keys.size(); i++) {
499       if (i != 0)
500         out.print(" AND ");
501
502       out.print("o." + keys.get(i).getName());
503       out.print("=?");
504     }
505
506     out.println("\";");
507     out.println("com.caucho.amber.AmberQuery query;");
508     out.println("query = __caucho_session.prepareQuery(sql);");
509
510     out.println("int index = 1;");
511
512     // ejb/06h0
513
getEntitySourceType().getId().generateSet(out, "query", "index", getEntitySourceType().getInstanceClassName() + ".this"); // "__ResinExt.this");
514

515     out.println("java.sql.ResultSet rs = query.executeQuery();");
516
517     out.println("if (rs.next())");
518     out.println(" return rs.getInt(1);");
519     out.println("else");
520     out.println(" return 0;");
521
522     out.popDepth();
523     out.println("} catch (java.sql.SQLException e) {");
524     out.println(" throw com.caucho.amber.AmberRuntimeException.create(e);");
525     out.println("}");
526
527     out.popDepth();
528     out.println("}");
529   }
530
531   /**
532    * Generates the set property.
533    */

534   public void generateSetProperty(JavaWriter out)
535     throws IOException JavaDoc
536   {
537     // commented out: jpa/0s2d
538
// JMethod setter = getSetterMethod();
539
//
540
// if (setter == null)
541
// return;
542
//
543
// JClass []paramTypes = setter.getParameterTypes();
544

545     JType type;
546
547     if (! getEntitySourceType().isFieldAccess()) {
548       type = getGetterMethod().getGenericReturnType();
549     }
550     else {
551       JField field = RelatedType.getField(getBeanClass(), getName());
552       type = field.getGenericType();
553     }
554
555     out.println();
556     // commented out: jpa/0s2d
557
// out.print("public void " + setter.getName() + "(");
558
// out.print(getJavaTypeName() + " value)");
559
out.print("public void " + getSetterName() + "(");
560     out.print(type.getName() + " value)");
561     out.println("{");
562     out.pushDepth();
563
564     // out.println("if (" + generateSuperGetter() + " == value)");
565
// out.println(" return;");
566
// out.println();
567

568     //
569
// jpa/0j57 needs to generate the following snippet:
570
//
571
// _caucho___caucho_get_xAnnualReviews
572
// = new com.caucho.amber.collection.CollectionImpl<qa.XAnnualReview>(__caucho_session, null);
573
// _caucho___caucho_get_xAnnualReviews.addAll(0, value);
574
//
575
// jpa/0j57:
576

577     out.println("try {");
578     out.pushDepth();
579
580     String JavaDoc var = "_caucho_field_" + getGetterName();
581
582     out.print(var + " = new ");
583
584     type = getJavaType();
585
586     boolean isSet = type.isAssignableTo(Set JavaDoc.class);
587     boolean isMap = false;
588     if (!isSet) {
589       isMap = type.isAssignableTo(Map JavaDoc.class);
590     }
591
592     JType []paramArgs = type.getActualTypeArguments();
593     JType param = paramArgs.length > 0 ? paramArgs[0] : null;
594     JType param2 = paramArgs.length > 1 ? paramArgs[1] : null;
595
596     String JavaDoc collectionImpl;
597
598     if (isSet)
599       collectionImpl = "com.caucho.amber.collection.SetImpl";
600     else if (isMap)
601       collectionImpl = "com.caucho.amber.collection.MapImpl";
602     else
603       collectionImpl = "com.caucho.amber.collection.CollectionImpl";
604
605     out.print(collectionImpl);
606
607     if (param != null) {
608       out.print("<");
609       out.print(param.getPrintName());
610       if (isMap) {
611         if (param2 != null) {
612           out.print(", ");
613           out.print(param2.getPrintName());
614         }
615       }
616       out.print(">");
617     }
618
619     out.print("(__caucho_session, null");
620     if (isMap) {
621       out.print(", ");
622       out.print(getEntityTargetType().getBeanClass().getName());
623       out.print(".class.getDeclaredMethod(\"get");
624       String JavaDoc getterMapKey = getMapKey();
625       getterMapKey = Character.toUpperCase(getterMapKey.charAt(0)) + getterMapKey.substring(1);
626       out.print(getterMapKey); // "getId");
627
out.print("\")");
628     }
629     out.println(");");
630
631     out.print(var + ".");
632
633     if (isMap)
634       out.println("putAll(value);");
635     else if (isSet)
636       out.println("addAll(value);");
637     else
638       out.println("addAll(0, value);");
639
640     out.popDepth();
641     out.println("} catch(Exception e) {");
642     out.println(" throw com.caucho.amber.AmberRuntimeException.create(e);");
643     out.println("}");
644
645     out.popDepth();
646     out.println("}");
647   }
648
649   /**
650    * Generates code for foreign entity create/delete
651    */

652   public void generateInvalidateForeign(JavaWriter out)
653     throws IOException JavaDoc
654   {
655     Table table = getLinkColumns().getSourceTable();
656
657     out.println("if (\"" + table.getName() + "\".equals(table)) {");
658     out.pushDepth();
659
660     String JavaDoc var = "_caucho_field_" + getGetterName();
661
662     out.println("if (" + var + " != null)");
663     out.println(" " + var + ".update();");
664     out.popDepth();
665     out.println("}");
666   }
667
668   /**
669    * Generates the expire code
670    *
671    * ejb/06hi
672    */

673   public void generateExpire(JavaWriter out)
674     throws IOException JavaDoc
675   {
676     String JavaDoc var = "_caucho_field_" + getGetterName();
677
678     out.println(var + " = null;");
679   }
680 }
681
Popular Tags