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 boolean isWriteOuter()
    74      {
    75          return false;
    76      }
    77
    78      public Set getDependencies()
    79      {
    80          SchemaProperty[] properties = schemaType.getProperties();
    81          HashSet deps = new HashSet();
    82          for (int i = 0; i < properties.length; i++)
    83          {
    84              SchemaType etype = properties[i].getType();
    85              SchemaProperty[] iprops = etype.getElementProperties();
    86              for (int j = 0; j < iprops.length; j++)
    87              {
    88                  SchemaType itype = iprops[j].getType();
    89
    90                  if (!itype.isPrimitiveType() && itype.getSourceName() != null)
    91                  {
    92                      deps.add(new XmlBeansType(itype));
    93                  }
    94              }
    95          }
    96          return deps;
    97      }
    98
    99      public QName getSchemaType()
    100     {
    101         if (schemaType.isDocumentType())
    102             return schemaType.getDocumentElementName();
    103         else if (schemaType.getName() != null)
    104             return schemaType.getName();
    105         else
    106         {
    107             // No name for this type, use outer type (and recur up if same)
    108             SchemaType outer = schemaType.getOuterType();
    109             while (outer != null)
    110             {
    111                 if (outer.isDocumentType())
    112                     return outer.getDocumentElementName();
    113                 else if (outer.getName() != null)
    114                     return outer.getName();
    115                 else
    116                     outer = outer.getOuterType();
    117             }
    118
    119             // No outer type, no type on this, should not be possible, so explode
    120             throw new XFireRuntimeException("No type name is defined for <" + schemaType + "> " +
    121                                             "and no outer type containing the inline type -- this " +
    122                                             "should not be possible to be a legally defined schema");
    123         }
    124     }
    125
    126     public Object readObject(MessageReader mreader, MessageContext context)
    127         throws XFireFault
    128     {
    129         try
    130         {
    131             XMLStreamReader reader = ((ElementReader) mreader).getXMLStreamReader();
    132             XmlObject parsed = XmlObject.Factory.parse(reader);
    133
    134             /* Add namespace declarations from the XMLStreamReader NamespaceContext.
    135              * This is important when values reference QNames. For instance,
    136              * xsi:type="xsd:string". If the xsd namespace is declared on the SOAP
    137              * envelope then XMLBeans won't pick up.
    138              */
    139             XmlCursor cursor = parsed.newCursor();
    140             try
    141             {
    142                 cursor.toFirstContentToken();
    143                 Map namespaces = (Map) context.getProperty(ReadHeadersHandler.DECLARED_NAMESPACES);
    144                 for (Iterator itr = namespaces.entrySet().iterator(); itr.hasNext();)
    145                 {
    146                     Map.Entry entry = (Map.Entry) itr.next();
    147                     cursor.insertNamespace((String) entry.getKey(), (String) entry.getValue());
    148                 }
    149             }
    150             finally
    151             {
    152                 cursor.dispose();
    153             }
    154
    155             return parsed;
    156         }
    157         catch( XmlException e )
    158         {
    159             throw new XFireFault("Could not read request.", e, XFireFault.SENDER);
    160         }
    161     }
    162
    163     public void writeObject(Object value, MessageWriter writer, MessageContext context)
    164         throws XFireFault
    165     {
    166         try
    167         {
    168             XmlObject obj = (XmlObject) value;
    169
    170             XmlCursor cursor = obj.newCursor();
    171
    172             STAXUtils.copy(cursor.newXMLStreamReader(),
    173                             ((ElementWriter) writer).getXMLStreamWriter());
    174         }
    175         catch (XMLStreamException e)
    176         {
    177             throw new XFireFault("Could not write response.", e, XFireFault.SENDER);
    178         }
    179     }
    180 }