Anonymous avatar Anonymous committed ef192e6

WW-1506
- Sitemesh plugin's struts-plugin.xml uses incorrect filter for both freemarker and velocity

git-svn-id: http://svn.opensymphony.com/svn/xwork/trunk@1196 e221344d-f017-0410-9bd5-d282ab1896d7

Comments (0)

Files changed (8)

src/java/com/opensymphony/xwork2/config/ConfigurationProvider.java

  */
 package com.opensymphony.xwork2.config;
 
-import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Properties;
 
-import com.opensymphony.xwork2.inject.Container;
 import com.opensymphony.xwork2.inject.ContainerBuilder;
 
 
     
     public void init(Configuration configuration) throws ConfigurationException;
     
-    public void register(ContainerBuilder builder, Properties props) throws ConfigurationException;
+    public void register(ContainerBuilder builder, Properties props, List<Class<?>> ignoreFailureStaticInjection) throws ConfigurationException;
     
     public void loadPackages() throws ConfigurationException;
     

src/java/com/opensymphony/xwork2/config/impl/DefaultConfiguration.java

 
         ContainerProperties props = new ContainerProperties();
         ContainerBuilder builder = new ContainerBuilder();
+        List<Class<?>> ignoreFailureStaticInjection = new ArrayList<Class<?>>();
+        ignoreFailureStaticInjection.add(Object.class);
         for (ConfigurationProvider configurationProvider : providers)
         {
             configurationProvider.init(this);
-            configurationProvider.register(builder, props);
+            configurationProvider.register(builder, props, ignoreFailureStaticInjection);
         }
         props.setConstants(builder);
         
             public Object create(Context context) throws Exception {
                 return DefaultConfiguration.this;
             }
-            
         });
         
-        container = builder.create(false);
+        container = builder.create(false, ignoreFailureStaticInjection);
         objectFactory = container.getInstance(ObjectFactory.class);
         
         for (ConfigurationProvider configurationProvider : providers)

src/java/com/opensymphony/xwork2/config/providers/XmlConfigurationProvider.java

         } 
     }
     
