/******************************************************************************* * Copyright (c) 2007, 2008 Gregory Jordan * * This file is part of PhyloWidget. * * PhyloWidget is free software: you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation, either version 2 of the License, or (at your option) any later * version. * * PhyloWidget is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License along with * PhyloWidget. If not, see <http://www.gnu.org/licenses/>. */ package org.andrewberman.ui.unsorted; import java.applet.Applet; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.net.MalformedURLException; import java.net.URL; public class JSCaller { private Applet app; public boolean reflectionWorking = true; Method getWindow = null; Method eval = null; Method call = null; Method setMember = null; Method getMember = null; Object jsObject = null; public JSCaller(Applet app) { this.app = app; try { initialize(); } catch (Exception e) { return; } } private void initialize() { /* * If we've already got the jsObject, then we're already initialized. */ if (!reflectionWorking) { // throw new RuntimeException("Reflection not working!"); } if (jsObject != null) return; try { ClassLoader cl = app.getClass().getClassLoader(); Class c = cl.loadClass("netscape.javascript.JSObject"); Method methods[] = c.getMethods(); for (Method m : methods) { if (m.getName().compareTo("getWindow") == 0) getWindow = m; else if (m.getName().compareTo("eval") == 0) eval = m; else if (m.getName().compareTo("call") == 0) call = m; else if (m.getName().compareTo("setMember") == 0) setMember = m; else if (m.getName().compareTo("getMember") == 0) getMember = m; } jsObject = getWindow.invoke(c, app); reflectionWorking = true; } catch (Exception e) { reflectionWorking = false; throw new RuntimeException("JS reflection failed -- maybe we're not inside a browser?"); } } public synchronized void injectJavaScript(String file) { initialize(); try { InputStream in = openStreamRaw(file); BufferedReader read = new BufferedReader(new InputStreamReader(in)); StringBuffer buff = new StringBuffer(); String s; while ((s = read.readLine()) != null) { buff.append(s.trim()); } eval(buff.toString()); } catch (Exception e) { e.printStackTrace(); } } public synchronized Object eval(String expression) throws Exception { initialize(); // app.getAppletContext().showDocument(new URL("javascript:"+expression)); Object result = eval.invoke(jsObject, expression); return null; } public synchronized Object call(String methodName, Object... args) throws Exception { return callWithObject(jsObject, methodName, args); } public synchronized Object call(String methodName) throws Exception { return callWithObject(jsObject,methodName); } public synchronized Object callWithObject(Object object,String methodName, Object... args) throws Exception { initialize(); Object result = call.invoke(object, methodName,args); return result; } public synchronized void setMember(String memberName, Object value) throws Exception { initialize(); setMember.invoke(jsObject,memberName, value); } public synchronized Object getMember(String memberName) throws Exception { initialize(); Object result = getMember.invoke(jsObject,memberName); return result; } public synchronized Object getWindow() { initialize(); return jsObject; } private InputStream openStreamRaw(String filename) { InputStream stream = null; if (filename == null) return null; if (filename.length() == 0) { // an error will be called by the parent function //System.err.println("The filename passed to openStream() was empty."); return null; } // safe to check for this as a url first. this will prevent online // access logs from being spammed with GET /sketchfolder/http://blahblah try { URL url = new URL(filename); stream = url.openStream(); return stream; } catch (MalformedURLException mfue) { // not a url, that's fine } catch (FileNotFoundException fnfe) { // Java 1.5 likes to throw this when URL not available. (fix for 0119) // http://dev.processing.org/bugs/show_bug.cgi?id=403 } catch (IOException e) { // changed for 0117, shouldn't be throwing exception e.printStackTrace(); //System.err.println("Error downloading from URL " + filename); return null; //throw new RuntimeException("Error downloading from URL " + filename); } // using getClassLoader() prevents java from converting dots // to slashes or requiring a slash at the beginning. // (a slash as a prefix means that it'll load from the root of // the jar, rather than trying to dig into the package location) ClassLoader cl = getClass().getClassLoader(); // by default, data files are exported to the root path of the jar. // (not the data folder) so check there first. stream = cl.getResourceAsStream("data/" + filename); if (stream != null) { String cn = stream.getClass().getName(); // this is an irritation of sun's java plug-in, which will return // a non-null stream for an object that doesn't exist. like all good // things, this is probably introduced in java 1.5. awesome! // http://dev.processing.org/bugs/show_bug.cgi?id=359 if (!cn.equals("sun.plugin.cache.EmptyInputStream")) { return stream; } } // when used with an online script, also need to check without the // data folder, in case it's not in a subfolder called 'data' // http://dev.processing.org/bugs/show_bug.cgi?id=389 stream = cl.getResourceAsStream(filename); if (stream != null) { String cn = stream.getClass().getName(); if (!cn.equals("sun.plugin.cache.EmptyInputStream")) { return stream; } } return stream; } }