Browse Source
Add a new <spring:argument> tag that cab be nested within <spring:message> and <spring:theme>. The tag is based on the <fmt:param> tag and uses conventions found throughout other Spring tags. Issue: SPR-9678pull/298/merge
8 changed files with 396 additions and 11 deletions
@ -0,0 +1,36 @@ |
|||||||
|
/* |
||||||
|
* Copyright 2002-2013 the original author or authors. |
||||||
|
* |
||||||
|
* Licensed 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.springframework.web.servlet.tags; |
||||||
|
|
||||||
|
import javax.servlet.jsp.JspTagException; |
||||||
|
|
||||||
|
/** |
||||||
|
* Allows implementing tag to utilize nested {@code spring:argument} tags. |
||||||
|
* |
||||||
|
* @author Nicholas Williams |
||||||
|
* @since 4.0 |
||||||
|
* @see ArgumentTag |
||||||
|
*/ |
||||||
|
public interface ArgumentAware { |
||||||
|
|
||||||
|
/** |
||||||
|
* Callback hook for nested spring:argument tags to pass their value |
||||||
|
* to the parent tag. |
||||||
|
* @param argument the result of the nested {@code spring:argument} tag |
||||||
|
*/ |
||||||
|
void addArgument(Object argument) throws JspTagException; |
||||||
|
} |
||||||
@ -0,0 +1,88 @@ |
|||||||
|
/* |
||||||
|
* Copyright 2002-2013 the original author or authors. |
||||||
|
* |
||||||
|
* Licensed 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.springframework.web.servlet.tags; |
||||||
|
|
||||||
|
import javax.servlet.jsp.JspException; |
||||||
|
import javax.servlet.jsp.tagext.BodyTagSupport; |
||||||
|
|
||||||
|
/** |
||||||
|
* JSP tag for collecting arguments and passing them to an {@link ArgumentAware} ancestor |
||||||
|
* in the tag hierarchy. |
||||||
|
* |
||||||
|
* <p>This tag must be nested under an argument aware tag. |
||||||
|
* |
||||||
|
* @author Nicholas Williams |
||||||
|
* @since 4.0 |
||||||
|
* @see MessageTag |
||||||
|
* @see ThemeTag |
||||||
|
*/ |
||||||
|
@SuppressWarnings("serial") |
||||||
|
public class ArgumentTag extends BodyTagSupport { |
||||||
|
|
||||||
|
private Object value; |
||||||
|
|
||||||
|
private boolean valueSet; |
||||||
|
|
||||||
|
// tag lifecycle
|
||||||
|
|
||||||
|
@Override |
||||||
|
public int doEndTag() throws JspException { |
||||||
|
Object argument = null; |
||||||
|
if (this.valueSet) { |
||||||
|
argument = this.value; |
||||||
|
} |
||||||
|
else if (getBodyContent() != null) { |
||||||
|
// get the value from the tag body
|
||||||
|
argument = getBodyContent().getString().trim(); |
||||||
|
} |
||||||
|
|
||||||
|
// find a param aware ancestor
|
||||||
|
ArgumentAware argumentAwareTag = (ArgumentAware) findAncestorWithClass(this, |
||||||
|
ArgumentAware.class); |
||||||
|
if (argumentAwareTag == null) { |
||||||
|
throw new JspException( |
||||||
|
"The argument tag must be a descendant of a tag that supports arguments"); |
||||||
|
} |
||||||
|
|
||||||
|
argumentAwareTag.addArgument(argument); |
||||||
|
|
||||||
|
return EVAL_PAGE; |
||||||
|
} |
||||||
|
|
||||||
|
// tag attribute mutators
|
||||||
|
|
||||||
|
/** |
||||||
|
* Sets the value of the argument |
||||||
|
* |
||||||
|
* <p> |
||||||
|
* Optional. If not set, the tag's body content is evaluated. |
||||||
|
* |
||||||
|
* @param value the parameter value |
||||||
|
*/ |
||||||
|
public void setValue(Object value) { |
||||||
|
this.value = value; |
||||||
|
this.valueSet = true; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void release() { |
||||||
|
super.release(); |
||||||
|
this.value = null; |
||||||
|
this.valueSet = false; |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
@ -0,0 +1,119 @@ |
|||||||
|
/* |
||||||
|
* Copyright 2002-2013 the original author or authors. |
||||||
|
* |
||||||
|
* Licensed 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.springframework.web.servlet.tags; |
||||||
|
|
||||||
|
import javax.servlet.jsp.JspException; |
||||||
|
import javax.servlet.jsp.PageContext; |
||||||
|
import javax.servlet.jsp.tagext.Tag; |
||||||
|
import javax.servlet.jsp.tagext.TagSupport; |
||||||
|
|
||||||
|
import org.springframework.mock.web.test.MockBodyContent; |
||||||
|
import org.springframework.mock.web.test.MockHttpServletResponse; |
||||||
|
|
||||||
|
/** |
||||||
|
* Unit tests for ArgumentTag |
||||||
|
* |
||||||
|
* @author Nicholas Williams |
||||||
|
*/ |
||||||
|
public class ArgumentTagTests extends AbstractTagTests { |
||||||
|
|
||||||
|
private ArgumentTag tag; |
||||||
|
|
||||||
|
private MockArgumentSupportTag parent; |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void setUp() throws Exception { |
||||||
|
PageContext context = createPageContext(); |
||||||
|
parent = new MockArgumentSupportTag(); |
||||||
|
tag = new ArgumentTag(); |
||||||
|
tag.setPageContext(context); |
||||||
|
tag.setParent(parent); |
||||||
|
} |
||||||
|
|
||||||
|
public void testArgumentWithStringValue() throws JspException { |
||||||
|
tag.setValue("value1"); |
||||||
|
|
||||||
|
int action = tag.doEndTag(); |
||||||
|
|
||||||
|
assertEquals(Tag.EVAL_PAGE, action); |
||||||
|
assertEquals("value1", parent.getArgument()); |
||||||
|
} |
||||||
|
|
||||||
|
public void testArgumentWithImplicitNullValue() throws JspException { |
||||||
|
int action = tag.doEndTag(); |
||||||
|
|
||||||
|
assertEquals(Tag.EVAL_PAGE, action); |
||||||
|
assertNull(parent.getArgument()); |
||||||
|
} |
||||||
|
|
||||||
|
public void testArgumentWithExplicitNullValue() throws JspException { |
||||||
|
tag.setValue(null); |
||||||
|
|
||||||
|
int action = tag.doEndTag(); |
||||||
|
|
||||||
|
assertEquals(Tag.EVAL_PAGE, action); |
||||||
|
assertNull(parent.getArgument()); |
||||||
|
} |
||||||
|
|
||||||
|
public void testArgumentWithBodyValue() throws JspException { |
||||||
|
tag.setBodyContent(new MockBodyContent("value2", |
||||||
|
new MockHttpServletResponse())); |
||||||
|
|
||||||
|
int action = tag.doEndTag(); |
||||||
|
|
||||||
|
assertEquals(Tag.EVAL_PAGE, action); |
||||||
|
assertEquals("value2", parent.getArgument()); |
||||||
|
} |
||||||
|
|
||||||
|
public void testArgumentWithValueThenReleaseThenBodyValue() throws JspException { |
||||||
|
tag.setValue("value3"); |
||||||
|
|
||||||
|
int action = tag.doEndTag(); |
||||||
|
|
||||||
|
assertEquals(Tag.EVAL_PAGE, action); |
||||||
|
assertEquals("value3", parent.getArgument()); |
||||||
|
|
||||||
|
tag.release(); |
||||||
|
|
||||||
|
parent = new MockArgumentSupportTag(); |
||||||
|
tag.setPageContext(createPageContext()); |
||||||
|
tag.setParent(parent); |
||||||
|
tag.setBodyContent(new MockBodyContent("value4", |
||||||
|
new MockHttpServletResponse())); |
||||||
|
|
||||||
|
action = tag.doEndTag(); |
||||||
|
|
||||||
|
assertEquals(Tag.EVAL_PAGE, action); |
||||||
|
assertEquals("value4", parent.getArgument()); |
||||||
|
} |
||||||
|
|
||||||
|
@SuppressWarnings("serial") |
||||||
|
private class MockArgumentSupportTag extends TagSupport implements ArgumentAware { |
||||||
|
|
||||||
|
Object argument; |
||||||
|
|
||||||
|
@Override |
||||||
|
public void addArgument(Object argument) { |
||||||
|
this.argument = argument; |
||||||
|
} |
||||||
|
|
||||||
|
private Object getArgument() { |
||||||
|
return argument; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
Loading…
Reference in new issue