PageRenderTime 22ms CodeModel.GetById 5ms app.highlight 15ms RepoModel.GetById 0ms app.codeStats 0ms

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

#
Java | 202 lines | 132 code | 23 blank | 47 comment | 31 complexity | 7ab57ec6da62b5c18f37bc31db55ce68 MD5 | raw file
Possible License(s): BSD-3-Clause, AGPL-1.0, Apache-2.0, LGPL-2.0, LGPL-3.0, GPL-2.0, CC-BY-SA-3.0, LGPL-2.1, GPL-3.0, MPL-2.0-no-copyleft-exception, IPL-1.0
  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*/
 51class LHS implements ParserConstants, java.io.Serializable
 52{
 53	NameSpace nameSpace;
 54
 55	static final int
 56		VARIABLE = 0,
 57		FIELD = 1,
 58		PROPERTY = 2,
 59		INDEX = 3;
 60
 61	int type;
 62
 63	String varName;
 64	String propName;
 65	Field field;
 66	Object object;
 67	int index;
 68
 69	LHS(NameSpace nameSpace, String varName)
 70	{
 71		type = VARIABLE;
 72		this.varName = varName;
 73		this.nameSpace = nameSpace;
 74	}
 75
 76	// Static field
 77	LHS(Field field)
 78	{
 79		type = FIELD;
 80		this.object = null;
 81		this.field = field;
 82	}
 83
 84	// Object field
 85	LHS(Object object, Field field)
 86	{
 87		if(object == null)
 88			throw new NullPointerException("constructed empty LHS");
 89
 90		type = FIELD;
 91		this.object = object;
 92		this.field = field;
 93	}
 94
 95	// Object property
 96	LHS(Object object, String propName)
 97	{
 98		if(object == null)
 99			throw new NullPointerException("constructed empty LHS");
100
101		type = PROPERTY;
102		this.object = object;
103		this.propName = propName;
104	}
105
106	// Array index
107	LHS(Object array, int index)
108	{
109		if(array == null)
110			throw new NullPointerException("constructed empty LHS");
111
112		type = INDEX;
113		this.object = array;
114		this.index = index;
115	}
116
117	public Object getValue() throws EvalError
118	{
119		if(type == VARIABLE)
120			return nameSpace.getVariable(varName);
121		else if (type == FIELD)
122			try {
123				return field.get(object);
124			}
125			catch(IllegalAccessException e2) {
126				throw new EvalError("Can't read field: " + field);
127			}
128		else if(type == PROPERTY)
129			try {
130				return Reflect.getObjectProperty(object, propName);
131			}
132			catch(ReflectError e) {
133				Interpreter.debug(e.getMessage());
134				throw new EvalError("No such property: " + propName);
135			}
136		else if(type == INDEX)
137			try
138			{
139				return Reflect.getIndex(object, index);
140			}
141			catch(Exception e)
142			{
143				throw new EvalError("Array access: " + e);
144			}
145
146		throw new InterpreterError("LHS type");
147	}
148
149	public Object assign( Object val ) throws EvalError
150	{
151		if ( type == VARIABLE )
152			nameSpace.setVariable(varName, val);
153		else 
154		if ( type == FIELD )
155			try {
156				if(val instanceof Primitive)
157					val = ((Primitive)val).getValue();
158
159				field.set(object, val);
160				return val;
161			}
162			catch( NullPointerException e) {   
163    			throw new EvalError(
164					"LHS ("+field.getName()+") not a static field.");
165			}     
166   			catch( IllegalAccessException e2) {   
167				throw new EvalError(
168					"LHS ("+field.getName()+") can't access field.");
169			}     
170			catch( IllegalArgumentException e3) {
171				throw new EvalError(
172					"Argument type mismatch. "
173					+ (val == null ? "null" : val.getClass().getName())
174					+ " not assignable to field "+field.getName());
175			}
176
177		else if(type == PROPERTY)
178			if ( object instanceof Hashtable )
179				((Hashtable)object).put(propName, val);
180			else
181				try {
182					Reflect.setObjectProperty(object, propName, val);
183				}
184				catch(ReflectError e) {
185					Interpreter.debug("Assignment: " + e.getMessage());
186					throw new EvalError("No such property: " + propName);
187				}
188		else if(type == INDEX)
189			try {
190				Reflect.setIndex(object, index, val);
191			} catch(TargetError e1) { // pass along target error
192				throw e1;
193			} catch(Exception e) {
194				throw new EvalError("Assignment: " + e.getMessage());
195			}
196
197		return val;
198	}
199
200	public String toString() { return "LHS"; }
201}
202