org.apereo.portal.utils.ResourceLoader.java Source code

Java tutorial

Introduction

Here is the source code for org.apereo.portal.utils.ResourceLoader.java

Source

/**
 * Licensed to Apereo under one or more contributor license
 * agreements. See the NOTICE file distributed with this work
 * for additional information regarding copyright ownership.
 * Apereo licenses this file to you under the Apache License,
 * Version 2.0 (the "License"); you may not use this file
 * except in compliance with the License.  You may obtain a
 * copy of the License at the following location:
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package org.apereo.portal.utils;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Map;
import java.util.Properties;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apereo.portal.ResourceMissingException;
import org.apereo.portal.properties.PropertiesManager;
import org.w3c.dom.Document;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

/**
 * <p>This utility provides methods for accessing resources.
 * The methods generally use the classpath to find the resource
 * if the requested URL isn't already specified as a fully-qualified
 * URL string.</p>
 * <p>The methods of this class sort of replace the old UtiltiesBean.fixURI() method.</p>
 * @author Ken Weiner, kweiner@unicon.net
 * @version $Revision$
 * @since uPortal 2.0
 * @deprecated use CachingResourceLoader
 */
@Deprecated
public class ResourceLoader {

    private static final Log log = LogFactory.getLog(ResourceLoader.class);

    private static DocumentBuilderFactory validatingDocumentBuilderFactory;

    private static DocumentBuilderFactory nonValidatingDocumentBuilderFactory;

    private static Map<Tuple<Class<?>, String>, URL> resourceUrlCache;
    private static Map<Tuple<Class<?>, String>, ResourceMissingException> resourceUrlNotFoundCache;

    static {
        validatingDocumentBuilderFactory = DocumentBuilderFactory.newInstance();
        nonValidatingDocumentBuilderFactory = DocumentBuilderFactory.newInstance();

        validatingDocumentBuilderFactory.setValidating(true);
        nonValidatingDocumentBuilderFactory.setValidating(false);

        validatingDocumentBuilderFactory.setNamespaceAware(true);
        nonValidatingDocumentBuilderFactory.setNamespaceAware(true);

        try {
            String handler = PropertiesManager.getProperty("org.apereo.portal.utils.ResourceLoader.HttpsHandler");
            if ((System.getProperty("java.protocol.handler.pkgs") != null)
                    && !(System.getProperty("java.protocol.handler.pkgs").equals(""))) {
                handler = handler + "|" + System.getProperty("java.protocol.handler.pkgs");
            }
            System.setProperty("java.protocol.handler.pkgs", handler);
        } catch (Exception e) {
            log.error("Unable to set HTTPS Protocol handler", e);
        }
    }

    /**
     * @return the resourceUrlCache
     */
    public Map<Tuple<Class<?>, String>, URL> getResourceUrlCache() {
        return resourceUrlCache;
    }

    /**
     * @param resourceUrlCache the resourceUrlCache to set
     */
    public void setResourceUrlCache(Map<Tuple<Class<?>, String>, URL> resourceUrlCache) {
        ResourceLoader.resourceUrlCache = resourceUrlCache;
    }

    /**
     * @return the resourceUrlNotFoundCache
     */
    public Map<Tuple<Class<?>, String>, ResourceMissingException> getResourceUrlNotFoundCache() {
        return resourceUrlNotFoundCache;
    }

    /**
     * @param resourceUrlNotFoundCache the resourceUrlNotFoundCache to set
     */
    public void setResourceUrlNotFoundCache(
            Map<Tuple<Class<?>, String>, ResourceMissingException> resourceUrlNotFoundCache) {
        ResourceLoader.resourceUrlNotFoundCache = resourceUrlNotFoundCache;
    }

