Added
Link Here
|
1 |
/* |
2 |
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. |
3 |
* |
4 |
* Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved. |
5 |
* |
6 |
* The contents of this file are subject to the terms of either the GNU |
7 |
* General Public License Version 2 only ("GPL") or the Common |
8 |
* Development and Distribution License("CDDL") (collectively, the |
9 |
* "License"). You may not use this file except in compliance with the |
10 |
* License. You can obtain a copy of the License at |
11 |
* http://www.netbeans.org/cddl-gplv2.html |
12 |
* or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the |
13 |
* specific language governing permissions and limitations under the |
14 |
* License. When distributing the software, include this License Header |
15 |
* Notice in each file and include the License file at |
16 |
* nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this |
17 |
* particular file as subject to the "Classpath" exception as provided |
18 |
* by Sun in the GPL Version 2 section of the License file that |
19 |
* accompanied this code. If applicable, add the following below the |
20 |
* License Header, with the fields enclosed by brackets [] replaced by |
21 |
* your own identifying information: |
22 |
* "Portions Copyrighted [year] [name of copyright owner]" |
23 |
* |
24 |
* Contributor(s): |
25 |
* |
26 |
* The Original Software is NetBeans. The Initial Developer of the Original |
27 |
* Software is Sun Microsystems, Inc. Portions Copyright 2002-2003 Sun |
28 |
* Microsystems, Inc. All Rights Reserved. |
29 |
* |
30 |
* If you wish your version of this file to be governed by only the CDDL |
31 |
* or only the GPL Version 2, indicate your decision by adding |
32 |
* "[Contributor] elects to include this software in this distribution |
33 |
* under the [CDDL or GPL Version 2] license." If you do not indicate a |
34 |
* single choice of license, a recipient has the option to distribute |
35 |
* your version of this file under either the CDDL, the GPL Version 2 or |
36 |
* to extend the choice of license to its licensees as provided above. |
37 |
* However, if you add GPL Version 2 code and therefore, elected the GPL |
38 |
* Version 2 license, then the option applies only if the new code is |
39 |
* made subject to such option by the copyright holder. |
40 |
*/ |
41 |
|
42 |
package org.netbeans.modules.settings.convertors; |
43 |
|
44 |
import java.beans.PropertyChangeListener; |
45 |
import java.beans.XMLDecoder; |
46 |
import java.beans.XMLEncoder; |
47 |
import java.io.BufferedReader; |
48 |
import java.io.ByteArrayOutputStream; |
49 |
import java.io.IOException; |
50 |
import java.util.Map; |
51 |
import java.util.Properties; |
52 |
import java.util.logging.Level; |
53 |
import java.util.logging.Logger; |
54 |
|
55 |
import org.xml.sax.SAXException; |
56 |
|
57 |
import org.openide.filesystems.FileObject; |
58 |
|
59 |
import org.netbeans.spi.settings.Convertor; |
60 |
import org.netbeans.spi.settings.Saver; |
61 |
|
62 |
import org.netbeans.modules.settings.Env; |
63 |
import org.openide.util.Exceptions; |
64 |
import org.openide.util.Lookup; |
65 |
import org.openide.util.io.ReaderInputStream; |
66 |
|
67 |
/** Convertor using {@link java.beans.XMLEncoder} and |
68 |
* {@link java.beans.XMLDecoder}. |
69 |
* |
70 |
* @author Jaroslav Tulach |
71 |
*/ |
72 |
public final class XMLBeanConvertor extends Convertor implements PropertyChangeListener { |
73 |
/** file attribute containnig value whether the setting object will be |
74 |
* stored automaticaly (preventStoring==false) or SaveCookie will be provided. |
75 |
* Default value is <code>preventStoring==false</code>. Usage |
76 |
* <code><attr name="xmlproperties.preventStoring" boolvalue="[true|false]"/> |
77 |
* </code> |
78 |
*/ |
79 |
public final static String EA_PREVENT_STORING = "xmlbean.preventStoring"; //NOI18N |
80 |
/** file attribute containnig list of property names their changes will be ignored. Usage |
81 |
* <code><attr name="xmlproperties.ignoreChanges" stringvalue="name[, ...]"/> |
82 |
* </code> |
83 |
*/ |
84 |
public final static String EA_IGNORE_CHANGES = "xmlbean.ignoreChanges"; //NOI18N |
85 |
/** cached property names to be filtered */ |
86 |
private java.util.Set ignoreProperites; |
87 |
|
88 |
/** create convertor instance; should be used in module layers |
89 |
* @param providerFO provider file object |
90 |
*/ |
91 |
public static Convertor create(Map map) { |
92 |
return new XMLBeanConvertor(map); |
93 |
} |
94 |
private final Map map; |
95 |
|
96 |
public XMLBeanConvertor(Map map) { |
97 |
this.map = map; |
98 |
} |
99 |
|
100 |
public Object read(java.io.Reader r) throws IOException, ClassNotFoundException { |
101 |
BufferedReader buf = new BufferedReader(r); |
102 |
buf.readLine(); |
103 |
String doctype = buf.readLine(); |
104 |
if (!doctype.contains("<!DOCTYPE xmlbeans")) { // NOI18N |
105 |
throw new IOException("Expecting DOCTYPE on second line: " + doctype); // NOI18N |
106 |
} |
107 |
XMLDecoder d = new XMLDecoder(new ReaderInputStream(buf, "UTF-8")); |
108 |
return d.readObject(); |
109 |
} |
110 |
|
111 |
public void write(java.io.Writer w, Object inst) throws IOException { |
112 |
ByteArrayOutputStream out = new ByteArrayOutputStream(); |
113 |
XMLEncoder e = new XMLEncoder(out); |
114 |
e.writeObject(inst); |
115 |
e.close(); |
116 |
String data = new String(out.toByteArray(), "UTF-8"); |
117 |
data = data.replaceFirst("<java", "<!DOCTYPE xmlbeans PUBLIC \"-//NetBeans//DTD XML beans 1.0//EN\" \"http://www.netbeans.org/dtds/xml-beans-1_0.dtd\">\n<java"); |
118 |
w.write(data); |
119 |
} |
120 |
|
121 |
/** an object listening on the setting changes */ |
122 |
private Saver saver; |
123 |
public void registerSaver(Object inst, Saver s) { |
124 |
if (saver != null) { |
125 |
XMLSettingsSupport.err.warning("[Warning] Saver already registered"); |
126 |
return; |
127 |
} |
128 |
|
129 |
// add propertyChangeListener |
130 |
try { |
131 |
java.lang.reflect.Method method = inst.getClass().getMethod( |
132 |
"addPropertyChangeListener", // NOI18N |
133 |
new Class[] {PropertyChangeListener.class}); |
134 |
method.invoke(inst, new Object[] {this}); |
135 |
this.saver = s; |
136 |
//System.out.println("XMLPropertiesConvertor.registerPropertyListener...ok " + inst); |
137 |
} catch (NoSuchMethodException ex) { |
138 |
XMLSettingsSupport.err.warning( |
139 |
"ObjectChangesNotifier: NoSuchMethodException: " + // NOI18N |
140 |
inst.getClass().getName() + ".addPropertyChangeListener"); // NOI18N |
141 |
} catch (IllegalAccessException ex) { |
142 |
Exceptions.printStackTrace(ex); |
143 |
} catch (java.lang.reflect.InvocationTargetException ex) { |
144 |
Exceptions.printStackTrace(ex); |
145 |
} |
146 |
} |
147 |
|
148 |
public void unregisterSaver(Object inst, Saver s) { |
149 |
if (saver == null) return; |
150 |
if (saver != s) { |
151 |
XMLSettingsSupport.err.warning("[Warning] trying unregistered unknown Saver"); |
152 |
return; |
153 |
} |
154 |
try { |
155 |
java.lang.reflect.Method method = inst.getClass().getMethod( |
156 |
"removePropertyChangeListener", // NOI18N |
157 |
new Class[] {PropertyChangeListener.class}); |
158 |
method.invoke(inst, new Object[] {this}); |
159 |
this.saver = null; |
160 |
//System.out.println("XMLPropertiesConvertor.unregisterPropertyListener...ok " + inst); |
161 |
} catch (NoSuchMethodException ex) { |
162 |
XMLSettingsSupport.err.fine( |
163 |
"ObjectChangesNotifier: NoSuchMethodException: " + // NOI18N |
164 |
inst.getClass().getName() + ".removePropertyChangeListener"); // NOI18N |
165 |
// just changes done through gui will be saved |
166 |
} catch (IllegalAccessException ex) { |
167 |
Exceptions.printStackTrace(ex); |
168 |
// just changes done through gui will be saved |
169 |
} catch (java.lang.reflect.InvocationTargetException ex) { |
170 |
Exceptions.printStackTrace(ex); |
171 |
// just changes done through gui will be saved |
172 |
} |
173 |
} |
174 |
|
175 |
public void propertyChange(java.beans.PropertyChangeEvent evt) { |
176 |
if (saver == null || ignoreChange(evt)) return; |
177 |
if (acceptSave()) { |
178 |
try { |
179 |
saver.requestSave(); |
180 |
} catch (IOException ex) { |
181 |
Logger.getLogger(XMLBeanConvertor.class.getName()).log(Level.WARNING, null, ex); |
182 |
} |
183 |
} else { |
184 |
saver.markDirty(); |
185 |
} |
186 |
} |
187 |
|
188 |
|
189 |
//////////////////////////////////////////////////////////// |
190 |
// Private implementation |
191 |
//////////////////////////////////////////////////////////// |
192 |
|
193 |
/** filtering of Property Change Events */ |
194 |
private boolean ignoreChange(java.beans.PropertyChangeEvent pce) { |
195 |
if (pce == null || pce.getPropertyName() == null) return true; |
196 |
|
197 |
if (ignoreProperites == null) { |
198 |
ignoreProperites = Env.parseAttribute( |
199 |
map.get(EA_IGNORE_CHANGES)); |
200 |
} |
201 |
if (ignoreProperites.contains(pce.getPropertyName())) return true; |
202 |
|
203 |
return ignoreProperites.contains("all"); // NOI18N |
204 |
} |
205 |
|
206 |
private boolean acceptSave() { |
207 |
Object storing = map.get(EA_PREVENT_STORING); |
208 |
if (storing == null) return true; |
209 |
if (storing instanceof Boolean) |
210 |
return !((Boolean) storing).booleanValue(); |
211 |
if (storing instanceof String) |
212 |
return !Boolean.valueOf((String) storing).booleanValue(); |
213 |
return true; |
214 |
} |
215 |
} |