diff --git a/core/src/main/java/org/apache/struts2/components/Anchor.java b/core/src/main/java/org/apache/struts2/components/Anchor.java index 163931010..5d960c5aa 100644 --- a/core/src/main/java/org/apache/struts2/components/Anchor.java +++ b/core/src/main/java/org/apache/struts2/components/Anchor.java @@ -80,14 +80,17 @@ public class Anchor extends ClosingUIBean { urlProvider.setHttpServletResponse(response); } + @Override public String getDefaultOpenTemplate() { return OPEN_TEMPLATE; } + @Override protected String getDefaultTemplate() { return TEMPLATE; } + @Override public boolean usesBody() { return true; } @@ -96,16 +99,17 @@ public class Anchor extends ClosingUIBean { protected void evaluateExtraParams() { super.evaluateExtraParams(); - if (href != null) + if (href != null) { addParameter("href", ensureAttributeSafelyNotEscaped(findString(href))); - else { + } else { //no href, build it from URL attributes StringWriter sw = new StringWriter(); urlRenderer.beforeRenderUrl(urlProvider); urlRenderer.renderUrl(sw, urlProvider); String builtHref = sw.toString(); - if (StringUtils.isNotEmpty(builtHref)) + if (StringUtils.isNotEmpty(builtHref)) { addParameter("href", ensureAttributeSafelyNotEscaped(builtHref)); + } } } @@ -115,10 +119,10 @@ public class Anchor extends ClosingUIBean { } @Inject - public void setUrlRenderer(UrlRenderer urlRenderer) { - urlProvider.setUrlRenderer(urlRenderer); + public void setUrlRenderer(UrlRenderer urlRenderer) { + urlProvider.setUrlRenderer(urlRenderer); this.urlRenderer = urlRenderer; - } + } @Inject(required=false) public void setExtraParameterProvider(ExtraParameterProvider provider) { @@ -135,6 +139,7 @@ public class Anchor extends ClosingUIBean { /** * Overrides to be able to render body in a template rather than always before the template */ + @Override public boolean end(Writer writer, String body) { this.processingTagBody = false; evaluateParams(); @@ -143,15 +148,14 @@ public class Anchor extends ClosingUIBean { mergeTemplate(writer, buildTemplateName(template, getDefaultTemplate())); } catch (Exception e) { LOG.error("error when rendering", e); - } - finally { + } finally { popComponentStack(); } return false; } - + @Override public void addParameter(String key, Object value) { /* the parameters added by this method are used in the template. this method is also @@ -160,8 +164,9 @@ public class Anchor extends ClosingUIBean { */ if (processingTagBody) { this.urlParameters.put(key, value); - } else + } else { super.addParameter(key, value); + } } @Override @@ -173,8 +178,9 @@ public class Anchor extends ClosingUIBean { */ if (processingTagBody) { this.urlParameters.putAll(params); - } else + } else { super.addAllParameters(params); + } } public UrlProvider getUrlProvider() { @@ -196,6 +202,7 @@ public class Anchor extends ClosingUIBean { urlProvider.setScheme(scheme); } + @Override @StrutsTagAttribute(description = "The target value to use, if not using action") public void setValue(String value) { urlProvider.setValue(value); diff --git a/core/src/main/java/org/apache/struts2/components/UIBean.java b/core/src/main/java/org/apache/struts2/components/UIBean.java index 1a0356a0c..b7c4432e4 100644 --- a/core/src/main/java/org/apache/struts2/components/UIBean.java +++ b/core/src/main/java/org/apache/struts2/components/UIBean.java @@ -528,6 +528,7 @@ public abstract class UIBean extends Component { this.templateEngineManager = mgr; } + @Override public boolean end(Writer writer, String body) { evaluateParams(); try { @@ -883,7 +884,7 @@ public abstract class UIBean extends Component { evaluateExtraParams(); } - protected String escape(String name) { + protected String escape(String name) { // escape any possible values that can make the ID painful to work with in JavaScript if (name != null) { return name.replaceAll("[\\/\\.\\[\\]]", "_"); @@ -930,7 +931,7 @@ public abstract class UIBean extends Component { form.addParameter("customOnsubmitEnabled", Boolean.TRUE); } else { if (LOG.isWarnEnabled()) { - LOG.warn("Cannot find an Ancestor form, custom onsubmit is NOT enabled"); + LOG.warn("Cannot find an Ancestor form, custom onsubmit is NOT enabled"); } } } @@ -1240,7 +1241,7 @@ public abstract class UIBean extends Component { this.tooltipIconPath = tooltipIconPath; } - public void setDynamicAttributes(Map tagDynamicAttributes) { + public void setDynamicAttributes(Map tagDynamicAttributes) { for (Map.Entry entry : tagDynamicAttributes.entrySet()) { String key = entry.getKey(); @@ -1250,19 +1251,20 @@ public abstract class UIBean extends Component { } } - @Override - /** - * supports dynamic attributes for freemarker ui tags - * @see https://issues.apache.org/jira/browse/WW-3174 + @Override + /** + * supports dynamic attributes for freemarker ui tags + * @see https://issues.apache.org/jira/browse/WW-3174 * @see https://issues.apache.org/jira/browse/WW-4166 - */ + */ public void copyParams(Map params) { super.copyParams(params); for (Object o : params.entrySet()) { Map.Entry entry = (Map.Entry) o; String key = (String) entry.getKey(); - if(!isValidTagAttribute(key) && !key.equals("dynamicAttributes")) + if (!isValidTagAttribute(key) && !key.equals("dynamicAttributes")) { dynamicAttributes.put(key, entry.getValue()); + } } } diff --git a/core/src/main/java/org/apache/struts2/components/UrlRenderer.java b/core/src/main/java/org/apache/struts2/components/UrlRenderer.java index 29890250e..b2f838a9a 100644 --- a/core/src/main/java/org/apache/struts2/components/UrlRenderer.java +++ b/core/src/main/java/org/apache/struts2/components/UrlRenderer.java @@ -28,26 +28,26 @@ import java.io.Writer; * */ public interface UrlRenderer { - - /** - * Preprocessing step - * @param provider The {@link UrlProvider} component that "owns" this renderer. - */ - void beforeRenderUrl(UrlProvider provider); - - /** - * Render a URL. - * @param writer A writer that the implementation can use to write the result to. - * @param provider The {@link UrlProvider} component that "owns" this renderer. - */ - void renderUrl(Writer writer, UrlProvider provider); - - /** - * Render a Form URL. - * @param formComponent The {@link Form} component that "owns" this renderer. - */ - void renderFormUrl(Form formComponent); - void setActionMapper(ActionMapper actionMapper); + /** + * Preprocessing step + * @param provider The {@link UrlProvider} component that "owns" this renderer. + */ + void beforeRenderUrl(UrlProvider provider); + + /** + * Render a URL. + * @param writer A writer that the implementation can use to write the result to. + * @param provider The {@link UrlProvider} component that "owns" this renderer. + */ + void renderUrl(Writer writer, UrlProvider provider); + + /** + * Render a Form URL. + * @param formComponent The {@link Form} component that "owns" this renderer. + */ + void renderFormUrl(Form formComponent); + + void setActionMapper(ActionMapper actionMapper); } diff --git a/core/src/test/java/org/apache/struts2/components/UIBeanTest.java b/core/src/test/java/org/apache/struts2/components/UIBeanTest.java index 2b3da96c3..31f6e3487 100644 --- a/core/src/test/java/org/apache/struts2/components/UIBeanTest.java +++ b/core/src/test/java/org/apache/struts2/components/UIBeanTest.java @@ -19,18 +19,19 @@ package org.apache.struts2.components; import com.opensymphony.xwork2.ActionContext; +import com.opensymphony.xwork2.config.ConfigurationException; import com.opensymphony.xwork2.util.ValueStack; import org.apache.struts2.StrutsInternalTestCase; +import org.apache.struts2.components.template.Template; +import org.apache.struts2.components.template.TemplateEngine; +import org.apache.struts2.components.template.TemplateEngineManager; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletResponse; + import java.util.Collections; import java.util.Map; -/** - * - * @version $Date$ $Id$ - */ public class UIBeanTest extends StrutsInternalTestCase { public void testPopulateComponentHtmlId1() throws Exception { @@ -161,4 +162,121 @@ public class UIBeanTest extends StrutsInternalTestCase { assertEquals("12", txtFld.getTheme()); } + public void testMergeTemplateNullEngineException() throws Exception { + ValueStack stack = ActionContext.getContext().getValueStack(); + MockHttpServletRequest req = new MockHttpServletRequest(); + MockHttpServletResponse res = new MockHttpServletResponse(); + //templateEngineManager that returns null as TemplateEngine + TemplateEngineManager templateEngineManager = new TemplateEngineManager() { + public TemplateEngine getTemplateEngine(Template template, String templateTypeOverride) { + return null; + } + }; + TextField txtFld = new TextField(stack, req, res); + + txtFld.setTemplateEngineManager(templateEngineManager); + + try { + txtFld.mergeTemplate(null, new Template(null, null, null)); + fail("Exception not thrown"); + } catch(final Exception e){ + assertTrue(e instanceof ConfigurationException); + } + } + + public void testBuildTemplate() throws Exception { + String defaultTemplateName = "default"; + String customTemplateName = "custom"; + ValueStack stack = ActionContext.getContext().getValueStack(); + MockHttpServletRequest req = new MockHttpServletRequest(); + MockHttpServletResponse res = new MockHttpServletResponse(); + + TextField txtFld = new TextField(stack, req, res); + + Template defaultTemplate = txtFld.buildTemplateName(null, defaultTemplateName); + Template customTemplate = txtFld.buildTemplateName(customTemplateName, defaultTemplateName); + + assertEquals(defaultTemplateName, defaultTemplate.getName()); + assertEquals(customTemplateName, customTemplate.getName()); + } + + public void testGetTemplateDirExplicit() throws Exception { + String explicitTemplateDir = "explicitTemplateDirectory"; + String attrTemplateDir = "attrTemplateDirectory"; + String defaultTemplateDir = "defaultTemplateDirectory"; + ValueStack stack = ActionContext.getContext().getValueStack(); + MockHttpServletRequest req = new MockHttpServletRequest(); + MockHttpServletResponse res = new MockHttpServletResponse(); + Map context = Collections.singletonMap("templateDir", attrTemplateDir); + ActionContext.getContext().put("attr", context); + + TextField txtFld = new TextField(stack, req, res); + txtFld.setTemplateDir(explicitTemplateDir); + txtFld.setDefaultTemplateDir(defaultTemplateDir); + + assertEquals(explicitTemplateDir, txtFld.getTemplateDir()); + } + + public void testGetTemplateDirAttr() throws Exception { + String attrTemplateDir = "attrTemplateDirectory"; + String defaultTemplateDir = "defaultTemplateDirectory"; + ValueStack stack = ActionContext.getContext().getValueStack(); + MockHttpServletRequest req = new MockHttpServletRequest(); + MockHttpServletResponse res = new MockHttpServletResponse(); + Map context = Collections.singletonMap("templateDir", attrTemplateDir); + ActionContext.getContext().put("attr", context); + + TextField txtFld = new TextField(stack, req, res); + txtFld.setDefaultTemplateDir(defaultTemplateDir); + + assertEquals(attrTemplateDir, txtFld.getTemplateDir()); + } + + public void testGetTemplateDirDefault() throws Exception { + String defaultTemplateDir = "defaultTemplateDirectory"; + ValueStack stack = ActionContext.getContext().getValueStack(); + MockHttpServletRequest req = new MockHttpServletRequest(); + MockHttpServletResponse res = new MockHttpServletResponse(); + + TextField txtFld = new TextField(stack, req, res); + txtFld.setDefaultTemplateDir(defaultTemplateDir); + + assertEquals(defaultTemplateDir, txtFld.getTemplateDir()); + } + + public void testGetTemplateDirNoneSet() throws Exception { + ValueStack stack = ActionContext.getContext().getValueStack(); + MockHttpServletRequest req = new MockHttpServletRequest(); + MockHttpServletResponse res = new MockHttpServletResponse(); + + TextField txtFld = new TextField(stack, req, res); + + assertEquals("template", txtFld.getTemplateDir()); + } + + public void testSetAccesskey() { + String accesskeyValue = "myAccesskey"; + ValueStack stack = ActionContext.getContext().getValueStack(); + MockHttpServletRequest req = new MockHttpServletRequest(); + MockHttpServletResponse res = new MockHttpServletResponse(); + + TextField txtFld = new TextField(stack, req, res); + txtFld.setAccesskey(accesskeyValue); + txtFld.evaluateParams(); + + assertEquals(accesskeyValue, txtFld.getParameters().get("accesskey")); + } + + public void testValueParameterEvaluation() { + String value = "myValue"; + ValueStack stack = ActionContext.getContext().getValueStack(); + MockHttpServletRequest req = new MockHttpServletRequest(); + MockHttpServletResponse res = new MockHttpServletResponse(); + + TextField txtFld = new TextField(stack, req, res); + txtFld.addParameter("value", value); + txtFld.evaluateParams(); + + assertEquals(value, txtFld.getParameters().get("nameValue")); + } }