package org.apache.cocoon.components.flow.scheme;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.zip.GZIPInputStream;
import org.apache.avalon.framework.configuration.Configurable;
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.configuration.ConfigurationException;
import org.apache.avalon.framework.context.Context;
import org.apache.avalon.framework.context.ContextException;
import org.apache.avalon.framework.context.Contextualizable;
import org.apache.cocoon.Constants;
import org.apache.cocoon.components.flow.AbstractInterpreter;
import org.apache.cocoon.components.flow.Interpreter;
import org.apache.cocoon.components.treeprocessor.InvokeContext;
import org.apache.cocoon.environment.Environment;
import org.apache.cocoon.environment.Source;
import sisc.AppContext;
import sisc.DynamicEnv;
import sisc.data.ImmutableString;
import sisc.data.Procedure;
import sisc.data.Symbol;
import sisc.data.Value;
public class SchemeInterpreter extends AbstractInterpreter
implements Configurable, Contextualizable
{
protected Context cocoonContext;
protected ArrayList interPool;
protected AppContext siscContext;
public void contextualize(Context context)
throws ContextException
{
this.cocoonContext = context;
}
public void configure(Configuration confs)
throws ConfigurationException
{
String heapFileName = confs.getAttribute("heap", null);
if (heapFileName == null)
throw new ConfigurationException("Heap Scheme file not specified");
siscContext = new AppContext();
interPool = new ArrayList();
sisc.Interpreter interp = getInterpreter();
try {
org.apache.cocoon.environment.Context context =
(org.apache.cocoon.environment.Context)cocoonContext.get(Constants.CONTEXT_ENVIRONMENT_CONTEXT);
System.out.println("Loading heap "
+ context.getResource(heapFileName));
InputStream is = context.getResource(heapFileName).openStream();
BufferedInputStream bis = new BufferedInputStream(is);
GZIPInputStream gzis = new GZIPInputStream(bis);
DataInputStream dis
= new DataInputStream(new BufferedInputStream(gzis));
siscContext.loadEnv(interp, dis);
}
catch (Exception ex) {
System.err.println("Error loading heap:" + ex);
ex.printStackTrace();
throw new ConfigurationException("Cannot load heap file: " + ex);
}
siscContext.setEvaluator("eval");
}
/**
* Obtain a Scheme Interpreter from the internal pool of
* interpreters.
*
* @return an <code>Interpreter</code> value
*/
public sisc.Interpreter getInterpreter()
{
synchronized(interPool) {
int size = interPool.size();
if (size != 0)
return (sisc.Interpreter)interPool.remove(size - 1);
}
// Create a new interpreter and return it
DynamicEnv environment = new DynamicEnv(System.in, System.out);
environment.parameters.put("environment", null);
sisc.Interpreter interp = new sisc.Interpreter(siscContext, environment);
return interp;
}
/**
* Put back into the pool an Interpreter instance.
*
* @param interp an <code>Interpreter</code> value
*/
public void releaseInterpreter(sisc.Interpreter interp)
{
synchronized(interPool) {
interPool.add(interp);
}
}
public Source readScript(Environment environment, String sourceName)
throws Exception
{
Source source = null;
System.out.println("Reading file " + sourceName);
sisc.Interpreter interp = getInterpreter();
try {
source = environment.resolve(sourceName);
InputStream inputStream = source.getInputStream();
Reader reader = new BufferedReader(new InputStreamReader(inputStream));
StringBuffer buffer = new StringBuffer();
char[] cbuf = new char[1024];
int len;
while ((len = reader.read(cbuf)) != -1)
buffer.append(cbuf, 0, len);
interp.eval(buffer.toString());
}
finally {
releaseInterpreter(interp);
}
return source;
}
public void callFunction(String funName, List params,
Environment environment, InvokeContext ctx)
throws Exception
{
checkForModifiedScripts(environment);
sisc.Interpreter interp = getInterpreter();
Map dynVars = interp.dynenv.parameters;
try {
int size = params.size();
Value[] args = new Value[size];
for (int i = 0; i < size; i++) {
args[i]
= new ImmutableString(((Interpreter.Argument)params.get(i)).value);
}
Symbol funSym = Symbol.get(funName);
Procedure function = (Procedure)interp.ctx.toplevel_env.lookup(funSym);
interp.eval(function, args);
}
finally {
releaseInterpreter(interp);
}
}
public void handleContinuation(String continuationId,
Environment environment, InvokeContext ctx)
throws Exception
{
}
}