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 }