KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > es > NativeObject


1 /*
2  * Copyright (c) 1998-2006 Caucho Technology -- all rights reserved
3  *
4  * This file is part of Resin(R) Open Source
5  *
6  * Each copy or derived work must preserve the copyright notice and this
7  * notice unmodified.
8  *
9  * Resin Open Source is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * Resin Open Source is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
17  * of NON-INFRINGEMENT. See the GNU General Public License for more
18  * details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with Resin Open Source; if not, write to the
22  * Free SoftwareFoundation, Inc.
23  * 59 Temple Place, Suite 330
24  * Boston, MA 02111-1307 USA
25  *
26  * @author Scott Ferguson
27  */

28
29 package com.caucho.es;
30
31 import com.caucho.util.IntMap;
32
33 /**
34  * JavaScript object
35  */

36 class NativeObject extends Native {
37   static final int TO_OBJECT = 2;
38   static final int TO_STRING = TO_OBJECT + 1;
39   static final int VALUE_OF = TO_STRING + 1;
40   static final int TO_SOURCE = VALUE_OF + 1;
41   static final int WATCH = TO_SOURCE + 1;
42   static final int UNWATCH = WATCH + 1;
43
44   /**
45    * Create a new object based on a prototype
46    */

47   private NativeObject(String JavaDoc name, int n, int len)
48   {
49     super(name, len);
50
51     this.n = n;
52   }
53
54   /**
55    * Creates the native Object object
56    */

57   static ESObject create(Global resin)
58   {
59     Native nativeObj = new NativeObject("Object", TO_OBJECT, 1);
60     resin.objProto = new ESObject("Object", esBase);
61
62     NativeWrapper obj = new NativeWrapper(resin, nativeObj,
63                       resin.objProto, ESThunk.OBJ_THUNK);
64
65     put(resin.objProto, "toString", TO_STRING, 0, DONT_ENUM);
66     put(resin.objProto, "valueOf", VALUE_OF, 0, DONT_ENUM);
67
68     put(resin.objProto, "toSource", TO_SOURCE, 0, DONT_ENUM);
69     put(resin.objProto, "watch", WATCH, 0, DONT_ENUM);
70     put(resin.objProto, "unwatch", UNWATCH, 0, DONT_ENUM);
71
72     resin.objProto.setClean();
73     obj.setClean();
74
75     return obj;
76   }
77   
78   private static void put(ESObject obj, String JavaDoc name, int n, int len,
79               int flags)
80   {
81     ESId id = ESId.intern(name);
82     NativeObject fun = new NativeObject(name, n, len);
83     
84     try {
85       obj.put(id, fun, flags);
86     } catch (Exception JavaDoc e) {
87       throw new RuntimeException JavaDoc();
88     }
89   }
90
91   public ESBase call(Call eval, int length) throws Throwable JavaDoc
92   {
93     switch (n) {
94       // Object prototype stuff
95
case TO_STRING:
96       // XXX: Is this correct? Test.
97
ESBase arg = eval.getArg(-1);
98
99       if (arg instanceof ESObject)
100     return toString((ESObject) arg);
101       else
102     return toString(arg.toObject());
103
104     case VALUE_OF:
105       arg = eval.getArg(-1);
106       if (arg instanceof ESWrapper) {
107     ESWrapper obj = (ESWrapper) arg;
108
109     if (obj.value instanceof ESBase)
110       return (ESBase) obj.value;
111     else
112       return obj.toStr();
113       }
114       return arg;
115
116     case TO_OBJECT:
117       if (length <= 0 ||
118       (arg = eval.getArg(0)) == ESBase.esNull ||
119       arg == ESBase.esUndefined ||
120       arg == ESBase.esEmpty)
121     return Global.getGlobalProto().createObject();
122
123       else if (length > 1)
124         return createObjectLiteral(eval, length);
125
126       else
127     return arg.toObject();
128
129     case TO_SOURCE:
130       arg = eval.getThis();
131       Global.getGlobalProto().clearMark();
132       IntMap map = new IntMap();
133
134       arg.toSource(map, true);
135       return arg.toSource(map, false);
136
137     case WATCH:
138       if (length < 2)
139     throw new ESException("watch expects two arguments");
140
141       ESBase obj = eval.getThis();
142
143       ESString key = eval.getArg(0).toStr();
144       ESBase fun = eval.getArg(1);
145       if (! (fun instanceof ESClosure) && ! (fun instanceof Native))
146     throw new ESException("watch requires function");
147
148       ((ESObject) obj).watch(key, fun);
149
150       return esUndefined;
151
152     case UNWATCH:
153       if (length < 1)
154     throw new ESException("unwatch expects one argument");
155
156       obj = eval.getThis();
157
158       key = eval.getArg(0).toStr();
159
160       ((ESObject) obj).unwatch(key);
161
162       return esUndefined;
163
164     default:
165       throw new RuntimeException JavaDoc("Unknown object function");
166     }
167   }
168
169   public ESBase construct(Call eval, int length) throws Throwable JavaDoc
170   {
171     if (n != TO_OBJECT)
172       return super.construct(eval, length);
173
174     if (length == 0 || eval.getArg(0) == esNull ||
175     eval.getArg(0) == esUndefined || eval.getArg(0) == esEmpty) {
176       return Global.getGlobalProto().createObject();
177     }
178     if (length > 1) {
179       return createObjectLiteral(eval, length);
180     }
181
182     return eval.getArg(0).toObject();
183   }
184
185   private ESBase createObjectLiteral(Call call, int length)
186     throws Throwable JavaDoc
187   {
188     ESObject obj = Global.getGlobalProto().createObject();
189
190     for (int i = 0; i + 1 < length; i += 2) {
191       ESString key = call.getArg(i, length).toStr();
192       ESBase value = call.getArg(i + 1, length);
193
194       obj.setProperty(key, value);
195     }
196
197     return obj;
198   }
199   
200   static public ESBase toString(ESObject obj) throws ESException
201   {
202     return ESString.create("[object " + obj.getClassName() + "]");
203   }
204 }
205
Popular Tags