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]