use of org.eclipse.jetty.webapp.MetaData in project jetty.project by eclipse.
the class TestConfiguration method testIt.
@Test
public void testIt() throws Exception {
ClassLoader old_loader = Thread.currentThread().getContextClassLoader();
try {
InitialContext ic = new InitialContext();
Server server = new Server();
WebAppContext wac = new WebAppContext();
wac.setServer(server);
wac.setClassLoader(new WebAppClassLoader(Thread.currentThread().getContextClassLoader(), wac));
MetaData metaData = new MetaData();
PlusDescriptorProcessor plusProcessor = new PlusDescriptorProcessor();
//bind some EnvEntrys at the server level
EnvEntry ee1 = new EnvEntry(server, "xxx/a", "100", true);
EnvEntry ee2 = new EnvEntry(server, "yyy/b", "200", false);
EnvEntry ee3 = new EnvEntry(server, "zzz/c", "300", false);
EnvEntry ee4 = new EnvEntry(server, "zzz/d", "400", false);
EnvEntry ee5 = new EnvEntry(server, "zzz/f", "500", true);
//bind some EnvEntrys at the webapp level
EnvEntry ee6 = new EnvEntry(wac, "xxx/a", "900", true);
EnvEntry ee7 = new EnvEntry(wac, "yyy/b", "910", true);
EnvEntry ee8 = new EnvEntry(wac, "zzz/c", "920", false);
EnvEntry ee9 = new EnvEntry(wac, "zzz/e", "930", false);
assertNotNull(NamingEntryUtil.lookupNamingEntry(server, "xxx/a"));
assertNotNull(NamingEntryUtil.lookupNamingEntry(server, "yyy/b"));
assertNotNull(NamingEntryUtil.lookupNamingEntry(server, "zzz/c"));
assertNotNull(NamingEntryUtil.lookupNamingEntry(server, "zzz/d"));
assertNotNull(NamingEntryUtil.lookupNamingEntry(wac, "xxx/a"));
assertNotNull(NamingEntryUtil.lookupNamingEntry(wac, "yyy/b"));
assertNotNull(NamingEntryUtil.lookupNamingEntry(wac, "zzz/c"));
assertNotNull(NamingEntryUtil.lookupNamingEntry(wac, "zzz/e"));
//make a new env configuration
EnvConfiguration envConfig = new EnvConfiguration();
Thread.currentThread().setContextClassLoader(wac.getClassLoader());
MetaData metadata = new MetaData();
envConfig.preConfigure(wac);
envConfig.configure(wac);
envConfig.bindEnvEntries(wac);
String val = (String) ic.lookup("java:comp/env/xxx/a");
//webapp naming overrides server
assertEquals("900", val);
val = (String) ic.lookup("java:comp/env/yyy/b");
//webapp overrides server
assertEquals("910", val);
val = (String) ic.lookup("java:comp/env/zzz/c");
//webapp overrides server
assertEquals("920", val);
val = (String) ic.lookup("java:comp/env/zzz/d");
//from server naming
assertEquals("400", val);
val = (String) ic.lookup("java:comp/env/zzz/e");
//from webapp naming
assertEquals("930", val);
NamingEntry ne = (NamingEntry) ic.lookup("java:comp/env/" + NamingEntry.__contextName + "/xxx/a");
assertNotNull(ne);
ne = (NamingEntry) ic.lookup("java:comp/env/" + NamingEntry.__contextName + "/yyy/b");
assertNotNull(ne);
ne = (NamingEntry) ic.lookup("java:comp/env/" + NamingEntry.__contextName + "/zzz/c");
assertNotNull(ne);
ne = (NamingEntry) ic.lookup("java:comp/env/" + NamingEntry.__contextName + "/zzz/d");
assertNotNull(ne);
ne = (NamingEntry) ic.lookup("java:comp/env/" + NamingEntry.__contextName + "/zzz/e");
assertNotNull(ne);
plusProcessor.bindEnvEntry("foo", "99");
assertEquals("99", ic.lookup("java:comp/env/foo"));
plusProcessor.bindEnvEntry("xxx/a", "7");
//webapp overrides web.xml
assertEquals("900", ic.lookup("java:comp/env/xxx/a"));
plusProcessor.bindEnvEntry("yyy/b", "7");
//webapp overrides web.xml
assertEquals("910", ic.lookup("java:comp/env/yyy/b"));
plusProcessor.bindEnvEntry("zzz/c", "7");
//webapp does NOT override web.xml
assertEquals("7", ic.lookup("java:comp/env/zzz/c"));
plusProcessor.bindEnvEntry("zzz/d", "7");
//server does NOT override web.xml
assertEquals("7", ic.lookup("java:comp/env/zzz/d"));
plusProcessor.bindEnvEntry("zzz/e", "7");
//webapp does NOT override web.xml
assertEquals("7", ic.lookup("java:comp/env/zzz/e"));
plusProcessor.bindEnvEntry("zzz/f", "7");
//server overrides web.xml
assertEquals("500", ic.lookup("java:comp/env/zzz/f"));
((Context) ic.lookup("java:comp")).destroySubcontext("env");
ic.destroySubcontext("xxx");
ic.destroySubcontext("yyy");
ic.destroySubcontext("zzz");
} finally {
Thread.currentThread().setContextClassLoader(old_loader);
}
}
use of org.eclipse.jetty.webapp.MetaData 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.webapp.MetaData in project jetty.project by eclipse.
the class ResourceAnnotationHandler method handleMethod.
/**
* Process a Resource annotation on a Method.
* <p>
* This will generate a JNDI entry, and an Injection to be
* processed when an instance of the class is created.
*
* @param clazz the class to process
* @param method the method to process
*/
public void handleMethod(Class<?> clazz, Method method) {
Resource resource = (Resource) method.getAnnotation(Resource.class);
if (resource != null) {
//JavaEE Spec 5.2.3: Method cannot be static
if (Modifier.isStatic(method.getModifiers())) {
LOG.warn("Skipping Resource annotation on " + clazz.getName() + "." + method.getName() + ": cannot be static");
return;
}
// only 1 parameter
if (!method.getName().startsWith("set")) {
LOG.warn("Skipping Resource annotation on " + clazz.getName() + "." + method.getName() + ": invalid java bean, does not start with 'set'");
return;
}
if (method.getParameterCount() != 1) {
LOG.warn("Skipping Resource annotation on " + clazz.getName() + "." + method.getName() + ": invalid java bean, not single argument to method");
return;
}
if (Void.TYPE != method.getReturnType()) {
LOG.warn("Skipping Resource annotation on " + clazz.getName() + "." + method.getName() + ": invalid java bean, not void");
return;
}
//default name is the javabean property name
String name = method.getName().substring(3);
name = name.substring(0, 1).toLowerCase(Locale.ENGLISH) + name.substring(1);
name = clazz.getCanonicalName() + "/" + name;
name = (resource.name() != null && !resource.name().trim().equals("") ? resource.name() : name);
String mappedName = (resource.mappedName() != null && !resource.mappedName().trim().equals("") ? resource.mappedName() : null);
Class<?> paramType = method.getParameterTypes()[0];
Class<?> resourceType = resource.type();
//Servlet Spec 3.0 p. 76
//If a descriptor has specified at least 1 injection target for this
//resource, then it overrides this annotation
MetaData metaData = _context.getMetaData();
if (metaData.getOriginDescriptor("resource-ref." + name + ".injection") != null) {
//it overrides this annotation
return;
}
//check if an injection has already been setup for this target by web.xml
InjectionCollection injections = (InjectionCollection) _context.getAttribute(InjectionCollection.INJECTION_COLLECTION);
if (injections == null) {
injections = new InjectionCollection();
_context.setAttribute(InjectionCollection.INJECTION_COLLECTION, injections);
}
Injection injection = injections.getInjection(name, clazz, method, paramType);
if (injection == null) {
try {
//try binding name to environment
//try the webapp's environment first
boolean bound = org.eclipse.jetty.plus.jndi.NamingEntryUtil.bindToENC(_context, name, mappedName);
//try the server's environment
if (!bound)
bound = org.eclipse.jetty.plus.jndi.NamingEntryUtil.bindToENC(_context.getServer(), name, mappedName);
//try the jvm's environment
if (!bound)
bound = org.eclipse.jetty.plus.jndi.NamingEntryUtil.bindToENC(null, name, mappedName);
//NamingEntry, just a value bound in java:comp/env
if (!bound) {
try {
InitialContext ic = new InitialContext();
String nameInEnvironment = (mappedName != null ? mappedName : name);
ic.lookup("java:comp/env/" + nameInEnvironment);
bound = true;
} catch (NameNotFoundException e) {
bound = false;
}
}
if (bound) {
LOG.debug("Bound " + (mappedName == null ? name : mappedName) + " as " + name);
// Make the Injection for it
injection = new Injection();
injection.setTarget(clazz, method, paramType, resourceType);
injection.setJndiName(name);
injection.setMappingName(mappedName);
injections.add(injection);
//TODO - an @Resource is equivalent to a resource-ref, resource-env-ref, message-destination
metaData.setOrigin("resource-ref." + name + ".injection", resource, clazz);
} else if (!isEnvEntryType(paramType)) {
// JavaEE Spec. sec 5.4.1.3
throw new IllegalStateException("No resource at " + (mappedName == null ? name : mappedName));
}
} catch (NamingException e) {
// JavaEE Spec. sec 5.4.1.3
if (!isEnvEntryType(paramType))
throw new IllegalStateException(e);
}
}
}
}
use of org.eclipse.jetty.webapp.MetaData in project jetty.project by eclipse.
the class RunAsAnnotationHandler method doHandle.
public void doHandle(Class clazz) {
if (!Servlet.class.isAssignableFrom(clazz))
return;
javax.annotation.security.RunAs runAs = (javax.annotation.security.RunAs) clazz.getAnnotation(javax.annotation.security.RunAs.class);
if (runAs != null) {
String role = runAs.value();
if (role != null) {
ServletHolder holder = getServletHolderForClass(clazz);
if (holder != null) {
MetaData metaData = _context.getMetaData();
Descriptor d = metaData.getOriginDescriptor(holder.getName() + ".servlet.run-as");
//let the annotation override it
if (d == null) {
metaData.setOrigin(holder.getName() + ".servlet.run-as", runAs, clazz);
org.eclipse.jetty.plus.annotation.RunAs ra = new org.eclipse.jetty.plus.annotation.RunAs();
ra.setTargetClassName(clazz.getCanonicalName());
ra.setRoleName(role);
RunAsCollection raCollection = (RunAsCollection) _context.getAttribute(RunAsCollection.RUNAS_COLLECTION);
if (raCollection == null) {
raCollection = new RunAsCollection();
_context.setAttribute(RunAsCollection.RUNAS_COLLECTION, raCollection);
}
raCollection.add(ra);
}
}
} else
LOG.warn("Bad value for @RunAs annotation on class " + clazz.getName());
}
}
use of org.eclipse.jetty.webapp.MetaData 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);
}
}
}
Aggregations