/*
* Copyright 2002-2010 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.form;
import java.beans.PropertyEditorSupport;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.jsp.tagext.Tag;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.springframework.beans.Colour;
import org.springframework.beans.Pet;
import org.springframework.beans.TestBean;
import org.springframework.beans.propertyeditors.StringTrimmerEditor;
import org.springframework.validation.BeanPropertyBindingResult;
import org.springframework.validation.BindingResult;
/**
* @author Rob Harrop
* @author Juergen Hoeller
*/
public class CheckboxTagTests extends AbstractFormTagTests {
private CheckboxTag tag;
private TestBean bean;
protected void onSetUp() {
this.tag = new CheckboxTag() {
protected TagWriter createTagWriter() {
return new TagWriter(getWriter());
}
};
this.tag.setPageContext(getPageContext());
}
public void testWithSingleValueBooleanObjectChecked() throws Exception {
this.tag.setPath("someBoolean");
int result = this.tag.doStartTag();
assertEquals(Tag.SKIP_BODY, result);
String output = getOutput();
// wrap the output so it is valid XML
output = "<doc>" + output + "</doc>";
SAXReader reader = new SAXReader();
Document document = reader.read(new StringReader(output));
Element rootElement = document.getRootElement();
assertEquals("Both tag and hidden element not rendered", 2, rootElement.elements().size());
Element checkboxElement = (Element) rootElement.elements().get(0);
assertEquals("input", checkboxElement.getName());
assertEquals("checkbox", checkboxElement.attribute("type").getValue());
assertEquals("someBoolean", checkboxElement.attribute("name").getValue());
assertEquals("someBoolean1", checkboxElement.attribute("id").getValue());
assertEquals("checked", checkboxElement.attribute("checked").getValue());
assertEquals("true", checkboxElement.attribute("value").getValue());
}
public void testWithIndexedBooleanObjectNotChecked() throws Exception {
this.tag.setPath("someMap[key]");
int result = this.tag.doStartTag();
assertEquals(Tag.SKIP_BODY, result);
String output = getOutput();
// wrap the output so it is valid XML
output = "<doc>" + output + "</doc>";
SAXReader reader = new SAXReader();
Document document = reader.read(new StringReader(output));
Element rootElement = document.getRootElement();
assertEquals("Both tag and hidden element not rendered", 2, rootElement.elements().size());
Element checkboxElement = (Element) rootElement.elements().get(0);
assertEquals("input", checkboxElement.getName());
assertEquals("checkbox", checkboxElement.attribute("type").getValue());
assertEquals("someMapkey1", checkboxElement.attribute("id").getValue());
assertEquals("someMapkey", checkboxElement.attribute("name").getValue());
assertEquals("checked", checkboxElement.attribute("checked").getValue());
assertEquals("true", checkboxElement.attribute("value").getValue());
}
public void testWithSingleValueBooleanChecked() throws Exception {
this.tag.setPath("jedi");
int result = this.tag.doStartTag();
assertEquals(Tag.SKIP_BODY, result);
String output = getOutput();
// wrap the output so it is valid XML
output = "<doc>" + output + "</doc>";
SAXReader reader = new SAXReader();
Document document = reader.read(new StringReader(output));
Element checkboxElement = (Element) document.getRootElement().elements().get(0);
assertEquals("input", checkboxElement.getName());
assertEquals("checkbox", checkboxElement.attribute("type").getValue());
assertEquals("jedi", checkboxElement.attribute("name").getValue());
assertEquals("checked", checkboxElement.attribute("checked").getValue());
assertEquals("true", checkboxElement.attribute("value").getValue());
}
public void testWithSingleValueBooleanObjectUnchecked() throws Exception {
this.bean.setSomeBoolean(new Boolean(false));
this.tag.setPath("someBoolean");
int result = this.tag.doStartTag();
assertEquals(Tag.SKIP_BODY, result);
String output = getOutput();
// wrap the output so it is valid XML
output = "<doc>" + output + "</doc>";
SAXReader reader = new SAXReader();
Document document = reader.read(new StringReader(output));
Element checkboxElement = (Element) document.getRootElement().elements().get(0);
assertEquals("input", checkboxElement.getName());
assertEquals("checkbox", checkboxElement.attribute("type").getValue());
assertEquals("someBoolean", checkboxElement.attribute("name").getValue());
assertNull(checkboxElement.attribute("checked"));
assertEquals("true", checkboxElement.attribute("value").getValue());
}
public void testWithSingleValueBooleanUnchecked() throws Exception {
this.bean.setJedi(false);
this.tag.setPath("jedi");
int result = this.tag.doStartTag();
assertEquals(Tag.SKIP_BODY, result);
String output = getOutput();
// wrap the output so it is valid XML
output = "<doc>" + output + "</doc>";
SAXReader reader = new SAXReader();
Document document = reader.read(new StringReader(output));
Element checkboxElement = (Element) document.getRootElement().elements().get(0);
assertEquals("input", checkboxElement.getName());
assertEquals("checkbox", checkboxElement.attribute("type").getValue());
assertEquals("jedi", checkboxElement.attribute("name").getValue());
assertNull(checkboxElement.attribute("checked"));
assertEquals("true", checkboxElement.attribute("value").getValue());
}
public void testWithSingleValueNull() throws Exception {
this.bean.setName(null);
this.tag.setPath("name");
this.tag.setValue("Rob Harrop");
int result = this.tag.doStartTag();
assertEquals(Tag.SKIP_BODY, result);
String output = getOutput();
// wrap the output so it is valid XML
output = "<doc>" + output + "</doc>";
SAXReader reader = new SAXReader();
Document document = reader.read(new StringReader(output));
Element checkboxElement = (Element) document.getRootElement().elements().get(0);
assertEquals("input", checkboxElement.getName());
assertEquals("checkbox", checkboxElement.attribute("type").getValue());
assertEquals("name", checkboxElement.attribute("name").getValue());
assertNull(checkboxElement.attribute("checked"));
assertEquals("Rob Harrop", checkboxElement.attribute("value").getValue());
}
public void testWithSingleValueNotNull() throws Exception {
this.bean.setName("Rob Harrop");
this.tag.setPath("name");
this.tag.setValue("Rob Harrop");
int result = this.tag.doStartTag();
assertEquals(Tag.SKIP_BODY, result);
String output = getOutput();
// wrap the output so it is valid XML
output = "<doc>" + output + "</doc>";
SAXReader reader = new SAXReader();
Document document = reader.read(new StringReader(output));
Element checkboxElement = (Element) document.getRootElement().elements().get(0);
assertEquals("input", checkboxElement.getName());
assertEquals("checkbox", checkboxElement.attribute("type").getValue());
assertEquals("name", checkboxElement.attribute("name").getValue());
assertEquals("checked", checkboxElement.attribute("checked").getValue());
assertEquals("Rob Harrop", checkboxElement.attribute("value").getValue());
}
public void testWithSingleValueAndEditor() throws Exception {
this.bean.setName("Rob Harrop");
this.tag.setPath("name");
this.tag.setValue(" Rob Harrop");
BeanPropertyBindingResult bindingResult = new BeanPropertyBindingResult(this.bean, COMMAND_NAME);
bindingResult.getPropertyEditorRegistry().registerCustomEditor(String.class, new StringTrimmerEditor(false));
getPageContext().getRequest().setAttribute(BindingResult.MODEL_KEY_PREFIX + COMMAND_NAME, bindingResult);
int result = this.tag.doStartTag();
assertEquals(Tag.SKIP_BODY, result);
String output = getOutput();
// wrap the output so it is valid XML
output = "<doc>" + output + "</doc>";
SAXReader reader = new SAXReader();
Document document = reader.read(new StringReader(output));
Element checkboxElement = (Element) document.getRootElement().elements().get(0);
assertEquals("input", checkboxElement.getName());
assertEquals("checkbox", checkboxElement.attribute("type").getValue());
assertEquals("name", checkboxElement.attribute("name").getValue());
assertEquals("checked", checkboxElement.attribute("checked").getValue());
assertEquals(" Rob Harrop", checkboxElement.attribute("value").getValue());
}
public void testWithMultiValueChecked() throws Exception {
this.tag.setPath("stringArray");
this.tag.setValue("foo");
int result = this.tag.doStartTag();
assertEquals(Tag.SKIP_BODY, result);
String output = getOutput();
// wrap the output so it is valid XML
output = "<doc>" + output + "</doc>";
SAXReader reader = new SAXReader();
Document document = reader.read(new StringReader(output));
Element checkboxElement = (Element) document.getRootElement().elements().get(0);
assertEquals("input", checkboxElement.getName());
assertEquals("checkbox", checkboxElement.attribute("type").getValue());
assertEquals("stringArray", checkboxElement.attribute("name").getValue());
assertEquals("checked", checkboxElement.attribute("checked").getValue());
assertEquals("foo", checkboxElement.attribute("value").getValue());
}
public void testWithMultiValueUnchecked() throws Exception {
this.tag.setPath("stringArray");
this.tag.setValue("abc");
int result = this.tag.doStartTag();
assertEquals(Tag.SKIP_BODY, result);
String output = getOutput();
// wrap the output so it is valid XML
output = "<doc>" + output + "</doc>";
SAXReader reader = new SAXReader();
Document document = reader.read(new StringReader(output));
Element checkboxElement = (Element) document.getRootElement().elements().get(0);
assertEquals("input", checkboxElement.getName());
assertEquals("checkbox", checkboxElement.attribute("type").getValue());
assertEquals("stringArray", checkboxElement.attribute("name").getValue());
assertNull(checkboxElement.attribute("checked"));
assertEquals("abc", checkboxElement.attribute("value").getValue());
}
public void testWithMultiValueWithEditor() throws Exception {
this.tag.setPath("stringArray");
this.tag.setValue(" foo");
BeanPropertyBindingResult bindingResult = new BeanPropertyBindingResult(this.bean, COMMAND_NAME);
MyStringTrimmerEditor editor = new MyStringTrimmerEditor();
bindingResult.getPropertyEditorRegistry().registerCustomEditor(String.class, editor);
getPageContext().getRequest().setAttribute(BindingResult.MODEL_KEY_PREFIX + COMMAND_NAME, bindingResult);
int result = this.tag.doStartTag();
assertEquals(Tag.SKIP_BODY, result);
assertEquals(1, editor.count);
String output = getOutput();
// wrap the output so it is valid XML
output = "<doc>" + output + "</doc>";
SAXReader reader = new SAXReader();
Document document = reader.read(new StringReader(output));
Element checkboxElement = (Element) document.getRootElement().elements().get(0);
assertEquals("input", checkboxElement.getName());
assertEquals("checkbox", checkboxElement.attribute("type").getValue());
assertEquals("stringArray", checkboxElement.attribute("name").getValue());
assertEquals("checked", checkboxElement.attribute("checked").getValue());
assertEquals(" foo", checkboxElement.attribute("value").getValue());
}
public void testWithMultiValueIntegerWithEditor() throws Exception {
this.tag.setPath("someIntegerArray");
this.tag.setValue(" 1");
BeanPropertyBindingResult bindingResult = new BeanPropertyBindingResult(this.bean, COMMAND_NAME);
MyIntegerEditor editor = new MyIntegerEditor();
bindingResult.getPropertyEditorRegistry().registerCustomEditor(Integer.class, editor);
getPageContext().getRequest().setAttribute(BindingResult.MODEL_KEY_PREFIX + COMMAND_NAME, bindingResult);
int result = this.tag.doStartTag();
assertEquals(Tag.SKIP_BODY, result);
assertEquals(1, editor.count);
String output = getOutput();
// wrap the output so it is valid XML
output = "<doc>" + output + "</doc>";
SAXReader reader = new SAXReader();
Document document = reader.read(new StringReader(output));
Element checkboxElement = (Element) document.getRootElement().elements().get(0);
assertEquals("input", checkboxElement.getName());
assertEquals("checkbox", checkboxElement.attribute("type").getValue());
assertEquals("someIntegerArray", checkboxElement.attribute("name").getValue());
assertEquals("checked", checkboxElement.attribute("checked").getValue());
assertEquals(" 1", checkboxElement.attribute("value").getValue());
}
public void testWithCollection() throws Exception {
this.tag.setPath("someList");
this.tag.setValue("foo");
int result = this.tag.doStartTag();
assertEquals(Tag.SKIP_BODY, result);
String output = getOutput();
// wrap the output so it is valid XML
output = "<doc>" + output + "</doc>";
SAXReader reader = new SAXReader();
Document document = reader.read(new StringReader(output));
Element checkboxElement = (Element) document.getRootElement().elements().get(0);
assertEquals("input", checkboxElement.getName());
assertEquals("checkbox", checkboxElement.attribute("type").getValue());
assertEquals("someList", checkboxElement.attribute("name").getValue());
assertEquals("checked", checkboxElement.attribute("checked").getValue());
assertEquals("foo", checkboxElement.attribute("value").getValue());
}
public void testWithObjectChecked() throws Exception {
this.tag.setPath("date");
this.tag.setValue(getDate());
int result = this.tag.doStartTag();
assertEquals(Tag.SKIP_BODY, result);
String output = getOutput();
// wrap the output so it is valid XML
output = "<doc>" + output + "</doc>";
SAXReader reader = new SAXReader();
Document document = reader.read(new StringReader(output));
Element checkboxElement = (Element) document.getRootElement().elements().get(0);
assertEquals("input", checkboxElement.getName());
assertEquals("checkbox", checkboxElement.attribute("type").getValue());
assertEquals("date", checkboxElement.attribute("name").getValue());
assertEquals("checked", checkboxElement.attribute("checked").getValue());
assertEquals(getDate().toString(), checkboxElement.attribute("value").getValue());
}
public void testWithObjectUnchecked() throws Exception {
this.tag.setPath("date");
Date date = new Date();
this.tag.setValue(date);
int result = this.tag.doStartTag();
assertEquals(Tag.SKIP_BODY, result);
String output = getOutput();
// wrap the output so it is valid XML
output = "<doc>" + output + "</doc>";
SAXReader reader = new SAXReader();
Document document = reader.read(new StringReader(output));
Element checkboxElement = (Element) document.getRootElement().elements().get(0);
assertEquals("input", checkboxElement.getName());
assertEquals("checkbox", checkboxElement.attribute("type").getValue());
assertEquals("date", checkboxElement.attribute("name").getValue());
assertNull(checkboxElement.attribute("checked"));
assertEquals(date.toString(), checkboxElement.attribute("value").getValue());
}
public void testCollectionOfColoursSelected() throws Exception {
this.tag.setPath("otherColours");
this.tag.setValue("RED");
int result = this.tag.doStartTag();
assertEquals(Tag.SKIP_BODY, result);
String output = getOutput();
// wrap the output so it is valid XML
output = "<doc>" + output + "</doc>";
SAXReader reader = new SAXReader();
Document document = reader.read(new StringReader(output));
Element checkboxElement = (Element) document.getRootElement().elements().get(0);
assertEquals("input", checkboxElement.getName());
assertEquals("checkbox", checkboxElement.attribute("type").getValue());
assertEquals("otherColours", checkboxElement.attribute("name").getValue());
assertEquals("checked", checkboxElement.attribute("checked").getValue());
}
public void testCollectionOfColoursNotSelected() throws Exception {
this.tag.setPath("otherColours");
this.tag.setValue("PURPLE");
int result = this.tag.doStartTag();
assertEquals(Tag.SKIP_BODY, result);
String output = getOutput();
// wrap the output so it is valid XML
output = "<doc>" + output + "</doc>";
SAXReader reader = new SAXReader();
Document document = reader.read(new StringReader(output));
Element checkboxElement = (Element) document.getRootElement().elements().get(0);
assertEquals("input", checkboxElement.getName());
assertEquals("checkbox", checkboxElement.attribute("type").getValue());
assertEquals("otherColours", checkboxElement.attribute("name").getValue());
assertNull(checkboxElement.attribute("checked"));
}
public void testCollectionOfPetsAsString() throws Exception {
this.tag.setPath("pets");
this.tag.setValue("Spot");
int result = this.tag.doStartTag();
assertEquals(Tag.SKIP_BODY, result);
String output = getOutput();
// wrap the output so it is valid XML
output = "<doc>" + output + "</doc>";
SAXReader reader = new SAXReader();
Document document = reader.read(new StringReader(output));
Element checkboxElement = (Element) document.getRootElement().elements().get(0);
assertEquals("input", checkboxElement.getName());
assertEquals("checkbox", checkboxElement.attribute("type").getValue());
assertEquals("pets", checkboxElement.attribute("name").getValue());
assertEquals("checked", checkboxElement.attribute("checked").getValue());
}
public void testCollectionOfPetsAsStringNotSelected() throws Exception {
this.tag.setPath("pets");
this.tag.setValue("Santa's Little Helper");
int result = this.tag.doStartTag();
assertEquals(Tag.SKIP_BODY, result);
String output = getOutput();
// wrap the output so it is valid XML
output = "<doc>" + output + "</doc>";
SAXReader reader = new SAXReader();
Document document = reader.read(new StringReader(output));
Element checkboxElement = (Element) document.getRootElement().elements().get(0);
assertEquals("input", checkboxElement.getName());
assertEquals("checkbox", checkboxElement.attribute("type").getValue());
assertEquals("pets", checkboxElement.attribute("name").getValue());
assertNull(checkboxElement.attribute("checked"));
}
public void testCollectionOfPets() throws Exception {
this.tag.setPath("pets");
this.tag.setValue(new Pet("Rudiger"));
int result = this.tag.doStartTag();
assertEquals(Tag.SKIP_BODY, result);
String output = getOutput();
// wrap the output so it is valid XML
output = "<doc>" + output + "</doc>";
SAXReader reader = new SAXReader();
Document document = reader.read(new StringReader(output));
Element checkboxElement = (Element) document.getRootElement().elements().get(0);
assertEquals("input", checkboxElement.getName());
assertEquals("checkbox", checkboxElement.attribute("type").getValue());
assertEquals("pets", checkboxElement.attribute("name").getValue());
assertEquals("Rudiger", checkboxElement.attribute("value").getValue());
assertEquals("checked", checkboxElement.attribute("checked").getValue());
}
public void testCollectionOfPetsNotSelected() throws Exception {
this.tag.setPath("pets");
this.tag.setValue(new Pet("Santa's Little Helper"));
int result = this.tag.doStartTag();
assertEquals(Tag.SKIP_BODY, result);
String output = getOutput();
// wrap the output so it is valid XML
output = "<doc>" + output + "</doc>";
SAXReader reader = new SAXReader();
Document document = reader.read(new StringReader(output));
Element checkboxElement = (Element) document.getRootElement().elements().get(0);
assertEquals("input", checkboxElement.getName());
assertEquals("checkbox", checkboxElement.attribute("type").getValue());
assertEquals("pets", checkboxElement.attribute("name").getValue());
assertEquals("Santa's Little Helper", checkboxElement.attribute("value").getValue());
assertNull(checkboxElement.attribute("checked"));
}
public void testCollectionOfPetsWithEditor() throws Exception {
this.tag.setPath("pets");
this.tag.setValue(new ItemPet("Rudiger"));
BeanPropertyBindingResult bindingResult = new BeanPropertyBindingResult(this.bean, COMMAND_NAME);
PropertyEditorSupport editor = new ItemPet.CustomEditor();
bindingResult.getPropertyEditorRegistry().registerCustomEditor(ItemPet.class, editor);
getPageContext().getRequest().setAttribute(BindingResult.MODEL_KEY_PREFIX + COMMAND_NAME, bindingResult);
int result = this.tag.doStartTag();
assertEquals(Tag.SKIP_BODY, result);
String output = getOutput();
// wrap the output so it is valid XML
output = "<doc>" + output + "</doc>";
SAXReader reader = new SAXReader();
Document document = reader.read(new StringReader(output));
Element checkboxElement = (Element) document.getRootElement().elements().get(0);
assertEquals("input", checkboxElement.getName());
assertEquals("checkbox", checkboxElement.attribute("type").getValue());
assertEquals("pets", checkboxElement.attribute("name").getValue());
assertEquals("Rudiger", checkboxElement.attribute("value").getValue());
assertEquals("checked", checkboxElement.attribute("checked").getValue());
}
public void testWithNullValue() throws Exception {
try {
this.tag.setPath("name");
this.tag.doStartTag();
fail("Should not be able to render with a null value when binding to a non-boolean.");
}
catch (IllegalArgumentException e) {
// success
}
}
public void testHiddenElementOmittedOnDisabled() throws Exception {
this.tag.setPath("someBoolean");
this.tag.setDisabled("true");
int result = this.tag.doStartTag();
assertEquals(Tag.SKIP_BODY, result);
String output = getOutput();
// wrap the output so it is valid XML
output = "<doc>" + output + "</doc>";
SAXReader reader = new SAXReader();
Document document = reader.read(new StringReader(output));
Element rootElement = document.getRootElement();
assertEquals("Both tag and hidden element rendered incorrectly", 1, rootElement.elements().size());
Element checkboxElement = (Element) rootElement.elements().get(0);
assertEquals("input", checkboxElement.getName());
assertEquals("checkbox", checkboxElement.attribute("type").getValue());
assertEquals("someBoolean", checkboxElement.attribute("name").getValue());
assertEquals("checked", checkboxElement.attribute("checked").getValue());
assertEquals("true", checkboxElement.attribute("value").getValue());
}
private Date getDate() {
Calendar cal = Calendar.getInstance();
cal.set(Calendar.YEAR, 10);
cal.set(Calendar.MONTH, 10);
cal.set(Calendar.DATE, 10);
cal.set(Calendar.HOUR, 10);
cal.set(Calendar.MINUTE, 10);
cal.set(Calendar.SECOND, 10);
return cal.getTime();
}
protected TestBean createTestBean() {
List colours = new ArrayList();
colours.add(Colour.BLUE);
colours.add(Colour.RED);
colours.add(Colour.GREEN);
List pets = new ArrayList();
pets.add(new Pet("Rudiger"));
pets.add(new Pet("Spot"));
pets.add(new Pet("Fluffy"));
pets.add(new Pet("Mufty"));
List someList = new ArrayList();
someList.add("foo");
someList.add("bar");
Map someMap = new LinkedHashMap();
someMap.put("key", Boolean.TRUE);
this.bean = new TestBean();
this.bean.setDate(getDate());
this.bean.setName("Rob Harrop");
this.bean.setJedi(true);
this.bean.setSomeBoolean(new Boolean(true));
this.bean.setStringArray(new String[] {"bar", "foo"});
this.bean.setSomeIntegerArray(new Integer[] {new Integer(2), new Integer(1)});
this.bean.setOtherColours(colours);
this.bean.setPets(pets);
List list = new ArrayList();
list.add("foo");
list.add("bar");
this.bean.setSomeList(list);
this.bean.setSomeList(someList);
this.bean.setSomeMap(someMap);
return this.bean;
}
private class MyStringTrimmerEditor extends StringTrimmerEditor {
public int count = 0;
public MyStringTrimmerEditor() {
super(false);
}
public void setAsText(String text) {
this.count++;
super.setAsText(text);
}
}
private class MyIntegerEditor extends PropertyEditorSupport {
public int count = 0;
public void setAsText(String text) {
this.count++;
setValue(new Integer(text.trim()));
}
}
}