JETTY-780

git-svn-id: svn+ssh://dev.eclipse.org/svnroot/rt/org.eclipse.jetty/jetty/trunk@859 7e9141cc-0065-0410-87d8-b60c137991c4
This commit is contained in:
Jan Bartel 2009-09-10 11:51:11 +00:00
parent c5983dbb1d
commit d627905f4b
20 changed files with 679 additions and 472 deletions

View File

@ -6,6 +6,7 @@ jetty-7.0.0.RC6-SNAPSHOT
+ 288055 jetty-client fails to resolve failed resolution attempts correctly
+ 288153 jetty-client resend doesn't reset exchange
+ 288182 PUT request fails during retry
+ JETTY-780 CNFE during startup of webapp with spring-context >= 2.5.1
+ JETTY-1080 modify previous fix to work on windows
+ JETTY-1084 HEAD command not setting content-type in response under certain circumstances
+ JETTY-1086 Use UncheckedPrintWriter

View File

@ -164,7 +164,7 @@ public class AnnotationParser
String annotation, List<Value>values);
public void handleMethod (String className, String methodName, int access,
String params, String signature,String[] exceptions,
String desc, String signature,String[] exceptions,
String annotation, List<Value>values);
public void handleField (String className, String fieldName, int access,
@ -180,7 +180,7 @@ public class AnnotationParser
public interface MethodHandler
{
public void handle (String className, String methodName, int access, String params, String signature,String[] exceptions);
public void handle (String className, String methodName, int access, String desc, String signature,String[] exceptions);
}
public interface FieldHandler
@ -325,7 +325,7 @@ public class AnnotationParser
public MethodVisitor visitMethod (final int access,
final String name,
final String params,
final String methodDesc,
final String signature,
final String[] exceptions)
{
@ -343,7 +343,7 @@ public class AnnotationParser
AnnotationHandler handler = AnnotationParser.this._annotationHandlers.get(_annotationName);
if (handler != null)
{
handler.handleMethod(_className, name, access, params, signature, exceptions, _annotationName, _annotationValues);
handler.handleMethod(_className, name, access, methodDesc, signature, exceptions, _annotationName, _annotationValues);
}
}
};

View File

