/* * This file is part or JMathLib * * Check it out at http://www.jmathlib.de * * Author: * (c) 2005-2009 */ package jmathlib.core.functions; import jmathlib.core.tokens.FunctionToken; import jmathlib.core.tokens.VariableToken; import jmathlib.core.tokens.Token; import jmathlib.core.tokens.Expression; import jmathlib.core.interpreter.*; import java.applet.*; import java.util.*; import java.io.*; import java.net.*; /**Class for storing and managing the functions being used*/ public class FunctionManager { class SystemFileFunctionLoader extends FileFunctionLoader { SystemFileFunctionLoader(File _functionDir, boolean _traverseChildren) { super(_functionDir, _traverseChildren, true); } } // indicates if FunctionManager is running in an application or an applet private boolean runningStandalone; // different function loaders private Vector functionLoaders = new Vector(); // flag for caching of p files boolean pFileCachingEnabledB = false; /**Creates the function manager and defines any internal functions if this is an application then it creates a class loader to load external functions @param runningStandalone = true if the program is running as an application*/ public FunctionManager(boolean _runningStandalone) { //, Applet _applet) { runningStandalone = _runningStandalone; if (runningStandalone) { //Add the predefined (system) function loader for the current directory. functionLoaders.add(new SystemFileFunctionLoader(new File("."),false)); //"." + File.separator), false)); //webLoader = null; String classPath = System.getProperty("java.class.path"); //Find and then setup the base JMathlib (pre-defined) functions boolean end = false; while (!end) { int pos = classPath.indexOf(File.pathSeparator); String path = classPath; if (pos > -1) { path = classPath.substring(0, pos); classPath = classPath.substring(pos + 1); } else { classPath = ""; end = true; } File basePath = new File(path, "jmathlib/toolbox"); if (basePath.exists()) { //Add the predefined (system) function loader for the predefined Mathlib function directory. functionLoaders.add(new SystemFileFunctionLoader(new File(path), true)); break; //exit loop (found pre-defined function location) } } } else { System.out.println("web:"); //+applet); //functionLoaders.add(new WebFunctionLoader(applet.getCodeBase(), "")); //functionLoaders.add(new WebFunctionLoader(null, "")); functionLoaders.add(new WebFunctionLoader()); } } /** * For each of the FunctionLoaders, check that any cached functions are up to date. If * some are out of date, or have been deleted, ensure that the cache it updated. */ public void checkAndRehashTimeStamps() { for (int i = 0; i < this.functionLoaders.size(); i++) { FunctionLoader l = (FunctionLoader) functionLoaders.elementAt(i); l.checkAndRehashTimeStamps(); } } /**find a function It checks user functions then external functions then internal functions @param token - The function token containing the name of the function @return the Function found*/ public Function findFunction(FunctionToken token) throws java.lang.Exception { Function func = null; String funcName = token.getName(); int index = -1; //then check the external functions try { if (runningStandalone) { // JMathlib is running as a standalone application //Search for class, m or p file for (int i = 0; i < functionLoaders.size(); i++) { FunctionLoader l = (FunctionLoader) functionLoaders.elementAt(i); func = l.findFunction(funcName); if (func != null) { return func; } } // functions not found (no class or m- or p-file) // if (token.getOperand(0) != null) { ErrorLogger.debugLine("************checking first param****************"); //get first parameter //Token first = ((Expression)token.getOperand(0)).getLeft(); Token first = token.getOperand(0); ErrorLogger.debugLine("class = " + first.getClass()); //if parameter is variable token if ((first instanceof VariableToken) || (first instanceof Expression)) { ErrorLogger.debugLine("************searching for java class***********"); String className = ""; if (first instanceof VariableToken) { className = ((VariableToken) first).getName(); } else if (first instanceof FunctionToken) { className = ((FunctionToken) first).getName(); } else { className = first.toString(); className = className.substring(0, className.length() - 2); } ErrorLogger.debugLine("classname = " + className); for (int i = 0; i < functionLoaders.size(); i++) { FileFunctionLoader l = (FileFunctionLoader) functionLoaders.elementAt(i); Class extFunctionClass = l.findOnlyFunctionClass(className); if (extFunctionClass != null) { ErrorLogger.debugLine("found class " + className); ReflectionFunctionCall reflect = new ReflectionFunctionCall(extFunctionClass, token.toString()); ErrorLogger.debugLine("+++++func1 " + reflect.toString()); return reflect; } } } } } else { // NOT standalone, but APPLET // use webloader //Search for class, m or p file for (int i = 0; i < functionLoaders.size(); i++) { FunctionLoader l = (WebFunctionLoader) functionLoaders.elementAt(i); func = l.findFunction(funcName); if (func != null) { return func; } } return null; } // end webLoader } catch (Exception exception) { exception.printStackTrace(); } return func; } public Function findFunctionByName(String funcName) throws java.lang.Exception { FunctionToken token = new FunctionToken(funcName); return findFunction(token); } public void clear() { ErrorLogger.debugLine("FunctionManager: clear user functions"); for (int i = 0; i < functionLoaders.size(); i++) { FunctionLoader l = (FunctionLoader) functionLoaders.elementAt(i); l.clearCache(); } } /** set caching of p-file to on of off * * @param pFileCaching true= caching of p-files on; false: caching of p-files off */ public void setPFileCaching(boolean pFileCaching) { pFileCachingEnabledB = pFileCaching; for (int i = 0; i < this.functionLoaders.size(); i++) { FunctionLoader l = (FunctionLoader) functionLoaders.elementAt(i); l.setPFileCaching(pFileCaching); } } /** * return whether of not caching of p-files is enabled of not * @return status of caching p-files */ public boolean getPFileCaching() { return pFileCachingEnabledB; } /** * * @return */ public int getFunctionLoaderCount() { return functionLoaders.size(); } /** * * @param index * @return */ public FunctionLoader getFunctionLoader(int index) { return (FunctionLoader) functionLoaders.elementAt(index); } /** * * @param loader * @return */ public boolean removeFunctionLoader(FunctionLoader loader) { if (loader.isSystemLoader()) throw new IllegalArgumentException("Cannot remove a System Function Loader"); return functionLoaders.remove(loader); } /** * * @param loader * @return */ public boolean addFunctionLoader(FunctionLoader loader) { return functionLoaders.add(loader); } /** * * @param index * @param loader */ public void addFunctionLoaderAt(int index, FunctionLoader loader) { functionLoaders.add(index, loader); } /** * */ public void clearCustomFunctionLoaders() { Iterator itr = functionLoaders.iterator(); while (itr.hasNext()) { FunctionLoader fl = (FunctionLoader)itr.next(); if (!fl.isSystemLoader()) itr.remove(); } } /** * * @param path */ public void setWorkingDirectory(File path) { if (runningStandalone) { FileFunctionLoader l = (FileFunctionLoader) functionLoaders.get(0); l.setBaseDirectory(path); } } /** * * @return */ public File getWorkingDirectory() { if (runningStandalone) { FileFunctionLoader l = (FileFunctionLoader) functionLoaders.get(0); return l.getBaseDirectory(); } return null; } }