    /**
     * Finds a resource with a given name.  This is a convenience method for accessing a resource
     * from a channel or from the uPortal framework.  If a well-formed URL is passed in,
     * this method will use that URL unchanged to find the resource.
     * If the URL is not well-formed, this method will look for
     * the desired resource relative to the classpath.
     * If the resource name starts with "/", it is unchanged. Otherwise, the package name
     * of the requesting class is prepended to the resource name.
     * @param requestingClass the java.lang.Class object of the class that is attempting to load the resource
     * @param resource a String describing the full or partial URL of the resource to load
     * @return a URL identifying the requested resource
     * @throws ResourceMissingException
     */
    public static URL getResourceAsURL(Class<?> requestingClass, String resource) throws ResourceMissingException {
        final Tuple<Class<?>, String> cacheKey = new Tuple<Class<?>, String>(requestingClass, resource);

        //Look for a cached URL 
        final Map<Tuple<Class<?>, String>, URL> resourceUrlCache = ResourceLoader.resourceUrlCache;
        URL resourceURL = resourceUrlCache != null ? resourceUrlCache.get(cacheKey) : null;
        if (resourceURL != null) {
            return resourceURL;
        }

        //Look for a failed lookup
        final Map<Tuple<Class<?>, String>, ResourceMissingException> resourceUrlNotFoundCache = ResourceLoader.resourceUrlNotFoundCache;
        ResourceMissingException exception = resourceUrlNotFoundCache != null
                ? resourceUrlNotFoundCache.get(cacheKey)
                : null;
        if (exception != null) {
            throw new ResourceMissingException(exception);
        }

        try {
            resourceURL = new URL(resource);
        } catch (MalformedURLException murle) {
            // URL is invalid, now try to load from classpath
            resourceURL = requestingClass.getResource(resource);

            if (resourceURL == null) {
                String resourceRelativeToClasspath = null;
                if (resource.startsWith("/"))
                    resourceRelativeToClasspath = resource;
                else
                    resourceRelativeToClasspath = '/' + requestingClass.getPackage().getName().replace('.', '/')
                            + '/' + resource;
                exception = new ResourceMissingException(resource, resourceRelativeToClasspath,
                        "Resource not found in classpath: " + resourceRelativeToClasspath);
                if (resourceUrlNotFoundCache != null) {
                    resourceUrlNotFoundCache.put(cacheKey, exception);
                }
                throw new ResourceMissingException(exception);
            }
        }

        if (resourceUrlCache != null) {
            resourceUrlCache.put(cacheKey, resourceURL);
        }
        return resourceURL;
    }

    /**
     * Returns the requested resource as a URL string.
     * @param requestingClass the java.lang.Class object of the class that is attempting to load the resource
     * @param resource a String describing the full or partial URL of the resource to load
     * @return the requested resource as a URL string
     * @throws ResourceMissingException
     */
    public static String getResourceAsURLString(Class<?> requestingClass, String resource)
            throws ResourceMissingException {
        return getResourceAsURL(requestingClass, resource).toString();
    }

    public static long getResourceLastModified(Class<?> requestingClass, String resource) {
        final URL contentUrl = getResourceAsURL(requestingClass, resource);
        final String contentFileName = contentUrl.getFile();

        //Use JAR modified time if the resource is in a .jar file denoted by ! delimeter
        final int delimIndex = contentFileName.indexOf('!');

        final File contentFile;
        if (delimIndex > 0) {
            contentFile = new File(contentFileName.substring(0, delimIndex));
        } else {
            contentFile = new File(contentFileName);
        }

        return contentFile.lastModified();
    }

    /**
     * Returns the requested resource as a stream.
     * @param requestingClass the java.lang.Class object of the class that is attempting to load the resource
     * @param resource a String describing the full or partial URL of the resource to load
     * @return the requested resource as a stream
     * @throws ResourceMissingException
     * @throws java.io.IOException
     */
    public static InputStream getResourceAsStream(Class<?> requestingClass, String resource)
            throws ResourceMissingException, IOException {
        return getResourceAsURL(requestingClass, resource).openStream();
    }

    /**
     * Returns the requested resource as a SAX input source.
     * @param requestingClass the java.lang.Class object of the class that is attempting to load the resource
     * @param resource a String describing the full or partial URL of the resource to load
     * @return the requested resource as a SAX input source
     * @throws ResourceMissingException
     * @throws java.io.IOException
     */
    public static InputSource getResourceAsSAXInputSource(Class<?> requestingClass, String resource)
            throws ResourceMissingException, IOException {
        URL url = getResourceAsURL(requestingClass, resource);
        InputSource source = new InputSource(url.openStream());
        source.setPublicId(url.toExternalForm());
        return source;
    }

