f987e95f7b0a99106af6bb1ffa3d8f2b9c3d626e
[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.logging.log4j.LogManager;
22 import org.apache.logging.log4j.Logger;
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
38 private static Logger logger = LogManager.getLogger();
39
40 private Reader baseReader = null;
41 private Reader importReader = null;
42 private String contextURI = null;
43 private String wsdlLocation = null;
44 private String documentBase = null;
45 private String importBase = null;
46 private ClassLoader loader = null;
47
48 public LSIDWSDLLocator(String ctxt, String wsdlURI, ClassLoader cl) {
49 contextURI = ctxt;
50 wsdlLocation = wsdlURI;
51 loader = cl;
52 }
53
54 public LSIDWSDLLocator(String docBase, Reader reader, ClassLoader cl) {
55 documentBase = docBase;
56 baseReader = reader;
57 loader = cl;
58 }
59
60 /**
61 * @see javax.wsdl.xml.WSDLLocator#getBaseReader()
62 */
63 public Reader getBaseReader() {
64 if (baseReader == null) {
65 try {
66 URL url = null;
67 URL contextURL = (contextURI != null) ? StringUtils.getURL(
68 null, contextURI) : null;
69 if (loader != null) {
70 InputStream in = null;
71 try {
72 if (contextURL != null) {
73 url = new URL(contextURL, wsdlLocation);
74 } else {
75 if (wsdlLocation.indexOf(":") == -1) {
76 url = new URL("file", null, wsdlLocation);
77 } else {
78 url = new URL(wsdlLocation);
79 }
80 }
81 String wsdlRelativeLocation = url.getPath();
82 if (wsdlRelativeLocation.startsWith("/")) {
83 wsdlRelativeLocation = wsdlRelativeLocation
84 .substring(1);
85 }
86 in = loader
87 .getResourceAsStream(wsdlRelativeLocation);
88 baseReader = new InputStreamReader(in);
89 } catch (Exception exc) {
90 }
91 }
92 if (baseReader == null) {
93 url = StringUtils.getURL(contextURL, wsdlLocation);
94 baseReader = new InputStreamReader(StringUtils
95 .getContentAsInputStream(url));
96 }
97 if (url != null) {
98 documentBase = url.toString();
99 }
100 } catch (Exception e) {
101 documentBase = wsdlLocation;
102 }
103 }
104
105 return baseReader;
106 }
107
108 /**
109 * @see javax.wsdl.xml.WSDLLocator#getBaseURI()
110 */
111 @Override
112 public String getBaseURI() {
113 return documentBase;
114 }
115
116 /**
117 * used to read imports as a document is parsed
118 *
119 * @see javax.wsdl.xml.WSDLLocator#getImportReader(String, String)
120 */
121 public Reader getImportReader(String base, String relativeLocation) {
122 // Reset importReader if finding import within import
123 importReader = null;
124 boolean triedSU = false;
125 try {
126 // If a ClassLoader was used to load the base
127 // document, chances
128 // are we need to use it to find the import.
129 URL url = null;
130 if (loader != null) {
131 if (relativeLocation.startsWith("/")
132 || relativeLocation.startsWith("\\")) {
133 // Relative location has been specified from a root dir.
134 // However,
135 // using a ClassLoader, root dirs don't mean anything.
136 relativeLocation = relativeLocation.substring(1,relativeLocation.length());
137 InputStream in = loader.getResourceAsStream(relativeLocation);
138 importReader = new InputStreamReader(in);
139 } else if (relativeLocation.indexOf("://") != -1) {
140 // This is a fully specified URL of some kind so don't
141 // use the
142 // ClassLoader to find the import.
143 triedSU = true;
144 url = StringUtils.getURL(null, relativeLocation);
145 importReader = new InputStreamReader(StringUtils
146 .getContentAsInputStream(url));
147 } else {
148 // Import location has been specified relative to the
149 // base document
150 // and so we can to try to form the complete path to it.
151 if (base != null) {
152 int i = base.lastIndexOf("/");
153 if (i == -1) {
154 i = base.lastIndexOf("\\");
155 }
156 if (i != -1) {
157 String path = base.substring(0, i + 1);
158 String resolvedPath = path + relativeLocation;
159 if (relativeLocation.startsWith("..")) {
160 resolvedPath = resolvePath(path,
161 relativeLocation);
162 }
163 if (resolvedPath == null) {
164 throw new Exception("Invalid Path");
165 }
166
167 // Make sure that resolved path starts with
168 // file:
169 if (resolvedPath.startsWith("file:")) {
170 url = new URL(null, resolvedPath);
171 } else {
172 url = new URL(null, "file:" + resolvedPath);
173 }
174 } else {
175 url = new URL(null, "file:" + base + File.separator + relativeLocation);
176 }
177 InputStream in = loader.getResourceAsStream(url.getPath());
178 importReader = new InputStreamReader(in);
179 } else {
180 url = new URL(null, "file:" + relativeLocation);
181 InputStream in = loader.getResourceAsStream(url.getPath());
182 importReader = new InputStreamReader(in);
183 }
184 }
185 } else {
186 triedSU = true;
187 URL contextURL = (base != null) ? StringUtils.getURL(null,
188 base) : null;
189 url = StringUtils.getURL(contextURL, relativeLocation);
190 importReader = new InputStreamReader(StringUtils
191 .getContentAsInputStream(url));
192 }
193 importBase = (url == null) ? relativeLocation : url.toString();
194 } catch (Exception e) {
195 logger.error(e.toString());
196 logger.error(e.getMessage());
197 // If we have not tried using a non-ClassLoader route, try it
198 // now
199 // as a last resort.
200 if (!triedSU) {
201 try {
202 URL contextURL = (base != null) ? StringUtils.getURL(
203 null, base) : null;
204 URL url = StringUtils.getURL(contextURL,
205 relativeLocation);
206 importReader = new InputStreamReader(StringUtils
207 .getContentAsInputStream(url));
208 importBase = (url == null) ? relativeLocation : url
209 .toString();
210 } catch (Exception e2) {
211 logger.error(e2.toString());
212 logger.error("Cannot find " + importBase + " so setting importBase to unknownImportURI");
213 // we can't find the import so set a temporary value for
214 // the import URI. This is
215 // necessary to avoid a NullPointerException in
216 // WSDLReaderImpl
217 importBase = "unknownImportURI";
218 }
219 } else {
220 logger.error("Cannot find " + importBase + " so setting importBase to unknownImportURI");
221 // we can't find the import so set a temporary value for the
222 // import URI. This is
223 // necessary to avoid a NullPointerException in
224 // WSDLReaderImpl
225 importBase = "unknownImportURI";
226 }
227 }
228
229 return importReader;
230 }
231
232 /**
233 * Resolve a path when the relative location begins with ..
234 */
235 private String resolvePath(String ba, String rel) {
236 StringBuffer sb = new StringBuffer(rel);
237 int dd = 0;
238 while (sb.length() > 0) {
239 if (sb.length() > 3 && sb.charAt(0) == '.'
240 && sb.charAt(1) == '.'
241 && (sb.charAt(2) == '/' || sb.charAt(2) == '\\')) {
242 dd++;
243 sb.delete(0, 3);
244 } else {
245 break;
246 }
247 }
248 StringBuffer sb2 = new StringBuffer(ba);
249 int j = sb2.length() - 1;
250 int found = 0;
251 for (int k = j; k >= 0; k--) {
252 if (k != j && (sb2.charAt(k) == '/' || sb2.charAt(k) == '\\')) {
253 found++;
254 }
255 if (found < dd) {
256 sb2.deleteCharAt(k);
257 } else {
258 break;
259 }
260 }
261 if (found + 1 < dd) {
262 return null;
263 }
264 return sb2.toString() + sb.toString();
265 }
266
267 /**
268 * @see javax.wsdl.xml.WSDLLocator#getLatestImportURI()
269 */
270 @Override
271 public String getLatestImportURI() {
272 return importBase;
273 }
274
275 /**
276 * @see javax.wsdl.xml.WSDLLocator#getBaseInputSource()
277 */
278 @Override
279 public InputSource getBaseInputSource() {
280 return new InputSource(getBaseReader());
281 }
282
283 /**
284 * @see javax.wsdl.xml.WSDLLocator#getImportInputSource(String, String)
285 */
286 @Override
287 public InputSource getImportInputSource(String arg0, String arg1) {
288 return new InputSource(getImportReader(arg0, arg1));
289 }
290
291 @Override
292 public void close() {
293 if (baseReader != null) {
294 try {
295 baseReader.close();
296 } catch (IOException e) {
297 // TODO Auto-generated catch block
298 e.printStackTrace();
299 }
300 }
301 if (importReader != null) {
302 try {
303 importReader.close();
304 } catch (IOException e) {
305 // TODO Auto-generated catch block
306 e.printStackTrace();
307 }
308 }
309 }
310
311 }