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.samples.extensions;
017:
018: import java.beans.FeatureDescriptor;
019: import java.lang.reflect.Method;
020: import java.util.Iterator;
021:
022: import javax.el.ELContext;
023: import javax.el.ELResolver;
024: import javax.el.ExpressionFactory;
025: import javax.el.PropertyNotWritableException;
026: import javax.el.ValueExpression;
027:
028: import de.odysseus.el.ExpressionFactoryImpl;
029: import de.odysseus.el.tree.TreeBuilder;
030: import de.odysseus.el.tree.TreeStore;
031: import de.odysseus.el.tree.impl.Builder;
032: import de.odysseus.el.tree.impl.Cache;
033: import de.odysseus.el.util.SimpleContext;
034:
035: /**
036: * Simple method resolver to illustrate <em>JUEL</em>'s method invocation extension.
037: * This resolver is responsible to resolve a single method.
038: *
039: * @author Christoph Beck
040: */
041: public class MethodInvocations {
042: static class MethodResolver extends ELResolver {
043: private final Method method;
044:
045: public MethodResolver(Method method) {
046: this .method = method;
047: }
048:
049: @Override
050: public Method getValue(ELContext context, Object base,
051: Object prop) {
052: if (method.getDeclaringClass().isInstance(base)
053: && method.getName().equals(prop.toString())) {
054: context.setPropertyResolved(true);
055: return method;
056: }
057: return null;
058: }
059:
060: @Override
061: public void setValue(ELContext context, Object base,
062: Object property, Object value) {
063: throw new PropertyNotWritableException();
064: }
065:
066: @Override
067: public Class<?> getCommonPropertyType(ELContext context,
068: Object base) {
069: return Object.class;
070: }
071:
072: @Override
073: public boolean isReadOnly(ELContext context, Object base,
074: Object property) {
075: return true;
076: }
077:
078: @Override
079: public Class<?> getType(ELContext context, Object base,
080: Object property) {
081: return null;
082: }
083:
084: @Override
085: public Iterator<FeatureDescriptor> getFeatureDescriptors(
086: ELContext context, Object base) {
087: return null;
088: }
089: }
090:
091: /**
092: * Sample usage: enable method invocations of <code>String.matches(String)</code>.
093: */
094: public static void main(String... args)
095: throws NoSuchMethodException {
096: // this is the method we want to invoke
097: Method method = String.class.getMethod("matches", String.class);
098:
099: // create our customized builder
100: TreeBuilder builder = new Builder(
101: Builder.Feature.METHOD_INVOCATIONS);
102:
103: // create our factory which uses our customized builder
104: ExpressionFactory f = new ExpressionFactoryImpl(new TreeStore(
105: builder, new Cache(10)));
106:
107: // create our resolver
108: ELResolver resolver = new MethodResolver(method);
109:
110: // create our context
111: ELContext context = new SimpleContext(resolver);
112:
113: // let's go...
114: ValueExpression e = null;
115:
116: e = f.createValueExpression(context,
117: "${'foo'.matches('foo|bar')}", boolean.class);
118: System.out.println(e.getValue(context)); // --> true
119:
120: e = f.createValueExpression(context,
121: "${'bar'.matches('foo|bar')}", boolean.class);
122: System.out.println(e.getValue(context)); // --> true
123:
124: e = f.createValueExpression(context,
125: "${'baz'.matches('foo|bar')}", boolean.class);
126: System.out.println(e.getValue(context)); // --> false
127: }
128: }
|