cocoon-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From giacomo <giac...@apache.org>
Subject Re: Interpreted sitemap
Date Sun, 11 Nov 2001 11:17:21 GMT
On Sat, 10 Nov 2001, Ovidiu Predescu wrote:

> On Sat, 10 Nov 2001 09:55:07 +0100 (CET), giacomo <giacomo@apache.org> wrote:
>
> > On Fri, 9 Nov 2001, Ovidiu Predescu wrote:
> >
> > > Hi Sylvain,
> > >
> > > I finally had time to look at the new implementation of the sitemap
> > > code. It's looking good!
> > >
> > > On Thu, 08 Nov 2001 16:21:23 +0100, Sylvain Wallez <sylvain.wallez@anyware-tech.com>
wrote:
> > >
> > > > Ovidiu Predescu a écrit :
> > > > >
> > > > > On Wed, 07 Nov 2001 10:21:59 +0100, Sylvain Wallez <sylvain.wallez@anyware-tech.com>
wrote:
> > > > >
> > > > > > > One of the my requirements for this re-implementation is
to allow
> > > > > > > things other than SAX events to flow on the pipeline. I'm
specifically
> > > > > > > thinking of Java objects that could represent the incoming
HTTP
> > > > > > > request as an object, for unorthodox types of processing.
Of course
> > > > > > > the interfaces of the components in the pipeline have to
be compatible
> > > > > > > for such an approach to work.
> > > > > >
> > > > > > Could you explain in more detail these unorthodox types ? Can't
this be
> > > > > > solved by a custom Environment implementation and/or a Generator
?
> > > > >
> > > > > I don't think it can, but maybe you can prove me wrong.
> > > > >
> > > > > What I need is the ability to have a custom generator that reads
the
> > > > > input HTTP request, and constructs a Java object out of it.
> > > > >
> > > > > An example is when the SOAP message is actually SOAP with
> > > > > attachments. In that case I'd like to pass on the pipeline a JAXM
> > > > > SOAPMessage object, together with the output SOAPMessage object.
The
> > > > > transformers will operate on incoming message and construct the
> > > > > outgoing message, as the processing flows through the pipeline. The
> > > > > trick is I still want to make use of the great XML processing
> > > > > capabilities of Cocoon, and don't want to reinvent a new framework
for
> > > > > this.
> > > >
> > > > What about storing the object in the objectModel or in a Request
> > > > attribute ? This makes it available to every element of the processing
> > > > chain. Or did I miss something ?
> > >
> > > Nevermind, I think what I want to do can be implemented by passing the
> > > needed objects in the Environment as you suggested earlier, or even in
> > > the object model.
> >
> > Again, my suggestion is NOT TO USE THE OBJECT_MODEL for this. The
> > abstracted environment gives you all you need (Request, Session,
> > Context) to put stuff according to your needed scope into the system.
>
> OK, I get your point. The Environment should give you the right life
> scope for the things you place in it. It's indeed very neat, thanks
> for clarifying this.

You're always welcome :)

