KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > triactive > jdo > store > ClassBaseTable


1 /*
2  * Copyright 2004 (C) TJDO.
3  * All rights reserved.
4  *
5  * This software is distributed under the terms of the TJDO License version 1.0.
6  * See the terms of the TJDO License in the documentation provided with this software.
7  *
8  * $Id: ClassBaseTable.java,v 1.6 2004/01/18 03:01:06 jackknifebarber Exp $
9  */

10
11 package com.triactive.jdo.store;
12
13 import com.triactive.jdo.PersistenceManager;
14 import com.triactive.jdo.StateManager;
15 import com.triactive.jdo.model.ClassMetaData;
16 import com.triactive.jdo.model.FieldMetaData;
17 import com.triactive.jdo.model.MapMetaData;
18 import java.sql.Connection JavaDoc;
19 import java.sql.SQLException JavaDoc;
20 import java.util.ArrayList JavaDoc;
21 import java.util.HashMap JavaDoc;
22 import java.util.Iterator JavaDoc;
23 import java.util.List JavaDoc;
24 import javax.jdo.Extent;
25 import javax.jdo.JDOFatalInternalException;
26 import javax.jdo.JDOUnsupportedOptionException;
27
28
29 /**
30  * A database base table that serves as backing for a persistence-capable Java
31  * class.
32  *
33  * @author <a HREF="mailto:mmartin5@austin.rr.com">Mike Martin</a>
34  * @version $Revision: 1.6 $
35  */

