Author: lukaszlenart
Date: Fri Apr  6 08:17:00 2012
New Revision: 1310221

URL: http://svn.apache.org/viewvc?rev=1310221&view=rev
Log:
WW-3174 adds logic to support dynamic attributes in tags used with FreeMarker 
templates

Added:
    
struts/struts2/trunk/core/src/test/resources/org/apache/struts2/views/freemarker/dynaAttributes.ftl
      - copied, changed from r1310204, 
struts/struts2/trunk/core/src/test/resources/org/apache/struts2/views/freemarker/callActionFreeMarker.ftl
Modified:
    
struts/struts2/trunk/core/src/main/java/org/apache/struts2/components/UIBean.java
    
struts/struts2/trunk/core/src/test/java/org/apache/struts2/views/freemarker/FreeMarkerResultTest.java
    struts/struts2/trunk/core/src/test/resources/struts.xml

Modified: 
struts/struts2/trunk/core/src/main/java/org/apache/struts2/components/UIBean.java
URL: 
http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/main/java/org/apache/struts2/components/UIBean.java?rev=1310221&r1=1310220&r2=1310221&view=diff
==============================================================================
--- 
struts/struts2/trunk/core/src/main/java/org/apache/struts2/components/UIBean.java
 (original)
+++ 
struts/struts2/trunk/core/src/main/java/org/apache/struts2/components/UIBean.java
 Fri Apr  6 08:17:00 2012
@@ -21,31 +21,34 @@
 
 package org.apache.struts2.components;
 
-import java.io.Writer;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
+import com.opensymphony.xwork2.config.ConfigurationException;
+import com.opensymphony.xwork2.inject.Inject;
+import com.opensymphony.xwork2.util.ValueStack;
+import com.opensymphony.xwork2.util.logging.Logger;
+import com.opensymphony.xwork2.util.logging.LoggerFactory;
 import org.apache.struts2.StrutsConstants;
 import org.apache.struts2.StrutsException;
-import org.apache.struts2.util.TextProviderHelper;
 import org.apache.struts2.components.template.Template;
 import org.apache.struts2.components.template.TemplateEngine;
 import org.apache.struts2.components.template.TemplateEngineManager;
 import org.apache.struts2.components.template.TemplateRenderingContext;
+import org.apache.struts2.util.TextProviderHelper;
 import org.apache.struts2.views.annotations.StrutsTagAttribute;
 import org.apache.struts2.views.util.ContextUtil;
 
-import com.opensymphony.xwork2.config.ConfigurationException;
-import com.opensymphony.xwork2.inject.Inject;
-import com.opensymphony.xwork2.util.ValueStack;
-import com.opensymphony.xwork2.util.logging.Logger;
-import com.opensymphony.xwork2.util.logging.LoggerFactory;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.Writer;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
 
 /**
  * UIBean is the standard superclass of all Struts UI componentns.
@@ -491,6 +494,9 @@ public abstract class UIBean extends Com
     protected String defaultUITheme;
     protected TemplateEngineManager templateEngineManager;
 
+    // dynamic attributes support for tags used with FreeMarker templates
+    protected static Map<Class, Set<String>> standardAttributesMap = new 
ConcurrentHashMap<Class, Set<String>>();
+
     @Inject(StrutsConstants.STRUTS_UI_TEMPLATEDIR)
     public void setDefaultTemplateDir(String dir) {
         this.defaultTemplateDir = dir;
@@ -1195,7 +1201,48 @@ public abstract class UIBean extends Com
         this.tooltipIconPath = tooltipIconPath;
     }
 
-    public void setDynamicAttributes(Map<String,Object> dynamicAttributes) {
-        this.dynamicAttributes = dynamicAttributes;
-    }
+       public void setDynamicAttributes(Map<String, Object> dynamicAttributes) 
{
+               this.dynamicAttributes.putAll(dynamicAttributes);
 }
+
+       @Override
+       /**
+        * supports dynamic attributes for freemarker ui tags
+        * @see https://issues.apache.org/jira/browse/WW-3174
+        */
+       public void copyParams(Map params) {
+               super.copyParams(params);
+               Set<String> standardAttributes = getStandardAttributes();
+        for (Object o : params.entrySet()) {
+            Map.Entry entry = (Map.Entry) o;
+            String key = (String) entry.getKey();
+            if (!key.equals("dynamicAttributes") && 
!standardAttributes.contains(key)){
+                dynamicAttributes.put(key, entry.getValue());
+            }
+        }
+       }
+       
+       protected Set<String> getStandardAttributes() {
+        Class clz = getClass();
+        Set<String> standardAttributes = standardAttributesMap.get(clz);
+        if (standardAttributes == null) {
+            standardAttributes = new HashSet<String>();
+            standardAttributesMap.put(clz, standardAttributes);
+            while (clz != null) {
+                for (Field f : clz.getDeclaredFields()) {
+                    if (Modifier.isProtected(f.getModifiers())
+                            && (f.getType().equals(String.class) || 
clz.equals(ListUIBean.class)
+                            && f.getName().equals("list")))
+                        standardAttributes.add(f.getName());
+                }
+                if (clz.equals(UIBean.class)) {
+                    break;
+                } else {
+                    clz = clz.getSuperclass();
+                }
+            }
+        }
+               return standardAttributes;
+       }
+
+}
\ No newline at end of file

