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