View Javadoc

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             // TODO: How do we make sure this is imported???
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 }