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]