001: /*
002: * Copyright (c) 1998-2006 Caucho Technology -- all rights reserved
003: *
004: * This file is part of Resin(R) Open Source
005: *
006: * Each copy or derived work must preserve the copyright notice and this
007: * notice unmodified.
008: *
009: * Resin Open Source is free software; you can redistribute it and/or modify
010: * it under the terms of the GNU General Public License as published by
011: * the Free Software Foundation; either version 2 of the License, or
012: * (at your option) any later version.
013: *
014: * Resin Open Source is distributed in the hope that it will be useful,
015: * but WITHOUT ANY WARRANTY; without even the implied warranty of
016: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
017: * of NON-INFRINGEMENT. See the GNU General Public License for more
018: * details.
019: *
020: * You should have received a copy of the GNU General Public License
021: * along with Resin Open Source; if not, write to the
022: * Free SoftwareFoundation, Inc.
023: * 59 Temple Place, Suite 330
024: * Boston, MA 02111-1307 USA
025: *
026: * @author Scott Ferguson
027: */
028:
029: package com.caucho.es;
030:
031: import com.caucho.util.IntMap;
032:
033: import java.util.HashMap;
034:
035: /**
036: * Implementation class serving as the base for wrapped Java objects.
037: */
038: public class ESBeanWrapper extends ESBase {
039: static ESId CALL = ESId.intern("call");
040: protected static ESId LENGTH = ESId.intern("length");
041:
042: public int set;
043: public IntMap hasDispatch;
044: public IntMap setDispatch;
045: public IntMap[] subGets;
046: public IntMap[] subSets;
047: public HashMap methods;
048: public IntMap methodDispatch;
049:
050: protected Object value;
051: protected String name;
052: ESString[] formals;
053: int length;
054: public int n = -3;
055: int newN;
056:
057: protected ESBeanWrapper() {
058: }
059:
060: public long getVersionId() {
061: return 0;
062: }
063:
064: private String decompile() {
065: StringBuffer sbuf = new StringBuffer();
066:
067: sbuf.append("function ");
068: sbuf.append(name);
069: sbuf.append("(");
070: for (int i = 0; formals != null && i < formals.length; i++) {
071: if (i != 0)
072: sbuf.append(", ");
073: sbuf.append(formals[i]);
074: }
075:
076: sbuf.append(") ");
077:
078: sbuf.append("{ ");
079: sbuf.append("[native code]");
080: sbuf.append(" }");
081:
082: return sbuf.toString();
083: }
084:
085: public ESString toStr() throws ESException {
086: if (n == -1)
087: return ESString.create(value == null ? "null" : value
088: .toString());
089: else
090: return ESString.create(decompile());
091: }
092:
093: public double toNum() throws ESException {
094: if (value instanceof Number)
095: return ((Number) value).doubleValue();
096: else
097: throw new ESException("no number: " + getClass().getName());
098: }
099:
100: public ESBase getProperty(ESString name) throws Throwable {
101: ESBase value = hasProperty(name);
102:
103: if (value != null)
104: return value;
105: else
106: return esEmpty;
107: }
108:
109: public ESBase hasProperty(ESString name) throws Throwable {
110: return null;
111: }
112:
113: public ESString toSource(IntMap map, boolean isLoopPath)
114: throws ESException {
115: if (isLoopPath)
116: return null;
117: else
118: return toStr();
119: }
120:
121: public ESBase toPrimitive(int hint) throws ESException {
122: if (value instanceof ESBase)
123: return (ESBase) value;
124: else
125: return toStr();
126: }
127:
128: public Object toJavaObject() {
129: return value != null ? value : this ;
130: }
131:
132: public boolean toBoolean() {
133: return true;
134: }
135:
136: protected ESBeanWrapper dup() {
137: throw new UnsupportedOperationException();
138: }
139:
140: protected ESBeanWrapper dup(int set) {
141: ESBeanWrapper child = dup();
142:
143: child.value = value;
144: child.set = set;
145: child.hasDispatch = subGets[set];
146: child.setDispatch = subSets[set];
147: child.subGets = subGets;
148: child.subSets = subSets;
149: child.methods = methods;
150:
151: return child;
152: }
153:
154: public ESBeanWrapper wrap(Object value) {
155: throw new RuntimeException();
156: }
157:
158: public ESBeanWrapper wrapStatic() {
159: throw new RuntimeException();
160: }
161:
162: public boolean ecmaEquals(ESBase b) {
163: if (!(b instanceof ESBeanWrapper))
164: return false;
165: else
166: return value.equals(((ESBeanWrapper) b).value);
167: }
168:
169: public Object copy(HashMap refs) {
170: return this ;
171: }
172:
173: public ESBase typeof() {
174: return ESString.create("object");
175: }
176:
177: public ESBase call(Call eval, int length, int n) throws Throwable {
178: throw new ESNullException(toStr() + " is not a function");
179: }
180:
181: public ESBase call(Call eval, int length) throws Throwable {
182: return call(eval, length, n);
183: }
184:
185: public ESBase call(Call eval, int length, ESString key)
186: throws Throwable {
187: int n = methodDispatch.get(key);
188: if (n < 0)
189: throw new ESUndefinedException(getClass().getName()
190: + ": undefined call `" + key + "'");
191:
192: return call(eval, length, n);
193: }
194:
195: public ESBase construct(Call eval, int length) throws Throwable {
196: if (n != newN) {
197: throw new ESException("cannot create " + name);
198: }
199:
200: ESBase value = call(eval, length);
201:
202: if (value == esUndefined || value == null)
203: throw new ESException("cannot create " + name);
204:
205: return value;
206: }
207:
208: public boolean isModified() {
209: return true;
210: }
211: }
|