On Wed, Oct 02, 2002 at 12:04:23PM +0200, Christian Haul wrote:
...
> > > I think with this interface, we can still have input module 
> > > chaining. It would just be attributes that get 'chained', not 
> > > whole objects. So we could have:
> > > 
> > > <component-instance class="...RequestModule" name="request-attr"/>
> > >   <input-module name="session-attr"/>
> > > </component-instance>
> > > <component-instance class="...SessionModule" name="session-attr">
> > >   <input-module name="xmlconfig"/>
> > > </component-instance>
> > > <component-instance class="...XMLModule" name="xmlconfig">
> > >   <config>context:///forrestconf.xml</config>
> > >   <attribute-map from="*" to="/forrestconf/*"/>
> > >   <input-module name="defaults"/>
> > > </component-instance>
> > > <component-instance class="...DefaultsMetaModule" name="defaults">
>       <!-- how about this: -->
>       <input type="request-attr" priority="2"/>
>       <input type="session-attr" priority="1"/>
>       <input type="xmlconfig" priority="0"/>
> > >   <values>
> > >     <skin>default-skin</skin>
> > >   </values>
> > > </component-instance>

I think I see what the confusion is.

You're proposing simple Composition of modules:

 <component-instance class="...DefaultsMetaModule" name="defaults">
      <input type="request-attr" priority="2"/>
      <input type="session-attr" priority="1"/>
      ...
 </component-instance>

In this model (the current one), certain modules are designated 'meta'
modules, and act on others.


An alternative is 'chaining' of modules, similar to Unix pipelines:

<component-instance name="A">
   <input-module name="B"/>
</component-instance>
<component-instance name="B">
   <input-module name="C"/>
</component-instance>
<component-instance name="C"/>

In this model, every module is potentially a 'meta' module, as it can
take as input any other module. Think of 'input-module' as 'stdin'.

The other big difference in this model is that the order is reversed.
DefaultsMetaModule is at the end of the chain. It's very simple,
basically a hashtable. It can contain defaults for multiple other
modules:

<component-instance name="A">
  <input-module name="defaults"/>
</component-instance>
<component-instance name="B">
  <input-module name="defaults"/>
</component-instance>
<component-instance class="...DefaultsModule" name="defaults">
  <values>
    ...
  </values>
</component-instance>


> The idea of meta modules was to provide functions that may apply to
> different sources. Like read a string and convert it to a
> java.util.Date or access a java.util.Map entry (easily replacable with
> the jxpath support in attributes)

That's easy to do. Imagine a module that converts milliseconds since 1970
to formatted date strings:

<component-instance class="...TimeModule" name="time"/> 
<component-instance class="...DateFormatterModule" name="date">
  <input-module name="time"/>
</component-instance>

So {time:now} would give you 1033557024000, and {date:now} gives you
'Wed, 02 Oct 2002 21:11:24". Alternatively, you could feed random numbers
into DateFormatter to get random dates.

I can give lots more examples if you like. I think this chaining could be
really powerful :) We keep the current attribute-centric API, and gain
all the advantages of "meta" modules.

As for inheritance, that's just a handy technique for implementing
chaining. We'd have:

    AbstractInputModule
            |
 AbstractChainedInputModule   (handles 'input-module' and name mapping)
            /\
          /    \
        /        \
DateFormatter  AbstractJXPathModule
                      |
                      \_ RequestModule
                      \_ SessionModule
                      \_ XMLModule


> This is the same discussion as with the jxpath. Should it be inherited
> or composed. Since I belive this should be configurable by the user
> (no reason not to have a number of different configurations for a
> site!) I would vote for composition.
>
> In addition I believe that it stays simpler to write custom
> modules. Which should be a design goal.

Absolutely. I think that with chained modules, we can push almost all the
complexity into a superclass, and new modules will be really simple to
write. For example, the number-to-date Module above should be a few
lines.

> +1 for attribute mapping ("map-attribute" confuses because of "map:attribute"?)

Oh yes.. mapping is a little extension to the chaining model. Say A's
names are all simple: 'foo', 'bar'. And B's names are all XPath, so
they're '/skinconf/foo', /skinconf/bar'. Then the mapping rule
translates from A's naming system into B's

<component-instance name="B">
  <attribute-mapping from="*" to="/skinconf/*"/>
  <input-module name="A"/>
</component-instance>

Ehm.. more code, less talk :)

--Jeff

>       Chris.
> -- 
> C h r i s t i a n       H a u l
> [EMAIL PROTECTED]
>     fingerprint: 99B0 1D9D 7919 644A 4837  7D73 FEF9 6856 335A 9E08
> 

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, email: [EMAIL PROTECTED]

Reply via email to