cocoon-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Stefano Mazzocchi <stef...@apache.org>
Subject Re: [RT] Componentizing Cocoon Applications
Date Wed, 06 Feb 2002 23:59:44 GMT
Berin Loritsch wrote:

> KISS is the best way.  Start with something simple, and expand on the
> idea until you need something better.

Well, I don't resonate much with KISS principle but I do like the XP
concept of doing 'the simplest thing that can possibly work'.

> However, XML and Java have different representations.  My assertion is that
> the schema (whether XSchema or something else) is the interface for XML
> documents.

I agree with this.

> >
> >                                        - o -
> >
> > Ok, let's keep on the parallel here: the
> > 'http://apache.org/cocoon/roles/skin/1.0' contract (well, the URI is the
> > indentifier, but it's a one2one relationship so I will call the
> > identifier 'the contract' since it's its name) is composed of:
> >
> >  1) an internal addressing space
> >
> > that's it.
> >
> > Both you and Berin suggest that this might not be enough to indicate a
> > contract: I disagree, the above is sure enough. But I agree with you
> > guys that an addressing space might not be the best solution to describe
> > the relationships because is somewhat too general.
> >
> > Let me explain: when we connect to
> >
> >    <transform src="[skin]://docbook/docbook2html.xslt"/>
> >
> > this is nothing different from doing
> >
> >   ((ObjectStore) store).store(key, object);
> >
> > for Avalon components because
> >
> >  skin -> 'http://apache.org/cocoon/roles/skin/1.0'
> >  ObjectStore -> 'org.mystuff.components.ObjectStore'
> 
> Yes, but in this example you are mixing the contract of transform and skin.

Just like you call a method of your java component, you are using 'one'
capability (the docbook2html transformation behavior) of your skin
component. I don't see your point.

> I don't see that as clean.  If we are going to introduce the concept of
> components, we must provide a distinct markup for them.
> 
> <match pattern="*.html">
>    <generate src="docs/{1}.xml"/>
>    <transform src="stylesheets/docbook2skin.xslt"/>
>    <apply component="http://apache.org/cocoon/roles/skin/1.0"/>
>    <serialize/>
> </match>
> 
> And in another place, the component is defined. The definition of the
> component in this case would be a simple sub-pipeline (i.e. transformer).

