001: /**
002: * Copyright 2006 Webmedia Group Ltd.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: **/package org.araneaframework.uilib.form.control;
016:
017: import java.util.ArrayList;
018: import java.util.Arrays;
019: import java.util.Collection;
020: import java.util.HashMap;
021: import java.util.HashSet;
022: import java.util.Iterator;
023: import java.util.List;
024: import java.util.Map;
025: import java.util.Set;
026: import org.apache.commons.collections.Transformer;
027: import org.araneaframework.uilib.support.DisplayItem;
028: import org.araneaframework.uilib.support.UiLibMessages;
029: import org.araneaframework.uilib.util.DisplayItemContainer;
030: import org.araneaframework.uilib.util.DisplayItemUtil;
031: import org.araneaframework.uilib.util.MessageUtil;
032:
033: /**
034: * This class represents a multiselect control (aka list).
035: *
036: * @author Jevgeni Kabanov (ekabanov <i>at</i> araneaframework <i>dot</i> org)
037: *
038: */
039: public class MultiSelectControl extends StringArrayRequestControl
040: implements DisplayItemContainer {
041:
042: //*********************************************************************
043: //* FIELDS
044: //*********************************************************************
045:
046: /**
047: * The {@link org.araneaframework.uilib.util.DisplayItemUtil}.
048: */
049: protected List items = new ArrayList();
050:
051: //*********************************************************************
052: //* PUBLIC METHODS
053: //*********************************************************************
054:
055: /**
056: * Adds a display-item to the element.
057: *
058: * @param item the item to be added.
059: */
060: public void addItem(DisplayItem item) {
061: items.add(item);
062: }
063:
064: /**
065: * Adds a display-items to the element.
066: *
067: * @param items the items to be added.
068: */
069: public void addItems(Collection items) {
070: this .items.addAll(items);
071: }
072:
073: /**
074: * Clears the list of select-items.
075: */
076: public void clearItems() {
077: items.clear();
078: }
079:
080: public List getDisplayItems() {
081: return items;
082: }
083:
084: public int getValueIndex(String value) {
085: return DisplayItemUtil.getValueIndex(items, value);
086: }
087:
088: /**
089: * Adds the display-items corresponding to the given value and label fields in Value Object.
090: *
091: * @param valueObjects <code>Collection</code> of Value Objects.
092: * @param valueName the name of the Value Object field corresponding to the value of the select
093: * item.
094: * @param labelName the name of the Value Object field corresponding to the label of the select
095: * item.
096: *
097: * @deprecated use {@link MultiSelectControl#addFromBeanCollection(Collection, String, String)} instead
098: */
099: public void addDisplayItems(Collection valueObjects,
100: String valueName, String labelName) {
101: DisplayItemUtil.addItemsFromBeanCollection(this , valueObjects,
102: valueName, labelName);
103: }
104:
105: /**
106: * Creates {@link DisplayItem}s corresponding to beans in <code>beanCollection</code> and adds
107: * these to this {@link MultiSelectControl}.
108: *
109: * @param beanCollection <code>Collection</code> of beans
110: * @param valueName name of bean field that determines {@link DisplayItem}s <code>value</code>
111: * @param displayStringName name of bean field that determines {@link DisplayItem}s <code>displayString</code>
112: *
113: * @since 1.1
114: */
115: public void addFromBeanCollection(Collection beanCollection,
116: String valueName, String displayStringName) {
117: DisplayItemUtil.addItemsFromBeanCollection(this ,
118: beanCollection, valueName, displayStringName);
119: }
120:
121: /**
122: * Creates {@link DisplayItem}s corresponding to beans in <code>beanCollection</code> and adds
123: * these to this {@link MultiSelectControl}.
124: *
125: * @param beanCollection <code>Collection</code> of beans
126: * @param valueName name of bean field that determines {@link DisplayItem}s <code>value</code>
127: * @param displayTransformer Transformer producing label ({@link DisplayItem}s <code>displayString</code>) for a bean
128: *
129: * @since 1.1
130: */
131: public void addFromBeanCollection(Collection beanCollection,
132: String valueName, Transformer displayTransformer) {
133: DisplayItemUtil.addItemsFromBeanCollection(this ,
134: beanCollection, valueName, displayTransformer);
135: }
136:
137: /**
138: * Creates {@link DisplayItem}s corresponding to beans in <code>beanCollection</code> and adds
139: * these to this {@link MultiSelectControl}.
140: *
141: * @param beanCollection <code>Collection</code> of beans
142: * @param valueTransformer Transformer producing value ({@link DisplayItem#getValue()}) from a bean.
143: * @param displayStringName name of bean field that determines {@link DisplayItem}s <code>displayString</code>
144: *
145: * @since 1.1
146: */
147: public void addFromBeanCollection(Collection beanCollection,
148: Transformer valueTransformer, String displayStringName) {
149: DisplayItemUtil.addItemsFromBeanCollection(this ,
150: beanCollection, valueTransformer, displayStringName);
151: }
152:
153: /**
154: * Creates {@link DisplayItem}s corresponding to beans in <code>beanCollection</code> and adds
155: * these to this {@link MultiSelectControl}.
156: *
157: * @param beanCollection <code>Collection</code> of beans
158: * @param valueTransformer Transformer producing value ({@link DisplayItem#getValue()}) from a bean.
159: * @param displayTransformer Transformer producing label (displayString) from a bean
160: *
161: * @since 1.1
162: */
163: public void addFromBeanCollection(Collection beanCollection,
164: Transformer valueTransformer, Transformer displayTransformer) {
165: DisplayItemUtil.addItemsFromBeanCollection(this ,
166: beanCollection, valueTransformer, displayTransformer);
167: }
168:
169: /**
170: * Returns "List<String>".
171: *
172: * @return "List<String>".
173: */
174: public String getRawValueType() {
175: return "List<String>";
176: }
177:
178: //*********************************************************************
179: //* INTERNAL METHODS
180: //*********************************************************************
181:
182: /**
183: * Returns {@link ViewModel}.
184: * @return {@link ViewModel}.
185: */
186: public Object getViewModel() {
187: return new ViewModel();
188: }
189:
190: /**
191: * Removes all empty strings from the <code>String[]</code> request parameters.
192: */
193: protected String[] preprocessRequestParameters(
194: String[] parameterValues) {
195: //Removes submitted empty values
196: if (parameterValues != null && parameterValues.length > 0) {
197:
198: List processedParameterValues = new ArrayList();
199:
200: for (int i = 0; i < parameterValues.length; i++) {
201: if (parameterValues[i] != null
202: && !"".equals(parameterValues[i])) {
203: processedParameterValues.add(parameterValues[i]);
204: }
205: }
206:
207: parameterValues = convertToStringArray(processedParameterValues);
208: } else {
209: parameterValues = new String[] {};
210: }
211:
212: if (parameterValues != null) {
213: for (int i = 0; i < parameterValues.length; i++) {
214:
215: if (!DisplayItemUtil.isValueInItems(
216: MultiSelectControl.this , parameterValues[i]))
217: throw new SecurityException(
218: "A value '"
219: + parameterValues[i]
220: + "' not found in the list has been submitted to a multiselect select control!");
221: }
222: }
223:
224: if (innerData != null) {
225: //Handles disabled DisplayItems
226: Set previousDisabledValues = new HashSet(Arrays
227: .asList((Object[]) innerData));
228: Set currentValues = new HashSet(
229: parameterValues == null ? new ArrayList() : Arrays
230: .asList(parameterValues));
231: Set disabledItemValues = new HashSet();
232:
233: for (Iterator i = items.iterator(); i.hasNext();) {
234: DisplayItem item = (DisplayItem) i.next();
235: if (item.isDisabled())
236: disabledItemValues.add(item.getValue());
237: }
238:
239: previousDisabledValues.retainAll(disabledItemValues);
240: currentValues.addAll(previousDisabledValues);
241:
242: parameterValues = convertToStringArray(currentValues);
243: }
244: return parameterValues;
245: }
246:
247: /**
248: * Converts the given <code>List<String></code> to a <code>String[]</code>.
249: *
250: * @param data <code>List<String></code>.
251: * @return <code>String[]</code>.
252: */
253: protected String[] convertToStringArray(Collection data) {
254: String[] result = new String[data.size()];
255:
256: Iterator i = data.iterator();
257: int j = 0;
258:
259: while (i.hasNext()) {
260: result[j] = (String) i.next();
261: j++;
262: }
263:
264: return result;
265: }
266:
267: protected void validateNotNull() {
268: if (isMandatory() && ((Collection) getRawValue()).isEmpty()) {
269: addError(MessageUtil.localizeAndFormat(
270: UiLibMessages.MANDATORY_FIELD, MessageUtil
271: .localize(getLabel(), getEnvironment()),
272: getEnvironment()));
273: }
274: }
275:
276: /**
277: * Converts <code>String[]</code> to <code>List<String></code>.
278: */
279: protected Object fromRequestParameters(String[] parameterValues) {
280: return Arrays.asList(parameterValues);
281: }
282:
283: /**
284: * Converts <code>List<String></code> to <code>String[]</code>.
285: */
286: protected String[] toResponseParameters(Object controlValue) {
287: return convertToStringArray((Collection) controlValue);
288: }
289:
290: //*********************************************************************
291: //* VIEW MODEL
292: //*********************************************************************
293:
294: /**
295: * Represents a multiselect control view model.
296: *
297: * @author Jevgeni Kabanov (ekabanov <i>at</i> araneaframework <i>dot</i> org)
298: *
299: */
300: public class ViewModel extends StringArrayRequestControl.ViewModel {
301:
302: private List selectItems;
303: private Map selectItemMap = new HashMap();
304: private Set valueSet = new HashSet();
305:
306: /**
307: * Takes an outer class snapshot.
308: */
309: public ViewModel() {
310: this .selectItems = items;
311:
312: for (Iterator i = selectItems.iterator(); i.hasNext();) {
313: DisplayItem displayItem = (DisplayItem) i.next();
314: selectItemMap.put(displayItem.getValue(), displayItem);
315: }
316:
317: String[] values = getValues();
318: if (values != null) {
319: for (int i = 0; i < values.length; i++)
320: valueSet.add(values[i]);
321: }
322: }
323:
324: /**
325: * Returns a <code>List</code> of {@link DisplayItem}s.
326: * @return a <code>List</code> of {@link DisplayItem}s.
327: */
328: public List getSelectItems() {
329: return selectItems;
330: }
331:
332: public DisplayItem getSelectItemByValue(String value) {
333: return (DisplayItem) selectItemMap.get(value);
334: }
335:
336: public Set getValueSet() {
337: return valueSet;
338: }
339: }
340: }
|