KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > upgrade > systemoptions > SettingsRecognizer


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.upgrade.systemoptions;
21
22 import java.io.BufferedInputStream JavaDoc;
23 import java.io.ByteArrayInputStream JavaDoc;
24 import java.io.ByteArrayOutputStream JavaDoc;
25 import java.io.CharArrayWriter JavaDoc;
26 import java.io.IOException JavaDoc;
27 import java.io.InputStream JavaDoc;
28 import java.io.InputStreamReader JavaDoc;
29 import java.io.ObjectInput JavaDoc;
30 import java.io.ObjectInputStream JavaDoc;
31 import java.io.OutputStream JavaDoc;
32 import java.io.PrintWriter JavaDoc;
33 import java.io.Reader JavaDoc;
34 import java.io.StringWriter JavaDoc;
35 import java.lang.reflect.Method JavaDoc;
36 import java.util.HashSet JavaDoc;
37 import java.util.Set JavaDoc;
38 import java.util.Stack JavaDoc;
39 import org.openide.ErrorManager;
40 import org.openide.filesystems.FileObject;
41 //import org.openide.modules.SpecificationVersion;
42
import org.openide.util.Lookup;
43 import org.openide.util.SharedClassObject;
44 import org.xml.sax.Attributes JavaDoc;
45 import org.xml.sax.SAXException JavaDoc;
46 import org.xml.sax.XMLReader JavaDoc;
47
48 /**
49  * Copy of XMLSettingsSupport.SettingsRecognizer by Jan Pokorsky
50  */

