View Javadoc

    1   package org.codehaus.xfire.xmlbeans;
    2
    3   import java.util.HashMap;
    4   import java.util.List;
    5   import java.util.Map;
    6
    7   import javax.wsdl.WSDLException;
    8
    9   import org.apache.xmlbeans.SchemaType;
    10  import org.apache.xmlbeans.XmlBeans;
    11  import org.apache.xmlbeans.XmlObject;
    12  import org.codehaus.xfire.XFireRuntimeException;
    13  import org.codehaus.xfire.service.Service;
    14  import org.codehaus.xfire.soap.SoapConstants;
    15  import org.codehaus.xfire.transport.TransportManager;
    16  import org.codehaus.xfire.wsdl11.WSDL11ParameterBinding;
    17  import org.codehaus.xfire.wsdl11.builder.WSDLBuilder;
    18  import org.codehaus.yom.Document;
    19  import org.codehaus.yom.Element;
    20  import org.codehaus.yom.stax.StaxBuilder;
    21  import org.codehaus.yom.xpath.YOMXPath;
    22  import org.jaxen.JaxenException;
    23  import org.jaxen.XPath;
    24
    25  public class XmlBeansWSDLBuilder
    26      extends WSDLBuilder
    27  {
    28      private final static StaxBuilder builder = new StaxBuilder();
    29      private static Map schemas = new HashMap();
    30
    31      public XmlBeansWSDLBuilder(Service service, TransportManager tman, WSDL11ParameterBinding paramBinding) throws WSDLException
    32      {
    33          super(service, tman, paramBinding);
    34      }
    35
    36      public void addDependency(org.codehaus.xfire.wsdl.SchemaType type)
    37      {
    38          if (!hasDependency(type))
    39          {
    40              if (type instanceof XmlBeansType)
    41              {
    42                  XmlBeansType xbeanType = (XmlBeansType) type;
    43
    44                  String ns = xbeanType.getSchemaType().getNamespaceURI();
    45                  if (!hasSchema(ns))
    46                  {
    47                      Element schema = getSchema(xbeanType);
    48                      schema.detach();
    49                      setSchema(ns, schema);
    50                  }
    51              }
    52          }
    53
    54          super.addDependency(type);
    55      }
    56
    57      public Element getSchema(XmlBeansType xbeanType)
    58      {
    59          SchemaType type = XmlBeans.typeForClass(xbeanType.getTypeClass());
    60          String name = type.getSourceName();
    61          if (name == null) return null;
    62
    63          Element schema = (Element) schemas.get(name);
    64          if (schema != null) return schema;
    65
    66          ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
    67          try
    68          {
    69              XmlObject obj = XmlObject.Factory.parse(classLoader.getResourceAsStream("schemaorg_apache_xmlbeans/src/" + name));
    70
    71              schema = builder.buildElement(null, obj.newXMLStreamReader());
    72              Document schemaDoc = new Document(schema);
    73
    74              String ns = xbeanType.getSchemaType().getNamespaceURI();
    75              String expr = "//xsd:schema[@targetNamespace='" + ns + "']";
    76
    77              List nodes = getMatches(schema, expr);
    78              if (nodes.size() == 0)
    79              {
    80                  return null;
    81              }
    82
    83              Element node = (Element) nodes.get(0);
    84
    85              nodes = getMatches(schema, "//xsd:import");
    86              for (int i = 0; i < nodes.size(); i++)
    87              {
    88                  Element imp = (Element) nodes.get(i);
    89
    90                  String importedNs = imp.getAttributeValue("namespace");
    91
    92                  // TODO: How do we make sure this is imported???
    93
    94                  imp.detach();
    95              }
    96
    97              return node;
    98          }
    99          catch (Exception e)
    100         {
    101             throw new XFireRuntimeException("Couldn't load schema.", e);
    102         }
    103     }
    104
    105     private List getMatches(Object doc, String xpath)
    106     {
    107         try
    108         {
    109             XPath path = new YOMXPath(xpath);
    110             path.addNamespace("xsd", SoapConstants.XSD);
    111             path.addNamespace("s", SoapConstants.XSD);
    112             List result = path.selectNodes(doc);
    113             return result;
    114         }
    115         catch(JaxenException e)
    116         {
    117             throw new XFireRuntimeException("Error evaluating xpath " + xpath, e);
    118         }
    119     }
    120 }