You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@cocoon.apache.org by Nicola Ken Barozzi <ni...@apache.org> on 2003/07/01 10:50:30 UTC

Re: Aspect-based pipelines and link view ( Re: Link view goodness)

Upayavira wrote, On 30/06/2003 18.18:
> Guys,
> 
> 
>>The link stuff is a cross-cutting concern. This thread has IMHO shown
>>how aspects can be easily added to the sitemap, and effectively used.
>>Let's see...
...
>>><map:resource name="gather-links" from-position="content">
>>>  <!-- Any required link munging -->
>>>  <map:transformer type="gather-links"/>
>>></map:resource>
...
>>Seems like simply adding this capability to resources is nice. We
>>could similarly make a link-view that uses the same transformer and a
>>serializer. In this way it could also be compatible with the 3pass
>>method. Hmmm...
>>
>>>Ie, a Resource inserted in each pipeline after the 'content' label.
>>>Rather AOP'ish.
>>
>>Yup. As link gathering is a cross-cutting concern, it also makes sense
>>conceptually.
> 
> So you're saying, with a resource that has a 'from-position' attribute, that specifies 
> after which label it should be inserted? That makes sense. So you only have to have 
> the resource once per sitemap, rather than having to insert it into every pipeline. 

Exactly.

As you say, it automatically gets inserted in each place where I would 
have to put it manually.

So it's not part of the single pipelines, but it's a common "aspect" of 
the system that gets applied.

For example, if I wanted to log all method exits, I could put by hand a 
log() call in each method. Or I could factor out this aspect and specify 
with a rule where it applies, like saying:

  foreach(method.return){
   log()
  }

The important thing here is how I can tell the system about where to 
apply that code. It's important that it can be explained as a common 
rule, or else I'll be just moving the single log calls out of the 
methods, with no gain.

Here, linking has to be applied to a *group* of pipelines, in a specific 
*part* of them.
IE: "for xml pipelines, where the content is done, insert this transformer".

> But - what if the pipeline itself needs modifying to expose links from within PDFs for 
> example. The LinkGatheringTransformer I have coded has two modes, one where it 
> just hunts for href, src and xlink attributes, and the other that searches for attributes 
> in the http://apache.org/cocoon/link-gatherer/1.0 namespace (probably to be used 
> with a 'link' prefix). This latter kind is required for gathering links that don't conform to 
> the href, src or xlink conventions. Just auto-inserting a link gatherer wouldn't work in 
> this case.

It has to be possible to define when one or the other apply.
Examples of the two usages?

...
>>Now we say: "when the view is triggered, start at a label"
>>After it could be:  "when the view is triggered, start at position"
>>Instead we need: "when the position is met, check if it has to be
>>triggered".
>>
>>Here is an example that uses this "inverted" AOPish system for views.
>>
>>The following adds two aspects:
>>  - an aspect gets called from every content position and gathers
>>  links. - the other one gets called from every content position. If
>>  the 
>>request has a cocoon-view=links, then the links are serialized.
>>
>><map:aspects>
>>  <map:aspect type="from-label" test="content">
>>    <!-- Any required link munging -->
>>    <map:transformer type="gather-links"/>
>>  </map:aspect>
>>  <map:aspect type="from-label" test="content">
>>     <map:action type="request-param">
>>       <map:param name="cocoon-view" value="link">
>>       <map:serializer type="links"/>
>>     </map:action>
>>  </map:aspect>
>></map:aspects>
>>
>>This would make it very easy to add security-based checks, logging, or
>>any other stuff.
>>
>><map:aspects>
>>  <map:aspect type="pipeline" test="start">
>>    <map:action type="check-security"/>
>>  </map:aspect>
>>  <map:aspect type="pipeline" test="all">
>>    <map:transformer type="logger"/>
>>  </map:aspect>
>>  <map:aspect type="error" test="all">
>>    <map:action type="notify-admin"/>
>>  </map:aspect>
>></map:aspects>
>>
>>What do others think?
...
> 
> I'm afraid you left me completely behind there. I've not really yet understood what 
> AOP is, and your ideas go far further than my Cocoon implementation skills currently 
> allow.

It's quite easy once you go behind the words...

> I'd quite like to find something that can be implemented reasonably short term, and 
> then explore these more far-reaching ideas as time passes (and as the size and 
> capacity of my brain increases).
> 
> Are you guys interested for the time being in a LinkGatheringTransformer as 
> described above? Or is there something not too far away that we can do now to 
> gather links?

  - Upayavira sanity check System -
  - please wait... -
  - ... -

  - control NicolaKen ...
  - in progress...

  *** ALERT ALERT ***
  *** Highly volatile thoughts ***
  *** ALERT ALERT ***

Ok, I got the message ;-)

Thanks for bringing me back to earth, I have the ?slight? ;-) tendency 
of flying high.

Let's see what we need to resolve for this case.

We said that the current gatherer has the problem of being fixed.
We have seen that a transformer placed in the right place can be more 
configurable.

So, the reasonable solution that comes from this is that if the 
user-defined pipeline is caching links, those are used.
If not, Cocoon inserts a gatherer in the right position.

This mixes ease of use with configurability right now.

But then we need amore definitive solution.
Without calling them aspects, let's call them inserts for now.
They are rules that make Cocoon insert resources or pipelines give 
particular rules.

For example, let's say that we want Cocoon to add a 
LinkGatheringTransformer at the end of each pipeline.

   <map:insert type="index" location="last">
     <map:transformer type="gather-links"/>
   </map:insert>

Let's say we want to add it at the beginning instead:

   <map:insert type="index" location="last">
     <map:transformer type="gather-links"/>
   </map:insert>

If we want to add after the label content:

   <map:insert type="label" location="content">
     <map:transformer type="gather-links"/>
   </map:insert>

What here is missing is the declaration of the inserts.
Like when calling transformers I have to define the Transformer type, 
here I have to define the Inserter type.

   <map:components>
     <map:inserters>
       <map:inserter name="label"
                     class="org.apache.cocoon.inserters.LabelInserter"/>
       <map:inserter name="index"
                     class="org.apache.cocoon.inserters.IndexInserter"/>
     </map:inserters>
   </map:components>

Where an Inserter is a Components that gets a Pipeline and a series of 
Pipeline Components and inserts those in the pipeline as loaction indicates.

   public void insert(Pipeline p,
                      PipelineComponent[] components,
                      String location){
     ...

   }

The sitemap would call all inserters on all pipelines prior to starting.

This though needs additions to our contracts. What about making a 
special pipeline that can be aspected?

   <map:pipes default="aspected">
     <map:pipe name="aspected" 
src="org.apache.cocoon.components.pipeline.impl.AspectedProcessingPipeline">
       <param name="label:content" value="call-resource:link-gatherer"/>
       <param name="index:first"   value="call-resource:link-gatherer"/>
     </map:pipe>
   </map:pipes>

Bleah :-P

Let's start with the automatic-or-Transformer thing for now, then 
eventually evolve out of it.

-- 
Nicola Ken Barozzi                   nicolaken@apache.org
             - verba volant, scripta manent -
    (discussions get forgotten, just code remains)
---------------------------------------------------------------------