1 9 package javolution.xml; 10 11 import java.io.IOException ; 12 import javolution.Javolution; 13 import javolution.JavolutionError; 14 import javolution.lang.ClassInitializer; 15 import javolution.lang.Reflection; 16 import javolution.lang.Reusable; 17 import javolution.text.Appendable; 18 import javolution.text.CharArray; 19 import javolution.text.Text; 20 import javolution.util.FastMap; 21 import javolution.util.FastMap.Entry; 22 import javolution.xml.stream.XMLStreamException; 23 import javolution.xml.stream.XMLStreamReaderImpl; 24 import javolution.xml.stream.XMLStreamWriterImpl; 25 import j2me.lang.CharSequence; 26 import j2me.util.Collection; 27 import j2me.util.Iterator; 28 import j2me.util.Map; 29 30 120 public class XMLBinding implements Reusable { 121 122 125 private static FastMap STATIC_MAPPING = new FastMap().setShared(true); 126 127 130 static final XMLBinding DEFAULT = new XMLBinding(); 131 132 136 protected static XMLFormat XML = new XMLFormat() { 137 138 public void read(InputElement xml, Object obj) 139 throws XMLStreamException { 140 XMLBinding binding = (XMLBinding) obj; 141 binding._classAttributeName = xml.getAttribute( 142 "classAttributeName", (String ) null); 143 binding._classAttributeURI = xml.getAttribute("classAttributeURI", 144 (String ) null); 145 FastMap fm = binding._aliasToClass = (FastMap) xml.get( 146 "AliasToClass", FastMap.class); 147 for (Entry e = fm.head(), t = fm.tail(); (e = (Entry) e.getNext()) != t;) { 149 binding._classToAlias.put(e.getValue(), e.getKey()); 150 } 151 } 152 153 public void write(Object obj, OutputElement xml) 154 throws XMLStreamException { 155 XMLBinding binding = (XMLBinding) obj; 156 xml.setAttribute("classAttributeName", binding._classAttributeName); 157 xml.setAttribute("classAttributeURI", binding._classAttributeURI); 158 xml.add(binding._aliasToClass, "AliasToClass", FastMap.class); 159 } 160 }; 161 162 165 private String _classAttributeName = "class"; 166 167 170 private String _classAttributeURI = null; 171 172 175 private FastMap _classToAlias = new FastMap(); 176 177 180 private FastMap _aliasToClass = new FastMap(); 181 182 185 public XMLBinding() { 186 } 187 188 195 public void setAlias(Class cls, String alias) { 196 Class prevForAlias = (Class ) _aliasToClass.put(alias, cls); 197 if (prevForAlias != null) { 199 _classToAlias.put(prevForAlias, null); 200 } 201 _classToAlias.put(cls, alias); 202 } 203 204 212 public void setClassAttribute(String name) { 213 _classAttributeName = name; 214 _classAttributeURI = null; 215 } 216 217 227 public void setClassAttribute(String localName, String uri) { 228 _classAttributeName = localName; 229 _classAttributeURI = uri; 230 } 231 232 240 publicXMLFormatgetFormat(Class cls) { 241 Object xmlFormat = STATIC_MAPPING.get(cls); 242 return (xmlFormat != null) ? (XMLFormat) xmlFormat : searchFormat(cls); 243 } 244 245 private XMLFormat searchFormat(Class cls) { 246 ClassInitializer.initialize(cls); 248 249 XMLFormat bestMatchFormat = null; 251 for (int i = 0, j = XMLFormat._ClassInstancesLength; i < j; i++) { 252 XMLFormat xmlFormat = XMLFormat._ClassInstances[i]; 253 if (xmlFormat._class.isAssignableFrom(cls)) { if ((bestMatchFormat == null) 255 || (bestMatchFormat._class 256 .isAssignableFrom(xmlFormat._class))) { 257 bestMatchFormat = xmlFormat; 258 } 259 } 260 } 261 if (bestMatchFormat == null) 262 throw new JavolutionError("Cannot find format for " + cls); 263 264 STATIC_MAPPING.put(cls, bestMatchFormat); 265 return bestMatchFormat; 266 } 267 268 277 protected String getName(Class cls) { 278 String alias = (String ) _classToAlias.get(cls); 279 return (alias != null) ? alias : cls.getName(); 280 } 281 282 292 protected Class getClass(CharArray name) throws ClassNotFoundException { 293 Class cls = (Class ) _aliasToClass.get(name); 294 return (cls != null) ? cls : Reflection.getClass(name); 295 } 296 297 305 protected String getLocalName(Class cls) { 306 return this.getName(cls); 307 } 308 309 317 protected String getURI(Class cls) { 318 return null; 319 } 320 321 331 protected Class getClass(CharArray localName, CharArray uri) 332 throws ClassNotFoundException { 333 return getClass(localName); 334 } 335 336 public void reset() { 338 _aliasToClass.reset(); 339 _classToAlias.reset(); 340 } 341 342 349 final Class readClassAttribute(XMLStreamReaderImpl reader) 350 throws XMLStreamException { 351 if (_classAttributeName == null) 352 throw new XMLStreamException( 353 "Binding has no class attribute defined, cannot retrieve class"); 354 CharArray className = reader.getAttributeValue( 355 toCsq(_classAttributeURI), toCsq(_classAttributeName)); 356 if (className == null) 357 throw new XMLStreamException( 358 "Cannot retrieve class (class attribute not found)"); 359 try { 360 return getClass(className); 361 } catch (ClassNotFoundException e) { 362 throw new XMLStreamException(e); 363 } 364 } 365 366 373 final void writeClassAttribute(XMLStreamWriterImpl writer, Class cls) 374 throws XMLStreamException { 375 376 if (_classAttributeName != null) { 377 String value = getName(cls); 378 if (_classAttributeURI == null) { 379 writer.writeAttribute(toCsq(_classAttributeName), toCsq(value)); 380 } else { 381 writer.writeAttribute(toCsq(_classAttributeURI), 382 toCsq(_classAttributeName), toCsq(value)); 383 } 384 } 385 } 386 387 392 static final XMLFormatOBJECT_XML = new XMLFormat(new Object () 393 .getClass()) { 394 395 public void read(javolution.xml.XMLFormat.InputElement xml, Object obj) { 396 } 398 399 public void write(Object obj, javolution.xml.XMLFormat.OutputElement xml) { 400 } 402 }; 403 404 409 static final XMLFormatCLASS_XML = new XMLFormat("".getClass() 410 .getClass()) { 411 412 public boolean isReferenceable() { 413 return false; } 415 416 public Object newInstance(Class cls, 417 javolution.xml.XMLFormat.InputElement xml) 418 throws XMLStreamException { 419 CharArray name = xml.getAttribute("name"); 420 if (name == null) 421 throw new XMLStreamException("Attribute 'name' missing"); 422 Class clazz; 423 try { 424 clazz = Reflection.getClass(name); 425 } catch (ClassNotFoundException e) { 426 throw new XMLStreamException(e); 427 } 428 return clazz; 429 } 430 431 public void read(javolution.xml.XMLFormat.InputElement xml, Object obj) 432 throws XMLStreamException { 433 } 435 436 public void write(Object obj, javolution.xml.XMLFormat.OutputElement xml) 437 throws XMLStreamException { 438 xml.setAttribute("name", ((Class ) obj).getName()); 439 } 440 }; 441 442 447 static final XMLFormatSTRING_XML = new XMLFormat("".getClass()) { 448 449 public Object newInstance(Class cls, 450 javolution.xml.XMLFormat.InputElement xml) 451 throws XMLStreamException { 452 return xml.getAttribute("value", ""); 453 } 454 455 public void read(InputElement xml, Object obj) 456 throws XMLStreamException { 457 } 459 460 public void write(Object obj, OutputElement xml) 461 throws XMLStreamException { 462 xml.setAttribute("value", (String ) obj); 463 } 464 }; 465 466 471 static final XMLFormatAPPENDABLE_XML = new XMLFormat( 472 Javolution.j2meGetClass("javolution.text.Appendable")) { 473 474 public void read(InputElement xml, Object obj) 475 throws XMLStreamException { 476 CharSequence csq = xml.getAttribute("value"); 477 if (csq != null) { 478 try { 479 ((Appendable ) obj).append(csq); 480 } catch (IOException e) { 481 throw new XMLStreamException(e); 482 } 483 } 484 } 485 486 public void write(Object obj, OutputElement xml) 487 throws XMLStreamException { 488 if (obj instanceof CharSequence ) { 489 xml.setAttribute("value", (CharSequence ) obj); 490 } else { 491 xml.setAttribute("value", obj.toString()); 492 } 493 } 494 }; 495 496 503 static final XMLFormatCOLLECTION_XML = new XMLFormat( 504 Javolution.j2meGetClass("j2me.util.Collection")) { 505 506 public void read(InputElement xml, Object obj) 507 throws XMLStreamException { 508 Collection collection = (Collection) obj; 509 while (xml.hasNext()) { 510 collection.add(xml.getNext()); 511 } 512 } 513 514 public void write(Object obj, OutputElement xml) 515 throws XMLStreamException { 516 Collection collection = (Collection) obj; 517 for (Iterator i = collection.iterator(); i.hasNext();) { 518 xml.add(i.next()); 519 } 520 } 521 }; 522 523 539 static final XMLFormatMAP_XML = new XMLFormat(Javolution 540 .j2meGetClass("j2me.util.Map")) { 541 542 public void read(InputElement xml, Object obj) 543 throws XMLStreamException { 544 final Map map = (Map) obj; 545 while (xml.hasNext()) { 546 Object key = xml.get("Key"); 547 Object value = xml.get("Value"); 548 map.put(key, value); 549 } 550 } 551 552 public void write(Object obj, OutputElement xml) 553 throws XMLStreamException { 554 final Map map = (Map) obj; 555 for (Iterator it = map.entrySet().iterator(); it.hasNext();) { 556 Map.Entry entry = (Map.Entry) it.next(); 557 xml.add(entry.getKey(), "Key"); 558 xml.add(entry.getValue(), "Value"); 559 } 560 } 561 }; 562 563 570 602 603 606 static final XMLFormatBOOLEAN_XML = new XMLFormat( 607 new Boolean (true).getClass()) { 608 609 public boolean isReferenceable() { 610 return false; } 612 613 public Object newInstance(Class cls, 614 javolution.xml.XMLFormat.InputElement xml) 615 throws XMLStreamException { 616 return new Boolean (xml.getAttribute("value", false)); 617 } 618 619 public void read(InputElement xml, Object obj) 620 throws XMLStreamException { 621 } 623 624 public void write(Object obj, OutputElement xml) 625 throws XMLStreamException { 626 xml.setAttribute("value", ((Boolean ) obj).booleanValue()); 627 } 628 }; 629 630 633 static final XMLFormatBYTE_XML = new XMLFormat( 634 new Byte ((byte) 0).getClass()) { 635 636 public boolean isReferenceable() { 637 return false; } 639 640 public Object newInstance(Class cls, 641 javolution.xml.XMLFormat.InputElement xml) 642 throws XMLStreamException { 643 return new Byte ((byte) xml.getAttribute("value", 0)); 644 } 645 646 public void read(InputElement xml, Object obj) 647 throws XMLStreamException { 648 } 650 651 public void write(Object obj, OutputElement xml) 652 throws XMLStreamException { 653 xml.setAttribute("value", ((Byte ) obj).byteValue()); 654 } 655 }; 656 657 660 static final XMLFormatCHARACTER_XML = new XMLFormat( 661 new Character (' ').getClass()) { 662 663 public boolean isReferenceable() { 664 return false; } 666 667 public Object newInstance(Class cls, 668 javolution.xml.XMLFormat.InputElement xml) 669 throws XMLStreamException { 670 CharSequence csq = xml.getAttribute("value"); 671 if ((csq == null) || (csq.length() != 1)) 672 throw new XMLStreamException( 673 "Missing or invalid value attribute"); 674 return new Character (csq.charAt(0)); 675 } 676 677 public void read(InputElement xml, Object obj) 678 throws XMLStreamException { 679 } 681 682 public void write(Object obj, OutputElement xml) 683 throws XMLStreamException { 684 xml.setAttribute("value", Text.valueOf(((Character ) obj) 685 .charValue())); 686 } 687 }; 688 689 692 static final XMLFormatSHORT_XML = new XMLFormat(new Short ( 693 (short) 0).getClass()) { 694 695 public boolean isReferenceable() { 696 return false; } 698 699 public Object newInstance(Class cls, 700 javolution.xml.XMLFormat.InputElement xml) 701 throws XMLStreamException { 702 return new Short ((short) xml.getAttribute("value", 0)); 703 } 704 705 public void read(InputElement xml, Object obj) 706 throws XMLStreamException { 707 } 709 710 public void write(Object obj, OutputElement xml) 711 throws XMLStreamException { 712 xml.setAttribute("value", ((Short ) obj).shortValue()); 713 } 714 }; 715 716 719 static final XMLFormatINTEGER_XML = new XMLFormat( 720 new Integer (0).getClass()) { 721 722 public boolean isReferenceable() { 723 return false; } 725 726 public Object newInstance(Class cls, 727 javolution.xml.XMLFormat.InputElement xml) 728 throws XMLStreamException { 729 return new Integer (xml.getAttribute("value", 0)); 730 } 731 732 public void read(InputElement xml, Object obj) 733 throws XMLStreamException { 734 } 736 737 public void write(Object obj, OutputElement xml) 738 throws XMLStreamException { 739 xml.setAttribute("value", ((Integer ) obj).intValue()); 740 } 741 }; 742 743 746 static final XMLFormatLONG_XML = new XMLFormat(new Long (0) 747 .getClass()) { 748 749 public boolean isReferenceable() { 750 return false; } 752 753 public Object newInstance(Class cls, 754 javolution.xml.XMLFormat.InputElement xml) 755 throws XMLStreamException { 756 return new Long (xml.getAttribute("value", 0L)); 757 } 758 759 public void read(InputElement xml, Object obj) 760 throws XMLStreamException { 761 } 763 764 public void write(Object obj, OutputElement xml) 765 throws XMLStreamException { 766 xml.setAttribute("value", ((Long ) obj).longValue()); 767 } 768 }; 769 770 775 795 796 801 820 821 private static CharSequence toCsq(Object str) { 822 return Javolution.j2meToCharSeq(str); 823 } 824 825 } | Popular Tags |