    /**
     * Get the contents of a URL as an XML Document
     * @param requestingClass the java.lang.Class object of the class that is attempting to load the resource
     * @param resource a String describing the full or partial URL of the resource whose contents to load
     * @param validate boolean. True if the document builder factory should validate, false otherwise.
     * @return the actual contents of the resource as an XML Document
     * @throws ResourceMissingException
     * @throws java.io.IOException
     * @throws javax.xml.parsers.ParserConfigurationException
     * @throws org.xml.sax.SAXException
     */
    public static Document getResourceAsDocument(Class<?> requestingClass, String resource, boolean validate)
            throws ResourceMissingException, IOException, ParserConfigurationException, SAXException {
        Document document = null;
        InputStream inputStream = null;

        try {

            DocumentBuilderFactory factoryToUse = null;

            if (validate) {
                factoryToUse = ResourceLoader.validatingDocumentBuilderFactory;
            } else {
                factoryToUse = ResourceLoader.nonValidatingDocumentBuilderFactory;
            }
            inputStream = getResourceAsStream(requestingClass, resource);
            DocumentBuilder db = factoryToUse.newDocumentBuilder();

            db.setEntityResolver(new DTDResolver());
            db.setErrorHandler(new SAXErrorHandler("ResourceLoader.getResourceAsDocument(" + resource + ")"));
            document = db.parse(inputStream);
        } finally {
            if (inputStream != null)
                inputStream.close();
        }
        return document;
    }

    /**
     * Get the contents of a URL as an XML Document, first trying to read the Document with validation turned on,
     * and falling back to reading it with validation turned off.
     * @param requestingClass the java.lang.Class object of the class that is attempting to load the resource
     * @param resource a String describing the full or partial URL of the resource whose contents to load
     * @return the actual contents of the resource as an XML Document
     * @throws ResourceMissingException
     * @throws java.io.IOException
     * @throws javax.xml.parsers.ParserConfigurationException
     * @throws org.xml.sax.SAXException
     */
    public static Document getResourceAsDocument(Class<?> requestingClass, String resource)
            throws ResourceMissingException, IOException, ParserConfigurationException, SAXException {

        // Default is non-validating...
        return getResourceAsDocument(requestingClass, resource, false);

    }

    /**
     * Get the contents of a URL as a java.util.Properties object
     * @param requestingClass the java.lang.Class object of the class that is attempting to load the resource
     * @param resource a String describing the full or partial URL of the resource whose contents to load
     * @return the actual contents of the resource as a Properties object
     * @throws ResourceMissingException
     * @throws java.io.IOException
     */
    public static Properties getResourceAsProperties(Class<?> requestingClass, String resource)
            throws ResourceMissingException, IOException {
        InputStream inputStream = null;
        Properties props = null;
        try {
            inputStream = getResourceAsStream(requestingClass, resource);
            props = new Properties();
            props.load(inputStream);
        } finally {
            if (inputStream != null)
                inputStream.close();
        }
        return props;
    }

    /**
     * Get the contents of a URL as a String
     * @param requestingClass the java.lang.Class object of the class that is attempting to load the resource
     * @param resource a String describing the full or partial URL of the resource whose contents to load
     * @return the actual contents of the resource as a String
     * @throws ResourceMissingException
     * @throws java.io.IOException
     */
    public static String getResourceAsString(Class<?> requestingClass, String resource)
            throws ResourceMissingException, IOException {
        String line = null;
        BufferedReader in = null;
        StringBuffer sbText = null;
        try {
            in = new BufferedReader(new InputStreamReader(getResourceAsStream(requestingClass, resource)));
            sbText = new StringBuffer(1024);
            while ((line = in.readLine()) != null)
                sbText.append(line).append("\n");
        } finally {
            if (in != null)
                in.close();
        }
        return sbText.toString();
    }
}