use of org.eclipse.jetty.servlet.Source in project jetty.project by eclipse.
the class WebServletAnnotation method apply.
/**
* @see DiscoveredAnnotation#apply()
*/
public void apply() {
//TODO check this algorithm with new rules for applying descriptors and annotations in order
Class<? extends Servlet> clazz = (Class<? extends Servlet>) getTargetClass();
if (clazz == null) {
LOG.warn(_className + " cannot be loaded");
return;
}
//Servlet Spec 8.1.1
if (!HttpServlet.class.isAssignableFrom(clazz)) {
LOG.warn(clazz.getName() + " is not assignable from javax.servlet.http.HttpServlet");
return;
}
WebServlet annotation = (WebServlet) clazz.getAnnotation(WebServlet.class);
if (annotation.urlPatterns().length > 0 && annotation.value().length > 0) {
LOG.warn(clazz.getName() + " defines both @WebServlet.value and @WebServlet.urlPatterns");
return;
}
String[] urlPatterns = annotation.value();
if (urlPatterns.length == 0)
urlPatterns = annotation.urlPatterns();
if (urlPatterns.length == 0) {
LOG.warn(clazz.getName() + " defines neither @WebServlet.value nor @WebServlet.urlPatterns");
return;
}
//canonicalize the patterns
ArrayList<String> urlPatternList = new ArrayList<String>();
for (String p : urlPatterns) urlPatternList.add(ServletPathSpec.normalize(p));
String servletName = (annotation.name().equals("") ? clazz.getName() : annotation.name());
MetaData metaData = _context.getMetaData();
//the new mapping
ServletMapping mapping = null;
//Find out if a <servlet> already exists with this name
ServletHolder[] holders = _context.getServletHandler().getServlets();
ServletHolder holder = null;
if (holders != null) {
for (ServletHolder h : holders) {
if (h.getName() != null && servletName.equals(h.getName())) {
holder = h;
break;
}
}
}
//handle creation/completion of a servlet
if (holder == null) {
//No servlet of this name has already been defined, either by a descriptor
//or another annotation (which would be impossible).
Source source = new Source(Source.Origin.ANNOTATION, clazz.getName());
holder = _context.getServletHandler().newServletHolder(source);
holder.setHeldClass(clazz);
metaData.setOrigin(servletName + ".servlet.servlet-class", annotation, clazz);
holder.setName(servletName);
holder.setDisplayName(annotation.displayName());
metaData.setOrigin(servletName + ".servlet.display-name", annotation, clazz);
holder.setInitOrder(annotation.loadOnStartup());
metaData.setOrigin(servletName + ".servlet.load-on-startup", annotation, clazz);
holder.setAsyncSupported(annotation.asyncSupported());
metaData.setOrigin(servletName + ".servlet.async-supported", annotation, clazz);
for (WebInitParam ip : annotation.initParams()) {
holder.setInitParameter(ip.name(), ip.value());
metaData.setOrigin(servletName + ".servlet.init-param." + ip.name(), ip, clazz);
}
_context.getServletHandler().addServlet(holder);
mapping = new ServletMapping(source);
mapping.setServletName(holder.getName());
mapping.setPathSpecs(LazyList.toStringArray(urlPatternList));
} else {
//can complete it, see http://java.net/jira/browse/SERVLET_SPEC-42
if (holder.getClassName() == null)
holder.setClassName(clazz.getName());
if (holder.getHeldClass() == null)
holder.setHeldClass(clazz);
//if not, add it
for (WebInitParam ip : annotation.initParams()) {
if (metaData.getOrigin(servletName + ".servlet.init-param." + ip.name()) == Origin.NotSet) {
holder.setInitParameter(ip.name(), ip.value());
metaData.setOrigin(servletName + ".servlet.init-param." + ip.name(), ip, clazz);
}
}
//check the url-patterns
//ServletSpec 3.0 p81 If a servlet already has url mappings from a
//webxml or fragment descriptor the annotation is ignored.
//However, we want to be able to replace mappings that were given in webdefault.xml
List<ServletMapping> existingMappings = getServletMappingsForServlet(servletName);
//about processing these url mappings
if (existingMappings.isEmpty() || !containsNonDefaultMappings(existingMappings)) {
mapping = new ServletMapping(new Source(Source.Origin.ANNOTATION, clazz.getName()));
mapping.setServletName(servletName);
mapping.setPathSpecs(LazyList.toStringArray(urlPatternList));
}
}
//servlet
if (mapping != null) {
//url mapping was permitted by annotation processing rules
//take a copy of the existing servlet mappings that we can iterate over and remove from. This is
//because the ServletHandler interface does not support removal of individual mappings.
List<ServletMapping> allMappings = ArrayUtil.asMutableList(_context.getServletHandler().getServletMappings());
// guard against duplicate path mapping here: that is the job of the ServletHandler
for (String p : urlPatternList) {
ServletMapping existingMapping = _context.getServletHandler().getServletMapping(p);
if (existingMapping != null && existingMapping.isDefault()) {
String[] updatedPaths = ArrayUtil.removeFromArray(existingMapping.getPathSpecs(), p);
//if we removed the last path from a servletmapping, delete the servletmapping
if (updatedPaths == null || updatedPaths.length == 0) {
boolean success = allMappings.remove(existingMapping);
if (LOG.isDebugEnabled())
LOG.debug("Removed empty mapping {} from defaults descriptor success:{}", existingMapping, success);
} else {
existingMapping.setPathSpecs(updatedPaths);
if (LOG.isDebugEnabled())
LOG.debug("Removed path {} from mapping {} from defaults descriptor ", p, existingMapping);
}
}
_context.getMetaData().setOrigin(servletName + ".servlet.mapping." + p, annotation, clazz);
}
allMappings.add(mapping);
_context.getServletHandler().setServletMappings(allMappings.toArray(new ServletMapping[allMappings.size()]));
}
}
use of org.eclipse.jetty.servlet.Source in project jetty.project by eclipse.
the class WebFilterAnnotation method apply.
/**
* @see DiscoveredAnnotation#apply()
*/
public void apply() {
// TODO verify against rules for annotation v descriptor
Class clazz = getTargetClass();
if (clazz == null) {
LOG.warn(_className + " cannot be loaded");
return;
}
//Servlet Spec 8.1.2
if (!Filter.class.isAssignableFrom(clazz)) {
LOG.warn(clazz.getName() + " is not assignable from javax.servlet.Filter");
return;
}
MetaData metaData = _context.getMetaData();
WebFilter filterAnnotation = (WebFilter) clazz.getAnnotation(WebFilter.class);
if (filterAnnotation.value().length > 0 && filterAnnotation.urlPatterns().length > 0) {
LOG.warn(clazz.getName() + " defines both @WebFilter.value and @WebFilter.urlPatterns");
return;
}
String name = (filterAnnotation.filterName().equals("") ? clazz.getName() : filterAnnotation.filterName());
String[] urlPatterns = filterAnnotation.value();
if (urlPatterns.length == 0)
urlPatterns = filterAnnotation.urlPatterns();
FilterHolder holder = _context.getServletHandler().getFilter(name);
if (holder == null) {
//Filter with this name does not already exist, so add it
holder = _context.getServletHandler().newFilterHolder(new Source(Source.Origin.ANNOTATION, clazz.getName()));
holder.setName(name);
holder.setHeldClass(clazz);
metaData.setOrigin(name + ".filter.filter-class", filterAnnotation, clazz);
holder.setDisplayName(filterAnnotation.displayName());
metaData.setOrigin(name + ".filter.display-name", filterAnnotation, clazz);
for (WebInitParam ip : filterAnnotation.initParams()) {
holder.setInitParameter(ip.name(), ip.value());
metaData.setOrigin(name + ".filter.init-param." + ip.name(), ip, clazz);
}
FilterMapping mapping = new FilterMapping();
mapping.setFilterName(holder.getName());
if (urlPatterns.length > 0) {
ArrayList<String> paths = new ArrayList<String>();
for (String s : urlPatterns) {
paths.add(ServletPathSpec.normalize(s));
}
mapping.setPathSpecs(paths.toArray(new String[paths.size()]));
}
if (filterAnnotation.servletNames().length > 0) {
ArrayList<String> names = new ArrayList<String>();
for (String s : filterAnnotation.servletNames()) {
names.add(s);
}
mapping.setServletNames(names.toArray(new String[names.size()]));
}
EnumSet<DispatcherType> dispatcherSet = EnumSet.noneOf(DispatcherType.class);
for (DispatcherType d : filterAnnotation.dispatcherTypes()) {
dispatcherSet.add(d);
}
mapping.setDispatcherTypes(dispatcherSet);
metaData.setOrigin(name + ".filter.mappings", filterAnnotation, clazz);
holder.setAsyncSupported(filterAnnotation.asyncSupported());
metaData.setOrigin(name + ".filter.async-supported", filterAnnotation, clazz);
_context.getServletHandler().addFilter(holder);
_context.getServletHandler().addFilterMapping(mapping);
} else {
//init-params of the same name.
for (WebInitParam ip : filterAnnotation.initParams()) {
//if (holder.getInitParameter(ip.name()) == null)
if (metaData.getOrigin(name + ".filter.init-param." + ip.name()) == Origin.NotSet) {
holder.setInitParameter(ip.name(), ip.value());
metaData.setOrigin(name + ".filter.init-param." + ip.name(), ip, clazz);
}
}
FilterMapping[] mappings = _context.getServletHandler().getFilterMappings();
boolean mappingExists = false;
if (mappings != null) {
for (FilterMapping m : mappings) {
if (m.getFilterName().equals(name)) {
mappingExists = true;
break;
}
}
}
//from the annotation
if (!mappingExists) {
FilterMapping mapping = new FilterMapping();
mapping.setFilterName(holder.getName());
if (urlPatterns.length > 0) {
ArrayList<String> paths = new ArrayList<String>();
for (String s : urlPatterns) {
paths.add(ServletPathSpec.normalize(s));
}
mapping.setPathSpecs(paths.toArray(new String[paths.size()]));
}
if (filterAnnotation.servletNames().length > 0) {
ArrayList<String> names = new ArrayList<String>();
for (String s : filterAnnotation.servletNames()) {
names.add(s);
}
mapping.setServletNames(names.toArray(new String[names.size()]));
}
EnumSet<DispatcherType> dispatcherSet = EnumSet.noneOf(DispatcherType.class);
for (DispatcherType d : filterAnnotation.dispatcherTypes()) {
dispatcherSet.add(d);
}
mapping.setDispatcherTypes(dispatcherSet);
_context.getServletHandler().addFilterMapping(mapping);
metaData.setOrigin(name + ".filter.mappings", filterAnnotation, clazz);
}
}
}
use of org.eclipse.jetty.servlet.Source in project jetty.project by eclipse.
the class WebListenerAnnotation method apply.
/**
* @see DiscoveredAnnotation#apply()
*/
public void apply() {
Class<? extends java.util.EventListener> clazz = (Class<? extends EventListener>) getTargetClass();
if (clazz == null) {
LOG.warn(_className + " cannot be loaded");
return;
}
try {
if (ServletContextListener.class.isAssignableFrom(clazz) || ServletContextAttributeListener.class.isAssignableFrom(clazz) || ServletRequestListener.class.isAssignableFrom(clazz) || ServletRequestAttributeListener.class.isAssignableFrom(clazz) || HttpSessionListener.class.isAssignableFrom(clazz) || HttpSessionAttributeListener.class.isAssignableFrom(clazz) || HttpSessionIdListener.class.isAssignableFrom(clazz)) {
java.util.EventListener listener = (java.util.EventListener) _context.getServletContext().createInstance(clazz);
MetaData metaData = _context.getMetaData();
if (metaData.getOrigin(clazz.getName() + ".listener") == Origin.NotSet) {
ListenerHolder h = _context.getServletHandler().newListenerHolder(new Source(Source.Origin.ANNOTATION, clazz.getName()));
h.setListener(listener);
_context.getServletHandler().addListener(h);
_context.addEventListener(listener);
}
} else
LOG.warn(clazz.getName() + " does not implement one of the servlet listener interfaces");
} catch (Exception e) {
LOG.warn(e);
}
}
use of org.eclipse.jetty.servlet.Source in project jetty.project by eclipse.
the class StandardDescriptorProcessor method visitServlet.
public void visitServlet(WebAppContext context, Descriptor descriptor, XmlParser.Node node) {
String id = node.getAttribute("id");
// initialize holder
String name = node.getString("servlet-name", false, true);
ServletHolder holder = _servletHolderMap.get(name);
//If servlet of that name does not already exist, create it.
if (holder == null) {
holder = context.getServletHandler().newServletHolder(new Source(Source.Origin.DESCRIPTOR, descriptor.getResource().toString()));
holder.setName(name);
_servletHolderMap.put(name, holder);
_servletHolders.add(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);
String originName = name + ".servlet.init-param." + pname;
Descriptor originDescriptor = context.getMetaData().getOriginDescriptor(originName);
switch(context.getMetaData().getOrigin(originName)) {
case NotSet:
{
//init-param not already set, so set it
holder.setInitParameter(pname, pvalue);
context.getMetaData().setOrigin(originName, descriptor);
break;
}
case WebXml:
case WebDefaults:
case WebOverride:
{
//otherwise just ignore it
if (!(descriptor instanceof FragmentDescriptor) && (descriptor != originDescriptor)) {
holder.setInitParameter(pname, pvalue);
context.getMetaData().setOrigin(originName, descriptor);
}
break;
}
case WebFragment:
{
//previously set by a web-fragment, make sure that the value matches, otherwise its an error
if ((descriptor != originDescriptor) && !holder.getInitParameter(pname).equals(pvalue))
throw new IllegalStateException("Mismatching init-param " + pname + "=" + pvalue + " in " + descriptor.getResource());
break;
}
default:
// TODO throw ISE?
LOG.warn(new Throwable());
}
}
String servlet_class = node.getString("servlet-class", false, true);
if ("".equals(servlet_class))
servlet_class = null;
//Handle the default jsp servlet instance
if (id != null && id.equals("jsp") && servlet_class != null) {
try {
Loader.loadClass(servlet_class);
} catch (ClassNotFoundException e) {
LOG.info("NO JSP Support for {}, did not find {}", context.getContextPath(), servlet_class);
servlet_class = "org.eclipse.jetty.servlet.NoJspServlet";
}
}
//Set the servlet-class
if (servlet_class != null) {
((WebDescriptor) descriptor).addClassName(servlet_class);
switch(context.getMetaData().getOrigin(name + ".servlet.servlet-class")) {
case NotSet:
{
//the class of the servlet has not previously been set, so set it
holder.setClassName(servlet_class);
context.getMetaData().setOrigin(name + ".servlet.servlet-class", descriptor);
break;
}
case WebXml:
case WebDefaults:
case WebOverride:
{
//the class of the servlet was set by a web xml file, only allow web-override/web-default to change it
if (!(descriptor instanceof FragmentDescriptor)) {
holder.setClassName(servlet_class);
context.getMetaData().setOrigin(name + ".servlet.servlet-class", descriptor);
}
break;
}
case WebFragment:
{
//the class was set by another fragment, ensure this fragment's value is the same
if (!servlet_class.equals(holder.getClassName()))
throw new IllegalStateException("Conflicting servlet-class " + servlet_class + " in " + descriptor.getResource());
break;
}
default:
// TODO throw ISE?
LOG.warn(new Throwable());
}
}
// Handle JSP file
String jsp_file = node.getString("jsp-file", false, true);
if (jsp_file != null)
holder.setForcedPath(jsp_file);
// handle load-on-startup
XmlParser.Node startup = node.get("load-on-startup");
if (startup != null) {
String s = startup.toString(false, true).toLowerCase(Locale.ENGLISH);
int order = 0;
if (s.startsWith("t")) {
LOG.warn("Deprecated boolean load-on-startup. Please use integer");
order = 1;
} else {
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);
}
}
switch(context.getMetaData().getOrigin(name + ".servlet.load-on-startup")) {
case NotSet:
{
//not already set, so set it now
holder.setInitOrder(order);
context.getMetaData().setOrigin(name + ".servlet.load-on-startup", descriptor);
break;
}
case WebXml:
case WebDefaults:
case WebOverride:
{
//if it was already set by a web xml descriptor and we're parsing another web xml descriptor, then override it
if (!(descriptor instanceof FragmentDescriptor)) {
holder.setInitOrder(order);
context.getMetaData().setOrigin(name + ".servlet.load-on-startup", descriptor);
}
break;
}
case WebFragment:
{
//it was already set by another fragment, if we're parsing a fragment, the values must match
if (order != holder.getInitOrder())
throw new IllegalStateException("Conflicting load-on-startup value in " + descriptor.getResource());
break;
}
default:
// TODO throw ISE?
LOG.warn(new Throwable());
}
}
Iterator<Node> 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);
switch(context.getMetaData().getOrigin(name + ".servlet.role-name." + roleName)) {
case NotSet:
{
//set it
holder.setUserRoleLink(roleName, roleLink);
context.getMetaData().setOrigin(name + ".servlet.role-name." + roleName, descriptor);
break;
}
case WebXml:
case WebDefaults:
case WebOverride:
{
//only another web xml descriptor (web-default,web-override web.xml) can override an already set value
if (!(descriptor instanceof FragmentDescriptor)) {
holder.setUserRoleLink(roleName, roleLink);
context.getMetaData().setOrigin(name + ".servlet.role-name." + roleName, descriptor);
}
break;
}
case WebFragment:
{
if (!holder.getUserRoleLink(roleName).equals(roleLink))
throw new IllegalStateException("Conflicting role-link for role-name " + roleName + " for servlet " + name + " in " + descriptor.getResource());
break;
}
default:
// TODO throw ISE?
LOG.warn(new Throwable());
}
} 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) {
switch(context.getMetaData().getOrigin(name + ".servlet.run-as")) {
case NotSet:
{
//run-as not set, so set it
holder.setRunAsRole(roleName);
context.getMetaData().setOrigin(name + ".servlet.run-as", descriptor);
break;
}
case WebXml:
case WebDefaults:
case WebOverride:
{
//run-as was set by a web xml, only allow it to be changed if we're currently parsing another web xml(override/default)
if (!(descriptor instanceof FragmentDescriptor)) {
holder.setRunAsRole(roleName);
context.getMetaData().setOrigin(name + ".servlet.run-as", descriptor);
}
break;
}
case WebFragment:
{
//run-as was set by another fragment, this fragment must show the same value
if (!holder.getRunAsRole().equals(roleName))
throw new IllegalStateException("Conflicting run-as role " + roleName + " for servlet " + name + " in " + descriptor.getResource());
break;
}
default:
// TODO throw ISE?
LOG.warn(new Throwable());
}
}
}
String async = node.getString("async-supported", false, true);
if (async != null) {
boolean val = async.length() == 0 || Boolean.valueOf(async);
switch(context.getMetaData().getOrigin(name + ".servlet.async-supported")) {
case NotSet:
{
//set it
holder.setAsyncSupported(val);
context.getMetaData().setOrigin(name + ".servlet.async-supported", descriptor);
break;
}
case WebXml:
case WebDefaults:
case WebOverride:
{
//async-supported set by previous web xml descriptor, only allow override if we're parsing another web descriptor(web.xml/web-override.xml/web-default.xml)
if (!(descriptor instanceof FragmentDescriptor)) {
holder.setAsyncSupported(val);
context.getMetaData().setOrigin(name + ".servlet.async-supported", descriptor);
}
break;
}
case WebFragment:
{
//async-supported set by another fragment, this fragment's value must match
if (holder.isAsyncSupported() != val)
throw new IllegalStateException("Conflicting async-supported=" + async + " for servlet " + name + " in " + descriptor.getResource());
break;
}
default:
// TODO throw ISE?
LOG.warn(new Throwable());
}
}
String enabled = node.getString("enabled", false, true);
if (enabled != null) {
boolean is_enabled = enabled.length() == 0 || Boolean.valueOf(enabled);
switch(context.getMetaData().getOrigin(name + ".servlet.enabled")) {
case NotSet:
{
//hasn't been set yet, so set it
holder.setEnabled(is_enabled);
context.getMetaData().setOrigin(name + ".servlet.enabled", descriptor);
break;
}
case WebXml:
case WebDefaults:
case WebOverride:
{
//was set in a web xml descriptor, only allow override from another web xml descriptor
if (!(descriptor instanceof FragmentDescriptor)) {
holder.setEnabled(is_enabled);
context.getMetaData().setOrigin(name + ".servlet.enabled", descriptor);
}
break;
}
case WebFragment:
{
//was set by another fragment, this fragment's value must match
if (holder.isEnabled() != is_enabled)
throw new IllegalStateException("Conflicting value of servlet enabled for servlet " + name + " in " + descriptor.getResource());
break;
}
default:
// TODO throw ISE?
LOG.warn(new Throwable());
}
}
/*
* If multipart config not set, then set it and record it was by the web.xml or fragment.
* If it was set by web.xml then if this is a fragment, ignore the settings.
* If it was set by a fragment, if this is a fragment and the values are different, error!
*/
XmlParser.Node multipart = node.get("multipart-config");
if (multipart != null) {
String location = multipart.getString("location", false, true);
String maxFile = multipart.getString("max-file-size", false, true);
String maxRequest = multipart.getString("max-request-size", false, true);
String threshold = multipart.getString("file-size-threshold", false, true);
MultipartConfigElement element = new MultipartConfigElement(location, (maxFile == null || "".equals(maxFile) ? -1L : Long.parseLong(maxFile)), (maxRequest == null || "".equals(maxRequest) ? -1L : Long.parseLong(maxRequest)), (threshold == null || "".equals(threshold) ? 0 : Integer.parseInt(threshold)));
switch(context.getMetaData().getOrigin(name + ".servlet.multipart-config")) {
case NotSet:
{
//hasn't been set, so set it
holder.getRegistration().setMultipartConfig(element);
context.getMetaData().setOrigin(name + ".servlet.multipart-config", descriptor);
break;
}
case WebXml:
case WebDefaults:
case WebOverride:
{
//was set in a web xml, only allow changes if we're parsing another web xml (web.xml/web-default.xml/web-override.xml)
if (!(descriptor instanceof FragmentDescriptor)) {
holder.getRegistration().setMultipartConfig(element);
context.getMetaData().setOrigin(name + ".servlet.multipart-config", descriptor);
}
break;
}
case WebFragment:
{
//another fragment set the value, this fragment's values must match exactly or it is an error
MultipartConfigElement cfg = ((ServletHolder.Registration) holder.getRegistration()).getMultipartConfig();
if (cfg.getMaxFileSize() != element.getMaxFileSize())
throw new IllegalStateException("Conflicting multipart-config max-file-size for servlet " + name + " in " + descriptor.getResource());
if (cfg.getMaxRequestSize() != element.getMaxRequestSize())
throw new IllegalStateException("Conflicting multipart-config max-request-size for servlet " + name + " in " + descriptor.getResource());
if (cfg.getFileSizeThreshold() != element.getFileSizeThreshold())
throw new IllegalStateException("Conflicting multipart-config file-size-threshold for servlet " + name + " in " + descriptor.getResource());
if ((cfg.getLocation() != null && (element.getLocation() == null || element.getLocation().length() == 0)) || (cfg.getLocation() == null && (element.getLocation() != null || element.getLocation().length() > 0)))
throw new IllegalStateException("Conflicting multipart-config location for servlet " + name + " in " + descriptor.getResource());
break;
}
default:
// TODO throw ISE?
LOG.warn(new Throwable());
}
}
}
use of org.eclipse.jetty.servlet.Source in project jetty.project by eclipse.
the class StandardDescriptorProcessor method visitFilter.
public void visitFilter(WebAppContext context, Descriptor descriptor, XmlParser.Node node) {
String name = node.getString("filter-name", false, true);
FilterHolder holder = _filterHolderMap.get(name);
if (holder == null) {
holder = context.getServletHandler().newFilterHolder(new Source(Source.Origin.DESCRIPTOR, descriptor.getResource().toString()));
holder.setName(name);
_filterHolderMap.put(name, holder);
_filterHolders.add(holder);
}
String filter_class = node.getString("filter-class", false, true);
if (filter_class != null) {
((WebDescriptor) descriptor).addClassName(filter_class);
switch(context.getMetaData().getOrigin(name + ".filter.filter-class")) {
case NotSet:
{
//no class set yet
holder.setClassName(filter_class);
context.getMetaData().setOrigin(name + ".filter.filter-class", descriptor);
break;
}
case WebXml:
case WebDefaults:
case WebOverride:
{
//filter class was set in web.xml, only allow other web xml descriptors (override/default) to change it
if (!(descriptor instanceof FragmentDescriptor)) {
holder.setClassName(filter_class);
context.getMetaData().setOrigin(name + ".filter.filter-class", descriptor);
}
break;
}
case WebFragment:
{
//the filter class was set up by a web fragment, all fragments must be the same
if (!holder.getClassName().equals(filter_class))
throw new IllegalStateException("Conflicting filter-class for filter " + name + " in " + descriptor.getResource());
break;
}
default:
// TODO throw ISE?
LOG.warn(new Throwable());
}
}
Iterator<XmlParser.Node> iter = node.iterator("init-param");
while (iter.hasNext()) {
XmlParser.Node paramNode = iter.next();
String pname = paramNode.getString("param-name", false, true);
String pvalue = paramNode.getString("param-value", false, true);
switch(context.getMetaData().getOrigin(name + ".filter.init-param." + pname)) {
case NotSet:
{
//init-param not already set, so set it
holder.setInitParameter(pname, pvalue);
context.getMetaData().setOrigin(name + ".filter.init-param." + pname, descriptor);
break;
}
case WebXml:
case WebDefaults:
case WebOverride:
{
//otherwise just ignore it
if (!(descriptor instanceof FragmentDescriptor)) {
holder.setInitParameter(pname, pvalue);
context.getMetaData().setOrigin(name + ".filter.init-param." + pname, descriptor);
}
break;
}
case WebFragment:
{
//previously set by a web-fragment, make sure that the value matches, otherwise its an error
if (!holder.getInitParameter(pname).equals(pvalue))
throw new IllegalStateException("Mismatching init-param " + pname + "=" + pvalue + " in " + descriptor.getResource());
break;
}
default:
// TODO throw ISE?
LOG.warn(new Throwable());
}
}
String async = node.getString("async-supported", false, true);
if (async != null)
holder.setAsyncSupported(async.length() == 0 || Boolean.valueOf(async));
if (async != null) {
boolean val = async.length() == 0 || Boolean.valueOf(async);
switch(context.getMetaData().getOrigin(name + ".filter.async-supported")) {
case NotSet:
{
//set it
holder.setAsyncSupported(val);
context.getMetaData().setOrigin(name + ".filter.async-supported", descriptor);
break;
}
case WebXml:
case WebDefaults:
case WebOverride:
{
//async-supported set by previous web xml descriptor, only allow override if we're parsing another web descriptor(web.xml/web-override.xml/web-default.xml)
if (!(descriptor instanceof FragmentDescriptor)) {
holder.setAsyncSupported(val);
context.getMetaData().setOrigin(name + ".filter.async-supported", descriptor);
}
break;
}
case WebFragment:
{
//async-supported set by another fragment, this fragment's value must match
if (holder.isAsyncSupported() != val)
throw new IllegalStateException("Conflicting async-supported=" + async + " for filter " + name + " in " + descriptor.getResource());
break;
}
default:
// TODO throw ISE?
LOG.warn(new Throwable());
}
}
}
Aggregations