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.tree.impl.ast;
017:
018: import java.lang.reflect.InvocationTargetException;
019: import java.lang.reflect.Method;
020: import java.util.List;
021:
022: import javax.el.ELContext;
023: import javax.el.ELException;
024:
025: import de.odysseus.el.misc.LocalMessages;
026: import de.odysseus.el.misc.TypeConversions;
027: import de.odysseus.el.tree.Bindings;
028: import de.odysseus.el.tree.FunctionNode;
029:
030: public final class AstFunction extends AstRightValue implements
031: FunctionNode {
032: private final String name;
033: private final int index;
034: private final List<AstNode> nodes;
035:
036: public AstFunction(String name, int index, List<AstNode> nodes) {
037: this .nodes = nodes;
038: this .name = name;
039: this .index = index;
040: }
041:
042: @Override
043: public Object eval(Bindings bindings, ELContext context) {
044: Method method = bindings.getFunction(index);
045: Class[] types = method.getParameterTypes();
046: Object[] params = null;
047: if (types.length > 0) {
048: params = new Object[types.length];
049: for (int i = 0; i < params.length; i++) {
050: Object param = nodes.get(i).eval(bindings, context);
051: if (param != null || types[i].isPrimitive()) {
052: params[i] = TypeConversions.coerceToType(param,
053: types[i]);
054: }
055: }
056: }
057: try {
058: return method.invoke(null, params);
059: } catch (IllegalAccessException e) {
060: throw new ELException(LocalMessages.get(
061: "error.function.access", name), e);
062: } catch (InvocationTargetException e) {
063: throw new ELException(LocalMessages.get(
064: "error.function.invocation", name), e.getCause());
065: }
066: }
067:
068: @Override
069: public String toString() {
070: return name + "(...)";
071: }
072:
073: @Override
074: public void appendStructure(StringBuilder b, Bindings bindings) {
075: b.append(bindings == null ? name : "<fn>");
076: b.append("(");
077: if (getCardinality() > 0) {
078: nodes.get(0).appendStructure(b, bindings);
079: for (int i = 1; i < getCardinality(); i++) {
080: b.append(", ");
081: nodes.get(i).appendStructure(b, bindings);
082: }
083: }
084: b.append(")");
085: }
086:
087: public int getIndex() {
088: return index;
089: }
090:
091: public String getName() {
092: return name;
093: }
094:
095: public int getParamCount() {
096: return getCardinality();
097: }
098:
099: public int getCardinality() {
100: return nodes == null ? 0 : nodes.size();
101: }
102:
103: public AstNode getChild(int i) {
104: return nodes == null ? null : nodes.get(i);
105: }
106: }
|