/** * Set Environment for Interpreter * * @param i Interpreter */ private void loadEnvironment(Interpreter i) { if (m_ctx == null) return; Iterator<String> it = m_ctx.keySet().iterator(); while (it.hasNext()) { String key = it.next(); Object value = m_ctx.get(key); try { if (value instanceof Boolean) i.set(key, ((Boolean) value).booleanValue()); else if (value instanceof Integer) i.set(key, ((Integer) value).intValue()); else if (value instanceof Double) i.set(key, ((Double) value).doubleValue()); else i.set(key, value); } catch (EvalError ee) { log.log(Level.SEVERE, "", ee); } } } // setEnvironment
/** * Set Environment * * @param prop * @param WindowNo included Window variables */ public void setEnvironment(Ctx prop, int WindowNo) { if (prop == null) prop = Env.getCtx(); m_ctx = new HashMap<String, Object>(); // Convert properties to HashMap Iterator<String> it = prop.keySet().iterator(); while (it.hasNext()) { String key = it.next(); // filter if (key == null || key.length() == 0 || key.startsWith("P") // Preferences || (key.indexOf("|") != -1 && !key.startsWith(String.valueOf(WindowNo))) // other Window Settings ) continue; String value = prop.getContext(key); setEnvironment(key, value); } } // setEnvironment
private static Interpreter getInterpreter(String contextId) throws EvalError { // Get the appropriate interpreter Interpreter i = null; boolean createdInterp = false; synchronized (interpreters) { // serialize two gets of the same name i = interpreters.get(contextId); if (i == null) { i = new Interpreter(); interpreters.put(contextId, i); createdInterp = true; } } if (createdInterp) { Log.log("Created context: " + contextId + " (" + i + ")"); // Now configure stdin and stdout to capture 10k of content // Store references to the circular buffers within the interpreter itself. // This provides a nice place to store them plus theoretically allows // advanced use from within the bsh environment. // On Windows print() outputs \r\n but in XQuery that's normalized to \n // so the 10k of Java buffer may produce less than 10k of content in XQuery! OutputStream circularOutput = new CircularByteArrayOutputStream(10240); PrintStream printOutput = new PrintStream(circularOutput); i.setOut(printOutput); i.set("mljamout", circularOutput); OutputStream circularError = new CircularByteArrayOutputStream(10240); PrintStream printError = new PrintStream(circularError); i.setErr(printError); i.set("mljamerr", circularError); // Capture the built-in System.out and System.err also. // (Commented out since System appears global, can't do per interpreter.) // i.set("mljamprintout", printOutput); // i.set("mljamprinterr", printError); // i.eval("System.setOut(mljamprintout);"); // i.eval("System.setErr(mljamprinterr);"); // Need to expose hexdecode() and base64decode() built-in functions i.eval("hexdecode(String s) { return com.xqdev.jam.MLJAM.hexDecode(s); }"); i.eval("base64decode(String s) { return com.xqdev.jam.MLJAM.base64Decode(s); }"); // Let's tell the context what its id is i.set("mljamid", contextId); } // Update the last accessed time, used for cleaning i.set("mljamlast", System.currentTimeMillis()); // If it's been long enough, go snooping for stale contexts if (System.currentTimeMillis() > lastClean + CLEAN_INTERVAL) { Log.log("Initiated periodic scan for stale context objects"); lastClean = System.currentTimeMillis(); Iterator<Interpreter> itr = interpreters.values().iterator(); while (itr.hasNext()) { Interpreter interp = itr.next(); Long last = (Long) interp.get("mljamlast"); if (System.currentTimeMillis() > last + STALE_TIMEOUT) { itr.remove(); Log.log("Staled context: " + interp.get("mljamid") + " (" + interp + ")"); } else if ((System.currentTimeMillis() > last + TEMP_STALE_TIMEOUT) && ("" + interp.get("mljamid")).startsWith("temp:")) { itr.remove(); Log.log("Staled temp context: " + interp.get("mljamid") + " (" + interp + ")"); } } } return i; }