001: /*=============================================================================
002: * Copyright Texas Instruments 2000-2004. All Rights Reserved.
003: *
004: * This program is free software; you can redistribute it and/or
005: * modify it under the terms of the GNU Lesser General Public
006: * License as published by the Free Software Foundation; either
007: * version 2 of the License, or (at your option) any later version.
008: *
009: * This program is distributed in the hope that it will be useful,
010: * but WITHOUT ANY WARRANTY; without even the implied warranty of
011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012: * Lesser General Public License for more details.
013: *
014: * You should have received a copy of the GNU Lesser General Public
015: * License along with this library; if not, write to the Free Software
016: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
017: *
018: * $ProjectHeader: OSCRIPT 0.155 Fri, 20 Dec 2002 18:34:22 -0800 rclark $
019: */
020:
021: package oscript.data;
022:
023: import java.lang.reflect.*;
024: import java.util.LinkedList;
025: import java.util.Iterator;
026:
027: import oscript.exceptions.*;
028:
029: /**
030: * A wrapper for a method of a java object. Because the method that is
031: * called is determined by the arguments to the method when it is called,
032: * rather than when it is dereferenced, this is actually a wrapper for
033: * an array of all methods in a class with a certain name.
034: *
035: * @author Rob Clark (rob@ti.com)
036: */
037: public class JavaMethodWrapper extends Value implements Runnable {
038: private int id;
039: private Object javaObject;
040: private Method[] methods;
041:
042: /**
043: * The type object for an script java method.
044: */
045: public final static Value TYPE = BuiltinType
046: .makeBuiltinType("oscript.data.JavaMethodWrapper");
047: public final static String PARENT_TYPE_NAME = "oscript.data.OObject";
048: public final static String TYPE_NAME = "JavaMethod";
049: public final static String[] MEMBER_NAMES = new String[] {
050: "castToString", "callAsFunction" };
051:
052: /*=======================================================================*/
053: /**
054: * Class Constructor.
055: *
056: * @param id the name of the method
057: * @param javaObject the java-object this method is in
058: * @param methods the methods this is a wrapper for
059: */
060: JavaMethodWrapper(int id, Object javaObject, Method[] methods) {
061: super ();
062:
063: this .id = id;
064: this .javaObject = javaObject;
065: this .methods = methods;
066: }
067:
068: /*=======================================================================*/
069: /**
070: * Get the type of this object. The returned type doesn't have to take
071: * into account the possibility of a script type extending a built-in
072: * type, since that is handled by {@link #getType}.
073: *
074: * @return the object's type
075: */
076: protected Value getTypeImpl() {
077: return TYPE;
078: }
079:
080: /*=======================================================================*/
081: /**
082: * Implementing the runnable interface.
083: */
084: public void run() {
085: callAsFunction(NO_ARGS);
086: }
087:
088: private static final Value[] NO_ARGS = new Value[0];
089:
090: /*=======================================================================*/
091: /**
092: * Return a hash code value for this object.
093: *
094: * @return a hash code value
095: * @see java.lang.Object#hashCode()
096: */
097: public int hashCode() {
098: return methods[0].hashCode();
099: }
100:
101: /*=======================================================================*/
102: /**
103: * Compare two objects for equality.
104: *
105: * @param obj the object to compare to this object
106: * @return <code>true</code> if equals, else <code>false</code>
107: * @see java.lang.Object#equals(java.lang.Object)
108: */
109: public boolean equals(Object obj) {
110: return ((obj instanceof JavaMethodWrapper) && (((JavaMethodWrapper) obj).methods[0]
111: .equals(methods[0])));
112: }
113:
114: /*=======================================================================*/
115: /**
116: * Perform the "==" operation.
117: *
118: * @param val the other value
119: * @return the result
120: * @throws PackagedScriptObjectException(NoSuchMethodException)
121: */
122: public Value bopEquals(Value val)
123: throws PackagedScriptObjectException {
124: return OBoolean.makeBoolean(equals(val));
125: }
126:
127: /*=======================================================================*/
128: /**
129: * Perform the "!=" operation.
130: *
131: * @param val the other value
132: * @return the result
133: * @throws PackagedScriptObjectException(NoSuchMethodException)
134: */
135: public Value bopNotEquals(Value val)
136: throws PackagedScriptObjectException {
137: return OBoolean.makeBoolean(!equals(val));
138: }
139:
140: /*=======================================================================*/
141: /**
142: * Convert this object to a native java <code>String</code> value.
143: *
144: * @return a String value
145: * @throws PackagedScriptObjectException(NoSuchMethodException)
146: */
147: public String castToString() throws PackagedScriptObjectException {
148: return "[method: " + Symbol.getSymbol(id).castToString() + "]";
149: }
150:
151: /*=======================================================================*/
152: /**
153: * Call this object as a function.
154: *
155: * @param sf the current stack frame
156: * @param args the arguments to the function, or <code>null</code> if none
157: * @return the value returned by the function
158: * @throws PackagedScriptObjectException
159: * @see Function
160: */
161: public Value callAsFunction(oscript.util.StackFrame sf,
162: oscript.util.MemberTable args)
163: throws PackagedScriptObjectException {
164: return JavaBridge.convertToScriptObject(JavaBridge.call(
165: methodAccessor, id, javaObject, methods, sf, args));
166: }
167:
168: private static final JavaBridge.JavaCallableAccessor methodAccessor = new JavaBridge.JavaCallableAccessor() {
169:
170: public Class[] getParameterTypes(Object javaCallable) {
171: return ((Method) javaCallable).getParameterTypes();
172: }
173:
174: public Object call(Object javaCallable, Object javaObject,
175: Object[] args) throws InvocationTargetException,
176: InstantiationException, IllegalAccessException {
177: return ((Method) javaCallable).invoke(javaObject, args);
178: }
179: };
180: }
181:
182: /*
183: * Local Variables:
184: * tab-width: 2
185: * indent-tabs-mode: nil
186: * mode: java
187: * c-indentation-style: java
188: * c-basic-offset: 2
189: * eval: (c-set-offset 'substatement-open '0)
190: * eval: (c-set-offset 'case-label '+)
191: * eval: (c-set-offset 'inclass '+)
192: * eval: (c-set-offset 'inline-open '0)
193: * End:
194: */
|