Skip to content

Commit 42e3da5

Browse files
authored
Merge pull request apache#577 from apache/WW-5192-radio
[WW-5192] Fixes broken radio tag when using with enums
2 parents f3cb892 + b77c2f4 commit 42e3da5

File tree

7 files changed

+312
-162
lines changed

7 files changed

+312
-162
lines changed

apps/showcase/pom.xml

+6
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,9 @@
172172
<includes>
173173
<include>it.org.apache.struts2.showcase.*Test</include>
174174
</includes>
175+
<systemPropertyVariables>
176+
<http.port>8090</http.port>
177+
</systemPropertyVariables>
175178
</configuration>
176179
<executions>
177180
<execution>
@@ -201,6 +204,9 @@
201204
<value>false</value>
202205
</systemProperty>
203206
</systemProperties>
207+
<httpConnector>
208+
<port>8090</port>
209+
</httpConnector>
204210
<scanIntervalSeconds>10</scanIntervalSeconds>
205211
<webAppSourceDirectory>${basedir}/src/main/webapp/</webAppSourceDirectory>
206212
<webAppConfig>

core/src/main/java/org/apache/struts2/components/Radio.java

+4
Original file line numberDiff line numberDiff line change
@@ -80,4 +80,8 @@ protected boolean lazyEvaluation() {
8080
return true;
8181
}
8282

83+
protected Class<?> getValueClassType() {
84+
return String.class;
85+
}
86+
8387
}

core/src/test/java/org/apache/struts2/TestAction.java

+48-29
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,12 @@
2727
import com.opensymphony.xwork2.validator.annotations.ValidatorType;
2828
import org.apache.struts2.views.jsp.ui.User;
2929

30-
import java.util.*;
30+
import java.util.Arrays;
31+
import java.util.Collection;
32+
import java.util.HashMap;
33+
import java.util.List;
34+
import java.util.Map;
3135

