1 package org.apache.ojb.broker.metadata; 2 3 17 18 import java.util.List ; 19 import java.util.Map ; 20 import java.util.HashMap ; 21 22 import org.apache.commons.lang.SystemUtils; 23 import org.apache.ojb.broker.metadata.fieldaccess.AnonymousPersistentField; 24 import org.apache.ojb.broker.metadata.fieldaccess.PersistentField; 25 import org.apache.ojb.broker.metadata.fieldaccess.PersistentFieldFactory; 26 import org.apache.ojb.broker.util.ClassHelper; 27 import org.apache.ojb.broker.util.logging.Logger; 28 import org.apache.ojb.broker.util.logging.LoggerFactory; 29 30 36 public class SuperReferenceDescriptor extends ObjectReferenceDescriptor 37 { 38 private transient Logger log; 39 40 public static final String SUPER_FIELD_INTERNAL_NAME = "ojbSuperFieldInternal"; 41 public static final String SUPER_FIELD_NAME = RepositoryElements.TAG_SUPER; 42 43 private Boolean javaInheritance; 44 private Map declaredInheritanceFields = new HashMap (); 45 46 public SuperReferenceDescriptor(ClassDescriptor descriptor) 47 { 48 super(descriptor); 49 super.setPersistentField(new SuperReferenceField(this)); 51 super.setLazy(false); 53 super.setCascadeRetrieve(true); 54 super.setCascadingStore(CASCADE_OBJECT); 55 super.setCascadingDelete(CASCADE_OBJECT); 56 } 57 58 public boolean isSuperReferenceDescriptor() 59 { 60 return true; 61 } 62 63 public void setItemClass(Class c) 64 { 65 super.setItemClass(c); 66 getClassDescriptor().setBaseClass(c.getName()); 67 } 68 69 73 public void setPersistentField(Class c, String fieldname) 74 { 75 } 77 78 82 public void setPersistentField(PersistentField pf) 83 { 84 } 86 87 public void setLazy(boolean lazy) 88 { 89 getLog().info("Not allowed to change this property, will ignore setting"); 90 } 91 92 public void setCascadeRetrieve(boolean b) 93 { 94 getLog().info("Not allowed to change this property, will ignore setting"); 95 } 96 97 public void setCascadingStore(int cascade) 98 { 99 getLog().info("Not allowed to change this property, will ignore setting"); 100 } 101 102 public void setCascadingStore(String value) 103 { 104 getLog().info("Not allowed to change this property, will ignore setting"); 105 } 106 107 public void setCascadingDelete(int cascade) 108 { 109 getLog().info("Not allowed to change this property, will ignore setting"); 110 } 111 112 public void setCascadingDelete(String value) 113 { 114 getLog().info("Not allowed to change this property, will ignore setting"); 115 } 116 117 public void setCascadeStore(boolean cascade) 118 { 119 getLog().info("Not allowed to change this property, will ignore setting"); 120 } 121 122 public void setCascadeDelete(boolean cascade) 123 { 124 getLog().info("Not allowed to change this property, will ignore setting"); 125 } 126 127 public SuperReferenceField getInheritanceField() 128 { 129 return (SuperReferenceField) getPersistentField(); 130 } 131 132 138 public boolean isJavaInheritance() 139 { 140 if(javaInheritance == null) 141 { 142 javaInheritance = getClassDescriptor().getSuperClassDescriptor().getClassOfObject() 143 .isAssignableFrom(getClassDescriptor().getClassOfObject()) ? Boolean.TRUE : Boolean.FALSE; 144 } 145 return javaInheritance.booleanValue(); 146 } 147 148 synchronized PersistentField getDeclaredInheritanceField(Class target, String name) 149 { 150 Map fields = (HashMap ) declaredInheritanceFields.get(target); 151 if(fields == null) 152 { 153 fields = new HashMap (); 154 declaredInheritanceFields.put(target, fields); 155 } 156 PersistentField pf = (PersistentField) fields.get(name); 157 if(pf == null) 158 { 159 pf = PersistentFieldFactory.createPersistentField(target, name); 160 fields.put(name, pf); 162 } 163 return pf; 164 } 165 166 private Logger getLog() 167 { 168 if(log == null) 169 { 170 log = LoggerFactory.getLogger(SuperReferenceField.class); 171 } 172 return log; 173 } 174 175 176 180 public static final class SuperReferenceField extends AnonymousPersistentField 181 { 182 private transient Logger log; 183 184 private SuperReferenceDescriptor superRef; 185 186 public SuperReferenceField(SuperReferenceDescriptor superRef) 187 { 188 super(SUPER_FIELD_INTERNAL_NAME); 189 this.superRef = superRef; 190 } 191 192 private Logger getLog() 193 { 194 if(log == null) 195 { 196 log = LoggerFactory.getLogger(SuperReferenceField.class); 197 } 198 return log; 199 } 200 201 209 public synchronized void set(Object target, Object value) throws MetadataException 210 { 211 ClassDescriptor superCld = superRef.getClassDescriptor().getSuperClassDescriptor(); 213 if(superRef.isJavaInheritance()) 214 { 215 copyFields(superCld, target, superCld, value, true, true); 216 } 217 else 218 { 219 copyFields(superRef.getClassDescriptor(), target, superCld, value, false, false); 220 } 221 } 222 223 234 public synchronized Object get(Object obj) throws MetadataException 235 { 236 if(obj == null) return null; 237 if(superRef.isJavaInheritance()) 238 { 239 return obj; 240 } 241 else 242 { 243 return getObjectWithDeclaredSuperClass(obj); 244 } 245 } 246 247 private Object getObjectWithDeclaredSuperClass(Object obj) 248 { 249 Object value = getFromFieldCache(obj); 250 if(value == null) 251 { 252 ClassDescriptor baseCld = null; 253 try 254 { 255 baseCld = superRef.getClassDescriptor().getSuperClassDescriptor(); 256 value = ClassHelper.buildNewObjectInstance(baseCld); 257 } 258 catch(Exception e) 259 { 260 throw new MetadataException("Can't create new base class object for '" 261 + (baseCld != null ? baseCld.getClassNameOfObject() : null) + "'", e); 262 } 263 copyFields(baseCld, value, superRef.getClassDescriptor(), obj, true, false); 264 putToFieldCache(obj, value); 265 } 266 return value; 267 } 268 269 void copyFields(ClassDescriptor targetCld, Object target, ClassDescriptor sourceCld, Object source, boolean targetIsSuper, boolean javaInheritance) 270 { 271 if(getLog().isDebugEnabled()) 272 { 273 String msg = ("Copy fields from " + SystemUtils.LINE_SEPARATOR 274 + "source object '" + (source != null ? source.getClass().getName() : null) + "'" + SystemUtils.LINE_SEPARATOR 275 + "using source fields declared in '" + sourceCld.getClassNameOfObject() + "'" + SystemUtils.LINE_SEPARATOR 276 + "to target object '" + (target != null ? target.getClass().getName() : null) + "'" + SystemUtils.LINE_SEPARATOR 277 + "using target fields declared in '" + targetCld.getClassNameOfObject() + "'" + SystemUtils.LINE_SEPARATOR 278 + "the fields to copy are declared in '" + (targetIsSuper ? targetCld.getClassNameOfObject() : sourceCld.getClassNameOfObject()) + "' class" + SystemUtils.LINE_SEPARATOR 279 + "the used classes are associated by java inheritance: " + javaInheritance + SystemUtils.LINE_SEPARATOR); 280 getLog().debug(msg); 281 } 282 292 FieldDescriptor[] fields = targetIsSuper ? targetCld.getFieldDescriptions() : sourceCld.getFieldDescriptions(); 293 for(int i = 0; i < fields.length; i++) 294 { 295 FieldDescriptor field = fields[i]; 296 if(!field.isAnonymous()) 297 { 298 performFieldCopy(target, targetCld, source, sourceCld, 299 field.getPersistentField(), targetIsSuper, javaInheritance); 300 } 301 } 302 List refs = targetIsSuper ? targetCld.getCollectionDescriptors() : sourceCld.getCollectionDescriptors(); 303 for(int i = 0; i < refs.size(); i++) 304 { 305 CollectionDescriptor col = (CollectionDescriptor) refs.get(i); 306 PersistentField pf = col.getPersistentField(); 307 performFieldCopy(target, targetCld, source, sourceCld, pf, targetIsSuper, javaInheritance); 308 } 309 310 refs = targetIsSuper ? targetCld.getObjectReferenceDescriptors() : sourceCld.getObjectReferenceDescriptors(); 311 for(int i = 0; i < refs.size(); i++) 312 { 313 ObjectReferenceDescriptor ord = (ObjectReferenceDescriptor) refs.get(i); 314 PersistentField pf = ord.getPersistentField(); 315 performFieldCopy(target, targetCld, source, sourceCld, pf, targetIsSuper, javaInheritance); 316 } 317 } 318 319 private void performFieldCopy(Object target, ClassDescriptor targetCld, Object source, 320 ClassDescriptor sourceCld, PersistentField pf, boolean targetIsSuper, boolean javaInheritance) 321 { 322 if(javaInheritance) 323 { 324 pf.set(target, pf.get(source)); 325 } 326 else 327 { 328 if(targetIsSuper) 329 { 330 if(pf instanceof SuperReferenceField) 331 { 332 log.error("Declared inheritance doesn't support nested super references, target '" 333 + targetCld.getClassNameOfObject() + "' has super reference"); 334 } 335 else 336 { 337 PersistentField tmp = superRef.getDeclaredInheritanceField(sourceCld.getClassOfObject(), pf.getName()); 338 pf.set(target, tmp.get(source)); 339 } 340 } 341 else 342 { 343 PersistentField tmp = superRef.getDeclaredInheritanceField(targetCld.getClassOfObject(), pf.getName()); 344 tmp.set(target, pf.get(source)); 345 } 346 } 347 } 348 } 349 } 350 351 | Popular Tags |