You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@lenya.apache.org by "J. Wolfgang Kaltz" <ka...@interactivesystems.info> on 2005/03/16 11:04:43 UTC

[1.4] understanding use case handling internals

Dear all,
in order to try to address the open issues discussed recently about the 
use case handling, I'm looking at the use case handling internals, and 
by the same token, at the Avalon component handling. (Avalon may be 
"dead" but for the time being, since it is the component framework 
Cocoon and Lenya are based upon, I suppose all devs must gain a good 
understanding of it).

I'm posting what I've understood so far in the hopes that
1/ someone can help me understand what goes on at steps 13 and 14 (see 
below) and correct any nonsense I may have written;
2/ it will help those not yet familiar with Lenya internals to gain a 
better understanding

On a "related infos" note, I see that there is also
http://wiki.apache.org/lenya/CreatePageWalkthrough and 
http://wiki.apache.org/lenya/GetPageWalkthrough
which also cover these issues partially.


So, any corrections / pointers to the following will be appreciated:

Tracing a call to the example use case "admin.addUser" (just the first 
call to activate it, not yet the execution) :

1. request URL admin/users.html with parameter lenya.usecase=admin.addUser
2. pattern ** is matched in sitemap.xmap (last matcher)
3. The "authorizer" action is called, so Lenya authorization happens:
    - first, a policy for admin/users.html is looked for, but none exists
    - then the access to the URL area "admin" is checked, according to 
admin/subtree-policy.acml
    - then the "usecase-policies.xml" is checked; this use case is not 
