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
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 }