PageRenderTime 44ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 0ms

/projects/springframework-3.0.5/projects/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/tags/form/SelectTagTests.java

https://gitlab.com/essere.lab.public/qualitas.class-corpus
Java | 863 lines | 679 code | 143 blank | 41 comment | 9 complexity | 46af52ed9d194a6b384d62e2054dd4d9 MD5 | raw file
  1. /*
  2. * Copyright 2002-2010 the original author or authors.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package org.springframework.web.servlet.tags.form;
  17. import java.beans.PropertyEditor;
  18. import java.beans.PropertyEditorSupport;
  19. import java.io.StringReader;
  20. import java.text.ParseException;
  21. import java.util.ArrayList;
  22. import java.util.Collections;
  23. import java.util.Comparator;
  24. import java.util.HashMap;
  25. import java.util.LinkedList;
  26. import java.util.List;
  27. import java.util.Locale;
  28. import java.util.Map;
  29. import java.util.TreeMap;
  30. import javax.servlet.jsp.JspException;
  31. import javax.servlet.jsp.tagext.Tag;
  32. import org.dom4j.Attribute;
  33. import org.dom4j.Document;
  34. import org.dom4j.DocumentException;
  35. import org.dom4j.Element;
  36. import org.dom4j.io.SAXReader;
  37. import org.springframework.beans.TestBean;
  38. import org.springframework.beans.propertyeditors.CustomCollectionEditor;
  39. import org.springframework.format.Formatter;
  40. import org.springframework.format.support.FormattingConversionService;
  41. import org.springframework.mock.web.MockHttpServletRequest;
  42. import org.springframework.validation.BeanPropertyBindingResult;
  43. import org.springframework.validation.BindingResult;
  44. import org.springframework.web.servlet.support.BindStatus;
  45. import org.springframework.web.servlet.tags.TransformTag;
  46. /**
  47. * @author Rob Harrop
  48. * @author Juergen Hoeller
  49. * @author Jeremy Grelle
  50. * @author Dave Syer
  51. */
  52. public class SelectTagTests extends AbstractFormTagTests {
  53. private static final Locale LOCALE_AT = new Locale("de", "AT");
  54. private static final Locale LOCALE_NL = new Locale("nl", "NL");
  55. private SelectTag tag;
  56. private TestBeanWithRealCountry bean;
  57. protected void onSetUp() {
  58. this.tag = new SelectTag() {
  59. protected TagWriter createTagWriter() {
  60. return new TagWriter(getWriter());
  61. }
  62. };
  63. this.tag.setPageContext(getPageContext());
  64. }
  65. public void testDynamicAttributes() throws JspException {
  66. String dynamicAttribute1 = "attr1";
  67. String dynamicAttribute2 = "attr2";
  68. this.tag.setPath("country");
  69. this.tag.setItems(Collections.EMPTY_LIST);
  70. this.tag.setItemValue("isoCode");
  71. this.tag.setItemLabel("name");
  72. this.tag.setDynamicAttribute(null, dynamicAttribute1, dynamicAttribute1);
  73. this.tag.setDynamicAttribute(null, dynamicAttribute2, dynamicAttribute2);
  74. int result = this.tag.doStartTag();
  75. assertEquals(Tag.SKIP_BODY, result);
  76. String output = getOutput();
  77. assertContainsAttribute(output, dynamicAttribute1, dynamicAttribute1);
  78. assertContainsAttribute(output, dynamicAttribute2, dynamicAttribute2);
  79. }
  80. public void testEmptyItems() throws Exception {
  81. this.tag.setPath("country");
  82. this.tag.setItems(Collections.EMPTY_LIST);
  83. this.tag.setItemValue("isoCode");
  84. this.tag.setItemLabel("name");
  85. int result = this.tag.doStartTag();
  86. assertEquals(Tag.SKIP_BODY, result);
  87. String output = getOutput();
  88. assertEquals("<select id=\"country\" name=\"country\"></select>", output);
  89. }
  90. public void testNullItems() throws Exception {
  91. this.tag.setPath("country");
  92. this.tag.setItems(null);
  93. this.tag.setItemValue("isoCode");
  94. this.tag.setItemLabel("name");
  95. int result = this.tag.doStartTag();
  96. assertEquals(Tag.SKIP_BODY, result);
  97. String output = getOutput();
  98. assertEquals("<select id=\"country\" name=\"country\"></select>", output);
  99. }
  100. public void testWithList() throws Exception {
  101. this.tag.setPath("country");
  102. this.tag.setItems(Country.getCountries());
  103. assertList(true);
  104. }
  105. public void testWithResolvedList() throws Exception {
  106. this.tag.setPath("country");
  107. this.tag.setItems("${countries}");
  108. assertList(true);
  109. }
  110. public void testWithOtherValue() throws Exception {
  111. TestBean tb = getTestBean();
  112. tb.setCountry("AT");
  113. this.tag.setPath("country");
  114. this.tag.setItems(Country.getCountries());
  115. assertList(false);
  116. }
  117. public void testWithNullValue() throws Exception {
  118. TestBean tb = getTestBean();
  119. tb.setCountry(null);
  120. this.tag.setPath("country");
  121. this.tag.setItems(Country.getCountries());
  122. assertList(false);
  123. }
  124. public void testWithListAndNoLabel() throws Exception {
  125. this.tag.setPath("country");
  126. this.tag.setItems("${countries}");
  127. this.tag.setItemValue("isoCode");
  128. int result = this.tag.doStartTag();
  129. assertEquals(Tag.SKIP_BODY, result);
  130. validateOutput(getOutput(), true);
  131. }
  132. public void testWithListAndTransformTag() throws Exception {
  133. this.tag.setPath("country");
  134. this.tag.setItems(Country.getCountries());
  135. assertList(true);
  136. TransformTag transformTag = new TransformTag();
  137. transformTag.setValue(Country.getCountries().get(0));
  138. transformTag.setVar("key");
  139. transformTag.setParent(this.tag);
  140. transformTag.setPageContext(getPageContext());
  141. transformTag.doStartTag();
  142. assertEquals("Austria(AT)", getPageContext().findAttribute("key"));
  143. }
  144. public void testWithListAndTransformTagAndEditor() throws Exception {
  145. this.tag.setPath("realCountry");
  146. this.tag.setItems("${countries}");
  147. BeanPropertyBindingResult bindingResult = new BeanPropertyBindingResult(getTestBean(), "testBean");
  148. bindingResult.getPropertyAccessor().registerCustomEditor(Country.class, new PropertyEditorSupport() {
  149. public void setAsText(String text) throws IllegalArgumentException {
  150. setValue(Country.getCountryWithIsoCode(text));
  151. }
  152. public String getAsText() {
  153. return ((Country) getValue()).getName();
  154. }
  155. });
  156. getPageContext().getRequest().setAttribute(BindingResult.MODEL_KEY_PREFIX + "testBean", bindingResult);
  157. this.tag.doStartTag();
  158. TransformTag transformTag = new TransformTag();
  159. transformTag.setValue(Country.getCountries().get(0));
  160. transformTag.setVar("key");
  161. transformTag.setParent(this.tag);
  162. transformTag.setPageContext(getPageContext());
  163. transformTag.doStartTag();
  164. String output = getOutput();
  165. System.err.println(output);
  166. assertEquals("Austria", getPageContext().findAttribute("key"));
  167. }
  168. public void testWithListAndEditor() throws Exception {
  169. this.tag.setPath("realCountry");
  170. this.tag.setItems("${countries}");
  171. this.tag.setItemValue("isoCode");
  172. this.tag.setItemLabel("name");
  173. BeanPropertyBindingResult bindingResult = new BeanPropertyBindingResult(getTestBean(), "testBean");
  174. bindingResult.getPropertyAccessor().registerCustomEditor(Country.class, new PropertyEditorSupport() {
  175. public void setAsText(String text) throws IllegalArgumentException {
  176. setValue(Country.getCountryWithIsoCode(text));
  177. }
  178. public String getAsText() {
  179. return ((Country) getValue()).getName();
  180. }
  181. });
  182. getPageContext().getRequest().setAttribute(BindingResult.MODEL_KEY_PREFIX + "testBean", bindingResult);
  183. this.tag.doStartTag();
  184. String output = getOutput();
  185. assertTrue(output.startsWith("<select "));
  186. assertTrue(output.endsWith("</select>"));
  187. assertTrue(output.contains("option value=\"AT\" selected=\"selected\">Austria"));
  188. }
  189. public void testNestedPathWithListAndEditorAndNullValue() throws Exception {
  190. this.tag.setPath("bean.realCountry");
  191. this.tag.setItems("${countries}");
  192. this.tag.setItemValue("isoCode");
  193. this.tag.setItemLabel("name");
  194. this.tag.setMultiple("false");
  195. TestBeanWrapper testBean = new TestBeanWrapper();
  196. TestBeanWithRealCountry withCountry = (TestBeanWithRealCountry) getTestBean();
  197. withCountry.setRealCountry(null);
  198. testBean.setBean(withCountry);
  199. BeanPropertyBindingResult bindingResult = new BeanPropertyBindingResult(testBean , "testBean");
  200. bindingResult.getPropertyAccessor().registerCustomEditor(Country.class, new PropertyEditorSupport() {
  201. public void setAsText(String text) throws IllegalArgumentException {
  202. if (text==null || text.length()==0) {
  203. setValue(null);
  204. return;
  205. }
  206. setValue(Country.getCountryWithIsoCode(text));
  207. }
  208. public String getAsText() {
  209. Country value = (Country) getValue();
  210. if (value==null) {
  211. return null;
  212. }
  213. return ((Country) value).getName();
  214. }
  215. });
  216. getPageContext().getRequest().setAttribute(BindingResult.MODEL_KEY_PREFIX + "testBean", bindingResult);
  217. this.tag.doStartTag();
  218. String output = getOutput();
  219. System.err.println(output);
  220. assertTrue(output.startsWith("<select "));
  221. assertTrue(output.endsWith("</select>"));
  222. assertFalse(output.contains("selected=\"selected\""));
  223. }
  224. public void testNestedPathWithListAndEditor() throws Exception {
  225. this.tag.setPath("bean.realCountry");
  226. this.tag.setItems("${countries}");
  227. this.tag.setItemValue("isoCode");
  228. this.tag.setItemLabel("name");
  229. TestBeanWrapper testBean = new TestBeanWrapper();
  230. testBean.setBean(getTestBean());
  231. BeanPropertyBindingResult bindingResult = new BeanPropertyBindingResult(testBean , "testBean");
  232. bindingResult.getPropertyAccessor().registerCustomEditor(Country.class, new PropertyEditorSupport() {
  233. public void setAsText(String text) throws IllegalArgumentException {
  234. setValue(Country.getCountryWithIsoCode(text));
  235. }
  236. public String getAsText() {
  237. return ((Country) getValue()).getName();
  238. }
  239. });
  240. getPageContext().getRequest().setAttribute(BindingResult.MODEL_KEY_PREFIX + "testBean", bindingResult);
  241. this.tag.doStartTag();
  242. String output = getOutput();
  243. assertTrue(output.startsWith("<select "));
  244. assertTrue(output.endsWith("</select>"));
  245. assertTrue(output.contains("option value=\"AT\" selected=\"selected\">Austria"));
  246. }
  247. public void testWithListAndEditorAndNullValue() throws Exception {
  248. this.tag.setPath("realCountry");
  249. this.tag.setItems("${countries}");
  250. this.tag.setItemValue("isoCode");
  251. this.tag.setItemLabel("name");
  252. TestBeanWithRealCountry testBean = (TestBeanWithRealCountry) getTestBean();
  253. testBean.setRealCountry(null);
  254. BeanPropertyBindingResult bindingResult = new BeanPropertyBindingResult(testBean, "testBean");
  255. bindingResult.getPropertyAccessor().registerCustomEditor(Country.class, new PropertyEditorSupport() {
  256. public void setAsText(String text) throws IllegalArgumentException {
  257. setValue(Country.getCountryWithIsoCode(text));
  258. }
  259. public String getAsText() {
  260. Country value = (Country) getValue();
  261. if (value==null) {
  262. return "";
  263. }
  264. return ((Country) value).getName();
  265. }
  266. });
  267. getPageContext().getRequest().setAttribute(BindingResult.MODEL_KEY_PREFIX + "testBean", bindingResult);
  268. this.tag.doStartTag();
  269. String output = getOutput();
  270. System.err.println(output);
  271. assertTrue(output.startsWith("<select "));
  272. assertTrue(output.endsWith("</select>"));
  273. assertFalse(output.contains("selected=\"selected\""));
  274. }
  275. public void testWithMap() throws Exception {
  276. this.tag.setPath("sex");
  277. this.tag.setItems("${sexes}");
  278. int result = this.tag.doStartTag();
  279. assertEquals(Tag.SKIP_BODY, result);
  280. }
  281. public void testWithInvalidList() throws Exception {
  282. this.tag.setPath("country");
  283. this.tag.setItems("${other}");
  284. this.tag.setItemValue("isoCode");
  285. try {
  286. this.tag.doStartTag();
  287. fail("Must not be able to use a non-Collection typed value as the value of 'items'");
  288. }
  289. catch (JspException expected) {
  290. String message = expected.getMessage();
  291. assertTrue(message.indexOf("items") > -1);
  292. assertTrue(message.indexOf("org.springframework.beans.TestBean") > -1);
  293. }
  294. }
  295. public void testWithNestedOptions() throws Exception {
  296. this.tag.setPath("country");
  297. int result = this.tag.doStartTag();
  298. assertEquals(Tag.EVAL_BODY_INCLUDE, result);
  299. BindStatus value = (BindStatus) getPageContext().getAttribute(SelectTag.LIST_VALUE_PAGE_ATTRIBUTE);
  300. assertEquals("Selected country not exposed in page context", "UK", value.getValue());
  301. result = this.tag.doEndTag();
  302. assertEquals(Tag.EVAL_PAGE, result);
  303. this.tag.doFinally();
  304. String output = getOutput();
  305. assertTrue(output.startsWith("<select "));
  306. assertTrue(output.endsWith("</select>"));
  307. assertContainsAttribute(output, "name", "country");
  308. }
  309. public void testWithStringArray() throws Exception {
  310. this.tag.setPath("name");
  311. this.tag.setItems(getNames());
  312. assertStringArray();
  313. }
  314. public void testWithResolvedStringArray() throws Exception {
  315. this.tag.setPath("name");
  316. this.tag.setItems("${names}");
  317. assertStringArray();
  318. }
  319. public void testWithIntegerArray() throws Exception {
  320. this.tag.setPath("someIntegerArray");
  321. Integer[] array = new Integer[50];
  322. for (int i = 0; i < array.length; i++) {
  323. array[i] = new Integer(i);
  324. }
  325. this.tag.setItems(array);
  326. int result = this.tag.doStartTag();
  327. assertEquals(Tag.SKIP_BODY, result);
  328. String output = getOutput();
  329. output = "<doc>" + output + "</doc>";
  330. SAXReader reader = new SAXReader();
  331. Document document = reader.read(new StringReader(output));
  332. Element rootElement = document.getRootElement();
  333. assertEquals(2, rootElement.elements().size());
  334. Element selectElement = rootElement.element("select");
  335. assertEquals("select", selectElement.getName());
  336. assertEquals("someIntegerArray", selectElement.attribute("name").getValue());
  337. List children = selectElement.elements();
  338. assertEquals("Incorrect number of children", array.length, children.size());
  339. Element e = (Element) selectElement.selectSingleNode("option[text() = '12']");
  340. assertEquals("'12' node not selected", "selected", e.attribute("selected").getValue());
  341. e = (Element) selectElement.selectSingleNode("option[text() = '34']");
  342. assertEquals("'34' node not selected", "selected", e.attribute("selected").getValue());
  343. }
  344. public void testWithFloatCustom() throws Exception {
  345. PropertyEditor propertyEditor = new SimpleFloatEditor();
  346. BeanPropertyBindingResult errors = new BeanPropertyBindingResult(getTestBean(), COMMAND_NAME);
  347. errors.getPropertyAccessor().registerCustomEditor(Float.class, propertyEditor);
  348. exposeBindingResult(errors);
  349. this.tag.setPath("myFloat");
  350. Float[] array = new Float[] {
  351. new Float("12.30"), new Float("12.32"), new Float("12.34"), new Float("12.36"),
  352. new Float("12.38"), new Float("12.40"), new Float("12.42"), new Float("12.44"),
  353. new Float("12.46"), new Float("12.48")
  354. };
  355. this.tag.setItems(array);
  356. int result = this.tag.doStartTag();
  357. assertEquals(Tag.SKIP_BODY, result);
  358. String output = getOutput();
  359. assertTrue(output.startsWith("<select "));
  360. assertTrue(output.endsWith("</select>"));
  361. SAXReader reader = new SAXReader();
  362. Document document = reader.read(new StringReader(output));
  363. Element rootElement = document.getRootElement();
  364. assertEquals("select", rootElement.getName());
  365. assertEquals("myFloat", rootElement.attribute("name").getValue());
  366. List children = rootElement.elements();
  367. assertEquals("Incorrect number of children", array.length, children.size());
  368. Element e = (Element) rootElement.selectSingleNode("option[text() = '12.34f']");
  369. assertEquals("'12.34' node not selected", "selected", e.attribute("selected").getValue());
  370. e = (Element) rootElement.selectSingleNode("option[text() = '12.32f']");
  371. assertNull("'12.32' node incorrectly selected", e.attribute("selected"));
  372. }
  373. public void testWithMultiList() throws Exception {
  374. List list = new ArrayList();
  375. list.add(Country.COUNTRY_UK);
  376. list.add(Country.COUNTRY_AT);
  377. this.bean.setSomeList(list);
  378. this.tag.setPath("someList");
  379. this.tag.setItems("${countries}");
  380. this.tag.setItemValue("isoCode");
  381. int result = this.tag.doStartTag();
  382. assertEquals(Tag.SKIP_BODY, result);
  383. String output = getOutput();
  384. output = "<doc>" + output + "</doc>";
  385. SAXReader reader = new SAXReader();
  386. Document document = reader.read(new StringReader(output));
  387. Element rootElement = document.getRootElement();
  388. assertEquals(2, rootElement.elements().size());
  389. Element selectElement = rootElement.element("select");
  390. assertEquals("select", selectElement.getName());
  391. assertEquals("someList", selectElement.attribute("name").getValue());
  392. List children = selectElement.elements();
  393. assertEquals("Incorrect number of children", 4, children.size());
  394. Element e = (Element) selectElement.selectSingleNode("option[@value = 'UK']");
  395. assertEquals("UK node not selected", "selected", e.attribute("selected").getValue());
  396. assertEquals("United Kingdom(UK)", e.getText());
  397. e = (Element) selectElement.selectSingleNode("option[@value = 'AT']");
  398. assertEquals("AT node not selected", "selected", e.attribute("selected").getValue());
  399. assertEquals("Austria(AT)", e.getText());
  400. }
  401. public void testWithElementFormatter() throws Exception {
  402. this.bean.setRealCountry(Country.COUNTRY_UK);
  403. BeanPropertyBindingResult errors = new BeanPropertyBindingResult(this.bean, COMMAND_NAME);
  404. FormattingConversionService cs = new FormattingConversionService();
  405. cs.addFormatterForFieldType(Country.class, new Formatter<Country>() {
  406. public String print(Country object, Locale locale) {
  407. return object.getName();
  408. }
  409. public Country parse(String text, Locale locale) throws ParseException {
  410. return new Country(text, text);
  411. }
  412. });
  413. errors.initConversion(cs);
  414. exposeBindingResult(errors);
  415. this.tag.setPath("realCountry");
  416. this.tag.setItems("${countries}");
  417. this.tag.setItemValue("isoCode");
  418. int result = this.tag.doStartTag();
  419. assertEquals(Tag.SKIP_BODY, result);
  420. String output = getOutput();
  421. output = "<doc>" + output + "</doc>";
  422. SAXReader reader = new SAXReader();
  423. Document document = reader.read(new StringReader(output));
  424. Element rootElement = document.getRootElement();
  425. assertEquals(1, rootElement.elements().size());
  426. Element selectElement = rootElement.element("select");
  427. assertEquals("select", selectElement.getName());
  428. assertEquals("realCountry", selectElement.attribute("name").getValue());
  429. List children = selectElement.elements();
  430. assertEquals("Incorrect number of children", 4, children.size());
  431. Element e = (Element) selectElement.selectSingleNode("option[@value = 'UK']");
  432. assertEquals("UK node not selected", "selected", e.attribute("selected").getValue());
  433. assertEquals("United Kingdom", e.getText());
  434. }
  435. public void testWithMultiListAndElementFormatter() throws Exception {
  436. List list = new ArrayList();
  437. list.add(Country.COUNTRY_UK);
  438. list.add(Country.COUNTRY_AT);
  439. this.bean.setSomeList(list);
  440. BeanPropertyBindingResult errors = new BeanPropertyBindingResult(this.bean, COMMAND_NAME);
  441. FormattingConversionService cs = new FormattingConversionService();
  442. cs.addFormatterForFieldType(Country.class, new Formatter<Country>() {
  443. public String print(Country object, Locale locale) {
  444. return object.getName();
  445. }
  446. public Country parse(String text, Locale locale) throws ParseException {
  447. return new Country(text, text);
  448. }
  449. });
  450. errors.initConversion(cs);
  451. exposeBindingResult(errors);
  452. this.tag.setPath("someList");
  453. this.tag.setItems("${countries}");
  454. this.tag.setItemValue("isoCode");
  455. int result = this.tag.doStartTag();
  456. assertEquals(Tag.SKIP_BODY, result);
  457. String output = getOutput();
  458. output = "<doc>" + output + "</doc>";
  459. SAXReader reader = new SAXReader();
  460. Document document = reader.read(new StringReader(output));
  461. Element rootElement = document.getRootElement();
  462. assertEquals(2, rootElement.elements().size());
  463. Element selectElement = rootElement.element("select");
  464. assertEquals("select", selectElement.getName());
  465. assertEquals("someList", selectElement.attribute("name").getValue());
  466. List children = selectElement.elements();
  467. assertEquals("Incorrect number of children", 4, children.size());
  468. Element e = (Element) selectElement.selectSingleNode("option[@value = 'UK']");
  469. assertEquals("UK node not selected", "selected", e.attribute("selected").getValue());
  470. assertEquals("United Kingdom", e.getText());
  471. e = (Element) selectElement.selectSingleNode("option[@value = 'AT']");
  472. assertEquals("AT node not selected", "selected", e.attribute("selected").getValue());
  473. assertEquals("Austria", e.getText());
  474. }
  475. public void testWithMultiListAndCustomEditor() throws Exception {
  476. List list = new ArrayList();
  477. list.add(Country.COUNTRY_UK);
  478. list.add(Country.COUNTRY_AT);
  479. this.bean.setSomeList(list);
  480. BeanPropertyBindingResult errors = new BeanPropertyBindingResult(this.bean, COMMAND_NAME);
  481. errors.getPropertyAccessor().registerCustomEditor(List.class, new CustomCollectionEditor(LinkedList.class) {
  482. public String getAsText() {
  483. return getValue().toString();
  484. }
  485. });
  486. exposeBindingResult(errors);
  487. this.tag.setPath("someList");
  488. this.tag.setItems("${countries}");
  489. this.tag.setItemValue("isoCode");
  490. int result = this.tag.doStartTag();
  491. assertEquals(Tag.SKIP_BODY, result);
  492. String output = getOutput();
  493. output = "<doc>" + output + "</doc>";
  494. SAXReader reader = new SAXReader();
  495. Document document = reader.read(new StringReader(output));
  496. Element rootElement = document.getRootElement();
  497. assertEquals(2, rootElement.elements().size());
  498. Element selectElement = rootElement.element("select");
  499. assertEquals("select", selectElement.getName());
  500. assertEquals("someList", selectElement.attribute("name").getValue());
  501. List children = selectElement.elements();
  502. assertEquals("Incorrect number of children", 4, children.size());
  503. Element e = (Element) selectElement.selectSingleNode("option[@value = 'UK']");
  504. assertEquals("UK node not selected", "selected", e.attribute("selected").getValue());
  505. e = (Element) selectElement.selectSingleNode("option[@value = 'AT']");
  506. assertEquals("AT node not selected", "selected", e.attribute("selected").getValue());
  507. }
  508. public void testWithMultiMap() throws Exception {
  509. Map someMap = new HashMap();
  510. someMap.put("M", "Male");
  511. someMap.put("F", "Female");
  512. this.bean.setSomeMap(someMap);
  513. this.tag.setPath("someMap");
  514. this.tag.setItems("${sexes}");
  515. int result = this.tag.doStartTag();
  516. assertEquals(Tag.SKIP_BODY, result);
  517. String output = getOutput();
  518. output = "<doc>" + output + "</doc>";
  519. SAXReader reader = new SAXReader();
  520. Document document = reader.read(new StringReader(output));
  521. Element rootElement = document.getRootElement();
  522. assertEquals(2, rootElement.elements().size());
  523. Element selectElement = rootElement.element("select");
  524. assertEquals("select", selectElement.getName());
  525. assertEquals("someMap", selectElement.attribute("name").getValue());
  526. List children = selectElement.elements();
  527. assertEquals("Incorrect number of children", 2, children.size());
  528. Element e = (Element) selectElement.selectSingleNode("option[@value = 'M']");
  529. assertEquals("M node not selected", "selected", e.attribute("selected").getValue());
  530. e = (Element) selectElement.selectSingleNode("option[@value = 'F']");
  531. assertEquals("F node not selected", "selected", e.attribute("selected").getValue());
  532. }
  533. /**
  534. * Tests new support added as a result of <a
  535. * href="http://opensource.atlassian.com/projects/spring/browse/SPR-2660"
  536. * target="_blank">SPR-2660</a>.
  537. * <p>
  538. * Specifically, if the <code>items</code> attribute is supplied a
  539. * {@link Map}, and <code>itemValue</code> and <code>itemLabel</code>
  540. * are supplied non-null values, then:
  541. * </p>
  542. * <ul>
  543. * <li><code>itemValue</code> will be used as the property name of the
  544. * map's <em>key</em>, and</li>
  545. * <li><code>itemLabel</code> will be used as the property name of the
  546. * map's <em>value</em>.</li>
  547. * </ul>
  548. */
  549. public void testWithMultiMapWithItemValueAndItemLabel() throws Exception {
  550. // Save original default locale.
  551. final Locale defaultLocale = Locale.getDefault();
  552. // Use a locale that doesn't result in the generation of HTML entities
  553. // (e.g., not German, where รค becomes &auml;)
  554. Locale.setDefault(Locale.US);
  555. try {
  556. final Country austria = Country.COUNTRY_AT;
  557. final Country usa = Country.COUNTRY_US;
  558. final Map someMap = new HashMap();
  559. someMap.put(austria, LOCALE_AT);
  560. someMap.put(usa, Locale.US);
  561. this.bean.setSomeMap(someMap);
  562. this.tag.setPath("someMap"); // see: TestBean
  563. this.tag.setItems("${countryToLocaleMap}"); // see: extendRequest()
  564. this.tag.setItemValue("isoCode"); // Map key: Country
  565. this.tag.setItemLabel("displayLanguage"); // Map value: Locale
  566. BeanPropertyBindingResult bindingResult = new BeanPropertyBindingResult(getTestBean(), COMMAND_NAME);
  567. bindingResult.getPropertyAccessor().registerCustomEditor(Country.class, new PropertyEditorSupport() {
  568. public void setAsText(final String text) throws IllegalArgumentException {
  569. setValue(Country.getCountryWithIsoCode(text));
  570. }
  571. public String getAsText() {
  572. return ((Country) getValue()).getIsoCode();
  573. }
  574. });
  575. exposeBindingResult(bindingResult);
  576. int result = this.tag.doStartTag();
  577. assertEquals(Tag.SKIP_BODY, result);
  578. String output = getOutput();
  579. output = "<doc>" + output + "</doc>";
  580. SAXReader reader = new SAXReader();
  581. Document document = reader.read(new StringReader(output));
  582. Element rootElement = document.getRootElement();
  583. assertEquals(2, rootElement.elements().size());
  584. Element selectElement = rootElement.element("select");
  585. assertEquals("select", selectElement.getName());
  586. assertEquals("someMap", selectElement.attribute("name").getValue());
  587. List children = selectElement.elements();
  588. assertEquals("Incorrect number of children", 3, children.size());
  589. Element e;
  590. e = (Element) selectElement.selectSingleNode("option[@value = '" + austria.getIsoCode() + "']");
  591. assertNotNull("Option node not found with Country ISO code value [" + austria.getIsoCode() + "].", e);
  592. assertEquals("AT node not selected.", "selected", e.attribute("selected").getValue());
  593. assertEquals("AT Locale displayLanguage property not used for option label.",
  594. LOCALE_AT.getDisplayLanguage(), e.getData());
  595. e = (Element) selectElement.selectSingleNode("option[@value = '" + usa.getIsoCode() + "']");
  596. assertNotNull("Option node not found with Country ISO code value [" + usa.getIsoCode() + "].", e);
  597. assertEquals("US node not selected.", "selected", e.attribute("selected").getValue());
  598. assertEquals("US Locale displayLanguage property not used for option label.",
  599. Locale.US.getDisplayLanguage(), e.getData());
  600. }
  601. finally {
  602. // Restore original default locale.
  603. Locale.setDefault(defaultLocale);
  604. }
  605. }
  606. public void testMultiWithEmptyCollection() throws Exception {
  607. this.bean.setSomeList(new ArrayList());
  608. this.tag.setPath("someList");
  609. this.tag.setItems("${countries}");
  610. this.tag.setItemValue("isoCode");
  611. int result = this.tag.doStartTag();
  612. assertEquals(Tag.SKIP_BODY, result);
  613. String output = getOutput();
  614. output = "<doc>" + output + "</doc>";
  615. SAXReader reader = new SAXReader();
  616. Document document = reader.read(new StringReader(output));
  617. Element rootElement = document.getRootElement();
  618. assertEquals(2, rootElement.elements().size());
  619. Element selectElement = rootElement.element("select");
  620. assertEquals("select", selectElement.getName());
  621. assertEquals("someList", selectElement.attribute("name").getValue());
  622. assertEquals("multiple", selectElement.attribute("multiple").getValue());
  623. List children = selectElement.elements();
  624. assertEquals("Incorrect number of children", 4, children.size());
  625. Element inputElement = rootElement.element("input");
  626. assertNotNull(inputElement);
  627. }
  628. private void assertStringArray() throws JspException, DocumentException {
  629. int result = this.tag.doStartTag();
  630. assertEquals(Tag.SKIP_BODY, result);
  631. String output = getOutput();
  632. assertTrue(output.startsWith("<select "));
  633. assertTrue(output.endsWith("</select>"));
  634. SAXReader reader = new SAXReader();
  635. Document document = reader.read(new StringReader(output));
  636. Element rootElement = document.getRootElement();
  637. assertEquals("select", rootElement.getName());
  638. assertEquals("name", rootElement.attribute("name").getValue());
  639. List children = rootElement.elements();
  640. assertEquals("Incorrect number of children", 4, children.size());
  641. Element e = (Element) rootElement.selectSingleNode("option[text() = 'Rob']");
  642. assertEquals("Rob node not selected", "selected", e.attribute("selected").getValue());
  643. }
  644. private Map getCountryToLocaleMap() {
  645. Map map = new TreeMap(new Comparator() {
  646. public int compare(Object o1, Object o2) {
  647. return ((Country)o1).getName().compareTo(((Country)o2).getName());
  648. }
  649. });
  650. map.put(Country.COUNTRY_AT, LOCALE_AT);
  651. map.put(Country.COUNTRY_NL, LOCALE_NL);
  652. map.put(Country.COUNTRY_US, Locale.US);
  653. return map;
  654. }
  655. private String[] getNames() {
  656. return new String[]{"Rod", "Rob", "Juergen", "Adrian"};
  657. }
  658. private Map getSexes() {
  659. Map sexes = new HashMap();
  660. sexes.put("F", "Female");
  661. sexes.put("M", "Male");
  662. return sexes;
  663. }
  664. protected void extendRequest(MockHttpServletRequest request) {
  665. super.extendRequest(request);
  666. request.setAttribute("countries", Country.getCountries());
  667. request.setAttribute("countryToLocaleMap", getCountryToLocaleMap());
  668. request.setAttribute("sexes", getSexes());
  669. request.setAttribute("other", new TestBean());
  670. request.setAttribute("names", getNames());
  671. }
  672. private void assertList(boolean selected) throws JspException, DocumentException {
  673. this.tag.setItemValue("isoCode");
  674. this.tag.setItemLabel("name");
  675. this.tag.setSize("5");
  676. int result = this.tag.doStartTag();
  677. assertEquals(Tag.SKIP_BODY, result);
  678. String output = getOutput();
  679. validateOutput(output, selected);
  680. assertContainsAttribute(output, "size", "5");
  681. }
  682. private void validateOutput(String output, boolean selected) throws DocumentException {
  683. SAXReader reader = new SAXReader();
  684. Document document = reader.read(new StringReader(output));
  685. Element rootElement = document.getRootElement();
  686. assertEquals("select", rootElement.getName());
  687. assertEquals("country", rootElement.attribute("name").getValue());
  688. List children = rootElement.elements();
  689. assertEquals("Incorrect number of children", 4, children.size());
  690. Element e = (Element) rootElement.selectSingleNode("option[@value = 'UK']");
  691. Attribute selectedAttr = e.attribute("selected");
  692. if (selected) {
  693. assertTrue(selectedAttr != null && "selected".equals(selectedAttr.getValue()));
  694. }
  695. else {
  696. assertNull(selectedAttr);
  697. }
  698. }
  699. protected TestBean createTestBean() {
  700. this.bean = new TestBeanWithRealCountry();
  701. this.bean.setName("Rob");
  702. this.bean.setCountry("UK");
  703. this.bean.setSex("M");
  704. this.bean.setMyFloat(new Float("12.34"));
  705. this.bean.setSomeIntegerArray(new Integer[]{new Integer(12), new Integer(34)});
  706. return this.bean;
  707. }
  708. private TestBean getTestBean() {
  709. return (TestBean) getPageContext().getRequest().getAttribute(COMMAND_NAME);
  710. }
  711. public static class TestBeanWrapper {
  712. private TestBean bean;
  713. public TestBean getBean() {
  714. return bean;
  715. }
  716. public void setBean(TestBean bean) {
  717. this.bean = bean;
  718. }
  719. }
  720. }