Package org.apache.cocoon.tools.rcl.wrapper.servlet

Source Code of org.apache.cocoon.tools.rcl.wrapper.servlet.ReloadingClassloaderManager

/*
* 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.
*/
package org.apache.cocoon.tools.rcl.wrapper.servlet;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;

import javax.servlet.ServletContext;

import org.apache.commons.io.IOUtils;
import org.apache.commons.jci.ReloadingClassLoader;
import org.apache.commons.jci.monitor.FilesystemAlterationMonitor;

public abstract class ReloadingClassloaderManager {

    private static final String FILE_PROTOCOL = "file:";

    private static ClassLoader reloadingClassloader = null;

    public static synchronized ClassLoader getClassLoader(ServletContext context) {
        // if there is no classloader, create one
        if (ReloadingClassloaderManager.reloadingClassloader == null) {
            // create the URL classloader
            final ClassLoader urlClassloader = createURLClassLoader(context);

            // check, if the reloading classloader should be used
            if (isReloadingClassloaderEnabled(context)) {
                final ReloadingClassLoader classloader = new ReloadingClassLoader(urlClassloader);
                final FilesystemAlterationMonitor fam = new FilesystemAlterationMonitor();

                org.apache.commons.jci.listeners.ReloadingListener rl = new CocoonReloadingListener();
                rl.addReloadNotificationListener(classloader);

                addResourcesToFam(fam, rl, getRclConfResourceUrls(context));
                fam.start();

                ReloadingClassloaderManager.reloadingClassloader = classloader;
            } else {
                // otherwise use the URL classloader only
                ReloadingClassloaderManager.reloadingClassloader = urlClassloader;
            }
        }

        return ReloadingClassloaderManager.reloadingClassloader;
    }

    protected static ClassLoader createURLClassLoader(ServletContext context) {
        try {
            List<URL> urlsList = new ArrayList<URL>();
            List<?> lines = IOUtils.readLines(context.getResourceAsStream(Constants.WEB_INF_RCL_URLCL_CONF));

            for (Iterator<?> linesIt = lines.iterator(); linesIt.hasNext();) {
                String line = (String) linesIt.next();
                urlsList.add(new URL(line));
            }

            URL[] urls = urlsList.toArray(new URL[urlsList.size()]);

            return new URLClassLoader(urls, ReloadingClassloaderManager.class.getClassLoader());
        } catch (Exception e) {
            throw new ReloadingClassloaderCreationException("Error while creating the URLClassLoader from context:/"
                    + Constants.WEB_INF_RCL_URLCL_CONF, e);
        }
    }

    protected static boolean isReloadingClassloaderEnabled(ServletContext servletContext) {
        Properties rclProps = new Properties();

        try {
            rclProps.load(servletContext.getResourceAsStream(Constants.WEB_INF_RCLWRAPPER_PROPERTIES));
        } catch (IOException e) {
            throw new ReloadingClassloaderCreationException("Error while reading "
                    + Constants.WEB_INF_RCLWRAPPER_PROPERTIES + " from servlet context.", e);
        }

        String reloadingEnabled = rclProps.getProperty(Constants.RELOADING_CLASSLOADER_ENABLED, "true");
        return reloadingEnabled.trim().toLowerCase().equals("true");
    }

    private static void addResourcesToFam(final FilesystemAlterationMonitor fam,
            org.apache.commons.jci.listeners.ReloadingListener rl, List<?> resourceUrl) {
        for (Iterator<?> linesIt = resourceUrl.iterator(); linesIt.hasNext();) {
            String line = (String) linesIt.next();
            if (!line.startsWith(FILE_PROTOCOL)) {
                throw new ReloadingClassloaderCreationException("Only support URLs with file: protocol.");
            }
            String url = line.substring(FILE_PROTOCOL.length());
            // windows paths
            if (url.indexOf(2) == ':') {
                url = url.substring(1);
            }

            // add libraries to the RCL
            if(url.endsWith(".jar")) {
                // deactivate reloading of JARs since it isn't supported the JCI:
                // see https://issues.apache.org/jira/browse/JCI-60
                continue;
            }
            fam.addListener(new File(url), rl);
        }
    }

    private static List<?> getRclConfResourceUrls(ServletContext context) {
        List<?> lines = null;

        try {
            lines = IOUtils.readLines(context.getResourceAsStream(Constants.WEB_INF_RCLWRAPPER_RCL_CONF));
        } catch (IOException ioe) {
            throw new ReloadingClassloaderCreationException("Error while creating the URLClassLoader from context:/"
                    + Constants.WEB_INF_RCLWRAPPER_RCL_CONF, ioe);
        }

        return lines;
    }
}
TOP

Related Classes of org.apache.cocoon.tools.rcl.wrapper.servlet.ReloadingClassloaderManager

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.