-    public void register(ContainerBuilder containerBuilder, Properties props) throws ConfigurationException {
+    public void register(ContainerBuilder containerBuilder, Properties props, List<Class<?>> ignoreFailureStaticInjection) throws ConfigurationException {
         LOG.info("Parsing configuration file ["+configFileName+"]");
         Map<String,Node> loadedBeans = new HashMap<String,Node>();
         for (Document doc : documents) {
                             }
                             if ("true".equals(onlyStatic)) {
                                 containerBuilder.injectStatics(cimpl);
+                                if (optional) {
+                                	ignoreFailureStaticInjection.add(cimpl);
+                                }
                             } else {
                                 if (containerBuilder.contains(ctype, name)) {
                                     Location loc = LocationUtils.getLocation(loadedBeans.get(ctype.getName()+name));

src/java/com/opensymphony/xwork2/inject/ContainerBuilder.java

 import java.lang.reflect.Member;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.LinkedHashMap;
 import java.util.List;
    *  development.
    * @throws IllegalStateException if called more than once
    */
+  @SuppressWarnings("unchecked")
   public Container create(boolean loadSingletons) {
+	  return create(loadSingletons,  Collections.EMPTY_LIST);
+  }
+  
+  public Container create(boolean loadSingletons, List<Class<?>> ignoreFailureStaticInjection) {
     ensureNotCreated();
     created = true;
     final ContainerImpl container = new ContainerImpl(
         }
       });
     }
-    container.injectStatics(staticInjections);
+    container.injectStatics(staticInjections, ignoreFailureStaticInjection);
     return container;
   }
 

src/java/com/opensymphony/xwork2/inject/ContainerImpl.java

 import java.lang.reflect.Modifier;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
 /**
  * Default {@link Container} implementation.
  *
  * @author crazybob@google.com (Bob Lee)
  */
 class ContainerImpl implements Container {
+	
+   private static final Log LOG = LogFactory.getLog(ContainerImpl.class);
 
   final Map<Key<?>, InternalFactory<?>> factories;
 
     addInjectorsForMethods(clazz.getDeclaredMethods(), false, injectors);
   }
 
+  @SuppressWarnings("unchecked")
   void injectStatics(List<Class<?>> staticInjections) {
+	  injectStatics(staticInjections, Collections.EMPTY_LIST);
+  }
+  
+  void injectStatics(List<Class<?>> staticInjections, List<Class<?>> ignoreFailureStaticInject) {
     final List<Injector> injectors = new ArrayList<Injector>();
 
     for (Class<?> clazz : staticInjections) {
-      addInjectorsForFields(clazz.getDeclaredFields(), true, injectors);
-      addInjectorsForMethods(clazz.getDeclaredMethods(), true, injectors);
+      boolean ignoreFailureDuringStaticInjection = false;
+      if (ignoreFailureStaticInject.contains(clazz)) {
+    		  ignoreFailureDuringStaticInjection = true;
+      }
+      addInjectorsForFields(clazz.getDeclaredFields(), true, injectors, ignoreFailureDuringStaticInjection);
+      addInjectorsForMethods(clazz.getDeclaredMethods(), true, injectors, ignoreFailureDuringStaticInjection);
     }
 
     callInContext(new ContextualCallable<Void>() {
     });
   }
 
+  void addInjectorsForMethods(Method[] methods, boolean statics, 
+		  List<Injector> injectors) {
+	  addInjectorsForMethods(methods, statics, injectors, false);
+  }
+  
   void addInjectorsForMethods(Method[] methods, boolean statics,
-      List<Injector> injectors) {
+      List<Injector> injectors, final boolean ignoreFailureStaticDuringInject) {
     addInjectorsForMembers(Arrays.asList(methods), statics, injectors,
         new InjectorFactory<Method>() {
           public Injector create(ContainerImpl container, Method method,
               String name) throws MissingDependencyException {
-            return new MethodInjector(container, method, name);
+            return new MethodInjector(container, method, name, ignoreFailureStaticDuringInject);
           }
         });
   }
+  
+  @SuppressWarnings("unchecked")
+  void addInjectorsForFields(Field[] fields, boolean statics, 
+		  List<Injector> injectors) {
+	  addInjectorsForFields(fields, statics, injectors, false);
+  }
 
   void addInjectorsForFields(Field[] fields, boolean statics,
-      List<Injector> injectors) {
+      List<Injector> injectors, final boolean  ignoreFailureStaticDuringInject) {
     addInjectorsForMembers(Arrays.asList(fields), statics, injectors,
         new InjectorFactory<Field>() {
           public Injector create(ContainerImpl container, Field field,
               String name) throws MissingDependencyException {
-            return new FieldInjector(container, field, name);
+            return new FieldInjector(container, field, name, ignoreFailureStaticDuringInject);
           }
         });
   }
     final Field field;
     final InternalFactory<?> factory;
     final ExternalContext<?> externalContext;
+    final boolean ignoreFailureOnStaticInject;
 
-    public FieldInjector(ContainerImpl container, Field field, String name)
+    public FieldInjector(ContainerImpl container, Field field, String name) 
+    	throws MissingDependencyException {
+    		this(container, field, name, false);
+    }
+    
+    public FieldInjector(ContainerImpl container, Field field, String name, 
+    		boolean ignoreFailureOnStaticInject)
         throws MissingDependencyException {
       this.field = field;
+      this.ignoreFailureOnStaticInject = ignoreFailureOnStaticInject;
       field.setAccessible(true);
 
       Key<?> key = Key.newInstance(field.getType(), name);
       context.setExternalContext(externalContext);
       try {
         field.set(o, factory.create(context));
-      } catch (IllegalAccessException e) {
-        throw new AssertionError(e);
-      } finally {
+      } catch (Throwable e) {
+    	  if (ignoreFailureOnStaticInject) {
+    		  	LOG.info("failed to inject an optional static field ["+field+"]");
+    	  }
+    	  else {
+    	  		throw new AssertionError(e);
+      	  }
+      }
+      finally {
         context.setExternalContext(previous);
       }
     }
 
     final Method method;
     final ParameterInjector<?>[] parameterInjectors;
-
-    public MethodInjector(ContainerImpl container, Method method, String name)
+    final boolean ignoreFailureStaticDuringInject;
+    
+    public MethodInjector(ContainerImpl container, Method method, String name) 
+    	throws MissingDependencyException {
+    	this(container, method, name, false);
+    }
+    
+    public MethodInjector(ContainerImpl container, Method method, String name, boolean ignoreFailureStaticDuringInject)
         throws MissingDependencyException {
       this.method = method;
+      this.ignoreFailureStaticDuringInject = ignoreFailureStaticDuringInject;
       method.setAccessible(true);
 
       Class<?>[] parameterTypes = method.getParameterTypes();
     public void inject(InternalContext context, Object o) {
       try {
         method.invoke(o, getParameters(method, context, parameterInjectors));
-      } catch (Exception e) {
-        throw new RuntimeException(e);
+      } catch (Throwable e) {
+    	  if (ignoreFailureStaticDuringInject) {
+    		  LOG.info("failed to inject static method ["+method+"]");
+    	  }
+    	  else {
+    		  throw new RuntimeException(e);
+    	  }
       }
     }
   }

src/test/com/opensymphony/xwork2/ActionNestingTest.java

 import com.opensymphony.xwork2.util.ValueStackFactory;
 
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 import java.util.Properties;
 
             this.configuration = configuration;
         }
 
-        public void register(ContainerBuilder builder, Properties props) {
+        public void register(ContainerBuilder builder, Properties props, List<Class<?>> ignoreFailureStaticInjection) {
             builder.factory(ObjectFactory.class);
             builder.factory(ActionProxyFactory.class, DefaultActionProxyFactory.class);
         }

src/test/com/opensymphony/xwork2/config/providers/MockConfigurationProvider.java

         return false;
     }
 
-    public void register(ContainerBuilder builder, Properties props) throws ConfigurationException {
-        // TODO Auto-generated method stub
-        
+    public void register(ContainerBuilder builder, Properties props, List<Class<?>> ignoreFailureStaticInjection) throws ConfigurationException {
+    	// do nothing
     }
 }

src/test/com/opensymphony/xwork2/interceptor/PreResultListenerTest.java

 import junit.framework.TestCase;
 
 import java.util.HashMap;
+import java.util.List;
 import java.util.Properties;
 
 
                 return false;
             }
 
-            public void register(ContainerBuilder builder, Properties props) throws ConfigurationException {
+            public void register(ContainerBuilder builder, Properties props, List<Class<?>> ignoreFailureStaticInjection) throws ConfigurationException {
                 // TODO Auto-generated method stub
                 
             }
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.