1 package org.codehaus.xfire.jaxb;
2
3 import org.codehaus.xfire.XFireRuntimeException;
4 import org.codehaus.xfire.aegis.type.Type;
5 import org.codehaus.xfire.soap.SoapConstants;
6 import org.codehaus.yom.Document;
7 import org.codehaus.yom.Element;
8 import org.codehaus.yom.stax.StaxBuilder;
9 import org.codehaus.yom.xpath.YOMXPath;
10 import org.jaxen.JaxenException;
11 import org.jaxen.XPath;
12
13 import javax.xml.stream.XMLStreamException;
14 import java.io.FileInputStream;
15 import java.io.FileNotFoundException;
16 import java.io.InputStream;
17 import java.util.*;
18
19 /***
20 * User: chris
21 * Date: Aug 21, 2005
22 * Time: 1:41:05 PM
23 */
24 public class JaxbSchemaProvider
25 {
26 private Document[] schemas;
27 private Map schemaCache;
28
29 public JaxbSchemaProvider(List schemaLocations)
30 {
31 schemaCache = new HashMap();
32 List schemaList = new ArrayList();
33
34 StaxBuilder builder = new StaxBuilder();
35 for (Iterator iterator = schemaLocations.iterator(); iterator.hasNext();)
36 {
37 String s = (String) iterator.next();
38 InputStream fileInputStream = null;
39 try
40 {
41 fileInputStream = new FileInputStream(s);
42 } catch (FileNotFoundException e)
43 {
44 fileInputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream(s);
45 }
46 if (fileInputStream == null)
47 throw new XFireRuntimeException("couldnt load schema file:" + s);
48 Document schema = null;
49 try
50 {
51 schema = builder.build(fileInputStream);
52 } catch (XMLStreamException e)
53 {
54 throw new XFireRuntimeException("error parsing schema file:" + s, e);
55 }
56 schemaList.add(schema);
57
58 }
59 schemas = (Document[]) schemaList.toArray(new Document[schemaList.size()]);
60
61 }
62
63
64 public Element getSchema(Type jaxbType, JaxbWsdlBuilder jaxbWsdlBuilder)
65 {
66 Element schema = null;
67
68
69 List nodes = null;
70 String ns = jaxbType.getSchemaType().getNamespaceURI();
71 Element o = (Element) schemaCache.get(ns);
72 if (o != null)
73 return o;
74 boolean found = false;
75 for (int i = 0; i < schemas.length; i++)
76 {
77
78 Document document = schemas[i];
79 schema = document.getRootElement();
80 String expr = "//xsd:schema[@targetNamespace='" + ns + "']";
81
82 nodes = getMatches(schema, expr);
83 if (nodes.size() != 0)
84 {
85
86 found = true;
87 break;
88 }
89 }
90
91 if (!found)
92 throw new XFireRuntimeException("couldnt find namespace " + ns);
93 Element node = (Element) nodes.get(0);
94
95 nodes = getMatches(schema, "//xsd:import");
96 for (int i = 0; i < nodes.size(); i++)
97 {
98 Element imp = (Element) nodes.get(i);
99
100 String importedNs = imp.getAttributeValue("namespace");
101
102
103
104 imp.detach();
105 }
106 schemaCache.put(ns, node);
107 return node;
108 }
109
110 private List getMatches(Object doc, String xpath)
111 {
112 try
113 {
114 XPath path = new YOMXPath(xpath);
115 path.addNamespace("xsd", SoapConstants.XSD);
116 path.addNamespace("s", SoapConstants.XSD);
117 List result = path.selectNodes(doc);
118 return result;
119 }
120 catch (JaxenException e)
121 {
122 throw new XFireRuntimeException("Error evaluating xpath " + xpath, e);
123 }
124 }
125 }