1 16 package org.apache.commons.betwixt.io; 17 18 import java.beans.IntrospectionException ; 19 import java.io.IOException ; 20 import java.util.ArrayList ; 21 import java.util.Collection ; 22 import java.util.HashMap ; 23 import java.util.Iterator ; 24 25 import org.apache.commons.betwixt.AttributeDescriptor; 26 import org.apache.commons.betwixt.BindingConfiguration; 27 import org.apache.commons.betwixt.Descriptor; 28 import org.apache.commons.betwixt.ElementDescriptor; 29 import org.apache.commons.betwixt.XMLBeanInfo; 30 import org.apache.commons.betwixt.XMLIntrospector; 31 import org.apache.commons.betwixt.digester.XMLIntrospectorHelper; 32 import org.apache.commons.betwixt.expression.Context; 33 import org.apache.commons.betwixt.expression.Expression; 34 import org.apache.commons.betwixt.io.id.SequentialIDGenerator; 35 import org.apache.commons.collections.ArrayStack; 36 import org.apache.commons.logging.Log; 37 import org.apache.commons.logging.LogFactory; 38 import org.xml.sax.Attributes ; 39 import org.xml.sax.SAXException ; 40 import org.xml.sax.helpers.AttributesImpl ; 41 42 45 50 88 public abstract class AbstractBeanWriter { 89 90 91 private XMLIntrospector introspector = new XMLIntrospector(); 92 93 94 private Log log = LogFactory.getLog( AbstractBeanWriter.class ); 95 96 private HashMap idMap = new HashMap (); 97 98 private ArrayStack beanStack = new ArrayStack(); 99 100 private IDGenerator idGenerator = new SequentialIDGenerator(); 101 102 private boolean writeEmptyElements = true; 103 104 private BindingConfiguration bindingConfiguration = new BindingConfiguration(); 105 106 private WriteContextImpl writeContext = new WriteContextImpl(); 107 108 private Collection namespacesDeclared = new ArrayList (); 109 110 117 public void start() throws IOException , SAXException { 118 } 119 120 127 128 public void end() throws IOException , SAXException { 129 } 130 131 146 public void write(Object bean) throws 147 IOException , 148 SAXException , 149 IntrospectionException { 150 if (log.isDebugEnabled()) { 151 log.debug( "Writing bean graph..." ); 152 log.debug( bean ); 153 } 154 start(); 155 writeBean( null, null, null, bean, makeContext( bean ) ); 156 end(); 157 if (log.isDebugEnabled()) { 158 log.debug( "Finished writing bean graph." ); 159 } 160 } 161 162 177 public void write( 178 String qualifiedName, 179 Object bean) 180 throws 181 IOException , 182 SAXException , 183 IntrospectionException { 184 start(); 185 writeBean( "", qualifiedName, qualifiedName, bean, makeContext( bean ) ); 186 end(); 187 } 188 189 207 private void writeBean ( 208 String namespaceUri, 209 String localName, 210 String qualifiedName, 211 Object bean, 212 Context context) 213 throws 214 IOException , 215 SAXException , 216 IntrospectionException { 217 218 if ( log.isTraceEnabled() ) { 219 log.trace( "Writing bean graph (qualified name '" + qualifiedName + "'" ); 220 } 221 222 XMLBeanInfo beanInfo = introspector.introspect( bean ); 224 if ( beanInfo != null ) { 225 ElementDescriptor elementDescriptor = beanInfo.getElementDescriptor(); 226 if ( elementDescriptor != null ) { 227 context = context.newContext( bean ); 228 if ( qualifiedName == null ) { 229 qualifiedName = elementDescriptor.getQualifiedName(); 230 } 231 if ( namespaceUri == null ) { 232 namespaceUri = elementDescriptor.getURI(); 233 } 234 if ( localName == null ) { 235 localName = elementDescriptor.getLocalName(); 236 } 237 238 String ref = null; 239 String id = null; 240 241 if ( elementDescriptor.isSimple() ) { 243 writeElement( 245 namespaceUri, 246 localName, 247 qualifiedName, 248 elementDescriptor, 249 context ); 250 251 } else { 252 pushBean ( context.getBean() ); 253 if ( getBindingConfiguration().getMapIDs() ) { 254 ref = (String ) idMap.get( context.getBean() ); 255 } 256 if ( ref == null ) { 257 AttributeDescriptor idAttribute = beanInfo.getIDAttribute(); 259 if (idAttribute == null) { 260 id = idGenerator.nextId(); 262 idMap.put( bean, id ); 263 264 if ( getBindingConfiguration().getMapIDs() ) { 265 writeElement( 267 namespaceUri, 268 localName, 269 qualifiedName, 270 elementDescriptor, 271 context , 272 beanInfo.getIDAttributeName(), 273 id); 274 275 } else { 276 writeElement( 278 namespaceUri, 279 localName, 280 qualifiedName, 281 elementDescriptor, 282 context ); 283 } 284 285 } else { 286 Object exp = idAttribute.getTextExpression().evaluate( context ); 290 if (exp == null) { 291 log.debug("Using random id"); 293 id = idGenerator.nextId(); 294 295 } else { 296 id = exp.toString(); 298 } 299 idMap.put( bean, id); 300 301 writeElement( 303 namespaceUri, 304 localName, 305 qualifiedName, 306 elementDescriptor, 307 context ); 308 } 309 } else { 310 311 if ( !ignoreElement( elementDescriptor, context )) { 312 writeIDREFElement( 314 elementDescriptor, 315 namespaceUri, 316 localName, 317 qualifiedName, 318 beanInfo.getIDREFAttributeName(), 319 ref); 320 } 321 } 322 popBean(); 323 } 324 } 325 } 326 327 log.trace( "Finished writing bean graph." ); 328 } 329 330 336 public IDGenerator getIdGenerator() { 337 return idGenerator; 338 } 339 340 347 public void setIdGenerator(IDGenerator idGenerator) { 348 this.idGenerator = idGenerator; 349 } 350 351 352 353 358 public BindingConfiguration getBindingConfiguration() { 359 return bindingConfiguration; 360 } 361 362 367 public void setBindingConfiguration(BindingConfiguration bindingConfiguration) { 368 this.bindingConfiguration = bindingConfiguration; 369 } 370 371 380 public boolean getWriteIDs() { 381 return getBindingConfiguration().getMapIDs(); 382 } 383 384 392 public void setWriteIDs(boolean writeIDs) { 393 getBindingConfiguration().setMapIDs( writeIDs ); 394 } 395 396 407 public boolean getWriteEmptyElements() { 408 return writeEmptyElements; 409 } 410 411 422 public void setWriteEmptyElements(boolean writeEmptyElements) { 423 this.writeEmptyElements = writeEmptyElements; 424 } 425 426 436 public XMLIntrospector getXMLIntrospector() { 437 return introspector; 438 } 439 440 441 451 public void setXMLIntrospector(XMLIntrospector introspector) { 452 this.introspector = introspector; 453 } 454 455 460 public final Log getAbstractBeanWriterLog() { 461 return log; 462 } 463 464 469 public final void setAbstractBeanWriterLog(Log log) { 470 this.log = log; 471 } 472 473 476 488 protected void startElement( 489 WriteContext context, 490 String uri, 491 String localName, 492 String qName, 493 Attributes attr) 494 throws 495 IOException , 496 SAXException { 497 startElement(uri, localName, qName, attr); 499 } 500 501 512 protected void endElement( 513 WriteContext context, 514 String uri, 515 String localName, 516 String qName) 517 throws 518 IOException , 519 SAXException { 520 endElement(uri, localName, qName); 522 } 523 524 533 protected void bodyText(WriteContext context, String text) 534 throws IOException , SAXException { 535 bodyText(text); 537 } 538 539 542 554 protected void startElement( 555 String uri, 556 String localName, 557 String qName, 558 Attributes attr) 559 throws 560 IOException , 561 SAXException {} 562 563 574 protected void endElement( 575 String uri, 576 String localName, 577 String qName) 578 throws 579 IOException , 580 SAXException {} 581 582 591 protected void bodyText(String text) throws IOException , SAXException {} 592 593 596 608 private void writeElement( 609 String namespaceUri, 610 String localName, 611 String qualifiedName, 612 ElementDescriptor elementDescriptor, 613 Context context ) 614 throws 615 IOException , 616 SAXException , 617 IntrospectionException { 618 if( log.isTraceEnabled() ) { 619 log.trace( "Writing: " + qualifiedName + " element: " + elementDescriptor ); 620 } 621 622 if ( !ignoreElement( elementDescriptor, context )) { 623 if ( log.isTraceEnabled() ) { 624 log.trace( "Element " + elementDescriptor + " is empty." ); 625 } 626 627 Attributes attributes = addNamespaceDeclarations( 628 new ElementAttributes( elementDescriptor, context ), namespaceUri); 629 writeContext.setCurrentDescriptor(elementDescriptor); 630 startElement( 631 writeContext, 632 namespaceUri, 633 localName, 634 qualifiedName, 635 attributes); 636 637 writeElementContent( elementDescriptor, context ) ; 638 writeContext.setCurrentDescriptor(elementDescriptor); 639 endElement( writeContext, namespaceUri, localName, qualifiedName ); 640 641 } 642 } 643 644 650 private Attributes addNamespaceDeclarations(Attributes attributes, String elementNamespaceUri) { 651 Attributes result = attributes; 652 AttributesImpl withDeclarations = null; 653 for (int i=-1, size=attributes.getLength(); i<size ; i++) { 654 String uri = null; 655 if (i == -1) { 656 uri = elementNamespaceUri; 657 } else { 658 uri = attributes.getURI(i); 659 } 660 if (uri != null && !"".equals(uri) && !namespacesDeclared.contains(uri)) { 661 if (withDeclarations == null) { 662 withDeclarations = new AttributesImpl (attributes); 663 } 664 withDeclarations.addAttribute("", "", "xmlns:" 665 + getXMLIntrospector().getConfiguration().getPrefixMapper().getPrefix(uri), "NOTATION", uri); 666 namespacesDeclared.add(uri); 667 } 668 } 669 670 if (withDeclarations != null) { 671 result = withDeclarations; 672 } 673 return result; 674 } 675 676 677 691 private void writeElement( 692 String namespaceUri, 693 String localName, 694 String qualifiedName, 695 ElementDescriptor elementDescriptor, 696 Context context, 697 String idAttribute, 698 String idValue ) 699 throws 700 IOException , 701 SAXException , 702 IntrospectionException { 703 704 if ( !ignoreElement( elementDescriptor, context ) ) { 705 writeContext.setCurrentDescriptor(elementDescriptor); 706 Attributes attributes = new IDElementAttributes( 707 elementDescriptor, 708 context, 709 idAttribute, 710 idValue ); 711 startElement( 712 writeContext, 713 namespaceUri, 714 localName, 715 qualifiedName, 716 addNamespaceDeclarations(attributes, namespaceUri)); 717 718 writeElementContent( elementDescriptor, context ) ; 719 writeContext.setCurrentDescriptor(elementDescriptor); 720 endElement( writeContext, namespaceUri, localName, qualifiedName ); 721 722 } else if ( log.isTraceEnabled() ) { 723 log.trace( "Element " + qualifiedName + " is empty." ); 724 } 725 } 726 727 728 740 private void writeRestOfElement( 741 String uri, 742 String localName, 743 String qualifiedName, 744 ElementDescriptor elementDescriptor, 745 Context context ) 746 throws 747 IOException , 748 SAXException , 749 IntrospectionException { 750 751 writeElementContent( elementDescriptor, context ); 752 } 753 754 766 private void writeIDREFElement( 767 ElementDescriptor elementDescriptor, 768 String uri, 769 String localName, 770 String qualifiedName, 771 String idrefAttributeName, 772 String idrefAttributeValue ) 773 throws 774 IOException , 775 SAXException , 776 IntrospectionException { 777 778 779 780 AttributesImpl attributes = new AttributesImpl (); 782 attributes.addAttribute( 784 "", 785 idrefAttributeName, 786 idrefAttributeName, 787 "IDREF", 788 idrefAttributeValue); 789 writeContext.setCurrentDescriptor(elementDescriptor); 790 startElement( writeContext, uri, localName, qualifiedName, addNamespaceDeclarations(attributes, uri)); 791 endElement( writeContext, uri, localName, qualifiedName ); 792 } 793 794 804 private void writeElementContent( 805 ElementDescriptor elementDescriptor, 806 Context context ) 807 throws 808 IOException , 809 SAXException , 810 IntrospectionException { 811 writeContext.setCurrentDescriptor( elementDescriptor ); 812 Descriptor[] childDescriptors = elementDescriptor.getContentDescriptors(); 813 if ( childDescriptors != null && childDescriptors.length > 0 ) { 814 for ( int i = 0, size = childDescriptors.length; i < size; i++ ) { 816 if (childDescriptors[i] instanceof ElementDescriptor) { 817 ElementDescriptor childDescriptor = (ElementDescriptor) childDescriptors[i]; 819 Context childContext = context; 820 Expression childExpression = childDescriptor.getContextExpression(); 821 if ( childExpression != null ) { 822 Object childBean = childExpression.evaluate( context ); 823 if ( childBean != null ) { 824 String qualifiedName = childDescriptor.getQualifiedName(); 825 String namespaceUri = childDescriptor.getURI(); 826 String localName = childDescriptor.getLocalName(); 827 if ( childBean instanceof Iterator ) { 829 for ( Iterator iter = (Iterator ) childBean; iter.hasNext(); ) { 830 Object object = iter.next(); 831 if (object == null) { 832 continue; 833 } 834 writeBean( 835 namespaceUri, 836 localName, 837 qualifiedName, 838 object, 839 context ); 840 } 841 } else { 842 writeBean( 843 namespaceUri, 844 localName, 845 qualifiedName, 846 childBean, 847 context ); 848 } 849 } 850 } else { 851 writeElement( 852 childDescriptor.getURI(), 853 childDescriptor.getLocalName(), 854 childDescriptor.getQualifiedName(), 855 childDescriptor, 856 childContext ); 857 } 858 } else { 859 Expression expression = childDescriptors[i].getTextExpression(); 862 if ( expression != null ) { 863 Object value = expression.evaluate( context ); 864 String text = convertToString( 865 value, 866 childDescriptors[i], 867 context ); 868 if ( text != null && text.length() > 0 ) {; 869 bodyText( writeContext, text ); 870 } 871 } 872 } 873 } 874 } else { 875 Expression expression = elementDescriptor.getTextExpression(); 877 if ( expression != null ) { 878 Object value = expression.evaluate( context ); 879 String text = convertToString( value, elementDescriptor, context ); 880 if ( text != null && text.length() > 0 ) { 881 bodyText( writeContext, text ); 882 } 883 } 884 } 885 } 886 887 893 protected void pushBean( Object bean ) { 894 if ( !getBindingConfiguration().getMapIDs() ) { 896 Iterator it = beanStack.iterator(); 897 while ( it.hasNext() ) { 898 Object next = it.next(); 899 if ( bean == next ) { 902 if ( log.isDebugEnabled() ) { 903 log.debug("Element stack: "); 904 Iterator debugStack = beanStack.iterator(); 905 while ( debugStack.hasNext() ) { 906 log.debug(debugStack.next()); 907 } 908 } 909 log.error("Cyclic reference at bean: " + bean); 910 throw new CyclicReferenceException(); 911 } 912 } 913 } 914 if (log.isTraceEnabled()) { 915 log.trace( "Pushing onto object stack: " + bean ); 916 } 917 beanStack.push( bean ); 918 } 919 920 925 protected Object popBean() { 926 Object bean = beanStack.pop(); 927 if (log.isTraceEnabled()) { 928 log.trace( "Popped from object stack: " + bean ); 929 } 930 return bean; 931 } 932 933 940 private boolean ignoreElement( ElementDescriptor descriptor, Context context ) { 941 if ( ! getWriteEmptyElements() ) { 942 return isEmptyElement( descriptor, context ); 943 } 944 return false; 945 } 946 947 959 private boolean isEmptyElement( ElementDescriptor descriptor, Context context ) { 960 if ( log.isTraceEnabled() ) { 961 log.trace( "Is " + descriptor + " empty?" ); 962 } 963 964 if ( descriptor.hasAttributes() ) { 966 log.trace( "Element has attributes." ); 967 return false; 968 } 969 970 Expression expression = descriptor.getTextExpression(); 972 if ( expression != null ) { 973 Object value = expression.evaluate( context ); 974 String text = convertToString( value, descriptor, context ); 975 if ( text != null && text.length() > 0 ) { 976 log.trace( "Element has body text which isn't empty." ); 977 return false; 978 } 979 } 980 981 if ( XMLIntrospectorHelper.isLoopType( descriptor.getPropertyType() ) ) { 983 log.trace("Loop type so not empty."); 984 return false; 985 } 986 987 if ( descriptor.hasChildren() ) { 990 for ( int i=0, size=descriptor.getElementDescriptors().length; i<size; i++ ) { 991 if ( ! isEmptyElement( descriptor.getElementDescriptors()[i], context ) ) { 992 log.trace( "Element has child which isn't empty." ); 993 return false; 994 } 995 } 996 } 997 998 log.trace( "Element is empty." ); 999 return true; 1000 } 1001 1002 1003 1007 private class ElementAttributes implements Attributes { 1008 1009 private AttributeDescriptor[] attributes; 1010 1011 private Context context; 1012 1013 1014 1015 1021 ElementAttributes( ElementDescriptor descriptor, Context context ) { 1022 attributes = descriptor.getAttributeDescriptors(); 1023 this.context = context; 1024 } 1025 1026 1032 public int getIndex( String qName ) { 1033 for ( int i=0; i<attributes.length; i++ ) { 1034 if (attributes[i].getQualifiedName() != null 1035 && attributes[i].getQualifiedName().equals( qName )) { 1036 return i; 1037 } 1038 } 1039 return -1; 1040 } 1041 1042 1049 public int getIndex( String uri, String localName ) { 1050 for ( int i=0; i<attributes.length; i++ ) { 1051 if ( 1052 attributes[i].getURI() != null 1053 && attributes[i].getURI().equals(uri) 1054 && attributes[i].getLocalName() != null 1055 && attributes[i].getURI().equals(localName)) { 1056 return i; 1057 } 1058 } 1059 1060 return -1; 1061 } 1062 1063 1068 public int getLength() { 1069 return attributes.length; 1070 } 1071 1072 1078 public String getLocalName( int index ) { 1079 if ( indexInRange( index ) ) { 1080 return attributes[index].getLocalName(); 1081 } 1082 1083 return null; 1084 } 1085 1086 1092 public String getQName( int index ) { 1093 if ( indexInRange( index ) ) { 1094 return attributes[index].getQualifiedName(); 1095 } 1096 1097 return null; 1098 } 1099 1100 1106 public String getType( int index ) { 1107 if ( indexInRange( index ) ) { 1108 return "CDATA"; 1109 } 1110 return null; 1111 } 1112 1113 1119 public String getType( String qName ) { 1120 return getType( getIndex( qName ) ); 1121 } 1122 1123 1130 public String getType( String uri, String localName ) { 1131 return getType( getIndex( uri, localName )); 1132 } 1133 1134 1141 public String getURI( int index ) { 1142 if ( indexInRange( index ) ) { 1143 return attributes[index].getURI(); 1144 } 1145 return null; 1146 } 1147 1148 1155 public String getValue( int index ) { 1156 if ( indexInRange( index )) { 1157 Expression expression = attributes[index].getTextExpression(); 1158 if ( expression != null ) { 1159 Object value = expression.evaluate( context ); 1160 return convertToString( value, attributes[index], context ); 1161 } 1162 1163 return ""; 1164 } 1165 return null; 1166 } 1167 1168 1176 public String getValue( String qName ) { 1177 return getValue( getIndex( qName ) ); 1178 } 1179 1180 1189 public String getValue( String uri, String localName ) { 1190 return getValue( getIndex( uri, localName ) ); 1191 } 1192 1193 1199 private boolean indexInRange( int index ) { 1200 return ( index >= 0 && index < attributes.length ); 1201 } 1202 } 1203 1204 1211 private class IDElementAttributes extends ElementAttributes { 1212 1213 private String idValue; 1214 1215 private String idAttributeName; 1216 1217 private boolean matchingAttribute = false; 1218 private int length; 1219 private int idIndex; 1220 1221 1229 IDElementAttributes( 1230 ElementDescriptor descriptor, 1231 Context context, 1232 String idAttributeName, 1233 String idValue) { 1234 super(descriptor, context); 1235 this.idValue = idValue; 1236 this.idAttributeName = idAttributeName; 1237 1238 AttributeDescriptor[] attributeDescriptors = descriptor.getAttributeDescriptors(); 1240 length = attributeDescriptors.length; 1241 for (int i=0; i<length; i++) { 1242 if (idAttributeName.equals(attributeDescriptors[i])) { 1243 matchingAttribute = true; 1244 idIndex = i; 1245 break; 1246 } 1247 } 1248 if (!matchingAttribute) { 1249 length += 1; 1250 idIndex = length-1; 1251 } 1252 } 1253 1254 public int getIndex(String uri, String localName) { 1255 if (localName.equals(idAttributeName)) { 1256 return idIndex; 1257 } 1258 1259 return super.getIndex(uri, localName); 1260 } 1261 1262 public int getIndex(String qName) { 1263 if (qName.equals(idAttributeName)) { 1264 return idIndex; 1265 } 1266 1267 return super.getIndex(qName); 1268 } 1269 1270 public int getLength() { 1271 return length; 1272 } 1273 1274 public String getLocalName(int index) { 1275 if (index == idIndex) { 1276 return idAttributeName; 1277 } 1278 return super.getLocalName(index); 1279 } 1280 1281 public String getQName(int index) { 1282 if (index == idIndex) { 1283 return idAttributeName; 1284 } 1285 return super.getQName(index); 1286 } 1287 1288 public String getType(int index) { 1289 if (index == idIndex) { 1290 return "ID"; 1291 } 1292 return super.getType(index); 1293 } 1294 1295 public String getType(String uri, String localName) { 1296 return getType(getIndex(uri, localName)); 1297 } 1298 1299 public String getType(String qName) { 1300 return getType(getIndex(qName)); 1301 } 1302 1303 public String getURI(int index) { 1304 if (index == idIndex) { 1308 return ""; 1309 } 1310 return super.getURI(index); 1311 } 1312 1313 public String getValue(int index) { 1314 if (index == idIndex) { 1315 return idValue; 1316 } 1317 return super.getValue(index); 1318 } 1319 1320 public String getValue(String uri, String localName) { 1321 return getValue(getIndex(uri, localName)); 1322 } 1323 1324 public String getValue(String qName) { 1325 return getValue(getIndex(qName)); 1326 } 1327 1328 } 1329 1330 1331 1334 1335 1342 protected int getIndentLevel() { 1343 return 0; 1344 } 1345 1346 1349 1357 protected void expressElementStart(String qualifiedName) 1358 throws IOException , SAXException { 1359 } 1361 1362 1372 protected void expressElementStart(String uri, String localName, String qualifiedName) 1373 throws IOException , SAXException { 1374 expressElementStart( qualifiedName ); 1375 } 1376 1377 1384 protected void expressTagClose() throws IOException , SAXException {} 1385 1386 1395 protected void expressElementEnd(String qualifiedName) 1396 throws IOException , SAXException { 1397 } 1399 1400 1411 protected void expressElementEnd( 1412 String uri, 1413 String localName, 1414 String qualifiedName) 1415 throws 1416 IOException , 1417 SAXException { 1418 expressElementEnd(qualifiedName); 1419 } 1420 1421 1422 1429 protected void expressElementEnd() throws IOException , SAXException {} 1430 1431 1440 protected void expressBodyText(String text) throws IOException , SAXException {} 1441 1442 1451 protected void expressAttribute( 1452 String qualifiedName, 1453 String value) 1454 throws 1455 IOException , 1456 SAXException { 1457 } 1459 1460 1471 protected void expressAttribute( 1472 String namespaceUri, 1473 String localName, 1474 String qualifiedName, 1475 String value) 1476 throws 1477 IOException , 1478 SAXException { 1479 expressAttribute(qualifiedName, value); 1480 } 1481 1482 1483 1494 protected void write( 1495 String qualifiedName, 1496 ElementDescriptor elementDescriptor, 1497 Context context ) 1498 throws 1499 IOException , 1500 SAXException , 1501 IntrospectionException { 1502 writeElement( "", qualifiedName, qualifiedName, elementDescriptor, context ); 1503 } 1504 1505 1518 protected void write( 1519 String qualifiedName, 1520 ElementDescriptor elementDescriptor, 1521 Context context, 1522 String idAttribute, 1523 String idValue ) 1524 throws 1525 IOException , 1526 SAXException , 1527 IntrospectionException { 1528 writeElement( 1529 "", 1530 qualifiedName, 1531 qualifiedName, 1532 elementDescriptor, 1533 context, 1534 idAttribute, 1535 idValue ); 1536 } 1537 1538 1549 protected void writeRestOfElement( 1550 String qualifiedName, 1551 ElementDescriptor elementDescriptor, 1552 Context context ) 1553 throws 1554 IOException , 1555 SAXException , 1556 IntrospectionException { 1557 writeRestOfElement( "", qualifiedName, qualifiedName, elementDescriptor, context ); 1558 } 1559 1560 1571 protected void writeIDREFElement( 1572 String qualifiedName, 1573 String idrefAttributeName, 1574 String idrefAttributeValue ) 1575 throws 1576 IOException , 1577 SAXException , 1578 IntrospectionException { 1579 AttributesImpl attributes = new AttributesImpl (); 1581 attributes.addAttribute( 1582 "", 1583 idrefAttributeName, 1584 idrefAttributeName, 1585 "IDREF", 1586 idrefAttributeValue); 1587 startElement( "", qualifiedName, qualifiedName, attributes); 1588 endElement( "", qualifiedName, qualifiedName ); 1589 } 1590 1591 1592 1603 protected boolean writeContent( 1604 ElementDescriptor elementDescriptor, 1605 Context context ) 1606 throws 1607 IOException , 1608 SAXException , 1609 IntrospectionException { 1610 return false; 1611 } 1612 1613 1614 1623 protected void writeAttributes( 1624 ElementDescriptor elementDescriptor, 1625 Context context ) 1626 throws 1627 IOException , SAXException { 1628 if (!elementDescriptor.isWrapCollectionsInElement()) { 1629 return; 1630 } 1631 1632 AttributeDescriptor[] attributeDescriptors = elementDescriptor.getAttributeDescriptors(); 1633 if ( attributeDescriptors != null ) { 1634 for ( int i = 0, size = attributeDescriptors.length; i < size; i++ ) { 1635 AttributeDescriptor attributeDescriptor = attributeDescriptors[i]; 1636 writeAttribute( attributeDescriptor, context ); 1637 } 1638 } 1639 } 1640 1641 1642 1651 protected void writeAttribute( 1652 AttributeDescriptor attributeDescriptor, 1653 Context context ) 1654 throws 1655 IOException , SAXException { 1656 Expression expression = attributeDescriptor.getTextExpression(); 1657 if ( expression != null ) { 1658 Object value = expression.evaluate( context ); 1659 if ( value != null ) { 1660 String text = value.toString(); 1661 if ( text != null && text.length() > 0 ) { 1662 expressAttribute( 1663 attributeDescriptor.getURI(), 1664 attributeDescriptor.getLocalName(), 1665 attributeDescriptor.getQualifiedName(), 1666 text); 1667 } 1668 } 1669 } 1670 } 1671 1678 protected void writePrintln() throws IOException {} 1679 1680 1687 protected void writeIndent() throws IOException {} 1688 1689 1697 private String convertToString( Object value , Descriptor descriptor, Context context ) { 1698 return getBindingConfiguration() 1699 .getObjectStringConverter() 1700 .objectToString( value, descriptor.getPropertyType(), null, context ); 1701 } 1702 1703 1709 private Context makeContext(Object bean) { 1710 return new Context( bean, log, bindingConfiguration ); 1711 } 1712 1713 1714 1717 private static class WriteContextImpl extends WriteContext { 1718 1719 private ElementDescriptor currentDescriptor; 1720 1721 1724 public ElementDescriptor getCurrentDescriptor() { 1725 return currentDescriptor; 1726 } 1727 1728 1732 public void setCurrentDescriptor(ElementDescriptor currentDescriptor) { 1733 this.currentDescriptor = currentDescriptor; 1734 } 1735 1736 } 1737} 1738 | Popular Tags |