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.CollectionMetaData; 17 import com.triactive.jdo.model.FieldMetaData; 18 import com.triactive.jdo.util.IntArrayList; 19 import java.lang.reflect.Field ; 20 import java.util.Collection ; 21 import java.util.Iterator ; 22 import javax.jdo.JDOUserException; 23 24 25 class InverseSetStore extends AbstractSetStore 26 { 27 private final int ownerFieldNumber; 28 29 public InverseSetStore(FieldMetaData fmd, StoreManager storeMgr) 30 { 31 this.storeMgr = storeMgr; 32 33 dba = storeMgr.getDatabaseAdapter(); 34 35 Field field = fmd.getField(); 36 ClassMetaData cmd = fmd.getClassMetaData(); 37 CollectionMetaData colmd = fmd.getCollectionMetaData(); 38 if (colmd == null) 39 throw new JDOUserException("No collection metadata found in " + fmd); 40 41 elementType = colmd.getElementType(); 42 elementsAreEmbedded = false; 43 44 FieldMetaData eofmd = colmd.getOwnerField(); 45 46 FieldMetaData omd = eofmd.getOwnedByCollection(); 47 if (omd == null || !omd.equals(fmd)) 48 throw new InvalidMetaDataRelationshipException(fmd, "owner-field", eofmd, "collection-field"); 49 50 String ownerFieldName = eofmd.getName(); 51 52 ClassMetaData emd = eofmd.getClassMetaData(); 53 ownerFieldNumber = emd.getAbsoluteFieldNumber(ownerFieldName); 54 55 ClassBaseTable elementTable = storeMgr.getClassBaseTable(elementType); 56 57 if (!elementTable.isFieldPersistent(ownerFieldNumber)) 58 throw new JDOUserException("Non-persistent field type for collection owner field: " + field.getDeclaringClass().getName() + "." + field.getName()); 59 60 Mapping m = elementTable.getFieldMapping(ownerFieldNumber); 61 if (!(m instanceof ColumnMapping) || m instanceof PostWriteProcessing) 62 throw new JDOUserException("Invalid field type for collection owner field: " + field.getDeclaringClass().getName() + "." + field.getName()); 63 64 ownerMapping = (ColumnMapping)m; 65 elementMapping = (ColumnMapping)dba.getMapping(elementType); 66 67 setTable = elementTable; 68 setName = "inverseSet"; 69 70 ownerColumn = ownerMapping.getColumn(); 71 elementColumn = elementTable.getIDMapping().getColumn(); 72 73 loadStmt = "SELECT " + elementColumn.getName() + 74 " FROM " + elementTable.getName() + 75 " WHERE " + ownerColumn.getName() + " = ?"; 76 sizeStmt = "SELECT COUNT(" + elementColumn.getName() + ")" + 77 " FROM " + elementTable.getName() + 78 " WHERE " + ownerColumn.getName() + " = ?"; 79 containsStmt = "SELECT " + elementColumn.getName() + 80 " FROM " + elementTable.getName() + 81 " WHERE " + ownerColumn.getName() + " = ? AND " + elementColumn.getName() + " = ?"; 82 addStmt = null; 83 removeStmt = null; 84 clearStmt = null; 85 86 89 int fieldCount = emd.getInheritedFieldCount() + emd.getFieldCount(); 90 IntArrayList colfn = new IntArrayList(fieldCount); 91 ColumnMapping[] colfm = new ColumnMapping[fieldCount]; 92 93 boolean[] defaultFetchGroupFields = emd.getDefaultFetchGroupFieldFlags(); 94 95 for (int i = 0; i < fieldCount; ++i) 96 { 97 if (defaultFetchGroupFields[i]) 98 { 99 m = elementTable.getFieldMapping(i); 100 101 if (m instanceof ColumnMapping) 102 { 103 colfn.add(i); 104 colfm[i] = (ColumnMapping)m; 105 } 106 } 107 } 108 109 if (colfn.isEmpty()) 110 { 111 prefetchFieldNumbers = null; 112 prefetchFieldMappings = null; 113 } 114 else 115 { 116 prefetchFieldNumbers = colfn.toArray(); 117 prefetchFieldMappings = colfm; 118 } 119 } 120 121 122 public QueryStatement newQueryStatement(StateManager sm, Class candidateClass) 123 { 124 if (!elementType.isAssignableFrom(candidateClass)) 125 throw new IncompatibleQueryElementTypeException(elementType, candidateClass); 126 127 ClassBaseTable candidateTable = storeMgr.getClassBaseTable(candidateClass); 128 QueryStatement stmt = dba.newQueryStatement(candidateTable); 129 130 SQLExpression ownerExpr = new ObjectExpression(stmt, stmt.getColumn(ownerColumn)); 131 SQLExpression ownerVal = ownerMapping.newSQLLiteral(stmt, sm.getObject()); 132 133 stmt.andCondition(ownerExpr.eq(ownerVal)); 134 135 stmt.select(elementColumn); 136 137 return stmt; 138 } 139 140 141 public QueryStatement.QueryColumn 142 joinElementsTo(QueryStatement stmt, 143 QueryStatement.QueryColumn ownerIDColumn, 144 SQLIdentifier setRangeVar, 145 Class filteredElementType, 146 SQLIdentifier elementRangeVar) 147 { 148 if (!elementType.isAssignableFrom(filteredElementType)) 149 throw new IncompatibleQueryElementTypeException(elementType, filteredElementType); 150 151 152 ClassBaseTable filteredElementTable = storeMgr.getClassBaseTable(filteredElementType); 153 154 stmt.newTableExpression(filteredElementTable, elementRangeVar); 155 stmt.innerJoin(ownerIDColumn, stmt.getColumn(elementRangeVar, ownerColumn)); 156 157 Column elementTableIDColumn = filteredElementTable.getIDMapping().getColumn(); 158 159 return stmt.getColumn(elementRangeVar, elementTableIDColumn); 160 } 161 162 163 public boolean add(StateManager sm, Object element) 164 { 165 PersistenceManager pm = sm.getPersistenceManager(); 166 StateManager esm = pm.findStateManager(element); 167 168 175 if (esm == null) 176 { 177 pm.makeTransactional(element); 178 esm = pm.findStateManager(element); 179 } 180 181 boolean wasPersistent = esm.isPersistent((javax.jdo.spi.PersistenceCapable)element); 182 183 189 Object oldOwner = esm.getField(ownerFieldNumber); 190 Object newOwner = sm.getObject(); 191 esm.setField(ownerFieldNumber, oldOwner, newOwner); 192 pm.makePersistent(element); 193 194 return !wasPersistent || oldOwner != newOwner; 195 } 196 197 198 public boolean remove(StateManager sm, Object element) 199 { 200 if (!validateElementForReading(sm, element)) 201 return false; 202 203 PersistenceManager pm = sm.getPersistenceManager(); 204 StateManager esm = pm.findStateManager(element); 205 206 Object oldOwner = esm.getField(ownerFieldNumber); 207 208 if (oldOwner != sm.getObject()) 209 return false; 210 else 211 { 212 if (ownerColumn.isNullable()) 213 esm.setField(ownerFieldNumber, oldOwner, null); 214 else 215 pm.deletePersistent(element); 216 217 return true; 218 } 219 } 220 221 222 public void clear(StateManager sm) 223 { 224 PersistenceManager pm = sm.getPersistenceManager(); 225 Collection elements = load(sm); 226 227 if (ownerColumn.isNullable()) 228 { 229 Iterator i = elements.iterator(); 230 231 while (i.hasNext()) 232 { 233 StateManager esm = pm.findStateManager(i.next()); 234 esm.setField(ownerFieldNumber, esm.getField(ownerFieldNumber), null); 235 } 236 } 237 else 238 pm.deletePersistentAll(elements); 239 } 240 } 241 | Popular Tags |