Package winstone

Source Code of winstone.HostConfiguration

/*
* Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
* Distributed under the terms of either:
* - the common development and distribution license (CDDL), v1.0; or
* - the GNU Lesser General Public License, v2.1 or later
*/
package winstone;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

import org.w3c.dom.Document;
import org.w3c.dom.Node;

/**
* Manages the references to individual webapps within the container. This object handles
* the mapping of url-prefixes to webapps, and init and shutdown of any webapps it manages.
*
* @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
* @version $Id: HostConfiguration.java,v 1.8 2007/08/02 06:16:00 rickknowles Exp $
*/
public class HostConfiguration implements Runnable {
   
    private static final long FLUSH_PERIOD = 60000L;
   
    private static final String WEB_INF = "WEB-INF";
    private static final String WEB_XML = "web.xml";

    private String hostname;
    private Map args;
    private Map webapps;
    private Cluster cluster;
    private ObjectPool objectPool;
    private ClassLoader commonLibCL;
    private File commonLibCLPaths[];
   
    private Thread thread;
   
    public HostConfiguration(String hostname, Cluster cluster, ObjectPool objectPool, ClassLoader commonLibCL,
            File commonLibCLPaths[], Map args, String webappsDirName) throws IOException {
        this.hostname = hostname;
        this.args = args;
        this.webapps = new Hashtable();
        this.cluster = cluster;
        this.objectPool = objectPool;
        this.commonLibCL = commonLibCL;
        this.commonLibCLPaths = commonLibCLPaths;
       
        // Is this the single or multiple configuration ? Check args
        String warfile = (String) args.get("warfile");
        String webroot = (String) args.get("webroot");
       
        // If single-webapp mode
        if ((webappsDirName == null) && ((warfile != null) || (webroot != null))) {
            String prefix = (String) args.get("prefix");
            if (prefix == null) {
                prefix = "";
            }
            try {
                this.webapps.put(prefix, initWebApp(prefix, getWebRoot(webroot, warfile), "webapp"));
            } catch (Throwable err) {
                Logger.log(Logger.ERROR, Launcher.RESOURCES, "HostConfig.WebappInitError", prefix, err);
            }
        }
        // Otherwise multi-webapp mode
        else {
            initMultiWebappDir(webappsDirName);
        }
        Logger.log(Logger.DEBUG, Launcher.RESOURCES, "HostConfig.InitComplete",
                new String[] {this.webapps.size() + "", this.webapps.keySet() + ""});
       
       
        this.thread = new Thread(this, "WinstoneHostConfigurationMgmt:" + this.hostname);
        this.thread.setDaemon(true);
        this.thread.start();
    }

    public WebAppConfiguration getWebAppByURI(String uri) {
        if (uri == null) {
            return null;
        } else if (uri.equals("/") || uri.equals("")) {
            return (WebAppConfiguration) this.webapps.get("");
        } else if (uri.startsWith("/")) {
            String decoded = WinstoneRequest.decodeURLToken(uri);
            String noLeadingSlash = decoded.substring(1);
            int slashPos = noLeadingSlash.indexOf("/");
            if (slashPos == -1) {
                return (WebAppConfiguration) this.webapps.get(decoded);
            } else {
                return (WebAppConfiguration) this.webapps.get(
                        decoded.substring(0, slashPos + 1));
            }
        } else {
            return null;
        }
    }
   
    protected WebAppConfiguration initWebApp(String prefix, File webRoot,
            String contextName) throws IOException {
        Node webXMLParentNode = null;
        File webInfFolder = new File(webRoot, WEB_INF);
        if (webInfFolder.exists()) {
            File webXmlFile = new File(webInfFolder, WEB_XML);
            if (webXmlFile.exists()) {
                Logger.log(Logger.DEBUG, Launcher.RESOURCES, "HostConfig.ParsingWebXml");
                Document webXMLDoc = new WebXmlParser(this.commonLibCL)
                        .parseStreamToXML(webXmlFile);
                if (webXMLDoc != null) {
                    webXMLParentNode = webXMLDoc.getDocumentElement();
                    Logger.log(Logger.DEBUG, Launcher.RESOURCES, "HostConfig.WebXmlParseComplete");
                } else {
                    Logger.log(Logger.DEBUG, Launcher.RESOURCES, "HostConfig.WebXmlParseFailed");
                }
            }
        }

        // Instantiate the webAppConfig
        return new WebAppConfiguration(this, this.cluster, webRoot
                .getCanonicalPath(), prefix, this.objectPool, this.args,
                webXMLParentNode, this.commonLibCL,
                this.commonLibCLPaths, contextName);
    }
   
