PageRenderTime 13ms CodeModel.GetById 1ms app.highlight 9ms RepoModel.GetById 1ms app.codeStats 0ms

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

#
Java | 223 lines | 73 code | 20 blank | 130 comment | 4 complexity | 8f46e97099eaf05eba35bc6943879cb2 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.io.IOException;
 38
 39/**
 40	'This' is the type of bsh scripted objects.
 41	A 'This' object is a bsh scripted object context.  It holds a namespace 
 42	reference and implements event listeners and various other interfaces.
 43
 44	This holds a reference to the declaring interpreter for callbacks from
 45	outside of bsh.
 46*/
 47public class This implements java.io.Serializable, Runnable {
 48	/**
 49		The namespace that this This reference wraps.
 50	*/
 51	NameSpace namespace;
 52
 53	/**
 54		This is the interpreter running when the This ref was created.
 55		It's used as a default interpreter for callback through the This
 56		where there is no current interpreter instance 
 57		e.g. interface proxy or event call backs from outside of bsh.
 58	*/
 59	transient Interpreter declaringInterpreter;
 60
 61	/**
 62		invokeMethod() here is generally used by outside code to callback
 63		into the bsh interpreter. e.g. when we are acting as an interface
 64		for a scripted listener, etc.  In this case there is no real call stack
 65		so we make a default one starting with the special JAVACODE namespace
 66		and our namespace as the next.
 67	*/
 68// not thread safe... trying workaround
 69	//transient CallStack callstack;
 70
 71	/**
 72		getThis() is a factory for bsh.This type references.  The capabilities
 73		of ".this" references in bsh are version dependent up until jdk1.3.
 74		The version dependence was to support different default interface
 75		implementations.  i.e. different sets of listener interfaces which
 76		scripted objects were capable of implementing.  In jdk1.3 the 
 77		reflection proxy mechanism was introduced which allowed us to 
 78		implement arbitrary interfaces.  This is fantastic.
 79
 80		A This object is a thin layer over a namespace, comprising a bsh object
 81		context.  We create it here only if needed for the namespace.
 82
 83		Note: this method could be considered slow because of the way it 
 84		dynamically factories objects.  However I've also done tests where 
 85		I hard-code the factory to return JThis and see no change in the 
 86		rough test suite time.  This references are also cached in NameSpace.  
 87	*/
 88    static This getThis( 
 89		NameSpace namespace, Interpreter declaringInterpreter ) 
 90	{
 91		try {
 92			if ( Capabilities.canGenerateInterfaces() )
 93				return (This)Reflect.constructObject( "bsh.XThis",
 94					new Object [] { namespace, declaringInterpreter } );
 95			else if ( Capabilities.haveSwing() )
 96				return (This)Reflect.constructObject( "bsh.JThis",
 97					new Object [] { namespace, declaringInterpreter } );
 98			else
 99				return new This( namespace, declaringInterpreter );
100
101		} catch ( Exception e ) {
102			throw new InterpreterError("internal error 1 in This: "+e);
103		} 
104    }
105
106	/**
107		Get a version of the interface.
108		If this type of This implements it directly return this,
109		else try complain that we don't have the proxy mechanism.
110	*/
111	public Object getInterface( Class clas ) 
112		throws EvalError
113	{
114		if ( clas.isInstance( this ) )
115			return this;
116		else
117			throw new EvalError( "Dynamic proxy mechanism not available. "
118			+ "Cannot construct interface type: "+clas );
119	}
120
121	/*
122		I wish protected access were limited to children and not also 
123		package scope... I want this to be a singleton implemented by various
124		children.  
125	*/
126	protected This( NameSpace namespace, Interpreter declaringInterpreter ) { 
127		this.namespace = namespace; 
128		this.declaringInterpreter = declaringInterpreter;
129		//initCallStack( namespace );
130	}
131
132	public NameSpace getNameSpace() {
133		return namespace;
134	}
135
136	public String toString() {
137		return "'this' reference to Bsh object: " + namespace.name;
138	}
139
140	public void run() {
141		try {
142			invokeMethod( "run", new Object[0] );
143		} catch( EvalError e ) {
144			declaringInterpreter.error(
145				"Exception in runnable:" + e );
146		}
147	}
148
149	/**
150		Invoke specified method from outside java code, using the declaring 
151		interpreter and current namespace.
152
153		The call stack will appear as if the method is being invoked from
154		outside of bsh in native java code.
155	*/
156	public Object invokeMethod( String name, Object [] args ) 
157		throws EvalError
158	{
159		// null callstack, one will be created for us in namespace.invokMethod
160		// null callerInfo is legal
161		return invokeMethod( name, args, declaringInterpreter, null, null );
162	}
163
164	/**
165		Invoke specified method with specified interpreter.
166		This is simply a convenience method.
167	*/
168	public Object invokeMethod( 
169		String name, Object [] args, Interpreter interpreter, 
170			CallStack callstack, SimpleNode callerInfo  ) 
171		throws EvalError
172	{
173		return namespace.invokeMethod( 
174			name, args, interpreter, callstack, callerInfo );
175	}
176
177
178	/**
179		Bind a This reference to a parent's namespace with the specified
180		declaring interpreter.  Also re-init the callstack.  It's necessary 
181		to bind a This reference before it can be used after deserialization.
182		This is used by the bsh load() command.
183		<p>
184
185		This is a static utility method because it's used by a bsh command
186		bind() and the interpreter doesn't currently allow access to direct 
187		methods of This objects (small hack)
188	*/
189	public static void bind( 
190		This ths, NameSpace namespace, Interpreter declaringInterpreter ) 
191	{ 
192		ths.namespace.setParent( namespace ); 
193		ths.declaringInterpreter = declaringInterpreter;
194		//ths.initCallStack( namespace );
195	}
196
197	/**
198		Remove a This reference from a parent's namespace.
199		It's necessary to unbind a This reference before serialization if
200		you don't want serialization to save the entire interpreter and all
201		enclosing namespaces.  This is used by the bsh save() command.
202		<p>
203
204		This is a static utility method because it's used by a bsh command
205		bind() and the interpreter doesn't currently allow access to direct 
206		methods of This objects (small hack)
207	public static void unbind( This ths ) {
208	}
209*/
210
211/*
212	private final void initCallStack( NameSpace namespace ) {
213		callstack = new CallStack();
214		callstack.push( namespace );
215	}
216*/
217	CallStack newCallStack() {
218		CallStack callstack = new CallStack();
219		callstack.push( namespace );
220		return callstack;
221	}
222}
223