ovidiu 01/12/21 10:46:42
Added: scratchpad/schecoon/src/org/apache/cocoon/scheme/sitemap
SitemapComponents.java SitemapManager.java
Log:
Added. Hook up the Scheme sitemap into Cocoon.
Revision Changes Path
1.1
xml-cocoon2/scratchpad/schecoon/src/org/apache/cocoon/scheme/sitemap/SitemapComponents.java
Index: SitemapComponents.java
===================================================================
package org.apache.cocoon.scheme.sitemap;
import org.apache.avalon.framework.component.ComponentManager;
import org.apache.avalon.framework.parameters.Parameters;
import org.apache.cocoon.components.pipeline.EventPipeline;
import org.apache.cocoon.environment.Environment;
import sisc.ContinuationException;
import sisc.Interpreter;
import sisc.ModuleAdapter;
import sisc.data.Pair;
import sisc.data.Symbol;
import sisc.data.Value;
import sisc.modules.J2S;
/**
* This class contains the definition of the Scheme functions:
*
* <ul>
*
* <li><b>sitemap:generate</b> - create a new {@link
* org.apache.cocoon.components.pipeline.EventPipeline}, and adds the
* generator specified by the function arguments to it.</it>
*
* <li><b>sitemap:transform</b> - creates a transformer object of the type
* specified by the arguments, adds it to the pipeline passed as
* argument, and returns the pipeline.</li>
*
* <li><b>sitemap:read</b> - creates a new {@link
* org.apache.cocoon.components.pipeline.StreamPipeline} and a new
* {@link org.apache.cocoon.reading.Reader}, adds the reader to the
* pipeline, and returns the pipeline.
*
* </ul>
*
* @author <a href="mailto:[EMAIL PROTECTED]">Ovidiu Predescu</a>
* @since December 20, 2001
*
* @see org.apache.cocoon.components.pipeline.EventPipeline
* @see org.apache.cocoon.components.pipeline.StreamPipeline
* @see org.apache.cocoon.reading.Reader
*/
public class SitemapComponents extends ModuleAdapter
{
public String getModuleName()
{
return "Apache Cocoon Sitemap Components";
}
public float getModuleVersion()
{
return 1.0f;
}
public static final int GENERATE = 1, TRANSFORM = 2, READER = 3;
protected Parameters emptyParam = new Parameters();
/**
* Creates a new <code>SitemapComponents</code> instance. Defines
* the Scheme functions implemented by this module.
*/
public SitemapComponents()
{
define("sitemap:generate", GENERATE);
define("sitemap:transform", TRANSFORM);
define("sitemap:read", READER);
}
/**
* The SISC evaluator function for this module. Executes the actual
* Java code corresponding to the Scheme functions defined by the
* module.
*
* @param primid an <code>int</code> value
* @param r an <code>Interpreter</code> value
* @return a <code>Value</code> value
*/
public Value eval(int primid, Interpreter r)
throws ContinuationException
{
try {
switch (r.vlr.length) {
// Three argument functions
case 3:
switch (primid) {
case GENERATE:
return generate(r.vlr[0], r.vlr[1], r.vlr[2]);
case READER:
return read(r.vlr[0], r.vlr[1], r.vlr[2]);
default:
break;
}
// Four argument functions
case 4:
switch (primid) {
case TRANSFORM:
return transform (r.vlr[0], r.vlr[1], r.vlr[2], r.vlr[3]);
}
}
}
catch (Exception ex) {
ex.printStackTrace();
throw new RuntimeException(ex.toString());
}
throw new RuntimeException("Invalid number of arguments to function "
+ r.acc);
}
/**
* Type cast function from a Scheme wrapper of a ComponentManager.
*
* @param scm a Scheme wrapper instance of a ComponentManager.
* @return a <code>ComponentManager</code> value
*/
static public ComponentManager componentManager(Value scm)
{
try {
return (ComponentManager)(((J2S.JavaObject)scm).o);
}
catch (ClassCastException ex) {
typeError("ComponentManager", scm);
}
return null;
}
/**
* Type cast function from a Scheme wrapper of an Environment
* instance.
*
* @param senv a Scheme wrapper of an Environment instance.
* @return an <code>Environment</code> value
*/
static public Environment environment(Value senv)
{
try {
return (Environment)(((J2S.JavaObject)senv).o);
}
catch (ClassCastException ex) {
typeError("Environment", senv);
}
return null;
}
/**
* Retrieve an entry from an association list. Uses eq? to compare
* the CAR of each entry.
*
* @param l the association list
* @param v the value to be searched for
* @return a <code>Pair</code> value representing the entry, or
* <tt>FALSE</tt> if no such entry is present.
*/
static public Value assq (Value l, Value v)
{
Pair list = pair(l);
while (list != EMPTYLIST) {
Pair entry = pair(list.car);
if (entry.car.eq(v))
return entry;
list = pair(list.cdr);
}
return FALSE;
}
/**
* Assumes the <tt>sparams</tt> is either an association list or the
* FALSE value. It returns either an empty Avalon
* <tt>Parameters</tt> instance, or a <tt>Parameters</tt> instance
* that contains the values extracted from the association list.
*
* @param sparams a <code>Value</code> value, either <tt>FALSE</tt>
* or an association list
* @return an Avalon <code>Parameters</code> instance
*/
public Parameters getParameters(Value sparams)
{
Parameters params = emptyParam;
if (!sparams.eq(FALSE)) {
params = new Parameters();
Pair sparamValues = pair(pair(sparams).cdr);
while (sparamValues != EMPTYLIST) {
Pair entry = pair(sparamValues.car);
String name = string(entry.car);
String value = string(entry.cdr);
params.setParameter(name, value);
sparamValues = pair(sparamValues.cdr);
}
}
return params;
}
/**
* <p>Creates a new <tt>EventPipeline</tt> instance, and a new
* Generator instance. Adds the Generator to the pipeline.
*
* <p>The type of the generator is specified in the <tt>sargs</tt>
* list, which is a Scheme association list. The parameters to be
* passed to the generators, if any, should be present in this
* association list as the value of the <it>params</it> entry. This
* value should be another association list, where the CAR of each
* entry is the name of the parameter, and the CDR of the entry is
* the actual value.
*
* <p>The recognized parameters are:
*
* <ul>
*
* <li><b>src</b> - (required) the source of the generator
*
* <li><b>type</b> - (optional) the type of generator. If not
* specified, <it>file</it> is assumed.
*
* <li><b>params</b> - (optional) the parameters to be passed to
* the generator. The CDR of this association entry should be
* another association entry, that contains the names and values of
* the parameters.
*
* </ul>
*
* @param scm the Scheme wrapper for the ComponentManager instance
* @param senv the Scheme wrapper for the Environment instance
* @param sargs the Scheme arguments, as list
* @return a Scheme wrapper for the <tt>EventPipeline</tt> instance
*/
public Value generate(Value scm, Value senv, Value sargs)
throws Exception
{
ComponentManager manager = componentManager(scm);
Environment env = environment(senv);
EventPipeline eventPipeline;
eventPipeline = (EventPipeline)manager.lookup(EventPipeline.ROLE);
eventPipeline.recompose(manager);
// Obtain the 'src' attribute
Value ssrc = assq(sargs, Symbol.get("src"));
System.out.println("sargs = " + sargs + ", ssrc = " + ssrc);
if (ssrc.eq(FALSE))
throw new RuntimeException("No 'src' attribute specified for 'generate'!");
String src = string(pair(ssrc).cdr);
// Obtain the 'type' attribute
Value stype = assq(sargs, Symbol.get("type"));
String type = "file";
if (!stype.eq(FALSE))
type = string(pair(ssrc).cdr);
// Obtain the parameters
Value sparams = assq(sargs, Symbol.get("params"));
Parameters params = getParameters(sparams);
eventPipeline.setGenerator(type, src, params);
return new J2S.JavaObject(eventPipeline);
}
public Value read(Value scm, Value senv, Value sargs)
{
return null;
}
public Value transform(Value scm, Value senv, Value sargs, Value spipeline)
{
return null;
}
}
1.1
xml-cocoon2/scratchpad/schecoon/src/org/apache/cocoon/scheme/sitemap/SitemapManager.java
Index: SitemapManager.java
===================================================================
package org.apache.cocoon.scheme.sitemap;
import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintStream;
import java.util.Map;
import java.util.Stack;
import java.util.zip.GZIPInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.avalon.framework.component.ComponentManager;
import org.apache.avalon.framework.component.Composable;
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.avalon.framework.logger.AbstractLoggable;
import org.apache.avalon.framework.thread.ThreadSafe;
import org.apache.cocoon.Constants;
import org.apache.cocoon.Processor;
import org.apache.cocoon.components.pipeline.EventPipeline;
import org.apache.cocoon.components.pipeline.StreamPipeline;
import org.apache.cocoon.environment.Environment;
import org.apache.cocoon.environment.http.HttpContext;
import org.apache.cocoon.environment.http.HttpEnvironment;
import org.apache.cocoon.scheme.servlet.REPLGenericServlet;
import org.apache.cocoon.util.ClassUtils;
import sisc.AppContext;
import sisc.DynamicEnv;
import sisc.Interpreter;
import sisc.data.ImmutableString;
import sisc.data.Procedure;
import sisc.data.Symbol;
import sisc.data.Value;
import sisc.modules.J2S;
/**
* The Java side of the Cocoon Scheme Sitemap Manager. This class is
* responsible with setting up the proper context for the Scheme
* interpreter, and invoking the Scheme function that implements the
* sitemap dispatcher.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Ovidiu Predescu</a>
* @since December 18, 2001
*/
public class SitemapManager
extends org.apache.cocoon.sitemap.SitemapManager
implements ThreadSafe, Contextualizable, Composable
{
protected Symbol mainFunction;
protected Stack interPool;
AppContext siscContext;
Context cocoonContext;
HttpContext httpContext;
J2S.JavaObject cm;
public void contextualize(Context context)
throws ContextException
{
this.cocoonContext = context;
httpContext = (HttpContext)context.get(Constants.CONTEXT_ENVIRONMENT_CONTEXT);
}
/**
* Obtain the ComponentManager instance and wrap it into a Scheme
* object, that's passed later to the Scheme sitemap function.
*
* @param manager a <code>ComponentManager</code> value
*/
public void compose(ComponentManager manager)
{
super.compose(manager);
cm = new J2S.JavaObject(manager);
}
/**
* Properly setup the Scheme interpreter, by loading the heap file.
*
* @param sconf a <code>Configuration</code> value
* @exception ConfigurationException if an error occurs
*/
public void configure(Configuration sconf)
throws ConfigurationException
{
super.configure(sconf);
String mainFunctionString = sconf.getAttribute("entry-point");
if (mainFunctionString == null)
throw new ConfigurationException("Scheme entry point not specified");
String heapFileName = sconf.getAttribute("heap");
if (heapFileName == null)
throw new ConfigurationException("Heap Scheme file not specified");
synchronized (httpContext) {
siscContext =
(AppContext)httpContext.getAttribute(REPLGenericServlet.appCtxAttrName);
if (siscContext == null) {
siscContext = new AppContext();
httpContext.setAttribute(REPLGenericServlet.appCtxAttrName, siscContext);
interPool = new Stack();
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);
}
mainFunction = Symbol.get(mainFunctionString);
siscContext.setEvaluator("eval");
}
}
}
/**
* Obtain a Scheme Interpreter from the internal pool of
* interpreters.
*
* @return an <code>Interpreter</code> value
*/
public Interpreter getInterpreter()
{
synchronized(interPool) {
if (!interPool.empty())
return (Interpreter)interPool.pop();
// Create a new interpreter and return it
DynamicEnv environment = new DynamicEnv(System.in, System.out);
Interpreter interp = new Interpreter(siscContext, environment);
return interp;
}
}
/**
* Put back into the pool an Interpreter instance.
*
* @param interp an <code>Interpreter</code> value
*/
public void releaseInterpreter(Interpreter interp)
{
synchronized(interPool) {
interPool.push(interp);
}
}
/**
* Translate the XML sitemap definition into a Scheme
* representation, and pass it to the Scheme interpreter for
* evaluation.
*
* @param environment an <code>Environment</code> value
* @exception Exception if an error occurs
*/
public void generateSitemap(Environment environment)
throws Exception
{
}
/**
* This method invokes the main Scheme function responsible with
* dispatching the request according to the sitemap definition.
*
* @param environment an <code>Environment</code> value
* @return a <code>boolean</code> value
* @exception Exception if an error occurs
*/
public boolean process(Environment environment)
throws Exception
{
String requestedURI = environment.getURI();
J2S.JavaObject senv = new J2S.JavaObject(environment);
ImmutableString servletPath = new ImmutableString(requestedURI);
Interpreter interp = getInterpreter();
Value[] args = new Value[] {servletPath, cm, senv};
try {
interp.eval((Procedure)interp.ctx.toplevel_env.lookup(mainFunction),
args);
}
finally {
releaseInterpreter(interp);
}
return true;
}
public boolean process(Environment environment,
StreamPipeline pipeline,
EventPipeline eventPipeline)
throws Exception
{
System.out.println("process(environment, pipeline, eventPipeline)");
return true;
}
}
----------------------------------------------------------------------
In case of troubles, e-mail: [EMAIL PROTECTED]
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]