    public String getHostname() {
        return this.hostname;
    }
   
    /**
     * Destroy this webapp instance. Kills the webapps, plus any servlets,
     * attributes, etc
     *
     * @param webApp The webapp to destroy
     */
    private void destroyWebApp(String prefix) {
        WebAppConfiguration webAppConfig = (WebAppConfiguration) this.webapps.get(prefix);
        if (webAppConfig != null) {
            webAppConfig.destroy();
            this.webapps.remove(prefix);
        }
    }
   
    public void destroy() {
        Set prefixes = new HashSet(this.webapps.keySet());
        for (Iterator i = prefixes.iterator(); i.hasNext(); ) {
            destroyWebApp((String) i.next());
        }
        if (this.thread != null) {
            this.thread.interrupt();
        }
    }
   
    public void invalidateExpiredSessions() {
        Set webapps = new HashSet(this.webapps.values());
        for (Iterator i = webapps.iterator(); i.hasNext(); ) {
            ((WebAppConfiguration) i.next()).invalidateExpiredSessions();
        }
    }

    public void run() {
        boolean interrupted = false;
        while (!interrupted) {
            try {
                Thread.sleep(FLUSH_PERIOD);
                invalidateExpiredSessions();
            } catch (InterruptedException err) {
                interrupted = true;
            }
        }
        this.thread = null;
    }
   
    public void reloadWebApp(String prefix) throws IOException {
        WebAppConfiguration webAppConfig = (WebAppConfiguration) this.webapps.get(prefix);
        if (webAppConfig != null) {
            String webRoot = webAppConfig.getWebroot();
            String contextName = webAppConfig.getContextName();
            destroyWebApp(prefix);
            try {
                this.webapps.put(prefix, initWebApp(prefix, new File(webRoot), contextName));
            } catch (Throwable err) {
                Logger.log(Logger.ERROR, Launcher.RESOURCES, "HostConfig.WebappInitError", prefix, err);
            }
        } else {
            throw new WinstoneException(Launcher.RESOURCES.getString("HostConfig.PrefixUnknown", prefix));
        }
    }   
   
    /**
     * Setup the webroot. If a warfile is supplied, extract any files that the
     * war file is newer than. If none is supplied, use the default temp
     * directory.
     */
    protected File getWebRoot(String requestedWebroot, String warfileName) throws IOException {
        if (warfileName != null) {
            Logger.log(Logger.INFO, Launcher.RESOURCES,
                    "HostConfig.BeginningWarExtraction");

            // open the war file
            File warfileRef = new File(warfileName);
            if (!warfileRef.exists() || !warfileRef.isFile())
                throw new WinstoneException(Launcher.RESOURCES.getString(
                        "HostConfig.WarFileInvalid", warfileName));

            // Get the webroot folder (or a temp dir if none supplied)
            File unzippedDir = null;
            if (requestedWebroot != null) {
                unzippedDir = new File(requestedWebroot);
            } else {
                File tempFile = File.createTempFile("dummy", "dummy");
                String userName = System.getProperty("user.name");
                unzippedDir = new File(tempFile.getParent(), "winstone/" +
                        (userName != null ? WinstoneResourceBundle.globalReplace(userName,
                                new String[][] {{"/", ""}, {"\\", ""}, {",", ""}}) + "/" : "") +
                        warfileRef.getName());
                tempFile.delete();
            }
            if (unzippedDir.exists()) {
                if (!unzippedDir.isDirectory()) {
                    throw new WinstoneException(Launcher.RESOURCES.getString(
                            "HostConfig.WebRootNotDirectory", unzippedDir.getPath()));
                } else {
                    Logger.log(Logger.DEBUG, Launcher.RESOURCES,
                            "HostConfig.WebRootExists", unzippedDir.getCanonicalPath());
                }
            } else {
                unzippedDir.mkdirs();
            }

            // Iterate through the files
            JarFile warArchive = new JarFile(warfileRef);
            for (Enumeration e = warArchive.entries(); e.hasMoreElements();) {
                JarEntry element = (JarEntry) e.nextElement();
                if (element.isDirectory()) {
                    continue;
                }
                String elemName = element.getName();

                // If archive date is newer than unzipped file, overwrite
                File outFile = new File(unzippedDir, elemName);
                if (outFile.exists() && (outFile.lastModified() > warfileRef.lastModified())) {
                    continue;
                }
                outFile.getParentFile().mkdirs();
                byte buffer[] = new byte[8192];

                // Copy out the extracted file
                InputStream inContent = warArchive.getInputStream(element);
                OutputStream outStream = new FileOutputStream(outFile);
                int readBytes = inContent.read(buffer);
                while (readBytes != -1) {
                    outStream.write(buffer, 0, readBytes);
                    readBytes = inContent.read(buffer);
                }
                inContent.close();
                outStream.close();
            }

            // Return webroot
            return unzippedDir;
        } else {
            return new File(requestedWebroot);
        }
    }
   
