001: package fr.aliacom.util;
002:
003: import java.io.ByteArrayOutputStream;
004: import java.io.File;
005: import java.io.FileInputStream;
006: import java.io.IOException;
007: import java.io.InputStream;
008: import java.util.Collections;
009: import java.util.LinkedList;
010: import java.util.List;
011: import java.util.jar.JarInputStream;
012: import java.util.zip.ZipEntry;
013: import java.util.zip.ZipFile;
014:
015: import org.python.core.PyObject;
016: import org.python.core.__builtin__;
017:
018: /**
019: * @author tom
020: *
021: * (C) 2001, 2002 Thomas Cataldo
022: */
023: public final class InterpreterPool {
024:
025: private static final InterpreterPool singleton;
026:
027: static {
028: singleton = new InterpreterPool();
029: }
030:
031: public static InterpreterPool getInstance() {
032: return singleton;
033: }
034:
035: private LRUCache codeMap;
036: private List freeList;
037:
038: private InterpreterPool() {
039: codeMap = new LRUCache(10); // caches the last 10 scripts
040: freeList = Collections.synchronizedList(new LinkedList());
041: for (int i = 0; i < 5; i++) {
042: freeList.add(new JythonInterpreter(this ));
043: }
044: }
045:
046: private void addCode(String name, String code) {
047: PyObject pyObject = __builtin__.compile(code, "<template>",
048: "exec");
049: codeMap.put(name, pyObject);
050: }
051:
052: LRUCache getCodeMap() {
053: return codeMap;
054: }
055:
056: /**
057: * Finds all the .py files in a JAR, and caches a compiled version
058: * memory for faster execution.
059: *
060: * @param file a jar file
061: * @throws IOException
062: */
063: public void parseJAR(File file) throws IOException {
064: JarInputStream jis = new JarInputStream(new FileInputStream(
065: file));
066: ZipFile zf = new ZipFile(file);
067: ZipEntry ze = null;
068: while ((ze = jis.getNextEntry()) != null) {
069: if (ze.getName().endsWith(".py")) {
070: InputStream in = zf.getInputStream(ze);
071: ByteArrayOutputStream out = new ByteArrayOutputStream();
072:
073: final byte[] buf = new byte[4096];
074: int readCount;
075: while ((readCount = in.read(buf, 0, buf.length)) > 0) {
076: out.write(buf, 0, readCount);
077:
078: }
079: out.flush();
080: out.close();
081: in.close();
082: addCode(ze.getName(), out.toString());
083: }
084: }
085: }
086:
087: /**
088: * Get one of the cached jython interpreter.
089: * This method blocks until an interpreter is available.
090: *
091: * All the classes defined in a script will be destroyed
092: * when the interpreter is released.
093: *
094: * @return a jython interpreter
095: * @throws InterruptedException
096: */
097: public synchronized JythonInterpreter getInterpreter()
098: throws InterruptedException {
099: if (Thread.interrupted()) {
100: throw new InterruptedException();
101: }
102: while (freeList.isEmpty()) {
103: wait();
104: }
105: return (JythonInterpreter) freeList.remove(0);
106: }
107:
108: synchronized void release(JythonInterpreter interp) {
109: freeList.add(interp);
110: notifyAll();
111: }
112:
113: }
|