1 19 20 package org.netbeans.modules.settings.convertors; 21 22 import java.io.*; 23 import java.lang.reflect.Method ; 24 import java.util.*; 25 import java.util.logging.Level ; 26 import java.util.logging.Logger ; 27 28 import org.openide.filesystems.*; 29 import org.openide.modules.ModuleInfo; 30 import org.openide.modules.SpecificationVersion; 31 import org.openide.util.Exceptions; 32 import org.openide.util.Lookup; 33 import org.openide.util.SharedClassObject; 34 35 import org.xml.sax.Attributes ; 36 import org.xml.sax.SAXException ; 37 import org.xml.sax.XMLReader ; 38 39 44 final class XMLSettingsSupport { 45 46 public static final String INSTANCE_DTD_ID = "-//NetBeans//DTD Session settings 1.0//EN"; public static final String INSTANCE_DTD_WWW = "http://www.netbeans.org/dtds/sessionsettings-1_0.dtd"; 49 public static final String XML_EXT = "settings"; public static final String LINE_SEPARATOR = System.getProperty("line.separator"); 51 52 53 static final Logger err = Logger.getLogger(XMLSettingsSupport.class.getName()); 55 59 private static void storeInstanceOf (Set<Class > classes, PrintWriter pw) throws IOException { 60 SortedSet<String > clazzNames = new TreeSet<String >(); for (Class clz: classes) { 62 clazzNames.add(clz.getName()); 63 } 64 StringBuilder sb = new StringBuilder (200); for (String s: clazzNames) { 66 sb.append(" <instanceof class=\""). append(s). 68 append("\"/>").append(LINE_SEPARATOR); } 70 pw.print(sb.toString()); 71 } 72 73 77 public static void storeToXML10 (Object inst, Writer os, ModuleInfo mi) 78 throws IOException { 79 PrintWriter pw = new PrintWriter (os); 80 81 pw.println ("<?xml version=\"1.0\"?>"); pw.println ("<!DOCTYPE settings PUBLIC \""+INSTANCE_DTD_ID+ "\" \""+INSTANCE_DTD_WWW+"\">"); pw.println ("<settings version=\"1.0\">"); storeModule(mi, pw); 86 storeInstanceOf(getSuperClasses(inst.getClass(), null), pw); 87 storeSerialData(inst, pw); 89 90 pw.println ("</settings>"); pw.flush (); 92 } 93 94 99 private static void storeToXML10 (Class clazz, Writer os, ModuleInfo mi) 100 throws IOException { 101 102 PrintWriter pw = new PrintWriter (os); 103 pw.println ("<?xml version=\"1.0\"?>"); pw.println ("<!DOCTYPE settings PUBLIC \""+INSTANCE_DTD_ID+ "\" \""+INSTANCE_DTD_WWW+"\">"); pw.println ("<settings version=\"1.0\">"); storeModule(mi, pw); 108 storeInstanceOf(getSuperClasses(clazz, null), pw); 109 pw.println (" <instance class=\""+clazz.getName()+"\"/>"); pw.println ("</settings>"); pw.flush (); 112 } 113 114 private static void storeModule(ModuleInfo mi, PrintWriter pw) 115 throws IOException { 116 if (mi == null) return; 117 118 String modulName = mi.getCodeName(); 119 SpecificationVersion spec = mi.getSpecificationVersion(); 120 StringBuffer sb = new StringBuffer (80); 121 sb.append(" <module"); if (modulName != null && modulName.length() != 0) { 123 sb.append(" name=\"").append(modulName).append('"'); } 125 if (spec != null) { 126 sb.append(" spec=\"").append(spec.toString()).append('"'); } 128 sb.append("/>"); pw.println(sb.toString()); 130 } 131 132 133 136 private static class SpecialObjectOutputStream extends org.openide.util.io.NbObjectOutputStream { 137 138 private boolean first; 139 140 public SpecialObjectOutputStream(OutputStream os) throws IOException { 141 super (os); 142 first = true; 143 } 144 145 148 public Object replaceObject (Object obj) throws IOException { 149 if (first) { 150 if (obj == null) 151 throw new NotSerializableException(); 153 first = false; 154 } 155 return super.replaceObject(obj); 156 } 157 158 159 } 160 161 163 private static class SpecialObjectInputStream extends java.io.ObjectInputStream { 164 165 public SpecialObjectInputStream(InputStream is) throws IOException { 166 super(is); 167 try { 168 enableResolveObject (true); 169 } catch (SecurityException ex) { 170 throw new IOException (ex.toString ()); 171 } 172 } 173 174 177 protected Class resolveClass(ObjectStreamClass v) throws IOException, ClassNotFoundException { 178 ClassLoader cl = getNBClassLoader(); 179 try { 180 return Class.forName(v.getName(), false, cl); 181 } catch (ClassNotFoundException cnfe) { 182 String msg = "Offending classloader: " + cl; Exceptions.attachMessage(cnfe, msg); 184 throw cnfe; 185 } 186 } 187 188 193 protected ObjectStreamClass readClassDescriptor() throws IOException, ClassNotFoundException { 194 ObjectStreamClass ose = super.readClassDescriptor(); 195 196 String name = ose.getName(); 197 String newN = org.openide.util.Utilities.translate(name); 198 199 if (name == newN) { 200 return ose; 202 } 203 204 ClassLoader cl = getNBClassLoader(); 205 try { 206 Class origCl = Class.forName(name, false, cl); 207 return ObjectStreamClass.lookup(origCl); 209 } catch (ClassNotFoundException ex) { 210 } 212 213 Class clazz = Class.forName(newN, false, cl); 214 ObjectStreamClass newOse = ObjectStreamClass.lookup(clazz); 215 216 if (newOse == null) { 219 throw new java.io.NotSerializableException (newN); 220 } 221 222 return newOse; 223 } 224 225 226 private static ClassLoader getNBClassLoader() { 227 ClassLoader c = (ClassLoader ) org.openide.util.Lookup.getDefault().lookup(ClassLoader .class); 228 return c != null ? c : ClassLoader.getSystemClassLoader(); 229 } 230 231 } 232 233 234 private final static char[] HEXDIGITS = {'0', '1', '2', '3', '4', '5', '6', '7', 236 '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 237 '0', '1', '2', '3', '4', '5', '6', '7'}; 238 239 private static final int INDENT = 8; 240 private static final int BLOCK = 100; 241 private static final int BUFFSIZE = INDENT + BLOCK; 242 private static void storeSerialData (Object inst, PrintWriter pw) throws IOException { 243 pw.println (" <serialdata class=\""+inst.getClass().getName()+"\">"); 245 ByteArrayOutputStream baos = new ByteArrayOutputStream (1024); 246 ObjectOutput oo = new SpecialObjectOutputStream (baos); 247 oo.writeObject (inst); 248 byte[] bdata = baos.toByteArray (); 249 250 char[] cdata = new char[BUFFSIZE]; 251 for (int i=0; i < INDENT; i++ ) cdata[i] = ' '; 252 253 int i = 0; int j; int blen = bdata.length; 256 257 while (i < blen) { 258 int mark = INDENT + Math.min( 2*(blen-i), BLOCK ); 259 for (j=INDENT; j < mark; j += 2) { 260 int b = ((int)bdata[i++]) + 256; 261 cdata[j] = HEXDIGITS[b >> 4]; 262 cdata[j+1] = HEXDIGITS[b & 15]; 263 } 264 pw.write(cdata, 0, j); 265 pw.println(); 266 } 267 pw.println (" </serialdata>"); pw.flush(); 269 } 270 271 272 private static Set<Class > getSuperClasses(Class clazz, Set<Class > classes) { 273 if (classes == null) { 274 classes = new HashSet<Class >(); 275 } 276 277 if (clazz == null || !classes.add(clazz)) { 278 return classes; 279 } 280 281 Class [] cs = clazz.getInterfaces(); 282 283 if (cs != null) { 287 for (int i = 0; i < cs.length; i++) { 288 getSuperClasses(cs[i], classes); 289 } 290 } else { 291 err.severe( 292 "Error: if you encounter this message, please attach " + "the class name to the issue http://www.netbeans.org/issues/show_bug.cgi?id=16257. " + "Class.getInterfaces() == null for the class: " + clazz); } 296 297 return getSuperClasses(clazz.getSuperclass(), classes); 298 } 299 300 301 private static Class getServiceTypeClass(Class type) { 302 if (!org.openide.ServiceType.class.isAssignableFrom(type)) 303 throw new IllegalArgumentException (); 304 while (type.getSuperclass () != org.openide.ServiceType.class) { 306 type = type.getSuperclass(); 307 } 308 return type; 309 } 310 311 312 final static class SettingsRecognizer extends org.xml.sax.helpers.DefaultHandler { 313 314 private static final String ELM_SETTING = "settings"; private static final String ATR_SETTING_VERSION = "version"; 317 private static final String ELM_MODULE = "module"; private static final String ATR_MODULE_NAME = "name"; private static final String ATR_MODULE_SPEC = "spec"; private static final String ATR_MODULE_IMPL = "impl"; 322 private static final String ELM_INSTANCE = "instance"; private static final String ATR_INSTANCE_CLASS = "class"; private static final String ATR_INSTANCE_METHOD = "method"; 326 private static final String ELM_INSTANCEOF = "instanceof"; private static final String ATR_INSTANCEOF_CLASS = "class"; 329 private static final String ELM_SERIALDATA = "serialdata"; private static final String ATR_SERIALDATA_CLASS = "class"; 332 334 private boolean header; 335 private Stack<String > stack; 336 337 private String version; 338 private String instanceClass; 339 private String instanceMethod; 340 private Set<String > instanceOf = new HashSet<String >(); 341 342 private byte[] serialdata; 343 private CharArrayWriter chaos = null; 344 345 private String codeName; 346 private String codeNameBase; 347 private int codeNameRelease; 348 private SpecificationVersion moduleSpec; 349 private String moduleImpl; 350 351 private final FileObject source; 352 353 357 public SettingsRecognizer (boolean header, FileObject source) { 358 this.header = header; 359 this.source = source; 360 } 361 362 public boolean isAllRead() { 363 return !header; 364 } 365 366 public void setAllRead(boolean all) { 367 if (!header) return; 368 header = all; 369 } 370 371 public String getSettingsVerison() { 372 return version; 373 } 374 375 public String getCodeName() { 376 return codeName; 377 } 378 379 public String getCodeNameBase() { 380 return codeNameBase; 381 } 382 383 public int getCodeNameRelease() { 384 return codeNameRelease; 385 } 386 387 public SpecificationVersion getSpecificationVersion() { 388 return moduleSpec; 389 } 390 391 public String getModuleImpl() { 392 return moduleImpl; 393 } 394 395 396 public Set<String > getInstanceOf() { 397 return instanceOf; 398 } 399 400 401 public String getMethodName() { 402 return instanceMethod; 403 } 404 405 406 private InputStream getSerializedInstance() { 407 if (serialdata == null) return null; 408 return new ByteArrayInputStream(serialdata); 409 } 410 411 public org.xml.sax.InputSource resolveEntity(String publicId, String systemId) 412 throws SAXException { 413 if (INSTANCE_DTD_ID.equals (publicId)) { 414 return new org.xml.sax.InputSource (new ByteArrayInputStream (new byte[0])); 415 } else { 416 return null; } 418 } 419 420 public void characters(char[] values, int start, int length) throws SAXException { 421 if (header) return; 422 String element = stack.peek(); 423 if (ELM_SERIALDATA.equals(element)) { 424 if (chaos == null) chaos = new CharArrayWriter(length); 426 chaos.write(values, start, length); 427 } 428 } 429 430 public void startElement(String uri, String localName, String qName, Attributes attribs) throws SAXException { 431 stack.push(qName); 432 if (ELM_SETTING.equals(qName)) { 433 version = attribs.getValue(ATR_SETTING_VERSION); 434 } else if (ELM_MODULE.equals(qName)) { 435 codeName = attribs.getValue(ATR_MODULE_NAME); 436 resolveModuleElm(codeName); 437 moduleImpl = attribs.getValue(ATR_MODULE_IMPL); 438 try { 439 String spec = attribs.getValue(ATR_MODULE_SPEC); 440 moduleSpec = spec == null ? null : new SpecificationVersion(spec); 441 } catch (NumberFormatException nfe) { 442 throw new SAXException (nfe); 443 } 444 } else if (ELM_INSTANCEOF.equals(qName)) { 445 instanceOf.add(org.openide.util.Utilities.translate( 446 attribs.getValue(ATR_INSTANCEOF_CLASS))); 447 } else if (ELM_INSTANCE.equals(qName)) { 448 instanceClass = attribs.getValue(ATR_INSTANCE_CLASS); 449 if (instanceClass == null) { 450 System.err.println("Hint: NPE is caused by broken settings file: " + source ); } 452 instanceClass = org.openide.util.Utilities.translate(instanceClass); 453 instanceMethod = attribs.getValue(ATR_INSTANCE_METHOD); 454 } else if (ELM_SERIALDATA.equals(qName)) { 455 instanceClass = attribs.getValue(ATR_SERIALDATA_CLASS); 456 instanceClass = org.openide.util.Utilities.translate(instanceClass); 457 if (header) throw new StopSAXException(); 458 } 459 } 460 461 462 private void resolveModuleElm (String codeName) { 463 if (codeName != null) { 464 int slash = codeName.indexOf ("/"); if (slash == -1) { 466 codeNameBase = codeName; 467 codeNameRelease = -1; 468 } else { 469 codeNameBase = codeName.substring (0, slash); 470 try { 471 codeNameRelease = Integer.parseInt(codeName.substring(slash + 1)); 472 } catch (NumberFormatException ex) { 473 Exceptions.attachLocalizedMessage(ex, 474 "Content: \n" + 475 getFileContent(source)); Exceptions.attachLocalizedMessage(ex, 477 "Source: " + source); Logger.getLogger(XMLSettingsSupport.class.getName()).log(Level.WARNING, null, ex); 479 codeNameRelease = -1; 480 } 481 } 482 } else { 483 codeNameBase = null; 484 codeNameRelease = -1; 485 } 486 } 487 488 public void endElement(String uri, String localName, String qName) throws SAXException { 489 String element = stack.pop(); 491 if (ELM_SERIALDATA.equals(element)) { 492 if (chaos != null) { 493 ByteArrayOutputStream baos = new ByteArrayOutputStream(chaos.size() >> 1); 494 try { 495 chars2Bytes(baos, chaos.toCharArray(), 0, chaos.size()); 496 serialdata = baos.toByteArray(); 497 } catch (IOException ex) { 498 Logger.getLogger(XMLSettingsSupport.class.getName()).log(Level.WARNING, null, ex); 499 } finally { 500 chaos = null; try { 502 baos.close(); 503 } catch (IOException ex) { 504 } 506 } 507 } 508 } 509 } 510 511 515 private Object readSerial(InputStream is) throws IOException, ClassNotFoundException { 516 if (is == null) return null; 517 try { 518 ObjectInput oi = new SpecialObjectInputStream (is); 519 try { 520 Object o = oi.readObject (); 521 return o; 522 } finally { 523 oi.close(); 524 } 525 } catch (IOException ex) { 526 Exceptions.attachLocalizedMessage(ex, 527 "Content: \n" + 528 getFileContent(source)); Exceptions.attachLocalizedMessage(ex, "Source: " + source); Exceptions.attachLocalizedMessage(ex, 531 "Cannot read class: " + 532 instanceClass); throw ex; 534 } catch (ClassNotFoundException ex) { 535 Exceptions.attachLocalizedMessage(ex, 536 "Content: \n" + 537 getFileContent(source)); Exceptions.attachLocalizedMessage(ex, "Source: " + source); throw ex; 540 } 541 } 542 543 548 public Object instanceCreate() throws java.io.IOException , ClassNotFoundException { 549 Object inst = null; 550 551 inst = readSerial(getSerializedInstance()); 553 554 if (inst == null) { 556 if (instanceMethod != null) { 557 inst = createFromMethod(instanceClass, instanceMethod); 558 } else { 559 Class <?> clazz = instanceClass(); 561 if (SharedClassObject.class.isAssignableFrom(clazz)) { 562 inst = SharedClassObject.findObject(clazz.asSubclass(SharedClassObject.class), false); 563 if (null != inst) { 564 try { 566 Method method = SharedClassObject.class.getDeclaredMethod("reset", new Class [0]); method.setAccessible(true); 568 method.invoke(inst, new Object [0]); 569 } catch (Exception e) { 570 Exceptions.printStackTrace(e); 571 } 572 } else { 573 inst = SharedClassObject.findObject(clazz.asSubclass(SharedClassObject.class), true); 574 } 575 } else { 576 try { 577 inst = clazz.newInstance(); 578 } catch (Exception ex) { 579 IOException ioe = new IOException(); 580 ioe.initCause(ex); 581 Exceptions.attachMessage(ioe, 582 "Content: \n" + 583 getFileContent(source)); Exceptions.attachMessage(ioe, 585 "Class: " + clazz); Exceptions.attachMessage(ioe, 587 "Source: " + 588 source); throw ioe; 590 } 591 } 592 } 593 } 594 595 return inst; 596 } 597 598 600 private static String getFileContent (FileObject fo) { 601 try { 602 InputStreamReader isr = new InputStreamReader(fo.getInputStream()); 603 char[] cbuf = new char[1024]; 604 int length; 605 StringBuffer sbuf = new StringBuffer (1024); 606 while (true) { 607 length = isr.read(cbuf); 608 if (length > 0) { 609 sbuf.append(cbuf, 0, length); 610 } else { 611 return sbuf.toString(); 612 } 613 } 614 } catch (Exception ex) { 615 StringWriter sw = new StringWriter(); 616 ex.printStackTrace(new PrintWriter(sw)); 617 return sw.toString(); 618 } 619 } 620 621 622 private Object createFromMethod(String srcClazz, String srcMethod) 623 throws ClassNotFoundException , IOException { 624 int dotIndex = instanceMethod.lastIndexOf('.'); 625 String targetClass; 626 String targetMethod; 627 if (dotIndex > 0) { 628 targetClass = srcMethod.substring(0, dotIndex); 629 targetMethod = srcMethod.substring(dotIndex + 1); 630 } else { 631 targetClass = srcClazz; 632 targetMethod = srcMethod; 633 } 634 635 Class <?> clazz = loadClass(targetClass); 636 637 try { 638 Object instance; 639 try { 640 Method method = clazz.getMethod(targetMethod, new Class []{FileObject.class}); 641 method.setAccessible(true); 642 instance = method.invoke(null, source); 643 } catch (NoSuchMethodException ex) { 644 Method method = clazz.getMethod(targetMethod); 645 method.setAccessible(true); 646 instance = method.invoke(null, new Object [0]); 647 } 648 if (instance == null) { 649 throw new IOException("Null return not permitted from " + targetClass + "." + targetMethod); } 652 return instance; 653 } catch (Exception ex) { 654 IOException ioe = new IOException("Error reading " + source + 655 ": " + ex); 656 657 ioe.initCause(ex); 658 Exceptions.attachMessage(ioe, 659 "Content:\n" + getFileContent(source)); 660 Exceptions.attachMessage(ioe, "Method: " + srcMethod); 661 Exceptions.attachMessage(ioe, "Class: " + clazz); 662 throw ioe; 663 } 664 } 665 666 674 public Class instanceClass() throws java.io.IOException , ClassNotFoundException { 675 if (instanceClass == null) { 676 throw new ClassNotFoundException (source + 677 ": missing 'class' attribute in 'instance' element"); } 679 680 return loadClass(instanceClass); 681 } 682 683 684 private Class <?> loadClass(String clazz) throws ClassNotFoundException { 685 return Lookup.getDefault().lookup(ClassLoader .class).loadClass(clazz); 686 } 687 688 689 public String instanceName() { 690 if (instanceClass == null) { 691 return ""; } else { 693 return instanceClass; 694 } 695 } 696 697 private int tr(char c) { 698 if (c >= '0' && c <= '9') return c - '0'; 699 if (c >= 'A' && c <= 'F') return c - 'A' + 10; 700 if (c >= 'a' && c <= 'f') return c - 'a' + 10; 701 return -1; 702 } 703 704 707 private void chars2Bytes (OutputStream os, char[] chars, int off, int length) 708 throws IOException { 709 byte rbyte; 710 int read; 711 712 for (int i = off; i < length; ) { 713 read = tr(chars[i++]); 714 if (read >= 0) rbyte = (byte) (read << 4); else continue; 716 717 while (i < length) { 718 read = tr(chars[i++]); 719 if (read >= 0) { 720 rbyte += (byte) read; 721 os.write(rbyte); 722 break; 723 } 724 } 725 } 726 } 727 728 729 public void parse() throws IOException { 730 InputStream in = null; 731 732 try { 733 if (header) { 734 if (err.isLoggable(Level.FINE) && source.getSize () < 12000) { 735 byte[] arr = new byte[(int)source.getSize ()]; 737 InputStream temp = source.getInputStream (); 738 int len = temp.read (arr); 739 if (len != arr.length) { 740 throw new IOException ("Could not read " + arr.length + " bytes from " + source + " just " + len); } 742 743 err.finer("Parsing:" + new String (arr)); 744 745 temp.close (); 746 747 in = new ByteArrayInputStream (arr); 748 } else { 749 in = source.getInputStream (); 750 } 751 Set<String > iofs = quickParse(new BufferedInputStream(in)); 752 if (iofs != null) { 753 instanceOf = iofs; 754 return; 755 } 756 } 757 } catch (IOException ioe) { 758 } finally { 760 if (in != null) in.close(); 761 } 762 stack = new Stack<String >(); 763 try { 764 in = source.getInputStream(); 765 XMLReader reader = org.openide.xml.XMLUtil.createXMLReader(); 766 reader.setContentHandler(this); 767 reader.setErrorHandler(this); 768 reader.setEntityResolver(this); 769 reader.parse(new org.xml.sax.InputSource (new BufferedInputStream(in))); 770 } catch (XMLSettingsSupport.StopSAXException ex) { 771 } catch (SAXException ex) { 773 IOException ioe = new IOException(source.toString()); ioe.initCause(ex); 775 Exceptions.attachMessage(ioe, 776 "Content: \n" + 777 getFileContent(source)); Exceptions.attachMessage(ioe, "Source: " + source); throw ioe; 780 } finally { 781 stack = null; 782 try { 783 if (in != null) { 784 in.close(); 785 } 786 } catch (IOException ex) { 787 } 789 } 790 } 791 792 793 public void parse(Reader source) throws IOException { 794 stack = new Stack<String >(); 795 796 try { 797 XMLReader reader = org.openide.xml.XMLUtil.createXMLReader(); 798 reader.setContentHandler(this); 799 reader.setErrorHandler(this); 800 reader.setEntityResolver(this); 801 reader.parse(new org.xml.sax.InputSource (source)); 802 } catch (XMLSettingsSupport.StopSAXException ex) { 803 } catch (SAXException ex) { 805 IOException ioe = new IOException(source.toString()); ioe.initCause(ex); 807 throw ioe; 808 } finally { 809 stack = null; 810 } 811 } 812 813 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(); private static final byte[] MODULE_SETTINGS_INTRO_END = "> <".getBytes(); private static final byte[] MODULE_SETTINGS_MODULE_NAME = "odule name=\"".getBytes(); private static final byte[] MODULE_SETTINGS_MODULE_SPEC = "spec=\"".getBytes(); private static final byte[] MODULE_SETTINGS_MODULE_IMPL = "impl=\"".getBytes(); private static final byte[] MODULE_SETTINGS_TAG_END = "> <".getBytes(); private static final byte[] MODULE_SETTINGS_INSTANCE = "nstance".getBytes(); private static final byte[] MODULE_SETTINGS_INSTANCE_CLZ = "class=\"".getBytes(); private static final byte[] MODULE_SETTINGS_INSTANCE_MTD = "method=\"".getBytes(); private static final byte[] MODULE_SETTINGS_OF = "f class=\"".getBytes(); private static final byte[] MODULE_SETTINGS_SERIAL = "erialdata class=\"".getBytes(); private static final byte[] MODULE_SETTINGS_END = "settings>".getBytes(); 828 833 private Set<String > quickParse(InputStream is) throws IOException { 834 Set<String > iofs = new HashSet<String >(); 835 836 if (!expect(is, MODULE_SETTINGS_INTRO)) { 837 err.fine("Could not read intro "+source); return null; 839 } 840 version = readTo(is, '"'); 841 if (version == null) { 842 err.fine("Could not read version "+source); return null; 844 } 845 if (!expect(is, MODULE_SETTINGS_INTRO_END)) { 846 err.fine("Could not read stuff after cnb "+source); return null; 848 } 849 int c; 851 PARSE: 852 while (true) { 853 c = is.read(); 854 switch (c) { 855 case 'm': 856 if (!expect(is, MODULE_SETTINGS_MODULE_NAME)) { 858 err.fine("Could not read up to <module name=\" "+source); return null; 860 } 861 String codeName = readTo(is, '"'); 862 if (codeName == null) { 863 err.fine("Could not read module name value "+source); return null; 865 } 866 codeName = codeName.intern(); 867 resolveModuleElm(codeName); 868 c = is.read(); 869 if (c == '/') { 870 if (!expect(is, MODULE_SETTINGS_TAG_END)) { 871 err.fine("Could not read up to end of module tag "+source); return null; 873 } 874 break; 875 } 876 else if (c != ' ') { 877 err.fine("Could not space after module name "+source); return null; 879 } 880 if (!expect(is, MODULE_SETTINGS_MODULE_SPEC)) { 882 err.fine("Could not read up to spec=\" "+source); return null; 884 } 885 String mspec = readTo(is, '"'); 886 if (mspec == null) { 887 err.fine("Could not read module spec value "+source); return null; 889 } 890 try { 891 moduleSpec = new SpecificationVersion(mspec); 892 } catch (NumberFormatException nfe) { 893 return null; 894 } 895 c = is.read(); 896 if (c == '/') { 897 if (!expect(is, MODULE_SETTINGS_TAG_END)) { 898 err.fine("Could not read up to end of <module name spec/> tag "+source); return null; 900 } 901 break; 902 } 903 else if (c != ' ') { 904 err.fine("Could not read space after module name "+source); return null; 906 } 907 if (!expect(is, MODULE_SETTINGS_MODULE_IMPL)) { 909 err.fine("Could not read up to impl=\" "+source); return null; 911 } 912 moduleImpl = readTo(is, '"'); 913 if (moduleImpl == null) { 914 err.fine("Could not read module impl value "+source); return null; 916 } 917 moduleImpl = moduleImpl.intern(); 918 if (!expect(is, MODULE_SETTINGS_TAG_END)) { 920 err.fine("Could not read up to /> < "+source); return null; 922 } 923 break; 924 case 'i': 925 if (!expect(is, MODULE_SETTINGS_INSTANCE)) { 927 err.fine("Could not read up to instance "+source); return null; 929 } 930 c = is.read(); 932 if (c == 'o') { 933 if (!expect(is, MODULE_SETTINGS_OF)) { 934 err.fine("Could not read up to instance"); return null; 936 } 937 String iof = readTo(is, '"'); 938 if (iof == null) { 939 err.fine("Could not read instanceof value "+source); return null; 941 } 942 iof = org.openide.util.Utilities.translate(iof).intern(); 943 iofs.add (iof); 944 if (is.read() != '/') { 945 err.fine("No / at end of <instanceof> " + iof+" "+source); return null; 947 } 948 if (!expect(is, MODULE_SETTINGS_TAG_END)) { 949 err.fine("Could not read up to next tag after <instanceof> " + iof+" "+source); return null; 951 } 952 } 953 else if (c == ' ') { 954 if (!expect(is, MODULE_SETTINGS_INSTANCE_CLZ)) { 956 err.fine("Could not read up to class=\" "+source); return null; 958 } 959 instanceClass = readTo(is, '"'); 960 if (instanceClass == null) { 961 err.fine("Could not read instance class value "+source); return null; 963 } 964 instanceClass = org.openide.util.Utilities.translate(instanceClass).intern(); 965 c = is.read(); 966 if (c == '/') { 967 if (!expect(is, MODULE_SETTINGS_TAG_END)) { 968 err.fine("Could not read up to end of instance tag "+source); return null; 970 } 971 break; 972 } 973 else if (c != ' ') { 974 err.fine("Could not space after instance class "+source); return null; 976 } 977 if (!expect(is, MODULE_SETTINGS_INSTANCE_MTD)) { 979 err.fine("Could not read up to method=\" "+source); return null; 981 } 982 instanceMethod = readTo(is, '"'); 983 if (instanceMethod == null) { 984 err.fine("Could not read method value "+source); return null; 986 } 987 instanceMethod = instanceMethod.intern(); 988 c = is.read(); 989 if (c == '/') { 990 if (!expect(is, MODULE_SETTINGS_TAG_END)) { 991 err.fine("Could not read up to end of instance tag "+source); return null; 993 } 994 break; 995 } 996 err.fine("Strange stuff after method attribute "+source); return null; 998 } 999 else { 1000 err.fine("Could not read after to instance "+source); return null; 1002 } 1003 break; 1004 case 's': 1005 if (!expect(is, MODULE_SETTINGS_SERIAL)) { 1007 err.fine("Could not read up to <serialdata class=\" "+source); return null; 1009 } 1010 instanceClass = readTo(is, '"'); 1011 if (instanceClass == null) { 1012 err.fine("Could not read serialdata class value "+source); return null; 1014 } 1015 instanceClass = org.openide.util.Utilities.translate(instanceClass).intern(); 1016 c = is.read(); 1018 if (c != '>') { 1019 err.fine("Could not read up to end of serialdata tag "+source); return null; 1021 } 1022 break PARSE; 1023 case '/': 1024 if (!expect(is, MODULE_SETTINGS_END)) { 1027 err.fine("Could not read up to end of settings tag "+source); return null; 1029 } 1030 break PARSE; 1031 default: 1032 err.fine("Strange stuff after <" + (char)c+" "+source); return null; 1034 } 1035 } 1036 if (instanceClass != null && !iofs.isEmpty()) { 1037 return iofs; 1038 } 1039 return null; 1040 } 1041 1042 1046 private boolean expect(InputStream is, byte[] stuff) throws IOException { 1047 int len = stuff.length; 1048 boolean inWhitespace = false; 1049 for (int i = 0; i < len; ) { 1050 int c = is.read(); 1051 if (c == 10 || c == 13 || c == ' ' || c == '\t') { 1052 if (inWhitespace) { 1054 continue; 1055 } else { 1056 inWhitespace = true; 1057 c = ' '; 1058 } 1059 } else { 1060 inWhitespace = false; 1061 } 1062 if (c != stuff[i++]) { 1063 return false; 1064 } 1065 } 1066 if (stuff[len - 1] == 10) { 1067 if (!is.markSupported()) throw new IOException("Mark not supported"); is.mark(1); 1071 int c = is.read(); 1072 if (c != -1 && c != 10 && c != 13) { 1073 is.reset(); 1075 } 1076 } 1077 return true; 1078 } 1079 1084 private String readTo(InputStream is, char delim) throws IOException { 1085 if (delim == 10) { 1086 throw new IOException("Not implemented"); } 1090 CharArrayWriter caw = new CharArrayWriter(100); 1091 boolean inNewline = false; 1092 while (true) { 1093 int c = is.read(); 1094 if (c == -1) return null; 1095 if (c > 126) return null; 1096 if (c == 10 || c == 13) { 1097 if (inNewline) { 1099 continue; 1100 } else { 1101 inNewline = true; 1102 c = 10; 1103 } 1104 } else if (c < 32 && c != 9) { 1105 return null; 1107 } else { 1108 inNewline = false; 1109 } 1110 if (c == delim) { 1111 return caw.toString(); 1112 } else { 1113 caw.write(c); 1114 } 1115 } 1116 } 1117 1118 } 1119 1120 final static class StopSAXException extends SAXException { 1121 public StopSAXException() { 1122 super("Parser stopped"); } 1124 } 1125 1126 public static final class Convertor extends org.netbeans.spi.settings.Convertor { 1127 1128 public Object read(java.io.Reader r) throws java.io.IOException , ClassNotFoundException { 1129 XMLSettingsSupport.SettingsRecognizer rec = new XMLSettingsSupport.SettingsRecognizer(false, null); 1132 rec.parse(r); 1133 return rec.instanceCreate(); 1134 } 1135 1136 public void registerSaver(Object inst, org.netbeans.spi.settings.Saver s) { 1137 } 1138 1139 public void unregisterSaver(Object inst, org.netbeans.spi.settings.Saver s) { 1140 } 1141 1142 public void write(java.io.Writer w, Object inst) throws java.io.IOException { 1143 XMLSettingsSupport.storeToXML10(inst, w, ModuleInfoManager.getDefault().getModuleInfo(inst.getClass())); 1144 } 1145 1146 } 1147} 1148 | Popular Tags |