Author: markt
Date: Fri Jun 1 22:03:10 2012
New Revision: 1345367
URL: http://svn.apache.org/viewvc?rev=1345367&view=rev
Log:
Refactor some duplicate code into an new utility class with an eye to the
proposed patch for BZ 53333
Added:
tomcat/trunk/java/org/apache/catalina/util/Introspection.java (with props)
Modified:
tomcat/trunk/java/org/apache/catalina/core/DefaultInstanceManager.java
tomcat/trunk/java/org/apache/catalina/core/LocalStrings.properties
tomcat/trunk/java/org/apache/catalina/startup/ContextConfig.java
tomcat/trunk/java/org/apache/catalina/startup/LocalStrings.properties
tomcat/trunk/java/org/apache/catalina/startup/WebAnnotationSet.java
tomcat/trunk/java/org/apache/catalina/util/LocalStrings.properties
Modified: tomcat/trunk/java/org/apache/catalina/core/DefaultInstanceManager.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/core/DefaultInstanceManager.java?rev=1345367&r1=1345366&r2=1345367&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/core/DefaultInstanceManager.java
(original)
+++ tomcat/trunk/java/org/apache/catalina/core/DefaultInstanceManager.java Fri
Jun 1 22:03:10 2012
@@ -14,11 +14,8 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
-
package org.apache.catalina.core;
-
import java.beans.Introspector;
import java.io.IOException;
import java.io.InputStream;
@@ -52,6 +49,7 @@ import javax.xml.ws.WebServiceRef;
import org.apache.catalina.ContainerServlet;
import org.apache.catalina.Globals;
import org.apache.catalina.security.SecurityUtil;
+import org.apache.catalina.util.Introspection;
import org.apache.tomcat.InstanceManager;
import org.apache.tomcat.util.ExceptionUtils;
import org.apache.tomcat.util.res.StringManager;
@@ -61,6 +59,16 @@ import org.apache.tomcat.util.res.String
*/
public class DefaultInstanceManager implements InstanceManager {
+ // Used when there are no annotations in a class
+ private static final AnnotationCacheEntry[] ANNOTATIONS_EMPTY
+ = new AnnotationCacheEntry[0];
+
+ /**
+ * The string manager for this package.
+ */
+ protected static final StringManager sm =
+ StringManager.getManager(Constants.Package);
+
private final Context context;
private final Map<String, Map<String, String>> injectionMap;
protected final ClassLoader classLoader;
@@ -73,10 +81,6 @@ public class DefaultInstanceManager impl
private final Map<Class<?>, AnnotationCacheEntry[]> annotationCache =
new WeakHashMap<Class<?>, AnnotationCacheEntry[]>();
- // Used when there are no annotations in a class
- private static final AnnotationCacheEntry[] ANNOTATIONS_EMPTY
- = new AnnotationCacheEntry[0];
-
public DefaultInstanceManager(Context context, Map<String, Map<String,
String>> injectionMap, org.apache.catalina.Context catalinaContext, ClassLoader
containerClassLoader) {
classLoader = catalinaContext.getLoader().getClassLoader();
privileged = catalinaContext.getPrivileged();
@@ -286,19 +290,7 @@ public class DefaultInstanceManager impl
if (context != null) {
// Initialize fields annotations for resource injection if
// JNDI is enabled
- Field[] fields = null;
- if (Globals.IS_SECURITY_ENABLED) {
- final Class<?> clazz2 = clazz;
- fields = AccessController.doPrivileged(
- new PrivilegedAction<Field[]>(){
- @Override
- public Field[] run(){
- return clazz2.getDeclaredFields();
- }
- });
- } else {
- fields = clazz.getDeclaredFields();
- }
+ Field[] fields = Introspection.getDeclaredFields(clazz);
for (Field field : fields) {
if (injections != null &&
injections.containsKey(field.getName())) {
annotations.add(new AnnotationCacheEntry(
@@ -338,30 +330,15 @@ public class DefaultInstanceManager impl
}
// Initialize methods annotations
- Method[] methods = null;
- if (Globals.IS_SECURITY_ENABLED) {
- final Class<?> clazz2 = clazz;
- methods = AccessController.doPrivileged(
- new PrivilegedAction<Method[]>(){
- @Override
- public Method[] run(){
- return clazz2.getDeclaredMethods();
- }
- });
- } else {
- methods = clazz.getDeclaredMethods();
- }
+ Method[] methods = Introspection.getDeclaredMethods(clazz);
Method postConstruct = null;
Method preDestroy = null;
for (Method method : methods) {
- String methodName = method.getName();
if (context != null) {
// Resource injection only if JNDI is enabled
- if (injections != null && methodName.startsWith("set")
- && methodName.length() > 3
- && method.getParameterTypes().length == 1
- &&
method.getReturnType().getName().equals("void")) {
- String fieldName = getName(method);
+ if (injections != null &&
+ Introspection.isValidSetter(method)) {
+ String fieldName = Introspection.getName(method);
if (injections.containsKey(fieldName)) {
annotations.add(new AnnotationCacheEntry(
method.getName(),
@@ -634,11 +611,9 @@ public class DefaultInstanceManager impl
Object instance, Method method, String name, Class<?> clazz)
throws NamingException, IllegalAccessException,
InvocationTargetException {
- if (!method.getName().startsWith("set")
- || method.getName().length() < 4
- || method.getParameterTypes().length != 1
- || !method.getReturnType().getName().equals("void")) {
- throw new IllegalArgumentException("Invalid method resource
injection annotation");
+ if (!Introspection.isValidSetter(method)) {
+ throw new IllegalArgumentException(
+ sm.getString("defaultInstanceManager.invalidInjection"));
}
Object lookedupResource;
@@ -650,7 +625,7 @@ public class DefaultInstanceManager impl
lookedupResource = context.lookup(normalizedName);
} else {
lookedupResource = context.lookup(
- clazz.getName() + "/" + getName(method));
+ clazz.getName() + "/" + Introspection.getName(method));
}
synchronized (method) {
@@ -661,7 +636,8 @@ public class DefaultInstanceManager impl
}
}
- public static String getName(Method setter) {
+ @Deprecated
+ public static String XXXgetName(Method setter) {
// Note: method signature has already been checked for correctness.
// The method name always starts with "set".
return Introspector.decapitalize(setter.getName().substring(3));
Modified: tomcat/trunk/java/org/apache/catalina/core/LocalStrings.properties
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/core/LocalStrings.properties?rev=1345367&r1=1345366&r2=1345367&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/core/LocalStrings.properties
(original)
+++ tomcat/trunk/java/org/apache/catalina/core/LocalStrings.properties Fri Jun
1 22:03:10 2012
@@ -68,6 +68,7 @@ containerBase.backgroundProcess.loader=E
containerBase.backgroundProcess.manager=Exception processing manager {0}
background process
containerBase.backgroundProcess.realm=Exception processing realm {0}
background process
containerBase.backgroundProcess.valve=Exception processing valve {0}
background process
+defaultInstanceManager.invalidInjection=Invalid method resource injection
annotation
filterChain.filter=Filter execution threw an exception
filterChain.servlet=Servlet execution threw an exception
jreLeakListener.gcDaemonFail=Failed to trigger creation of the GC Daemon
thread during Tomcat start to prevent possible memory leaks. This is expected
on non-Sun JVMs.
Modified: tomcat/trunk/java/org/apache/catalina/startup/ContextConfig.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/startup/ContextConfig.java?rev=1345367&r1=1345366&r2=1345367&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/startup/ContextConfig.java (original)
+++ tomcat/trunk/java/org/apache/catalina/startup/ContextConfig.java Fri Jun 1
22:03:10 2012
@@ -75,6 +75,7 @@ import org.apache.catalina.deploy.Securi
import org.apache.catalina.deploy.ServletDef;
import org.apache.catalina.deploy.WebXml;
import org.apache.catalina.util.ContextName;
+import org.apache.catalina.util.Introspection;
import org.apache.juli.logging.Log;
import org.apache.juli.logging.LogFactory;
import org.apache.naming.resources.DirContextURLConnection;
@@ -2021,7 +2022,7 @@ public class ContextConfig implements Li
}
if (entry.getSciSet().size() > 0) {
// Need to try and load the class
- clazz = loadClass(className);
+ clazz = Introspection.loadClass(context, className);
if (clazz == null) {
// Can't load the class so no point continuing
return;
@@ -2049,7 +2050,8 @@ public class ContextConfig implements Li
if (entry.getKey().getName().equals(
getClassName(annotationEntry.getAnnotationType()))) {
if (clazz == null) {
- clazz = loadClass(className);
+ clazz = Introspection.loadClass(
+ context, className);
if (clazz == null) {
// Can't load the class so no point
// continuing
@@ -2163,31 +2165,6 @@ public class ContextConfig implements Li
return Collections.emptySet();
}
- private Class<?> loadClass(String className) {
- Class<?> clazz = null;
- try {
- clazz = context.getLoader().getClassLoader().loadClass(className);
- } catch (NoClassDefFoundError e) {
- log.debug(sm.getString("contextConfig.invalidSciHandlesTypes",
- className), e);
- return null;
- } catch (ClassNotFoundException e) {
- log.debug(sm.getString("contextConfig.invalidSciHandlesTypes",
- className), e);
- return null;
- } catch (ClassFormatError e) {
- log.debug(sm.getString("contextConfig.invalidSciHandlesTypes",
- className), e);
- return null;
- } catch (Throwable t) {
- ExceptionUtils.handleThrowable(t);
- log.debug(sm.getString("contextConfig.invalidSciHandlesTypes",
- className), t);
- return null;
- }
- return clazz;
- }
-
private static final String getClassName(String internalForm) {
if (!internalForm.startsWith("L")) {
return internalForm;
Modified: tomcat/trunk/java/org/apache/catalina/startup/LocalStrings.properties
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/startup/LocalStrings.properties?rev=1345367&r1=1345366&r2=1345367&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/startup/LocalStrings.properties
(original)
+++ tomcat/trunk/java/org/apache/catalina/startup/LocalStrings.properties Fri
Jun 1 22:03:10 2012
@@ -44,7 +44,6 @@ contextConfig.inputStreamFile=Unable to
contextConfig.inputStreamJar=Unable to process Jar entry [{0}] from Jar [{1}]
for annotations
contextConfig.inputStreamJndi=Unable to process resource element [{0}] for
annotations
contextConfig.invalidSci=The ServletContentInitializer [{0}] could not be
created
-contextConfig.invalidSciHandlesTypes=Unable to load class [{0}] to check
against the @HandlesTypes annotation of one or more ServletContentInitializers.
contextConfig.jndiUrl=Unable to process JNDI URL [{0}] for annotations
contextConfig.jndiUrlNotDirContextConn=The connection created for URL [{0}]
was not a DirContextURLConnection
contextConfig.jspFile.error=JSP file {0} must start with a ''/'
@@ -122,6 +121,7 @@ userConfig.error=Error deploying web app
userConfig.start=UserConfig: Processing START
userConfig.stop=UserConfig: Processing STOP
userConfig.deploy.threaded.error=Error waiting for multi-thread deployment of
user directories to complete
+webAnnotationSet.invalidInjection=Invalid method resource injection annotation.
webRuleSet.absoluteOrdering=<absolute-ordering> element not valid in
web-fragment.xml and will be ignored
webRuleSet.absoluteOrderingCount=<absolute-ordering> element is limited to 1
occurrence
webRuleSet.nameCount=<name> element is limited to 1 occurrence
Modified: tomcat/trunk/java/org/apache/catalina/startup/WebAnnotationSet.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/startup/WebAnnotationSet.java?rev=1345367&r1=1345366&r2=1345367&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/startup/WebAnnotationSet.java
(original)
+++ tomcat/trunk/java/org/apache/catalina/startup/WebAnnotationSet.java Fri Jun
1 22:03:10 2012
@@ -14,15 +14,10 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
-
package org.apache.catalina.startup;
-
import java.lang.reflect.Field;
import java.lang.reflect.Method;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
import javax.annotation.Resource;
import javax.annotation.Resources;
@@ -31,15 +26,15 @@ import javax.annotation.security.RunAs;
import org.apache.catalina.Container;
import org.apache.catalina.Context;
-import org.apache.catalina.Globals;
import org.apache.catalina.Wrapper;
-import org.apache.catalina.core.DefaultInstanceManager;
import org.apache.catalina.deploy.ContextEnvironment;
import org.apache.catalina.deploy.ContextResource;
import org.apache.catalina.deploy.ContextResourceEnvRef;
import org.apache.catalina.deploy.ContextService;
import org.apache.catalina.deploy.FilterDef;
import org.apache.catalina.deploy.MessageDestinationRef;
+import org.apache.catalina.util.Introspection;
+import org.apache.tomcat.util.res.StringManager;
/**
* <p><strong>AnnotationSet</strong> for processing the annotations of the web
application
@@ -53,9 +48,15 @@ public class WebAnnotationSet {
private static final String SEPARATOR = "/";
- // --------------------------------------------------------- Public Methods
+ /**
+ * The string resources for this package.
+ */
+ protected static final StringManager sm =
+ StringManager.getManager(Constants.Package);
+ // --------------------------------------------------------- Public Methods
+
/**
* Process the annotations on a context.
*/
@@ -79,7 +80,8 @@ public class WebAnnotationSet {
Class<?> classClass = null;
String[] applicationListeners = context.findApplicationListeners();
for (int i = 0; i < applicationListeners.length; i++) {
- classClass = loadClass(context, applicationListeners[i]);
+ classClass = Introspection.loadClass(context,
+ applicationListeners[i]);
if (classClass == null) {
continue;
}
@@ -98,7 +100,8 @@ public class WebAnnotationSet {
Class<?> classClass = null;
FilterDef[] filterDefs = context.findFilterDefs();
for (int i = 0; i < filterDefs.length; i++) {
- classClass = loadClass(context, (filterDefs[i]).getFilterClass());
+ classClass = Introspection.loadClass(context,
+ (filterDefs[i]).getFilterClass());
if (classClass == null) {
continue;
}
@@ -127,7 +130,8 @@ public class WebAnnotationSet {
continue;
}
- classClass = loadClass(context, wrapper.getServletClass());
+ classClass = Introspection.loadClass(context,
+ wrapper.getServletClass());
if (classClass == null) {
continue;
}
@@ -254,7 +258,7 @@ public class WebAnnotationSet {
protected static void loadFieldsAnnotation(Context context,
Class<?> classClass) {
// Initialize the annotations
- Field[] fields = getDeclaredFields(classClass);
+ Field[] fields = Introspection.getDeclaredFields(classClass);
if (fields != null && fields.length > 0) {
for (Field field : fields) {
if (field.isAnnotationPresent(Resource.class)) {
@@ -272,16 +276,19 @@ public class WebAnnotationSet {
protected static void loadMethodsAnnotation(Context context,
Class<?> classClass) {
// Initialize the annotations
- Method[] methods = getDeclaredMethods(classClass);
+ Method[] methods = Introspection.getDeclaredMethods(classClass);
if (methods != null && methods.length > 0) {
for (Method method : methods) {
if (method.isAnnotationPresent(Resource.class)) {
Resource annotation = method.getAnnotation(Resource.class);
- checkBeanNamingConventions(method);
+ if (!Introspection.isValidSetter(method)) {
+ throw new IllegalArgumentException(sm.getString(
+ "webAnnotationSet.invalidInjection"));
+ }
String defaultName = classClass.getName() + SEPARATOR +
- DefaultInstanceManager.getName(method);
+ Introspection.getName(method);
String defaultType =
(method.getParameterTypes()[0]).getCanonicalName();
@@ -405,16 +412,6 @@ public class WebAnnotationSet {
}
- private static void checkBeanNamingConventions(Method method) {
- if (!method.getName().startsWith("set")
- || method.getName().length() < 4
- || method.getParameterTypes().length != 1
- || !method.getReturnType().getName().equals("void")) {
- throw new IllegalArgumentException("Invalid method resource
injection annotation.");
- }
- }
-
-
private static String getType(Resource annotation, String defaultType) {
String type = annotation.type().getCanonicalName();
if (type == null || type.equals("java.lang.Object")) {
@@ -435,54 +432,4 @@ public class WebAnnotationSet {
}
return name;
}
-
-
- private static Field[] getDeclaredFields(Class<?> classClass) {
- Field[] fields = null;
- if (Globals.IS_SECURITY_ENABLED) {
- final Class<?> clazz = classClass;
- fields = AccessController.doPrivileged(
- new PrivilegedAction<Field[]>(){
- @Override
- public Field[] run(){
- return clazz.getDeclaredFields();
- }
- });
- } else {
- fields = classClass.getDeclaredFields();
- }
- return fields;
- }
-
-
- private static Method[] getDeclaredMethods(Class<?> classClass) {
- Method[] methods = null;
- if (Globals.IS_SECURITY_ENABLED) {
- final Class<?> clazz = classClass;
- methods = AccessController.doPrivileged(
- new PrivilegedAction<Method[]>(){
- @Override
- public Method[] run(){
- return clazz.getDeclaredMethods();
- }
- });
- } else {
- methods = classClass.getDeclaredMethods();
- }
- return methods;
- }
-
-
- private static Class<?> loadClass(Context context, String fileString) {
- ClassLoader classLoader = context.getLoader().getClassLoader();
- Class<?> classClass = null;
- try {
- classClass = classLoader.loadClass(fileString);
- } catch (ClassNotFoundException e) {
- // We do nothing
- } catch (NoClassDefFoundError e) {
- // We do nothing
- }
- return classClass;
- }
}
Added: tomcat/trunk/java/org/apache/catalina/util/Introspection.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/util/Introspection.java?rev=1345367&view=auto
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/util/Introspection.java (added)
+++ tomcat/trunk/java/org/apache/catalina/util/Introspection.java Fri Jun 1
22:03:10 2012
@@ -0,0 +1,137 @@
+/*
+ * 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.beans.Introspector;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+import org.apache.catalina.Container;
+import org.apache.catalina.Globals;
+import org.apache.juli.logging.Log;
+import org.apache.tomcat.util.ExceptionUtils;
+import org.apache.tomcat.util.res.StringManager;
+
+/**
+ * Provides introspection utilities that either require knowledge of Tomcat
+ * internals or are solely used by Tomcat internals.
+ */
+public class Introspection {
+
+ private static StringManager sm =
+ StringManager.getManager("org.apache.catalina.util");
+
+
+ /**
+ * Extract the Java Bean field name from the setter name.
+ *
+ * Note: This method assumes that the method name has already been checked
+ * for correctness.
+ */
+ public static String getName(Method setter) {
+ return Introspector.decapitalize(setter.getName().substring(3));
+ }
+
+
+ /**
+ * Determines if a method has a valid name and signature for a Java Bean
+ * setter.
+ *
+ * @param method The method to test
+ *
+ * @return <code>true</code> if the method does have a valid name and
+ * signature, else <code>false</code>
+ */
+ public static boolean isValidSetter(Method method) {
+ if (method.getName().startsWith("set")
+ && method.getName().length() > 3
+ && method.getParameterTypes().length == 1
+ && method.getReturnType().getName().equals("void")) {
+ return true;
+ }
+ return false;
+ }
+
+
+ /**
+ * Obtain the declared fields for a class taking account of any security
+ * manager that may be configured.
+ */
+ public static Field[] getDeclaredFields(final Class<?> clazz) {
+ Field[] fields = null;
+ if (Globals.IS_SECURITY_ENABLED) {
+ fields = AccessController.doPrivileged(
+ new PrivilegedAction<Field[]>(){
+ @Override
+ public Field[] run(){
+ return clazz.getDeclaredFields();
+ }
+ });
+ } else {
+ fields = clazz.getDeclaredFields();
+ }
+ return fields;
+ }
+
+
+ /**
+ * Obtain the declared methods for a class taking account of any security
+ * manager that may be configured.
+ */
+ public static Method[] getDeclaredMethods(final Class<?> clazz) {
+ Method[] methods = null;
+ if (Globals.IS_SECURITY_ENABLED) {
+ methods = AccessController.doPrivileged(
+ new PrivilegedAction<Method[]>(){
+ @Override
+ public Method[] run(){
+ return clazz.getDeclaredMethods();
+ }
+ });
+ } else {
+ methods = clazz.getDeclaredMethods();
+ }
+ return methods;
+ }
+
+
+ /**
+ * Attempt to load a class using the given Container's class loader. If the
+ * class cannot be loaded, a debug level log message will be written to the
+ * Container's log and null will be returned.
+ */
+ public static Class<?> loadClass(Container container, String className) {
+ ClassLoader cl = container.getLoader().getClassLoader();
+ Log log = container.getLogger();
+ Class<?> clazz = null;
+ try {
+ clazz = cl.loadClass(className);
+ } catch (ClassNotFoundException e) {
+ log.debug(sm.getString("introspection.classLoadFailed"), e);
+ } catch (NoClassDefFoundError e) {
+ log.debug(sm.getString("introspection.classLoadFailed"), e);
+ } catch (ClassFormatError e) {
+ log.debug(sm.getString("introspection.classLoadFailed"), e);
+ } catch (Throwable t) {
+ ExceptionUtils.handleThrowable(t);
+ log.debug(sm.getString("introspection.classLoadFailed"), t);
+ }
+ return clazz;
+ }
+}
Propchange: tomcat/trunk/java/org/apache/catalina/util/Introspection.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: tomcat/trunk/java/org/apache/catalina/util/LocalStrings.properties
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/util/LocalStrings.properties?rev=1345367&r1=1345366&r2=1345367&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/util/LocalStrings.properties
(original)
+++ tomcat/trunk/java/org/apache/catalina/util/LocalStrings.properties Fri Jun
1 22:03:10 2012
@@ -22,6 +22,7 @@ extensionValidator.web-application-manif
extensionValidator.extension-not-found-error=ExtensionValidator[{0}][{1}]:
Required extension [{2}] not found.
extensionValidator.extension-validation-error=ExtensionValidator[{0}]: Failure
to find [{1}] required extension(s).
extensionValidator.failload=Failure loading extension [{0}]
+introspection.classLoadFailed=Failed to load class [{0}]
lifecycleBase.alreadyDestroyed=The destroy() method was called on component
[{0}] after destroy() had already been called. The second call will be ignored.
lifecycleBase.alreadyStarted=The start() method was called on component [{0}]
after start() had already been called. The second call will be ignored.
lifecycleBase.alreadyStopped=The stop() method was called on component [{0}]
after stop() had already been called. The second call will be ignored.
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]