001: /*
002: * Copyright 2007 Google Inc.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License"); you may not
005: * use this file except in compliance with the License. You may obtain a copy of
006: * the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
012: * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
013: * License for the specific language governing permissions and limitations under
014: * the License.
015: */
016: package com.google.gwt.dev.shell.mac;
017:
018: import com.google.gwt.dev.shell.CompilingClassLoader;
019: import com.google.gwt.dev.shell.JavaDispatch;
020: import com.google.gwt.dev.shell.JavaDispatchImpl;
021: import com.google.gwt.dev.shell.JsValue;
022: import com.google.gwt.dev.shell.JsValueGlue;
023: import com.google.gwt.dev.shell.mac.LowLevelSaf.DispatchMethod;
024: import com.google.gwt.dev.shell.mac.LowLevelSaf.DispatchObject;
025:
026: import java.lang.reflect.Field;
027: import java.lang.reflect.Method;
028:
029: /**
030: * Wraps an arbitrary Java Object as a Dispatch component. The class was
031: * motivated by the need to expose Java objects into JavaScript.
032: *
033: * An instance of this class with no target is used to globally access all
034: * static methods or fields.
035: */
036: class WebKitDispatchAdapter implements DispatchObject {
037:
038: private final CompilingClassLoader classLoader;
039:
040: private final JavaDispatch javaDispatch;
041:
042: /**
043: * This constructor initializes as the static dispatcher, which handles only
044: * static method calls and field references.
045: *
046: * @param cl this class's classLoader
047: */
048: WebKitDispatchAdapter(CompilingClassLoader cl) {
049: javaDispatch = new JavaDispatchImpl(cl);
050: this .classLoader = cl;
051: }
052:
053: /**
054: * This constructor initializes a dispatcher, around a particular instance.
055: *
056: * @param cl this class's classLoader
057: * @param target the object being wrapped as an IDispatch
058: */
059: WebKitDispatchAdapter(CompilingClassLoader cl, Object target) {
060: javaDispatch = new JavaDispatchImpl(cl, target);
061: this .classLoader = cl;
062: }
063:
064: /* (non-Javadoc)
065: * @see com.google.gwt.dev.shell.mac.LowLevelSaf.DispatchObject#getField(java.lang.String)
066: */
067: public int getField(String name) {
068: int dispId = classLoader.getDispId(name);
069: if (dispId < 0) {
070: return LowLevelSaf.jsUndefined();
071: }
072: if (javaDispatch.isField(dispId)) {
073: Field field = javaDispatch.getField(dispId);
074: JsValueSaf jsValue = new JsValueSaf();
075: JsValueGlue.set(jsValue, classLoader, field.getType(),
076: javaDispatch.getFieldValue(dispId));
077: int jsval = jsValue.getJsValue();
078: return jsval;
079: } else {
080: Method method = javaDispatch.getMethod(dispId);
081: DispatchMethod dispMethod = (DispatchMethod) classLoader
082: .getMethodDispatch(method);
083: if (dispMethod == null) {
084: dispMethod = new MethodDispatch(classLoader, method);
085: classLoader.putMethodDispatch(method, dispMethod);
086: }
087: return LowLevelSaf.wrapFunction(method.toString(),
088: dispMethod);
089: }
090: }
091:
092: /* (non-Javadoc)
093: * @see com.google.gwt.dev.shell.mac.LowLevelSaf.DispatchObject#getTarget()
094: */
095: public Object getTarget() {
096: return javaDispatch.getTarget();
097: }
098:
099: /* (non-Javadoc)
100: * @see com.google.gwt.dev.shell.mac.LowLevelSaf.DispatchObject#setField(java.lang.String, int)
101: */
102: public void setField(String name, int value) {
103: JsValue jsValue = new JsValueSaf(value);
104: int dispId = classLoader.getDispId(name);
105: if (dispId < 0) {
106: // TODO: expandos?
107: throw new RuntimeException("No such field " + name);
108: }
109: if (javaDispatch.isMethod(dispId)) {
110: throw new RuntimeException("Cannot reassign method " + name);
111: }
112: Field field = javaDispatch.getField(dispId);
113: Object val = JsValueGlue.get(jsValue, field.getType(),
114: "setField");
115: javaDispatch.setFieldValue(dispId, val);
116: }
117:
118: @Override
119: public String toString() {
120: return getTarget().toString();
121: }
122:
123: }
|