1 package xdoclet.modules.ojb.constraints; 2 3 import xdoclet.modules.ojb.CommaListIterator; 4 import xdoclet.modules.ojb.model.ClassDescriptorDef; 5 import xdoclet.modules.ojb.model.CollectionDescriptorDef; 6 import xdoclet.modules.ojb.model.FieldDescriptorDef; 7 import xdoclet.modules.ojb.model.ModelDef; 8 import xdoclet.modules.ojb.model.PropertyHelper; 9 10 24 25 31 public class CollectionDescriptorConstraints extends FeatureDescriptorConstraints 32 { 33 34 private final static String JAVA_COLLECTION_INTERFACE = "java.util.Collection"; 35 36 private final static String MANAGEABLE_COLLECTION_INTERFACE = "org.apache.ojb.broker.ManageableCollection"; 37 38 private final static String QUERY_CUSTOMIZER_INTERFACE = "org.apache.ojb.broker.accesslayer.QueryCustomizer"; 39 40 47 public void check(CollectionDescriptorDef collDef, String checkLevel) throws ConstraintException 48 { 49 ensureElementClassRef(collDef, checkLevel); 50 checkInheritedForeignkey(collDef, checkLevel); 51 ensureCollectionClass(collDef, checkLevel); 52 checkProxyPrefetchingLimit(collDef, checkLevel); 53 checkOrderby(collDef, checkLevel); 54 checkQueryCustomizer(collDef, checkLevel); 55 } 56 57 64 private void ensureElementClassRef(CollectionDescriptorDef collDef, String checkLevel) throws ConstraintException 65 { 66 if (CHECKLEVEL_NONE.equals(checkLevel)) 67 { 68 return; 69 } 70 71 String arrayElementClassName = collDef.getProperty(PropertyHelper.OJB_PROPERTY_ARRAY_ELEMENT_CLASS_REF); 72 73 if (!collDef.hasProperty(PropertyHelper.OJB_PROPERTY_ELEMENT_CLASS_REF)) 74 { 75 if (arrayElementClassName != null) 76 { 77 collDef.setProperty(PropertyHelper.OJB_PROPERTY_ELEMENT_CLASS_REF, arrayElementClassName); 79 } 80 else 81 { 82 throw new ConstraintException("Collection "+collDef.getName()+" in class "+collDef.getOwner().getName()+" does not specify its element class"); 83 } 84 } 85 86 ModelDef model = (ModelDef)collDef.getOwner().getOwner(); 88 String elementClassName = collDef.getProperty(PropertyHelper.OJB_PROPERTY_ELEMENT_CLASS_REF); 89 ClassDescriptorDef elementClassDef = model.getClass(elementClassName); 90 91 if (elementClassDef == null) 92 { 93 throw new ConstraintException("Collection "+collDef.getName()+" in class "+collDef.getOwner().getName()+" references an unknown class "+elementClassName); 94 } 95 if (!elementClassDef.getBooleanProperty(PropertyHelper.OJB_PROPERTY_OJB_PERSISTENT, false)) 96 { 97 throw new ConstraintException("The element class "+elementClassName+" of the collection "+collDef.getName()+" in class "+collDef.getOwner().getName()+" is not persistent"); 98 } 99 if (CHECKLEVEL_STRICT.equals(checkLevel) && (arrayElementClassName != null)) 100 { 101 try 103 { 104 InheritanceHelper helper = new InheritanceHelper(); 105 106 if (!helper.isSameOrSubTypeOf(elementClassDef, arrayElementClassName, true)) 107 { 108 throw new ConstraintException("The element class "+elementClassName+" of the collection "+collDef.getName()+" in class "+collDef.getOwner().getName()+" is not the same or a subtype of the array base type "+arrayElementClassName); 109 } 110 } 111 catch (ClassNotFoundException ex) 112 { 113 throw new ConstraintException("Could not find the class "+ex.getMessage()+" on the classpath while checking the collection "+collDef.getName()+" in class "+collDef.getOwner().getName()); 114 } 115 } 116 collDef.setProperty(PropertyHelper.OJB_PROPERTY_ELEMENT_CLASS_REF, elementClassDef.getName()); 118 } 119 120 126 private void checkInheritedForeignkey(CollectionDescriptorDef collDef, String checkLevel) throws ConstraintException 127 { 128 if (CHECKLEVEL_NONE.equals(checkLevel)) 129 { 130 return; 131 } 132 if (!collDef.isInherited() && !collDef.isNested()) 133 { 134 return; 135 } 136 if (!collDef.hasProperty(PropertyHelper.OJB_PROPERTY_INDIRECTION_TABLE)) 137 { 138 return; 139 } 140 141 String localFk = collDef.getProperty(PropertyHelper.OJB_PROPERTY_FOREIGNKEY); 142 String inheritedFk = collDef.getOriginal().getProperty(PropertyHelper.OJB_PROPERTY_FOREIGNKEY); 143 144 if (!CommaListIterator.sameLists(localFk, inheritedFk)) 145 { 146 throw new ConstraintException("The foreignkey property has been changed for the m:n collection "+collDef.getName()+" in class "+collDef.getOwner().getName()); 147 } 148 } 149 150 157 private void ensureCollectionClass(CollectionDescriptorDef collDef, String checkLevel) throws ConstraintException 158 { 159 if (CHECKLEVEL_NONE.equals(checkLevel)) 160 { 161 return; 162 } 163 164 if (collDef.hasProperty(PropertyHelper.OJB_PROPERTY_ARRAY_ELEMENT_CLASS_REF)) 165 { 166 if (collDef.hasProperty(PropertyHelper.OJB_PROPERTY_COLLECTION_CLASS)) 168 { 169 throw new ConstraintException("Collection "+collDef.getName()+" in class "+collDef.getOwner().getName()+" is an array but does specify collection-class"); 170 } 171 else 172 { 173 return; 175 } 176 } 177 178 if (CHECKLEVEL_STRICT.equals(checkLevel)) 179 { 180 InheritanceHelper helper = new InheritanceHelper(); 181 ModelDef model = (ModelDef)collDef.getOwner().getOwner(); 182 String specifiedClass = collDef.getProperty(PropertyHelper.OJB_PROPERTY_COLLECTION_CLASS); 183 String variableType = collDef.getProperty(PropertyHelper.OJB_PROPERTY_VARIABLE_TYPE); 184 185 try 186 { 187 if (specifiedClass != null) 188 { 189 if (!helper.isSameOrSubTypeOf(specifiedClass, variableType)) 191 { 192 throw new ConstraintException("The type "+specifiedClass+" specified as collection-class of the collection "+collDef.getName()+" in class "+collDef.getOwner().getName()+" is not a sub type of the variable type "+variableType); 193 } 194 if (!helper.isSameOrSubTypeOf(specifiedClass, MANAGEABLE_COLLECTION_INTERFACE)) 195 { 196 throw new ConstraintException("The type "+specifiedClass+" specified as collection-class of the collection "+collDef.getName()+" in class "+collDef.getOwner().getName()+" does not implement "+MANAGEABLE_COLLECTION_INTERFACE); 197 } 198 } 199 else 200 { 201 if (helper.isSameOrSubTypeOf(variableType, MANAGEABLE_COLLECTION_INTERFACE)) 203 { 204 collDef.setProperty(PropertyHelper.OJB_PROPERTY_COLLECTION_CLASS, variableType); 206 } 207 else if (!helper.isSameOrSubTypeOf(variableType, JAVA_COLLECTION_INTERFACE)) 208 { 209 throw new ConstraintException("The collection "+collDef.getName()+" in class "+collDef.getOwner().getName()+" needs the collection-class attribute as its variable type does not implement "+JAVA_COLLECTION_INTERFACE); 210 } 211 } 212 } 213 catch (ClassNotFoundException ex) 214 { 215 throw new ConstraintException("Could not find the class "+ex.getMessage()+" on the classpath while checking the collection "+collDef.getName()+" in class "+collDef.getOwner().getName()); 216 } 217 } 218 } 219 220 227 private void checkOrderby(CollectionDescriptorDef collDef, String checkLevel) throws ConstraintException 228 { 229 if (CHECKLEVEL_NONE.equals(checkLevel)) 230 { 231 return; 232 } 233 234 String orderbySpec = collDef.getProperty(PropertyHelper.OJB_PROPERTY_ORDERBY); 235 236 if ((orderbySpec == null) || (orderbySpec.length() == 0)) 237 { 238 return; 239 } 240 241 ClassDescriptorDef ownerClass = (ClassDescriptorDef)collDef.getOwner(); 242 String elementClassName = collDef.getProperty(PropertyHelper.OJB_PROPERTY_ELEMENT_CLASS_REF).replace('$', '.'); 243 ClassDescriptorDef elementClass = ((ModelDef)ownerClass.getOwner()).getClass(elementClassName); 244 FieldDescriptorDef fieldDef; 245 String token; 246 String fieldName; 247 String ordering; 248 int pos; 249 250 for (CommaListIterator it = new CommaListIterator(orderbySpec); it.hasNext();) 251 { 252 token = it.getNext(); 253 pos = token.indexOf('='); 254 if (pos == -1) 255 { 256 fieldName = token; 257 ordering = null; 258 } 259 else 260 { 261 fieldName = token.substring(0, pos); 262 ordering = token.substring(pos + 1); 263 } 264 fieldDef = elementClass.getField(fieldName); 265 if (fieldDef == null) 266 { 267 throw new ConstraintException("The field "+fieldName+" specified in the orderby attribute of the collection "+collDef.getName()+" in class "+ownerClass.getName()+" hasn't been found in the element class "+elementClass.getName()); 268 } 269 if ((ordering != null) && (ordering.length() > 0) && 270 !"ASC".equals(ordering) && !"DESC".equals(ordering)) 271 { 272 throw new ConstraintException("The ordering "+ordering+" specified in the orderby attribute of the collection "+collDef.getName()+" in class "+ownerClass.getName()+" is invalid"); 273 } 274 } 275 } 276 277 284 private void checkQueryCustomizer(CollectionDescriptorDef collDef, String checkLevel) throws ConstraintException 285 { 286 if (!CHECKLEVEL_STRICT.equals(checkLevel)) 287 { 288 return; 289 } 290 291 String queryCustomizerName = collDef.getProperty(PropertyHelper.OJB_PROPERTY_QUERY_CUSTOMIZER); 292 293 if (queryCustomizerName == null) 294 { 295 return; 296 } 297 298 try 299 { 300 InheritanceHelper helper = new InheritanceHelper(); 301 302 if (!helper.isSameOrSubTypeOf(queryCustomizerName, QUERY_CUSTOMIZER_INTERFACE)) 303 { 304 throw new ConstraintException("The class "+queryCustomizerName+" specified as query-customizer of collection "+collDef.getName()+" in class "+collDef.getOwner().getName()+" does not implement the interface "+QUERY_CUSTOMIZER_INTERFACE); 305 } 306 } 307 catch (ClassNotFoundException ex) 308 { 309 throw new ConstraintException("The class "+ex.getMessage()+" specified as query-customizer of collection "+collDef.getName()+" in class "+collDef.getOwner().getName()+" was not found on the classpath"); 310 } 311 } 312 } 313 | Popular Tags |