hmmmm... what I don't like about your proposals is that they appear to
be much less verbose (and it's a good thing) but also much less
self-explanatory (which is a bad thing).

> Perhaps the better approach would be something like this:
> 
> <match pattern="*.html">
>    <component src="{1}" role="http://apache.org/cocoon/roles/authenticate/1.0">
>      <valid-roles>
>        <role>Vendor</role>
>        <role>Retailer</role>
>      </valid-roles>
>      <component role="http://mycompany.com/roles/product-approval/1.0"/>
>    </component>
> </match>

Hmmm...
 
> The communicates that we are using components with components.  It communicates
> that we want the "authenticate" component to wrap all requests to the
> "product-approval" component only allowing the "Vendor" and "Retailer" roles.
> Furthermore, the "product-approval" component uses the "skin" component for its
> presentation.

? where is the skin part?

> The contracts for a component is that it's pipeline must be complete.  For embeded
> pipelines such as we have here, the outer pipeline acts as the generator for the
> internal pipeline.  The Serializer of the inner pipeline is stripped.

This is what I don't like about your proposals (this and past ones): you
are removing a verbosity that is necessary at this point to make the
pipelines self-describing.
 
> The Component definitions for the pipeline management can be something like this:
> 
> <component role="http://apache.org/cocoon/roles/authenticate/1.0">
>      <!-- Map Components (i.e. generators/transformers/actions/etc.) are
>           defined here
>      -->
>      <map:components>
>        <map:actions/>
>        <map:action-sets/>
>      </map:components>
> 
>      <!-- Taking advantage of the fall through function of actions, we select the
>           generator if the authentication is valid.  Notice the "embed:{uri}"
>           protocol.  Embed means that the source from the embedded component is
>           used.  The "component" protocol is a new protocol necessary to mark
>           resources within the Component file.
>      -->
>      <act set="authorized">
>         <map:select type="embeddedComponent">
>           <map:case test="yes">
>             <generate src="embed:component"/>
>           </map:case>
>           <map:otherwise>
>             <generate src="component://login-successful"/>
>           </map:otherwise>
>         </map:select>
>      </act>
> 
>      <!-- At this point, the user is not authorized, so we want to authenticate
>           them.  We have our own pipelines here.
>      -->
>      <act set="authenticate">
>        <generator src="component://login-form.xml"/>
>      </act>
> 
>      <!-- Finally, we have either obtained the generator we want, or we have
>           come to the place where there is an error.  The error can be that the
>           login authenticated correctly, but was not able to be authorized for
>           the resource.
>      -->
>      <generator src="component://login-error.xml"/>
>      <map:select type="hasComponent">
>        <map:case test="http://apache.org/cocoon/roles/skin/1.0">
>           <component role="http://apache.org/cocoon/roles/skin/1.0"/>
>        </map:case>
>        <map:otherwise>
>          <transform src="component://stylesheets/form2html.xslt"/>
>        </map:otherwise>
>      </map:select>
>      <serialize/>
> </component>
> 
> This markup explains how we can create components with the sitemap markup with the addition
> of a couple of protocols, selectors, and tags.  Perhaps what is more important at this
point
> is that all components are described in terms of pipeline.  A component is a predefined
pipeline,
> that can have parts of it overridden by other embeded components.
> 
> Furthermore, it opens the door to have purely code components that do not have to be
compiled.

I can't say I resonate with this, but I admit is a good step forward
since it's a first step in a behavioral deployment descriptor.... but I
still have the impression that is not good enough.... hmmm, I have to
think more about it because right now I don't have anything better to
propose...

> It is preferred to have all components behave in a self-contained fashion , but use other
components
> if they exist.  Avalon Phoenix (the server kernel) addresses this with the concept of
Blocks.
> A Block is a Service that can be provided to any other service.  Each block has a "BlockInfo"
> associated with it.  The BlockInfo publishes the service that is provided (i.e. the interface
> that it implements), the version, and any dependencies it has on other Blocks.  A BlockInfo
is
> implementation based, so different implementations can require different sets of external
blocks.
> 
> Here is an example from a distributed print server I wrote recently:
> 
> <blockinfo>
> 
>    <!-- section to describe block -->
>    <block>
>      <version>1.0</version>
>    </block>
> 
>    <!-- services that are offered by this block -->
>    <services>
>      <service name="com.infoplanning.printserver.services.PrintServer"
>               version="1.0" />
>    </services>
> 
>    <dependencies>
>      <dependency>
>        <service name="org.apache.avalon.cornerstone.services.sockets.SocketManager"
version="1.0"/>
>      </dependency>
>      <dependency>
>        <service name="org.apache.avalon.cornerstone.services.connection.ConnectionManager"
>                 version="1.0"/>
>      </dependency>
>      <dependency>
>        <service name="com.infoplanning.printserver.services.PrintQueue" version="1.0"/>
>      </dependency>
>    </dependencies>
> 
> </blockinfo>
> 
> We had at one time discussed optional dependencies, but I can't remember the solution
for
> that.  I *believe* that instead of placing the <dependency/> information in the
<dependencies/>
> element, they were places as children of the <requests/> element.  That way the
Component will
> use the requested component if available--but won't fail if it does not exist.
> 
> Perhaps something like this would be a good starting place?

The real question is: cocoon webapps are more similar to Avalon Blocks
or to Avalon Components?

Components are smaller entities and are more cross-cutting, Blocks are
bigger entities that rarely cross-cut.

But Avalon Components are not hotly deployable, while Avalon Blocks were
designed to (NOTE for avalon newbies: Cocoon uses avalon components and
could be itself pictured as a block).

But probably, even Cocoon has two different types of parts: components
and blocks, depending on the amount of cross-cutting.

For example, a skin is a component, a webmail is a block (that uses a
skin).

But maybe this is getting too far for now...

bah, dunno, what do others have to say about this?

-- 
Stefano Mazzocchi      One must still have chaos in oneself to be
                          able to give birth to a dancing star.
<stefano@apache.org>                             Friedrich Nietzsche
--------------------------------------------------------------------

---------------------------------------------------------------------
To unsubscribe, e-mail: cocoon-dev-unsubscribe@xml.apache.org
For additional commands, email: cocoon-dev-help@xml.apache.org


Mime
View raw message