KickJava   Java API By Example, From Geeks To Geeks.

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


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.PathExpr;
34 import com.caucho.amber.manager.AmberConnection;
35 import com.caucho.amber.manager.AmberPersistenceUnit;
36 import com.caucho.amber.query.QueryParser;
37 import com.caucho.amber.table.Table;
38 import com.caucho.amber.type.AbstractStatefulType;
39 import com.caucho.amber.type.RelatedType;
40 import com.caucho.bytecode.JClass;
41 import com.caucho.bytecode.JClassWrapper;
42 import com.caucho.bytecode.JField;
43 import com.caucho.bytecode.JMethod;
44 import com.caucho.bytecode.JType;
45 import com.caucho.config.ConfigException;
46 import com.caucho.java.JavaWriter;
47 import com.caucho.log.Log;
48 import com.caucho.util.CharBuffer;
49 import com.caucho.util.L10N;
50
51 import java.io.IOException JavaDoc;
52 import java.io.Serializable JavaDoc;
53 import java.sql.SQLException JavaDoc;
54 import java.util.ArrayList JavaDoc;
55 import java.util.HashSet JavaDoc;
56 import java.util.logging.Logger JavaDoc;
57
58 /**
59  * Configuration for a bean's property
60  */

61 abstract public class AbstractField implements AmberField {
62   private static final L10N L = new L10N(AbstractField.class);
63   protected static final Logger JavaDoc log = Log.open(AbstractField.class);
64
65   private AbstractStatefulType _sourceType;
66
67   private String JavaDoc _name;
68
69   private JType _javaType;
70
71   private JMethod _getterMethod;
72   private JMethod _setterMethod;
73
74   private boolean _isLazy = true;
75
76   private int _updateIndex;
77   private int _loadGroupIndex = -1;
78
79   AbstractField(AbstractStatefulType sourceType)
80   {
81     _sourceType = sourceType;
82   }
83
84   AbstractField(AbstractStatefulType sourceType, String JavaDoc name)
85     throws ConfigException
86   {
87     this(sourceType);
88
89     setName(name);
90   }
91
92   /**
93    * Sets the name.
94    */

95   public void setName(String JavaDoc name)
96     throws ConfigException
97   {
98     _name = name;
99
100     if (! getSourceType().isFieldAccess()) {
101       char ch = name.charAt(0);
102       if (Character.isLowerCase(ch))
103         name = Character.toUpperCase(ch) + name.substring(1);
104
105       String JavaDoc getter = "get" + name;
106       String JavaDoc setter = "set" + name;
107
108       _getterMethod = AbstractStatefulType.getGetter(getBeanClass(), getter);
109
110       if (_getterMethod == null) {
111         getter = "is" + name;
112         _getterMethod = AbstractStatefulType.getGetter(getBeanClass(), getter);
113       }
114
115       /* jpa/0u21
116       if (_getterMethod == null)
117         throw new ConfigException(L.l("{0}: {1} has no matching getter.",
118                                       getBeanClass().getName(), name));
119       */

120
121       if (_getterMethod == null) {
122         JField field = AbstractStatefulType.getField(getBeanClass(), _name);
123
124         if (field == null)
125           throw new ConfigException(L.l("{0}: {1} has no matching field.",
126                                         getBeanClass().getName(), _name));
127
128         _javaType = field.getGenericType();
129       }
130       else {
131         _javaType = _getterMethod.getGenericReturnType();
132
133         _setterMethod = AbstractStatefulType.getSetter(getBeanClass(), setter);
134       }
135     }
136     else {
137       JField field = AbstractStatefulType.getField(getBeanClass(), name);
138
139       if (field == null)
140         throw new ConfigException(L.l("{0}: {1} has no matching field.",
141                                       getBeanClass().getName(), name));
142
143       _javaType = field.getGenericType();
144     }
145
146     /*
147       if (_setterMethod == null && ! isAbstract())
148       throw new ConfigException(L.l("{0}: {1} has no matching setter.",
149       getBeanClass().getName(), name));
150     */

151   }
152
153   /**
154    * Returns the field name.
155    */

156   public String JavaDoc getName()
157   {
158     return _name;
159   }
160
161   /**
162    * Sets the java type.
163    */

164   protected void setJavaType(JType type)
165   {
166     _javaType = type;
167   }
168
169   /**
170    * Sets the java type.
171    */

172   protected void setJavaType(Class JavaDoc type)
173   {
174     setJavaType(new JClassWrapper(type, getPersistenceUnit().getJClassLoader()));
175   }
176
177   /**
178    * Returns the owning entity class.
179    */

180   public AbstractStatefulType getSourceType()
181   {
182     return _sourceType;
183   }
184
185   /**
186    * Returns the amber manager.
187    */

188   public AmberPersistenceUnit getPersistenceUnit()
189   {
190     return getSourceType().getPersistenceUnit();
191   }
192
193   /**
194    * Returns the bean class.
195    */

196   public JClass getBeanClass()
197   {
198     return getSourceType().getBeanClass();
199   }
200
201   /**
202    * Returns the source type as
203    * entity or mapped-superclass.
204    */

205   public RelatedType getEntitySourceType()
206   {
207     return (RelatedType) getSourceType();
208   }
209
210   /**
211    * Returns the table containing the field's columns.
212    */

213   public Table getTable()
214   {
215     return getEntitySourceType().getTable();
216   }
217
218   /**
219    * Returns the property index.
220    */

221   public int getIndex()
222   {
223     return _updateIndex;
224   }
225
226   /**
227    * Set the property index.
228    */

229   public void setIndex(int index)
230   {
231     _updateIndex = index;
232   }
233
234   /**
235    * Returns the property's group index.
236    */

237   public int getLoadGroupIndex()
238   {
239     return _loadGroupIndex;
240   }
241
242   /**
243    * Returns the load group mask.
244    */

245   public long getCreateLoadMask(int group)
246   {
247     int index = getLoadGroupIndex();
248
249     if (64 * group <= index && index < 64 * (group + 1))
250       return 1L << (index % 64);
251     else
252       return 0;
253   }
254
255   /**
256    * Returns true for a lazy field.
257    */

258   public boolean isLazy()
259   {
260     return _isLazy;
261   }
262
263   /**
264    * Set true for a lazy field.
265    */

266   public void setLazy(boolean isLazy)
267   {
268     _isLazy = isLazy;
269   }
270
271   /**
272    * Returns the getter method.
273    */

274   public JMethod getGetterMethod()
275   {
276     return _getterMethod;
277   }
278
279   /**
280    * Returns the getter name.
281    */

282   public String JavaDoc getGetterName()
283   {
284     if (getSourceType().isFieldAccess())
285       return "__caucho_get_" + getName();
286     else
287       return _getterMethod.getName();
288   }
289
290   /**
291    * Returns the getter name.
292    */

293   public String JavaDoc getJavaTypeName()
294   {
295     return getJavaType().getPrintName();
296   }
297
298   /**
299    * Returns the Java code for the type.
300    */

301   private String JavaDoc getJavaTypeName(Class JavaDoc cl)
302   {
303     if (cl.isArray())
304       return getJavaTypeName(cl.getComponentType()) + "[]";
305     else
306       return cl.getName();
307   }
308
309   /**
310    * Returns the field's type
311    */

312   public JType getJavaType()
313   {
314     return _javaType;
315   }
316
317   /**
318    * Returns the setter method.
319    */

320   public JMethod getSetterMethod()
321   {
322     return _setterMethod;
323   }
324
325   /**
326    * Returns the setter name.
327    */

328   public String JavaDoc getSetterName()
329   {
330     if (getSourceType().isFieldAccess())
331       return "__caucho_set_" + getName();
332     else if (_setterMethod != null)
333       return _setterMethod.getName();
334     else
335       return "set" + getGetterName().substring(3);
336   }
337
338   /**
339    * Returns true if values are accessed by the fields.
340    */

341   public boolean isFieldAccess()
342   {
343     return getSourceType().isFieldAccess();
344   }
345
346   /**
347    * Returns true if the methods are abstract.
348    */

349   public boolean isAbstract()
350   {
351     // jpa/0u21
352

353     if (getSourceType().isFieldAccess() || getSourceType().isIdClass())
354       return true;
355     else if (_getterMethod == null)
356       return false;
357     else
358       return _getterMethod.isAbstract();
359   }
360
361   /**
362    * Returns true if the field is cascadable.
363    */

364   public boolean isCascadable()
365   {
366     return false;
367   }
368
369   /**
370    * Returns true if the methods are abstract.
371    */

372   public boolean isUpdateable()
373   {
374     return true;
375   }
376
377   /**
378    * Initialize the field.
379    */

380   public void init()
381     throws ConfigException
382   {
383     if (_loadGroupIndex < 0) {
384       if (_isLazy)
385         _loadGroupIndex = getEntitySourceType().nextLoadGroupIndex();
386       else
387         _loadGroupIndex = getEntitySourceType().getDefaultLoadGroupIndex();
388     }
389   }
390
391   /**
392    * Generates the post constructor initialization.
393    */

394   public void generatePostConstructor(JavaWriter out)
395     throws IOException JavaDoc
396   {
397   }
398
399   /**
400    * Generates any prologue.
401    */

402   public void generatePrologue(JavaWriter out, HashSet JavaDoc<Object JavaDoc> completedSet)
403     throws IOException JavaDoc
404   {
405     if (isAbstract()) {
406       out.println();
407       out.print("public ");
408       out.print(getJavaType().getPrintName());
409       out.print(" " + getFieldName() + ";");
410     }
411   }
412
413   /**
414    * Generates the select clause for an entity load.
415    */

416   public String JavaDoc generateLoadSelect(Table table, String JavaDoc id)
417   {
418     return null;
419   }
420
421   /**
422    * Generates the select clause.
423    */

424   public String JavaDoc generateSelect(String JavaDoc id)
425   {
426     return null;
427   }
428
429   /**
430    * Generates the JPA QL select clause.
431    */

432   public String JavaDoc generateJavaSelect(String JavaDoc id)
433   {
434     return null;
435   }
436
437   /**
438    * Generates the where clause.
439    */

440   public String JavaDoc generateWhere(String JavaDoc id)
441   {
442     return null;
443   }
444
445   /**
446    * Generates the where clause.
447    */

448   public void generateUpdate(CharBuffer sql)
449   {
450   }
451
452   /**
453    * Generates loading cache
454    */

455   public void generateUpdate(JavaWriter out, String JavaDoc maskVar, String JavaDoc pstmt,
456                              String JavaDoc index)
457     throws IOException JavaDoc
458   {
459     int group = getIndex() / 64;
460     long mask = 1L << getIndex() % 64;
461
462     out.println();
463     out.println("if ((" + maskVar + "_" + group + " & " + mask + "L) != 0) {");
464     out.pushDepth();
465
466     generateSet(out, pstmt, index);
467
468     out.popDepth();
469     out.println("}");
470   }
471
472   /**
473    * Generates loading code
474    */

475   public boolean hasLoadGroup(int index)
476   {
477     return index == _loadGroupIndex;
478   }
479
480   /**
481    * Generates loading code
482    */

483   public int generateLoad(JavaWriter out, String JavaDoc rs,
484                           String JavaDoc indexVar, int index)
485     throws IOException JavaDoc
486   {
487     return index;
488   }
489
490   /**
491    * Generates loading code
492    */

493   public int generateLoadEager(JavaWriter out, String JavaDoc rs,
494                                String JavaDoc indexVar, int index)
495     throws IOException JavaDoc
496   {
497     return index;
498   }
499
500   /**
501    * Generates loading cache
502    */

503   public void generateLoadFromObject(JavaWriter out, String JavaDoc obj)
504     throws IOException JavaDoc
505   {
506     if (getGetterMethod() == null || getSetterMethod() == null)
507       return;
508
509     String JavaDoc getter = getGetterName();
510
511     String JavaDoc loadVar = "__caucho_loadMask_" + (getLoadGroupIndex() / 64);
512     long loadMask = (1L << getLoadGroupIndex());
513
514     out.println("if ((" + loadVar + " & " + loadMask + "L) != 0)");
515     out.print(" ");
516
517     out.println(" " + generateSuperSetter(generateGet(obj)) + ";");
518   }
519
520   /**
521    * Generates loading cache
522    */

523   public void generateSet(JavaWriter out, String JavaDoc obj)
524     throws IOException JavaDoc
525   {
526     out.println(generateSuperSetter(obj) + ";");
527   }
528
529   /**
530    * Generates loading cache
531    */

532   public void generateUpdateFromObject(JavaWriter out, String JavaDoc obj)
533     throws IOException JavaDoc
534   {
535     out.println(generateSuperSetter(generateGet(obj)) + ";");
536   }
537
538   /**
539    * Generates the field getter.
540    *
541    * @param value the non-null value
542    */

543   public void generateGet(JavaWriter out, String JavaDoc value)
544     throws IOException JavaDoc
545   {
546     out.print(generateGet(value));
547   }
548
549   /**
550    * Returns the null value.
551    */

552   public String JavaDoc generateNull()
553   {
554     return "null";
555   }
556
557   /**
558    * Generates the field getter.
559    *
560    * @param value the non-null value
561    */

562   public String JavaDoc generateGet(String JavaDoc obj)
563   {
564     if (obj == null)
565       return generateNull();
566
567     if (obj.equals("super"))
568       return generateSuperGetter();
569     else if (! isAbstract())
570       return obj + "." + _getterMethod.getName() + "()";
571     else if (_getterMethod != null)
572       return obj + "." + _getterMethod.getName() + "()";
573     else
574       return obj + "." + getFieldName();
575   }
576
577   /**
578    * Generates the field setter.
579    *
580    * @param value the non-null value
581    */

582   public String JavaDoc generateSet(String JavaDoc obj, String JavaDoc value)
583   {
584     if (obj.equals("super"))
585       return generateSuperSetter(value);
586     else if (isAbstract())
587       return obj + "." + getFieldName() + " = " + value;
588     else if (_setterMethod != null)
589       return obj + "." + _setterMethod.getName() + "(" + value + ")";
590     else
591       return ""; // ejb/0gb9
592
}
593
594   /**
595    * Returns the field name.
596    */

597   protected String JavaDoc getFieldName()
598   {
599     return "__amber_" + getName();
600   }
601
602   /**
603    * Generates the insert.
604    */

605   public final String JavaDoc generateInsert()
606   {
607     return null;
608   }
609
610   /**
611    * Generates the insert.
612    */

613   public void generateInsertColumns(ArrayList JavaDoc<String JavaDoc> columns)
614   {
615   }
616
617   /**
618    * Generates the get property.
619    */

620   public void generateGetProperty(JavaWriter out)
621     throws IOException JavaDoc
622   {
623
624   }
625
626   /**
627    * Generates the set property.
628    */

629   public void generateSetProperty(JavaWriter out)
630     throws IOException JavaDoc
631   {
632   }
633
634   /**
635    * Returns the actual data.
636    */

637   public String JavaDoc generateSuperGetter()
638   {
639     /*
640       if (isAbstract() || getGetterMethod() == null)
641       return getFieldName();
642       else
643     */

644     return("__caucho_super_get_" + getName() + "()");
645   }
646
647   /**
648    * Sets the actual data.
649    */

650   public String JavaDoc generateSuperSetter(String JavaDoc value)
651   {
652     /*
653       if (isAbstract() || getGetterMethod() == null)
654       return(getFieldName() + " = " + value + ";");
655       else
656     */

657     return "__caucho_super_set_" + getName() + "(" + value + ")";
658   }
659
660   /**
661    * Generates the get property.
662    */

663   public void generateSuperGetter(JavaWriter out)
664     throws IOException JavaDoc
665   {
666     out.println();
667     out.println("public final " + getJavaTypeName() + " __caucho_super_get_" + getName() + "()");
668     out.println("{");
669     out.pushDepth();
670
671     if (isAbstract() || getGetterMethod() == null)
672       out.println("return " + getFieldName() + ";");
673     else
674       out.println("return super." + getGetterName() + "();");
675
676     out.popDepth();
677     out.println("}");
678   }
679
680   /**
681    * Generates the set property.
682    */

683   public void generateSuperSetter(JavaWriter out)
684     throws IOException JavaDoc
685   {
686     out.println();
687     out.println("public final void __caucho_super_set_" + getName() + "(" + getJavaTypeName() + " v)");
688     out.println("{");
689     out.pushDepth();
690
691     if (isAbstract() || getGetterMethod() == null)
692       out.println(getFieldName() + " = v;");
693     else if (getSetterMethod() != null)
694       out.println("super." + getSetterMethod().getName() + "(v);");
695
696     out.popDepth();
697     out.println("}");
698   }
699
700   /**
701    * Generates the table create.
702    */

703   public String JavaDoc generateCreateTableSQL(AmberPersistenceUnit manager)
704   {
705     return null;
706   }
707
708   /**
709    * Generates the set clause.
710    */

711   public void generateSet(JavaWriter out, String JavaDoc pstmt, String JavaDoc index)
712     throws IOException JavaDoc
713   {
714     generateSet(out, pstmt, index, "super");
715   }
716
717   /**
718    * Generates the set clause for the insert clause.
719    */

720   public void generateInsertSet(JavaWriter out, String JavaDoc pstmt,
721                                 String JavaDoc index, String JavaDoc obj)
722     throws IOException JavaDoc
723   {
724     generateSet(out, pstmt, index, obj);
725   }
726
727   /**
728    * Generates the set clause for the insert clause.
729    */

730   public void generateUpdateSet(JavaWriter out, String JavaDoc pstmt,
731                                 String JavaDoc index, String JavaDoc obj)
732     throws IOException JavaDoc
733   {
734     generateSet(out, pstmt, index, obj);
735   }
736
737   /**
738    * Updates the cached copy.
739    */

740   public void generateCopyUpdateObject(JavaWriter out,
741                                        String JavaDoc dst, String JavaDoc src,
742                                        int updateIndex)
743     throws IOException JavaDoc
744   {
745     // commented out: jpa/0l03
746

747     if (getIndex() == updateIndex) {
748       String JavaDoc value = generateGet(src);
749       out.println(generateSet(dst, value) + ";");
750     }
751   }
752
753   /**
754    * Updates the cached copy.
755    */

756   public void generateCopyLoadObject(JavaWriter out,
757                                      String JavaDoc dst, String JavaDoc src,
758                                      int loadIndex)
759     throws IOException JavaDoc
760   {
761     // commented out: jpa/0l02
762

763     // jpa/0g0l
764
if (getLoadGroupIndex() == loadIndex) {
765       String JavaDoc value = generateGet(src);
766       out.println(generateSet(dst, value) + ";");
767     }
768   }
769
770   /**
771    * Generates the set clause.
772    */

773   public void generateSet(JavaWriter out, String JavaDoc pstmt,
774                           String JavaDoc index, String JavaDoc obj)
775     throws IOException JavaDoc
776   {
777   }
778
779   /**
780    * Converts to an object.
781    */

782   public String JavaDoc toObject(String JavaDoc value)
783   {
784     return value;
785   }
786
787   /**
788    * Links to the target.
789    */

790   public void link()
791   {
792   }
793
794   /**
795    * Generates the pre-delete code
796    */

797   public void generatePreDelete(JavaWriter out)
798     throws IOException JavaDoc
799   {
800   }
801
802   /**
803    * Generates the delete foreign
804    */

805   public void generatePostDelete(JavaWriter out)
806     throws IOException JavaDoc
807   {
808   }
809
810   /**
811    * Generates the expire code
812    */

813   public void generateExpire(JavaWriter out)
814     throws IOException JavaDoc
815   {
816   }
817
818   /**
819    * Generates code for foreign entity create/delete
820    */

821   public void generateInvalidateForeign(JavaWriter out)
822     throws IOException JavaDoc
823   {
824   }
825
826   /**
827    * Deletes the children
828    */

829   public void childDelete(AmberConnection aConn, Serializable JavaDoc primaryKey)
830     throws SQLException JavaDoc
831   {
832   }
833
834   /**
835    * Generates code to convert to the type from the object.
836    */

837   public String JavaDoc generateCastFromObject(String JavaDoc value)
838   {
839     return value;
840   }
841
842   /**
843    * Generates code to test the equals.
844    */

845   public String JavaDoc generateEquals(String JavaDoc leftBase, String JavaDoc value)
846   {
847     return leftBase + ".equals(" + value + ")";
848   }
849
850   /**
851    * Creates the expression for the field.
852    */

853   public AmberExpr createExpr(QueryParser parser, PathExpr parent)
854   {
855     throw new UnsupportedOperationException JavaDoc(getClass().getName());
856   }
857
858   public String JavaDoc toString()
859   {
860     return getClass().getName() + "[" + getName() + "]";
861   }
862 }
863
Popular Tags