KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > amber > type > RelatedType


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 Rodrigo Westrupp
28  */

29
30 package com.caucho.amber.type;
31
32 import com.caucho.amber.AmberRuntimeException;
33 import com.caucho.amber.entity.AmberCompletion;
34 import com.caucho.amber.entity.AmberEntityHome;
35 import com.caucho.amber.entity.Entity;
36 import com.caucho.amber.entity.EntityItem;
37 import com.caucho.amber.field.AmberField;
38 import com.caucho.amber.field.EntityManyToOneField;
39 import com.caucho.amber.field.Id;
40 import com.caucho.amber.field.IdField;
41 import com.caucho.amber.field.VersionField;
42 import com.caucho.amber.idgen.AmberTableGenerator;
43 import com.caucho.amber.idgen.IdGenerator;
44 import com.caucho.amber.idgen.SequenceIdGenerator;
45 import com.caucho.amber.manager.AmberConnection;
46 import com.caucho.amber.manager.AmberPersistenceUnit;
47 import com.caucho.amber.table.Column;
48 import com.caucho.amber.table.Table;
49 import com.caucho.bytecode.JClass;
50 import com.caucho.config.ConfigException;
51 import com.caucho.java.JavaWriter;
52 import com.caucho.lifecycle.Lifecycle;
53 import com.caucho.util.CharBuffer;
54 import com.caucho.util.L10N;
55
56 import java.io.IOException JavaDoc;
57 import java.sql.ResultSet JavaDoc;
58 import java.sql.SQLException JavaDoc;
59 import java.util.ArrayList JavaDoc;
60 import java.util.HashMap JavaDoc;
61 import java.util.HashSet JavaDoc;
62 import java.util.logging.Logger JavaDoc;
63
64 /**
65  * Base for entity or mapped-superclass types.
66  */