36
37 public class ClassBaseTable extends JDOBaseTable implements ClassTable
38 {
39     private final ClassMetaData cmd;
40     private final Class JavaDoc clazz;
41
42     private ClassBaseTable supertable;
43     private ColumnMapping idMapping;
44     private Mapping[] fieldMappings;
45
46
47     ClassBaseTable(TableMetadata tmd, ClassMetaData cmd, StoreManager storeMgr)
48     {
49         super(tmd, storeMgr);
50
51         this.cmd = cmd;
52
53         clazz = cmd.getPCClass();
54
55         switch (cmd.getIdentityType())
56         {
57             case ClassMetaData.NO_IDENTITY:
58                 throw new JDOUnsupportedOptionException("No identity not supported: " + clazz.getName());
59
60             case ClassMetaData.APPLICATION_IDENTITY:
61                 throw new JDOUnsupportedOptionException("Application identity not supported: " + clazz.getName());
62
63             case ClassMetaData.DATASTORE_IDENTITY:
64                 break;
65
66             default:
67                 throw new JDOFatalInternalException("Invalid identity type on class " + clazz.getName());
68         }
69     }
70
71
72     public void initialize()
73     {
74         assertIsUninitialized();
75
76         Class JavaDoc superclass = cmd.getPCSuperclass();
77         supertable = superclass == null ? null : storeMgr.getClassBaseTable(superclass);
78
79         Column idColumn = newColumn(OID.class, name, Role.NONE).setPrimaryKeyPart();
80
81         idMapping = dba.getMapping(idColumn);
82
83         int fieldCount = cmd.getFieldCount();
84         fieldMappings = new Mapping[fieldCount];
85
86         for (int relativeFieldNumber = 0; relativeFieldNumber < fieldCount; ++relativeFieldNumber)
87         {
88             FieldMetaData fmd = cmd.getFieldRelative(relativeFieldNumber);
89
90             switch (fmd.getPersistenceModifier())
91             {
92                 case FieldMetaData.PERSISTENCE_MODIFIER_NONE:
93                 default:
94                     throw new JDOFatalInternalException("Invalid persistence modifier on field " + fmd.getName());
95
96                 case FieldMetaData.PERSISTENCE_MODIFIER_TRANSACTIONAL:
97                     break;
98
99                 case FieldMetaData.PERSISTENCE_MODIFIER_PERSISTENT:
100                     fieldMappings[relativeFieldNumber] = dba.getMapping(this, relativeFieldNumber);
101                     break;
102             }
103         }
104
105         state = TABLE_STATE_INITIALIZED;
106     }
107
108
109     public Class JavaDoc getType()
110     {
111         return clazz;
112     }
113
114
115     public ClassMetaData getClassMetaData()
116     {
117         return cmd;
118     }
119
120
121     protected List JavaDoc getExpectedForeignKeys()
122     {
123         List JavaDoc foreignKeys = super.getExpectedForeignKeys();
124
125         if (supertable != null)
126             foreignKeys.add(0, new ForeignKey(idMapping.getColumn(), supertable, false));
127
128         return foreignKeys;
129     }
130
131
132     protected List JavaDoc getSQLCreateStatements()
133     {
134         List JavaDoc stmts = super.getSQLCreateStatements();
135
136         stmts.addAll(getSQLAddUniqueConstraintsStatements());
137
138         return stmts;
139     }
140
141
142     private List JavaDoc getSQLAddUniqueConstraintsStatements()
143     {
144         ArrayList JavaDoc stmts = new ArrayList JavaDoc();
145         HashMap JavaDoc candidateKeysByMapField = new HashMap JavaDoc();
146         int fieldCount = cmd.getFieldCount();
147
148         for (int relativeFieldNumber = 0; relativeFieldNumber < fieldCount; ++relativeFieldNumber)
149         {
150             FieldMetaData fmd = cmd.getFieldRelative(relativeFieldNumber);
151             FieldMetaData mfmd = fmd.getOwnedByMap();
152
153             if (mfmd != null)
154             {
155                 MapMetaData mmd = mfmd.getMapMetaData();
156
157                 if (mmd.isInverseMap())
158                 {
159                     FieldMetaData omd = mmd.getOwnerField();
160                     FieldMetaData kmd = mmd.getKeyField();
161
162                     if (omd == null || !omd.equals(fmd))
163                         throw new InvalidMetaDataRelationshipException(fmd, "map-field", mfmd, "owner-field");
164                     if (kmd == null)
165                         throw new ClassDefinitionException("Missing map \"key-field\" in " + mfmd);
166
167                     Mapping om = getFieldMapping(omd.getName());
168                     Mapping km = getFieldMapping(kmd.getName());
169
170                     if (!(om instanceof ColumnMapping))
171                         throw new ClassDefinitionException("Invalid \"owner-field\" type: " + om.getType());
172                     if (!(km instanceof ColumnMapping))
173                         throw new ClassDefinitionException("Invalid \"key-field\" type: " + km.getType());
174
175                     Column ownerCol = ((ColumnMapping)om).getColumn();
176                     Column keyCol = ((ColumnMapping)km).getColumn();
177
178                     if (dba.supportsNullsInCandidateKeys() || (!ownerCol.isNullable() && !keyCol.isNullable()))
179                     {
180                         CandidateKey ck = new CandidateKey(this);
181
182                         ck.addColumn(ownerCol);
183                         ck.addColumn(keyCol);
184
185                         if (candidateKeysByMapField.put(mfmd, ck) != null)
186                             throw new ClassDefinitionException("Duplicate map owner field pointing to " + mfmd);
187                     }
188                 }
189             }
190         }
191
192         Iterator JavaDoc cks = candidateKeysByMapField.values().iterator();
193         int ckNum = 0;
194
195         while (cks.hasNext())
196         {
197             CandidateKeyIdentifier ckName = new CandidateKeyIdentifier(this, ++ckNum);
198
199             stmts.add(dba.getAddCandidateKeyStatement(ckName, (CandidateKey)cks.next()));
200         }
201
202         return stmts;
203     }
204
205
206     public Column newColumn(int relativeFieldNumber)
207     {
208         FieldMetaData fmd = cmd.getFieldRelative(relativeFieldNumber);
209
210         if (fmd.isPrimaryKeyPart())
211             throw new JDOUnsupportedOptionException("Primary key part fields not supported, class = " + clazz.getName() + ", field = " + fmd.getName());
212
213         Class JavaDoc type = fmd.getType();
214         Column col = newColumn(type, fmd.getName());
215
216         col.setOptions(fmd);
217
218         if (fmd.getNullValueHandling() != FieldMetaData.NULL_VALUE_EXCEPTION && !type.isPrimitive())
219             col.setNullable();
220
221         return col;
222     }
223
224
225     public ClassBaseTable getSupertable()
226     {
227         assertIsInitialized();
228
229         return supertable;
230     }
231
232
233     public ColumnMapping getIDMapping()
234     {
235         assertIsInitialized();
236
237         return idMapping;
238     }
239
240
241     // Must handle superclass fields.
242
public boolean isFieldPersistent(int fieldNumber)
243     {
244         assertIsInitialized();
245
246         int ifc = cmd.getInheritedFieldCount();
247
248         if (fieldNumber < ifc)
249             return supertable.isFieldPersistent(fieldNumber);
250         else
251             return fieldMappings[fieldNumber - ifc] != null;
252     }
253
254
255     // Must handle superclass fields.
256
public Mapping getFieldMapping(int fieldNumber)
257     {
258         assertIsInitialized();
259
260         int ifc = cmd.getInheritedFieldCount();
261
262         if (fieldNumber < ifc)
263             return supertable.getFieldMapping(fieldNumber);
264         else
265         {
266             Mapping m = fieldMappings[fieldNumber - ifc];
267
268             if (m == null)
269                 throw new NoSuchPersistentFieldException(clazz, fieldNumber);
270
271             return m;
272         }
273     }
274
275
276     // Must handle superclass fields.
277
public Mapping getFieldMapping(String JavaDoc fieldName)
278     {
279         assertIsInitialized();
280
281         Mapping m = null;
282         ClassBaseTable cbt = this;
283
284         do
285         {
286             int rfn = cbt.cmd.getRelativeFieldNumber(fieldName);
287
288             if (rfn >= 0)
289             {
290                 m = cbt.fieldMappings[rfn];
291                 break;
292             }
293
294             cbt = cbt.supertable;
295         } while (cbt != null);
296
297         if (m == null)
298             throw new NoSuchPersistentFieldException(clazz, fieldName);
299
300         return m;
301     }
302
303
304     private void assertPCClass(StateManager sm)
305     {
306         Class JavaDoc c = sm.getObject().getClass();
307
308         if (!clazz.isAssignableFrom(c))
309             throw new JDOFatalInternalException("Table class = " + clazz + ", object class = " + c);
310     }
311
312
313     public Extent newExtent(PersistenceManager pm, boolean subclasses)
314     {
315         assertIsValidated();
316
317         return new ClassBaseTableExtent(pm, this, subclasses);
318     }
319
320
321     public void insert(StateManager sm)
322     {
323         assertIsValidated();
324         assertPCClass(sm);
325
326         if (supertable != null)
327             supertable.insert(sm);
328
329         InsertRequest ir = storeMgr.getInsertRequest(this);
330
331         ir.execute(sm);
332     }
333
334
335     public void lookup(StateManager sm)
336     {
337         assertIsValidated();
338         assertPCClass(sm);
339
340         LookupRequest lr = storeMgr.getLookupRequest(this);
341
342         lr.execute(sm);
343     }
344
345
346     public void fetch(StateManager sm, int[] fieldNumbers)
347     {
348         assertIsValidated();
349         assertPCClass(sm);
350
351         if (supertable != null)
352             supertable.fetch(sm, fieldNumbers);
353
354         FetchRequest fr = storeMgr.getFetchRequest(this, fieldNumbers);
355
356         fr.execute(sm);
357     }
358
359
360     public void update(StateManager sm, int[] fieldNumbers)
361     {
362         assertIsValidated();
363         assertPCClass(sm);
364
365         if (supertable != null)
366             supertable.update(sm, fieldNumbers);
367
368         UpdateRequest ur = storeMgr.getUpdateRequest(this, fieldNumbers);
369
370         ur.execute(sm);
371     }
372
373
374     public void delete(StateManager sm)
375     {
376         assertIsValidated();
377         assertPCClass(sm);
378
379         DeleteRequest dr = storeMgr.getDeleteRequest(this);
380
381         dr.execute(sm);
382
383         if (supertable != null)
384             supertable.delete(sm);
385     }
386 }
387
Popular Tags