cocoon-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Hunsberger, Peter" <Peter.Hunsber...@stjude.org>
Subject RE: [RT] Cocoon Input Model
Date Mon, 01 Mar 2004 16:17:00 GMT
Steve Krulewitz <shooz@mm.st> writes:

> I agree that more sophisticated input handing would make general web 
> applications much easier to write in Cocoon... here are some 
> more random 
> thoughts on the subject:
> 
> Input can come from many sources:
> 
> - http query string
> - http post stream
> - http cookie
> - user session object (from disk? database?)
> - raw socket?
> - any of the above interpreted as XML
> 
> The purpose of input handing should be to massage and 
> validate data sent 
> over HTTP to something that you can confidently hand over to 
> a strongly 
> typed business object.  Here are some of the things that, in my 
> experience, this usually amounts to:
> 
> - required value checking
> - datatype checking and casting (is it a date?  then make it 
> a j.u.Date)
> - min/max string length or value checking
> - value formatting
> - database value checking (is that state_id the user sent 
> really in my 
> table of states?)
> - hash check of fields (to verify the data has not been modified over 
> the round trip -- does this hash match the hash of these 
> other fields?)
> - converting the value of a single field, or the entire input 
> stream, to XML
> - decrypting of a single field into multiple fields (and then 
> apply the 
> above to the decrypted fields)
> 
> This, of course, sounds a whole lot like forms processing, 
> and I don't 
> see any reason why it shouldn't be handled by cforms.  

Well, not everyone may be using cforms; I think you want a more generic
capability that everyone, including cforms, can pick up....

> The input 
> "pipeline" would look something like:
> 
> 1. A deserializer component is used to convert the raw input 
> into XML. 
> A deserializer component would be mated to each type of input -- for 
> example, the HTTPDeserializer would turn HTTP headers into a 
> simple XML 
> document (or just selected parts of the header based on a parameter).
> 
> 2. More than one deserializer could be employed for a 
> particular request 
> -- the result would be aggregated into a single document.
> 
> 3. cforms validation
> 
> 4. transformations**
> 
> 5. either make result XML available as input to a pipeline (as a 
> generator) or bind to a Java object for use in an 
> action/flow/jxtemplate.
> 
> ** Including transformation steps in this "pipeline" might seem like 
> overkill, however I would find it very useful.  If the user 
> sends an ID, 
> a SQLTransformer here could be used to convert that ID into more 
> information from the database.  This is _not_ the same as using a 
> SQLTransformer in the output pipeline since we want to be 
> able to access 
> this data from flow through the Java object produced in step 5.
> 
> Now where does this belong in the sitemap?  I think these input 
> pipelines should be separate from the main pipelines, and be called 
> similar to the way actions do:
> 
> <map:input-pipeline name="orders">
>    <map:aggregate>
>      <map:generate type="httpdeserializer">
>        <map:parameter name="query" value="customerid,orderid"/>
>     </map:generate>
>     <map:transform type="sql"/>
>     <map:serialize type="object"/>
> </map:input-pipeline>
> 
> ...
> 
> <map:pipeline match="/orders">
>    <map:input name="orders"/>
>    <map:generate type="jx"/>
>    <map:transform "orders.xslt"/>
>    <map:serialize/>
> </map:pipleline>
> 
> ~~~~~~~~~~
> 
> Of course, this also opens a lot of questions on how cforms is 
> integrated into cocoon... and where do "input" pipelines end 
> and where 
> "output" pipelines begin?

I've been watching this thread thinking that I really need to be
involved with it since we are doing so much of this kind of thing.
However, I couldn't figure out exactly what to say, although I agreed
with the general requirements something didn't seem quite right.  I
think this set of comments crystalized things for me: *** Cocoon already
has "input pipelines". *** The flow "processPipelineTo" function can
take any arbitrary source and run it through a pipeline as part of
generic response handling.  

As I've written before, this is how we do generic validation.  Consider
for example, the flowscript function:

function _validate( page, args )
{
    var sourceURI = "cocoon:run/_validate/"+page;
    var destinationURI = "xmodule:request-attr:validate";

    var resolver = null;
    var destination = null;
    try
    {
        resolver = cocoon.getComponent(
Packages.org.apache.cocoon.environment.SourceResolver.ROLE );
        destination = resolver.resolveURI( destinationURI );
        output = destination.getOutputStream();
        cocoon.processPipelineTo( sourceURI, {}, output );
        output.close();
        if ( cocoon.request.getAttribute( "validationErrorLevel" ) == 0
)
            return true;
    } catch ( error ) {
        print( " page=" + page + " args=" + args + " error: " + error +"
ouput="+ output.toString() );
        throw error;
    } finally {
        if (destination != null)
            resolver.release( destination );
        cocoon.releaseComponent( resolver );
    }
    return false;
}

This runs the pipeline:

            <map:match pattern="*/_validate/**">
                <map:generate src="cocoon:/{1}/requestdata"/>
                <map:transform src="stylesheets/resolve_request.xsl"/>
                <map:transform
src="cocoon:/{1}/validationTemplate/{2}"/>
                <map:transform type="CTcheck"/>
                <map:serialize type="xml"/>
            </map:match>

Two important things:

1) in the flowscript the varible "output" has the complete contents of
this pipeline in it, it can be folded back into any handling you want
via flowscript variable passing (eg, as an XSLT parameter containing a
nodeset).

2) if you don't want to use a parameter you can also pick the contents
of this pipeline back up via xmodule input/output handling which is what
we do (the xmodule destination above). BTW, I keep meaning to thank
Daniel for this: thanks Daniel! 

So, bottom line, I don't think Cocoon needs any new sitemap constructs
to do what is being discussed, unless what is needed is a way to do this
without flow?  However, trying to do this without flow seems to me to
mean going back to regular actions, so I can't see any real reason to do
this...


Mime
View raw message