1 16 17 package org.apache.axis.encoding; 18 19 import java.io.IOException ; 20 import java.io.Writer ; 21 import java.lang.IllegalAccessException ; 22 import java.lang.NoSuchMethodException ; 23 import java.lang.reflect.InvocationTargetException ; 24 import java.lang.reflect.Method ; 25 import java.util.ArrayList ; 26 import java.util.Calendar ; 27 import java.util.Date ; 28 import java.util.HashMap ; 29 import java.util.HashSet ; 30 import java.util.Iterator ; 31 import java.util.Stack ; 32 33 import javax.xml.namespace.QName ; 34 import javax.xml.rpc.JAXRPCException ; 35 import javax.xml.rpc.holders.QNameHolder ; 36 import org.apache.axis.AxisEngine; 37 import org.apache.axis.Constants; 38 import org.apache.axis.Message; 39 import org.apache.axis.MessageContext; 40 import org.apache.axis.AxisProperties; 41 import org.apache.axis.attachments.Attachments; 42 import org.apache.axis.client.Call; 43 import org.apache.axis.components.logger.LogFactory; 44 import org.apache.axis.components.encoding.XMLEncoder; 45 import org.apache.axis.components.encoding.XMLEncoderFactory; 46 import org.apache.axis.description.OperationDesc; 47 import org.apache.axis.description.TypeDesc; 48 import org.apache.axis.encoding.ser.BaseSerializerFactory; 49 import org.apache.axis.constants.Use; 50 import org.apache.axis.handlers.soap.SOAPService; 51 import org.apache.axis.schema.SchemaVersion; 52 import org.apache.axis.soap.SOAPConstants; 53 import org.apache.axis.types.HexBinary; 54 import org.apache.axis.utils.IDKey; 55 import org.apache.axis.utils.Mapping; 56 import org.apache.axis.utils.Messages; 57 import org.apache.axis.utils.NSStack; 58 import org.apache.axis.utils.XMLUtils; 59 import org.apache.axis.utils.JavaUtils; 60 import org.apache.axis.utils.cache.MethodCache; 61 import org.apache.axis.wsdl.symbolTable.SchemaUtils; 62 import org.apache.axis.wsdl.symbolTable.SymbolTable; 63 import org.apache.axis.wsdl.symbolTable.Utils; 64 import org.apache.commons.logging.Log; 65 import org.w3c.dom.Attr ; 66 import org.w3c.dom.CDATASection ; 67 import org.w3c.dom.CharacterData ; 68 import org.w3c.dom.Comment ; 69 import org.w3c.dom.Element ; 70 import org.w3c.dom.NamedNodeMap ; 71 import org.w3c.dom.Node ; 72 import org.w3c.dom.NodeList ; 73 import org.w3c.dom.Text ; 74 import org.xml.sax.Attributes ; 75 import org.xml.sax.helpers.AttributesImpl ; 76 77 83 public class SerializationContext implements javax.xml.rpc.encoding.SerializationContext 84 { 85 protected static Log log = 86 LogFactory.getLog(SerializationContext.class.getName()); 87 88 private final boolean debugEnabled = log.isDebugEnabled(); 92 93 private NSStack nsStack = null; 94 private boolean writingStartTag = false; 95 private boolean onlyXML = true; 96 private int indent=0; 97 private Stack elementStack = new Stack (); 98 private Writer writer; 99 private int lastPrefixIndex = 1; 100 private MessageContext msgContext; 101 private QName currentXMLType; 102 103 private QName itemQName; 104 105 private QName itemType; 106 107 108 private SOAPConstants soapConstants = SOAPConstants.SOAP11_CONSTANTS; 109 110 private static QName multirefQName = new QName ("","multiRef"); 111 private static Class [] SERIALIZER_CLASSES = 112 new Class [] {String .class, Class .class, QName .class}; 113 private static final String SERIALIZER_METHOD = "getSerializer"; 114 115 123 private boolean doMultiRefs = false; 124 125 128 private boolean disablePrettyXML = false; 129 130 131 134 private boolean enableNamespacePrefixOptimization = false; 135 136 139 private boolean pretty = false; 140 141 144 private boolean sendXMLDecl = true; 145 146 149 private boolean sendXSIType = true; 150 151 155 private Boolean sendNull = Boolean.TRUE; 156 157 161 private HashMap multiRefValues = null; 162 private int multiRefIndex = -1; 163 private boolean noNamespaceMappings = true; 164 private QName writeXMLType; 165 private XMLEncoder encoder = null; 166 167 168 protected boolean startOfDocument = true; 169 170 171 private String encoding = XMLEncoderFactory.DEFAULT_ENCODING; 172 173 class MultiRefItem { 174 String id; 175 QName xmlType; 176 Boolean sendType; 177 Object value; 178 MultiRefItem(String id, 179 QName xmlType, 180 Boolean sendType, Object value) { 181 this.id = id; 182 this.xmlType = xmlType; 183 this.sendType = sendType; 184 this.value = value; 185 } 186 187 } 188 199 private HashSet secondLevelObjects = null; 200 private Object forceSer = null; 201 private boolean outputMultiRefsFlag = false; 202 203 206 SchemaVersion schemaVersion = SchemaVersion.SCHEMA_2001; 207 208 212 HashMap preferredPrefixes = new HashMap (); 213 214 218 public SerializationContext(Writer writer) 219 { 220 this.writer = writer; 221 initialize(); 222 } 223 224 private void initialize() { 225 preferredPrefixes.put(soapConstants.getEncodingURI(), 228 Constants.NS_PREFIX_SOAP_ENC); 229 preferredPrefixes.put(Constants.NS_URI_XML, 230 Constants.NS_PREFIX_XML); 231 preferredPrefixes.put(schemaVersion.getXsdURI(), 232 Constants.NS_PREFIX_SCHEMA_XSD); 233 preferredPrefixes.put(schemaVersion.getXsiURI(), 234 Constants.NS_PREFIX_SCHEMA_XSI); 235 preferredPrefixes.put(soapConstants.getEnvelopeURI(), 236 Constants.NS_PREFIX_SOAP_ENV); 237 nsStack = new NSStack(enableNamespacePrefixOptimization); 238 } 239 240 241 246 public SerializationContext(Writer writer, MessageContext msgContext) 247 { 248 this.writer = writer; 249 this.msgContext = msgContext; 250 251 if ( msgContext != null ) { 252 soapConstants = msgContext.getSOAPConstants(); 253 254 schemaVersion = msgContext.getSchemaVersion(); 256 257 Boolean shouldSendDecl = (Boolean )msgContext.getProperty( 258 AxisEngine.PROP_XML_DECL); 259 if (shouldSendDecl != null) 260 sendXMLDecl = shouldSendDecl.booleanValue(); 261 262 Boolean shouldSendMultiRefs = 263 (Boolean )msgContext.getProperty(AxisEngine.PROP_DOMULTIREFS); 264 if (shouldSendMultiRefs != null) 265 doMultiRefs = shouldSendMultiRefs.booleanValue(); 266 267 Boolean shouldDisablePrettyXML = 268 (Boolean )msgContext.getProperty(AxisEngine.PROP_DISABLE_PRETTY_XML); 269 if (shouldDisablePrettyXML != null) 270 disablePrettyXML = shouldDisablePrettyXML.booleanValue(); 271 272 Boolean shouldDisableNamespacePrefixOptimization = 273 (Boolean )msgContext.getProperty(AxisEngine.PROP_ENABLE_NAMESPACE_PREFIX_OPTIMIZATION); 274 if (shouldDisableNamespacePrefixOptimization != null) { 275 enableNamespacePrefixOptimization = shouldDisableNamespacePrefixOptimization.booleanValue(); 276 } else { 277 enableNamespacePrefixOptimization = JavaUtils.isTrue(AxisProperties.getProperty(AxisEngine.PROP_ENABLE_NAMESPACE_PREFIX_OPTIMIZATION, 278 "true")); 279 } 280 boolean sendTypesDefault = sendXSIType; 281 282 OperationDesc operation = msgContext.getOperation(); 285 if (operation != null) { 286 if (operation.getUse() != Use.ENCODED) { 287 doMultiRefs = false; 288 sendTypesDefault = false; 289 } 290 } else { 291 SOAPService service = msgContext.getService(); 293 if (service != null) { 294 if (service.getUse() != Use.ENCODED) { 295 doMultiRefs = false; 296 sendTypesDefault = false; 297 } 298 } 299 } 300 301 if ( !msgContext.isPropertyTrue(Call.SEND_TYPE_ATTR, sendTypesDefault )) 305 sendXSIType = false ; 306 307 } else { 315 enableNamespacePrefixOptimization = JavaUtils.isTrue(AxisProperties.getProperty(AxisEngine.PROP_ENABLE_NAMESPACE_PREFIX_OPTIMIZATION, 316 "true")); 317 } 318 319 initialize(); 321 } 322 323 327 public boolean getPretty() { 328 return pretty; 329 } 330 331 335 public void setPretty(boolean pretty) { 336 if(!disablePrettyXML) { 337 this.pretty = pretty; 338 } 339 } 340 341 345 public boolean getDoMultiRefs() { 346 return doMultiRefs; 347 } 348 349 352 public void setDoMultiRefs (boolean shouldDo) 353 { 354 doMultiRefs = shouldDo; 355 } 356 357 361 public void setSendDecl(boolean sendDecl) 362 { 363 sendXMLDecl = sendDecl; 364 } 365 366 370 public boolean shouldSendXSIType() { 371 return sendXSIType; 372 } 373 374 378 public TypeMapping getTypeMapping() 379 { 380 if (msgContext == null) 382 return DefaultTypeMappingImpl.getSingletonDelegate(); 383 384 String encodingStyle = msgContext.getEncodingStyle(); 385 if (encodingStyle == null) 386 encodingStyle = soapConstants.getEncodingURI(); 387 return (TypeMapping) msgContext. 388 getTypeMappingRegistry().getTypeMapping(encodingStyle); 389 } 390 391 395 public TypeMappingRegistry getTypeMappingRegistry() { 396 if (msgContext == null) 397 return null; 398 return msgContext.getTypeMappingRegistry(); 399 } 400 401 410 public String getPrefixForURI(String uri) 411 { 412 return getPrefixForURI(uri, null, false); 413 } 414 415 421 public String getPrefixForURI(String uri, String defaultPrefix) 422 { 423 return getPrefixForURI(uri, defaultPrefix, false); 424 } 425 426 432 public String getPrefixForURI(String uri, String defaultPrefix, boolean attribute) 433 { 434 if ((uri == null) || (uri.length() == 0)) 435 return null; 436 437 String prefix = nsStack.getPrefix(uri, attribute); 440 441 if (prefix == null) { 442 prefix = (String )preferredPrefixes.get(uri); 443 444 if (prefix == null) { 445 if (defaultPrefix == null) { 446 prefix = "ns" + lastPrefixIndex++; 447 while(nsStack.getNamespaceURI(prefix)!=null) { 448 prefix = "ns" + lastPrefixIndex++; 449 } 450 } else { 451 prefix = defaultPrefix; 452 } 453 } 454 455 registerPrefixForURI(prefix, uri); 456 } 457 458 return prefix; 459 } 460 461 466 public void registerPrefixForURI(String prefix, String uri) 467 { 468 if (debugEnabled) { 469 log.debug(Messages.getMessage("register00", prefix, uri)); 470 } 471 472 if ((uri != null) && (prefix != null)) { 473 if (noNamespaceMappings) { 474 nsStack.push(); 475 noNamespaceMappings = false; 476 } 477 String activePrefix = nsStack.getPrefix(uri,true); 478 if(activePrefix == null || !activePrefix.equals(prefix)) { 479 nsStack.add(uri, prefix); 480 } 481 } 482 } 483 484 487 public Message getCurrentMessage() 488 { 489 if (msgContext == null) 490 return null; 491 return msgContext.getCurrentMessage(); 492 } 493 494 497 public MessageContext getMessageContext() { 498 return msgContext; 499 } 500 501 508 public String getEncodingStyle() { 509 return msgContext == null ? Use.DEFAULT.getEncoding() : msgContext.getEncodingStyle(); 510 } 511 512 517 public boolean isEncoded() { 518 return Constants.isSOAP_ENC(getEncodingStyle()); 519 } 520 521 526 public String qName2String(QName qName, boolean writeNS) 527 { 528 String prefix = null; 529 String namespaceURI = qName.getNamespaceURI(); 530 String localPart = qName.getLocalPart(); 531 532 if(localPart != null && localPart.length() > 0) { 533 int index = localPart.indexOf(':'); 534 if(index!=-1){ 535 prefix = localPart.substring(0,index); 536 if(prefix.length()>0 && !prefix.equals("urn")){ 537 registerPrefixForURI(prefix, namespaceURI); 538 localPart = localPart.substring(index+1); 539 } else { 540 prefix = null; 541 } 542 } 543 localPart = Utils.getLastLocalPart(localPart); 544 } 545 546 if (namespaceURI.length() == 0) { 547 if (writeNS) { 548 String defaultNS = nsStack.getNamespaceURI(""); 551 if (defaultNS != null && defaultNS.length() > 0) { 552 registerPrefixForURI("", ""); 553 } 554 } 555 } else { 556 prefix = getPrefixForURI(namespaceURI); 557 } 558 559 if ((prefix == null) || (prefix.length() == 0)) 560 return localPart; 561 562 return prefix + ':' + localPart; 563 } 564 565 public String qName2String(QName qName) 566 { 567 return qName2String(qName, false); 568 } 569 570 579 public String attributeQName2String(QName qName) { 580 String prefix = null; 581 String uri = qName.getNamespaceURI(); 582 if (uri.length() > 0) { 583 prefix = getPrefixForURI(uri, null, true); 584 } 585 586 if ((prefix == null) || (prefix.length() == 0)) 587 return qName.getLocalPart(); 588 589 return prefix + ':' + qName.getLocalPart(); 590 } 591 592 597 public QName getQNameForClass(Class cls) 598 { 599 return getTypeMapping().getTypeQName(cls); 600 } 601 602 610 public boolean isPrimitive(Object value) 611 { 612 if (value == null) return true; 613 614 Class javaType = value.getClass(); 615 616 if (javaType.isPrimitive()) return true; 617 618 if (javaType == String .class) return true; 619 if (Calendar .class.isAssignableFrom(javaType)) return true; 620 if (Date .class.isAssignableFrom(javaType)) return true; 621 if (HexBinary.class.isAssignableFrom(javaType)) return true; 622 if (Element .class.isAssignableFrom(javaType)) return true; 623 if (javaType == byte[].class) return true; 624 625 if (javaType.isArray()) return true; 642 643 QName qName = getQNameForClass(javaType); 648 if (qName != null && Constants.isSchemaXSD(qName.getNamespaceURI())) { 649 if (SchemaUtils.isSimpleSchemaType(qName)) { 650 return true; 651 } 652 } 653 654 return false; 655 } 656 657 673 public void serialize(QName elemQName, 674 Attributes attributes, 675 Object value) 676 throws IOException { 677 serialize(elemQName, attributes, value, null, null, null); 678 } 679 680 697 public void serialize(QName elemQName, 698 Attributes attributes, 699 Object value, 700 QName xmlType) 701 throws IOException { 702 serialize(elemQName, attributes, value, xmlType, null, null); 703 } 704 705 728 public void serialize(QName elemQName, 729 Attributes attributes, 730 Object value, 731 QName xmlType, 732 boolean sendNull, 733 Boolean sendType) 734 throws IOException 735 { 736 serialize( elemQName, attributes, value, xmlType, 737 (sendNull) ? Boolean.TRUE : Boolean.FALSE, 738 sendType); 739 } 740 741 761 public void serialize(QName elemQName, 762 Attributes attributes, 763 Object value, 764 QName xmlType, 765 Boolean sendNull, 766 Boolean sendType) 767 throws IOException 768 { 769 boolean sendXSITypeCache = sendXSIType; 770 if (sendType != null) { 771 sendXSIType = sendType.booleanValue(); 772 } 773 boolean shouldSendType = shouldSendXSIType(); 774 775 try { 776 Boolean sendNullCache = this.sendNull; 777 if (sendNull != null) { 778 this.sendNull = sendNull; 779 } else { 780 sendNull = this.sendNull; 781 } 782 783 if (value == null) { 784 if (this.sendNull.booleanValue()) { 787 AttributesImpl attrs = new AttributesImpl (); 788 if (attributes != null && 0 < attributes.getLength()) 789 attrs.setAttributes(attributes); 790 if (shouldSendType) 791 attrs = (AttributesImpl ) setTypeAttribute(attrs, xmlType); 792 String nil = schemaVersion.getNilQName().getLocalPart(); 793 attrs.addAttribute(schemaVersion.getXsiURI(), nil, "xsi:" + nil, 794 "CDATA", "true"); 795 startElement(elemQName, attrs); 796 endElement(); 797 } 798 this.sendNull = sendNullCache; 799 return; 800 } 801 802 Message msg= getCurrentMessage(); 803 if(null != msg){ 804 Attachments attachments= getCurrentMessage().getAttachmentsImpl(); 806 807 if( null != attachments && attachments.isAttachment(value)){ 808 810 serializeActual(elemQName, attributes, value, 812 xmlType, sendType); 813 814 this.sendNull = sendNullCache; 817 return; 818 } 819 } 820 821 826 835 if (doMultiRefs && isEncoded() && 836 (value != forceSer) && !isPrimitive(value)) { 837 if (multiRefIndex == -1) 838 multiRefValues = new HashMap (); 839 840 String id; 841 842 MultiRefItem mri = (MultiRefItem)multiRefValues.get( 844 getIdentityKey(value)); 845 if (mri == null) { 846 multiRefIndex++; 849 id = "id" + multiRefIndex; 850 mri = new MultiRefItem (id, xmlType, sendType, value); 851 multiRefValues.put(getIdentityKey(value), mri); 852 853 857 if (soapConstants == SOAPConstants.SOAP12_CONSTANTS) { 858 AttributesImpl attrs = new AttributesImpl (); 859 if (attributes != null && 0 < attributes.getLength()) 860 attrs.setAttributes(attributes); 861 attrs.addAttribute("", Constants.ATTR_ID, "id", "CDATA", 862 id); 863 serializeActual(elemQName, attrs, value, xmlType, sendType); 864 this.sendNull = sendNullCache; 865 return; 866 } 867 868 869 882 if (outputMultiRefsFlag) { 883 if (secondLevelObjects == null) 884 secondLevelObjects = new HashSet (); 885 secondLevelObjects.add(getIdentityKey(value)); 886 } 887 } else { 888 id = mri.id; 890 } 891 892 AttributesImpl attrs = new AttributesImpl (); 894 if (attributes != null && 0 < attributes.getLength()) 895 attrs.setAttributes(attributes); 896 attrs.addAttribute("", soapConstants.getAttrHref(), soapConstants.getAttrHref(), 897 "CDATA", '#' + id); 898 899 startElement(elemQName, attrs); 900 endElement(); 901 this.sendNull = sendNullCache; 902 return; 903 } 904 905 if (value == forceSer) 911 forceSer = null; 912 913 serializeActual(elemQName, attributes, value, xmlType, sendType); 915 } finally { 916 sendXSIType = sendXSITypeCache; 917 } 918 } 919 920 929 private IDKey getIdentityKey(Object value) { 930 return new IDKey(value); 931 } 932 933 938 public void outputMultiRefs() throws IOException 939 { 940 if (!doMultiRefs || (multiRefValues == null) || 941 soapConstants == SOAPConstants.SOAP12_CONSTANTS) 942 return; 943 outputMultiRefsFlag = true; 944 AttributesImpl attrs = new AttributesImpl (); 945 attrs.addAttribute("","","","",""); 946 947 String encodingURI = soapConstants.getEncodingURI(); 948 String prefix = getPrefixForURI(encodingURI); 950 String root = prefix + ":root"; 951 attrs.addAttribute(encodingURI, Constants.ATTR_ROOT, root, 952 "CDATA", "0"); 953 954 String encodingStyle; 957 if (msgContext != null) { 958 encodingStyle = msgContext.getEncodingStyle(); 959 } else { 960 encodingStyle = soapConstants.getEncodingURI(); 961 } 962 String encStyle = getPrefixForURI(soapConstants.getEnvelopeURI()) + 963 ':' + Constants.ATTR_ENCODING_STYLE; 964 attrs.addAttribute(soapConstants.getEnvelopeURI(), 965 Constants.ATTR_ENCODING_STYLE, 966 encStyle, 967 "CDATA", 968 encodingStyle); 969 970 HashSet keys = new HashSet (); 973 keys.addAll(multiRefValues.keySet()); 974 Iterator i = keys.iterator(); 975 while (i.hasNext()) { 976 while (i.hasNext()) { 977 AttributesImpl attrs2 = new AttributesImpl (attrs); 978 Object val = i.next(); 979 MultiRefItem mri = (MultiRefItem) multiRefValues.get(val); 980 attrs2.setAttribute(0, "", Constants.ATTR_ID, "id", "CDATA", 981 mri.id); 982 983 forceSer = mri.value; 984 985 serialize(multirefQName, attrs2, mri.value, 990 mri.xmlType, 991 this.sendNull, 992 Boolean.TRUE); } 994 995 if (secondLevelObjects != null) { 1000 i = secondLevelObjects.iterator(); 1001 secondLevelObjects = null; 1002 } 1003 } 1004 1005 forceSer = null; 1007 outputMultiRefsFlag = false; 1008 multiRefValues = null; 1009 multiRefIndex = -1; 1010 secondLevelObjects = null; 1011 } 1012 1013 public void writeXMLDeclaration() throws IOException { 1014 writer.write("<?xml version=\"1.0\" encoding=\""); 1015 writer.write(encoding); 1016 writer.write("\"?>"); 1017 startOfDocument = false; 1018 } 1019 1020 1026 public void startElement(QName qName, Attributes attributes) 1027 throws IOException 1028 { 1029 java.util.ArrayList vecQNames = null; 1030 if (debugEnabled) { 1031 log.debug(Messages.getMessage("startElem00", 1032 "[" + qName.getNamespaceURI() + "]:" + qName.getLocalPart())); 1033 } 1034 1035 if (startOfDocument && sendXMLDecl) { 1036 writeXMLDeclaration(); 1037 } 1038 1039 if (writingStartTag) { 1040 writer.write('>'); 1041 if (pretty) writer.write('\n'); 1042 indent++; 1043 } 1044 1045 if (pretty) for (int i=0; i<indent; i++) writer.write(' '); 1046 String elementQName = qName2String(qName, true); 1047 writer.write('<'); 1048 1049 writer.write(elementQName); 1050 1051 if (writeXMLType != null) { 1052 attributes = setTypeAttribute(attributes, writeXMLType); 1053 writeXMLType = null; 1054 } 1055 1056 if (attributes != null) { 1057 for (int i = 0; i < attributes.getLength(); i++) { 1058 String qname = attributes.getQName(i); 1059 writer.write(' '); 1060 1061 String prefix = ""; 1062 String uri = attributes.getURI(i); 1063 if (uri != null && uri.length() > 0) { 1064 if (qname.length() == 0) { 1065 prefix = getPrefixForURI(uri); 1067 } else { 1068 int idx = qname.indexOf(':'); 1070 if (idx > -1) { 1071 prefix = qname.substring(0, idx); 1072 prefix = getPrefixForURI(uri, 1073 prefix, true); 1074 } 1075 } 1076 if (prefix.length() > 0) { 1077 qname = prefix + ':' + attributes.getLocalName(i); 1078 } else { 1079 qname = attributes.getLocalName(i); 1080 } 1081 } else { 1082 qname = attributes.getQName(i); 1083 if(qname.length() == 0) 1084 qname = attributes.getLocalName(i); 1085 } 1086 1087 if (qname.startsWith("xmlns")) { 1088 if (vecQNames == null) vecQNames = new ArrayList (); 1089 vecQNames.add(qname); 1090 } 1091 writer.write(qname); 1092 writer.write("=\""); 1093 1094 getEncoder().writeEncoded(writer, attributes.getValue(i)); 1095 1096 writer.write('"'); 1097 } 1098 } 1099 1100 if (noNamespaceMappings) { 1101 nsStack.push(); 1102 } else { 1103 for (Mapping map=nsStack.topOfFrame(); map!=null; map=nsStack.next()) { 1104 if (!(map.getNamespaceURI().equals(Constants.NS_URI_XMLNS) && map.getPrefix().equals("xmlns")) && 1105 !(map.getNamespaceURI().equals(Constants.NS_URI_XML) && map.getPrefix().equals("xml"))) 1106 { 1107 StringBuffer sb = new StringBuffer ("xmlns"); 1108 if (map.getPrefix().length() > 0) { 1109 sb.append(':'); 1110 sb.append(map.getPrefix()); 1111 } 1112 if ((vecQNames==null) || (vecQNames.indexOf(sb.toString())==-1)) { 1113 writer.write(' '); 1114 sb.append("=\""); 1115 sb.append(map.getNamespaceURI()); 1116 sb.append('"'); 1117 writer.write(sb.toString()); 1118 } 1119 } 1120 } 1121 1122 noNamespaceMappings = true; 1123 } 1124 1125 writingStartTag = true; 1126 1127 elementStack.push(elementQName); 1128 1129 onlyXML=true; 1130 } 1131 1132 1135 public void endElement() 1136 throws IOException 1137 { 1138 String elementQName = (String )elementStack.pop(); 1139 1140 if (debugEnabled) { 1141 log.debug(Messages.getMessage("endElem00", "" + elementQName)); 1142 } 1143 1144 nsStack.pop(); 1145 1146 if (writingStartTag) { 1147 writer.write("/>"); 1148 if (pretty) writer.write('\n'); 1149 writingStartTag = false; 1150 return; 1151 } 1152 1153 if (onlyXML) { 1154 indent--; 1155 if (pretty) for (int i=0; i<indent; i++) writer.write(' '); 1156 } 1157 writer.write("</"); 1158 writer.write(elementQName); 1159 writer.write('>'); 1160 if (pretty) if (indent>0) writer.write('\n'); 1161 onlyXML=true; 1162 } 1163 1164 1171 public void writeChars(char [] p1, int p2, int p3) 1172 throws IOException 1173 { 1174 if (startOfDocument && sendXMLDecl) { 1175 writeXMLDeclaration(); 1176 } 1177 1178 if (writingStartTag) { 1179 writer.write('>'); 1180 writingStartTag = false; 1181 } 1182 writeSafeString(String.valueOf(p1,p2,p3)); 1183 onlyXML=false; 1184 } 1185 1186 1190 public void writeString(String string) 1191 throws IOException 1192 { 1193 if (startOfDocument && sendXMLDecl) { 1194 writeXMLDeclaration(); 1195 } 1196 1197 if (writingStartTag) { 1198 writer.write('>'); 1199 writingStartTag = false; 1200 } 1201 writer.write(string); 1202 onlyXML=false; 1203 } 1204 1205 1210 public void writeSafeString(String string) 1211 throws IOException 1212 { 1213 if (startOfDocument && sendXMLDecl) { 1214 writeXMLDeclaration(); 1215 } 1216 1217 if (writingStartTag) { 1218 writer.write('>'); 1219 writingStartTag = false; 1220 } 1221 1222 getEncoder().writeEncoded(writer, string); 1223 onlyXML=false; 1224 } 1225 1226 1230 public void writeDOMElement(Element el) 1231 throws IOException 1232 { 1233 if (startOfDocument && sendXMLDecl) { 1234 writeXMLDeclaration(); 1235 } 1236 1237 if (el instanceof org.apache.axis.message.Text) { 1239 writeSafeString(((Text )el).getData()); 1240 return; 1241 } 1242 1243 AttributesImpl attributes = null; 1244 NamedNodeMap attrMap = el.getAttributes(); 1245 1246 if (attrMap.getLength() > 0) { 1247 attributes = new AttributesImpl (); 1248 for (int i = 0; i < attrMap.getLength(); i++) { 1249 Attr attr = (Attr )attrMap.item(i); 1250 String tmp = attr.getNamespaceURI(); 1251 if ( tmp != null && tmp.equals(Constants.NS_URI_XMLNS) ) { 1252 String prefix = attr.getLocalName(); 1253 if (prefix != null) { 1254 if (prefix.equals("xmlns")) 1255 prefix = ""; 1256 String nsURI = attr.getValue(); 1257 registerPrefixForURI(prefix, nsURI); 1258 } 1259 continue; 1260 } 1261 1262 attributes.addAttribute(attr.getNamespaceURI(), 1263 attr.getLocalName(), 1264 attr.getName(), 1265 "CDATA", attr.getValue()); 1266 } 1267 } 1268 1269 String namespaceURI = el.getNamespaceURI(); 1270 String localPart = el.getLocalName(); 1271 if(namespaceURI == null || namespaceURI.length()==0) 1272 localPart = el.getNodeName(); 1273 QName qName = new QName (namespaceURI, localPart); 1274 1275 startElement(qName, attributes); 1276 1277 NodeList children = el.getChildNodes(); 1278 for (int i = 0; i < children.getLength(); i++) { 1279 Node child = children.item(i); 1280 if (child instanceof Element ) { 1281 writeDOMElement((Element )child); 1282 } else if (child instanceof CDATASection ) { 1283 writeString("<![CDATA["); 1284 writeString(((Text )child).getData()); 1285 writeString("]]>"); 1286 } else if (child instanceof Comment ) { 1287 writeString("<!--"); 1288 writeString(((CharacterData )child).getData()); 1289 writeString("-->"); 1290 } else if (child instanceof Text ) { 1291 writeSafeString(((Text )child).getData()); 1292 } 1293 } 1294 1295 endElement(); 1296 } 1297 1298 1304 public final Serializer getSerializerForJavaType(Class javaType) { 1305 SerializerFactory serF = null; 1306 Serializer ser = null; 1307 try { 1308 serF = (SerializerFactory) getTypeMapping().getSerializer(javaType); 1309 if (serF != null) { 1310 ser = (Serializer) serF.getSerializerAs(Constants.AXIS_SAX); 1311 } 1312 } catch (JAXRPCException e) { 1313 } 1314 1315 return ser; 1316 } 1317 1318 1324 public Attributes setTypeAttribute(Attributes attributes, QName type) 1325 { 1326 if (type == null || 1327 type.getLocalPart().indexOf(SymbolTable.ANON_TOKEN) >= 0 || 1328 ((attributes != null) && 1329 (attributes.getIndex(Constants.URI_DEFAULT_SCHEMA_XSI, 1330 "type") != -1))) 1331 return attributes; 1332 1333 AttributesImpl attrs = new AttributesImpl (); 1334 if (attributes != null && 0 < attributes.getLength() ) 1335 attrs.setAttributes(attributes); 1336 1337 String prefix = getPrefixForURI(Constants.URI_DEFAULT_SCHEMA_XSI, 1338 "xsi"); 1339 1340 attrs.addAttribute(Constants.URI_DEFAULT_SCHEMA_XSI, 1341 "type", 1342 prefix + ":type", 1343 "CDATA", attributeQName2String(type)); 1344 return attrs; 1345 } 1346 1347 1356 private void serializeActual(QName elemQName, 1357 Attributes attributes, 1358 Object value, 1359 QName xmlType, 1360 Boolean sendType) 1361 throws IOException 1362 { 1363 boolean shouldSendType = (sendType == null) ? shouldSendXSIType() : 1364 sendType.booleanValue(); 1365 1366 if (value != null) { 1367 Class javaType = value.getClass(); 1368 TypeMapping tm = getTypeMapping(); 1369 1370 if (tm == null) { 1371 throw new IOException ( 1372 Messages.getMessage("noSerializer00", 1373 value.getClass().getName(), 1374 "" + this)); 1375 } 1376 1377 currentXMLType = xmlType; 1381 1382 if (Constants.equals(Constants.XSD_ANYTYPE,xmlType)){ 1384 xmlType = null; 1385 shouldSendType = true; 1386 } 1387 1388 QNameHolder actualXMLType = new QNameHolder (); 1390 Serializer ser = getSerializer(javaType, xmlType, 1391 actualXMLType); 1392 1393 if ( ser != null ) { 1394 if (shouldSendType || 1398 (xmlType != null && 1399 (!xmlType.equals(actualXMLType.value)))) { 1400 1401 if(!isEncoded()) { 1402 if (Constants.isSOAP_ENC(actualXMLType.value.getNamespaceURI())) { 1403 } else { 1405 if(!(javaType.isArray() && xmlType != null && Constants.isSchemaXSD(xmlType.getNamespaceURI())) ) { 1406 writeXMLType = actualXMLType.value; 1407 } 1408 } 1409 } else { 1410 writeXMLType = actualXMLType.value; 1411 } 1412 } 1413 1414 ser.serialize(elemQName, attributes, value, this); 1427 return; 1428 } 1429 throw new IOException (Messages.getMessage("noSerializer00", 1430 value.getClass().getName(), "" + tm)); 1431 } 1432 } 1434 1435 private Serializer getSerializerFromClass(Class javaType, QName qname) { 1436 1437 Serializer serializer = null; 1438 try { 1439 Method method = 1440 MethodCache.getInstance().getMethod(javaType, 1441 SERIALIZER_METHOD, 1442 SERIALIZER_CLASSES); 1443 if (method != null) { 1444 serializer = (Serializer) method.invoke(null, 1445 new Object [] {getEncodingStyle(), javaType, qname}); 1446 } 1447 } catch (NoSuchMethodException e) { 1448 } catch (IllegalAccessException e) { 1449 } catch (InvocationTargetException e) { 1450 } 1451 return serializer; 1452 } 1453 1454 1458 public QName getCurrentXMLType() { 1459 return currentXMLType; 1460 } 1461 1462 1467 private SerializerFactory getSerializerFactoryFromInterface(Class javaType, 1468 QName xmlType, 1469 TypeMapping tm) 1470 { 1471 SerializerFactory serFactory = null ; 1472 Class [] interfaces = javaType.getInterfaces(); 1473 if (interfaces != null) { 1474 for (int i = 0; i < interfaces.length; i++) { 1475 Class iface = interfaces[i]; 1476 serFactory = (SerializerFactory) tm.getSerializer(iface, 1477 xmlType); 1478 if (serFactory == null) 1479 serFactory = getSerializerFactoryFromInterface(iface, xmlType, tm); 1480 if (serFactory != null) 1481 break; 1482 1483 } 1484 } 1485 return serFactory; 1486 } 1487 1488 1497 private Serializer getSerializer(Class javaType, QName xmlType, 1498 QNameHolder actualXMLType) { 1499 SerializerFactory serFactory = null ; 1500 TypeMapping tm = getTypeMapping(); 1501 if (actualXMLType != null) { 1502 actualXMLType.value = null; 1503 } 1504 1505 while (javaType != null) { 1506 serFactory = (SerializerFactory) tm.getSerializer(javaType, xmlType); 1508 if (serFactory != null) { 1509 break; 1510 } 1511 1512 Serializer serializer = getSerializerFromClass(javaType, xmlType); 1514 if (serializer != null) { 1515 if (actualXMLType != null) { 1516 TypeDesc typedesc = TypeDesc.getTypeDescForClass(javaType); 1517 if (typedesc != null) { 1518 actualXMLType.value = typedesc.getXmlType(); 1519 } 1520 } 1521 return serializer; 1522 } 1523 1524 serFactory = getSerializerFactoryFromInterface(javaType, xmlType, tm); 1526 if (serFactory != null) { 1527 break; 1528 } 1529 1530 javaType = javaType.getSuperclass(); 1532 } 1533 1534 Serializer ser = null; 1536 if ( serFactory != null ) { 1537 ser = (Serializer) serFactory.getSerializerAs(Constants.AXIS_SAX); 1538 1539 if (actualXMLType != null) { 1540 if (serFactory instanceof BaseSerializerFactory) { 1544 actualXMLType.value = 1545 ((BaseSerializerFactory) serFactory).getXMLType(); 1546 } 1547 boolean encoded = isEncoded(); 1548 if (actualXMLType.value == null || 1549 (!encoded && 1550 (actualXMLType.value.equals(Constants.SOAP_ARRAY) || 1551 actualXMLType.value.equals(Constants.SOAP_ARRAY12)))) { 1552 actualXMLType.value = tm.getXMLType(javaType, 1553 xmlType, 1554 encoded); 1555 } 1556 } 1557 } 1558 1559 return ser; 1560 } 1561 1562 public String getValueAsString(Object value, QName xmlType) throws IOException { 1563 Class cls = value.getClass(); 1564 Serializer ser = getSerializer(cls, xmlType, null); 1565 if (!(ser instanceof SimpleValueSerializer)) { 1566 throw new IOException ( 1567 Messages.getMessage("needSimpleValueSer", 1568 ser.getClass().getName())); 1569 } 1570 SimpleValueSerializer simpleSer = (SimpleValueSerializer)ser; 1571 return simpleSer.getValueAsString(value, this); 1572 } 1573 1574 public void setWriteXMLType(QName type) { 1575 writeXMLType = type; 1576 } 1577 1578 public XMLEncoder getEncoder() { 1579 if(encoder == null) { 1580 encoder = XMLUtils.getXMLEncoder(encoding); 1581 } 1582 return encoder; 1583 } 1584 1585 1589 public String getEncoding() { 1590 return encoding; 1591 } 1592 1593 1596 public void setEncoding(String encoding) { 1597 this.encoding = encoding; 1598 } 1599 1600 public QName getItemQName() { 1601 return itemQName; 1602 } 1603 1604 public void setItemQName(QName itemQName) { 1605 this.itemQName = itemQName; 1606 } 1607 1608 public QName getItemType() { 1609 return itemType; 1610 } 1611 1612 public void setItemType(QName itemType) { 1613 this.itemType = itemType; 1614 } 1615} | Popular Tags |