>
> > > > > > > My thoughts were to take the Ant XML->Java conversion
engine, extend
> > > > > > > it to use the SAX2 API, and create Avalon components that
represent
> > > > > > > the pipeline. The Ant engine is indeed a very simple, yet
powerful and
> > > > > > > extensible way to create a hierarchy of Java objects from
an XML
> > > > > > > document.
> > > > > >
> > > > > > Didn't know about this Java/XML stuff in Ant. I will look at
it.
> > > > >
> > > > > It's a very simple way to hook up Java objects. Essentially each
XML
> > > > > element is represented by a Java class. For each child element of
this
> > > > > element you need to implement an add<ChildElementName>(<ClassName>)
> > > > > method. For each attribute understood by your element, you need to
> > > > > implement a set<AttributeName>(<type>) method. Now you
do have some
> > > > > constructs by which you can add to an element _any_ element you like,
> > > > > which is very useful when you want your element to support arbitrary
> > > > > elements.
> > > > >
> > > > > The Ant engine starts reading the XML file and during the SAX parsing
> > > > > it creates the necessary objects and hooks them up as needed. After
> > > > > the whole Java tree gets constructed this way, it will invoke the
> > > > > execute() method on the topmost object. This triggers the execution
of
> > > > > the build.
> > > >
> > > > I've looked at it : it's nice, but doesn't exactly correspond to what
I
> > > > need.
> > > >
> > > > Firstly, the new TreeProcessor reads sitemap.xmap in a
> > > > so-easy-to-process Avalon configuration, while Ant is entirely
> > > > SAX-based. However, it would be good to have a Configuration2JavaBean
or
> > > > something like that. Have to think about it.
> > > >
> > > > Secondly, and more important : the tree of processing objects isn't
> > > > built directly from the XML tree. The sitemap file is used to build a
> > > > tree of NodeBuilder objects, that in turn create the actual
> > > > ProcessingNodes that will process the environment. This allows the
> > > > builders to choose between different implementations of ProcessingNode
> > > > depending on the environment : use of threadsafe or single-threaded
> > > > components, disctinction between PreparedMatcher and Matcher, etc. This
> > > > is key for maximum speed at process time.
> > >
> > > I believe there is a fundamental difference between the way Avalon and
> > > Ant process an XML configuration file.
> > >
> > > 1) Avalon reads the whole XML file and creates a hierarchy of
> > > Configuration objects. You then obtain the top level Configuration
> > > object and start constructing your data structure from this data. In a
> > > sense the Configuration data structure is very similar with a DOM
> > > tree.
> >
> > But more light wighted than DOM.
>
> Yes. I was referring to DOM more in the sense of an abstract syntax
> tree (AST) from a parsing point of view. You first create this AST
> then traverse it to generate a different data structure.
>
> > > The Ant SAX-based engine eliminates the need to create such an
> > > intermediary data structure. Instead the Ant engine creates the data
> > > structure as it processes the SAX events. The result of the parsing is
> > > exactly the data structure you need.
> >
> > How does Ant know what "data structure" I (I think you meant an Ant Task
> > which is something like a componet in Avalon) needs? With reflection?
>
> It uses a simple mapping file which specifies which XML elements are
> associated with what Java classes. As you already hinted to, the
> implementation uses reflection quite heavily to create the data
> structure.
>
> One more thing. I was not suggesting to use the whole Ant
> infrastructure unmodified, as it has too much Ant related
> stuff. Rather we can take bits and pieces, and extend them to be more
> generic. The same code could probably be used later on by the Ant team
> in building the new Ant2. You could see this engine as creating Avalon
> components instead of Ant tasks; nothing stops us from doing this.
>
> > > 2) With the Avalon model, the code for constructing the final data
> > > structure is spread along the classes that represent the data
> > > structure. Each class has to define how to map from a Configuration
> > > object into its own representation, and has to deal with loading and
> > > instantiation of the classes corresponding to their subelements.
> >
> > In Avalon each component is itself responsible to map Configuration to
> > its own needs. This comes from the fact that a component can take many
> > different roles where in Ant you only have one role Task and thus you
> > can uniform configuration process.
>
> The same is true in Ant. You can map multiple XML elements to the same
> Java class that implements a task.
>
> > But what I don't get is what you say about "loading and
> > instantiation of the classes corresponding to their
> > subelements". Can you explain more in detail?
>
> Take a look at the TreeBuilder.configure() and
> ComponentsNodeBuilder.buildNode(). Notice the code that checks whether
> a class name specified in the config file exists, and how it records
> it. These methods look very similar, yet the logic is quite specific
> for their particular need.
>
> > > With Ant, this whole logic is hidden inside the SAX based engine. The
> > > only thing the class should be concerned with is implementing the
> > > right set<Attribute> and/or add<Element> methods, depending on
the
> > > attributes or elements they support.
> >
> > Oh, this is a bean approach which is not used in Avalon (I think because
> > of the need to use reflection). In fact I don't really like that. The
> > Avalon approch to define a Configurable interface to tell the CM that a
> > component wants a configuration is much more elegant IMHO.
> >
> > > The two models are more like a "pull" model in the Avalon case, as
> > > opposed to a "push" model in the Ant case.
> >
> > This is not true. Avalon strictly bases on the IoC model. This is
> > definitively not a pull method. Instead of using relection to make the
> > engine know what the configuration of a component might be (like in Ant
> > as you told us) is has a much stronger contract based on interfaces. In
> > Avalon components are exposed to others you have a single point of
> > controling your configuration entry point instead within Ant you need to
> > "spread along the classes" you protecting code from "evil" configuration
> > tries if you Ant-Task would be exposed to others (yes, I'm totally bias
> > on the Avalon approach :).
>
> No problem with the personal biases here ;-) I guess I'm more lazy
> having a background in loose languages like Lisp, Smalltalk, and
> Objective-C.
>
> I don't say Avalon's model is wrong, I'm just saying is different than
> Ant's bean/reflection approach. Both of them do the job equally well,
> and as I said earlier, what really matters is the performance at
> runtime, where none of these models are used.