Modified: 
struts/struts2/trunk/core/src/test/java/org/apache/struts2/views/freemarker/FreeMarkerResultTest.java
URL: 
http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/test/java/org/apache/struts2/views/freemarker/FreeMarkerResultTest.java?rev=1310221&r1=1310220&r2=1310221&view=diff
==============================================================================
--- 
struts/struts2/trunk/core/src/test/java/org/apache/struts2/views/freemarker/FreeMarkerResultTest.java
 (original)
+++ 
struts/struts2/trunk/core/src/test/java/org/apache/struts2/views/freemarker/FreeMarkerResultTest.java
 Fri Apr  6 08:17:00 2012
@@ -21,12 +21,12 @@
 
 package org.apache.struts2.views.freemarker;
 
-import java.io.File;
-import java.io.PrintWriter;
-import java.io.StringWriter;
-
-import junit.framework.TestCase;
-
+import com.opensymphony.xwork2.ActionContext;
+import com.opensymphony.xwork2.mock.MockActionInvocation;
+import com.opensymphony.xwork2.util.ClassLoaderUtil;
+import com.opensymphony.xwork2.util.ValueStack;
+import freemarker.template.Configuration;
+import freemarker.template.TemplateExceptionHandler;
 import org.apache.struts2.ServletActionContext;
 import org.apache.struts2.StrutsStatics;
 import org.apache.struts2.StrutsTestCase;
@@ -35,20 +35,13 @@ import org.apache.struts2.dispatcher.map
 import org.apache.struts2.dispatcher.mapper.ActionMapping;
 import org.apache.struts2.views.jsp.StrutsMockHttpServletResponse;
 import org.apache.struts2.views.jsp.StrutsMockServletContext;
-import org.springframework.mock.web.MockHttpServletRequest;
-import org.springframework.mock.web.MockServletContext;
-import org.springframework.core.io.DefaultResourceLoader;
 import org.easymock.EasyMock;
-
-import com.opensymphony.xwork2.ActionContext;
-import com.opensymphony.xwork2.mock.MockActionInvocation;
-import com.opensymphony.xwork2.util.ValueStack;
-import com.opensymphony.xwork2.util.ValueStackFactory;
+import org.springframework.mock.web.MockHttpServletRequest;
 
 import javax.servlet.ServletContext;