mentioned there, so authorization is true
4. Authorization was successful, so
4a. sub-sitemap "global-sitemap.xmap" is mounted
4b. pattern */admin/** is matched in global-sitemap.xmap:335 -> this 
mounts the sub-sitemap "lenya/admin.xmap" and thus a change of directory 
context to the subdirectory "lenya"
5. Avalon creates an instance of the custom sitemap matcher 
"UsecaseRegistrationMatcher", presumably because it is used in the 
"admin.xmap".
6. Cocoon calls the "match" method of the "UsecaseRegistrationMatcher" 
matcher. This method asks the Avalon ServiceManager for a service 
implementing "o.a.l.cms.usecase.UsecaseResolver". This triggers Avalon 
to create an instance of "UsecaseResolverImpl", because in 
org/apache/lenya/lenya.roles there is a role (in the Avalon sense) which 
associates this class as default class for the role "....UsecaseResolver").
7. The custom sitemap matcher "registered-usecase" returns true, for the 
pattern 'null' (the URL pattern  is actually not relevant here, only the 
value of the lenya.usecase parameter is relevant
8. Accordingly, the pipeline in admin.xmap mounts the sub-sitemap 
"usecases/usecase.xmap". This changes the web-context to the 
lenya/usecases subdirectory.
9. In the "usecases/usecase.xmap", the <map:match type="usecase" 
pattern="*"> is matched, because the parameter lenya.usecase is present 
(and obviously because the URL pattern matchers above in the sitemap 
where not matched). So, the Flowscript function "executeUsecase" is called.
10. Avalon resolves "usecases.js" because this is defined in the 
"usecases/usecase.xmap" sitemap
11. In "usecases.js", Cocoon is asked for a component implementing the 
role  "o.a.l.cms.usecase.UsecaseResolver", so Avalon creates an instance 
of "UsecaseResolverImpl", as described above. Then, usecases.js calls 
the resolve() method of the "UsecaseResolverImpl"
12. UsecaseResolverImpl.resolve(), whose goal it is to return a 
"Usecase", calls Avalon's ServiceSelector select() method with the name 
of the use case (in this case, "admin.addUser").
I think that Avalon matches this in cocoon.xconf's <usecases> section, 
where the following is defined:
   <component-instance class="org.apache.lenya.cms.ac.usecases.AddUser" 
logger="lenya.admin" name="admin.addUser"/>
So Avalon creates an instance of "o.a.l.cms.ac.usecases.AddUser".
13. Avalon creates an instance of "o.a.l.cms.usecase.UnitOfWorkImpl", 
but I am not sure why:
   - AddUser's doCheckExecutionConditions() method is not called yet at 
this time
   - something else must trigger the creation of a UnitOfWorkImpl. I see 
that UnitOfWorkImpl is the default class implementing the (Avalon) role 
"o.a.l.cms.usecase.UnitOfWork"
Furthermore, Avalon creates instances of 
"o.a.l.cms.publication.DocumentManagerImpl" and 
"o.a.l.cms.cocoon.flow.FlowHelperImpl", which are default classes for 
Avalon roles
(But why are they created now ?)
14. A redirect to 'cocoon:/view/admin/addUser' occurs (WHY ?)
15. The request is matched by the pattern 'view/**' in 
usecases/usecase.xmap:23
16. Flowscript 'addUser.jx' is retrieved
17. Request for 'cocoon://lenya-screen.xsl' -> this is matched in the 
main sitemap, sitemap.xmap:544 (pattern "lenya-screen.xsl"), so this 
triggers the usual page2xhtml.xsl


Again, thx for any comments
Wolfgang


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


Re: [1.4] understanding use case handling internals

Posted by "Gregor J. Rothfuss" <gr...@apache.org>.
J. Wolfgang Kaltz wrote:

> So maybe what we should do, is distinguish the sitemap handling for 
> usecases according to the area (as opposed to distinguishing according 
> to the name pattern) ? Can we delegate the non-generic steps to an 
> area-specific usecase.xmap sitemap (or a new pipeline in the already 
> existing area-specific sitemap), by using the {page-envelope:area} ?

this won't work. the site area has both menu usecases and tab usecases

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


Re: [1.4] understanding use case handling internals

Posted by Andreas Hartmann <an...@apache.org>.
J. Wolfgang Kaltz wrote:
> Andreas Hartmann schrieb:
> 
>> J. Wolfgang Kaltz wrote:
>> [snip stuff about what happens in the sitemaps when a use case is called]
>>
>> Yes, exactly. This approach differs from the site area, where the
>> usecases don't enter the info.xmap but use their own presentation
>> meachanism in usecase.xmap. I don't yet know which approach to prefer.
> 
> 
> IMO the usecases/usecase.xmap should be generic, i.e. not have specific 
> handling for site area. Also, the handling currently assumes that any 
> usecase whose name begins with "tab" is a site usecase, which obviously 
> is a risky assumption.
> 
> So maybe what we should do, is distinguish the sitemap handling for 
> usecases according to the area (as opposed to distinguishing according 
> to the name pattern) ? Can we delegate the non-generic steps to an 
> area-specific usecase.xmap sitemap (or a new pipeline in the already 
> existing area-specific sitemap), by using the {page-envelope:area} ?

Yes, I guess that should be possible. I agree that there shouldn't
be area-specific handling in usecase.xmap, but I also want to avoid
code duplication which would probably occur when we introduce multiple
usecase-handling sitemaps ...

Maybe you could try your approach and post your observations?

-- Andreas

> (I'm not sure what I'm suggesting makes sense as I don't fully 
> understand the internals yet - but the goal of this is to have a clear 
> handling of usecases in each area, specifically for allowing to 
> integrate the use case within the remaining GUI of the area)
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@lenya.apache.org
> For additional commands, e-mail: dev-help@lenya.apache.org


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


Re: [1.4] understanding use case handling internals

Posted by "J. Wolfgang Kaltz" <ka...@interactivesystems.info>.
Andreas Hartmann schrieb:
> J. Wolfgang Kaltz wrote:
> [snip stuff about what happens in the sitemaps when a use case is called]
> 
> Yes, exactly. This approach differs from the site area, where the
> usecases don't enter the info.xmap but use their own presentation
> meachanism in usecase.xmap. I don't yet know which approach to prefer.

IMO the usecases/usecase.xmap should be generic, i.e. not have specific 
handling for site area. Also, the handling currently assumes that any 
usecase whose name begins with "tab" is a site usecase, which obviously 
is a risky assumption.

So maybe what we should do, is distinguish the sitemap handling for 
usecases according to the area (as opposed to distinguishing according 
to the name pattern) ? Can we delegate the non-generic steps to an 
area-specific usecase.xmap sitemap (or a new pipeline in the already 
existing area-specific sitemap), by using the {page-envelope:area} ?

(I'm not sure what I'm suggesting makes sense as I don't fully 
understand the internals yet - but the goal of this is to have a clear 
handling of usecases in each area, specifically for allowing to 
integrate the use case within the remaining GUI of the area)


Re: [1.4] understanding use case handling internals

Posted by Andreas Hartmann <an...@apache.org>.
J. Wolfgang Kaltz wrote:

[...]

> I guess it is a design decision to say which accesses to business 
> objects should happen via the unit-of-work pattern, and which should 
> happen otherwise.
> So far, the unit-of-work is used when a new document is created, whereas 
> when something else happens (e.g. a document is moved, a user is created 
> etc.), the access is outside the unit-of-work pattern.

I hope as soon as someone is familiar with the purpose of the
UnitOfWork, things will be quite straightforward.


> This is fine by me, like I said it is a design decision. It's just that, 
> when looking at the interface, it's not clear that this is how it's 
> done. I will add some info to the Java docs, hope that's OK.

Sure, that would be fine.

-- Andreas


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


Re: [1.4] understanding use case handling internals

Posted by "J. Wolfgang Kaltz" <ka...@interactivesystems.info>.
Andreas Hartmann schrieb:
>> [...]
>> IIUC the AbstractOperation provides access to documents via the 
>> unit-of-work pattern, and AbstractUsecase (which is a subclass) also 
>> provides access to documents via DocumentManager.
> 
> 
> "Access to objects" (in terms of generating objects) is actually only
> provided by the DocumentIdentityMap's DocumentFactory. The DocumentManager
> is a service to manipulate documents.
> 
> So the responsibilities are quite separated:
> 
> UnitOfWork/IdentityMap:
>   - generate documents
>   - take care that only 1 instance of a document is created
> 
> DocumentManager
>   - manipulate documents (move, copy, add documents to publications, ...)
> 
> 
>> I'm wondering if this is somehow redundant, meaning potentially 2 
>> different ways to access the same document ?
> 
> 
> Would you mind providing a code example?
> 

Thx for the clarification, I understand now the 2 different purposes 
these accesses serve.

I guess it is a design decision to say which accesses to business 
objects should happen via the unit-of-work pattern, and which should 
happen otherwise.
So far, the unit-of-work is used when a new document is created, whereas 
when something else happens (e.g. a document is moved, a user is created 
etc.), the access is outside the unit-of-work pattern.

This is fine by me, like I said it is a design decision. It's just that, 
when looking at the interface, it's not clear that this is how it's 
done. I will add some info to the Java docs, hope that's OK.



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


Re: [1.4] understanding use case handling internals

Posted by Andreas Hartmann <an...@apache.org>.
J. Wolfgang Kaltz wrote:
> Andreas Hartmann schrieb:
> 
>> J. Wolfgang Kaltz wrote:
>>
>> [...]
>>
>>> - do I understand correctly that, in fact, UnitOfWork is used to 
>>> provide access to documents,
>>
>>
>>
>> Actually it is an implementation of the Unit Of Work Pattern
>> (http://www.martinfowler.com/eaaCatalog/unitOfWork.html).
>>
>> It will be extended so that not only documents can be stored in
>> the identity map. That was just a start.
> 
> 
> I understand - citing that page, the unit of work "maintains a list of 
> objects affected by a business transaction and coordinates the writing 
> out of changes and the resolution of concurrency problems."
> 
> But I wonder what UnitOfWork interface can/should be described that far 
> high up in the use case hierarchy? Right now, at the top level, it 
> provides access to documents; probably most use cases will need access 
> to documents so that may make sense. Admin use cases don't need access 
> to documents, but do access other objects, which might also require 
> coordination. So should a common admin use case implement the UnitOfWork 
> for those ? Or should they also be raised to the level of the 
> AbstractOperation ?
> 
> To summarize, I see 2 approaches to implement the unit of work pattern 
> in the use case hierarchy;
> 1/ have one unit of work implementation at the top-level of the 
> hierarchy, as is the case now -> this would mean providing access to all 
> objects affected by the use cases

I think I'd go for number (1). Actually I already started to generalize the
DocumentIdentityMap to an IdentityMap and introduced an interface
Transactionable (maybe another name is more appropriate) for objects
which can be stored in the IdentityMap.

We would need a mechanism to generate a unique key for objects
regardless of their class ... I don't know how to achieve this.
I'll read a little more about the pattern :)

> 2/ implement a unit of work pattern for each categorization of use 
> cases, whereas this categorization is made according to the types of 
> objects that need to be accessed -> don't know if this is practical

[...]

>>> Further, in AbstractUsecase, which is a subclass of the 
>>> AbstractOperation, there is a DocumentManager - does this serve a 
>>> completely different functionality or is some overlap with the 
>>> DocumentIdentityMap, due e.g. to historical reasons ?
>>
>>
>>
>> Hmmm, I don't understand what you mean ...
> 
> 
> IIUC the AbstractOperation provides access to documents via the 
> unit-of-work pattern, and AbstractUsecase (which is a subclass) also 
> provides access to documents via DocumentManager.

"Access to objects" (in terms of generating objects) is actually only
provided by the DocumentIdentityMap's DocumentFactory. The DocumentManager
is a service to manipulate documents.

So the responsibilities are quite separated:

UnitOfWork/IdentityMap:
   - generate documents
   - take care that only 1 instance of a document is created

DocumentManager
   - manipulate documents (move, copy, add documents to publications, ...)


> I'm wondering if this is somehow redundant, meaning potentially 2 
> different ways to access the same document ?

Would you mind providing a code example?


-- Andreas


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


Re: [1.4] understanding use case handling internals

Posted by "J. Wolfgang Kaltz" <ka...@interactivesystems.info>.
Andreas Hartmann schrieb:
> J. Wolfgang Kaltz wrote:
> 
> [...]
>> - do I understand correctly that, in fact, UnitOfWork is used to 
>> provide access to documents,
> 
> 
> Actually it is an implementation of the Unit Of Work Pattern
> (http://www.martinfowler.com/eaaCatalog/unitOfWork.html).
> 
> It will be extended so that not only documents can be stored in
> the identity map. That was just a start.

I understand - citing that page, the unit of work "maintains a list of 
objects affected by a business transaction and coordinates the writing 
out of changes and the resolution of concurrency problems."

But I wonder what UnitOfWork interface can/should be described that far 
high up in the use case hierarchy? Right now, at the top level, it 
provides access to documents; probably most use cases will need access 
to documents so that may make sense. Admin use cases don't need access 
to documents, but do access other objects, which might also require 
coordination. So should a common admin use case implement the UnitOfWork 
for those ? Or should they also be raised to the level of the 
AbstractOperation ?

To summarize, I see 2 approaches to implement the unit of work pattern 
in the use case hierarchy;
1/ have one unit of work implementation at the top-level of the 
hierarchy, as is the case now -> this would mean providing access to all 
objects affected by the use cases
2/ implement a unit of work pattern for each categorization of use 
cases, whereas this categorization is made according to the types of 
objects that need to be accessed -> don't know if this is practical

Or am I misunderstanding something ?


> 
> 
>> since all it does is provide access to DocumentIdentityMap ? If so the 
>> name is quite misleading - from the name I thought it was somehow a 
>> step within a usecase.
> 
> 
> I chose the name because it is suggested in the pattern.

Yes, I understand. It's just confusing for someone looking at it for the 
first time: when looking at non-document use cases, they have a unit of 
work which they don't use, whereas they access the list of objects that 
they do need in another manner.

> 
> 
>> Further, in AbstractUsecase, which is a subclass of the 
>> AbstractOperation, there is a DocumentManager - does this serve a 
>> completely different functionality or is some overlap with the 
>> DocumentIdentityMap, due e.g. to historical reasons ?
> 
> 
> Hmmm, I don't understand what you mean ...

IIUC the AbstractOperation provides access to documents via the 
unit-of-work pattern, and AbstractUsecase (which is a subclass) also 
provides access to documents via DocumentManager.
I'm wondering if this is somehow redundant, meaning potentially 2 
different ways to access the same document ?
(I admit I haven't yet been able to look at what exactly happens in the 
document accesses, so maybe what I'm saying here does not make much 
sense ;) )


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


Re: [1.4] understanding use case handling internals

Posted by Andreas Hartmann <an...@apache.org>.
J. Wolfgang Kaltz wrote:

[...]

> - I notice that AbstractOperation has a "UnitOfWork" for which an 
> instance is created in initialize()
> 
> - however this UnitOfWork instance is not used by the admin use cases
> The API says regarding UnitOfWorkImpl:
>     Abstract base class for operations on documents.
> But there seem to be no classes extending this class, so this doc is 
> probably misleading.

Yes, it is. I'll change it.


> - do I understand correctly that, in fact, UnitOfWork is used to provide 
> access to documents,

Actually it is an implementation of the Unit Of Work Pattern
(http://www.martinfowler.com/eaaCatalog/unitOfWork.html).

It will be extended so that not only documents can be stored in
the identity map. That was just a start.


> since all it does is provide access to 
> DocumentIdentityMap ? If so the name is quite misleading - from the name 
> I thought it was somehow a step within a usecase.

I chose the name because it is suggested in the pattern.


> Further, in 
> AbstractUsecase, which is a subclass of the AbstractOperation, there is 
> a DocumentManager - does this serve a completely different functionality 
> or is some overlap with the DocumentIdentityMap, due e.g. to historical 
> reasons ?

Hmmm, I don't understand what you mean ...


> - AbstractOperation could instantiate a UnitOfWork only upon access, but 
> this would require more changes because getUnitOfWork could throw an 
> exception, requiring a change in the Operation interface :(

try {
     this.unitOfWork = (UnitOfWork) this.manager.lookup(UnitOfWork.ROLE);
}
catch (ServiceException e) {
     throw new RuntimeException("Could not create unit of work: ", e);
}

This way, no changes are necessary.


-- Andreas



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


Re: [1.4] understanding use case handling internals

Posted by "J. Wolfgang Kaltz" <ka...@interactivesystems.info>.
Andreas Hartmann schrieb:
>>> (...)
>>> I guess this should be changed to lazy loading due to performance
>>> issues.
>>
>>
>>
>> Yes, especially since the admin use cases don't use the DocumentManager.
>> Is it OK then if I simply move the lookup to the getDocumentManager 
>> method and check that in ?
> 
> 
> Yes, that should be fine.
OK
Next issue among the same lines, with the goal of hopefully simplifying 
the process when a use case is triggered:

- I notice that AbstractOperation has a "UnitOfWork" for which an 
instance is created in initialize()

- however this UnitOfWork instance is not used by the admin use cases
The API says regarding UnitOfWorkImpl:
     Abstract base class for operations on documents.
But there seem to be no classes extending this class, so this doc is 
probably misleading.

- do I understand correctly that, in fact, UnitOfWork is used to provide 
access to documents, since all it does is provide access to 
DocumentIdentityMap ? If so the name is quite misleading - from the name 
I thought it was somehow a step within a usecase. Further, in 
AbstractUsecase, which is a subclass of the AbstractOperation, there is 
a DocumentManager - does this serve a completely different functionality 
or is some overlap with the DocumentIdentityMap, due e.g. to historical 
reasons ?

- AbstractOperation could instantiate a UnitOfWork only upon access, but 
this would require more changes because getUnitOfWork could throw an 
exception, requiring a change in the Operation interface :(

Thx for any clarification regarding these mechanisms and/or suggestions


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


Re: [1.4] understanding use case handling internals

Posted by Andreas Hartmann <an...@apache.org>.
J. Wolfgang Kaltz wrote:
> Thx Andreas for your comments, I'm reading all of them, but first 
> specifically:
> 
> 
> Andreas Hartmann schrieb:
>  >> [...]
> 
>>> Furthermore, Avalon creates instances of 
>>> "o.a.l.cms.publication.DocumentManagerImpl" and
>>
>>
>>
>> AbstractUsecase:
>>
>>     public final void initialize() throws Exception {
>>         super.initialize();
>>         this.documentManager = (DocumentManager) 
>> this.manager.lookup(DocumentManager.ROLE);
>>     }
>>
>> I guess this should be changed to lazy loading due to performance
>> issues.
> 
> 
> Yes, especially since the admin use cases don't use the DocumentManager.
> Is it OK then if I simply move the lookup to the getDocumentManager 
> method and check that in ?

Yes, that should be fine.

Thanks!
-- Andreas


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


Re: [1.4] understanding use case handling internals

Posted by "J. Wolfgang Kaltz" <ka...@interactivesystems.info>.
Thx Andreas for your comments, I'm reading all of them, but first 
specifically:


Andreas Hartmann schrieb:
 >> [...]
>> Furthermore, Avalon creates instances of 
>> "o.a.l.cms.publication.DocumentManagerImpl" and
> 
> 
> AbstractUsecase:
> 
>     public final void initialize() throws Exception {
>         super.initialize();
>         this.documentManager = (DocumentManager) 
> this.manager.lookup(DocumentManager.ROLE);
>     }
> 
> I guess this should be changed to lazy loading due to performance
> issues.

Yes, especially since the admin use cases don't use the DocumentManager.
Is it OK then if I simply move the lookup to the getDocumentManager 
method and check that in ?


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


Re: [1.4] understanding use case handling internals

Posted by Andreas Hartmann <an...@apache.org>.
J. Wolfgang Kaltz wrote:
> Dear all,
> in order to try to address the open issues discussed recently about the 
> use case handling, I'm looking at the use case handling internals, and 
> by the same token, at the Avalon component handling. (Avalon may be 
> "dead" but for the time being, since it is the component framework 
> Cocoon and Lenya are based upon, I suppose all devs must gain a good 
> understanding of it).
> 
> I'm posting what I've understood so far in the hopes that
> 1/ someone can help me understand what goes on at steps 13 and 14 (see 
> below) and correct any nonsense I may have written;
> 2/ it will help those not yet familiar with Lenya internals to gain a 
> better understanding
> 
> On a "related infos" note, I see that there is also
> http://wiki.apache.org/lenya/CreatePageWalkthrough and 
> http://wiki.apache.org/lenya/GetPageWalkthrough
> which also cover these issues partially.
> 
> 
> So, any corrections / pointers to the following will be appreciated:
> 
> Tracing a call to the example use case "admin.addUser" (just the first 
> call to activate it, not yet the execution) :
> 
> 1. request URL admin/users.html with parameter lenya.usecase=admin.addUser
> 2. pattern ** is matched in sitemap.xmap (last matcher)
> 3. The "authorizer" action is called, so Lenya authorization happens:
>    - first, a policy for admin/users.html is looked for, but none exists
>    - then the access to the URL area "admin" is checked, according to 
> admin/subtree-policy.acml
>    - then the "usecase-policies.xml" is checked; this use case is not 
> mentioned there, so authorization is true
> 4. Authorization was successful, so
> 4a. sub-sitemap "global-sitemap.xmap" is mounted
> 4b. pattern */admin/** is matched in global-sitemap.xmap:335 -> this 
> mounts the sub-sitemap "lenya/admin.xmap" and thus a change of directory 
> context to the subdirectory "lenya"
> 5. Avalon creates an instance of the custom sitemap matcher 
> "UsecaseRegistrationMatcher", presumably because it is used in the 
> "admin.xmap".

Yes, exactly. This approach differs from the site area, where the
usecases don't enter the info.xmap but use their own presentation
meachanism in usecase.xmap. I don't yet know which approach to prefer.


> 6. Cocoon calls the "match" method of the "UsecaseRegistrationMatcher" 
> matcher. This method asks the Avalon ServiceManager for a service 
> implementing "o.a.l.cms.usecase.UsecaseResolver". This triggers Avalon 
> to create an instance of "UsecaseResolverImpl", because in 
> org/apache/lenya/lenya.roles there is a role (in the Avalon sense) which 
> associates this class as default class for the role "....UsecaseResolver").
> 7. The custom sitemap matcher "registered-usecase" returns true, for the 
> pattern 'null' (the URL pattern  is actually not relevant here, only the 
> value of the lenya.usecase parameter is relevant
> 8. Accordingly, the pipeline in admin.xmap mounts the sub-sitemap 
> "usecases/usecase.xmap". This changes the web-context to the 
> lenya/usecases subdirectory.
> 9. In the "usecases/usecase.xmap", the <map:match type="usecase" 
> pattern="*"> is matched, because the parameter lenya.usecase is present 
> (and obviously because the URL pattern matchers above in the sitemap 
> where not matched). So, the Flowscript function "executeUsecase" is called.
> 10. Avalon resolves "usecases.js" because this is defined in the 
> "usecases/usecase.xmap" sitemap
> 11. In "usecases.js", Cocoon is asked for a component implementing the 
> role  "o.a.l.cms.usecase.UsecaseResolver", so Avalon creates an instance 
> of "UsecaseResolverImpl", as described above. Then, usecases.js calls 
> the resolve() method of the "UsecaseResolverImpl"
> 12. UsecaseResolverImpl.resolve(), whose goal it is to return a 
> "Usecase", calls Avalon's ServiceSelector select() method with the name 
> of the use case (in this case, "admin.addUser").
> I think that Avalon matches this in cocoon.xconf's <usecases> section, 
> where the following is defined:
>   <component-instance class="org.apache.lenya.cms.ac.usecases.AddUser" 
> logger="lenya.admin" name="admin.addUser"/>
> So Avalon creates an instance of "o.a.l.cms.ac.usecases.AddUser".

Yes, exactly. The available services are already determined on startup.
The instanciation depends on the interfaces your Usecase handler class
implements:

   Startable:   The service is already started on Cocoon startup.

   ThreadSafe:  The service is instanciated only once, one object is
                shared by all clients. This means it must be thread safe.

   Poolable:    You have a pool of objects. This reduces instanciation
                time (if a component is available in the pool), but
                requires memory.

   Recyclable:  I'm not quite sure, but IIRC this means that the component
                is not destroyed but only recycled when it is released.
                This also reduces instanciation time.

You find more info about these interfaces in the Avalon docs.


> 13. Avalon creates an instance of "o.a.l.cms.usecase.UnitOfWorkImpl", 
> but I am not sure why:

This happens in AbstractOperation.initialize(). This method is called
when a component is initialized which implements the Initializable
interface.

AbstractUsecase extends AbstractOperation.


>   - AddUser's doCheckExecutionConditions() method is not called yet at 
> this time
>   - something else must trigger the creation of a UnitOfWorkImpl. I see 
> that UnitOfWorkImpl is the default class implementing the (Avalon) role 
> "o.a.l.cms.usecase.UnitOfWork"
> Furthermore, Avalon creates instances of 
> "o.a.l.cms.publication.DocumentManagerImpl" and

AbstractUsecase:

     public final void initialize() throws Exception {
         super.initialize();
         this.documentManager = (DocumentManager) 
this.manager.lookup(DocumentManager.ROLE);
     }

I guess this should be changed to lazy loading due to performance
issues.

> "o.a.l.cms.cocoon.flow.FlowHelperImpl", which are default classes for 
> Avalon roles
> (But why are they created now ?)

This is done in usecases.js:

	var flowHelper = 
cocoon.getComponent("org.apache.lenya.cms.cocoon.flow.FlowHelper");


> 14. A redirect to 'cocoon:/view/admin/addUser' occurs (WHY ?)

usecases.js:

		var view = selectView(usecaseName);
                 ...
			cocoon.sendPageAndWait(view, {
			    "usecase" : usecase
			});



> 15. The request is matched by the pattern 'view/**' in 
> usecases/usecase.xmap:23
> 16. Flowscript 'addUser.jx' is retrieved
> 17. Request for 'cocoon://lenya-screen.xsl' -> this is matched in the 
> main sitemap, sitemap.xmap:544 (pattern "lenya-screen.xsl"), so this 
> triggers the usual page2xhtml.xsl

Thanks for your explaination! I'm sure it will help others to
make familiar with the usecase framework. Maybe you'd like to add
it (or parts of it) to the documentation?

-- Andreas


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


Re: [1.4] understanding use case handling internals

Posted by Andreas Hartmann <an...@apache.org>.
J. Wolfgang Kaltz wrote:

[...]

> 16. Flowscript 'addUser.jx' is retrieved

A small note: addUser.jx is not a flowscript but a JX template.
Please excuse my nitpicking if this was just a typo.

-- Andreas


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