Exactly.

> > > Personally I prefer the push model (the Ant way), as it's much easier
> > > to write and maintain over a longer period of time. The code that
> > > deals with the loading and instantiation of the right classes is
> > > centralized, thus you have to write it once and for all only in the
> > > engine.
> >
> > Loading and instantiation is also centralized in Avalon (into the CM)
> > but you have a much clearer contract to it via interfaces, thus I
> > prefer the IoC model much more.
>
> But you still need to do quite a bit of work in each class when
> initializing from a Configuration object.

The main difference I see is that Avalon let the component decide how
they want to cope with configuration data (Configuration/Parameter
objects) where as Ant strictly uses a bean (Setters) approach. Now we
can discuss for hours about the pros and cons of both approaches. My
point is that we should stick with one method only to be clearer from a
developers point of view.

> > > Obviously you can achieve exactly the same results with either
> > > model. What matters is the design of the final data structure. This is
> > > what will be used at execution time, not the intermediary data
> > > structures created when reading the config file or the sitemap.
> >
> > Avalon was made with security by design whereas the bean approch Ant
> > uses is not that strong in that point.
>
> I'm not sure why security is such a strong point here. Theoretically
> one can still call the configure() method passing a bad Configuration
> object. Can you explain what is the protection offered by the Avalon
> model compared to the bean model? It looks to me that since the
> objects live in the same data space, if I have a handle on them I can
> change their state any way I want.

Well, you said that code is spread along components to do their
configuration in Avalon and I said the bean approach in Ant will spreads
code to secure itself from evil configuration tries along its Tasks.

class foo Configurable {
  private Configuration config;
  public void configure (Configuration conf) {
    if (config != null) {
      throw Exception ("trying to reconfigure an already " +
                       "configured component");
    }
    config = conf;
  }
}

where as in Ant it will look like this:

class foo Task {
  private String a;
  private int b=-1;
  public void setA(String a) {
    if (a != null) {
      throw Exception ("trying to reconfigure an already " +
                       "configured component");
    }
    this.a = ....;
  }
  public void setB(int b) {
    if (b != -1) /*this test could be wrong anyway*/ {
      throw Exception ("trying to reconfigure an already " +
                       "configured component");
    }
    this.b = ....;
  }
}

You see my point to oppose your argument ;) ?

The bean approach (to be generic enough to get away from saying "in
Ant") might lead to weak security or clutter up a class wich have
security in mind concerning configurability. You'd like to say that a
single point of passing configuration will spread variable
initialisation/checking accross several classes. Yes, both arguments can
be seen to be true so everybody need to checkout what's best for his
project to use but I suggest you stick with one approach only.

Giacomo

>
> > > Other than the way the config file/sitemap are read, the final
> > > runtime data structure looks very nice. Even though its incomplete
> > > I can see where you're headed. So far I like the approach, so keep
> > > up the good work! I'm sure we'll have a very nice and fast sitemap
> > > implementation pretty soon.
> >
> > Well, I wasn't able to look at your code, Sylvain, thus I cannot make
> > any statements yet. But as I know your skill you've shown during your
> > time here at Cocoon I'm very confident that it is looking good :)
>
>
> Regards,
>


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


Mime
View raw message