1 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 ; 19 import java.sql.SQLException ; 20 import java.util.ArrayList ; 21 import java.util.HashMap ; 22 import java.util.Iterator ; 23 import java.util.List ; 24 import javax.jdo.Extent; 25 import javax.jdo.JDOFatalInternalException; 26 import javax.jdo.JDOUnsupportedOptionException; 27 28 29 36 37 public class ClassBaseTable extends JDOBaseTable implements ClassTable 38 { 39 private final ClassMetaData cmd; 40 private final Class 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 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 getType() 110 { 111 return clazz; 112 } 113 114 115 public ClassMetaData getClassMetaData() 116 { 117 return cmd; 118 } 119 120 121 protected List getExpectedForeignKeys() 122 { 123 List 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 getSQLCreateStatements() 133 { 134 List stmts = super.getSQLCreateStatements(); 135 136 stmts.addAll(getSQLAddUniqueConstraintsStatements()); 137 138 return stmts; 139 } 140 141 142 private List getSQLAddUniqueConstraintsStatements() 143 { 144 ArrayList stmts = new ArrayList (); 145 HashMap candidateKeysByMapField = new HashMap (); 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 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 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 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 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 public Mapping getFieldMapping(String 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 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 |