001: /*
002: * Helma License Notice
003: *
004: * The contents of this file are subject to the Helma License
005: * Version 2.0 (the "License"). You may not use this file except in
006: * compliance with the License. A copy of the License is available at
007: * http://adele.helma.org/download/helma/license.txt
008: *
009: * Copyright 1998-2003 Helma Software. All Rights Reserved.
010: *
011: * $RCSfile$
012: * $Author: root $
013: * $Revision: 8604 $
014: * $Date: 2007-09-28 15:16:38 +0200 (Fre, 28 Sep 2007) $
015: */
016:
017: package helma.scripting.rhino;
018:
019: import helma.framework.core.*;
020: import helma.framework.ResponseTrans;
021: import helma.framework.repository.Resource;
022: import org.mozilla.javascript.*;
023: import java.lang.reflect.Method;
024: import java.util.HashMap;
025: import java.util.Map;
026: import java.util.ArrayList;
027: import java.io.UnsupportedEncodingException;
028: import java.io.IOException;
029:
030: /**
031: *
032: */
033: public class JavaObject extends NativeJavaObject {
034:
035: RhinoCore core;
036: String protoName;
037: NativeJavaObject unscriptedJavaObj;
038:
039: static HashMap overload;
040:
041: static {
042: overload = new HashMap();
043: Method[] m = JavaObject.class.getMethods();
044: for (int i = 0; i < m.length; i++) {
045: if ("href".equals(m[i].getName())
046: || "renderSkin".equals(m[i].getName())
047: || "renderSkinAsString".equals(m[i].getName())
048: || "getResource".equals(m[i].getName())
049: || "getResources".equals(m[i].getName())) {
050: overload.put(m[i].getName(), m[i]);
051: }
052: }
053: }
054:
055: /**
056: * Creates a new JavaObject wrapper.
057: */
058: public JavaObject(Scriptable scope, Object obj, String protoName,
059: Scriptable prototype, RhinoCore core) {
060: this .parent = scope;
061: this .javaObject = obj;
062: this .protoName = protoName;
063: this .core = core;
064: staticType = obj.getClass();
065: unscriptedJavaObj = new NativeJavaObject(scope, obj, staticType);
066: setPrototype(prototype);
067: initMembers();
068: }
069:
070: /**
071: *
072: *
073: * @param skinobj ...
074: * @param paramobj ...
075: *
076: * @return ...
077: */
078: public boolean renderSkin(Object skinobj, Object paramobj)
079: throws UnsupportedEncodingException, IOException {
080: RhinoEngine engine = RhinoEngine.getRhinoEngine();
081: Skin skin = engine.toSkin(skinobj, protoName);
082:
083: if (skin != null) {
084: skin.render(engine.reval, javaObject,
085: (paramobj == Undefined.instance) ? null : paramobj);
086: }
087:
088: return true;
089: }
090:
091: /**
092: *
093: *
094: * @param skinobj ...
095: * @param paramobj ...
096: *
097: * @return ...
098: */
099: public String renderSkinAsString(Object skinobj, Object paramobj)
100: throws UnsupportedEncodingException, IOException {
101: RhinoEngine engine = RhinoEngine.getRhinoEngine();
102: Skin skin = engine.toSkin(skinobj, protoName);
103:
104: if (skin != null) {
105: return skin.renderAsString(engine.reval, javaObject,
106: (paramobj == Undefined.instance) ? null : paramobj);
107: }
108:
109: return "";
110: }
111:
112: /**
113: *
114: *
115: * @param action ...
116: *
117: * @return ...
118: */
119: public Object href(Object action)
120: throws UnsupportedEncodingException, IOException {
121: if (javaObject == null) {
122: return null;
123: }
124:
125: String act = null;
126:
127: if (action != null) {
128: if (action instanceof Wrapper) {
129: act = ((Wrapper) action).unwrap().toString();
130: } else if (!(action instanceof Undefined)) {
131: act = action.toString();
132: }
133: }
134:
135: String basicHref = core.app.getNodeHref(javaObject, act);
136:
137: return core.postProcessHref(javaObject, protoName, basicHref);
138: }
139:
140: /**
141: * Checks whether the given property is defined in this object.
142: */
143: public boolean has(String name, Scriptable start) {
144: return overload.containsKey(name) || super .has(name, start);
145: }
146:
147: /**
148: * Get a named property from this object.
149: */
150: public Object get(String name, Scriptable start) {
151: Object value;
152:
153: // we really are not supposed to walk down the prototype chain in get(),
154: // but we break the rule in order to be able to override java methods,
155: // which are looked up by super.get() below
156: Scriptable proto = getPrototype();
157: while (proto != null) {
158: value = proto.get(name, start);
159: // Skip FunctionObject properties, which represent native wrapped
160: // java host methods. The prototype chain is made of HopObjects, and
161: // we can't invoked these on our wrapped java object.
162: if (value != NOT_FOUND
163: && !(value instanceof FunctionObject)) {
164: return value;
165: }
166: proto = proto.getPrototype();
167: }
168:
169: value = overload.get(name);
170: if (value != null) {
171: return new FunctionObject(name, (Method) value, this );
172: }
173:
174: if ("_prototype".equals(name) || "__prototype__".equals(name)) {
175: return protoName;
176: }
177:
178: if ("__proto__".equals(name)) {
179: return getPrototype();
180: }
181:
182: if ("__javaObject__".equals(name)) {
183: return unscriptedJavaObj;
184: }
185:
186: return super .get(name, start);
187: }
188:
189: /**
190: * Returns a prototype's resource of a given name. Walks up the prototype's
191: * inheritance chain if the resource is not found
192: *
193: * @param resourceName the name of the resource, e.g. "type.properties",
194: * "messages.properties", "script.js", etc.
195: * @return the resource, if found, null otherwise
196: */
197: public Object getResource(String resourceName) {
198: RhinoEngine engine = RhinoEngine.getRhinoEngine();
199: Prototype prototype = engine.core.app
200: .getPrototypeByName(protoName);
201: while (prototype != null) {
202: Resource[] resources = prototype.getResources();
203: for (int i = resources.length - 1; i >= 0; i--) {
204: Resource resource = resources[i];
205: if (resource.exists()
206: && resource.getShortName().equals(resourceName))
207: return Context.toObject(resource, core.global);
208: }
209: prototype = prototype.getParentPrototype();
210: }
211: return null;
212: }
213:
214: /**
215: * Returns an array containing the prototype's resource with a given name.
216: *
217: * @param resourceName the name of the resource, e.g. "type.properties",
218: * "messages.properties", "script.js", etc.
219: * @return an array of resources with the given name
220: */
221: public Object getResources(String resourceName) {
222: RhinoEngine engine = RhinoEngine.getRhinoEngine();
223: Prototype prototype = engine.core.app
224: .getPrototypeByName(protoName);
225: ArrayList a = new ArrayList();
226: while (prototype != null) {
227: Resource[] resources = prototype.getResources();
228: for (int i = resources.length - 1; i >= 0; i--) {
229: Resource resource = resources[i];
230: if (resource.exists()
231: && resource.getShortName().equals(resourceName))
232: a.add(Context.toObject(resource, core.global));
233: }
234: prototype = prototype.getParentPrototype();
235: }
236: return Context.getCurrentContext().newArray(core.global,
237: a.toArray());
238: }
239:
240: }
|