001: /*
002: * Copyright 2006, 2007 Odysseus Software GmbH
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: */
016: package de.odysseus.el.util;
017:
018: import java.beans.FeatureDescriptor;
019: import java.util.Collections;
020: import java.util.HashMap;
021: import java.util.Iterator;
022: import java.util.Map;
023:
024: import javax.el.ArrayELResolver;
025: import javax.el.BeanELResolver;
026: import javax.el.CompositeELResolver;
027: import javax.el.ELContext;
028: import javax.el.ELException;
029: import javax.el.ELResolver;
030: import javax.el.ListELResolver;
031: import javax.el.MapELResolver;
032: import javax.el.PropertyNotFoundException;
033: import javax.el.PropertyNotWritableException;
034: import javax.el.ResourceBundleELResolver;
035:
036: /**
037: * Simple resolver implementation.
038: *
039: * @author Christoph Beck
040: */
041: public class SimpleResolver extends ELResolver {
042: private static final ELResolver DEFAULT_RESOLVER_READ_ONLY = new CompositeELResolver() {
043: {
044: add(new ArrayELResolver(true));
045: add(new ListELResolver(true));
046: add(new MapELResolver(true));
047: add(new ResourceBundleELResolver());
048: add(new BeanELResolver(true));
049: }
050: };
051: private static final ELResolver DEFAULT_RESOLVER_READ_WRITE = new CompositeELResolver() {
052: {
053: add(new ArrayELResolver(false));
054: add(new ListELResolver(false));
055: add(new MapELResolver(false));
056: add(new ResourceBundleELResolver());
057: add(new BeanELResolver(false));
058: }
059: };
060: private final Map<Object, Object> map = Collections
061: .synchronizedMap(new HashMap<Object, Object>());
062: private final ELResolver delegate;
063: private final boolean readOnly;
064:
065: /**
066: * Create a resolver capable of resolving top-level identifiers.
067: * Everything else is passed to the supplied delegate.
068: */
069: public SimpleResolver(ELResolver delegate, boolean readOnly) {
070: this .delegate = delegate;
071: this .readOnly = readOnly;
072: }
073:
074: /**
075: * Create a read/write resolver capable of resolving top-level identifiers.
076: * Everything else is passed to the supplied delegate.
077: */
078: public SimpleResolver(ELResolver delegate) {
079: this (delegate, false);
080: }
081:
082: /**
083: * Create a resolver capable of resolving top-level identifiers,
084: * bean properties, array values, list values, map values and resource values.
085: */
086: public SimpleResolver(boolean readOnly) {
087: this (readOnly ? DEFAULT_RESOLVER_READ_ONLY
088: : DEFAULT_RESOLVER_READ_WRITE, readOnly);
089: }
090:
091: /**
092: * Create a read/write resolver capable of resolving top-level identifiers,
093: * bean properties, array values, list values, map values and resource values.
094: */
095: public SimpleResolver() {
096: this (DEFAULT_RESOLVER_READ_WRITE, false);
097: }
098:
099: private boolean resolve(ELContext context, Object base) {
100: context.setPropertyResolved(base == null);
101: return context.isPropertyResolved();
102: }
103:
104: private Object get(Object property)
105: throws PropertyNotFoundException {
106: if (map.containsKey(property)) {
107: return map.get(property);
108: }
109: throw new PropertyNotFoundException("Cannot find property "
110: + property);
111: }
112:
113: @Override
114: public Class<?> getCommonPropertyType(ELContext context, Object base) {
115: return resolve(context, base) ? Object.class : delegate
116: .getCommonPropertyType(context, base);
117: }
118:
119: @Override
120: public Iterator<FeatureDescriptor> getFeatureDescriptors(
121: ELContext context, Object base) {
122: return resolve(context, base) ? null : delegate
123: .getFeatureDescriptors(context, base);
124: }
125:
126: @Override
127: public Class<?> getType(ELContext context, Object base,
128: Object property) throws NullPointerException,
129: PropertyNotFoundException, ELException {
130: return resolve(context, base) ? Object.class : delegate
131: .getType(context, base, property);
132: }
133:
134: @Override
135: public Object getValue(ELContext context, Object base,
136: Object property) throws NullPointerException,
137: PropertyNotFoundException, ELException {
138: return resolve(context, base) ? get(property) : delegate
139: .getValue(context, base, property);
140: }
141:
142: @Override
143: public boolean isReadOnly(ELContext context, Object base,
144: Object property) throws NullPointerException,
145: PropertyNotFoundException, ELException {
146: return resolve(context, base) ? readOnly : delegate.isReadOnly(
147: context, base, property);
148: }
149:
150: @Override
151: public void setValue(ELContext context, Object base,
152: Object property, Object value) throws NullPointerException,
153: PropertyNotFoundException, PropertyNotWritableException,
154: ELException {
155: if (resolve(context, base)) {
156: if (readOnly) {
157: throw new PropertyNotWritableException(
158: "resolver is read only!");
159: }
160: map.put(property, value);
161: } else {
162: delegate.setValue(context, base, property, value);
163: }
164: }
165: }
|