32-
33-
/**
34-
*/
3536
public class TestAction extends ActionSupport {
3637

3738
private static final long serialVersionUID = -8891365561914451494L;
@@ -50,31 +51,33 @@ public class TestAction extends ActionSupport {
5051
private SomeEnum status = SomeEnum.COMPLETED;
5152
private Float floatNumber;
5253
private Long id;
54+
private List<SomeEnum> enumList;
55+
private List<Integer> intList;
5356

54-
private final Map<String, String> texts = new HashMap<String, String>();
57+
private final Map<String, String> texts = new HashMap<>();
5558

5659
/**
5760
* Define a text resource within this action that will be returned by the getText methods
58-
* here before delegating to the default TextProvider
59-
*
60-
* call
61-
* @param key
62-
* @param value
61+
* here before delegating to the default TextProvider call
6362
*/
6463
public void setText(String key, String value) {
6564
this.texts.put(key, value);
6665
}
6766

68-
/** Returns the test value if defined otherwise delegates to the default TextProvider */
67+
/**
68+
* Returns the test value if defined otherwise delegates to the default TextProvider
69+
*/
6970
public String getText(String key) {
7071
if (this.texts.containsKey(key)) {
7172
return this.texts.get(key);
7273
}
7374
return super.getText(key);
7475
}
7576

76-
/** This is the method invoked by the {@link org.apache.struts2.util.TextProviderHelper}.
77-
* Returns the test value if defined otherwise delegates to the default TextProvider */
77+
/**
78+
* This is the method invoked by the {@link org.apache.struts2.util.TextProviderHelper}.
79+
* Returns the test value if defined otherwise delegates to the default TextProvider
80+
*/
7881
public String getText(String key, String defaultValue, List<?> args, ValueStack stack) {
7982
if (this.texts.containsKey(key)) {
8083
return this.texts.get(key);
@@ -180,20 +183,21 @@ public String execute() throws Exception {
180183
}
181184

182185
@Validations(
183-
requiredFields = {
184-
@RequiredFieldValidator(type = ValidatorType.SIMPLE, fieldName = "status", message = "You must enter a value for field.")
185-
},
186-
requiredStrings = {
187-
@RequiredStringValidator(type = ValidatorType.SIMPLE, fieldName = "result", message = "You must enter a value for field.")
188-
}
186+
requiredFields = {
187+
@RequiredFieldValidator(type = ValidatorType.SIMPLE, fieldName = "status", message = "You must enter a value for field.")
188+
},
189+
requiredStrings = {
190+
@RequiredStringValidator(type = ValidatorType.SIMPLE, fieldName = "result", message = "You must enter a value for field.")
191+
}
189192
)
190193
public String annotatedExecute1() throws Exception {
191194
return Action.SUCCESS;
192195
}
196+
193197
@Validations(
194-
requiredFields = {
195-
@RequiredFieldValidator(type = ValidatorType.SIMPLE, fieldName = "status", message = "You must enter a value for field.")
196-
}
198+
requiredFields = {
199+
@RequiredFieldValidator(type = ValidatorType.SIMPLE, fieldName = "status", message = "You must enter a value for field.")
200+
}
197201
)
198202
public String annotatedExecute2() throws Exception {
199203
return Action.SUCCESS;
@@ -207,16 +211,16 @@ public String doInput() throws Exception {
207211
return INPUT;
208212
}
209213

210-
public SomeEnum getStatus() {
211-
return status;
212-
}
214+
public SomeEnum getStatus() {
215+
return status;
216+
}
213217

214-
public void setStatus(SomeEnum status) {
215-
this.status = status;
216-
}
218+
public void setStatus(SomeEnum status) {
219+
this.status = status;
220+
}
217221

218222
public List<SomeEnum> getStatusList() {
219-
return Arrays.asList(SomeEnum.values());
223+
return Arrays.asList(SomeEnum.values());
220224
}
221225

222226
public Float getFloatNumber() {
@@ -235,4 +239,19 @@ public void setId(Long id) {
235239
this.id = id;
236240
}
237241

242+
public List<SomeEnum> getEnumList() {
243+
return enumList;
244+
}
245+
246+
public void setEnumList(List<SomeEnum> enumList) {
247+
this.enumList = enumList;
248+
}
249+
250+
public List<Integer> getIntList() {
251+
return intList;
252+
}
253+
254+
public void setIntList(List<Integer> intList) {
255+
this.intList = intList;
256+
}
238257
}

core/src/test/java/org/apache/struts2/views/jsp/AbstractTagTest.java

+32-36
Original file line numberDiff line numberDiff line change
@@ -18,36 +18,31 @@
1818
*/
1919
package org.apache.struts2.views.jsp;
2020

21-
import java.io.File;
22-
import java.io.StringWriter;
23-
import java.util.HashMap;
24-
import java.util.Locale;
25-
import java.util.Map;
26-
27-
import javax.servlet.http.HttpServletResponse;
28-
import javax.servlet.jsp.JspWriter;
29-
21+
import com.mockobjects.dynamic.Mock;
22+
import com.opensymphony.xwork2.Action;
23+
import com.opensymphony.xwork2.ActionContext;
24+
import com.opensymphony.xwork2.inject.Container;
25+
import com.opensymphony.xwork2.util.ValueStack;
3026
import org.apache.commons.lang3.builder.EqualsBuilder;
3127
import org.apache.struts2.ServletActionContext;
3228
import org.apache.struts2.StrutsInternalTestCase;
3329
import org.apache.struts2.TestAction;
3430
import org.apache.struts2.dispatcher.ApplicationMap;
3531
import org.apache.struts2.dispatcher.Dispatcher;
36-
import org.apache.struts2.dispatcher.MockDispatcher;
3732
import org.apache.struts2.dispatcher.HttpParameters;
33+
import org.apache.struts2.dispatcher.MockDispatcher;
3834
import org.apache.struts2.dispatcher.RequestMap;
3935
import org.apache.struts2.dispatcher.SessionMap;
4036

41-
import com.mockobjects.dynamic.Mock;
42-
import com.opensymphony.xwork2.Action;
43-
import com.opensymphony.xwork2.ActionContext;
44-
import com.opensymphony.xwork2.inject.Container;
45-
import com.opensymphony.xwork2.util.ValueStack;
46-
37+
import javax.servlet.http.HttpServletResponse;
38+
import javax.servlet.jsp.JspWriter;
39+
import java.io.File;
40+
import java.io.StringWriter;
41+
import java.util.HashMap;
42+
import java.util.Map;
4743

4844
/**
4945
* Base class to extend for unit testing UI Tags.
50-
*
5146
*/
5247
public abstract class AbstractTagTest extends StrutsInternalTestCase {
5348
protected Action action;
@@ -62,7 +57,7 @@ public abstract class AbstractTagTest extends StrutsInternalTestCase {
6257
protected StrutsMockHttpServletRequest request;
6358
protected StrutsMockPageContext pageContext;
6459
protected HttpServletResponse response;
65-
60+
6661
protected Mock mockContainer;
6762

6863
/**
@@ -114,11 +109,11 @@ protected void createMocks() {
114109
Dispatcher.setInstance(du);
115110
session = new SessionMap<>(request);
116111
Map<String, Object> extraContext = du.createContextMap(new RequestMap(request),
117-
HttpParameters.create(request.getParameterMap()).build(),
118-
session,
119-
new ApplicationMap(pageContext.getServletContext()),
120-
request,
121-
response);
112+
HttpParameters.create(request.getParameterMap()).build(),
113+
session,
114+
new ApplicationMap(pageContext.getServletContext()),
115+
request,
116+
response);
122117
// let's not set the locale -- there is a test that checks if Dispatcher actually picks this up...
123118
// ... but generally we want to just use no locale (let it stay system default)
124119
extraContext = ActionContext.of(extraContext).withLocale(null).getContextMap();
@@ -149,18 +144,18 @@ protected void tearDown() throws Exception {
149144
}
150145

151146
/**
152-
* Compare if two component tags are considered equal according to their fields as accessed
147+
* Compare if two component tags are considered equal according to their fields as accessed
153148
* via reflection.
154-
*
155-
* Utilizes {@link EqualsBuilder#reflectionEquals(java.lang.Object, java.lang.Object, boolean)} to perform
149+
* <p>
150+
* Utilizes {@link EqualsBuilder#reflectionEquals(java.lang.Object, java.lang.Object, boolean)} to perform
156151
* the check, and compares transient fields as well. This may fail when run while a security manager is
157152
* active, due to a need to user reflection.
158-
*
153+
* <p>
159154
* This method may be useful for checking if the state of a tag is what is expected after a given set of operations,
160155
* or after clearing state such as for calls involving {@link StrutsBodyTagSupport#clearTagStateForTagPoolingServers()}
161156
* has taken place following {@link StrutsBodyTagSupport#doEndTag()} processing. When making comparisons, keep in mind the
162157
* pageContext and parent Tag state are not cleared by clearTagStateForTagPoolingServers().
163-
*
158+
*
164159
* @param tag1 the first {@link StrutsBodyTagSupport} to compare against the other.
165160
* @param tag2 the second {@link StrutsBodyTagSupport} to compare against the other.
166161
* @return true if the Tags are equal based on field comparisons by reflection, false otherwise.
@@ -170,15 +165,16 @@ protected boolean strutsBodyTagsAreReflectionEqual(StrutsBodyTagSupport tag1, St
170165
}
171166

172167
/**
173-
* Helper method to simplify setting the performClearTagStateForTagPoolingServers state for a
174-
* {@link ComponentTagSupport} tag's {@link Component} to match expectations for the test.
175-
*
168+
* Helper method to simplify setting the performClearTagStateForTagPoolingServers state for a
169+
* {@link ComponentTagSupport} tag's {@link import org.apache.struts2.components.Component} to match expectations
170+
* for the test.
171+
* <p>
176172
* The component reference is not available to the tag until after the doStartTag() method is called.
177-
* We need to ensure the component's {@link Component#performClearTagStateForTagPoolingServers} state matches
178-
* what we set for the Tag when a non-default (true) value is used, so this method accesses the component instance,
179-
* sets the value specified and forces the tag's parameters to be repopulated again.
180-
*
181-
* @param tag The ComponentTagSupport tag upon whose component we will set the performClearTagStateForTagPoolingServers state.
173+
* We need to ensure the component's {@link import org.apache.struts2.components.Component#performClearTagStateForTagPoolingServers}
174+
* state matches what we set for the Tag when a non-default (true) value is used, so this method accesses
175+
* the component instance, sets the value specified and forces the tag's parameters to be repopulated again.
176+
*
177+
* @param tag The ComponentTagSupport tag upon whose component we will set the performClearTagStateForTagPoolingServers state.
182178
* @param performClearTagStateForTagPoolingServers true to clear tag state, false otherwise
183179
*/
184180
protected void setComponentTagClearTagState(ComponentTagSupport tag, boolean performClearTagStateForTagPoolingServers) {

0 commit comments

Comments
 (0)