All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.eclipse.jetty.deploy.providers.WebAppProvider Maven / Gradle / Ivy

There is a newer version: 11.0.0.beta1
Show newest version
//
//  ========================================================================
//  Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd.
//  ------------------------------------------------------------------------
//  All rights reserved. This program and the accompanying materials
//  are made available under the terms of the Eclipse Public License v1.0
//  and Apache License v2.0 which accompanies this distribution.
//
//      The Eclipse Public License is available at
//      http://www.eclipse.org/legal/epl-v10.html
//
//      The Apache License v2.0 is available at
//      http://www.opensource.org/licenses/apache2.0.php
//
//  You may elect to redistribute this code under either of these licenses.
//  ========================================================================
//

package org.eclipse.jetty.deploy.providers;

import java.io.File;
import java.io.FilenameFilter;
import java.util.Locale;

import org.eclipse.jetty.deploy.App;
import org.eclipse.jetty.deploy.ConfigurationManager;
import org.eclipse.jetty.deploy.util.FileID;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.util.URIUtil;
import org.eclipse.jetty.util.annotation.ManagedAttribute;
import org.eclipse.jetty.util.annotation.ManagedObject;
import org.eclipse.jetty.util.resource.Resource;
import org.eclipse.jetty.webapp.WebAppContext;
import org.eclipse.jetty.xml.XmlConfiguration;

