001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: package javax.el;
019:
020: import java.beans.FeatureDescriptor;
021: import java.util.ArrayList;
022: import java.util.Arrays;
023: import java.util.Collections;
024: import java.util.Iterator;
025: import java.util.List;
026:
027: public class ListELResolver extends ELResolver {
028:
029: private final boolean readOnly;
030:
031: private final static Class UNMODIFIABLE = Collections
032: .unmodifiableList(new ArrayList()).getClass();
033:
034: public ListELResolver() {
035: this .readOnly = false;
036: }
037:
038: public ListELResolver(boolean readOnly) {
039: this .readOnly = readOnly;
040: }
041:
042: public Object getValue(ELContext context, Object base,
043: Object property) throws NullPointerException,
044: PropertyNotFoundException, ELException {
045: if (context == null) {
046: throw new NullPointerException();
047: }
048:
049: if (base instanceof List) {
050: context.setPropertyResolved(true);
051: List list = (List) base;
052: int idx = coerce(property);
053: if (idx < 0 || idx >= list.size()) {
054: return null;
055: }
056: return list.get(idx);
057: }
058:
059: return null;
060: }
061:
062: public Class<?> getType(ELContext context, Object base,
063: Object property) throws NullPointerException,
064: PropertyNotFoundException, ELException {
065: if (context == null) {
066: throw new NullPointerException();
067: }
068:
069: if (base instanceof List) {
070: context.setPropertyResolved(true);
071: List list = (List) base;
072: int idx = coerce(property);
073: if (idx < 0 || idx >= list.size()) {
074: return null;
075: }
076: Object obj = list.get(idx);
077: return (obj != null) ? obj.getClass() : null;
078: }
079:
080: return null;
081: }
082:
083: public void setValue(ELContext context, Object base,
084: Object property, Object value) throws NullPointerException,
085: PropertyNotFoundException, PropertyNotWritableException,
086: ELException {
087: if (context == null) {
088: throw new NullPointerException();
089: }
090:
091: if (base instanceof List) {
092: context.setPropertyResolved(true);
093: List list = (List) base;
094:
095: if (this .readOnly) {
096: throw new PropertyNotWritableException(message(context,
097: "resolverNotWriteable", new Object[] { base
098: .getClass().getName() }));
099: }
100:
101: int idx = coerce(property);
102: try {
103: list.set(idx, value);
104: } catch (UnsupportedOperationException e) {
105: throw new PropertyNotWritableException(e);
106: } catch (IndexOutOfBoundsException e) {
107: throw new PropertyNotFoundException(e);
108: }
109: }
110: }
111:
112: public boolean isReadOnly(ELContext context, Object base,
113: Object property) throws NullPointerException,
114: PropertyNotFoundException, ELException {
115: if (context == null) {
116: throw new NullPointerException();
117: }
118:
119: if (base instanceof List) {
120: context.setPropertyResolved(true);
121: List list = (List) base;
122: int idx = coerce(property);
123: if (idx < 0 || idx >= list.size()) {
124: throw new PropertyNotFoundException(
125: new ArrayIndexOutOfBoundsException(idx)
126: .getMessage());
127: }
128: return this .readOnly
129: || UNMODIFIABLE.equals(list.getClass());
130: }
131:
132: return this .readOnly;
133: }
134:
135: public Iterator<FeatureDescriptor> getFeatureDescriptors(
136: ELContext context, Object base) {
137: if (base instanceof List) {
138: FeatureDescriptor[] descs = new FeatureDescriptor[((List) base)
139: .size()];
140: for (int i = 0; i < descs.length; i++) {
141: descs[i] = new FeatureDescriptor();
142: descs[i].setDisplayName("[" + i + "]");
143: descs[i].setExpert(false);
144: descs[i].setHidden(false);
145: descs[i].setName("" + i);
146: descs[i].setPreferred(true);
147: descs[i].setValue(RESOLVABLE_AT_DESIGN_TIME,
148: Boolean.FALSE);
149: descs[i].setValue(TYPE, Integer.class);
150: }
151: return Arrays.asList(descs).iterator();
152: }
153: return null;
154: }
155:
156: public Class<?> getCommonPropertyType(ELContext context, Object base) {
157: if (base != null && base instanceof List) {
158: return Integer.class;
159: }
160: return null;
161: }
162:
163: private final static int coerce(Object property) {
164: if (property instanceof Number) {
165: return ((Number) property).intValue();
166: }
167: if (property instanceof Character) {
168: return ((Character) property).charValue();
169: }
170: if (property instanceof Boolean) {
171: return (((Boolean) property).booleanValue() ? 1 : 0);
172: }
173: if (property instanceof String) {
174: return Integer.parseInt((String) property);
175: }
176: throw new IllegalArgumentException(property != null ? property
177: .toString() : "null");
178: }
179: }
|