- DefinedTerm is ordered as in enum (#3752)
[cdmlib.git] / cdmlib-model / src / main / java / eu / etaxonomy / cdm / model / common / LSIDWSDLLocator.java
1 /**
2 * Copyright (C) 2009 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
5 *
6 * The contents of this file are subject to the Mozilla Public License Version 1.1
7 * See LICENSE.TXT at the top of this package for the full license terms.
8 */
9
10 package eu.etaxonomy.cdm.model.common;
11
12 import java.io.File;
13 import java.io.IOException;
14 import java.io.InputStream;
15 import java.io.InputStreamReader;
16 import java.io.Reader;
17 import java.net.URL;
18
19 import javax.wsdl.xml.WSDLLocator;
20
21 import org.apache.commons.logging.Log;
22 import org.apache.commons.logging.LogFactory;
23 import org.xml.sax.InputSource;
24
25 import com.ibm.wsdl.util.StringUtils;
26
27 /**
28 * WSDLLocator based almost totally upon WSIFWSDLLocatorImpl by Owen Burroughs
29 * Created primarily because locating the required wsdl documents in the classpath
30 * seems like a safer thing than using a file path and relying on users remembering to
31 * copy the correct wsdl files into the correct places.
32 *
33 * @author ben.clark
34 * @author Owen Burroughs
35 */
36 public class LSIDWSDLLocator implements WSDLLocator {
37 private static Log log = LogFactory.getLog(LSIDWSDLLocator.class);
38
39 private Reader baseReader = null;
40 private Reader importReader = null;
41 private String contextURI = null;
42 private String wsdlLocation = null;
43 private String documentBase = null;
44 private String importBase = null;
45 private ClassLoader loader = null;
46
47 public LSIDWSDLLocator(String ctxt, String wsdlURI, ClassLoader cl) {
48 contextURI = ctxt;
49 wsdlLocation = wsdlURI;
50 loader = cl;
51 }
52
53 public LSIDWSDLLocator(String docBase, Reader reader, ClassLoader cl) {
54 documentBase = docBase;
55 baseReader = reader;
56 loader = cl;
57 }
58
59 /**
60 * @see javax.wsdl.xml.WSDLLocator#getBaseReader()
61 */
62 public Reader getBaseReader() {
63 if (baseReader == null) {
64 try {
65 URL url = null;
66 URL contextURL = (contextURI != null) ? StringUtils.getURL(
67 null, contextURI) : null;
68 if (loader != null) {
69 InputStream in = null;
70 try {
71 if (contextURL != null)
72 url = new URL(contextURL, wsdlLocation);
73 else {
74 if (wsdlLocation.indexOf(":") == -1)
75 url = new URL("file", null, wsdlLocation);
76 else
77 url = new URL(wsdlLocation);
78 }
79 String wsdlRelativeLocation = url.getPath();
80 if (wsdlRelativeLocation.startsWith("/"))
81 wsdlRelativeLocation = wsdlRelativeLocation
82 .substring(1);
83 in = loader
84 .getResourceAsStream(wsdlRelativeLocation);
85 baseReader = new InputStreamReader(in);
86 } catch (Exception exc) {
87 }
88 }
89 if (baseReader == null) {
90 url = StringUtils.getURL(contextURL, wsdlLocation);
91 baseReader = new InputStreamReader(StringUtils
92 .getContentAsInputStream(url));
93 }
94 if (url != null)
95 documentBase = url.toString();
96 } catch (Exception e) {
97 documentBase = wsdlLocation;
98 }
99 }
100
101 return baseReader;
102 }
103
104 /**
105 * @see javax.wsdl.xml.WSDLLocator#getBaseURI()
106 */
107 public String getBaseURI() {
108 return documentBase;
109 }
110
111 /**
112 * used to read imports as a document is parsed
113 *
114 * @see javax.wsdl.xml.WSDLLocator#getImportReader(String, String)
115 */
116 public Reader getImportReader(String base, String relativeLocation) {
117 // Reset importReader if finding import within import
118 importReader = null;
119 boolean triedSU = false;
120 try {
121 // If a ClassLoader was used to load the base
122 // document, chances
123 // are we need to use it to find the import.
124 URL url = null;
125 if (loader != null) {
126 if (relativeLocation.startsWith("/")
127 || relativeLocation.startsWith("\\")) {
128 // Relative location has been specified from a root dir.
129 // However,
130 // using a ClassLoader, root dirs don't mean anything.
131 relativeLocation = relativeLocation.substring(1,relativeLocation.length());
132 InputStream in = loader.getResourceAsStream(relativeLocation);
133 importReader = new InputStreamReader(in);
134 } else if (relativeLocation.indexOf("://") != -1) {
135 // This is a fully specified URL of some kind so don't
136 // use the
137 // ClassLoader to find the import.
138 triedSU = true;
139 url = StringUtils.getURL(null, relativeLocation);
140 importReader = new InputStreamReader(StringUtils
141 .getContentAsInputStream(url));
142 } else {
143 // Import location has been specified relative to the
144 // base document
145 // and so we can to try to form the complete path to it.
146 if (base != null) {
147 int i = base.lastIndexOf("/");
148 if (i == -1) {
149 i = base.lastIndexOf("\\");
150 }
151 if (i != -1) {
152 String path = base.substring(0, i + 1);
153 String resolvedPath = path + relativeLocation;
154 if (relativeLocation.startsWith("..")) {
155 resolvedPath = resolvePath(path,
156 relativeLocation);
157 }
158 if (resolvedPath == null) {
159 throw new Exception("Invalid Path");
160 }
161
162 // Make sure that resolved path starts with
163 // file:
164 if (resolvedPath.startsWith("file:")) {
165 url = new URL(null, resolvedPath);
166 } else {
167 url = new URL(null, "file:" + resolvedPath);
168 }
169 } else {
170 url = new URL(null, "file:" + base + File.separator + relativeLocation);
171 }
172 InputStream in = loader.getResourceAsStream(url.getPath());
173 importReader = new InputStreamReader(in);
174 } else {
175 url = new URL(null, "file:" + relativeLocation);
176 InputStream in = loader.getResourceAsStream(url.getPath());
177 importReader = new InputStreamReader(in);
178 }
179 }
180 } else {
181 triedSU = true;
182 URL contextURL = (base != null) ? StringUtils.getURL(null,
183 base) : null;
184 url = StringUtils.getURL(contextURL, relativeLocation);
185 importReader = new InputStreamReader(StringUtils
186 .getContentAsInputStream(url));
187 }
188 importBase = (url == null) ? relativeLocation : url.toString();
189 } catch (Exception e) {
190 log.error(e.toString());
191 log.error(e.getMessage());
192 // If we have not tried using a non-ClassLoader route, try it
193 // now
194 // as a last resort.
195 if (!triedSU) {
196 try {
197 URL contextURL = (base != null) ? StringUtils.getURL(
198 null, base) : null;
199 URL url = StringUtils.getURL(contextURL,
200 relativeLocation);
201 importReader = new InputStreamReader(StringUtils
202 .getContentAsInputStream(url));
203 importBase = (url == null) ? relativeLocation : url
204 .toString();
205 } catch (Exception e2) {
206 log.error(e2.toString());
207 log.error("Cannot find " + importBase + " so setting importBase to unknownImportURI");
208 // we can't find the import so set a temporary value for
209 // the import URI. This is
210 // necessary to avoid a NullPointerException in
211 // WSDLReaderImpl
212 importBase = "unknownImportURI";
213 }
214 } else {
215 log.error("Cannot find " + importBase + " so setting importBase to unknownImportURI");
216 // we can't find the import so set a temporary value for the
217 // import URI. This is
218 // necessary to avoid a NullPointerException in
219 // WSDLReaderImpl
220 importBase = "unknownImportURI";
221 }
222 }
223
224 return importReader;
225 }
226
227 /**
228 * Resolve a path when the relative location begins with ..
229 */
230 private String resolvePath(String ba, String rel) {
231 StringBuffer sb = new StringBuffer(rel);
232 int dd = 0;
233 while (sb.length() > 0) {
234 if (sb.length() > 3 && sb.charAt(0) == '.'
235 && sb.charAt(1) == '.'
236 && (sb.charAt(2) == '/' || sb.charAt(2) == '\\')) {
237 dd++;
238 sb.delete(0, 3);
239 } else {
240 break;
241 }
242 }
243 StringBuffer sb2 = new StringBuffer(ba);
244 int j = sb2.length() - 1;
245 int found = 0;
246 for (int k = j; k >= 0; k--) {
247 if (k != j && (sb2.charAt(k) == '/' || sb2.charAt(k) == '\\')) {
248 found++;
249 }
250 if (found < dd) {
251 sb2.deleteCharAt(k);
252 } else {
253 break;
254 }
255 }
256 if (found + 1 < dd)
257 return null;
258 return sb2.toString() + sb.toString();
259 }
260
261 /**
262 * @see javax.wsdl.xml.WSDLLocator#getLatestImportURI()
263 */
264 public String getLatestImportURI() {
265 return importBase;
266 }
267
268 /**
269 * @see javax.wsdl.xml.WSDLLocator#getBaseInputSource()
270 */
271 public InputSource getBaseInputSource() {
272 return new InputSource(getBaseReader());
273 }
274
275 /**
276 * @see javax.wsdl.xml.WSDLLocator#getImportInputSource(String, String)
277 */
278 public InputSource getImportInputSource(String arg0, String arg1) {
279 return new InputSource(getImportReader(arg0, arg1));
280 }
281
282 public void close() {
283 if (baseReader != null)
284 try {
285 baseReader.close();
286 } catch (IOException e) {
287 // TODO Auto-generated catch block
288 e.printStackTrace();
289 }
290 if (importReader != null)
291 try {
292 importReader.close();
293 } catch (IOException e) {
294 // TODO Auto-generated catch block
295 e.printStackTrace();
296 }
297 }
298
299 }