1 19 package org.apache.cayenne.reflect; 20 21 import java.util.ArrayList ; 22 import java.util.Collection ; 23 import java.util.HashMap ; 24 import java.util.Iterator ; 25 import java.util.Map ; 26 27 import org.apache.cayenne.CayenneRuntimeException; 28 import org.apache.cayenne.PersistenceState; 29 import org.apache.cayenne.map.ObjAttribute; 30 import org.apache.cayenne.map.ObjEntity; 31 import org.apache.commons.collections.IteratorUtils; 32 33 39 public class PersistentDescriptor implements ClassDescriptor { 40 41 static final Integer TRANSIENT_STATE = new Integer (PersistenceState.TRANSIENT); 42 static final Integer HOLLOW_STATE = new Integer (PersistenceState.HOLLOW); 43 static final Integer COMMITTED_STATE = new Integer (PersistenceState.COMMITTED); 44 45 protected ClassDescriptor superclassDescriptor; 46 47 protected Class objectClass; 49 protected Map declaredProperties; 50 protected Map subclassDescriptors; 51 protected Accessor persistenceStateAccessor; 52 53 protected ObjEntity entity; 54 55 protected Collection declaredIdProperties; 56 57 60 public PersistentDescriptor() { 61 this.declaredProperties = new HashMap (); 62 this.subclassDescriptors = new HashMap (); 63 } 64 65 69 public void addDeclaredProperty(Property property) { 70 declaredProperties.put(property.getName(), property); 71 72 if (property instanceof AttributeProperty) { 73 ObjAttribute attribute = ((AttributeProperty) property).getAttribute(); 74 if (attribute.getDbAttributeName() != null 75 && attribute.getDbAttribute().isPrimaryKey()) { 76 77 if (declaredIdProperties == null) { 78 declaredIdProperties = new ArrayList (2); 79 } 80 81 declaredIdProperties.add(property); 82 } 83 } 84 } 85 86 90 public void removeDeclaredProperty(String propertyName) { 91 Object removed = declaredProperties.remove(propertyName); 92 93 if (declaredIdProperties != null && removed != null) { 94 declaredIdProperties.remove(removed); 95 } 96 } 97 98 public void addSubclassDescriptor(ClassDescriptor subclassDescriptor) { 99 subclassDescriptors.put( 100 subclassDescriptor.getEntity().getClassName(), 101 subclassDescriptor); 102 } 103 104 public ObjEntity getEntity() { 105 return entity; 106 } 107 108 public boolean isFault(Object object) { 109 if (superclassDescriptor != null) { 110 return superclassDescriptor.isFault(object); 111 } 112 113 if (object == null) { 114 return false; 115 } 116 117 return HOLLOW_STATE.equals(persistenceStateAccessor.getValue(object)); 118 } 119 120 public Class getObjectClass() { 121 return objectClass; 122 } 123 124 void setObjectClass(Class objectClass) { 125 this.objectClass = objectClass; 126 } 127 128 public ClassDescriptor getSubclassDescriptor(Class objectClass) { 129 if (objectClass == null) { 130 throw new IllegalArgumentException ("Null objectClass"); 131 } 132 133 if (subclassDescriptors.isEmpty()) { 134 return this; 135 } 136 137 ClassDescriptor subclassDescriptor = (ClassDescriptor) subclassDescriptors 138 .get(objectClass.getName()); 139 140 if (subclassDescriptor == null) { 142 Class currentClass = objectClass; 143 while (subclassDescriptor == null 144 && (currentClass = currentClass.getSuperclass()) != null) { 145 subclassDescriptor = (ClassDescriptor) subclassDescriptors 146 .get(currentClass.getName()); 147 } 148 } 149 150 return subclassDescriptor != null ? subclassDescriptor : this; 151 } 152 153 157 public Iterator getProperties() { 158 Iterator declaredIt = IteratorUtils.unmodifiableIterator(declaredProperties 159 .values() 160 .iterator()); 161 162 if (getSuperclassDescriptor() == null) { 163 return declaredIt; 164 } 165 else { 166 return IteratorUtils.chainedIterator( 167 superclassDescriptor.getProperties(), 168 declaredIt); 169 } 170 } 171 172 public Iterator getIdProperties() { 173 174 Iterator it = null; 175 176 if (getSuperclassDescriptor() != null) { 177 it = getSuperclassDescriptor().getIdProperties(); 178 } 179 180 if (declaredIdProperties != null) { 181 it = (it != null) ? IteratorUtils.chainedIterator(it, declaredIdProperties 182 .iterator()) : declaredIdProperties.iterator(); 183 } 184 185 return it != null ? it : IteratorUtils.EMPTY_ITERATOR; 186 } 187 188 192 public Property getProperty(String propertyName) { 193 Property property = getDeclaredProperty(propertyName); 194 195 if (property == null && superclassDescriptor != null) { 196 property = superclassDescriptor.getProperty(propertyName); 197 } 198 199 return property; 200 } 201 202 public Property getDeclaredProperty(String propertyName) { 203 return (Property) declaredProperties.get(propertyName); 204 } 205 206 210 public ClassDescriptor getSuperclassDescriptor() { 211 return superclassDescriptor; 212 } 213 214 217 public Object createObject() { 218 if (objectClass == null) { 219 throw new NullPointerException ( 220 "Null objectClass. Descriptor wasn't initialized properly."); 221 } 222 223 try { 224 return objectClass.newInstance(); 225 } 226 catch (Throwable e) { 227 throw new CayenneRuntimeException("Error creating object of class '" 228 + objectClass.getName() 229 + "'", e); 230 } 231 } 232 233 237 public void injectValueHolders(Object object) throws PropertyException { 238 239 if (getSuperclassDescriptor() != null) { 241 getSuperclassDescriptor().injectValueHolders(object); 242 } 243 244 Iterator it = declaredProperties.values().iterator(); 245 while (it.hasNext()) { 246 Property property = (Property) it.next(); 247 property.injectValueHolder(object); 248 } 249 } 250 251 255 public void shallowMerge(final Object from, final Object to) throws PropertyException { 256 257 visitProperties(new PropertyVisitor() { 258 259 public boolean visitAttribute(AttributeProperty property) { 260 property.writePropertyDirectly( 261 to, 262 property.readPropertyDirectly(to), 263 property.readPropertyDirectly(from)); 264 return true; 265 } 266 267 public boolean visitToOne(ToOneProperty property) { 268 property.invalidate(to); 269 return true; 270 } 271 272 public boolean visitToMany(ToManyProperty property) { 273 return true; 274 } 275 }); 276 } 277 278 281 public boolean visitDeclaredProperties(PropertyVisitor visitor) { 282 Iterator it = declaredProperties.values().iterator(); 283 while (it.hasNext()) { 284 Property next = (Property) it.next(); 285 if (!next.visit(visitor)) { 286 return false; 287 } 288 } 289 290 return true; 291 } 292 293 296 public boolean visitAllProperties(PropertyVisitor visitor) { 297 if (!visitProperties(visitor)) { 298 return false; 299 } 300 301 if (!subclassDescriptors.isEmpty()) { 302 Iterator it = subclassDescriptors.values().iterator(); 303 while (it.hasNext()) { 304 ClassDescriptor next = (ClassDescriptor) it.next(); 305 if (!next.visitDeclaredProperties(visitor)) { 306 return false; 307 } 308 } 309 } 310 311 return true; 312 } 313 314 public boolean visitProperties(PropertyVisitor visitor) { 315 if (superclassDescriptor != null 316 && !superclassDescriptor.visitProperties(visitor)) { 317 return false; 318 } 319 320 return visitDeclaredProperties(visitor); 321 } 322 323 public void setPersistenceStateAccessor(Accessor persistenceStateAccessor) { 324 this.persistenceStateAccessor = persistenceStateAccessor; 325 } 326 327 public void setEntity(ObjEntity entity) { 328 this.entity = entity; 329 } 330 331 public void setSuperclassDescriptor(ClassDescriptor superclassDescriptor) { 332 this.superclassDescriptor = superclassDescriptor; 333 } 334 } 335 | Popular Tags |