001: /* Copyright 2001 The JA-SIG Collaborative. All rights reserved.
002: * See license distributed with this file and
003: * available online at http://www.uportal.org/license.html
004: */
005:
006: package org.jasig.portal.utils;
007:
008: import java.io.BufferedReader;
009: import java.io.File;
010: import java.io.IOException;
011: import java.io.InputStream;
012: import java.io.InputStreamReader;
013: import java.io.UnsupportedEncodingException;
014: import java.net.MalformedURLException;
015: import java.net.URL;
016: import java.net.URLDecoder;
017: import java.util.Properties;
018:
019: import javax.xml.parsers.DocumentBuilder;
020: import javax.xml.parsers.DocumentBuilderFactory;
021: import javax.xml.parsers.ParserConfigurationException;
022:
023: import org.jasig.portal.ResourceMissingException;
024: import org.jasig.portal.car.CarResources;
025: import org.jasig.portal.properties.PropertiesManager;
026: import org.apache.commons.logging.Log;
027: import org.apache.commons.logging.LogFactory;
028: import org.w3c.dom.Document;
029: import org.xml.sax.InputSource;
030: import org.xml.sax.SAXException;
031:
032: /**
033: * <p>This utility provides methods for accessing resources.
034: * The methods generally use the classpath to find the resource
035: * if the requested URL isn't already specified as a fully-qualified
036: * URL string.</p>
037: * <p>The methods of this class sort of replace the old UtiltiesBean.fixURI() method.</p>
038: * @author Ken Weiner, kweiner@unicon.net
039: * @version $Revision: 42275 $
040: * @since uPortal 2.0
041: */
042:
043: public class ResourceLoader {
044:
045: private static final Log log = LogFactory
046: .getLog(ResourceLoader.class);
047:
048: private static DocumentBuilderFactory validatingDocumentBuilderFactory;
049:
050: private static DocumentBuilderFactory nonValidatingDocumentBuilderFactory;
051:
052: static {
053: validatingDocumentBuilderFactory = DocumentBuilderFactory
054: .newInstance();
055: nonValidatingDocumentBuilderFactory = DocumentBuilderFactory
056: .newInstance();
057:
058: validatingDocumentBuilderFactory.setValidating(true);
059: nonValidatingDocumentBuilderFactory.setValidating(false);
060:
061: validatingDocumentBuilderFactory.setNamespaceAware(true);
062: nonValidatingDocumentBuilderFactory.setNamespaceAware(true);
063:
064: try {
065: String handler = PropertiesManager
066: .getProperty("org.jasig.portal.utils.ResourceLoader.HttpsHandler");
067: if ((System.getProperty("java.protocol.handler.pkgs") != null)
068: && !(System
069: .getProperty("java.protocol.handler.pkgs")
070: .equals(""))) {
071: handler = handler
072: + "|"
073: + System
074: .getProperty("java.protocol.handler.pkgs");
075: }
076: System.setProperty("java.protocol.handler.pkgs", handler);
077: } catch (Exception e) {
078: log.error("Unable to set HTTPS Protocol handler", e);
079: }
080: }
081:
082: /**
083: * Finds a resource with a given name. This is a convenience method for accessing a resource
084: * from a channel or from the uPortal framework. If a well-formed URL is passed in,
085: * this method will use that URL unchanged to find the resource.
086: * If the URL is not well-formed, this method will look for
087: * the desired resource relative to the classpath.
088: * If the resource name starts with "/", it is unchanged. Otherwise, the package name
089: * of the requesting class is prepended to the resource name.
090: * @param requestingClass the java.lang.Class object of the class that is attempting to load the resource
091: * @param resource a String describing the full or partial URL of the resource to load
092: * @return a URL identifying the requested resource
093: * @throws org.jasig.portal.ResourceMissingException
094: */
095: public static URL getResourceAsURL(Class requestingClass,
096: String resource) throws ResourceMissingException {
097: URL resourceURL = null;
098: try {
099: resourceURL = new URL(resource);
100: } catch (MalformedURLException murle) {
101: // URL is invalid, now try to load from classpath
102: resourceURL = requestingClass.getResource(resource);
103:
104: if (resourceURL == null) {
105: // try in a car file
106: resourceURL = CarResources.getInstance()
107: .getClassLoader().getResource(resource);
108: }
109:
110: if (resourceURL == null) {
111: String resourceRelativeToClasspath = null;
112: if (resource.startsWith("/"))
113: resourceRelativeToClasspath = resource;
114: else
115: resourceRelativeToClasspath = '/'
116: + requestingClass.getPackage().getName()
117: .replace('.', '/') + '/' + resource;
118: throw new ResourceMissingException(resource,
119: resourceRelativeToClasspath,
120: "Resource not found in classpath: "
121: + resourceRelativeToClasspath);
122: }
123: }
124: return resourceURL;
125: }
126:
127: /**
128: * Returns the requested resource as a URL string.
129: * @param requestingClass the java.lang.Class object of the class that is attempting to load the resource
130: * @param resource a String describing the full or partial URL of the resource to load
131: * @return the requested resource as a URL string
132: * @throws org.jasig.portal.ResourceMissingException
133: */
134: public static String getResourceAsURLString(Class requestingClass,
135: String resource) throws ResourceMissingException {
136: return getResourceAsURL(requestingClass, resource).toString();
137: }
138:
139: /**
140: * Returns the requested resource as a File.
141: * @param requestingClass the java.lang.Class object of the class that is attempting to load the resource
142: * @param resource a String describing the full or partial URL of the resource to load
143: * @return the requested resource as a File
144: * @throws org.jasig.portal.ResourceMissingException
145: */
146: public static File getResourceAsFile(Class requestingClass,
147: String resource) throws ResourceMissingException {
148: return new File(getResourceAsFileString(requestingClass,
149: resource));
150: }
151:
152: /**
153: * Returns the requested resource as a File string.
154: * @param requestingClass the java.lang.Class object of the class that is attempting to load the resource
155: * @param resource a String describing the full or partial URL of the resource to load
156: * @return the requested resource as a File string
157: * @throws org.jasig.portal.ResourceMissingException
158: */
159: public static String getResourceAsFileString(Class requestingClass,
160: String resource) throws ResourceMissingException {
161: try {
162: return URLDecoder.decode(getResourceAsURL(requestingClass,
163: resource).getFile(), "UTF-8");
164: } catch (UnsupportedEncodingException e) {
165: throw new RuntimeException(e);
166: }
167: }
168:
169: /**
170: * Returns the requested resource as a stream.
171: * @param requestingClass the java.lang.Class object of the class that is attempting to load the resource
172: * @param resource a String describing the full or partial URL of the resource to load
173: * @return the requested resource as a stream
174: * @throws org.jasig.portal.ResourceMissingException
175: * @throws java.io.IOException
176: */
177: public static InputStream getResourceAsStream(
178: Class requestingClass, String resource)
179: throws ResourceMissingException, IOException {
180: return getResourceAsURL(requestingClass, resource).openStream();
181: }
182:
183: /**
184: * Returns the requested resource as a SAX input source.
185: * @param requestingClass the java.lang.Class object of the class that is attempting to load the resource
186: * @param resource a String describing the full or partial URL of the resource to load
187: * @return the requested resource as a SAX input source
188: * @throws org.jasig.portal.ResourceMissingException
189: * @throws java.io.IOException
190: */
191: public static InputSource getResourceAsSAXInputSource(
192: Class requestingClass, String resource)
193: throws ResourceMissingException, IOException {
194: URL url = getResourceAsURL(requestingClass, resource);
195: InputSource source = new InputSource(url.openStream());
196: source.setPublicId(url.toExternalForm());
197: return source;
198: }
199:
200: /**
201: * Get the contents of a URL as an XML Document
202: * @param requestingClass the java.lang.Class object of the class that is attempting to load the resource
203: * @param resource a String describing the full or partial URL of the resource whose contents to load
204: * @param validate boolean. True if the document builder factory should validate, false otherwise.
205: * @return the actual contents of the resource as an XML Document
206: * @throws org.jasig.portal.ResourceMissingException
207: * @throws java.io.IOException
208: * @throws javax.xml.parsers.ParserConfigurationException
209: * @throws org.xml.sax.SAXException
210: */
211: public static Document getResourceAsDocument(Class requestingClass,
212: String resource, boolean validate)
213: throws ResourceMissingException, IOException,
214: ParserConfigurationException, SAXException {
215: Document document = null;
216: InputStream inputStream = null;
217:
218: try {
219:
220: DocumentBuilderFactory factoryToUse = null;
221:
222: if (validate) {
223: factoryToUse = ResourceLoader.validatingDocumentBuilderFactory;
224: } else {
225: factoryToUse = ResourceLoader.nonValidatingDocumentBuilderFactory;
226: }
227: inputStream = getResourceAsStream(requestingClass, resource);
228: DocumentBuilder db = factoryToUse.newDocumentBuilder();
229:
230: db.setEntityResolver(new DTDResolver());
231: db.setErrorHandler(new SAXErrorHandler(
232: "ResourceLoader.getResourceAsDocument(" + resource
233: + ")"));
234: document = db.parse(inputStream);
235: } finally {
236: if (inputStream != null)
237: inputStream.close();
238: }
239: return document;
240: }
241:
242: /**
243: * Get the contents of a URL as an XML Document, first trying to read the Document with validation turned on,
244: * and falling back to reading it with validation turned off.
245: * @param requestingClass the java.lang.Class object of the class that is attempting to load the resource
246: * @param resource a String describing the full or partial URL of the resource whose contents to load
247: * @return the actual contents of the resource as an XML Document
248: * @throws org.jasig.portal.ResourceMissingException
249: * @throws java.io.IOException
250: * @throws javax.xml.parsers.ParserConfigurationException
251: * @throws org.xml.sax.SAXException
252: */
253: public static Document getResourceAsDocument(Class requestingClass,
254: String resource) throws ResourceMissingException,
255: IOException, ParserConfigurationException, SAXException {
256:
257: try {
258: // first try with validation turned on
259: return getResourceAsDocument(requestingClass, resource,
260: true);
261: } catch (Exception e) {
262:
263: if (log.isDebugEnabled()) {
264: log.debug("Problem getting resource [" + resource
265: + "] as requested by class ["
266: + requestingClass.getName() + "]", e);
267:
268: } else {
269: log.warn("Problem getting resource [" + resource
270: + "] as requested by class ["
271: + requestingClass.getName() + "]");
272:
273: }
274:
275: // try again with validation turned off
276: return getResourceAsDocument(requestingClass, resource,
277: false);
278: }
279:
280: }
281:
282: /**
283: * Get the contents of a URL as a java.util.Properties object
284: * @param requestingClass the java.lang.Class object of the class that is attempting to load the resource
285: * @param resource a String describing the full or partial URL of the resource whose contents to load
286: * @return the actual contents of the resource as a Properties object
287: * @throws org.jasig.portal.ResourceMissingException
288: * @throws java.io.IOException
289: */
290: public static Properties getResourceAsProperties(
291: Class requestingClass, String resource)
292: throws ResourceMissingException, IOException {
293: InputStream inputStream = null;
294: Properties props = null;
295: try {
296: inputStream = getResourceAsStream(requestingClass, resource);
297: props = new Properties();
298: props.load(inputStream);
299: } finally {
300: if (inputStream != null)
301: inputStream.close();
302: }
303: return props;
304: }
305:
306: /**
307: * Get the contents of a URL as a String
308: * @param requestingClass the java.lang.Class object of the class that is attempting to load the resource
309: * @param resource a String describing the full or partial URL of the resource whose contents to load
310: * @return the actual contents of the resource as a String
311: * @throws org.jasig.portal.ResourceMissingException
312: * @throws java.io.IOException
313: */
314: public static String getResourceAsString(Class requestingClass,
315: String resource) throws ResourceMissingException,
316: IOException {
317: String line = null;
318: BufferedReader in = null;
319: StringBuffer sbText = null;
320: try {
321: in = new BufferedReader(new InputStreamReader(
322: getResourceAsStream(requestingClass, resource)));
323: sbText = new StringBuffer(1024);
324: while ((line = in.readLine()) != null)
325: sbText.append(line).append("\n");
326: } finally {
327: if (in != null)
328: in.close();
329: }
330: return sbText.toString();
331: }
332: }
|