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