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.Iterator;
022:
023: public class CompositeELResolver extends ELResolver {
024:
025: private int size;
026:
027: private ELResolver[] resolvers;
028:
029: public CompositeELResolver() {
030: this .size = 0;
031: this .resolvers = new ELResolver[2];
032: }
033:
034: public void add(ELResolver elResolver) {
035: if (elResolver == null) {
036: throw new NullPointerException();
037: }
038:
039: if (this .size >= this .resolvers.length) {
040: ELResolver[] nr = new ELResolver[this .size * 2];
041: System.arraycopy(this .resolvers, 0, nr, 0, this .size);
042: this .resolvers = nr;
043: }
044: this .resolvers[this .size++] = elResolver;
045: }
046:
047: public Object getValue(ELContext context, Object base,
048: Object property) throws NullPointerException,
049: PropertyNotFoundException, ELException {
050: context.setPropertyResolved(false);
051: int sz = this .size;
052: Object result = null;
053: for (int i = 0; i < sz; i++) {
054: result = this .resolvers[i]
055: .getValue(context, base, property);
056: if (context.isPropertyResolved()) {
057: return result;
058: }
059: }
060: return null;
061: }
062:
063: public void setValue(ELContext context, Object base,
064: Object property, Object value) throws NullPointerException,
065: PropertyNotFoundException, PropertyNotWritableException,
066: ELException {
067: context.setPropertyResolved(false);
068: int sz = this .size;
069: for (int i = 0; i < sz; i++) {
070: this .resolvers[i].setValue(context, base, property, value);
071: if (context.isPropertyResolved()) {
072: return;
073: }
074: }
075: }
076:
077: public boolean isReadOnly(ELContext context, Object base,
078: Object property) throws NullPointerException,
079: PropertyNotFoundException, ELException {
080: context.setPropertyResolved(false);
081: int sz = this .size;
082: boolean readOnly = false;
083: for (int i = 0; i < sz; i++) {
084: readOnly = this .resolvers[i].isReadOnly(context, base,
085: property);
086: if (context.isPropertyResolved()) {
087: return readOnly;
088: }
089: }
090: return false;
091: }
092:
093: public Iterator<FeatureDescriptor> getFeatureDescriptors(
094: ELContext context, Object base) {
095: return new FeatureIterator(context, base, this .resolvers,
096: this .size);
097: }
098:
099: public Class<?> getCommonPropertyType(ELContext context, Object base) {
100: int sz = this .size;
101: Class<?> commonType = null, type = null;
102: for (int i = 0; i < sz; i++) {
103: type = this .resolvers[i].getCommonPropertyType(context,
104: base);
105: if (type != null
106: && (commonType == null || commonType
107: .isAssignableFrom(type))) {
108: commonType = type;
109: }
110: }
111: return commonType;
112: }
113:
114: public Class<?> getType(ELContext context, Object base,
115: Object property) throws NullPointerException,
116: PropertyNotFoundException, ELException {
117: context.setPropertyResolved(false);
118: int sz = this .size;
119: Class<?> type;
120: for (int i = 0; i < sz; i++) {
121: type = this .resolvers[i].getType(context, base, property);
122: if (context.isPropertyResolved()) {
123: return type;
124: }
125: }
126: return null;
127: }
128:
129: private final static class FeatureIterator implements
130: Iterator<FeatureDescriptor> {
131:
132: private final ELContext context;
133:
134: private final Object base;
135:
136: private final ELResolver[] resolvers;
137:
138: private final int size;
139:
140: private Iterator itr;
141:
142: private int idx;
143:
144: public FeatureIterator(ELContext context, Object base,
145: ELResolver[] resolvers, int size) {
146: this .context = context;
147: this .base = base;
148: this .resolvers = resolvers;
149: this .size = size;
150:
151: this .idx = 0;
152: this .guaranteeIterator();
153: }
154:
155: private void guaranteeIterator() {
156: while (this .itr == null && this .idx < this .size) {
157: this .itr = this .resolvers[this .idx]
158: .getFeatureDescriptors(this .context, this .base);
159: this .idx++;
160: }
161: }
162:
163: public boolean hasNext() {
164: return this .itr != null;
165: }
166:
167: public FeatureDescriptor next() {
168: Object result = null;
169: if (this .itr != null) {
170: if (this .itr.hasNext()) {
171: result = this .itr.next();
172: if (!this .itr.hasNext()) {
173: this .itr = null;
174: this .guaranteeIterator();
175: }
176: }
177: }
178: return (FeatureDescriptor) result;
179: }
180:
181: public void remove() {
182: throw new UnsupportedOperationException();
183: }
184: }
185:
186: }
|