New Configuration structure. This structure will be modified in jetty-8 to accommodate servlet spec3. This checkin moves jetty-7 closer to that final structure. Configuration now consists of 3 phases: preConfigure(), configure() and postConfigure(). All Configurations can now be chained together rather than having to override/replace existing Configurations.
git-svn-id: svn+ssh://dev.eclipse.org/svnroot/rt/org.eclipse.jetty/jetty/trunk@230 7e9141cc-0065-0410-87d8-b60c137991c4
This commit is contained in:
parent
c236945c53
commit
688fbac7aa
|
@ -141,7 +141,7 @@ public class AnnotationProcessor
|
||||||
{
|
{
|
||||||
for (Class clazz:_finder.getClassesForAnnotation(RunAs.class))
|
for (Class clazz:_finder.getClassesForAnnotation(RunAs.class))
|
||||||
{
|
{
|
||||||
if (!javax.servlet.Servlet.class.isAssignableFrom(clazz) && !(_pojoInstances.containsKey(clazz)))
|
if (!javax.servlet.Servlet.class.isAssignableFrom(clazz))
|
||||||
{
|
{
|
||||||
Log.debug("Ignoring runAs notation on on-servlet class "+clazz.getName());
|
Log.debug("Ignoring runAs notation on on-servlet class "+clazz.getName());
|
||||||
continue;
|
continue;
|
||||||
|
@ -611,8 +611,7 @@ public class AnnotationProcessor
|
||||||
javax.servlet.ServletRequestListener.class.isAssignableFrom(c) ||
|
javax.servlet.ServletRequestListener.class.isAssignableFrom(c) ||
|
||||||
javax.servlet.ServletRequestAttributeListener.class.isAssignableFrom(c) ||
|
javax.servlet.ServletRequestAttributeListener.class.isAssignableFrom(c) ||
|
||||||
javax.servlet.http.HttpSessionListener.class.isAssignableFrom(c) ||
|
javax.servlet.http.HttpSessionListener.class.isAssignableFrom(c) ||
|
||||||
javax.servlet.http.HttpSessionAttributeListener.class.isAssignableFrom(c) ||
|
javax.servlet.http.HttpSessionAttributeListener.class.isAssignableFrom(c))
|
||||||
(_pojoInstances.get(c) != null))
|
|
||||||
|
|
||||||
isServlet=true;
|
isServlet=true;
|
||||||
|
|
||||||
|
@ -620,26 +619,7 @@ public class AnnotationProcessor
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get an already-created instance of a pojo, or create one
|
|
||||||
* otherwise.
|
|
||||||
* @param clazz
|
|
||||||
* @return
|
|
||||||
* @throws InstantiationException
|
|
||||||
* @throws IllegalAccessException
|
|
||||||
*/
|
|
||||||
private Object getPojoInstanceFor (Class clazz)
|
|
||||||
throws InstantiationException, IllegalAccessException
|
|
||||||
{
|
|
||||||
Object instance = _pojoInstances.get(clazz);
|
|
||||||
if (instance == null)
|
|
||||||
{
|
|
||||||
instance = clazz.newInstance();
|
|
||||||
_pojoInstances.put(clazz, instance);
|
|
||||||
}
|
|
||||||
return instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean isEnvEntryType (Class type)
|
private static boolean isEnvEntryType (Class type)
|
||||||
{
|
{
|
||||||
boolean result = false;
|
boolean result = false;
|
||||||
|
|
|
@ -14,13 +14,17 @@
|
||||||
package org.eclipse.jetty.annotations;
|
package org.eclipse.jetty.annotations;
|
||||||
|
|
||||||
import java.util.EventListener;
|
import java.util.EventListener;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.eclipse.jetty.plus.servlet.ServletHandler;
|
||||||
|
import org.eclipse.jetty.security.SecurityHandler;
|
||||||
import org.eclipse.jetty.servlet.FilterHolder;
|
import org.eclipse.jetty.servlet.FilterHolder;
|
||||||
import org.eclipse.jetty.servlet.FilterMapping;
|
import org.eclipse.jetty.servlet.FilterMapping;
|
||||||
import org.eclipse.jetty.servlet.ServletHolder;
|
import org.eclipse.jetty.servlet.ServletHolder;
|
||||||
import org.eclipse.jetty.servlet.ServletMapping;
|
import org.eclipse.jetty.servlet.ServletMapping;
|
||||||
import org.eclipse.jetty.util.LazyList;
|
import org.eclipse.jetty.util.LazyList;
|
||||||
import org.eclipse.jetty.util.log.Log;
|
import org.eclipse.jetty.util.log.Log;
|
||||||
|
import org.eclipse.jetty.webapp.WebAppContext;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configuration
|
* Configuration
|
||||||
|
@ -42,7 +46,7 @@ public class Configuration extends org.eclipse.jetty.plus.webapp.Configuration
|
||||||
/**
|
/**
|
||||||
* @see org.eclipse.jetty.plus.webapp.AbstractConfiguration#parseAnnotations()
|
* @see org.eclipse.jetty.plus.webapp.AbstractConfiguration#parseAnnotations()
|
||||||
*/
|
*/
|
||||||
public void parseAnnotations() throws Exception
|
public void parseAnnotations(final WebAppContext context) throws Exception
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* TODO Need to also take account of hidden classes on system classpath that should never
|
* TODO Need to also take account of hidden classes on system classpath that should never
|
||||||
|
@ -67,20 +71,20 @@ public class Configuration extends org.eclipse.jetty.plus.webapp.Configuration
|
||||||
|
|
||||||
//if no pattern for the container path is defined, then by default scan NOTHING
|
//if no pattern for the container path is defined, then by default scan NOTHING
|
||||||
Log.debug("Scanning system jars");
|
Log.debug("Scanning system jars");
|
||||||
finder.find(getWebAppContext().getClassLoader().getParent(), true, getWebAppContext().getInitParameter(__container_pattern), false,
|
finder.find(context.getClassLoader().getParent(), true, context.getInitParameter(__container_pattern), false,
|
||||||
new ClassNameResolver ()
|
new ClassNameResolver ()
|
||||||
{
|
{
|
||||||
public boolean isExcluded (String name)
|
public boolean isExcluded (String name)
|
||||||
{
|
{
|
||||||
if (getWebAppContext().isSystemClass(name)) return false;
|
if (context.isSystemClass(name)) return false;
|
||||||
if (getWebAppContext().isServerClass(name)) return true;
|
if (context.isServerClass(name)) return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean shouldOverride (String name)
|
public boolean shouldOverride (String name)
|
||||||
{
|
{
|
||||||
//looking at system classpath
|
//looking at system classpath
|
||||||
if (getWebAppContext().isParentLoaderPriority())
|
if (context.isParentLoaderPriority())
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -88,58 +92,67 @@ public class Configuration extends org.eclipse.jetty.plus.webapp.Configuration
|
||||||
|
|
||||||
Log.debug("Scanning WEB-INF/lib jars");
|
Log.debug("Scanning WEB-INF/lib jars");
|
||||||
//if no pattern for web-inf/lib is defined, then by default scan everything in it
|
//if no pattern for web-inf/lib is defined, then by default scan everything in it
|
||||||
finder.find (getWebAppContext().getClassLoader(), false, getWebAppContext().getInitParameter(__web_inf_pattern), true,
|
finder.find (context.getClassLoader(), false, context.getInitParameter(__web_inf_pattern), true,
|
||||||
new ClassNameResolver()
|
new ClassNameResolver()
|
||||||
{
|
{
|
||||||
public boolean isExcluded (String name)
|
public boolean isExcluded (String name)
|
||||||
{
|
{
|
||||||
if (getWebAppContext().isSystemClass(name)) return true;
|
if (context.isSystemClass(name)) return true;
|
||||||
if (getWebAppContext().isServerClass(name)) return false;
|
if (context.isServerClass(name)) return false;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean shouldOverride (String name)
|
public boolean shouldOverride (String name)
|
||||||
{
|
{
|
||||||
//looking at webapp classpath, found already-parsed class of same name - did it come from system or duplicate in webapp?
|
//looking at webapp classpath, found already-parsed class of same name - did it come from system or duplicate in webapp?
|
||||||
if (getWebAppContext().isParentLoaderPriority())
|
if (context.isParentLoaderPriority())
|
||||||
return false;
|
return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Log.debug("Scanning classes in WEB-INF/classes");
|
Log.debug("Scanning classes in WEB-INF/classes");
|
||||||
finder.find(_context.getWebInf().addPath("classes/"),
|
finder.find(context.getWebInf().addPath("classes/"),
|
||||||
new ClassNameResolver()
|
new ClassNameResolver()
|
||||||
{
|
{
|
||||||
public boolean isExcluded (String name)
|
public boolean isExcluded (String name)
|
||||||
{
|
{
|
||||||
if (getWebAppContext().isSystemClass(name)) return true;
|
if (context.isSystemClass(name)) return true;
|
||||||
if (getWebAppContext().isServerClass(name)) return false;
|
if (context.isServerClass(name)) return false;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean shouldOverride (String name)
|
public boolean shouldOverride (String name)
|
||||||
{
|
{
|
||||||
//looking at webapp classpath, found already-parsed class of same name - did it come from system or duplicate in webapp?
|
//looking at webapp classpath, found already-parsed class of same name - did it come from system or duplicate in webapp?
|
||||||
if (getWebAppContext().isParentLoaderPriority())
|
if (context.isParentLoaderPriority())
|
||||||
return false;
|
return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
AnnotationProcessor processor = new AnnotationProcessor(getWebAppContext(), finder, _runAsCollection, _injections, _callbacks,
|
ServletHandler servletHandler = (ServletHandler)context.getServletHandler();
|
||||||
LazyList.getList(_servlets), LazyList.getList(_filters), LazyList.getList(_listeners),
|
List filters = LazyList.array2List(servletHandler.getFilters());
|
||||||
LazyList.getList(_servletMappings), LazyList.getList(_filterMappings));
|
List filterMappings = LazyList.array2List(servletHandler.getFilterMappings());
|
||||||
|
List servlets = LazyList.array2List(servletHandler.getServlets());
|
||||||
|
List servletMappings = LazyList.array2List(servletHandler.getServletMappings());
|
||||||
|
List listeners = LazyList.array2List(context.getEventListeners());
|
||||||
|
|
||||||
|
AnnotationProcessor processor = new AnnotationProcessor(context, finder, _runAsCollection, _injections, _callbacks,
|
||||||
|
servlets, filters,listeners,
|
||||||
|
servletMappings, filterMappings);
|
||||||
processor.process();
|
processor.process();
|
||||||
_servlets = processor.getServlets();
|
|
||||||
_filters = processor.getFilters();
|
servlets = processor.getServlets();
|
||||||
_servletMappings = processor.getServletMappings();
|
filters = processor.getFilters();
|
||||||
_filterMappings = processor.getFilterMappings();
|
servletMappings = processor.getServletMappings();
|
||||||
_listeners = processor.getListeners();
|
filterMappings = processor.getFilterMappings();
|
||||||
_servletHandler.setFilters((FilterHolder[])LazyList.toArray(_filters,FilterHolder.class));
|
listeners = processor.getListeners();
|
||||||
_servletHandler.setFilterMappings((FilterMapping[])LazyList.toArray(_filterMappings,FilterMapping.class));
|
|
||||||
_servletHandler.setServlets((ServletHolder[])LazyList.toArray(_servlets,ServletHolder.class));
|
servletHandler.setFilters((FilterHolder[])LazyList.toArray(filters,FilterHolder.class));
|
||||||
_servletHandler.setServletMappings((ServletMapping[])LazyList.toArray(_servletMappings,ServletMapping.class));
|
servletHandler.setFilterMappings((FilterMapping[])LazyList.toArray(filterMappings,FilterMapping.class));
|
||||||
getWebAppContext().setEventListeners((EventListener[])LazyList.toArray(_listeners,EventListener.class));
|
servletHandler.setServlets((ServletHolder[])LazyList.toArray(servlets,ServletHolder.class));
|
||||||
|
servletHandler.setServletMappings((ServletMapping[])LazyList.toArray(servletMappings,ServletMapping.class));
|
||||||
|
context.setEventListeners((EventListener[])LazyList.toArray(listeners,EventListener.class));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,6 +42,9 @@
|
||||||
<!-- =========================================================== -->
|
<!-- =========================================================== -->
|
||||||
<Array id="plusConfig" type="java.lang.String">
|
<Array id="plusConfig" type="java.lang.String">
|
||||||
<Item>org.eclipse.jetty.webapp.WebInfConfiguration</Item>
|
<Item>org.eclipse.jetty.webapp.WebInfConfiguration</Item>
|
||||||
|
<Item>org.eclipse.jetty.webapp.WebXmlConfiguration</Item>
|
||||||
|
<Item>org.eclipse.jetty.webapp.MetaInfConfiguration</Item>
|
||||||
|
<Item>org.eclipse.jetty.webapp.FragmentConfiguration</Item>
|
||||||
<Item>org.eclipse.jetty.plus.webapp.EnvConfiguration</Item>
|
<Item>org.eclipse.jetty.plus.webapp.EnvConfiguration</Item>
|
||||||
<Item>org.eclipse.jetty.plus.webapp.Configuration</Item>
|
<Item>org.eclipse.jetty.plus.webapp.Configuration</Item>
|
||||||
<Item>org.eclipse.jetty.webapp.JettyWebXmlConfiguration</Item>
|
<Item>org.eclipse.jetty.webapp.JettyWebXmlConfiguration</Item>
|
||||||
|
|
|
@ -201,6 +201,7 @@ public abstract class NamingEntry
|
||||||
objectName.addAll(0, prefix);
|
objectName.addAll(0, prefix);
|
||||||
objectNameString = objectName.toString();
|
objectNameString = objectName.toString();
|
||||||
NamingUtil.bind(ic, objectNameString, objectToBind);
|
NamingUtil.bind(ic, objectNameString, objectToBind);
|
||||||
|
System.err.println("Bound: "+objectName.toString()+" to "+objectToBind);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -239,7 +239,7 @@ public class NamingEntryUtil
|
||||||
if (scope==null)
|
if (scope==null)
|
||||||
return "";
|
return "";
|
||||||
|
|
||||||
String str = scope.toString();
|
String str = scope.getClass().getName()+"@"+scope.hashCode();
|
||||||
str=str.replace('/', '_').replace(' ', '_');
|
str=str.replace('/', '_').replace(' ', '_');
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,8 +31,10 @@ import org.eclipse.jetty.security.SecurityHandler;
|
||||||
import org.eclipse.jetty.servlet.ServletHolder;
|
import org.eclipse.jetty.servlet.ServletHolder;
|
||||||
import org.eclipse.jetty.util.TypeUtil;
|
import org.eclipse.jetty.util.TypeUtil;
|
||||||
import org.eclipse.jetty.util.log.Log;
|
import org.eclipse.jetty.util.log.Log;
|
||||||
|
import org.eclipse.jetty.webapp.Configuration;
|
||||||
import org.eclipse.jetty.webapp.WebAppContext;
|
import org.eclipse.jetty.webapp.WebAppContext;
|
||||||
import org.eclipse.jetty.webapp.WebXmlConfiguration;
|
import org.eclipse.jetty.webapp.WebXmlConfiguration;
|
||||||
|
import org.eclipse.jetty.webapp.WebXmlProcessor;
|
||||||
import org.eclipse.jetty.xml.XmlParser;
|
import org.eclipse.jetty.xml.XmlParser;
|
||||||
|
|
||||||
|
|
||||||
|
@ -42,22 +44,348 @@ import org.eclipse.jetty.xml.XmlParser;
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractConfiguration extends WebXmlConfiguration
|
public abstract class AbstractConfiguration implements Configuration
|
||||||
{
|
{
|
||||||
protected LifeCycleCallbackCollection _callbacks = new LifeCycleCallbackCollection();
|
protected LifeCycleCallbackCollection _callbacks = new LifeCycleCallbackCollection();
|
||||||
protected InjectionCollection _injections = new InjectionCollection();
|
protected InjectionCollection _injections = new InjectionCollection();
|
||||||
protected RunAsCollection _runAsCollection = new RunAsCollection();
|
protected RunAsCollection _runAsCollection = new RunAsCollection();
|
||||||
protected SecurityHandler _securityHandler;
|
protected SecurityHandler _securityHandler;
|
||||||
|
|
||||||
public abstract void bindEnvEntry (String name, Object value) throws Exception;
|
public abstract void bindEnvEntry (WebAppContext context, String name, Object value) throws Exception;
|
||||||
|
|
||||||
public abstract void bindResourceRef (String name, Class type) throws Exception;
|
public abstract void bindResourceRef (WebAppContext context, String name, Class type) throws Exception;
|
||||||
|
|
||||||
public abstract void bindResourceEnvRef (String name, Class type) throws Exception;
|
public abstract void bindResourceEnvRef (WebAppContext context, String name, Class type) throws Exception;
|
||||||
|
|
||||||
public abstract void bindUserTransaction () throws Exception;
|
public abstract void bindUserTransaction (WebAppContext context) throws Exception;
|
||||||
|
|
||||||
|
public abstract void bindMessageDestinationRef (WebAppContext context, String name, Class type) throws Exception;
|
||||||
|
|
||||||
|
protected abstract void parseAnnotations (WebAppContext context) throws Exception;
|
||||||
|
|
||||||
|
|
||||||
|
public class PlusWebXmlProcessor
|
||||||
|
{
|
||||||
|
WebAppContext _context;
|
||||||
|
|
||||||
|
public PlusWebXmlProcessor (WebAppContext context)
|
||||||
|
{
|
||||||
|
_context = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void process (XmlParser.Node root)
|
||||||
|
throws Exception
|
||||||
|
{
|
||||||
|
if (root == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
|
||||||
|
Iterator iter = root.iterator();
|
||||||
|
XmlParser.Node node = null;
|
||||||
|
while (iter.hasNext())
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Object o = iter.next();
|
||||||
|
if (!(o instanceof XmlParser.Node)) continue;
|
||||||
|
node = (XmlParser.Node) o;
|
||||||
|
String name = node.getTag();
|
||||||
|
initWebXmlElement(name, node);
|
||||||
|
}
|
||||||
|
catch (ClassNotFoundException e)
|
||||||
|
{
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Log.warn("Configuration problem at " + node, e);
|
||||||
|
throw new UnavailableException("Configuration problem");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void initWebXmlElement(String element,XmlParser.Node node) throws Exception
|
||||||
|
{
|
||||||
|
if ("env-entry".equals(element))
|
||||||
|
{
|
||||||
|
initEnvEntry (node);
|
||||||
|
}
|
||||||
|
else if ("resource-ref".equals(element))
|
||||||
|
{
|
||||||
|
//resource-ref entries are ONLY for connection factories
|
||||||
|
//the resource-ref says how the app will reference the jndi lookup relative
|
||||||
|
//to java:comp/env, but it is up to the deployer to map this reference to
|
||||||
|
//a real resource in the environment. At the moment, we insist that the
|
||||||
|
//jetty.xml file name of the resource has to be exactly the same as the
|
||||||
|
//name in web.xml deployment descriptor, but it shouldn't have to be
|
||||||
|
initResourceRef(node);
|
||||||
|
}
|
||||||
|
else if ("resource-env-ref".equals(element))
|
||||||
|
{
|
||||||
|
//resource-env-ref elements are a non-connection factory type of resource
|
||||||
|
//the app looks them up relative to java:comp/env
|
||||||
|
//again, need a way for deployer to link up app naming to real naming.
|
||||||
|
//Again, we insist now that the name of the resource in jetty.xml is
|
||||||
|
//the same as web.xml
|
||||||
|
initResourceEnvRef(node);
|
||||||
|
}
|
||||||
|
else if ("message-destination-ref".equals(element))
|
||||||
|
{
|
||||||
|
initMessageDestinationRef(node);
|
||||||
|
}
|
||||||
|
else if ("post-construct".equals(element))
|
||||||
|
{
|
||||||
|
//post-construct is the name of a class and method to call after all
|
||||||
|
//resources have been setup but before the class is put into use
|
||||||
|
initPostConstruct(node);
|
||||||
|
}
|
||||||
|
else if ("pre-destroy".equals(element))
|
||||||
|
{
|
||||||
|
//pre-destroy is the name of a class and method to call just as
|
||||||
|
//the instance is being destroyed
|
||||||
|
initPreDestroy(node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* JavaEE 5.4.1.3
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param node
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
protected void initEnvEntry (XmlParser.Node node)
|
||||||
|
throws Exception
|
||||||
|
{
|
||||||
|
String name=node.getString("env-entry-name",false,true);
|
||||||
|
String type = node.getString("env-entry-type",false,true);
|
||||||
|
String valueStr = node.getString("env-entry-value",false,true);
|
||||||
|
|
||||||
|
//if there's no value there's no point in making a jndi entry
|
||||||
|
//nor processing injection entries
|
||||||
|
if (valueStr==null || valueStr.equals(""))
|
||||||
|
{
|
||||||
|
Log.warn("No value for env-entry-name "+name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//the javaee_5.xsd says that the env-entry-type is optional
|
||||||
|
//if there is an <injection> element, because you can get
|
||||||
|
//type from the element, but what to do if there is more
|
||||||
|
//than one <injection> element, do you just pick the type
|
||||||
|
//of the first one?
|
||||||
|
|
||||||
|
//check for <injection> elements
|
||||||
|
initInjection (node, name, TypeUtil.fromName(type));
|
||||||
|
|
||||||
|
//bind the entry into jndi
|
||||||
|
Object value = TypeUtil.valueOf(type,valueStr);
|
||||||
|
bindEnvEntry(_context, name, value);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Common Annotations Spec section 2.3:
|
||||||
|
* resource-ref is for:
|
||||||
|
* - javax.sql.DataSource
|
||||||
|
* - javax.jms.ConnectionFactory
|
||||||
|
* - javax.jms.QueueConnectionFactory
|
||||||
|
* - javax.jms.TopicConnectionFactory
|
||||||
|
* - javax.mail.Session
|
||||||
|
* - java.net.URL
|
||||||
|
* - javax.resource.cci.ConnectionFactory
|
||||||
|
* - org.omg.CORBA_2_3.ORB
|
||||||
|
* - any other connection factory defined by a resource adapter
|
||||||
|
* @param node
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
protected void initResourceRef (XmlParser.Node node)
|
||||||
|
throws Exception
|
||||||
|
{
|
||||||
|
String jndiName = node.getString("res-ref-name",false,true);
|
||||||
|
String type = node.getString("res-type", false, true);
|
||||||
|
String auth = node.getString("res-auth", false, true);
|
||||||
|
String shared = node.getString("res-sharing-scope", false, true);
|
||||||
|
|
||||||
|
//check for <injection> elements
|
||||||
|
Class typeClass = TypeUtil.fromName(type);
|
||||||
|
if (typeClass==null)
|
||||||
|
typeClass = _context.loadClass(type);
|
||||||
|
initInjection (node, jndiName, typeClass);
|
||||||
|
|
||||||
|
bindResourceRef(_context, jndiName, typeClass);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Common Annotations Spec section 2.3:
|
||||||
|
* resource-env-ref is for:
|
||||||
|
* - javax.transaction.UserTransaction
|
||||||
|
* - javax.resource.cci.InteractionSpec
|
||||||
|
* - anything else that is not a connection factory
|
||||||
|
* @param node
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
protected void initResourceEnvRef (XmlParser.Node node)
|
||||||
|
throws Exception
|
||||||
|
{
|
||||||
|
String jndiName = node.getString("resource-env-ref-name",false,true);
|
||||||
|
String type = node.getString("resource-env-ref-type", false, true);
|
||||||
|
|
||||||
|
//check for <injection> elements
|
||||||
|
|
||||||
|
//JavaEE Spec sec 5.7.1.3 says the resource-env-ref-type
|
||||||
|
//is mandatory, but the schema says it is optional!
|
||||||
|
Class typeClass = TypeUtil.fromName(type);
|
||||||
|
if (typeClass==null)
|
||||||
|
typeClass = _context.loadClass(type);
|
||||||
|
initInjection (node, jndiName, typeClass);
|
||||||
|
|
||||||
|
bindResourceEnvRef(_context, jndiName, typeClass);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Common Annotations Spec section 2.3:
|
||||||
|
* message-destination-ref is for:
|
||||||
|
* - javax.jms.Queue
|
||||||
|
* - javax.jms.Topic
|
||||||
|
* @param node
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
protected void initMessageDestinationRef (XmlParser.Node node)
|
||||||
|
throws Exception
|
||||||
|
{
|
||||||
|
String jndiName = node.getString("message-destination-ref-name",false,true);
|
||||||
|
String type = node.getString("message-destination-type",false,true);
|
||||||
|
String usage = node.getString("message-destination-usage",false,true);
|
||||||
|
|
||||||
|
Class typeClass = TypeUtil.fromName(type);
|
||||||
|
if (typeClass==null)
|
||||||
|
typeClass = _context.loadClass(type);
|
||||||
|
initInjection(node, jndiName, typeClass);
|
||||||
|
|
||||||
|
bindMessageDestinationRef(_context, jndiName, typeClass);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process <post-construct>
|
||||||
|
* @param node
|
||||||
|
*/
|
||||||
|
protected void initPostConstruct(XmlParser.Node node)
|
||||||
|
{
|
||||||
|
String className = node.getString("lifecycle-callback-class", false, true);
|
||||||
|
String methodName = node.getString("lifecycle-callback-method", false, true);
|
||||||
|
|
||||||
|
if (className==null || className.equals(""))
|
||||||
|
{
|
||||||
|
Log.warn("No lifecycle-callback-class specified");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (methodName==null || methodName.equals(""))
|
||||||
|
{
|
||||||
|
Log.warn("No lifecycle-callback-method specified for class "+className);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Class clazz = _context.loadClass(className);
|
||||||
|
LifeCycleCallback callback = new PostConstructCallback();
|
||||||
|
callback.setTarget(clazz, methodName);
|
||||||
|
_callbacks.add(callback);
|
||||||
|
}
|
||||||
|
catch (ClassNotFoundException e)
|
||||||
|
{
|
||||||
|
Log.warn("Couldn't load post-construct target class "+className);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process <pre-destroy>
|
||||||
|
* @param node
|
||||||
|
*/
|
||||||
|
protected void initPreDestroy(XmlParser.Node node)
|
||||||
|
{
|
||||||
|
String className = node.getString("lifecycle-callback-class", false, true);
|
||||||
|
String methodName = node.getString("lifecycle-callback-method", false, true);
|
||||||
|
if (className==null || className.equals(""))
|
||||||
|
{
|
||||||
|
Log.warn("No lifecycle-callback-class specified for pre-destroy");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (methodName==null || methodName.equals(""))
|
||||||
|
{
|
||||||
|
Log.warn("No lifecycle-callback-method specified for pre-destroy class "+className);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Class clazz = _context.loadClass(className);
|
||||||
|
LifeCycleCallback callback = new PreDestroyCallback();
|
||||||
|
callback.setTarget(clazz, methodName);
|
||||||
|
_callbacks.add(callback);
|
||||||
|
}
|
||||||
|
catch (ClassNotFoundException e)
|
||||||
|
{
|
||||||
|
Log.warn("Couldn't load pre-destory target class "+className);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Iterate over the <injection-target> entries for a node
|
||||||
|
*
|
||||||
|
* @param node
|
||||||
|
* @param jndiName
|
||||||
|
* @param valueClass
|
||||||
|
* @return the type of the injectable
|
||||||
|
*/
|
||||||
|
protected void initInjection (XmlParser.Node node, String jndiName, Class valueClass)
|
||||||
|
{
|
||||||
|
Iterator itor = node.iterator("injection-target");
|
||||||
|
|
||||||
|
while(itor.hasNext())
|
||||||
|
{
|
||||||
|
XmlParser.Node injectionNode = (XmlParser.Node)itor.next();
|
||||||
|
String targetClassName = injectionNode.getString("injection-target-class", false, true);
|
||||||
|
String targetName = injectionNode.getString("injection-target-name", false, true);
|
||||||
|
if ((targetClassName==null) || targetClassName.equals(""))
|
||||||
|
{
|
||||||
|
Log.warn("No classname found in injection-target");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ((targetName==null) || targetName.equals(""))
|
||||||
|
{
|
||||||
|
Log.warn("No field or method name in injection-target");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// comments in the javaee_5.xsd file specify that the targetName is looked
|
||||||
|
// for first as a java bean property, then if that fails, as a field
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Class clazz = _context.loadClass(targetClassName);
|
||||||
|
Injection injection = new Injection();
|
||||||
|
injection.setTargetClass(clazz);
|
||||||
|
injection.setJndiName(jndiName);
|
||||||
|
injection.setTarget(clazz, targetName, valueClass);
|
||||||
|
_injections.add(injection);
|
||||||
|
}
|
||||||
|
catch (ClassNotFoundException e)
|
||||||
|
{
|
||||||
|
Log.warn("Couldn't load injection target class "+targetClassName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public abstract void bindMessageDestinationRef (String name, Class type) throws Exception;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -68,388 +396,82 @@ public abstract class AbstractConfiguration extends WebXmlConfiguration
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public void setWebAppContext (WebAppContext context)
|
public void preConfigure (WebAppContext context)
|
||||||
|
throws Exception
|
||||||
{
|
{
|
||||||
super.setWebAppContext(context);
|
//set up our special ServletHandler to remember injections and lifecycle callbacks
|
||||||
|
|
||||||
//set up our special ServletHandler to remember injections and lifecycle callbacks
|
|
||||||
ServletHandler servletHandler = new ServletHandler();
|
ServletHandler servletHandler = new ServletHandler();
|
||||||
_securityHandler = getWebAppContext().getSecurityHandler();
|
_securityHandler = context.getSecurityHandler();
|
||||||
org.eclipse.jetty.servlet.ServletHandler existingHandler = getWebAppContext().getServletHandler();
|
org.eclipse.jetty.servlet.ServletHandler existingHandler = context.getServletHandler();
|
||||||
servletHandler.setFilterMappings(existingHandler.getFilterMappings());
|
servletHandler.setFilterMappings(existingHandler.getFilterMappings());
|
||||||
servletHandler.setFilters(existingHandler.getFilters());
|
servletHandler.setFilters(existingHandler.getFilters());
|
||||||
servletHandler.setServlets(existingHandler.getServlets());
|
servletHandler.setServlets(existingHandler.getServlets());
|
||||||
servletHandler.setServletMappings(existingHandler.getServletMappings());
|
servletHandler.setServletMappings(existingHandler.getServletMappings());
|
||||||
getWebAppContext().setServletHandler(servletHandler);
|
context.setServletHandler(servletHandler);
|
||||||
_securityHandler.setHandler(servletHandler);
|
_securityHandler.setHandler(servletHandler);
|
||||||
}
|
|
||||||
|
|
||||||
public void configureDefaults ()
|
|
||||||
throws Exception
|
|
||||||
{
|
|
||||||
super.configureDefaults();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void configureWebApp ()
|
public void configure (WebAppContext context)
|
||||||
throws Exception
|
throws Exception
|
||||||
{
|
{
|
||||||
super.configureWebApp();
|
bindUserTransaction(context);
|
||||||
bindUserTransaction();
|
|
||||||
|
WebXmlProcessor webXmlProcessor = (WebXmlProcessor)context.getAttribute(WebXmlProcessor.__web_processor);
|
||||||
|
if (webXmlProcessor == null)
|
||||||
|
throw new IllegalStateException ("No processor for web xml");
|
||||||
|
|
||||||
|
//parse classes for annotations, if necessary
|
||||||
|
if (!webXmlProcessor.isMetaDataComplete())
|
||||||
|
{
|
||||||
|
if (Log.isDebugEnabled()) Log.debug("Processing annotations");
|
||||||
|
parseAnnotations(context);
|
||||||
|
}
|
||||||
|
//TODO: When webdefaults.xml, web.xml, fragments and web-override.xml are merged into an effective web.xml this
|
||||||
|
//will change
|
||||||
|
PlusWebXmlProcessor plusProcessor = new PlusWebXmlProcessor(context);
|
||||||
|
plusProcessor.process(webXmlProcessor.getWebDefault());
|
||||||
|
plusProcessor.process(webXmlProcessor.getWebXml());
|
||||||
|
|
||||||
|
//TODO: can web-fragment contain resource-ref and injection-targets?
|
||||||
|
for (XmlParser.Node frag: webXmlProcessor.getFragments())
|
||||||
|
plusProcessor.process(frag);
|
||||||
|
|
||||||
|
plusProcessor.process(webXmlProcessor.getOverrideWeb());
|
||||||
|
|
||||||
|
|
||||||
|
//configure injections and callbacks to be called by the FilterHolder and ServletHolder
|
||||||
|
//when they lazily instantiate the Filter/Servlet.
|
||||||
|
((ServletHandler)context.getServletHandler()).setInjections(_injections);
|
||||||
|
((ServletHandler)context.getServletHandler()).setCallbacks(_callbacks);
|
||||||
|
|
||||||
|
//do any injects on the listeners that were created and then
|
||||||
|
//also callback any postConstruct lifecycle methods
|
||||||
|
injectAndCallPostConstructCallbacks(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void deconfigureWebApp()
|
public void deconfigure (WebAppContext context)
|
||||||
throws Exception
|
throws Exception
|
||||||
{
|
{
|
||||||
//call any preDestroy methods on the listeners
|
//call any preDestroy methods on the listeners
|
||||||
callPreDestroyCallbacks();
|
callPreDestroyCallbacks(context);
|
||||||
|
|
||||||
super.deconfigureWebApp();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void configure(String webXml)
|
|
||||||
throws Exception
|
|
||||||
{
|
|
||||||
//parse web.xml
|
|
||||||
super.configure(webXml);
|
|
||||||
|
|
||||||
//parse classes for annotations, if necessary
|
|
||||||
if (!_metaDataComplete)
|
|
||||||
{
|
|
||||||
if (Log.isDebugEnabled()) Log.debug("Processing annotations");
|
|
||||||
parseAnnotations();
|
|
||||||
}
|
|
||||||
//do any injects on the listeners that were created and then
|
|
||||||
//also callback any postConstruct lifecycle methods
|
|
||||||
injectAndCallPostConstructCallbacks();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
protected void initialize(XmlParser.Node config)
|
protected void injectAndCallPostConstructCallbacks(WebAppContext context)
|
||||||
throws ClassNotFoundException,UnavailableException
|
|
||||||
{
|
|
||||||
super.initialize(config);
|
|
||||||
|
|
||||||
//configure injections and callbacks to be called by the FilterHolder and ServletHolder
|
|
||||||
//when they lazily instantiate the Filter/Servlet.
|
|
||||||
((ServletHandler)getWebAppContext().getServletHandler()).setInjections(_injections);
|
|
||||||
((ServletHandler)getWebAppContext().getServletHandler()).setCallbacks(_callbacks);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
protected void initWebXmlElement(String element,XmlParser.Node node) throws Exception
|
|
||||||
{
|
|
||||||
if ("env-entry".equals(element))
|
|
||||||
{
|
|
||||||
initEnvEntry (node);
|
|
||||||
}
|
|
||||||
else if ("resource-ref".equals(element))
|
|
||||||
{
|
|
||||||
//resource-ref entries are ONLY for connection factories
|
|
||||||
//the resource-ref says how the app will reference the jndi lookup relative
|
|
||||||
//to java:comp/env, but it is up to the deployer to map this reference to
|
|
||||||
//a real resource in the environment. At the moment, we insist that the
|
|
||||||
//jetty.xml file name of the resource has to be exactly the same as the
|
|
||||||
//name in web.xml deployment descriptor, but it shouldn't have to be
|
|
||||||
initResourceRef(node);
|
|
||||||
}
|
|
||||||
else if ("resource-env-ref".equals(element))
|
|
||||||
{
|
|
||||||
//resource-env-ref elements are a non-connection factory type of resource
|
|
||||||
//the app looks them up relative to java:comp/env
|
|
||||||
//again, need a way for deployer to link up app naming to real naming.
|
|
||||||
//Again, we insist now that the name of the resource in jetty.xml is
|
|
||||||
//the same as web.xml
|
|
||||||
initResourceEnvRef(node);
|
|
||||||
}
|
|
||||||
else if ("message-destination-ref".equals(element))
|
|
||||||
{
|
|
||||||
initMessageDestinationRef(node);
|
|
||||||
}
|
|
||||||
else if ("post-construct".equals(element))
|
|
||||||
{
|
|
||||||
//post-construct is the name of a class and method to call after all
|
|
||||||
//resources have been setup but before the class is put into use
|
|
||||||
initPostConstruct(node);
|
|
||||||
}
|
|
||||||
else if ("pre-destroy".equals(element))
|
|
||||||
{
|
|
||||||
//pre-destroy is the name of a class and method to call just as
|
|
||||||
//the instance is being destroyed
|
|
||||||
initPreDestroy(node);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
super.initWebXmlElement(element, node);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* JavaEE 5.4.1.3
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param node
|
|
||||||
* @throws Exception
|
|
||||||
*/
|
|
||||||
protected void initEnvEntry (XmlParser.Node node)
|
|
||||||
throws Exception
|
|
||||||
{
|
|
||||||
String name=node.getString("env-entry-name",false,true);
|
|
||||||
String type = node.getString("env-entry-type",false,true);
|
|
||||||
String valueStr = node.getString("env-entry-value",false,true);
|
|
||||||
|
|
||||||
//if there's no value there's no point in making a jndi entry
|
|
||||||
//nor processing injection entries
|
|
||||||
if (valueStr==null || valueStr.equals(""))
|
|
||||||
{
|
|
||||||
Log.warn("No value for env-entry-name "+name);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//the javaee_5.xsd says that the env-entry-type is optional
|
|
||||||
//if there is an <injection> element, because you can get
|
|
||||||
//type from the element, but what to do if there is more
|
|
||||||
//than one <injection> element, do you just pick the type
|
|
||||||
//of the first one?
|
|
||||||
|
|
||||||
//check for <injection> elements
|
|
||||||
initInjection (node, name, TypeUtil.fromName(type));
|
|
||||||
|
|
||||||
//bind the entry into jndi
|
|
||||||
Object value = TypeUtil.valueOf(type,valueStr);
|
|
||||||
bindEnvEntry(name, value);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Common Annotations Spec section 2.3:
|
|
||||||
* resource-ref is for:
|
|
||||||
* - javax.sql.DataSource
|
|
||||||
* - javax.jms.ConnectionFactory
|
|
||||||
* - javax.jms.QueueConnectionFactory
|
|
||||||
* - javax.jms.TopicConnectionFactory
|
|
||||||
* - javax.mail.Session
|
|
||||||
* - java.net.URL
|
|
||||||
* - javax.resource.cci.ConnectionFactory
|
|
||||||
* - org.omg.CORBA_2_3.ORB
|
|
||||||
* - any other connection factory defined by a resource adapter
|
|
||||||
* @param node
|
|
||||||
* @throws Exception
|
|
||||||
*/
|
|
||||||
protected void initResourceRef (XmlParser.Node node)
|
|
||||||
throws Exception
|
|
||||||
{
|
|
||||||
String jndiName = node.getString("res-ref-name",false,true);
|
|
||||||
String type = node.getString("res-type", false, true);
|
|
||||||
String auth = node.getString("res-auth", false, true);
|
|
||||||
String shared = node.getString("res-sharing-scope", false, true);
|
|
||||||
|
|
||||||
//check for <injection> elements
|
|
||||||
Class typeClass = TypeUtil.fromName(type);
|
|
||||||
if (typeClass==null)
|
|
||||||
typeClass = getWebAppContext().loadClass(type);
|
|
||||||
initInjection (node, jndiName, typeClass);
|
|
||||||
|
|
||||||
bindResourceRef(jndiName, typeClass);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Common Annotations Spec section 2.3:
|
|
||||||
* resource-env-ref is for:
|
|
||||||
* - javax.transaction.UserTransaction
|
|
||||||
* - javax.resource.cci.InteractionSpec
|
|
||||||
* - anything else that is not a connection factory
|
|
||||||
* @param node
|
|
||||||
* @throws Exception
|
|
||||||
*/
|
|
||||||
protected void initResourceEnvRef (XmlParser.Node node)
|
|
||||||
throws Exception
|
|
||||||
{
|
|
||||||
String jndiName = node.getString("resource-env-ref-name",false,true);
|
|
||||||
String type = node.getString("resource-env-ref-type", false, true);
|
|
||||||
|
|
||||||
//check for <injection> elements
|
|
||||||
|
|
||||||
//JavaEE Spec sec 5.7.1.3 says the resource-env-ref-type
|
|
||||||
//is mandatory, but the schema says it is optional!
|
|
||||||
Class typeClass = TypeUtil.fromName(type);
|
|
||||||
if (typeClass==null)
|
|
||||||
typeClass = getWebAppContext().loadClass(type);
|
|
||||||
initInjection (node, jndiName, typeClass);
|
|
||||||
|
|
||||||
bindResourceEnvRef(jndiName, typeClass);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Common Annotations Spec section 2.3:
|
|
||||||
* message-destination-ref is for:
|
|
||||||
* - javax.jms.Queue
|
|
||||||
* - javax.jms.Topic
|
|
||||||
* @param node
|
|
||||||
* @throws Exception
|
|
||||||
*/
|
|
||||||
protected void initMessageDestinationRef (XmlParser.Node node)
|
|
||||||
throws Exception
|
|
||||||
{
|
|
||||||
String jndiName = node.getString("message-destination-ref-name",false,true);
|
|
||||||
String type = node.getString("message-destination-type",false,true);
|
|
||||||
String usage = node.getString("message-destination-usage",false,true);
|
|
||||||
|
|
||||||
Class typeClass = TypeUtil.fromName(type);
|
|
||||||
if (typeClass==null)
|
|
||||||
typeClass = getWebAppContext().loadClass(type);
|
|
||||||
initInjection(node, jndiName, typeClass);
|
|
||||||
|
|
||||||
bindMessageDestinationRef(jndiName, typeClass);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Process <post-construct>
|
|
||||||
* @param node
|
|
||||||
*/
|
|
||||||
protected void initPostConstruct(XmlParser.Node node)
|
|
||||||
{
|
|
||||||
String className = node.getString("lifecycle-callback-class", false, true);
|
|
||||||
String methodName = node.getString("lifecycle-callback-method", false, true);
|
|
||||||
|
|
||||||
if (className==null || className.equals(""))
|
|
||||||
{
|
|
||||||
Log.warn("No lifecycle-callback-class specified");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (methodName==null || methodName.equals(""))
|
|
||||||
{
|
|
||||||
Log.warn("No lifecycle-callback-method specified for class "+className);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Class clazz = getWebAppContext().loadClass(className);
|
|
||||||
LifeCycleCallback callback = new PostConstructCallback();
|
|
||||||
callback.setTarget(clazz, methodName);
|
|
||||||
_callbacks.add(callback);
|
|
||||||
}
|
|
||||||
catch (ClassNotFoundException e)
|
|
||||||
{
|
|
||||||
Log.warn("Couldn't load post-construct target class "+className);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Process <pre-destroy>
|
|
||||||
* @param node
|
|
||||||
*/
|
|
||||||
protected void initPreDestroy(XmlParser.Node node)
|
|
||||||
{
|
|
||||||
String className = node.getString("lifecycle-callback-class", false, true);
|
|
||||||
String methodName = node.getString("lifecycle-callback-method", false, true);
|
|
||||||
if (className==null || className.equals(""))
|
|
||||||
{
|
|
||||||
Log.warn("No lifecycle-callback-class specified for pre-destroy");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (methodName==null || methodName.equals(""))
|
|
||||||
{
|
|
||||||
Log.warn("No lifecycle-callback-method specified for pre-destroy class "+className);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Class clazz = getWebAppContext().loadClass(className);
|
|
||||||
LifeCycleCallback callback = new PreDestroyCallback();
|
|
||||||
callback.setTarget(clazz, methodName);
|
|
||||||
_callbacks.add(callback);
|
|
||||||
}
|
|
||||||
catch (ClassNotFoundException e)
|
|
||||||
{
|
|
||||||
Log.warn("Couldn't load pre-destory target class "+className);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Iterate over the <injection-target> entries for a node
|
|
||||||
*
|
|
||||||
* @param node
|
|
||||||
* @param jndiName
|
|
||||||
* @param valueClass
|
|
||||||
* @return the type of the injectable
|
|
||||||
*/
|
|
||||||
protected void initInjection (XmlParser.Node node, String jndiName, Class valueClass)
|
|
||||||
{
|
|
||||||
Iterator itor = node.iterator("injection-target");
|
|
||||||
|
|
||||||
while(itor.hasNext())
|
|
||||||
{
|
|
||||||
XmlParser.Node injectionNode = (XmlParser.Node)itor.next();
|
|
||||||
String targetClassName = injectionNode.getString("injection-target-class", false, true);
|
|
||||||
String targetName = injectionNode.getString("injection-target-name", false, true);
|
|
||||||
if ((targetClassName==null) || targetClassName.equals(""))
|
|
||||||
{
|
|
||||||
Log.warn("No classname found in injection-target");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if ((targetName==null) || targetName.equals(""))
|
|
||||||
{
|
|
||||||
Log.warn("No field or method name in injection-target");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// comments in the javaee_5.xsd file specify that the targetName is looked
|
|
||||||
// for first as a java bean property, then if that fails, as a field
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Class clazz = getWebAppContext().loadClass(targetClassName);
|
|
||||||
Injection injection = new Injection();
|
|
||||||
injection.setTargetClass(clazz);
|
|
||||||
injection.setJndiName(jndiName);
|
|
||||||
injection.setTarget(clazz, targetName, valueClass);
|
|
||||||
_injections.add(injection);
|
|
||||||
}
|
|
||||||
catch (ClassNotFoundException e)
|
|
||||||
{
|
|
||||||
Log.warn("Couldn't load injection target class "+targetClassName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parse all classes that are mentioned in web.xml (servlets, filters, listeners)
|
|
||||||
* for annotations.
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @throws Exception
|
|
||||||
*/
|
|
||||||
protected abstract void parseAnnotations () throws Exception;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
protected void injectAndCallPostConstructCallbacks()
|
|
||||||
throws Exception
|
throws Exception
|
||||||
{
|
{
|
||||||
//look thru the servlets to apply any runAs annotations
|
//look thru the servlets to apply any runAs annotations
|
||||||
//NOTE: that any run-as in web.xml will already have been applied
|
//NOTE: that any run-as in web.xml will already have been applied
|
||||||
ServletHolder[] holders = getWebAppContext().getServletHandler().getServlets();
|
ServletHolder[] holders = context.getServletHandler().getServlets();
|
||||||
for (int i=0;holders!=null && i<holders.length;i++)
|
for (int i=0;holders!=null && i<holders.length;i++)
|
||||||
{
|
{
|
||||||
_runAsCollection.setRunAs(holders[i], _securityHandler);
|
_runAsCollection.setRunAs(holders[i], _securityHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
EventListener[] listeners = getWebAppContext().getEventListeners();
|
EventListener[] listeners = context.getEventListeners();
|
||||||
for (int i=0;listeners!=null && i<listeners.length;i++)
|
for (int i=0;listeners!=null && i<listeners.length;i++)
|
||||||
{
|
{
|
||||||
_injections.inject(listeners[i]);
|
_injections.inject(listeners[i]);
|
||||||
|
@ -458,10 +480,10 @@ public abstract class AbstractConfiguration extends WebXmlConfiguration
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected void callPreDestroyCallbacks ()
|
protected void callPreDestroyCallbacks (WebAppContext context)
|
||||||
throws Exception
|
throws Exception
|
||||||
{
|
{
|
||||||
EventListener[] listeners = getWebAppContext().getEventListeners();
|
EventListener[] listeners = context.getEventListeners();
|
||||||
for (int i=0; listeners!=null && i<listeners.length;i++)
|
for (int i=0; listeners!=null && i<listeners.length;i++)
|
||||||
{
|
{
|
||||||
_callbacks.callPreDestroyCallback(listeners[i]);
|
_callbacks.callPreDestroyCallback(listeners[i]);
|
||||||
|
|
|
@ -26,6 +26,7 @@ import org.eclipse.jetty.plus.jndi.NamingEntry;
|
||||||
import org.eclipse.jetty.plus.jndi.NamingEntryUtil;
|
import org.eclipse.jetty.plus.jndi.NamingEntryUtil;
|
||||||
import org.eclipse.jetty.plus.jndi.Transaction;
|
import org.eclipse.jetty.plus.jndi.Transaction;
|
||||||
import org.eclipse.jetty.util.log.Log;
|
import org.eclipse.jetty.util.log.Log;
|
||||||
|
import org.eclipse.jetty.webapp.WebAppContext;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -50,7 +51,7 @@ public class Configuration extends AbstractConfiguration
|
||||||
* @param value
|
* @param value
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public void bindEnvEntry(String name, Object value) throws Exception
|
public void bindEnvEntry(WebAppContext context, String name, Object value) throws Exception
|
||||||
{
|
{
|
||||||
InitialContext ic = null;
|
InitialContext ic = null;
|
||||||
boolean bound = false;
|
boolean bound = false;
|
||||||
|
@ -90,10 +91,10 @@ public class Configuration extends AbstractConfiguration
|
||||||
* @param name
|
* @param name
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public void bindResourceRef(String name, Class typeClass)
|
public void bindResourceRef(WebAppContext context, String name, Class typeClass)
|
||||||
throws Exception
|
throws Exception
|
||||||
{
|
{
|
||||||
bindEntry(name, typeClass);
|
bindEntry(context, name, typeClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -101,20 +102,20 @@ public class Configuration extends AbstractConfiguration
|
||||||
* @param name
|
* @param name
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public void bindResourceEnvRef(String name, Class typeClass)
|
public void bindResourceEnvRef(WebAppContext context, String name, Class typeClass)
|
||||||
throws Exception
|
throws Exception
|
||||||
{
|
{
|
||||||
bindEntry(name, typeClass);
|
bindEntry(context, name, typeClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void bindMessageDestinationRef(String name, Class typeClass)
|
public void bindMessageDestinationRef(WebAppContext context, String name, Class typeClass)
|
||||||
throws Exception
|
throws Exception
|
||||||
{
|
{
|
||||||
bindEntry(name, typeClass);
|
bindEntry(context, name, typeClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void bindUserTransaction ()
|
public void bindUserTransaction (WebAppContext context)
|
||||||
throws Exception
|
throws Exception
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
@ -127,38 +128,38 @@ public class Configuration extends AbstractConfiguration
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void configureClassLoader ()
|
public void preConfigure (WebAppContext context)
|
||||||
throws Exception
|
throws Exception
|
||||||
{
|
{
|
||||||
super.configureClassLoader();
|
super.preConfigure(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public void configure (WebAppContext context)
|
||||||
|
throws Exception
|
||||||
|
{
|
||||||
|
super.configure (context);
|
||||||
|
}
|
||||||
|
|
||||||
public void configureDefaults ()
|
public void postConfigure (WebAppContext context)
|
||||||
throws Exception
|
throws Exception
|
||||||
{
|
{
|
||||||
super.configureDefaults();
|
//lock this webapp's java:comp namespace as per J2EE spec
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void configureWebApp ()
|
|
||||||
throws Exception
|
|
||||||
{
|
|
||||||
super.configureWebApp();
|
|
||||||
//lock this webapp's java:comp namespace as per J2EE spec
|
|
||||||
ClassLoader oldLoader = Thread.currentThread().getContextClassLoader();
|
ClassLoader oldLoader = Thread.currentThread().getContextClassLoader();
|
||||||
Thread.currentThread().setContextClassLoader(getWebAppContext().getClassLoader());
|
Thread.currentThread().setContextClassLoader(context.getClassLoader());
|
||||||
lockCompEnv();
|
lockCompEnv();
|
||||||
Thread.currentThread().setContextClassLoader(oldLoader);
|
Thread.currentThread().setContextClassLoader(oldLoader);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void deconfigureWebApp() throws Exception
|
public void deconfigure (WebAppContext context) throws Exception
|
||||||
{
|
{
|
||||||
ClassLoader oldLoader = Thread.currentThread().getContextClassLoader();
|
ClassLoader oldLoader = Thread.currentThread().getContextClassLoader();
|
||||||
Thread.currentThread().setContextClassLoader(getWebAppContext().getClassLoader());
|
Thread.currentThread().setContextClassLoader(context.getClassLoader());
|
||||||
unlockCompEnv();
|
unlockCompEnv();
|
||||||
|
_key = null;
|
||||||
Thread.currentThread().setContextClassLoader(oldLoader);
|
Thread.currentThread().setContextClassLoader(oldLoader);
|
||||||
super.deconfigureWebApp();
|
super.deconfigure (context);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void lockCompEnv ()
|
protected void lockCompEnv ()
|
||||||
|
@ -185,7 +186,7 @@ public class Configuration extends AbstractConfiguration
|
||||||
/**
|
/**
|
||||||
* @see org.eclipse.jetty.plus.webapp.AbstractConfiguration#parseAnnotations()
|
* @see org.eclipse.jetty.plus.webapp.AbstractConfiguration#parseAnnotations()
|
||||||
*/
|
*/
|
||||||
public void parseAnnotations() throws Exception
|
public void parseAnnotations(WebAppContext context) throws Exception
|
||||||
{
|
{
|
||||||
//see org.eclipse.jetty.annotations.Configuration instead
|
//see org.eclipse.jetty.annotations.Configuration instead
|
||||||
}
|
}
|
||||||
|
@ -205,7 +206,7 @@ public class Configuration extends AbstractConfiguration
|
||||||
* @param typeClass
|
* @param typeClass
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
private void bindEntry (String name, Class typeClass)
|
private void bindEntry (WebAppContext context, String name, Class typeClass)
|
||||||
throws Exception
|
throws Exception
|
||||||
{
|
{
|
||||||
String nameInEnvironment = name;
|
String nameInEnvironment = name;
|
||||||
|
@ -213,7 +214,7 @@ public class Configuration extends AbstractConfiguration
|
||||||
|
|
||||||
//check if the name in web.xml has been mapped to something else
|
//check if the name in web.xml has been mapped to something else
|
||||||
//check a context-specific naming environment first
|
//check a context-specific naming environment first
|
||||||
Object scope = getWebAppContext();
|
Object scope = context;
|
||||||
NamingEntry ne = NamingEntryUtil.lookupNamingEntry(scope, name);
|
NamingEntry ne = NamingEntryUtil.lookupNamingEntry(scope, name);
|
||||||
|
|
||||||
if (ne!=null && (ne instanceof Link))
|
if (ne!=null && (ne instanceof Link))
|
||||||
|
@ -221,33 +222,38 @@ public class Configuration extends AbstractConfiguration
|
||||||
//if we found a mapping, get out name it is mapped to in the environment
|
//if we found a mapping, get out name it is mapped to in the environment
|
||||||
nameInEnvironment = (String)((Link)ne).getObjectToBind();
|
nameInEnvironment = (String)((Link)ne).getObjectToBind();
|
||||||
Link l = (Link)ne;
|
Link l = (Link)ne;
|
||||||
|
System.err.println("Link, with nameInEnvironment="+nameInEnvironment);
|
||||||
}
|
}
|
||||||
|
|
||||||
//try finding that mapped name in the webapp's environment first
|
//try finding that mapped name in the webapp's environment first
|
||||||
scope = getWebAppContext();
|
System.err.println("Trying to find "+nameInEnvironment+" in webapp scope");
|
||||||
|
scope = context;
|
||||||
bound = NamingEntryUtil.bindToENC(scope, name, nameInEnvironment);
|
bound = NamingEntryUtil.bindToENC(scope, name, nameInEnvironment);
|
||||||
|
|
||||||
if (bound)
|
if (bound)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
System.err.println("Trying to find "+nameInEnvironment+" in server scope");
|
||||||
//try the server's environment
|
//try the server's environment
|
||||||
scope = getWebAppContext().getServer();
|
scope = context.getServer();
|
||||||
bound = NamingEntryUtil.bindToENC(scope, name, nameInEnvironment);
|
bound = NamingEntryUtil.bindToENC(scope, name, nameInEnvironment);
|
||||||
if (bound)
|
if (bound)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
System.err.println("Trying to find "+nameInEnvironment+" in jvm scope");
|
||||||
//try the jvm environment
|
//try the jvm environment
|
||||||
bound = NamingEntryUtil.bindToENC(null, name, nameInEnvironment);
|
bound = NamingEntryUtil.bindToENC(null, name, nameInEnvironment);
|
||||||
if (bound)
|
if (bound)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
||||||
|
System.err.println("Didn't find "+nameInEnvironment+" anywhere - looking for "+typeClass.getName()+"/default in server or jvm scope");
|
||||||
//There is no matching resource so try a default name.
|
//There is no matching resource so try a default name.
|
||||||
//The default name syntax is: the [res-type]/default
|
//The default name syntax is: the [res-type]/default
|
||||||
//eg javax.sql.DataSource/default
|
//eg javax.sql.DataSource/default
|
||||||
nameInEnvironment = typeClass.getName()+"/default";
|
nameInEnvironment = typeClass.getName()+"/default";
|
||||||
//First try the server scope
|
//First try the server scope
|
||||||
NamingEntry defaultNE = NamingEntryUtil.lookupNamingEntry(getWebAppContext().getServer(), nameInEnvironment);
|
NamingEntry defaultNE = NamingEntryUtil.lookupNamingEntry(context.getServer(), nameInEnvironment);
|
||||||
if (defaultNE==null)
|
if (defaultNE==null)
|
||||||
defaultNE = NamingEntryUtil.lookupNamingEntry(null, nameInEnvironment);
|
defaultNE = NamingEntryUtil.lookupNamingEntry(null, nameInEnvironment);
|
||||||
|
|
||||||
|
|
|
@ -40,67 +40,37 @@ import org.eclipse.jetty.xml.XmlConfiguration;
|
||||||
*/
|
*/
|
||||||
public class EnvConfiguration implements Configuration
|
public class EnvConfiguration implements Configuration
|
||||||
{
|
{
|
||||||
private WebAppContext webAppContext;
|
|
||||||
private Context compCtx;
|
private Context compCtx;
|
||||||
private Context envCtx;
|
private Context envCtx;
|
||||||
private URL jettyEnvXmlUrl;
|
private URL jettyEnvXmlUrl;
|
||||||
|
|
||||||
protected void createEnvContext ()
|
|
||||||
throws NamingException
|
|
||||||
{
|
|
||||||
Context context = new InitialContext();
|
|
||||||
compCtx = (Context)context.lookup ("java:comp");
|
|
||||||
envCtx = compCtx.createSubcontext("env");
|
|
||||||
if (Log.isDebugEnabled())
|
|
||||||
Log.debug("Created java:comp/env for webapp "+getWebAppContext().getContextPath());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @see org.eclipse.jetty.webapp.Configuration#setWebAppContext(org.eclipse.jetty.webapp.WebAppContext)
|
|
||||||
* @param context
|
|
||||||
*/
|
|
||||||
public void setWebAppContext(WebAppContext context)
|
|
||||||
{
|
|
||||||
this.webAppContext = context;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setJettyEnvXml (URL url)
|
public void setJettyEnvXml (URL url)
|
||||||
{
|
{
|
||||||
this.jettyEnvXmlUrl = url;
|
this.jettyEnvXmlUrl = url;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @see org.eclipse.jetty.webapp.Configuration#getWebAppContext()
|
|
||||||
*/
|
|
||||||
public WebAppContext getWebAppContext()
|
|
||||||
{
|
|
||||||
return webAppContext;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @see org.eclipse.jetty.webapp.Configuration#configureClassLoader()
|
|
||||||
* @throws Exception
|
|
||||||
*/
|
|
||||||
public void configureClassLoader() throws Exception
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see org.eclipse.jetty.webapp.Configuration#configureDefaults()
|
* @see org.eclipse.jetty.webapp.Configuration#configureDefaults()
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public void configureDefaults() throws Exception
|
public void preConfigure (WebAppContext context) throws Exception
|
||||||
{
|
{
|
||||||
//create a java:comp/env
|
//create a java:comp/env
|
||||||
createEnvContext();
|
createEnvContext();
|
||||||
|
if (Log.isDebugEnabled())
|
||||||
|
Log.debug("Created java:comp/env for webapp "+context.getContextPath());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see org.eclipse.jetty.webapp.Configuration#configureWebApp()
|
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public void configureWebApp() throws Exception
|
public void configure (WebAppContext context) throws Exception
|
||||||
{
|
{
|
||||||
//check to see if an explicit file has been set, if not,
|
//check to see if an explicit file has been set, if not,
|
||||||
//look in WEB-INF/jetty-env.xml
|
//look in WEB-INF/jetty-env.xml
|
||||||
|
@ -109,7 +79,7 @@ public class EnvConfiguration implements Configuration
|
||||||
|
|
||||||
//look for a file called WEB-INF/jetty-env.xml
|
//look for a file called WEB-INF/jetty-env.xml
|
||||||
//and process it if it exists
|
//and process it if it exists
|
||||||
org.eclipse.jetty.util.resource.Resource web_inf = getWebAppContext().getWebInf();
|
org.eclipse.jetty.util.resource.Resource web_inf = context.getWebInf();
|
||||||
if(web_inf!=null && web_inf.isDirectory())
|
if(web_inf!=null && web_inf.isDirectory())
|
||||||
{
|
{
|
||||||
org.eclipse.jetty.util.resource.Resource jettyEnv = web_inf.addPath("jetty-env.xml");
|
org.eclipse.jetty.util.resource.Resource jettyEnv = web_inf.addPath("jetty-env.xml");
|
||||||
|
@ -119,38 +89,48 @@ public class EnvConfiguration implements Configuration
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//apply the jetty-env.xml file
|
||||||
if (jettyEnvXmlUrl != null)
|
if (jettyEnvXmlUrl != null)
|
||||||
{
|
{
|
||||||
|
System.err.println("Applying "+jettyEnvXmlUrl);
|
||||||
XmlConfiguration configuration = new XmlConfiguration(jettyEnvXmlUrl);
|
XmlConfiguration configuration = new XmlConfiguration(jettyEnvXmlUrl);
|
||||||
configuration.configure(getWebAppContext());
|
configuration.configure(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
//add java:comp/env entries for any EnvEntries that have been defined so far
|
//add java:comp/env entries for any EnvEntries that have been defined so far
|
||||||
bindEnvEntries();
|
bindEnvEntries(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void postConfigure(WebAppContext context) throws Exception
|
||||||
|
{
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove all jndi setup
|
* Remove all jndi setup
|
||||||
* @see org.eclipse.jetty.webapp.Configuration#deconfigureWebApp()
|
* @see org.eclipse.jetty.webapp.Configuration#deconfigureWebApp()
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public void deconfigureWebApp() throws Exception
|
public void deconfigure (WebAppContext context) throws Exception
|
||||||
{
|
{
|
||||||
//get rid of any bindings for comp/env for webapp
|
//get rid of any bindings for comp/env for webapp
|
||||||
ClassLoader oldLoader = Thread.currentThread().getContextClassLoader();
|
ClassLoader oldLoader = Thread.currentThread().getContextClassLoader();
|
||||||
Thread.currentThread().setContextClassLoader(webAppContext.getClassLoader());
|
Thread.currentThread().setContextClassLoader(context.getClassLoader());
|
||||||
compCtx.destroySubcontext("env");
|
compCtx.destroySubcontext("env");
|
||||||
|
|
||||||
//unbind any NamingEntries that were configured in this webapp's name space
|
//unbind any NamingEntries that were configured in this webapp's name space
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Context scopeContext = NamingEntryUtil.getContextForScope(getWebAppContext());
|
Context scopeContext = NamingEntryUtil.getContextForScope(context);
|
||||||
scopeContext.destroySubcontext(NamingEntry.__contextName);
|
scopeContext.destroySubcontext(NamingEntry.__contextName);
|
||||||
}
|
}
|
||||||
catch (NameNotFoundException e)
|
catch (NameNotFoundException e)
|
||||||
{
|
{
|
||||||
Log.ignore(e);
|
Log.ignore(e);
|
||||||
Log.debug("No naming entries configured in environment for webapp "+getWebAppContext());
|
Log.debug("No naming entries configured in environment for webapp "+context);
|
||||||
}
|
}
|
||||||
Thread.currentThread().setContextClassLoader(oldLoader);
|
Thread.currentThread().setContextClassLoader(oldLoader);
|
||||||
}
|
}
|
||||||
|
@ -162,7 +142,7 @@ public class EnvConfiguration implements Configuration
|
||||||
* We first bind EnvEntries declared in Server scope, then WebAppContext scope.
|
* We first bind EnvEntries declared in Server scope, then WebAppContext scope.
|
||||||
* @throws NamingException
|
* @throws NamingException
|
||||||
*/
|
*/
|
||||||
public void bindEnvEntries ()
|
public void bindEnvEntries (WebAppContext context)
|
||||||
throws NamingException
|
throws NamingException
|
||||||
{
|
{
|
||||||
Log.debug("Binding env entries from the jvm scope");
|
Log.debug("Binding env entries from the jvm scope");
|
||||||
|
@ -179,7 +159,7 @@ public class EnvConfiguration implements Configuration
|
||||||
|
|
||||||
Log.debug("Binding env entries from the server scope");
|
Log.debug("Binding env entries from the server scope");
|
||||||
|
|
||||||
scope = getWebAppContext().getServer();
|
scope = context.getServer();
|
||||||
list = NamingEntryUtil.lookupNamingEntries(scope, EnvEntry.class);
|
list = NamingEntryUtil.lookupNamingEntries(scope, EnvEntry.class);
|
||||||
itor = list.iterator();
|
itor = list.iterator();
|
||||||
while (itor.hasNext())
|
while (itor.hasNext())
|
||||||
|
@ -191,7 +171,7 @@ public class EnvConfiguration implements Configuration
|
||||||
}
|
}
|
||||||
|
|
||||||
Log.debug("Binding env entries from the context scope");
|
Log.debug("Binding env entries from the context scope");
|
||||||
scope = getWebAppContext();
|
scope = context;
|
||||||
list = NamingEntryUtil.lookupNamingEntries(scope, EnvEntry.class);
|
list = NamingEntryUtil.lookupNamingEntries(scope, EnvEntry.class);
|
||||||
itor = list.iterator();
|
itor = list.iterator();
|
||||||
while (itor.hasNext())
|
while (itor.hasNext())
|
||||||
|
@ -202,4 +182,12 @@ public class EnvConfiguration implements Configuration
|
||||||
NamingUtil.bind(envCtx, namingEntryName.toString(), ee);//also save the EnvEntry in the context so we can check it later
|
NamingUtil.bind(envCtx, namingEntryName.toString(), ee);//also save the EnvEntry in the context so we can check it later
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void createEnvContext ()
|
||||||
|
throws NamingException
|
||||||
|
{
|
||||||
|
Context context = new InitialContext();
|
||||||
|
compCtx = (Context)context.lookup ("java:comp");
|
||||||
|
envCtx = compCtx.createSubcontext("env");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,11 +67,11 @@ public class TestConfiguration extends TestCase
|
||||||
assertNotNull(NamingEntryUtil.lookupNamingEntry(wac, "zzz/e"));
|
assertNotNull(NamingEntryUtil.lookupNamingEntry(wac, "zzz/e"));
|
||||||
|
|
||||||
Configuration config = new Configuration();
|
Configuration config = new Configuration();
|
||||||
config.setWebAppContext(wac);
|
|
||||||
EnvConfiguration envConfig = new EnvConfiguration();
|
EnvConfiguration envConfig = new EnvConfiguration();
|
||||||
envConfig.setWebAppContext(wac);
|
|
||||||
envConfig.configureDefaults();
|
envConfig.preConfigure(wac);
|
||||||
envConfig.bindEnvEntries();
|
envConfig.bindEnvEntries(wac);
|
||||||
|
|
||||||
String val = (String)ic.lookup("java:comp/env/xxx/a");
|
String val = (String)ic.lookup("java:comp/env/xxx/a");
|
||||||
assertEquals("900", val); //webapp naming overrides server
|
assertEquals("900", val); //webapp naming overrides server
|
||||||
|
@ -95,20 +95,20 @@ public class TestConfiguration extends TestCase
|
||||||
ne = (NamingEntry)ic.lookup("java:comp/env/"+NamingEntry.__contextName+"/zzz/e");
|
ne = (NamingEntry)ic.lookup("java:comp/env/"+NamingEntry.__contextName+"/zzz/e");
|
||||||
assertNotNull(ne);
|
assertNotNull(ne);
|
||||||
|
|
||||||
config.bindEnvEntry("foo", "99");
|
config.bindEnvEntry(wac, "foo", "99");
|
||||||
assertEquals("99",ic.lookup( "java:comp/env/foo"));
|
assertEquals("99",ic.lookup( "java:comp/env/foo"));
|
||||||
|
|
||||||
config.bindEnvEntry("xxx/a", "7");
|
config.bindEnvEntry(wac, "xxx/a", "7");
|
||||||
assertEquals("900", ic.lookup("java:comp/env/xxx/a")); //webapp overrides web.xml
|
assertEquals("900", ic.lookup("java:comp/env/xxx/a")); //webapp overrides web.xml
|
||||||
config.bindEnvEntry("yyy/b", "7");
|
config.bindEnvEntry(wac, "yyy/b", "7");
|
||||||
assertEquals("910", ic.lookup("java:comp/env/yyy/b"));//webapp overrides web.xml
|
assertEquals("910", ic.lookup("java:comp/env/yyy/b"));//webapp overrides web.xml
|
||||||
config.bindEnvEntry("zzz/c", "7");
|
config.bindEnvEntry(wac,"zzz/c", "7");
|
||||||
assertEquals("7", ic.lookup("java:comp/env/zzz/c"));//webapp does NOT override web.xml
|
assertEquals("7", ic.lookup("java:comp/env/zzz/c"));//webapp does NOT override web.xml
|
||||||
config.bindEnvEntry("zzz/d", "7");
|
config.bindEnvEntry(wac,"zzz/d", "7");
|
||||||
assertEquals("7", ic.lookup("java:comp/env/zzz/d"));//server does NOT override web.xml
|
assertEquals("7", ic.lookup("java:comp/env/zzz/d"));//server does NOT override web.xml
|
||||||
config.bindEnvEntry("zzz/e", "7");
|
config.bindEnvEntry(wac,"zzz/e", "7");
|
||||||
assertEquals("7", ic.lookup("java:comp/env/zzz/e"));//webapp does NOT override web.xml
|
assertEquals("7", ic.lookup("java:comp/env/zzz/e"));//webapp does NOT override web.xml
|
||||||
config.bindEnvEntry("zzz/f", "7");
|
config.bindEnvEntry(wac,"zzz/f", "7");
|
||||||
assertEquals("500", ic.lookup("java:comp/env/zzz/f"));//server overrides web.xml
|
assertEquals("500", ic.lookup("java:comp/env/zzz/f"));//server overrides web.xml
|
||||||
|
|
||||||
((Context)ic.lookup("java:comp")).destroySubcontext("env");
|
((Context)ic.lookup("java:comp")).destroySubcontext("env");
|
||||||
|
|
|
@ -17,61 +17,39 @@ package org.eclipse.jetty.webapp;
|
||||||
/* ------------------------------------------------------------------------------- */
|
/* ------------------------------------------------------------------------------- */
|
||||||
/** Base Class for WebApplicationContext Configuration.
|
/** Base Class for WebApplicationContext Configuration.
|
||||||
* This class can be extended to customize or extend the configuration
|
* This class can be extended to customize or extend the configuration
|
||||||
* of the WebApplicationContext. If WebApplicationContext.setConfiguration is not
|
* of the WebApplicationContext.
|
||||||
* called, then an XMLConfiguration instance is created.
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public interface Configuration
|
public interface Configuration
|
||||||
{
|
{
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------------- */
|
/* ------------------------------------------------------------------------------- */
|
||||||
/** Set up a context on which to perform the configuration.
|
/** Set up for configuration.
|
||||||
* @param context
|
|
||||||
*/
|
|
||||||
public void setWebAppContext (WebAppContext context);
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------------- */
|
|
||||||
/** Get the context on which the configuration is performed.
|
|
||||||
*/
|
|
||||||
public WebAppContext getWebAppContext();
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------------- */
|
|
||||||
/** Configure ClassPath.
|
|
||||||
* This method is called to configure the context ClassLoader. It is called just
|
|
||||||
* after a new WebAppClassLoader is constructed and before it has been used.
|
|
||||||
* Class paths may be added, options changed or the loader totally replaced.
|
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public void configureClassLoader()
|
public void preConfigure (WebAppContext context) throws Exception;
|
||||||
throws Exception;
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------------- */
|
|
||||||
/** Configure Defaults.
|
|
||||||
* This method is called to intialize the context to the containers default configuration.
|
|
||||||
* Typically this would mean application of the webdefault.xml file.
|
|
||||||
* @throws Exception
|
|
||||||
*/
|
|
||||||
public void configureDefaults()
|
|
||||||
throws Exception;
|
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------------- */
|
/* ------------------------------------------------------------------------------- */
|
||||||
/** Configure WebApp.
|
/** Configure WebApp.
|
||||||
* This method is called to apply the standard and vendor deployment descriptors.
|
*
|
||||||
* Typically this is web.xml and jetty-web.xml.
|
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public void configureWebApp()
|
public void configure (WebAppContext context) throws Exception;
|
||||||
throws Exception;
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------------- */
|
||||||
|
/** Clear down after configuration.
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public void postConfigure (WebAppContext context) throws Exception;
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------------- */
|
/* ------------------------------------------------------------------------------- */
|
||||||
/** DeConfigure WebApp.
|
/** DeConfigure WebApp.
|
||||||
* This method is called to undo all configuration done to this webapphandler. This is
|
* This method is called to undo all configuration done. This is
|
||||||
* called to allow the context to work correctly over a stop/start cycle
|
* called to allow the context to work correctly over a stop/start cycle
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public void deconfigureWebApp()
|
public void deconfigure (WebAppContext context) throws Exception;
|
||||||
throws Exception;
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,125 @@
|
||||||
|
// ========================================================================
|
||||||
|
// Copyright (c) 2009 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.webapp;
|
||||||
|
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.jar.JarEntry;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import org.eclipse.jetty.util.log.Log;
|
||||||
|
import org.eclipse.jetty.util.resource.Resource;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* FragmentConfiguration
|
||||||
|
*
|
||||||
|
* Process web-fragments in jars
|
||||||
|
*/
|
||||||
|
public class FragmentConfiguration implements Configuration
|
||||||
|
{
|
||||||
|
public void preConfigure(WebAppContext context) throws Exception
|
||||||
|
{
|
||||||
|
WebXmlProcessor processor = (WebXmlProcessor)context.getAttribute(WebXmlProcessor.__web_processor);
|
||||||
|
if (processor == null)
|
||||||
|
{
|
||||||
|
processor = new WebXmlProcessor (context);
|
||||||
|
context.setAttribute(WebXmlProcessor.__web_processor, processor);
|
||||||
|
}
|
||||||
|
|
||||||
|
//parse web-fragment.xmls
|
||||||
|
parseWebFragments(context, processor);
|
||||||
|
|
||||||
|
//TODO for jetty-8/servletspec 3 we will need to merge the parsed web fragments into the
|
||||||
|
//effective pom in this preConfigure step
|
||||||
|
}
|
||||||
|
|
||||||
|
public void configure(WebAppContext context) throws Exception
|
||||||
|
{
|
||||||
|
//TODO for jetty-8/servletspec3 the fragments will not be separately processed here, but
|
||||||
|
//will be done by webXmlConfiguration when it processes the effective merged web.xml
|
||||||
|
WebXmlProcessor processor = (WebXmlProcessor)context.getAttribute(WebXmlProcessor.__web_processor);
|
||||||
|
if (processor == null)
|
||||||
|
{
|
||||||
|
processor = new WebXmlProcessor (context);
|
||||||
|
context.setAttribute(WebXmlProcessor.__web_processor, processor);
|
||||||
|
}
|
||||||
|
processor.processFragments();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void deconfigure(WebAppContext context) throws Exception
|
||||||
|
{
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void postConfigure(WebAppContext context) throws Exception
|
||||||
|
{
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------------- */
|
||||||
|
/**
|
||||||
|
* Look for any web.xml fragments in META-INF of jars in WEB-INF/lib
|
||||||
|
*
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public void parseWebFragments (final WebAppContext context, final WebXmlProcessor processor) throws Exception
|
||||||
|
{
|
||||||
|
// Check to see if a specific search pattern has been set.
|
||||||
|
String tmp = (String) context.getInitParameter("org.eclipse.jetty.webapp.WebXmlFragmentPattern");
|
||||||
|
Pattern webFragPattern = (tmp == null ? null : Pattern.compile(tmp));
|
||||||
|
|
||||||
|
List<URL> urls = (List<URL>)context.getAttribute(MetaInfConfiguration.__webFragJars);
|
||||||
|
|
||||||
|
JarScanner fragScanner = new JarScanner()
|
||||||
|
{
|
||||||
|
public void processEntry(URL jarUrl, JarEntry entry)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
String name = entry.getName();
|
||||||
|
if (name.toLowerCase().equals("meta-inf/web-fragment.xml"))
|
||||||
|
{
|
||||||
|
Resource webXmlFrag = context.newResource("jar:" + jarUrl + "!/" + name);
|
||||||
|
Log.debug("web.xml fragment found {}", webXmlFrag);
|
||||||
|
// Process web.xml
|
||||||
|
// web-fragment
|
||||||
|
// servlet
|
||||||
|
// servlet-mapping
|
||||||
|
// filter
|
||||||
|
// filter-mapping
|
||||||
|
// listener
|
||||||
|
processor.parseFragment(webXmlFrag.getURL());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Log.warn("Problem processing jar entry " + entry, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//process only the jars that have web fragments in them, according to the pattern provided
|
||||||
|
if (urls != null)
|
||||||
|
fragScanner.scan(webFragPattern, urls.toArray(new URL[urls.size()]), true);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (Log.isDebugEnabled()) Log.debug("No jars with web-fragments");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -43,6 +43,60 @@ public abstract class JarScanner
|
||||||
|
|
||||||
public abstract void processEntry (URL jarUrl, JarEntry entry);
|
public abstract void processEntry (URL jarUrl, JarEntry entry);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find jar names from the provided list matching a pattern.
|
||||||
|
*
|
||||||
|
* If the pattern is null and isNullInclusive is true, then
|
||||||
|
* all jar names will match.
|
||||||
|
*
|
||||||
|
* A pattern is a set of acceptable jar names. Each acceptable
|
||||||
|
* jar name is a regex. Each regex can be separated by either a
|
||||||
|
* "," or a "|". If you use a "|" this or's together the jar
|
||||||
|
* name patterns. This means that ordering of the matches is
|
||||||
|
* unimportant to you. If instead, you want to match particular
|
||||||
|
* jar names, and you want to match them in order, you should
|
||||||
|
* separate the regexs with "," instead.
|
||||||
|
*
|
||||||
|
* Eg "aaa-.*\\.jar|bbb-.*\\.jar"
|
||||||
|
* Will iterate over the jar names and match
|
||||||
|
* in any order.
|
||||||
|
*
|
||||||
|
* Eg "aaa-*\\.jar,bbb-.*\\.jar"
|
||||||
|
* Will iterate over the jar names, matching
|
||||||
|
* all those starting with "aaa-" first, then "bbb-".
|
||||||
|
*
|
||||||
|
* @param pattern
|
||||||
|
* @param loader
|
||||||
|
* @param isNullInclusive if true, an empty pattern means all names match, if false, none match
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public void scan (Pattern pattern, URL[] urls, boolean isNullInclusive)
|
||||||
|
throws Exception
|
||||||
|
{
|
||||||
|
if (urls!=null)
|
||||||
|
{
|
||||||
|
String[] patterns = (pattern==null?null:pattern.pattern().split(","));
|
||||||
|
|
||||||
|
List<Pattern> subPatterns = new ArrayList<Pattern>();
|
||||||
|
for (int i=0; patterns!=null && i<patterns.length;i++)
|
||||||
|
subPatterns.add(Pattern.compile(patterns[i]));
|
||||||
|
if (subPatterns.isEmpty())
|
||||||
|
subPatterns.add(pattern);
|
||||||
|
|
||||||
|
if (subPatterns.isEmpty())
|
||||||
|
{
|
||||||
|
processJars(null, urls, isNullInclusive);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//for each subpattern, iterate over all the urls, processing those that match
|
||||||
|
for (Pattern p : subPatterns)
|
||||||
|
{
|
||||||
|
processJars(p, urls, isNullInclusive);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find jar names from the classloader matching a pattern.
|
* Find jar names from the classloader matching a pattern.
|
||||||
|
|
|
@ -29,46 +29,22 @@ import org.eclipse.jetty.xml.XmlConfiguration;
|
||||||
*/
|
*/
|
||||||
public class JettyWebXmlConfiguration implements Configuration
|
public class JettyWebXmlConfiguration implements Configuration
|
||||||
{
|
{
|
||||||
private WebAppContext _context;
|
public void preConfigure(WebAppContext context) throws Exception
|
||||||
|
{
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see Configuration#setWebAppContext
|
* Configure
|
||||||
*/
|
|
||||||
public void setWebAppContext (WebAppContext context)
|
|
||||||
{
|
|
||||||
_context = context;
|
|
||||||
}
|
|
||||||
|
|
||||||
public WebAppContext getWebAppContext ()
|
|
||||||
{
|
|
||||||
return _context;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** configureClassPath
|
|
||||||
* Not used.
|
|
||||||
* @see Configuration#configureClassLoader
|
|
||||||
*/
|
|
||||||
public void configureClassLoader () throws Exception
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/** configureDefaults
|
|
||||||
* Not used.
|
|
||||||
* @see Configuration#configureDefaults
|
|
||||||
*/
|
|
||||||
public void configureDefaults () throws Exception
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/** configureWebApp
|
|
||||||
* Apply web-jetty.xml configuration
|
* Apply web-jetty.xml configuration
|
||||||
* @see Configuration#configureWebApp()
|
* @see Configuration#configure(WebAppContext)
|
||||||
*/
|
*/
|
||||||
public void configureWebApp () throws Exception
|
public void configure (WebAppContext context) throws Exception
|
||||||
{
|
{
|
||||||
//cannot configure if the _context is already started
|
//cannot configure if the _context is already started
|
||||||
if (_context.isStarted())
|
if (context.isStarted())
|
||||||
{
|
{
|
||||||
if (Log.isDebugEnabled()){Log.debug("Cannot configure webapp after it is started");}
|
if (Log.isDebugEnabled()){Log.debug("Cannot configure webapp after it is started");}
|
||||||
return;
|
return;
|
||||||
|
@ -77,7 +53,7 @@ public class JettyWebXmlConfiguration implements Configuration
|
||||||
if(Log.isDebugEnabled())
|
if(Log.isDebugEnabled())
|
||||||
Log.debug("Configuring web-jetty.xml");
|
Log.debug("Configuring web-jetty.xml");
|
||||||
|
|
||||||
Resource web_inf=getWebAppContext().getWebInf();
|
Resource web_inf = context.getWebInf();
|
||||||
// handle any WEB-INF descriptors
|
// handle any WEB-INF descriptors
|
||||||
if(web_inf!=null&&web_inf.isDirectory())
|
if(web_inf!=null&&web_inf.isDirectory())
|
||||||
{
|
{
|
||||||
|
@ -91,31 +67,35 @@ public class JettyWebXmlConfiguration implements Configuration
|
||||||
if(jetty.exists())
|
if(jetty.exists())
|
||||||
{
|
{
|
||||||
// No server classes while configuring
|
// No server classes while configuring
|
||||||
String[] old_server_classes = _context.getServerClasses();
|
String[] old_server_classes = context.getServerClasses();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_context.setServerClasses(null);
|
context.setServerClasses(null);
|
||||||
if(Log.isDebugEnabled())
|
if(Log.isDebugEnabled())
|
||||||
Log.debug("Configure: "+jetty);
|
Log.debug("Configure: "+jetty);
|
||||||
XmlConfiguration jetty_config=new XmlConfiguration(jetty.getURL());
|
XmlConfiguration jetty_config=new XmlConfiguration(jetty.getURL());
|
||||||
jetty_config.configure(getWebAppContext());
|
jetty_config.configure(context);
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
if (_context.getServerClasses()==null)
|
if (context.getServerClasses()==null)
|
||||||
_context.setServerClasses(old_server_classes);
|
context.setServerClasses(old_server_classes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** deconfigureWebApp
|
public void postConfigure(WebAppContext context) throws Exception
|
||||||
* @see Configuration#deconfigureWebApp()
|
|
||||||
*/
|
|
||||||
public void deconfigureWebApp () throws Exception
|
|
||||||
{
|
{
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void deconfigure(WebAppContext context) throws Exception
|
||||||
|
{
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,140 @@
|
||||||
|
// ========================================================================
|
||||||
|
// Copyright (c) 2009 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.webapp;
|
||||||
|
|
||||||
|
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.jar.JarEntry;
|
||||||
|
|
||||||
|
import org.eclipse.jetty.util.log.Log;
|
||||||
|
import org.eclipse.jetty.util.resource.Resource;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MetaInfConfiguration
|
||||||
|
*
|
||||||
|
* Scan META-INF of all jars in WEB-INF/lib to find:
|
||||||
|
* <ul>
|
||||||
|
* <li>tlds
|
||||||
|
* <li>web-fragment.xml
|
||||||
|
* <li>resources
|
||||||
|
* </ul>
|
||||||
|
*/
|
||||||
|
public class MetaInfConfiguration implements Configuration
|
||||||
|
{
|
||||||
|
|
||||||
|
public static final String __tldJars = "org.eclipse.jetty.tlds";
|
||||||
|
public static final String __webFragJars = "org.eclipse.jetty.webFragments";
|
||||||
|
public static final String __metaResourceJars = "org.eclipse.jetty.metaResources";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public void preConfigure(final WebAppContext context) throws Exception
|
||||||
|
{
|
||||||
|
|
||||||
|
//Find all jars in WEB-INF
|
||||||
|
Resource web_inf = context.getWebInf();
|
||||||
|
Resource web_inf_lib = web_inf.addPath("/lib");
|
||||||
|
List<URL> urls = new ArrayList<URL>();
|
||||||
|
|
||||||
|
if (web_inf_lib.exists() && web_inf_lib.isDirectory())
|
||||||
|
{
|
||||||
|
String[] files=web_inf_lib.list();
|
||||||
|
for (int f=0;files!=null && f<files.length;f++)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Resource file = web_inf_lib.addPath(files[f]);
|
||||||
|
String fnlc = file.getName().toLowerCase();
|
||||||
|
int dot = fnlc.lastIndexOf('.');
|
||||||
|
String extension = (dot < 0 ? null : fnlc.substring(dot));
|
||||||
|
if (extension != null && (extension.equals(".jar") || extension.equals(".zip")))
|
||||||
|
{
|
||||||
|
urls.add(file.getURL());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Log.warn(Log.EXCEPTION,ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final List<URL> tldJars = new ArrayList<URL>();
|
||||||
|
final List<URL> webFragJars = new ArrayList<URL>();
|
||||||
|
final List<URL> metaResourceJars = new ArrayList<URL>();
|
||||||
|
|
||||||
|
JarScanner fragScanner = new JarScanner()
|
||||||
|
{
|
||||||
|
public void processEntry(URL jarUrl, JarEntry entry)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
String name = entry.getName().toLowerCase();
|
||||||
|
if (name.startsWith("meta-inf"))
|
||||||
|
{
|
||||||
|
if (name.equals("meta-inf/web-fragment.xml"))
|
||||||
|
{
|
||||||
|
addJar(jarUrl, webFragJars);
|
||||||
|
}
|
||||||
|
else if (name.endsWith(".tld"))
|
||||||
|
{
|
||||||
|
addJar(jarUrl, tldJars);
|
||||||
|
}
|
||||||
|
else if (name.equals("meta-inf/resources"))
|
||||||
|
{
|
||||||
|
addJar(jarUrl, metaResourceJars);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Log.warn("Problem processing jar entry " + entry, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
fragScanner.scan(null, urls.toArray(new URL[urls.size()]), true);
|
||||||
|
|
||||||
|
context.setAttribute(__tldJars, tldJars);
|
||||||
|
context.setAttribute(__webFragJars, webFragJars);
|
||||||
|
context.setAttribute(__metaResourceJars, metaResourceJars);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void configure(WebAppContext context) throws Exception
|
||||||
|
{
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void deconfigure(WebAppContext context) throws Exception
|
||||||
|
{
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void postConfigure(WebAppContext context) throws Exception
|
||||||
|
{
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addJar (URL jarUrl, List<URL> list)
|
||||||
|
{
|
||||||
|
if (!list.contains(jarUrl))
|
||||||
|
list.add(jarUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -14,9 +14,11 @@
|
||||||
package org.eclipse.jetty.webapp;
|
package org.eclipse.jetty.webapp;
|
||||||
|
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.EventListener;
|
import java.util.EventListener;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.jar.JarEntry;
|
import java.util.jar.JarEntry;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
@ -50,14 +52,24 @@ public class TagLibConfiguration implements Configuration
|
||||||
{
|
{
|
||||||
public static final String __web_inf_pattern = "org.eclipse.jetty.webapp.WebInfIncludeTLDJarPattern";
|
public static final String __web_inf_pattern = "org.eclipse.jetty.webapp.WebInfIncludeTLDJarPattern";
|
||||||
public static final String __container_pattern = "org.eclipse.jetty.server.webapp.ContainerIncludeTLDJarPattern";
|
public static final String __container_pattern = "org.eclipse.jetty.server.webapp.ContainerIncludeTLDJarPattern";
|
||||||
WebAppContext _context;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public class TagLibJarScanner extends JarScanner
|
/**
|
||||||
|
* TagLibJarScanner
|
||||||
|
*
|
||||||
|
* Scan jars for META-INF/*.tlds
|
||||||
|
*/
|
||||||
|
public class TagLibJarScanner extends JarScanner
|
||||||
{
|
{
|
||||||
Set _tlds;
|
Set _tlds;
|
||||||
|
WebAppContext _context;
|
||||||
|
|
||||||
|
public TagLibJarScanner (WebAppContext context)
|
||||||
|
{
|
||||||
|
_context = context;
|
||||||
|
}
|
||||||
|
|
||||||
public void setTldSet (Set tlds)
|
public void setTldSet (Set tlds)
|
||||||
{
|
{
|
||||||
|
@ -88,52 +100,164 @@ public class TagLibConfiguration implements Configuration
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
public void setWebAppContext(WebAppContext context)
|
|
||||||
{
|
|
||||||
_context=context;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
public WebAppContext getWebAppContext()
|
|
||||||
{
|
|
||||||
return _context;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
public void configureClassLoader() throws Exception
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
/*
|
|
||||||
* @see org.eclipse.jetty.servlet.WebAppContext.Configuration#configureDefaults()
|
|
||||||
*/
|
|
||||||
public void configureDefaults() throws Exception
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
public class TldProcessor
|
||||||
/*
|
{
|
||||||
* @see org.eclipse.jetty.servlet.WebAppContext.Configuration#configureWebApp()
|
public static final String __taglib_processor = "org.eclipse.jetty.tagLibProcessor";
|
||||||
*/
|
XmlParser _parser;
|
||||||
public void configureWebApp() throws Exception
|
WebAppContext _context;
|
||||||
{
|
List<XmlParser.Node> _roots = new ArrayList<XmlParser.Node>();
|
||||||
|
|
||||||
Set tlds = new HashSet();
|
|
||||||
|
|
||||||
|
|
||||||
// Find tld's from web.xml
|
public TldProcessor (WebAppContext context)
|
||||||
// When the XMLConfigurator (or other configurator) parsed the web.xml,
|
throws Exception
|
||||||
// It should have created aliases for all TLDs. So search resources aliases
|
|
||||||
// for aliases ending in tld
|
|
||||||
if (_context.getResourceAliases()!=null &&
|
|
||||||
_context.getBaseResource()!=null &&
|
|
||||||
_context.getBaseResource().exists())
|
|
||||||
{
|
{
|
||||||
Iterator iter=_context.getResourceAliases().values().iterator();
|
_context = context;
|
||||||
|
createParser();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createParser ()
|
||||||
|
throws Exception
|
||||||
|
{
|
||||||
|
// Create a TLD parser
|
||||||
|
_parser = new XmlParser(false);
|
||||||
|
|
||||||
|
URL taglib11=null;
|
||||||
|
URL taglib12=null;
|
||||||
|
URL taglib20=null;
|
||||||
|
URL taglib21=null;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Class jsp_page = Loader.loadClass(WebXmlConfiguration.class,"javax.servlet.jsp.JspPage");
|
||||||
|
taglib11=jsp_page.getResource("javax/servlet/jsp/resources/web-jsptaglibrary_1_1.dtd");
|
||||||
|
taglib12=jsp_page.getResource("javax/servlet/jsp/resources/web-jsptaglibrary_1_2.dtd");
|
||||||
|
taglib20=jsp_page.getResource("javax/servlet/jsp/resources/web-jsptaglibrary_2_0.xsd");
|
||||||
|
taglib21=jsp_page.getResource("javax/servlet/jsp/resources/web-jsptaglibrary_2_1.xsd");
|
||||||
|
}
|
||||||
|
catch(Exception e)
|
||||||
|
{
|
||||||
|
Log.ignore(e);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
if(taglib11==null)
|
||||||
|
taglib11=Loader.getResource(Servlet.class,"javax/servlet/jsp/resources/web-jsptaglibrary_1_1.dtd",true);
|
||||||
|
if(taglib12==null)
|
||||||
|
taglib12=Loader.getResource(Servlet.class,"javax/servlet/jsp/resources/web-jsptaglibrary_1_2.dtd",true);
|
||||||
|
if(taglib20==null)
|
||||||
|
taglib20=Loader.getResource(Servlet.class,"javax/servlet/jsp/resources/web-jsptaglibrary_2_0.xsd",true);
|
||||||
|
if(taglib21==null)
|
||||||
|
taglib21=Loader.getResource(Servlet.class,"javax/servlet/jsp/resources/web-jsptaglibrary_2_1.xsd",true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if(taglib11!=null)
|
||||||
|
{
|
||||||
|
_parser.redirectEntity("web-jsptaglib_1_1.dtd",taglib11);
|
||||||
|
_parser.redirectEntity("web-jsptaglibrary_1_1.dtd",taglib11);
|
||||||
|
}
|
||||||
|
if(taglib12!=null)
|
||||||
|
{
|
||||||
|
_parser.redirectEntity("web-jsptaglib_1_2.dtd",taglib12);
|
||||||
|
_parser.redirectEntity("web-jsptaglibrary_1_2.dtd",taglib12);
|
||||||
|
}
|
||||||
|
if(taglib20!=null)
|
||||||
|
{
|
||||||
|
_parser.redirectEntity("web-jsptaglib_2_0.xsd",taglib20);
|
||||||
|
_parser.redirectEntity("web-jsptaglibrary_2_0.xsd",taglib20);
|
||||||
|
}
|
||||||
|
if(taglib21!=null)
|
||||||
|
{
|
||||||
|
_parser.redirectEntity("web-jsptaglib_2_1.xsd",taglib21);
|
||||||
|
_parser.redirectEntity("web-jsptaglibrary_2_1.xsd",taglib21);
|
||||||
|
}
|
||||||
|
|
||||||
|
_parser.setXpath("/taglib/listener/listener-class");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public XmlParser.Node parse (Resource tld)
|
||||||
|
throws Exception
|
||||||
|
{
|
||||||
|
XmlParser.Node root;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
//xerces on apple appears to sometimes close the zip file instead
|
||||||
|
//of the inputstream, so try opening the input stream, but if
|
||||||
|
//that doesn't work, fallback to opening a new url
|
||||||
|
root = _parser.parse(tld.getInputStream());
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
root = _parser.parse(tld.getURL().toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (root==null)
|
||||||
|
{
|
||||||
|
Log.warn("No TLD root in {}",tld);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
_roots.add(root);
|
||||||
|
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void processRoots ()
|
||||||
|
{
|
||||||
|
for (XmlParser.Node root: _roots)
|
||||||
|
process(root);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void process (XmlParser.Node root)
|
||||||
|
{
|
||||||
|
for (int i=0;i<root.size();i++)
|
||||||
|
{
|
||||||
|
Object o=root.get(i);
|
||||||
|
if (o instanceof XmlParser.Node)
|
||||||
|
{
|
||||||
|
XmlParser.Node node = (XmlParser.Node)o;
|
||||||
|
if ("listener".equals(node.getTag()))
|
||||||
|
{
|
||||||
|
String className=node.getString("listener-class",false,true);
|
||||||
|
if (Log.isDebugEnabled()) Log.debug("listener="+className);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Class listenerClass = _context.loadClass(className);
|
||||||
|
EventListener l = (EventListener)listenerClass.newInstance();
|
||||||
|
_context.addEventListener(l);
|
||||||
|
}
|
||||||
|
catch(Exception e)
|
||||||
|
{
|
||||||
|
Log.warn("Could not instantiate listener "+className+": "+e);
|
||||||
|
Log.debug(e);
|
||||||
|
}
|
||||||
|
catch(Error e)
|
||||||
|
{
|
||||||
|
Log.warn("Could not instantiate listener "+className+": "+e);
|
||||||
|
Log.debug(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void preConfigure(WebAppContext context) throws Exception
|
||||||
|
{
|
||||||
|
Set tlds = new HashSet();
|
||||||
|
|
||||||
|
// Find tld's from web.xml
|
||||||
|
// When web.xml was processed, it should have created aliases for all TLDs. So search resources aliases
|
||||||
|
// for aliases ending in tld
|
||||||
|
if (context.getResourceAliases()!=null &&
|
||||||
|
context.getBaseResource()!=null &&
|
||||||
|
context.getBaseResource().exists())
|
||||||
|
{
|
||||||
|
Iterator iter=context.getResourceAliases().values().iterator();
|
||||||
while(iter.hasNext())
|
while(iter.hasNext())
|
||||||
{
|
{
|
||||||
String location = (String)iter.next();
|
String location = (String)iter.next();
|
||||||
|
@ -141,14 +265,14 @@ public class TagLibConfiguration implements Configuration
|
||||||
{
|
{
|
||||||
if (!location.startsWith("/"))
|
if (!location.startsWith("/"))
|
||||||
location="/WEB-INF/"+location;
|
location="/WEB-INF/"+location;
|
||||||
Resource l=_context.getBaseResource().addPath(location);
|
Resource l=context.getBaseResource().addPath(location);
|
||||||
tlds.add(l);
|
tlds.add(l);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Look for any tlds in WEB-INF directly.
|
// Look for any tlds in WEB-INF directly.
|
||||||
Resource web_inf = _context.getWebInf();
|
Resource web_inf = context.getWebInf();
|
||||||
if (web_inf!=null)
|
if (web_inf!=null)
|
||||||
{
|
{
|
||||||
String[] contents = web_inf.list();
|
String[] contents = web_inf.list();
|
||||||
|
@ -156,13 +280,14 @@ public class TagLibConfiguration implements Configuration
|
||||||
{
|
{
|
||||||
if (contents[i]!=null && contents[i].toLowerCase().endsWith(".tld"))
|
if (contents[i]!=null && contents[i].toLowerCase().endsWith(".tld"))
|
||||||
{
|
{
|
||||||
Resource l=_context.getWebInf().addPath(contents[i]);
|
Resource l=context.getWebInf().addPath(contents[i]);
|
||||||
tlds.add(l);
|
tlds.add(l);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Look for tlds in any jars
|
// Look for tlds in any jars
|
||||||
//Use an opt-in style:
|
//Use an opt-in style:
|
||||||
//
|
//
|
||||||
|
@ -181,81 +306,33 @@ public class TagLibConfiguration implements Configuration
|
||||||
// else
|
// else
|
||||||
// examine only files matching pattern
|
// examine only files matching pattern
|
||||||
//
|
//
|
||||||
String tmp = _context.getInitParameter(__web_inf_pattern);
|
String tmp = context.getInitParameter(__web_inf_pattern);
|
||||||
Pattern webInfPattern = (tmp==null?null:Pattern.compile(tmp));
|
Pattern webInfPattern = (tmp==null?null:Pattern.compile(tmp));
|
||||||
tmp = _context.getInitParameter(__container_pattern);
|
tmp = context.getInitParameter(__container_pattern);
|
||||||
Pattern containerPattern = (tmp==null?null:Pattern.compile(tmp));
|
Pattern containerPattern = (tmp==null?null:Pattern.compile(tmp));
|
||||||
|
|
||||||
TagLibJarScanner tldScanner = new TagLibJarScanner();
|
List<URL> tldJars = (List<URL>)context.getAttribute(MetaInfConfiguration.__tldJars);
|
||||||
|
|
||||||
|
TagLibJarScanner tldScanner = new TagLibJarScanner(context);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
tldScanner.setTldSet(tlds);
|
tldScanner.setTldSet(tlds);
|
||||||
tldScanner.scan(webInfPattern, Thread.currentThread().getContextClassLoader(), true, false);
|
//scan the jars we know have META-INF/tld files
|
||||||
|
if (tldJars != null)
|
||||||
|
tldScanner.scan(webInfPattern, tldJars.toArray(new URL[tldJars.size()]), true);
|
||||||
|
|
||||||
|
//scan the parent loader for tld files
|
||||||
tldScanner.scan(containerPattern, Thread.currentThread().getContextClassLoader().getParent(), false, true);
|
tldScanner.scan(containerPattern, Thread.currentThread().getContextClassLoader().getParent(), false, true);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
Log.warn(e);
|
Log.warn(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Create a processor for the tlds and save it
|
||||||
// Create a TLD parser
|
TldProcessor processor = new TldProcessor (context);
|
||||||
XmlParser parser = new XmlParser(false);
|
context.setAttribute(TldProcessor.__taglib_processor, processor);
|
||||||
|
// Parse the tlds into memory
|
||||||
URL taglib11=null;
|
|
||||||
URL taglib12=null;
|
|
||||||
URL taglib20=null;
|
|
||||||
URL taglib21=null;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Class jsp_page = Loader.loadClass(WebXmlConfiguration.class,"javax.servlet.jsp.JspPage");
|
|
||||||
taglib11=jsp_page.getResource("javax/servlet/jsp/resources/web-jsptaglibrary_1_1.dtd");
|
|
||||||
taglib12=jsp_page.getResource("javax/servlet/jsp/resources/web-jsptaglibrary_1_2.dtd");
|
|
||||||
taglib20=jsp_page.getResource("javax/servlet/jsp/resources/web-jsptaglibrary_2_0.xsd");
|
|
||||||
taglib21=jsp_page.getResource("javax/servlet/jsp/resources/web-jsptaglibrary_2_1.xsd");
|
|
||||||
}
|
|
||||||
catch(Exception e)
|
|
||||||
{
|
|
||||||
Log.ignore(e);
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
if(taglib11==null)
|
|
||||||
taglib11=Loader.getResource(Servlet.class,"javax/servlet/jsp/resources/web-jsptaglibrary_1_1.dtd",true);
|
|
||||||
if(taglib12==null)
|
|
||||||
taglib12=Loader.getResource(Servlet.class,"javax/servlet/jsp/resources/web-jsptaglibrary_1_2.dtd",true);
|
|
||||||
if(taglib20==null)
|
|
||||||
taglib20=Loader.getResource(Servlet.class,"javax/servlet/jsp/resources/web-jsptaglibrary_2_0.xsd",true);
|
|
||||||
if(taglib21==null)
|
|
||||||
taglib21=Loader.getResource(Servlet.class,"javax/servlet/jsp/resources/web-jsptaglibrary_2_1.xsd",true);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if(taglib11!=null)
|
|
||||||
{
|
|
||||||
parser.redirectEntity("web-jsptaglib_1_1.dtd",taglib11);
|
|
||||||
parser.redirectEntity("web-jsptaglibrary_1_1.dtd",taglib11);
|
|
||||||
}
|
|
||||||
if(taglib12!=null)
|
|
||||||
{
|
|
||||||
parser.redirectEntity("web-jsptaglib_1_2.dtd",taglib12);
|
|
||||||
parser.redirectEntity("web-jsptaglibrary_1_2.dtd",taglib12);
|
|
||||||
}
|
|
||||||
if(taglib20!=null)
|
|
||||||
{
|
|
||||||
parser.redirectEntity("web-jsptaglib_2_0.xsd",taglib20);
|
|
||||||
parser.redirectEntity("web-jsptaglibrary_2_0.xsd",taglib20);
|
|
||||||
}
|
|
||||||
if(taglib21!=null)
|
|
||||||
{
|
|
||||||
parser.redirectEntity("web-jsptaglib_2_1.xsd",taglib21);
|
|
||||||
parser.redirectEntity("web-jsptaglibrary_2_1.xsd",taglib21);
|
|
||||||
}
|
|
||||||
|
|
||||||
parser.setXpath("/taglib/listener/listener-class");
|
|
||||||
|
|
||||||
// Parse all the discovered TLDs
|
|
||||||
Iterator iter = tlds.iterator();
|
Iterator iter = tlds.iterator();
|
||||||
while (iter.hasNext())
|
while (iter.hasNext())
|
||||||
{
|
{
|
||||||
|
@ -263,57 +340,7 @@ public class TagLibConfiguration implements Configuration
|
||||||
{
|
{
|
||||||
Resource tld = (Resource)iter.next();
|
Resource tld = (Resource)iter.next();
|
||||||
if (Log.isDebugEnabled()) Log.debug("TLD="+tld);
|
if (Log.isDebugEnabled()) Log.debug("TLD="+tld);
|
||||||
|
processor.parse(tld);
|
||||||
XmlParser.Node root;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
//xerces on apple appears to sometimes close the zip file instead
|
|
||||||
//of the inputstream, so try opening the input stream, but if
|
|
||||||
//that doesn't work, fallback to opening a new url
|
|
||||||
root = parser.parse(tld.getInputStream());
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
root = parser.parse(tld.getURL().toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (root==null)
|
|
||||||
{
|
|
||||||
Log.warn("No TLD root in {}",tld);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i=0;i<root.size();i++)
|
|
||||||
{
|
|
||||||
Object o=root.get(i);
|
|
||||||
if (o instanceof XmlParser.Node)
|
|
||||||
{
|
|
||||||
XmlParser.Node node = (XmlParser.Node)o;
|
|
||||||
if ("listener".equals(node.getTag()))
|
|
||||||
{
|
|
||||||
String className=node.getString("listener-class",false,true);
|
|
||||||
if (Log.isDebugEnabled()) Log.debug("listener="+className);
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Class listenerClass=getWebAppContext().loadClass(className);
|
|
||||||
EventListener l=(EventListener)listenerClass.newInstance();
|
|
||||||
_context.addEventListener(l);
|
|
||||||
}
|
|
||||||
catch(Exception e)
|
|
||||||
{
|
|
||||||
Log.warn("Could not instantiate listener "+className+": "+e);
|
|
||||||
Log.debug(e);
|
|
||||||
}
|
|
||||||
catch(Error e)
|
|
||||||
{
|
|
||||||
Log.warn("Could not instantiate listener "+className+": "+e);
|
|
||||||
Log.debug(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch(Exception e)
|
catch(Exception e)
|
||||||
{
|
{
|
||||||
|
@ -321,11 +348,31 @@ public class TagLibConfiguration implements Configuration
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void configure (WebAppContext context) throws Exception
|
||||||
|
{
|
||||||
|
TldProcessor processor = (TldProcessor)context.getAttribute(TldProcessor.__taglib_processor);
|
||||||
|
if (processor == null)
|
||||||
|
{
|
||||||
|
Log.warn("No TldProcessor configured, skipping tld processing");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
public void deconfigureWebApp() throws Exception
|
//Create listeners from the parsed tld trees
|
||||||
{
|
processor.processRoots();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void postConfigure(WebAppContext context) throws Exception
|
||||||
|
{
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void deconfigure(WebAppContext context) throws Exception
|
||||||
|
{
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,6 +73,8 @@ public class WebAppContext extends ServletContextHandler
|
||||||
{
|
{
|
||||||
"org.eclipse.jetty.webapp.WebInfConfiguration",
|
"org.eclipse.jetty.webapp.WebInfConfiguration",
|
||||||
"org.eclipse.jetty.webapp.WebXmlConfiguration",
|
"org.eclipse.jetty.webapp.WebXmlConfiguration",
|
||||||
|
"org.eclipse.jetty.webapp.MetaInfConfiguration",
|
||||||
|
"org.eclipse.jetty.webapp.FragmentConfiguration",
|
||||||
"org.eclipse.jetty.webapp.JettyWebXmlConfiguration",
|
"org.eclipse.jetty.webapp.JettyWebXmlConfiguration",
|
||||||
"org.eclipse.jetty.webapp.TagLibConfiguration"
|
"org.eclipse.jetty.webapp.TagLibConfiguration"
|
||||||
} ;
|
} ;
|
||||||
|
@ -107,7 +109,6 @@ public class WebAppContext extends ServletContextHandler
|
||||||
"org.slf4j." // hide slf4j
|
"org.slf4j." // hide slf4j
|
||||||
};
|
};
|
||||||
private File _tmpDir;
|
private File _tmpDir;
|
||||||
private boolean _isExistingTmpDir;
|
|
||||||
private String _war;
|
private String _war;
|
||||||
private String _extraClasspath;
|
private String _extraClasspath;
|
||||||
private Throwable _unavailableException;
|
private Throwable _unavailableException;
|
||||||
|
@ -296,9 +297,7 @@ public class WebAppContext extends ServletContextHandler
|
||||||
// Setup configurations
|
// Setup configurations
|
||||||
loadConfigurations();
|
loadConfigurations();
|
||||||
|
|
||||||
for (int i=0;i<_configurations.length;i++)
|
|
||||||
_configurations[i].setWebAppContext(this);
|
|
||||||
|
|
||||||
// Configure classloader
|
// Configure classloader
|
||||||
_ownClassLoader=false;
|
_ownClassLoader=false;
|
||||||
if (getClassLoader()==null)
|
if (getClassLoader()==null)
|
||||||
|
@ -319,19 +318,17 @@ public class WebAppContext extends ServletContextHandler
|
||||||
loader=loader.getParent();
|
loader=loader.getParent();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Prepare for configuration
|
||||||
for (int i=0;i<_configurations.length;i++)
|
for (int i=0;i<_configurations.length;i++)
|
||||||
_configurations[i].configureClassLoader();
|
_configurations[i].preConfigure(this);
|
||||||
|
|
||||||
getTempDirectory();
|
|
||||||
if (_tmpDir!=null && !_isExistingTmpDir && !isTempWorkDirectory())
|
|
||||||
{
|
|
||||||
File sentinel = new File(_tmpDir, ".active");
|
|
||||||
if(!sentinel.exists())
|
|
||||||
sentinel.mkdir();
|
|
||||||
}
|
|
||||||
|
|
||||||
super.doStart();
|
super.doStart();
|
||||||
|
|
||||||
|
// Clean up after configuration
|
||||||
|
for (int i=0;i<_configurations.length;i++)
|
||||||
|
_configurations[i].postConfigure(this);
|
||||||
|
|
||||||
|
|
||||||
if (isLogUrlOnStart())
|
if (isLogUrlOnStart())
|
||||||
dumpUrl();
|
dumpUrl();
|
||||||
|
@ -373,9 +370,9 @@ public class WebAppContext extends ServletContextHandler
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// Configure classloader
|
|
||||||
for (int i=_configurations.length;i-->0;)
|
for (int i=_configurations.length;i-->0;)
|
||||||
_configurations[i].deconfigureWebApp();
|
_configurations[i].deconfigure(this);
|
||||||
|
|
||||||
_configurations=null;
|
_configurations=null;
|
||||||
|
|
||||||
// restore security handler
|
// restore security handler
|
||||||
|
@ -384,13 +381,6 @@ public class WebAppContext extends ServletContextHandler
|
||||||
_sessionHandler.setHandler(_securityHandler);
|
_sessionHandler.setHandler(_securityHandler);
|
||||||
_securityHandler.setHandler(_servletHandler);
|
_securityHandler.setHandler(_servletHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
// delete temp directory if we had to create it or if it isn't called work
|
|
||||||
if (_tmpDir!=null && !_isExistingTmpDir && !isTempWorkDirectory()) //_tmpDir!=null && !"work".equals(_tmpDir.getName()))
|
|
||||||
{
|
|
||||||
IO.delete(_tmpDir);
|
|
||||||
_tmpDir=null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
|
@ -540,186 +530,7 @@ public class WebAppContext extends ServletContextHandler
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
/**
|
|
||||||
* Get a temporary directory in which to unpack the war etc etc.
|
|
||||||
* The algorithm for determining this is to check these alternatives
|
|
||||||
* in the order shown:
|
|
||||||
*
|
|
||||||
* <p>A. Try to use an explicit directory specifically for this webapp:</p>
|
|
||||||
* <ol>
|
|
||||||
* <li>
|
|
||||||
* Iff an explicit directory is set for this webapp, use it. Do NOT set
|
|
||||||
* delete on exit.
|
|
||||||
* </li>
|
|
||||||
* <li>
|
|
||||||
* Iff javax.servlet.context.tempdir context attribute is set for
|
|
||||||
* this webapp && exists && writeable, then use it. Do NOT set delete on exit.
|
|
||||||
* </li>
|
|
||||||
* </ol>
|
|
||||||
*
|
|
||||||
* <p>B. Create a directory based on global settings. The new directory
|
|
||||||
* will be called "Jetty_"+host+"_"+port+"__"+context+"_"+virtualhost
|
|
||||||
* Work out where to create this directory:
|
|
||||||
* <ol>
|
|
||||||
* <li>
|
|
||||||
* Iff $(jetty.home)/work exists create the directory there. Do NOT
|
|
||||||
* set delete on exit. Do NOT delete contents if dir already exists.
|
|
||||||
* </li>
|
|
||||||
* <li>
|
|
||||||
* Iff WEB-INF/work exists create the directory there. Do NOT set
|
|
||||||
* delete on exit. Do NOT delete contents if dir already exists.
|
|
||||||
* </li>
|
|
||||||
* <li>
|
|
||||||
* Else create dir in $(java.io.tmpdir). Set delete on exit. Delete
|
|
||||||
* contents if dir already exists.
|
|
||||||
* </li>
|
|
||||||
* </ol>
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public File getTempDirectory()
|
|
||||||
{
|
|
||||||
if (_tmpDir!=null && _tmpDir.isDirectory() && _tmpDir.canWrite())
|
|
||||||
return _tmpDir;
|
|
||||||
|
|
||||||
// Initialize temporary directory
|
|
||||||
//
|
|
||||||
// I'm afraid that this is very much black magic.
|
|
||||||
// but if you can think of better....
|
|
||||||
Object t = getAttribute(TEMPDIR);
|
|
||||||
|
|
||||||
if (t!=null && (t instanceof File))
|
|
||||||
{
|
|
||||||
_tmpDir=(File)t;
|
|
||||||
if (_tmpDir.isDirectory() && _tmpDir.canWrite())
|
|
||||||
return _tmpDir;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (t!=null && (t instanceof String))
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
_tmpDir=new File((String)t);
|
|
||||||
|
|
||||||
if (_tmpDir.isDirectory() && _tmpDir.canWrite())
|
|
||||||
{
|
|
||||||
if(Log.isDebugEnabled())Log.debug("Converted to File "+_tmpDir+" for "+this);
|
|
||||||
setAttribute(TEMPDIR,_tmpDir);
|
|
||||||
return _tmpDir;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch(Exception e)
|
|
||||||
{
|
|
||||||
Log.warn(Log.EXCEPTION,e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// No tempdir so look for a work directory to use as tempDir base
|
|
||||||
File work=null;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
File w=new File(System.getProperty("jetty.home"),"work");
|
|
||||||
if (w.exists() && w.canWrite() && w.isDirectory())
|
|
||||||
work=w;
|
|
||||||
else if (getBaseResource()!=null)
|
|
||||||
{
|
|
||||||
Resource web_inf = getWebInf();
|
|
||||||
if (web_inf !=null && web_inf.exists())
|
|
||||||
{
|
|
||||||
w=new File(web_inf.getFile(),"work");
|
|
||||||
if (w.exists() && w.canWrite() && w.isDirectory())
|
|
||||||
work=w;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch(Exception e)
|
|
||||||
{
|
|
||||||
Log.ignore(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
// No tempdir set so make one!
|
|
||||||
try
|
|
||||||
{
|
|
||||||
|
|
||||||
String temp = getCanonicalNameForWebAppTmpDir();
|
|
||||||
|
|
||||||
if (work!=null)
|
|
||||||
_tmpDir=new File(work,temp);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_tmpDir=new File(System.getProperty("java.io.tmpdir"),temp);
|
|
||||||
|
|
||||||
if (_tmpDir.exists())
|
|
||||||
{
|
|
||||||
if(Log.isDebugEnabled())Log.debug("Delete existing temp dir "+_tmpDir+" for "+this);
|
|
||||||
if (!IO.delete(_tmpDir))
|
|
||||||
{
|
|
||||||
if(Log.isDebugEnabled())Log.debug("Failed to delete temp dir "+_tmpDir);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_tmpDir.exists())
|
|
||||||
{
|
|
||||||
String old=_tmpDir.toString();
|
|
||||||
_tmpDir=File.createTempFile(temp+"_","");
|
|
||||||
if (_tmpDir.exists())
|
|
||||||
_tmpDir.delete();
|
|
||||||
Log.warn("Can't reuse "+old+", using "+_tmpDir);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!_tmpDir.exists())
|
|
||||||
_tmpDir.mkdir();
|
|
||||||
|
|
||||||
//if not in a dir called "work" then we want to delete it on jvm exit
|
|
||||||
if (!isTempWorkDirectory())
|
|
||||||
_tmpDir.deleteOnExit();
|
|
||||||
if(Log.isDebugEnabled())Log.debug("Created temp dir "+_tmpDir+" for "+this);
|
|
||||||
}
|
|
||||||
catch(Exception e)
|
|
||||||
{
|
|
||||||
_tmpDir=null;
|
|
||||||
Log.ignore(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_tmpDir==null)
|
|
||||||
{
|
|
||||||
try{
|
|
||||||
// that didn't work, so try something simpler (ish)
|
|
||||||
_tmpDir=File.createTempFile("JettyContext","");
|
|
||||||
if (_tmpDir.exists())
|
|
||||||
_tmpDir.delete();
|
|
||||||
_tmpDir.mkdir();
|
|
||||||
_tmpDir.deleteOnExit();
|
|
||||||
if(Log.isDebugEnabled())Log.debug("Created temp dir "+_tmpDir+" for "+this);
|
|
||||||
}
|
|
||||||
catch(IOException e)
|
|
||||||
{
|
|
||||||
Log.warn("tmpdir",e); System.exit(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
setAttribute(TEMPDIR,_tmpDir);
|
|
||||||
return _tmpDir;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if the _tmpDir itself is called "work", or if the _tmpDir
|
|
||||||
* is in a directory called "work".
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public boolean isTempWorkDirectory ()
|
|
||||||
{
|
|
||||||
if (_tmpDir == null)
|
|
||||||
return false;
|
|
||||||
if (_tmpDir.getName().equalsIgnoreCase("work"))
|
|
||||||
return true;
|
|
||||||
File t = _tmpDir.getParentFile();
|
|
||||||
if (t == null)
|
|
||||||
return false;
|
|
||||||
return (t.getName().equalsIgnoreCase("work"));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
/**
|
/**
|
||||||
|
@ -735,7 +546,8 @@ public class WebAppContext extends ServletContextHandler
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
public Resource getWebInf() throws IOException
|
public Resource getWebInf() throws IOException
|
||||||
{
|
{
|
||||||
resolveWebApp();
|
if (super.getBaseResource() == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
// Iw there a WEB-INF directory?
|
// Iw there a WEB-INF directory?
|
||||||
Resource web_inf= super.getBaseResource().addPath("WEB-INF/");
|
Resource web_inf= super.getBaseResource().addPath("WEB-INF/");
|
||||||
|
@ -813,104 +625,8 @@ public class WebAppContext extends ServletContextHandler
|
||||||
return super.toString()+(_war==null?"":(","+_war));
|
return super.toString()+(_war==null?"":(","+_war));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
/** Resolve Web App directory
|
|
||||||
* If the BaseResource has not been set, use the war resource to
|
|
||||||
* derive a webapp resource (expanding WAR if required).
|
|
||||||
*/
|
|
||||||
protected void resolveWebApp() throws IOException
|
|
||||||
{
|
|
||||||
Resource web_app = super.getBaseResource();
|
|
||||||
if (web_app == null)
|
|
||||||
{
|
|
||||||
if (_war==null || _war.length()==0)
|
|
||||||
_war=getResourceBase();
|
|
||||||
|
|
||||||
// Set dir or WAR
|
|
||||||
web_app= newResource(_war);
|
|
||||||
|
|
||||||
// Accept aliases for WAR files
|
|
||||||
if (web_app.getAlias() != null)
|
|
||||||
{
|
|
||||||
Log.debug(web_app + " anti-aliased to " + web_app.getAlias());
|
|
||||||
web_app= newResource(web_app.getAlias());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Log.isDebugEnabled())
|
|
||||||
Log.debug("Try webapp=" + web_app + ", exists=" + web_app.exists() + ", directory=" + web_app.isDirectory());
|
|
||||||
|
|
||||||
// Is the WAR usable directly?
|
|
||||||
if (web_app.exists() && !web_app.isDirectory() && !web_app.toString().startsWith("jar:"))
|
|
||||||
{
|
|
||||||
// No - then lets see if it can be turned into a jar URL.
|
|
||||||
Resource jarWebApp= newResource("jar:" + web_app + "!/");
|
|
||||||
if (jarWebApp.exists() && jarWebApp.isDirectory())
|
|
||||||
{
|
|
||||||
web_app= jarWebApp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we should extract or the URL is still not usable
|
|
||||||
if (web_app.exists() && (
|
|
||||||
(_copyDir && web_app.getFile()!= null && web_app.getFile().isDirectory())
|
|
||||||
||
|
|
||||||
(_extractWAR && web_app.getFile()!= null && !web_app.getFile().isDirectory())
|
|
||||||
||
|
|
||||||
(_extractWAR && web_app.getFile() == null)
|
|
||||||
||
|
|
||||||
!web_app.isDirectory()
|
|
||||||
))
|
|
||||||
{
|
|
||||||
// Then extract it if necessary.
|
|
||||||
File extractedWebAppDir= new File(getTempDirectory(), "webapp");
|
|
||||||
|
|
||||||
if (web_app.getFile()!=null && web_app.getFile().isDirectory())
|
|
||||||
{
|
|
||||||
// Copy directory
|
|
||||||
Log.info("Copy " + web_app.getFile() + " to " + extractedWebAppDir);
|
|
||||||
IO.copyDir(web_app.getFile(),extractedWebAppDir);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!extractedWebAppDir.exists())
|
|
||||||
{
|
|
||||||
//it hasn't been extracted before so extract it
|
|
||||||
extractedWebAppDir.mkdir();
|
|
||||||
Log.info("Extract " + _war + " to " + extractedWebAppDir);
|
|
||||||
JarResource.extract(web_app, extractedWebAppDir, false);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//only extract if the war file is newer
|
|
||||||
if (web_app.lastModified() > extractedWebAppDir.lastModified())
|
|
||||||
{
|
|
||||||
extractedWebAppDir.delete();
|
|
||||||
extractedWebAppDir.mkdir();
|
|
||||||
Log.info("Extract " + _war + " to " + extractedWebAppDir);
|
|
||||||
JarResource.extract(web_app, extractedWebAppDir, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
web_app= Resource.newResource(extractedWebAppDir.getCanonicalPath());
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Now do we have something usable?
|
|
||||||
if (!web_app.exists() || !web_app.isDirectory())
|
|
||||||
{
|
|
||||||
Log.warn("Web application not found " + _war);
|
|
||||||
throw new java.io.FileNotFoundException(_war);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Log.isDebugEnabled())
|
|
||||||
Log.debug("webapp=" + web_app);
|
|
||||||
|
|
||||||
// ResourcePath
|
|
||||||
super.setBaseResource(web_app);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
/**
|
/**
|
||||||
|
@ -1112,8 +828,6 @@ public class WebAppContext extends ServletContextHandler
|
||||||
dir.mkdir();
|
dir.mkdir();
|
||||||
dir.deleteOnExit();
|
dir.deleteOnExit();
|
||||||
}
|
}
|
||||||
else if (dir != null)
|
|
||||||
_isExistingTmpDir = true;
|
|
||||||
|
|
||||||
if (dir!=null && ( !dir.exists() || !dir.isDirectory() || !dir.canWrite()))
|
if (dir!=null && ( !dir.exists() || !dir.isDirectory() || !dir.canWrite()))
|
||||||
throw new IllegalArgumentException("Bad temp directory: "+dir);
|
throw new IllegalArgumentException("Bad temp directory: "+dir);
|
||||||
|
@ -1122,6 +836,11 @@ public class WebAppContext extends ServletContextHandler
|
||||||
setAttribute(TEMPDIR,_tmpDir);
|
setAttribute(TEMPDIR,_tmpDir);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public File getTempDirectory ()
|
||||||
|
{
|
||||||
|
return _tmpDir;
|
||||||
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
/**
|
/**
|
||||||
* @param war The war to set as a file name or URL
|
* @param war The war to set as a file name or URL
|
||||||
|
@ -1175,120 +894,14 @@ public class WebAppContext extends ServletContextHandler
|
||||||
protected void startContext()
|
protected void startContext()
|
||||||
throws Exception
|
throws Exception
|
||||||
{
|
{
|
||||||
// Configure defaults
|
|
||||||
for (int i=0;i<_configurations.length;i++)
|
|
||||||
_configurations[i].configureDefaults();
|
|
||||||
|
|
||||||
// Is there a WEB-INF work directory
|
|
||||||
Resource web_inf=getWebInf();
|
|
||||||
if (web_inf!=null)
|
|
||||||
{
|
|
||||||
Resource work= web_inf.addPath("work");
|
|
||||||
if (work.exists()
|
|
||||||
&& work.isDirectory()
|
|
||||||
&& work.getFile() != null
|
|
||||||
&& work.getFile().canWrite()
|
|
||||||
&& getAttribute(TEMPDIR) == null)
|
|
||||||
setAttribute(TEMPDIR, work.getFile());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Configure webapp
|
// Configure webapp
|
||||||
for (int i=0;i<_configurations.length;i++)
|
for (int i=0;i<_configurations.length;i++)
|
||||||
_configurations[i].configureWebApp();
|
_configurations[i].configure(this);
|
||||||
|
|
||||||
|
|
||||||
super.startContext();
|
super.startContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a canonical name for a webapp tmp directory.
|
|
||||||
* The form of the name is:
|
|
||||||
* "Jetty_"+host+"_"+port+"__"+resourceBase+"_"+context+"_"+virtualhost+base36 hashcode of whole string
|
|
||||||
*
|
|
||||||
* host and port uniquely identify the server
|
|
||||||
* context and virtual host uniquely identify the webapp
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
private String getCanonicalNameForWebAppTmpDir ()
|
|
||||||
{
|
|
||||||
StringBuffer canonicalName = new StringBuffer();
|
|
||||||
canonicalName.append("Jetty");
|
|
||||||
|
|
||||||
//get the host and the port from the first connector
|
|
||||||
Connector[] connectors = getServer().getConnectors();
|
|
||||||
|
|
||||||
|
|
||||||
//Get the host
|
|
||||||
canonicalName.append("_");
|
|
||||||
String host = (connectors==null||connectors[0]==null?"":connectors[0].getHost());
|
|
||||||
if (host == null)
|
|
||||||
host = "0.0.0.0";
|
|
||||||
canonicalName.append(host.replace('.', '_'));
|
|
||||||
|
|
||||||
//Get the port
|
|
||||||
canonicalName.append("_");
|
|
||||||
//try getting the real port being listened on
|
|
||||||
int port = (connectors==null||connectors[0]==null?0:connectors[0].getLocalPort());
|
|
||||||
//if not available (eg no connectors or connector not started),
|
|
||||||
//try getting one that was configured.
|
|
||||||
if (port < 0)
|
|
||||||
port = connectors[0].getPort();
|
|
||||||
canonicalName.append(port);
|
|
||||||
|
|
||||||
|
|
||||||
//Resource base
|
|
||||||
canonicalName.append("_");
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Resource resource = super.getBaseResource();
|
|
||||||
if (resource == null)
|
|
||||||
{
|
|
||||||
if (_war==null || _war.length()==0)
|
|
||||||
resource=newResource(getResourceBase());
|
|
||||||
|
|
||||||
// Set dir or WAR
|
|
||||||
resource= newResource(_war);
|
|
||||||
}
|
|
||||||
|
|
||||||
String tmp = URIUtil.decodePath(resource.getURL().getPath());
|
|
||||||
if (tmp.endsWith("/"))
|
|
||||||
tmp = tmp.substring(0, tmp.length()-1);
|
|
||||||
if (tmp.endsWith("!"))
|
|
||||||
tmp = tmp.substring(0, tmp.length() -1);
|
|
||||||
//get just the last part which is the filename
|
|
||||||
int i = tmp.lastIndexOf("/");
|
|
||||||
canonicalName.append(tmp.substring(i+1, tmp.length()));
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
Log.warn("Can't generate resourceBase as part of webapp tmp dir name", e);
|
|
||||||
}
|
|
||||||
|
|
||||||
//Context name
|
|
||||||
canonicalName.append("_");
|
|
||||||
String contextPath = getContextPath();
|
|
||||||
contextPath=contextPath.replace('/','_');
|
|
||||||
contextPath=contextPath.replace('\\','_');
|
|
||||||
canonicalName.append(contextPath);
|
|
||||||
|
|
||||||
//Virtual host (if there is one)
|
|
||||||
canonicalName.append("_");
|
|
||||||
String[] vhosts = getVirtualHosts();
|
|
||||||
canonicalName.append((vhosts==null||vhosts[0]==null?"":vhosts[0]));
|
|
||||||
|
|
||||||
//base36 hash of the whole string for uniqueness
|
|
||||||
String hash = Integer.toString(canonicalName.toString().hashCode(),36);
|
|
||||||
canonicalName.append("_");
|
|
||||||
canonicalName.append(hash);
|
|
||||||
|
|
||||||
// sanitize
|
|
||||||
for (int i=0;i<canonicalName.length();i++)
|
|
||||||
{
|
|
||||||
char c=canonicalName.charAt(i);
|
|
||||||
if (!Character.isJavaIdentifierPart(c))
|
|
||||||
canonicalName.setCharAt(i,'.');
|
|
||||||
}
|
|
||||||
|
|
||||||
return canonicalName.toString();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,94 +1,484 @@
|
||||||
// ========================================================================
|
|
||||||
// Copyright (c) 2003-2009 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.webapp;
|
package org.eclipse.jetty.webapp;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import org.eclipse.jetty.server.Connector;
|
||||||
|
import org.eclipse.jetty.util.IO;
|
||||||
|
import org.eclipse.jetty.util.URIUtil;
|
||||||
import org.eclipse.jetty.util.log.Log;
|
import org.eclipse.jetty.util.log.Log;
|
||||||
|
import org.eclipse.jetty.util.resource.JarResource;
|
||||||
import org.eclipse.jetty.util.resource.Resource;
|
import org.eclipse.jetty.util.resource.Resource;
|
||||||
/* ------------------------------------------------------------------------------- */
|
|
||||||
/**
|
|
||||||
* Configure class path from a WEB-INF directory found within a contexts resource base.
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class WebInfConfiguration implements Configuration
|
public class WebInfConfiguration implements Configuration
|
||||||
{
|
{
|
||||||
protected WebAppContext _context;
|
public static final String TEMPDIR_CREATED = "org.eclipse.jetty.tmpdirCreated";
|
||||||
|
|
||||||
public WebInfConfiguration()
|
public void preConfigure(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);
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------------- */
|
File work = findWorkDirectory(context);
|
||||||
public void setWebAppContext (WebAppContext context)
|
if (work != null)
|
||||||
|
makeTempDirectory(work, context, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public void postConfigure(WebAppContext context) throws Exception
|
||||||
{
|
{
|
||||||
_context = context;
|
// TODO Auto-generated method stub
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------------- */
|
|
||||||
public WebAppContext getWebAppContext()
|
|
||||||
{
|
|
||||||
return _context;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------------- */
|
public void configure(WebAppContext context) throws Exception
|
||||||
/** Configure ClassPath.
|
|
||||||
* This method is called before the context ClassLoader is created.
|
|
||||||
* Paths and libraries should be added to the context using the setClassPath,
|
|
||||||
* addClassPath and addClassPaths methods. The default implementation looks
|
|
||||||
* for WEB-INF/classes, WEB-INF/lib/*.zip and WEB-INF/lib/*.jar
|
|
||||||
* @throws Exception
|
|
||||||
*/
|
|
||||||
public void configureClassLoader()
|
|
||||||
throws Exception
|
|
||||||
{
|
{
|
||||||
//cannot configure if the context is already started
|
//cannot configure if the context is already started
|
||||||
if (_context.isStarted())
|
if (context.isStarted())
|
||||||
{
|
{
|
||||||
if (Log.isDebugEnabled()){Log.debug("Cannot configure webapp after it is started");}
|
if (Log.isDebugEnabled()){Log.debug("Cannot configure webapp "+context+" after it is started");}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Resource web_inf=_context.getWebInf();
|
Resource web_inf = context.getWebInf();
|
||||||
|
|
||||||
// Add WEB-INF classes and lib classpaths
|
// Add WEB-INF classes and lib classpaths
|
||||||
if (web_inf != null && web_inf.isDirectory() && _context.getClassLoader() instanceof WebAppClassLoader)
|
if (web_inf != null && web_inf.isDirectory() && context.getClassLoader() instanceof WebAppClassLoader)
|
||||||
{
|
{
|
||||||
// Look for classes directory
|
// Look for classes directory
|
||||||
Resource classes= web_inf.addPath("classes/");
|
Resource classes= web_inf.addPath("classes/");
|
||||||
if (classes.exists())
|
if (classes.exists())
|
||||||
((WebAppClassLoader)_context.getClassLoader()).addClassPath(classes.toString());
|
((WebAppClassLoader)context.getClassLoader()).addClassPath(classes.toString());
|
||||||
|
|
||||||
// Look for jars
|
// Look for jars
|
||||||
Resource lib= web_inf.addPath("lib/");
|
Resource lib= web_inf.addPath("lib/");
|
||||||
if (lib.exists() || lib.isDirectory())
|
if (lib.exists() || lib.isDirectory())
|
||||||
((WebAppClassLoader)_context.getClassLoader()).addJars(lib);
|
((WebAppClassLoader)context.getClassLoader()).addJars(lib);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public void deconfigure(WebAppContext context) throws Exception
|
||||||
|
{
|
||||||
|
// delete temp directory if we had to create it or if it isn't called work
|
||||||
|
Boolean containerCreated = (Boolean)context.getAttribute(TEMPDIR_CREATED);
|
||||||
|
|
||||||
}
|
if (context.getTempDirectory()!=null && (containerCreated != null && containerCreated.booleanValue()) && !isTempWorkDirectory(context.getTempDirectory()))
|
||||||
|
{
|
||||||
/* ------------------------------------------------------------------------------- */
|
IO.delete(context.getTempDirectory());
|
||||||
public void configureDefaults() throws Exception
|
setTempDirectory(null, context);
|
||||||
{
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------------- */
|
|
||||||
public void configureWebApp() throws Exception
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
/**
|
||||||
|
* Get a temporary directory in which to unpack the war etc etc.
|
||||||
|
* The algorithm for determining this is to check these alternatives
|
||||||
|
* in the order shown:
|
||||||
|
*
|
||||||
|
* <p>A. Try to use an explicit directory specifically for this webapp:</p>
|
||||||
|
* <ol>
|
||||||
|
* <li>
|
||||||
|
* Iff an explicit directory is set for this webapp, use it. Do NOT set
|
||||||
|
* delete on exit.
|
||||||
|
* </li>
|
||||||
|
* <li>
|
||||||
|
* Iff javax.servlet.context.tempdir context attribute is set for
|
||||||
|
* this webapp && exists && writeable, then use it. Do NOT set delete on exit.
|
||||||
|
* </li>
|
||||||
|
* </ol>
|
||||||
|
*
|
||||||
|
* <p>B. Create a directory based on global settings. The new directory
|
||||||
|
* will be called "Jetty_"+host+"_"+port+"__"+context+"_"+virtualhost
|
||||||
|
* Work out where to create this directory:
|
||||||
|
* <ol>
|
||||||
|
* <li>
|
||||||
|
* Iff $(jetty.home)/work exists create the directory there. Do NOT
|
||||||
|
* set delete on exit. Do NOT delete contents if dir already exists.
|
||||||
|
* </li>
|
||||||
|
* <li>
|
||||||
|
* Iff WEB-INF/work exists create the directory there. Do NOT set
|
||||||
|
* delete on exit. Do NOT delete contents if dir already exists.
|
||||||
|
* </li>
|
||||||
|
* <li>
|
||||||
|
* Else create dir in $(java.io.tmpdir). Set delete on exit. Delete
|
||||||
|
* contents if dir already exists.
|
||||||
|
* </li>
|
||||||
|
* </ol>
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public void resolveTempDirectory (WebAppContext context)
|
||||||
{
|
{
|
||||||
|
//If a tmp directory is already set, we're done
|
||||||
|
File tmpDir = context.getTempDirectory();
|
||||||
|
if (tmpDir!=null && tmpDir.isDirectory() && tmpDir.canWrite())
|
||||||
|
return; //Already have a suitable tmp dir configured
|
||||||
|
|
||||||
|
|
||||||
|
//None configured, try and come up with one
|
||||||
|
//First ... see if one is configured in a context attribute
|
||||||
|
//either as a File or name of a file
|
||||||
|
Object t = context.getAttribute(WebAppContext.TEMPDIR);
|
||||||
|
if (t != null)
|
||||||
|
{
|
||||||
|
//Is it a File?
|
||||||
|
if (t instanceof File)
|
||||||
|
{
|
||||||
|
tmpDir=(File)t;
|
||||||
|
if (tmpDir.isDirectory() && tmpDir.canWrite())
|
||||||
|
{
|
||||||
|
context.setTempDirectory(tmpDir);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// The context attribute specified a name not a File
|
||||||
|
if (t instanceof String)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
tmpDir=new File((String)t);
|
||||||
|
|
||||||
|
if (tmpDir.isDirectory() && tmpDir.canWrite())
|
||||||
|
{
|
||||||
|
context.setAttribute(context.TEMPDIR,tmpDir);
|
||||||
|
context.setTempDirectory(tmpDir);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch(Exception e)
|
||||||
|
{
|
||||||
|
Log.warn(Log.EXCEPTION,e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Second ... make a tmp directory, in a work directory if one exists
|
||||||
|
String temp = getCanonicalNameForWebAppTmpDir(context);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
//Put the tmp dir in the work directory if we had one
|
||||||
|
File work = new File(System.getProperty("jetty.home"),"work");
|
||||||
|
if (!work.exists() || !work.canWrite() || !work.isDirectory())
|
||||||
|
work = null;
|
||||||
|
|
||||||
|
if (work!=null)
|
||||||
|
makeTempDirectory(work, context, false); //make a tmp dir inside work, don't delete if it exists
|
||||||
|
else
|
||||||
|
makeTempDirectory(new File(System.getProperty("java.io.tmpdir")), context, true); //make a tmpdir, delete if it already exists
|
||||||
|
}
|
||||||
|
catch(Exception e)
|
||||||
|
{
|
||||||
|
tmpDir=null;
|
||||||
|
Log.ignore(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Third ... Something went wrong trying to make the tmp directory, just make
|
||||||
|
//a jvm managed tmp directory
|
||||||
|
if (context.getTempDirectory() == null)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Last resort
|
||||||
|
tmpDir=File.createTempFile("JettyContext","");
|
||||||
|
if (tmpDir.exists())
|
||||||
|
tmpDir.delete();
|
||||||
|
tmpDir.mkdir();
|
||||||
|
tmpDir.deleteOnExit();
|
||||||
|
setTempDirectory(tmpDir, context);
|
||||||
|
}
|
||||||
|
catch(IOException e)
|
||||||
|
{
|
||||||
|
Log.warn("tmpdir",e); System.exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void makeTempDirectory (File parent, WebAppContext context, boolean deleteExisting)
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
if (parent != null && parent.exists() && parent.canWrite() && parent.isDirectory())
|
||||||
|
{
|
||||||
|
String temp = getCanonicalNameForWebAppTmpDir(context);
|
||||||
|
File tmpDir = new File(parent,temp);
|
||||||
|
|
||||||
|
if (deleteExisting && tmpDir.exists())
|
||||||
|
{
|
||||||
|
if (!IO.delete(tmpDir))
|
||||||
|
{
|
||||||
|
if(Log.isDebugEnabled())Log.debug("Failed to delete temp dir "+tmpDir);
|
||||||
|
}
|
||||||
|
|
||||||
|
//If we can't delete the existing tmp dir, create a new one
|
||||||
|
if (tmpDir.exists())
|
||||||
|
{
|
||||||
|
String old=tmpDir.toString();
|
||||||
|
tmpDir=File.createTempFile(temp+"_","");
|
||||||
|
if (tmpDir.exists())
|
||||||
|
tmpDir.delete();
|
||||||
|
Log.warn("Can't reuse "+old+", using "+tmpDir);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!tmpDir.exists())
|
||||||
|
tmpDir.mkdir();
|
||||||
|
|
||||||
|
//If the parent is not a work directory
|
||||||
|
if (!isTempWorkDirectory(tmpDir))
|
||||||
|
{
|
||||||
|
tmpDir.deleteOnExit();
|
||||||
|
//TODO why is this here?
|
||||||
|
File sentinel = new File(tmpDir, ".active");
|
||||||
|
if(!sentinel.exists())
|
||||||
|
sentinel.mkdir();
|
||||||
|
}
|
||||||
|
setTempDirectory(tmpDir, context);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------------- */
|
|
||||||
public void deconfigureWebApp() throws Exception
|
public void setTempDirectory (File tmpDir, WebAppContext context)
|
||||||
{
|
{
|
||||||
|
context.setAttribute(TEMPDIR_CREATED, Boolean.TRUE);
|
||||||
|
context.setAttribute(context.TEMPDIR,tmpDir);
|
||||||
|
context.setTempDirectory(tmpDir);
|
||||||
|
if(Log.isDebugEnabled())Log.debug("Set temp dir "+tmpDir);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void unpack (WebAppContext context) throws IOException
|
||||||
|
{
|
||||||
|
Resource web_app = context.getBaseResource();
|
||||||
|
if (web_app == null)
|
||||||
|
{
|
||||||
|
String war = context.getWar();
|
||||||
|
if (war==null || war.length()==0)
|
||||||
|
war=context.getResourceBase();
|
||||||
|
|
||||||
|
// Set dir or WAR
|
||||||
|
web_app = context.newResource(war);
|
||||||
|
|
||||||
|
// Accept aliases for WAR files
|
||||||
|
if (web_app.getAlias() != null)
|
||||||
|
{
|
||||||
|
Log.debug(web_app + " anti-aliased to " + web_app.getAlias());
|
||||||
|
web_app = context.newResource(web_app.getAlias());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Log.isDebugEnabled())
|
||||||
|
Log.debug("Try webapp=" + web_app + ", exists=" + web_app.exists() + ", directory=" + web_app.isDirectory());
|
||||||
|
|
||||||
|
// Is the WAR usable directly?
|
||||||
|
if (web_app.exists() && !web_app.isDirectory() && !web_app.toString().startsWith("jar:"))
|
||||||
|
{
|
||||||
|
// No - then lets see if it can be turned into a jar URL.
|
||||||
|
Resource jarWebApp = context.newResource("jar:" + web_app + "!/");
|
||||||
|
if (jarWebApp.exists() && jarWebApp.isDirectory())
|
||||||
|
{
|
||||||
|
web_app= jarWebApp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we should extract or the URL is still not usable
|
||||||
|
if (web_app.exists() &&
|
||||||
|
(
|
||||||
|
(context.isCopyWebDir() && web_app.getFile()!= null && web_app.getFile().isDirectory())
|
||||||
|
||
|
||||||
|
(context.isExtractWAR() && web_app.getFile()!= null && !web_app.getFile().isDirectory())
|
||||||
|
||
|
||||||
|
(context.isExtractWAR() && web_app.getFile() == null)
|
||||||
|
||
|
||||||
|
!web_app.isDirectory()
|
||||||
|
))
|
||||||
|
{
|
||||||
|
// Then extract it if necessary to the temporary location
|
||||||
|
File extractedWebAppDir= new File(context.getTempDirectory(), "webapp");
|
||||||
|
|
||||||
|
if (web_app.getFile()!=null && web_app.getFile().isDirectory())
|
||||||
|
{
|
||||||
|
// Copy directory
|
||||||
|
Log.info("Copy " + web_app.getFile() + " to " + extractedWebAppDir);
|
||||||
|
IO.copyDir(web_app.getFile(),extractedWebAppDir);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!extractedWebAppDir.exists())
|
||||||
|
{
|
||||||
|
//it hasn't been extracted before so extract it
|
||||||
|
extractedWebAppDir.mkdir();
|
||||||
|
Log.info("Extract " + war + " to " + extractedWebAppDir);
|
||||||
|
JarResource.extract(web_app, extractedWebAppDir, false);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//only extract if the war file is newer
|
||||||
|
if (web_app.lastModified() > extractedWebAppDir.lastModified())
|
||||||
|
{
|
||||||
|
extractedWebAppDir.delete();
|
||||||
|
extractedWebAppDir.mkdir();
|
||||||
|
Log.info("Extract " + war + " to " + extractedWebAppDir);
|
||||||
|
JarResource.extract(web_app, extractedWebAppDir, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
web_app = Resource.newResource(extractedWebAppDir.getCanonicalPath());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now do we have something usable?
|
||||||
|
if (!web_app.exists() || !web_app.isDirectory())
|
||||||
|
{
|
||||||
|
Log.warn("Web application not found " + war);
|
||||||
|
throw new java.io.FileNotFoundException(war);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
context.setBaseResource(web_app);
|
||||||
|
System.err.println("SetBaseResource in WebInfConfiguration, toString="+context.toString());
|
||||||
|
|
||||||
|
|
||||||
|
if (Log.isDebugEnabled())
|
||||||
|
Log.debug("webapp=" + web_app);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public File findWorkDirectory (WebAppContext context) throws IOException
|
||||||
|
{
|
||||||
|
if (context.getBaseResource() != null)
|
||||||
|
{
|
||||||
|
Resource web_inf = context.getWebInf();
|
||||||
|
if (web_inf !=null && web_inf.exists())
|
||||||
|
{
|
||||||
|
return new File(web_inf.getFile(),"work");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the tmpDir itself is called "work", or if the tmpDir
|
||||||
|
* is in a directory called "work".
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public boolean isTempWorkDirectory (File tmpDir)
|
||||||
|
{
|
||||||
|
if (tmpDir == null)
|
||||||
|
return false;
|
||||||
|
if (tmpDir.getName().equalsIgnoreCase("work"))
|
||||||
|
return true;
|
||||||
|
File t = tmpDir.getParentFile();
|
||||||
|
if (t == null)
|
||||||
|
return false;
|
||||||
|
return (t.getName().equalsIgnoreCase("work"));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a canonical name for a webapp tmp directory.
|
||||||
|
* The form of the name is:
|
||||||
|
* "Jetty_"+host+"_"+port+"__"+resourceBase+"_"+context+"_"+virtualhost+base36 hashcode of whole string
|
||||||
|
*
|
||||||
|
* host and port uniquely identify the server
|
||||||
|
* context and virtual host uniquely identify the webapp
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public String getCanonicalNameForWebAppTmpDir (WebAppContext context)
|
||||||
|
{
|
||||||
|
StringBuffer canonicalName = new StringBuffer();
|
||||||
|
canonicalName.append("Jetty");
|
||||||
|
|
||||||
|
//get the host and the port from the first connector
|
||||||
|
Connector[] connectors = context.getServer().getConnectors();
|
||||||
|
|
||||||
|
|
||||||
|
//Get the host
|
||||||
|
canonicalName.append("_");
|
||||||
|
String host = (connectors==null||connectors[0]==null?"":connectors[0].getHost());
|
||||||
|
if (host == null)
|
||||||
|
host = "0.0.0.0";
|
||||||
|
canonicalName.append(host.replace('.', '_'));
|
||||||
|
|
||||||
|
//Get the port
|
||||||
|
canonicalName.append("_");
|
||||||
|
//try getting the real port being listened on
|
||||||
|
int port = (connectors==null||connectors[0]==null?0:connectors[0].getLocalPort());
|
||||||
|
//if not available (eg no connectors or connector not started),
|
||||||
|
//try getting one that was configured.
|
||||||
|
if (port < 0)
|
||||||
|
port = connectors[0].getPort();
|
||||||
|
canonicalName.append(port);
|
||||||
|
|
||||||
|
|
||||||
|
//Resource base
|
||||||
|
canonicalName.append("_");
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Resource resource = context.getBaseResource();
|
||||||
|
if (resource == null)
|
||||||
|
{
|
||||||
|
if (context.getWar()==null || context.getWar().length()==0)
|
||||||
|
resource=context.newResource(context.getResourceBase());
|
||||||
|
|
||||||
|
// Set dir or WAR
|
||||||
|
resource = context.newResource(context.getWar());
|
||||||
|
}
|
||||||
|
|
||||||
|
String tmp = URIUtil.decodePath(resource.getURL().getPath());
|
||||||
|
if (tmp.endsWith("/"))
|
||||||
|
tmp = tmp.substring(0, tmp.length()-1);
|
||||||
|
if (tmp.endsWith("!"))
|
||||||
|
tmp = tmp.substring(0, tmp.length() -1);
|
||||||
|
//get just the last part which is the filename
|
||||||
|
int i = tmp.lastIndexOf("/");
|
||||||
|
canonicalName.append(tmp.substring(i+1, tmp.length()));
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Log.warn("Can't generate resourceBase as part of webapp tmp dir name", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Context name
|
||||||
|
canonicalName.append("_");
|
||||||
|
String contextPath = context.getContextPath();
|
||||||
|
contextPath=contextPath.replace('/','_');
|
||||||
|
contextPath=contextPath.replace('\\','_');
|
||||||
|
canonicalName.append(contextPath);
|
||||||
|
|
||||||
|
//Virtual host (if there is one)
|
||||||
|
canonicalName.append("_");
|
||||||
|
String[] vhosts = context.getVirtualHosts();
|
||||||
|
canonicalName.append((vhosts==null||vhosts[0]==null?"":vhosts[0]));
|
||||||
|
|
||||||
|
//base36 hash of the whole string for uniqueness
|
||||||
|
String hash = Integer.toString(canonicalName.toString().hashCode(),36);
|
||||||
|
canonicalName.append("_");
|
||||||
|
canonicalName.append(hash);
|
||||||
|
|
||||||
|
// sanitize
|
||||||
|
for (int i=0;i<canonicalName.length();i++)
|
||||||
|
{
|
||||||
|
char c=canonicalName.charAt(i);
|
||||||
|
if (!Character.isJavaIdentifierPart(c))
|
||||||
|
canonicalName.setCharAt(i,'.');
|
||||||
|
}
|
||||||
|
|
||||||
|
return canonicalName.toString();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,954 @@
|
||||||
|
// ========================================================================
|
||||||
|
// Copyright (c) 2009 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.webapp;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.EventListener;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import javax.servlet.Servlet;
|
||||||
|
import javax.servlet.UnavailableException;
|
||||||
|
|
||||||
|
import org.eclipse.jetty.http.security.Constraint;
|
||||||
|
import org.eclipse.jetty.security.ConstraintAware;
|
||||||
|
import org.eclipse.jetty.security.ConstraintMapping;
|
||||||
|
import org.eclipse.jetty.security.SecurityHandler;
|
||||||
|
import org.eclipse.jetty.security.authentication.FormAuthenticator;
|
||||||
|
import org.eclipse.jetty.servlet.ErrorPageErrorHandler;
|
||||||
|
import org.eclipse.jetty.servlet.FilterHolder;
|
||||||
|
import org.eclipse.jetty.servlet.FilterMapping;
|
||||||
|
import org.eclipse.jetty.servlet.ServletHandler;
|
||||||
|
import org.eclipse.jetty.servlet.ServletHolder;
|
||||||
|
import org.eclipse.jetty.servlet.ServletMapping;
|
||||||
|
import org.eclipse.jetty.util.LazyList;
|
||||||
|
import org.eclipse.jetty.util.Loader;
|
||||||
|
import org.eclipse.jetty.util.log.Log;
|
||||||
|
import org.eclipse.jetty.util.resource.Resource;
|
||||||
|
import org.eclipse.jetty.xml.XmlParser;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* WebXmlProcessor
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class WebXmlProcessor
|
||||||
|
{
|
||||||
|
public static final String __web_processor = "org.eclipse.jetty.webProcessor";
|
||||||
|
|
||||||
|
protected WebAppContext _context;
|
||||||
|
protected XmlParser _xmlParser;
|
||||||
|
protected XmlParser.Node _webDefaultsRoot;
|
||||||
|
protected XmlParser.Node _webXmlRoot;
|
||||||
|
protected List<XmlParser.Node> _webFragmentRoots = new ArrayList<XmlParser.Node>();
|
||||||
|
protected XmlParser.Node _webOverrideRoot;
|
||||||
|
protected int _version;
|
||||||
|
protected boolean _metaDataComplete = false;
|
||||||
|
|
||||||
|
protected ServletHandler _servletHandler;
|
||||||
|
protected SecurityHandler _securityHandler;
|
||||||
|
protected Object _filters;
|
||||||
|
protected Object _filterMappings;
|
||||||
|
protected Object _servlets;
|
||||||
|
protected Object _servletMappings;
|
||||||
|
protected Object _listeners;
|
||||||
|
protected Object _welcomeFiles;
|
||||||
|
protected Set<String> _roles = new HashSet<String>();
|
||||||
|
protected Object _constraintMappings;
|
||||||
|
protected Map _errorPages;
|
||||||
|
protected boolean _hasJSP;
|
||||||
|
protected String _jspServletName;
|
||||||
|
protected String _jspServletClass;
|
||||||
|
protected boolean _defaultWelcomeFileList;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public static XmlParser webXmlParser() throws ClassNotFoundException
|
||||||
|
{
|
||||||
|
XmlParser xmlParser=new XmlParser();
|
||||||
|
//set up cache of DTDs and schemas locally
|
||||||
|
URL dtd22=Loader.getResource(Servlet.class,"javax/servlet/resources/web-app_2_2.dtd",true);
|
||||||
|
URL dtd23=Loader.getResource(Servlet.class,"javax/servlet/resources/web-app_2_3.dtd",true);
|
||||||
|
URL j2ee14xsd=Loader.getResource(Servlet.class,"javax/servlet/resources/j2ee_1_4.xsd",true);
|
||||||
|
URL webapp24xsd=Loader.getResource(Servlet.class,"javax/servlet/resources/web-app_2_4.xsd",true);
|
||||||
|
URL webapp25xsd=Loader.getResource(Servlet.class,"javax/servlet/resources/web-app_2_5.xsd",true);
|
||||||
|
URL webapp30xsd=Loader.getResource(Servlet.class,"javax/servlet/resources/web-app_3_0.xsd",true);
|
||||||
|
URL webcommon30xsd=Loader.getResource(Servlet.class,"javax/servlet/resources/web-common_3_0.xsd",true);
|
||||||
|
URL webfragment30xsd=Loader.getResource(Servlet.class,"javax/servlet/resources/web-fragment_3_0.xsd",true);
|
||||||
|
URL schemadtd=Loader.getResource(Servlet.class,"javax/servlet/resources/XMLSchema.dtd",true);
|
||||||
|
URL xmlxsd=Loader.getResource(Servlet.class,"javax/servlet/resources/xml.xsd",true);
|
||||||
|
URL webservice11xsd=Loader.getResource(Servlet.class,"javax/servlet/resources/j2ee_web_services_client_1_1.xsd",true);
|
||||||
|
URL webservice12xsd=Loader.getResource(Servlet.class,"javax/servlet/resources/javaee_web_services_client_1_2.xsd",true);
|
||||||
|
URL datatypesdtd=Loader.getResource(Servlet.class,"javax/servlet/resources/datatypes.dtd",true);
|
||||||
|
|
||||||
|
URL jsp20xsd = null;
|
||||||
|
URL jsp21xsd = null;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Class jsp_page = Loader.loadClass(WebXmlConfiguration.class, "javax.servlet.jsp.JspPage");
|
||||||
|
jsp20xsd = jsp_page.getResource("/javax/servlet/resources/jsp_2_0.xsd");
|
||||||
|
jsp21xsd = jsp_page.getResource("/javax/servlet/resources/jsp_2_1.xsd");
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Log.ignore(e);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
if (jsp20xsd == null) jsp20xsd = Loader.getResource(Servlet.class, "javax/servlet/resources/jsp_2_0.xsd", true);
|
||||||
|
if (jsp21xsd == null) jsp21xsd = Loader.getResource(Servlet.class, "javax/servlet/resources/jsp_2_1.xsd", true);
|
||||||
|
}
|
||||||
|
|
||||||
|
redirect(xmlParser,"web-app_2_2.dtd",dtd22);
|
||||||
|
redirect(xmlParser,"-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN",dtd22);
|
||||||
|
redirect(xmlParser,"web.dtd",dtd23);
|
||||||
|
redirect(xmlParser,"web-app_2_3.dtd",dtd23);
|
||||||
|
redirect(xmlParser,"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN",dtd23);
|
||||||
|
redirect(xmlParser,"XMLSchema.dtd",schemadtd);
|
||||||
|
redirect(xmlParser,"http://www.w3.org/2001/XMLSchema.dtd",schemadtd);
|
||||||
|
redirect(xmlParser,"-//W3C//DTD XMLSCHEMA 200102//EN",schemadtd);
|
||||||
|
redirect(xmlParser,"jsp_2_0.xsd",jsp20xsd);
|
||||||
|
redirect(xmlParser,"http://java.sun.com/xml/ns/j2ee/jsp_2_0.xsd",jsp20xsd);
|
||||||
|
redirect(xmlParser,"jsp_2_1.xsd",jsp21xsd);
|
||||||
|
redirect(xmlParser,"http://java.sun.com/xml/ns/javaee/jsp_2_1.xsd",jsp21xsd);
|
||||||
|
redirect(xmlParser,"j2ee_1_4.xsd",j2ee14xsd);
|
||||||
|
redirect(xmlParser,"http://java.sun.com/xml/ns/j2ee/j2ee_1_4.xsd",j2ee14xsd);
|
||||||
|
redirect(xmlParser,"web-app_2_4.xsd",webapp24xsd);
|
||||||
|
redirect(xmlParser,"http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd",webapp24xsd);
|
||||||
|
redirect(xmlParser,"web-app_2_5.xsd",webapp25xsd);
|
||||||
|
redirect(xmlParser,"http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd",webapp25xsd);
|
||||||
|
redirect(xmlParser,"web-app_3_0.xsd",webapp30xsd);
|
||||||
|
redirect(xmlParser,"http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd",webapp30xsd);
|
||||||
|
redirect(xmlParser,"web-common_3_0.xsd",webcommon30xsd);
|
||||||
|
redirect(xmlParser,"http://java.sun.com/xml/ns/javaee/web-common_3_0.xsd",webcommon30xsd);
|
||||||
|
redirect(xmlParser,"web-fragment_3_0.xsd",webfragment30xsd);
|
||||||
|
redirect(xmlParser,"http://java.sun.com/xml/ns/javaee/web-fragment_3_0.xsd",webfragment30xsd);
|
||||||
|
redirect(xmlParser,"xml.xsd",xmlxsd);
|
||||||
|
redirect(xmlParser,"http://www.w3.org/2001/xml.xsd",xmlxsd);
|
||||||
|
redirect(xmlParser,"datatypes.dtd",datatypesdtd);
|
||||||
|
redirect(xmlParser,"http://www.w3.org/2001/datatypes.dtd",datatypesdtd);
|
||||||
|
redirect(xmlParser,"j2ee_web_services_client_1_1.xsd",webservice11xsd);
|
||||||
|
redirect(xmlParser,"http://www.ibm.com/webservices/xsd/j2ee_web_services_client_1_1.xsd",webservice11xsd);
|
||||||
|
redirect(xmlParser,"javaee_web_services_client_1_2.xsd",webservice12xsd);
|
||||||
|
redirect(xmlParser,"http://www.ibm.com/webservices/xsd/javaee_web_services_client_1_2.xsd",webservice12xsd);
|
||||||
|
|
||||||
|
return xmlParser;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------------- */
|
||||||
|
protected static void redirect(XmlParser parser, String resource, URL source)
|
||||||
|
{
|
||||||
|
if (source != null) parser.redirectEntity(resource, source);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public WebXmlProcessor (WebAppContext context) throws ClassNotFoundException
|
||||||
|
{
|
||||||
|
_context = context;
|
||||||
|
_xmlParser = webXmlParser();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public int getVersion ()
|
||||||
|
{
|
||||||
|
return _version;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isMetaDataComplete ()
|
||||||
|
{
|
||||||
|
return _metaDataComplete;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void processForVersion (XmlParser.Node config)
|
||||||
|
{
|
||||||
|
String version = config.getAttribute("version", "DTD");
|
||||||
|
if ("2.5".equals(version))
|
||||||
|
_version = 25;
|
||||||
|
else if ("2.4".equals(version))
|
||||||
|
_version = 24;
|
||||||
|
else if ("3.0".equals(version))
|
||||||
|
_version = 30;
|
||||||
|
else if ("DTD".equals(version))
|
||||||
|
{
|
||||||
|
_version = 23;
|
||||||
|
String dtd = _xmlParser.getDTD();
|
||||||
|
if (dtd != null && dtd.indexOf("web-app_2_2") >= 0) _version = 22;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_version < 25)
|
||||||
|
_metaDataComplete = true; // does not apply before 2.5
|
||||||
|
else
|
||||||
|
_metaDataComplete = Boolean.valueOf((String) config.getAttribute("metadata-complete", "false")).booleanValue();
|
||||||
|
|
||||||
|
Log.debug("Calculated metadatacomplete = " + _metaDataComplete + " with version=" + version);
|
||||||
|
|
||||||
|
_context.setAttribute("metadata-complete", String.valueOf(_metaDataComplete));
|
||||||
|
}
|
||||||
|
|
||||||
|
public XmlParser.Node parseDefaults (URL webDefaults)
|
||||||
|
throws Exception
|
||||||
|
{
|
||||||
|
_webDefaultsRoot = _xmlParser.parse(webDefaults.toString());
|
||||||
|
return _webDefaultsRoot;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public XmlParser.Node parseWebXml (URL webXml)
|
||||||
|
throws Exception
|
||||||
|
{
|
||||||
|
_webXmlRoot = _xmlParser.parse(webXml.toString());
|
||||||
|
processForVersion(_webXmlRoot);
|
||||||
|
return _webXmlRoot;
|
||||||
|
}
|
||||||
|
|
||||||
|
public XmlParser.Node parseFragment (URL fragment)
|
||||||
|
throws Exception
|
||||||
|
{
|
||||||
|
if (isMetaDataComplete())
|
||||||
|
return null; //do not process anything else if main web.xml file is complete
|
||||||
|
|
||||||
|
//Metadata-complete is not set, or there is no web.xml
|
||||||
|
XmlParser.Node root = _xmlParser.parse(fragment.toString());
|
||||||
|
_webFragmentRoots.add(root);
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
|
||||||
|
public XmlParser.Node parseOverride (URL override)
|
||||||
|
throws Exception
|
||||||
|
{
|
||||||
|
_xmlParser.setValidating(false);
|
||||||
|
_webOverrideRoot = _xmlParser.parse(override.toString());
|
||||||
|
return _webOverrideRoot;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void processDefaults ()
|
||||||
|
throws Exception
|
||||||
|
{
|
||||||
|
process (_webDefaultsRoot);
|
||||||
|
_defaultWelcomeFileList = _context.getWelcomeFiles() != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void processWebXml ()
|
||||||
|
throws Exception
|
||||||
|
{
|
||||||
|
process (_webXmlRoot);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void processFragments ()
|
||||||
|
throws Exception
|
||||||
|
{
|
||||||
|
for (XmlParser.Node frag : _webFragmentRoots)
|
||||||
|
{
|
||||||
|
process (frag);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void processOverride ()
|
||||||
|
throws Exception
|
||||||
|
{
|
||||||
|
process(_webOverrideRoot);
|
||||||
|
}
|
||||||
|
|
||||||
|
public XmlParser.Node getWebXml ()
|
||||||
|
{
|
||||||
|
return _webXmlRoot;
|
||||||
|
}
|
||||||
|
|
||||||
|
public XmlParser.Node getOverrideWeb ()
|
||||||
|
{
|
||||||
|
return _webOverrideRoot;
|
||||||
|
}
|
||||||
|
|
||||||
|
public XmlParser.Node getWebDefault ()
|
||||||
|
{
|
||||||
|
return _webDefaultsRoot;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<XmlParser.Node> getFragments ()
|
||||||
|
{
|
||||||
|
return _webFragmentRoots;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void process (XmlParser.Node config)
|
||||||
|
throws Exception
|
||||||
|
{
|
||||||
|
//Get the current objects from the context
|
||||||
|
_servletHandler = _context.getServletHandler();
|
||||||
|
_securityHandler = (SecurityHandler)_context.getSecurityHandler();
|
||||||
|
_filters = LazyList.array2List(_servletHandler.getFilters());
|
||||||
|
_filterMappings = LazyList.array2List(_servletHandler.getFilterMappings());
|
||||||
|
_servlets = LazyList.array2List(_servletHandler.getServlets());
|
||||||
|
_servletMappings = LazyList.array2List(_servletHandler.getServletMappings());
|
||||||
|
_listeners = LazyList.array2List(_context.getEventListeners());
|
||||||
|
_welcomeFiles = LazyList.array2List(_context.getWelcomeFiles());
|
||||||
|
if (_securityHandler instanceof ConstraintAware)
|
||||||
|
{
|
||||||
|
_constraintMappings = LazyList.array2List(((ConstraintAware) _securityHandler).getConstraintMappings());
|
||||||
|
|
||||||
|
if (((ConstraintAware) _securityHandler).getRoles() != null)
|
||||||
|
{
|
||||||
|
_roles.addAll(((ConstraintAware) _securityHandler).getRoles());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_errorPages = _context.getErrorHandler() instanceof ErrorPageErrorHandler ? ((ErrorPageErrorHandler)_context.getErrorHandler()).getErrorPages() : null;
|
||||||
|
|
||||||
|
Iterator iter = config.iterator();
|
||||||
|
XmlParser.Node node = null;
|
||||||
|
while (iter.hasNext())
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Object o = iter.next();
|
||||||
|
if (!(o instanceof XmlParser.Node)) continue;
|
||||||
|
node = (XmlParser.Node) o;
|
||||||
|
String name = node.getTag();
|
||||||
|
initWebXmlElement(name, node);
|
||||||
|
}
|
||||||
|
catch (ClassNotFoundException e)
|
||||||
|
{
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Log.warn("Configuration problem at " + node, e);
|
||||||
|
throw new UnavailableException("Configuration problem");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Set the context with the results of the processing
|
||||||
|
_servletHandler.setFilters((FilterHolder[]) LazyList.toArray(_filters, FilterHolder.class));
|
||||||
|
_servletHandler.setFilterMappings((FilterMapping[]) LazyList.toArray(_filterMappings, FilterMapping.class));
|
||||||
|
_servletHandler.setServlets((ServletHolder[]) LazyList.toArray(_servlets, ServletHolder.class));
|
||||||
|
_servletHandler.setServletMappings((ServletMapping[]) LazyList.toArray(_servletMappings, ServletMapping.class));
|
||||||
|
_context.setEventListeners((EventListener[]) LazyList.toArray(_listeners, EventListener.class));
|
||||||
|
_context.setWelcomeFiles((String[]) LazyList.toArray(_welcomeFiles, String.class));
|
||||||
|
// TODO jaspi check this
|
||||||
|
if (_securityHandler instanceof ConstraintAware)
|
||||||
|
{
|
||||||
|
((ConstraintAware) _securityHandler).setConstraintMappings((ConstraintMapping[]) LazyList.toArray(_constraintMappings,
|
||||||
|
ConstraintMapping.class),
|
||||||
|
_roles);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_errorPages != null && _context.getErrorHandler() instanceof ErrorPageErrorHandler)
|
||||||
|
((ErrorPageErrorHandler)_context.getErrorHandler()).setErrorPages(_errorPages);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
/**
|
||||||
|
* Handle web.xml element. This method is called for each top level element
|
||||||
|
* within the web.xml file. It may be specialized by derived WebAppHandlers
|
||||||
|
* to provide additional configuration and handling.
|
||||||
|
*
|
||||||
|
* @param element The element name
|
||||||
|
* @param node The node containing the element.
|
||||||
|
*/
|
||||||
|
protected void initWebXmlElement(String element, XmlParser.Node node) throws Exception
|
||||||
|
{
|
||||||
|
if ("display-name".equals(element))
|
||||||
|
initDisplayName(node);
|
||||||
|
else if ("description".equals(element))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
else if ("context-param".equals(element))
|
||||||
|
initContextParam(node);
|
||||||
|
else if ("servlet".equals(element))
|
||||||
|
initServlet(node);
|
||||||
|
else if ("servlet-mapping".equals(element))
|
||||||
|
initServletMapping(node);
|
||||||
|
else if ("session-config".equals(element))
|
||||||
|
initSessionConfig(node);
|
||||||
|
else if ("mime-mapping".equals(element))
|
||||||
|
initMimeConfig(node);
|
||||||
|
else if ("welcome-file-list".equals(element))
|
||||||
|
initWelcomeFileList(node);
|
||||||
|
else if ("locale-encoding-mapping-list".equals(element))
|
||||||
|
initLocaleEncodingList(node);
|
||||||
|
else if ("error-page".equals(element))
|
||||||
|
initErrorPage(node);
|
||||||
|
else if ("taglib".equals(element))
|
||||||
|
initTagLib(node);
|
||||||
|
else if ("jsp-config".equals(element))
|
||||||
|
initJspConfig(node);
|
||||||
|
else if ("resource-ref".equals(element))
|
||||||
|
{
|
||||||
|
if (Log.isDebugEnabled()) Log.debug("No implementation: " + node);
|
||||||
|
}
|
||||||
|
else if ("security-constraint".equals(element))
|
||||||
|
initSecurityConstraint(node);
|
||||||
|
else if ("login-config".equals(element))
|
||||||
|
initLoginConfig(node);
|
||||||
|
else if ("security-role".equals(element))
|
||||||
|
initSecurityRole(node);
|
||||||
|
else if ("filter".equals(element))
|
||||||
|
initFilter(node);
|
||||||
|
else if ("filter-mapping".equals(element))
|
||||||
|
initFilterMapping(node);
|
||||||
|
else if ("listener".equals(element))
|
||||||
|
initListener(node);
|
||||||
|
else if ("distributable".equals(element))
|
||||||
|
initDistributable(node);
|
||||||
|
else if ("web-fragment".equals(element))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (Log.isDebugEnabled())
|
||||||
|
{
|
||||||
|
Log.debug("Element {} not handled in {}", element, this);
|
||||||
|
Log.debug(node.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
protected void initDisplayName(XmlParser.Node node)
|
||||||
|
{
|
||||||
|
_context.setDisplayName(node.toString(false, true));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
protected void initContextParam(XmlParser.Node node)
|
||||||
|
{
|
||||||
|
String name = node.getString("param-name", false, true);
|
||||||
|
String value = node.getString("param-value", false, true);
|
||||||
|
if (Log.isDebugEnabled()) Log.debug("ContextParam: " + name + "=" + value);
|
||||||
|
_context.getInitParams().put(name, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
protected void initFilter(XmlParser.Node node)
|
||||||
|
{
|
||||||
|
String name = node.getString("filter-name", false, true);
|
||||||
|
FilterHolder holder = _servletHandler.getFilter(name);
|
||||||
|
if (holder == null)
|
||||||
|
{
|
||||||
|
holder = _servletHandler.newFilterHolder();
|
||||||
|
holder.setName(name);
|
||||||
|
_filters = LazyList.add(_filters, holder);
|
||||||
|
}
|
||||||
|
|
||||||
|
String filter_class = node.getString("filter-class", false, true);
|
||||||
|
if (filter_class != null) holder.setClassName(filter_class);
|
||||||
|
|
||||||
|
Iterator iter = node.iterator("init-param");
|
||||||
|
while (iter.hasNext())
|
||||||
|
{
|
||||||
|
XmlParser.Node paramNode = (XmlParser.Node) iter.next();
|
||||||
|
String pname = paramNode.getString("param-name", false, true);
|
||||||
|
String pvalue = paramNode.getString("param-value", false, true);
|
||||||
|
holder.setInitParameter(pname, pvalue);
|
||||||
|
}
|
||||||
|
|
||||||
|
String async=node.getString("async-support",false,true);
|
||||||
|
if (async!=null)
|
||||||
|
holder.setAsyncSupported(Boolean.valueOf(async));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
protected void initFilterMapping(XmlParser.Node node)
|
||||||
|
{
|
||||||
|
String filter_name = node.getString("filter-name", false, true);
|
||||||
|
|
||||||
|
FilterMapping mapping = new FilterMapping();
|
||||||
|
|
||||||
|
mapping.setFilterName(filter_name);
|
||||||
|
|
||||||
|
ArrayList paths = new ArrayList();
|
||||||
|
Iterator iter = node.iterator("url-pattern");
|
||||||
|
while (iter.hasNext())
|
||||||
|
{
|
||||||
|
String p = ((XmlParser.Node) iter.next()).toString(false, true);
|
||||||
|
p = normalizePattern(p);
|
||||||
|
paths.add(p);
|
||||||
|
}
|
||||||
|
mapping.setPathSpecs((String[]) paths.toArray(new String[paths.size()]));
|
||||||
|
|
||||||
|
ArrayList names = new ArrayList();
|
||||||
|
iter = node.iterator("servlet-name");
|
||||||
|
while (iter.hasNext())
|
||||||
|
{
|
||||||
|
String n = ((XmlParser.Node) iter.next()).toString(false, true);
|
||||||
|
names.add(n);
|
||||||
|
}
|
||||||
|
mapping.setServletNames((String[]) names.toArray(new String[names.size()]));
|
||||||
|
|
||||||
|
int dispatcher=FilterMapping.DEFAULT;
|
||||||
|
iter=node.iterator("dispatcher");
|
||||||
|
while(iter.hasNext())
|
||||||
|
{
|
||||||
|
String d=((XmlParser.Node)iter.next()).toString(false,true);
|
||||||
|
dispatcher|=FilterMapping.dispatch(d);
|
||||||
|
}
|
||||||
|
mapping.setDispatches(dispatcher);
|
||||||
|
|
||||||
|
_filterMappings = LazyList.add(_filterMappings, mapping);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
protected String normalizePattern(String p)
|
||||||
|
{
|
||||||
|
if (p != null && p.length() > 0 && !p.startsWith("/") && !p.startsWith("*")) return "/" + p;
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
protected void initServlet(XmlParser.Node node)
|
||||||
|
{
|
||||||
|
String id = node.getAttribute("id");
|
||||||
|
|
||||||
|
// initialize holder
|
||||||
|
String servlet_name = node.getString("servlet-name", false, true);
|
||||||
|
ServletHolder holder = _servletHandler.getServlet(servlet_name);
|
||||||
|
if (holder == null)
|
||||||
|
{
|
||||||
|
holder = _servletHandler.newServletHolder();
|
||||||
|
holder.setName(servlet_name);
|
||||||
|
_servlets = LazyList.add(_servlets, holder);
|
||||||
|
}
|
||||||
|
|
||||||
|
// init params
|
||||||
|
Iterator iParamsIter = node.iterator("init-param");
|
||||||
|
while (iParamsIter.hasNext())
|
||||||
|
{
|
||||||
|
XmlParser.Node paramNode = (XmlParser.Node) iParamsIter.next();
|
||||||
|
String pname = paramNode.getString("param-name", false, true);
|
||||||
|
String pvalue = paramNode.getString("param-value", false, true);
|
||||||
|
holder.setInitParameter(pname, pvalue);
|
||||||
|
}
|
||||||
|
|
||||||
|
String servlet_class = node.getString("servlet-class", false, true);
|
||||||
|
|
||||||
|
// Handle JSP
|
||||||
|
if (id != null && id.equals("jsp"))
|
||||||
|
{
|
||||||
|
_jspServletName = servlet_name;
|
||||||
|
_jspServletClass = servlet_class;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Loader.loadClass(this.getClass(), servlet_class);
|
||||||
|
_hasJSP = true;
|
||||||
|
}
|
||||||
|
catch (ClassNotFoundException e)
|
||||||
|
{
|
||||||
|
Log.info("NO JSP Support for {}, did not find {}", _context.getContextPath(), servlet_class);
|
||||||
|
_hasJSP = false;
|
||||||
|
_jspServletClass = servlet_class = "org.eclipse.jetty.servlet.NoJspServlet";
|
||||||
|
}
|
||||||
|
if (holder.getInitParameter("scratchdir") == null)
|
||||||
|
{
|
||||||
|
File tmp = _context.getTempDirectory();
|
||||||
|
File scratch = new File(tmp, "jsp");
|
||||||
|
if (!scratch.exists()) scratch.mkdir();
|
||||||
|
holder.setInitParameter("scratchdir", scratch.getAbsolutePath());
|
||||||
|
|
||||||
|
if ("?".equals(holder.getInitParameter("classpath")))
|
||||||
|
{
|
||||||
|
String classpath = _context.getClassPath();
|
||||||
|
Log.debug("classpath=" + classpath);
|
||||||
|
if (classpath != null) holder.setInitParameter("classpath", classpath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (servlet_class != null) holder.setClassName(servlet_class);
|
||||||
|
|
||||||
|
// Handler JSP file
|
||||||
|
String jsp_file = node.getString("jsp-file", false, true);
|
||||||
|
if (jsp_file != null)
|
||||||
|
{
|
||||||
|
holder.setForcedPath(jsp_file);
|
||||||
|
holder.setClassName(_jspServletClass);
|
||||||
|
}
|
||||||
|
|
||||||
|
// handle startup
|
||||||
|
XmlParser.Node startup = node.get("load-on-startup");
|
||||||
|
if (startup != null)
|
||||||
|
{
|
||||||
|
String s = startup.toString(false, true).toLowerCase();
|
||||||
|
if (s.startsWith("t"))
|
||||||
|
{
|
||||||
|
Log.warn("Deprecated boolean load-on-startup. Please use integer");
|
||||||
|
holder.setInitOrder(1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int order = 0;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (s != null && s.trim().length() > 0) order = Integer.parseInt(s);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Log.warn("Cannot parse load-on-startup " + s + ". Please use integer");
|
||||||
|
Log.ignore(e);
|
||||||
|
}
|
||||||
|
holder.setInitOrder(order);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Iterator sRefsIter = node.iterator("security-role-ref");
|
||||||
|
while (sRefsIter.hasNext())
|
||||||
|
{
|
||||||
|
XmlParser.Node securityRef = (XmlParser.Node) sRefsIter.next();
|
||||||
|
String roleName = securityRef.getString("role-name", false, true);
|
||||||
|
String roleLink = securityRef.getString("role-link", false, true);
|
||||||
|
if (roleName != null && roleName.length() > 0 && roleLink != null && roleLink.length() > 0)
|
||||||
|
{
|
||||||
|
if (Log.isDebugEnabled()) Log.debug("link role " + roleName + " to " + roleLink + " for " + this);
|
||||||
|
holder.setUserRoleLink(roleName, roleLink);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Log.warn("Ignored invalid security-role-ref element: " + "servlet-name=" + holder.getName() + ", " + securityRef);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
XmlParser.Node run_as = node.get("run-as");
|
||||||
|
if (run_as != null)
|
||||||
|
{
|
||||||
|
String roleName = run_as.getString("role-name", false, true);
|
||||||
|
if (roleName != null)
|
||||||
|
holder.setRunAsRole(roleName);
|
||||||
|
}
|
||||||
|
|
||||||
|
String async=node.getString("async-support",false,true);
|
||||||
|
if (async!=null)
|
||||||
|
holder.setAsyncSupported(Boolean.valueOf(async));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
protected void initServletMapping(XmlParser.Node node)
|
||||||
|
{
|
||||||
|
String servlet_name = node.getString("servlet-name", false, true);
|
||||||
|
ServletMapping mapping = new ServletMapping();
|
||||||
|
mapping.setServletName(servlet_name);
|
||||||
|
|
||||||
|
ArrayList paths = new ArrayList();
|
||||||
|
Iterator iter = node.iterator("url-pattern");
|
||||||
|
while (iter.hasNext())
|
||||||
|
{
|
||||||
|
String p = ((XmlParser.Node) iter.next()).toString(false, true);
|
||||||
|
p = normalizePattern(p);
|
||||||
|
paths.add(p);
|
||||||
|
}
|
||||||
|
mapping.setPathSpecs((String[]) paths.toArray(new String[paths.size()]));
|
||||||
|
|
||||||
|
_servletMappings = LazyList.add(_servletMappings, mapping);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
protected void initListener(XmlParser.Node node)
|
||||||
|
{
|
||||||
|
String className = node.getString("listener-class", false, true);
|
||||||
|
Object listener = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Class listenerClass = _context.loadClass(className);
|
||||||
|
listener = newListenerInstance(listenerClass);
|
||||||
|
if (!(listener instanceof EventListener))
|
||||||
|
{
|
||||||
|
Log.warn("Not an EventListener: " + listener);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_listeners = LazyList.add(_listeners, listener);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Log.warn("Could not instantiate listener " + className, e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
protected Object newListenerInstance(Class clazz) throws InstantiationException, IllegalAccessException
|
||||||
|
{
|
||||||
|
return clazz.newInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
protected void initDistributable(XmlParser.Node node)
|
||||||
|
{
|
||||||
|
// the element has no content, so its simple presence
|
||||||
|
// indicates that the webapp is distributable...
|
||||||
|
if (!_context.isDistributable())
|
||||||
|
_context.setDistributable(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
protected void initSessionConfig(XmlParser.Node node)
|
||||||
|
{
|
||||||
|
XmlParser.Node tNode = node.get("session-timeout");
|
||||||
|
if (tNode != null)
|
||||||
|
{
|
||||||
|
int timeout = Integer.parseInt(tNode.toString(false, true));
|
||||||
|
_context.getSessionHandler().getSessionManager().setMaxInactiveInterval(timeout * 60);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
protected void initMimeConfig(XmlParser.Node node)
|
||||||
|
{
|
||||||
|
String extension = node.getString("extension", false, true);
|
||||||
|
if (extension != null && extension.startsWith(".")) extension = extension.substring(1);
|
||||||
|
String mimeType = node.getString("mime-type", false, true);
|
||||||
|
_context.getMimeTypes().addMimeMapping(extension, mimeType);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
protected void initWelcomeFileList(XmlParser.Node node)
|
||||||
|
{
|
||||||
|
if (_defaultWelcomeFileList)
|
||||||
|
_welcomeFiles = null; // erase welcome files from default web.xml
|
||||||
|
|
||||||
|
_defaultWelcomeFileList = false;
|
||||||
|
Iterator iter = node.iterator("welcome-file");
|
||||||
|
while (iter.hasNext())
|
||||||
|
{
|
||||||
|
XmlParser.Node indexNode = (XmlParser.Node) iter.next();
|
||||||
|
String welcome = indexNode.toString(false, true);
|
||||||
|
_welcomeFiles = LazyList.add(_welcomeFiles, welcome);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
protected void initLocaleEncodingList(XmlParser.Node node)
|
||||||
|
{
|
||||||
|
Iterator iter = node.iterator("locale-encoding-mapping");
|
||||||
|
while (iter.hasNext())
|
||||||
|
{
|
||||||
|
XmlParser.Node mapping = (XmlParser.Node) iter.next();
|
||||||
|
String locale = mapping.getString("locale", false, true);
|
||||||
|
String encoding = mapping.getString("encoding", false, true);
|
||||||
|
_context.addLocaleEncoding(locale, encoding);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
protected void initErrorPage(XmlParser.Node node)
|
||||||
|
{
|
||||||
|
String error = node.getString("error-code", false, true);
|
||||||
|
if (error == null || error.length() == 0) error = node.getString("exception-type", false, true);
|
||||||
|
String location = node.getString("location", false, true);
|
||||||
|
|
||||||
|
if (_errorPages == null)
|
||||||
|
_errorPages = new HashMap();
|
||||||
|
_errorPages.put(error, location);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
protected void initTagLib(XmlParser.Node node)
|
||||||
|
{
|
||||||
|
String uri = node.getString("taglib-uri", false, true);
|
||||||
|
String location = node.getString("taglib-location", false, true);
|
||||||
|
|
||||||
|
_context.setResourceAlias(uri, location);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
protected void initJspConfig(XmlParser.Node node)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < node.size(); i++)
|
||||||
|
{
|
||||||
|
Object o = node.get(i);
|
||||||
|
if (o instanceof XmlParser.Node && "taglib".equals(((XmlParser.Node) o).getTag())) initTagLib((XmlParser.Node) o);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Map URLs from jsp property groups to JSP servlet.
|
||||||
|
// this is more JSP stupidness creaping into the servlet spec
|
||||||
|
Iterator iter = node.iterator("jsp-property-group");
|
||||||
|
Object paths = null;
|
||||||
|
while (iter.hasNext())
|
||||||
|
{
|
||||||
|
XmlParser.Node group = (XmlParser.Node) iter.next();
|
||||||
|
Iterator iter2 = group.iterator("url-pattern");
|
||||||
|
while (iter2.hasNext())
|
||||||
|
{
|
||||||
|
String url = ((XmlParser.Node) iter2.next()).toString(false, true);
|
||||||
|
url = normalizePattern(url);
|
||||||
|
paths = LazyList.add(paths, url);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (LazyList.size(paths) > 0)
|
||||||
|
{
|
||||||
|
String jspName = getJSPServletName();
|
||||||
|
if (jspName != null)
|
||||||
|
{
|
||||||
|
ServletMapping mapping = new ServletMapping();
|
||||||
|
mapping.setServletName(jspName);
|
||||||
|
mapping.setPathSpecs(LazyList.toStringArray(paths));
|
||||||
|
_servletMappings = LazyList.add(_servletMappings, mapping);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
protected void initSecurityConstraint(XmlParser.Node node)
|
||||||
|
{
|
||||||
|
Constraint scBase = new Constraint();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
XmlParser.Node auths = node.get("auth-constraint");
|
||||||
|
|
||||||
|
if (auths != null)
|
||||||
|
{
|
||||||
|
scBase.setAuthenticate(true);
|
||||||
|
// auth-constraint
|
||||||
|
Iterator iter = auths.iterator("role-name");
|
||||||
|
Object roles = null;
|
||||||
|
while (iter.hasNext())
|
||||||
|
{
|
||||||
|
String role = ((XmlParser.Node) iter.next()).toString(false, true);
|
||||||
|
roles = LazyList.add(roles, role);
|
||||||
|
}
|
||||||
|
scBase.setRoles(LazyList.toStringArray(roles));
|
||||||
|
}
|
||||||
|
|
||||||
|
XmlParser.Node data = node.get("user-data-constraint");
|
||||||
|
if (data != null)
|
||||||
|
{
|
||||||
|
data = data.get("transport-guarantee");
|
||||||
|
String guarantee = data.toString(false, true).toUpperCase();
|
||||||
|
if (guarantee == null || guarantee.length() == 0 || "NONE".equals(guarantee))
|
||||||
|
scBase.setDataConstraint(Constraint.DC_NONE);
|
||||||
|
else if ("INTEGRAL".equals(guarantee))
|
||||||
|
scBase.setDataConstraint(Constraint.DC_INTEGRAL);
|
||||||
|
else if ("CONFIDENTIAL".equals(guarantee))
|
||||||
|
scBase.setDataConstraint(Constraint.DC_CONFIDENTIAL);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Log.warn("Unknown user-data-constraint:" + guarantee);
|
||||||
|
scBase.setDataConstraint(Constraint.DC_CONFIDENTIAL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Iterator iter = node.iterator("web-resource-collection");
|
||||||
|
while (iter.hasNext())
|
||||||
|
{
|
||||||
|
XmlParser.Node collection = (XmlParser.Node) iter.next();
|
||||||
|
String name = collection.getString("web-resource-name", false, true);
|
||||||
|
Constraint sc = (Constraint) scBase.clone();
|
||||||
|
sc.setName(name);
|
||||||
|
|
||||||
|
Iterator iter2 = collection.iterator("url-pattern");
|
||||||
|
while (iter2.hasNext())
|
||||||
|
{
|
||||||
|
String url = ((XmlParser.Node) iter2.next()).toString(false, true);
|
||||||
|
url = normalizePattern(url);
|
||||||
|
|
||||||
|
Iterator iter3 = collection.iterator("http-method");
|
||||||
|
if (iter3.hasNext())
|
||||||
|
{
|
||||||
|
while (iter3.hasNext())
|
||||||
|
{
|
||||||
|
String method = ((XmlParser.Node) iter3.next()).toString(false, true);
|
||||||
|
ConstraintMapping mapping = new ConstraintMapping();
|
||||||
|
mapping.setMethod(method);
|
||||||
|
mapping.setPathSpec(url);
|
||||||
|
mapping.setConstraint(sc);
|
||||||
|
_constraintMappings = LazyList.add(_constraintMappings, mapping);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ConstraintMapping mapping = new ConstraintMapping();
|
||||||
|
mapping.setPathSpec(url);
|
||||||
|
mapping.setConstraint(sc);
|
||||||
|
_constraintMappings = LazyList.add(_constraintMappings, mapping);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (CloneNotSupportedException e)
|
||||||
|
{
|
||||||
|
Log.warn(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
protected void initLoginConfig(XmlParser.Node node) throws Exception
|
||||||
|
{
|
||||||
|
XmlParser.Node method = node.get("auth-method");
|
||||||
|
if (method != null)
|
||||||
|
{
|
||||||
|
XmlParser.Node name = node.get("realm-name");
|
||||||
|
_securityHandler.setRealmName(name == null ? "default" : name.toString(false, true));
|
||||||
|
_securityHandler.setAuthMethod(method.toString(false, true));
|
||||||
|
|
||||||
|
|
||||||
|
if (Constraint.__FORM_AUTH.equals(_securityHandler.getAuthMethod()))
|
||||||
|
{
|
||||||
|
XmlParser.Node formConfig = node.get("form-login-config");
|
||||||
|
if (formConfig != null)
|
||||||
|
{
|
||||||
|
String loginPageName = null;
|
||||||
|
XmlParser.Node loginPage = formConfig.get("form-login-page");
|
||||||
|
if (loginPage != null)
|
||||||
|
loginPageName = loginPage.toString(false, true);
|
||||||
|
String errorPageName = null;
|
||||||
|
XmlParser.Node errorPage = formConfig.get("form-error-page");
|
||||||
|
if (errorPage != null)
|
||||||
|
errorPageName = errorPage.toString(false, true);
|
||||||
|
_securityHandler.setInitParameter(FormAuthenticator.__FORM_LOGIN_PAGE,loginPageName);
|
||||||
|
_securityHandler.setInitParameter(FormAuthenticator.__FORM_ERROR_PAGE,errorPageName);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new IllegalArgumentException("!form-login-config");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
protected void initSecurityRole(XmlParser.Node node)
|
||||||
|
{
|
||||||
|
XmlParser.Node roleNode = node.get("role-name");
|
||||||
|
String role = roleNode.toString(false, true);
|
||||||
|
_roles.add(role);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
protected String getJSPServletName()
|
||||||
|
{
|
||||||
|
if (_jspServletName == null)
|
||||||
|
{
|
||||||
|
Map.Entry entry = _context.getServletHandler().getHolderEntry("test.jsp");
|
||||||
|
if (entry != null)
|
||||||
|
{
|
||||||
|
ServletHolder holder = (ServletHolder) entry.getValue();
|
||||||
|
_jspServletName = holder.getName();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return _jspServletName;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue