Updated the change bundle.
Comments welcome.
-------- Original Message --------
Subject: [REVIEW] Misc cleanup and small change to
PostConstruct/PreDestroy annotation handling.
Date: Thu, 12 Jan 2006 11:47:33 -0800
From: Ryan Lubke <Ryan.Lubke_at_Sun.COM>
Reply-To: dev_at_javaserverfaces.dev.java.net
To: dev_at_javaserverfaces.dev.java.net
See attached.
Try to save a few cycles by not scanning for PostConstruct/PreDestroy
methods every time a ManagedBean is created. Instead
store the methods into Arrays when the ManagedBeanFactory
is instantiated.
Also remove the hard compile/runtime dependency on
PostConstruct/PreDestory classes.
SECTION: Modified Files
----------------------------
M jsf-ri/src/com/sun/faces/el/ImplicitObjectELResolverForJsp.java
M jsf-ri/src/com/sun/faces/util/MessageUtils.java
M jsf-tools/template-src/MessageFactory.java
- leverage varargs
M jsf-ri/src/javax/faces/Messages.properties
M jsf-ri/src/javax/faces/Messages_de.properties
M jsf-ri/src/javax/faces/Messages_en.properties
M jsf-ri/src/javax/faces/Messages_es.properties
M jsf-ri/src/javax/faces/Messages_fr.properties
- correct typo
M jsf-ri/src/com/sun/faces/spi/ManagedBeanFactory.java
- add two methods to ManageBeanFactory SPI
* getPostConstructMethods
* getPreDestroyMethods
M jsf-ri/src/com/sun/faces/config/ManagedBeanFactoryImpl.java
- When factory is created, scan the class for annotated
methods.
- Added enum which will detect the availability of
PostConstruct/PreDestory to remove hard compile/
runtime dependency on said annotations.
M jsf-ri/src/com/sun/faces/spi/ManagedBeanFactoryWrapper.java
- Implementation of new interface methods.
M jsf-ri/src/com/sun/faces/application/ApplicationAssociate.java
- changes to accoodate method relocations
M jsf-ri/src/com/sun/faces/util/Util.java
- Moved getMethodsWithAnnotations to be a private method
of ManagedBeanFactoryImpl
M jsf-ri/src/com/sun/faces/LogStrings.properties
- Added message for case where PostConstruct and PreDestroy
aren't available.
SECTION: Diffs
----------------------------
Index: jsf-ri/src/com/sun/faces/LogStrings.properties
===================================================================
RCS file: /cvs/javaserverfaces-sources/jsf-ri/src/com/sun/faces/LogStrings.properties,v
retrieving revision 1.4
diff -u -r1.4 LogStrings.properties
--- jsf-ri/src/com/sun/faces/LogStrings.properties 3 Nov 2005 19:18:21 -0000 1.4
+++ jsf-ri/src/com/sun/faces/LogStrings.properties 12 Jan 2006 22:55:03 -0000
@@ -35,6 +35,6 @@
jsf.illegal_view_id_error=JSF1010: Illegal view ID {0}. The ID must begin with ''/''
jsf.navigation.no_matching_outcome="JSF1012: Unable to find matching navigation case from view ID ''{0}'' for outcome ''{1}''
jsf.navigation.no_matching_outcome_action="JSF1013: Unable to find matching navigation case from view ID ''{0}'' for outcome ''{1}'' and action ''{2}''
-
+jsf.util_no_annotation_processed="JSF1014: Unable to load annotation class ''{0}''. As a result, this annotation will not be processed.
# core tags
jsf.core.tags.eval_result_not_expected_type=JSF1011: Evaluation of expression for attribute ''{0}'' resulted in unexpected type. Expected {1}, but received {2}.
Index: jsf-ri/src/com/sun/faces/application/ApplicationAssociate.java
===================================================================
RCS file: /cvs/javaserverfaces-sources/jsf-ri/src/com/sun/faces/application/ApplicationAssociate.java,v
retrieving revision 1.24
diff -u -r1.24 ApplicationAssociate.java
--- jsf-ri/src/com/sun/faces/application/ApplicationAssociate.java 11 Jan 2006 15:28:02 -0000 1.24
+++ jsf-ri/src/com/sun/faces/application/ApplicationAssociate.java 12 Jan 2006 22:55:03 -0000
@@ -29,40 +29,37 @@
package com.sun.faces.application;
+import javax.el.CompositeELResolver;
+import javax.el.ExpressionFactory;
+import javax.faces.FacesException;
+import javax.faces.component.UIViewRoot;
+import javax.faces.context.ExternalContext;
+import javax.faces.context.FacesContext;
+import javax.faces.el.PropertyResolver;
+import javax.faces.el.VariableResolver;
+import javax.servlet.ServletContext;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
+import java.util.Locale;
import java.util.Map;
+import java.util.ResourceBundle;
import java.util.TreeSet;
import java.util.logging.Level;
import java.util.logging.Logger;
-import javax.el.CompositeELResolver;
-import javax.el.ExpressionFactory;
-import javax.faces.FacesException;
-import javax.faces.context.ExternalContext;
-import javax.faces.context.FacesContext;
-import javax.faces.el.PropertyResolver;
-import javax.faces.el.VariableResolver;
-
import com.sun.faces.RIConstants;
import com.sun.faces.config.ConfigureListener;
+import com.sun.faces.config.beans.ResourceBundleBean;
import com.sun.faces.spi.ManagedBeanFactory;
import com.sun.faces.spi.ManagedBeanFactory.Scope;
-import com.sun.faces.config.beans.ResourceBundleBean;
-import com.sun.faces.util.Util;
import com.sun.faces.util.MessageUtils;
-
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.util.Locale;
-import java.util.ResourceBundle;
-import javax.annotation.PostConstruct;
-import javax.annotation.PreDestroy;
-import javax.faces.component.UIViewRoot;
-import javax.servlet.ServletContext;
+import com.sun.faces.util.Util;
/**
* <p>Break out the things that are associated with the Application, but
@@ -78,7 +75,7 @@
public class ApplicationAssociate {
// Log instance for this class
- private static Logger logger = Util.getLogger(Util.FACES_LOGGER
+ private static final Logger LOGGER = Util.getLogger(Util.FACES_LOGGER
+ Util.APPLICATION_LOGGER);
private ApplicationImpl app = null;
@@ -93,13 +90,22 @@
* Simple struct encapsulating a managed bean instance with its list
* of PreDestroy methods.
*/
- private static class ManagedBeanPreDestroyStruct extends Object {
+ private static class ManagedBeanPreDestroyStruct {
private Object bean = null;
- private List<Method> preDestroys = null;
- ManagedBeanPreDestroyStruct(Object bean, List<Method> preDestroys) {
+ private Method[] preDestroys = null;
+ ManagedBeanPreDestroyStruct(Object bean, Method[] preDestroys) {
this.bean = bean;
this.preDestroys = preDestroys;
}
+
+ Object getBean() {
+ return bean;
+ }
+
+ Method[] getPreDestroys() {
+ return preDestroys;
+ }
+
void clear() {
this.bean = null;
this.preDestroys = null;
@@ -146,11 +152,18 @@
"ApplicationAssociate";
private ArrayList elResolversFromFacesConfig = null;
+
+ @SuppressWarnings("deprecation")
private VariableResolver legacyVRChainHead = null;
+
+ @SuppressWarnings("deprecation")
private PropertyResolver legacyPRChainHead = null;
private ExpressionFactory expressionFactory = null;
+ @SuppressWarnings("deprecation")
private PropertyResolver legacyPropertyResolver = null;
+
+ @SuppressWarnings("deprecation")
private VariableResolver legacyVariableResolver = null;
private CompositeELResolver facesELResolverForJsp = null;
@@ -207,18 +220,22 @@
applicationMap.remove(ASSOCIATE_KEY);
}
+ @SuppressWarnings("deprecation")
public void setLegacyVRChainHead(VariableResolver resolver) {
this.legacyVRChainHead = resolver;
}
+ @SuppressWarnings("deprecation")
public VariableResolver getLegacyVRChainHead() {
return legacyVRChainHead;
}
-
+
+ @SuppressWarnings("deprecation")
public void setLegacyPRChainHead(PropertyResolver resolver) {
this.legacyPRChainHead = resolver;
}
-
+
+ @SuppressWarnings("deprecation")
public PropertyResolver getLegacyPRChainHead() {
return legacyPRChainHead;
}
@@ -255,6 +272,7 @@
* Maintains the PropertyResolver called through
* Application.setPropertyResolver()
*/
+ @SuppressWarnings("deprecation")
public void setLegacyPropertyResolver(PropertyResolver resolver){
this.legacyPropertyResolver = resolver;
}
@@ -263,6 +281,7 @@
* Returns the PropertyResolver called through
* Application.getPropertyResolver()
*/
+ @SuppressWarnings("deprecation")
public PropertyResolver getLegacyPropertyResolver(){
return legacyPropertyResolver;
}
@@ -271,6 +290,7 @@
* Maintains the PropertyResolver called through
* Application.setVariableResolver()
*/
+ @SuppressWarnings("deprecation")
public void setLegacyVariableResolver(VariableResolver resolver){
this.legacyVariableResolver = resolver;
}
@@ -279,6 +299,7 @@
* Returns the VariableResolver called through
* Application.getVariableResolver()
*/
+ @SuppressWarnings("deprecation")
public VariableResolver getLegacyVariableResolver(){
return legacyVariableResolver;
}
@@ -422,8 +443,8 @@
ManagedBeanFactory factory) {
managedBeanFactoriesMap.put(managedBeanName, factory);
factory.setManagedBeanFactoryMap(managedBeanFactoriesMap);
- if (logger.isLoggable(Level.FINE)) {
- logger.log(Level.FINE, "Added managedBeanFactory " + factory +
+ if (LOGGER.isLoggable(Level.FINE)) {
+ LOGGER.log(Level.FINE, "Added managedBeanFactory " + factory +
" for" + managedBeanName);
}
}
@@ -450,8 +471,8 @@
String managedBeanName) throws FacesException {
ManagedBeanFactory managedBean = managedBeanFactoriesMap.get(managedBeanName);
if (managedBean == null) {
- if (logger.isLoggable(Level.FINE)) {
- logger.fine("Couldn't find a factory for " + managedBeanName);
+ if (LOGGER.isLoggable(Level.FINE)) {
+ LOGGER.fine("Couldn't find a factory for " + managedBeanName);
}
return null;
}
@@ -472,15 +493,15 @@
synchronized (applicationMap) {
try {
bean = managedBean.newInstance(context);
- handlePostConstruct(managedBeanName, scope, bean);
- if (logger.isLoggable(Level.FINE)) {
- logger.fine("Created application scoped bean " +
+ handlePostConstruct(managedBean, bean);
+ if (LOGGER.isLoggable(Level.FINE)) {
+ LOGGER.fine("Created application scoped bean " +
managedBeanName + " successfully ");
}
} catch (Exception ex) {
Object[] params = {managedBeanName};
- if (logger.isLoggable(Level.SEVERE)) {
- logger.log(Level.SEVERE,
+ if (LOGGER.isLoggable(Level.SEVERE)) {
+ LOGGER.log(Level.SEVERE,
"jsf.managed_bean_creation_error", params);
}
throw new FacesException(ex);
@@ -493,15 +514,15 @@
synchronized (sessionMap) {
try {
bean = managedBean.newInstance(context);
- handlePostConstruct(managedBeanName, scope, bean);
- if (logger.isLoggable(Level.FINE)) {
- logger.fine("Created session scoped bean "
+ handlePostConstruct(managedBean, bean);
+ if (LOGGER.isLoggable(Level.FINE)) {
+ LOGGER.fine("Created session scoped bean "
+ managedBeanName + " successfully ");
}
} catch (Exception ex) {
Object[] params = {managedBeanName};
- if (logger.isLoggable(Level.SEVERE)) {
- logger.log(Level.SEVERE,
+ if (LOGGER.isLoggable(Level.SEVERE)) {
+ LOGGER.log(Level.SEVERE,
"jsf.managed_bean_creation_error", params);
}
throw new FacesException(ex);
@@ -515,16 +536,16 @@
try {
bean = managedBean.newInstance(context);
if (scopeIsRequest) {
- handlePostConstruct(managedBeanName, scope, bean);
+ handlePostConstruct(managedBean, bean);
}
- if (logger.isLoggable(Level.FINE)) {
- logger.log(Level.FINE, "Created bean " + managedBeanName +
+ if (LOGGER.isLoggable(Level.FINE)) {
+ LOGGER.log(Level.FINE, "Created bean " + managedBeanName +
" successfully ");
}
} catch (Exception ex) {
Object[] params = {managedBeanName};
- if (logger.isLoggable(Level.SEVERE)) {
- logger.log(Level.SEVERE,
+ if (LOGGER.isLoggable(Level.SEVERE)) {
+ LOGGER.log(Level.SEVERE,
"jsf.managed_bean_creation_error", params);
}
throw new FacesException(ex);
@@ -549,44 +570,35 @@
/**
* <p>Called from {_at_link #createAndMaybeStoreManagedBeans}.
- * Discover the methods on argument <code>bean</code> annotated with
- * <code>@PostConstruct</code> and <code>@PreDestroy</code> using
- * {_at_link Util#getMethodsWithAnnotation}. This method returns a
- * possibly empty <code>List<Method></code>. For each method
- * in the postConstruct list, invoke it. For each method for each
- * non NONE scoped bean in the preDestroyList, add to the
- * preDestroyMethods array in the proper scope.</p>
+ * For each method in the postConstruct list, invoke it.
+ * For each method for each non NONE scoped bean in the
+ * preDestroyList, add to the preDestroyMethods array in
+ * the proper scope.</p>
*
- * @param beanName the name of the bean for which to call PostConstruct
- * annotated methods. If <code>null</code>, all beans in argument
- * <code>scope</code> have their PreDestroy annotated methods
- * called.
- *
- * @param scope the managed bean scope in which to look for the bean
- * or beans.
+ * @param mbFactory the <code>ManagedBeanFactory</code> used to create
+ * <code>bean</code>
*
* @param bean the actual managed bean instance. Injection must
* have already been performed.
*/
- private void handlePostConstruct(String beanName,
- Scope scope, Object bean) throws IllegalAccessException,
- IllegalArgumentException,
- InvocationTargetException {
- List<Method> postConstructs = Util.getMethodsWithAnnotation(bean,
- PostConstruct.class);
- List<Method> preDestroys = Util.getMethodsWithAnnotation(bean,
- PreDestroy.class);
- assert(null != postConstructs && null != preDestroys);
+ private void handlePostConstruct(ManagedBeanFactory mbFactory, Object bean)
+ throws IllegalAccessException,
+ IllegalArgumentException,
+ InvocationTargetException {
- for (Method method : postConstructs) {
+ assert(null != mbFactory && null != bean);
+ Scope scope = mbFactory.getScope();
+ for (Method method : mbFactory.getPostConstructMethods()) {
method.invoke(bean);
}
// We can't call @PreDestroy on NONE scoped beans.
- if (!preDestroys.isEmpty() && scope != Scope.NONE) {
+ Method[] preDestroys = mbFactory.getPreDestroyMethods();
+ if (preDestroys.length > 0 && scope != Scope.NONE) {
- preDestroyMethods[scope.ordinal()].put(beanName,
- new ManagedBeanPreDestroyStruct(bean, preDestroys));
+ preDestroyMethods[scope.ordinal()].put(
+ mbFactory.getManagedBeanBean().getManagedBeanName(),
+ new ManagedBeanPreDestroyStruct(bean, preDestroys));
}
}
@@ -643,20 +655,20 @@
if (null != struct) {
if (scope != Scope.REQUEST) {
synchronized(scope) {
- for (Method method : struct.preDestroys) {
- method.invoke(struct.bean);
+ for (Method method : struct.getPreDestroys()) {
+ method.invoke(struct.getBean());
}
- struct.preDestroys.clear();
+
struct.clear();
destroyMap.remove(beanName);
}
}
else {
assert(scope == Scope.REQUEST);
- for (Method method : struct.preDestroys) {
- method.invoke(struct.bean);
+ for (Method method : struct.getPreDestroys()) {
+ method.invoke(struct.getBean());
}
- struct.preDestroys.clear();
+
struct.clear();
destroyMap.remove(beanName);
}
@@ -673,11 +685,10 @@
// annotated methods
for (Map.Entry<String, ManagedBeanPreDestroyStruct> entry :
destroyMap.entrySet()) {
- for (Method method : entry.getValue().preDestroys) {
- method.invoke(entry.getValue().bean);
+ for (Method method : entry.getValue().getPreDestroys()) {
+ method.invoke(entry.getValue().getBean());
}
- names.add(entry.getKey());
- entry.getValue().preDestroys.clear();
+ names.add(entry.getKey());
entry.getValue().clear();
}
@@ -688,11 +699,7 @@
}
}
-
-
-
-
/**
* This Comparator class will help sort the <code>ConfigNavigationCase</code> objects
* based on their <code>fromViewId</code> properties in descending order -
Index: jsf-ri/src/com/sun/faces/config/ManagedBeanFactoryImpl.java
===================================================================
RCS file: /cvs/javaserverfaces-sources/jsf-ri/src/com/sun/faces/config/ManagedBeanFactoryImpl.java,v
retrieving revision 1.3
diff -u -r1.3 ManagedBeanFactoryImpl.java
--- jsf-ri/src/com/sun/faces/config/ManagedBeanFactoryImpl.java 11 Jan 2006 15:28:03 -0000 1.3
+++ jsf-ri/src/com/sun/faces/config/ManagedBeanFactoryImpl.java 12 Jan 2006 22:55:03 -0000
@@ -30,6 +30,8 @@
package com.sun.faces.config;
import java.lang.reflect.Array;
+import java.lang.reflect.Method;
+import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
@@ -107,25 +109,55 @@
*/
private final static byte TYPE_IS_SIMPLE = 3;
+ private static final Method[] EMPTY_METHODS = new Method[0];
+
private static final String MANAGED_BEAN_CREATED_STACK =
RIConstants.FACES_PREFIX + "managedBeanStack";
- //
- // Class Variables
- //
+ private static enum Annotations {
+ POST_CONSTRUCT("javax.annotation.PostConstruct"),
+ PRE_DESTROY("javax.annotation.PreDestroy");
+
+ Annotations(String annotationClassName) {
+ ClassLoader loader = Thread.currentThread().getContextClassLoader();
+ if (loader != null) {
+ try {
+ annotationClass =
+ loader.loadClass(annotationClassName);
+ if (!annotationClass.isAnnotation()) {
+ annotationClass = null;
+ }
+ } catch (ClassNotFoundException cne) {
+ if (LOGGER.isLoggable(Level.INFO)) {
+ LOGGER.log(Level.INFO,
+ "jsf.util_no_annotation_processed",
+ annotationClassName);
+ }
+ }
+ }
+ }
+
+ private Class annotationClass;
+
+ public Class getAnnotationClass() {
+ return annotationClass;
+ }
+ }
/**
* <p>The <code>Log</code> instance for this class.</p>
*/
- private static Logger logger = Util.getLogger(Util.FACES_LOGGER
+ private static final Logger LOGGER = Util.getLogger(Util.FACES_LOGGER
+ Util.CONFIG_LOGGER);
-
+ private Method[] postConstructMethods = null;
+ private Method[] preDestroyMethods = null;
+
// Attribute Instance Variables
- ManagedBeanBean managedBean;
- Scope scope = Scope.NONE;
+ private ManagedBeanBean managedBean;
+ private Scope scope = Scope.NONE;
// Relationship Instance Variables
@@ -149,8 +181,31 @@
this.managedBean = managedBean; // (ManagedBeanBean) managedBean.clone();
//set the scope
scope = getScopeFromString(managedBean.getManagedBeanScope());
+
+ // try to get the managedbean class
+ try {
+ Class<?> managedBeanClass =
+ Thread.currentThread().getContextClassLoader()
+ .loadClass(managedBean.getManagedBeanClass());
+ postConstructMethods =
+ getMethodsWithAnnotation(managedBeanClass,
+ Annotations.POST_CONSTRUCT);
+ preDestroyMethods =
+ getMethodsWithAnnotation(managedBeanClass,
+ Annotations.PRE_DESTROY);
+ } catch (ClassNotFoundException cnfe) {
+ throw new FacesException(cnfe);
+ }
}
-
+
+ public Method[] getPostConstructMethods() {
+ return postConstructMethods;
+ }
+
+ public Method[] getPreDestroyMethods() {
+ return preDestroyMethods;
+ }
+
private Scope getScopeFromString(String scopeString) {
Scope result = Scope.NONE;
if (null != scopeString) {
@@ -183,8 +238,8 @@
public Map<String,ManagedBeanFactory> getManagedBeanFactoryMap() {
if (null == managedBeanFactoryMap) {
- if (logger.isLoggable(Level.INFO)) {
- logger.info("Contract violation: ManagedBeanFactory must be initialized with managedBeanFactoryMap after instantiation.");
+ if (LOGGER.isLoggable(Level.INFO)) {
+ LOGGER.info("Contract violation: ManagedBeanFactory must be initialized with managedBeanFactoryMap after instantiation.");
}
}
@@ -236,8 +291,8 @@
}
if ( beanList.contains(managedBean.getManagedBeanName())) {
- if ( logger.isLoggable(Level.WARNING)) {
- logger.warning("Possible cyclic reference to managedBean " +
+ if ( LOGGER.isLoggable(Level.WARNING)) {
+ LOGGER.warning("Possible cyclic reference to managedBean " +
managedBean.getManagedBeanName() + " ");
}
Object[] obj = new Object[1];
@@ -451,8 +506,8 @@
int len = 0;
if (0 == (len = valuesFromConfig.length)) {
- if (logger.isLoggable(Level.FINE)) {
- logger.fine("zero length array");
+ if (LOGGER.isLoggable(Level.FINE)) {
+ LOGGER.fine("zero length array");
}
return null;
}
@@ -500,8 +555,8 @@
strValue = null;
if (null == mapEntries || 0 == valuesFromConfig.length) {
- if (logger.isLoggable(Level.FINE)) {
- logger.fine("null or zero length array");
+ if (LOGGER.isLoggable(Level.FINE)) {
+ LOGGER.fine("null or zero length array");
}
return;
}
@@ -1083,6 +1138,41 @@
}
}
return result;
+ }
+
+ /**
+ * Returns a List of Methods on the instance referenced by argument
+ * <code>obj</code> that are annotated with the annotation
+ * referenced by argument <code>annoClass</code>. If none are
+ * found, returns the empty list.
+ *
+ * @param clazz the class for which to inspect for annotated methods
+ *_at_param annotation the <code>Annotation</code> of interest
+ */
+ private static Method[] getMethodsWithAnnotation(Class clazz,
+ Annotations annotation) {
+ List<Method> list = null;
+ if (null != clazz) {
+ Class<? extends Annotation> annoClass = annotation.getAnnotationClass();
+ if (annoClass == null) {
+ return EMPTY_METHODS;
+ }
+
+ Method[] methods = clazz.getMethods();
+
+ for (Method method : methods) {
+ if (null != method.getAnnotation(annoClass)) {
+ if (null == list) {
+ list = new ArrayList<Method>();
+ }
+ list.add(method);
+ }
+ }
+ }
+ if (null == list) {
+ return EMPTY_METHODS;
+ }
+ return list.toArray(new Method[list.size()]);
}
Index: jsf-ri/src/com/sun/faces/el/ImplicitObjectELResolverForJsp.java
===================================================================
RCS file: /cvs/javaserverfaces-sources/jsf-ri/src/com/sun/faces/el/ImplicitObjectELResolverForJsp.java,v
retrieving revision 1.7
diff -u -r1.7 ImplicitObjectELResolverForJsp.java
--- jsf-ri/src/com/sun/faces/el/ImplicitObjectELResolverForJsp.java 11 Jan 2006 15:28:05 -0000 1.7
+++ jsf-ri/src/com/sun/faces/el/ImplicitObjectELResolverForJsp.java 12 Jan 2006 22:55:03 -0000
@@ -127,10 +127,10 @@
switch (index) {
case FACES_CONTEXT:
throw new PropertyNotWritableException(MessageUtils.getExceptionMessageString
- (MessageUtils.OBJECT_IS_READONLY, new String[]{"facesContext"}));
+ (MessageUtils.OBJECT_IS_READONLY, "facesContext"));
case VIEW:
throw new PropertyNotWritableException(MessageUtils.getExceptionMessageString
- (MessageUtils.OBJECT_IS_READONLY, new String[]{"view"}));
+ (MessageUtils.OBJECT_IS_READONLY, "view"));
default:
}
}
Index: jsf-ri/src/com/sun/faces/spi/ManagedBeanFactory.java
===================================================================
RCS file: /cvs/javaserverfaces-sources/jsf-ri/src/com/sun/faces/spi/ManagedBeanFactory.java,v
retrieving revision 1.1
diff -u -r1.1 ManagedBeanFactory.java
--- jsf-ri/src/com/sun/faces/spi/ManagedBeanFactory.java 24 Aug 2005 16:13:34 -0000 1.1
+++ jsf-ri/src/com/sun/faces/spi/ManagedBeanFactory.java 12 Jan 2006 22:55:03 -0000
@@ -31,6 +31,8 @@
import com.sun.faces.config.beans.ManagedBeanBean;
import java.util.Map;
+import java.lang.reflect.Method;
+
import javax.faces.context.FacesContext;
/**
@@ -102,16 +104,16 @@
* into the managed bean creation lifecycle to provide a lifecycle
* notification scheme.</p>
*
- * @author edburns
+ * @author edburns, rlubke
*/
-public abstract class ManagedBeanFactory extends Object {
+public abstract class ManagedBeanFactory {
public enum Scope {
NONE, REQUEST, SESSION, APPLICATION
}
/**
- * <p>Return the {_at_link #Scope} of the managed-bean created by this
+ * <p>Return the {_at_link Scope} of the managed-bean created by this
* factory.</p>
*/
@@ -157,5 +159,23 @@
*/
public abstract Map<String, ManagedBeanFactory> getManagedBeanFactoryMap();
+
+ /**
+ * Return all methods of this ManageBean that are marked with
+ * the <code>PostConstruct</code> annotation.
+ *
+ * @return all <code>PostConstruct</code> methods or a zero-length
+ * array if no such methods are found.
+ */
+ public abstract Method[] getPostConstructMethods();
+
+ /**
+ * Return all methods of this ManageBean that are marked with
+ * the <code>PreDestroy</code> annotation.
+ *
+ * @return all <code>PostDestroy</code> methods or a zero-length
+ * array if no such methods are found.
+ */
+ public abstract Method[] getPreDestroyMethods();
}
Index: jsf-ri/src/com/sun/faces/spi/ManagedBeanFactoryWrapper.java
===================================================================
RCS file: /cvs/javaserverfaces-sources/jsf-ri/src/com/sun/faces/spi/ManagedBeanFactoryWrapper.java,v
retrieving revision 1.1
diff -u -r1.1 ManagedBeanFactoryWrapper.java
--- jsf-ri/src/com/sun/faces/spi/ManagedBeanFactoryWrapper.java 24 Aug 2005 16:13:34 -0000 1.1
+++ jsf-ri/src/com/sun/faces/spi/ManagedBeanFactoryWrapper.java 12 Jan 2006 22:55:03 -0000
@@ -31,6 +31,8 @@
import com.sun.faces.config.beans.ManagedBeanBean;
import java.util.Map;
+import java.lang.reflect.Method;
+
import javax.faces.context.FacesContext;
/**
@@ -41,7 +43,7 @@
* <code>ManagedBeanFactory</code> argument and stores it as an ivar,
* returning it from the {_at_link #getWrapped} method.</p>
*
- * @author edburns
+ * @author edburns, rlubke
*/
public abstract class ManagedBeanFactoryWrapper extends ManagedBeanFactory {
@@ -81,7 +83,7 @@
}
/**
- * @see ManagedBeanFactory#setManagedFactoryMap
+ * @see ManagedBeanFactory#setManagedBeanFactoryMap(java.util.Map<java.lang.String,com.sun.faces.spi.ManagedBeanFactory>)
*/
public void setManagedBeanFactoryMap(Map<String, ManagedBeanFactory> others) {
@@ -89,11 +91,25 @@
}
/**
- * @see ManagedBeanFactory#getManagedFactoryMap
+ * @see ManagedBeanFactory#getManagedBeanFactoryMap()
*/
public Map<String, ManagedBeanFactory> getManagedBeanFactoryMap() {
return getWrapped().getManagedBeanFactoryMap();
+ }
+
+ /**
+ * @see com.sun.faces.spi.ManagedBeanFactory#getPostConstructMethods()
+ */
+ public Method[] getPostConstructMethods() {
+ return getWrapped().getPostConstructMethods();
+ }
+
+ /**
+ * @see com.sun.faces.spi.ManagedBeanFactory#getPreDestroyMethods()
+ */
+ public Method[] getPreDestroyMethods() {
+ return getWrapped().getPreDestroyMethods();
}
Index: jsf-ri/src/com/sun/faces/util/MessageUtils.java
===================================================================
RCS file: /cvs/javaserverfaces-sources/jsf-ri/src/com/sun/faces/util/MessageUtils.java,v
retrieving revision 1.1
diff -u -r1.1 MessageUtils.java
--- jsf-ri/src/com/sun/faces/util/MessageUtils.java 11 Jan 2006 15:28:14 -0000 1.1
+++ jsf-ri/src/com/sun/faces/util/MessageUtils.java 12 Jan 2006 22:55:03 -0000
@@ -226,22 +226,7 @@
// ---------------------------------------------------------- Public Methods
-
-
- /**
- * <p>Creates a new <code>FacesMessage</code> instance using the
- * specified #messageId.</p>
- *
- * @param messageId the message ID
- * @return a new <code>FacesMessage</code> based on the provided
- * <code>messageId</code>
- */
- public static synchronized FacesMessage getExceptionMessage(
- String messageId) {
-
- return getExceptionMessage(messageId, null);
-
- }
+
/**
* <p>Creates a new <code>FacesMessage</code> instance using the
@@ -254,27 +239,11 @@
*/
public static synchronized FacesMessage getExceptionMessage(
String messageId,
- Object[] params) {
+ Object... params) {
return MessageFactory.getMessage(messageId, params);
- }
-
-
- /**
- * <p>Returns the localized message for the specified
- * #messageId.</p>
- *
- * @param messageId the message ID
- * @return the localized message for the specified
- * <code>messageId</code>
- */
- public static synchronized String getExceptionMessageString(
- String messageId) {
-
- return getExceptionMessageString(messageId, null);
-
- }
+ }
/**
@@ -288,7 +257,7 @@
*/
public static synchronized String getExceptionMessageString(
String messageId,
- Object[] params) {
+ Object... params) {
String result = null;
Index: jsf-ri/src/com/sun/faces/util/Util.java
===================================================================
RCS file: /cvs/javaserverfaces-sources/jsf-ri/src/com/sun/faces/util/Util.java,v
retrieving revision 1.182
diff -u -r1.182 Util.java
--- jsf-ri/src/com/sun/faces/util/Util.java 11 Jan 2006 15:28:14 -0000 1.182
+++ jsf-ri/src/com/sun/faces/util/Util.java 12 Jan 2006 22:55:03 -0000
@@ -31,10 +31,9 @@
package com.sun.faces.util;
-import com.sun.faces.RIConstants;
-import com.sun.faces.renderkit.RenderKitImpl;
-import java.beans.FeatureDescriptor;
-
+import javax.el.ELContext;
+import javax.el.ELResolver;
+import javax.el.ValueExpression;
import javax.faces.FacesException;
import javax.faces.FactoryFinder;
import javax.faces.application.Application;
@@ -42,39 +41,38 @@
import javax.faces.application.StateManager;
import javax.faces.application.ViewHandler;
import javax.faces.component.UIComponent;
-import javax.faces.component.UISelectItem;
-import javax.faces.component.UISelectItems;
+import javax.faces.component.UIViewRoot;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.faces.context.FacesContextFactory;
import javax.faces.convert.Converter;
import javax.faces.el.ReferenceSyntaxException;
-import javax.el.ValueExpression;
-import javax.el.ELContext;
+import javax.faces.el.ValueBinding;
import javax.faces.lifecycle.LifecycleFactory;
-import javax.faces.model.SelectItem;
import javax.faces.render.RenderKit;
import javax.faces.render.RenderKitFactory;
import javax.servlet.ServletContext;
-import javax.faces.el.ValueBinding;
import javax.servlet.jsp.jstl.fmt.LocalizationContext;
+import java.beans.FeatureDescriptor;
+import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
-import java.lang.reflect.Method;
import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
import java.util.ArrayList;
-import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.StringTokenizer;
-import java.util.logging.Logger;
+import java.util.Arrays;
+import java.util.HashMap;
import java.util.logging.Level;
-import javax.el.ELResolver;
-import javax.faces.component.UIViewRoot;
+import java.util.logging.Logger;
+import com.sun.faces.RIConstants;
+import com.sun.faces.renderkit.RenderKitImpl;
import com.sun.faces.spi.ManagedBeanFactory.Scope;
/**
@@ -108,7 +106,7 @@
public static final String APPLICATION_LOGGER = ".application";
public static final String CONTEXT_LOGGER = ".context";
public static final String CONFIG_LOGGER = ".config";
- public static final String LIFECYCLE_LOGGER = ".lifecycle";
+ public static final String LIFECYCLE_LOGGER = ".lifecycle";
/**
* Flag that, when true, enables special behavior in the RI to enable
@@ -795,7 +793,7 @@
* <code>sessionScope.TestBean.one</code> should return "session"
* as the scope.</p>
*
- * @param ValueExpression the expression
+ * @param valueBinding the expression
*
* @param outString an allocated String Array into which we put the
* first segment.
@@ -1043,6 +1041,7 @@
// Look for the presence of the method by method name.
Class c = instance.getClass();
Method[] methods = c.getDeclaredMethods();
+
for (int i = 0; i < methods.length; i++) {
if (methods[i].getName().equals(methodName)) {
result = true;
@@ -1051,38 +1050,5 @@
}
return result;
}
-
- /**
- * Returns a List of Methods on the instance referenced by argument
- * <code>obj</code> that are annotated with the annotation
- * referenced by argument <code>annoClass</code>. If none are
- * found, returns the empty list.
- *
- * @param the instance for which to inspect for annotated methods
- *
- * @param annoClass the Class of annotation to look for
- */
- public static List<Method> getMethodsWithAnnotation(Object obj, Class annoClass) {
- List<Method> list = null;
- Method [] methods = null;
- if (null != obj) {
- Class objClass = obj.getClass();
- methods = objClass.getMethods();
-
- for (int i = 0; i < methods.length; i++) {
- if (null != methods[i].getAnnotation(annoClass)) {
- if (null == list) {
- list = new ArrayList<Method>();
- }
- list.add(methods[i]);
- }
- }
- }
- if (null == list) {
- list = Collections.EMPTY_LIST;
- }
- return list;
- }
-
} // end of class Util
Index: jsf-ri/src/javax/faces/Messages.properties
===================================================================
RCS file: /cvs/javaserverfaces-sources/jsf-ri/src/javax/faces/Messages.properties,v
retrieving revision 1.35
diff -u -r1.35 Messages.properties
--- jsf-ri/src/javax/faces/Messages.properties 22 Nov 2005 18:48:35 -0000 1.35
+++ jsf-ri/src/javax/faces/Messages.properties 12 Jan 2006 22:55:03 -0000
@@ -183,7 +183,7 @@
com.sun.faces.VALIDATOR_NOT_FOUND_ERROR=Validator Not Found for identifier: ''{0}''.
-com.sun.faces.CYCLIC_REFERENCE_ERROR=Possible cycle reference to managed bean "{0}"
+com.sun.faces.CYCLIC_REFERENCE_ERROR=Possible cyclic reference to managed bean "{0}"
com.sun.faces.OBJECT_IS_READONLY="{0} object is read only"
com.sun.faces.APPLICATION_INIT_COMPLETE_ERROR_ID=ELResolvers cannot be added after the application initialization is complete.
com.sun.faces.INCORRECT_JSP_VERSION=Incorrect JSP version found, method ''{0}'' does not exist.
Index: jsf-ri/src/javax/faces/Messages_de.properties
===================================================================
RCS file: /cvs/javaserverfaces-sources/jsf-ri/src/javax/faces/Messages_de.properties,v
retrieving revision 1.31
diff -u -r1.31 Messages_de.properties
--- jsf-ri/src/javax/faces/Messages_de.properties 22 Nov 2005 18:48:36 -0000 1.31
+++ jsf-ri/src/javax/faces/Messages_de.properties 12 Jan 2006 22:55:03 -0000
@@ -165,7 +165,7 @@
com.sun.faces.ASSERTION_FAILED=Assertion-Fehler
com.sun.faces.OBJECT_CREATION_ERROR=One or more confgured application objects could not be created. Check your web application logs for details.
-com.sun.faces.CYCLIC_REFERENCE_ERROR=Possible cycle reference to managed bean "{0}"
+com.sun.faces.CYCLIC_REFERENCE_ERROR=Possible cyclic reference to managed bean "{0}"
com.sun.faces.OBJECT_IS_READONLY="{0} object is read only"
com.sun.faces.APPLICATION_INIT_COMPLETE_ERROR_ID=ELResolvers cannot be added after the application initialization is complete.
Index: jsf-ri/src/javax/faces/Messages_en.properties
===================================================================
RCS file: /cvs/javaserverfaces-sources/jsf-ri/src/javax/faces/Messages_en.properties,v
retrieving revision 1.4
diff -u -r1.4 Messages_en.properties
--- jsf-ri/src/javax/faces/Messages_en.properties 22 Nov 2005 18:48:36 -0000 1.4
+++ jsf-ri/src/javax/faces/Messages_en.properties 12 Jan 2006 22:55:03 -0000
@@ -183,7 +183,7 @@
com.sun.faces.VALIDATOR_NOT_FOUND_ERROR=Validator Not Found for identifier: ''{0}''.
-com.sun.faces.CYCLIC_REFERENCE_ERROR=Possible cycle reference to managed bean "{0}"
+com.sun.faces.CYCLIC_REFERENCE_ERROR=Possible cyclic reference to managed bean "{0}"
com.sun.faces.OBJECT_IS_READONLY="{0} object is read only"
com.sun.faces.APPLICATION_INIT_COMPLETE_ERROR_ID=ELResolvers cannot be added after the application initialization is complete.
com.sun.faces.INCORRECT_JSP_VERSION=Incorrect JSP version found, method ''{0}'' does not exist.
Index: jsf-ri/src/javax/faces/Messages_es.properties
===================================================================
RCS file: /cvs/javaserverfaces-sources/jsf-ri/src/javax/faces/Messages_es.properties,v
retrieving revision 1.31
diff -u -r1.31 Messages_es.properties
--- jsf-ri/src/javax/faces/Messages_es.properties 22 Nov 2005 18:48:36 -0000 1.31
+++ jsf-ri/src/javax/faces/Messages_es.properties 12 Jan 2006 22:55:03 -0000
@@ -165,7 +165,7 @@
com.sun.faces.ASSERTION_FAILED=Assertion Error
com.sun.faces.OBJECT_CREATION_ERROR=One or more confgured application objects could not be created. Check your web application logs for details.
-com.sun.faces.CYCLIC_REFERENCE_ERROR=Possible cycle reference to managed bean "{0}"
+com.sun.faces.CYCLIC_REFERENCE_ERROR=Possible cyclic reference to managed bean "{0}"
com.sun.faces.OBJECT_IS_READONLY="{0} object is read only"
com.sun.faces.APPLICATION_INIT_COMPLETE_ERROR_ID=ELResolvers cannot be added after the application initialization is complete.
Index: jsf-ri/src/javax/faces/Messages_fr.properties
===================================================================
RCS file: /cvs/javaserverfaces-sources/jsf-ri/src/javax/faces/Messages_fr.properties,v
retrieving revision 1.30
diff -u -r1.30 Messages_fr.properties
--- jsf-ri/src/javax/faces/Messages_fr.properties 22 Nov 2005 18:48:37 -0000 1.30
+++ jsf-ri/src/javax/faces/Messages_fr.properties 12 Jan 2006 22:55:03 -0000
@@ -164,7 +164,7 @@
com.sun.faces.ASSERTION_FAILED=Assertion Failed
com.sun.faces.OBJECT_CREATION_ERROR=One or more confgured application objects could not be created. Check your web application logs for details.
-com.sun.faces.CYCLIC_REFERENCE_ERROR=Possible cycle reference to managed bean "{0}"
+com.sun.faces.CYCLIC_REFERENCE_ERROR=Possible cyclic reference to managed bean "{0}"
com.sun.faces.OBJECT_IS_READONLY="{0} object is read only"
com.sun.faces.APPLICATION_INIT_COMPLETE_ERROR_ID=ELResolvers cannot be added after the application initialization is complete.
com.sun.faces.INCORRECT_JSP_VERSION=Incorrect JSP version found, method ''{0}'' does not exist.
Index: jsf-tools/template-src/MessageFactory.java
===================================================================
RCS file: /cvs/javaserverfaces-sources/jsf-tools/template-src/MessageFactory.java,v
retrieving revision 1.10
diff -u -r1.10 MessageFactory.java
--- jsf-tools/template-src/MessageFactory.java 22 Aug 2005 22:12:29 -0000 1.10
+++ jsf-tools/template-src/MessageFactory.java 12 Jan 2006 22:55:03 -0000
@@ -58,47 +58,17 @@
* <code>protection</code>.</p>
*/
-_at_protection@ class MessageFactory extends Object
-{
- //
- // Protected Constants
- //
-
- //
- // Class Variables
- //
-
- //
- // Instance Variables
- //
-
- // Attribute Instance Variables
-
- // Relationship Instance Variables
-
- //
- // Constructors and Initializers
- //
+_at_protection@ class MessageFactory {
private MessageFactory() {
}
-
- //
- // Class methods
- //
-
- //
- // General Methods
- //
-
+
/**
-
- * This version of getMessage() is used in the RI for localizing RI
- * specific messages.
-
- */
-
- @protection@ static FacesMessage getMessage(String messageId, Object params[]) {
+ * This version of getMessage() is used for localizing implementation
+ * specific messages.
+ */
+ @protection@ static FacesMessage getMessage(String messageId,
+ Object... params) {
Locale locale = null;
FacesContext context = FacesContext.getCurrentInstance();
// context.getViewRoot() may not have been initialized at this point.
@@ -111,79 +81,80 @@
locale = Locale.getDefault();
}
- return getMessage(locale, messageId, params);
+ return getMessage(locale, messageId, params);
}
- @protection@ static FacesMessage getMessage(Locale locale, String messageId,
- Object params[]) {
- FacesMessage result = null;
- String
- summary = null,
- detail = null,
- bundleName = null;
- ResourceBundle bundle = null;
-
- // see if we have a user-provided bundle
- if (null != (bundleName = getApplication().getMessageBundle())) {
- if (null !=
- (bundle =
- ResourceBundle.getBundle(bundleName, locale,
- getCurrentLoader(bundleName)))) {
- // see if we have a hit
- try {
- summary = bundle.getString(messageId);
+ @protection@ static FacesMessage getMessage(Locale locale,
+ String messageId,
+ Object... params) {
+ FacesMessage result = null;
+ String summary = null;
+ String detail = null;
+ String bundleName = null;
+ ResourceBundle bundle = null;
+
+ // see if we have a user-provided bundle
+ if (null != (bundleName = getApplication().getMessageBundle())) {
+ if (null !=
+ (bundle =
+ ResourceBundle.getBundle(bundleName, locale,
+ getCurrentLoader(bundleName)))) {
+ // see if we have a hit
+ try {
+ summary = bundle.getString(messageId);
detail = bundle.getString(messageId + "_detail");
- }
- catch (MissingResourceException e) {
- }
- }
- }
-
- // we couldn't find a summary in the user-provided bundle
- if (null == summary) {
- // see if we have a summary in the app provided bundle
- bundle = ResourceBundle.getBundle(FacesMessage.FACES_MESSAGES,
- locale,
- getCurrentLoader(bundleName));
- if (null == bundle) {
- throw new NullPointerException();
- }
- // see if we have a hit
- try {
- summary = bundle.getString(messageId);
+ }
+ catch (MissingResourceException e) {
+ }
+ }
+ }
+
+ // we couldn't find a summary in the user-provided bundle
+ if (null == summary) {
+ // see if we have a summary in the app provided bundle
+ bundle = ResourceBundle.getBundle(FacesMessage.FACES_MESSAGES,
+ locale,
+ getCurrentLoader(bundleName));
+ if (null == bundle) {
+ throw new NullPointerException();
+ }
+ // see if we have a hit
+ try {
+ summary = bundle.getString(messageId);
detail = bundle.getString(messageId + "_detail");
- }
- catch (MissingResourceException e) {
- }
- }
-
- // we couldn't find a summary anywhere! Return null
- if (null == summary) {
- return null;
- }
-
- if (null == summary || null == bundle) {
- throw new NullPointerException(" summary " + summary + " bundle " +
- bundle);
- }
- // At this point, we have a summary and a bundle.
- //
+ } catch (MissingResourceException e) {
+ }
+ }
+
+ // we couldn't find a summary anywhere! Return null
+ if (null == summary) {
+ return null;
+ }
+
+ if (null == summary || null == bundle) {
+ throw new NullPointerException(" summary "
+ + summary
+ + " bundle "
+ + bundle);
+ }
+ // At this point, we have a summary and a bundle.
return (new BindingFacesMessage(locale, summary, detail, params));
}
//
// Methods from MessageFactory
- //
- @protection@ static FacesMessage getMessage(FacesContext context, String messageId) {
- return getMessage(context, messageId, null);
- }
+ //
- @protection@ static FacesMessage getMessage(FacesContext context, String messageId,
- Object params[]) {
+ @protection@ static FacesMessage getMessage(FacesContext context,
+ String messageId,
+ Object... params) {
+
if (context == null || messageId == null ) {
- throw new NullPointerException(" context " + context + " messageId " +
- messageId);
+ throw new NullPointerException(" context "
+ + context
+ + " messageId "
+ + messageId);
}
Locale locale = null;
// viewRoot may not have been initialized at this point.
@@ -192,9 +163,11 @@
} else {
locale = Locale.getDefault();
}
- if (null == locale) {
- throw new NullPointerException(" locale " + locale);
- }
+
+ if (null == locale) {
+ throw new NullPointerException(" locale " + locale);
+ }
+
FacesMessage message = getMessage(locale, messageId, params);
if (message != null) {
return message;
@@ -202,35 +175,12 @@
locale = Locale.getDefault();
return (getMessage(locale, messageId, params));
}
-
- @protection@ static FacesMessage getMessage(FacesContext context, String messageId,
- Object param0) {
- return getMessage(context, messageId, new Object[]{param0});
- }
-
- @protection@ static FacesMessage getMessage(FacesContext context, String messageId,
- Object param0, Object param1) {
- return getMessage(context, messageId, new Object[]{param0, param1});
- }
-
- @protection@ static FacesMessage getMessage(FacesContext context, String messageId,
- Object param0, Object param1,
- Object param2) {
- return getMessage(context, messageId,
- new Object[]{param0, param1, param2});
- }
-
- @protection@ static FacesMessage getMessage(FacesContext context, String messageId,
- Object param0, Object param1,
- Object param2, Object param3) {
- return getMessage(context, messageId,
- new Object[]{param0, param1, param2, param3});
- }
+
// Gets the "label" property from the component.
-
@protection@ static Object getLabel(FacesContext context,
- UIComponent component) {
+ UIComponent component) {
+
Object o = component.getAttributes().get("label");
if (o == null || (o instanceof String && ((String) o).length() == 0)) {
o = component.getValueBinding("label");
@@ -243,22 +193,22 @@
}
protected static Application getApplication() {
- FacesContext context = FacesContext.getCurrentInstance();
- if (context != null) {
- return (FacesContext.getCurrentInstance().getApplication());
- }
- ApplicationFactory afactory = (ApplicationFactory)
- FactoryFinder.getFactory(FactoryFinder.APPLICATION_FACTORY);
- return (afactory.getApplication());
+ FacesContext context = FacesContext.getCurrentInstance();
+ if (context != null) {
+ return (FacesContext.getCurrentInstance().getApplication());
+ }
+ ApplicationFactory afactory = (ApplicationFactory)
+ FactoryFinder.getFactory(FactoryFinder.APPLICATION_FACTORY);
+ return (afactory.getApplication());
}
protected static ClassLoader getCurrentLoader(Object fallbackClass) {
ClassLoader loader =
- Thread.currentThread().getContextClassLoader();
- if (loader == null) {
- loader = fallbackClass.getClass().getClassLoader();
- }
- return loader;
+ Thread.currentThread().getContextClassLoader();
+ if (loader == null) {
+ loader = fallbackClass.getClass().getClassLoader();
+ }
+ return loader;
}
/**
@@ -347,4 +297,5 @@
private Object[] parameters;
private Object[] resolvedParameters;
}
+
} // end of class MessageFactory