KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > settings > convertors > XMLPropertiesConvertor


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 2002-2003 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.modules.settings.convertors;
21
22 import java.beans.PropertyChangeListener JavaDoc;
23 import java.io.IOException JavaDoc;
24 import java.util.Properties JavaDoc;
25 import java.util.logging.Level JavaDoc;
26 import java.util.logging.Logger JavaDoc;
27
28 import org.xml.sax.SAXException JavaDoc;
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 /** Implementation of xml properties format described by
40  * /org/netbeans/modules/settings/resources/properties.dtd
41  *
42  * @author Jan Pokorsky
43  */

44 public final class XMLPropertiesConvertor extends Convertor implements PropertyChangeListener JavaDoc {
45     /** file attribute containnig value whether the setting object will be
46      * stored automaticaly (preventStoring==false) or SaveCookie will be provided.
47      * Default value is <code>preventStoring==false</code>. Usage
48      * <code>&lt;attr name="xmlproperties.preventStoring" boolvalue="[true|false]"/>
49      * </code>
50      */

51     public final static String JavaDoc EA_PREVENT_STORING = "xmlproperties.preventStoring"; //NOI18N
52
/** file attribute containnig list of property names their changes will be ignored. Usage
53      * <code>&lt;attr name="xmlproperties.ignoreChanges" stringvalue="name[, ...]"/>
54      * </code>
55      */

56     public final static String JavaDoc EA_IGNORE_CHANGES = "xmlproperties.ignoreChanges"; //NOI18N
57
private FileObject providerFO;
58     /** cached property names to be filtered */
59     private java.util.Set JavaDoc ignoreProperites;
60     
61     /** create convertor instance; should be used in module layers
62      * @param providerFO provider file object
63      */

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 JavaDoc read(java.io.Reader JavaDoc r) throws IOException JavaDoc, ClassNotFoundException JavaDoc {
73         Object JavaDoc def = defaultInstanceCreate();
74         readSetting(r, def);
75         return def;
76     }
77     
78     public void write(java.io.Writer JavaDoc w, Object JavaDoc inst) throws IOException JavaDoc {
79         w.write("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>"+XMLSettingsSupport.LINE_SEPARATOR); // NOI18N
80
w.write("<!DOCTYPE properties PUBLIC \""); // NOI18N
81

82         FileObject foEntity = Env.findEntityRegistration(providerFO);
83         if (foEntity == null) foEntity = providerFO;
84         Object JavaDoc publicId = foEntity.getAttribute(Env.EA_PUBLICID);
85         if (publicId == null || !(publicId instanceof String JavaDoc)) {
86             throw new IOException JavaDoc("missing or invalid attribute: " + //NOI18N
87
Env.EA_PUBLICID + ", provider: " + foEntity); //NOI18N
88
}
89         
90         w.write((String JavaDoc) publicId);
91         w.write("\" \"http://www.netbeans.org/dtds/properties-1_0.dtd\">"+XMLSettingsSupport.LINE_SEPARATOR); // NOI18N
92
w.write("<properties>"+XMLSettingsSupport.LINE_SEPARATOR); // NOI18N
93
Properties JavaDoc p = getProperties(inst);
94         if (p != null && !p.isEmpty()) writeProperties(w, p);
95         w.write("</properties>"+XMLSettingsSupport.LINE_SEPARATOR); // NOI18N
96
}
97     
98     /** an object listening on the setting changes */
99     private Saver saver;
100     public void registerSaver(Object JavaDoc inst, Saver s) {
101         if (saver != null) {
102             XMLSettingsSupport.err.warning("[Warning] Saver already registered");
103             return;
104         }
105         
106         // add propertyChangeListener
107
try {
108             java.lang.reflect.Method JavaDoc method = inst.getClass().getMethod(
109                 "addPropertyChangeListener", // NOI18N
110
new Class JavaDoc[] {PropertyChangeListener JavaDoc.class});
111             method.invoke(inst, new Object JavaDoc[] {this});
112             this.saver = s;
113 //System.out.println("XMLPropertiesConvertor.registerPropertyListener...ok " + inst);
114
} catch (NoSuchMethodException JavaDoc ex) {
115             XMLSettingsSupport.err.warning(
116             "ObjectChangesNotifier: NoSuchMethodException: " + // NOI18N
117
inst.getClass().getName() + ".addPropertyChangeListener"); // NOI18N
118
} catch (IllegalAccessException JavaDoc ex) {
119             Exceptions.printStackTrace(ex);
120         } catch (java.lang.reflect.InvocationTargetException JavaDoc ex) {
121             Exceptions.printStackTrace(ex);
122         }
123     }
124     
125     public void unregisterSaver(Object JavaDoc 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 JavaDoc method = inst.getClass().getMethod(
133                 "removePropertyChangeListener", // NOI18N
134
new Class JavaDoc[] {PropertyChangeListener JavaDoc.class});
135             method.invoke(inst, new Object JavaDoc[] {this});
136             this.saver = null;
137 //System.out.println("XMLPropertiesConvertor.unregisterPropertyListener...ok " + inst);
138
} catch (NoSuchMethodException JavaDoc ex) {
139             XMLSettingsSupport.err.fine(
140             "ObjectChangesNotifier: NoSuchMethodException: " + // NOI18N
141
inst.getClass().getName() + ".removePropertyChangeListener"); // NOI18N
142
// just changes done through gui will be saved
143
} catch (IllegalAccessException JavaDoc ex) {
144             Exceptions.printStackTrace(ex);
145             // just changes done through gui will be saved
146
} catch (java.lang.reflect.InvocationTargetException JavaDoc ex) {
147             Exceptions.printStackTrace(ex);
148             // just changes done through gui will be saved
149
}
150     }
151     
152     public void propertyChange(java.beans.PropertyChangeEvent JavaDoc evt) {
153         if (saver == null || ignoreChange(evt)) return;
154         if (acceptSave()) {
155             try {
156                 saver.requestSave();
157             } catch (IOException JavaDoc ex) {
158                 Logger.getLogger(XMLPropertiesConvertor.class.getName()).log(Level.WARNING, null, ex);
159             }
160         } else {
161             saver.markDirty();
162         }
163     }
164     
165     
166     ////////////////////////////////////////////////////////////
167
// Private implementation
168
////////////////////////////////////////////////////////////
169

