KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > axis > encoding > ser > BeanSerializer


1 /*
2  * The Apache Software License, Version 1.1
3  *
4  *
5  * Copyright (c) 2001-2003 The Apache Software Foundation. All rights
6  * reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright
16  * notice, this list of conditions and the following disclaimer in
17  * the documentation and/or other materials provided with the
18  * distribution.
19  *
20  * 3. The end-user documentation included with the redistribution,
21  * if any, must include the following acknowledgment:
22  * "This product includes software developed by the
23  * Apache Software Foundation (http://www.apache.org/)."
24  * Alternately, this acknowledgment may appear in the software itself,
25  * if and wherever such third-party acknowledgments normally appear.
26  *
27  * 4. The names "Axis" and "Apache Software Foundation" must
28  * not be used to endorse or promote products derived from this
29  * software without prior written permission. For written
30  * permission, please contact apache@apache.org.
31  *
32  * 5. Products derived from this software may not be called "Apache",
33  * nor may "Apache" appear in their name, without prior written
34  * permission of the Apache Software Foundation.
35  *
36  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39  * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
40  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47  * SUCH DAMAGE.
48  * ====================================================================
49  *
50  * This software consists of voluntary contributions made by many
51  * individuals on behalf of the Apache Software Foundation. For more
52  * information on the Apache Software Foundation, please see
53  * <http://www.apache.org/>.
54  */

55
56 package org.jboss.axis.encoding.ser;
57
58 import org.jboss.axis.AxisFault;
59 import org.jboss.axis.Constants;
60 import org.jboss.axis.MessageContext;
61 import org.jboss.axis.description.ElementDesc;
62 import org.jboss.axis.description.FieldDesc;
63 import org.jboss.axis.description.OperationDesc;
64 import org.jboss.axis.description.TypeDesc;
65 import org.jboss.axis.encoding.SerializationContext;
66 import org.jboss.axis.encoding.Serializer;
67 import org.jboss.axis.enums.Style;
68 import org.jboss.axis.message.SOAPElementAxisImpl;
69 import org.jboss.axis.soap.SOAPConstants;
70 import org.jboss.axis.utils.BeanPropertyDescriptor;
71 import org.jboss.axis.utils.BeanUtils;
72 import org.jboss.axis.utils.JavaUtils;
73 import org.jboss.axis.utils.Messages;
74 import org.jboss.axis.wsdl.fromJava.Types;
75 import org.jboss.logging.Logger;
76 import org.w3c.dom.Element JavaDoc;
77 import org.xml.sax.Attributes JavaDoc;
78 import org.xml.sax.helpers.AttributesImpl JavaDoc;
79
80 import javax.xml.namespace.QName JavaDoc;
81 import java.io.IOException JavaDoc;
82 import java.lang.reflect.Array JavaDoc;
83 import java.lang.reflect.InvocationTargetException JavaDoc;
84 import java.lang.reflect.Modifier JavaDoc;
85 import java.util.List JavaDoc;
86
87 /**
88  * General purpose serializer/deserializerFactory for an arbitrary java bean.
89  *
90  * @author Sam Ruby <rubys@us.ibm.com>
91  * @author Rich Scheuerle <scheu@us.ibm.com>
92  * @author Tom Jordahl <tomj@macromedia.com>
93  */

