1 10 11 package com.triactive.jdo.model; 12 13 import com.triactive.jdo.ClassNotPersistenceCapableException; 14 import com.triactive.jdo.store.NoSuchPersistentFieldException; 15 import java.lang.reflect.Field ; 16 import java.util.Arrays ; 17 import java.util.Collection ; 18 import java.util.List ; 19 import java.util.Map ; 20 import java.util.Set ; 21 import org.w3c.dom.Element ; 22 import org.w3c.dom.Node ; 23 24 25 public class FieldMetaData extends MetaData implements Comparable , ColumnOptions 26 { 27 public static final int PERSISTENCE_MODIFIER_NONE = 0; 28 public static final int PERSISTENCE_MODIFIER_PERSISTENT = 1; 29 public static final int PERSISTENCE_MODIFIER_TRANSACTIONAL = 2; 30 31 public static final int NULL_VALUE_NONE = 0; 32 public static final int NULL_VALUE_DEFAULT = 1; 33 public static final int NULL_VALUE_EXCEPTION = 2; 34 35 private static final List persistenceModifierValues = Arrays.asList(new String [] 36 { "none", "persistent", "transactional" }); 37 38 private static final List nullValueValues = Arrays.asList(new String [] 39 { "none", "default", "exception" }); 40 41 protected final ClassMetaData owner; 42 protected final Field field; 43 protected final Class type; 44 protected final boolean embedded; 45 protected final int persistenceModifier; 46 protected final boolean primaryKey; 47 protected final int nullValue; 48 protected boolean defaultFetchGroup; 49 protected final ArrayMetaData arrayMetaData; 50 protected final CollectionMetaData collectionMetaData; 51 protected final MapMetaData mapMetaData; 52 53 54 public static FieldMetaData forField(Class clazz, String fieldName) 55 { 56 ClassMetaData cmd = ClassMetaData.forClass(clazz); 57 58 if (cmd == null) 59 throw new ClassNotPersistenceCapableException(clazz); 60 61 int fieldNumber = cmd.getAbsoluteFieldNumber(fieldName); 62 63 if (fieldNumber < 0) 64 throw new NoSuchPersistentFieldException(clazz, fieldName); 65 66 return cmd.getFieldAbsolute(fieldNumber); 67 } 68 69 70 public FieldMetaData(ClassMetaData owner, Element fldElement) 71 { 72 super(owner.getSourceURL(), fldElement); 73 74 this.owner = owner; 75 76 String fieldName = fldElement.getAttribute("name"); 77 78 try 79 { 80 this.field = owner.getPCClass().getDeclaredField(fieldName); 81 } 82 catch (NoSuchFieldException e) 83 { 84 throw new XMLMetaDataException(owner.getSourceURL(), "Field " + fieldName + " not found in " + owner.getPCClass(), e); 85 } 86 87 this.type = field.getType(); 88 89 92 String embeddedAttr = fldElement.getAttribute("embedded"); 93 boolean embedded; 94 95 if (embeddedAttr.length() > 0) 96 this.embedded = Boolean.valueOf(embeddedAttr).booleanValue(); 97 else 98 this.embedded = Types.isDefaultEmbeddedType(type); 99 100 103 String pmAttr = fldElement.getAttribute("persistence-modifier"); 104 105 if (pmAttr.length() > 0) 106 { 107 persistenceModifier = persistenceModifierValues.indexOf(pmAttr); 108 109 if (persistenceModifier < 0) 110 throw new XMLMetaDataException(owner.getSourceURL(), "Unrecognized persistence-modifier " + pmAttr); 111 } 112 else 113 persistenceModifier = PERSISTENCE_MODIFIER_PERSISTENT; 114 115 118 primaryKey = Boolean.valueOf(fldElement.getAttribute("primary-key")).booleanValue(); 119 120 123 String nvAttr = fldElement.getAttribute("null-value"); 124 125 if (nvAttr.length() > 0) 126 { 127 nullValue = nullValueValues.indexOf(nvAttr); 128 129 if (nullValue < 0) 130 throw new XMLMetaDataException(owner.getSourceURL(), "Unrecognized null-value " + nvAttr); 131 } 132 else 133 nullValue = NULL_VALUE_NONE; 134 135 138 String defaultFetchGroupAttr = fldElement.getAttribute("default-fetch-group"); 139 140 if (defaultFetchGroupAttr.length() > 0) 141 defaultFetchGroup = Boolean.valueOf(defaultFetchGroupAttr).booleanValue(); 142 else 143 defaultFetchGroup = persistenceModifier == PERSISTENCE_MODIFIER_PERSISTENT && 144 Types.isDefaultFetchGroupType(type); 145 146 ArrayMetaData amd = null; 147 CollectionMetaData cmd = null; 148 MapMetaData mmd = null; 149 150 for (Node node = fldElement.getFirstChild(); node != null; node = node.getNextSibling()) 151 { 152 if (node instanceof Element ) 153 { 154 Element child = (Element )node; 155 String childTag = child.getTagName(); 156 157 if (childTag.equals("array")) 158 { 159 if (!type.isArray()) 160 throw new XMLMetaDataException(owner.getSourceURL(), "Field " + getName() + " has an array element but is not an array"); 161 162 if (amd != null) 163 throw new XMLMetaDataException(owner.getSourceURL(), "Duplicate array element in " + this); 164 165 amd = new ArrayMetaData(this, child); 166 } 167 else if (childTag.equals("collection")) 168 { 169 if (!Collection .class.isAssignableFrom(type)) 170 throw new XMLMetaDataException(owner.getSourceURL(), "Field " + getName() + " has a collection element but is not a Collection"); 171 172 if (cmd != null) 173 throw new XMLMetaDataException(owner.getSourceURL(), "Duplicate collection element in " + this); 174 175 cmd = new CollectionMetaData(this, child); 176 } 177 else if (childTag.equals("map")) 178 { 179 if (!Map .class.isAssignableFrom(type)) 180 throw new XMLMetaDataException(owner.getSourceURL(), "Field " + getName() + " has a map element but is not a Map"); 181 182 if (mmd != null) 183 throw new XMLMetaDataException(owner.getSourceURL(), "Duplicate map element in " + this); 184 185 mmd = new MapMetaData(this, child); 186 } 187 } 188 } 189 190 arrayMetaData = amd; 191 collectionMetaData = cmd; 192 mapMetaData = mmd; 193 } 194 195 public FieldMetaData(ClassMetaData owner, Field field) 196 { 197 super(); 198 199 this.owner = owner; 200 this.field = field; 201 202 type = field.getType(); 203 embedded = Types.isDefaultEmbeddedType(type); 204 persistenceModifier = PERSISTENCE_MODIFIER_PERSISTENT; 205 primaryKey = false; 206 nullValue = NULL_VALUE_NONE; 207 defaultFetchGroup = Types.isDefaultFetchGroupType(type); 208 arrayMetaData = null; 209 collectionMetaData = null; 210 mapMetaData = null; 211 } 212 213 public Class getType() 214 { 215 return type; 216 } 217 218 public boolean isEmbedded() 219 { 220 return embedded; 221 } 222 223 public String getJavaName() 224 { 225 return owner.getJavaName() + '.' + field.getName(); 226 } 227 228 public ClassMetaData getClassMetaData() 229 { 230 return owner; 231 } 232 233 public String getName() 234 { 235 return field.getName(); 236 } 237 238 public Field getField() 239 { 240 return field; 241 } 242 243 public int getPersistenceModifier() 244 { 245 return persistenceModifier; 246 } 247 248 public boolean isPrimaryKeyPart() 249 { 250 return primaryKey; 251 } 252 253 public int getNullValueHandling() 254 { 255 return nullValue; 256 } 257 258 public boolean isInDefaultFetchGroup() 259 { 260 return defaultFetchGroup; 261 } 262 263 public void setDefaultFetchGroup(boolean defaultFetchGroup) 264 { 265 this.defaultFetchGroup = defaultFetchGroup; 266 } 267 268 public String getLength() 269 { 270 return getVendorExtension(MY_VENDOR, "length"); 271 } 272 273 public String getPrecision() 274 { 275 return getVendorExtension(MY_VENDOR, "precision"); 276 } 277 278 public String getScale() 279 { 280 return getVendorExtension(MY_VENDOR, "scale"); 281 } 282 283 public ArrayMetaData getArrayMetaData() 284 { 285 return arrayMetaData; 286 } 287 288 public CollectionMetaData getCollectionMetaData() 289 { 290 return collectionMetaData; 291 } 292 293 public MapMetaData getMapMetaData() 294 { 295 return mapMetaData; 296 } 297 298 public FieldMetaData getOwnedByCollection() 299 { 300 String collFieldName = getVendorExtension(MY_VENDOR, "collection-field"); 301 302 if (collFieldName == null) 303 collFieldName = getVendorExtension("sunw", "inverse"); 304 305 return collFieldName == null ? null : forField(type, collFieldName); 306 } 307 308 public FieldMetaData getOwnedByMap() 309 { 310 String mapFieldName = getVendorExtension(MY_VENDOR, "map-field"); 311 312 return mapFieldName == null ? null : forField(type, mapFieldName); 313 } 314 315 void getReferencedClasses(final String vendorID, final List ordered, final Set referenced) 316 { 317 ClassMetaData cmd = ClassMetaData.forClass(type); 318 319 if (cmd != null) 320 cmd.getReferencedClasses(vendorID, ordered, referenced); 321 322 if (arrayMetaData != null) 323 arrayMetaData.getReferencedClasses(vendorID, ordered, referenced); 324 325 if (collectionMetaData != null) 326 collectionMetaData.getReferencedClasses(vendorID, ordered, referenced); 327 328 if (mapMetaData != null) 329 mapMetaData.getReferencedClasses(vendorID, ordered, referenced); 330 } 331 332 public int compareTo(Object obj) 333 { 334 return getName().compareTo(((FieldMetaData)obj).getName()); 335 } 336 337 public String toString() 338 { 339 return "Metadata for " + owner.getPCClass().getName() + '.' + getName(); 340 } 341 } 342 | Popular Tags |