170     /** filtering of Property Change Events */
171     private boolean ignoreChange(java.beans.PropertyChangeEvent JavaDoc 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"); // NOI18N
181
}
182     
183     private boolean acceptSave() {
184         Object JavaDoc storing = providerFO.getAttribute(EA_PREVENT_STORING);
185         if (storing == null) return true;
186         if (storing instanceof Boolean JavaDoc)
187             return !((Boolean JavaDoc) storing).booleanValue();
188         if (storing instanceof String JavaDoc)
189             return !Boolean.valueOf((String JavaDoc) storing).booleanValue();
190         return true;
191     }
192     
193     private final static String JavaDoc INDENT = " "; // NOI18N
194
private String JavaDoc instanceClass = null;
195     
196
197     private Object JavaDoc defaultInstanceCreate() throws IOException JavaDoc, ClassNotFoundException JavaDoc {
198         Object JavaDoc instanceCreate = providerFO.getAttribute(Env.EA_INSTANCE_CREATE);
199         if (instanceCreate != null) return instanceCreate;
200         
201         Class JavaDoc c = getInstanceClass();
202         try {
203             return c.newInstance();
204         } catch (Exception JavaDoc ex) { // IllegalAccessException, InstantiationException
205
IOException JavaDoc ioe = new IOException JavaDoc("Cannot create instance of " + c.getName()); // NOI18N
206
ioe.initCause(ex);
207             throw ioe;
208         }
209     }
210
211     private Class JavaDoc getInstanceClass() throws IOException JavaDoc, ClassNotFoundException JavaDoc {
212         if (instanceClass == null) {
213             Object JavaDoc name = providerFO.getAttribute(Env.EA_INSTANCE_CLASS_NAME);
214             if (name == null || !(name instanceof String JavaDoc)) {
215                 throw new IllegalStateException JavaDoc(
216                     "missing or invalid ea attribute: " +
217                     Env.EA_INSTANCE_CLASS_NAME); //NOI18N
218
}
219             instanceClass = (String JavaDoc) name;
220         }
221         return ((ClassLoader JavaDoc)Lookup.getDefault().lookup(ClassLoader JavaDoc.class)).loadClass(instanceClass);
222     }
223     
224     private void readSetting(java.io.Reader JavaDoc input, Object JavaDoc inst) throws IOException JavaDoc {
225         try {
226             java.lang.reflect.Method JavaDoc m = inst.getClass().getDeclaredMethod(
227                 "readProperties", new Class JavaDoc[] {Properties JavaDoc.class}); // NOI18N
228
m.setAccessible(true);
229             XMLPropertiesConvertor.Reader r = new XMLPropertiesConvertor.Reader();
230             r.parse(input);
231             m.setAccessible(true);
232             m.invoke(inst, new Object JavaDoc[] {r.getProperties()});
233         } catch (NoSuchMethodException JavaDoc ex) {
234             IOException JavaDoc ioe = new IOException JavaDoc(ex.getMessage());
235             ioe.initCause(ex);
236             throw ioe;
237         } catch (IllegalAccessException JavaDoc ex) {
238             IOException JavaDoc ioe = new IOException JavaDoc(ex.getMessage());
239             ioe.initCause(ex);
240             throw ioe;
241         } catch (java.lang.reflect.InvocationTargetException JavaDoc ex) {
242             Throwable JavaDoc t = ex.getTargetException();
243             IOException JavaDoc ioe = new IOException JavaDoc(ex.getMessage());
244             ioe.initCause(t);
245             throw ioe;
246         }
247     }
248     
249     private static void writeProperties(java.io.Writer JavaDoc w, Properties JavaDoc p) throws IOException JavaDoc {
250         java.util.Iterator JavaDoc it = p.keySet().iterator();
251         String JavaDoc key;
252         while (it.hasNext()) {
253             key = (String JavaDoc) it.next();
254             w.write(INDENT);
255             w.write("<property name=\""); // NOI18N
256
w.write(key);
257             w.write("\" value=\""); // NOI18N
258
w.write(p.getProperty(key));
259             w.write("\"/>"+XMLSettingsSupport.LINE_SEPARATOR); // NOI18N
260
}
261     }
262
263     private static Properties JavaDoc getProperties (Object JavaDoc inst) throws IOException JavaDoc {
264         try {
265             java.lang.reflect.Method JavaDoc m = inst.getClass().getDeclaredMethod(
266                 "writeProperties", new Class JavaDoc[] {Properties JavaDoc.class}); // NOI18N
267
m.setAccessible(true);
268             Properties JavaDoc prop = new Properties JavaDoc();
269             m.invoke(inst, new Object JavaDoc[] {prop});
270             return prop;
271         } catch (NoSuchMethodException JavaDoc ex) {
272             IOException JavaDoc ioe = new IOException JavaDoc(ex.getMessage());
273             ioe.initCause(ex);
274             throw ioe;
275         } catch (IllegalAccessException JavaDoc ex) {
276             IOException JavaDoc ioe = new IOException JavaDoc(ex.getMessage());
277             ioe.initCause(ex);
278             throw ioe;
279         } catch (java.lang.reflect.InvocationTargetException JavaDoc ex) {
280             Throwable JavaDoc t = ex.getTargetException();
281             IOException JavaDoc ioe = new IOException JavaDoc(ex.getMessage());
282             ioe.initCause(t);
283             throw ioe;
284         }
285     }
286     
287     /** support for reading xml/properties format */
288     private static class Reader extends org.xml.sax.helpers.DefaultHandler JavaDoc implements org.xml.sax.ext.LexicalHandler JavaDoc {
289         Reader() {}
290
291         private static final String JavaDoc ELM_PROPERTY = "property"; // NOI18N
292
private static final String JavaDoc ATR_PROPERTY_NAME = "name"; // NOI18N
293
private static final String JavaDoc ATR_PROPERTY_VALUE = "value"; // NOI18N
294

295         private Properties JavaDoc props = new Properties JavaDoc();
296         private String JavaDoc publicId;
297
298         public org.xml.sax.InputSource JavaDoc resolveEntity(String JavaDoc publicId, String JavaDoc systemId)
299         throws SAXException JavaDoc {
300             if (this.publicId != null && this.publicId.equals (publicId)) {
301                 return new org.xml.sax.InputSource JavaDoc (new java.io.ByteArrayInputStream JavaDoc (new byte[0]));
302             } else {
303                 return null; // i.e. follow advice of systemID
304
}
305         }
306
307         public void startElement(String JavaDoc uri, String JavaDoc localName, String JavaDoc qName, org.xml.sax.Attributes JavaDoc attribs) throws SAXException JavaDoc {
308             if (ELM_PROPERTY.equals(qName)) {
309                 String JavaDoc propertyName = attribs.getValue(ATR_PROPERTY_NAME);
310                 String JavaDoc propertyValue = attribs.getValue(ATR_PROPERTY_VALUE);
311                 props.setProperty(propertyName, propertyValue);
312             }
313         }
314
315         public void parse(java.io.Reader JavaDoc src) throws IOException JavaDoc {
316             try {
317                 org.xml.sax.XMLReader JavaDoc reader = org.openide.xml.XMLUtil.createXMLReader(false, false);
318                 reader.setContentHandler(this);
319                 reader.setEntityResolver(this);
320                 org.xml.sax.InputSource JavaDoc is =
321                     new org.xml.sax.InputSource JavaDoc(src);
322                 try {
323                     reader.setProperty("http://xml.org/sax/properties/lexical-handler", this); //NOI18N
324
} catch (SAXException JavaDoc sex) {
325                     XMLSettingsSupport.err.warning(
326                     "Warning: XML parser does not support lexical-handler feature."); //NOI18N
327
}
328                 reader.parse(is);
329             } catch (SAXException JavaDoc ex) {
330                 IOException JavaDoc ioe = new IOException JavaDoc();
331                 ioe.initCause(ex);
332                 throw ioe;
333             }
334         }
335         
336         public Properties JavaDoc getProperties() {
337             return props;
338         }
339         
340         public String JavaDoc getPublicID() {
341             return publicId;
342         }
343
344         // LexicalHandler implementation
345
public void startDTD(String JavaDoc name, String JavaDoc publicId, String JavaDoc systemId) throws SAXException JavaDoc {
346             this.publicId = publicId;
347         }
348         
349         public void endDTD() throws SAXException JavaDoc {}
350         public void startEntity(String JavaDoc str) throws SAXException JavaDoc {}
351         public void endEntity(String JavaDoc str) throws SAXException JavaDoc {}
352         public void comment(char[] values, int param, int param2) throws SAXException JavaDoc {}
353         public void startCDATA() throws SAXException JavaDoc {}
354         public void endCDATA() throws SAXException JavaDoc {}
355     }
356 }
357
Popular Tags