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.util.List;
024: import java.util.Map;
025:
026: import oscript.exceptions.*;
027:
028: /**
029: * A wrapper for a java object.
030: *
031: * @author Rob Clark (rob@ti.com)
032: */
033: public class JavaObjectWrapper extends Value {
034: private Object javaObject;
035: private Value type;
036:
037: /*=======================================================================*/
038: /**
039: * Class Constructor.
040: *
041: * @param javaObject the java object this object is a wrapper for
042: */
043: JavaObjectWrapper(Object javaObject) {
044: super ();
045:
046: this .javaObject = javaObject;
047:
048: if (javaObject == null)
049: throw new ProgrammingErrorException(
050: "javaObject shouldn't be null");
051: }
052:
053: /*=======================================================================*/
054: /**
055: * Get the type of this object. The returned type doesn't have to take
056: * into account the possibility of a script type extending a built-in
057: * type, since that is handled by {@link #getType}.
058: *
059: * @return the object's type
060: */
061: protected Value getTypeImpl() {
062: if (type == null)
063: type = JavaClassWrapper.getClassWrapper(javaObject
064: .getClass());
065: return type;
066: }
067:
068: /*=======================================================================*/
069: /**
070: * Return the object used for implementing <i>synchronized</i>. For a
071: * normal script object, the object is it's own monitor. For a java
072: * object, it is the java object rather than the {@link JavaObjectWrapper}.
073: *
074: * @return the object to synchronize on
075: */
076: public Object getMonitor() {
077: return javaObject;
078: }
079:
080: private static final Value[] NO_ARGS = new Value[0];
081:
082: /*=======================================================================*/
083: /**
084: * Convert this object to a native java <code>boolean</code> value.
085: *
086: * @return a boolean value
087: * @throws PackagedScriptObjectException(NoSuchMemberException)
088: */
089: public boolean castToBoolean() throws PackagedScriptObjectException {
090: Value fxn = getMember("booleanValue", false);
091:
092: if (fxn == null)
093: return super .castToBoolean();
094: else
095: return fxn.callAsFunction(NO_ARGS).castToBoolean();
096: }
097:
098: /*=======================================================================*/
099: /**
100: * Convert this object to a native java <code>String</code> value.
101: *
102: * @return a String value
103: * @throws PackagedScriptObjectException(NoSuchMethodException)
104: */
105: public String castToString() throws PackagedScriptObjectException {
106: String str = javaObject.toString();
107:
108: if (str == null)
109: str = NULL.castToString();
110:
111: return str;
112: }
113:
114: /*=======================================================================*/
115: /**
116: * Convert this object to a native java <code>long</code> value.
117: *
118: * @return a long value
119: * @throws PackagedScriptObjectException(NoSuchMemberException)
120: */
121: public long castToExactNumber()
122: throws PackagedScriptObjectException {
123: Value fxn = getMember("longValue", false);
124:
125: if (fxn == null)
126: fxn = getMember("intValue", false);
127:
128: if (fxn == null)
129: fxn = getMember("shortValue", false);
130:
131: if (fxn == null)
132: fxn = getMember("byteValue", false);
133:
134: if (fxn == null)
135: return super .castToExactNumber();
136: else
137: return fxn.callAsFunction(NO_ARGS).castToExactNumber();
138: }
139:
140: /*=======================================================================*/
141: /**
142: * Convert this object to a native java <code>double</code> value.
143: *
144: * @return a double value
145: * @throws PackagedScriptObjectException(NoSuchMemberException)
146: */
147: public double castToInexactNumber()
148: throws PackagedScriptObjectException {
149: Value fxn = getMember("doubleValue", false);
150:
151: if (fxn == null)
152: fxn = getMember("floatValue", false);
153:
154: if (fxn == null)
155: return super .castToInexactNumber();
156: else
157: return fxn.callAsFunction(NO_ARGS).castToInexactNumber();
158: }
159:
160: /*=======================================================================*/
161: /**
162: * Convert this object to a native java <code>Object</code> value.
163: *
164: * @return a java object
165: * @throws PackagedScriptObjectException(NoSuchMethodException)
166: */
167: public Object castToJavaObject()
168: throws PackagedScriptObjectException {
169: return javaObject;
170: }
171:
172: /*=======================================================================*/
173: /**
174: * Perform the "==" operation.
175: *
176: * @param val the other value
177: * @return the result
178: * @throws PackagedScriptObjectException(NoSuchMemberException)
179: */
180: public Value bopEquals(Value val)
181: throws PackagedScriptObjectException {
182: Object valJavaObject = val.castToJavaObject();
183:
184: if ((javaObject instanceof Comparable)
185: && (valJavaObject instanceof Comparable)) {
186: int r = ((Comparable) javaObject).compareTo(valJavaObject);
187:
188: return OBoolean.makeBoolean(r == 0);
189: }
190:
191: if (javaObject.equals(valJavaObject))
192: return OBoolean.TRUE;
193: else
194: return val.bopEqualsR(this , noSuchMember("=="));
195: }
196:
197: public Value bopEqualsR(Value val, PackagedScriptObjectException e)
198: throws PackagedScriptObjectException {
199: Object valJavaObject = val.castToJavaObject();
200:
201: if ((javaObject instanceof Comparable)
202: && (valJavaObject instanceof Comparable)) {
203: int r = ((Comparable) valJavaObject).compareTo(javaObject);
204:
205: return OBoolean.makeBoolean(r == 0);
206: }
207:
208: if (valJavaObject.equals(javaObject))
209: return OBoolean.TRUE;
210: else
211: return super .bopEqualsR(val, e);
212: }
213:
214: /*=======================================================================*/
215: /**
216: * Perform the "!=" operation.
217: *
218: * @param val the other value
219: * @return the result
220: * @throws PackagedScriptObjectException(NoSuchMemberException)
221: */
222: public Value bopNotEquals(Value val)
223: throws PackagedScriptObjectException {
224: Object valJavaObject = val.castToJavaObject();
225:
226: if ((javaObject instanceof Comparable)
227: && (valJavaObject instanceof Comparable)) {
228: int r = ((Comparable) javaObject).compareTo(valJavaObject);
229:
230: return OBoolean.makeBoolean(r != 0);
231: }
232:
233: if (javaObject.equals(valJavaObject))
234: return OBoolean.FALSE;
235: else
236: return val.bopNotEqualsR(this , noSuchMember("!="));
237: }
238:
239: public Value bopNotEqualsR(Value val,
240: PackagedScriptObjectException e)
241: throws PackagedScriptObjectException {
242: Object valJavaObject = val.castToJavaObject();
243:
244: if ((javaObject instanceof Comparable)
245: && (valJavaObject instanceof Comparable)) {
246: int r = ((Comparable) valJavaObject).compareTo(javaObject);
247:
248: return OBoolean.makeBoolean(r != 0);
249: }
250:
251: if (valJavaObject.equals(javaObject))
252: return OBoolean.FALSE;
253: else
254: return super .bopNotEqualsR(val, e);
255: }
256:
257: /*=======================================================================*/
258: /**
259: * Perform the "<" operation.
260: *
261: * @param val the other value
262: * @return the result
263: * @throws PackagedScriptObjectException(NoSuchMemberException)
264: */
265: public Value bopLessThan(Value val)
266: throws PackagedScriptObjectException {
267: Object valJavaObject = val.castToJavaObject();
268:
269: if ((javaObject instanceof Comparable)
270: && (valJavaObject instanceof Comparable)) {
271: int r = ((Comparable) javaObject).compareTo(valJavaObject);
272:
273: return OBoolean.makeBoolean(r < 0);
274: }
275:
276: return super .bopLessThan(val);
277: }
278:
279: public Value bopLessThanR(Value val, PackagedScriptObjectException e)
280: throws PackagedScriptObjectException {
281: Object valJavaObject = val.castToJavaObject();
282:
283: if ((javaObject instanceof Comparable)
284: && (valJavaObject instanceof Comparable)) {
285: int r = ((Comparable) valJavaObject).compareTo(javaObject);
286:
287: return OBoolean.makeBoolean(r < 0);
288: }
289:
290: return super .bopLessThanR(val, e);
291: }
292:
293: /*=======================================================================*/
294: /**
295: * Perform the ">" operation.
296: *
297: * @param val the other value
298: * @return the result
299: * @throws PackagedScriptObjectException(NoSuchMemberException)
300: */
301: public Value bopGreaterThan(Value val)
302: throws PackagedScriptObjectException {
303: Object valJavaObject = val.castToJavaObject();
304:
305: if ((javaObject instanceof Comparable)
306: && (valJavaObject instanceof Comparable)) {
307: int r = ((Comparable) javaObject).compareTo(valJavaObject);
308:
309: return OBoolean.makeBoolean(r > 0);
310: }
311:
312: return super .bopGreaterThan(val);
313: }
314:
315: public Value bopGreaterThanR(Value val,
316: PackagedScriptObjectException e)
317: throws PackagedScriptObjectException {
318: Object valJavaObject = val.castToJavaObject();
319:
320: if ((javaObject instanceof Comparable)
321: && (valJavaObject instanceof Comparable)) {
322: int r = ((Comparable) valJavaObject).compareTo(javaObject);
323:
324: return OBoolean.makeBoolean(r > 0);
325: }
326:
327: return super .bopGreaterThanR(val, e);
328: }
329:
330: /*=======================================================================*/
331: /**
332: * Perform the "<=" operation.
333: *
334: * @param val the other value
335: * @return the result
336: * @throws PackagedScriptObjectException(NoSuchMemberException)
337: */
338: public Value bopLessThanOrEquals(Value val)
339: throws PackagedScriptObjectException {
340: Object valJavaObject = val.castToJavaObject();
341:
342: if ((javaObject instanceof Comparable)
343: && (valJavaObject instanceof Comparable)) {
344: int r = ((Comparable) javaObject).compareTo(valJavaObject);
345:
346: return OBoolean.makeBoolean(r <= 0);
347: }
348:
349: return super .bopLessThanOrEquals(val);
350: }
351:
352: public Value bopLessThanOrEqualsR(Value val,
353: PackagedScriptObjectException e)
354: throws PackagedScriptObjectException {
355: Object valJavaObject = val.castToJavaObject();
356:
357: if ((javaObject instanceof Comparable)
358: && (valJavaObject instanceof Comparable)) {
359: int r = ((Comparable) valJavaObject).compareTo(javaObject);
360:
361: return OBoolean.makeBoolean(r <= 0);
362: }
363:
364: return super .bopLessThanOrEqualsR(val, e);
365: }
366:
367: /*=======================================================================*/
368: /**
369: * Perform the ">=" operation.
370: *
371: * @param val the other value
372: * @return the result
373: * @throws PackagedScriptObjectException(NoSuchMemberException)
374: */
375: public Value bopGreaterThanOrEquals(Value val)
376: throws PackagedScriptObjectException {
377: Object valJavaObject = val.castToJavaObject();
378:
379: if ((javaObject instanceof Comparable)
380: && (valJavaObject instanceof Comparable)) {
381: int r = ((Comparable) javaObject).compareTo(valJavaObject);
382:
383: return OBoolean.makeBoolean(r >= 0);
384: }
385:
386: return super .bopGreaterThanOrEquals(val);
387: }
388:
389: public Value bopGreaterThanOrEqualsR(Value val,
390: PackagedScriptObjectException e)
391: throws PackagedScriptObjectException {
392: Object valJavaObject = val.castToJavaObject();
393:
394: if ((javaObject instanceof Comparable)
395: && (valJavaObject instanceof Comparable)) {
396: int r = ((Comparable) valJavaObject).compareTo(javaObject);
397:
398: return OBoolean.makeBoolean(r >= 0);
399: }
400:
401: return super .bopGreaterThanOrEqualsR(val, e);
402: }
403:
404: /*=======================================================================*/
405: /**
406: * For types that implement <code>elementAt</code>, this returns the
407: * number of elements.
408: *
409: * @return an integer length
410: * @throws PackagedScriptObjectException(NoSuchMemberException)
411: * @see #elementAt
412: * @see #elementsAt
413: */
414: public int length() throws PackagedScriptObjectException {
415: if (javaObject instanceof Map)
416: JavaBridge.convertToScriptObject(((Map) javaObject).size());
417: else if (javaObject instanceof List)
418: JavaBridge
419: .convertToScriptObject(((List) javaObject).size());
420:
421: return super .length();
422: }
423:
424: /*=======================================================================*/
425: /**
426: * Get the specified index of this object, if this object is an array. If
427: * needed, the array is grown to the appropriate size.
428: *
429: * @param idx the index to get
430: * @return a reference to the member
431: * @throws PackagedScriptObjectException(NoSuchMemberException)
432: * @see #length
433: * @see #elementsAt
434: */
435: public Value elementAt(Value idx)
436: throws PackagedScriptObjectException {
437: if (javaObject instanceof Map)
438: return new MapAccessor((Map) javaObject, idx
439: .castToJavaObject());
440: else if (javaObject instanceof List)
441: return new ListAccessor((List) javaObject, (int) (idx
442: .castToExactNumber()));
443:
444: return super .elementAt(idx);
445: }
446:
447: private static class MapAccessor extends AbstractReference {
448: private Map map;
449: private Object key;
450:
451: MapAccessor(Map map, Object key) {
452: super ();
453: this .map = map;
454: this .key = key;
455: }
456:
457: public void opAssign(Value val)
458: throws PackagedScriptObjectException {
459: map.put(key, val.castToJavaObject());
460: }
461:
462: protected Value get() {
463: return JavaBridge.convertToScriptObject(map.get(key));
464: }
465: }
466:
467: private static class ListAccessor extends AbstractReference {
468: private List list;
469: private int idx;
470:
471: ListAccessor(List list, int idx) {
472: super ();
473: this .list = list;
474: this .idx = idx;
475: }
476:
477: public void opAssign(Value val)
478: throws PackagedScriptObjectException {
479: list.set(idx, val.castToJavaObject());
480: }
481:
482: protected Value get() {
483: return JavaBridge.convertToScriptObject(list.get(idx));
484: }
485: }
486:
487: /*=======================================================================*/
488: /**
489: * Get the specified range of this object, if this object is an array.
490: * This returns a copy of a range of the array.
491: *
492: * @param idx1 the index index of the beginning of the range, inclusive
493: * @param idx2 the index of the end of the range, inclusive
494: * @return a copy of the specified range of this array
495: * @throws PackagedScriptObjectException(NoSuchMemberException)
496: * @see #length
497: * @see #elementAt
498: */
499: public Value elementsAt(Value idx1, Value idx2)
500: throws PackagedScriptObjectException {
501: if (javaObject instanceof List) {
502: List l = (List) javaObject;
503: int i1 = (int) (idx1.castToExactNumber());
504: int i2 = (int) (idx2.castToExactNumber());
505:
506: Value arr = new OArray();
507:
508: for (int i = i1; i <= i2; i++)
509: arr.elementAt(JavaBridge.convertToScriptObject(i))
510: .opAssign(
511: JavaBridge.convertToScriptObject(l
512: .get(i)));
513:
514: return arr;
515: }
516:
517: return super .elementsAt(idx1, idx2);
518: }
519: }
520:
521: /*
522: * Local Variables:
523: * tab-width: 2
524: * indent-tabs-mode: nil
525: * mode: java
526: * c-indentation-style: java
527: * c-basic-offset: 2
528: * eval: (c-set-offset 'substatement-open '0)
529: * eval: (c-set-offset 'case-label '+)
530: * eval: (c-set-offset 'inclass '+)
531: * eval: (c-set-offset 'inline-open '0)
532: * End:
533: */
|