1 56 package org.objectstyle.cayenne.access; 57 58 import java.util.Collection ; 59 import java.util.HashMap ; 60 import java.util.Iterator ; 61 import java.util.Map ; 62 63 import org.apache.commons.collections.Factory; 64 import org.apache.commons.collections.Transformer; 65 import org.objectstyle.cayenne.CayenneRuntimeException; 66 import org.objectstyle.cayenne.DataObject; 67 import org.objectstyle.cayenne.ObjectId; 68 import org.objectstyle.cayenne.dba.PkGenerator; 69 import org.objectstyle.cayenne.map.DbEntity; 70 import org.objectstyle.cayenne.map.ObjEntity; 71 72 80 class EntityDescriptor { 81 82 DataNode node; 83 ObjEntity entity; 84 DbEntity dbEntity; 85 Map snapshotTransformers; 86 87 EntityDescriptor(DataNode node, ObjEntity entity) { 88 this.node = node; 89 this.entity = entity; 90 this.dbEntity = entity.getDbEntity(); 91 initTransformers(); 92 } 93 94 private void initTransformers() { 95 96 Collection attributes = dbEntity.getAttributes(); 97 this.snapshotTransformers = new HashMap ((int) (attributes.size() * 4.00 / 3.00)); 98 99 101 Iterator it = entity.getAttributes().iterator(); 102 while (it.hasNext()) { 103 105 } 106 } 107 108 113 Map deferredSnapshot(DataObject object) { 114 Map snapshot = new HashMap ((int) (snapshotTransformers.size() * 4.00 / 3.00)); 115 Iterator it = snapshotTransformers.entrySet().iterator(); 116 while (it.hasNext()) { 117 Map.Entry entry = (Map.Entry ) it.next(); 118 snapshot.put(entry.getKey(), ((Transformer) entry.getValue()) 119 .transform(object)); 120 } 121 122 return snapshot; 123 } 124 125 Object deferredSnapshotValue(DataObject object, String dbAttributeName) { 126 Transformer transformer = (Transformer) snapshotTransformers 127 .get(dbAttributeName); 128 129 if (transformer == null) { 130 throw new CayenneRuntimeException("Invalid DbAttribute: " + dbAttributeName); 131 } 132 133 return transformer.transform(object); 134 } 135 136 140 abstract class DataObjectTransformer implements Transformer { 141 142 public Object transform(Object input) { 143 if (input instanceof DataObject) { 144 return (DataObject) transformDataObject((DataObject) input); 145 } 146 147 throw new CayenneRuntimeException("Invalid input: " + input); 148 } 149 150 protected abstract Object transformDataObject(DataObject object); 151 } 152 153 final class NullPredicateTransformer extends DataObjectTransformer { 155 156 String attributeName; 157 DataObjectTransformer[] transformers; 158 159 NullPredicateTransformer(DataObjectTransformer[] transformers, 160 String attributeName) { 161 this.transformers = transformers; 162 this.attributeName = attributeName; 163 } 164 165 protected Object transformDataObject(DataObject object) { 166 for (int i = 0; i < transformers.length; i++) { 167 Object value = transformers[i].transformDataObject(object); 168 if (value != null) { 169 return value; 170 } 171 } 172 173 throw new CayenneRuntimeException("Problem getting snapshot value for " 174 + object.getClass() 175 + ", attribute name: " 176 + attributeName); 177 } 178 } 179 180 final class ObjectPropertyTransformer extends DataObjectTransformer { 181 182 String property; 183 184 ObjectPropertyTransformer(String property) { 185 this.property = property; 186 } 187 188 protected Object transformDataObject(DataObject object) { 189 return object.readPropertyDirectly(property); 190 } 191 } 192 193 final class PropagatedValueTransformer extends DataObjectTransformer { 194 195 String masterProperty; 196 String masterIDKey; 197 boolean deferred; 198 boolean required; 199 200 PropagatedValueTransformer(String masterProperty, String masterIDKey, 201 boolean required, boolean deferred) { 202 this.masterIDKey = masterIDKey; 203 this.masterProperty = masterProperty; 204 this.required = required; 205 this.deferred = deferred; 206 } 207 208 protected Object transformDataObject(DataObject object) { 209 210 DataObject targetDo = (DataObject) object 211 .readPropertyDirectly(masterProperty); 212 213 if (targetDo == null) { 214 throw new CayenneRuntimeException( 215 "Problem extracting master PK value - null master object for " 216 + object.getClass() 217 + "." 218 + masterProperty); 219 } 220 221 ObjectId targetKey = targetDo.getObjectId(); 222 223 if (deferred) { 224 return new DeferredIDValueFactory(targetKey, masterIDKey); 225 } 226 227 Object value = targetKey.getValueForAttribute(masterIDKey); 228 229 if (required && value == null) { 230 throw new CayenneRuntimeException( 231 "Problem extracting master PK value - null master PK " 232 + object.getClass() 233 + "." 234 + masterProperty); 235 } 236 237 return value; 238 } 239 } 240 241 final class CayenneGeneratedPKTransformer extends DataObjectTransformer { 242 243 PkGenerator generator; 244 245 CayenneGeneratedPKTransformer(PkGenerator generator) { 246 this.generator = generator; 247 } 248 249 protected Object transformDataObject(DataObject object) { 250 try { 251 return generator.generatePkForDbEntity(node, dbEntity); 252 } 253 catch (Exception ex) { 254 throw new CayenneRuntimeException("Error generating PK: " 255 + ex.getMessage(), ex); 256 } 257 } 258 } 259 260 264 final static class DeferredIDValueFactory implements Factory { 265 266 ObjectId objectID; 267 String idKey; 268 269 DeferredIDValueFactory(ObjectId objectID, String idKey) { 270 this.objectID = objectID; 271 this.idKey = idKey; 272 } 273 274 public Object create() { 275 if (!objectID.isReplacementIdAttached()) { 276 throw new CayenneRuntimeException("Replacement value for key '" 277 + idKey 278 + "' is not available in ObjectId " 279 + objectID); 280 } 281 282 Map replacementId = objectID.getReplacementIdMap(); 283 Object value = replacementId.get(idKey); 284 if (value == null) { 285 throw new CayenneRuntimeException("Replacement value for key '" 286 + idKey 287 + "' is not available in ObjectId " 288 + objectID); 289 } 290 291 return value; 292 } 293 } 294 } | Popular Tags |