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: 12.1.0.alpha0
Show newest version
//
//  ========================================================================
//  Copyright (c) 1995-2019 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.Server;
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); Resource r = Resource.newResource(file); if (getMonitoredResources().contains(r) && r.isDirectory()) { return false; } // 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? return !"cvs".equals(lowername) && !"cvsroot".equals(lowername);// OK to deploy it then } // else is it a war file if (lowername.endsWith(".war")) { //defer deployment decision to fileChanged() return true; } // else is it a context XML file return lowername.endsWith(".xml"); } } 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 : 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; } protected void initializeWebAppContextDefaults(WebAppContext webapp) { if (_defaultsDescriptor != null) webapp.setDefaultsDescriptor(_defaultsDescriptor); webapp.setExtractWAR(_extractWars); webapp.setParentLoaderPriority(_parentLoaderPriority); if (_configurationClasses != null) webapp.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. */ webapp.setAttribute(WebAppContext.BASETEMPDIR, _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.getURI().toURL()) { @Override public void initializeDefaults(Object context) { super.initializeDefaults(context); if (context instanceof WebAppContext) { WebAppContext webapp = (WebAppContext)context; initializeWebAppContextDefaults(webapp); } } }; getDeploymentManager().scope(xmlc, resource); 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()); initializeWebAppContextDefaults(webAppContext); 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 .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); return; } //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); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy