1 56 package org.objectstyle.cayenne.dataview; 57 58 import java.io.File ; 59 import java.io.IOException ; 60 import java.io.InputStream ; 61 import java.io.Reader ; 62 import java.net.URL ; 63 import java.text.Format ; 64 import java.util.Collection ; 65 import java.util.Collections ; 66 import java.util.HashMap ; 67 import java.util.HashSet ; 68 import java.util.Iterator ; 69 import java.util.List ; 70 import java.util.Locale ; 71 import java.util.Map ; 72 import java.util.Set ; 73 import java.util.TreeMap ; 74 75 import org.apache.commons.lang.BooleanUtils; 76 import org.apache.commons.lang.StringUtils; 77 import org.apache.commons.lang.Validate; 78 import org.apache.commons.lang.math.NumberUtils; 79 import org.jdom.Document; 80 import org.jdom.Element; 81 import org.jdom.JDOMException; 82 import org.jdom.input.SAXBuilder; 83 import org.objectstyle.cayenne.DataObject; 84 import org.objectstyle.cayenne.map.EntityResolver; 85 import org.objectstyle.cayenne.map.ObjAttribute; 86 import org.objectstyle.cayenne.map.ObjEntity; 87 import org.objectstyle.cayenne.map.ObjRelationship; 88 89 95 public class DataView { 96 97 private Locale locale = Locale.US; 98 99 private DataTypeSpec dataTypeSpec = new DataTypeSpec(); 101 102 private FormatFactory formatFactory = new FormatFactory(); 104 105 private EntityResolver entityResolver; 107 108 private Map objEntityViews = new TreeMap (); 109 private Set lookupEntityViewFields; 110 private LookupCache lookupCache = new LookupCache(); 111 private EventDispatcher fieldValueChangeDispatcher; 112 113 private Map lookupReferenceTable; 115 116 public DataView() { 117 } 118 119 public EntityResolver getEntityResolver() { 120 return entityResolver; 121 } 122 123 public void setEntityResolver(EntityResolver entityResolver) { 124 Validate.notNull(entityResolver); 125 this.entityResolver = entityResolver; 126 } 127 128 public void load(File [] xmlSources) throws IOException { 129 Validate.noNullElements(xmlSources); 130 SAXBuilder builder = new SAXBuilder(); 131 Document[] documents = new Document[xmlSources.length]; 132 for (int i = 0; i < xmlSources.length; i++) { 133 try { 134 documents[i] = builder.build(xmlSources[i]); 135 } 136 catch (JDOMException ex) { 137 ex.printStackTrace(); 138 } 139 } 140 load(documents); 141 } 142 143 public void load(URL [] xmlSources) throws IOException { 144 Validate.noNullElements(xmlSources); 145 SAXBuilder builder = new SAXBuilder(); 146 Document[] documents = new Document[xmlSources.length]; 147 for (int i = 0; i < xmlSources.length; i++) { 148 try { 149 documents[i] = builder.build(xmlSources[i]); 150 } 151 catch (JDOMException ex) { 152 ex.printStackTrace(); 153 } 154 } 155 load(documents); 156 } 157 158 public void load(Reader [] xmlSources) throws IOException { 159 Validate.noNullElements(xmlSources); 160 SAXBuilder builder = new SAXBuilder(); 161 Document[] documents = new Document[xmlSources.length]; 162 for (int i = 0; i < xmlSources.length; i++) { 163 try { 164 documents[i] = builder.build(xmlSources[i]); 165 } 166 catch (JDOMException ex) { 167 ex.printStackTrace(); 168 } 169 } 170 load(documents); 171 } 172 173 public void load(InputStream [] xmlSources) throws IOException { 174 Validate.noNullElements(xmlSources); 175 SAXBuilder builder = new SAXBuilder(); 176 Document[] documents = new Document[xmlSources.length]; 177 for (int i = 0; i < xmlSources.length; i++) { 178 try { 179 documents[i] = builder.build(xmlSources[i]); 180 } 181 catch (JDOMException ex) { 182 ex.printStackTrace(); 183 } 184 } 185 load(documents); 186 } 187 188 public void load(Document[] views) { 189 Validate.noNullElements(views); 190 lookupReferenceTable = new HashMap (); 191 for (int i = 0; i < views.length; i++) { 192 Element root = views[i].getRootElement(); 193 List entityViews = root.getChildren("obj-entity-view"); 194 for (Iterator j = entityViews.iterator(); j.hasNext();) { 195 Element entityViewElement = (Element) j.next(); 196 loadEntityView(entityViewElement); 197 } 198 } 199 resolveLookupReferences(); 200 lookupReferenceTable = null; 201 } 202 203 private void resolveLookupReferences() { 204 lookupEntityViewFields = new HashSet (); 205 for (Iterator i = lookupReferenceTable.entrySet().iterator(); i.hasNext();) { 206 Map.Entry entry = (Map.Entry ) i.next(); 207 ObjEntityViewField field = (ObjEntityViewField) entry.getKey(); 208 String [] lookupDescriptor = (String []) entry.getValue(); 209 ObjEntityView lookupEntityView = getObjEntityView(lookupDescriptor[0]); 210 ObjEntityViewField lookupField = lookupEntityView 211 .getField(lookupDescriptor[1]); 212 field.setLookupField(lookupField); 213 lookupEntityViewFields.add(lookupField); 214 } 215 } 216 217 private void loadEntityView(Element element) { 218 String name = element.getAttributeValue("name"); 219 Validate.isTrue(name != null && !objEntityViews.containsKey(name)); 220 String objEntityName = element.getAttributeValue("obj-entity-name"); 221 Validate.notNull(objEntityName); 222 ObjEntity objEntity = entityResolver.getObjEntity(objEntityName); 223 ObjEntityView entityView = new ObjEntityView(); 224 entityView.setName(name); 225 entityView.setObjEntity(objEntity); 226 objEntityViews.put(name, entityView); 227 entityView.setOwner(this); 228 List fields = element.getChildren("field"); 229 for (Iterator i = fields.iterator(); i.hasNext();) { 230 Element fieldElement = (Element) i.next(); 231 loadField(entityView, fieldElement); 232 } 233 } 234 235 private void loadField(ObjEntityView entityView, Element element) { 236 String name = element.getAttributeValue("name"); 237 ObjEntityViewField field = new ObjEntityViewField(); 238 field.setName(name); 239 String prefIndex = element.getAttributeValue("pref-index"); 240 field.setPreferredIndex(NumberUtils.toInt(prefIndex, -1)); 241 entityView.insertField(field); 242 243 String calcType = element.getAttributeValue("calc-type"); 244 Validate.notNull(calcType); 245 CalcTypeEnum fieldCalcType = CalcTypeEnum.getEnum(calcType); 246 Validate.isTrue( 247 CalcTypeEnum.NO_CALC_TYPE.equals(fieldCalcType) 248 || CalcTypeEnum.LOOKUP_TYPE.equals(fieldCalcType), 249 "Calc Type not supported yet: ", 250 fieldCalcType); 251 field.setCalcType(fieldCalcType); 252 253 ObjEntity objEntity = entityView.getObjEntity(); 254 255 if (CalcTypeEnum.NO_CALC_TYPE.equals(fieldCalcType)) { 256 String objAttributeName = element.getAttributeValue("obj-attribute-name"); 257 Validate.notNull(objAttributeName); 258 ObjAttribute objAttribute = (ObjAttribute) objEntity 259 .getAttribute(objAttributeName); 260 field.setObjAttribute(objAttribute); 261 } 262 else if (CalcTypeEnum.LOOKUP_TYPE.equals(fieldCalcType)) { 263 String objRelationshipName = element 264 .getAttributeValue("obj-relationship-name"); 265 Validate.notNull(objRelationshipName); 266 ObjRelationship objRelationship = (ObjRelationship) objEntity 267 .getRelationship(objRelationshipName); 268 field.setObjRelationship(objRelationship); 269 Element lookupElement = element.getChild("lookup"); 270 Validate.notNull(lookupElement); 271 String lookupEntityView = lookupElement 272 .getAttributeValue("obj-entity-view-name"); 273 Validate.notNull(lookupEntityView); 274 String lookupEntityField = lookupElement.getAttributeValue("field-name"); 275 Validate.notNull(lookupEntityField); 276 String [] lookupDescriptor = new String [] { 277 lookupEntityView, lookupEntityField 278 }; 279 lookupReferenceTable.put(field, lookupDescriptor); 280 } 281 282 String dataType = element.getAttributeValue("data-type"); 283 Validate.notNull(dataType); 284 field.setDataType(dataTypeSpec.getDataType(dataType)); 285 286 String editable = element.getAttributeValue("editable"); 287 field.setEditable(BooleanUtils.toBoolean(editable)); 288 289 String visible = element.getAttributeValue("visible"); 290 field.setVisible(BooleanUtils.toBoolean(visible)); 291 292 Element captionElement = element.getChild("caption"); 293 if (captionElement != null) 294 field.setCaption(StringUtils.stripToEmpty(captionElement.getText())); 295 296 Element editFormatElement = element.getChild("edit-format"); 297 if (editFormatElement != null) { 298 String formatClassName = editFormatElement.getAttributeValue("class"); 299 Validate.notNull(formatClassName); 300 Class formatClass; 301 try { 302 formatClass = Class.forName(formatClassName); 303 Map parameters = DataView.childrenToMap(editFormatElement); 304 Format format = formatFactory.createFormat( 305 formatClass, 306 locale, 307 parameters); 308 field.setEditFormat(format); 309 } 310 catch (ClassNotFoundException ex) { 311 } 312 } 313 314 Element displayFormatElement = element.getChild("display-format"); 315 if (displayFormatElement != null) { 316 String formatClassName = displayFormatElement.getAttributeValue("class"); 317 Validate.notNull(formatClassName); 318 Class formatClass; 319 try { 320 formatClass = Class.forName(formatClassName); 321 Map parameters = DataView.childrenToMap(displayFormatElement); 322 Format format = formatFactory.createFormat( 323 formatClass, 324 locale, 325 parameters); 326 field.setDisplayFormat(format); 327 } 328 catch (ClassNotFoundException ex) { 329 } 330 } 331 332 Element defaultValueElement = element.getChild("default-value"); 333 if (defaultValueElement != null) { 334 String defaultValueStr = StringUtils.stripToEmpty(defaultValueElement 335 .getText()); 336 Object defaultValue = dataTypeSpec.create( 337 field.getDataType(), 338 defaultValueStr); 339 field.setDefaultValue(defaultValue); 340 } 341 } 342 343 public Set getObjEntityViewNames() { 344 return Collections.unmodifiableSet(objEntityViews.keySet()); 345 } 346 347 public Collection getObjEntityViews() { 348 return Collections.unmodifiableCollection(objEntityViews.values()); 349 } 350 351 public ObjEntityView getObjEntityView(String viewName) { 352 return (ObjEntityView) objEntityViews.get(viewName); 353 } 354 355 public LookupCache getLookupCache() { 356 return lookupCache; 357 } 358 359 public void setLookupCache(LookupCache lookupCache) { 360 Validate.notNull(lookupCache); 361 this.lookupCache = lookupCache; 362 } 363 364 public Set getLookupObjEntityViewFields() { 365 return Collections.unmodifiableSet(lookupEntityViewFields); 366 } 367 368 public Locale getLocale() { 369 return locale; 370 } 371 372 public void setLocale(Locale locale) { 373 this.locale = locale; 374 } 375 376 public DataTypeSpec getDataTypeSpec() { 377 return dataTypeSpec; 378 } 379 380 public void setDataTypeSpec(DataTypeSpec dataTypeSpec) { 381 this.dataTypeSpec = dataTypeSpec; 382 } 383 384 public FormatFactory getFormatFactory() { 385 return formatFactory; 386 } 387 388 public void setFormatFactory(FormatFactory formatFactory) { 389 this.formatFactory = formatFactory; 390 } 391 392 private static Map childrenToMap(Element element) { 393 List children = element.getChildren(); 394 if (children.isEmpty()) 395 return Collections.EMPTY_MAP; 396 else { 397 Map map = new HashMap (children.size()); 398 for (Iterator i = children.iterator(); i.hasNext();) { 399 Element child = (Element) i.next(); 400 map.put(child.getName(), StringUtils.stripToNull(child.getText())); 401 } 402 return map; 403 } 404 } 405 406 public void addFieldValueChangeListener(FieldValueChangeListener listener) { 407 fieldValueChangeDispatcher = EventDispatcher.add( 408 fieldValueChangeDispatcher, 409 listener); 410 } 411 412 public void removeFieldValueChangeListener(FieldValueChangeListener listener) { 413 fieldValueChangeDispatcher = EventDispatcher.remove( 414 fieldValueChangeDispatcher, 415 listener); 416 } 417 418 public void clearFieldValueChangeListeners() { 419 if (fieldValueChangeDispatcher != null) { 420 fieldValueChangeDispatcher.clear(); 421 fieldValueChangeDispatcher = null; 422 } 423 } 424 425 public void fireFieldValueChangeEvent( 426 ObjEntityViewField source, 427 DataObject modifiedObject, 428 Object oldValue, 429 Object newValue) { 430 if (fieldValueChangeDispatcher != null && source.getRootOwner() == this) { 431 fieldValueChangeDispatcher.dispatch(new FieldValueChangeEvent( 432 source, 433 modifiedObject, 434 oldValue, 435 newValue)); 436 } 437 } 438 } | Popular Tags |