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.lang.reflect.Array;
022: import java.util.Arrays;
023: import java.util.Iterator;
024:
025: public class ArrayELResolver extends ELResolver {
026:
027: private final boolean readOnly;
028:
029: public ArrayELResolver() {
030: this .readOnly = false;
031: }
032:
033: public ArrayELResolver(boolean readOnly) {
034: this .readOnly = readOnly;
035: }
036:
037: public Object getValue(ELContext context, Object base,
038: Object property) throws NullPointerException,
039: PropertyNotFoundException, ELException {
040: if (context == null) {
041: throw new NullPointerException();
042: }
043:
044: if (base != null && base.getClass().isArray()) {
045: context.setPropertyResolved(true);
046: int idx = coerce(property);
047: if (idx < 0 || idx >= Array.getLength(base)) {
048: return null;
049: } else {
050: return Array.get(base, idx);
051: }
052: }
053:
054: return null;
055: }
056:
057: public Class<?> getType(ELContext context, Object base,
058: Object property) throws NullPointerException,
059: PropertyNotFoundException, ELException {
060: if (context == null) {
061: throw new NullPointerException();
062: }
063:
064: if (base != null && base.getClass().isArray()) {
065: context.setPropertyResolved(true);
066: int idx = coerce(property);
067: checkBounds(base, idx);
068: return base.getClass().getComponentType();
069: }
070:
071: return null;
072: }
073:
074: public void setValue(ELContext context, Object base,
075: Object property, Object value) throws NullPointerException,
076: PropertyNotFoundException, PropertyNotWritableException,
077: ELException {
078: if (context == null) {
079: throw new NullPointerException();
080: }
081:
082: if (base != null && base.getClass().isArray()) {
083: context.setPropertyResolved(true);
084:
085: if (this .readOnly) {
086: throw new PropertyNotWritableException(message(context,
087: "resolverNotWriteable", new Object[] { base
088: .getClass().getName() }));
089: }
090:
091: int idx = coerce(property);
092: checkBounds(base, idx);
093: Array.set(base, idx, value);
094: }
095: }
096:
097: public boolean isReadOnly(ELContext context, Object base,
098: Object property) throws NullPointerException,
099: PropertyNotFoundException, ELException {
100: if (context == null) {
101: throw new NullPointerException();
102: }
103:
104: if (base != null && base.getClass().isArray()) {
105: context.setPropertyResolved(true);
106: int idx = coerce(property);
107: checkBounds(base, idx);
108: }
109:
110: return this .readOnly;
111: }
112:
113: public Iterator<FeatureDescriptor> getFeatureDescriptors(
114: ELContext context, Object base) {
115: if (base != null && base.getClass().isArray()) {
116: FeatureDescriptor[] descs = new FeatureDescriptor[Array
117: .getLength(base)];
118: for (int i = 0; i < descs.length; i++) {
119: descs[i] = new FeatureDescriptor();
120: descs[i].setDisplayName("[" + i + "]");
121: descs[i].setExpert(false);
122: descs[i].setHidden(false);
123: descs[i].setName("" + i);
124: descs[i].setPreferred(true);
125: descs[i].setValue(RESOLVABLE_AT_DESIGN_TIME,
126: Boolean.FALSE);
127: descs[i].setValue(TYPE, Integer.class);
128: }
129: return Arrays.asList(descs).iterator();
130: }
131: return null;
132: }
133:
134: public Class<?> getCommonPropertyType(ELContext context, Object base) {
135: if (base != null && base.getClass().isArray()) {
136: return Integer.class;
137: }
138: return null;
139: }
140:
141: private final static void checkBounds(Object base, int idx) {
142: if (idx < 0 || idx >= Array.getLength(base)) {
143: throw new PropertyNotFoundException(
144: new ArrayIndexOutOfBoundsException(idx)
145: .getMessage());
146: }
147: }
148:
149: private final static int coerce(Object property) {
150: if (property instanceof Number) {
151: return ((Number) property).intValue();
152: }
153: if (property instanceof Character) {
154: return ((Character) property).charValue();
155: }
156: if (property instanceof Boolean) {
157: return (((Boolean) property).booleanValue() ? 1 : 0);
158: }
159: if (property instanceof String) {
160: return Integer.parseInt((String) property);
161: }
162: throw new IllegalArgumentException(property != null ? property
163: .toString() : "null");
164: }
165:
166: }
|