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