/*
* Copyright 2002-2016 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.PropertyEditor;
import java.beans.PropertyEditorSupport;
import java.io.StringReader;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.TreeMap;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.Tag;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.junit.Test;
import org.springframework.beans.propertyeditors.CustomCollectionEditor;
import org.springframework.format.Formatter;
import org.springframework.format.support.FormattingConversionService;
import org.springframework.tests.sample.beans.TestBean;
import org.springframework.validation.BeanPropertyBindingResult;
import org.springframework.validation.BindingResult;
import org.springframework.web.servlet.support.BindStatus;
import org.springframework.web.servlet.tags.TransformTag;
import static org.junit.Assert.*;
/**
* @author Rob Harrop
* @author Juergen Hoeller
* @author Jeremy Grelle
* @author Dave Syer
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
public class SelectTagTests extends AbstractFormTagTests {
private static final Locale LOCALE_AT = new Locale("de", "AT");
private static final Locale LOCALE_NL = new Locale("nl", "NL");
private SelectTag tag;
private TestBeanWithRealCountry bean;
@Override
@SuppressWarnings("serial")
protected void onSetUp() {
this.tag = new SelectTag() {
@Override
protected TagWriter createTagWriter() {
return new TagWriter(getWriter());
}
};
this.tag.setPageContext(getPageContext());
}
@Test
public void dynamicAttributes() throws JspException {
String dynamicAttribute1 = "attr1";
String dynamicAttribute2 = "attr2";
this.tag.setPath("country");
this.tag.setItems(Collections.EMPTY_LIST);
this.tag.setItemValue("isoCode");
this.tag.setItemLabel("name");
this.tag.setDynamicAttribute(null, dynamicAttribute1, dynamicAttribute1);
this.tag.setDynamicAttribute(null, dynamicAttribute2, dynamicAttribute2);
int result = this.tag.doStartTag();
assertEquals(Tag.SKIP_BODY, result);
String output = getOutput();
assertContainsAttribute(output, dynamicAttribute1, dynamicAttribute1);
assertContainsAttribute(output, dynamicAttribute2, dynamicAttribute2);
}
@Test
public void emptyItems() throws Exception {
this.tag.setPath("country");
this.tag.setItems(Collections.EMPTY_LIST);
this.tag.setItemValue("isoCode");
this.tag.setItemLabel("name");
int result = this.tag.doStartTag();
assertEquals(Tag.SKIP_BODY, result);
String output = getOutput();
assertEquals("<select id=\"country\" name=\"country\"></select>", output);
}
@Test
public void nullItems() throws Exception {
this.tag.setPath("country");
this.tag.setItems(null);
this.tag.setItemValue("isoCode");
this.tag.setItemLabel("name");
int result = this.tag.doStartTag();
assertEquals(Tag.SKIP_BODY, result);
String output = getOutput();
assertEquals("<select id=\"country\" name=\"country\"></select>", output);
}
@Test
public void withList() throws Exception {
this.tag.setPath("country");
this.tag.setItems(Country.getCountries());
assertList(true);
}
@Test
public void withResolvedList() throws Exception {
this.tag.setPath("country");
this.tag.setItems(Country.getCountries());
assertList(true);
}
@Test
public void withOtherValue() throws Exception {
TestBean tb = getTestBean();
tb.setCountry("AT");
this.tag.setPath("country");
this.tag.setItems(Country.getCountries());
assertList(false);
}
@Test
public void withNullValue() throws Exception {
TestBean tb = getTestBean();
tb.setCountry(null);
this.tag.setPath("country");
this.tag.setItems(Country.getCountries());
assertList(false);
}
@Test
public void withListAndNoLabel() throws Exception {
this.tag.setPath("country");
this.tag.setItems(Country.getCountries());
this.tag.setItemValue("isoCode");
int result = this.tag.doStartTag();
assertEquals(Tag.SKIP_BODY, result);
validateOutput(getOutput(), true);
}
@Test
public void withListAndTransformTag() throws Exception {
this.tag.setPath("country");
this.tag.setItems(Country.getCountries());
assertList(true);
TransformTag transformTag = new TransformTag();
transformTag.setValue(Country.getCountries().get(0));
transformTag.setVar("key");
transformTag.setParent(this.tag);
transformTag.setPageContext(getPageContext());
transformTag.doStartTag();
assertEquals("Austria(AT)", getPageContext().findAttribute("key"));
}
@Test
public void withListAndTransformTagAndEditor() throws Exception {
this.tag.setPath("realCountry");
this.tag.setItems(Country.getCountries());
BeanPropertyBindingResult bindingResult = new BeanPropertyBindingResult(getTestBean(), "testBean");
bindingResult.getPropertyAccessor().registerCustomEditor(Country.class, new PropertyEditorSupport() {
@Override
public void setAsText(String text) throws IllegalArgumentException {
setValue(Country.getCountryWithIsoCode(text));
}
@Override
public String getAsText() {
return ((Country) getValue()).getName();
}
});
getPageContext().getRequest().setAttribute(BindingResult.MODEL_KEY_PREFIX + "testBean", bindingResult);
this.tag.doStartTag();
TransformTag transformTag = new TransformTag();
transformTag.setValue(Country.getCountries().get(0));
transformTag.setVar("key");
transformTag.setParent(this.tag);
transformTag.setPageContext(getPageContext());
transformTag.doStartTag();
assertEquals("Austria", getPageContext().findAttribute("key"));
}
@Test
public void withListAndEditor() throws Exception {
this.tag.setPath("realCountry");
this.tag.setItems(Country.getCountries());
this.tag.setItemValue("isoCode");
this.tag.setItemLabel("name");
BeanPropertyBindingResult bindingResult = new BeanPropertyBindingResult(getTestBean(), "testBean");
bindingResult.getPropertyAccessor().registerCustomEditor(Country.class, new PropertyEditorSupport() {
@Override
public void setAsText(String text) throws IllegalArgumentException {
setValue(Country.getCountryWithIsoCode(text));
}
@Override
public String getAsText() {
return ((Country) getValue()).getName();
}
});
getPageContext().getRequest().setAttribute(BindingResult.MODEL_KEY_PREFIX + "testBean", bindingResult);
this.tag.doStartTag();
String output = getOutput();
assertTrue(output.startsWith("<select "));
assertTrue(output.endsWith("</select>"));
assertTrue(output.contains("option value=\"AT\" selected=\"selected\">Austria"));
}
@Test
public void nestedPathWithListAndEditorAndNullValue() throws Exception {
this.tag.setPath("bean.realCountry");
this.tag.setItems(Country.getCountries());
this.tag.setItemValue("isoCode");
this.tag.setItemLabel("name");
this.tag.setMultiple("false");
TestBeanWrapper testBean = new TestBeanWrapper();
TestBeanWithRealCountry withCountry = (TestBeanWithRealCountry) getTestBean();
withCountry.setRealCountry(null);
testBean.setBean(withCountry);
BeanPropertyBindingResult bindingResult = new BeanPropertyBindingResult(testBean , "testBean");
bindingResult.getPropertyAccessor().registerCustomEditor(Country.class, new PropertyEditorSupport() {
@Override
public void setAsText(String text) throws IllegalArgumentException {
if (text==null || text.length()==0) {
setValue(null);
return;
}
setValue(Country.getCountryWithIsoCode(text));
}
@Override
public String getAsText() {
Country value = (Country) getValue();
if (value==null) {
return null;
}
return value.getName();
}
});
getPageContext().getRequest().setAttribute(BindingResult.MODEL_KEY_PREFIX + "testBean", bindingResult);
this.tag.doStartTag();
String output = getOutput();
assertTrue(output.startsWith("<select "));
assertTrue(output.endsWith("</select>"));
assertFalse(output.contains("selected=\"selected\""));
assertFalse(output.contains("multiple=\"multiple\""));
}
@Test
public void nestedPathWithListAndEditor() throws Exception {
this.tag.setPath("bean.realCountry");
this.tag.setItems(Country.getCountries());
this.tag.setItemValue("isoCode");
this.tag.setItemLabel("name");
TestBeanWrapper testBean = new TestBeanWrapper();
testBean.setBean(getTestBean());
BeanPropertyBindingResult bindingResult = new BeanPropertyBindingResult(testBean , "testBean");
bindingResult.getPropertyAccessor().registerCustomEditor(Country.class, new PropertyEditorSupport() {
@Override
public void setAsText(String text) throws IllegalArgumentException {
setValue(Country.getCountryWithIsoCode(text));
}
@Override
public String getAsText() {
return ((Country) getValue()).getName();
}
});
getPageContext().getRequest().setAttribute(BindingResult.MODEL_KEY_PREFIX + "testBean", bindingResult);
this.tag.doStartTag();
String output = getOutput();
assertTrue(output.startsWith("<select "));
assertTrue(output.endsWith("</select>"));
assertTrue(output.contains("option value=\"AT\" selected=\"selected\">Austria"));
}
@Test
public void withListAndEditorAndNullValue() throws Exception {
this.tag.setPath("realCountry");
this.tag.setItems(Country.getCountries());
this.tag.setItemValue("isoCode");
this.tag.setItemLabel("name");
TestBeanWithRealCountry testBean = (TestBeanWithRealCountry) getTestBean();
testBean.setRealCountry(null);
BeanPropertyBindingResult bindingResult = new BeanPropertyBindingResult(testBean, "testBean");
bindingResult.getPropertyAccessor().registerCustomEditor(Country.class, new PropertyEditorSupport() {
@Override
public void setAsText(String text) throws IllegalArgumentException {
setValue(Country.getCountryWithIsoCode(text));
}
@Override
public String getAsText() {
Country value = (Country) getValue();
if (value==null) {
return "";
}
return value.getName();
}
});
getPageContext().getRequest().setAttribute(BindingResult.MODEL_KEY_PREFIX + "testBean", bindingResult);
this.tag.doStartTag();
String output = getOutput();
assertTrue(output.startsWith("<select "));
assertTrue(output.endsWith("</select>"));
assertFalse(output.contains("selected=\"selected\""));
}
@Test
public void withMap() throws Exception {
this.tag.setPath("sex");
this.tag.setItems(getSexes());
int result = this.tag.doStartTag();
assertEquals(Tag.SKIP_BODY, result);
}
@Test
public void withInvalidList() throws Exception {
this.tag.setPath("country");
this.tag.setItems(new TestBean());
this.tag.setItemValue("isoCode");
try {
this.tag.doStartTag();
fail("Must not be able to use a non-Collection typed value as the value of 'items'");
}
catch (JspException expected) {
String message = expected.getMessage();
assertTrue(message.contains("items"));
assertTrue(message.contains("org.springframework.tests.sample.beans.TestBean"));
}
}
@Test
public void withNestedOptions() throws Exception {
this.tag.setPath("country");
int result = this.tag.doStartTag();
assertEquals(Tag.EVAL_BODY_INCLUDE, result);
BindStatus value = (BindStatus) getPageContext().getAttribute(SelectTag.LIST_VALUE_PAGE_ATTRIBUTE);
assertEquals("Selected country not exposed in page context", "UK", value.getValue());
result = this.tag.doEndTag();
assertEquals(Tag.EVAL_PAGE, result);
this.tag.doFinally();
String output = getOutput();
assertTrue(output.startsWith("<select "));
assertTrue(output.endsWith("</select>"));
assertContainsAttribute(output, "name", "country");
}
@Test
public void withStringArray() throws Exception {
this.tag.setPath("name");
this.tag.setItems(getNames());
assertStringArray();
}
@Test
public void withResolvedStringArray() throws Exception {
this.tag.setPath("name");
this.tag.setItems(getNames());
assertStringArray();
}
@Test
public void withIntegerArray() throws Exception {
this.tag.setPath("someIntegerArray");
Integer[] array = new Integer[50];
for (int i = 0; i < array.length; i++) {
array[i] = new Integer(i);
}
this.tag.setItems(array);
int result = this.tag.doStartTag();
assertEquals(Tag.SKIP_BODY, result);
String output = getOutput();
output = "<doc>" + output + "</doc>";
SAXReader reader = new SAXReader();
Document document = reader.read(new StringReader(output));
Element rootElement = document.getRootElement();
assertEquals(2, rootElement.elements().size());
Element selectElement = rootElement.element("select");
assertEquals("select", selectElement.getName());
assertEquals("someIntegerArray", selectElement.attribute("name").getValue());
List children = selectElement.elements();
assertEquals("Incorrect number of children", array.length, children.size());
Element e = (Element) selectElement.selectSingleNode("option[text() = '12']");
assertEquals("'12' node not selected", "selected", e.attribute("selected").getValue());
e = (Element) selectElement.selectSingleNode("option[text() = '34']");
assertEquals("'34' node not selected", "selected", e.attribute("selected").getValue());
}
@Test
public void withFloatCustom() throws Exception {
PropertyEditor propertyEditor = new SimpleFloatEditor();
BeanPropertyBindingResult errors = new BeanPropertyBindingResult(getTestBean(), COMMAND_NAME);
errors.getPropertyAccessor().registerCustomEditor(Float.class, propertyEditor);
exposeBindingResult(errors);
this.tag.setPath("myFloat");
Float[] array = new Float[] {
new Float("12.30"), new Float("12.32"), new Float("12.34"), new Float("12.36"),
new Float("12.38"), new Float("12.40"), new Float("12.42"), new Float("12.44"),
new Float("12.46"), new Float("12.48")
};
this.tag.setItems(array);
int result = this.tag.doStartTag();
assertEquals(Tag.SKIP_BODY, result);
String output = getOutput();
assertTrue(output.startsWith("<select "));
assertTrue(output.endsWith("</select>"));
SAXReader reader = new SAXReader();
Document document = reader.read(new StringReader(output));
Element rootElement = document.getRootElement();
assertEquals("select", rootElement.getName());
assertEquals("myFloat", rootElement.attribute("name").getValue());
List children = rootElement.elements();
assertEquals("Incorrect number of children", array.length, children.size());
Element e = (Element) rootElement.selectSingleNode("option[text() = '12.34f']");
assertEquals("'12.34' node not selected", "selected", e.attribute("selected").getValue());
e = (Element) rootElement.selectSingleNode("option[text() = '12.32f']");
assertNull("'12.32' node incorrectly selected", e.attribute("selected"));
}
@Test
public void withMultiList() throws Exception {
List list = new ArrayList();
list.add(Country.COUNTRY_UK);
list.add(Country.COUNTRY_AT);
this.bean.setSomeList(list);
this.tag.setPath("someList");
this.tag.setItems(Country.getCountries());
this.tag.setItemValue("isoCode");
int result = this.tag.doStartTag();
assertEquals(Tag.SKIP_BODY, result);
String output = getOutput();
output = "<doc>" + output + "</doc>";
SAXReader reader = new SAXReader();
Document document = reader.read(new StringReader(output));
Element rootElement = document.getRootElement();
assertEquals(2, rootElement.elements().size());
Element selectElement = rootElement.element("select");
assertEquals("select", selectElement.getName());
assertEquals("someList", selectElement.attribute("name").getValue());
List children = selectElement.elements();
assertEquals("Incorrect number of children", 4, children.size());
Element e = (Element) selectElement.selectSingleNode("option[@value = 'UK']");
assertEquals("UK node not selected", "selected", e.attribute("selected").getValue());
assertEquals("United Kingdom(UK)", e.getText());
e = (Element) selectElement.selectSingleNode("option[@value = 'AT']");
assertEquals("AT node not selected", "selected", e.attribute("selected").getValue());
assertEquals("Austria(AT)", e.getText());
}
@Test
public void withElementFormatter() throws Exception {
this.bean.setRealCountry(Country.COUNTRY_UK);
BeanPropertyBindingResult errors = new BeanPropertyBindingResult(this.bean, COMMAND_NAME);
FormattingConversionService cs = new FormattingConversionService();
cs.addFormatterForFieldType(Country.class, new Formatter<Country>() {
@Override
public String print(Country object, Locale locale) {
return object.getName();
}
@Override
public Country parse(String text, Locale locale) throws ParseException {
return new Country(text, text);
}
});
errors.initConversion(cs);
exposeBindingResult(errors);
this.tag.setPath("realCountry");
this.tag.setItems(Country.getCountries());
this.tag.setItemValue("isoCode");
int result = this.tag.doStartTag();
assertEquals(Tag.SKIP_BODY, result);
String output = getOutput();
output = "<doc>" + output + "</doc>";
SAXReader reader = new SAXReader();
Document document = reader.read(new StringReader(output));
Element rootElement = document.getRootElement();
assertEquals(1, rootElement.elements().size());
Element selectElement = rootElement.element("select");
assertEquals("select", selectElement.getName());
assertEquals("realCountry", selectElement.attribute("name").getValue());
List children = selectElement.elements();
assertEquals("Incorrect number of children", 4, children.size());
Element e = (Element) selectElement.selectSingleNode("option[@value = 'UK']");
assertEquals("UK node not selected", "selected", e.attribute("selected").getValue());
assertEquals("United Kingdom", e.getText());
}
@Test
public void withMultiListAndElementFormatter() throws Exception {
List list = new ArrayList();
list.add(Country.COUNTRY_UK);
list.add(Country.COUNTRY_AT);
this.bean.setSomeList(list);
BeanPropertyBindingResult errors = new BeanPropertyBindingResult(this.bean, COMMAND_NAME);
FormattingConversionService cs = new FormattingConversionService();
cs.addFormatterForFieldType(Country.class, new Formatter<Country>() {
@Override
public String print(Country object, Locale locale) {
return object.getName();
}
@Override
public Country parse(String text, Locale locale) throws ParseException {
return new Country(text, text);
}
});
errors.initConversion(cs);
exposeBindingResult(errors);
this.tag.setPath("someList");
this.tag.setItems(Country.getCountries());
this.tag.setItemValue("isoCode");
int result = this.tag.doStartTag();
assertEquals(Tag.SKIP_BODY, result);
String output = getOutput();
output = "<doc>" + output + "</doc>";
SAXReader reader = new SAXReader();
Document document = reader.read(new StringReader(output));
Element rootElement = document.getRootElement();
assertEquals(2, rootElement.elements().size());
Element selectElement = rootElement.element("select");
assertEquals("select", selectElement.getName());
assertEquals("someList", selectElement.attribute("name").getValue());
List children = selectElement.elements();
assertEquals("Incorrect number of children", 4, children.size());
Element e = (Element) selectElement.selectSingleNode("option[@value = 'UK']");
assertEquals("UK node not selected", "selected", e.attribute("selected").getValue());
assertEquals("United Kingdom", e.getText());
e = (Element) selectElement.selectSingleNode("option[@value = 'AT']");
assertEquals("AT node not selected", "selected", e.attribute("selected").getValue());
assertEquals("Austria", e.getText());
}
@Test
public void withMultiListAndCustomEditor() throws Exception {
List list = new ArrayList();
list.add(Country.COUNTRY_UK);
list.add(Country.COUNTRY_AT);
this.bean.setSomeList(list);
BeanPropertyBindingResult errors = new BeanPropertyBindingResult(this.bean, COMMAND_NAME);
errors.getPropertyAccessor().registerCustomEditor(List.class, new CustomCollectionEditor(LinkedList.class) {
@Override
public String getAsText() {
return getValue().toString();
}
});
exposeBindingResult(errors);
this.tag.setPath("someList");
this.tag.setItems(Country.getCountries());
this.tag.setItemValue("isoCode");
int result = this.tag.doStartTag();
assertEquals(Tag.SKIP_BODY, result);
String output = getOutput();
output = "<doc>" + output + "</doc>";
SAXReader reader = new SAXReader();
Document document = reader.read(new StringReader(output));
Element rootElement = document.getRootElement();
assertEquals(2, rootElement.elements().size());
Element selectElement = rootElement.element("select");
assertEquals("select", selectElement.getName());
assertEquals("someList", selectElement.attribute("name").getValue());
List children = selectElement.elements();
assertEquals("Incorrect number of children", 4, children.size());
Element e = (Element) selectElement.selectSingleNode("option[@value = 'UK']");
assertEquals("UK node not selected", "selected", e.attribute("selected").getValue());
e = (Element) selectElement.selectSingleNode("option[@value = 'AT']");
assertEquals("AT node not selected", "selected", e.attribute("selected").getValue());
}
@Test
public void withMultiMap() throws Exception {
Map someMap = new HashMap();
someMap.put("M", "Male");
someMap.put("F", "Female");
this.bean.setSomeMap(someMap);
this.tag.setPath("someMap");
this.tag.setItems(getSexes());
int result = this.tag.doStartTag();
assertEquals(Tag.SKIP_BODY, result);
String output = getOutput();
output = "<doc>" + output + "</doc>";
SAXReader reader = new SAXReader();
Document document = reader.read(new StringReader(output));
Element rootElement = document.getRootElement();
assertEquals(2, rootElement.elements().size());
Element selectElement = rootElement.element("select");
assertEquals("select", selectElement.getName());
assertEquals("someMap", selectElement.attribute("name").getValue());
List children = selectElement.elements();
assertEquals("Incorrect number of children", 2, children.size());
Element e = (Element) selectElement.selectSingleNode("option[@value = 'M']");
assertEquals("M node not selected", "selected", e.attribute("selected").getValue());
e = (Element) selectElement.selectSingleNode("option[@value = 'F']");
assertEquals("F node not selected", "selected", e.attribute("selected").getValue());
}
/**
* Tests new support added as a result of <a
* href="http://opensource.atlassian.com/projects/spring/browse/SPR-2660"
* target="_blank">SPR-2660</a>.
* <p>
* Specifically, if the {@code items} attribute is supplied a
* {@link Map}, and {@code itemValue} and {@code itemLabel}
* are supplied non-null values, then:
* </p>
* <ul>
* <li>{@code itemValue} will be used as the property name of the
* map's <em>key</em>, and</li>
* <li>{@code itemLabel} will be used as the property name of the
* map's <em>value</em>.</li>
* </ul>
*/
@Test
public void withMultiMapWithItemValueAndItemLabel() throws Exception {
// Save original default locale.
final Locale defaultLocale = Locale.getDefault();
// Use a locale that doesn't result in the generation of HTML entities
// (e.g., not German, where \u00e4 becomes ä)
Locale.setDefault(Locale.US);
try {
final Country austria = Country.COUNTRY_AT;
final Country usa = Country.COUNTRY_US;
final Map someMap = new HashMap();
someMap.put(austria, LOCALE_AT);
someMap.put(usa, Locale.US);
this.bean.setSomeMap(someMap);
this.tag.setPath("someMap"); // see: TestBean
this.tag.setItems(getCountryToLocaleMap());
this.tag.setItemValue("isoCode"); // Map key: Country
this.tag.setItemLabel("displayLanguage"); // Map value: Locale
BeanPropertyBindingResult bindingResult = new BeanPropertyBindingResult(getTestBean(), COMMAND_NAME);
bindingResult.getPropertyAccessor().registerCustomEditor(Country.class, new PropertyEditorSupport() {
@Override
public void setAsText(final String text) throws IllegalArgumentException {
setValue(Country.getCountryWithIsoCode(text));
}
@Override
public String getAsText() {
return ((Country) getValue()).getIsoCode();
}
});
exposeBindingResult(bindingResult);
int result = this.tag.doStartTag();
assertEquals(Tag.SKIP_BODY, result);
String output = getOutput();
output = "<doc>" + output + "</doc>";
SAXReader reader = new SAXReader();
Document document = reader.read(new StringReader(output));
Element rootElement = document.getRootElement();
assertEquals(2, rootElement.elements().size());
Element selectElement = rootElement.element("select");
assertEquals("select", selectElement.getName());
assertEquals("someMap", selectElement.attribute("name").getValue());
List children = selectElement.elements();
assertEquals("Incorrect number of children", 3, children.size());
Element e;
e = (Element) selectElement.selectSingleNode("option[@value = '" + austria.getIsoCode() + "']");
assertNotNull("Option node not found with Country ISO code value [" + austria.getIsoCode() + "].", e);
assertEquals("AT node not selected.", "selected", e.attribute("selected").getValue());
assertEquals("AT Locale displayLanguage property not used for option label.",
LOCALE_AT.getDisplayLanguage(), e.getData());
e = (Element) selectElement.selectSingleNode("option[@value = '" + usa.getIsoCode() + "']");
assertNotNull("Option node not found with Country ISO code value [" + usa.getIsoCode() + "].", e);
assertEquals("US node not selected.", "selected", e.attribute("selected").getValue());
assertEquals("US Locale displayLanguage property not used for option label.",
Locale.US.getDisplayLanguage(), e.getData());
}
finally {
// Restore original default locale.
Locale.setDefault(defaultLocale);
}
}
@Test
public void multipleForCollection() throws Exception {
this.bean.setSomeList(new ArrayList());
this.tag.setPath("someList");
this.tag.setItems(Country.getCountries());
this.tag.setItemValue("isoCode");
int result = this.tag.doStartTag();
assertEquals(Tag.SKIP_BODY, result);
String output = getOutput();
output = "<doc>" + output + "</doc>";
SAXReader reader = new SAXReader();
Document document = reader.read(new StringReader(output));
Element rootElement = document.getRootElement();
assertEquals(2, rootElement.elements().size());
Element selectElement = rootElement.element("select");
assertEquals("select", selectElement.getName());
assertEquals("someList", selectElement.attribute("name").getValue());
assertEquals("multiple", selectElement.attribute("multiple").getValue());
List children = selectElement.elements();
assertEquals("Incorrect number of children", 4, children.size());
Element inputElement = rootElement.element("input");
assertNotNull(inputElement);
}
@Test
public void multipleWithStringValue() throws Exception {
this.tag.setPath("name");
this.tag.setItems(Country.getCountries());
this.tag.setItemValue("isoCode");
this.tag.setMultiple("multiple");
int result = this.tag.doStartTag();
assertEquals(Tag.SKIP_BODY, result);
String output = getOutput();
output = "<doc>" + output + "</doc>";
SAXReader reader = new SAXReader();
Document document = reader.read(new StringReader(output));
Element rootElement = document.getRootElement();
assertEquals(2, rootElement.elements().size());
Element selectElement = rootElement.element("select");
assertEquals("select", selectElement.getName());
assertEquals("name", selectElement.attribute("name").getValue());
assertEquals("multiple", selectElement.attribute("multiple").getValue());
List children = selectElement.elements();
assertEquals("Incorrect number of children", 4, children.size());
Element inputElement = rootElement.element("input");
assertNotNull(inputElement);
}
@Test
public void multipleExplicitlyTrue() throws Exception {
this.tag.setPath("name");
this.tag.setItems(Country.getCountries());
this.tag.setItemValue("isoCode");
this.tag.setMultiple("true");
int result = this.tag.doStartTag();
assertEquals(Tag.SKIP_BODY, result);
String output = getOutput();
output = "<doc>" + output + "</doc>";
SAXReader reader = new SAXReader();
Document document = reader.read(new StringReader(output));
Element rootElement = document.getRootElement();
assertEquals(2, rootElement.elements().size());
Element selectElement = rootElement.element("select");
assertEquals("select", selectElement.getName());
assertEquals("name", selectElement.attribute("name").getValue());
assertEquals("multiple", selectElement.attribute("multiple").getValue());
List children = selectElement.elements();
assertEquals("Incorrect number of children", 4, children.size());
Element inputElement = rootElement.element("input");
assertNotNull(inputElement);
}
@Test
public void multipleExplicitlyFalse() throws Exception {
this.tag.setPath("name");
this.tag.setItems(Country.getCountries());
this.tag.setItemValue("isoCode");
this.tag.setMultiple("false");
int result = this.tag.doStartTag();
assertEquals(Tag.SKIP_BODY, result);
String output = getOutput();
output = "<doc>" + output + "</doc>";
SAXReader reader = new SAXReader();
Document document = reader.read(new StringReader(output));
Element rootElement = document.getRootElement();
assertEquals(1, rootElement.elements().size());
Element selectElement = rootElement.element("select");
assertEquals("select", selectElement.getName());
assertEquals("name", selectElement.attribute("name").getValue());
assertNull(selectElement.attribute("multiple"));
List children = selectElement.elements();
assertEquals("Incorrect number of children", 4, children.size());
}
@Test
public void multipleWithBooleanTrue() throws Exception {
this.tag.setPath("name");
this.tag.setItems(Country.getCountries());
this.tag.setItemValue("isoCode");
this.tag.setMultiple(true);
int result = this.tag.doStartTag();
assertEquals(Tag.SKIP_BODY, result);
String output = getOutput();
output = "<doc>" + output + "</doc>";
SAXReader reader = new SAXReader();
Document document = reader.read(new StringReader(output));
Element rootElement = document.getRootElement();
assertEquals(2, rootElement.elements().size());
Element selectElement = rootElement.element("select");
assertEquals("select", selectElement.getName());
assertEquals("name", selectElement.attribute("name").getValue());
assertEquals("multiple", selectElement.attribute("multiple").getValue());
List children = selectElement.elements();
assertEquals("Incorrect number of children", 4, children.size());
Element inputElement = rootElement.element("input");
assertNotNull(inputElement);
}
@Test
public void multipleWithBooleanFalse() throws Exception {
this.tag.setPath("name");
this.tag.setItems(Country.getCountries());
this.tag.setItemValue("isoCode");
this.tag.setMultiple(false);
int result = this.tag.doStartTag();
assertEquals(Tag.SKIP_BODY, result);
String output = getOutput();
output = "<doc>" + output + "</doc>";
SAXReader reader = new SAXReader();
Document document = reader.read(new StringReader(output));
Element rootElement = document.getRootElement();
assertEquals(1, rootElement.elements().size());
Element selectElement = rootElement.element("select");
assertEquals("select", selectElement.getName());
assertEquals("name", selectElement.attribute("name").getValue());
assertNull(selectElement.attribute("multiple"));
List children = selectElement.elements();
assertEquals("Incorrect number of children", 4, children.size());
}
private void assertStringArray() throws JspException, DocumentException {
int result = this.tag.doStartTag();
assertEquals(Tag.SKIP_BODY, result);
String output = getOutput();
assertTrue(output.startsWith("<select "));
assertTrue(output.endsWith("</select>"));
SAXReader reader = new SAXReader();
Document document = reader.read(new StringReader(output));
Element rootElement = document.getRootElement();
assertEquals("select", rootElement.getName());
assertEquals("name", rootElement.attribute("name").getValue());
List children = rootElement.elements();
assertEquals("Incorrect number of children", 4, children.size());
Element e = (Element) rootElement.selectSingleNode("option[text() = 'Rob']");
assertEquals("Rob node not selected", "selected", e.attribute("selected").getValue());
}
private Map getCountryToLocaleMap() {
Map map = new TreeMap(new Comparator() {
@Override
public int compare(Object o1, Object o2) {
return ((Country)o1).getName().compareTo(((Country)o2).getName());
}
});
map.put(Country.COUNTRY_AT, LOCALE_AT);
map.put(Country.COUNTRY_NL, LOCALE_NL);
map.put(Country.COUNTRY_US, Locale.US);
return map;
}
private String[] getNames() {
return new String[]{"Rod", "Rob", "Juergen", "Adrian"};
}
private Map getSexes() {
Map<String, String> sexes = new HashMap<>();
sexes.put("F", "Female");
sexes.put("M", "Male");
return sexes;
}
private void assertList(boolean selected) throws JspException, DocumentException {
this.tag.setItemValue("isoCode");
this.tag.setItemLabel("name");
this.tag.setSize("5");
int result = this.tag.doStartTag();
assertEquals(Tag.SKIP_BODY, result);
String output = getOutput();
validateOutput(output, selected);
assertContainsAttribute(output, "size", "5");
}
private void validateOutput(String output, boolean selected) throws DocumentException {
SAXReader reader = new SAXReader();
Document document = reader.read(new StringReader(output));
Element rootElement = document.getRootElement();
assertEquals("select", rootElement.getName());
assertEquals("country", rootElement.attribute("name").getValue());
List children = rootElement.elements();
assertEquals("Incorrect number of children", 4, children.size());
Element e = (Element) rootElement.selectSingleNode("option[@value = 'UK']");
Attribute selectedAttr = e.attribute("selected");
if (selected) {
assertTrue(selectedAttr != null && "selected".equals(selectedAttr.getValue()));
}
else {
assertNull(selectedAttr);
}
}
@Override
protected TestBean createTestBean() {
this.bean = new TestBeanWithRealCountry();
this.bean.setName("Rob");
this.bean.setCountry("UK");
this.bean.setSex("M");
this.bean.setMyFloat(new Float("12.34"));
this.bean.setSomeIntegerArray(new Integer[]{new Integer(12), new Integer(34)});
return this.bean;
}
private TestBean getTestBean() {
return (TestBean) getPageContext().getRequest().getAttribute(COMMAND_NAME);
}
public static class TestBeanWrapper {
private TestBean bean;
public TestBean getBean() {
return bean;
}
public void setBean(TestBean bean) {
this.bean = bean;
}
}
}