94 public class BeanSerializer implements Serializer
95 {
96    private static Logger log = Logger.getLogger(BeanSerializer.class.getName());
97
98    QName JavaDoc xmlType;
99    Class JavaDoc javaType;
100
101    protected BeanPropertyDescriptor[] propertyDescriptor;
102    protected TypeDesc typeDesc;
103
104
105    // Construct BeanSerializer for the indicated class/qname
106
public BeanSerializer(Class JavaDoc javaType, QName JavaDoc xmlType)
107    {
108       this(javaType, xmlType, TypeDesc.getTypeDescForClass(javaType));
109    }
110
111    // Construct BeanSerializer for the indicated class/qname
112
public BeanSerializer(Class JavaDoc javaType, QName JavaDoc xmlType, TypeDesc typeDesc)
113    {
114       this.xmlType = xmlType;
115       this.javaType = javaType;
116       this.typeDesc = typeDesc;
117
118       if (typeDesc != null)
119       {
120          propertyDescriptor = typeDesc.getPropertyDescriptors();
121       }
122       else
123       {
124          propertyDescriptor = BeanUtils.getPd(javaType, null);
125       }
126    }
127
128    // Construct BeanSerializer for the indicated class/qname/propertyDesc
129
public BeanSerializer(Class JavaDoc javaType, QName JavaDoc xmlType, TypeDesc typeDesc,
130                          BeanPropertyDescriptor[] propertyDescriptor)
131    {
132       this.xmlType = xmlType;
133       this.javaType = javaType;
134       this.typeDesc = typeDesc;
135       this.propertyDescriptor = propertyDescriptor;
136    }
137
138    /**
139     * Serialize a bean. Done simply by serializing each bean property.
140     *
141     * @param name is the element name
142     * @param attributes are the attributes...serialize is free to add more.
143     * @param value is the value
144     * @param context is the SerializationContext
145     */

146    public void serialize(QName JavaDoc name, Attributes JavaDoc attributes,
147                          Object JavaDoc value, SerializationContext context)
148            throws IOException JavaDoc
149    {
150
151       log.debug("serialize [name=" + name + ",value=" + value + "]");
152
153       MessageContext messageContext = context.getMessageContext();
154       OperationDesc operation = messageContext.getOperation();
155
156       // For document style make sure the bean has a qualified name
157
// and there is no default namespace
158
// TDI 24-June-2004
159
if (operation != null && operation.getStyle() == Style.DOCUMENT)
160       {
161          String JavaDoc uri = name.getNamespaceURI();
162          String JavaDoc prefix = name.getPrefix();
163          if (prefix.length() == 0 && uri.length() > 0)
164          {
165             // If this uri was registered as the default namespace, we get the empty prefix
166
prefix = context.getPrefixForURI(uri);
167             if (prefix.equals("")) prefix = "ns1";
168             name = new QName JavaDoc(uri, name.getLocalPart(), prefix);
169             context.registerPrefixForURI(prefix, uri);
170             context.setNoDefaultNamespace(true);
171          }
172       }
173
174       // Check for meta-data in the bean that will tell us if any of the
175
// properties are actually attributes, add those to the element
176
// attribute list
177
Attributes JavaDoc beanAttrs = getObjectAttributes(value, attributes, context);
178
179       // Get the encoding style
180
String JavaDoc encodingStyle = messageContext.getEncodingStyle();
181       boolean isEncoded = Constants.isSOAP_ENC(encodingStyle);
182
183       // check whether we have and xsd:any namespace="##any" type
184
boolean suppressElement = !context.getMessageContext().isEncoded() &&
185               name.getNamespaceURI().equals("") &&
186               name.getLocalPart().equals("any");
187
188       if (!suppressElement)
189       {
190          context.startElement(name, beanAttrs);
191       }
192
193       try
194       {
195          // Serialize each property
196
for (int i = 0; i < propertyDescriptor.length; i++)
197          {
198             BeanPropertyDescriptor bpDesc = propertyDescriptor[i];
199
200             String JavaDoc propName = bpDesc.getName();
201             if (propName.equals("class"))
202                continue;
203
204             QName JavaDoc qname = null;
205             QName JavaDoc xmlType = null;
206             QName JavaDoc itemXmlType = null;
207             boolean isOmittable = false;
208
209             // If we have type metadata, check to see what we're doing
210
// with this field. If it's an attribute, skip it. If it's
211
// an element, use whatever qname is in there. If we can't
212
// find any of this info, use the default.
213

214             if (typeDesc != null)
215             {
216                FieldDesc field = typeDesc.getFieldByName(propName);
217                if (field == null)
218                {
219                   String JavaDoc upperName = propName.substring(0, 1).toUpperCase() + propName.substring(1);
220                   field = typeDesc.getFieldByName(upperName);
221                }
222                
223                if (field != null)
224                {
225
226                   if (!field.isElement())
227                      continue;
228
229                   // This is a very special case where a property wants to be serialized
230
// as bean content. Allowing mixed content.
231
// TDI 22-Jun-2004
232
if (((ElementDesc)field).isAsContent())
233                   {
234                      Object JavaDoc propValue = bpDesc.get(value);
235                      String JavaDoc strval = context.getValueAsString(propValue, xmlType);
236                      context.writeSafeString(strval);
237                      continue;
238                   }
239
240                   itemXmlType = ((ElementDesc)field).getItemXmlType();
241
242                   // If we're SOAP encoded, just use the local part,
243
// not the namespace. Otherwise use the whole
244
// QName.
245
if (isEncoded)
246                   {
247                      qname = new QName JavaDoc(field.getXmlName().getLocalPart());
248                   }
249                   else
250                   {
251                      qname = field.getXmlName();
252                   }
253                   isOmittable = field.isMinOccursZero();
254                   xmlType = field.getXmlType();
255                }
256             }
257
258             if (qname == null)
259             {
260                qname = new QName JavaDoc(propName);
261             }
262
263             if (xmlType == null)
264             {
265                // look up the type QName using the class
266
xmlType = context.getQNameForClass(bpDesc.getType());
267             }
268
269             // Read the value from the property
270
if (bpDesc.isReadable())
271             {
272                if (!bpDesc.isIndexed())
273                {
274                   // Normal case: serialize the value
275
Object JavaDoc propValue = bpDesc.get(value);
276                   // if meta data says minOccurs=0, then we can skip
277
// it if its value is null and we aren't doing SOAP
278
// encoding.
279
if (propValue == null && isOmittable && !isEncoded)
280                      continue;
281
282                   // If this is literal style and the propValue is an Array
283
// serialize each item as if it was the property.
284
// This should probably be handled by a LiteralArraySerializer.
285
// TDI 20-June-2004
286
// com/sun/ts/tests/interop/webservices/jaxrpc/wsi/rpc/literal/marshalltest#MarshallJavaArrayTest
287
if (!isEncoded && propValue != null && JavaUtils.isArrayClass(propValue.getClass())
288                           && !Constants.XSD_BASE64.equals(xmlType) && !Constants.XSD_HEXBIN.equals(xmlType))
289                   {
290                      QName JavaDoc itemType;
291
292                      if (itemXmlType == null)
293                      {
294                         Class JavaDoc componentType = propValue.getClass().getComponentType();
295                         itemType = context.getQNameForClass(componentType);
296                      }
297                      else
298                      {
299                         itemType = itemXmlType;
300                      }
301
302                      log.debug("Item type is " + itemType);
303                      for (int j = 0; j < Array.getLength(propValue); j++)
304                      {
305                         Object JavaDoc item = Array.get(propValue, j);
306                         context.serialize(qname, null, item, itemType, true, new Boolean JavaDoc(false));
307                      }
308                   }
309                   else
310                   {
311                      context.serialize(qname, null, propValue, xmlType, true, new Boolean JavaDoc(isEncoded));
312                   }
313                }
314                else
315                {
316                   // Collection of properties: serialize each one
317
int j = 0;
318                   while (j >= 0)
319                   {
320                      Object JavaDoc propValue = null;
321                      try
322                      {
323                         propValue = bpDesc.get(value, j);
324                         j++;
325                      }
326                      catch (Exception JavaDoc e)
327                      {
328                         j = -1;
329                      }
330                      if (j >= 0)
331                      {
332                         context.serialize(qname, null,
333                                 propValue, xmlType,
334                                 true, null);
335                      }
336                   }
337                }
338             }
339          }
340
341          BeanPropertyDescriptor anyDesc = typeDesc == null ? null : typeDesc.getAnyDesc();
342
343          if (anyDesc != null)
344          {
345             // If we have "extra" content here, it'll be an array
346
// of MessageElements. Serialize each one.
347
Object JavaDoc anyVal = anyDesc.get(value);
348             if (anyVal != null && anyVal instanceof SOAPElementAxisImpl[])
349             {
350                SOAPElementAxisImpl[] anyContent = (SOAPElementAxisImpl[])anyVal;
351                for (int i = 0; i < anyContent.length; i++)
352                {
353                   SOAPElementAxisImpl element = anyContent[i];
354                   element.output(context);
355                }
356             }
357          }
358       }
359       catch (InvocationTargetException JavaDoc ite)
360       {
361          Throwable JavaDoc target = ite.getTargetException();
362          log.error(Messages.getMessage("exception00"), target);
363          throw new IOException JavaDoc(target.toString());
364       }
365       catch (Exception JavaDoc e)
366       {
367          log.error(Messages.getMessage("exception00"), e);
368          throw new IOException JavaDoc(e.toString());
369       }
370
371       if (!suppressElement)
372          context.endElement();
373    }
374
375
376    public String JavaDoc getMechanismType()
377    {
378       return Constants.AXIS_SAX;
379    }
380
381    /**
382     * Return XML schema for the specified type, suitable for insertion into
383     * the &lt;types&gt; element of a WSDL document, or underneath an
384     * &lt;element&gt; or &lt;attribute&gt; declaration.
385     *
386     * @param javaType the Java Class we're writing out schema for
387     * @param types the Java2WSDL Types object which holds the context
388     * for the WSDL being generated.
389     * @return a type element containing a schema simpleType/complexType
390     * @see org.jboss.axis.wsdl.fromJava.Types
391     */

392    public Element JavaDoc writeSchema(Class JavaDoc javaType, Types types) throws Exception JavaDoc
393    {
394
395       // ComplexType representation of bean class
396
Element JavaDoc complexType = types.createElement("complexType");
397
398       // See if there is a super class, stop if we hit a stop class
399
Element JavaDoc e = null;
400       Class JavaDoc superClass = javaType.getSuperclass();
401       BeanPropertyDescriptor[] superPd = null;
402       List JavaDoc stopClasses = types.getStopClasses();
403       if (superClass != null &&
404               superClass != java.lang.Object JavaDoc.class &&
405               superClass != java.lang.Exception JavaDoc.class &&
406               superClass != java.lang.Throwable JavaDoc.class &&
407               superClass != java.rmi.RemoteException JavaDoc.class &&
408               superClass != org.jboss.axis.AxisFault.class &&
409               (stopClasses == null ||
410               !(stopClasses.contains(superClass.getName()))))
411       {
412          // Write out the super class
413
String JavaDoc base = types.writeType(superClass);
414          Element JavaDoc complexContent = types.createElement("complexContent");
415          complexType.appendChild(complexContent);
416          Element JavaDoc extension = types.createElement("extension");
417          complexContent.appendChild(extension);
418          extension.setAttribute("base", base);
419          e = extension;
420          // Get the property descriptors for the super class
421
TypeDesc superTypeDesc = TypeDesc.getTypeDescForClass(superClass);
422          if (superTypeDesc != null)
423          {
424             superPd = superTypeDesc.getPropertyDescriptors();
425          }
426          else
427          {
428             superPd = BeanUtils.getPd(superClass, null);
429          }
430       }
431       else
432       {
433          e = complexType;
434       }
435
436       // Add fields under sequence element.
437
// Note: In most situations it would be okay
438
// to put the fields under an all element.
439
// However it is illegal schema to put an
440
// element with minOccurs=0 or maxOccurs>1 underneath
441
// an all element. This is the reason why a sequence
442
// element is used.
443
Element JavaDoc all = types.createElement("sequence");
444       e.appendChild(all);
445
446       if (Modifier.isAbstract(javaType.getModifiers()))
447       {
448          complexType.setAttribute("abstract", "true");
449       }
450
451       // Serialize each property
452
for (int i = 0; i < propertyDescriptor.length; i++)
453       {
454          String JavaDoc propName = propertyDescriptor[i].getName();
455
456          // Don't serializer properties named class
457
boolean writeProperty = true;
458          if (propName.equals("class"))
459          {
460             writeProperty = false;
461          }
462
463          // Don't serialize the property if it is present
464
// in the super class property list
465
if (superPd != null && writeProperty)
466          {
467             for (int j = 0; j < superPd.length && writeProperty; j++)
468             {
469                if (propName.equals(superPd[j].getName()))
470                {
471                   writeProperty = false;
472                }
473             }
474          }
475          if (!writeProperty)
476          {
477             continue;
478          }
479
480          Class JavaDoc fieldType = propertyDescriptor[i].getType();
481
482          // If we have type metadata, check to see what we're doing
483
// with this field. If it's an attribute, skip it. If it's
484
// an element, use whatever qname is in there. If we can't
485
// find any of this info, use the default.
486

487          if (typeDesc != null)
488          {
489             FieldDesc field = typeDesc.getFieldByName(propName);
490
491             if (field != null)
492             {
493                QName JavaDoc qname = field.getXmlName();
494                QName JavaDoc fieldXmlType = field.getXmlType();
495                boolean isAnonymous = fieldXmlType != null && fieldXmlType.getLocalPart().startsWith(">");
496
497                if (qname != null)
498                {
499                   // FIXME!
500
// Check to see if this is in the right namespace -
501
// if it's not, we need to use an <element ref="">
502
// to represent it!!!
503

504                   // Use the default...
505
propName = qname.getLocalPart();
506                }
507                if (!field.isElement())
508                {
509                   writeAttribute(types,
510                           propName,
511                           fieldType,
512                           fieldXmlType,
513                           complexType);
514                }
515                else
516                {
517                   writeField(types,
518                           propName,
519                           fieldType,
520                           propertyDescriptor[i].isIndexed(),
521                           field.isMinOccursZero(),
522                           all, isAnonymous);
523                }
524             }
525             else
526             {
527                writeField(types,
528                        propName,
529                        fieldType,
530                        propertyDescriptor[i].isIndexed(), false, all, false);
531             }
532          }
533          else
534          {
535             writeField(types,
536                     propName,
537                     fieldType,
538                     propertyDescriptor[i].isIndexed(), false, all, false);
539          }
540       }
541
542       // done
543
return complexType;
544    }
545
546    /**
547     * write a schema representation of the given Class field and append it to
548     * the where Node, recurse on complex types
549     *
550     * @param fieldName name of the field
551     * @param fieldType type of the field
552     * @param isUnbounded causes maxOccurs="unbounded" if set
553     * @param where location for the generated schema node
554     * @throws Exception
555     */

556    protected void writeField(Types types, String JavaDoc fieldName,
557                              Class JavaDoc fieldType,
558                              boolean isUnbounded,
559                              boolean isOmittable,
560                              Element JavaDoc where,
561                              boolean isAnonymous) throws Exception JavaDoc
562    {
563       Element JavaDoc elem;
564       if (isAnonymous)
565       {
566          elem = types.createElementWithAnonymousType(fieldName,
567                  fieldType, isOmittable, where.getOwnerDocument());
568       }
569       else
570       {
571          String JavaDoc elementType = types.writeType(fieldType);
572
573          if (elementType == null)
574          {
575             // If writeType returns null, then emit an anytype in such situations.
576
QName JavaDoc anyQN = Constants.XSD_ANYTYPE;
577             String JavaDoc prefix = types.getNamespaces().getCreatePrefix(anyQN.getNamespaceURI());
578             elementType = prefix + ":" + anyQN.getLocalPart();
579          }
580
581          elem = types.createElement(fieldName,
582                  elementType,
583                  types.isNullable(fieldType),
584                  isOmittable,
585                  where.getOwnerDocument());
586       }
587
588       if (isUnbounded)
589       {
590          elem.setAttribute("maxOccurs", "unbounded");
591       }
592
593       where.appendChild(elem);
594    }
595
596    /**
597     * write aa attribute element and append it to the 'where' Node
598     *
599     * @param fieldName name of the field
600     * @param fieldType type of the field
601     * @param where location for the generated schema node
602     * @throws Exception
603     */

604    protected void writeAttribute(Types types,
605                                  String JavaDoc fieldName,
606                                  Class JavaDoc fieldType,
607                                  QName JavaDoc fieldXmlType,
608                                  Element JavaDoc where) throws Exception JavaDoc
609    {
610
611       // Attribute must be a simple type.
612
if (!types.isAcceptableAsAttribute(fieldType))
613       {
614          throw new AxisFault(Messages.getMessage("AttrNotSimpleType00",
615                  fieldName,
616                  fieldType.getName()));
617       }
618       Element JavaDoc elem = types.createAttributeElement(fieldName,
619               fieldType, fieldXmlType,
620               false,
621               where.getOwnerDocument());
622       where.appendChild(elem);
623    }
624
625    /**
626     * Check for meta-data in the bean that will tell us if any of the
627     * properties are actually attributes, add those to the element
628     * attribute list
629     *
630     * @param value the object we are serializing
631     * @return attributes for this element, null if none
632     */

633    protected Attributes JavaDoc getObjectAttributes(Object JavaDoc value,
634                                             Attributes JavaDoc attributes,
635                                             SerializationContext context)
636    {
637
638       if (typeDesc == null || !typeDesc.hasAttributes())
639          return attributes;
640
641       AttributesImpl JavaDoc attrs;
642       if (attributes == null)
643       {
644          attrs = new AttributesImpl JavaDoc();
645       }
646       else if (attributes instanceof AttributesImpl JavaDoc)
647       {
648          attrs = (AttributesImpl JavaDoc)attributes;
649       }
650       else
651       {
652          attrs = new AttributesImpl JavaDoc(attributes);
653       }
654
655       try
656       {
657          // Find each property that is an attribute
658
// and add it to our attribute list
659
for (int i = 0; i < propertyDescriptor.length; i++)
660          {
661             String JavaDoc propName = propertyDescriptor[i].getName();
662             if (propName.equals("class"))
663                continue;
664
665             FieldDesc field = typeDesc.getFieldByName(propName);
666             // skip it if its not an attribute
667
if (field == null || field.isElement())
668                continue;
669
670             QName JavaDoc qname = field.getXmlName();
671             if (qname == null)
672             {
673                qname = new QName JavaDoc("", propName);
674             }
675
676             if (propertyDescriptor[i].isReadable() &&
677                     !propertyDescriptor[i].isIndexed())
678             {
679                // add to our attributes
680
Object JavaDoc propValue = propertyDescriptor[i].get(value);
681                // If the property value does not exist, don't serialize
682
// the attribute. In the future, the decision to serializer
683
// the attribute may be more sophisticated. For example, don't
684
// serialize if the attribute matches the default value.
685
if (propValue != null)
686                {
687                   setAttributeProperty(propValue, qname, attrs, context);
688                }
689             }
690          }
691       }
692       catch (Exception JavaDoc e)
693       {
694          // no attributes
695
return attrs;
696       }
697
698       return attrs;
699    }
700
701    private void setAttributeProperty(Object JavaDoc propValue,
702                                      QName JavaDoc qname,
703                                      AttributesImpl JavaDoc attrs,
704                                      SerializationContext context) throws Exception JavaDoc
705    {
706       String JavaDoc propString = context.getValueAsString(propValue, null);
707       String JavaDoc namespace = qname.getNamespaceURI();
708       String JavaDoc localName = qname.getLocalPart();
709
710       // Force SOAP Envelope namespace on known header element attributes
711
// com/sun/ts/tests/jaxrpc/ee/wsi/document/literal/headertest uses a bean with mustUnderstand property
712
SOAPConstants soapConstants = context.getMessageContext().getSOAPConstants();
713       QName JavaDoc parentElementQName = (QName JavaDoc)context.getElementStack().peek();
714       QName JavaDoc headerQName = soapConstants.getHeaderQName();
715       if (headerQName.equals(parentElementQName))
716       {
717          if (localName.equals("mustUnderstand") || localName.equals("role"))
718          {
719             namespace = soapConstants.getEnvelopeURI();
720          }
721       }
722
723       attrs.addAttribute(namespace,
724               localName,
725               context.attributeQName2String(qname),
726               "CDATA",
727               propString);
728    }
729 }
730
Popular Tags