1 16 17 18 package org.apache.xmlrpc; 19 20 import java.io.InputStream ; 21 import java.io.InputStreamReader ; 22 import java.util.Hashtable ; 23 import java.util.Stack ; 24 import java.util.Vector ; 25 import org.xml.sax.AttributeList ; 26 import org.xml.sax.HandlerBase ; 27 import org.xml.sax.InputSource ; 28 import org.xml.sax.Parser ; 29 import org.xml.sax.SAXException ; 30 import org.xml.sax.SAXParseException ; 31 import uk.co.wilson.xml.MinML; 32 33 50 public abstract class XmlRpc extends HandlerBase 51 { 52 55 public static final String version = "Apache XML-RPC 2.0"; 59 60 63 private static final String DEFAULT_PARSER = MinML.class.getName(); 64 65 68 private static int maxThreads = 100; 69 70 String methodName; 71 72 75 private static Class parserClass; 76 private static Hashtable saxDrivers = new Hashtable (8); 77 78 static 79 { 80 saxDrivers.put("xerces", "org.apache.xerces.parsers.SAXParser"); 85 saxDrivers.put("xp", "com.jclark.xml.sax.Driver"); 86 saxDrivers.put("ibm1", "com.ibm.xml.parser.SAXDriver"); 87 saxDrivers.put("ibm2", "com.ibm.xml.parsers.SAXParser"); 88 saxDrivers.put("aelfred", "com.microstar.xml.SAXDriver"); 89 saxDrivers.put("oracle1", "oracle.xml.parser.XMLParser"); 90 saxDrivers.put("oracle2", "oracle.xml.parser.v2.SAXParser"); 91 saxDrivers.put("openxml", "org.openxml.parser.XMLSAXParser"); 92 } 93 94 Stack values; 96 Value currentValue; 97 98 102 StringBuffer cdata; 103 boolean readCdata; 104 105 static final int STRING = 0; 107 static final int INTEGER = 1; 108 static final int BOOLEAN = 2; 109 static final int DOUBLE = 3; 110 static final int DATE = 4; 111 static final int BASE64 = 5; 112 static final int STRUCT = 6; 113 static final int ARRAY = 7; 114 115 int errorLevel; 117 String errorMsg; 118 119 static final int NONE = 0; 120 static final int RECOVERABLE = 1; 121 static final int FATAL = 2; 122 123 126 static boolean keepalive = false; 127 128 131 public static boolean debug = false; 132 133 136 final static String types[] = 137 { 138 "String", 139 "Integer", 140 "Boolean", 141 "Double", 142 "Date", 143 "Base64", 144 "Struct", 145 "Array" 146 }; 147 148 153 static String encoding = XmlWriter.UTF8; 154 155 162 static String defaultInputEncoding = null; 163 164 private TypeFactory typeFactory; 165 private String inputEncoding; 166 167 174 protected XmlRpc() 175 { 176 String typeFactoryName = null; 177 try 178 { 179 typeFactoryName = System.getProperty(TypeFactory.class.getName()); 180 } 181 catch (SecurityException e) 182 { 183 if (debug) 186 { 187 System.out.println("Unable to determine the value of the " + 188 "system property '" + 189 TypeFactory.class.getName() + "': " + 190 e.getMessage()); 191 } 192 } 193 this.typeFactory = createTypeFactory(typeFactoryName); 194 this.inputEncoding = defaultInputEncoding; 195 } 196 197 204 protected XmlRpc(String typeFactoryName) 205 { 206 this.typeFactory = createTypeFactory(typeFactoryName); 207 } 208 209 217 private TypeFactory createTypeFactory(String className) 218 { 219 Class c = null; 220 if (className != null && className.length() > 0) 221 { 222 try 223 { 224 c = Class.forName(className); 225 } 226 catch (ClassNotFoundException e) 227 { 228 System.err.println("Error loading TypeFactory '" + 229 "' " + c.getName() + 230 "': Using the default instead: " + 231 e.getMessage()); 232 } 233 } 234 235 if (c == null || DefaultTypeFactory.class.equals(c)) 237 { 238 return new DefaultTypeFactory(); 239 } 240 241 try 242 { 243 return (TypeFactory) c.newInstance(); 244 } 245 catch (Exception e) 246 { 247 System.err.println("Unable to create configured TypeFactory '" + 248 c.getName() + "': " + e.getMessage() + 249 ": Falling back to default"); 250 if (debug) 251 { 252 e.printStackTrace(); 253 } 254 return new DefaultTypeFactory(); 255 } 256 } 257 258 269 public static void setDriver(String driver) throws ClassNotFoundException 270 { 271 String parserClassName = null; 272 try 273 { 274 parserClassName = (String ) saxDrivers.get(driver); 275 if (parserClassName == null) 276 { 277 parserClassName = driver; 280 } 281 parserClass = Class.forName(parserClassName); 282 } 283 catch (ClassNotFoundException x) 284 { 285 throw new ClassNotFoundException ("SAX driver not found: " 286 + parserClassName); 287 } 288 } 289 290 293 public static void setDriver(Class driver) 294 { 295 parserClass = driver; 296 } 297 298 303 public static void setEncoding(String enc) 304 { 305 encoding = enc; 306 } 307 308 314 public String getEncoding() 315 { 316 return XmlWriter.canonicalizeEncoding(encoding); 317 } 318 319 325 public static void setDefaultInputEncoding(String enc) 326 { 327 defaultInputEncoding = enc; 328 } 329 330 337 public static String getDefaultInputEncoding() 338 { 339 return defaultInputEncoding; 340 } 341 342 349 public void setInputEncoding(String enc) 350 { 351 inputEncoding = enc; 352 } 353 354 360 public String getInputEncoding() 361 { 362 return inputEncoding; 363 } 364 365 368 public static int getMaxThreads() 369 { 370 return maxThreads; 371 } 372 373 376 public static void setMaxThreads(int maxThreads) 377 { 378 XmlRpc.maxThreads = maxThreads; 379 } 380 381 384 public static void setDebug(boolean val) 385 { 386 debug = val; 387 } 388 389 392 public static void setKeepAlive(boolean val) 393 { 394 keepalive = val; 395 } 396 397 400 public static boolean getKeepAlive() 401 { 402 return keepalive; 403 } 404 405 409 synchronized void parse(InputStream is) throws Exception 410 { 411 errorLevel = NONE; 413 errorMsg = null; 414 values = new Stack (); 415 if (cdata == null) 416 { 417 cdata = new StringBuffer (128); 418 } 419 else 420 { 421 cdata.setLength(0); 422 } 423 readCdata = false; 424 currentValue = null; 425 426 long now = System.currentTimeMillis(); 427 if (parserClass == null) 428 { 429 String driver; 431 try 432 { 433 driver = System.getProperty("sax.driver", DEFAULT_PARSER); 434 } 435 catch (SecurityException e) 436 { 437 driver = DEFAULT_PARSER; 439 } 440 setDriver(driver); 441 } 442 443 Parser parser = null; 444 try 445 { 446 parser = (Parser ) parserClass.newInstance(); 447 } 448 catch (NoSuchMethodError nsm) 449 { 450 throw new Exception ("Can't create Parser: " + parserClass); 453 } 454 455 parser.setDocumentHandler(this); 456 parser.setErrorHandler(this); 457 458 if (debug) 459 { 460 System.out.println("Beginning parsing XML input stream"); 461 } 462 try 463 { 464 if(inputEncoding == null) 465 { 466 parser.parse(new InputSource (is)); 467 } 468 else 469 { 470 parser.parse( new InputSource ( new InputStreamReader (is, inputEncoding))); 471 } 472 } 473 finally 474 { 475 if (cdata.length() > 128 * 4) 477 { 478 cdata = null; 481 } 482 } 483 if (debug) 484 { 485 System.out.println ("Spent " + (System.currentTimeMillis() - now) 486 + " millis parsing"); 487 } 488 } 489 490 495 protected abstract void objectParsed(Object what); 496 497 498 501 504 public void characters(char ch[], int start, int length) 505 throws SAXException 506 { 507 if (readCdata) 508 { 509 cdata.append(ch, start, length); 510 } 511 } 512 513 516 public void endElement(String name) throws SAXException 517 { 518 519 if (debug) 520 { 521 System.out.println("endElement: " + name); 522 } 523 524 if (currentValue != null && readCdata) 526 { 527 currentValue.characterData(cdata.toString()); 528 cdata.setLength(0); 529 readCdata = false; 530 } 531 532 if ("value".equals(name)) 533 { 534 int depth = values.size(); 538 if (depth < 2 || values.elementAt(depth - 2).hashCode() != STRUCT) 539 { 540 Value v = currentValue; 541 values.pop(); 542 if (depth < 2) 543 { 544 objectParsed(v.value); 546 currentValue = null; 547 } 548 else 549 { 550 currentValue = (Value) values.peek(); 553 currentValue.endElement(v); 554 } 555 } 556 } 557 558 if ("member".equals(name)) 560 { 561 Value v = currentValue; 562 values.pop(); 563 currentValue = (Value) values.peek(); 564 currentValue.endElement(v); 565 } 566 567 else if ("methodName".equals(name)) 568 { 569 methodName = cdata.toString(); 570 cdata.setLength(0); 571 readCdata = false; 572 } 573 } 574 575 578 public void startElement(String name, AttributeList atts) 579 throws SAXException 580 { 581 if (debug) 582 { 583 System.out.println("startElement: " + name); 584 } 585 586 if ("value".equals(name)) 587 { 588 Value v = new Value(); 589 values.push(v); 590 currentValue = v; 591 cdata.setLength(0); 593 readCdata = true; 594 } 595 else if ("methodName".equals(name)) 596 { 597 cdata.setLength(0); 598 readCdata = true; 599 } 600 else if ("name".equals(name)) 601 { 602 cdata.setLength(0); 603 readCdata = true; 604 } 605 else if ("string".equals(name)) 606 { 607 cdata.setLength(0); 609 readCdata = true; 610 } 611 else if ("i4".equals(name) || "int".equals(name)) 612 { 613 currentValue.setType(INTEGER); 614 cdata.setLength(0); 615 readCdata = true; 616 } 617 else if ("boolean".equals(name)) 618 { 619 currentValue.setType(BOOLEAN); 620 cdata.setLength(0); 621 readCdata = true; 622 } 623 else if ("double".equals(name)) 624 { 625 currentValue.setType(DOUBLE); 626 cdata.setLength(0); 627 readCdata = true; 628 } 629 else if ("dateTime.iso8601".equals(name)) 630 { 631 currentValue.setType(DATE); 632 cdata.setLength(0); 633 readCdata = true; 634 } 635 else if ("base64".equals(name)) 636 { 637 currentValue.setType(BASE64); 638 cdata.setLength(0); 639 readCdata = true; 640 } 641 else if ("struct".equals(name)) 642 { 643 currentValue.setType(STRUCT); 644 } 645 else if ("array".equals(name)) 646 { 647 currentValue.setType(ARRAY); 648 } 649 } 650 651 656 public void error(SAXParseException e) throws SAXException 657 { 658 System.err.println("Error parsing XML: " + e); 659 errorLevel = RECOVERABLE; 660 errorMsg = e.toString(); 661 } 662 663 668 public void fatalError(SAXParseException e) throws SAXException 669 { 670 System.err.println("Fatal error parsing XML: " + e); 671 errorLevel = FATAL; 672 errorMsg = e.toString(); 673 } 674 675 678 class Value 679 { 680 int type; 681 Object value; 682 String nextMemberName; 684 685 Hashtable struct; 686 Vector array; 687 688 691 public Value() 692 { 693 this.type = STRING; 694 } 695 696 699 public void endElement(Value child) 700 { 701 switch (type) 702 { 703 case ARRAY: 704 array.addElement(child.value); 705 break; 706 case STRUCT: 707 struct.put(nextMemberName, child.value); 708 } 709 } 710 711 715 public void setType(int type) 716 { 717 this.type = type; 719 switch (type) 720 { 721 case ARRAY: 722 value = array = new Vector (); 723 break; 724 case STRUCT: 725 value = struct = new Hashtable (); 726 break; 727 } 728 } 729 730 734 public void characterData(String cdata) 735 { 736 switch (type) 737 { 738 case INTEGER: 739 value = typeFactory.createInteger(cdata); 740 break; 741 case BOOLEAN: 742 value = typeFactory.createBoolean(cdata); 743 break; 744 case DOUBLE: 745 value = typeFactory.createDouble(cdata); 746 break; 747 case DATE: 748 value = typeFactory.createDate(cdata); 749 break; 750 case BASE64: 751 value = typeFactory.createBase64(cdata); 752 break; 753 case STRING: 754 value = typeFactory.createString(cdata); 755 break; 756 case STRUCT: 757 nextMemberName = cdata; 759 break; 760 } 761 } 762 763 769 public int hashCode() 770 { 771 return type; 772 } 773 774 778 public String toString() 779 { 780 return (types[type] + " element " + value); 781 } 782 } 783 } 784 | Popular Tags |