| 1 4 package org.terracotta.dso.editors.xmlbeans; 5 6 import org.apache.xmlbeans.SchemaProperty; 7 import org.apache.xmlbeans.SchemaStringEnumEntry; 8 import org.apache.xmlbeans.SchemaType; 9 import org.apache.xmlbeans.StringEnumAbstractBase; 10 import org.apache.xmlbeans.XmlAnySimpleType; 11 import org.apache.xmlbeans.XmlError; 12 import org.apache.xmlbeans.XmlInteger; 13 import org.apache.xmlbeans.XmlObject; 14 import org.apache.xmlbeans.XmlOptions; 15 import org.apache.xmlbeans.XmlToken; 16 17 import org.dijon.Label; 18 19 import java.lang.reflect.Method ; 20 import java.text.NumberFormat ; 21 import java.util.ArrayList ; 22 import java.util.StringTokenizer ; 23 24 import javax.swing.Icon ; 25 import javax.swing.ImageIcon ; 26 import javax.swing.JComponent ; 27 import javax.xml.namespace.QName ; 28 29 32 public class XmlObjectHolderHelper { 33 private XmlObject m_parent; 34 private Class m_parentType; 35 private SchemaType m_parentSchemaType; 36 private String m_elementName; 37 private String m_fieldName; 38 private SchemaProperty m_schemaProperty; 39 private SchemaType m_propertySchemaType; 40 private String m_defaultStringValue; 41 42 private transient ArrayList <XmlObjectStructureListener> m_listenerList; 43 private transient XmlObjectStructureChangeEvent m_changeEvent; 44 45 private static Icon m_problemIcon; 46 47 private static final Class [] NO_PARAMS = new Class [0]; 48 private static final Object [] NO_ARGS = new Object [0]; 49 50 public XmlObject getParent() { 51 return m_parent; 52 } 53 54 public Class getParentType() { 55 return m_parentType; 56 } 57 58 public String getElementName() { 59 return m_elementName; 60 } 61 62 public String getFieldName() { 63 return m_fieldName; 64 } 65 66 public void init(Class parentType, String elementName) { 67 m_parentType = parentType; 68 m_elementName = elementName; 69 m_fieldName = convertElementName(elementName); 70 71 if(Character.isDigit(elementName.charAt(elementName.length()-1))) { 74 m_elementName = elementName.substring(0, elementName.length()-1); 75 } 76 77 m_parentSchemaType = null; 78 m_schemaProperty = null; 79 m_propertySchemaType = null; 80 m_defaultStringValue = null; 81 } 82 83 public void setup(XmlObject parent) { 84 m_parent = parent; 85 if(m_changeEvent != null) { 86 m_changeEvent.setXmlObject(parent); 87 } 88 } 89 90 public void tearDown() { 91 m_parent = null; 92 if(m_changeEvent != null) { 93 m_changeEvent.setXmlObject(null); 94 } 95 } 96 97 private static String convertElementName(String s) { 98 StringBuffer sb = new StringBuffer (); 99 StringTokenizer st = new StringTokenizer (s, "-"); 100 String tok; 101 102 while(st.hasMoreTokens()) { 103 tok = st.nextToken(); 104 sb.append(Character.toUpperCase(tok.charAt(0))); 105 sb.append(tok.substring(1)); 106 } 107 108 return sb.toString(); 109 } 110 111 public XmlObject getXmlObject() { 112 if(m_parent != null) { 113 try { 114 return (XmlObject)invokePrefixedParentNoParams("xget"); 115 } catch(Exception e) {e.printStackTrace();} 116 } 117 118 return null; 119 } 120 121 public XmlObject ensureXmlObject() { 122 XmlObject xmlObject = null; 123 124 if(m_parent != null && (xmlObject = getXmlObject()) == null) { 125 try { 126 Class [] params = new Class [] {getPropertySchemaType().getJavaClass()}; 127 Object [] args = new Object [] {getSchemaProperty().getDefaultValue()}; 128 String methodName = "xset"+m_fieldName; 129 Method method = m_parentType.getMethod(methodName, params); 130 131 method.invoke(m_parent, args); 132 133 xmlObject = getXmlObject(); 134 } catch(Exception e) {e.printStackTrace();} 135 } 136 137 return xmlObject; 138 } 139 140 private SchemaType getParentSchemaType() { 141 if(m_parentSchemaType == null) { 142 try { 143 m_parentSchemaType = (SchemaType) 144 m_parentType.getField("type").get(null); 145 } catch(Exception e) {e.printStackTrace();} 146 } 147 148 return m_parentSchemaType; 149 } 150 151 private SchemaProperty getSchemaProperty() { 152 if(m_schemaProperty == null) { 153 QName qname = QName.valueOf(m_elementName); 154 SchemaType type = getParentSchemaType(); 155 156 if((m_schemaProperty = type.getElementProperty(qname)) == null) { 157 m_schemaProperty = type.getAttributeProperty(qname); 158 } 159 } 160 161 return m_schemaProperty; 162 } 163 164 private SchemaType getPropertySchemaType() { 165 if(m_propertySchemaType == null) { 166 m_propertySchemaType = getSchemaProperty().getType(); 167 } 168 return m_propertySchemaType; 169 } 170 171 public boolean hasStringEnumValues() { 173 return getPropertySchemaType().hasStringEnumValues(); 174 } 175 176 public StringEnumAbstractBase[] getEnumValues() { 178 SchemaStringEnumEntry[] enumEntries = getPropertySchemaType().getStringEnumEntries(); 179 int size = enumEntries.length; 180 StringEnumAbstractBase[] entries = new StringEnumAbstractBase[size]; 181 182 for(int i = 0; i < size; i++) { 183 entries[i] = enumForInt(enumEntries[i].getIntValue()); 184 } 185 186 return entries; 187 } 188 189 public StringEnumAbstractBase defaultEnumValue() { 191 return enumForString(defaultStringValue()); 192 } 193 194 public boolean isRequired() { 196 return getSchemaProperty().getMinOccurs().intValue() > 0; 197 } 198 199 public boolean hasDefault() { 201 return getSchemaProperty().hasDefault() > 0; 202 } 203 204 public boolean isSet() { 205 if(m_parent == null) { 206 return false; 207 } 208 209 if(isRequired()) { 210 return true; 211 } 212 213 try { 214 return ((Boolean )invokePrefixedParentNoParams("isSet")).booleanValue(); 215 } catch(Exception e) { 216 e.printStackTrace(); 217 return false; 218 } 219 } 220 221 222 public StringEnumAbstractBase getEnumValue() { 223 return enumForString(((XmlToken)getXmlObject()).getStringValue()); 224 } 225 226 public StringEnumAbstractBase enumForInt(int i) { 227 return getPropertySchemaType().enumForInt(i); 228 } 229 230 public StringEnumAbstractBase enumForString(String s) { 231 return getPropertySchemaType().enumForString(s); 232 } 233 234 private XmlAnySimpleType getPropertyFacet(int facet) { 235 return getPropertySchemaType().getFacet(facet); 236 } 237 238 public Integer minInclusive() { 239 XmlInteger min = (XmlInteger)getPropertyFacet(SchemaType.FACET_MIN_INCLUSIVE); 240 return new Integer (min.getBigIntegerValue().intValue()); 241 } 242 243 public Integer maxInclusive() { 244 XmlInteger min = (XmlInteger)getPropertyFacet(SchemaType.FACET_MAX_INCLUSIVE); 245 return new Integer (min.getBigIntegerValue().intValue()); 246 } 247 248 public int defaultInteger() { 250 return parseInt(defaultStringValue()); 251 } 252 253 public Integer defaultIntegerValue() { 255 return new Integer (defaultInteger()); 256 } 257 258 public int getInteger() { 259 return parseInt(getStringValue(), defaultInteger()); 260 } 261 262 public Integer getIntegerValue() { 263 return new Integer (getInteger()); 264 } 265 266 public boolean defaultBoolean() { 268 return defaultBooleanValue().booleanValue(); 269 } 270 271 public Boolean defaultBooleanValue() { 273 return Boolean.valueOf(defaultStringValue()); 274 } 275 276 public boolean getBoolean() { 277 return getBooleanValue().booleanValue(); 278 } 279 280 public Boolean getBooleanValue() { 281 return Boolean.valueOf(getStringValue()); 282 } 283 284 public String defaultStringValue() { 285 if(m_defaultStringValue == null) { 286 m_defaultStringValue = getSchemaProperty().getDefaultText(); 287 } 288 return m_defaultStringValue; 289 } 290 291 public String getStringValue() { 292 return ((XmlAnySimpleType)getXmlObject()).getStringValue(); 293 } 294 295 public void set(String text) { 296 if(m_parent == null) { 297 return; 298 } 299 300 try { 301 XmlObject xmlObject = ensureXmlObject(); 302 Class [] params = new Class [] {String .class}; 303 Object [] args = new Object [] {text}; 304 String methodName = "setStringValue"; 305 Class objClass = xmlObject.getClass(); 306 Method method = objClass.getMethod(methodName, params); 307 308 method.invoke(xmlObject, args); 309 fireXmlObjectStructureChanged(); 310 } catch(Exception e) {e.printStackTrace();} 311 } 312 313 public void unset() { 314 if(m_parent == null || isRequired() || !isSet()) { 315 return; 316 } 317 318 try { 319 invokePrefixedParentNoParams("unset"); 320 fireXmlObjectStructureChanged(); 321 } catch(Exception e) {e.printStackTrace();} 322 } 323 324 private Object invokePrefixedParentNoParams(String prefix) throws Exception { 325 Method method = m_parentType.getMethod(prefix+m_fieldName, NO_PARAMS); 326 return (method != null) ? method.invoke(m_parent, NO_ARGS) : null; 327 } 328 329 private Icon getProblemIcon() { 330 if(m_problemIcon == null) { 331 String uri = "/images/eclipse/problem.gif"; 332 m_problemIcon = new ImageIcon (getClass().getResource(uri)); 333 } 334 return m_problemIcon; 335 } 336 337 public void validateXmlObject(JComponent component) { 338 XmlObject xmlObject = getXmlObject(); 339 String tip = null; 340 Icon icon = null; 341 Label label = (Label)component.getClientProperty("labeledBy"); 342 343 if(xmlObject != null) { 344 ArrayList errors = new ArrayList (); 345 XmlOptions opts = new XmlOptions(); 346 347 opts.setErrorListener(errors); 348 if(!xmlObject.validate(opts)) { 349 StringBuffer sb = new StringBuffer ("<html><ul>"); 350 351 for(int i = 0; i < errors.size(); i++) { 352 sb.append("<li>"); 353 sb.append(((XmlError)errors.get(i)).getMessage()); 354 sb.append("</li>"); 355 } 356 sb.append("</ul></html>"); 357 tip = sb.toString(); 358 359 if(label != null) { 360 icon = getProblemIcon(); 361 } 362 } 363 } 364 365 component.setToolTipText(tip); 366 if(label != null) { 367 label.setIcon(icon); 368 } 369 } 370 371 public synchronized void addXmlObjectStructureListener(XmlObjectStructureListener listener) { 372 if(listener != null) { 373 if(m_listenerList == null) { 374 m_listenerList = new ArrayList <XmlObjectStructureListener>(); 375 } 376 m_listenerList.add(listener); 377 } 378 } 379 380 public synchronized void removeXmlObjectStructureListener(XmlObjectStructureListener listener) { 381 if(listener != null) { 382 if(m_listenerList != null) { 383 m_listenerList.remove(listener); 384 } 385 } 386 } 387 388 private XmlObjectStructureChangeEvent getChangeEvent() { 389 if(m_changeEvent == null) { 390 m_changeEvent = new XmlObjectStructureChangeEvent(); 391 if(m_parent != null) { 392 m_changeEvent.setXmlObject(m_parent); 393 } 394 } 395 396 return m_changeEvent; 397 } 398 399 private XmlObjectStructureListener[] getListenerArray() { 400 return m_listenerList.toArray(new XmlObjectStructureListener[0]); 401 } 402 403 protected void fireXmlObjectStructureChanged() { 404 if(m_listenerList != null) { 405 XmlObjectStructureListener[] listeners = getListenerArray(); 406 XmlObjectStructureChangeEvent event = getChangeEvent(); 407 408 for(int i = 0; i < listeners.length; i++) { 409 listeners[i].structureChanged(event); 410 } 411 } 412 } 413 414 protected static int parseInt(String s) { 415 return parseInt(s, 42); 416 } 417 418 protected static int parseInt(String s, int defaultValue) { 419 try { 420 return NumberFormat.getIntegerInstance().parse(s).intValue(); 421 } catch(Exception e) {return defaultValue;} 422 } 423 } 424 | Popular Tags |