1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17 /* Generated By:JJTree: Do not edit this line. AstValue.java */
18
19 package org.apache.el.parser;
20
21 import java.lang.reflect.InvocationTargetException;
22 import java.lang.reflect.Method;
23
24 import javax.el.ELException;
25 import javax.el.ELResolver;
26 import javax.el.MethodInfo;
27 import javax.el.PropertyNotFoundException;
28
29 import org.apache.el.lang.ELSupport;
30 import org.apache.el.lang.EvaluationContext;
31 import org.apache.el.util.MessageFactory;
32 import org.apache.el.util.ReflectionUtil;
33
34
35 /**
36 * @author Jacob Hookom [jacob@hookom.net]
37 * @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: jim $
38 */
39 public final class AstValue extends SimpleNode {
40
41 protected static class Target {
42 protected Object base;
43
44 protected Object property;
45 }
46
47 public AstValue(int id) {
48 super(id);
49 }
50
51 public Class getType(EvaluationContext ctx) throws ELException {
52 Target t = getTarget(ctx);
53 ctx.setPropertyResolved(false);
54 return ctx.getELResolver().getType(ctx, t.base, t.property);
55 }
56
57 private final Target getTarget(EvaluationContext ctx) throws ELException {
58 // evaluate expr-a to value-a
59 Object base = this.children[0].getValue(ctx);
60
61 // if our base is null (we know there are more properites to evaluate)
62 if (base == null) {
63 throw new PropertyNotFoundException(MessageFactory.get(
64 "error.unreachable.base", this.children[0].getImage()));
65 }
66
67 // set up our start/end
68 Object property = null;
69 int propCount = this.jjtGetNumChildren() - 1;
70 int i = 1;
71
72 // evaluate any properties before our target
73 ELResolver resolver = ctx.getELResolver();
74 if (propCount > 1) {
75 while (base != null && i < propCount) {
76 property = this.children[i].getValue(ctx);
77 ctx.setPropertyResolved(false);
78 base = resolver.getValue(ctx, base, property);
79 i++;
80 }
81 // if we are in this block, we have more properties to resolve,
82 // but our base was null
83 if (base == null || property == null) {
84 throw new PropertyNotFoundException(MessageFactory.get(
85 "error.unreachable.property", property));
86 }
87 }
88
89 property = this.children[i].getValue(ctx);
90
91 if (property == null) {
92 throw new PropertyNotFoundException(MessageFactory.get(
93 "error.unreachable.property", this.children[i]));
94 }
95
96 Target t = new Target();
97 t.base = base;
98 t.property = property;
99 return t;
100 }
101
102 public Object getValue(EvaluationContext ctx) throws ELException {
103 Object base = this.children[0].getValue(ctx);
104 int propCount = this.jjtGetNumChildren();
105 int i = 1;
106 Object property = null;
107 ELResolver resolver = ctx.getELResolver();
108 while (base != null && i < propCount) {
109 property = this.children[i].getValue(ctx);
110 if (property == null) {
111 return null;
112 } else {
113 ctx.setPropertyResolved(false);
114 base = resolver.getValue(ctx, base, property);
115 }
116 i++;
117 }
118 return base;
119 }
120
121 public boolean isReadOnly(EvaluationContext ctx) throws ELException {
122 Target t = getTarget(ctx);
123 ctx.setPropertyResolved(false);
124 return ctx.getELResolver().isReadOnly(ctx, t.base, t.property);
125 }
126
127 public void setValue(EvaluationContext ctx, Object value)
128 throws ELException {
129 Target t = getTarget(ctx);
130 ctx.setPropertyResolved(false);
131 ELResolver resolver = ctx.getELResolver();
132 resolver.setValue(ctx, t.base, t.property,
133 // coerce to the expected type
134 ELSupport.coerceToType(value,
135 resolver.getType(ctx, t.base, t.property)));
136 }
137
138 public MethodInfo getMethodInfo(EvaluationContext ctx, Class[] paramTypes)
139 throws ELException {
140 Target t = getTarget(ctx);
141 Method m = ReflectionUtil.getMethod(t.base, t.property, paramTypes);
142 return new MethodInfo(m.getName(), m.getReturnType(), m
143 .getParameterTypes());
144 }
145
146 public Object invoke(EvaluationContext ctx, Class[] paramTypes,
147 Object[] paramValues) throws ELException {
148 Target t = getTarget(ctx);
149 Method m = ReflectionUtil.getMethod(t.base, t.property, paramTypes);
150 Object result = null;
151 try {
152 result = m.invoke(t.base, (Object[]) paramValues);
153 } catch (IllegalAccessException iae) {
154 throw new ELException(iae);
155 } catch (InvocationTargetException ite) {
156 throw new ELException(ite.getCause());
157 }
158 return result;
159 }
160 }