+++ /dev/null
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache;
-
-import java.lang.reflect.InvocationTargetException;
-
-import javax.naming.NamingException;
-
-/**
- * Comment
- *
- * @author <a href="mailto:bill@jboss.org">Bill Burke</a>
- * @version $Revision$
- */
-public interface AnnotationProcessor {
- public void postConstruct(Object instance)
- throws IllegalAccessException, InvocationTargetException;
- public void preDestroy(Object instance)
- throws IllegalAccessException, InvocationTargetException;
- public void processAnnotations(Object instance)
- throws IllegalAccessException, InvocationTargetException, NamingException;
-}
--- /dev/null
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+
+package org.apache;
+
+import java.lang.reflect.InvocationTargetException;
+
+import javax.naming.NamingException;
+
+/**
+ * @version $Rev:$ $Date:$
+ */
+public interface InstanceManager {
+
+ public Object newInstance(String className)
+ throws IllegalAccessException, InvocationTargetException, NamingException,
+ InstantiationException, ClassNotFoundException;
+
+ public Object newInstance(String fqcn, ClassLoader classLoader)
+ throws IllegalAccessException, InvocationTargetException, NamingException,
+ InstantiationException, ClassNotFoundException;
+
+ public void newInstance(Object o)
+ throws IllegalAccessException, InvocationTargetException, NamingException;
+
+ public void destroyInstance(Object o)
+ throws IllegalAccessException, InvocationTargetException;
+}
package org.apache.catalina.core;
-import java.io.IOException;
-import java.io.InputStream;
import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Enumeration;
+import java.util.HashMap;
import java.util.Map;
-import java.util.Properties;
import javax.naming.NamingException;
import javax.servlet.Filter;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
-import org.apache.AnnotationProcessor;
+import org.apache.InstanceManager;
import org.apache.catalina.Context;
import org.apache.catalina.Globals;
import org.apache.catalina.deploy.FilterDef;
protected static StringManager sm =
StringManager.getManager(Constants.Package);
-
+
// ----------------------------------------------------------- Constructors
* @exception InstantiationException if an exception occurs while
* instantiating the filter object
* @exception ServletException if thrown by the filter's init() method
- * @throws NamingException
- * @throws InvocationTargetException
+ * @throws NamingException
+ * @throws InvocationTargetException
*/
public ApplicationFilterConfig(Context context, FilterDef filterDef)
throws ClassCastException, ClassNotFoundException,
super();
- if (restrictedFilters == null) {
- restrictedFilters = new Properties();
- try {
- InputStream is =
- this.getClass().getClassLoader().getResourceAsStream
- ("org/apache/catalina/core/RestrictedFilters.properties");
- if (is != null) {
- restrictedFilters.load(is);
- } else {
- context.getLogger().error(sm.getString("applicationFilterConfig.restrictedFiltersResources"));
- }
- } catch (IOException e) {
- context.getLogger().error(sm.getString("applicationFilterConfig.restrictedServletsResources"), e);
- }
- }
-
this.context = context;
setFilterDef(filterDef);
*/
private FilterDef filterDef = null;
-
/**
- * Restricted filters (which can only be loaded by a privileged webapp).
+ * the InstanceManager used to create and destroy filter instances.
*/
- protected static Properties restrictedFilters = null;
+ private transient InstanceManager instanceManager;
+
-
// --------------------------------------------------- FilterConfig Methods
* @exception InstantiationException if an exception occurs while
* instantiating the filter object
* @exception ServletException if thrown by the filter's init() method
- * @throws NamingException
- * @throws InvocationTargetException
+ * @throws NamingException
+ * @throws InvocationTargetException
*/
Filter getFilter() throws ClassCastException, ClassNotFoundException,
- IllegalAccessException, InstantiationException, ServletException,
+ IllegalAccessException, InstantiationException, ServletException,
InvocationTargetException, NamingException {
// Return the existing filter instance, if any
// Identify the class loader we will be using
String filterClass = filterDef.getFilterClass();
- ClassLoader classLoader = null;
- if (filterClass.startsWith("org.apache.catalina."))
- classLoader = this.getClass().getClassLoader();
- else
- classLoader = context.getLoader().getClassLoader();
-
- ClassLoader oldCtxClassLoader =
- Thread.currentThread().getContextClassLoader();
+ this.filter = (Filter) getInstanceManager().newInstance(filterClass);
- // Instantiate a new instance of this filter and return it
- Class clazz = classLoader.loadClass(filterClass);
- if (!isFilterAllowed(clazz)) {
- throw new SecurityException
- (sm.getString("applicationFilterConfig.privilegedFilter",
- filterClass));
- }
- this.filter = (Filter) clazz.newInstance();
- if (!context.getIgnoreAnnotations()) {
- if (context instanceof StandardContext) {
- AnnotationProcessor processor = ((StandardContext)context).getAnnotationProcessor();
- processor.processAnnotations(this.filter);
- processor.postConstruct(this.filter);
- }
- }
if (context instanceof StandardContext &&
- ((StandardContext) context).getSwallowOutput()) {
+ context.getSwallowOutput()) {
try {
SystemLogHandler.startCapture();
filter.init(this);
}
-
- /**
- * Return <code>true</code> if loading this filter is allowed.
- */
- protected boolean isFilterAllowed(Class filterClass) {
-
- // Privileged webapps may load all servlets without restriction
- if (context.getPrivileged()) {
- return true;
- }
-
- Class clazz = filterClass;
- while (clazz != null && !clazz.getName().equals("javax.servlet.Filter")) {
- if ("restricted".equals(restrictedFilters.getProperty(clazz.getName()))) {
- return (false);
- }
- clazz = clazz.getSuperclass();
- }
-
- return (true);
-
- }
-
-
/**
* Release the Filter instance associated with this FilterConfig,
* if there is one.
{
if (Globals.IS_SECURITY_ENABLED) {
try {
- SecurityUtil.doAsPrivilege("destroy", filter);
- } catch(java.lang.Exception ex){
+ SecurityUtil.doAsPrivilege("destroy", filter);
+ } catch(java.lang.Exception ex){
context.getLogger().error("ApplicationFilterConfig.doAsPrivilege", ex);
}
SecurityUtil.remove(filter);
- } else {
+ } else {
filter.destroy();
}
if (!context.getIgnoreAnnotations()) {
try {
- ((StandardContext)context).getAnnotationProcessor().preDestroy(this.filter);
+ ((StandardContext) context).getInstanceManager().destroyInstance(this.filter);
} catch (Exception e) {
context.getLogger().error("ApplicationFilterConfig.preDestroy", e);
}
* @exception InstantiationException if an exception occurs while
* instantiating the filter object
* @exception ServletException if thrown by the filter's init() method
- * @throws NamingException
- * @throws InvocationTargetException
+ * @throws NamingException
+ * @throws InvocationTargetException
*/
void setFilterDef(FilterDef filterDef)
throws ClassCastException, ClassNotFoundException,
if (this.filter != null){
if( Globals.IS_SECURITY_ENABLED) {
try{
- SecurityUtil.doAsPrivilege("destroy", filter);
- } catch(java.lang.Exception ex){
+ SecurityUtil.doAsPrivilege("destroy", filter);
+ } catch(java.lang.Exception ex){
context.getLogger().error("ApplicationFilterConfig.doAsPrivilege", ex);
}
SecurityUtil.remove(filter);
- } else {
+ } else {
filter.destroy();
}
if (!context.getIgnoreAnnotations()) {
try {
- ((StandardContext)context).getAnnotationProcessor().preDestroy(this.filter);
+ ((StandardContext) context).getInstanceManager().destroyInstance(this.filter);
} catch (Exception e) {
context.getLogger().error("ApplicationFilterConfig.preDestroy", e);
}
// -------------------------------------------------------- Private Methods
+ private InstanceManager getInstanceManager() {
+ if (instanceManager == null) {
+ if (context instanceof StandardContext) {
+ instanceManager = ((StandardContext)context).getInstanceManager();
+ } else {
+ instanceManager = new DefaultInstanceManager(null,
+ new HashMap<String, Map<String, String>>(),
+ context,
+ getClass().getClassLoader());
+ }
+ }
+ return instanceManager;
+ }
}
--- /dev/null
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package org.apache.catalina.core;
+
+
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.Map;
+import java.util.Properties;
+import java.security.AccessController;
+import java.security.PrivilegedExceptionAction;
+import java.security.PrivilegedActionException;
+import java.io.InputStream;
+import java.io.IOException;
+
+import javax.annotation.PostConstruct;
+import javax.annotation.PreDestroy;
+import javax.annotation.Resource;
+import javax.ejb.EJB;
+import javax.naming.Context;
+import javax.naming.NamingException;
+import javax.persistence.PersistenceContext;
+import javax.persistence.PersistenceUnit;
+import javax.xml.ws.WebServiceRef;
+import javax.servlet.Filter;
+import javax.servlet.Servlet;
+
+import org.apache.InstanceManager;
+import org.apache.catalina.security.SecurityUtil;
+import org.apache.catalina.ContainerServlet;
+import org.apache.catalina.core.Constants;
+import org.apache.catalina.util.StringManager;
+
+/**
+ * @version $Rev:$ $Date:$
+ */
+public class DefaultInstanceManager implements InstanceManager {
+
+ private final Context context;
+ private final Map<String, Map<String, String>> injectionMap;
+ protected final ClassLoader classLoader;
+ protected final ClassLoader containerClassLoader;
+ protected boolean privileged;
+ protected boolean ignoreAnnotations;
+ private Properties restrictedFilters = new Properties();
+ private Properties restrictedListeners = new Properties();
+ private Properties restrictedServlets = new Properties();
+
+ public DefaultInstanceManager(Context context, Map<String, Map<String, String>> injectionMap, org.apache.catalina.Context catalinaContext, ClassLoader containerClassLoader) {
+ classLoader = catalinaContext.getLoader().getClassLoader();
+ privileged = catalinaContext.getPrivileged();
+ this.containerClassLoader = containerClassLoader;
+ ignoreAnnotations = catalinaContext.getIgnoreAnnotations();
+ StringManager sm = StringManager.getManager(Constants.Package);
+ try {
+ InputStream is =
+ this.getClass().getClassLoader().getResourceAsStream
+ ("org/apache/catalina/core/RestrictedServlets.properties");
+ if (is != null) {
+ restrictedServlets.load(is);
+ } else {
+ catalinaContext.getLogger().error(sm.getString("defaultInstanceManager.restrictedServletsResource"));
+ }
+ } catch (IOException e) {
+ catalinaContext.getLogger().error(sm.getString("defaultInstanceManager.restrictedServletsResource"), e);
+ }
+
+ try {
+ InputStream is =
+ this.getClass().getClassLoader().getResourceAsStream
+ ("org/apache/catalina/core/RestrictedListeners.properties");
+ if (is != null) {
+ restrictedFilters.load(is);
+ } else {
+ catalinaContext.getLogger().error(sm.getString("defaultInstanceManager.restrictedListenersResources"));
+ }
+ } catch (IOException e) {
+ catalinaContext.getLogger().error(sm.getString("defaultInstanceManager.restrictedListenersResources"), e);
+ }
+ try {
+ InputStream is =
+ this.getClass().getClassLoader().getResourceAsStream
+ ("org/apache/catalina/core/RestrictedFilters.properties");
+ if (is != null) {
+ restrictedFilters.load(is);
+ } else {
+ catalinaContext.getLogger().error(sm.getString("defaultInstanceManager.restrictedFiltersResources"));
+ }
+ } catch (IOException e) {
+ catalinaContext.getLogger().error(sm.getString("defaultInstanceManager.restrictedServletsResources"), e);
+ }
+ this.context = context;
+ this.injectionMap = injectionMap;
+ }
+
+ public Object newInstance(String className) throws IllegalAccessException, InvocationTargetException, NamingException, InstantiationException, ClassNotFoundException {
+ Class clazz = loadClassMaybePrivileged(className, classLoader);
+ return newInstance(clazz.newInstance(), clazz);
+ }
+
+ public Object newInstance(final String className, final ClassLoader classLoader) throws IllegalAccessException, NamingException, InvocationTargetException, InstantiationException, ClassNotFoundException {
+ Class clazz = classLoader.loadClass(className);
+ return newInstance(clazz.newInstance(), clazz);
+ }
+
+ public void newInstance(Object o)
+ throws IllegalAccessException, InvocationTargetException, NamingException {
+ newInstance(o, o.getClass());
+ }
+
+ private Object newInstance(Object instance, Class clazz) throws IllegalAccessException, InvocationTargetException, NamingException {
+ if (!ignoreAnnotations) {
+ Map<String, String> injections = injectionMap.get(clazz.getName());
+ processAnnotations(instance, injections);
+ postConstruct(instance, clazz);
+ }
+ return instance;
+ }
+
+ public void destroyInstance(Object instance) throws IllegalAccessException, InvocationTargetException {
+ if (!ignoreAnnotations) {
+ preDestroy(instance, instance.getClass());
+ }
+ }
+
+ /**
+ * Call postConstruct method on the specified instance recursively from deepest superclass to actual class.
+ *
+ * @param instance object to call postconstruct methods on
+ * @param clazz (super) class to examine for postConstruct annotation.
+ * @throws IllegalAccessException if postConstruct method is inaccessible.
+ * @throws java.lang.reflect.InvocationTargetException
+ * if call fails
+ */
+ protected void postConstruct(Object instance, Class clazz)
+ throws IllegalAccessException, InvocationTargetException {
+ Class superClass = clazz.getSuperclass();
+ if (superClass != Object.class) {
+ postConstruct(instance, superClass);
+ }
+
+ Method[] methods = clazz.getDeclaredMethods();
+ Method postConstruct = null;
+ for (Method method : methods) {
+ if (method.isAnnotationPresent(PostConstruct.class)) {
+ if ((postConstruct != null)
+ || (method.getParameterTypes().length != 0)
+ || (Modifier.isStatic(method.getModifiers()))
+ || (method.getExceptionTypes().length > 0)
+ || (!method.getReturnType().getName().equals("void"))) {
+ throw new IllegalArgumentException("Invalid PostConstruct annotation");
+ }
+ postConstruct = method;
+ }
+ }
+
+ // At the end the postconstruct annotated
+ // method is invoked
+ if (postConstruct != null) {
+ boolean accessibility = postConstruct.isAccessible();
+ postConstruct.setAccessible(true);
+ postConstruct.invoke(instance);
+ postConstruct.setAccessible(accessibility);
+ }
+
+ }
+
+
+ /**
+ * Call preDestroy method on the specified instance recursively from deepest superclass to actual class.
+ *
+ * @param instance object to call preDestroy methods on
+ * @param clazz (super) class to examine for preDestroy annotation.
+ * @throws IllegalAccessException if preDestroy method is inaccessible.
+ * @throws java.lang.reflect.InvocationTargetException
+ * if call fails
+ */
+ protected void preDestroy(Object instance, Class clazz)
+ throws IllegalAccessException, InvocationTargetException {
+ Class superClass = clazz.getSuperclass();
+ if (superClass != Object.class) {
+ preDestroy(instance, superClass);
+ }
+
+ Method[] methods = clazz.getDeclaredMethods();
+ Method preDestroy = null;
+ for (Method method : methods) {
+ if (method.isAnnotationPresent(PreDestroy.class)) {
+ if ((method.getParameterTypes().length != 0)
+ || (Modifier.isStatic(method.getModifiers()))
+ || (method.getExceptionTypes().length > 0)
+ || (!method.getReturnType().getName().equals("void"))) {
+ throw new IllegalArgumentException("Invalid PreDestroy annotation");
+ }
+ preDestroy = method;
+ break;
+ }
+ }
+
+ // At the end the postconstruct annotated
+ // method is invoked
+ if (preDestroy != null) {
+ boolean accessibility = preDestroy.isAccessible();
+ preDestroy.setAccessible(true);
+ preDestroy.invoke(instance);
+ preDestroy.setAccessible(accessibility);
+ }
+
+ }
+
+
+ /**
+ * Inject resources in specified instance.
+ *
+ * @param instance instance to inject into
+ * @param injections map of injections for this class from xml deployment descriptor
+ * @throws IllegalAccessException if injection target is inaccessible
+ * @throws javax.naming.NamingException if value cannot be looked up in jndi
+ * @throws java.lang.reflect.InvocationTargetException
+ * if injection fails
+ */
+ protected void processAnnotations(Object instance, Map<String, String> injections)
+ throws IllegalAccessException, InvocationTargetException, NamingException {
+
+ if (context == null) {
+ // No resource injection
+ return;
+ }
+
+ // Initialize fields annotations
+ Field[] fields = instance.getClass().getDeclaredFields();
+ for (Field field : fields) {
+ if (injections != null && injections.containsKey(field.getName())) {
+ lookupFieldResource(context, instance, field, injections.get(field.getName()));
+ } else if (field.isAnnotationPresent(Resource.class)) {
+ Resource annotation = field.getAnnotation(Resource.class);
+ lookupFieldResource(context, instance, field, annotation.name());
+ } else if (field.isAnnotationPresent(EJB.class)) {
+ EJB annotation = field.getAnnotation(EJB.class);
+ lookupFieldResource(context, instance, field, annotation.name());
+ } else if (field.isAnnotationPresent(WebServiceRef.class)) {
+ WebServiceRef annotation =
+ field.getAnnotation(WebServiceRef.class);
+ lookupFieldResource(context, instance, field, annotation.name());
+ } else if (field.isAnnotationPresent(PersistenceContext.class)) {
+ PersistenceContext annotation =
+ field.getAnnotation(PersistenceContext.class);
+ lookupFieldResource(context, instance, field, annotation.name());
+ } else if (field.isAnnotationPresent(PersistenceUnit.class)) {
+ PersistenceUnit annotation =
+ field.getAnnotation(PersistenceUnit.class);
+ lookupFieldResource(context, instance, field, annotation.name());
+ }
+ }
+
+ // Initialize methods annotations
+ Method[] methods = instance.getClass().getDeclaredMethods();
+ for (Method method : methods) {
+ String methodName = method.getName();
+ if (injections != null && methodName.startsWith("set") && methodName.length() > 3) {
+ String fieldName = Character.toLowerCase(methodName.charAt(3)) + methodName.substring(4);
+ if (injections.containsKey(fieldName)) {
+ lookupMethodResource(context, instance, method, injections.get(fieldName));
+ break;
+ }
+ }
+ if (method.isAnnotationPresent(Resource.class)) {
+ Resource annotation = method.getAnnotation(Resource.class);
+ lookupMethodResource(context, instance, method, annotation.name());
+ } else if (method.isAnnotationPresent(EJB.class)) {
+ EJB annotation = method.getAnnotation(EJB.class);
+ lookupMethodResource(context, instance, method, annotation.name());
+ } else if (method.isAnnotationPresent(WebServiceRef.class)) {
+ WebServiceRef annotation =
+ method.getAnnotation(WebServiceRef.class);
+ lookupMethodResource(context, instance, method, annotation.name());
+ } else if (method.isAnnotationPresent(PersistenceContext.class)) {
+ PersistenceContext annotation =
+ method.getAnnotation(PersistenceContext.class);
+ lookupMethodResource(context, instance, method, annotation.name());
+ } else if (method.isAnnotationPresent(PersistenceUnit.class)) {
+ PersistenceUnit annotation =
+ method.getAnnotation(PersistenceUnit.class);
+ lookupMethodResource(context, instance, method, annotation.name());
+ }
+ }
+
+ }
+
+
+ protected Class loadClassMaybePrivileged(final String className, final ClassLoader classLoader) throws ClassNotFoundException {
+ Class clazz;
+ if (SecurityUtil.isPackageProtectionEnabled()) {
+ try {
+ clazz = AccessController.doPrivileged(new PrivilegedExceptionAction<Class>() {
+
+ public Class run() throws Exception {
+ return loadClass(className, classLoader);
+ }
+ });
+ } catch (PrivilegedActionException e) {
+ Throwable t = e.getCause();
+ if (t instanceof ClassNotFoundException) {
+ throw (ClassNotFoundException) t;
+ }
+ throw new RuntimeException(t);
+ }
+ } else {
+ clazz = loadClass(className, classLoader);
+ }
+ checkAccess(clazz);
+ return clazz;
+ }
+
+ protected Class loadClass(String className, ClassLoader classLoader) throws ClassNotFoundException {
+ if (className.startsWith("org.apache.catalina")) {
+ return containerClassLoader.loadClass(className);
+ }
+ try {
+ Class clazz = containerClassLoader.loadClass(className);
+ if (ContainerServlet.class.isAssignableFrom(clazz)) {
+ return clazz;
+ }
+ } catch (Throwable t) {
+ //ignore
+ }
+ return classLoader.loadClass(className);
+ }
+
+ private void checkAccess(Class clazz) {
+ if (privileged) return;
+ if (clazz.isAssignableFrom(Filter.class)) {
+ checkAccess(clazz, restrictedFilters);
+ } else if (clazz.isAssignableFrom(Servlet.class)) {
+ checkAccess(clazz, restrictedServlets);
+ } else {
+ checkAccess(clazz, restrictedListeners);
+ }
+ }
+
+ private void checkAccess(Class clazz, Properties restricted) {
+ while (clazz != null) {
+ if ("restricted".equals(restricted.getProperty(clazz.getName()))) {
+ throw new SecurityException("Restricted class" + clazz);
+ }
+ clazz = clazz.getSuperclass();
+ }
+
+ }
+
+ /**
+ * Inject resources in specified field.
+ *
+ * @param context jndi context to extract value from
+ * @param instance object to inject into
+ * @param field field target for injection
+ * @param name jndi name value is bound under
+ * @throws IllegalAccessException if field is inaccessible
+ * @throws javax.naming.NamingException if value is not accessible in naming context
+ */
+ protected static void lookupFieldResource(Context context,
+ Object instance, Field field, String name)
+ throws NamingException, IllegalAccessException {
+
+ Object lookedupResource;
+ boolean accessibility;
+
+ if ((name != null) &&
+ (name.length() > 0)) {
+ lookedupResource = context.lookup(name);
+ } else {
+ lookedupResource = context.lookup(instance.getClass().getName() + "/" + field.getName());
+ }
+
+ accessibility = field.isAccessible();
+ field.setAccessible(true);
+ field.set(instance, lookedupResource);
+ field.setAccessible(accessibility);
+ }
+
+ /**
+ * Inject resources in specified method.
+ *
+ * @param context jndi context to extract value from
+ * @param instance object to inject into
+ * @param method field target for injection
+ * @param name jndi name value is bound under
+ * @throws IllegalAccessException if method is inaccessible
+ * @throws javax.naming.NamingException if value is not accessible in naming context
+ * @throws java.lang.reflect.InvocationTargetException
+ * if setter call fails
+ */
+ protected static void lookupMethodResource(Context context,
+ Object instance, Method method, String name)
+ throws NamingException, IllegalAccessException, InvocationTargetException {
+
+ if (!method.getName().startsWith("set")
+ || method.getParameterTypes().length != 1
+ || !method.getReturnType().getName().equals("void")) {
+ throw new IllegalArgumentException("Invalid method resource injection annotation");
+ }
+
+ Object lookedupResource;
+ boolean accessibility;
+
+ if ((name != null) &&
+ (name.length() > 0)) {
+ lookedupResource = context.lookup(name);
+ } else {
+ lookedupResource =
+ context.lookup(instance.getClass().getName() + "/" + method.getName().substring(3));
+ }
+
+ accessibility = method.isAccessible();
+ method.setAccessible(true);
+ method.invoke(instance, lookedupResource);
+ method.setAccessible(accessibility);
+ }
+}
standardWrapper.notContext=Parent container of a Wrapper must be a Context
standardWrapper.notFound=Servlet {0} is not available
standardWrapper.notServlet=Class {0} is not a Servlet
-standardWrapper.privilegedServlet=Servlet of class {0} is privileged and cannot be loaded by this web application
standardWrapper.releaseFilters=Release filters exception for servlet {0}
standardWrapper.serviceException=Servlet.service() for servlet {0} threw exception
standardWrapper.statusHeader=HTTP Status {0} - {1}
standardWrapper.unloadException=Servlet {0} threw unload() exception
standardWrapper.unloading=Cannot allocate servlet {0} because it is being unloaded
standardWrapper.waiting=Waiting for {0} instance(s) to be deallocated
-standardWrapper.restrictedServletsResource=Restricted servlets property file not found
-applicationFilterConfig.restrictedFiltersResource=Restricted filters property file not found
-applicationFilterConfig.privilegedFilter=Filter of class {0} is privileged and cannot be loaded by this web application
+defaultInstanceManager.restrictedServletsResource=Restricted servlets property file not found
+defaultInstanceManager.privilegedServlet=Servlet of class {0} is privileged and cannot be loaded by this web application
+defaultInstanceManager.restrictedFiltersResource=Restricted filters property file not found
+defaultInstanceManager.privilegedFilter=Filter of class {0} is privileged and cannot be loaded by this web application
+defaultInstanceManager.restrictedListenersResources="Restricted listeners property file not found
\ No newline at end of file
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
import java.util.Stack;
import java.util.TreeMap;
import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionListener;
-import org.apache.AnnotationProcessor;
+import org.apache.InstanceManager;
import org.apache.catalina.Container;
import org.apache.catalina.ContainerListener;
import org.apache.catalina.Context;
import org.apache.catalina.deploy.ErrorPage;
import org.apache.catalina.deploy.FilterDef;
import org.apache.catalina.deploy.FilterMap;
+import org.apache.catalina.deploy.Injectable;
+import org.apache.catalina.deploy.InjectionTarget;
import org.apache.catalina.deploy.LoginConfig;
import org.apache.catalina.deploy.MessageDestination;
import org.apache.catalina.deploy.MessageDestinationRef;
import org.apache.catalina.startup.ContextConfig;
import org.apache.catalina.startup.TldConfig;
import org.apache.catalina.util.CharsetMapper;
-import org.apache.catalina.util.DefaultAnnotationProcessor;
import org.apache.catalina.util.ExtensionValidator;
import org.apache.catalina.util.RequestUtil;
import org.apache.catalina.util.URLEncoder;
/**
- * Annotation processor.
+ * Lifecycle provider.
*/
- private AnnotationProcessor annotationProcessor = null;
+ private InstanceManager instanceManager = null;
/**
// ----------------------------------------------------- Context Properties
- public AnnotationProcessor getAnnotationProcessor() {
- return annotationProcessor;
+ public InstanceManager getInstanceManager() {
+ return instanceManager;
}
- public void setAnnotationProcessor(AnnotationProcessor annotationProcessor) {
- this.annotationProcessor = annotationProcessor;
+ public void setInstanceManager(InstanceManager instanceManager) {
+ this.instanceManager = instanceManager;
}
* @return The work path
*/
public String getWorkPath() {
- if (getWorkDir() == null) {
- return null;
- }
File workDir = new File(getWorkDir());
if (!workDir.isAbsolute()) {
File catalinaHome = engineBase();
log.debug("Configuring application event listeners");
// Instantiate the required listeners
- ClassLoader loader = getLoader().getClassLoader();
String listeners[] = findApplicationListeners();
Object results[] = new Object[listeners.length];
boolean ok = true;
getLogger().debug(" Configuring event listener class '" +
listeners[i] + "'");
try {
- Class clazz = loader.loadClass(listeners[i]);
- results[i] = clazz.newInstance();
- // Annotation processing
- if (!getIgnoreAnnotations()) {
- getAnnotationProcessor().processAnnotations(results[i]);
- getAnnotationProcessor().postConstruct(results[i]);
- }
+ results[i] = instanceManager.newInstance(listeners[i]);
} catch (Throwable t) {
getLogger().error
(sm.getString("standardContext.applicationListener",
ok = false;
}
}
- // Annotation processing
- if (!getIgnoreAnnotations()) {
- try {
- getAnnotationProcessor().preDestroy(listeners[j]);
- } catch (Throwable t) {
- getLogger().error
- (sm.getString("standardContext.listenerStop",
- listeners[j].getClass().getName()), t);
- ok = false;
- }
+ try {
+ getInstanceManager().destroyInstance(listeners[j]);
+ } catch (Throwable t) {
+ getLogger().error
+ (sm.getString("standardContext.listenerStop",
+ listeners[j].getClass().getName()), t);
+ ok = false;
}
}
}
// Annotation processing
listeners = getApplicationEventListeners();
- if (!getIgnoreAnnotations() && listeners != null) {
+ if (listeners != null) {
for (int i = 0; i < listeners.length; i++) {
int j = (listeners.length - 1) - i;
if (listeners[j] == null)
continue;
try {
- getAnnotationProcessor().preDestroy(listeners[j]);
+ getInstanceManager().destroyInstance(listeners[j]);
} catch (Throwable t) {
getLogger().error
(sm.getString("standardContext.listenerStop",
// Binding thread
oldCCL = bindThread();
- // Set annotation processing parameter for Jasper (unfortunately, since
- // this can be configured in many places and not just in /WEB-INF/web.xml,
- // there are not many solutions)
- // Initialize annotation processor
- if (ok && !getIgnoreAnnotations()) {
- if (annotationProcessor == null) {
+ if (ok ) {
+ if (instanceManager == null) {
+ javax.naming.Context context = null;
if (isUseNaming() && namingContextListener != null) {
- annotationProcessor =
- new DefaultAnnotationProcessor(namingContextListener.getEnvContext());
- } else {
- annotationProcessor = new DefaultAnnotationProcessor(null);
+ context = namingContextListener.getEnvContext();
}
+ Map<String, Map<String, String>> injectionMap =
+ buildInjectionMap(getIgnoreAnnotations() ? new NamingResources(): getNamingResources());
+ instanceManager = new DefaultInstanceManager
+ (context, injectionMap, this, this.getClass().getClassLoader());
+ getServletContext().setAttribute(InstanceManager.class.getName(), instanceManager);
}
- getServletContext().setAttribute
- (AnnotationProcessor.class.getName(), annotationProcessor);
}
try {
//cacheContext();
}
+ private Map<String, Map<String, String>> buildInjectionMap(NamingResources namingResources) {
+ Map<String, Map<String, String>> injectionMap = new HashMap<String, Map<String, String>>();
+ for (Injectable resource: namingResources.findLocalEjbs()) {
+ addInjectionTarget(resource, injectionMap);
+ }
+ for (Injectable resource: namingResources.findEjbs()) {
+ addInjectionTarget(resource, injectionMap);
+ }
+ for (Injectable resource: namingResources.findEnvironments()) {
+ addInjectionTarget(resource, injectionMap);
+ }
+ for (Injectable resource: namingResources.findMessageDestinationRefs()) {
+ addInjectionTarget(resource, injectionMap);
+ }
+ for (Injectable resource: namingResources.findResourceEnvRefs()) {
+ addInjectionTarget(resource, injectionMap);
+ }
+ for (Injectable resource: namingResources.findResources()) {
+ addInjectionTarget(resource, injectionMap);
+ }
+ for (Injectable resource: namingResources.findServices()) {
+ addInjectionTarget(resource, injectionMap);
+ }
+ return injectionMap;
+ }
+
+ private void addInjectionTarget(Injectable resource, Map<String, Map<String, String>> injectionMap) {
+ List<InjectionTarget> injectionTargets = resource.getInjectionTargets();
+ if (injectionTargets != null && injectionTargets.size() > 0) {
+ String jndiName = resource.getName();
+ for (InjectionTarget injectionTarget: injectionTargets) {
+ String clazz = injectionTarget.getTargetClass();
+ Map<String, String> injections = injectionMap.get(clazz);
+ if (injections == null) {
+ injections = new HashMap<String, String>();
+ injectionMap.put(clazz, injections);
+ }
+ injections.put(injectionTarget.getTargetName(), jndiName);
+ }
+ }
+ }
+
/**
* Processes TLDs.
*
package org.apache.catalina.core;
-import java.lang.reflect.Method;
-import java.io.IOException;
-import java.io.InputStream;
import java.io.PrintStream;
+import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
-import java.util.Properties;
import java.util.Stack;
-import java.security.AccessController;
-import java.security.PrivilegedActionException;
-import java.security.PrivilegedExceptionAction;
-import javax.servlet.Servlet;
-import javax.servlet.ServletConfig;
-import javax.servlet.ServletContext;
-import javax.servlet.ServletException;
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
-import javax.servlet.SingleThreadModel;
-import javax.servlet.UnavailableException;
+
import javax.management.ListenerNotFoundException;
import javax.management.MBeanNotificationInfo;
import javax.management.Notification;
import javax.management.NotificationFilter;
import javax.management.NotificationListener;
import javax.management.ObjectName;
+import javax.servlet.Servlet;
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.SingleThreadModel;
+import javax.servlet.UnavailableException;
import org.apache.PeriodicEventListener;
import org.apache.catalina.Container;
import org.apache.catalina.InstanceEvent;
import org.apache.catalina.InstanceListener;
import org.apache.catalina.LifecycleException;
-import org.apache.catalina.Loader;
import org.apache.catalina.Wrapper;
+import org.apache.InstanceManager;
import org.apache.catalina.security.SecurityUtil;
import org.apache.catalina.util.Enumerator;
import org.apache.catalina.util.InstanceSupport;
pipeline.setBasic(swValve);
broadcaster = new NotificationBroadcasterSupport();
- if (restrictedServlets == null) {
- restrictedServlets = new Properties();
- try {
- InputStream is =
- this.getClass().getClassLoader().getResourceAsStream
- ("org/apache/catalina/core/RestrictedServlets.properties");
- if (is != null) {
- restrictedServlets.load(is);
- } else {
- log.error(sm.getString("standardWrapper.restrictedServletsResource"));
- }
- } catch (IOException e) {
- log.error(sm.getString("standardWrapper.restrictedServletsResource"), e);
- }
- }
-
}
ServletRequest.class,
ServletResponse.class};
- /**
- * Restricted servlets (which can only be loaded by a privileged webapp).
- */
- protected static Properties restrictedServlets = null;
-
-
+
// ------------------------------------------------------------- Properties
(sm.getString("standardWrapper.notClass", getName()));
}
- // Acquire an instance of the class loader to be used
- Loader loader = getLoader();
- if (loader == null) {
- unavailable(null);
- throw new ServletException
- (sm.getString("standardWrapper.missingLoader", getName()));
- }
-
- ClassLoader classLoader = loader.getClassLoader();
-
- // Special case class loader for a container provided servlet
- //
- if (isContainerProvidedServlet(actualClass) &&
- ! ((Context)getParent()).getPrivileged() ) {
- // If it is a priviledged context - using its own
- // class loader will work, since it's a child of the container
- // loader
- classLoader = this.getClass().getClassLoader();
- }
-
- // Load the specified servlet class from the appropriate class loader
- Class classClass = null;
- try {
- if (SecurityUtil.isPackageProtectionEnabled()){
- final ClassLoader fclassLoader = classLoader;
- final String factualClass = actualClass;
- try{
- classClass = (Class)AccessController.doPrivileged(
- new PrivilegedExceptionAction(){
- public Object run() throws Exception{
- if (fclassLoader != null) {
- return fclassLoader.loadClass(factualClass);
- } else {
- return Class.forName(factualClass);
- }
- }
- });
- } catch(PrivilegedActionException pax){
- Exception ex = pax.getException();
- if (ex instanceof ClassNotFoundException){
- throw (ClassNotFoundException)ex;
- } else {
- getServletContext().log( "Error loading "
- + fclassLoader + " " + factualClass, ex );
- }
- }
- } else {
- if (classLoader != null) {
- classClass = classLoader.loadClass(actualClass);
- } else {
- classClass = Class.forName(actualClass);
- }
- }
- } catch (ClassNotFoundException e) {
- unavailable(null);
- getServletContext().log( "Error loading " + classLoader + " " + actualClass, e );
- throw new ServletException
- (sm.getString("standardWrapper.missingClass", actualClass),
- e);
- }
-
- if (classClass == null) {
- unavailable(null);
- throw new ServletException
- (sm.getString("standardWrapper.missingClass", actualClass));
- }
-
- // Instantiate and initialize an instance of the servlet class itself
+ InstanceManager instanceManager = ((StandardContext)getParent()).getInstanceManager();
try {
- servlet = (Servlet) classClass.newInstance();
- // Annotation processing
- if (!((Context) getParent()).getIgnoreAnnotations()) {
- if (getParent() instanceof StandardContext) {
- ((StandardContext)getParent()).getAnnotationProcessor().processAnnotations(servlet);
- ((StandardContext)getParent()).getAnnotationProcessor().postConstruct(servlet);
- }
- }
+ servlet = (Servlet) instanceManager.newInstance(actualClass);
} catch (ClassCastException e) {
unavailable(null);
// Restore the context ClassLoader
(sm.getString("standardWrapper.notServlet", actualClass), e);
} catch (Throwable e) {
unavailable(null);
-
+
// Added extra log statement for Bugzilla 36630:
// http://issues.apache.org/bugzilla/show_bug.cgi?id=36630
if(log.isDebugEnabled()) {
(sm.getString("standardWrapper.instantiate", actualClass), e);
}
- // Check if loading the servlet in this web application should be
- // allowed
- if (!isServletAllowed(servlet)) {
- throw new SecurityException
- (sm.getString("standardWrapper.privilegedServlet",
- actualClass));
- }
-
// Special handling for ContainerServlet instances
if ((servlet instanceof ContainerServlet) &&
(isContainerProvidedServlet(actualClass) ||
// Annotation processing
if (!((Context) getParent()).getIgnoreAnnotations()) {
- ((StandardContext)getParent()).getAnnotationProcessor().preDestroy(instance);
+ ((StandardContext)getParent()).getInstanceManager().destroyInstance(instance);
}
} catch (Throwable t) {
}
// Annotation processing
if (!((Context) getParent()).getIgnoreAnnotations()) {
- ((StandardContext)getParent()).getAnnotationProcessor().preDestroy(s);
+ ((StandardContext)getParent()).getInstanceManager().destroyInstance(s);
}
}
} catch (Throwable t) {
}
- /**
- * Return <code>true</code> if loading this servlet is allowed.
- */
- protected boolean isServletAllowed(Object servlet) {
-
- // Privileged webapps may load all servlets without restriction
- if (((Context) getParent()).getPrivileged()) {
- return true;
- }
-
- if (servlet instanceof ContainerServlet) {
- return (false);
- }
-
- Class clazz = servlet.getClass();
- while (clazz != null && !clazz.getName().equals("javax.servlet.http.HttpServlet")) {
- if ("restricted".equals(restrictedServlets.getProperty(clazz.getName()))) {
- return (false);
- }
- clazz = clazz.getSuperclass();
- }
-
- return (true);
-
- }
-
-
protected Method[] getAllDeclaredMethods(Class c) {
if (c.equals(javax.servlet.http.HttpServlet.class)) {
broadcaster.sendNotification(notification);
}
} catch( Exception ex ) {
- log.info("Error registering servlet with jmx " + this, ex);
+ log.info("Error registering servlet with jmx " + this);
}
if (isJspServlet) {
.registerComponent(instance, jspMonitorON, null);
} catch( Exception ex ) {
log.info("Error registering JSP monitoring with jmx " +
- instance, ex);
+ instance);
}
}
}
is="true"
type="boolean"/>
- <attribute name="annotationProcessor"
- description="Object that processes things like injection annotations"
- type="org.apache.AnnotationProcessor" />
+ <attribute name="instanceManager"
+ description="Object that creates and destroys servlets, filters, and listeners. Include dependency injection and postConstruct/preDestory handling"
+ type="org.apache.catalina.instanceManagement.InstanceManager" />
<attribute name="antiJARLocking"
description="Take care to not lock jar files"
package org.apache.catalina.deploy;
import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
/**
* @version $Revision$ $Date$
*/
-public class ContextEnvironment implements Serializable {
+public class ContextEnvironment implements Serializable, Injectable {
// ------------------------------------------------------------- Properties
this.value = value;
}
+
+ private List<InjectionTarget> injectionTargets = new ArrayList<InjectionTarget>();
+
+ public void addInjectionTarget(String injectionTargetName, String jndiName) {
+ InjectionTarget target = new InjectionTarget(injectionTargetName, jndiName);
+ injectionTargets.add(target);
+ }
+
+ public List<InjectionTarget> getInjectionTargets() {
+ return injectionTargets;
+ }
+
// --------------------------------------------------------- Public Methods
--- /dev/null
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+
+package org.apache.catalina.deploy;
+
+import java.util.List;
+
+public interface Injectable {
+ public String getName();
+ public void addInjectionTarget(String injectionTargetName, String jndiName);
+ public List<InjectionTarget> getInjectionTargets();
+}
--- /dev/null
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+
+package org.apache.catalina.deploy;
+
+/**
+ * @version $Rev:$ $Date:$
+ */
+public class InjectionTarget {
+ private String targetClass;
+ private String targetName;
+
+
+ public InjectionTarget() {
+ }
+
+ public InjectionTarget(String targetClass, String targetName) {
+ this.targetClass = targetClass;
+ this.targetName = targetName;
+ }
+
+ public String getTargetClass() {
+ return targetClass;
+ }
+
+ public void setTargetClass(String targetClass) {
+ this.targetClass = targetClass;
+ }
+
+ public String getTargetName() {
+ return targetName;
+ }
+
+ public void setTargetName(String targetName) {
+ this.targetName = targetName;
+ }
+
+}
package org.apache.catalina.deploy;
import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
/**
* @since Tomcat 5.0
*/
-public class MessageDestinationRef implements Serializable {
+public class MessageDestinationRef implements Serializable, Injectable {
// ------------------------------------------------------------- Properties
this.usage = usage;
}
+ private List<InjectionTarget> injectionTargets = new ArrayList<InjectionTarget>();
+
+ public void addInjectionTarget(String injectionTargetName, String jndiName) {
+ InjectionTarget target = new InjectionTarget(injectionTargetName, jndiName);
+ injectionTargets.add(target);
+ }
+
+ public List<InjectionTarget> getInjectionTargets() {
+ return injectionTargets;
+ }
// --------------------------------------------------------- Public Methods
import java.io.Serializable;
import java.util.Iterator;
import java.util.HashMap;
+import java.util.List;
+import java.util.ArrayList;
/**
* @version $Revision$ $Date$
*/
-public class ResourceBase implements Serializable {
+public class ResourceBase implements Serializable, Injectable {
// ------------------------------------------------------------- Properties
public Iterator listProperties() {
return properties.keySet().iterator();
}
-
-
+
+ private List<InjectionTarget> injectionTargets = new ArrayList<InjectionTarget>();
+
+ public void addInjectionTarget(String injectionTargetName, String jndiName) {
+ InjectionTarget target = new InjectionTarget(injectionTargetName, jndiName);
+ injectionTargets.add(target);
+ }
+
+ public List<InjectionTarget> getInjectionTargets() {
+ return injectionTargets;
+ }
+
// -------------------------------------------------------- Package Methods
(basePackage +
"core.StandardWrapper$1");
loader.loadClass
- (basePackage +
- "core.ApplicationHttpRequest$AttributeNamesEnumerator");
+ (basePackage +
+ "core.ApplicationHttpRequest$AttributeNamesEnumerator");
}
import org.apache.catalina.deploy.ContextHandler;
import org.apache.catalina.deploy.ContextService;
import org.apache.catalina.deploy.SecurityConstraint;
-import org.apache.catalina.deploy.SecurityRoleRef;
import org.apache.tomcat.util.IntrospectionUtils;
import org.apache.tomcat.util.digester.CallMethodRule;
import org.apache.tomcat.util.digester.CallParamRule;
digester.addRule(prefix + "web-app/distributable",
new SetDistributableRule());
- digester.addObjectCreate(prefix + "web-app/ejb-local-ref",
- "org.apache.catalina.deploy.ContextLocalEjb");
- digester.addRule(prefix + "web-app/ejb-local-ref",
- new SetNextNamingRule("addLocalEjb",
- "org.apache.catalina.deploy.ContextLocalEjb"));
-
- digester.addCallMethod(prefix + "web-app/ejb-local-ref/description",
- "setDescription", 0);
- digester.addCallMethod(prefix + "web-app/ejb-local-ref/ejb-link",
- "setLink", 0);
- digester.addCallMethod(prefix + "web-app/ejb-local-ref/ejb-ref-name",
- "setName", 0);
- digester.addCallMethod(prefix + "web-app/ejb-local-ref/ejb-ref-type",
- "setType", 0);
- digester.addCallMethod(prefix + "web-app/ejb-local-ref/local",
- "setLocal", 0);
- digester.addCallMethod(prefix + "web-app/ejb-local-ref/local-home",
- "setHome", 0);
-
- digester.addObjectCreate(prefix + "web-app/ejb-ref",
- "org.apache.catalina.deploy.ContextEjb");
- digester.addRule(prefix + "web-app/ejb-ref",
- new SetNextNamingRule("addEjb",
- "org.apache.catalina.deploy.ContextEjb"));
-
- digester.addCallMethod(prefix + "web-app/ejb-ref/description",
- "setDescription", 0);
- digester.addCallMethod(prefix + "web-app/ejb-ref/ejb-link",
- "setLink", 0);
- digester.addCallMethod(prefix + "web-app/ejb-ref/ejb-ref-name",
- "setName", 0);
- digester.addCallMethod(prefix + "web-app/ejb-ref/ejb-ref-type",
- "setType", 0);
- digester.addCallMethod(prefix + "web-app/ejb-ref/home",
- "setHome", 0);
- digester.addCallMethod(prefix + "web-app/ejb-ref/remote",
- "setRemote", 0);
-
- digester.addObjectCreate(prefix + "web-app/env-entry",
- "org.apache.catalina.deploy.ContextEnvironment");
- digester.addRule(prefix + "web-app/env-entry",
- new SetNextNamingRule("addEnvironment",
- "org.apache.catalina.deploy.ContextEnvironment"));
-
- digester.addCallMethod(prefix + "web-app/env-entry/description",
- "setDescription", 0);
- digester.addCallMethod(prefix + "web-app/env-entry/env-entry-name",
- "setName", 0);
- digester.addCallMethod(prefix + "web-app/env-entry/env-entry-type",
- "setType", 0);
- digester.addCallMethod(prefix + "web-app/env-entry/env-entry-value",
- "setValue", 0);
+ configureNamingRules(digester);
digester.addObjectCreate(prefix + "web-app/error-page",
"org.apache.catalina.deploy.ErrorPage");
digester.addCallParam(prefix + "web-app/mime-mapping/extension", 0);
digester.addCallParam(prefix + "web-app/mime-mapping/mime-type", 1);
+
+ digester.addObjectCreate(prefix + "web-app/security-constraint",
+ "org.apache.catalina.deploy.SecurityConstraint");
+ digester.addSetNext(prefix + "web-app/security-constraint",
+ "addConstraint",
+ "org.apache.catalina.deploy.SecurityConstraint");
+
+ digester.addRule(prefix + "web-app/security-constraint/auth-constraint",
+ new SetAuthConstraintRule());
+ digester.addCallMethod(prefix + "web-app/security-constraint/auth-constraint/role-name",
+ "addAuthRole", 0);
+ digester.addCallMethod(prefix + "web-app/security-constraint/display-name",
+ "setDisplayName", 0);
+ digester.addCallMethod(prefix + "web-app/security-constraint/user-data-constraint/transport-guarantee",
+ "setUserConstraint", 0);
+
+ digester.addObjectCreate(prefix + "web-app/security-constraint/web-resource-collection",
+ "org.apache.catalina.deploy.SecurityCollection");
+ digester.addSetNext(prefix + "web-app/security-constraint/web-resource-collection",
+ "addCollection",
+ "org.apache.catalina.deploy.SecurityCollection");
+ digester.addCallMethod(prefix + "web-app/security-constraint/web-resource-collection/http-method",
+ "addMethod", 0);
+ digester.addCallMethod(prefix + "web-app/security-constraint/web-resource-collection/url-pattern",
+ "addPattern", 0);
+ digester.addCallMethod(prefix + "web-app/security-constraint/web-resource-collection/web-resource-name",
+ "setName", 0);
+
+ digester.addCallMethod(prefix + "web-app/security-role/role-name",
+ "addSecurityRole", 0);
+
+ digester.addRule(prefix + "web-app/servlet",
+ new WrapperCreateRule());
+ digester.addSetNext(prefix + "web-app/servlet",
+ "addChild",
+ "org.apache.catalina.Container");
+
+ digester.addCallMethod(prefix + "web-app/servlet/init-param",
+ "addInitParameter", 2);
+ digester.addCallParam(prefix + "web-app/servlet/init-param/param-name",
+ 0);
+ digester.addCallParam(prefix + "web-app/servlet/init-param/param-value",
+ 1);
+
+ digester.addCallMethod(prefix + "web-app/servlet/jsp-file",
+ "setJspFile", 0);
+ digester.addCallMethod(prefix + "web-app/servlet/load-on-startup",
+ "setLoadOnStartupString", 0);
+ digester.addCallMethod(prefix + "web-app/servlet/run-as/role-name",
+ "setRunAs", 0);
+
+ digester.addCallMethod(prefix + "web-app/servlet/security-role-ref",
+ "addSecurityReference", 2);
+ digester.addCallParam(prefix + "web-app/servlet/security-role-ref/role-link", 1);
+ digester.addCallParam(prefix + "web-app/servlet/security-role-ref/role-name", 0);
+
+ digester.addCallMethod(prefix + "web-app/servlet/servlet-class",
+ "setServletClass", 0);
+ digester.addCallMethod(prefix + "web-app/servlet/servlet-name",
+ "setName", 0);
+
+ digester.addRule(prefix + "web-app/servlet-mapping",
+ new CallMethodMultiRule("addServletMapping", 2, 0));
+ digester.addCallParam(prefix + "web-app/servlet-mapping/servlet-name", 1);
+ digester.addRule(prefix + "web-app/servlet-mapping/url-pattern", new CallParamMultiRule(0));
+
+ digester.addRule(prefix + "web-app/session-config",
+ sessionConfig);
+
+ digester.addCallMethod(prefix + "web-app/session-config/session-timeout",
+ "setSessionTimeout", 1,
+ new Class[] { Integer.TYPE });
+ digester.addCallParam(prefix + "web-app/session-config/session-timeout", 0);
+
+ digester.addCallMethod(prefix + "web-app/taglib",
+ "addTaglib", 2);
+ digester.addCallParam(prefix + "web-app/taglib/taglib-location", 1);
+ digester.addCallParam(prefix + "web-app/taglib/taglib-uri", 0);
+
+ digester.addCallMethod(prefix + "web-app/welcome-file-list/welcome-file",
+ "addWelcomeFile", 0);
+
+ digester.addCallMethod(prefix + "web-app/locale-encoding-mapping-list/locale-encoding-mapping",
+ "addLocaleEncodingMappingParameter", 2);
+ digester.addCallParam(prefix + "web-app/locale-encoding-mapping-list/locale-encoding-mapping/locale", 0);
+ digester.addCallParam(prefix + "web-app/locale-encoding-mapping-list/locale-encoding-mapping/encoding", 1);
+
+ }
+
+ protected void configureNamingRules(Digester digester) {
+ //ejb-local-ref
+ digester.addObjectCreate(prefix + "web-app/ejb-local-ref",
+ "org.apache.catalina.deploy.ContextLocalEjb");
+ digester.addRule(prefix + "web-app/ejb-local-ref",
+ new SetNextNamingRule("addLocalEjb",
+ "org.apache.catalina.deploy.ContextLocalEjb"));
+
+ digester.addCallMethod(prefix + "web-app/ejb-local-ref/description",
+ "setDescription", 0);
+ digester.addCallMethod(prefix + "web-app/ejb-local-ref/ejb-link",
+ "setLink", 0);
+ digester.addCallMethod(prefix + "web-app/ejb-local-ref/ejb-ref-name",
+ "setName", 0);
+ digester.addCallMethod(prefix + "web-app/ejb-local-ref/ejb-ref-type",
+ "setType", 0);
+ digester.addCallMethod(prefix + "web-app/ejb-local-ref/local",
+ "setLocal", 0);
+ digester.addCallMethod(prefix + "web-app/ejb-local-ref/local-home",
+ "setHome", 0);
+ configureInjectionRules(digester, "web-app/ejb-local-ref/");
+
+ //ejb-ref
+ digester.addObjectCreate(prefix + "web-app/ejb-ref",
+ "org.apache.catalina.deploy.ContextEjb");
+ digester.addRule(prefix + "web-app/ejb-ref",
+ new SetNextNamingRule("addEjb",
+ "org.apache.catalina.deploy.ContextEjb"));
+
+ digester.addCallMethod(prefix + "web-app/ejb-ref/description",
+ "setDescription", 0);
+ digester.addCallMethod(prefix + "web-app/ejb-ref/ejb-link",
+ "setLink", 0);
+ digester.addCallMethod(prefix + "web-app/ejb-ref/ejb-ref-name",
+ "setName", 0);
+ digester.addCallMethod(prefix + "web-app/ejb-ref/ejb-ref-type",
+ "setType", 0);
+ digester.addCallMethod(prefix + "web-app/ejb-ref/home",
+ "setHome", 0);
+ digester.addCallMethod(prefix + "web-app/ejb-ref/remote",
+ "setRemote", 0);
+ configureInjectionRules(digester, "web-app/ejb-ref/");
+
+ //env-entry
+ digester.addObjectCreate(prefix + "web-app/env-entry",
+ "org.apache.catalina.deploy.ContextEnvironment");
+ digester.addRule(prefix + "web-app/env-entry",
+ new SetNextNamingRule("addEnvironment",
+ "org.apache.catalina.deploy.ContextEnvironment"));
+
+ digester.addCallMethod(prefix + "web-app/env-entry/description",
+ "setDescription", 0);
+ digester.addCallMethod(prefix + "web-app/env-entry/env-entry-name",
+ "setName", 0);
+ digester.addCallMethod(prefix + "web-app/env-entry/env-entry-type",
+ "setType", 0);
+ digester.addCallMethod(prefix + "web-app/env-entry/env-entry-value",
+ "setValue", 0);
+ configureInjectionRules(digester, "web-app/env-entry/");
+
+ //resource-env-ref
digester.addObjectCreate(prefix + "web-app/resource-env-ref",
"org.apache.catalina.deploy.ContextResourceEnvRef");
digester.addRule(prefix + "web-app/resource-env-ref",
"setName", 0);
digester.addCallMethod(prefix + "web-app/resource-env-ref/resource-env-ref-type",
"setType", 0);
+ configureInjectionRules(digester, "web-app/ejb-local-ref/");
+ //message-destination
digester.addObjectCreate(prefix + "web-app/message-destination",
"org.apache.catalina.deploy.MessageDestination");
digester.addSetNext(prefix + "web-app/message-destination",
digester.addCallMethod(prefix + "web-app/message-destination/message-destination-name",
"setName", 0);
+ //message-destination-ref
digester.addObjectCreate(prefix + "web-app/message-destination-ref",
"org.apache.catalina.deploy.MessageDestinationRef");
digester.addSetNext(prefix + "web-app/message-destination-ref",
digester.addCallMethod(prefix + "web-app/message-destination-ref/message-destination-usage",
"setUsage", 0);
+ configureInjectionRules(digester, "web-app/message-destination-ref/");
+
+ //resource-ref
digester.addObjectCreate(prefix + "web-app/resource-ref",
"org.apache.catalina.deploy.ContextResource");
digester.addRule(prefix + "web-app/resource-ref",
"setScope", 0);
digester.addCallMethod(prefix + "web-app/resource-ref/res-type",
"setType", 0);
+ configureInjectionRules(digester, "web-app/resource-ref/");
- digester.addObjectCreate(prefix + "web-app/security-constraint",
- "org.apache.catalina.deploy.SecurityConstraint");
- digester.addSetNext(prefix + "web-app/security-constraint",
- "addConstraint",
- "org.apache.catalina.deploy.SecurityConstraint");
-
- digester.addRule(prefix + "web-app/security-constraint/auth-constraint",
- new SetAuthConstraintRule());
- digester.addCallMethod(prefix + "web-app/security-constraint/auth-constraint/role-name",
- "addAuthRole", 0);
- digester.addCallMethod(prefix + "web-app/security-constraint/display-name",
- "setDisplayName", 0);
- digester.addCallMethod(prefix + "web-app/security-constraint/user-data-constraint/transport-guarantee",
- "setUserConstraint", 0);
-
- digester.addObjectCreate(prefix + "web-app/security-constraint/web-resource-collection",
- "org.apache.catalina.deploy.SecurityCollection");
- digester.addSetNext(prefix + "web-app/security-constraint/web-resource-collection",
- "addCollection",
- "org.apache.catalina.deploy.SecurityCollection");
- digester.addCallMethod(prefix + "web-app/security-constraint/web-resource-collection/http-method",
- "addMethod", 0);
- digester.addCallMethod(prefix + "web-app/security-constraint/web-resource-collection/url-pattern",
- "addPattern", 0);
- digester.addCallMethod(prefix + "web-app/security-constraint/web-resource-collection/web-resource-name",
- "setName", 0);
-
- digester.addCallMethod(prefix + "web-app/security-role/role-name",
- "addSecurityRole", 0);
-
+ //service-ref
digester.addObjectCreate(prefix + "web-app/service-ref",
"org.apache.catalina.deploy.ContextService");
digester.addRule(prefix + "web-app/service-ref",
digester.addRule(prefix + "web-app/service-ref/handler",
new SetNextRule("addHandler",
"org.apache.catalina.deploy.ContextHandler"));
-
+
digester.addCallMethod(prefix + "web-app/service-ref/handler/handler-name",
"setName", 0);
digester.addCallMethod(prefix + "web-app/service-ref/handler/handler-class",
"addSoapRole", 0);
digester.addCallMethod(prefix + "web-app/service-ref/handler/port-name",
"addPortName", 0);
-
- digester.addRule(prefix + "web-app/servlet",
- new WrapperCreateRule());
- digester.addSetNext(prefix + "web-app/servlet",
- "addChild",
- "org.apache.catalina.Container");
-
- digester.addCallMethod(prefix + "web-app/servlet/init-param",
- "addInitParameter", 2);
- digester.addCallParam(prefix + "web-app/servlet/init-param/param-name",
- 0);
- digester.addCallParam(prefix + "web-app/servlet/init-param/param-value",
- 1);
-
- digester.addCallMethod(prefix + "web-app/servlet/jsp-file",
- "setJspFile", 0);
- digester.addCallMethod(prefix + "web-app/servlet/load-on-startup",
- "setLoadOnStartupString", 0);
- digester.addCallMethod(prefix + "web-app/servlet/run-as/role-name",
- "setRunAs", 0);
-
- digester.addRule(prefix + "web-app/servlet/security-role-ref",
- new SecurityRoleRefCreateRule());
- digester.addCallMethod(
- prefix + "web-app/servlet/security-role-ref/role-link",
- "setLink", 0);
- digester.addCallMethod(
- prefix + "web-app/servlet/security-role-ref/role-name",
- "setName", 0);
-
- digester.addCallMethod(prefix + "web-app/servlet/servlet-class",
- "setServletClass", 0);
- digester.addCallMethod(prefix + "web-app/servlet/servlet-name",
- "setName", 0);
-
- digester.addRule(prefix + "web-app/servlet-mapping",
- new CallMethodMultiRule("addServletMapping", 2, 0));
- digester.addCallParam(prefix + "web-app/servlet-mapping/servlet-name", 1);
- digester.addRule(prefix + "web-app/servlet-mapping/url-pattern", new CallParamMultiRule(0));
+ configureInjectionRules(digester, "web-app/service-ref/");
- digester.addRule(prefix + "web-app/session-config",
- sessionConfig);
-
- digester.addCallMethod(prefix + "web-app/session-config/session-timeout",
- "setSessionTimeout", 1,
- new Class[] { Integer.TYPE });
- digester.addCallParam(prefix + "web-app/session-config/session-timeout", 0);
- digester.addCallMethod(prefix + "web-app/taglib",
- "addTaglib", 2);
- digester.addCallParam(prefix + "web-app/taglib/taglib-location", 1);
- digester.addCallParam(prefix + "web-app/taglib/taglib-uri", 0);
+ }
- digester.addCallMethod(prefix + "web-app/welcome-file-list/welcome-file",
- "addWelcomeFile", 0);
+ protected void configureInjectionRules(Digester digester, String base) {
- digester.addCallMethod(prefix + "web-app/locale-encoding-mapping-list/locale-encoding-mapping",
- "addLocaleEncodingMappingParameter", 2);
- digester.addCallParam(prefix + "web-app/locale-encoding-mapping-list/locale-encoding-mapping/locale", 0);
- digester.addCallParam(prefix + "web-app/locale-encoding-mapping-list/locale-encoding-mapping/encoding", 1);
+ digester.addCallMethod(prefix + base + "injection-target", "addInjectionTarget", 2);
+ digester.addCallParam(prefix + base + "injection-target/injection-target-class", 0);
+ digester.addCallParam(prefix + base + "injection-target/injection-target-name", 1);
}
+
/**
* Reset counter used for validating the web.xml file.
*/
public void begin(String namespace, String name, Attributes attributes)
throws Exception {
+ Context context = (Context) digester.peek(digester.getCount() - 1);
Object top = digester.peek();
Class paramClasses[] = new Class[1];
paramClasses[0] = "String".getClass();
}
}
-/**
- * A Rule that adds a security-role-ref to a servlet, allowing for the fact that
- * role-link is an optional element.
- */
-final class SecurityRoleRefCreateRule extends Rule {
-
- public SecurityRoleRefCreateRule() {
- }
-
- public void begin(String namespace, String name, Attributes attributes)
- throws Exception {
- SecurityRoleRef securityRoleRef = new SecurityRoleRef();
- digester.push(securityRoleRef);
- if (digester.getLogger().isDebugEnabled())
- digester.getLogger().debug("new SecurityRoleRef");
- }
-
- public void end(String namespace, String name)
- throws Exception {
- SecurityRoleRef securityRoleRef = (SecurityRoleRef) digester.pop();
- Wrapper wrapper = (Wrapper) digester.peek();
-
- wrapper.addSecurityReference(securityRoleRef.getName(),
- securityRoleRef.getLink());
-
- if (digester.getLogger().isDebugEnabled())
- digester.getLogger().debug("pop SecurityRoleRef");
- }
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.catalina.util;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-
-import javax.annotation.PostConstruct;
-import javax.annotation.PreDestroy;
-import javax.annotation.Resource;
-import javax.ejb.EJB;
-import javax.naming.NamingException;
-import javax.persistence.PersistenceContext;
-import javax.persistence.PersistenceUnit;
-import javax.xml.ws.WebServiceRef;
-
-import org.apache.AnnotationProcessor;
-
-
-/**
- * Verify the annotation and Process it.
- *
- * @author Fabien Carrion
- * @author Remy Maucherat
- * @version $Revision$, $Date$
- */
-public class DefaultAnnotationProcessor implements AnnotationProcessor {
-
- protected javax.naming.Context context = null;
-
- public DefaultAnnotationProcessor(javax.naming.Context context) {
- this.context = context;
- }
-
-
- /**
- * Call postConstruct method on the specified instance.
- */
- public void postConstruct(Object instance)
- throws IllegalAccessException, InvocationTargetException {
-
- Method[] methods = instance.getClass().getDeclaredMethods();
- Method postConstruct = null;
- for (int i = 0; i < methods.length; i++) {
- if (methods[i].isAnnotationPresent(PostConstruct.class)) {
- if ((postConstruct != null)
- || (methods[i].getParameterTypes().length != 0)
- || (Modifier.isStatic(methods[i].getModifiers()))
- || (methods[i].getExceptionTypes().length > 0)
- || (!methods[i].getReturnType().getName().equals("void"))) {
- throw new IllegalArgumentException("Invalid PostConstruct annotation");
- }
- postConstruct = methods[i];
- }
- }
-
- // At the end the postconstruct annotated
- // method is invoked
- if (postConstruct != null) {
- boolean accessibility = postConstruct.isAccessible();
- postConstruct.setAccessible(true);
- postConstruct.invoke(instance);
- postConstruct.setAccessible(accessibility);
- }
-
- }
-
-
- /**
- * Call preDestroy method on the specified instance.
- */
- public void preDestroy(Object instance)
- throws IllegalAccessException, InvocationTargetException {
-
- Method[] methods = instance.getClass().getDeclaredMethods();
- Method preDestroy = null;
- for (int i = 0; i < methods.length; i++) {
- if (methods[i].isAnnotationPresent(PreDestroy.class)) {
- if ((preDestroy != null)
- || (methods[i].getParameterTypes().length != 0)
- || (Modifier.isStatic(methods[i].getModifiers()))
- || (methods[i].getExceptionTypes().length > 0)
- || (!methods[i].getReturnType().getName().equals("void"))) {
- throw new IllegalArgumentException("Invalid PreDestroy annotation");
- }
- preDestroy = methods[i];
- }
- }
-
- // At the end the postconstruct annotated
- // method is invoked
- if (preDestroy != null) {
- boolean accessibility = preDestroy.isAccessible();
- preDestroy.setAccessible(true);
- preDestroy.invoke(instance);
- preDestroy.setAccessible(accessibility);
- }
-
- }
-
-
- /**
- * Inject resources in specified instance.
- */
- public void processAnnotations(Object instance)
- throws IllegalAccessException, InvocationTargetException, NamingException {
-
- if (context == null) {
- // No resource injection
- return;
- }
-
- // Initialize fields annotations
- Field[] fields = instance.getClass().getDeclaredFields();
- for (int i = 0; i < fields.length; i++) {
- if (fields[i].isAnnotationPresent(Resource.class)) {
- Resource annotation = (Resource) fields[i].getAnnotation(Resource.class);
- lookupFieldResource(context, instance, fields[i], annotation.name());
- }
- if (fields[i].isAnnotationPresent(EJB.class)) {
- EJB annotation = (EJB) fields[i].getAnnotation(EJB.class);
- lookupFieldResource(context, instance, fields[i], annotation.name());
- }
- if (fields[i].isAnnotationPresent(WebServiceRef.class)) {
- WebServiceRef annotation =
- (WebServiceRef) fields[i].getAnnotation(WebServiceRef.class);
- lookupFieldResource(context, instance, fields[i], annotation.name());
- }
- if (fields[i].isAnnotationPresent(PersistenceContext.class)) {
- PersistenceContext annotation =
- (PersistenceContext) fields[i].getAnnotation(PersistenceContext.class);
- lookupFieldResource(context, instance, fields[i], annotation.name());
- }
- if (fields[i].isAnnotationPresent(PersistenceUnit.class)) {
- PersistenceUnit annotation =
- (PersistenceUnit) fields[i].getAnnotation(PersistenceUnit.class);
- lookupFieldResource(context, instance, fields[i], annotation.name());
- }
- }
-
- // Initialize methods annotations
- Method[] methods = instance.getClass().getDeclaredMethods();
- for (int i = 0; i < methods.length; i++) {
- if (methods[i].isAnnotationPresent(Resource.class)) {
- Resource annotation = (Resource) methods[i].getAnnotation(Resource.class);
- lookupMethodResource(context, instance, methods[i], annotation.name());
- }
- if (methods[i].isAnnotationPresent(EJB.class)) {
- EJB annotation = (EJB) methods[i].getAnnotation(EJB.class);
- lookupMethodResource(context, instance, methods[i], annotation.name());
- }
- if (methods[i].isAnnotationPresent(WebServiceRef.class)) {
- WebServiceRef annotation =
- (WebServiceRef) methods[i].getAnnotation(WebServiceRef.class);
- lookupMethodResource(context, instance, methods[i], annotation.name());
- }
- if (methods[i].isAnnotationPresent(PersistenceContext.class)) {
- PersistenceContext annotation =
- (PersistenceContext) methods[i].getAnnotation(PersistenceContext.class);
- lookupMethodResource(context, instance, methods[i], annotation.name());
- }
- if (methods[i].isAnnotationPresent(PersistenceUnit.class)) {
- PersistenceUnit annotation =
- (PersistenceUnit) methods[i].getAnnotation(PersistenceUnit.class);
- lookupMethodResource(context, instance, methods[i], annotation.name());
- }
- }
-
- }
-
-
- /**
- * Inject resources in specified field.
- */
- protected static void lookupFieldResource(javax.naming.Context context,
- Object instance, Field field, String name)
- throws NamingException, IllegalAccessException {
-
- Object lookedupResource = null;
- boolean accessibility = false;
-
- if ((name != null) &&
- (name.length() > 0)) {
- lookedupResource = context.lookup(name);
- } else {
- lookedupResource = context.lookup(instance.getClass().getName() + "/" + field.getName());
- }
-
- accessibility = field.isAccessible();
- field.setAccessible(true);
- field.set(instance, lookedupResource);
- field.setAccessible(accessibility);
- }
-
-
- /**
- * Inject resources in specified method.
- */
- protected static void lookupMethodResource(javax.naming.Context context,
- Object instance, Method method, String name)
- throws NamingException, IllegalAccessException, InvocationTargetException {
-
- if (!method.getName().startsWith("set")
- || method.getParameterTypes().length != 1
- || !method.getReturnType().getName().equals("void")) {
- throw new IllegalArgumentException("Invalid method resource injection annotation");
- }
-
- Object lookedupResource = null;
- boolean accessibility = false;
-
- if ((name != null) &&
- (name.length() > 0)) {
- lookedupResource = context.lookup(name);
- } else {
- lookedupResource =
- context.lookup(instance.getClass().getName() + "/" + method.getName().substring(3));
- }
-
- accessibility = method.isAccessible();
- method.setAccessible(true);
- method.invoke(instance, lookedupResource);
- method.setAccessible(accessibility);
- }
-
-
-}
public static final boolean IS_SECURITY_ENABLED =
(System.getSecurityManager() != null);
+ public static final boolean USE_INSTANCE_MANAGER_FOR_TAGS =
+ Boolean.valueOf(System.getProperty("org.apache.jasper.Constants.USE_INSTANCE_MANAGER_FOR_TAGS", "false")).booleanValue();
+
/**
* The name of the path parameter used to pass the session identifier
* back and forth with the client.
try {
getJspLoader();
- String name;
- if (isTagFile()) {
- name = tagInfo.getTagClassName();
- } else {
- name = getServletPackageName() + "." + getServletClassName();
- }
+ String name = getFQCN();
servletClass = jspLoader.loadClass(name);
} catch (ClassNotFoundException cex) {
throw new JasperException(Localizer.getMessage("jsp.error.unable.load"),
return servletClass;
}
+ public String getFQCN() {
+ String name;
+ if (isTagFile()) {
+ name = tagInfo.getTagClassName();
+ } else {
+ name = getServletPackageName() + "." + getServletClassName();
+ }
+ return name;
+ }
+
// ==================== protected methods ====================
static Object outputDirLock = new Object();
/**
* Generate Java source from Nodes
- *
+ *
* @author Anil K. Vijendran
* @author Danno Ferrin
* @author Mandar Raje
* @author Rajiv Mordani
* @author Pierre Delisle
- *
+ *
* Tomcat 4.1.x and Tomcat 5:
* @author Kin-man Chung
* @author Jan Luehe
* @author Shawn Bayern
* @author Mark Roth
* @author Denis Benoit
- *
+ *
* Tomcat 6.x
* @author Jacob Hookom
* @author Remy Maucherat
private static final Class[] OBJECT_CLASS = { Object.class };
- private static final String VAR_EXPRESSIONFACTORY =
+ private static final String VAR_EXPRESSIONFACTORY =
System.getProperty("org.apache.jasper.compiler.Generator.VAR_EXPRESSIONFACTORY", "_el_expressionfactory");
- private static final String VAR_ANNOTATIONPROCESSOR =
- System.getProperty("org.apache.jasper.compiler.Generator.VAR_ANNOTATIONPROCESSOR", "_jsp_annotationprocessor");
+ private static final String VAR_INSTANCEMANAGER =
+ System.getProperty("org.apache.jasper.compiler.Generator.VAR_INSTANCEMANAGER", "_jsp_instancemanager");
private ServletWriter out;
/*
* Generates getServletInfo() method that returns the value of the
* page directive's 'info' attribute, if present.
- *
+ *
* The Validator has already ensured that if the translation unit
* contains more than one page directive with an 'info' attribute,
* their values match.
/*
* Constructor
- *
+ *
* @param v Vector of tag handler pool names to populate
*/
TagHandlerPoolVisitor(Vector v) {
/*
* Creates the name of the tag handler pool whose tag handlers may
* be (re)used to service this action.
- *
+ *
* @return The name of the tag handler pool
*/
private String createTagHandlerPoolName(String prefix,
* Generates the _jspInit() method for instantiating the tag handler pools.
* For tag file, _jspInit has to be invoked manually, and the ServletConfig
* object explicitly passed.
- *
+ *
* In JSP 2.1, we also instantiate an ExpressionFactory
*/
private void generateInit() {
out.println(");");
}
}
-
+
out.printin(VAR_EXPRESSIONFACTORY);
out.print(" = _jspxFactory.getJspApplicationContext(");
if (ctxt.isTagFile()) {
}
out.println(".getServletContext()).getExpressionFactory();");
- out.printin(VAR_ANNOTATIONPROCESSOR);
- out.print(" = (org.apache.AnnotationProcessor) ");
+ out.printin(VAR_INSTANCEMANAGER);
+ out.print(" = org.apache.jasper.runtime.InstanceManagerFactory.getInstanceManager(");
if (ctxt.isTagFile()) {
out.print("config");
} else {
out.print("getServletConfig()");
}
- out.println(".getServletContext().getAttribute(org.apache.AnnotationProcessor.class.getName());");
+ out.println(");");
out.popIndent();
out.printil("}");
out.printil("public void _jspDestroy() {");
out.pushIndent();
-
+
if (isPoolingEnabled) {
for (int i = 0; i < tagHandlerPoolNames.size(); i++) {
out.printin((String) tagHandlerPoolNames.elementAt(i));
out.println(".release();");
}
}
-
+
out.popIndent();
out.printil("}");
out.println();
* Declare tag handler pools (tags of the same type and with the same
* attribute set share the same tag handler pool) (shared by servlet and tag
* handler preamble generation)
- *
+ *
* In JSP 2.1, we also scope an instance of ExpressionFactory
*/
private void genPreambleClassVariableDeclarations(String className)
out.printin("private javax.el.ExpressionFactory ");
out.print(VAR_EXPRESSIONFACTORY);
out.println(";");
- out.printin("private org.apache.AnnotationProcessor ");
- out.print(VAR_ANNOTATIONPROCESSOR);
+ out.printin("private org.apache.InstanceManager ");
+ out.print(VAR_INSTANCEMANAGER);
out.println(";");
out.println();
}
out.popIndent();
out.printil("}");
out.println();
-
+
generateInit();
generateDestroy();
}
* interpreter. If the result is a Named Attribute we insert the
* generated variable name. Otherwise the result is a string literal,
* quoted and escaped.
- *
+ *
* @param attr
* An JspAttribute object
* @param encode
/**
* Prints the attribute value specified in the param action, in the form
* of name=value string.
- *
+ *
* @param n
* the parent node for the param action nodes.
*/
String tagHandlerClassName = JspUtil
.getCanonicalName(tagHandlerClass);
- out.printin(tagHandlerClassName);
- out.print(" ");
- out.print(tagHandlerVar);
- out.print(" = ");
if (isPoolingEnabled && !(n.implementsJspIdConsumer())) {
+ out.printin(tagHandlerClassName);
+ out.print(" ");
+ out.print(tagHandlerVar);
+ out.print(" = ");
out.print("(");
out.print(tagHandlerClassName);
out.print(") ");
out.print(tagHandlerClassName);
out.println(".class);");
} else {
- out.print("new ");
- out.print(tagHandlerClassName);
- out.println("();");
- out.printin("org.apache.jasper.runtime.AnnotationHelper.postConstruct(");
- out.print(VAR_ANNOTATIONPROCESSOR);
- out.print(", ");
- out.print(tagHandlerVar);
- out.println(");");
+ writeNewInstance(tagHandlerVar, tagHandlerClassName);
}
// includes setting the context
out.println("[0]++;");
}
out.printin(tagHandlerVar);
- out
- .println(".setBodyContent((javax.servlet.jsp.tagext.BodyContent) out);");
+ out.println(".setBodyContent((javax.servlet.jsp.tagext.BodyContent) out);");
out.printin(tagHandlerVar);
out.println(".doInitBody();");
n.setEndJavaLine(out.getJavaLine());
}
+ private void writeNewInstance(String tagHandlerVar, String tagHandlerClassName) {
+ if (Constants.USE_INSTANCE_MANAGER_FOR_TAGS) {
+ out.printin(tagHandlerClassName);
+ out.print(" ");
+ out.print(tagHandlerVar);
+ out.print(" = (");
+ out.print(tagHandlerClassName);
+ out.print(")");
+ out.print(VAR_INSTANCEMANAGER);
+ out.print(".newInstance(\"");
+ out.print(tagHandlerClassName);
+ out.println("\", this.getClass().getClassLoader());");
+ } else {
+ out.printin(tagHandlerClassName);
+ out.print(" ");
+ out.print(tagHandlerVar);
+ out.print(" = (");
+ out.print("new ");
+ out.print(tagHandlerClassName);
+ out.println("());");
+ out.printin(VAR_INSTANCEMANAGER);
+ out.print(".newInstance(");
+ out.print(tagHandlerVar);
+ out.println(");");
+ }
+ }
+
+ private void writeDestroyInstance(String tagHandlerVar) {
+ out.printin(VAR_INSTANCEMANAGER);
+ out.print(".destroyInstance(");
+ out.print(tagHandlerVar);
+ out.println(");");
+ }
+
private void generateCustomEnd(Node.CustomTag n, String tagHandlerVar,
String tagEvalVar, String tagPushBodyCountVar) {
} else {
out.printin(tagHandlerVar);
out.println(".release();");
- out.printin("org.apache.jasper.runtime.AnnotationHelper.preDestroy(");
- out.print(VAR_ANNOTATIONPROCESSOR);
- out.print(", ");
- out.print(tagHandlerVar);
- out.println(");");
+ writeDestroyInstance(tagHandlerVar);
}
}
if (isTagFile || isFragment) {
} else {
out.printin(tagHandlerVar);
out.println(".release();");
- out.printin("org.apache.jasper.runtime.AnnotationHelper.preDestroy(");
- out.print(VAR_ANNOTATIONPROCESSOR);
- out.print(", ");
- out.print(tagHandlerVar);
- out.println(");");
+ writeDestroyInstance(tagHandlerVar);
}
if (n.implementsTryCatchFinally()) {
String tagHandlerClassName = JspUtil
.getCanonicalName(tagHandlerClass);
- out.printin(tagHandlerClassName);
- out.print(" ");
- out.print(tagHandlerVar);
- out.print(" = ");
- out.print("new ");
- out.print(tagHandlerClassName);
- out.println("();");
+ writeNewInstance(tagHandlerVar, tagHandlerClassName);
- // Resource injection
- out.printin("org.apache.jasper.runtime.AnnotationHelper.postConstruct(");
- out.print(VAR_ANNOTATIONPROCESSOR);
- out.print(", ");
- out.print(tagHandlerVar);
- out.println(");");
-
generateSetters(n, tagHandlerVar, handlerInfo, true);
// JspIdConsumer (after context has been set)
syncScriptingVars(n, VariableInfo.AT_END);
// Resource injection
- out.printin("org.apache.jasper.runtime.AnnotationHelper.preDestroy(");
- out.print(VAR_ANNOTATIONPROCESSOR);
- out.print(", ");
- out.print(tagHandlerVar);
- out.println(");");
+ writeDestroyInstance(tagHandlerVar);
n.setEndJavaLine(out.getJavaLine());
}
/*
* This method is called as part of the custom tag's start element.
- *
+ *
* If the given custom tag has a custom nesting level greater than 0,
* save the current values of its scripting variables to temporary
* variables, so those values may be restored in the tag's end element.
/*
* This method is called as part of the custom tag's end element.
- *
+ *
* If the given custom tag has a custom nesting level greater than 0,
* restore its scripting variables to their original values that were
* saved in the tag's start element.
// reset buffer
sb.setLength(0);
-
+
// create our mark
sb.append(n.getStart().toString());
sb.append(" '");
sb.append(attrValue);
- sb.append('\'');
+ sb.append('\'');
String mark = sb.toString();
-
+
// reset buffer
sb.setLength(0);
/**
* Generate code to create a map for the alias variables
- *
+ *
* @return the name of the map
*/
private String generateAliasMap(Node.CustomTag n, String tagHandlerVar)
for (int i = 0; attrs != null && i < attrs.length; i++) {
String attrValue = evaluateAttribute(handlerInfo, attrs[i], n,
tagHandlerVar);
-
+
Mark m = n.getStart();
out.printil("// "+m.getFile()+"("+m.getLineNumber()+","+m.getColumnNumber()+") "+ attrs[i].getTagAttributeInfo());
if (attrs[i].isDynamic()) {
/**
* Generate the code required to obtain the runtime value of the given
* named attribute.
- *
+ *
* @return The name of the temporary variable the result is stored in.
*/
public String generateNamedAttributeValue(Node.NamedAttribute n)
/**
* Similar to generateNamedAttributeValue, but create a JspFragment
* instead.
- *
+ *
* @param n
* The parent node of the named attribute
* @param tagHandlerVar
/**
* The main entry for Generator.
- *
+ *
* @param out
* The servlet output writer
* @param compiler
* share the code generator with JSPs.
*/
out.printil("PageContext _jspx_page_context = (PageContext)jspContext;");
-
+
// Declare implicit objects.
out.printil("HttpServletRequest request = "
+ "(HttpServletRequest) _jspx_page_context.getRequest();");
out.printil("ServletConfig config = _jspx_page_context.getServletConfig();");
out.printil("JspWriter out = jspContext.getOut();");
out.printil("_jspInit(config);");
-
+
// set current JspContext on ELContext
out.printil("jspContext.getELContext().putContext(JspContext.class,jspContext);");
-
+
generatePageScopedVariables(tagInfo);
declareTemporaryScriptingVars(tag);
out.popIndent();
out.printil("} finally {");
out.pushIndent();
-
+
// handle restoring VariableMapper
TagAttributeInfo[] attrInfos = tagInfo.getAttributes();
for (int i = 0; i < attrInfos.length; i++) {
out.println(");");
}
}
-
+
// restore nested JspContext on ELContext
out.printil("jspContext.getELContext().putContext(JspContext.class,super.getJspContext());");
-
+
out.printil("((org.apache.jasper.runtime.JspContextWrapper) jspContext).syncEndTagFile();");
if (isPoolingEnabled && !tagHandlerPoolNames.isEmpty()) {
out.printil("_jspDestroy();");
boolean variableMapperVar = false;
for (int i = 0; i < attrInfos.length; i++) {
String attrName = attrInfos[i].getName();
-
+
// handle assigning deferred vars to VariableMapper, storing
// previous values under '_el_ve[i]' for later re-assignment
if (attrInfos[i].isDeferredValue() || attrInfos[i].isDeferredMethod()) {
-
+
// we need to scope the modified VariableMapper for consistency and performance
if (!variableMapperVar) {
out.printil("javax.el.VariableMapper _el_variablemapper = jspContext.getELContext().getVariableMapper();");
variableMapperVar = true;
}
-
+
out.printin("javax.el.ValueExpression _el_ve");
out.print(i);
out.print(" = _el_variablemapper.setVariable(");
/**
* Constructor.
- *
+ *
* @param n
* The custom tag whose tag handler class is to be
* introspected
+++ /dev/null
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.jasper.runtime;
-
-import java.lang.reflect.InvocationTargetException;
-
-import javax.naming.NamingException;
-
-import org.apache.AnnotationProcessor;
-
-
-/**
- * Verify the annotation and Process it.
- *
- * @author Fabien Carrion
- * @author Remy Maucherat
- * @version $Revision$, $Date$
- */
-public class AnnotationHelper {
-
-
- /**
- * Call postConstruct method on the specified instance. Note: In Jasper, this
- * calls naming resources injection as well.
- */
- public static void postConstruct(AnnotationProcessor processor, Object instance)
- throws IllegalAccessException, InvocationTargetException, NamingException {
- if (processor != null) {
- processor.processAnnotations(instance);
- processor.postConstruct(instance);
- }
- }
-
-
- /**
- * Call preDestroy method on the specified instance.
- */
- public static void preDestroy(AnnotationProcessor processor, Object instance)
- throws IllegalAccessException, InvocationTargetException {
- if (processor != null) {
- processor.preDestroy(instance);
- }
- }
-
-
-}
--- /dev/null
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+
+package org.apache.jasper.runtime;
+
+import javax.servlet.ServletConfig;
+
+import org.apache.InstanceManager;
+
+/**
+ * @version $Rev:$ $Date:$
+ */
+public class InstanceManagerFactory {
+
+ private InstanceManagerFactory() {
+ }
+
+ public static InstanceManager getInstanceManager(ServletConfig config) {
+ InstanceManager instanceManager =
+ (InstanceManager) config.getServletContext().getAttribute(InstanceManager.class.getName());
+ if (instanceManager == null) {
+ throw new IllegalStateException("No org.apache.InstanceManager set in ServletContext");
+ }
+ return instanceManager;
+ }
+
+}
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.Tag;
-import org.apache.AnnotationProcessor;
+import org.apache.InstanceManager;
import org.apache.jasper.Constants;
import org.apache.juli.logging.Log;
import org.apache.juli.logging.LogFactory;
// index of next available tag handler
private int current;
- protected AnnotationProcessor annotationProcessor = null;
+ protected InstanceManager instanceManager = null;
public static TagHandlerPool getTagHandlerPool( ServletConfig config) {
TagHandlerPool result=null;
}
this.handlers = new Tag[maxSize];
this.current = -1;
- this.annotationProcessor =
- (AnnotationProcessor) config.getServletContext().getAttribute(AnnotationProcessor.class.getName());
+ instanceManager = InstanceManagerFactory.getInstanceManager(config);
}
/**
* @throws JspException if a tag handler cannot be instantiated
*/
public Tag get(Class handlerClass) throws JspException {
- Tag handler = null;
+ Tag handler;
synchronized( this ) {
if (current >= 0) {
handler = handlers[current--];
// Out of sync block - there is no need for other threads to
// wait for us to construct a tag for this thread.
try {
- Tag instance = (Tag) handlerClass.newInstance();
- AnnotationHelper.postConstruct(annotationProcessor, instance);
- return instance;
+ if (Constants.USE_INSTANCE_MANAGER_FOR_TAGS) {
+ return (Tag) instanceManager.newInstance(handlerClass.getName(), handlerClass.getClassLoader());
+ } else {
+ Tag instance = (Tag) handlerClass.newInstance();
+ instanceManager.newInstance(instance);
+ return instance;
+ }
} catch (Exception e) {
throw new JspException(e.getMessage(), e);
}
}
// There is no need for other threads to wait for us to release
handler.release();
- if (annotationProcessor != null) {
- try {
- AnnotationHelper.preDestroy(annotationProcessor, handler);
- } catch (Exception e) {
- log.warn("Error processing preDestroy on tag instance of "
- + handler.getClass().getName(), e);
- }
+ try {
+ instanceManager.destroyInstance(handler);
+ } catch (Exception e) {
+ log.warn("Error processing preDestroy on tag instance of "
+ + handler.getClass().getName(), e);
}
}
public synchronized void release() {
for (int i = current; i >= 0; i--) {
handlers[i].release();
- if (annotationProcessor != null) {
- try {
- AnnotationHelper.preDestroy(annotationProcessor, handlers[i]);
- } catch (Exception e) {
- log.warn("Error processing preDestroy on tag instance of "
- + handlers[i].getClass().getName(), e);
- }
+ try {
+ instanceManager.destroyInstance(handlers[i]);
+ } catch (Exception e) {
+ log.warn("Error processing preDestroy on tag instance of "
+ + handlers[i].getClass().getName(), e);
}
}
}
import javax.servlet.http.HttpServletResponse;
import javax.servlet.jsp.tagext.TagInfo;
-import org.apache.AnnotationProcessor;
+import org.apache.InstanceManager;
import org.apache.jasper.JasperException;
import org.apache.jasper.JspCompilationContext;
import org.apache.jasper.Options;
import org.apache.jasper.compiler.JavacErrorDetail;
import org.apache.jasper.compiler.JspRuntimeContext;
import org.apache.jasper.compiler.Localizer;
+import org.apache.jasper.runtime.InstanceManagerFactory;
import org.apache.jasper.runtime.JspSourceDependent;
import org.apache.juli.logging.Log;
import org.apache.juli.logging.LogFactory;
private Servlet theServlet;
private String jspUri;
- private Class servletClass;
private Class tagHandlerClass;
private JspCompilationContext ctxt;
private long available = 0L;
destroy();
Servlet servlet = null;
-
+
try {
- servletClass = ctxt.load();
- servlet = (Servlet) servletClass.newInstance();
- AnnotationProcessor annotationProcessor = (AnnotationProcessor) config.getServletContext().getAttribute(AnnotationProcessor.class.getName());
- if (annotationProcessor != null) {
- annotationProcessor.processAnnotations(servlet);
- annotationProcessor.postConstruct(servlet);
- }
+ InstanceManager instanceManager = InstanceManagerFactory.getInstanceManager(config);
+ servlet = (Servlet) instanceManager.newInstance(ctxt.getFQCN(), ctxt.getJspLoader());
} catch (IllegalAccessException e) {
throw new JasperException(e);
} catch (InstantiationException e) {
public void destroy() {
if (theServlet != null) {
theServlet.destroy();
- AnnotationProcessor annotationProcessor = (AnnotationProcessor) config.getServletContext().getAttribute(AnnotationProcessor.class.getName());
- if (annotationProcessor != null) {
- try {
- annotationProcessor.preDestroy(theServlet);
- } catch (Exception e) {
- // Log any exception, since it can't be passed along
- log.error(Localizer.getMessage("jsp.error.file.not.found",
- e.getMessage()), e);
- }
+ InstanceManager instanceManager = InstanceManagerFactory.getInstanceManager(config);
+ try {
+ instanceManager.destroyInstance(theServlet);
+ } catch (Exception e) {
+ // Log any exception, since it can't be passed along
+ log.error(Localizer.getMessage("jsp.error.file.not.found",
+ e.getMessage()), e);
}
}
}