work in progress... all but OSGi
This commit is contained in:
parent
2f15c3e4f9
commit
f19bd2c65a
|
@ -0,0 +1,84 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2016 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.ant;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.apache.tools.ant.AntClassLoader;
|
||||
import org.eclipse.jetty.util.PatternMatcher;
|
||||
import org.eclipse.jetty.util.resource.Resource;
|
||||
import org.eclipse.jetty.webapp.Configuration;
|
||||
import org.eclipse.jetty.webapp.MetaInfConfiguration;
|
||||
import org.eclipse.jetty.webapp.WebAppClassLoader;
|
||||
import org.eclipse.jetty.webapp.WebAppContext;
|
||||
import org.eclipse.jetty.webapp.WebInfConfiguration;
|
||||
import org.eclipse.jetty.webapp.WebXmlConfiguration;
|
||||
|
||||
public class AntMetaInfConfiguration extends MetaInfConfiguration
|
||||
{
|
||||
|
||||
@Override
|
||||
public Class<? extends Configuration> replaces()
|
||||
{
|
||||
return MetaInfConfiguration.class;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------- */
|
||||
@Override
|
||||
protected List<URI> getAllContainerJars(final WebAppContext context) throws URISyntaxException
|
||||
{
|
||||
List<URI> uris = new ArrayList<>();
|
||||
if (context.getClassLoader() != null)
|
||||
{
|
||||
ClassLoader loader = context.getClassLoader().getParent();
|
||||
while (loader != null)
|
||||
{
|
||||
if (loader instanceof URLClassLoader)
|
||||
{
|
||||
URL[] urls = ((URLClassLoader)loader).getURLs();
|
||||
if (urls != null)
|
||||
for(URL url:urls)
|
||||
uris.add(new URI(url.toString().replaceAll(" ","%20")));
|
||||
}
|
||||
else if (loader instanceof AntClassLoader)
|
||||
{
|
||||
AntClassLoader antLoader = (AntClassLoader)loader;
|
||||
String[] paths = antLoader.getClasspath().split(new String(new char[]{File.pathSeparatorChar}));
|
||||
if (paths != null)
|
||||
{
|
||||
for (String p:paths)
|
||||
{
|
||||
File f = new File(p);
|
||||
uris.add(f.toURI());
|
||||
}
|
||||
}
|
||||
}
|
||||
loader = loader.getParent();
|
||||
}
|
||||
}
|
||||
return uris;
|
||||
}
|
||||
}
|
|
@ -40,13 +40,11 @@ import org.apache.tools.ant.AntClassLoader;
|
|||
import org.apache.tools.ant.BuildException;
|
||||
import org.apache.tools.ant.Project;
|
||||
import org.apache.tools.ant.types.FileSet;
|
||||
import org.eclipse.jetty.annotations.AnnotationConfiguration;
|
||||
import org.eclipse.jetty.ant.types.Attribute;
|
||||
import org.eclipse.jetty.ant.types.Attributes;
|
||||
import org.eclipse.jetty.ant.types.FileMatchingConfiguration;
|
||||
import org.eclipse.jetty.ant.utils.TaskLog;
|
||||
import org.eclipse.jetty.plus.webapp.EnvConfiguration;
|
||||
import org.eclipse.jetty.plus.webapp.PlusConfiguration;
|
||||
import org.eclipse.jetty.servlet.FilterHolder;
|
||||
import org.eclipse.jetty.servlet.FilterMapping;
|
||||
import org.eclipse.jetty.servlet.Holder;
|
||||
|
@ -56,14 +54,9 @@ import org.eclipse.jetty.servlet.ServletMapping;
|
|||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
import org.eclipse.jetty.util.resource.Resource;
|
||||
import org.eclipse.jetty.webapp.Configuration;
|
||||
import org.eclipse.jetty.webapp.FragmentConfiguration;
|
||||
import org.eclipse.jetty.webapp.JettyWebXmlConfiguration;
|
||||
import org.eclipse.jetty.webapp.MetaInfConfiguration;
|
||||
import org.eclipse.jetty.webapp.WebAppClassLoader;
|
||||
import org.eclipse.jetty.webapp.WebAppContext;
|
||||
import org.eclipse.jetty.webapp.WebInfConfiguration;
|
||||
import org.eclipse.jetty.webapp.WebXmlConfiguration;
|
||||
import org.eclipse.jetty.xml.XmlConfiguration;
|
||||
|
||||
/**
|
||||
|
@ -81,10 +74,10 @@ public class AntWebAppContext extends WebAppContext
|
|||
private File jettyEnvXml;
|
||||
|
||||
/** List of web application libraries. */
|
||||
private List libraries = new ArrayList();
|
||||
private List<FileSet> libraries = new ArrayList<>();
|
||||
|
||||
/** List of web application class directories. */
|
||||
private List classes = new ArrayList();
|
||||
private List<FileSet> classes = new ArrayList<>();
|
||||
|
||||
/** context xml file to apply to the webapp */
|
||||
private File contextXml;
|
||||
|
@ -100,11 +93,6 @@ public class AntWebAppContext extends WebAppContext
|
|||
private List<File> scanFiles;
|
||||
|
||||
|
||||
|
||||
/** Extra scan targets. */
|
||||
private FileMatchingConfiguration extraScanTargetsConfiguration;
|
||||
|
||||
|
||||
private FileMatchingConfiguration librariesConfiguration;
|
||||
|
||||
|
||||
|
@ -409,8 +397,9 @@ public class AntWebAppContext extends WebAppContext
|
|||
{
|
||||
super();
|
||||
this.project = project;
|
||||
setAttribute(WebInfConfiguration.CONTAINER_JAR_PATTERN, DEFAULT_CONTAINER_INCLUDE_JAR_PATTERN);
|
||||
setAttribute(MetaInfConfiguration.CONTAINER_JAR_PATTERN, DEFAULT_CONTAINER_INCLUDE_JAR_PATTERN);
|
||||
setParentLoaderPriority(true);
|
||||
addConfiguration(new AntWebInfConfiguration(),new AntWebXmlConfiguration(),new AntMetaInfConfiguration());
|
||||
}
|
||||
|
||||
|
||||
|
@ -463,7 +452,7 @@ public class AntWebAppContext extends WebAppContext
|
|||
|
||||
|
||||
|
||||
public List getLibraries()
|
||||
public List<File> getLibraries()
|
||||
{
|
||||
return librariesConfiguration.getBaseDirectories();
|
||||
}
|
||||
|
@ -479,7 +468,7 @@ public class AntWebAppContext extends WebAppContext
|
|||
this.scanTargets = scanTargets;
|
||||
}
|
||||
|
||||
public List getScanTargetFiles ()
|
||||
public List<File> getScanTargetFiles ()
|
||||
{
|
||||
if (this.scanTargets == null)
|
||||
return null;
|
||||
|
@ -569,7 +558,6 @@ public class AntWebAppContext extends WebAppContext
|
|||
scanList.addAll(cpFiles);
|
||||
|
||||
//any extra scan targets
|
||||
@SuppressWarnings("unchecked")
|
||||
List<File> scanFiles = (List<File>)getScanTargetFiles();
|
||||
if (scanFiles != null)
|
||||
scanList.addAll(scanFiles);
|
||||
|
@ -608,7 +596,6 @@ public class AntWebAppContext extends WebAppContext
|
|||
try
|
||||
{
|
||||
TaskLog.logWithTimestamp("Starting web application "+this.getDescriptor());
|
||||
addConfiguration(new AntWebInfConfiguration(),new AntWebXmlConfiguration());
|
||||
|
||||
if (jettyEnvXml != null && jettyEnvXml.exists())
|
||||
getConfiguration(EnvConfiguration.class).setJettyEnvXml(Resource.toURL(jettyEnvXml));
|
||||
|
@ -674,17 +661,17 @@ public class AntWebAppContext extends WebAppContext
|
|||
public List<File> getClassPathFiles()
|
||||
{
|
||||
List<File> classPathFiles = new ArrayList<File>();
|
||||
Iterator classesIterator = classes.iterator();
|
||||
Iterator<FileSet> classesIterator = classes.iterator();
|
||||
while (classesIterator.hasNext())
|
||||
{
|
||||
FileSet clazz = (FileSet) classesIterator.next();
|
||||
FileSet clazz = classesIterator.next();
|
||||
classPathFiles.add(clazz.getDirectoryScanner(project).getBasedir());
|
||||
}
|
||||
|
||||
Iterator iterator = libraries.iterator();
|
||||
Iterator<FileSet> iterator = libraries.iterator();
|
||||
while (iterator.hasNext())
|
||||
{
|
||||
FileSet library = (FileSet) iterator.next();
|
||||
FileSet library = iterator.next();
|
||||
String[] includedFiles = library.getDirectoryScanner(project).getIncludedFiles();
|
||||
File baseDir = library.getDirectoryScanner(project).getBasedir();
|
||||
|
||||
|
@ -708,17 +695,17 @@ public class AntWebAppContext extends WebAppContext
|
|||
{
|
||||
FileMatchingConfiguration config = new FileMatchingConfiguration();
|
||||
|
||||
Iterator classesIterator = classes.iterator();
|
||||
Iterator<FileSet> classesIterator = classes.iterator();
|
||||
while (classesIterator.hasNext())
|
||||
{
|
||||
FileSet clazz = (FileSet) classesIterator.next();
|
||||
FileSet clazz = classesIterator.next();
|
||||
config.addDirectoryScanner(clazz.getDirectoryScanner(project));
|
||||
}
|
||||
|
||||
Iterator librariesIterator = libraries.iterator();
|
||||
Iterator<FileSet> librariesIterator = libraries.iterator();
|
||||
while (librariesIterator.hasNext())
|
||||
{
|
||||
FileSet library = (FileSet) librariesIterator.next();
|
||||
FileSet library = librariesIterator.next();
|
||||
config.addDirectoryScanner(library.getDirectoryScanner(project));
|
||||
}
|
||||
|
||||
|
|
|
@ -44,112 +44,6 @@ public class AntWebInfConfiguration extends WebInfConfiguration
|
|||
return WebInfConfiguration.class;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void preConfigure(final WebAppContext context) throws Exception
|
||||
{
|
||||
//Make a temp directory for the webapp if one is not already set
|
||||
resolveTempDirectory(context);
|
||||
|
||||
//Extract webapp if necessary
|
||||
unpack (context);
|
||||
|
||||
|
||||
//Apply an initial ordering to the jars which governs which will be scanned for META-INF
|
||||
//info and annotations. The ordering is based on inclusion patterns.
|
||||
String tmp = (String)context.getAttribute(WEBINF_JAR_PATTERN);
|
||||
Pattern webInfPattern = (tmp==null?null:Pattern.compile(tmp));
|
||||
tmp = (String)context.getAttribute(CONTAINER_JAR_PATTERN);
|
||||
Pattern containerPattern = (tmp==null?null:Pattern.compile(tmp));
|
||||
|
||||
//Apply ordering to container jars - if no pattern is specified, we won't
|
||||
//match any of the container jars
|
||||
PatternMatcher containerJarNameMatcher = new PatternMatcher ()
|
||||
{
|
||||
public void matched(URI uri) throws Exception
|
||||
{
|
||||
context.getMetaData().addContainerResource(Resource.newResource(uri));
|
||||
}
|
||||
};
|
||||
ClassLoader loader = context.getClassLoader();
|
||||
if (loader != null)
|
||||
{
|
||||
loader = loader.getParent();
|
||||
if (loader != null)
|
||||
{
|
||||
URI[] containerUris = null;
|
||||
|
||||
if (loader instanceof URLClassLoader)
|
||||
{
|
||||
URL[] urls = ((URLClassLoader)loader).getURLs();
|
||||
if (urls != null)
|
||||
{
|
||||
containerUris = new URI[urls.length];
|
||||
int i=0;
|
||||
for (URL u : urls)
|
||||
{
|
||||
try
|
||||
{
|
||||
containerUris[i] = u.toURI();
|
||||
}
|
||||
catch (URISyntaxException e)
|
||||
{
|
||||
containerUris[i] = new URI(u.toString().replaceAll(" ", "%20"));
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (loader instanceof AntClassLoader)
|
||||
{
|
||||
AntClassLoader antLoader = (AntClassLoader)loader;
|
||||
String[] paths = antLoader.getClasspath().split(new String(new char[]{File.pathSeparatorChar}));
|
||||
if (paths != null)
|
||||
{
|
||||
containerUris = new URI[paths.length];
|
||||
int i=0;
|
||||
for (String p:paths)
|
||||
{
|
||||
File f = new File(p);
|
||||
containerUris[i] = f.toURI();
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
containerJarNameMatcher.match(containerPattern, containerUris, false);
|
||||
}
|
||||
}
|
||||
|
||||
//Apply ordering to WEB-INF/lib jars
|
||||
PatternMatcher webInfJarNameMatcher = new PatternMatcher ()
|
||||
{
|
||||
@Override
|
||||
public void matched(URI uri) throws Exception
|
||||
{
|
||||
context.getMetaData().addWebInfJar(Resource.newResource(uri));
|
||||
}
|
||||
};
|
||||
List<Resource> jars = findJars(context);
|
||||
|
||||
//Convert to uris for matching
|
||||
URI[] uris = null;
|
||||
if (jars != null)
|
||||
{
|
||||
uris = new URI[jars.size()];
|
||||
int i=0;
|
||||
for (Resource r: jars)
|
||||
{
|
||||
uris[i++] = r.getURI();
|
||||
}
|
||||
}
|
||||
webInfJarNameMatcher.match(webInfPattern, uris, true); //null is inclusive, no pattern == all jars match
|
||||
|
||||
//No pattern to appy to classes, just add to metadata
|
||||
context.getMetaData().setWebInfClassesDirs(findClassDirs(context));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Adds classpath files into web application classloader, and
|
||||
* sets web.xml and base directory for the configured web application.
|
||||
|
|
|
@ -34,11 +34,11 @@ import org.apache.tools.ant.DirectoryScanner;
|
|||
public class FileMatchingConfiguration
|
||||
{
|
||||
|
||||
private List directoryScanners;
|
||||
private List<DirectoryScanner> directoryScanners;
|
||||
|
||||
public FileMatchingConfiguration()
|
||||
{
|
||||
this.directoryScanners = new ArrayList();
|
||||
this.directoryScanners = new ArrayList<>();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -54,10 +54,10 @@ public class FileMatchingConfiguration
|
|||
* @return a list of base directories denoted by a list of directory
|
||||
* scanners.
|
||||
*/
|
||||
public List getBaseDirectories()
|
||||
public List<File> getBaseDirectories()
|
||||
{
|
||||
List baseDirs = new ArrayList();
|
||||
Iterator scanners = directoryScanners.iterator();
|
||||
List<File> baseDirs = new ArrayList<>();
|
||||
Iterator<DirectoryScanner> scanners = directoryScanners.iterator();
|
||||
while (scanners.hasNext())
|
||||
{
|
||||
DirectoryScanner scanner = (DirectoryScanner) scanners.next();
|
||||
|
@ -75,7 +75,7 @@ public class FileMatchingConfiguration
|
|||
*/
|
||||
public boolean isIncluded(String pathToFile)
|
||||
{
|
||||
Iterator scanners = directoryScanners.iterator();
|
||||
Iterator<DirectoryScanner> scanners = directoryScanners.iterator();
|
||||
while (scanners.hasNext())
|
||||
{
|
||||
DirectoryScanner scanner = (DirectoryScanner) scanners.next();
|
||||
|
|
|
@ -21,7 +21,6 @@ package org.eclipse.jetty.deploy.bindings;
|
|||
import static org.hamcrest.Matchers.greaterThan;
|
||||
import static org.hamcrest.Matchers.hasSize;
|
||||
import static org.hamcrest.Matchers.isIn;
|
||||
import static org.hamcrest.Matchers.not;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
|
@ -87,11 +86,9 @@ public class GlobalWebappConfigBindingTest
|
|||
WebAppContext context = contexts.get(0);
|
||||
|
||||
Assert.assertNotNull("Context should not be null",context);
|
||||
String defaultClasses[] = context.getDefaultServerClasses();
|
||||
String currentClasses[] = context.getServerClasses();
|
||||
|
||||
String addedClass = "org.eclipse.foo."; // What was added by the binding
|
||||
Assert.assertThat("Default Server Classes",addedClass,not(isIn(defaultClasses)));
|
||||
Assert.assertThat("Current Server Classes",addedClass,isIn(currentClasses));
|
||||
|
||||
// boolean jndiPackage = false;
|
||||
|
|
|
@ -119,6 +119,7 @@ public class JettyWebAppContext extends WebAppContext
|
|||
// Turn off copyWebInf option as it is not applicable for plugin.
|
||||
super.setCopyWebInf(false);
|
||||
addConfiguration(new MavenWebInfConfiguration());
|
||||
addConfiguration(new MavenMetaInfConfiguration());
|
||||
addConfiguration(new EnvConfiguration());
|
||||
addConfiguration(new PlusConfiguration());
|
||||
addConfiguration(new AnnotationConfiguration());
|
||||
|
|
|
@ -0,0 +1,127 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2016 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.maven.plugin;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
import org.eclipse.jetty.util.resource.Resource;
|
||||
import org.eclipse.jetty.webapp.Configuration;
|
||||
import org.eclipse.jetty.webapp.MetaInfConfiguration;
|
||||
import org.eclipse.jetty.webapp.WebAppContext;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* MavenWebInfConfiguration
|
||||
*
|
||||
* WebInfConfiguration to take account of overlaid wars expressed as project dependencies and
|
||||
* potential configured via the maven-war-plugin.
|
||||
*/
|
||||
public class MavenMetaInfConfiguration extends MetaInfConfiguration
|
||||
{
|
||||
private static final Logger LOG = Log.getLogger(MavenMetaInfConfiguration.class);
|
||||
|
||||
protected static int COUNTER = 0;
|
||||
|
||||
@Override
|
||||
public Class<? extends Configuration> replaces()
|
||||
{
|
||||
return MetaInfConfiguration.class;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the jars to examine from the files from which we have
|
||||
* synthesized the classpath. Note that the classpath is not
|
||||
* set at this point, so we cannot get them from the classpath.
|
||||
* @param context the web app context
|
||||
* @return the list of jars found
|
||||
*/
|
||||
@Override
|
||||
protected List<Resource> findJars (WebAppContext context)
|
||||
throws Exception
|
||||
{
|
||||
List<Resource> list = new ArrayList<Resource>();
|
||||
JettyWebAppContext jwac = (JettyWebAppContext)context;
|
||||
if (jwac.getClassPathFiles() != null)
|
||||
{
|
||||
for (File f: jwac.getClassPathFiles())
|
||||
{
|
||||
if (f.getName().toLowerCase(Locale.ENGLISH).endsWith(".jar"))
|
||||
{
|
||||
try
|
||||
{
|
||||
list.add(Resource.newResource(f.toURI()));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LOG.warn("Bad url ", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
List<Resource> superList = super.findJars(context);
|
||||
if (superList != null)
|
||||
list.addAll(superList);
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Add in the classes dirs from test/classes and target/classes
|
||||
* @see org.eclipse.jetty.webapp.WebInfConfiguration#findClassDirs(org.eclipse.jetty.webapp.WebAppContext)
|
||||
*/
|
||||
@Override
|
||||
protected List<Resource> findClassDirs(WebAppContext context) throws Exception
|
||||
{
|
||||
List<Resource> list = new ArrayList<Resource>();
|
||||
|
||||
JettyWebAppContext jwac = (JettyWebAppContext)context;
|
||||
if (jwac.getClassPathFiles() != null)
|
||||
{
|
||||
for (File f: jwac.getClassPathFiles())
|
||||
{
|
||||
if (f.exists() && f.isDirectory())
|
||||
{
|
||||
try
|
||||
{
|
||||
list.add(Resource.newResource(f.toURI()));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LOG.warn("Bad url ", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
List<Resource> classesDirs = super.findClassDirs(context);
|
||||
if (classesDirs != null)
|
||||
list.addAll(classesDirs);
|
||||
return list;
|
||||
}
|
||||
}
|
|
@ -21,10 +21,7 @@ package org.eclipse.jetty.maven.plugin;
|
|||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
|
@ -36,7 +33,6 @@ import org.eclipse.jetty.webapp.WebAppContext;
|
|||
import org.eclipse.jetty.webapp.WebInfConfiguration;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* MavenWebInfConfiguration
|
||||
*
|
||||
|
@ -52,6 +48,16 @@ public class MavenWebInfConfiguration extends WebInfConfiguration
|
|||
protected Resource _originalResourceBase;
|
||||
protected List<Resource> _unpackedOverlayResources;
|
||||
|
||||
|
||||
|
||||
public MavenWebInfConfiguration()
|
||||
{
|
||||
super();
|
||||
addServerClass(
|
||||
"org.apache.maven.",
|
||||
"org.codehaus.plexus.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends Configuration> replaces()
|
||||
{
|
||||
|
@ -66,58 +72,26 @@ public class MavenWebInfConfiguration extends WebInfConfiguration
|
|||
JettyWebAppContext jwac = (JettyWebAppContext)context;
|
||||
|
||||
//put the classes dir and all dependencies into the classpath
|
||||
if (jwac.getClassPathFiles() != null)
|
||||
if (jwac.getClassPathFiles() != null && context.getClassLoader() instanceof WebAppClassLoader)
|
||||
{
|
||||
if (LOG.isDebugEnabled()) LOG.debug("Setting up classpath ...");
|
||||
Iterator itor = jwac.getClassPathFiles().iterator();
|
||||
while (itor.hasNext())
|
||||
((WebAppClassLoader)context.getClassLoader()).addClassPath(((File)itor.next()).getCanonicalPath());
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Setting up classpath ...");
|
||||
WebAppClassLoader loader=(WebAppClassLoader)context.getClassLoader();
|
||||
for (File classpath:jwac.getClassPathFiles())
|
||||
loader.addClassPath(classpath.getCanonicalPath());
|
||||
}
|
||||
|
||||
super.configure(context);
|
||||
|
||||
// knock out environmental maven and plexus classes from webAppContext
|
||||
String[] existingServerClasses = context.getServerClasses();
|
||||
String[] newServerClasses = new String[2+(existingServerClasses==null?0:existingServerClasses.length)];
|
||||
newServerClasses[0] = "org.apache.maven.";
|
||||
newServerClasses[1] = "org.codehaus.plexus.";
|
||||
System.arraycopy( existingServerClasses, 0, newServerClasses, 2, existingServerClasses.length );
|
||||
if (LOG.isDebugEnabled())
|
||||
{
|
||||
LOG.debug("Server classes:");
|
||||
for (int i=0;i<newServerClasses.length;i++)
|
||||
LOG.debug(newServerClasses[i]);
|
||||
}
|
||||
context.setServerClasses( newServerClasses );
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @see org.eclipse.jetty.webapp.WebInfConfiguration#preConfigure(org.eclipse.jetty.webapp.WebAppContext)
|
||||
*/
|
||||
public void preConfigure(WebAppContext context) throws Exception
|
||||
{
|
||||
super.preConfigure(context);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @see org.eclipse.jetty.webapp.AbstractConfiguration#postConfigure(org.eclipse.jetty.webapp.WebAppContext)
|
||||
*/
|
||||
public void postConfigure(WebAppContext context) throws Exception
|
||||
{
|
||||
super.postConfigure(context);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @see org.eclipse.jetty.webapp.WebInfConfiguration#deconfigure(org.eclipse.jetty.webapp.WebAppContext)
|
||||
|
@ -193,85 +167,6 @@ public class MavenWebInfConfiguration extends WebInfConfiguration
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the jars to examine from the files from which we have
|
||||
* synthesized the classpath. Note that the classpath is not
|
||||
* set at this point, so we cannot get them from the classpath.
|
||||
* @param context the web app context
|
||||
* @return the list of jars found
|
||||
*/
|
||||
@Override
|
||||
protected List<Resource> findJars (WebAppContext context)
|
||||
throws Exception
|
||||
{
|
||||
List<Resource> list = new ArrayList<Resource>();
|
||||
JettyWebAppContext jwac = (JettyWebAppContext)context;
|
||||
if (jwac.getClassPathFiles() != null)
|
||||
{
|
||||
for (File f: jwac.getClassPathFiles())
|
||||
{
|
||||
if (f.getName().toLowerCase(Locale.ENGLISH).endsWith(".jar"))
|
||||
{
|
||||
try
|
||||
{
|
||||
list.add(Resource.newResource(f.toURI()));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LOG.warn("Bad url ", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
List<Resource> superList = super.findJars(context);
|
||||
if (superList != null)
|
||||
list.addAll(superList);
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Add in the classes dirs from test/classes and target/classes
|
||||
* @see org.eclipse.jetty.webapp.WebInfConfiguration#findClassDirs(org.eclipse.jetty.webapp.WebAppContext)
|
||||
*/
|
||||
@Override
|
||||
protected List<Resource> findClassDirs(WebAppContext context) throws Exception
|
||||
{
|
||||
List<Resource> list = new ArrayList<Resource>();
|
||||
|
||||
JettyWebAppContext jwac = (JettyWebAppContext)context;
|
||||
if (jwac.getClassPathFiles() != null)
|
||||
{
|
||||
for (File f: jwac.getClassPathFiles())
|
||||
{
|
||||
if (f.exists() && f.isDirectory())
|
||||
{
|
||||
try
|
||||
{
|
||||
list.add(Resource.newResource(f.toURI()));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LOG.warn("Bad url ", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
List<Resource> classesDirs = super.findClassDirs(context);
|
||||
if (classesDirs != null)
|
||||
list.addAll(classesDirs);
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
protected Resource unpackOverlay (WebAppContext context, Overlay overlay)
|
||||
throws IOException
|
||||
{
|
||||
|
|
|
@ -36,6 +36,7 @@ import org.eclipse.jetty.server.handler.HandlerCollection;
|
|||
import org.eclipse.jetty.server.handler.RequestLogHandler;
|
||||
import org.eclipse.jetty.util.resource.Resource;
|
||||
import org.eclipse.jetty.webapp.Configuration;
|
||||
import org.eclipse.jetty.webapp.Configurations;
|
||||
import org.eclipse.jetty.webapp.WebAppContext;
|
||||
import org.eclipse.jetty.xml.XmlConfiguration;
|
||||
|
||||
|
@ -50,7 +51,7 @@ public class ServerSupport
|
|||
|
||||
public static void configureDefaultConfigurationClasses (Server server)
|
||||
{
|
||||
server.setAttribute(Configuration.ATTR, JettyWebAppContext.DEFAULT_CONFIGURATION_CLASSES);
|
||||
Configurations.setServerDefault(server);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -40,7 +40,6 @@ import org.eclipse.jetty.util.log.Log;
|
|||
import org.eclipse.jetty.util.log.Logger;
|
||||
import org.eclipse.jetty.util.resource.JarResource;
|
||||
import org.eclipse.jetty.util.resource.Resource;
|
||||
import org.eclipse.jetty.webapp.Configurations;
|
||||
import org.eclipse.jetty.webapp.WebAppContext;
|
||||
import org.eclipse.jetty.xml.XmlConfiguration;
|
||||
import org.osgi.framework.Bundle;
|
||||
|
@ -291,9 +290,15 @@ public abstract class AbstractWebAppProvider extends AbstractLifeCycle implement
|
|||
// Set up what has been configured on the provider
|
||||
_webApp.setParentLoaderPriority(isParentLoaderPriority());
|
||||
_webApp.setExtractWAR(isExtract());
|
||||
_webApp.setConfigurationClasses(getConfigurationClasses());
|
||||
|
||||
_webApp.addConfiguration(new OSGiWebInfConfiguration(),new OSGiMetaInfConfiguration());
|
||||
if (annotationsAvailable())
|
||||
_webApp.addConfiguration(new AnnotationConfiguration());
|
||||
|
||||
//add in EnvConfiguration and PlusConfiguration just after FragmentConfiguration
|
||||
if (jndiAvailable())
|
||||
_webApp.addConfiguration(new EnvConfiguration(),new PlusConfiguration());
|
||||
|
||||
if (getDefaultsDescriptor() != null)
|
||||
_webApp.setDefaultsDescriptor(getDefaultsDescriptor());
|
||||
|
||||
|
@ -568,36 +573,6 @@ public abstract class AbstractWebAppProvider extends AbstractLifeCycle implement
|
|||
return _tldBundles;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @param configurations The configuration class names.
|
||||
*/
|
||||
public void setConfigurationClasses(String[] configurations)
|
||||
{
|
||||
_configurationClasses = configurations == null ? null : (String[]) configurations.clone();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public String[] getConfigurationClasses()
|
||||
{
|
||||
if (_configurationClasses != null)
|
||||
return _configurationClasses;
|
||||
|
||||
Configurations defaults = Configurations.serverDefault(_serverWrapper.getServer());
|
||||
|
||||
//add before JettyWebXmlConfiguration
|
||||
if (annotationsAvailable())
|
||||
defaults.add(AnnotationConfiguration.class.getName());
|
||||
|
||||
//add in EnvConfiguration and PlusConfiguration just after FragmentConfiguration
|
||||
if (jndiAvailable())
|
||||
defaults.add(
|
||||
EnvConfiguration.class.getName(),
|
||||
PlusConfiguration.class.getName());
|
||||
String[] asArray = new String[defaults.size()];
|
||||
return defaults.toArray(asArray);
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public void setServerInstanceWrapper(ServerInstanceWrapper wrapper)
|
||||
|
|
|
@ -0,0 +1,341 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2016 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.osgi.boot;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.StringTokenizer;
|
||||
import java.util.TreeMap;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.eclipse.jetty.osgi.boot.utils.BundleFileLocatorHelperFactory;
|
||||
import org.eclipse.jetty.osgi.boot.utils.Util;
|
||||
import org.eclipse.jetty.osgi.boot.utils.internal.PackageAdminServiceTracker;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
import org.eclipse.jetty.util.resource.Resource;
|
||||
import org.eclipse.jetty.util.resource.ResourceCollection;
|
||||
import org.eclipse.jetty.webapp.Configuration;
|
||||
import org.eclipse.jetty.webapp.MetaInfConfiguration;
|
||||
import org.eclipse.jetty.webapp.WebAppContext;
|
||||
import org.eclipse.jetty.webapp.WebInfConfiguration;
|
||||
import org.osgi.framework.Bundle;
|
||||
import org.osgi.framework.FrameworkUtil;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* OSGiWebInfConfiguration
|
||||
*
|
||||
* Handle adding resources found in bundle fragments, and add them into the
|
||||
*/
|
||||
public class OSGiMetaInfConfiguration extends MetaInfConfiguration
|
||||
{
|
||||
private static final Logger LOG = Log.getLogger(WebInfConfiguration.class);
|
||||
|
||||
/**
|
||||
* Comma separated list of symbolic names of bundles that contain tlds that should be considered
|
||||
* as on the container classpath
|
||||
*/
|
||||
public static final String SYS_PROP_TLD_BUNDLES = "org.eclipse.jetty.osgi.tldbundles";
|
||||
/**
|
||||
* Regex of symbolic names of bundles that should be considered to be on the container classpath
|
||||
*/
|
||||
public static final String CONTAINER_BUNDLE_PATTERN = "org.eclipse.jetty.server.webapp.containerIncludeBundlePattern";
|
||||
public static final String FRAGMENT_AND_REQUIRED_BUNDLES = "org.eclipse.jetty.osgi.fragmentAndRequiredBundles";
|
||||
public static final String FRAGMENT_AND_REQUIRED_RESOURCES = "org.eclipse.jetty.osgi.fragmentAndRequiredResources";
|
||||
|
||||
@Override
|
||||
public Class<? extends Configuration> replaces()
|
||||
{
|
||||
return MetaInfConfiguration.class;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* Check to see if there have been any bundle symbolic names added of bundles that should be
|
||||
* regarded as being on the container classpath, and scanned for fragments, tlds etc etc.
|
||||
* This can be defined in:
|
||||
* <ol>
|
||||
* <li>SystemProperty SYS_PROP_TLD_BUNDLES</li>
|
||||
* <li>DeployerManager.setContextAttribute CONTAINER_BUNDLE_PATTERN</li>
|
||||
* </ol>
|
||||
*
|
||||
* We also allow individual bundles to specify particular bundles that might include TLDs via the Require-Tlds
|
||||
* MANIFEST.MF header.
|
||||
*
|
||||
* @see org.eclipse.jetty.webapp.WebInfConfiguration#preConfigure(org.eclipse.jetty.webapp.WebAppContext)
|
||||
*/
|
||||
@Override
|
||||
public void preConfigure(final WebAppContext context) throws Exception
|
||||
{
|
||||
super.preConfigure(context);
|
||||
|
||||
//Check to see if there have been any bundle symbolic names added of bundles that should be
|
||||
//regarded as being on the container classpath, and scanned for fragments, tlds etc etc.
|
||||
//This can be defined in:
|
||||
// 1. SystemProperty SYS_PROP_TLD_BUNDLES
|
||||
// 2. DeployerManager.setContextAttribute CONTAINER_BUNDLE_PATTERN
|
||||
String tmp = (String)context.getAttribute(CONTAINER_BUNDLE_PATTERN);
|
||||
Pattern pattern = (tmp==null?null:Pattern.compile(tmp));
|
||||
List<String> names = new ArrayList<String>();
|
||||
tmp = System.getProperty(SYS_PROP_TLD_BUNDLES);
|
||||
if (tmp != null)
|
||||
{
|
||||
StringTokenizer tokenizer = new StringTokenizer(tmp, ", \n\r\t", false);
|
||||
while (tokenizer.hasMoreTokens())
|
||||
names.add(tokenizer.nextToken());
|
||||
}
|
||||
HashSet<Resource> matchingResources = new HashSet<Resource>();
|
||||
if ( !names.isEmpty() || pattern != null)
|
||||
{
|
||||
Bundle[] bundles = FrameworkUtil.getBundle(OSGiMetaInfConfiguration.class).getBundleContext().getBundles();
|
||||
|
||||
for (Bundle bundle : bundles)
|
||||
{
|
||||
LOG.debug("Checking bundle {}:{}", bundle.getBundleId(), bundle.getSymbolicName());
|
||||
if (pattern != null)
|
||||
{
|
||||
// if bundle symbolic name matches the pattern
|
||||
if (pattern.matcher(bundle.getSymbolicName()).matches())
|
||||
{
|
||||
//get the file location of the jar and put it into the list of container jars that will be scanned for stuff (including tlds)
|
||||
matchingResources.addAll(getBundleAsResource(bundle));
|
||||
}
|
||||
}
|
||||
if (names != null)
|
||||
{
|
||||
//if there is an explicit bundle name, then check if it matches
|
||||
if (names.contains(bundle.getSymbolicName()))
|
||||
matchingResources.addAll(getBundleAsResource(bundle));
|
||||
}
|
||||
}
|
||||
}
|
||||
for (Resource r:matchingResources)
|
||||
{
|
||||
context.getMetaData().addContainerResource(r);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postConfigure(WebAppContext context) throws Exception
|
||||
{
|
||||
context.setAttribute(FRAGMENT_AND_REQUIRED_BUNDLES, null);
|
||||
context.setAttribute(FRAGMENT_AND_REQUIRED_RESOURCES, null);
|
||||
super.postConfigure(context);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* Consider the fragment bundles associated with the bundle of the webapp being deployed.
|
||||
*
|
||||
*
|
||||
* @see org.eclipse.jetty.webapp.WebInfConfiguration#findJars(org.eclipse.jetty.webapp.WebAppContext)
|
||||
*/
|
||||
@Override
|
||||
protected List<Resource> findJars (WebAppContext context)
|
||||
throws Exception
|
||||
{
|
||||
List<Resource> mergedResources = new ArrayList<Resource>();
|
||||
//get jars from WEB-INF/lib if there are any
|
||||
List<Resource> webInfJars = super.findJars(context);
|
||||
if (webInfJars != null)
|
||||
mergedResources.addAll(webInfJars);
|
||||
|
||||
//add fragment jars and any Required-Bundles as if in WEB-INF/lib of the associated webapp
|
||||
Bundle[] bundles = PackageAdminServiceTracker.INSTANCE.getFragmentsAndRequiredBundles((Bundle)context.getAttribute(OSGiWebappConstants.JETTY_OSGI_BUNDLE));
|
||||
if (bundles != null && bundles.length > 0)
|
||||
{
|
||||
Set<Bundle> fragsAndReqsBundles = (Set<Bundle>)context.getAttribute(FRAGMENT_AND_REQUIRED_BUNDLES);
|
||||
if (fragsAndReqsBundles == null)
|
||||
{
|
||||
fragsAndReqsBundles = new HashSet<Bundle>();
|
||||
context.setAttribute(FRAGMENT_AND_REQUIRED_BUNDLES, fragsAndReqsBundles);
|
||||
}
|
||||
|
||||
Set<Resource> fragsAndReqsResources = (Set<Resource>)context.getAttribute(FRAGMENT_AND_REQUIRED_RESOURCES);
|
||||
if (fragsAndReqsResources == null)
|
||||
{
|
||||
fragsAndReqsResources = new HashSet<Resource>();
|
||||
context.setAttribute(FRAGMENT_AND_REQUIRED_RESOURCES, fragsAndReqsResources);
|
||||
}
|
||||
|
||||
for (Bundle b : bundles)
|
||||
{
|
||||
//skip bundles that are not installed
|
||||
if (b.getState() == Bundle.UNINSTALLED)
|
||||
continue;
|
||||
|
||||
//add to context attribute storing associated fragments and required bundles
|
||||
fragsAndReqsBundles.add(b);
|
||||
File f = BundleFileLocatorHelperFactory.getFactory().getHelper().getBundleInstallLocation(b);
|
||||
Resource r = Resource.newResource(f.toURI());
|
||||
//add to convenience context attribute storing fragments and required bundles as Resources
|
||||
fragsAndReqsResources.add(r);
|
||||
mergedResources.add(r);
|
||||
}
|
||||
}
|
||||
|
||||
return mergedResources;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* Allow fragments to supply some resources that are added to the baseResource of the webapp.
|
||||
*
|
||||
* The resources can be either prepended or appended to the baseResource.
|
||||
*
|
||||
* @see org.eclipse.jetty.webapp.WebInfConfiguration#configure(org.eclipse.jetty.webapp.WebAppContext)
|
||||
*/
|
||||
@Override
|
||||
public boolean configure(WebAppContext context) throws Exception
|
||||
{
|
||||
TreeMap<String, Resource> prependedResourcesPath = new TreeMap<String, Resource>();
|
||||
TreeMap<String, Resource> appendedResourcesPath = new TreeMap<String, Resource>();
|
||||
|
||||
Bundle bundle = (Bundle)context.getAttribute(OSGiWebappConstants.JETTY_OSGI_BUNDLE);
|
||||
if (bundle != null)
|
||||
{
|
||||
Set<Bundle> fragments = (Set<Bundle>)context.getAttribute(FRAGMENT_AND_REQUIRED_BUNDLES);
|
||||
if (fragments != null && !fragments.isEmpty())
|
||||
{
|
||||
// sorted extra resource base found in the fragments.
|
||||
// the resources are either overriding the resourcebase found in the
|
||||
// web-bundle
|
||||
// or appended.
|
||||
// amongst each resource we sort them according to the alphabetical
|
||||
// order
|
||||
// of the name of the internal folder and the symbolic name of the
|
||||
// fragment.
|
||||
// this is useful to make sure that the lookup path of those
|
||||
// resource base defined by fragments is always the same.
|
||||
// This natural order could be abused to define the order in which
|
||||
// the base resources are
|
||||
// looked up.
|
||||
for (Bundle frag : fragments)
|
||||
{
|
||||
String path = Util.getManifestHeaderValue(OSGiWebappConstants.JETTY_WAR_FRAGMENT_FOLDER_PATH,OSGiWebappConstants.JETTY_WAR_FRAGMENT_RESOURCE_PATH,frag.getHeaders());
|
||||
convertFragmentPathToResource(path, frag, appendedResourcesPath);
|
||||
path = Util.getManifestHeaderValue(OSGiWebappConstants.JETTY_WAR_PATCH_FRAGMENT_FOLDER_PATH, OSGiWebappConstants.JETTY_WAR_PREPEND_FRAGMENT_RESOURCE_PATH, frag.getHeaders());
|
||||
convertFragmentPathToResource(path, frag, prependedResourcesPath);
|
||||
}
|
||||
if (!appendedResourcesPath.isEmpty())
|
||||
{
|
||||
LinkedHashSet<Resource> resources = new LinkedHashSet<Resource>();
|
||||
//Add in any existing setting of extra resource dirs
|
||||
Set<Resource> resourceDirs = (Set<Resource>)context.getAttribute(WebInfConfiguration.RESOURCE_DIRS);
|
||||
if (resourceDirs != null && !resourceDirs.isEmpty())
|
||||
resources.addAll(resourceDirs);
|
||||
//Then append the values from JETTY_WAR_FRAGMENT_FOLDER_PATH
|
||||
resources.addAll(appendedResourcesPath.values());
|
||||
|
||||
context.setAttribute(WebInfConfiguration.RESOURCE_DIRS, resources);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
super.configure(context);
|
||||
|
||||
// place the prepended resources at the beginning of the contexts's resource base
|
||||
if (!prependedResourcesPath.isEmpty())
|
||||
{
|
||||
Resource[] resources = new Resource[1+prependedResourcesPath.size()];
|
||||
System.arraycopy(prependedResourcesPath.values().toArray(new Resource[prependedResourcesPath.size()]), 0, resources, 0, prependedResourcesPath.size());
|
||||
resources[resources.length-1] = context.getBaseResource();
|
||||
context.setBaseResource(new ResourceCollection(resources));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* Resolves the bundle. Usually that would be a single URL per bundle. But we do some more work if there are jars
|
||||
* embedded in the bundle.
|
||||
*/
|
||||
private List<Resource> getBundleAsResource(Bundle bundle)
|
||||
throws Exception
|
||||
{
|
||||
List<Resource> resources = new ArrayList<Resource>();
|
||||
|
||||
File file = BundleFileLocatorHelperFactory.getFactory().getHelper().getBundleInstallLocation(bundle);
|
||||
if (file.isDirectory())
|
||||
{
|
||||
for (File f : file.listFiles())
|
||||
{
|
||||
if (f.getName().endsWith(".jar") && f.isFile())
|
||||
{
|
||||
resources.add(Resource.newResource(f));
|
||||
}
|
||||
else if (f.isDirectory() && f.getName().equals("lib"))
|
||||
{
|
||||
for (File f2 : file.listFiles())
|
||||
{
|
||||
if (f2.getName().endsWith(".jar") && f2.isFile())
|
||||
{
|
||||
resources.add(Resource.newResource(f));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
resources.add(Resource.newResource(file)); //TODO really???
|
||||
}
|
||||
else
|
||||
{
|
||||
resources.add(Resource.newResource(file));
|
||||
}
|
||||
|
||||
return resources;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Convert a path inside a fragment into a Resource
|
||||
* @param resourcePath
|
||||
* @param fragment
|
||||
* @param resourceMap
|
||||
* @throws Exception
|
||||
*/
|
||||
private void convertFragmentPathToResource (String resourcePath, Bundle fragment, Map<String, Resource> resourceMap )
|
||||
throws Exception
|
||||
{
|
||||
if (resourcePath == null)
|
||||
return;
|
||||
|
||||
URL url = fragment.getEntry(resourcePath);
|
||||
if (url == null)
|
||||
{
|
||||
throw new IllegalArgumentException("Unable to locate " + resourcePath
|
||||
+ " inside "
|
||||
+ " the fragment '"
|
||||
+ fragment.getSymbolicName()
|
||||
+ "'");
|
||||
}
|
||||
url = BundleFileLocatorHelperFactory.getFactory().getHelper().getLocalURL(url);
|
||||
String key = resourcePath.startsWith("/") ? resourcePath.substring(1) : resourcePath;
|
||||
resourceMap.put(key + ";" + fragment.getSymbolicName(), Resource.newResource(url));
|
||||
}
|
||||
}
|
|
@ -18,30 +18,8 @@
|
|||
|
||||
package org.eclipse.jetty.osgi.boot;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.StringTokenizer;
|
||||
import java.util.TreeMap;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.eclipse.jetty.osgi.boot.utils.BundleFileLocatorHelperFactory;
|
||||
import org.eclipse.jetty.osgi.boot.utils.Util;
|
||||
import org.eclipse.jetty.osgi.boot.utils.internal.PackageAdminServiceTracker;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
import org.eclipse.jetty.util.resource.Resource;
|
||||
import org.eclipse.jetty.util.resource.ResourceCollection;
|
||||
import org.eclipse.jetty.webapp.Configuration;
|
||||
import org.eclipse.jetty.webapp.WebAppContext;
|
||||
import org.eclipse.jetty.webapp.WebInfConfiguration;
|
||||
import org.osgi.framework.Bundle;
|
||||
import org.osgi.framework.FrameworkUtil;
|
||||
|
||||
|
||||
|
||||
|
@ -51,290 +29,19 @@ import org.osgi.framework.FrameworkUtil;
|
|||
* Handle adding resources found in bundle fragments, and add them into the
|
||||
*/
|
||||
public class OSGiWebInfConfiguration extends WebInfConfiguration
|
||||
{
|
||||
private static final Logger LOG = Log.getLogger(WebInfConfiguration.class);
|
||||
|
||||
/**
|
||||
* Comma separated list of symbolic names of bundles that contain tlds that should be considered
|
||||
* as on the container classpath
|
||||
*/
|
||||
public static final String SYS_PROP_TLD_BUNDLES = "org.eclipse.jetty.osgi.tldbundles";
|
||||
/**
|
||||
* Regex of symbolic names of bundles that should be considered to be on the container classpath
|
||||
*/
|
||||
public static final String CONTAINER_BUNDLE_PATTERN = "org.eclipse.jetty.server.webapp.containerIncludeBundlePattern";
|
||||
public static final String FRAGMENT_AND_REQUIRED_BUNDLES = "org.eclipse.jetty.osgi.fragmentAndRequiredBundles";
|
||||
public static final String FRAGMENT_AND_REQUIRED_RESOURCES = "org.eclipse.jetty.osgi.fragmentAndRequiredResources";
|
||||
|
||||
{
|
||||
@Deprecated
|
||||
public static final String SYS_PROP_TLD_BUNDLES = OSGiMetaInfConfiguration.SYS_PROP_TLD_BUNDLES;
|
||||
@Deprecated
|
||||
public static final String CONTAINER_BUNDLE_PATTERN = OSGiMetaInfConfiguration.CONTAINER_BUNDLE_PATTERN;
|
||||
@Deprecated
|
||||
public static final String FRAGMENT_AND_REQUIRED_BUNDLES = OSGiMetaInfConfiguration.FRAGMENT_AND_REQUIRED_BUNDLES;
|
||||
@Deprecated
|
||||
public static final String FRAGMENT_AND_REQUIRED_RESOURCES = OSGiMetaInfConfiguration.FRAGMENT_AND_REQUIRED_RESOURCES;
|
||||
|
||||
@Override
|
||||
public Class<? extends Configuration> replaces()
|
||||
{
|
||||
return WebInfConfiguration.class;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* Check to see if there have been any bundle symbolic names added of bundles that should be
|
||||
* regarded as being on the container classpath, and scanned for fragments, tlds etc etc.
|
||||
* This can be defined in:
|
||||
* <ol>
|
||||
* <li>SystemProperty SYS_PROP_TLD_BUNDLES</li>
|
||||
* <li>DeployerManager.setContextAttribute CONTAINER_BUNDLE_PATTERN</li>
|
||||
* </ol>
|
||||
*
|
||||
* We also allow individual bundles to specify particular bundles that might include TLDs via the Require-Tlds
|
||||
* MANIFEST.MF header.
|
||||
*
|
||||
* @see org.eclipse.jetty.webapp.WebInfConfiguration#preConfigure(org.eclipse.jetty.webapp.WebAppContext)
|
||||
*/
|
||||
@Override
|
||||
public void preConfigure(final WebAppContext context) throws Exception
|
||||
{
|
||||
super.preConfigure(context);
|
||||
|
||||
//Check to see if there have been any bundle symbolic names added of bundles that should be
|
||||
//regarded as being on the container classpath, and scanned for fragments, tlds etc etc.
|
||||
//This can be defined in:
|
||||
// 1. SystemProperty SYS_PROP_TLD_BUNDLES
|
||||
// 2. DeployerManager.setContextAttribute CONTAINER_BUNDLE_PATTERN
|
||||
String tmp = (String)context.getAttribute(CONTAINER_BUNDLE_PATTERN);
|
||||
Pattern pattern = (tmp==null?null:Pattern.compile(tmp));
|
||||
List<String> names = new ArrayList<String>();
|
||||
tmp = System.getProperty(SYS_PROP_TLD_BUNDLES);
|
||||
if (tmp != null)
|
||||
{
|
||||
StringTokenizer tokenizer = new StringTokenizer(tmp, ", \n\r\t", false);
|
||||
while (tokenizer.hasMoreTokens())
|
||||
names.add(tokenizer.nextToken());
|
||||
}
|
||||
HashSet<Resource> matchingResources = new HashSet<Resource>();
|
||||
if ( !names.isEmpty() || pattern != null)
|
||||
{
|
||||
Bundle[] bundles = FrameworkUtil.getBundle(OSGiWebInfConfiguration.class).getBundleContext().getBundles();
|
||||
|
||||
for (Bundle bundle : bundles)
|
||||
{
|
||||
LOG.debug("Checking bundle {}:{}", bundle.getBundleId(), bundle.getSymbolicName());
|
||||
if (pattern != null)
|
||||
{
|
||||
// if bundle symbolic name matches the pattern
|
||||
if (pattern.matcher(bundle.getSymbolicName()).matches())
|
||||
{
|
||||
//get the file location of the jar and put it into the list of container jars that will be scanned for stuff (including tlds)
|
||||
matchingResources.addAll(getBundleAsResource(bundle));
|
||||
}
|
||||
}
|
||||
if (names != null)
|
||||
{
|
||||
//if there is an explicit bundle name, then check if it matches
|
||||
if (names.contains(bundle.getSymbolicName()))
|
||||
matchingResources.addAll(getBundleAsResource(bundle));
|
||||
}
|
||||
}
|
||||
}
|
||||
for (Resource r:matchingResources)
|
||||
{
|
||||
context.getMetaData().addContainerResource(r);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postConfigure(WebAppContext context) throws Exception
|
||||
{
|
||||
context.setAttribute(FRAGMENT_AND_REQUIRED_BUNDLES, null);
|
||||
context.setAttribute(FRAGMENT_AND_REQUIRED_RESOURCES, null);
|
||||
super.postConfigure(context);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* Consider the fragment bundles associated with the bundle of the webapp being deployed.
|
||||
*
|
||||
*
|
||||
* @see org.eclipse.jetty.webapp.WebInfConfiguration#findJars(org.eclipse.jetty.webapp.WebAppContext)
|
||||
*/
|
||||
@Override
|
||||
protected List<Resource> findJars (WebAppContext context)
|
||||
throws Exception
|
||||
{
|
||||
List<Resource> mergedResources = new ArrayList<Resource>();
|
||||
//get jars from WEB-INF/lib if there are any
|
||||
List<Resource> webInfJars = super.findJars(context);
|
||||
if (webInfJars != null)
|
||||
mergedResources.addAll(webInfJars);
|
||||
|
||||
//add fragment jars and any Required-Bundles as if in WEB-INF/lib of the associated webapp
|
||||
Bundle[] bundles = PackageAdminServiceTracker.INSTANCE.getFragmentsAndRequiredBundles((Bundle)context.getAttribute(OSGiWebappConstants.JETTY_OSGI_BUNDLE));
|
||||
if (bundles != null && bundles.length > 0)
|
||||
{
|
||||
Set<Bundle> fragsAndReqsBundles = (Set<Bundle>)context.getAttribute(FRAGMENT_AND_REQUIRED_BUNDLES);
|
||||
if (fragsAndReqsBundles == null)
|
||||
{
|
||||
fragsAndReqsBundles = new HashSet<Bundle>();
|
||||
context.setAttribute(FRAGMENT_AND_REQUIRED_BUNDLES, fragsAndReqsBundles);
|
||||
}
|
||||
|
||||
Set<Resource> fragsAndReqsResources = (Set<Resource>)context.getAttribute(FRAGMENT_AND_REQUIRED_RESOURCES);
|
||||
if (fragsAndReqsResources == null)
|
||||
{
|
||||
fragsAndReqsResources = new HashSet<Resource>();
|
||||
context.setAttribute(FRAGMENT_AND_REQUIRED_RESOURCES, fragsAndReqsResources);
|
||||
}
|
||||
|
||||
for (Bundle b : bundles)
|
||||
{
|
||||
//skip bundles that are not installed
|
||||
if (b.getState() == Bundle.UNINSTALLED)
|
||||
continue;
|
||||
|
||||
//add to context attribute storing associated fragments and required bundles
|
||||
fragsAndReqsBundles.add(b);
|
||||
File f = BundleFileLocatorHelperFactory.getFactory().getHelper().getBundleInstallLocation(b);
|
||||
Resource r = Resource.newResource(f.toURI());
|
||||
//add to convenience context attribute storing fragments and required bundles as Resources
|
||||
fragsAndReqsResources.add(r);
|
||||
mergedResources.add(r);
|
||||
}
|
||||
}
|
||||
|
||||
return mergedResources;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* Allow fragments to supply some resources that are added to the baseResource of the webapp.
|
||||
*
|
||||
* The resources can be either prepended or appended to the baseResource.
|
||||
*
|
||||
* @see org.eclipse.jetty.webapp.WebInfConfiguration#configure(org.eclipse.jetty.webapp.WebAppContext)
|
||||
*/
|
||||
@Override
|
||||
public boolean configure(WebAppContext context) throws Exception
|
||||
{
|
||||
TreeMap<String, Resource> prependedResourcesPath = new TreeMap<String, Resource>();
|
||||
TreeMap<String, Resource> appendedResourcesPath = new TreeMap<String, Resource>();
|
||||
|
||||
Bundle bundle = (Bundle)context.getAttribute(OSGiWebappConstants.JETTY_OSGI_BUNDLE);
|
||||
if (bundle != null)
|
||||
{
|
||||
Set<Bundle> fragments = (Set<Bundle>)context.getAttribute(FRAGMENT_AND_REQUIRED_BUNDLES);
|
||||
if (fragments != null && !fragments.isEmpty())
|
||||
{
|
||||
// sorted extra resource base found in the fragments.
|
||||
// the resources are either overriding the resourcebase found in the
|
||||
// web-bundle
|
||||
// or appended.
|
||||
// amongst each resource we sort them according to the alphabetical
|
||||
// order
|
||||
// of the name of the internal folder and the symbolic name of the
|
||||
// fragment.
|
||||
// this is useful to make sure that the lookup path of those
|
||||
// resource base defined by fragments is always the same.
|
||||
// This natural order could be abused to define the order in which
|
||||
// the base resources are
|
||||
// looked up.
|
||||
for (Bundle frag : fragments)
|
||||
{
|
||||
String path = Util.getManifestHeaderValue(OSGiWebappConstants.JETTY_WAR_FRAGMENT_FOLDER_PATH,OSGiWebappConstants.JETTY_WAR_FRAGMENT_RESOURCE_PATH,frag.getHeaders());
|
||||
convertFragmentPathToResource(path, frag, appendedResourcesPath);
|
||||
path = Util.getManifestHeaderValue(OSGiWebappConstants.JETTY_WAR_PATCH_FRAGMENT_FOLDER_PATH, OSGiWebappConstants.JETTY_WAR_PREPEND_FRAGMENT_RESOURCE_PATH, frag.getHeaders());
|
||||
convertFragmentPathToResource(path, frag, prependedResourcesPath);
|
||||
}
|
||||
if (!appendedResourcesPath.isEmpty())
|
||||
{
|
||||
LinkedHashSet<Resource> resources = new LinkedHashSet<Resource>();
|
||||
//Add in any existing setting of extra resource dirs
|
||||
Set<Resource> resourceDirs = (Set<Resource>)context.getAttribute(WebInfConfiguration.RESOURCE_DIRS);
|
||||
if (resourceDirs != null && !resourceDirs.isEmpty())
|
||||
resources.addAll(resourceDirs);
|
||||
//Then append the values from JETTY_WAR_FRAGMENT_FOLDER_PATH
|
||||
resources.addAll(appendedResourcesPath.values());
|
||||
|
||||
context.setAttribute(WebInfConfiguration.RESOURCE_DIRS, resources);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
super.configure(context);
|
||||
|
||||
// place the prepended resources at the beginning of the contexts's resource base
|
||||
if (!prependedResourcesPath.isEmpty())
|
||||
{
|
||||
Resource[] resources = new Resource[1+prependedResourcesPath.size()];
|
||||
System.arraycopy(prependedResourcesPath.values().toArray(new Resource[prependedResourcesPath.size()]), 0, resources, 0, prependedResourcesPath.size());
|
||||
resources[resources.length-1] = context.getBaseResource();
|
||||
context.setBaseResource(new ResourceCollection(resources));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* Resolves the bundle. Usually that would be a single URL per bundle. But we do some more work if there are jars
|
||||
* embedded in the bundle.
|
||||
*/
|
||||
private List<Resource> getBundleAsResource(Bundle bundle)
|
||||
throws Exception
|
||||
{
|
||||
List<Resource> resources = new ArrayList<Resource>();
|
||||
|
||||
File file = BundleFileLocatorHelperFactory.getFactory().getHelper().getBundleInstallLocation(bundle);
|
||||
if (file.isDirectory())
|
||||
{
|
||||
for (File f : file.listFiles())
|
||||
{
|
||||
if (f.getName().endsWith(".jar") && f.isFile())
|
||||
{
|
||||
resources.add(Resource.newResource(f));
|
||||
}
|
||||
else if (f.isDirectory() && f.getName().equals("lib"))
|
||||
{
|
||||
for (File f2 : file.listFiles())
|
||||
{
|
||||
if (f2.getName().endsWith(".jar") && f2.isFile())
|
||||
{
|
||||
resources.add(Resource.newResource(f));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
resources.add(Resource.newResource(file)); //TODO really???
|
||||
}
|
||||
else
|
||||
{
|
||||
resources.add(Resource.newResource(file));
|
||||
}
|
||||
|
||||
return resources;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Convert a path inside a fragment into a Resource
|
||||
* @param resourcePath
|
||||
* @param fragment
|
||||
* @param resourceMap
|
||||
* @throws Exception
|
||||
*/
|
||||
private void convertFragmentPathToResource (String resourcePath, Bundle fragment, Map<String, Resource> resourceMap )
|
||||
throws Exception
|
||||
{
|
||||
if (resourcePath == null)
|
||||
return;
|
||||
|
||||
URL url = fragment.getEntry(resourcePath);
|
||||
if (url == null)
|
||||
{
|
||||
throw new IllegalArgumentException("Unable to locate " + resourcePath
|
||||
+ " inside "
|
||||
+ " the fragment '"
|
||||
+ fragment.getSymbolicName()
|
||||
+ "'");
|
||||
}
|
||||
url = BundleFileLocatorHelperFactory.getFactory().getHelper().getLocalURL(url);
|
||||
String key = resourcePath.startsWith("/") ? resourcePath.substring(1) : resourcePath;
|
||||
resourceMap.put(key + ";" + fragment.getSymbolicName(), Resource.newResource(url));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,11 +29,12 @@ import org.eclipse.jetty.annotations.ServletContainerInitializersStarter;
|
|||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
import org.eclipse.jetty.util.resource.Resource;
|
||||
import org.eclipse.jetty.webapp.AbstractConfiguration;
|
||||
import org.eclipse.jetty.webapp.Configuration;
|
||||
import org.eclipse.jetty.webapp.StandardDescriptorProcessor;
|
||||
import org.eclipse.jetty.webapp.WebAppClassLoader;
|
||||
import org.eclipse.jetty.webapp.WebAppContext;
|
||||
import org.eclipse.jetty.webapp.WebInfConfiguration;
|
||||
import org.eclipse.jetty.webapp.WebXmlConfiguration;
|
||||
|
||||
/**
|
||||
* QuickStartConfiguration
|
||||
|
@ -41,7 +42,7 @@ import org.eclipse.jetty.webapp.WebInfConfiguration;
|
|||
* Re-inflate a deployable webapp from a saved effective-web.xml
|
||||
* which combines all pre-parsed web xml descriptors and annotations.
|
||||
*/
|
||||
public class QuickStartConfiguration extends WebInfConfiguration
|
||||
public class QuickStartConfiguration extends AbstractConfiguration
|
||||
{
|
||||
private static final Logger LOG = Log.getLogger(QuickStartConfiguration.class);
|
||||
|
||||
|
@ -58,6 +59,16 @@ public class QuickStartConfiguration extends WebInfConfiguration
|
|||
private Mode _mode=Mode.AUTO;
|
||||
private boolean _quickStart;
|
||||
|
||||
|
||||
public QuickStartConfiguration()
|
||||
{
|
||||
super(false,
|
||||
new String[]{WebInfConfiguration.class.getName()},
|
||||
new String[]{WebXmlConfiguration.class.getName()},
|
||||
null,null
|
||||
);
|
||||
}
|
||||
|
||||
public void setMode(Mode mode)
|
||||
{
|
||||
_mode=mode;
|
||||
|
@ -68,11 +79,6 @@ public class QuickStartConfiguration extends WebInfConfiguration
|
|||
return _mode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends Configuration> replaces()
|
||||
{
|
||||
return WebInfConfiguration.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAddedByDefault()
|
||||
|
@ -86,20 +92,11 @@ public class QuickStartConfiguration extends WebInfConfiguration
|
|||
@Override
|
||||
public void preConfigure(WebAppContext context) throws Exception
|
||||
{
|
||||
//Make a temp directory for the webapp if one is not already set
|
||||
resolveTempDirectory(context);
|
||||
|
||||
// expand war
|
||||
if (!context.isExtractWAR() || context.isCopyWebDir() || context.isCopyWebInf())
|
||||
throw new IllegalStateException("Quickstart must be run is expanded war");
|
||||
unpack (context);
|
||||
|
||||
//check that webapp is suitable for quick start - it is not a packed war
|
||||
String war = context.getWar();
|
||||
if (war == null || war.length()<=0 || !context.getBaseResource().isDirectory())
|
||||
throw new IllegalStateException ("Bad Quickstart location");
|
||||
|
||||
|
||||
//look for quickstart-web.xml in WEB-INF of webapp
|
||||
Resource quickStartWebXml = getQuickStartWebXml(context);
|
||||
LOG.debug("quickStartWebXml={} exists={}",quickStartWebXml,quickStartWebXml.exists());
|
||||
|
@ -132,7 +129,6 @@ public class QuickStartConfiguration extends WebInfConfiguration
|
|||
else
|
||||
throw new IllegalStateException ("No "+quickStartWebXml);
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -144,11 +140,11 @@ public class QuickStartConfiguration extends WebInfConfiguration
|
|||
.filter(c->!__replacedConfigurations.contains(c.replaces())&&!__replacedConfigurations.contains(c.getClass()))
|
||||
.collect(Collectors.toList()).toArray(new Configuration[]{}));
|
||||
context.getMetaData().setWebXml(quickStartWebXml);
|
||||
context.getServletContext().setEffectiveMajorVersion(context.getMetaData().getWebXml().getMajorVersion());
|
||||
context.getServletContext().setEffectiveMinorVersion(context.getMetaData().getWebXml().getMinorVersion());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @see org.eclipse.jetty.webapp.AbstractConfiguration#configure(org.eclipse.jetty.webapp.WebAppContext)
|
||||
*/
|
||||
|
@ -158,22 +154,6 @@ public class QuickStartConfiguration extends WebInfConfiguration
|
|||
if (!_quickStart)
|
||||
return super.configure(context);
|
||||
|
||||
//TODO: set up the classpath here. This should be handled by the QuickStartDescriptorProcessor
|
||||
Resource webInf = context.getWebInf();
|
||||
|
||||
if (webInf != null && webInf.isDirectory() && context.getClassLoader() instanceof WebAppClassLoader)
|
||||
{
|
||||
// Look for classes directory
|
||||
Resource classes= webInf.addPath("classes/");
|
||||
if (classes.exists())
|
||||
((WebAppClassLoader)context.getClassLoader()).addClassPath(classes);
|
||||
|
||||
// Look for jars
|
||||
Resource lib= webInf.addPath("lib/");
|
||||
if (lib.exists() || lib.isDirectory())
|
||||
((WebAppClassLoader)context.getClassLoader()).addJars(lib);
|
||||
}
|
||||
|
||||
//add the processor to handle normal web.xml content
|
||||
context.getMetaData().addDescriptorProcessor(new StandardDescriptorProcessor());
|
||||
|
||||
|
|
|
@ -122,7 +122,7 @@ public class QuickStartGeneratorConfiguration extends AbstractConfiguration
|
|||
webappAttr.put("xmlns:xsi","http://www.w3.org/2001/XMLSchema-instance");
|
||||
webappAttr.put("xsi:schemaLocation","http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd");
|
||||
webappAttr.put("metadata-complete","true");
|
||||
webappAttr.put("version","3.1");
|
||||
webappAttr.put("version",_webApp.getServletContext().getEffectiveMajorVersion()+"."+_webApp.getServletContext().getEffectiveMinorVersion());
|
||||
|
||||
out.openTag("web-app",webappAttr);
|
||||
if (_webApp.getDisplayName() != null)
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
package org.eclipse.jetty.webapp;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
@ -74,8 +75,8 @@ public class AbstractConfiguration implements Configuration
|
|||
_enabledByDefault=enableByDefault;
|
||||
_after=Collections.unmodifiableList(after==null?Collections.emptyList():Arrays.asList(after).stream().map(Class::getName).collect(Collectors.toList()));
|
||||
_before=Collections.unmodifiableList(before==null?Collections.emptyList():Arrays.asList(before).stream().map(Class::getName).collect(Collectors.toList()));
|
||||
_system=Collections.unmodifiableList(systemClasses==null?Collections.emptyList():Arrays.asList(systemClasses));
|
||||
_server=Collections.unmodifiableList(serverClasses==null?Collections.emptyList():Arrays.asList(serverClasses));
|
||||
_system=new ArrayList<>(systemClasses==null?Collections.emptyList():Arrays.asList(systemClasses));
|
||||
_server=new ArrayList<>(serverClasses==null?Collections.emptyList():Arrays.asList(serverClasses));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -90,8 +91,20 @@ public class AbstractConfiguration implements Configuration
|
|||
_enabledByDefault=enableByDefault;
|
||||
_after=Collections.unmodifiableList(after==null?Collections.emptyList():Arrays.asList(after));
|
||||
_before=Collections.unmodifiableList(before==null?Collections.emptyList():Arrays.asList(before));
|
||||
_system=Collections.unmodifiableList(systemClasses==null?Collections.emptyList():Arrays.asList(systemClasses));
|
||||
_server=Collections.unmodifiableList(serverClasses==null?Collections.emptyList():Arrays.asList(serverClasses));
|
||||
_system=new ArrayList<>(systemClasses==null?Collections.emptyList():Arrays.asList(systemClasses));
|
||||
_server=new ArrayList<>(serverClasses==null?Collections.emptyList():Arrays.asList(serverClasses));
|
||||
}
|
||||
|
||||
protected void addSystemClass(String... systemClass)
|
||||
{
|
||||
for (String s:systemClass)
|
||||
_system.add(s);
|
||||
}
|
||||
|
||||
protected void addServerClass(String... serverClass)
|
||||
{
|
||||
for (String s:serverClass)
|
||||
_system.add(s);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -21,7 +21,6 @@ package org.eclipse.jetty.webapp;
|
|||
import java.util.AbstractList;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.ConcurrentModificationException;
|
||||
import java.util.HashMap;
|
||||
|
@ -43,24 +42,27 @@ public class Configurations extends AbstractList<Configuration>
|
|||
{
|
||||
private static final Logger LOG = Log.getLogger(Configurations.class);
|
||||
|
||||
private static final Map<String,Configuration> __known = new HashMap<>();
|
||||
private static final List<Configuration> __known = new ArrayList<>();
|
||||
private static final Map<String,Configuration> __knownByClassName = new HashMap<>();
|
||||
static
|
||||
{
|
||||
ServiceLoader<Configuration> configs = ServiceLoader.load(Configuration.class);
|
||||
for (Configuration configuration : configs)
|
||||
__known.put(configuration.getName(),configuration);
|
||||
|
||||
__knownByClassName.put(configuration.getName(),configuration);
|
||||
__known.addAll(__knownByClassName.values());
|
||||
sort(__known);
|
||||
if (LOG.isDebugEnabled())
|
||||
{
|
||||
for (Map.Entry<String, Configuration> e: __known.entrySet())
|
||||
LOG.debug("known {}",e);
|
||||
for (Configuration c: __known)
|
||||
LOG.debug("known {}",c);
|
||||
}
|
||||
LOG.debug("Known Configurations {}",__known.keySet());
|
||||
|
||||
LOG.debug("Known Configurations {}",__knownByClassName.keySet());
|
||||
}
|
||||
|
||||
public static Collection<Configuration> getKnown()
|
||||
public static List<Configuration> getKnown()
|
||||
{
|
||||
return Collections.unmodifiableCollection(__known.values());
|
||||
return __known;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
@ -73,7 +75,7 @@ public class Configurations extends AbstractList<Configuration>
|
|||
* @param server The server the default is for
|
||||
* @return the server default ClassList instance of the configuration classes for this server. Changes to this list will change the server default instance.
|
||||
*/
|
||||
public static Configurations setServerDefault(Server server) throws ClassNotFoundException, InstantiationException, IllegalAccessException
|
||||
public static Configurations setServerDefault(Server server)
|
||||
{
|
||||
Configurations configurations=server.getBean(Configurations.class);
|
||||
if (configurations!=null)
|
||||
|
@ -94,10 +96,8 @@ public class Configurations extends AbstractList<Configuration>
|
|||
*/
|
||||
public static Configurations serverDefault(Server server)
|
||||
{
|
||||
Configurations configurations;
|
||||
if (server==null)
|
||||
configurations=new Configurations(WebAppContext.DEFAULT_CONFIGURATION_CLASSES);
|
||||
else
|
||||
Configurations configurations=null;
|
||||
if (server!=null)
|
||||
{
|
||||
configurations= server.getBean(Configurations.class);
|
||||
if (configurations!=null)
|
||||
|
@ -110,11 +110,15 @@ public class Configurations extends AbstractList<Configuration>
|
|||
configurations = new Configurations((Configurations)attr);
|
||||
else if (attr instanceof String[])
|
||||
configurations = new Configurations((String[])attr);
|
||||
else
|
||||
configurations=new Configurations(WebAppContext.DEFAULT_CONFIGURATION_CLASSES);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (configurations==null)
|
||||
configurations=new Configurations(Configurations.getKnown().stream()
|
||||
.filter(Configuration::isAddedByDefault)
|
||||
.map(c->c.getClass().getName())
|
||||
.toArray(String[]::new));
|
||||
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("default configurations for {}: {}",server,configurations);
|
||||
|
||||
|
@ -134,7 +138,7 @@ public class Configurations extends AbstractList<Configuration>
|
|||
|
||||
protected static Configuration getConfiguration(String classname)
|
||||
{
|
||||
Configuration configuration = __known.get(classname);
|
||||
Configuration configuration = __knownByClassName.get(classname);
|
||||
if (configuration==null)
|
||||
{
|
||||
try
|
||||
|
@ -165,7 +169,9 @@ public class Configurations extends AbstractList<Configuration>
|
|||
|
||||
public Configurations(Configurations classlist)
|
||||
{
|
||||
_configurations.addAll(classlist._configurations);
|
||||
this(classlist._configurations.stream()
|
||||
.map(c->c.getClass().getName())
|
||||
.toArray(String[]::new));
|
||||
}
|
||||
|
||||
public void add(Configuration... configurations)
|
||||
|
@ -232,14 +238,24 @@ public class Configurations extends AbstractList<Configuration>
|
|||
}
|
||||
|
||||
public void sort()
|
||||
{
|
||||
sort(_configurations);
|
||||
if (LOG.isDebugEnabled())
|
||||
{
|
||||
for (Configuration c: _configurations)
|
||||
LOG.debug("sorted {}",c);
|
||||
}
|
||||
}
|
||||
|
||||
public static void sort(List<Configuration> configurations)
|
||||
{
|
||||
// Sort the configurations
|
||||
Map<String,Configuration> map = new HashMap<>();
|
||||
TopologicalSort<Configuration> sort = new TopologicalSort<>();
|
||||
|
||||
for (Configuration c:_configurations)
|
||||
for (Configuration c:configurations)
|
||||
map.put(c.getName(),c);
|
||||
for (Configuration c:_configurations)
|
||||
for (Configuration c:configurations)
|
||||
{
|
||||
for (String b:c.getConfigurationsBeforeThis())
|
||||
{
|
||||
|
@ -255,12 +271,7 @@ public class Configurations extends AbstractList<Configuration>
|
|||
}
|
||||
}
|
||||
|
||||
sort.sort(_configurations);
|
||||
if (LOG.isDebugEnabled())
|
||||
{
|
||||
for (Configuration c: _configurations)
|
||||
LOG.debug("sorted {}",c);
|
||||
}
|
||||
sort.sort(configurations);
|
||||
}
|
||||
|
||||
public List<Configuration> getConfigurations()
|
||||
|
@ -283,7 +294,7 @@ public class Configurations extends AbstractList<Configuration>
|
|||
private void add(String name,Configuration configuration)
|
||||
{
|
||||
// Is this configuration known?
|
||||
if (!__known.containsKey(name))
|
||||
if (!__knownByClassName.containsKey(name))
|
||||
LOG.warn("Unknown configuration {}. Not declared for ServiceLoader!",name);
|
||||
|
||||
// Do we need to replace any existing configuration?
|
||||
|
@ -321,7 +332,7 @@ public class Configurations extends AbstractList<Configuration>
|
|||
for (int i=0; i<_configurations.size() ;i++)
|
||||
{
|
||||
Configuration configuration=_configurations.get(i);
|
||||
LOG.debug("preConfigure {} with {}",this,configuration);
|
||||
LOG.debug("preConfigure with {}",configuration);
|
||||
configuration.preConfigure(webapp);
|
||||
|
||||
if (_configurations.get(i)!=configuration)
|
||||
|
@ -334,7 +345,7 @@ public class Configurations extends AbstractList<Configuration>
|
|||
// Configure webapp
|
||||
for (Configuration configuration : _configurations)
|
||||
{
|
||||
LOG.debug("configure {} with {}",this,configuration);
|
||||
LOG.debug("configure {}",configuration);
|
||||
if (!configuration.configure(webapp))
|
||||
return false;
|
||||
}
|
||||
|
@ -347,7 +358,7 @@ public class Configurations extends AbstractList<Configuration>
|
|||
// Configure webapp
|
||||
for (Configuration configuration : _configurations)
|
||||
{
|
||||
LOG.debug("postConfigure {} with {}",this,configuration);
|
||||
LOG.debug("postConfigure {}",configuration);
|
||||
configuration.postConfigure(webapp);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ import java.io.File;
|
|||
import java.io.IOException;
|
||||
import java.net.JarURLConnection;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.util.ArrayList;
|
||||
|
@ -98,7 +99,29 @@ public class MetaInfConfiguration extends AbstractConfiguration
|
|||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------------- */
|
||||
protected List<URI> getAllContainerJars(final WebAppContext context) throws URISyntaxException
|
||||
{
|
||||
List<URI> uris = new ArrayList<>();
|
||||
if (context.getClassLoader() != null)
|
||||
{
|
||||
ClassLoader loader = context.getClassLoader().getParent();
|
||||
while (loader != null)
|
||||
{
|
||||
if (loader instanceof URLClassLoader)
|
||||
{
|
||||
URL[] urls = ((URLClassLoader)loader).getURLs();
|
||||
if (urls != null)
|
||||
for(URL url:urls)
|
||||
uris.add(new URI(url.toString().replaceAll(" ","%20")));
|
||||
}
|
||||
loader = loader.getParent();
|
||||
}
|
||||
}
|
||||
return uris;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------- */
|
||||
@Override
|
||||
public void preConfigure(final WebAppContext context) throws Exception
|
||||
|
@ -106,16 +129,7 @@ public class MetaInfConfiguration extends AbstractConfiguration
|
|||
// discover matching container jars
|
||||
if (context.getClassLoader() != null)
|
||||
{
|
||||
ClassLoader loader = context.getClassLoader().getParent();
|
||||
List<URI> uris = new ArrayList<>();
|
||||
while (loader != null && (loader instanceof URLClassLoader))
|
||||
{
|
||||
URL[] urls = ((URLClassLoader)loader).getURLs();
|
||||
if (urls != null)
|
||||
for(URL url:urls)
|
||||
uris.add(new URI(url.toString().replaceAll(" ","%20")));
|
||||
loader = loader.getParent();
|
||||
}
|
||||
List<URI> uris = getAllContainerJars(context);
|
||||
|
||||
new PatternMatcher ()
|
||||
{
|
||||
|
|
|
@ -163,15 +163,6 @@ public class WebAppContext extends ServletContextHandler implements WebAppClassL
|
|||
|
||||
private String[] __dftProtectedTargets = {"/web-inf", "/meta-inf"};
|
||||
|
||||
/*
|
||||
* default configurations.
|
||||
*/
|
||||
public static final String[] DEFAULT_CONFIGURATION_CLASSES =
|
||||
Configurations.getKnown().stream()
|
||||
.filter(Configuration::isAddedByDefault)
|
||||
.map(c->c.getClass().getName())
|
||||
.toArray(String[]::new);
|
||||
|
||||
// System classes are classes that cannot be replaced by
|
||||
// the web application, and they are *always* loaded via
|
||||
// system classloader.
|
||||
|
@ -914,25 +905,6 @@ public class WebAppContext extends ServletContextHandler implements WebAppClassL
|
|||
return _parentLoaderPriority;
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public static String[] getDefaultConfigurationClasses ()
|
||||
{
|
||||
return DEFAULT_CONFIGURATION_CLASSES;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public String[] getDefaultServerClasses ()
|
||||
{
|
||||
return __dftServerClasses;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public String[] getDefaultSystemClasses ()
|
||||
{
|
||||
return __dftSystemClasses;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
protected void loadConfigurations()
|
||||
{
|
||||
|
@ -941,7 +913,6 @@ public class WebAppContext extends ServletContextHandler implements WebAppClassL
|
|||
return;
|
||||
|
||||
_configurations.add(Configurations.serverDefault(getServer()).toArray());
|
||||
_configurations.sort();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
@ -985,6 +956,7 @@ public class WebAppContext extends ServletContextHandler implements WebAppClassL
|
|||
_configurations.set(configurations);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public void setConfigurationClasses(List<String> configurations)
|
||||
{
|
||||
setConfigurationClasses(configurations.toArray(new String[configurations.size()]));
|
||||
|
|
|
@ -38,7 +38,14 @@ public class WebInfConfiguration extends AbstractConfiguration
|
|||
private static final Logger LOG = Log.getLogger(WebInfConfiguration.class);
|
||||
|
||||
public static final String TEMPDIR_CONFIGURED = "org.eclipse.jetty.tmpdirConfigured";
|
||||
|
||||
|
||||
@Deprecated
|
||||
public static final String CONTAINER_JAR_PATTERN = MetaInfConfiguration.CONTAINER_JAR_PATTERN;
|
||||
@Deprecated
|
||||
public static final String WEBINF_JAR_PATTERN = MetaInfConfiguration.WEBINF_JAR_PATTERN;
|
||||
@Deprecated
|
||||
public static final String RESOURCE_DIRS = MetaInfConfiguration.RESOURCE_DIRS;
|
||||
|
||||
protected Resource _preUnpackBaseResource;
|
||||
|
||||
public WebInfConfiguration()
|
||||
|
|
|
@ -57,10 +57,16 @@ public class WebAppContextTest
|
|||
@Test
|
||||
public void testConfigurationClassesFromDefault ()
|
||||
{
|
||||
String[] known_and_enabled=Configurations.getKnown().stream()
|
||||
.filter(Configuration::isAddedByDefault)
|
||||
.map(c->c.getClass().getName())
|
||||
.toArray(String[]::new);
|
||||
|
||||
Server server = new Server();
|
||||
|
||||
//test if no classnames set, its the defaults
|
||||
WebAppContext wac = new WebAppContext();
|
||||
assertThat(Arrays.asList(wac.getConfigurations()).stream().map(c->{return c.getClass().getName();}).collect(Collectors.toList()),Matchers.containsInAnyOrder(WebAppContext.DEFAULT_CONFIGURATION_CLASSES));
|
||||
assertThat(Arrays.asList(wac.getConfigurations()).stream().map(c->{return c.getClass().getName();}).collect(Collectors.toList()),Matchers.containsInAnyOrder(known_and_enabled));
|
||||
String[] classNames = wac.getConfigurationClasses();
|
||||
assertNotNull(classNames);
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# Setup default logging implementation for during testing
|
||||
org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog
|
||||
org.eclipse.jetty.LEVEL=INFO
|
||||
org.eclipse.jetty.webapp.LEVEL=DEBUG
|
||||
# org.eclipse.jetty.webapp.LEVEL=DEBUG
|
||||
# org.eclipse.jetty.util.LEVEL=DEBUG
|
||||
# org.eclipse.jetty.util.PathWatcher.Noisy.LEVEL=OFF
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# Setup default logging implementation for during testing
|
||||
org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog
|
||||
org.eclipse.jetty.LEVEL=INFO
|
||||
#org.eclipse.jetty.webapp.LEVEL=DEBUG
|
||||
#org.eclipse.jetty.quickstart.LEVEL=DEBUG
|
||||
org.eclipse.jetty.webapp.LEVEL=DEBUG
|
||||
org.eclipse.jetty.quickstart.LEVEL=DEBUG
|
||||
#org.eclipse.jetty.util.LEVEL=DEBUG
|
||||
#org.eclipse.jetty.util.PathWatcher.Noisy.LEVEL=OFF
|
||||
|
|
Loading…
Reference in New Issue