@ -13,25 +13,24 @@
package org.eclipse.jetty.annotations;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.List;
import org.eclipse.jetty.annotations.AnnotationParser.AnnotationHandler;
import org.eclipse.jetty.annotations.AnnotationParser.Value;
import org.eclipse.jetty.plus.annotation.LifeCycleCallbackCollection;
import org.eclipse.jetty.plus.annotation.PostConstructCallback;
import org.eclipse.jetty.util.Loader;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.webapp.WebAppContext;
public class PostConstructAnnotationHandler implements AnnotationHandler
{
protected WebAppContext _wac;
protected LifeCycleCallbackCollection _callbacks;
public PostConstructAnnotationHandler (WebAppContext wac)
{
_wac = wac;
_callbacks = (LifeCycleCallbackCollection)_wac.getAttribute(LifeCycleCallbackCollection.LIFECYCLE_CALLBACK_COLLECTION);
}
@ -47,35 +46,39 @@ public class PostConstructAnnotationHandler implements AnnotationHandler
Log.warn("@PostConstruct annotation not applicable to fields: "+className+"."+fieldName);
}
public void handleMethod(String className, String methodName, int access, String params, String signature, String[] exceptions, String annotation,
public void handleMethod(String className, String methodName, int access, String desc, String signature, String[] exceptions, String annotation,
List<Value> values)
{
LifeCycleCallbackCollection callbacks = (LifeCycleCallbackCollection)_wac.getAttribute(LifeCycleCallbackCollection.LIFECYCLE_CALLBACK_COLLECTION);
Class clazz = null;
{
try
{
clazz = Loader.loadClass(null, className);
Method m = clazz.getDeclaredMethod(methodName, Util.convertTypes(params));
if (!Util.isServletType(m.getDeclaringClass()))
org.objectweb.asm.Type[] args = org.objectweb.asm.Type.getArgumentTypes(desc);
if (args.length != 0)
{
Log.debug("Ignoring "+m.getName()+" as non-servlet type");
Log.warn("Skipping PostConstruct annotation on "+className+"."+methodName+": has parameters");
return;
}
if (org.objectweb.asm.Type.getReturnType(desc) != org.objectweb.asm.Type.VOID_TYPE)
{
Log.warn("Skipping PostConstruct annotation on "+className+"."+methodName+": is not void");
return;
}
if (exceptions != null && exceptions.length != 0)
{
Log.warn("Skipping PostConstruct annotation on "+className+"."+methodName+": throws checked exceptions");
return;
}
if ((access & org.objectweb.asm.Opcodes.ACC_STATIC) > 0)
{
Log.warn("Skipping PostConstruct annotation on "+className+"."+methodName+": is static");
return;
}
if (m.getParameterTypes().length != 0)
throw new IllegalStateException(m+" has parameters");
if (m.getReturnType() != Void.TYPE)
throw new IllegalStateException(m+" is not void");
if (m.getExceptionTypes().length != 0)
throw new IllegalStateException(m+" throws checked exceptions");
if (Modifier.isStatic(m.getModifiers()))
throw new IllegalStateException(m+" is static");
PostConstructCallback callback = new PostConstructCallback();
callback.setTargetClass(m.getDeclaringClass());
callback.setTarget(m);
callbacks.add(callback);
callback.setTarget(className, methodName);
_callbacks.add(callback);
}
catch (Exception e)
{

View File

@ -13,25 +13,24 @@
package org.eclipse.jetty.annotations;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.List;
import org.eclipse.jetty.annotations.AnnotationParser.AnnotationHandler;
import org.eclipse.jetty.annotations.AnnotationParser.Value;
import org.eclipse.jetty.plus.annotation.LifeCycleCallbackCollection;
import org.eclipse.jetty.plus.annotation.PreDestroyCallback;
import org.eclipse.jetty.util.Loader;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.webapp.WebAppContext;
public class PreDestroyAnnotationHandler implements AnnotationHandler
{
WebAppContext _wac;
LifeCycleCallbackCollection _callbacks;
public PreDestroyAnnotationHandler (WebAppContext wac)
{
_wac = wac;
_callbacks = (LifeCycleCallbackCollection)_wac.getAttribute(LifeCycleCallbackCollection.LIFECYCLE_CALLBACK_COLLECTION);
}
public void handleClass(String className, int version, int access, String signature, String superName, String[] interfaces, String annotation,
@ -46,35 +45,39 @@ public class PreDestroyAnnotationHandler implements AnnotationHandler
Log.warn("@PreDestroy annotation not applicable for fields: "+className+"."+fieldName);
}
public void handleMethod(String className, String methodName, int access, String params, String signature, String[] exceptions, String annotation,
public void handleMethod(String className, String methodName, int access, String desc, String signature, String[] exceptions, String annotation,
List<Value> values)
{
LifeCycleCallbackCollection callbacks = (LifeCycleCallbackCollection)_wac.getAttribute(LifeCycleCallbackCollection.LIFECYCLE_CALLBACK_COLLECTION);
Class clazz = null;
try
{
clazz = Loader.loadClass(null, className);
org.objectweb.asm.Type[] args = org.objectweb.asm.Type.getArgumentTypes(desc);
Method m = clazz.getDeclaredMethod(methodName, Util.convertTypes(params));
if (!Util.isServletType(m.getDeclaringClass()))
if (args.length != 0)
{
Log.debug("Ignored "+m.getName()+" as non-servlet type");
Log.warn("Skipping PreDestroy annotation on "+className+"."+methodName+": has parameters");
return;
}
if (org.objectweb.asm.Type.getReturnType(desc) != org.objectweb.asm.Type.VOID_TYPE)
{
Log.warn("Skipping PreDestroy annotation on "+className+"."+methodName+": is not void");
return;
}
if (exceptions != null && exceptions.length != 0)
{
Log.warn("Skipping PreDestroy annotation on "+className+"."+methodName+": throws checked exceptions");
return;
}
if ((access & org.objectweb.asm.Opcodes.ACC_STATIC) > 0)
{
Log.warn("Skipping PreDestroy annotation on "+className+"."+methodName+": is static");
return;
}
if (m.getParameterTypes().length != 0)
throw new IllegalStateException(m+" has parameters");
if (m.getReturnType() != Void.TYPE)
throw new IllegalStateException(m+" is not void");
if (m.getExceptionTypes().length != 0)
throw new IllegalStateException(m+" throws checked exceptions");
if (Modifier.isStatic(m.getModifiers()))
throw new IllegalStateException(m+" is static");
PreDestroyCallback callback = new PreDestroyCallback();
callback.setTargetClass(m.getDeclaringClass());
callback.setTarget(m);
callbacks.add(callback);
callback.setTarget(className, methodName);
_callbacks.add(callback);
}
catch (Exception e)
{

View File

@ -13,12 +13,8 @@
package org.eclipse.jetty.annotations;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.List;
import javax.annotation.Resource;
import javax.naming.InitialContext;
import javax.naming.NameNotFoundException;
import javax.naming.NamingException;
@ -27,18 +23,18 @@ import org.eclipse.jetty.annotations.AnnotationParser.AnnotationHandler;
import org.eclipse.jetty.annotations.AnnotationParser.Value;
import org.eclipse.jetty.plus.annotation.Injection;
import org.eclipse.jetty.plus.annotation.InjectionCollection;
import org.eclipse.jetty.util.IntrospectionUtil;
import org.eclipse.jetty.util.Loader;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.webapp.WebAppContext;
public class ResourceAnnotationHandler implements AnnotationHandler
{
protected WebAppContext _wac;
protected InjectionCollection _injections;
public ResourceAnnotationHandler (WebAppContext wac)
{
_wac = wac;
_injections = (InjectionCollection)_wac.getAttribute(InjectionCollection.INJECTION_COLLECTION);
}
@ -50,37 +46,26 @@ public class ResourceAnnotationHandler implements AnnotationHandler
public void handleClass(String className, int version, int access, String signature, String superName, String[] interfaces, String annotation,
List<Value> values)
{
Class clazz = null;
try
String name = null;
String mappedName = null;
String resourceType = null;
if (values != null)
{
clazz = Loader.loadClass(null, className);
}
catch (Exception e)
{
Log.warn(e);
}
if (!Util.isServletType(clazz))
{
Log.debug("Ignoring @Resource annotation on on-servlet type class "+clazz.getName());
return;
}
//Handle Resource annotation - add namespace entries
Resource resource = (Resource)clazz.getAnnotation(Resource.class);
if (resource != null)
{
String name = resource.name();
String mappedName = resource.mappedName();
Resource.AuthenticationType auth = resource.authenticationType();
Class type = resource.type();
boolean shareable = resource.shareable();
for (Value v : values)
{
if ("name".equals(v.getName()))
name = (String)v.getValue();
else if ("mappedName".equals(v.getName()))
mappedName = (String)v.getValue();
else if ("type".equals(v.getName()))
resourceType = (String)v.getValue();
}
if (name==null || name.trim().equals(""))
throw new IllegalStateException ("Class level Resource annotations must contain a name (Common Annotations Spec Section 2.3)");
try
{
//TODO don't ignore the shareable, auth etc etc
if (!org.eclipse.jetty.plus.jndi.NamingEntryUtil.bindToENC(_wac, name,mappedName))
if (!org.eclipse.jetty.plus.jndi.NamingEntryUtil.bindToENC(_wac.getServer(), name,mappedName))
throw new IllegalStateException("No resource at "+(mappedName==null?name:mappedName));
@ -95,52 +80,46 @@ public class ResourceAnnotationHandler implements AnnotationHandler
public void handleField(String className, String fieldName, int access, String fieldType, String signature, Object value, String annotation,
List<Value> values)
{
InjectionCollection injections = (InjectionCollection)_wac.getAttribute(InjectionCollection.INJECTION_COLLECTION);
Class clazz = null;
try
{
clazz = Loader.loadClass(null, className);
Field f = clazz.getDeclaredField(fieldName);
if (!Util.isServletType(clazz))
//JavaEE Spec 5.2.3: Field cannot be static
if ((access & org.objectweb.asm.Opcodes.ACC_STATIC) > 0)
{
Log.debug("Ignoring @Resource annotation on on-servlet type field "+fieldName);
Log.warn("Skipping Resource annotation on "+className+"."+fieldName+": cannot be static");
return;
}
Resource resource = (Resource)f.getAnnotation(Resource.class);
if (resource == null)
return;
//JavaEE Spec 5.2.3: Field cannot be static
if (Modifier.isStatic(f.getModifiers()))
throw new IllegalStateException(f+" cannot be static");
//JavaEE Spec 5.2.3: Field cannot be final
if (Modifier.isFinal(f.getModifiers()))
throw new IllegalStateException(f+" cannot be final");
if ((access & org.objectweb.asm.Opcodes.ACC_FINAL) > 0)
{
Log.warn("Skipping Resource annotation on "+className+"."+fieldName+": cannot be final");
return;
}
//work out default name
String name = f.getDeclaringClass().getCanonicalName()+"/"+f.getName();
//allow @Resource name= to override the field name
name = (resource.name()!=null && !resource.name().trim().equals("")? resource.name(): name);
//get the type of the Field
Class type = f.getType();
//if @Resource specifies a type, check it is compatible with field type
if ((resource.type() != null)
&&
!resource.type().equals(Object.class)
&&
(!IntrospectionUtil.isTypeCompatible(type, resource.type(), false)))
throw new IllegalStateException("@Resource incompatible type="+resource.type()+ " with field type ="+f.getType());
//get the mappedName if there is one
String mappedName = (resource.mappedName()!=null && !resource.mappedName().trim().equals("")?resource.mappedName():null);
//get other parts that can be specified in @Resource
Resource.AuthenticationType auth = resource.authenticationType();
boolean shareable = resource.shareable();
String name = className+"/"+fieldName;
String mappedName = null;
org.objectweb.asm.Type resourceType = null;
if (values != null)
{
for (Value val :values)
{
//allow @Resource name= to override the field name
if (val.getName().equals("name") && !"".equals((String)val.getValue()))
name = (String)(val.getValue());
//get the mappedName if there is one
else if (val.getName().equals("mappedName") && !"".equals((String)val.getValue()))
mappedName = (String)val.getValue();
//save @Resource type, so we can check it is compatible with field type later
else if (val.getName().equals("type"))
{
resourceType = (org.objectweb.asm.Type)(val.getValue());
}
}
}
//check if an injection has already been setup for this target by web.xml
Injection webXmlInjection = injections.getInjection(f.getDeclaringClass(), f);
Injection webXmlInjection = _injections.getInjection(name, className, fieldName);
if (webXmlInjection == null)
{
try
@ -171,14 +150,15 @@ public class ResourceAnnotationHandler implements AnnotationHandler
Log.debug("Bound "+(mappedName==null?name:mappedName) + " as "+ name);
// Make the Injection for it if the binding succeeded
Injection injection = new Injection();
injection.setTargetClass(f.getDeclaringClass());
injection.setTarget(className, fieldName, Util.asCanonicalName(resourceType));
injection.setJndiName(name);
injection.setMappingName(mappedName);
injection.setTarget(f);
injections.add(injection);
_injections.add(injection);
}
else if (!Util.isEnvEntryType(type))
else if (!Util.isEnvEntryType(fieldType))
{
System.err.println(fieldType);
//if this is an env-entry type resource and there is no value bound for it, it isn't
//an error, it just means that perhaps the code will use a default value instead
// JavaEE Spec. sec 5.4.1.3
@ -191,18 +171,10 @@ public class ResourceAnnotationHandler implements AnnotationHandler
//if this is an env-entry type resource and there is no value bound for it, it isn't
//an error, it just means that perhaps the code will use a default value instead
// JavaEE Spec. sec 5.4.1.3
if (!Util.isEnvEntryType(type))
if (!Util.isEnvEntryType(fieldType))
throw new IllegalStateException(e);
}
}
else
{
//if an injection is already set up for this name, then the types must be compatible
//JavaEE spec sec 5.2.4
Object val = webXmlInjection.lookupInjectedValue();
if (!IntrospectionUtil.isTypeCompatible(type, value.getClass(), false))
throw new IllegalStateException("Type of field="+type+" is not compatible with Resource type="+val.getClass());
}
}
catch (Exception e)
{
@ -217,23 +189,12 @@ public class ResourceAnnotationHandler implements AnnotationHandler
* processed when an instance of the class is created.
* @param injections
*/
public void handleMethod(String className, String methodName, int access, String params, String signature, String[] exceptions, String annotation,
public void handleMethod(String className, String methodName, int access, String desc, String signature, String[] exceptions, String annotation,
List<Value> values)
{
InjectionCollection injections = (InjectionCollection)_wac.getAttribute(InjectionCollection.INJECTION_COLLECTION);
Class clazz = null;
try
{
clazz = Loader.loadClass(null, className);
Class[] args = Util.convertTypes(params);
Method m = clazz.getDeclaredMethod(methodName, args);
if (!Util.isServletType(m.getDeclaringClass()))
{
Log.debug("Ignoring @Resource annotation on on-servlet type method "+m.getName());
return;
}
/*
* Commons Annotations Spec 2.3
* " The Resource annotation is used to declare a reference to a resource.
@ -251,44 +212,60 @@ public class ResourceAnnotationHandler implements AnnotationHandler
* Which IMHO, put more succinctly means "If you find a @Resource on any method
* or field, inject it!".
*/
Resource resource = (Resource)m.getAnnotation(Resource.class);
if (resource == null)
return;
//JavaEE Spec 5.2.3: Method cannot be static
if (Modifier.isStatic(m.getModifiers()))
throw new IllegalStateException(m+" cannot be static");
if ((access & org.objectweb.asm.Opcodes.ACC_STATIC) > 0)
{
Log.warn("Skipping Resource annotation on "+className+"."+methodName+": cannot be static");
return;
}
// Check it is a valid javabean
if (!IntrospectionUtil.isJavaBeanCompliantSetter(m))
throw new IllegalStateException(m+" is not a java bean compliant setter method");
// Check it is a valid javabean: must be void return type, the name must start with "set" and it must have
// only 1 parameter
if (!methodName.startsWith("set"))
{
Log.warn("Skipping Resource annotation on "+className+"."+methodName+": invalid java bean, does not start with 'set'");
return;
}
org.objectweb.asm.Type[] args = org.objectweb.asm.Type.getArgumentTypes(desc);
if (args == null || args.length != 1)
{
Log.warn("Skipping Resource annotation on "+className+"."+methodName+": invalid java bean, not single argument to method");
return;
}
org.objectweb.asm.Type retVal = org.objectweb.asm.Type.getReturnType(desc);
if (!org.objectweb.asm.Type.VOID_TYPE.equals(retVal))
{
Log.warn("Skipping Resource annotation on "+className+"."+methodName+": invalid java bean, not void");
return;
}
//default name is the javabean property name
String name = m.getName().substring(3);
String name = methodName.substring(3);
name = name.substring(0,1).toLowerCase()+name.substring(1);
name = m.getDeclaringClass().getCanonicalName()+"/"+name;
//allow default name to be overridden
name = (resource.name()!=null && !resource.name().trim().equals("")? resource.name(): name);
//get the mappedName if there is one
String mappedName = (resource.mappedName()!=null && !resource.mappedName().trim().equals("")?resource.mappedName():null);
Class type = m.getParameterTypes()[0];
//get other parts that can be specified in @Resource
Resource.AuthenticationType auth = resource.authenticationType();
boolean shareable = resource.shareable();
//if @Resource specifies a type, check it is compatible with setter param
if ((resource.type() != null)
&&
!resource.type().equals(Object.class)
&&
(!IntrospectionUtil.isTypeCompatible(type, resource.type(), false)))
throw new IllegalStateException("@Resource incompatible type="+resource.type()+ " with method param="+type+ " for "+m);
name = className+"/"+name;
String mappedName = null;
org.objectweb.asm.Type resourceType = null;
if (values != null)
{
for (Value v : values)
{
//allow default name to be overridden
if ("name".equals(v.getName()))
name = (String)(v.getValue());
//get the mappedName if there is one
else if ("mappedName".equals(v.getName()) && !"".equals((String)(v.getValue())))
mappedName = (String)(v.getValue());
else if ("type".equals(v.getName()))
{
resourceType = (org.objectweb.asm.Type)(v.getValue());
}
//TODO: authentication and shareable
}
}
//check if an injection has already been setup for this target by web.xml
Injection webXmlInjection = injections.getInjection(m.getDeclaringClass(), m);
Injection webXmlInjection = _injections.getInjection(name, className, methodName, Util.asCanonicalName(args[0]));
if (webXmlInjection == null)
{
try
@ -327,13 +304,12 @@ public class ResourceAnnotationHandler implements AnnotationHandler
Log.debug("Bound "+(mappedName==null?name:mappedName) + " as "+ name);
// Make the Injection for it
Injection injection = new Injection();
injection.setTargetClass(m.getDeclaringClass());
injection.setTarget(className, methodName, Util.asCanonicalName(args[0]), Util.asCanonicalName(resourceType));
injection.setJndiName(name);
injection.setMappingName(mappedName);
injection.setTarget(m);
injections.add(injection);
_injections.add(injection);
}
else if (!Util.isEnvEntryType(type))
else if (!Util.isEnvEntryType(args[0].getDescriptor()))
{
//if this is an env-entry type resource and there is no value bound for it, it isn't
@ -347,19 +323,10 @@ public class ResourceAnnotationHandler implements AnnotationHandler
//if this is an env-entry type resource and there is no value bound for it, it isn't
//an error, it just means that perhaps the code will use a default value instead
// JavaEE Spec. sec 5.4.1.3
if (!Util.isEnvEntryType(type))
if (!Util.isEnvEntryType(args[0].getDescriptor()))
throw new IllegalStateException(e);
}
}
else
{
//if an injection is already set up for this name, then the types must be compatible
//JavaEE spec sec 5.2.4
Object value = webXmlInjection.lookupInjectedValue();
if (!IntrospectionUtil.isTypeCompatible(type, value.getClass(), false))
throw new IllegalStateException("Type of field="+type+" is not compatible with Resource type="+value.getClass());
}
}
catch (Exception e)
{

View File

@ -15,13 +15,11 @@ package org.eclipse.jetty.annotations;
import java.util.List;
import javax.annotation.Resource;
import javax.annotation.Resources;
import javax.naming.NamingException;
import org.eclipse.jetty.annotations.AnnotationParser.AnnotationHandler;
import org.eclipse.jetty.annotations.AnnotationParser.ListValue;
import org.eclipse.jetty.annotations.AnnotationParser.Value;
import org.eclipse.jetty.util.Loader;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.webapp.WebAppContext;
@ -38,55 +36,43 @@ public class ResourcesAnnotationHandler implements AnnotationHandler
public void handleClass(String className, int version, int access, String signature, String superName, String[] interfaces, String annotation,
List<Value> values)
{
Class clazz = null;
try
if (values != null && values.size() == 1)
{
clazz = Loader.loadClass(null,className);
}
catch (Exception e)
{
Log.warn(e);
return;
}
if (!Util.isServletType(clazz))
{
Log.debug("@Resources annotation ignored on on-servlet type class "+clazz.getName());
return;
}
//Handle Resources annotation - add namespace entries
Resources resources = (Resources)clazz.getAnnotation(Resources.class);
if (resources == null)
return;
Resource[] resArray = resources.value();
if (resArray==null||resArray.length==0)
return;
for (int j=0;j<resArray.length;j++)
{
String name = resArray[j].name();
String mappedName = resArray[j].mappedName();
Resource.AuthenticationType auth = resArray[j].authenticationType();
Class type = resArray[j].type();
boolean shareable = resArray[j].shareable();
if (name==null || name.trim().equals(""))
List<ListValue> list = (List<ListValue>)(values.get(0).getValue());
for (ListValue resource : list)
{
Log.warn ("@Resource annotations on classes must contain a name (Common Annotations Spec Section 2.3)");
break;
}
try
{
//TODO don't ignore the shareable, auth etc etc
if (!org.eclipse.jetty.plus.jndi.NamingEntryUtil.bindToENC(_wac, name, mappedName))
if (!org.eclipse.jetty.plus.jndi.NamingEntryUtil.bindToENC(_wac.getServer(), name, mappedName))
throw new IllegalStateException("No resource bound at "+(mappedName==null?name:mappedName));
}
catch (NamingException e)
{
Log.warn(e);
List<Value> resourceValues = resource.getList();
String name = null;
String mappedName = null;
for (Value v:resourceValues)
{
if ("name".equals(v.getName()))
name = (String)v.getValue();
else if ("mappedName".equals(v.getName()))
mappedName = (String)v.getValue();
}
if (name == null)
Log.warn ("Skipping Resources(Resource) annotation with no name on class "+className);
else
{
try
{
//TODO don't ignore the shareable, auth etc etc
if (!org.eclipse.jetty.plus.jndi.NamingEntryUtil.bindToENC(_wac, name, mappedName))
if (!org.eclipse.jetty.plus.jndi.NamingEntryUtil.bindToENC(_wac.getServer(), name, mappedName))
Log.warn("Skipping Resources(Resource) annotation on "+className+" for name "+name+": No resource bound at "+(mappedName==null?name:mappedName));
}
catch (NamingException e)
{
Log.warn(e);
}
}
}
}
else
{
Log.warn("Skipping empty or incorrect Resources annotation on "+className);
}
}
public void handleField(String className, String fieldName, int access, String fieldType, String signature, Object value, String annotation,

View File

@ -37,27 +37,22 @@ public class RunAsAnnotationHandler implements AnnotationHandler
List<Value> values)
{
RunAsCollection runAsCollection = (RunAsCollection)_wac.getAttribute(RunAsCollection.RUNAS_COLLECTION);
Class clazz = null;
try
{
clazz = Loader.loadClass(null, className);
if (!javax.servlet.Servlet.class.isAssignableFrom(clazz))
if (values != null && values.size() == 1)
{
Log.debug("@RunAs annotation ignored on on-servlet class "+clazz.getName());
return;
}
RunAs runAs = (RunAs)clazz.getAnnotation(RunAs.class);
if (runAs != null)
{
String role = runAs.value();
String role = (String)values.get(0).getValue();
if (role != null)
{
org.eclipse.jetty.plus.annotation.RunAs ra = new org.eclipse.jetty.plus.annotation.RunAs();
ra.setTargetClass(clazz);
ra.setTargetClassName(className);
ra.setRoleName(role);
runAsCollection.add(ra);
}
}
else
Log.warn("Bad value for @RunAs annotation on class "+className);
}
catch (Exception e)
{

View File

@ -17,6 +17,7 @@ import java.lang.reflect.Array;
import java.util.List;
import org.eclipse.jetty.util.Loader;
import org.eclipse.jetty.util.TypeUtil;
import org.objectweb.asm.Type;
/**
@ -26,9 +27,14 @@ import org.objectweb.asm.Type;
*/
public class Util
{
private static Class[] __envEntryTypes =
private static Class[] __envEntryClassTypes =
new Class[] {String.class, Character.class, Integer.class, Boolean.class, Double.class, Byte.class, Short.class, Long.class, Float.class};
private static String[] __envEntryTypes =
new String[] { Type.getDescriptor(String.class), Type.getDescriptor(Character.class), Type.getDescriptor(Integer.class), Type.getDescriptor(Boolean.class),
Type.getDescriptor(Double.class), Type.getDescriptor(Byte.class), Type.getDescriptor(Short.class), Type.getDescriptor(Long.class), Type.getDescriptor(Float.class)};
/**
* Check if the presented method belongs to a class that is one
* of the classes with which a servlet container should be concerned.
@ -53,11 +59,21 @@ public class Util
}
public static boolean isEnvEntryType (Class type)
{
boolean result = false;
for (int i=0;i<__envEntryClassTypes.length && !result;i++)
{
result = (type.equals(__envEntryClassTypes[i]));
}
return result;
}
public static boolean isEnvEntryType (String desc)
{
boolean result = false;
for (int i=0;i<__envEntryTypes.length && !result;i++)
{
result = (type.equals(__envEntryTypes[i]));
result = (desc.equals(__envEntryTypes[i]));
}
return result;
}
@ -152,4 +168,59 @@ public class Util
}
public static String asCanonicalName (Type t)
{
if (t == null)
return null;
switch (t.getSort())
{
case Type.BOOLEAN:
{
return TypeUtil.toName(Boolean.TYPE);
}
case Type.ARRAY:
{
return t.getElementType().getClassName();
}
case Type.BYTE:
{
return TypeUtil.toName(Byte.TYPE);
}
case Type.CHAR:
{
return TypeUtil.toName(Character.TYPE);
}
case Type.DOUBLE:
{
return TypeUtil.toName(Double.TYPE);
}
case Type.FLOAT:
{
return TypeUtil.toName(Float.TYPE);
}
case Type.INT:
{
return TypeUtil.toName(Integer.TYPE);
}
case Type.LONG:
{
return TypeUtil.toName(Long.TYPE);
}
case Type.OBJECT:
{
return t.getClassName();
}
case Type.SHORT:
{
return TypeUtil.toName(Short.TYPE);
}
case Type.VOID:
{
return null;
}
default:
return null;
}
}
}

View File

@ -17,6 +17,7 @@ import java.io.IOException;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.annotation.Resource;
import javax.annotation.Resources;
import javax.annotation.security.RunAs;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
@ -26,11 +27,14 @@ import javax.servlet.http.HttpServletResponse;
@Resources({
@Resource(name="apple", mappedName="foo"),
@Resource(name="banana", mappedName="foo")
})
@RunAs("admin")
public class ServletC extends HttpServlet
{
@Resource (mappedName="foo")
@Resource (mappedName="foo", type=Double.class)
private Double foo;
@PreDestroy

View File

@ -58,10 +58,25 @@ public class TestAnnotationParser extends TestCase
}
public void handleMethod(String className, String methodName, int access, String params, String signature, String[] exceptions, String annotation,
public void handleMethod(String className, String methodName, int access, String desc, String signature, String[] exceptions, String annotation,
List<Value> values)
{
assertEquals("org.eclipse.jetty.annotations.ClassA", className);
System.err.println("Sample annotated method : classname="+className+" methodName="+methodName+" access="+access+" desc="+desc+" signature="+signature);
org.objectweb.asm.Type retType = org.objectweb.asm.Type.getReturnType(desc);
System.err.println("REturn type = "+retType);
org.objectweb.asm.Type[] params = org.objectweb.asm.Type.getArgumentTypes(desc);
if (params == null)
System.err.println("No params");
else
System.err.println(params.length+" params");
if (exceptions == null)
System.err.println("No exceptions");
else
System.err.println(exceptions.length+" exceptions");
assertEquals("org.eclipse.jetty.annotations.ClassA", className);
assertTrue(methods.contains(methodName));
assertEquals("org.eclipse.jetty.annotations.Sample", annotation);
}

View File

@ -54,12 +54,23 @@ public class TestServletAnnotations extends TestCase
assertNotNull (values);
assertNotNull (annotation);
assertTrue (annotation.endsWith("Resource"));
assertEquals (1, values.size());
Value anv = values.get(0);
assertEquals ("mappedName", anv.getName());
assertEquals ("foo", anv.getValue());
System.err.print(annotation+": ");
System.err.println(anv);
for (Value v :values)
{
if (v.getName().equals("mappedName"))
assertEquals ("foo", v.getValue());
else if (v.getName().equals("type"))
{
try
{
assertEquals(fieldType, ((org.objectweb.asm.Type)v.getValue()).getDescriptor());
}
catch (Exception e)
{
fail(e.getMessage());
}
}
}
}
public void handleMethod(String className, String methodName, int access, String params, String signature, String[] exceptions, String annotation,
@ -76,7 +87,7 @@ public class TestServletAnnotations extends TestCase
List<Value> values)
{}
public void handleMethod(String className, String methodName, int access, String params, String signature, String[] exceptions, String annotation,
public void handleMethod(String className, String methodName, int access, String desc, String signature, String[] exceptions, String annotation,
List<Value> values)
{
assertEquals ("org.eclipse.jetty.annotations.ServletC", className);
@ -91,8 +102,12 @@ public class TestServletAnnotations extends TestCase
assertTrue(annotation.endsWith("PostConstruct"));
assertTrue(values.isEmpty());
}
System.err.println(annotation+": "+methodName);
assertEquals (org.objectweb.asm.Type.VOID_TYPE, org.objectweb.asm.Type.getReturnType(desc));
assertEquals(0, org.objectweb.asm.Type.getArgumentTypes(desc).length);
int isstatic = access & org.objectweb.asm.Opcodes.ACC_STATIC;
assertTrue (isstatic == 0);
}
public void handleField(String className, String fieldName, int access, String fieldType, String signature, Object value, String annotation,
List<Value> values)
@ -108,9 +123,7 @@ public class TestServletAnnotations extends TestCase
assertEquals(1, values.size());
Value anv = values.get(0);
assertEquals("value", anv.getName());
assertEquals("admin", anv.getValue());
System.err.print(annotation+": ");
System.err.println(anv);
assertEquals("admin", anv.getValue());
}
public void handleMethod(String className, String methodName, int access, String params, String signature, String[] exceptions, String annotation,
@ -121,9 +134,45 @@ public class TestServletAnnotations extends TestCase
{}
}
class ResourcesAnnotationHandler implements AnnotationHandler
{
public void handleClass (String className, int version, int access, String signature, String superName, String[] interfaces, String annotation,
List<Value> values)
{
assertNotNull (values);
for (Value v : values)
{
List list = (List)(v.getValue());
for (Object o : list)
{
AnnotationParser.ListValue lv = (AnnotationParser.ListValue)o;
List<Value> theValues = lv.getList();
for (Value vv : theValues)
{
if ("name".equals((String)vv.getName()))
{
if (!"apple".equals((String)vv.getValue()) && !"banana".equals((String)vv.getValue()))
fail("Wrong name "+vv.getName());
}
else if ("mappedName".equals((String)vv.getName()))
assertEquals("foo", (String)vv.getValue());
}
}
}
}
public void handleMethod(String className, String methodName, int access, String params, String signature, String[] exceptions, String annotation,
List<Value> values)
{}
public void handleField(String className, String fieldName, int access, String fieldType, String signature, Object value, String annotation,
List<Value> values)
{}
}
parser.registerAnnotationHandler("javax.annotation.Resources", new ResourcesAnnotationHandler());
parser.registerAnnotationHandler("javax.annotation.Resource", new ResourceAnnotationHandler ());
parser.registerAnnotationHandler("javax.annotation.PostConstruct", new CallbackAnnotationHandler());
parser.registerAnnotationHandler("javax.annotation.PreDestroy", new CallbackAnnotationHandler());

View File

@ -21,8 +21,8 @@ import javax.annotation.Resources;
*
*/
@Resources({
@Resource(name="fluff", mappedName="resA"),
@Resource(name="stuff", mappedName="resB")
@Resource(name="peach", mappedName="resA"),
@Resource(name="pear", mappedName="resB")
})
public class ResourceB extends ResourceA
{

View File

@ -2,6 +2,7 @@ package org.eclipse.jetty.annotations.resources;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import javax.naming.Context;
@ -78,29 +79,32 @@ public class TestResourceAnnotations extends TestCase
//we should have Injections
assertNotNull(injections);
List<Injection> fieldInjections = injections.getFieldInjections(ResourceB.class);
assertNotNull(fieldInjections);
List<Injection> resBInjections = injections.getInjections(ResourceB.class.getCanonicalName());
assertNotNull(resBInjections);
//only 1 field injection because the other has no Resource mapping
assertEquals(1, fieldInjections.size());
assertEquals(1, resBInjections.size());
Injection fi = resBInjections.get(0);
assertEquals ("f", fi.getFieldName());
Injection fi = fieldInjections.get(0);
assertEquals ("f", fi.getTarget().getName());
fieldInjections = injections.getFieldInjections(ResourceA.class);
assertNotNull(fieldInjections);
assertEquals(4, fieldInjections.size());
//no method injections on class ResourceB
List<Injection> methodInjections = injections.getMethodInjections(ResourceB.class);
assertNotNull(methodInjections);
assertEquals(0, methodInjections.size());
//3 method injections on class ResourceA
methodInjections = injections.getMethodInjections(ResourceA.class);
assertNotNull(methodInjections);
assertEquals(3, methodInjections.size());
//3 method injections on class ResourceA, 4 field injections
List<Injection> resAInjections = injections.getInjections(ResourceA.class.getCanonicalName());
assertNotNull(resAInjections);
assertEquals(7, resAInjections.size());
int fieldCount = 0;
int methodCount = 0;
Iterator<Injection> itor = resAInjections.iterator();
while (itor.hasNext())
{
Injection x = itor.next();
if (x.isField())
fieldCount++;
else
methodCount++;
}
assertEquals(4, fieldCount);
assertEquals(3, methodCount);
//test injection
ResourceB binst = new ResourceB();
@ -166,8 +170,8 @@ public class TestResourceAnnotations extends TestCase
}
});
assertEquals(resourceA.getObjectToBind(), env.lookup("fluff"));
assertEquals(resourceB.getObjectToBind(), env.lookup("stuff"));
assertEquals(resourceA.getObjectToBind(), env.lookup("peach"));
assertEquals(resourceB.getObjectToBind(), env.lookup("pear"));
}
}

View File

@ -21,6 +21,8 @@ import javax.naming.InitialContext;
import javax.naming.NamingException;
import org.eclipse.jetty.util.IntrospectionUtil;
import org.eclipse.jetty.util.Loader;
import org.eclipse.jetty.util.TypeUtil;
import org.eclipse.jetty.util.log.Log;
/**
@ -37,6 +39,11 @@ public class Injection
private String _jndiName;
private String _mappingName;
private Member _target;
private String _className;
private String _fieldName;
private String _methodName;
private String _paramCanonicalName;
private String _annotationResourceType;
public Injection ()
@ -51,13 +58,35 @@ public class Injection
return _targetClass;
}
/**
* @param name the _className to set
*/
public void setTargetClass(Class clazz)
public String getTargetClassName()
{
_targetClass = clazz;
return _className;
}
public String getFieldName ()
{
return _fieldName;
}
public String getMethodName ()
{
return _methodName;
}
public String getParamCanonicalName ()
{
return _paramCanonicalName;
}
public boolean isField ()
{
return (_fieldName != null);
}
public boolean isMethod ()
{
return (_methodName != null);
}
/**
@ -97,15 +126,28 @@ public class Injection
return _target;
}
/**
* @param target the target to set
* Set up an injection target that is a field
* @param className
* @param fieldName
*/
public void setTarget(Member target)
public void setTarget (String className, String fieldName, String annotationResourceType)
{
this._target = target;
_className = className;
_fieldName = fieldName;
_annotationResourceType = annotationResourceType;
}
//TODO: define an equals method
public void setTarget (String className, String methodName, String paramCanonicalName, String annotationResourceType)
{
_className = className;
_methodName = methodName;
_paramCanonicalName = paramCanonicalName;
_annotationResourceType = annotationResourceType;
}
public void setTarget (Class clazz, String targetName, Class targetType)
{
@ -116,6 +158,9 @@ public class Injection
Log.debug("Looking for method for setter: "+setter+" with arg "+targetType);
_target = IntrospectionUtil.findMethod(clazz, setter, new Class[] {targetType}, true, false);
_targetClass = clazz;
_className = clazz.getCanonicalName();
_methodName = targetName;
_paramCanonicalName = targetType.getCanonicalName();
}
catch (NoSuchMethodException me)
{
@ -123,7 +168,9 @@ public class Injection
try
{
_target = IntrospectionUtil.findField(clazz, targetName, targetType, true, false);
_targetClass = clazz;
_targetClass = clazz;
_className = clazz.getCanonicalName();
_fieldName = targetName;
}
catch (NoSuchFieldException fe)
{
@ -139,16 +186,29 @@ public class Injection
* @throws Exception
*/
public void inject (Object injectable)
{
Member theTarget = getTarget();
if (theTarget instanceof Field)
{
try
{
injectField((Field)theTarget, injectable);
if (_target == null)
loadField();
if (_target == null)
loadMethod();
}
else if (theTarget instanceof Method)
catch (Exception e)
{
injectMethod((Method)theTarget, injectable);
throw new IllegalStateException (e);
}
if (_target != null)
{
if (_target instanceof Field)
injectField((Field)_target, injectable);
else
injectMethod((Method)_target, injectable);
}
else
throw new IllegalStateException ("No method or field to inject with "+getJndiName());
}
@ -171,66 +231,135 @@ public class Injection
* @param field
* @param injectable
*/
public void injectField (Field field, Object injectable)
{
try
protected void injectField (Field field, Object injectable)
{
if (validateInjection())
{
//validateInjection(field, injectable);
boolean accessibility = field.isAccessible();
field.setAccessible(true);
field.set(injectable, lookupInjectedValue());
field.setAccessible(accessibility);
}
catch (Exception e)
{
Log.warn(e);
throw new IllegalStateException("Inject failed for field "+field.getName());
try
{
System.err.println("Value to inject="+lookupInjectedValue());
boolean accessibility = field.isAccessible();
field.setAccessible(true);
field.set(injectable, lookupInjectedValue());
field.setAccessible(accessibility);
System.err.println("Injected field "+_fieldName+" of class "+_className);
}
catch (Exception e)
{
Log.warn(e);
throw new IllegalStateException("Inject failed for field "+field.getName());
}
}
else
throw new IllegalStateException ("Invalid injection for "+_className+"."+_fieldName);
}
/**
* Inject value from jndi into a setter method of an instance
* @param method
* @param injectable
*/
public void injectMethod (Method method, Object injectable)
protected void injectMethod (Method method, Object injectable)
{
//validateInjection(method, injectable);
try
if (validateInjection())
{
boolean accessibility = method.isAccessible();
method.setAccessible(true);
method.invoke(injectable, new Object[] {lookupInjectedValue()});
method.setAccessible(accessibility);
}
catch (Exception e)
{
Log.warn(e);
throw new IllegalStateException("Inject failed for method "+method.getName());
try
{
System.err.println("Value to inject="+lookupInjectedValue());
boolean accessibility = method.isAccessible();
method.setAccessible(true);
method.invoke(injectable, new Object[] {lookupInjectedValue()});
method.setAccessible(accessibility);
System.err.println("Injected method "+_methodName+" of class "+_className);
}
catch (Exception e)
{
Log.warn(e);
throw new IllegalStateException("Inject failed for method "+method.getName());
}
}
else
throw new IllegalStateException("Invalid injection for "+_className+"."+_methodName);
}
protected void loadField()
throws ClassNotFoundException, NoSuchFieldException
{
if (_fieldName == null || _className == null)
return;
if (_targetClass == null)
_targetClass = Loader.loadClass(null, _className);
_target = _targetClass.getDeclaredField(_fieldName);
}
private void validateInjection (Method method, Object injectable)
throws NoSuchMethodException
/**
* Load the target class and method.
* A valid injection target method only has 1 argument.
* @throws ClassNotFoundException
* @throws NoSuchMethodException
*/
protected void loadMethod ()
throws ClassNotFoundException, NoSuchMethodException
{
if ((injectable==null) || (method==null))
if (_methodName == null || _className == null)
return;
//check the injection target actually has a matching method
//TODO: think about this, they have to be assignable
injectable.getClass().getMethod(method.getName(), method.getParameterTypes());
if (_targetClass == null)
_targetClass = Loader.loadClass(null, _className);
System.err.println("Loaded target class "+_targetClass.getName());
System.err.println("Looking for method "+_methodName +" with argument of type "+_paramCanonicalName+" on class "+_className);
Class arg = TypeUtil.fromName(_paramCanonicalName);
if (arg == null)
arg = Loader.loadClass(null, _paramCanonicalName);
System.err.println("Loaded type: "+arg.getName());
_target = _targetClass.getDeclaredMethod(_methodName, new Class[] {arg});
}
private void validateInjection (Field field, Object injectable)
throws NoSuchFieldException
private boolean validateInjection ()
{
if ((field==null) || (injectable==null))
return;
//check that if the injection came from an annotation, the type specified in the annotation
//is compatible with the field or method to inject
//JavaEE spec sec 5.2.4
if (_annotationResourceType != null)
{
System.err.println("Validating against annotationResourceType="+_annotationResourceType);
if (_target == null)
return false;
try
{
Class<?> annotationType = TypeUtil.fromName(_annotationResourceType);
if (annotationType == null)
annotationType = Loader.loadClass(null, _annotationResourceType);
Field f = injectable.getClass().getField(field.getName());
if (!f.getType().isAssignableFrom(field.getType()))
throw new NoSuchFieldException("Mismatching type of field: "+f.getType().getName()+" v "+field.getType().getName());
}
if (_target instanceof Field)
{
return ((Field)_target).getType().isAssignableFrom(annotationType);
}
else if (_target instanceof Method)
{
Class<?>[] args = ((Method)_target).getParameterTypes();
return args[0].isAssignableFrom(annotationType);
}
return false;
}
catch (Exception e)
{
Log.warn("Unable to verify injection for "+_className+"."+ (_fieldName==null?_methodName:_fieldName));
return false;
}
}
else
return true;
}
}

View File

@ -19,6 +19,7 @@ import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
@ -32,87 +33,74 @@ import org.eclipse.jetty.util.log.Log;
public class InjectionCollection
{
public static final String INJECTION_COLLECTION = "org.eclipse.jetty.injectionCollection";
private HashMap<Class<?>, List<Injection>> fieldInjectionsMap = new HashMap<Class<?>, List<Injection>>();//map of classname to field injections
private HashMap<Class<?>, List<Injection>> methodInjectionsMap = new HashMap<Class<?>, List<Injection>>();//map of classname to method injections
private HashMap<String, List<Injection>> _injectionMap = new HashMap<String, List<Injection>>();//map of classname to injections
public void add (Injection injection)
{
if ((injection==null) || (injection.getTarget()==null) || (injection.getTargetClass()==null))
if ((injection==null) || injection.getTargetClassName()==null)
return;
if (Log.isDebugEnabled())
Log.debug("Adding injection for class="+injection.getTargetClass()+ " on a "+injection.getTarget());
Map<Class<?>, List<Injection>> injectionsMap = null;
if (injection.getTarget() instanceof Field)
injectionsMap = fieldInjectionsMap;
if (injection.getTarget() instanceof Method)
injectionsMap = methodInjectionsMap;
Log.debug("Adding injection for class="+(injection.getTargetClassName()+ " on a "+(injection.isField()?injection.getFieldName():injection.getMethodName())));
List<Injection> injections = (List<Injection>)injectionsMap.get(injection.getTargetClass());
List<Injection> injections = (List<Injection>)_injectionMap.get(injection.getTargetClassName());
if (injections==null)
{
injections = new ArrayList<Injection>();
injectionsMap.put(injection.getTargetClass(), injections);
_injectionMap.put(injection.getTargetClassName(), injections);
}
injections.add(injection);
}
public List<Injection> getFieldInjections (Class<?> clazz)
{
if (clazz==null)
return null;
List<Injection> list = (List<Injection>)fieldInjectionsMap.get(clazz);
if (list == null)
list = Collections.emptyList();
return list;
}
public List<Injection> getMethodInjections (Class<?> clazz)
{
if (clazz==null)
return null;
List<Injection> list = (List<Injection>)methodInjectionsMap.get(clazz);
if (list == null)
list = Collections.emptyList();
return list;
}
public List<Injection> getInjections (Class<?> clazz)
public List<Injection> getInjections (String className)
{
if (clazz==null)
return null;
List<Injection> results = new ArrayList<Injection> ();
results.addAll(getFieldInjections(clazz));
results.addAll(getMethodInjections(clazz));
return results;
}
public Injection getInjection (Class<?> clazz, Member member)
{
if (clazz==null)
return null;
if (member==null)
return null;
Map<Class<?>, List<Injection>> map = null;
if (member instanceof Field)
map = fieldInjectionsMap;
else if (member instanceof Method)
map = methodInjectionsMap;
if (map==null)
if (className==null)
return null;
List<Injection> injections = (List<Injection>)map.get(clazz);
return _injectionMap.get(className);
}
public Injection getInjection (String jndiName, String className, String fieldName)
{
if (fieldName == null || className == null)
return null;
List<Injection> injections = getInjections(className);
if (injections == null)
return null;
Iterator<Injection> itor = injections.iterator();
Injection injection = null;
for (int i=0;injections!=null && i<injections.size() && injection==null;i++)
while (itor.hasNext() && injection == null)
{
Injection candidate = (Injection)injections.get(i);
if (candidate.getTarget().equals(member))
injection = candidate;
Injection i = itor.next();
if (fieldName.equals(i.getFieldName()))
injection = i;
}
return injection;
}
public Injection getInjection (String jndiName, String className, String methodName, String paramCanonicalName)
{
if (className == null || methodName == null || paramCanonicalName == null)
return null;
List<Injection> injections = getInjections(className);
if (injections == null)
return null;
Iterator<Injection> itor = injections.iterator();
Injection injection = null;
while (itor.hasNext() && injection == null)
{
Injection i = itor.next();
if (methodName.equals(i.getMethodName()) && paramCanonicalName.equals(i.getParamCanonicalName()))
injection = i;
}
return injection;
}
@ -127,21 +115,13 @@ public class InjectionCollection
//looking at it's class hierarchy
Class<?> clazz = injectable.getClass();
while (clazz != null)
{
//Do field injections
List<Injection> injections = getFieldInjections(clazz);
for (Injection i : injections)
List<Injection> injections = _injectionMap.get(clazz.getCanonicalName());
if (injections != null)
{
i.inject(injectable);
}
//Do method injections
injections = getMethodInjections(clazz);
for (Injection i : injections)
{
i.inject(injectable);
for (Injection i : injections)
i.inject(injectable);
}
clazz = clazz.getSuperclass();

View File

@ -17,6 +17,7 @@ import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import org.eclipse.jetty.util.IntrospectionUtil;
import org.eclipse.jetty.util.Loader;
@ -30,6 +31,8 @@ public abstract class LifeCycleCallback
public static final Object[] __EMPTY_ARGS = new Object[] {};
private Method _target;
private Class _targetClass;
private String _className;
private String _methodName;
public LifeCycleCallback()
@ -44,16 +47,16 @@ public abstract class LifeCycleCallback
{
return _targetClass;
}
/**
* @param name the class to set
*/
public void setTargetClass(Class clazz)
public String getTargetClassName()
{
_targetClass = clazz;
return _className;
}
public String getMethodName()
{
return _methodName;
}
/**
* @return the target
@ -62,17 +65,13 @@ public abstract class LifeCycleCallback
{
return _target;
}
/**
* @param target the target to set
*/
public void setTarget(Method target)
public void setTarget (String className, String methodName)
{
this._target = target;
_className = className;
_methodName = methodName;
}
public void setTarget (Class clazz, String methodName)
{
@ -82,6 +81,8 @@ public abstract class LifeCycleCallback
validate(clazz, method);
_target = method;
_targetClass = clazz;
_className = clazz.getCanonicalName();
_methodName = methodName;
}
catch (NoSuchMethodException e)
{
@ -95,12 +96,20 @@ public abstract class LifeCycleCallback
public void callback (Object instance)
throws Exception
{
if (getTarget() != null)
if (_target == null)
{
if (_targetClass == null)
_targetClass = Loader.loadClass(null, _className);
_target = _targetClass.getDeclaredMethod(_methodName, new Class[]{}); //TODO
}
if (_target != null)
{
boolean accessibility = getTarget().isAccessible();
getTarget().setAccessible(true);
getTarget().invoke(instance, __EMPTY_ARGS);
getTarget().setAccessible(accessibility);
System.err.println("Calling callback on "+_className+"."+_methodName);
}
}

View File

@ -29,8 +29,8 @@ import org.eclipse.jetty.util.log.Log;
public class LifeCycleCallbackCollection
{
public static final String LIFECYCLE_CALLBACK_COLLECTION = "org.eclipse.jetty.lifecyleCallbackCollection";
private HashMap postConstructCallbacksMap = new HashMap();
private HashMap preDestroyCallbacksMap = new HashMap();
private HashMap<String, List<LifeCycleCallback>> postConstructCallbacksMap = new HashMap<String, List<LifeCycleCallback>>();
private HashMap<String, List<LifeCycleCallback>> preDestroyCallbacksMap = new HashMap<String, List<LifeCycleCallback>>();
@ -43,12 +43,12 @@ public class LifeCycleCallbackCollection
*/
public void add (LifeCycleCallback callback)
{
if ((callback==null) || (callback.getTargetClass()==null) || (callback.getTarget()==null))
if ((callback==null) || (callback.getTargetClassName()==null))
return;
if (Log.isDebugEnabled())
Log.debug("Adding callback for class="+callback.getTargetClass()+ " on "+callback.getTarget());
Map map = null;
Map<String, List<LifeCycleCallback>> map = null;
if (callback instanceof PreDestroyCallback)
map = preDestroyCallbacksMap;
if (callback instanceof PostConstructCallback)
@ -56,13 +56,12 @@ public class LifeCycleCallbackCollection
if (map == null)
throw new IllegalArgumentException ("Unsupported lifecycle callback type: "+callback);
List callbacks = (List)map.get(callback.getTargetClass());
List<LifeCycleCallback> callbacks = map.get(callback.getTargetClassName());
if (callbacks==null)
{
callbacks = new ArrayList();
map.put(callback.getTargetClass(), callbacks);
callbacks = new ArrayList<LifeCycleCallback>();
map.put(callback.getTargetClassName(), callbacks);
}
//don't add another callback for exactly the same method
@ -70,22 +69,22 @@ public class LifeCycleCallbackCollection
callbacks.add(callback);
}
public List getPreDestroyCallbacks (Object o)
public List<LifeCycleCallback> getPreDestroyCallbacks (Object o)
{
if (o == null)
return null;
Class clazz = o.getClass();
return (List)preDestroyCallbacksMap.get(clazz);
return preDestroyCallbacksMap.get(clazz.getName());
}
public List getPostConstructCallbacks (Object o)
public List<LifeCycleCallback> getPostConstructCallbacks (Object o)
{
if (o == null)
return null;
Class clazz = o.getClass();
return (List)postConstructCallbacksMap.get(clazz);
return postConstructCallbacksMap.get(clazz.getName());
}
/**
@ -101,7 +100,7 @@ public class LifeCycleCallbackCollection
return;
Class clazz = o.getClass();
List callbacks = (List)postConstructCallbacksMap.get(clazz);
List<LifeCycleCallback> callbacks = postConstructCallbacksMap.get(clazz.getName());
if (callbacks == null)
return;
@ -123,7 +122,7 @@ public class LifeCycleCallbackCollection
return;
Class clazz = o.getClass();
List callbacks = (List)preDestroyCallbacksMap.get(clazz);
List<LifeCycleCallback> callbacks = preDestroyCallbacksMap.get(clazz.getName());
if (callbacks == null)
return;

View File

@ -25,21 +25,21 @@ import org.eclipse.jetty.servlet.ServletHolder;
*/
public class RunAs
{
private Class _targetClass;
private String _className;
private String _roleName;
public RunAs()
{}
public void setTargetClass (Class clazz)
public void setTargetClassName (String className)
{
_targetClass=clazz;
_className = className;
}
public Class getTargetClass ()
public String getTargetClassName()
{
return _targetClass;
return _className;
}
public void setRoleName (String roleName)
@ -58,16 +58,9 @@ public class RunAs
{
if (holder == null)
return;
String className = getServletClassNameForHolder(holder);
String className = holder.getClassName();
if (className.equals(_targetClass.getName()))
if (className.equals(_className))
holder.setRunAsRole(_roleName);
}
public static String getServletClassNameForHolder (ServletHolder holder)
throws ServletException
{
return holder.getClassName();
}
}

View File

@ -35,12 +35,12 @@ public class RunAsCollection
public void add (RunAs runAs)
{
if ((runAs==null) || (runAs.getTargetClass()==null))
if ((runAs==null) || (runAs.getTargetClassName()==null))
return;
if (Log.isDebugEnabled())
Log.debug("Adding run-as for class="+runAs.getTargetClass());
_runAsMap.put(runAs.getTargetClass().getName(), runAs);
Log.debug("Adding run-as for class="+runAs.getTargetClassName());
_runAsMap.put(runAs.getTargetClassName(), runAs);
}
public RunAs getRunAs (Object o)
@ -54,7 +54,7 @@ public class RunAsCollection
ServletHolder holder = (ServletHolder)o;
String className = RunAs.getServletClassNameForHolder(holder);
String className = holder.getClassName();
return (RunAs)_runAsMap.get(className);
}
@ -69,7 +69,7 @@ public class RunAsCollection
ServletHolder holder = (ServletHolder)o;
String className = RunAs.getServletClassNameForHolder(holder);
String className = holder.getClassName();
RunAs runAs = (RunAs)_runAsMap.get(className);
if (runAs == null)
return;

View File

@ -374,7 +374,6 @@ public abstract class AbstractConfiguration implements Configuration
{
Class clazz = _context.loadClass(targetClassName);
Injection injection = new Injection();
injection.setTargetClass(clazz);
injection.setJndiName(jndiName);
injection.setTarget(clazz, targetName, valueClass);
injections.add(injection);