KickJava   Java API By Example, From Geeks To Geeks.

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


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

54
55 package org.jboss.axis.encoding.ser;
56
57 import org.jboss.axis.Constants;
58 import org.jboss.axis.description.ElementDesc;
59 import org.jboss.axis.description.FieldDesc;
60 import org.jboss.axis.description.TypeDesc;
61 import org.jboss.axis.encoding.DeserializationContext;
62 import org.jboss.axis.encoding.Deserializer;
63 import org.jboss.axis.encoding.DeserializerImpl;
64 import org.jboss.axis.encoding.TypeMapping;
65 import org.jboss.axis.message.SOAPElementAxisImpl;
66 import org.jboss.axis.message.SOAPHandler;
67 import org.jboss.axis.soap.SOAPConstants;
68 import org.jboss.axis.utils.BeanPropertyDescriptor;
69 import org.jboss.axis.utils.JavaUtils;
70 import org.jboss.axis.utils.Messages;
71 import org.jboss.logging.Logger;
72 import org.xml.sax.Attributes JavaDoc;
73 import org.xml.sax.SAXException JavaDoc;
74
75 import javax.xml.namespace.QName JavaDoc;
76 import java.lang.reflect.Constructor JavaDoc;
77 import java.util.ArrayList JavaDoc;
78 import java.util.Iterator JavaDoc;
79 import java.util.Map JavaDoc;
80
81 /**
82  * General purpose deserializer for an arbitrary java bean.
83  *
84  * @author Sam Ruby <rubys@us.ibm.com>
85  * @author Rich Scheuerle <scheu@us.ibm.com>
86  * @author Tom Jordahl <tomj@macromedia.com>
87  */

