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.Collection;
019: import java.util.HashMap;
020: import java.util.Iterator;
021: import java.util.List;
022: import java.util.Map;
023: import org.apache.commons.collections.Transformer;
024: import org.araneaframework.core.Assert;
025: import org.araneaframework.uilib.form.FormElement;
026: import org.araneaframework.uilib.form.FormElementContext;
027: import org.araneaframework.uilib.support.DisplayItem;
028: import org.araneaframework.uilib.util.DisplayItemContainer;
029: import org.araneaframework.uilib.util.DisplayItemUtil;
030:
031: /**
032: * This class represents a selectbox (aka dropdown) control.
033: *
034: * @author Jevgeni Kabanov (ekabanov <i>at</i> araneaframework <i>dot</i> org)
035: *
036: */
037: public class SelectControl extends StringValueControl implements
038: DisplayItemContainer {
039:
040: /**
041: * A list of {@link DisplayItem}s.
042: */
043: protected List items = new ArrayList();
044:
045: /**
046: * Adds a select-item to the element.
047: *
048: * @param item the item to be added.
049: */
050: public void addItem(DisplayItem item) {
051: Assert.notNullParam(item, "item");
052:
053: items.add(item);
054: }
055:
056: /**
057: * Adds a display-items to the element.
058: *
059: * @param items Collection<DisplayItem> the items to be added.
060: */
061: public void addItems(Collection items) {
062: Assert.noNullElementsParam(items, "items");
063:
064: this .items.addAll(items);
065: }
066:
067: /**
068: * Adds the display-items corresponding to the given value and label fields in Value Object.
069: *
070: * @param beanCollection <code>Collection</code> of beans, may not contain <code>null</code>.
071: * @param valueName the name of the Value Object field corresponding to the value of the select
072: * item.
073: * @param labelName the name of the Value Object field corresponding to the label of the select
074: * item.
075: *
076: * @deprecated use {@link SelectControl#addFromBeanCollection(Collection, String, String)} instead
077: */
078: public void addDisplayItems(Collection beanCollection,
079: String valueName, String labelName) {
080: addFromBeanCollection(beanCollection, valueName, labelName);
081: }
082:
083: /**
084: * Creates {@link DisplayItem}s corresponding to beans in <code>beanCollection</code> and adds
085: * these to this {@link SelectControl}.
086: *
087: * @param beanCollection <code>Collection</code> of beans
088: * @param valueName name of bean field that determines {@link DisplayItem}s <code>value</code>
089: * @param displayStringName name of bean field that determines {@link DisplayItem}s <code>displayString</code>
090: *
091: * @since 1.1
092: */
093: public void addFromBeanCollection(Collection beanCollection,
094: String valueName, String displayStringName) {
095: DisplayItemUtil.addItemsFromBeanCollection(this ,
096: beanCollection, valueName, displayStringName);
097: }
098:
099: /**
100: * Creates {@link DisplayItem}s corresponding to beans in <code>beanCollection</code> and adds
101: * these to this {@link SelectControl}.
102: *
103: * @param beanCollection <code>Collection</code> of beans
104: * @param valueName name of bean field that determines {@link DisplayItem}s <code>value</code>
105: * @param displayTransformer Transformer producing label ({@link DisplayItem}s <code>displayString</code>) for a bean
106: *
107: * @since 1.1
108: */
109: public void addFromBeanCollection(Collection beanCollection,
110: String valueName, Transformer displayTransformer) {
111: DisplayItemUtil.addItemsFromBeanCollection(this ,
112: beanCollection, valueName, displayTransformer);
113: }
114:
115: /**
116: * Creates {@link DisplayItem}s corresponding to beans in <code>beanCollection</code> and adds
117: * these to this {@link SelectControl}.
118: *
119: * @param beanCollection <code>Collection</code> of beans
120: * @param valueTransformer Transformer producing value ({@link DisplayItem#getValue()}) from a bean.
121: * @param displayStringName name of bean field that determines {@link DisplayItem}s <code>displayString</code>
122: *
123: * @since 1.1
124: */
125: public void addFromBeanCollection(Collection beanCollection,
126: Transformer valueTransformer, String displayStringName) {
127: DisplayItemUtil.addItemsFromBeanCollection(this ,
128: beanCollection, valueTransformer, displayStringName);
129: }
130:
131: /**
132: * Creates {@link DisplayItem}s corresponding to beans in <code>beanCollection</code> and adds
133: * these to this {@link SelectControl}.
134: *
135: * @param beanCollection <code>Collection</code> of beans
136: * @param valueTransformer Transformer producing value ({@link DisplayItem#getValue()}) from a bean.
137: * @param displayTransformer Transformer producing label (displayString) from a bean
138: *
139: * @since 1.1
140: */
141: public void addFromBeanCollection(Collection beanCollection,
142: Transformer valueTransformer, Transformer displayTransformer) {
143: DisplayItemUtil.addItemsFromBeanCollection(this ,
144: beanCollection, valueTransformer, displayTransformer);
145: }
146:
147: /**
148: * Clears the list of select-items.
149: */
150: public void clearItems() {
151: items.clear();
152: }
153:
154: public List getDisplayItems() {
155: return items;
156: }
157:
158: public int getValueIndex(String value) {
159: return DisplayItemUtil.getValueIndex(items, value);
160: }
161:
162: /**
163: * Returns {@link DisplayItem} corresponding to selected element. Current
164: * value by which seleced element is determined is reported by the {@link FormElement}
165: * to which this {@link SelectControl})belongs. If no {@link FormElement} is
166: * associated with {@link SelectControl}, this method returns <code>null</code>.
167: * @return {@link DisplayItem} corresponding to selected element.
168: * @since 1.0.5
169: */
170: public DisplayItem getSelectedItem() {
171: FormElementContext ctx = getFormElementCtx();
172: if (ctx == null)
173: return null;
174:
175: int index = getValueIndex((String) ctx.getValue());
176: return index >= 0 ? (DisplayItem) getDisplayItems().get(index)
177: : null;
178: }
179:
180: //*********************************************************************
181: //* INTERNAL METHODS
182: //*********************************************************************
183:
184: /**
185: * Controls that the value submitted by the user is found in the select
186: * items list.
187: */
188: protected void validateNotNull() {
189: super .validateNotNull();
190:
191: String data = innerData == null ? null
192: : ((String[]) innerData)[0];
193:
194: if (!DisplayItemUtil.isValueInItems(SelectControl.this , data))
195: throw new SecurityException(
196: "A value '"
197: + data
198: + "' not found in the list has been submitted to a select control!");
199: }
200:
201: /**
202: * Returns {@link ViewModel}.
203: * @return {@link ViewModel}.
204: */
205: public Object getViewModel() {
206: return new ViewModel();
207: }
208:
209: protected String preprocessRequestParameter(String parameterValue) {
210: //TODO: refactor ugly hack
211:
212: parameterValue = super
213: .preprocessRequestParameter(parameterValue);
214:
215: if (parameterValue != null
216: && !DisplayItemUtil.isValueInItems(SelectControl.this ,
217: parameterValue))
218: throw new SecurityException(
219: "A value '"
220: + parameterValue
221: + "' not found in the list has been submitted to a select control!");
222:
223: //Handles disabled DisplayItems
224: String[] previousValues = (String[]) innerData;
225:
226: if (previousValues != null && previousValues.length == 1) {
227: int valueIndex = getValueIndex(previousValues[0]);
228:
229: if (valueIndex != -1) {
230: DisplayItem previousDisplayItem = (DisplayItem) getDisplayItems()
231: .get(valueIndex);
232:
233: if (previousDisplayItem.isDisabled()
234: && parameterValue == null)
235: return previousDisplayItem.getValue();
236: }
237: }
238:
239: return parameterValue;
240: }
241:
242: //*********************************************************************
243: //* VIEW MODEL
244: //*********************************************************************
245:
246: /**
247: * @author Jevgeni Kabanov (ekabanov <i>at</i> araneaframework <i>dot</i> org)
248: *
249: */
250: public class ViewModel extends StringArrayRequestControl.ViewModel {
251:
252: private List selectItems;
253: private Map selectItemMap = new HashMap();
254:
255: /**
256: * Takes an outer class snapshot.
257: */
258: public ViewModel() {
259: this .selectItems = items;
260:
261: for (Iterator i = selectItems.iterator(); i.hasNext();) {
262: DisplayItem displayItem = (DisplayItem) i.next();
263: selectItemMap.put(displayItem.getValue(), displayItem);
264: }
265: }
266:
267: /**
268: * Returns a <code>List</code> of {@link DisplayItem}s.
269: * @return a <code>List</code> of {@link DisplayItem}s.
270: */
271: public List getSelectItems() {
272: return selectItems;
273: }
274:
275: public DisplayItem getSelectItemByValue(String value) {
276: return (DisplayItem) selectItemMap.get(value);
277: }
278:
279: public boolean containsItem(String itemValue) {
280: return selectItemMap.get(itemValue) != null;
281: }
282:
283: public String getLabelForValue(String itemValue) {
284: DisplayItem selectItemByValue = getSelectItemByValue(itemValue);
285: return selectItemByValue != null ? selectItemByValue
286: .getDisplayString() : "";
287: }
288: }
289: }
|