Source code: com/tripi/asp/GetIndexNode.java
1 /**
2 * ArrowHead ASP Server
3 * This is a source file for the ArrowHead ASP Server - an 100% Java
4 * VBScript interpreter and ASP server.
5 *
6 * For more information, see http://www.tripi.com/arrowhead
7 *
8 * Copyright (C) 2002 Terence Haddock
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 *
24 */
25 package com.tripi.asp;
26
27 import org.apache.log4j.Category;
28
29 /**
30 * This node handles the "map" expression in vbscript, such as
31 * Session("variable").
32 *
33 * @author Terence Haddock
34 * @version 0.9
35 */
36 public class GetIndexNode extends DefaultNode
37 {
38 /** Debugging category */
39 static Category DBG = Category.getInstance(GetIndexNode.class);
40
41 /** Expression to obtain index of */
42 Node ident;
43
44 /** Parameters to field expression */
45 VarListNode expr;
46
47 /** Is this expression for functions only? */
48 boolean func;
49
50 /**
51 * Get the parameters.
52 * @return parameters to obtain index of.
53 */
54 public VarListNode getExpression()
55 {
56 return expr;
57 }
58
59 /**
60 * Get the identifier.
61 * @return identifier to use
62 */
63 public Node getIdent()
64 {
65 return ident;
66 }
67
68 /**
69 * Constructor. Can be used for arrays, functions, and subroutines.
70 * @param ident Expression for field get.
71 * @param expr Parameter for field get
72 */
73 public GetIndexNode(Node ident, VarListNode expr)
74 {
75 this.ident = ident;
76 this.expr = expr;
77 this.func = false;
78 }
79
80 /**
81 * Constructor. Can be used to mark that subroutines not allowed.
82 * @param ident Expression for field get.
83 * @param expr Parameter for field get
84 * @param func Is this a function?
85 */
86 public GetIndexNode(Node ident, VarListNode expr, boolean func)
87 {
88 this.ident = ident;
89 this.expr = expr;
90 this.func = func;
91 }
92
93 /**
94 * Dumps the visual representation of this expression.
95 * @throws AspException if an error occurs.
96 * @see Node#dump()
97 */
98 public void dump() throws AspException
99 {
100 System.out.print("{I}");
101 ident.dump();
102 System.out.print("(");
103 expr.dump();
104 System.out.print(")");
105 }
106
107 /**
108 * Executes this node.
109 * @param context The context under which to evaluate this expression.
110 * @return value of this expression.
111 * @throws AspException if an error occurs.
112 * @see Node#execute(AspContext)
113 */
114 public Object execute(AspContext context) throws AspException
115 {
116 /* Intermidate object */
117 Node value;
118 if (DBG.isDebugEnabled())
119 DBG.debug("Get index of " + ident);
120 if (!(ident instanceof IdentNode))
121 {
122 /* Check for map or function nodes */
123 Object objVal = ident.execute(context);
124 /* De-reference the node */
125 while ((objVal instanceof SimpleReference) &&
126 !(objVal instanceof MapNode) &&
127 !(objVal instanceof FunctionNode)) {
128 if (DBG.isDebugEnabled())
129 DBG.debug("Dereference: " + objVal);
130 objVal = ((SimpleReference)objVal).getValue();
131 }
132 value = (Node)objVal;
133 } else {
134 /* Indirect reference */
135 Object objVal = context.getValue((IdentNode)ident);
136 while ((objVal instanceof SimpleReference) &&
137 !(objVal instanceof MapNode) &&
138 !(objVal instanceof FunctionNode)) {
139 if (DBG.isDebugEnabled())
140 DBG.debug("Dereference: " + objVal);
141 objVal = ((SimpleReference)objVal).getValue();
142 }
143 if (DBG.isDebugEnabled())
144 if (objVal != null)
145 DBG.debug("Execute on: " + objVal + "(" + objVal.getClass() + ")");
146 value = (Node)objVal;
147 }
148 /* Check for null pointer */
149 if (value == null || value instanceof NullNode) {
150 throw new AspException("NULL pointer exception");
151 }
152 /* Check for undefined functions or values */
153 if (value instanceof UndefinedValueNode) {
154 throw new AspException("Undefined function or value: "
155 + ident.toString().toUpperCase());
156 }
157 if (func && expr.size() > 1) {
158 if (value instanceof SubDefinitionNode) {
159 SubDefinitionNode sub = (SubDefinitionNode)value;
160 if (!sub.isFunction) {
161 throw new AspException("Call required for subroutine call");
162 }
163 }
164 }
165 if (value instanceof MapNode) {
166 /* Handle a map get */
167 if (DBG.isDebugEnabled())
168 DBG.debug("Map get on " + value.getClass());
169 Object ret = ((MapNode)value).getIndex(expr, context);
170 if (DBG.isDebugEnabled())
171 DBG.debug("Return: " + ret);
172 return ret;
173 }
174 if (value instanceof FunctionNode) {
175 /* Handle a function call */
176 if (DBG.isDebugEnabled())
177 DBG.debug("Execute on " + value.getClass());
178 Object ret = ((FunctionNode)value).execute(expr, context);
179 if (DBG.isDebugEnabled())
180 DBG.debug("Return: " + ret);
181 return ret;
182 }
183 /* Type conversion failure */
184 throw new AspException("Unknown type for (): " + value.getClass().getName());
185 }
186
187 /**
188 * Set the function flag.
189 * @param isFunc is a function?
190 */
191 public void setFunction(boolean isFunction)
192 {
193 this.func = isFunction;
194 }
195 };
196