001: // WARNING: This file was automatically generated. Do not edit it directly,
002: // or you will lose your changes.
003:
004: /*
005: * Licensed to the Apache Software Foundation (ASF) under one
006: * or more contributor license agreements. See the NOTICE file
007: * distributed with this work for additional information
008: * regarding copyright ownership. The ASF licenses this file
009: * to you under the Apache License, Version 2.0 (the
010: * "License"); you may not use this file except in compliance
011: * with the License. You may obtain a copy of the License at
012: *
013: * http://www.apache.org/licenses/LICENSE-2.0
014: *
015: * Unless required by applicable law or agreed to in writing,
016: * software distributed under the License is distributed on an
017: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
018: * KIND, either express or implied. See the License for the
019: * specific language governing permissions and limitations
020: * under the License.
021: */
022: package javax.faces.component;
023:
024: import java.lang.reflect.Array;
025: import java.util.ArrayList;
026: import java.util.Arrays;
027: import java.util.Collection;
028: import java.util.Collections;
029: import java.util.Iterator;
030: import java.util.List;
031: import javax.el.ValueExpression;
032: import javax.faces.application.FacesMessage;
033: import javax.faces.context.FacesContext;
034: import javax.faces.convert.ConverterException;
035: import javax.faces.el.ValueBinding;
036: import javax.faces.render.Renderer;
037:
038: /**
039: *
040: * <h4>Events:</h4>
041: * <table border="1" width="100%" cellpadding="3" summary="">
042: * <tr bgcolor="#CCCCFF" class="TableHeadingColor">
043: * <th align="left">Type</th>
044: * <th align="left">Phases</th>
045: * <th align="left">Description</th>
046: * </tr>
047: * <tr class="TableRowColor">
048: * <td valign="top"><code>javax.faces.event.ValueChangeEvent</code></td>
049: * <td valign="top" nowrap></td>
050: * <td valign="top">The valueChange event is delivered when the value
051: attribute is changed.</td>
052: * </tr>
053: * </table>
054: */
055: public class UISelectMany extends UIInput {
056:
057: static public final String COMPONENT_FAMILY = "javax.faces.SelectMany";
058: static public final String COMPONENT_TYPE = "javax.faces.SelectMany";
059:
060: /**
061: * Construct an instance of the UISelectMany.
062: */
063: public UISelectMany() {
064: setRendererType("javax.faces.Listbox");
065: }
066:
067: public static final String INVALID_MESSAGE_ID = "javax.faces.component.UISelectMany.INVALID";
068:
069: public Object[] getSelectedValues() {
070: return (Object[]) getValue();
071: }
072:
073: public void setSelectedValues(Object[] selectedValues) {
074: setValue(selectedValues);
075: }
076:
077: /**
078: * @deprecated Use getValueExpression instead
079: */
080: public ValueBinding getValueBinding(String name) {
081: if (name == null) {
082: throw new NullPointerException("name");
083: }
084: if (name.equals("selectedValues")) {
085: return super .getValueBinding("value");
086: } else {
087: return super .getValueBinding(name);
088: }
089: }
090:
091: /**
092: * @deprecated Use setValueExpression instead
093: */
094: public void setValueBinding(String name, ValueBinding binding) {
095: if (name == null) {
096: throw new NullPointerException("name");
097: }
098: if (name.equals("selectedValues")) {
099: super .setValueBinding("value", binding);
100: } else {
101: super .setValueBinding(name, binding);
102: }
103: }
104:
105: public ValueExpression getValueExpression(String name) {
106: if (name == null) {
107: throw new NullPointerException("name");
108: }
109: if (name.equals("selectedValues")) {
110: return super .getValueExpression("value");
111: } else {
112: return super .getValueExpression(name);
113: }
114: }
115:
116: public void setValueExpression(String name, ValueExpression binding) {
117: if (name == null) {
118: throw new NullPointerException("name");
119: }
120: if (name.equals("selectedValues")) {
121: super .setValueExpression("value", binding);
122: } else {
123: super .setValueExpression(name, binding);
124: }
125: }
126:
127: /**
128: * @return true if Objects are different (!)
129: */
130: protected boolean compareValues(Object previous, Object value) {
131: if (previous == null) {
132: // one is null, the other not
133: return value != null;
134: } else if (value == null) {
135: // one is null, the other not
136: return previous != null;
137: } else {
138: if (previous instanceof Object[]
139: && value instanceof Object[]) {
140: return compareObjectArrays((Object[]) previous,
141: (Object[]) value);
142: } else if (previous instanceof List
143: && value instanceof List) {
144: return compareLists((List) previous, (List) value);
145: } else if (previous.getClass().isArray()
146: && value.getClass().isArray()) {
147: return comparePrimitiveArrays(previous, value);
148: } else {
149: //Objects have different classes
150: return true;
151: }
152: }
153: }
154:
155: private boolean compareObjectArrays(Object[] previous,
156: Object[] value) {
157: int length = value.length;
158: if (previous.length != length) {
159: //different length
160: return true;
161: }
162:
163: boolean[] scoreBoard = new boolean[length];
164: for (int i = 0; i < length; i++) {
165: Object p = previous[i];
166: boolean found = false;
167: for (int j = 0; j < length; j++) {
168: if (scoreBoard[j] == false) {
169: Object v = value[j];
170: if ((p == null && v == null)
171: || (p != null && v != null && p.equals(v))) {
172: scoreBoard[j] = true;
173: found = true;
174: break;
175: }
176: }
177: }
178: if (!found) {
179: return true; //current element of previous array not found in new array
180: }
181: }
182:
183: return false; // arrays are identical
184: }
185:
186: private boolean compareLists(List previous, List value) {
187: int length = value.size();
188: if (previous.size() != length) {
189: //different length
190: return true;
191: }
192:
193: boolean[] scoreBoard = new boolean[length];
194: for (int i = 0; i < length; i++) {
195: Object p = previous.get(i);
196: boolean found = false;
197: for (int j = 0; j < length; j++) {
198: if (scoreBoard[j] == false) {
199: Object v = value.get(j);
200: if ((p == null && v == null)
201: || (p != null && v != null && p.equals(v))) {
202: scoreBoard[j] = true;
203: found = true;
204: break;
205: }
206: }
207: }
208: if (!found) {
209: return true; //current element of previous List not found in new List
210: }
211: }
212:
213: return false; // Lists are identical
214: }
215:
216: private boolean comparePrimitiveArrays(Object previous, Object value) {
217: int length = Array.getLength(value);
218: if (Array.getLength(previous) != length) {
219: //different length
220: return true;
221: }
222:
223: boolean[] scoreBoard = new boolean[length];
224: for (int i = 0; i < length; i++) {
225: Object p = Array.get(previous, i);
226: boolean found = false;
227: for (int j = 0; j < length; j++) {
228: if (scoreBoard[j] == false) {
229: Object v = Array.get(value, j);
230: if ((p == null && v == null)
231: || (p != null && v != null && p.equals(v))) {
232: scoreBoard[j] = true;
233: found = true;
234: break;
235: }
236: }
237: }
238: if (!found) {
239: return true; //current element of previous array not found in new array
240: }
241: }
242:
243: return false; // arrays are identical
244: }
245:
246: protected void validateValue(FacesContext context,
247: Object convertedValue) {
248: Iterator itemValues = _createItemValuesIterator(convertedValue);
249:
250: // verify that iterator was successfully created for convertedValue type
251: if (itemValues == null) {
252: _MessageUtils.addErrorMessage(context, this ,
253: INVALID_MESSAGE_ID, new Object[] { _MessageUtils
254: .getLabel(context, this ) });
255: setValid(false);
256: return;
257: }
258:
259: boolean hasValues = itemValues.hasNext();
260:
261: // if UISelectMany is required, then there must be some selected values
262: if (isRequired() && !hasValues) {
263: _MessageUtils.addErrorMessage(context, this ,
264: REQUIRED_MESSAGE_ID, new Object[] { _MessageUtils
265: .getLabel(context, this ) });
266: setValid(false);
267: return;
268: }
269:
270: // run the validators only if there are item values to validate
271: if (hasValues) {
272: _ComponentUtils.callValidators(context, this ,
273: convertedValue);
274: }
275:
276: if (isValid() && hasValues) {
277: // all selected values must match to the values of the available options
278:
279: _SelectItemsUtil._ValueConverter converter = new _SelectItemsUtil._ValueConverter() {
280: public Object getConvertedValue(FacesContext context,
281: String value) {
282: Object convertedValue = UISelectMany.this
283: .getConvertedValue(context,
284: new String[] { value });
285: if (convertedValue instanceof Collection) {
286: Iterator iter = ((Collection) convertedValue)
287: .iterator();
288: if (iter.hasNext()) {
289: return iter.next();
290: }
291: return null;
292: }
293: return ((Object[]) convertedValue)[0];
294: }
295: };
296:
297: Collection items = new ArrayList();
298: for (Iterator iter = new _SelectItemsIterator(this ); iter
299: .hasNext();) {
300: items.add(iter.next());
301: }
302: while (itemValues.hasNext()) {
303: Object itemValue = itemValues.next();
304:
305: if (!_SelectItemsUtil.matchValue(context, itemValue,
306: items.iterator(), converter)) {
307: _MessageUtils.addErrorMessage(context, this ,
308: INVALID_MESSAGE_ID,
309: new Object[] { _MessageUtils.getLabel(
310: context, this ) });
311: setValid(false);
312: return;
313: }
314: }
315: }
316: }
317:
318: /**
319: * First part is identical to super.validate except the empty condition.
320: * Second part: iterate through UISelectItem and UISelectItems and check
321: * current values against these items
322: */
323: public void validate(FacesContext context) {
324: // TODO : Setting the submitted value to null in the super class causes a bug, if set to null, you'll get the following error :
325: // java.lang.NullPointerException at org.apache.myfaces.renderkit._SharedRendererUtils.getConvertedUISelectManyValue(_SharedRendererUtils.java:118)
326: super .validate(context);
327: }
328:
329: protected Object getConvertedValue(FacesContext context,
330: Object submittedValue) {
331: try {
332: Renderer renderer = getRenderer(context);
333: if (renderer != null) {
334: return renderer.getConvertedValue(context, this ,
335: submittedValue);
336: } else if (submittedValue == null) {
337: return null;
338: } else if (submittedValue instanceof String[]) {
339: return _SharedRendererUtils
340: .getConvertedUISelectManyValue(context, this ,
341: (String[]) submittedValue);
342: }
343: } catch (ConverterException e) {
344: FacesMessage facesMessage = e.getFacesMessage();
345: if (facesMessage != null) {
346: context.addMessage(getClientId(context), facesMessage);
347: } else {
348: _MessageUtils.addErrorMessage(context, this ,
349: CONVERSION_MESSAGE_ID,
350: new Object[] { _MessageUtils.getLabel(context,
351: this ) });
352: }
353: setValid(false);
354: }
355: return submittedValue;
356: }
357:
358: private Iterator _createItemValuesIterator(Object convertedValue) {
359: if (convertedValue == null) {
360: return Collections.EMPTY_LIST.iterator();
361: } else {
362: Class valueClass = convertedValue.getClass();
363: if (valueClass.isArray()) {
364: return new _PrimitiveArrayIterator(convertedValue);
365: } else if (convertedValue instanceof Object[]) {
366: Object[] values = (Object[]) convertedValue;
367: return Arrays.asList(values).iterator();
368: } else if (convertedValue instanceof List) {
369: List values = (List) convertedValue;
370: return values.iterator();
371: } else {
372: // unsupported type for iteration
373: return null;
374: }
375: }
376: }
377:
378: @Override
379: public String getFamily() {
380: return COMPONENT_FAMILY;
381: }
382: }
|