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 }