88 public class BeanDeserializer extends DeserializerImpl
89 {
90    private static Logger log = Logger.getLogger(BeanDeserializer.class.getName());
91
92    QName JavaDoc xmlType;
93    Class JavaDoc javaType;
94    protected Map JavaDoc propertyMap;
95    protected QName JavaDoc prevQName;
96
97    /**
98     * Type metadata about this class for XML deserialization
99     */

100    protected TypeDesc typeDesc = null;
101
102    // This counter is updated to deal with deserialize collection properties
103
protected int collectionIndex = -1;
104
105    protected SimpleDeserializer cacheStringDSer = null;
106    protected QName JavaDoc cacheXMLType = null;
107    protected String JavaDoc lastFieldName = null;
108
109    // This is the constructor we find in startElement if the bean
110
// does not have a default constructor
111
protected DeferredBeanConstruction deferedConstruction;
112
113    // Construct BeanSerializer for the indicated class/qname
114
public BeanDeserializer(Class JavaDoc javaType, QName JavaDoc xmlType)
115    {
116       this(javaType, xmlType, TypeDesc.getTypeDescForClass(javaType));
117    }
118
119    // Construct BeanDeserializer for the indicated class/qname and meta Data
120
public BeanDeserializer(Class JavaDoc javaType, QName JavaDoc xmlType, TypeDesc typeDesc)
121    {
122       this(javaType, xmlType, typeDesc, BeanDeserializerFactory.getProperties(javaType, typeDesc));
123    }
124
125    // Construct BeanDeserializer for the indicated class/qname and meta Data
126
public BeanDeserializer(Class JavaDoc javaType, QName JavaDoc xmlType, TypeDesc typeDesc, Map JavaDoc propertyMap)
127    {
128       this.xmlType = xmlType;
129       this.javaType = javaType;
130       this.typeDesc = typeDesc;
131       this.propertyMap = propertyMap;
132
133       // create a value
134
try
135       {
136          value = javaType.newInstance();
137       }
138       catch (Exception JavaDoc e)
139       {
140          // Don't process the exception at this point.
141
// This is defered until the call to startElement
142
// which will throw the exception.
143
}
144    }
145
146    /**
147     * Set the bean properties that correspond to element attributes.
148     * <p/>
149     * This method is invoked after startElement when the element requires
150     * deserialization (i.e. the element is not an href and the value is not
151     * nil.)
152     *
153     * @param namespace is the namespace of the element
154     * @param localName is the name of the element
155     * @param prefix is the prefix of the element
156     * @param attributes are the attributes on the element...used to get the
157     * type
158     * @param context is the DeserializationContext
159     */

160    public void onStartElement(String JavaDoc namespace, String JavaDoc localName,
161                               String JavaDoc prefix, Attributes JavaDoc attributes,
162                               DeserializationContext context)
163            throws SAXException JavaDoc
164    {
165       // reset just in case
166
lastFieldName = null;
167
168       // Create the bean object if it was not already
169
// created in the constructor.
170
if (value == null)
171       {
172          try
173          {
174             value = javaType.newInstance();
175          }
176          catch (Exception JavaDoc e)
177          {
178
179             // Get the property classes
180
ArrayList JavaDoc propTypes = new ArrayList JavaDoc();
181             Iterator JavaDoc it = propertyMap.values().iterator();
182             while (it.hasNext())
183             {
184                BeanPropertyDescriptor bpd = (BeanPropertyDescriptor)it.next();
185                propTypes.add(bpd.getType());
186             }
187
188             // Get the constructors
189
Constructor JavaDoc[] ctors = javaType.getConstructors();
190
191             // Reset the defered construction, this is necessary if the deserializer
192
// is beeing reused, which I am not sure about
193
deferedConstruction = null;
194
195             // Find the constructor that matches the bean property types
196
for (int i = 0; deferedConstruction == null && i < ctors.length; i++)
197             {
198                Constructor JavaDoc ctor = ctors[i];
199                Class JavaDoc[] ctorArgs = ctor.getParameterTypes();
200                if (ctorArgs.length > 0)
201                {
202                   boolean allFound = true;
203                   for (int j = 0; j < ctorArgs.length; j++)
204                   {
205                      allFound &= propTypes.contains(ctorArgs[j]);
206                   }
207
208                   if (allFound)
209                   {
210                      deferedConstruction = new DeferredBeanConstruction(ctor);
211                   }
212                }
213             }
214
215             // if value still null, then we'll never be able to construct object
216
if (value == null && deferedConstruction == null)
217             {
218                // Failed to create an object.
219
throw new SAXException JavaDoc(Messages.getMessage("cantCreateBean00",
220                        javaType.getName(),
221                        e.toString()));
222             }
223          }
224       }
225
226       // If no type description meta data, there are no attributes,
227
// so we are done.
228
if (typeDesc == null)
229          return;
230
231       // Get the SOAP envelope URI
232
SOAPConstants soapConstants = context.getMessageContext().getSOAPConstants();
233       String JavaDoc soapenvURI = soapConstants.getEnvelopeURI();
234
235       // loop through the attributes and set bean properties that
236
// correspond to attributes
237
for (int i = 0; i < attributes.getLength(); i++)
238       {
239          // If the attribute belongs to the SOAP namespace, we ignore the attr namespace
240
// it might still be property of the bean
241
QName JavaDoc attrQName = null;
242          if (soapenvURI.equals(attributes.getURI(i)))
243             attrQName = new QName JavaDoc(attributes.getLocalName(i));
244          else
245             attrQName = new QName JavaDoc(attributes.getURI(i), attributes.getLocalName(i));
246
247          String JavaDoc fieldName = typeDesc.getFieldNameForAttribute(attrQName);
248          if (fieldName != null)
249          {
250             // look for the attribute property
251
BeanPropertyDescriptor bpd = (BeanPropertyDescriptor)propertyMap.get(fieldName);
252             if (bpd != null)
253             {
254                if (!bpd.isIndexed())
255                {
256                   // Get the Deserializer for the attribute
257
Deserializer dSer = getDeserializer(null, bpd.getType(), null, context);
258                   if (dSer == null)
259                      throw new SAXException JavaDoc(Messages.getMessage("unregistered00", bpd.getType().toString()));
260
261                   if (!(dSer instanceof SimpleDeserializer))
262                      throw new SAXException JavaDoc(Messages.getMessage("AttrNotSimpleType00", bpd.getName(), bpd.getType().toString()));
263
264                   // Success! Create an object from the string and set
265
// it in the bean
266
try
267                   {
268                      dSer.onStartElement(namespace, localName, prefix, attributes, context);
269                      Object JavaDoc val = ((SimpleDeserializer)dSer).makeValue(attributes.getValue(i));
270                      if (value != null)
271                      {
272                         bpd.set(value, val);
273                      }
274                      else if (deferedConstruction != null)
275                      {
276                         value = deferedConstruction.newBeanInstance(val);
277                      }
278                   }
279                   catch (Exception JavaDoc e)
280                   {
281                      throw new SAXException JavaDoc(e);
282                   }
283                }
284             }
285          }
286       } // attribute loop
287
}
288
289    /**
290     * Deserializer interface called on each child element encountered in
291     * the XML stream.
292     *
293     * @param namespace is the namespace of the child element
294     * @param localName is the local name of the child element
295     * @param prefix is the prefix used on the name of the child element
296     * @param attributes are the attributes of the child element
297     * @param context is the deserialization context.
298     * @return is a Deserializer to use to deserialize a child (must be
299     * a derived class of SOAPHandler) or null if no deserialization should
300     * be performed.
301     */

302    public SOAPHandler onStartChild(String JavaDoc namespace,
303                                    String JavaDoc localName,
304                                    String JavaDoc prefix,
305                                    Attributes JavaDoc attributes,
306                                    DeserializationContext context)
307            throws SAXException JavaDoc
308    {
309       log.debug("onStartChild: " + new QName JavaDoc(namespace, localName));
310
311       BeanPropertyDescriptor propDesc = null;
312       FieldDesc fieldDesc = null;
313
314       SOAPConstants soapConstants = context.getMessageContext().getSOAPConstants();
315       String JavaDoc encodingStyle = context.getMessageContext().getEncodingStyle();
316       boolean isEncoded = Constants.isSOAP_ENC(encodingStyle);
317
318       QName JavaDoc elemQName = new QName JavaDoc(namespace, localName);
319       // The collectionIndex needs to be reset for Beans with multiple arrays
320
if ((prevQName == null) || (!prevQName.equals(elemQName)))
321       {
322          collectionIndex = -1;
323       }
324       prevQName = elemQName;
325
326       // Fastpath nil checks...
327
// Commented out. If the bean property is an array (of simple types) that must groe to its propper size
328
// we need to process the nil
329
// TDI 20-June-2004
330
// com/sun/ts/tests/interop/webservices/jaxrpc/wsi/rpc/literal/marshalltest#MarshallJavaArrayTest
331
// if (context.isNil(attributes))
332
// return null;
333

334       if (typeDesc != null)
335       {
336          // Lookup the name appropriately (assuming an unqualified
337
// name for SOAP encoding, using the namespace otherwise)
338
String JavaDoc fieldName = typeDesc.getFieldNameForElement(elemQName);
339          if (fieldName != null)
340          {
341             propDesc = (BeanPropertyDescriptor)propertyMap.get(fieldName);
342             if (propDesc == null)
343             {
344                String JavaDoc lowerName = fieldName.substring(0, 1).toLowerCase() + fieldName.substring(1);
345                propDesc = (BeanPropertyDescriptor)propertyMap.get(lowerName);
346             }
347
348             fieldDesc = typeDesc.getFieldByName(fieldName);
349             if (fieldDesc == null)
350             {
351                String JavaDoc lowerName = fieldName.substring(0, 1).toLowerCase() + fieldName.substring(1);
352                fieldDesc = typeDesc.getFieldByName(lowerName);
353             }
354          }
355
356          // Hold on to the field name so that getDeserializer() can use it
357
lastFieldName = fieldName;
358       }
359       else
360       {
361          lastFieldName = null;
362       }
363
364       if (propDesc == null)
365       {
366          // look for a field by this name.
367
propDesc = (BeanPropertyDescriptor)propertyMap.get(localName);
368       }
369
370       // try and see if this is an xsd:any namespace="##any" element before
371
// reporting a problem
372
if (propDesc == null)
373       {
374          // try to put unknown elements into a SOAPElement property, if
375
// appropriate
376
propDesc = getAnyPropertyDesc();
377          if (propDesc != null)
378          {
379             try
380             {
381                SOAPElementAxisImpl[] curElements = (SOAPElementAxisImpl[])propDesc.get(value);
382                int length = 0;
383                if (curElements != null)
384                {
385                   length = curElements.length;
386                }
387                SOAPElementAxisImpl[] newElements = new SOAPElementAxisImpl[length + 1];
388                if (curElements != null)
389                {
390                   System.arraycopy(curElements, 0,
391                           newElements, 0, length);
392                }
393                SOAPElementAxisImpl thisEl = context.getCurElement();
394
395                newElements[length] = thisEl;
396                propDesc.set(value, newElements);
397                // if this is the first pass through the MessageContexts
398
// make sure that the correct any element is set,
399
// that is the child of the current MessageElement, however
400
// on the first pass this child has not been set yet, so
401
// defer it to the child SOAPHandler
402
if (!localName.equals(thisEl.getName()))
403                {
404                   return new SOAPHandler(newElements, length);
405                }
406                return new SOAPHandler();
407             }
408             catch (Exception JavaDoc e)
409             {
410                throw new SAXException JavaDoc(e);
411             }
412          }
413       }
414
415
416       if (propDesc == null)
417       {
418          // No such field
419
throw new SAXException JavaDoc(Messages.getMessage("badElem00", javaType.getName(),
420                  localName));
421       }
422
423       // Get the child's xsi:type if available
424
QName JavaDoc childXMLType = context.getTypeFromXSITypeAttr(namespace, localName, attributes);
425
426       String JavaDoc href = attributes.getValue(soapConstants.getAttrHref());
427
428       // If no xsi:type or href, check the meta-data for the field
429
if (childXMLType == null && fieldDesc != null && href == null)
430       {
431          childXMLType = fieldDesc.getXmlType();
432       }
433
434       // The bean property might be the super class of the actual type
435
Class JavaDoc propType = propDesc.getType();
436       TypeMapping tm = context.getTypeMapping();
437       Class JavaDoc childType = tm.getClassForQName(childXMLType);
438       if (childType != null && propType.isAssignableFrom(childType))
439          propType = childType;
440
441       // Get Deserializer for child, default to using DeserializerImpl
442
Deserializer dSer = getDeserializer(childXMLType, propType, href, context);
443
444       // It is an error if the dSer is not found - the only case where we
445
// wouldn't have a deserializer at this point is when we're trying
446
// to deserialize something we have no clue about (no good xsi:type,
447
// no good metadata).
448
if (dSer == null)
449       {
450
451 // FIXME : Currently this doesn't throw an error solely to enable the
452
// "terra" testcase to pass. We should, IMO, fix the test (either
453
// to support <xsd:list> or to throw an error when we find such a thing
454
// in the WSDL at WSDL2Java time). Once that's done, this should be
455
// uncommented and the next two lines deleted.
456
//
457
// throw new SAXException(Messages.getMessage("noDeser00",
458
// childXMLType.toString()));
459

460          dSer = new DeserializerImpl();
461          return (SOAPHandler)dSer;
462       }
463
464       // Register value target
465
if (propDesc.isWriteable() || deferedConstruction != null)
466       {
467          // If this is an indexed property, and the deserializer we found
468
// was NOT the ArrayDeserializer, this is a non-SOAP array:
469
// <bean>
470
// <field>value1</field>
471
// <field>value2</field>
472
// ...
473
// In this case, we want to use the collectionIndex and make sure
474
// the deserialized value for the child element goes into the
475
// right place in the collection.
476
if (propDesc.isIndexed() && !(dSer instanceof ArrayDeserializer))
477          {
478             collectionIndex++;
479             dSer.registerValueTarget(getBeanPropertyTarget(propDesc));
480          }
481          // If this is literal style and the property type is an Array
482
// deserialize each item as if it was the property.
483
// This should probably be handled by a LiteralArrayDeserializer.
484
// TDI 20-June-2004
485
// com/sun/ts/tests/interop/webservices/jaxrpc/wsi/rpc/literal/marshalltest#MarshallJavaArrayTest
486
else if (!isEncoded && JavaUtils.isArrayClass(propDesc.getType()) &&
487                  !(dSer instanceof Base64Deserializer) && !(dSer instanceof HexDeserializer))
488          {
489             collectionIndex++;
490             dSer.registerValueTarget(getBeanPropertyTarget(propDesc));
491          }
492          else
493          {
494             // If we're here, the element maps to a single field value,
495
// whether that be a "basic" type or an array, so use the
496
// normal (non-indexed) BeanPropertyTarget form.
497
collectionIndex = -1;
498             dSer.registerValueTarget(getBeanPropertyTarget(propDesc));
499          }
500       }
501
502       // Let the framework know that we need this deserializer to complete
503
// for the bean to complete.
504
addChildDeserializer(dSer);
505
506       return (SOAPHandler)dSer;
507    }
508
509    /** Check that we have a valid bean instance
510     */

511    public void onEndElement(String JavaDoc namespace, String JavaDoc localName, DeserializationContext context) throws SAXException JavaDoc
512    {
513       super.onEndElement(namespace, localName, context);
514
515       if (value == null && deferedConstruction != null)
516          throw new SAXException JavaDoc("Could not construct bean using: " + deferedConstruction);
517    }
518
519    /**
520     * Get the target, its either direct on the value or defered via an constructor
521     */

522    private BeanPropertyTarget getBeanPropertyTarget(BeanPropertyDescriptor propDesc)
523    {
524       BeanPropertyTarget target = null;
525
526       if (value != null)
527          target = new BeanPropertyTarget(value, propDesc, collectionIndex);
528       else if (deferedConstruction != null)
529          target = new BeanPropertyTarget(this, deferedConstruction, propDesc);
530       else
531          throw new IllegalStateException JavaDoc("Cannot get a valid property target");
532
533       return target;
534    }
535
536    /**
537     * Get a BeanPropertyDescriptor which indicates where we should
538     * put extensibility elements (i.e. XML which falls under the
539     * auspices of an &lt;xsd:any&gt; declaration in the schema)
540     *
541     * @return an appropriate BeanPropertyDescriptor, or null
542     */

543    public BeanPropertyDescriptor getAnyPropertyDesc()
544    {
545       if (typeDesc == null)
546          return null;
547
548       return typeDesc.getAnyDesc();
549    }
550
551    /**
552     * Get the Deserializer for the attribute or child element.
553     *
554     * @param xmlType QName of the attribute/child element or null if not known.
555     * @param javaType Class of the corresponding property
556     * @param href String is the value of the href attribute, which is used
557     * to determine whether the child element is complete or an
558     * href to another element.
559     * @param context DeserializationContext
560     * @return Deserializer or null if not found.
561     */

562    protected Deserializer getDeserializer(QName JavaDoc xmlType, Class JavaDoc javaType, String JavaDoc href, DeserializationContext context)
563    {
564
565       String JavaDoc encodingStyle = context.getMessageContext().getEncodingStyle();
566       boolean isEncoded = Constants.isSOAP_ENC(encodingStyle);
567
568       // See if we have a cached deserializer
569
if (cacheStringDSer != null)
570       {
571          if (String JavaDoc.class.equals(javaType) &&
572                  href == null &&
573                  (cacheXMLType == null && xmlType == null ||
574                  cacheXMLType != null && cacheXMLType.equals(xmlType)))
575          {
576             cacheStringDSer.reset();
577             return cacheStringDSer;
578          }
579       }
580
581       Deserializer dSer = null;
582       TypeMapping tm = context.getTypeMapping();
583
584       if (xmlType != null && href == null)
585       {
586          // Use the xmlType to get the deserializer.
587
dSer = context.getDeserializerForType(xmlType);
588       }
589
590       if (dSer == null)
591       {
592
593          // If the xmlType is not set, get a default xmlType
594
QName JavaDoc defaultXMLType = tm.getTypeQName(javaType);
595
596          // If there is not href, then get the deserializer
597
// using the javaType and default XMLType,
598
// If there is an href, the create the generic
599
// DeserializerImpl and set its default type (the
600
// default type is used if the href'd element does
601
// not have an xsi:type.
602
if (href == null)
603          {
604             dSer = context.getDeserializer(javaType, defaultXMLType);
605          }
606          else
607          {
608             dSer = new DeserializerImpl();
609             dSer.setDefaultType(defaultXMLType);
610          }
611       }
612
613       if (javaType.equals(String JavaDoc.class) &&
614               dSer instanceof SimpleDeserializer)
615       {
616          cacheStringDSer = (SimpleDeserializer)dSer;
617          cacheXMLType = xmlType;
618       }
619
620       // If this is literal style and the javaType is an Array
621
// deserialize each item as if it was the property.
622
// This should probably be handled by a LiteralArrayDeserializer.
623
// TDI 20-June-2004
624
// com/sun/ts/tests/interop/webservices/jaxrpc/wsi/rpc/literal/marshalltest#MarshallJavaArrayTest
625
if (dSer == null && !isEncoded && JavaUtils.isArrayClass(javaType) && javaType != Byte JavaDoc[].class && javaType != byte[].class)
626       {
627
628          FieldDesc fieldDesc = (lastFieldName != null) ? typeDesc.getFieldByName(lastFieldName) : null;
629          Class JavaDoc compType = javaType.getComponentType();
630          QName JavaDoc itemXmlType = null;
631
632          if (fieldDesc != null && fieldDesc instanceof ElementDesc)
633          {
634             itemXmlType = ((ElementDesc)fieldDesc).getItemXmlType();
635          }
636          
637          // If there is no itemXmlType defined, or no fieldDesc is available use the typemapping
638
// on the component type
639
if (itemXmlType == null)
640          {
641             itemXmlType = tm.getTypeQName(compType);
642          }
643
644          log.debug("Using itemXmlType = " + itemXmlType);
645
646          dSer = context.getDeserializer(compType, itemXmlType);
647       }
648
649       return dSer;
650    }
651
652    /**
653     * This will assign text content to the bean property that is an element
654     * with the asContent flag set to true. There can only be one, or is there a way to know which?
655     * TDI 22-June-2004
656     */

657    public void characters(char[] p1, int p2, int p3) throws SAXException JavaDoc
658    {
659       super.characters(p1, p2, p3);
660
661       if (typeDesc != null)
662       {
663          Iterator JavaDoc it = propertyMap.values().iterator();
664          while (it.hasNext())
665          {
666             BeanPropertyDescriptor bpDesc = (BeanPropertyDescriptor)it.next();
667             if (bpDesc.isWriteable())
668             {
669                String JavaDoc name = bpDesc.getName();
670                FieldDesc fieldDesc = typeDesc.getFieldByName(name);
671                if (fieldDesc instanceof ElementDesc && ((ElementDesc)fieldDesc).isAsContent())
672                {
673                   String JavaDoc strContent = new String JavaDoc(p1, p2, p3);
674                   try
675                   {
676                      log.debug("Setting content property: " + name + "=" + strContent);
677                      bpDesc.set(value, strContent);
678                   }
679                   catch (Exception JavaDoc e)
680                   {
681                      log.warn("Cannot set content property", e);
682                   }
683                }
684             }
685          }
686       }
687    }
688 }
689
Popular Tags