    protected void initMultiWebappDir(String webappsDirName) throws IOException {
        if (webappsDirName == null) {
            webappsDirName = "webapps";
        }
        File webappsDir = new File(webappsDirName);
        if (!webappsDir.exists()) {
            throw new WinstoneException(Launcher.RESOURCES.getString("HostConfig.WebAppDirNotFound", webappsDirName));
        } else if (!webappsDir.isDirectory()) {
            throw new WinstoneException(Launcher.RESOURCES.getString("HostConfig.WebAppDirIsNotDirectory", webappsDirName));
        } else {
            File children[] = webappsDir.listFiles();
            for (int n = 0; n < children.length; n++) {
                String childName = children[n].getName();
               
                // Check any directories for warfiles that match, and skip: only deploy the war file
                if (children[n].isDirectory()) {
                    File matchingWarFile = new File(webappsDir, children[n].getName() + ".war");
                    if (matchingWarFile.exists() && matchingWarFile.isFile()) {
                        Logger.log(Logger.DEBUG, Launcher.RESOURCES, "HostConfig.SkippingWarfileDir", childName);
                    } else {
                        String prefix = childName.equalsIgnoreCase("ROOT") ? "" : "/" + childName;
                        if (!this.webapps.containsKey(prefix)) {
                            try {
                                WebAppConfiguration webAppConfig = initWebApp(prefix, children[n], childName);
                                this.webapps.put(webAppConfig.getContextPath(), webAppConfig);
                                Logger.log(Logger.INFO, Launcher.RESOURCES, "HostConfig.DeployingWebapp", childName);
                            } catch (Throwable err) {
                                Logger.log(Logger.ERROR, Launcher.RESOURCES, "HostConfig.WebappInitError", prefix, err);
                            }
                        }
                    }
                } else if (childName.endsWith(".war")) {
                    String outputName = childName.substring(0, childName.lastIndexOf(".war"));
                    String prefix = outputName.equalsIgnoreCase("ROOT") ? "" : "/" + outputName;
                   
                    if (!this.webapps.containsKey(prefix)) {
                        File outputDir = new File(webappsDir, outputName);
                        outputDir.mkdirs();
                        try {
                            WebAppConfiguration webAppConfig = initWebApp(prefix,
                                            getWebRoot(new File(webappsDir, outputName).getCanonicalPath(),
                                                    children[n].getCanonicalPath()), outputName);
                            this.webapps.put(webAppConfig.getContextPath(), webAppConfig);
                            Logger.log(Logger.INFO, Launcher.RESOURCES, "HostConfig.DeployingWebapp", childName);
                        } catch (Throwable err) {
                            Logger.log(Logger.ERROR, Launcher.RESOURCES, "HostConfig.WebappInitError", prefix, err);
                        }
                    }
                }
            }
        }
    }
   
    public WebAppConfiguration getWebAppBySessionKey(String sessionKey) {
        List allwebapps = new ArrayList(this.webapps.values());
        for (Iterator i = allwebapps.iterator(); i.hasNext(); ) {
            WebAppConfiguration webapp = (WebAppConfiguration) i.next();
            WinstoneSession session = webapp.getSessionById(sessionKey, false);
            if (session != null) {
                return webapp;
            }
        }
        return null;
    }
}
TOP

Related Classes of winstone.HostConfiguration

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.