KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > core > registry > oldformats > SerialDataConvertor


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 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.core.registry.oldformats;
21
22 import org.openide.ErrorManager;
23 import org.openide.filesystems.FileLock;
24 import org.openide.filesystems.FileObject;
25 import org.openide.modules.ModuleInfo;
26 import org.openide.modules.SpecificationVersion;
27 import org.openide.util.Lookup;
28 import org.w3c.dom.*;
29 import org.xml.sax.Attributes JavaDoc;
30 import org.xml.sax.SAXException JavaDoc;
31 import org.xml.sax.XMLReader JavaDoc;
32 import org.xml.sax.helpers.DefaultHandler JavaDoc;
33 import org.netbeans.core.registry.oldformats.InstanceUtils;
34 import org.netbeans.core.registry.DocumentUtils;
35
36 import java.io.*;
37 import java.util.HashSet JavaDoc;
38 import java.util.Iterator JavaDoc;
39 import java.util.Set JavaDoc;
40 import java.util.Stack JavaDoc;
41
42 /**
43  *
44  * @author copy&pasted from core/settings
45  */

46
47 public class SerialDataConvertor {
48     
49     private static final String JavaDoc INSTANCE_DTD_ID = "-//NetBeans//DTD Session settings 1.0//EN"; // NOI18N
50
private static final String JavaDoc INSTANCE_DTD_WWW = "http://www.netbeans.org/dtds/sessionsettings-1_0.dtd"; // NOI18N
51

52     // enlarged to not need do the test for negative byte values
53
private final static char[] HEXDIGITS = {'0', '1', '2', '3', '4', '5', '6', '7',
54                                              '8', '9', 'A', 'B', 'C', 'D', 'E', 'F',
55                                              '0', '1', '2', '3', '4', '5', '6', '7'};
56     
57     private static final int INDENT = 8;
58     private static final int BLOCK = 64;
59     private static final int BUFFSIZE = INDENT + BLOCK;
60
61     private String JavaDoc moduleCodeName = null;
62     
63     public SerialDataConvertor() {
64     }
65
66     public static Object JavaDoc read(org.w3c.dom.Element JavaDoc element, FileObject fo) throws IOException, ClassNotFoundException JavaDoc {
67         String JavaDoc moduleCodeName = null;
68         String JavaDoc instanceClass = null;
69         String JavaDoc instanceMethod = null;
70         String JavaDoc serialData = null;
71         
72         NodeList nodes = element.getChildNodes();
73         for (int i = 0; i < nodes.getLength(); i++) {
74             Node node = nodes.item(i);
75             if (node.getNodeType() == Node.ELEMENT_NODE) {
76                 Element e = (Element)node;
77                 if (e.getNodeName().equals("module")) {
78                     moduleCodeName = e.getAttribute("name");
79                 }
80                 if (e.getNodeName().equals("instance")) {
81                     instanceClass = e.getAttribute("class");
82                     instanceMethod = e.getAttribute("method");
83                     if (instanceMethod.length() == 0) {
84                         instanceMethod = null;
85                     }
86                     instanceClass = org.openide.util.Utilities.translate(instanceClass);
87                 }
88                 if (e.getNodeName().equals("serialdata")) {
89                     instanceClass = e.getAttribute("class");
90                     serialData = DocumentUtils.getTextValue(e);
91                     instanceClass = org.openide.util.Utilities.translate(instanceClass);
92                 }
93             }
94         }
95         return createInstance(serialData, instanceClass, instanceMethod, fo);
96     }
97
98     public static boolean isSettingsFormat(org.w3c.dom.Element JavaDoc element) {
99         if (element.getNodeName().equals("settings") &&
100             element.getNamespaceURI() == null &&
101             element.getAttribute("version").equals("1.0")) {
102             return true;
103         } else {
104             return false;
105         }
106     }
107     
108     public static String JavaDoc getModuleCodeName(org.w3c.dom.Element JavaDoc element) {
109         NodeList nodes = element.getChildNodes();
110         for (int i = 0; i < nodes.getLength(); i++) {
111             Node node = nodes.item(i);
112             if (node.getNodeType() == Node.ELEMENT_NODE) {
113                 Element e = (Element)node;
114                 if (e.getNodeName().equals("module")) {
115                     return e.getAttribute("name");
116                 }
117             }
118         }
119         return null;
120     }
121
122     
123     public void write(FileObject fo, Object JavaDoc inst) throws IOException, UnsupportedOperationException JavaDoc {
124         FileLock lock = fo.lock();
125         OutputStream os = fo.getOutputStream(lock);
126         boolean ok = false;
127         try {
128             PrintWriter pw = new PrintWriter (os);
129             pw.println("<?xml version=\"1.0\"?>"); // NOI18N
130
pw.print("<!DOCTYPE settings PUBLIC \"");
131             pw.print(INSTANCE_DTD_ID); // NOI18N
132
pw.print("\" \"");
133             pw.print(INSTANCE_DTD_WWW);
134             pw.println("\">"); // NOI18N
135
pw.println("<settings version=\"1.0\">"); // NOI18N
136

137             storeModule(inst, pw);
138
139             storeInstanceOf(inst, pw);
140
141             // TODO: if (inst isBean) then user XMLArchiver instead of Serialization here
142
storeSerialData(inst, pw);
143
144             pw.println("</settings>"); // NOI18N
145
pw.flush();
146             ok = true;
147         } finally {
148             os.close();
149             lock.releaseLock();
150             if (!ok) {
151                 fo.delete();
152             }
153         }
154     }
155     
156     private static Object JavaDoc createInstance(String JavaDoc serialData, String JavaDoc instanceClass, String JavaDoc instanceMethod, FileObject fo) throws IOException, ClassNotFoundException JavaDoc {
157         if (serialData != null) {
158             return InstanceUtils.serialValue(serialData);
159         }
160         if (instanceMethod != null) {
161             return InstanceUtils.methodValue(instanceClass, instanceMethod, fo);
162         }
163         if (instanceClass != null) {
164             return InstanceUtils.newValue(instanceClass);
165         }
166         throw new IOException("Do not know how to create instance from file XXXX");
167         
168     }
169     
170     private void storeInstanceOf (Object JavaDoc inst, PrintWriter pw) throws IOException {
171         Iterator JavaDoc it = getSuperClasses(inst.getClass(), null).iterator();
172         Class JavaDoc clazz;
173         while (it.hasNext()) {
174             clazz = (Class JavaDoc) it.next();
175             pw.print(" <instanceof class=\""); // NOI18N
176
pw.print(clazz.getName());
177             pw.println("\"/>"); // NOI18N
178
}
179     }
180     
181     private void storeModule(Object JavaDoc inst, PrintWriter pw) throws IOException {
182         Iterator JavaDoc it = Lookup.getDefault().lookup(
183             new Lookup.Template(ModuleInfo.class)).allInstances().iterator();
184         while (it.hasNext()) {
185             ModuleInfo mi = (ModuleInfo)it.next();
186             if (mi.owns(inst.getClass())) {
187                 String JavaDoc modulName = mi.getCodeName();
188                 SpecificationVersion spec = mi.getSpecificationVersion();
189                 pw.print(" <module"); // NOI18N
190
if (modulName != null && modulName.length() != 0) {
191                     pw.print(" name=\"");
192                     pw.print(modulName);
193                     pw.print('"');// NOI18N
194
}
195                 if (spec != null) {
196                     pw.print(" spec=\"");
197                     pw.print(spec.toString());
198                     pw.print('"');// NOI18N
199
}
200                 pw.println("/>"); // NOI18N
201

202                 moduleCodeName = modulName;
203                 
204                 return;
205             }
206         }
207         ErrorManager.getDefault().log(ErrorManager.WARNING, "ModuleInfo was not found for class "+inst.getClass());
208     }
209     
210
211     // returns module code name of stored instance
212
public String JavaDoc getModuleCodeName() {
213         return moduleCodeName;
214     }
215     
216     private void storeSerialData (Object JavaDoc inst, PrintWriter pw) throws IOException {
217         pw.print (" <serialdata class=\"");
218         pw.print(inst.getClass().getName());
219         pw.println("\">"); // NOI18N
220

221         ByteArrayOutputStream baos = new ByteArrayOutputStream (1024);
222         ObjectOutput oo = new SpecialObjectOutputStream (baos);
223         oo.writeObject (inst);
224         byte[] bdata = baos.toByteArray ();
225         
226         char[] cdata = new char[BUFFSIZE];
227         for (int i=0; i < INDENT; i++ ) cdata[i] = ' ';
228         
229         int i = 0; // byte array pointer
230
int j; // char array pointer
231
int blen = bdata.length;
232         
233         while (i < blen) {
234             int mark = INDENT + Math.min( 2*(blen-i), BLOCK );
235             for (j=INDENT; j < mark; j += 2) {
236                 int b = ((int)bdata[i++]) + 256;
237                 cdata[j] = HEXDIGITS[b >> 4];
238                 cdata[j+1] = HEXDIGITS[b & 15];
239             }
240             pw.write(cdata, 0, j);
241             pw.println();
242         }
243         pw.println (" </serialdata>"); // NOI18N
244
pw.flush();
245     }
246     
247     /** Get everything what class extends or implements. */
248     private Set JavaDoc getSuperClasses(Class JavaDoc clazz, Set JavaDoc classes) {
249         if (classes == null) {
250             classes = new HashSet JavaDoc();
251         }
252         
253         if (clazz == null || !classes.add(clazz)) {
254             return classes;
255         }
256         
257         Class JavaDoc[] cs = clazz.getInterfaces();
258         
259         // XXX following validation should help to identify a wrong IBM's
260
// implementation of Class.getInterfaces(). The implementation for some
261
// classes returns null. See issue #16257.
262
if (cs != null) {
263             for (int i = 0; i < cs.length; i++) {
264                 getSuperClasses(cs[i], classes);
265             }
266         } else {
267             ErrorManager.getDefault().log(ErrorManager.ERROR,
268                 "Error: if you encounter this message, please attach " + //NOI18N
269
"the class name to the issue http://www.netbeans.org/issues/show_bug.cgi?id=16257. " + //NOI18N
270
"Class.getInterfaces() == null for the class: " + clazz); // NOI18N
271
}
272         
273         return getSuperClasses(clazz.getSuperclass(), classes);
274     }
275
276     
277     /** The only purpose of this object output stream subclass is to
278      * detect whether the serialized object does not return null
279      * in its writeReplace method. Such an object is ignored and exception
280      * is thrown. More details in issue #15563.
281      */

282     private static class SpecialObjectOutputStream extends org.openide.util.io.NbObjectOutputStream {
283
284         private boolean first;
285         
286         public SpecialObjectOutputStream(OutputStream os) throws IOException {
287             super (os);
288             first = true;
289         }
290
291         public Object JavaDoc replaceObject (Object JavaDoc obj) throws IOException {
292             if (first) {
293                 if (obj == null) {
294                     // Object doesn't want to be serialized.
295
throw new NotSerializableException();
296                 }
297                 first = false;
298             }
299             return super.replaceObject(obj);
300         }
301
302     }
303
304     private static class SettingsSAXHandler extends DefaultHandler JavaDoc {
305         
306         private static final String JavaDoc ELM_SETTING = "settings"; // NOI18N
307
private static final String JavaDoc ATR_SETTING_VERSION = "version"; // NOI18N
308

309         private static final String JavaDoc ELM_MODULE = "module"; // NOI18N
310
private static final String JavaDoc ATR_MODULE_NAME = "name"; // NOI18N
311
private static final String JavaDoc ATR_MODULE_SPEC = "spec"; // NOI18N
312
private static final String JavaDoc ATR_MODULE_IMPL = "impl"; // NOI18N
313

314         private static final String JavaDoc ELM_INSTANCE = "instance"; // NOI18N
315
private static final String JavaDoc ATR_INSTANCE_CLASS = "class"; // NOI18N
316
private static final String JavaDoc ATR_INSTANCE_METHOD = "method"; // NOI18N
317

318         private static final String JavaDoc ELM_INSTANCEOF = "instanceof"; // NOI18N
319
private static final String JavaDoc ATR_INSTANCEOF_CLASS = "class"; // NOI18N
320

321         private static final String JavaDoc ELM_SERIALDATA = "serialdata"; // NOI18N
322
private static final String JavaDoc ATR_SERIALDATA_CLASS = "class"; // NOI18N
323

324         
325         
326         // ATR_MODULE_NAME
327
private String JavaDoc codeName;
328         // ATR_INSTANCE_CLASS
329
private String JavaDoc instanceClass;
330        
331         // ATR_INSTANCEOF_CLASS
332
private Set JavaDoc instanceOf = new HashSet JavaDoc();
333
334         // ATR_INSTANCE_METHOD
335
private String JavaDoc instanceMethod;
336
337
338         // ATR_MODULE_SPEC
339
private SpecificationVersion moduleSpec;
340         // ATR_MODULE_IMPL
341
private String JavaDoc moduleImpl;
342
343         // ATR_SETTING_VERSION
344
private String JavaDoc version;
345         
346         
347         // ATR_SERIALDATA_CLASS
348
private String JavaDoc serialdata;
349         
350         
351         // module base name
352
private String JavaDoc codeNameBase;
353         
354         // module base version
355
private int codeNameRelease;
356
357         
358         private Stack JavaDoc stack;
359         private CharArrayWriter chaos = null;
360         
361         private boolean readModuleOnly;
362         
363         public SettingsSAXHandler(boolean readModuleOnly) {
364             stack = new Stack JavaDoc();
365             this.readModuleOnly = readModuleOnly;
366         }
367         
368         public org.xml.sax.InputSource JavaDoc resolveEntity(String JavaDoc publicId, String JavaDoc systemId) throws SAXException JavaDoc {
369             if (INSTANCE_DTD_ID.equals(publicId)) {
370                 return new org.xml.sax.InputSource JavaDoc(new ByteArrayInputStream(new byte[0]));
371             } else {
372                 return null; // i.e. follow advice of systemID
373
}
374         }
375         
376         public void characters(char[] values, int start, int length) throws SAXException JavaDoc {
377             String JavaDoc element = (String JavaDoc) stack.peek();
378             if (ELM_SERIALDATA.equals(element)) {
379                 // [PENDING] should be optimized to do not read all chars to memory
380
if (chaos == null) {
381                     chaos = new CharArrayWriter(length);
382                 }
383                 chaos.write(values, start, length);
384             }
385         }
386         
387         public void startElement(String JavaDoc uri, String JavaDoc localName, String JavaDoc qName, Attributes JavaDoc attribs) throws SAXException JavaDoc {
388             stack.push(qName);
389             if (ELM_SETTING.equals(qName)) {
390                 version = attribs.getValue(ATR_SETTING_VERSION);
391             } else if (ELM_MODULE.equals(qName)) {
392                 codeName = attribs.getValue(ATR_MODULE_NAME);
393                 resolveModuleElm(codeName);
394                 moduleImpl = attribs.getValue(ATR_MODULE_IMPL);
395                 if (readModuleOnly) {
396                     throw new StopSAXException();
397                 }
398                 try {
399                     String JavaDoc spec = attribs.getValue(ATR_MODULE_SPEC);
400                     moduleSpec = spec == null ? null : new SpecificationVersion(spec);
401                 } catch (NumberFormatException JavaDoc nfe) {
402                     throw new SAXException JavaDoc(nfe);
403                 }
404             } else if (ELM_INSTANCEOF.equals(qName)) {
405                 instanceOf.add(org.openide.util.Utilities.translate(attribs.getValue(ATR_INSTANCEOF_CLASS)));
406             } else if (ELM_INSTANCE.equals(qName)) {
407                 instanceClass = attribs.getValue(ATR_INSTANCE_CLASS);
408                 instanceClass = org.openide.util.Utilities.translate(instanceClass);
409                 instanceMethod = attribs.getValue(ATR_INSTANCE_METHOD);
410             } else if (ELM_SERIALDATA.equals(qName)) {
411                 instanceClass = attribs.getValue(ATR_SERIALDATA_CLASS);
412                 instanceClass = org.openide.util.Utilities.translate(instanceClass);
413             }
414         }
415         
416         /** reade codenamebase + revision */
417         private void resolveModuleElm(String JavaDoc codeName) {
418             if (codeName != null) {
419                 int slash = codeName.indexOf("/"); // NOI18N
420
if (slash == -1) {
421                     codeNameBase = codeName;
422                     codeNameRelease = -1;
423                 } else {
424                     codeNameBase = codeName.substring(0, slash);
425                     try {
426                         codeNameRelease = Integer.parseInt(codeName.substring(slash + 1));
427                     } catch (NumberFormatException JavaDoc ex) {
428                         ErrorManager emgr = ErrorManager.getDefault();
429                         emgr.annotate(ex, "Source: XXXXX"); // NOI18N
430
emgr.notify(ErrorManager.INFORMATIONAL, ex);
431                         codeNameRelease = -1;
432                     }
433                 }
434             } else {
435                 codeNameBase = null;
436                 codeNameRelease = -1;
437             }
438         }
439         
440         public void endElement(String JavaDoc uri, String JavaDoc localName, String JavaDoc qName) throws SAXException JavaDoc {
441             String JavaDoc element = (String JavaDoc) stack.pop();
442             if (ELM_SERIALDATA.equals(element)) {
443                 if (chaos != null) {
444                     serialdata = chaos.toString();
445                 }
446             }
447         }
448         
449     }
450     
451     final static class StopSAXException extends SAXException JavaDoc {
452         public StopSAXException() {
453             super("Parser stopped"); // NOI18N
454
}
455     }
456     
457 }
458
Popular Tags