1 /*
2 * The MIT License
3 *
4 * Original work sponsored and donated by National Board of e-Health (NSI), Denmark (http://www.nsi.dk)
5 *
6 * Copyright (C) 2011 National Board of e-Health (NSI), Denmark (http://www.nsi.dk)
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a copy of
9 * this software and associated documentation files (the "Software"), to deal in
10 * the Software without restriction, including without limitation the rights to
11 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
12 * of the Software, and to permit persons to whom the Software is furnished to do
13 * so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be included in all
16 * copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24 * SOFTWARE.
25 *
26 * $HeadURL: https://svn.softwareborsen.dk/sosi/trunk/modules/seal/src/main/java/dk/sosi/seal/xml/ClasspathResourceResolver.java $
27 * $Id: ClasspathResourceResolver.java 8697 2011-09-02 10:33:55Z chg@lakeside.dk $
28 */
29 package dk.sosi.seal.xml;
30
31 import dk.sosi.seal.model.ModelException;
32 import org.xml.sax.EntityResolver;
33 import org.xml.sax.InputSource;
34
35 import java.io.*;
36 import java.util.Collections;
37 import java.util.HashMap;
38 import java.util.Map;
39
40 /**
41 * Resourceresolver that will load schemas from the classpath.
42 * @author ${user}
43 * @author $$LastChangedBy: chg@lakeside.dk $$
44 * @version $$Revision: 8697 $$
45 * @since 1.3
46 */
47 public class ClasspathResourceResolver implements EntityResolver {
48
49 protected Map<String, String> inputMap;
50
51 public ClasspathResourceResolver() throws ModelException {
52 super();
53 inputMap = Collections.synchronizedMap(new HashMap<String,String>());
54 }
55
56 /**
57 * Get the schema as string specified by systemId either from the
58 * cache or by loading it from the classpath. After loading, the schema will
59 * be cached for future lookups.
60 * @param systemId
61 * The name of the schema to get e.g. soap.xsd
62 *
63 * @return Schema as String
64 * @throws IOException
65 */
66 private String getInput(String systemId) throws IOException {
67 String resourceAsString = inputMap.get(systemId);
68 if (resourceAsString == null ) {
69 String xsd = (systemId.lastIndexOf("/") != -1) ? systemId.substring(systemId.lastIndexOf("/")) : systemId;
70 //TODO maybe it is nicer to use contextclassloader to get resources?
71 //InputStream inputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream(xsd);
72 InputStream inputStream = getClass().getResourceAsStream(xsd);
73 if (inputStream != null)
74 resourceAsString = consumeStream(inputStream);
75 inputMap.put(systemId, resourceAsString);
76 }
77 return resourceAsString;
78 }
79
80 /**
81 * Callback. Resolve the resource (schema) specified by the input
82 * parameters.
83 *
84 * @param publicId
85 * @param systemId
86 * @return InputSource for the schema
87 * @throws IOException
88 */
89 public InputSource resolveEntity(String publicId, String systemId) throws IOException {
90 String resourceAsString = getInput(systemId);
91 InputSource is = new InputSource(new StringReader(resourceAsString));
92 is.setPublicId(publicId);
93 is.setSystemId(systemId);
94 return is;
95 }
96
97 public InputStream getResourceAsStream(String resource) throws IOException {
98 String resourceAsString = getInput(resource);
99 return new ByteArrayInputStream(resourceAsString.getBytes(XmlUtil.XML_ENCODING));
100 }
101
102 private String consumeStream(InputStream is) throws IOException {
103 ByteArrayOutputStream baos = new ByteArrayOutputStream();
104 byte[] buffer = new byte[8192];
105 int n;
106 while ((n = is.read(buffer, 0, buffer.length)) != -1) {
107 baos.write(buffer, 0, n);
108 }
109 return baos.toString(XmlUtil.XML_ENCODING);
110 }
111
112 }