1 19 20 package org.netbeans.modules.settings.convertors; 21 22 import java.beans.PropertyChangeListener ; 23 import java.io.IOException ; 24 import java.util.Properties ; 25 import java.util.logging.Level ; 26 import java.util.logging.Logger ; 27 28 import org.xml.sax.SAXException ; 29 30 import org.openide.filesystems.FileObject; 31 32 import org.netbeans.spi.settings.Convertor; 33 import org.netbeans.spi.settings.Saver; 34 35 import org.netbeans.modules.settings.Env; 36 import org.openide.util.Exceptions; 37 import org.openide.util.Lookup; 38 39 44 public final class XMLPropertiesConvertor extends Convertor implements PropertyChangeListener { 45 51 public final static String EA_PREVENT_STORING = "xmlproperties.preventStoring"; 56 public final static String EA_IGNORE_CHANGES = "xmlproperties.ignoreChanges"; private FileObject providerFO; 58 59 private java.util.Set ignoreProperites; 60 61 64 public static Convertor create(org.openide.filesystems.FileObject providerFO) { 65 return new XMLPropertiesConvertor(providerFO); 66 } 67 68 public XMLPropertiesConvertor(org.openide.filesystems.FileObject fo) { 69 this.providerFO = fo; 70 } 71 72 public Object read(java.io.Reader r) throws IOException , ClassNotFoundException { 73 Object def = defaultInstanceCreate(); 74 readSetting(r, def); 75 return def; 76 } 77 78 public void write(java.io.Writer w, Object inst) throws IOException { 79 w.write("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>"+XMLSettingsSupport.LINE_SEPARATOR); w.write("<!DOCTYPE properties PUBLIC \""); 82 FileObject foEntity = Env.findEntityRegistration(providerFO); 83 if (foEntity == null) foEntity = providerFO; 84 Object publicId = foEntity.getAttribute(Env.EA_PUBLICID); 85 if (publicId == null || !(publicId instanceof String )) { 86 throw new IOException ("missing or invalid attribute: " + Env.EA_PUBLICID + ", provider: " + foEntity); } 89 90 w.write((String ) publicId); 91 w.write("\" \"http://www.netbeans.org/dtds/properties-1_0.dtd\">"+XMLSettingsSupport.LINE_SEPARATOR); w.write("<properties>"+XMLSettingsSupport.LINE_SEPARATOR); Properties p = getProperties(inst); 94 if (p != null && !p.isEmpty()) writeProperties(w, p); 95 w.write("</properties>"+XMLSettingsSupport.LINE_SEPARATOR); } 97 98 99 private Saver saver; 100 public void registerSaver(Object inst, Saver s) { 101 if (saver != null) { 102 XMLSettingsSupport.err.warning("[Warning] Saver already registered"); 103 return; 104 } 105 106 try { 108 java.lang.reflect.Method method = inst.getClass().getMethod( 109 "addPropertyChangeListener", new Class [] {PropertyChangeListener .class}); 111 method.invoke(inst, new Object [] {this}); 112 this.saver = s; 113 } catch (NoSuchMethodException ex) { 115 XMLSettingsSupport.err.warning( 116 "ObjectChangesNotifier: NoSuchMethodException: " + inst.getClass().getName() + ".addPropertyChangeListener"); } catch (IllegalAccessException ex) { 119 Exceptions.printStackTrace(ex); 120 } catch (java.lang.reflect.InvocationTargetException ex) { 121 Exceptions.printStackTrace(ex); 122 } 123 } 124 125 public void unregisterSaver(Object inst, Saver s) { 126 if (saver == null) return; 127 if (saver != s) { 128 XMLSettingsSupport.err.warning("[Warning] trying unregistered unknown Saver"); 129 return; 130 } 131 try { 132 java.lang.reflect.Method method = inst.getClass().getMethod( 133 "removePropertyChangeListener", new Class [] {PropertyChangeListener .class}); 135 method.invoke(inst, new Object [] {this}); 136 this.saver = null; 137 } catch (NoSuchMethodException ex) { 139 XMLSettingsSupport.err.fine( 140 "ObjectChangesNotifier: NoSuchMethodException: " + inst.getClass().getName() + ".removePropertyChangeListener"); } catch (IllegalAccessException ex) { 144 Exceptions.printStackTrace(ex); 145 } catch (java.lang.reflect.InvocationTargetException ex) { 147 Exceptions.printStackTrace(ex); 148 } 150 } 151 152 public void propertyChange(java.beans.PropertyChangeEvent evt) { 153 if (saver == null || ignoreChange(evt)) return; 154 if (acceptSave()) { 155 try { 156 saver.requestSave(); 157 } catch (IOException ex) { 158 Logger.getLogger(XMLPropertiesConvertor.class.getName()).log(Level.WARNING, null, ex); 159 } 160 } else { 161 saver.markDirty(); 162 } 163 } 164 165 166 170 171 private boolean ignoreChange(java.beans.PropertyChangeEvent pce) { 172 if (pce == null || pce.getPropertyName() == null) return true; 173 174 if (ignoreProperites == null) { 175 ignoreProperites = Env.parseAttribute( 176 providerFO.getAttribute(EA_IGNORE_CHANGES)); 177 } 178 if (ignoreProperites.contains(pce.getPropertyName())) return true; 179 180 return ignoreProperites.contains("all"); } 182 183 private boolean acceptSave() { 184 Object storing = providerFO.getAttribute(EA_PREVENT_STORING); 185 if (storing == null) return true; 186 if (storing instanceof Boolean ) 187 return !((Boolean ) storing).booleanValue(); 188 if (storing instanceof String ) 189 return !Boolean.valueOf((String ) storing).booleanValue(); 190 return true; 191 } 192 193 private final static String INDENT = " "; private String instanceClass = null; 195 196 197 private Object defaultInstanceCreate() throws IOException , ClassNotFoundException { 198 Object instanceCreate = providerFO.getAttribute(Env.EA_INSTANCE_CREATE); 199 if (instanceCreate != null) return instanceCreate; 200 201 Class c = getInstanceClass(); 202 try { 203 return c.newInstance(); 204 } catch (Exception ex) { IOException ioe = new IOException ("Cannot create instance of " + c.getName()); ioe.initCause(ex); 207 throw ioe; 208 } 209 } 210 211 private Class getInstanceClass() throws IOException , ClassNotFoundException { 212 if (instanceClass == null) { 213 Object name = providerFO.getAttribute(Env.EA_INSTANCE_CLASS_NAME); 214 if (name == null || !(name instanceof String )) { 215 throw new IllegalStateException ( 216 "missing or invalid ea attribute: " + 217 Env.EA_INSTANCE_CLASS_NAME); } 219 instanceClass = (String ) name; 220 } 221 return ((ClassLoader )Lookup.getDefault().lookup(ClassLoader .class)).loadClass(instanceClass); 222 } 223 224 private void readSetting(java.io.Reader input, Object inst) throws IOException { 225 try { 226 java.lang.reflect.Method m = inst.getClass().getDeclaredMethod( 227 "readProperties", new Class [] {Properties .class}); m.setAccessible(true); 229 XMLPropertiesConvertor.Reader r = new XMLPropertiesConvertor.Reader(); 230 r.parse(input); 231 m.setAccessible(true); 232 m.invoke(inst, new Object [] {r.getProperties()}); 233 } catch (NoSuchMethodException ex) { 234 IOException ioe = new IOException (ex.getMessage()); 235 ioe.initCause(ex); 236 throw ioe; 237 } catch (IllegalAccessException ex) { 238 IOException ioe = new IOException (ex.getMessage()); 239 ioe.initCause(ex); 240 throw ioe; 241 } catch (java.lang.reflect.InvocationTargetException ex) { 242 Throwable t = ex.getTargetException(); 243 IOException ioe = new IOException (ex.getMessage()); 244 ioe.initCause(t); 245 throw ioe; 246 } 247 } 248 249 private static void writeProperties(java.io.Writer w, Properties p) throws IOException { 250 java.util.Iterator it = p.keySet().iterator(); 251 String key; 252 while (it.hasNext()) { 253 key = (String ) it.next(); 254 w.write(INDENT); 255 w.write("<property name=\""); w.write(key); 257 w.write("\" value=\""); w.write(p.getProperty(key)); 259 w.write("\"/>"+XMLSettingsSupport.LINE_SEPARATOR); } 261 } 262 263 private static Properties getProperties (Object inst) throws IOException { 264 try { 265 java.lang.reflect.Method m = inst.getClass().getDeclaredMethod( 266 "writeProperties", new Class [] {Properties .class}); m.setAccessible(true); 268 Properties prop = new Properties (); 269 m.invoke(inst, new Object [] {prop}); 270 return prop; 271 } catch (NoSuchMethodException ex) { 272 IOException ioe = new IOException (ex.getMessage()); 273 ioe.initCause(ex); 274 throw ioe; 275 } catch (IllegalAccessException ex) { 276 IOException ioe = new IOException (ex.getMessage()); 277 ioe.initCause(ex); 278 throw ioe; 279 } catch (java.lang.reflect.InvocationTargetException ex) { 280 Throwable t = ex.getTargetException(); 281 IOException ioe = new IOException (ex.getMessage()); 282 ioe.initCause(t); 283 throw ioe; 284 } 285 } 286 287 288 private static class Reader extends org.xml.sax.helpers.DefaultHandler implements org.xml.sax.ext.LexicalHandler { 289 Reader() {} 290 291 private static final String ELM_PROPERTY = "property"; private static final String ATR_PROPERTY_NAME = "name"; private static final String ATR_PROPERTY_VALUE = "value"; 295 private Properties props = new Properties (); 296 private String publicId; 297 298 public org.xml.sax.InputSource resolveEntity(String publicId, String systemId) 299 throws SAXException { 300 if (this.publicId != null && this.publicId.equals (publicId)) { 301 return new org.xml.sax.InputSource (new java.io.ByteArrayInputStream (new byte[0])); 302 } else { 303 return null; } 305 } 306 307 public void startElement(String uri, String localName, String qName, org.xml.sax.Attributes attribs) throws SAXException { 308 if (ELM_PROPERTY.equals(qName)) { 309 String propertyName = attribs.getValue(ATR_PROPERTY_NAME); 310 String propertyValue = attribs.getValue(ATR_PROPERTY_VALUE); 311 props.setProperty(propertyName, propertyValue); 312 } 313 } 314 315 public void parse(java.io.Reader src) throws IOException { 316 try { 317 org.xml.sax.XMLReader reader = org.openide.xml.XMLUtil.createXMLReader(false, false); 318 reader.setContentHandler(this); 319 reader.setEntityResolver(this); 320 org.xml.sax.InputSource is = 321 new org.xml.sax.InputSource (src); 322 try { 323 reader.setProperty("http://xml.org/sax/properties/lexical-handler", this); } catch (SAXException sex) { 325 XMLSettingsSupport.err.warning( 326 "Warning: XML parser does not support lexical-handler feature."); } 328 reader.parse(is); 329 } catch (SAXException ex) { 330 IOException ioe = new IOException (); 331 ioe.initCause(ex); 332 throw ioe; 333 } 334 } 335 336 public Properties getProperties() { 337 return props; 338 } 339 340 public String getPublicID() { 341 return publicId; 342 } 343 344 public void startDTD(String name, String publicId, String systemId) throws SAXException { 346 this.publicId = publicId; 347 } 348 349 public void endDTD() throws SAXException {} 350 public void startEntity(String str) throws SAXException {} 351 public void endEntity(String str) throws SAXException {} 352 public void comment(char[] values, int param, int param2) throws SAXException {} 353 public void startCDATA() throws SAXException {} 354 public void endCDATA() throws SAXException {} 355 } 356 } 357 | Popular Tags |