View Javadoc

    1   package org.codehaus.xfire.xmlbeans;
    2
    3   import java.util.HashSet;
    4   import java.util.Iterator;
    5   import java.util.Map;
    6   import java.util.Set;
    7
    8   import javax.xml.namespace.QName;
    9   import javax.xml.stream.XMLStreamException;
    10  import javax.xml.stream.XMLStreamReader;
    11
    12  import org.apache.commons.logging.Log;
    13  import org.apache.commons.logging.LogFactory;
    14  import org.apache.xmlbeans.SchemaProperty;
    15  import org.apache.xmlbeans.SchemaType;
    16  import org.apache.xmlbeans.XmlBeans;
    17  import org.apache.xmlbeans.XmlCursor;
    18  import org.apache.xmlbeans.XmlException;
    19  import org.apache.xmlbeans.XmlObject;
    20  import org.codehaus.xfire.MessageContext;
    21  import org.codehaus.xfire.XFireRuntimeException;
    22  import org.codehaus.xfire.aegis.MessageReader;
    23  import org.codehaus.xfire.aegis.MessageWriter;
    24  import org.codehaus.xfire.aegis.stax.ElementReader;
    25  import org.codehaus.xfire.aegis.stax.ElementWriter;
    26  import org.codehaus.xfire.aegis.type.Type;
    27  import org.codehaus.xfire.fault.XFireFault;
    28  import org.codehaus.xfire.soap.handler.ReadHeadersHandler;
    29  import org.codehaus.xfire.util.STAXUtils;
    30  import org.codehaus.yom.Element;
    31
    32  /***
    33   * @author <a href="mailto:dan@envoisolutions.com">Dan Diephouse</a>
    34   * @since Nov 13, 2004
    35   */
    36  public class XmlBeansType
    37      extends Type
    38  {
    39      private SchemaType schemaType;
    40
    41      private final static Log logger = LogFactory.getLog(XmlBeansType.class);
    42
    43      public XmlBeansType()
    44      {
    45      }
    46
    47      public XmlBeansType(SchemaType schemaType)
    48      {
    49          this.schemaType = schemaType;
    50          setTypeClass(schemaType.getJavaClass());
    51      }
    52
    53      public XmlBeansType(Class clazz)
    54      {
    55          this.schemaType = XmlBeans.typeForClass(clazz);
    56          setTypeClass(clazz);
    57      }
    58
    59      public void writeSchema(Element root)
    60      {
    61      }
    62
    63      public boolean isComplex()
    64      {
    65          return !schemaType.isPrimitiveType();
    66      }
    67
    68      public boolean isAbstract()
    69      {
    70          return schemaType.isAbstract();
    71      }
    72
    73      public Set getDependencies()
    74      {
    75          SchemaProperty[] properties = schemaType.getProperties();
    76          HashSet deps = new HashSet();
    77          for (int i = 0; i < properties.length; i++)
    78          {
    79              SchemaType etype = properties[i].getType();
    80              SchemaProperty[] iprops = etype.getElementProperties();
    81              for (int j = 0; j < iprops.length; j++)
    82              {
    83                  SchemaType itype = iprops[j].getType();
    84
    85                  if (!itype.isPrimitiveType() && itype.getSourceName() != null)
    86                  {
    87                      deps.add(new XmlBeansType(itype));
    88                  }
    89              }
    90          }
    91          return deps;
    92      }
    93
    94      public QName getSchemaType()
    95      {
    96          if (schemaType.isDocumentType())
    97              return schemaType.getDocumentElementName();
    98          else if (schemaType.getName() != null)
    99              return schemaType.getName();
    100         else
    101         {
    102             // No name for this type, use outer type (and recur up if same)
    103             SchemaType outer = schemaType.getOuterType();
    104             while (outer != null)
    105             {
    106                 if (outer.isDocumentType())
    107                     return outer.getDocumentElementName();
    108                 else if (outer.getName() != null)
    109                     return outer.getName();
    110                 else
    111                     outer = outer.getOuterType();
    112             }
    113
    114             // No outer type, no type on this, should not be possible, so explode
    115             throw new XFireRuntimeException("No type name is defined for <" + schemaType + "> " +
    116                                             "and no outer type containing the inline type -- this " +
    117                                             "should not be possible to be a legally defined schema");
    118         }
    119     }
    120
    121     public Object readObject(MessageReader mreader, MessageContext context)
    122         throws XFireFault
    123     {
    124         try
    125         {
    126             XMLStreamReader reader = ((ElementReader) mreader).getXMLStreamReader();
    127             XmlObject parsed = XmlObject.Factory.parse(reader);
    128
    129             /* Add namespace declarations from the XMLStreamReader NamespaceContext.
    130              * This is important when values reference QNames. For instance,
    131              * xsi:type="xsd:string". If the xsd namespace is declared on the SOAP
    132              * envelope then XMLBeans won't pick up.
    133              */
    134             XmlCursor cursor = parsed.newCursor();
    135             try
    136             {
    137                 cursor.toFirstContentToken();
    138                 Map namespaces = (Map) context.getProperty(ReadHeadersHandler.DECLARED_NAMESPACES);
    139                 for (Iterator itr = namespaces.entrySet().iterator(); itr.hasNext();)
    140                 {
    141                     Map.Entry entry = (Map.Entry) itr.next();
    142                     cursor.insertNamespace((String) entry.getKey(), (String) entry.getValue());
    143                 }
    144             }
    145             finally
    146             {
    147                 cursor.dispose();
    148             }
    149
    150             return parsed;
    151         }
    152         catch( XmlException e )
    153         {
    154             throw new XFireFault("Could not read request.", e, XFireFault.SENDER);
    155         }
    156     }
    157
    158     public void writeObject(Object value, MessageWriter writer, MessageContext context)
    159         throws XFireFault
    160     {
    161         try
    162         {
    163             XmlObject obj = (XmlObject) value;
    164
    165             XmlCursor cursor = obj.newCursor();
    166             if (cursor.toFirstChild() && cursor.toFirstChild())
    167             {
    168                 do
    169                 {
    170                     STAXUtils.copy(cursor.newXMLStreamReader(),
    171                                    ((ElementWriter) writer).getXMLStreamWriter());
    172                 }
    173                 while(cursor.toNextSibling());
    174             }
    175         }
    176         catch (XMLStreamException e)
    177         {
    178             throw new XFireFault("Could not write response.", e, XFireFault.SENDER);
    179         }
    180     }
    181 }