/* ------------------------------------------------------------ */
/** The webapps directory scanning provider.
 * 

* This provider scans one or more directories (typically "webapps") for contexts to * deploy, which may be:

    *
  • A standard WAR file (must end in ".war")
  • *
  • A directory containing an expanded WAR file
  • *
  • A directory containing static content
  • *
  • An XML descriptor in {@link XmlConfiguration} format that configures a {@link ContextHandler} instance
  • *
*

* To avoid double deployments and allow flexibility of the content of the scanned directories, the provider * implements some heuristics to ignore some files found in the scans:

    *
  • Hidden files (starting with ".") are ignored
  • *
  • Directories with names ending in ".d" are ignored
  • *
  • If a directory and a WAR file exist ( eg foo/ and foo.war) then the directory is assumed to be * the unpacked WAR and only the WAR is deployed (which may reused the unpacked directory)
  • *
  • If a directory and a matching XML file exist ( eg foo/ and foo.xml) then the directory is assumed to be * an unpacked WAR and only the XML is deployed (which may used the directory in it's configuration)
  • *
  • If a WAR file and a matching XML exist (eg foo.war and foo.xml) then the WAR is assumed to * be configured by the XML and only the XML is deployed. *
*

For XML configured contexts, the ID map will contain a reference to the {@link Server} instance called "Server" and * properties for the webapp file as "jetty.webapp" and directory as "jetty.webapps". */ @ManagedObject("Provider for start-up deployement of webapps based on presence in directory") public class WebAppProvider extends ScanningAppProvider { private boolean _extractWars = false; private boolean _parentLoaderPriority = false; private ConfigurationManager _configurationManager; private String _defaultsDescriptor; private File _tempDirectory; private String[] _configurationClasses; public class Filter implements FilenameFilter { @Override public boolean accept(File dir, String name) { if (!dir.exists()) { return false; } String lowername = name.toLowerCase(Locale.ENGLISH); File file = new File(dir,name); // ignore hidden files if (lowername.startsWith(".")) return false; // Ignore some directories if (file.isDirectory()) { // is it a nominated config directory if (lowername.endsWith(".d")) return false; // is it an unpacked directory for an existing war file? if (exists(name+".war")||exists(name+".WAR")) return false; // is it a directory for an existing xml file? if (exists(name+".xml")||exists(name+".XML")) return false; //is it a sccs dir? if ("cvs".equals(lowername) || "cvsroot".equals(lowername)) return false; // OK to deploy it then return true; } // else is it a war file if (lowername.endsWith(".war")) { //defer deployment decision to fileChanged() return true; } // else is it a context XML file if (lowername.endsWith(".xml")) return true; return false; } } /* ------------------------------------------------------------ */ public WebAppProvider() { super(); setFilenameFilter(new Filter()); setScanInterval(0); } /* ------------------------------------------------------------ */ /** Get the extractWars. * @return the extractWars */ @ManagedAttribute("extract war files") public boolean isExtractWars() { return _extractWars; } /* ------------------------------------------------------------ */ /** Set the extractWars. * @param extractWars the extractWars to set */ public void setExtractWars(boolean extractWars) { _extractWars = extractWars; } /* ------------------------------------------------------------ */ /** Get the parentLoaderPriority. * @return the parentLoaderPriority */ @ManagedAttribute("parent classloader has priority") public boolean isParentLoaderPriority() { return _parentLoaderPriority; } /* ------------------------------------------------------------ */ /** Set the parentLoaderPriority. * @param parentLoaderPriority the parentLoaderPriority to set */ public void setParentLoaderPriority(boolean parentLoaderPriority) { _parentLoaderPriority = parentLoaderPriority; } /* ------------------------------------------------------------ */ /** Get the defaultsDescriptor. * @return the defaultsDescriptor */ @ManagedAttribute("default descriptor for webapps") public String getDefaultsDescriptor() { return _defaultsDescriptor; } /* ------------------------------------------------------------ */ /** Set the defaultsDescriptor. * @param defaultsDescriptor the defaultsDescriptor to set */ public void setDefaultsDescriptor(String defaultsDescriptor) { _defaultsDescriptor = defaultsDescriptor; } /* ------------------------------------------------------------ */ public ConfigurationManager getConfigurationManager() { return _configurationManager; } /* ------------------------------------------------------------ */ /** Set the configurationManager. * @param configurationManager the configurationManager to set */ public void setConfigurationManager(ConfigurationManager configurationManager) { _configurationManager = configurationManager; } /* ------------------------------------------------------------ */ /** * @param configurations The configuration class names. */ public void setConfigurationClasses(String[] configurations) { _configurationClasses = configurations==null?null:(String[])configurations.clone(); } /* ------------------------------------------------------------ */ /** * */ @ManagedAttribute("configuration classes for webapps to be processed through") public String[] getConfigurationClasses() { return _configurationClasses; } /** * Set the Work directory where unpacked WAR files are managed from. *

* Default is the same as the java.io.tmpdir System Property. * * @param directory the new work directory */ public void setTempDir(File directory) { _tempDirectory = directory; } /* ------------------------------------------------------------ */ /** * Get the user supplied Work Directory. * * @return the user supplied work directory (null if user has not set Temp Directory yet) */ @ManagedAttribute("temp directory for use, null if no user set temp directory") public File getTempDir() { return _tempDirectory; } /* ------------------------------------------------------------ */ @Override public ContextHandler createContextHandler(final App app) throws Exception { Resource resource = Resource.newResource(app.getOriginId()); File file = resource.getFile(); if (!resource.exists()) throw new IllegalStateException("App resource does not exist "+resource); String context = file.getName(); if (resource.exists() && FileID.isXmlFile(file)) { XmlConfiguration xmlc = new XmlConfiguration(resource.getURL()) { @Override public void initializeDefaults(Object context) { super.initializeDefaults(context); if (context instanceof WebAppContext) { WebAppContext webapp = (WebAppContext)context; webapp.setParentLoaderPriority(_parentLoaderPriority); if (_defaultsDescriptor != null) webapp.setDefaultsDescriptor(_defaultsDescriptor); } } }; xmlc.getIdMap().put("Server", getDeploymentManager().getServer()); xmlc.getProperties().put("jetty.home",System.getProperty("jetty.home",".")); xmlc.getProperties().put("jetty.base",System.getProperty("jetty.base",".")); xmlc.getProperties().put("jetty.webapp",file.getCanonicalPath()); xmlc.getProperties().put("jetty.webapps",file.getParentFile().getCanonicalPath()); if (getConfigurationManager() != null) xmlc.getProperties().putAll(getConfigurationManager().getProperties()); return (ContextHandler)xmlc.configure(); } else if (file.isDirectory()) { // must be a directory } else if (FileID.isWebArchiveFile(file)) { // Context Path is the same as the archive. context = context.substring(0,context.length() - 4); } else { throw new IllegalStateException("unable to create ContextHandler for "+app); } // Ensure "/" is Not Trailing in context paths. if (context.endsWith("/") && context.length() > 0) { context = context.substring(0,context.length() - 1); } // Start building the webapplication WebAppContext webAppContext = new WebAppContext(); webAppContext.setDisplayName(context); // special case of archive (or dir) named "root" is / context if (context.equalsIgnoreCase("root")) { context = URIUtil.SLASH; } else if (context.toLowerCase(Locale.ENGLISH).startsWith("root-")) { int dash=context.toLowerCase(Locale.ENGLISH).indexOf('-'); String virtual = context.substring(dash+1); webAppContext.setVirtualHosts(new String[]{virtual}); context = URIUtil.SLASH; } // Ensure "/" is Prepended to all context paths. if (context.charAt(0) != '/') { context = "/" + context; } webAppContext.setContextPath(context); webAppContext.setWar(file.getAbsolutePath()); if (_defaultsDescriptor != null) { webAppContext.setDefaultsDescriptor(_defaultsDescriptor); } webAppContext.setExtractWAR(_extractWars); webAppContext.setParentLoaderPriority(_parentLoaderPriority); if (_configurationClasses != null) { webAppContext.setConfigurationClasses(_configurationClasses); } if (_tempDirectory != null) { /* Since the Temp Dir is really a context base temp directory, * Lets set the Temp Directory in a way similar to how WebInfConfiguration does it, * instead of setting the * WebAppContext.setTempDirectory(File). * If we used .setTempDirectory(File) all webapps will wind up in the * same temp / work directory, overwriting each others work. */ webAppContext.setAttribute(WebAppContext.BASETEMPDIR, _tempDirectory); } return webAppContext; } /* ------------------------------------------------------------ */ @Override protected void fileChanged(String filename) throws Exception { File file = new File(filename); if (!file.exists()) return; File parent = file.getParentFile(); //is the file that changed a directory? if (file.isDirectory()) { //is there a .xml file of the same name? if (exists(file.getName()+".xml")||exists(file.getName()+".XML")) return; //ignore it //is there .war file of the same name? if (exists(file.getName()+".war")||exists(file.getName()+".WAR")) return; //ignore it super.fileChanged(filename); return; } String lowname = file.getName().toLowerCase(Locale.ENGLISH); //is the file that changed a .war file? if (lowname.endsWith(".war")) { String name = file.getName(); String base=name.substring(0,name.length()-4); String xmlname = base+".xml"; if (exists(xmlname)) { //if a .xml file exists for it, then redeploy that instead File xml = new File (parent, xmlname); super.fileChanged(xml.getCanonicalPath()); return; } xmlname = base+".XML"; if (exists(xmlname)) { //if a .XML file exists for it, then redeploy that instead File xml = new File(parent, xmlname); super.fileChanged(xml.getCanonicalPath()); return; } //redeploy the changed war super.fileChanged(filename); return; } //is the file that changed a .xml file? if (lowname.endsWith(".xml")) super.fileChanged(filename); } /* ------------------------------------------------------------ */ @Override protected void fileAdded(String filename) throws Exception { File file = new File(filename); if (!file.exists()) return; //is the file that was added a directory? if (file.isDirectory()) { //is there a .xml file of the same name? if (exists(file.getName()+".xml")||exists(file.getName()+".XML")) return; //assume we will get added events for the xml file //is there .war file of the same name? if (exists(file.getName()+".war")||exists(file.getName()+".WAR")) return; //assume we will get added events for the war file super.fileAdded(filename); return; } //is the file that was added a .war file? String lowname = file.getName().toLowerCase(Locale.ENGLISH); if (lowname.endsWith(".war")) { String name = file.getName(); String base=name.substring(0,name.length()-4); //is there a .xml file of the same name? if (exists(base+".xml")||exists(base+".XML")) return; //ignore it as we should get addition of the xml file super.fileAdded(filename); return; } //is the file that was added an .xml file? if (lowname.endsWith(".xml")) super.fileAdded(filename); } /* ------------------------------------------------------------ */ @Override protected void fileRemoved(String filename) throws Exception { File file = new File(filename); //is the file that was removed a directory? if (file.isDirectory()) { //is there a .xml file of the same name? if (exists(file.getName()+".xml")||exists(file.getName()+".XML")) return; //assume we will get removed events for the xml file //is there .war file of the same name? if (exists(file.getName()+".war")||exists(file.getName()+".WAR")) return; //assume we will get removed events for the war file super.fileRemoved(filename); return; } //is the file that was removed a .war file? String lowname = file.getName().toLowerCase(Locale.ENGLISH); if (lowname.endsWith(".war")) { //is there a .xml file of the same name? String name = file.getName(); String base=name.substring(0,name.length()-4); if (exists(base+".xml")||exists(base+".XML")) return; //ignore it as we should get removal of the xml file super.fileRemoved(filename); return; } //is the file that was removed an .xml file? if (lowname.endsWith(".xml")) super.fileRemoved(filename); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy