PageRenderTime 43ms CodeModel.GetById 29ms app.highlight 11ms RepoModel.GetById 1ms app.codeStats 0ms

/jEdit/tags/jedit-4-0-pre5/bsh/LHS.java

#
Java | 205 lines | 132 code | 23 blank | 50 comment | 31 complexity | 10587853b7d5de544de6c85e813ca4ee MD5 | raw file
  1/*****************************************************************************
  2 *                                                                           *
  3 *  This file is part of the BeanShell Java Scripting distribution.          *
  4 *  Documentation and updates may be found at http://www.beanshell.org/      *
  5 *                                                                           *
  6 *  Sun Public License Notice:                                               *
  7 *                                                                           *
  8 *  The contents of this file are subject to the Sun Public License Version  *
  9 *  1.0 (the "License"); you may not use this file except in compliance with *
 10 *  the License. A copy of the License is available at http://www.sun.com    * 
 11 *                                                                           *
 12 *  The Original Code is BeanShell. The Initial Developer of the Original    *
 13 *  Code is Pat Niemeyer. Portions created by Pat Niemeyer are Copyright     *
 14 *  (C) 2000.  All Rights Reserved.                                          *
 15 *                                                                           *
 16 *  GNU Public License Notice:                                               *
 17 *                                                                           *
 18 *  Alternatively, the contents of this file may be used under the terms of  *
 19 *  the GNU Lesser General Public License (the "LGPL"), in which case the    *
 20 *  provisions of LGPL are applicable instead of those above. If you wish to *
 21 *  allow use of your version of this file only under the  terms of the LGPL *
 22 *  and not to allow others to use your version of this file under the SPL,  *
 23 *  indicate your decision by deleting the provisions above and replace      *
 24 *  them with the notice and other provisions required by the LGPL.  If you  *
 25 *  do not delete the provisions above, a recipient may use your version of  *
 26 *  this file under either the SPL or the LGPL.                              *
 27 *                                                                           *
 28 *  Patrick Niemeyer (pat@pat.net)                                           *
 29 *  Author of Learning Java, O'Reilly & Associates                           *
 30 *  http://www.pat.net/~pat/                                                 *
 31 *                                                                           *
 32 *****************************************************************************/
 33
 34
 35package bsh;
 36
 37import java.lang.reflect.Field;
 38import java.util.Hashtable;
 39
 40/**
 41	The left hand side in an assignment
 42
 43	This is probably the most debatable design issue in bsh...
 44	Because of the way things started, the grammar splits on whether
 45	something is an LHS or not...  The alternative would be to wrap all
 46	objects in bsh, rather than just carrying types that might be used in
 47	an assignment.  Wrapping all objects, say, in a generalized BshObject 
 48	type, would also provide a nice place to put all the reflection stuff, 
 49	which is now static in bsh.Reflect
 50
 51	Note: moving some stuff from Reflect to a BshObject, but not going
 52	as far as the above yet...
 53*/
 54class LHS implements ParserConstants, java.io.Serializable
 55{
 56	NameSpace nameSpace;
 57
 58	static final int
 59		VARIABLE = 0,
 60		FIELD = 1,
 61		PROPERTY = 2,
 62		INDEX = 3;
 63
 64	int type;
 65
 66	String varName;
 67	String propName;
 68	Field field;
 69	Object object;
 70	int index;
 71
 72	LHS(NameSpace nameSpace, String varName)
 73	{
 74		type = VARIABLE;
 75		this.varName = varName;
 76		this.nameSpace = nameSpace;
 77	}
 78
 79	// Static field
 80	LHS(Field field)
 81	{
 82		type = FIELD;
 83		this.object = null;
 84		this.field = field;
 85	}
 86
 87	// Object field
 88	LHS(Object object, Field field)
 89	{
 90		if(object == null)
 91			throw new NullPointerException("constructed empty LHS");
 92
 93		type = FIELD;
 94		this.object = object;
 95		this.field = field;
 96	}
 97
 98	// Object property
 99	LHS(Object object, String propName)
100	{
101		if(object == null)
102			throw new NullPointerException("constructed empty LHS");
103
104		type = PROPERTY;
105		this.object = object;
106		this.propName = propName;
107	}
108
109	// Array index
110	LHS(Object array, int index)
111	{
112		if(array == null)
113			throw new NullPointerException("constructed empty LHS");
114
115		type = INDEX;
116		this.object = array;
117		this.index = index;
118	}
119
120	public Object getValue() throws EvalError
121	{
122		if(type == VARIABLE)
123			return nameSpace.getVariable(varName);
124		else if (type == FIELD)
125			try {
126				return field.get(object);
127			}
128			catch(IllegalAccessException e2) {
129				throw new EvalError("Can't read field: " + field);
130			}
131		else if(type == PROPERTY)
132			try {
133				return Reflect.getObjectProperty(object, propName);
134			}
135			catch(ReflectError e) {
136				Interpreter.debug(e.getMessage());
137				throw new EvalError("No such property: " + propName);
138			}
139		else if(type == INDEX)
140			try
141			{
142				return Reflect.getIndex(object, index);
143			}
144			catch(Exception e)
145			{
146				throw new EvalError("Array access: " + e);
147			}
148
149		throw new InterpreterError("LHS type");
150	}
151
152	public Object assign( Object val ) throws EvalError
153	{
154		if ( type == VARIABLE )
155			nameSpace.setVariable(varName, val);
156		else 
157		if ( type == FIELD )
158			try {
159				if(val instanceof Primitive)
160					val = ((Primitive)val).getValue();
161
162				field.set(object, val);
163				return val;
164			}
165			catch( NullPointerException e) {   
166    			throw new EvalError(
167					"LHS ("+field.getName()+") not a static field.");
168			}     
169   			catch( IllegalAccessException e2) {   
170				throw new EvalError(
171					"LHS ("+field.getName()+") can't access field.");
172			}     
173			catch( IllegalArgumentException e3) {
174				throw new EvalError(
175					"Argument type mismatch. "
176					+ (val == null ? "null" : val.getClass().getName())
177					+ " not assignable to field "+field.getName());
178			}
179
180		else if(type == PROPERTY)
181			if ( object instanceof Hashtable )
182				((Hashtable)object).put(propName, val);
183			else
184				try {
185					Reflect.setObjectProperty(object, propName, val);
186				}
187				catch(ReflectError e) {
188					Interpreter.debug("Assignment: " + e.getMessage());
189					throw new EvalError("No such property: " + propName);
190				}
191		else if(type == INDEX)
192			try {
193				Reflect.setIndex(object, index, val);
194			} catch(TargetError e1) { // pass along target error
195				throw e1;
196			} catch(Exception e) {
197				throw new EvalError("Assignment: " + e.getMessage());
198			}
199
200		return val;
201	}
202
203	public String toString() { return "LHS"; }
204}
205