craigmcc 2002/12/23 14:00:25 Modified: conf/share struts-config_1_1.dtd src/share/org/apache/struts/config FormPropertyConfig.java src/test/org/apache/struts/action TestDynaActionForm.java src/test/org/apache/struts/mock TestMockBase.java src/test/org/apache/struts/util TestRequestUtils.java Log: Add an optional "size" attribute on <form-property>, so that you can ask for an array of a specific size without having to specify initial values in the "initial" attribute. For example, <form-property name="foo" type="java.lang.String[]" size="10"/> will cause the initialize() method of the DynaActionForm to create an array of ten Strings (all initialized to null). The size attribute will be ignored if the initial attribute is present. Updated unit tests included. This is the non-controversial half of the recommendations in Bugzilla #14800. I'm still reviewing the advisability of changing the way that initial arrays get cloned or not. PR: Bugzilla #14800 Submitted by: James Turner <turner at blackbear.com> Revision Changes Path 1.34 +6 -1 jakarta-struts/conf/share/struts-config_1_1.dtd Index: struts-config_1_1.dtd =================================================================== RCS file: /home/cvs/jakarta-struts/conf/share/struts-config_1_1.dtd,v retrieving revision 1.33 retrieving revision 1.34 diff -u -r1.33 -r1.34 --- struts-config_1_1.dtd 8 Dec 2002 00:22:56 -0000 1.33 +++ struts-config_1_1.dtd 23 Dec 2002 22:00:24 -0000 1.34 @@ -255,6 +255,10 @@ name The name of the JavaBean property described by this element. + size The number of array elements to create if the value of the + "type" attribute specifies an array, but there is no value + specified for the "initial" attribute. + type Fully qualified Java class name of the field underlying this property, optionally followed by "[]" to indicate that the field is indexed. @@ -263,6 +267,7 @@ <!ATTLIST form-property className %ClassName; #IMPLIED> <!ATTLIST form-property initial CDATA #IMPLIED> <!ATTLIST form-property name %PropName; #REQUIRED> +<!ATTLIST form-property size %Integer; #IMPLIED> <!ATTLIST form-property type %ClassName; #REQUIRED> 1.8 +54 -5 jakarta-struts/src/share/org/apache/struts/config/FormPropertyConfig.java Index: FormPropertyConfig.java =================================================================== RCS file: /home/cvs/jakarta-struts/src/share/org/apache/struts/config/FormPropertyConfig.java,v retrieving revision 1.7 retrieving revision 1.8 diff -u -r1.7 -r1.8 --- FormPropertyConfig.java 9 Jul 2002 23:57:37 -0000 1.7 +++ FormPropertyConfig.java 23 Dec 2002 22:00:24 -0000 1.8 @@ -103,10 +103,28 @@ */ public FormPropertyConfig(String name, String type, String initial) { + this(name, type, initial, 0); + + } + + + /** + * Constructor that preconfigures the relevant properties. + * + * @param name Name of this property + * @param type Fully qualified class name of this property + * @param initial Initial value of this property (if any) + * @param size Size of the array to be created if this property is an + * array with no defined initial value + */ + public FormPropertyConfig(String name, String type, + String initial, int size) { + super(); setName(name); setType(type); setInitial(initial); + setSize(size); } @@ -170,6 +188,27 @@ /** + * <p>The size of the array to be created if this property is an array + * type and there is no specified <code>initial</code> value.</p> + * + * @since Struts 1.1-b3 + */ + protected int size = 0; + + public int getSize() { + return (this.size); + } + + public void setSize(int size) { + if (configured) { + throw new IllegalStateException("Configuration is frozen"); + } + this.size = size; + } + + + + /** * The fully qualified Java class name of the implementation class * of this bean property, optionally followed by <code>[]</code> to * indicate that the property is indexed. @@ -258,7 +297,17 @@ if (!initialized) { try { Class clazz = getTypeClass(); - initialValue = ConvertUtils.convert(initial, clazz); + if (clazz.isArray()) { + if (initial != null) { + initialValue = + ConvertUtils.convert(initial, clazz); + } else { + initialValue = + Array.newInstance(clazz.getComponentType(), size); + } + } else { + initialValue = ConvertUtils.convert(initial, clazz); + } } catch (Throwable t) { initialValue = null; } 1.8 +8 -8 jakarta-struts/src/test/org/apache/struts/action/TestDynaActionForm.java Index: TestDynaActionForm.java =================================================================== RCS file: /home/cvs/jakarta-struts/src/test/org/apache/struts/action/TestDynaActionForm.java,v retrieving revision 1.7 retrieving revision 1.8 diff -u -r1.7 -r1.8 --- TestDynaActionForm.java 16 Nov 2002 04:58:47 -0000 1.7 +++ TestDynaActionForm.java 23 Dec 2002 22:00:24 -0000 1.8 @@ -219,9 +219,9 @@ } - // Test reset() method on indexed values to ensure that the + // Test initialize() method on indexed values to ensure that the // result returned by FormPropertyConfig().initial() is never clobbered - public void testIndexedReset() { + public void testIndexedInitialize() { // Update some values in the indexed properties dynaForm.set("intArray", 1, new Integer(111)); @@ -237,17 +237,17 @@ assertEquals("stringIndexed[4]", "New String 4", (String) dynaForm.get("stringIndexed", 4)); - // Perform reset and revalidate the original values + // Perform initialize() and revalidate the original values // while ensuring our initial values did not get corrupted - dynaForm.reset(mapping, (ServletRequest) null); + dynaForm.initialize(mapping); setupComplexProperties(); testGetIndexedValues(); } - // Test reset() method going back to initial values - public void testScalarReset() { + // Test initialize() method going back to initial values + public void testScalarInitialize() { // Update a bunch of scalar properties to new values dynaForm.set("booleanProperty", Boolean.FALSE); @@ -263,8 +263,8 @@ assertEquals("stringProperty", "New String Value", (String) dynaForm.get("stringProperty")); - // Reset and revalidate the original values - dynaForm.reset(mapping, (ServletRequest) null); + // Perform initialize() and revalidate the original values + dynaForm.initialize(mapping); setupComplexProperties(); testBeanCreate(); 1.8 +35 -4 jakarta-struts/src/test/org/apache/struts/mock/TestMockBase.java Index: TestMockBase.java =================================================================== RCS file: /home/cvs/jakarta-struts/src/test/org/apache/struts/mock/TestMockBase.java,v retrieving revision 1.7 retrieving revision 1.8 diff -u -r1.7 -r1.8 --- TestMockBase.java 16 Nov 2002 04:58:48 -0000 1.7 +++ TestMockBase.java 23 Dec 2002 22:00:24 -0000 1.8 @@ -215,6 +215,37 @@ mapping.setType("org.apache.struts.mock.MockAction"); appConfig.addActionConfig(mapping); + // Form Bean "/dynamic0" is a DynaActionForm with initializers + formBean = new ActionFormBean + ("dynamic0", + "org.apache.struts.action.DynaActionForm"); + formBean.addFormPropertyConfig + (new FormPropertyConfig("booleanProperty", "boolean", "true")); + formBean.addFormPropertyConfig + (new FormPropertyConfig("stringProperty", "java.lang.String", + "String Property")); + formBean.addFormPropertyConfig + (new FormPropertyConfig("intArray1", "int[]", + "{1,2,3}", 4)); // 4 should be ignored + formBean.addFormPropertyConfig + (new FormPropertyConfig("intArray2", "int[]", + null, 5)); // 5 should be respected + formBean.addFormPropertyConfig + (new FormPropertyConfig("stringArray1", "java.lang.String[]", + "{aaa,bbb,ccc}", 2)); // 2 should be ignored + formBean.addFormPropertyConfig + (new FormPropertyConfig("stringArray2", "java.lang.String[]", + null, 3)); // 3 should be respected + appConfig.addFormBeanConfig(formBean); + + // Action "/dynamic0" uses the "dynamic0" form bean in request scope + mapping = new ActionMapping(); + mapping.setName("dynamic0"); + mapping.setPath("/dynamic0"); + mapping.setScope("request"); + mapping.setType("org.apache.struts.mock.MockAction"); + appConfig.addActionConfig(mapping); + // Action "/noform" has no form bean associated with it mapping = new ActionMapping(); mapping.setPath("/noform"); 1.14 +83 -4 jakarta-struts/src/test/org/apache/struts/util/TestRequestUtils.java Index: TestRequestUtils.java =================================================================== RCS file: /home/cvs/jakarta-struts/src/test/org/apache/struts/util/TestRequestUtils.java,v retrieving revision 1.13 retrieving revision 1.14 diff -u -r1.13 -r1.14 --- TestRequestUtils.java 12 Nov 2002 03:56:09 -0000 1.13 +++ TestRequestUtils.java 23 Dec 2002 22:00:24 -0000 1.14 @@ -1096,6 +1096,85 @@ } + // Default module -- Dynamic ActionForm with initializers + public void testCreateActionForm4a() { + + // Retrieve an appropriately configured DynaActionForm instance + request.setPathElements("/myapp", "/dynamic0.do", null, null); + ActionMapping mapping = (ActionMapping) + appConfig.findActionConfig("/dynamic0"); + assertNotNull("Found /dynamic0 mapping", mapping); + assertNotNull("Mapping has non-null name", + mapping.getName()); + assertEquals("Mapping has correct name", + "dynamic0", + mapping.getName()); + assertNotNull("AppConfig has form bean " + mapping.getName(), + appConfig.findFormBeanConfig(mapping.getName())); + ActionForm form = RequestUtils.createActionForm + (request, mapping, appConfig, null); + assertNotNull("ActionForm returned", form); + assertTrue("ActionForm of correct type", + form instanceof DynaActionForm); + + // Validate the property values + DynaActionForm dform = (DynaActionForm) form; + Boolean booleanProperty = (Boolean) dform.get("booleanProperty"); + assertTrue("booleanProperty is true", booleanProperty.booleanValue()); + String stringProperty = (String) dform.get("stringProperty"); + assertEquals("stringProperty is correct", + "String Property", + stringProperty); + Object value = null; + + value = dform.get("intArray1"); + assertNotNull("intArray1 exists", value); + assertTrue("intArray1 is int[]", value instanceof int[]); + int intArray1[] = (int[]) value; + assertEquals("intArray1 length is correct", 3, intArray1.length); + assertEquals("intArray1[0] value is correct", 1, intArray1[0]); + assertEquals("intArray1[1] value is correct", 2, intArray1[1]); + assertEquals("intArray1[2] value is correct", 3, intArray1[2]); + + value = dform.get("intArray2"); + assertNotNull("intArray2 exists", value); + assertTrue("intArray2 is int[]", value instanceof int[]); + int intArray2[] = (int[]) value; + assertEquals("intArray2 length is correct", 5, intArray2.length); + assertEquals("intArray2[0] value is correct", 0, intArray2[0]); + assertEquals("intArray2[1] value is correct", 0, intArray2[1]); + assertEquals("intArray2[2] value is correct", 0, intArray2[2]); + assertEquals("intArray2[3] value is correct", 0, intArray2[3]); + assertEquals("intArray2[4] value is correct", 0, intArray2[4]); + + value = dform.get("stringArray1"); + assertNotNull("stringArray1 exists", value); + assertTrue("stringArray1 is int[]", value instanceof String[]); + String stringArray1[] = (String[]) value; + assertEquals("stringArray1 length is correct", 3, stringArray1.length); + assertEquals("stringArray1[0] value is correct", + "aaa", stringArray1[0]); + assertEquals("stringArray1[1] value is correct", + "bbb", stringArray1[1]); + assertEquals("stringArray1[2] value is correct", + "ccc", stringArray1[2]); + + value = dform.get("stringArray2"); + assertNotNull("stringArray2 exists", value); + assertTrue("stringArray2 is int[]", value instanceof String[]); + String stringArray2[] = (String[]) value; + assertEquals("stringArray2 length is correct", 3, stringArray2.length); + assertEquals("stringArray2[0] value is correct", + (String) null, stringArray2[0]); + assertEquals("stringArray2[1] value is correct", + (String) null, stringArray2[1]); + assertEquals("stringArray2[2] value is correct", + (String) null, stringArray2[2]); + + } + + + // ----------------------------------------------------------- requestURL()
-- To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>