-
-import freemarker.template.TemplateExceptionHandler;
-import freemarker.template.Configuration;
+import java.io.File;
+import java.io.PrintWriter;
+import java.io.StringWriter;
 
 /**
  * Test case for FreeMarkerResult.
@@ -184,6 +177,46 @@ public class FreeMarkerResultTest extend
         assertEquals("text/xml", response.getContentType());
     }
 
+    public void testDynamicAttributesSupport() throws Exception {
+        //get fm config to use it in mock servlet context
+        FreemarkerManager freemarkerManager = 
container.getInstance(FreemarkerManager.class);
+        Configuration freemarkerConfig = 
freemarkerManager.getConfiguration(ServletActionContext.getServletContext());
+        
freemarkerConfig.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
+
+        ServletContext servletContext = 
EasyMock.createNiceMock(ServletContext.class);
+
+        File file = new 
File(FreeMarkerResultTest.class.getResource("dynaAttributes.ftl").toURI());
+        
EasyMock.expect(servletContext.getRealPath("/tutorial/org/apache/struts2/views/freemarker/dynaAttributes.ftl")).andReturn(file.getAbsolutePath());
+
+        file = new 
File(ClassLoaderUtil.getResource("template/simple/text.ftl", 
getClass()).toURI());
+        
EasyMock.expect(servletContext.getRealPath("/template/simple/text.ftl")).andReturn(file.getAbsolutePath());
+
+        file = new File(ClassLoaderUtil.getResource("template/simple/css.ftl", 
getClass()).toURI());
+        
EasyMock.expect(servletContext.getRealPath("/template/simple/css.ftl")).andReturn(file.getAbsolutePath());
+
+        file = new 
File(ClassLoaderUtil.getResource("template/simple/scripting-events.ftl", 
getClass()).toURI());
+        
EasyMock.expect(servletContext.getRealPath("/template/simple/scripting-events.ftl")).andReturn(file.getAbsolutePath());
+
+        file = new 
File(ClassLoaderUtil.getResource("template/simple/common-attributes.ftl", 
getClass()).toURI());
+        
EasyMock.expect(servletContext.getRealPath("/template/simple/common-attributes.ftl")).andReturn(file.getAbsolutePath());
+
+        file = new 
File(ClassLoaderUtil.getResource("template/simple/dynamic-attributes.ftl", 
getClass()).toURI());
+        
EasyMock.expect(servletContext.getRealPath("/template/simple/dynamic-attributes.ftl")).andReturn(file.getAbsolutePath());
+
+        
EasyMock.expect(servletContext.getAttribute(FreemarkerManager.CONFIG_SERVLET_CONTEXT_KEY)).andReturn(freemarkerConfig).anyTimes();
+        EasyMock.replay(servletContext);
+
+        freemarkerConfig.setServletContextForTemplateLoading(servletContext, 
null);
+        ServletActionContext.setServletContext(servletContext);
+
+
+        request.setRequestURI("/tutorial/test6.action");
+        Dispatcher dispatcher = Dispatcher.getInstance();
+        ActionMapping mapping = 
dispatcher.getContainer().getInstance(ActionMapper.class).getMapping(request, 
dispatcher.getConfigurationManager());
+        dispatcher.serviceAction(request, response, servletContext, mapping);
+        assertEquals("<input type=\"text\" name=\"test\" value=\"\" 
id=\"test\" placeholder=\"input\" foo=\"bar\"/>", stringWriter.toString());
+    }
+
     protected void setUp() throws Exception {
         super.setUp();
         mgr = new FreemarkerManager();

Copied: 
struts/struts2/trunk/core/src/test/resources/org/apache/struts2/views/freemarker/dynaAttributes.ftl
 (from r1310204, 
struts/struts2/trunk/core/src/test/resources/org/apache/struts2/views/freemarker/callActionFreeMarker.ftl)
URL: 
http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/test/resources/org/apache/struts2/views/freemarker/dynaAttributes.ftl?p2=struts/struts2/trunk/core/src/test/resources/org/apache/struts2/views/freemarker/dynaAttributes.ftl&p1=struts/struts2/trunk/core/src/test/resources/org/apache/struts2/views/freemarker/callActionFreeMarker.ftl&r1=1310204&r2=1310221&rev=1310221&view=diff
==============================================================================
--- 
struts/struts2/trunk/core/src/test/resources/org/apache/struts2/views/freemarker/callActionFreeMarker.ftl
 (original)
+++ 
struts/struts2/trunk/core/src/test/resources/org/apache/struts2/views/freemarker/dynaAttributes.ftl
 Fri Apr  6 08:17:00 2012
@@ -20,4 +20,4 @@
  * under the License.
  */
 -->
-before<@s.action namespace="/tutorial" name="test4" executeResult="true" 
rethrowException="true"/>after
\ No newline at end of file
+<@s.textfield name="test" 
dynamicAttributes={"placeholder":"input","foo":"bar"}/>
\ No newline at end of file

Modified: struts/struts2/trunk/core/src/test/resources/struts.xml
URL: 
http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/test/resources/struts.xml?rev=1310221&r1=1310220&r2=1310221&view=diff
==============================================================================
--- struts/struts2/trunk/core/src/test/resources/struts.xml (original)
+++ struts/struts2/trunk/core/src/test/resources/struts.xml Fri Apr  6 08:17:00 
2012
@@ -63,6 +63,12 @@
             </result>
         </action>
 
+         <action name="test6" class="com.opensymphony.xwork2.ActionSupport">
+            <result type="freemarker">
+                <param 
name="location">org/apache/struts2/views/freemarker/dynaAttributes.ftl</param>
+            </result>
+        </action>
+
     </package>
 
     <package name="sitegraph" namespace="/tutorial/sitegraph" 
extends="struts-default">


Reply via email to