001: /*
002: * $RCSfile: Script.java,v $
003: *
004: * @(#)Script.java 1.26 99/03/24 15:34:13
005: *
006: * Copyright (c) 1996-1998 Sun Microsystems, Inc. All Rights Reserved.
007: *
008: * Sun grants you ("Licensee") a non-exclusive, royalty free, license to use,
009: * modify and redistribute this software in source and binary code form,
010: * provided that i) this copyright notice and license appear on all copies of
011: * the software; and ii) Licensee does not utilize the software in a manner
012: * which is disparaging to Sun.
013: *
014: * This software is provided "AS IS," without a warranty of any kind. ALL
015: * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
016: * IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
017: * NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE
018: * LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
019: * OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS
020: * LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
021: * INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
022: * CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
023: * OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
024: * POSSIBILITY OF SUCH DAMAGES.
025: *
026: * This software is not designed or intended for use in on-line control of
027: * aircraft, air traffic, aircraft navigation or aircraft communications; or in
028: * the design, construction, operation or maintenance of any nuclear
029: * facility. Licensee represents and warrants that it will not use or
030: * redistribute the Software for such purposes.
031: *
032: * $Revision: 1.3 $
033: * $Date: 2006/03/30 08:19:28 $
034: * $State: Exp $
035: */
036: /*
037: * @Author: Rick Goldberg
038: * @Author: Doug Gehringer
039: * @author Nikolai V. Chr.
040: *
041: */
042: package org.jdesktop.j3d.loaders.vrml97.impl;
043:
044: import java.io.File;
045: import java.net.MalformedURLException;
046: import java.net.URL;
047: import java.net.URLClassLoader;
048:
049: import java.util.Hashtable;
050: import java.util.StringTokenizer;
051:
052: /** Description of the Class */
053: public class Script extends BaseNode implements Notifier {
054: /** Description of the Field */
055: public Hashtable FieldSpec = new Hashtable(24);
056: vrml.node.Script specScript;
057: org.jdesktop.j3d.loaders.vrml97.impl.Event ievent;
058: vrml.Event event;
059: URLClassLoader scl;
060: String scriptName = "";
061:
062: // Exposed Field
063: MFString url;// currently unused
064:
065: // field
066: SFBool directOutput;
067: SFBool mustEvaluate;
068:
069: // the byteCodes are resolved by the Parser's class loader to
070: // an instance of vrml.node.Script
071:
072: String annexC = "Annex C1 of ISO/IEC 14772 clearly states \"Note that support for the ECMAScript is not required by ISO/IEC 14772\". and \"Browsers are not required to support any specific scripting language. However, browsers shall adhere to the protocol defined in the corresponding annex of ISO/IEC 14772 for any scripting language which is supported. \" and in our case, that is Annex B1 not Annex C1. Please use Java byte code Script nodes, thank you.";
073:
074: /**
075: *Constructor for the Script object
076: *
077: *@param loader Description of the Parameter
078: */
079: public Script(Loader loader) {
080: super (loader);
081: ievent = new org.jdesktop.j3d.loaders.vrml97.impl.Event(
082: "default", 0.0, (ConstField) null);
083: event = new vrml.Event(ievent);
084:
085: url = new MFString();
086: directOutput = new SFBool(false);
087: mustEvaluate = new SFBool(false);
088: initFields();
089: }
090:
091: /**
092: * Sets the byteCodes attribute of the Script object
093: *
094: *@param byteCodes The new byteCodes value
095: */
096: void setByteCodes(vrml.node.Script byteCodes) {
097: specScript = byteCodes;
098: }
099:
100: /**
101: * Gets the eventIn attribute of the Script object
102: *
103: *@param eventInName Description of the Parameter
104: *@return The eventIn value
105: *@exception vrml.InvalidEventInException Description of the Exception
106: */
107: public final Field getEventIn(String eventInName)
108: throws vrml.InvalidEventInException {
109:
110: Field f = (Field) FieldSpec.get(eventInName);
111: if ((f == null) || !f.isEventIn()) {
112: throw new vrml.InvalidEventInException();
113: }
114: return f;
115: }
116:
117: /**
118: * Gets the eventOut attribute of the Script object
119: *
120: *@param eventOutName Description of the Parameter
121: *@return The eventOut value
122: *@exception vrml.InvalidEventOutException Description of the Exception
123: */
124: public Field getEventOut(String eventOutName)
125: throws vrml.InvalidEventOutException {
126:
127: Field f = (Field) FieldSpec.get(eventOutName);
128: if ((f == null) || !f.isEventOut()) {
129: throw new vrml.InvalidEventOutException(eventOutName);
130: }
131: return f;
132: }
133:
134: /**
135: * Gets the field attribute of the Script object
136: *
137: *@param fieldName Description of the Parameter
138: *@return The field value
139: */
140: public final Field getField(String fieldName) {
141: fieldName = Field.baseName(fieldName);
142: Field f = (Field) FieldSpec.get(fieldName);
143: if (f == null) {
144: throw new vrml.InvalidFieldException();
145: }
146: return f;
147: }
148:
149: /** Description of the Method */
150: void initImpl() {
151: URL u;
152: String urlName;
153: StringTokenizer tok;
154: int countToks;
155: scriptName = url.strings[0];
156: // strip off ".class"
157: if (scriptName.endsWith(".class")) {
158: scriptName = scriptName.substring(0,
159: scriptName.length() - 6);
160: }
161:
162: if (loader.debug) {
163: System.out.println("Script.initImpl() called in " + this );
164: }
165: if (loader.loaderMode == Loader.LOAD_STATIC) {
166: return;
167: }
168: if (scriptName.startsWith("vrmlscript:")
169: || scriptName.startsWith("javascript:")
170: || scriptName.startsWith("ecma:")
171: || scriptName.startsWith("ECMA:")
172: || scriptName.startsWith("excema")) {
173: throw new vrml.InvalidVRMLSyntaxException(annexC);
174: } else {
175: scl = loader.scl;
176: try {
177: setByteCodes((vrml.node.Script) scl.loadClass(
178: scriptName).newInstance());
179: } catch (java.lang.ClassNotFoundException cnfe) {
180: vrml.InvalidVRMLSyntaxException i = new vrml.InvalidVRMLSyntaxException(
181: "Unable to load class " + scriptName);
182: i.initCause(cnfe);
183: throw i;
184: } catch (java.lang.InstantiationException ie) {
185: vrml.InvalidVRMLSyntaxException i = new vrml.InvalidVRMLSyntaxException(
186: "Unable to intance script node from data");
187: i.initCause(ie);
188: throw i;
189: } catch (java.lang.IllegalAccessException iae) {
190: vrml.InvalidVRMLSyntaxException i = new vrml.InvalidVRMLSyntaxException(
191: "Illegal access to script node data");
192: i.initCause(iae);
193: throw i;
194: }
195:
196: // these used to be in initialize()
197: specScript.registerOwner(this );
198: specScript.initialize();
199: }
200: implReady = true;
201: }
202:
203: /**
204: * Description of the Method
205: *
206: *@param eventInName Description of the Parameter
207: *@param time Description of the Parameter
208: */
209: public void notifyMethod(String eventInName, double time) {
210: if (loader.debug) {
211: System.out.println("Script.notifyMethod(" + eventInName
212: + ")");
213: }
214: if (eventInName.equals("url")) {
215: ;
216: } else if (eventInName.startsWith("route_")) {
217: // Noop
218: } else {
219: if (loader.debug) {
220: System.out.println("Passing event to script");
221: }
222: ievent.name = eventInName;
223: // the user sees an event with a const field in value
224: ievent.value = (getField(eventInName)).constify();
225: ievent.timeStamp = time;
226: specScript.processEvent(event);
227: specScript.eventsProcessed();
228: }
229: }
230:
231: // there is a processEvents(int count, Event[] events)
232: // method but we don't think at this time that scripts
233: // will use it.
234:
235: /**
236: * Gets the type attribute of the Script object
237: *
238: *@return The type value
239: */
240: public String getType() {
241: return "Script";
242: }
243:
244: /**
245: * Description of the Method
246: *
247: *@return Description of the Return Value
248: */
249: public Object clone() {
250: Script s;
251: String name;
252: s = new Script(loader);
253: java.util.Enumeration keys = FieldSpec.keys();
254: java.util.Enumeration elements = FieldSpec.elements();
255:
256: while (keys.hasMoreElements()) {
257: String fname = (String) keys.nextElement();
258: Field f = (Field) elements.nextElement();
259: Field c = (Field) f.clone();
260: if (f.isEventIn()) {
261: s.setEventIn(fname, c);
262: } else if (f.isEventOut()) {
263: s.setEventOut(fname, c);
264: } else {
265: s.setField(fname, c);
266: }
267: }
268:
269: // bug: setEventIn does not throw the isEventIn bit
270: s.url = (MFString) s.FieldSpec.get("url");
271: s.mustEvaluate = (SFBool) s.FieldSpec.get("mustEvaluate");
272: s.directOutput = (SFBool) s.FieldSpec.get("direcOutput");
273:
274: s.initImpl();
275:
276: //name = (String)((Object)specScript.toString());
277: //name = url.get1Value(0);
278: try {
279: //s.setByteCodes(loader.newInstance(
280: //name.substring(0,name.indexOf('@'))));
281: s.setByteCodes((vrml.node.Script) scl.loadClass(scriptName)
282: .newInstance());
283: //} catch (IllegalAccessException iae) {
284: //iae.printStackTrace();
285: //} catch (InstantiationException ie) {
286: //ie.printStackTrace();
287: //} catch (ClassNotFoundException cnfe) {
288: //cnfe.printStackTrace();
289: } catch (Exception e) {
290: System.out.println("Oops in " + this );
291: e.printStackTrace();
292: }
293: return (Object) s;
294: }
295:
296: /**
297: * Sets the eventIn attribute of the Script object
298: *
299: *@param eventInName The new eventIn value
300: *@param f The new eventIn value
301: */
302: public void setEventIn(String eventInName, Field f) {
303: if (loader.debug) {
304: System.out.println("Adding eventIn " + f.toStringId()
305: + "\n with name " + eventInName
306: + "\n to script node " + this .toStringId());
307: }
308: f
309: .init(this , FieldSpec, Field.EVENT_IN, f
310: .baseName(eventInName));
311: }
312:
313: /**
314: * Sets the eventOut attribute of the Script object
315: *
316: *@param eventOutName The new eventOut value
317: *@param f The new eventOut value
318: */
319: public void setEventOut(String eventOutName, Field f) {
320: if (loader.debug) {
321: System.out.println("Adding eventOut " + f.toStringId()
322: + "\n with name " + eventOutName
323: + "\n to script node " + this .toStringId());
324: }
325: f.init(this , FieldSpec, Field.EVENT_OUT, f
326: .baseName(eventOutName));
327: }
328:
329: /**
330: * Sets the field attribute of the Script object
331: *
332: *@param fieldName The new field value
333: *@param f The new field value
334: */
335: public void setField(String fieldName, Field f) {
336: if (loader.debug) {
337: System.out.println("Adding field " + f.toStringId()
338: + "\n with name " + fieldName
339: + "\n to script node " + this .toStringId());
340: }
341: f.init(this , FieldSpec, Field.FIELD, f.baseName(fieldName));
342: }
343:
344: /**
345: * Gets the browser attribute of the Script object
346: *
347: *@return The browser value
348: */
349: public org.jdesktop.j3d.loaders.vrml97.impl.Browser getBrowser() {
350: return browser;
351: }
352:
353: /** Description of the Method */
354: void initFields() {
355: url.init(this , FieldSpec, Field.EXPOSED_FIELD, "url");
356: directOutput.init(this , FieldSpec, Field.FIELD, "directOutput");
357: mustEvaluate.init(this , FieldSpec, Field.FIELD, "mustEvaluate");
358: }
359:
360: /**
361: * Description of the Method
362: *
363: *@return Description of the Return Value
364: */
365: public vrml.BaseNode wrap() {
366: return new vrml.node.Script(this);
367: }
368:
369: }
|