67 abstract public class RelatedType extends AbstractStatefulType {
68   private static final Logger JavaDoc log = Logger.getLogger(RelatedType.class.getName());
69   private static final L10N L = new L10N(RelatedType.class);
70
71   private Table _table;
72
73   private String JavaDoc _rootTableName;
74
75   private ArrayList JavaDoc<Table> _secondaryTables
76     = new ArrayList JavaDoc<Table>();
77
78   private ArrayList JavaDoc<ListenerType> _listeners
79     = new ArrayList JavaDoc<ListenerType>();
80
81   private Id _id;
82
83   private String JavaDoc _discriminatorValue;
84   private boolean _isJoinedSubClass;
85
86   private HashSet JavaDoc<String JavaDoc> _eagerFieldNames;
87
88   private HashMap JavaDoc<String JavaDoc,EntityType> _subEntities;
89
90   private boolean _hasDependent;
91
92   private JClass _proxyClass;
93
94   private AmberEntityHome _home;
95
96   protected int _defaultLoadGroupIndex;
97   protected int _loadGroupIndex;
98
99   protected int _minDirtyIndex;
100   protected int _dirtyIndex;
101
102   private boolean _excludeDefaultListeners;
103   private boolean _excludeSuperclassListeners;
104
105   protected boolean _hasLoadCallback;
106
107   private HashMap JavaDoc<String JavaDoc,IdGenerator> _idGenMap
108     = new HashMap JavaDoc<String JavaDoc,IdGenerator>();
109
110   private final Lifecycle _lifecycle = new Lifecycle();
111
112   private VersionField _versionField;
113
114
115   public RelatedType(AmberPersistenceUnit amberPersistenceUnit)
116   {
117     super(amberPersistenceUnit);
118   }
119
120   /**
121    * Returns the table.
122    */

123   public Table getTable()
124   {
125     if (_table == null)
126       setTable(_amberPersistenceUnit.createTable(getName()));
127
128     return _table;
129   }
130
131   /**
132    * Sets the table.
133    */

134   public void setTable(Table table)
135   {
136     _table = table;
137
138     if (_rootTableName == null)
139       _rootTableName = table.getName();
140   }
141
142   /**
143    * Returns the root table name.
144    */

145   public String JavaDoc getRootTableName()
146   {
147     return _rootTableName;
148   }
149
150   /**
151    * Sets the root table name.
152    */

153   public void setRootTableName(String JavaDoc rootTableName)
154   {
155     _rootTableName = rootTableName;
156   }
157
158   /**
159    * Returns the version field.
160    */

161   public VersionField getVersionField()
162   {
163     return _versionField;
164   }
165
166   /**
167    * Sets the version field.
168    */

169   public void setVersionField(VersionField versionField)
170   {
171     addField(versionField);
172
173     _versionField = versionField;
174   }
175
176   /**
177    * Adds a secondary table.
178    */

179   public void addSecondaryTable(Table table)
180   {
181     if (! _secondaryTables.contains(table)) {
182       _secondaryTables.add(table);
183     }
184
185     table.setType(this);
186   }
187
188   /**
189    * Gets the secondary tables.
190    */

191   public ArrayList JavaDoc<Table> getSecondaryTables()
192   {
193     return _secondaryTables;
194   }
195
196   /**
197    * Adds an entity listener.
198    */

199   public void addListener(ListenerType listener)
200   {
201     if (_listeners.contains(listener))
202       return;
203
204     _listeners.add(listener);
205   }
206
207   /**
208    * Gets the entity listeners.
209    */

210   public ArrayList JavaDoc<ListenerType> getListeners()
211   {
212     return _listeners;
213   }
214
215   /**
216    * Gets a secondary table.
217    */

218   public Table getSecondaryTable(String JavaDoc name)
219   {
220     for (Table table : _secondaryTables) {
221       if (table.getName().equals(name))
222         return table;
223     }
224
225     return null;
226   }
227
228   /**
229    * Returns true if and only if it has a
230    * many-to-one, one-to-one or embedded field/property.
231    */

232   public boolean hasDependent()
233   {
234     return _hasDependent;
235   }
236
237   /**
238    * Sets true if and only if it has a
239    * many-to-one, one-to-one or embedded field/property.
240    */

241   public void setHasDependent(boolean hasDependent)
242   {
243     _hasDependent = hasDependent;
244   }
245
246   /**
247    * Returns the java type.
248    */

249   public String JavaDoc getForeignTypeName()
250   {
251     return getId().getForeignTypeName();
252   }
253
254   /**
255    * Gets the proxy class.
256    */

257   public JClass getProxyClass()
258   {
259     if (_proxyClass != null)
260       return _proxyClass;
261     else
262       return _beanClass;
263   }
264
265   /**
266    * Gets the proxy class.
267    */

268   public void setProxyClass(JClass proxyClass)
269   {
270     _proxyClass = proxyClass;
271   }
272
273   /**
274    * Gets the instance class.
275    */

276   public Class JavaDoc getInstanceClass()
277   {
278     return getInstanceClass(Entity.class);
279   }
280
281   /**
282    * Sets the id.
283    */

284   public void setId(Id id)
285   {
286     _id = id;
287   }
288
289   /**
290    * Returns the id.
291    */

292   public Id getId()
293   {
294     return _id;
295   }
296
297   /**
298    * Set true for joined-subclass
299    */

300   public void setJoinedSubClass(boolean isJoinedSubClass)
301   {
302     _isJoinedSubClass = isJoinedSubClass;
303   }
304
305   /**
306    * Set true for joined-subclass
307    */

308   public boolean isJoinedSubClass()
309   {
310     if (getParentType() != null)
311       return getParentType().isJoinedSubClass();
312     else
313       return _isJoinedSubClass;
314   }
315
316   /**
317    * Sets the discriminator value.
318    */

319   public String JavaDoc getDiscriminatorValue()
320   {
321     if (_discriminatorValue != null)
322       return _discriminatorValue;
323     else {
324       String JavaDoc name = getBeanClass().getName();
325
326       int p = name.lastIndexOf('.');
327       if (p > 0)
328         return name.substring(0, p);
329       else
330         return name;
331     }
332   }
333
334   /**
335    * Sets the discriminator value.
336    */

337   public void setDiscriminatorValue(String JavaDoc value)
338   {
339     _discriminatorValue = value;
340   }
341
342   /**
343    * Returns true if read-only
344    */

345   public boolean isReadOnly()
346   {
347     return getTable().isReadOnly();
348   }
349
350   /**
351    * Sets true if read-only
352    */

353   public void setReadOnly(boolean isReadOnly)
354   {
355     getTable().setReadOnly(isReadOnly);
356   }
357
358   /**
359    * Returns the cache timeout.
360    */

361   public long getCacheTimeout()
362   {
363     return getTable().getCacheTimeout();
364   }
365
366   /**
367    * Sets the cache timeout.
368    */

369   public void setCacheTimeout(long timeout)
370   {
371     getTable().setCacheTimeout(timeout);
372   }
373
374   /**
375    * Adds a new field.
376    */

377   public void addField(AmberField field)
378   {
379     super.addField(field);
380
381     if (! field.isLazy()) {
382
383       if (_eagerFieldNames == null)
384         _eagerFieldNames = new HashSet JavaDoc<String JavaDoc>();
385
386       _eagerFieldNames.add(field.getName());
387     }
388   }
389
390   /**
391    * Gets the EAGER field names.
392    */

393   public HashSet JavaDoc<String JavaDoc> getEagerFieldNames()
394   {
395     return _eagerFieldNames;
396   }
397
398   /**
399    * Returns the field with a given name.
400    */

401   public AmberField getField(String JavaDoc name)
402   {
403     if (_id != null) {
404       ArrayList JavaDoc<IdField> keys = _id.getKeys();
405
406       for (int i = 0; i < keys.size(); i++) {
407         IdField key = keys.get(i);
408
409         if (key.getName().equals(name))
410           return key;
411       }
412     }
413
414     return super.getField(name);
415   }
416
417   /**
418    * Returns the columns.
419    */

420   public ArrayList JavaDoc<Column> getColumns()
421   {
422     return getTable().getColumns();
423   }
424
425   /**
426    * Gets the exclude default listeners flag.
427    */

428   public boolean getExcludeDefaultListeners()
429   {
430     return _excludeDefaultListeners;
431   }
432
433   /**
434    * Sets the exclude default listeners flag.
435    */

436   public void setExcludeDefaultListeners(boolean b)
437   {
438     _excludeDefaultListeners = b;
439   }
440
441   /**
442    * Gets the exclude superclass listeners flag.
443    */

444   public boolean getExcludeSuperclassListeners()
445   {
446     return _excludeSuperclassListeners;
447   }
448
449   /**
450    * Sets the exclude superclass listeners flag.
451    */

452   public void setExcludeSuperclassListeners(boolean b)
453   {
454     _excludeSuperclassListeners = b;
455   }
456
457   /**
458    * True if the load lifecycle callback should be generated.
459    */

460   public void setHasLoadCallback(boolean hasCallback)
461   {
462     _hasLoadCallback = hasCallback;
463   }
464
465   /**
466    * True if the load lifecycle callback should be generated.
467    */

468   public boolean getHasLoadCallback()
469   {
470     return _hasLoadCallback;
471   }
472
473   /**
474    * Returns the root type.
475    */

476   public RelatedType getRootType()
477   {
478     RelatedType parent = getParentType();
479
480     if (parent != null)
481       return parent.getRootType();
482     else
483       return this;
484   }
485
486   /**
487    * Returns the parent type.
488    */

489   public RelatedType getParentType()
490   {
491     return null;
492   }
493
494   /**
495    * Adds a sub-class.
496    */

497   public void addSubClass(SubEntityType type)
498   {
499     if (_subEntities == null)
500       _subEntities = new HashMap JavaDoc<String JavaDoc,EntityType>();
501
502     _subEntities.put(type.getDiscriminatorValue(), type);
503   }
504
505   /**
506    * Gets a sub-class.
507    */

508   public RelatedType getSubClass(String JavaDoc discriminator)
509   {
510     if (_subEntities == null)
511       return this;
512
513     RelatedType subType = _subEntities.get(discriminator);
514
515     if (subType != null)
516       return subType;
517     else
518       return this;
519   }
520
521   /**
522    * Creates a new entity for this specific instance type.
523    */

524   public Entity createBean()
525   {
526     try {
527       return (Entity) getInstanceClass().newInstance();
528     } catch (Exception JavaDoc e) {
529       throw new AmberRuntimeException(e);
530     }
531   }
532
533   /**
534    * Returns the home.
535    */

536   public AmberEntityHome getHome()
537   {
538     if (_home == null) {
539       _home = getPersistenceUnit().getEntityHome(getName());
540     }
541
542     return _home;
543   }
544
545   /**
546    * Returns the next load group.
547    */

548   public int nextLoadGroupIndex()
549   {
550     int nextLoadGroupIndex = getLoadGroupIndex() + 1;
551
552     _loadGroupIndex = nextLoadGroupIndex;
553
554     return nextLoadGroupIndex;
555   }
556
557   /**
558    * Returns the current load group.
559    */

560   public int getLoadGroupIndex()
561   {
562     return _loadGroupIndex;
563   }
564
565   /**
566    * Sets the next default loadGroupIndex
567    */

568   public void nextDefaultLoadGroupIndex()
569   {
570     _defaultLoadGroupIndex = nextLoadGroupIndex();
571   }
572
573   /**
574    * Returns the current load group.
575    */

576   public int getDefaultLoadGroupIndex()
577   {
578     return _defaultLoadGroupIndex;
579   }
580
581   /**
582    * Returns true if the load group is owned by this type (not a subtype).
583    */

584   public boolean isLoadGroupOwnedByType(int i)
585   {
586     return getDefaultLoadGroupIndex() <= i && i <= getLoadGroupIndex();
587   }
588
589   /**
590    * Returns the next dirty index
591    */

592   public int nextDirtyIndex()
593   {
594     int dirtyIndex = getDirtyIndex();
595
596     _dirtyIndex = dirtyIndex + 1;
597
598     return dirtyIndex;
599   }
600
601   /**
602    * Returns the current dirty group.
603    */

604   public int getDirtyIndex()
605   {
606     return _dirtyIndex;
607   }
608
609   /**
610    * Returns the min dirty group.
611    */

612   public int getMinDirtyIndex()
613   {
614     return _minDirtyIndex;
615   }
616
617   /**
618    * Returns true if the load group is owned by this type (not a subtype).
619    */

620   public boolean isDirtyIndexOwnedByType(int i)
621   {
622     return getMinDirtyIndex() <= i && i < getDirtyIndex();
623   }
624
625   /**
626    * Initialize the entity.
627    */

628   public void init()
629     throws ConfigException
630   {
631     if (getConfigException() != null)
632       return;
633
634     if (! _lifecycle.toInit())
635       return;
636
637     // forces table lazy load
638
getTable();
639
640     assert getId() != null : "null id for " + getName();
641
642     getId().init();
643
644     for (AmberField field : getFields()) {
645       if (field.isUpdateable())
646         field.setIndex(nextDirtyIndex());
647
648       field.init();
649     }
650   }
651
652   /**
653    * Start the entry.
654    */

655   public void start()
656     throws ConfigException
657   {
658     init();
659
660     if (! _lifecycle.toActive())
661       return;
662   }
663
664   /**
665    * Generates a string to load the field.
666    */

667   public int generateLoad(JavaWriter out, String JavaDoc rs,
668                           String JavaDoc indexVar, int index)
669     throws IOException JavaDoc
670   {
671     // ejb/0ag3
672
// out.print("(" + getInstanceClassName() + ") ");
673

674     out.print("aConn.loadProxy(\"" + getName() + "\", ");
675
676     index = getId().generateLoadForeign(out, rs, indexVar, index);
677
678     out.println(");");
679
680     return index;
681   }
682
683   /**
684    * Returns true if there's a field with the matching load group.
685    */

686   public boolean hasLoadGroup(int loadGroupIndex)
687   {
688     if (loadGroupIndex == 0)
689       return true;
690
691     for (AmberField field : getFields()) {
692       if (field.hasLoadGroup(loadGroupIndex))
693         return true;
694     }
695
696     return false;
697   }
698
699   /**
700    * Generates a string to load the field.
701    */

702   public int generateLoadEager(JavaWriter out, String JavaDoc rs,
703                                String JavaDoc indexVar, int index, int loadGroupIndex)
704     throws IOException JavaDoc
705   {
706     if (loadGroupIndex == 0 && getDiscriminator() != null)
707       index++;
708
709     ArrayList JavaDoc<AmberField> fields = getFields();
710     for (int i = 0; i < fields.size(); i++) {
711       AmberField field = fields.get(i);
712
713       if (field.getLoadGroupIndex() == loadGroupIndex)
714         index = field.generateLoadEager(out, rs, indexVar, index);
715     }
716
717     return index;
718   }
719
720   /**
721    * Generates a string to set the field.
722    */

723   public void generateSet(JavaWriter out, String JavaDoc pstmt,
724                           String JavaDoc index, String JavaDoc value)
725     throws IOException JavaDoc
726   {
727     if (getId() != null)
728       getId().generateSet(out, pstmt, index, value);
729   }
730
731   /**
732    * Gets the value.
733    */

734   public Object JavaDoc getObject(AmberConnection aConn, ResultSet JavaDoc rs, int index)
735     throws SQLException JavaDoc
736   {
737     return getHome().loadLazy(aConn, rs, index);
738   }
739
740   /**
741    * Finds the object
742    */

743   public EntityItem findItem(AmberConnection aConn, ResultSet JavaDoc rs, int index)
744     throws SQLException JavaDoc
745   {
746     return getHome().findItem(aConn, rs, index);
747   }
748
749   /**
750    * Gets the value.
751    */

752   public Object JavaDoc getLoadObject(AmberConnection aConn,
753                               ResultSet JavaDoc rs, int index)
754     throws SQLException JavaDoc
755   {
756     return getHome().loadFull(aConn, rs, index);
757   }
758
759   /**
760    * Sets the named generator.
761    */

762   public void setGenerator(String JavaDoc name, IdGenerator gen)
763   {
764     _idGenMap.put(name, gen);
765   }
766
767   /**
768    * Sets the named generator.
769    */

770   public IdGenerator getGenerator(String JavaDoc name)
771   {
772     return _idGenMap.get(name);
773   }
774
775   /**
776    * Gets the named generator.
777    */

778   public long nextGeneratorId(AmberConnection aConn, String JavaDoc name)
779     throws SQLException JavaDoc
780   {
781     IdGenerator idGen = _idGenMap.get(name);
782
783     if (idGen instanceof SequenceIdGenerator) {
784       ((SequenceIdGenerator) idGen).init(_amberPersistenceUnit);
785     }
786     else if (idGen instanceof AmberTableGenerator) {
787       // jpa/0g60
788
((AmberTableGenerator) idGen).init(_amberPersistenceUnit);
789     }
790
791     return idGen.allocate(aConn);
792   }
793
794   /**
795    * Loads from an object.
796    */

797   public void generateLoadFromObject(JavaWriter out, String JavaDoc obj)
798     throws IOException JavaDoc
799   {
800     getId().generateLoadFromObject(out, obj);
801
802     ArrayList JavaDoc<AmberField> fields = getFields();
803     for (int i = 0; i < fields.size(); i++) {
804       AmberField field = fields.get(i);
805
806       field.generateLoadFromObject(out, obj);
807     }
808   }
809
810   /**
811    * Copy from an object.
812    */

813   public void generateCopyLoadObject(JavaWriter out,
814                                      String JavaDoc dst, String JavaDoc src,
815                                      int loadGroup)
816     throws IOException JavaDoc
817   {
818     if (getParentType() != null)
819       getParentType().generateCopyUpdateObject(out, dst, src, loadGroup);
820
821     ArrayList JavaDoc<AmberField> fields = getFields();
822
823     for (int i = 0; i < fields.size(); i++) {
824       AmberField field = fields.get(i);
825
826       // XXX: setter issue, too
827

828       field.generateCopyLoadObject(out, dst, src, loadGroup);
829     }
830   }
831
832   /**
833    * Copy from an object.
834    */

835   public void generateCopyUpdateObject(JavaWriter out,
836                                        String JavaDoc dst, String JavaDoc src,
837                                        int updateIndex)
838     throws IOException JavaDoc
839   {
840     if (getParentType() != null)
841       getParentType().generateCopyUpdateObject(out, dst, src, updateIndex);
842
843     ArrayList JavaDoc<AmberField> fields = getFields();
844     for (int i = 0; i < fields.size(); i++) {
845       AmberField field = fields.get(i);
846
847       field.generateCopyUpdateObject(out, dst, src, updateIndex);
848     }
849   }
850
851   /**
852    * Generates the select clause for a load.
853    */

854   public String JavaDoc generateKeyLoadSelect(String JavaDoc id)
855   {
856     String JavaDoc select = getId().generateLoadSelect(id);
857
858     if (getDiscriminator() != null) {
859       if (select != null && ! select.equals(""))
860         select = select + ", ";
861
862       select = select + getDiscriminator().getName();
863     }
864
865     return select;
866   }
867
868   /**
869    * Generates the select clause for a load.
870    */

871   public String JavaDoc generateFullLoadSelect(String JavaDoc id)
872   {
873     CharBuffer cb = CharBuffer.allocate();
874
875     String JavaDoc idSelect = getId().generateSelect(id);
876
877     if (idSelect != null)
878       cb.append(idSelect);
879
880     String JavaDoc loadSelect = generateLoadSelect(id);
881
882     if (! idSelect.equals("") && ! loadSelect.equals(""))
883       cb.append(",");
884
885     cb.append(loadSelect);
886
887     return cb.close();
888   }
889
890   /**
891    * Generates the select clause for a load.
892    */

893   public String JavaDoc generateLoadSelect(String JavaDoc id)
894   {
895     return generateLoadSelect(getTable(), id, 0);
896   }
897
898   /**
899    * Generates the select clause for a load.
900    */

901   public String JavaDoc generateLoadSelect(Table table, String JavaDoc id)
902   {
903     return generateLoadSelect(table, id, 0);
904   }
905
906   /**
907    * Generates the select clause for a load.
908    */

909   public String JavaDoc generateLoadSelect(Table table, String JavaDoc id, int loadGroup)
910   {
911     CharBuffer cb = CharBuffer.allocate();
912
913     boolean hasSelect = false;
914
915     if (loadGroup == 0 && getParentType() != null) {
916       String JavaDoc parentSelect =
917         getParentType().generateLoadSelect(table, id, loadGroup);
918
919       cb.append(parentSelect);
920       if (! parentSelect.equals(""))
921         hasSelect = true;
922     }
923     else if ((getTable() == table) && // jpa/0l11
924
(loadGroup == 0 && getDiscriminator() != null)) {
925
926       if (id != null) {
927         cb.append(id + ".");
928       }
929
930       cb.append(getDiscriminator().getName());
931       hasSelect = true;
932     }
933
934     String JavaDoc propSelect = super.generateLoadSelect(table,
935                                                  id,
936                                                  loadGroup,
937                                                  hasSelect);
938     // jpa/0s26
939
if (propSelect != null)
940       cb.append(propSelect);
941
942     if (cb.length() == 0)
943       return null;
944     else
945       return cb.close();
946   }
947
948   /**
949    * Generates the update sql.
950    */

951   public String JavaDoc generateCreateSQL(Table table)
952   {
953     CharBuffer sql = new CharBuffer();
954
955     sql.append("insert into " + table.getName() + " (");
956
957     boolean isFirst = true;
958
959     ArrayList JavaDoc<String JavaDoc> idColumns = new ArrayList JavaDoc<String JavaDoc>();
960     for (IdField field : getId().getKeys()) {
961       for (Column key : field.getColumns()) {
962         String JavaDoc name;
963
964         if (table == key.getTable())
965           name = key.getName();
966         else
967           name = table.getDependentIdLink().getSourceColumn(key).getName();
968
969         idColumns.add(name);
970
971         if (! isFirst)
972           sql.append(", ");
973         isFirst = false;
974
975         sql.append(name);
976       }
977     }
978
979     if (table == getTable() && getDiscriminator() != null) {
980       if (! isFirst)
981         sql.append(", ");
982       isFirst = false;
983
984       sql.append(getDiscriminator().getName());
985     }
986
987     ArrayList JavaDoc<String JavaDoc> columns = new ArrayList JavaDoc<String JavaDoc>();
988     generateInsertColumns(table, columns);
989
990     for (String JavaDoc columnName : columns) {
991       if (! isFirst)
992         sql.append(", ");
993       isFirst = false;
994
995       sql.append(columnName);
996     }
997
998     sql.append(") values (");
999
1000    isFirst = true;
1001    for (int i = 0; i < idColumns.size(); i++) {
1002      if (! isFirst)
1003        sql.append(", ");
1004      isFirst = false;
1005
1006      sql.append("?");
1007    }
1008
1009    if (table == getTable() && getDiscriminator() != null) {
1010      if (! isFirst)
1011        sql.append(", ");
1012      isFirst = false;
1013
1014      sql.append("'" + getDiscriminatorValue() + "'");
1015    }
1016
1017    for (int i = 0; i < columns.size(); i++) {
1018      if (! isFirst)
1019        sql.append(", ");
1020      isFirst = false;
1021
1022      sql.append("?");
1023    }
1024
1025    sql.append(")");
1026
1027    return sql.toString();
1028  }
1029
1030  protected void generateInsertColumns(Table table, ArrayList JavaDoc<String JavaDoc> columns)
1031  {
1032    if (getParentType() != null)
1033      getParentType().generateInsertColumns(table, columns);
1034
1035    for (AmberField field : getFields()) {
1036      if (field.getTable() == table)
1037        field.generateInsertColumns(columns);
1038    }
1039  }
1040
1041  /**
1042   * Generates the update sql.
1043   */

1044  public void generateInsertSet(JavaWriter out,
1045                                Table table,
1046                                String JavaDoc pstmt,
1047                                String JavaDoc query,
1048                                String JavaDoc obj)
1049    throws IOException JavaDoc
1050  {
1051    if (getParentType() != null)
1052      getParentType().generateInsertSet(out, table, pstmt, query, obj);
1053
1054    for (AmberField field : getFields()) {
1055      if (field.getTable() == table)
1056        field.generateInsertSet(out, pstmt, query, obj);
1057    }
1058  }
1059
1060  /**
1061   * Generates the select clause for a load.
1062   */

1063  public String JavaDoc generateIdSelect(String JavaDoc id)
1064  {
1065    CharBuffer cb = CharBuffer.allocate();
1066
1067    cb.append(getId().generateSelect(id));
1068
1069    if (getDiscriminator() != null) {
1070      cb.append(", ");
1071      cb.append(getDiscriminator().getName());
1072    }
1073
1074    return cb.close();
1075  }
1076
1077  /**
1078   * Generates the update sql.
1079   */

1080  public void generateUpdateSQLPrefix(CharBuffer sql)
1081  {
1082    sql.append("update " + getTable().getName() + " set ");
1083  }
1084
1085  /**
1086   * Generates the update sql.
1087   *
1088   * @param sql the partially built sql
1089   * @param group the dirty group
1090   * @param mask the group's mask
1091   * @param isFirst marks the first set group
1092   */

1093  public boolean generateUpdateSQLComponent(CharBuffer sql,
1094                                            int group,
1095                                            long mask,
1096                                            boolean isFirst)
1097  {
1098    ArrayList JavaDoc<AmberField> fields = getFields();
1099
1100    while (mask != 0) {
1101      int i = 0;
1102      for (i = 0; (mask & (1L << i)) == 0; i++) {
1103      }
1104
1105      mask &= ~(1L << i);
1106
1107      AmberField field = null;
1108
1109      for (int j = 0; j < fields.size(); j++) {
1110        field = fields.get(j);
1111
1112        if (field.getIndex() == i + group * 64)
1113          break;
1114        else
1115          field = null;
1116      }
1117
1118      if (field != null) {
1119
1120        // jpa/0x00
1121
if (field instanceof VersionField)
1122          continue;
1123
1124        if (! isFirst)
1125          sql.append(", ");
1126        isFirst = false;
1127
1128        field.generateUpdate(sql);
1129      }
1130    }
1131
1132    // jpa/0x00
1133
for (int j = 0; j < fields.size(); j++) {
1134      AmberField field = fields.get(j);
1135
1136      if (field instanceof VersionField) {
1137        if (! isFirst)
1138          sql.append(", ");
1139        isFirst = false;
1140
1141        field.generateUpdate(sql);
1142        break;
1143      }
1144    }
1145
1146    return isFirst;
1147  }
1148
1149  /**
1150   * Generates the update sql.
1151   */

1152  public void generateUpdateSQLSuffix(CharBuffer sql)
1153  {
1154    sql.append(" where ");
1155
1156    sql.append(getId().generateMatchArgWhere(null));
1157
1158    // optimistic locking
1159
if (_versionField != null) {
1160      sql.append(" and ");
1161      sql.append(_versionField.generateMatchArgWhere(null));
1162    }
1163  }
1164
1165  /**
1166   * Generates the update sql.
1167   */

1168  public String JavaDoc generateUpdateSQL(long mask)
1169  {
1170    if (mask == 0)
1171      return null;
1172
1173    CharBuffer sql = CharBuffer.allocate();
1174
1175    sql.append("update " + getTable().getName() + " set ");
1176
1177    boolean isFirst = true;
1178
1179    ArrayList JavaDoc<AmberField> fields = getFields();
1180
1181    while (mask != 0) {
1182      int i = 0;
1183      for (i = 0; (mask & (1L << i)) == 0; i++) {
1184      }
1185
1186      mask &= ~(1L << i);
1187
1188      AmberField field = null;
1189
1190      for (int j = 0; j < fields.size(); j++) {
1191        field = fields.get(j);
1192
1193        if (field.getIndex() == i)
1194          break;
1195        else
1196          field = null;
1197      }
1198
1199      if (field != null) {
1200        if (! isFirst)
1201          sql.append(", ");
1202        isFirst = false;
1203
1204        field.generateUpdate(sql);
1205      }
1206    }
1207
1208    if (isFirst)
1209      return null;
1210
1211    sql.append(" where ");
1212
1213    sql.append(getId().generateMatchArgWhere(null));
1214
1215    return sql.toString();
1216  }
1217
1218  /**
1219   * Generates code after the remove.
1220   */

1221  public void generatePreDelete(JavaWriter out)
1222    throws IOException JavaDoc
1223  {
1224    for (AmberField field : getFields()) {
1225      field.generatePreDelete(out);
1226    }
1227  }
1228
1229  /**
1230   * Generates code after the remove.
1231   */

1232  public void generatePostDelete(JavaWriter out)
1233    throws IOException JavaDoc
1234  {
1235    for (AmberField field : getFields()) {
1236      field.generatePostDelete(out);
1237    }
1238  }
1239
1240  /**
1241   * Deletes by the primary key.
1242   */

1243  public void delete(AmberConnection aConn, Object JavaDoc key)
1244    throws SQLException JavaDoc
1245  {
1246    getHome().delete(aConn, key);
1247  }
1248
1249  /**
1250   * Deletes by the primary key.
1251   */

1252  public void update(Entity entity)
1253    throws SQLException JavaDoc
1254  {
1255    // aConn.addCompletion(_tableCompletion);
1256
}
1257
1258  /**
1259   * Returns a completion for the given field.
1260   */

1261  public AmberCompletion createManyToOneCompletion(String JavaDoc name,
1262                                                   Entity source,
1263                                                   Object JavaDoc newTarget)
1264  {
1265    AmberField field = getField(name);
1266
1267    if (field instanceof EntityManyToOneField) {
1268      EntityManyToOneField manyToOne = (EntityManyToOneField) field;
1269
1270      return getTable().getInvalidateCompletion();
1271    }
1272    else
1273      throw new IllegalStateException JavaDoc();
1274  }
1275
1276  /**
1277   * XXX: temp hack.
1278   */

1279  public boolean isEJBProxy(String JavaDoc typeName)
1280  {
1281    return (getBeanClass() != getProxyClass() &&
1282            getProxyClass().getName().equals(typeName));
1283  }
1284
1285  /**
1286   * Printable version of the entity.
1287   */

1288  public String JavaDoc toString()
1289  {
1290    return "RelatedType[" + _beanClass.getName() + "]";
1291  }
1292}
1293
Popular Tags