51 public class SettingsRecognizer extends org.xml.sax.helpers.DefaultHandler JavaDoc {
52     public static final String JavaDoc INSTANCE_DTD_ID = "-//NetBeans//DTD Session settings 1.0//EN"; // NOI18N
53
static final ErrorManager err = ErrorManager.getDefault().getInstance(SettingsRecognizer.class.getName()); // NOI18N
54

55     private static final String JavaDoc ELM_SETTING = "settings"; // NOI18N
56
private static final String JavaDoc ATR_SETTING_VERSION = "version"; // NOI18N
57

58     private static final String JavaDoc ELM_MODULE = "module"; // NOI18N
59
private static final String JavaDoc ATR_MODULE_NAME = "name"; // NOI18N
60
private static final String JavaDoc ATR_MODULE_SPEC = "spec"; // NOI18N
61
private static final String JavaDoc ATR_MODULE_IMPL = "impl"; // NOI18N
62

63     private static final String JavaDoc ELM_INSTANCE = "instance"; // NOI18N
64
private static final String JavaDoc ATR_INSTANCE_CLASS = "class"; // NOI18N
65
private static final String JavaDoc ATR_INSTANCE_METHOD = "method"; // NOI18N
66

67     private static final String JavaDoc ELM_INSTANCEOF = "instanceof"; // NOI18N
68
private static final String JavaDoc ATR_INSTANCEOF_CLASS = "class"; // NOI18N
69

70     private static final String JavaDoc ELM_SERIALDATA = "serialdata"; // NOI18N
71
private static final String JavaDoc ATR_SERIALDATA_CLASS = "class"; // NOI18N
72

73     //private static final String VERSION = "1.0"; // NOI18N
74

75     private boolean header;
76     private Stack JavaDoc<String JavaDoc> stack;
77     
78     private String JavaDoc version;
79     private String JavaDoc instanceClass;
80     private String JavaDoc instanceMethod;
81     private Set JavaDoc<String JavaDoc> instanceOf = new HashSet JavaDoc<String JavaDoc>();
82     
83     private byte[] serialdata;
84     private CharArrayWriter JavaDoc chaos = null;
85     
86     private String JavaDoc codeName;
87     private String JavaDoc codeNameBase;
88     private int codeNameRelease;
89     //private SpecificationVersion moduleSpec;
90
private String JavaDoc moduleImpl;
91     /** file with stored settings */
92     private final FileObject source;
93     
94     /** XML handler recognizing settings.
95      * @param header if true read just elements instanceof, module and attr classname.
96      * @param source file with stored settings
97      */

98     public SettingsRecognizer(boolean header, FileObject source) {
99         this.header = header;
100         this.source = source;
101     }
102     
103     public boolean isAllRead() {
104         return !header;
105     }
106     
107     public void setAllRead(boolean all) {
108         if (!header) return;
109         header = all;
110     }
111     
112     public String JavaDoc getSettingsVerison() {
113         return version;
114     }
115     
116     public String JavaDoc getCodeName() {
117         return codeName;
118     }
119     
120     public String JavaDoc getCodeNameBase() {
121         return codeNameBase;
122     }
123     
124     public int getCodeNameRelease() {
125         return codeNameRelease;
126     }
127     
128     /*public SpecificationVersion getSpecificationVersion() {
129         return moduleSpec;
130     }*/

131     
132     public String JavaDoc getModuleImpl() {
133         return moduleImpl;
134     }
135     
136     /** Set of names. */
137     public Set JavaDoc getInstanceOf() {
138         return instanceOf;
139     }
140     
141     /** Method attribute from the instance element. */
142     public String JavaDoc getMethodName() {
143         return instanceMethod;
144     }
145     
146     /** Serialized instance, can be null. */
147     public InputStream JavaDoc getSerializedInstance() {
148         if (serialdata == null) return null;
149         return new ByteArrayInputStream JavaDoc(serialdata);
150     }
151     
152     public org.xml.sax.InputSource JavaDoc resolveEntity(String JavaDoc publicId, String JavaDoc systemId)
153     throws SAXException JavaDoc {
154         if (INSTANCE_DTD_ID.equals(publicId)) {
155             return new org.xml.sax.InputSource JavaDoc(new ByteArrayInputStream JavaDoc(new byte[0]));
156         } else {
157             return null; // i.e. follow advice of systemID
158
}
159     }
160     
161     public void characters(char[] values, int start, int length) throws SAXException JavaDoc {
162         if (header) return;
163         String JavaDoc element = stack.peek();
164         if (ELM_SERIALDATA.equals(element)) {
165             // [PENDING] should be optimized to do not read all chars to memory
166
if (chaos == null) chaos = new CharArrayWriter JavaDoc(length);
167             chaos.write(values, start, length);
168         }
169     }
170     
171     public void startElement(String JavaDoc uri, String JavaDoc localName, String JavaDoc qName, Attributes JavaDoc attribs) throws SAXException JavaDoc {
172         stack.push(qName);
173         if (ELM_SETTING.equals(qName)) {
174             version = attribs.getValue(ATR_SETTING_VERSION);
175         } else if (ELM_MODULE.equals(qName)) {
176             codeName = attribs.getValue(ATR_MODULE_NAME);
177             resolveModuleElm(codeName);
178             moduleImpl = attribs.getValue(ATR_MODULE_IMPL);
179             try {
180                 String JavaDoc spec = attribs.getValue(ATR_MODULE_SPEC);
181                 //moduleSpec = spec == null ? null : new SpecificationVersion(spec);
182
} catch (NumberFormatException JavaDoc nfe) {
183                 throw new SAXException JavaDoc(nfe);
184             }
185         } else if (ELM_INSTANCEOF.equals(qName)) {
186             instanceOf.add(org.openide.util.Utilities.translate(
187                     attribs.getValue(ATR_INSTANCEOF_CLASS)));
188         } else if (ELM_INSTANCE.equals(qName)) {
189             instanceClass = attribs.getValue(ATR_INSTANCE_CLASS);
190             if (instanceClass == null) {
191                 System.err.println("Hint: NPE is caused by broken settings file: " + source ); // NOI18N
192
}
193             instanceClass = org.openide.util.Utilities.translate(instanceClass);
194             instanceMethod = attribs.getValue(ATR_INSTANCE_METHOD);
195         } else if (ELM_SERIALDATA.equals(qName)) {
196             instanceClass = attribs.getValue(ATR_SERIALDATA_CLASS);
197             instanceClass = org.openide.util.Utilities.translate(instanceClass);
198             if (header) throw new StopSAXException();
199         }
200     }
201     
202     /** reade codenamebase + revision */
203     private void resolveModuleElm(String JavaDoc codeName) {
204         if (codeName != null) {
205             int slash = codeName.indexOf("/"); // NOI18N
206
if (slash == -1) {
207                 codeNameBase = codeName;
208                 codeNameRelease = -1;
209             } else {
210                 codeNameBase = codeName.substring(0, slash);
211                 try {
212                     codeNameRelease = Integer.parseInt(codeName.substring(slash + 1));
213                 } catch (NumberFormatException JavaDoc ex) {
214                     ErrorManager emgr = ErrorManager.getDefault();
215                     emgr.annotate(ex, "Content: \n" + getFileContent(source)); // NOI18N
216
emgr.annotate(ex, "Source: " + source); // NOI18N
217
emgr.notify(ErrorManager.INFORMATIONAL, ex);
218                     codeNameRelease = -1;
219                 }
220             }
221         } else {
222             codeNameBase = null;
223             codeNameRelease = -1;
224         }
225     }
226     
227     public void endElement(String JavaDoc uri, String JavaDoc localName, String JavaDoc qName) throws SAXException JavaDoc {
228         //if (header) return;
229
String JavaDoc element = stack.pop();
230         if (ELM_SERIALDATA.equals(element)) {
231             if (chaos != null) {
232                 ByteArrayOutputStream JavaDoc baos = new ByteArrayOutputStream JavaDoc(chaos.size() >> 1);
233                 try {
234                     chars2Bytes(baos, chaos.toCharArray(), 0, chaos.size());
235                     serialdata = baos.toByteArray();
236                 } catch (IOException JavaDoc ex) {
237                     ErrorManager.getDefault().notify(
238                             ErrorManager.WARNING, ex
239                             );
240                 } finally {
241                     chaos = null; // don't keep the info twice
242
try {
243                         baos.close();
244                     } catch (IOException JavaDoc ex) {
245                         // doesn't matter
246
}
247                 }
248             }
249         }
250     }
251     
252     /** Tries to deserialize instance saved in is.
253      * @param is stream with stored object, can be null
254      * @return deserialized object or null
255      */

256     private Object JavaDoc readSerial(InputStream JavaDoc is) throws IOException JavaDoc, ClassNotFoundException JavaDoc {
257         if (is == null) return null;
258         try {
259             ObjectInput JavaDoc oi = new ObjectInputStream JavaDoc(is);
260             try {
261                 Object JavaDoc o = oi.readObject();
262                 return o;
263             } finally {
264                 oi.close();
265             }
266         } catch (IOException JavaDoc ex) {
267             ErrorManager emgr = ErrorManager.getDefault();
268             emgr.annotate(ex, "Content: \n" + getFileContent(source)); // NOI18N
269
emgr.annotate(ex, "Source: " + source); // NOI18N
270
emgr.annotate(ex, "Cannot read class: " + instanceClass); // NOI18N
271
throw ex;
272         } catch (ClassNotFoundException JavaDoc ex) {
273             ErrorManager emgr = ErrorManager.getDefault();
274             emgr.annotate(ex, "Content: \n" + getFileContent(source)); // NOI18N
275
emgr.annotate(ex, "Source: " + source); // NOI18N
276
throw ex;
277         }
278     }
279     
280     /** Create an instance.
281      * @return the instance of type {@link #instanceClass}
282      * @exception IOException if an I/O error occured
283      * @exception ClassNotFoundException if a class was not found
284      */

285     public Object JavaDoc instanceCreate() throws java.io.IOException JavaDoc, ClassNotFoundException JavaDoc {
286         Object JavaDoc inst = null;
287         
288         // deserialize
289
inst = readSerial(getSerializedInstance());
290         
291         // default instance
292
if (inst == null) {
293             if (instanceMethod != null) {
294                 inst = createFromMethod(instanceClass, instanceMethod);
295             } else {
296                 // use default constructor
297
Class JavaDoc<?> clazz = instanceClass();
298                 if (SharedClassObject.class.isAssignableFrom(clazz)) {
299                     inst = SharedClassObject.findObject(clazz.asSubclass(SharedClassObject.class), false);
300                     if (null != inst) {
301                         // instance already exists -> reset it to defaults
302
try {
303                             Method JavaDoc method = SharedClassObject.class.getDeclaredMethod("reset", new Class JavaDoc[0]); // NOI18N
304
method.setAccessible(true);
305                             method.invoke(inst, new Object JavaDoc[0]);
306                         } catch (Exception JavaDoc e) {
307                             ErrorManager.getDefault().notify(e);
308                         }
309                     } else {
310                         inst = SharedClassObject.findObject(clazz.asSubclass(SharedClassObject.class), true);
311                     }
312                 } else {
313                     try {
314                         inst = clazz.newInstance();
315                     } catch (Exception JavaDoc ex) {
316                         IOException JavaDoc ioe = new IOException JavaDoc();
317                         ErrorManager emgr = ErrorManager.getDefault();
318                         emgr.annotate(ioe, ex);
319                         emgr.annotate(ioe, "Content: \n" + getFileContent(source)); // NOI18N
320
emgr.annotate(ioe, "Class: " + clazz); // NOI18N
321
emgr.annotate(ioe, "Source: " + source); // NOI18N
322
throw ioe;
323                     }
324                 }
325             }
326         }
327         
328         return inst;
329     }
330     
331     /** Get file content as String. If some exception occures its stack trace
332      * is return instead. */

333     private static String JavaDoc getFileContent(FileObject fo) {
334         try {
335             InputStreamReader JavaDoc isr = new InputStreamReader JavaDoc(fo.getInputStream());
336             char[] cbuf = new char[1024];
337             int length;
338             StringBuffer JavaDoc sbuf = new StringBuffer JavaDoc(1024);
339             while (true) {
340                 length = isr.read(cbuf);
341                 if (length > 0) {
342                     sbuf.append(cbuf, 0, length);
343                 } else {
344                     return sbuf.toString();
345                 }
346             }
347         } catch (Exception JavaDoc ex) {
348             StringWriter JavaDoc sw = new StringWriter JavaDoc();
349             ex.printStackTrace(new PrintWriter JavaDoc(sw));
350             return sw.toString();
351         }
352     }
353     
354     /** create instance by invoking class method */
355     private Object JavaDoc createFromMethod(String JavaDoc srcClazz, String JavaDoc srcMethod)
356     throws ClassNotFoundException JavaDoc, IOException JavaDoc {
357         int dotIndex = instanceMethod.lastIndexOf('.');
358         String JavaDoc targetClass;
359         String JavaDoc targetMethod;
360         if (dotIndex > 0) {
361             targetClass = srcMethod.substring(0, dotIndex);
362             targetMethod = srcMethod.substring(dotIndex + 1);
363         } else {
364             targetClass = srcClazz;
365             targetMethod = srcMethod;
366         }
367         
368         Class JavaDoc<?> clazz = loadClass(targetClass);
369         
370         try {
371             Object JavaDoc instance;
372             try {
373                 Method JavaDoc method = clazz.getMethod(targetMethod, new Class JavaDoc[]{FileObject.class});
374                 method.setAccessible(true);
375                 instance = method.invoke(null, source);
376             } catch (NoSuchMethodException JavaDoc ex) {
377                 Method JavaDoc method = clazz.getMethod(targetMethod);
378                 method.setAccessible(true);
379                 instance = method.invoke(null, new Object JavaDoc[0]);
380             }
381             if (instance == null) {
382                 // Strictly verboten. Cf. BT #4827173 for example.
383
throw new IOException JavaDoc("Null return not permitted from " + targetClass + "." + targetMethod); // NOI18N
384
}
385             return instance;
386         } catch (Exception JavaDoc ex) {
387             IOException JavaDoc ioe = new IOException JavaDoc("Error reading " + source + ": " + ex); // NOI18N
388
ErrorManager emgr = ErrorManager.getDefault();
389             emgr.annotate(ioe, "Class: " + clazz); // NOI18N
390
emgr.annotate(ioe, "Method: " + srcMethod); // NOI18N
391
emgr.annotate(ioe, ex);
392             emgr.annotate(ioe, "Content:\n" + getFileContent(source)); // NOI18N
393
throw ioe;
394         }
395     }
396     
397     /** The representation type that may be created as instances.
398      * Can be used to test whether the instance is of an appropriate
399      * class without actually creating it.
400      *
401      * @return the representation class of the instance
402      * @exception IOException if an I/O error occurred
403      * @exception ClassNotFoundException if a class was not found
404      */

405     public Class JavaDoc instanceClass() throws java.io.IOException JavaDoc, ClassNotFoundException JavaDoc {
406         if (instanceClass == null) {
407             throw new ClassNotFoundException JavaDoc(source +
408                     ": missing 'class' attribute in 'instance' element"); //NOI18N
409
}
410         
411         return loadClass(instanceClass);
412     }
413     
414     /** try to load class from system and current classloader. */
415     private Class JavaDoc loadClass(String JavaDoc clazz) throws ClassNotFoundException JavaDoc {
416         return ((ClassLoader JavaDoc)Lookup.getDefault().lookup(ClassLoader JavaDoc.class)).loadClass(clazz);
417     }
418     
419     /** get class name of instance */
420     public String JavaDoc instanceName() {
421         if (instanceClass == null) {
422             return ""; // NOI18N
423
} else {
424             return instanceClass;
425         }
426     }
427     
428     private int tr(char c) {
429         if (c >= '0' && c <= '9') return c - '0';
430         if (c >= 'A' && c <= 'F') return c - 'A' + 10;
431         if (c >= 'a' && c <= 'f') return c - 'a' + 10;
432         return -1;
433     }
434     
435     /** Converts array of chars to array of bytes. All whitespaces and
436      * unknown chars are skipped.
437      */

438     private void chars2Bytes(OutputStream JavaDoc os, char[] chars, int off, int length)
439     throws IOException JavaDoc {
440         byte rbyte;
441         int read;
442         
443         for (int i = off; i < length; ) {
444             read = tr(chars[i++]);
445             if (read >= 0) rbyte = (byte) (read << 4); // * 16;
446
else continue;
447             
448             while (i < length) {
449                 read = tr(chars[i++]);
450                 if (read >= 0) {
451                     rbyte += (byte) read;
452                     os.write(rbyte);
453                     break;
454                 }
455             }
456         }
457     }
458     
459     /** Parse settings file. */
460     public void parse() throws IOException JavaDoc {
461         InputStream JavaDoc in = null;
462         
463         try {
464             if (header) {
465                 if (err.isLoggable(err.INFORMATIONAL) && source.getSize() < 12000) {
466                     // log the content of the stream
467
byte[] arr = new byte[(int)source.getSize()];
468                     InputStream JavaDoc temp = source.getInputStream();
469                     int len = temp.read(arr);
470                     if (len != arr.length) {
471                         throw new IOException JavaDoc("Could not read " + arr.length + " bytes from " + source + " just " + len); // NOI18N
472
}
473                     
474                     err.log("Parsing:" + new String JavaDoc(arr));
475                     
476                     temp.close();
477                     
478                     in = new ByteArrayInputStream JavaDoc(arr);
479                 } else {
480                     in = new BufferedInputStream JavaDoc(source.getInputStream());
481                 }
482                 Set JavaDoc<String JavaDoc> iofs = quickParse(new BufferedInputStream JavaDoc(in));
483                 if (iofs != null) {
484                     instanceOf = iofs;
485                     return;
486                 }
487             }
488         } catch (IOException JavaDoc ioe) {
489             // ignore - fallback to XML parser follows
490
} finally {
491             if (in != null) in.close();
492         }
493         stack = new Stack JavaDoc<String JavaDoc>();
494         try {
495             in = source.getInputStream();
496             XMLReader JavaDoc reader = org.openide.xml.XMLUtil.createXMLReader();
497             reader.setContentHandler(this);
498             reader.setErrorHandler(this);
499             reader.setEntityResolver(this);
500             reader.parse(new org.xml.sax.InputSource JavaDoc(new BufferedInputStream JavaDoc(in)));
501         } catch (SettingsRecognizer.StopSAXException ex) {
502             // Ok, header is read
503
} catch (SAXException JavaDoc ex) {
504             IOException JavaDoc ioe = new IOException JavaDoc(source.toString()); // NOI18N
505
ErrorManager emgr = ErrorManager.getDefault();
506             emgr.annotate(ioe, ex);
507             if (ex.getException() != null) {
508                 emgr.annotate(ioe, ex.getException());
509             }
510             emgr.annotate(ioe, "Content: \n" + getFileContent(source)); // NOI18N
511
emgr.annotate(ioe, "Source: " + source); // NOI18N
512
throw ioe;
513         } finally {
514             stack = null;
515             try {
516                 if (in != null) {
517                     in.close();
518                 }
519             } catch (IOException JavaDoc ex) {
520                 // ignore already closed
521
}
522         }
523     }
524     
525     /** Parse setting from source. */
526     public void parse(Reader JavaDoc source) throws IOException JavaDoc {
527         stack = new Stack JavaDoc<String JavaDoc>();
528         
529         try {
530             XMLReader JavaDoc reader = org.openide.xml.XMLUtil.createXMLReader();
531             reader.setContentHandler(this);
532             reader.setErrorHandler(this);
533             reader.setEntityResolver(this);
534             reader.parse(new org.xml.sax.InputSource JavaDoc(source));
535         } catch (SettingsRecognizer.StopSAXException ex) {
536             // Ok, header is read
537
} catch (SAXException JavaDoc ex) {
538             IOException JavaDoc ioe = new IOException JavaDoc(source.toString()); // NOI18N
539
ErrorManager emgr = ErrorManager.getDefault();
540             emgr.annotate(ioe, ex);
541             if (ex.getException() != null) {
542                 emgr.annotate(ioe, ex.getException());
543             }
544             throw ioe;
545         } finally {
546             stack = null;
547         }
548     }
549     
550     // Encoding irrelevant for these getBytes() calls: all are ASCII...
551
// (unless someone has their system encoding set to UCS-16!)
552
private static final byte[] MODULE_SETTINGS_INTRO = "<?xml version=\"1.0\"?> <!DOCTYPE settings PUBLIC \"-//NetBeans//DTD Session settings 1.0//EN\" \"http://www.netbeans.org/dtds/sessionsettings-1_0.dtd\"> <settings version=\"".getBytes(); // NOI18N
553
private static final byte[] MODULE_SETTINGS_INTRO_END = "> <".getBytes(); // NOI18N
554
private static final byte[] MODULE_SETTINGS_MODULE_NAME = "odule name=\"".getBytes(); // NOI18N
555
private static final byte[] MODULE_SETTINGS_MODULE_SPEC = "spec=\"".getBytes(); // NOI18N
556
private static final byte[] MODULE_SETTINGS_MODULE_IMPL = "impl=\"".getBytes(); // NOI18N
557
private static final byte[] MODULE_SETTINGS_TAG_END = "> <".getBytes(); // NOI18N
558
private static final byte[] MODULE_SETTINGS_INSTANCE = "nstance".getBytes(); // NOI18N
559
private static final byte[] MODULE_SETTINGS_INSTANCE_CLZ = "class=\"".getBytes(); // NOI18N
560
private static final byte[] MODULE_SETTINGS_INSTANCE_MTD = "method=\"".getBytes(); // NOI18N
561
private static final byte[] MODULE_SETTINGS_OF = "f class=\"".getBytes(); // NOI18N
562
private static final byte[] MODULE_SETTINGS_SERIAL = "erialdata class=\"".getBytes(); // NOI18N
563
private static final byte[] MODULE_SETTINGS_END = "settings>".getBytes(); // NOI18N
564

565     /** Attempts to read the stream in the same way as SAX parser but avoids using it.
566      * If it does not manage to parse it this way, it returns null, in which case
567      * you have to use a real parser.
568      * @see "#36718"
569      */

570     private Set JavaDoc<String JavaDoc> quickParse(InputStream JavaDoc is) throws IOException JavaDoc {
571         Set JavaDoc<String JavaDoc> iofs = new HashSet JavaDoc<String JavaDoc>(); // <String>
572

573         if (!expect(is, MODULE_SETTINGS_INTRO)) {
574             err.log("Could not read intro "+source); // NOI18N
575
return null;
576         }
577         version = readTo(is, '"');
578         if (version == null) {
579             err.log("Could not read version "+source); // NOI18N
580
return null;
581         }
582         if (!expect(is, MODULE_SETTINGS_INTRO_END)) {
583             err.log("Could not read stuff after cnb "+source); // NOI18N
584
return null;
585         }
586         // Now we have (module?, instanceof*, (instance | serialdata)).
587
int c;
588         PARSE:
589             while (true) {
590                 c = is.read();
591                 switch (c) {
592                     case 'm':
593                         // <module />
594
if (!expect(is, MODULE_SETTINGS_MODULE_NAME)) {
595                             err.log("Could not read up to <module name=\" "+source); // NOI18N
596
return null;
597                         }
598                         String JavaDoc codeName = readTo(is, '"');
599                         if (codeName == null) {
600                             err.log("Could not read module name value "+source); // NOI18N
601
return null;
602                         }
603                         codeName = codeName.intern();
604                         resolveModuleElm(codeName);
605                         c = is.read();
606                         if (c == '/') {
607                             if (!expect(is, MODULE_SETTINGS_TAG_END)) {
608                                 err.log("Could not read up to end of module tag "+source); // NOI18N
609
return null;
610                             }
611                             break;
612                         } else if (c != ' ') {
613                             err.log("Could not space after module name "+source); // NOI18N
614
return null;
615                         }
616                         // <module spec/>
617
if (!expect(is, MODULE_SETTINGS_MODULE_SPEC)) {
618                             err.log("Could not read up to spec=\" "+source); // NOI18N
619
return null;
620                         }
621                         String JavaDoc mspec = readTo(is, '"');
622                         if (mspec == null) {
623                             err.log("Could not read module spec value "+source); // NOI18N
624
return null;
625                         }
626                         try {
627                             //moduleSpec = new SpecificationVersion(mspec);
628
} catch (NumberFormatException JavaDoc nfe) {
629                             return null;
630                         }
631                         c = is.read();
632                         if (c == '/') {
633                             if (!expect(is, MODULE_SETTINGS_TAG_END)) {
634                                 err.log("Could not read up to end of <module name spec/> tag "+source); // NOI18N
635
return null;
636                             }
637                             break;
638                         } else if (c != ' ') {
639                             err.log("Could not read space after module name "+source); // NOI18N
640
return null;
641                         }
642                         // <module impl/>
643
if (!expect(is, MODULE_SETTINGS_MODULE_IMPL)) {
644                             err.log("Could not read up to impl=\" "+source); // NOI18N
645
return null;
646                         }
647                         moduleImpl = readTo(is, '"');
648                         if (moduleImpl == null) {
649                             err.log("Could not read module impl value "+source); // NOI18N
650
return null;
651                         }
652                         moduleImpl = moduleImpl.intern();
653                         // /> >
654
if (!expect(is, MODULE_SETTINGS_TAG_END)) {
655                             err.log("Could not read up to /> < "+source); // NOI18N
656
return null;
657                         }
658                         break;
659                     case 'i':
660                         // <instanceof> or <instance>
661
if (!expect(is, MODULE_SETTINGS_INSTANCE)) {
662                             err.log("Could not read up to instance "+source); // NOI18N
663
return null;
664                         }
665                         // Now we need to check which one
666
c = is.read();
667                         if (c == 'o') {
668                             if (!expect(is, MODULE_SETTINGS_OF)) {
669                                 err.log("Could not read up to instance"); // NOI18N
670
return null;
671                             }
672                             String JavaDoc iof = readTo(is, '"');
673                             if (iof == null) {
674                                 err.log("Could not read instanceof value "+source); // NOI18N
675
return null;
676                             }
677                             iof = org.openide.util.Utilities.translate(iof).intern();
678                             iofs.add(iof);
679                             if (is.read() != '/') {
680                                 err.log("No / at end of <instanceof> " + iof+" "+source); // NOI18N
681
return null;
682                             }
683                             if (!expect(is, MODULE_SETTINGS_TAG_END)) {
684                                 err.log("Could not read up to next tag after <instanceof> " + iof+" "+source); // NOI18N
685
return null;
686                             }
687                         } else if (c == ' ') {
688                             // read class and optional method
689
if (!expect(is, MODULE_SETTINGS_INSTANCE_CLZ)) {
690                                 err.log("Could not read up to class=\" "+source); // NOI18N
691
return null;
692                             }
693                             instanceClass = readTo(is, '"');
694                             if (instanceClass == null) {
695                                 err.log("Could not read instance class value "+source); // NOI18N
696
return null;
697                             }
698                             instanceClass = org.openide.util.Utilities.translate(instanceClass).intern();
699                             c = is.read();
700                             if (c == '/') {
701                                 if (!expect(is, MODULE_SETTINGS_TAG_END)) {
702                                     err.log("Could not read up to end of instance tag "+source); // NOI18N
703
return null;
704                                 }
705                                 break;
706                             } else if (c != ' ') {
707                                 err.log("Could not space after instance class "+source); // NOI18N
708
return null;
709                             }
710                             // <instance method/>
711
if (!expect(is, MODULE_SETTINGS_INSTANCE_MTD)) {
712                                 err.log("Could not read up to method=\" "+source); // NOI18N
713
return null;
714                             }
715                             instanceMethod = readTo(is, '"');
716                             if (instanceMethod == null) {
717                                 err.log("Could not read method value "+source); // NOI18N
718
return null;
719                             }
720                             instanceMethod = instanceMethod.intern();
721                             c = is.read();
722                             if (c == '/') {
723                                 if (!expect(is, MODULE_SETTINGS_TAG_END)) {
724                                     err.log("Could not read up to end of instance tag "+source); // NOI18N
725
return null;
726                                 }
727                                 break;
728                             }
729                             err.log("Strange stuff after method attribute "+source); // NOI18N
730
return null;
731                         } else {
732                             err.log("Could not read after to instance "+source); // NOI18N
733
return null;
734                         }
735                         break;
736                     case 's':
737                         // <serialdata class
738
if (!expect(is, MODULE_SETTINGS_SERIAL)) {
739                             err.log("Could not read up to <serialdata class=\" "+source); // NOI18N
740
return null;
741                         }
742                         instanceClass = readTo(is, '"');
743                         if (instanceClass == null) {
744                             err.log("Could not read serialdata class value "+source); // NOI18N
745
return null;
746                         }
747                         instanceClass = org.openide.util.Utilities.translate(instanceClass).intern();
748                         // here we are complete for header, otherwise we would need to go through serialdata stream
749
c = is.read();
750                         if (c != '>') {
751                             err.log("Could not read up to end of serialdata tag "+source); // NOI18N
752
return null;
753                         }
754                         break PARSE;
755                     case '/':
756                         // </settings
757
// XXX do not read further is neader is set
758
if (!expect(is, MODULE_SETTINGS_END)) {
759                             err.log("Could not read up to end of settings tag "+source); // NOI18N
760
return null;
761                         }
762                         break PARSE;
763                     default:
764                         err.log("Strange stuff after <" + (char)c+" "+source); // NOI18N
765
return null;
766                 }
767             }
768             if (instanceClass != null && !iofs.isEmpty()) {
769                 return iofs;
770             }
771             return null;
772     }
773     
774     /** Read some stuff from a stream and skip over it.
775      * Newlines conventions and whitespaces are normalized to one space.
776      * @return true upon success, false if stream contained something else
777      */

778     private boolean expect(InputStream JavaDoc is, byte[] stuff) throws IOException JavaDoc {
779         int len = stuff.length;
780         boolean inWhitespace = false;
781         for (int i = 0; i < len; ) {
782             int c = is.read();
783             if (c == 10 || c == 13 || c == ' ' || c == '\t') {
784                 // Normalize: s/[\t \r\n]+/\n/g
785
if (inWhitespace) {
786                     continue;
787                 } else {
788                     inWhitespace = true;
789                     c = ' ';
790                 }
791             } else {
792                 inWhitespace = false;
793             }
794             if (c != stuff[i++]) {
795                 return false;
796             }
797         }
798         if (stuff[len - 1] == 10) {
799             // Expecting something ending in a \n - so we have to
800
// read any further \r or \n and discard.
801
if (!is.markSupported()) throw new IOException JavaDoc("Mark not supported"); // NOI18N
802
is.mark(1);
803             int c = is.read();
804             if (c != -1 && c != 10 && c != 13) {
805                 // Got some non-newline character, push it back!
806
is.reset();
807             }
808         }
809         return true;
810     }
811     /** Read a maximal string until delim is encountered (which will be removed from stream).
812      * This impl reads only ASCII, for speed.
813      * Newline conventions are normalized to Unix \n.
814      * @return the read string, or null if the delim is not encountered before EOF.
815      */

816     private String JavaDoc readTo(InputStream JavaDoc is, char delim) throws IOException JavaDoc {
817         if (delim == 10) {
818             // Not implemented - stream might have "foo\r\n" and we would
819
// return "foo" and leave "\n" in the stream.
820
throw new IOException JavaDoc("Not implemented"); // NOI18N
821
}
822         CharArrayWriter JavaDoc caw = new CharArrayWriter JavaDoc(100);
823         boolean inNewline = false;
824         while (true) {
825             int c = is.read();
826             if (c == -1) return null;
827             if (c > 126) return null;
828             if (c == 10 || c == 13) {
829                 // Normalize: s/[\r\n]+/\n/g
830
if (inNewline) {
831                     continue;
832                 } else {
833                     inNewline = true;
834                     c = 10;
835                 }
836             } else if (c < 32 && c != 9) {
837                 // Random control character!
838
return null;
839             } else {
840                 inNewline = false;
841             }
842             if (c == delim) {
843                 return caw.toString();
844             } else {
845                 caw.write(c);
846             }
847         }
848     }
849     
850     final static class StopSAXException extends SAXException JavaDoc {
851         public StopSAXException() {
852             super("Parser stopped"); // NOI18N
853
}
854     }
855
856 }
Popular Tags