Package org.geoserver.web

Source Code of org.geoserver.web.GeoServerResourceStreamLocator$UrlResourceStream

/* Copyright (c) 2001 - 2007 TOPP - www.openplans.org. All rights reserved.
* This code is licensed under the GPL 2.0 license, available at the root
* application directory.
*/
package org.geoserver.web;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.JarURLConnection;
import java.net.URI;
import java.net.URL;
import java.net.URLConnection;
import java.util.Enumeration;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Pattern;

import org.apache.wicket.Application;
import org.apache.wicket.protocol.http.WebApplication;
import org.apache.wicket.util.resource.AbstractResourceStream;
import org.apache.wicket.util.resource.IFixedLocationResourceStream;
import org.apache.wicket.util.resource.IResourceStream;
import org.apache.wicket.util.resource.ResourceStreamNotFoundException;
import org.apache.wicket.util.resource.locator.ResourceStreamLocator;
import org.apache.wicket.util.time.Time;
import org.geotools.util.logging.Logging;

/**
* A custom resource stream locator which supports loading i18n properties files on a single file
* per module basis. It also works around https://issues.apache.org/jira/browse/WICKET-2534
*/
public class GeoServerResourceStreamLocator extends ResourceStreamLocator {
    public static Logger LOGGER = Logging.getLogger("org.geoserver.web");

    static Pattern GS_PROPERTIES = Pattern.compile("GeoServerApplication.*.properties");

    static Pattern GS_LOCAL_I18N = Pattern.compile("org/geoserver/.*(\\.properties|\\.xml)]");

    @SuppressWarnings( { "unchecked", "serial" })
    public IResourceStream locate(Class clazz, String path) {
        int i = path.lastIndexOf("/");
        if (i != -1) {
            String p = path.substring(i + 1);
            if (GS_PROPERTIES.matcher(p).matches()) {
                try {
                    // process the classpath for property files
                    Enumeration<URL> urls = getClass().getClassLoader().getResources(p);

                    // build up a single properties file
                    Properties properties = new Properties();

                    while (urls.hasMoreElements()) {
                        URL url = urls.nextElement();

                        InputStream in = url.openStream();
                        properties.load(in);
                        in.close();
                    }

                    // transform the properties to a stream
                    final ByteArrayOutputStream out = new ByteArrayOutputStream();
                    properties.store(out, "");

                    return new AbstractResourceStream() {
                        public InputStream getInputStream() throws ResourceStreamNotFoundException {
                            return new ByteArrayInputStream(out.toByteArray());
                        }

                        public void close() throws IOException {
                            out.close();
                        }
                    };
                } catch (IOException e) {
                    LOGGER.log(Level.WARNING, "", e);
                }
            } else if (GS_LOCAL_I18N.matcher(path).matches()) {
                return null;
            } else if (path.matches("org/geoserver/.*" + clazz.getName() + ".*_.*.html")) {
                return null;
            }
        }

        return super.locate(clazz, path);
    }

    /**
     * Search the the resource my means of the various classloaders available
     *
     * @param clazz
     * @param path
     * @return resource stream
     */
    protected IResourceStream locateByClassLoader(final Class clazz, final String path) {
        ClassLoader classLoader = null;
        if (clazz != null) {
            classLoader = clazz.getClassLoader();
        }

        if (classLoader == null) {
            // use context classloader when no specific classloader is set
            // (package resources for instance)
            classLoader = Thread.currentThread().getContextClassLoader();
        }

        if (classLoader == null) {
            // use Wicket classloader when no specific classloader is set
            classLoader = getClass().getClassLoader();
        }

        // Try loading path using classloader
        final URL url = classLoader.getResource(path);
        if (url != null) {
            return new UrlResourceStream(url);
        }
        return null;
    }
   
    /*
     * Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF 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
     *
     *      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.
     */

