cocoon-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Grzegorz Kossakowski <gkossakow...@apache.org>
Subject Re: Pipeline components and Object Model issues
Date Sun, 19 Aug 2007 14:03:50 GMT
Grzegorz Kossakowski pisze:
> Hello,
> 
> Joerg Heinicke asked[1] me to provide summary of the issue that Daniel 
> raised[2] and outline
> possible solutions so we can discuss them.
>  
> I think we should do the same for Object Model. I proposed[5] to create 
> new Spring scope (or reuse
> sitemap scope that must be implemented). Actually, such scope does, 
> behind-the-scene, what I
> described one paragraph above. It creates new instance (that may inherit 
> properties from old one) of
> Object Model when entering pipeline components. Then component is safe 
> to modify Object Model
> according to its needs or even pass it to subsequent, internal requets 
> (like calling service) and
> can be sure that Object Model contains only data belongs only to the 
> current component. What's very
> convenient, Spring scope would be completely transparent to the 
> components and even almost
> transparent to the pipeline's implementation. Pipeline's code would have 
> to only inform when scope
> is entered and leaved.
> 
> On the other hand, there is a subtle difference between threads ran 
> simultaneously and pipeline's
> components ran simultaneously. In latter case, we are in charge of 
> component's management and
> execution. That means we know exactly when one or another component is 
> executed so we can modify the
> same Object Model instance the way that changes to Object Model 
> performed in one component will be
> not visible in another one. Since switching between components occurs on 
> every SAX event we would
> have to adjust Object Model on-the-fly for every SAX event and every 
> component in a pipeline. This
> solution has been proposed[6] by Daniel that gave more detailed 
> description.

I've done more research and came to conclusion that we will need to combine ideas of custom
scope 
and environment changer. I'm going discuss technical details here.

Implementing custom scope has advantages that were outlined earlier. What I missed before
was how 
class implementing org.springframework.beans.factory.config.Scope interface knows which scope
is the 
active one? How it knows if new bean should be created or there is already one in this scope?

In order to keep this information accurate we need to switch scope every time component is
switched, 
which means effectively for every SAX event that comes along the pipeline. We already expressed

concerns about such solution because it may be too heavy but if we only change _scope_ it's
really 
lightweight and I expect it to have almost zero impact on performance. The code of such scope

changer would look like:

public class PipelineComponentScopeChanger implements ContentHandler {
   //This map will contain only one attribute "beans", this map is shared between all
   //PipelineScopeChanger instances and PipelineScope class
   private Map scopeAttributesHolder;

   //This map holds beans in this scope
   private Map beansInScope;

   private ContentHandler nextPipelineComponent;

public startElement(String namespaceURI, String localName, String qName, Attributes atts)
 {
   private Map currentBeansInScope = (Map)scopeAttributesHolder.get("beans");
   scopeAttributesHolder.put(beansInScope);
   nextPipelineComponent.startElement(namespaceURI, localName, qName, atts);
   scopeAttributesHolder.put(currentBeansInScope);
}

}

Same goes for all other SAX events. It's actually one extra get and two puts calls on Map.
Rather 
lightweight, yes?

Then code of PipelineComponentScope would look like:

public class PipelineComponentScope implements Scope {

   private Map scopeAttributesHolder;

public Object get(String name, ObjectFactory objectFactory) {
         Map scopedBeans = (Map)scopeAttributesHolder.get("beans");
         Object scopedObject = scopedBeans.get(name);
         if (scopedObject == null) {
             scopedObject = objectFactory.getObject();
             scopedBeans.put(name, scopedObject);
         }

         return scopedObject;
     }

}

You may wonder how this scopedAttributesHolder would be injected into these classes. Before

discussing this issue I would like to give you another remark.

I showed to you that PipelineComponentScopeChanger would implement ContentHandler so you could

thought that I'm going to follow Daniel suggestion[1] to put this changer between pipeline

components. Next idea that comes to mind is that we should create this changers in pipeline's
code 
because it's a place where we are in control of all components and can insert these changer.
Actually, I'm not going this path, or not literally.

I want to create dynamic proxies around pipeline components. Actual wrapping would be performed
by 
class implementing BeanPostProcessor interface. Taking one perspective one could say that
this it's 
almost the way as discussed one paragraph above. However, going with this path makes whole
pipeline 
scope completely *orthogonal* to the pipeline and its components' code. No existing class
will be 
touched and there is no requirement on pipeline components' configuration files. No need for
custom 
namespace in XML config, etc.

I feel proud of this solution as it solves non-trivial problem just in few lines of code and
few 
config files in transparent way. 8-)

Of course I did not mention some corner cases like pipeline component scope behaviour where
we are 
_not_ in pipeline component or how to properly initialize Object Model in pipeline scope.
I'm going 
to start implementing this right know so I'll figure out this issues shortly.

[1] http://article.gmane.org/gmane.text.xml.cocoon.devel/74435

-- 
Grzegorz Kossakowski
http://reflectingonthevicissitudes.wordpress.com/
*** My Internet Service Provider breaks my internet connection                ***
*** incessantly so I'll not be able to respond to e-mails                     ***
*** regularly and my work will be somehow irregular.                          ***
*** I'm already trying to switch ISP but it will take handful amount of time. ***


Mime
View raw message