Hello Marco!
This is my pass#2 over your mail, wish me luck :)
GMF> Futhermore, my specialContainer(WMSContainer) is a component of his
GMF> parentContainer
GMF> (implements Component... and NestedContainer as well).
GMF> At first I run into an endless-loop, because I extend specialContainer
GMF> by DefaultContainer, so the Component-Interface called initialize() and this
GMF> method
GMF> itself built the container and called once more initialize() (because of
GMF> extending
GMF> DefaultContainer :-( )
As I understood what you did was make a container be it's own
component. Yes, this yields an endless loop and your second
pass was much better.
GMF> Therefore, my specialContainerComponent does not extend DefaultContainer,
GMF> but uses one
GMF> with config.setContainerClass(). This method give you also the opportunity
GMF> to
GMF> use your own implementation of a container (maybe with disabled proxies).
GMF> The roleFile of the rootContainer : (at the moment only one childContainer)
GMF> <fortress-roles>
GMF> </fortress-roles>
Here's a snippet from URLSourceFactory (part of avalon-excalibur)
/**
* ... regular JavaDoc ...
*
* @avalon.component
* @avalon.service type=SourceFactory
* @x-avalon.info name=url-source
* @x-avalon.lifestyle type=singleton
*/
public class URLSourceFactory extends AbstractLogEnabled implements SourceFactory ..
Putting in these tags and running fortress collect-meta ant task makes
using the roles file unnecessary.
GMF> the configFile :
GMF> <configuration>
GMF> <wmsContainer id="wmsContainer" logger="components.WMSContainer"
activation="inline">>
GMF> <parameter name="max" value="2" />
GMF> </wmsContainer>
GMF> </configuration>
GMF> (RootContainer is a DefaultContainer... initialized absolutly normal...)
GMF> WMSContainerImpl implements WMSContainer, NestedContainer {
The hierarchy looks one level too deep for me..
In my prev mail I described the NestedContainer interface
public interface NestedContainer
{
String ROLE = NestedContainer.class.getName();
public ServiceManager getServiceManagerInstance() throws ...;
}
How come you had two interfaces: WMSContainer and NestedContainer?
It would look more natural if WMSContainerImpl was derived from
the DefaultContainer and implemented only NestedContainer, like
public class WMSContainerImpl extends DefaultContainer
implements NestedContainer
GMF> ...
GMF> service(ServiceManager man) {
GMF> upperSerMan = man;
GMF> }
GMF> initialize() {
GMF> FortessConfig config = new FortressConfig();
GMF> ...
GMF> config.buildOwnRoles();
GMF> config.buildOwnConfig();
GMF> (config.buildOwnLogger();
Hmm.. FortressConfig does not seem to have this methods..
GMF> ...
GMF> config.setServiceManager(upperSerMan);
GMF> config.setContainerConfiguration(sysConfig);
GMF> config.setLoggerManagerConfiguration(loggerConfig);
GMF> config.setRoleManagerConfiguration(roleConfig);
GMF> config.setContainerClass(NoProxyContainerImpl.class);
GMF> ...
GMF> }
GMF> ...
GMF> }
GMF> While running initialize() the service()-method has already been called by
GMF> parentContainer and so I can set reference of the parentServiceManager.
GMF> That?s all you need to lookup components from a parentContainer.
GMF> Notice, everything is down by the framework and it?s lifecycle.
Well, now the recipe :-)
If all you need is to separate configuration into several files
I would propose a different approach:
create your own ConfigurationBuilder. Derive it from the
DefaultConfiguration builder, but after it builds
a configuration make it walk all the created configuration
though and when it finds a node with no children of some
specific form or name, like
<include:include>path-to-file</include:include>
read the file and merge the two configurations together.
(There may be difficulties with r/o configurations, but
this is just to give you the general idea).
Or find some other way to make a composition of xml
configurations.
The idea is that by the moment DefaultContainer
sees the Configuration it has already been composed
of several xml files.
If you like the code you write for this, please submit
it back to Avalon and it will probably go into the
avalon-excalibur/configuration package.
If you do need to have several Fortress containers
in the hierarchy to _partition_ the component space
and _restrict_ the ability of components in one
container to access components in the another
(the opposite of what
NestedContainer.getServiceManagerInstance() does)
then I would suggest doing the following
/**
* A complete copy of Fortress DefaultContainer,
* but it has meta-data attached.
*
* @avalon.component
* @x-avalon.info name=default-container
* @x-avalon.lifestyle type=singleton
*/
public class MyDefaultContainer extends DefaultContainer
{
}
and have a configuration of the form
<config>
<componentA ../>
<componentB ../>
<default-container id='nested'>
<componentC ../>
<componentD ../>
</ ..>
</config>
of course, this configuration may be pre-merged as
relined above.
However
1) I'm not sure if it will be okay to have no
* @avalon.service type=...
meta-tag, but
a) if this is needed it will be fixed in the future
b) you can always create some "Dummy" role like
public interface Dummy
{
String ROLE = Dummy.class.getName();
}
and use it like
* @avalon.service type=your.package.Dummy
2) The 'nested' container you have just created will be useful iff
it has some child components that
* have
@x-avalon.lifestyle type=singleton
* are configured with
startup="inline"
* their startup has some (side-)effects valuable
on their own, like creating a new thread
that does something useful
3) I imagine that nested containers will be really useful in
the scenario that I called a.2, here it is more verbosely
relined.
public interface UsefullRoleA
{
String ROLE = ..
boolean usefulActionA()
}
/**
* @avalon.component
* @avalon.service type=your.package.UsefullRoleA
* @x-avalon.info name=xxx
* @x-avalon.lifestyle type=singleton
*/
public class XXX extends DefaultContainer implements UsefulRoleA
{
boolean usefulActionA()
{
// grab objects from our own service manager like
A a = (A) super.getServiceManager().lookup( A.Role );
// invoke some methods on those objects
boolean ret = a.doSmth();
return ret;
}
}
then you would have a config like
<config>
<componentA id='A' ../>
<componentB id='B' ../>
<xxx id='xxx'>
<componentC id='C' ../>
<componentD id='D' ../>
</xxx>
</config>
then your xxx component (a container and a component at the same
time)
will have access to all of the A,B,C,D compoents
while A and B will have access only to A, B and xxx.
components C and D will be internal to xxx and serve
its own internal needs only, namely will help it
to implement its own role UsefulRoleA.
Note that in all cases I never create a second ContainerManager.
In fact we need only one ContainerManager.
We need only for the topmost container.
The nested container is managed by it's parent container and
thus it needs no ContainerManager.
Plz ask questions if you have
-Anton
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]