    /**
     * This is a modified version of Wicket own {@link UrlResourceStream} that has
     * been modified to work around https://issues.apache.org/jira/browse/WICKET-2534 without
     * having to upgrade to Wicket 1.4
     *
     * @see org.apache.wicket.util.resource.IResourceStream
     * @see org.apache.wicket.util.watch.IModifiable
     * @author Jonathan Locke
     */
    static class UrlResourceStream extends AbstractResourceStream implements
            IFixedLocationResourceStream {
        private static final long serialVersionUID = 1L;

        /** Resource stream. */
        private transient InputStream inputStream;

        /** The URL to this resource. */
        private final URL url;

        /**
         * the handle to the file if it is a file resource
         */
        private File file;

        /** Length of stream. */
        private int contentLength;

        /** Content type for stream. */
        private String contentType;

        /** Last known time the stream was last modified. */
        private long lastModified;

        /**
         * Construct.
         *
         * @param url
         *            URL of resource
         */
        public UrlResourceStream(final URL url) {
            // Save URL
            this.url = url;
            URLConnection connection = null;
            try {
                connection = url.openConnection();
                contentLength = connection.getContentLength();
                contentType = connection.getContentType();
                try {
                    file = new File(new URI(url.toExternalForm()));
                } catch (Exception ex) {
                    LOGGER.fine("cannot convert url: " + url + " to file (" + ex.getMessage()
                            + "), falling back to the inputstream for polling");
                }
                if (file != null && !file.exists()) {
                    file = null;
                }
            } catch (IOException ex) {
                // It should be impossible to get here or the original URL
                // couldn't have been constructed. But we re-throw with details
                // anyway.
                final IllegalArgumentException illegalArgumentException = new IllegalArgumentException(
                        "Invalid URL parameter " + url);
                illegalArgumentException.initCause(ex);
                throw illegalArgumentException;
            } finally {
                // if applicable, disconnect
                if (connection != null) {
                    if (connection instanceof HttpURLConnection) {
                        ((HttpURLConnection) connection).disconnect();
                    } else {
                        try {
                            connection.getInputStream().close();
                        } catch (Exception ex) {
                            // ignore
                        }
                    }
                }
            }
        }

        /**
         * Closes this resource.
         *
         * @throws IOException
         */
        public void close() throws IOException {
            if (inputStream != null) {
                inputStream.close();
                inputStream = null;
            }
        }

        /**
         * @return The content type of this resource, such as "image/jpeg" or "text/html"
         */
        public String getContentType() {
            testContentType();
            return contentType;
        }

        /**
         * Method to test the content type on null or unknown. if this is the case the content type
         * is tried to be resolved throw the servlet context
         */
        private void testContentType() {
            if (contentType == null || contentType.indexOf("unknown") != -1) {
                Application application = Application.get();
                if (application instanceof WebApplication) {
                    // TODO Post 1.2: General: For non webapplication another method
                    // should be implemented (getMimeType on application?)
                    contentType = ((WebApplication) application).getServletContext().getMimeType(
                            url.getFile());
                    if (contentType == null) {
                        contentType = URLConnection.getFileNameMap().getContentTypeFor(
                                url.getFile());
                    }
                } else {
                    contentType = URLConnection.getFileNameMap().getContentTypeFor(url.getFile());
                }
            }
        }

        /**
         * @return A readable input stream for this resource.
         * @throws ResourceStreamNotFoundException
         */
        public InputStream getInputStream() throws ResourceStreamNotFoundException {
            if (inputStream == null) {
                try {
                    inputStream = url.openStream();
                } catch (IOException e) {
                    throw new ResourceStreamNotFoundException("Resource " + url
                            + " could not be opened", e);
                }
            }

            return inputStream;
        }

        /**
         * @return The URL to this resource (if any)
         */
        public URL getURL() {
            return url;
        }

        /**
         * @see org.apache.wicket.util.watch.IModifiable#lastModifiedTime()
         * @return The last time this resource was modified
         */
        public Time lastModifiedTime() {
            if (file != null) {
                long lastModified = file.lastModified();
                if (lastModified != this.lastModified) {
                    this.lastModified = lastModified;
                    contentLength = (int) file.length();
                }
            } else {
                URLConnection urlConnection = null;
                boolean close = false;
                try {
                    urlConnection = url.openConnection();
                    long lastModified = this.lastModified;
                    if (urlConnection instanceof JarURLConnection) {
                        JarURLConnection jarUrlConnection = (JarURLConnection) urlConnection;
                        URL jarFileUrl = jarUrlConnection.getJarFileURL();
                        URLConnection jarFileConnection = jarFileUrl.openConnection();
                        try {
                            lastModified = jarFileConnection.getLastModified();
                        } finally {
                            jarFileConnection.getInputStream().close();
                        }
                    } else {
                        close = true;
                        lastModified = urlConnection.getLastModified();
                    }
                    // update the last modified time.
                    if (lastModified != this.lastModified) {
                        this.lastModified = lastModified;
                        close = true;
                        contentLength = urlConnection.getContentLength();
                    }
                } catch (IOException e) {
                    if (url.toString().indexOf(".jar!") >= 0) {
                        if (LOGGER.isLoggable(Level.FINE)) {
                            LOGGER
                                    .fine("getLastModified for " + url + " failed: "
                                            + e.getMessage());
                        }
                    } else {
                        LOGGER.severe("getLastModified for " + url + " failed: " + e.getMessage());
                    }
                } finally {
                    // if applicable, disconnect
                    if (urlConnection != null) {
                        if (urlConnection instanceof HttpURLConnection) {
                            ((HttpURLConnection) urlConnection).disconnect();
                        } else if (close) {
                            try {
                                urlConnection.getInputStream().close();
                            } catch (Exception ex) {
                                // ignore
                            }
                        }
                    }
                }
            }
            return Time.milliseconds(lastModified);
        }

        /**
         * @see java.lang.Object#toString()
         */
        public String toString() {
            return url.toString();
        }

        /**
         * @see org.apache.wicket.util.resource.IResourceStream#length()
         */
        public long length() {
            return contentLength;
        }

        /**
         * @see org.apache.wicket.util.resource.IFixedLocationResourceStream#locationAsString()
         */
        public String locationAsString() {
            return url.toExternalForm();
        }
    }

}
TOP

Related Classes of org.geoserver.web.GeoServerResourceStreamLocator$UrlResourceStream

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.