Re: Discussion of Flow Issues
Christopher Oliver wrote: Stefano Mazzocchi wrote: Christopher Oliver wrote: http://cvs.apache.org/viewcvs.cgi/*checkout*/cocoon-2.1/src/java/org/apache/cocoon/components/flow/javascript/xmlForm.js?rev=1.3content-type=text/plain In order to communicate with XMLFormTransformer and to handle restarting continuations, this script needs access to: cocoon.session cocoon.componentManager cocoon.environment.objectModel cocoon.forwardTo() Why do you need direct access to the objectModel? Only because of the design of XMLForm: it stores the form view in the object model and several of the methods of org.apache.cocoon.component.xmlform.Form require the object model as a parameter. Ah, ok. Regardless of the flow, there doesn't appear to be lot of consistency in the way Cocoon components communicate: sometimes they stash stuff in request parameters, sometimes in the session, sometimes in the object model. In any case there seems to be no explicit contract, I'm all in favor of discussing the introduction of such explicit contract and make the system coherent. Do you have something in mind? Stefano.
Re: Discussion of Flow Issues
Stefano Mazzocchi wrote: Christopher Oliver wrote: snip/ Only because of the design of XMLForm: it stores the form view in the object model and several of the methods of org.apache.cocoon.component.xmlform.Form require the object model as a parameter. Ah, ok. Regardless of the flow, there doesn't appear to be lot of consistency in the way Cocoon components communicate: sometimes they stash stuff in request parameters, sometimes in the session, sometimes in the object model. In any case there seems to be no explicit contract, I'm all in favor of discussing the introduction of such explicit contract and make the system coherent. Do you have something in mind? We have to define the various scopes of each of these elements : - context attributes : global to the application (i.e. to all users) - session attributes : per-user values, common to all requests for a user. - request attributes : per-request values, common to all internal requests (i.e. cocoon:) used to handle an external request - object model : nearly per-request values, nearly meaning for the current request (be it internal or external) and all descendant internal requests. That being said, I don't know if XMLForm should use request or object model... Sylvain -- Sylvain Wallez Anyware Technologies http://www.apache.org/~sylvain http://www.anyware-tech.com { XML, Java, Cocoon, OpenSource }*{ Training, Consulting, Projects }
Re: Discussion of Flow Issues
Stefano Mazzocchi wrote: Vadim Gritsenko wrote: It's already not easy to separate! I can think of how to resolve issue 1 (dedicated FlowObjectModelHelper: ugly, but works) yuck! So, what do we do? Carsten, may I have your blessing for adding helper methods to ObjectModelHelper? I can even make interface out of WebContinuation instead of concrete class! Pretty please? :) Vadim
Re: Discussion of Flow Issues
Hi All! Jumping into this thread a bit late... On Tue, Mar 18, 2003 at 10:31:03AM -0800, Christopher Oliver wrote: You're not abusing sessions. cocoon.createSession() exists exactly for the purpose you mention. Nobody is suggesting that we remove it. What at least I was suggesting, is that because of this (that you can store session state in global JS variables) direct access to the underlying Session should not be needed by the average user of the flow. I see your point mate. The automatic handling of global variables in flow was one of the big attractions for me to use flow. One thing I'd like to discuss a little bit more is the relationship between individual flow interpreter instances and sub/sitemaps. Currently, there's one flow interpreter instance created per sitemap. So, when operating within the one sitemap everything is fine - however it has some implications for larger applications that use subsitemaps, etc. The following: map:flow language=JavaScript map:script src=context://WEB-INF/flow.js/ /map:flow defines some javascript methods that are encapsulated within that sitemap. It would be good if we had a nice way to promote the reuse of any javascript methods that could be reused in a sub/sitemap (I suppose subsitemaps could just include a common script, but perhaps there's a more attractive way). Another area is scope. Global variables managed by cocoon.createSession() are currently only available in the sitemap they're defined in, essentially making them local to that sitemap. ie. if flow.js defines: var currentUser = null; function login() { // assuming valid user // create a session and store user object cocoon.createSession(); currentUser = new User(username); // continue processing and send page } the currentUser reference is only available in the sitemap the flow.js was defined in. This means, subsitemaps have no reference to it in any way - something I would like to find a solution for if possible. I think this was one area where Ugo (and I) were using manual session manipulation to store cross sitemap data. Ovidiu and I once talked about the ability to inherit flow data/methods in subsitemaps, perhaps that's worth investigating a bit more ? Solving these implications would allow us to use flow to control an application at a higher level than just in one sitemap. What do you think ? Cheers, Marcus -- . ,,$, Marcus Crafter ;$' ':Computer Systems Engineer $: : ManageSoft GmbH $ o_)$$$: 82-84 Mainzer Landstrasse ;$,_/\ :' 60327 Frankfurt Germany ' /( \_' . :
Re: Discussion of Flow Issues
On 14/03/2003 19:18 Christopher Oliver wrote: Here's a summary of some of the recent issues with the Flow for discussion: Completely unrelated to the technical discussion which is way above my head, I found a nice weblog discussing graphical depictions of flow - with a well-known and not too easy example: http://www.boxesandarrows.com/archives/yahoo_mail_simplicity_holds_up_over_time.php If we ever need inspiration for that Flow editor in Cocoon 11.0 ... ;-) /Steven -- Steven Noelshttp://outerthought.org/ Outerthought - Open Source, Java XML Competence Support Center Read my weblog athttp://blogs.cocoondev.org/stevenn/ stevenn at outerthought.orgstevenn at apache.org
Re: Discussion of Flow Issues
On 19/03/2003 23:42 Steven Noels wrote: Completely unrelated to the technical discussion which is way above my head, I found a nice weblog discussing graphical depictions of flow - with a well-known and not too easy example: Some further linking: http://www.jjg.net/ia/visvocab/ /Steven -- Steven Noelshttp://outerthought.org/ Outerthought - Open Source, Java XML Competence Support Center Read my weblog athttp://blogs.cocoondev.org/stevenn/ stevenn at outerthought.orgstevenn at apache.org
Re: Discussion of Flow Issues
Hi Marcus, Those are very good questions. And I don't know the answer. See my response to Vadim about scopes and compiling scripts. We need to partition the scripts by application somehow. What defines an application in Cocoon. For example, does each get a separate class loader? Is there a relationship to sitemaps? Regards, Chris Marcus Crafter wrote: Hi All! One thing I'd like to discuss a little bit more is the relationship between individual flow interpreter instances and sub/sitemaps. Currently, there's one flow interpreter instance created per sitemap. So, when operating within the one sitemap everything is fine - however it has some implications for larger applications that use subsitemaps, etc. The following: map:flow language=JavaScript map:script src=context://WEB-INF/flow.js/ /map:flow defines some javascript methods that are encapsulated within that sitemap. It would be good if we had a nice way to promote the reuse of any javascript methods that could be reused in a sub/sitemap (I suppose subsitemaps could just include a common script, but perhaps there's a more attractive way). Another area is scope. Global variables managed by cocoon.createSession() are currently only available in the sitemap they're defined in, essentially making them local to that sitemap. ie. if flow.js defines: var currentUser = null; function login() { // assuming valid user // create a session and store user object cocoon.createSession(); currentUser = new User(username); // continue processing and send page } the currentUser reference is only available in the sitemap the flow.js was defined in. This means, subsitemaps have no reference to it in any way - something I would like to find a solution for if possible. I think this was one area where Ugo (and I) were using manual session manipulation to store cross sitemap data. Ovidiu and I once talked about the ability to inherit flow data/methods in subsitemaps, perhaps that's worth investigating a bit more ? Solving these implications would allow us to use flow to control an application at a higher level than just in one sitemap. What do you think ? Cheers, Marcus
RE: Discussion of Flow Issues
Vadim Gritsenko wrote: Stefano Mazzocchi wrote: Vadim Gritsenko wrote: It's already not easy to separate! I can think of how to resolve issue 1 (dedicated FlowObjectModelHelper: ugly, but works) yuck! So, what do we do? Carsten, may I have your blessing for adding helper methods to ObjectModelHelper? I can even make interface out of WebContinuation instead of concrete class! Ok, first I will not prevent you from doing so. It's ok to add the objects to the object model. But I still don't like adding helper methods to the ObjectModelHelper as this makes separating flow into a module/block near impossible or it will be an incompatible change. So I prefer making an own helper class for flow. *If* we later on come to the conclusion that it would be better (and working) to have the helpers in the ObjectModelHelper then we can move them without any pain. But again, if I'm the only one being against adding it to the ObjectModelHelper, well...do whatever you want, but be warned that I will put this on the table when we separate the flow stuff ;) Carsten
Re: Discussion of Flow Issues
Sylvain Wallez wrote: Stefano Mazzocchi wrote: 1) do we really need the session object? the flow is in fact deprecating the use of sessions for storing stateful data. I would love to *force* people to think into this way by not making the session available to them. We can always add it later if users really push us for it. +1. Moreover, the inadequate use of sessions to store data my completely break what the flow is giving us through continuations. I'm using the flow and I'm using sessions too. The applications I'm currently developing with the flow are composed of many independent flows, each with its own entry point. Consider the case of an e-commerce site. These entry points might be: - search for an item - add item to cart - show cart - delete item from cart - proceed to checkout I don't think I can combine all of these (and many more) in as single flow, held toghether with continuations. But I still have the need to have a user session spanning those operations, and I do this with per-session global variables in the flow. As you might know, global variables in a flowscript are associated with a session when you call cocoon.createSession(). In the above example, the cart, or the user's profile, would be associated with the session. I am somehow aware that I am abusing sessions here, and that there is a better way, but it's not that easy to follow, probably. If you can show it to me, I'd be glad to abandon sessions, but if you take them away right now, I'm going to be in trouble ;-). Ugo -- Ugo Cei - Consorzio di Bioingegneria e Informatica Medica P.le Volontari del Sangue, 2 - 27100 Pavia - Italy Phone: +39.0382.525100 - E-mail: [EMAIL PROTECTED]
Re: Discussion of Flow Issues
Vadim Gritsenko wrote: Sylvain Wallez wrote: I don't think this will make it difficult to separate it : the object model is a Map which can hold any kind of objects, and instrospection-based accessors such as JXPath don't care about the actual class of objects. 1) Helper functions like getContinuation() in ObjectModelHelper are not separatable; correct. 2) FlowVelocityGenerator, it has some clever hack on 130 lines or so specifically for the flow bean (see Hack? I use JXPath to determine the properties of the bean object); right, this has to go. 3) jpath logicsheet right now instead of being generic is hardwired to the flow too; right. It's already not easy to separate! I can think of how to resolve issue 1 (dedicated FlowObjectModelHelper: ugly, but works) yuck! and 3 (flow logicsheet for flow related stuff; jxpath logicsheet for generic stuff), not sure about 2 though. Extra Velocity generator is not nice. No, it's not. I'm starting to think that 'flow' is an 'aspect' of our Environment, so we would need some aspect orientation to take it out :( We should really post-pone this after 2.1 -0: Put session there, don't advertise it. Presence of the session object might facilitate migration from one approach to another, also will allow integration between different parts. This is a good point. What do others think? Stefano.
Re: Discussion of Flow Issues
Ugo Cei wrote: Sylvain Wallez wrote: Stefano Mazzocchi wrote: 1) do we really need the session object? the flow is in fact deprecating the use of sessions for storing stateful data. I would love to *force* people to think into this way by not making the session available to them. We can always add it later if users really push us for it. +1. Moreover, the inadequate use of sessions to store data my completely break what the flow is giving us through continuations. I'm using the flow and I'm using sessions too. The applications I'm currently developing with the flow are composed of many independent flows, each with its own entry point. Consider the case of an e-commerce site. These entry points might be: - search for an item - add item to cart - show cart - delete item from cart - proceed to checkout I don't think I can combine all of these (and many more) in as single flow, held toghether with continuations. But I still have the need to have a user session spanning those operations, and I do this with per-session global variables in the flow. As you might know, global variables in a flowscript are associated with a session when you call cocoon.createSession(). In the above example, the cart, or the user's profile, would be associated with the session. I am somehow aware that I am abusing sessions here, and that there is a better way, but it's not that easy to follow, probably. If you can show it to me, I'd be glad to abandon sessions, but if you take them away right now, I'm going to be in trouble ;-). Great, integration between different not-all-flowable parts is a *real* need for sessions in the FOM. So +1 to add it. Anybody against it? Stefano.
Re: Discussion of Flow Issues
I am somehow aware that I am abusing sessions here, and that there is a better way, but it's not that easy to follow, probably. If you can show it to me, I'd be glad to abandon sessions, but if you take them away right now, I'm going to be in trouble ;-). Great, integration between different not-all-flowable parts is a *real* need for sessions in the FOM. So +1 to add it. Anybody against it? I haven't had anything to say in this discussion so far, but somehow this deserves a comment... It would seem a shame to me to include sessions purely for 'inter-flow' communication. Given the thorough way you are all thinking about this, it seems a bit of a cop-out solution to just add sessions back in. Surely what Ugo needs is the ability to 'modularise' a single flow, in a way that makes it managable? Then you've got one flow (which is all I would say a single application should have, because there's just one interaction with a user), which removes the necessity for sessions (which would be very good), but still allows Ugo to manage a number of different routes through that flow, in an easily managable way. I've no idea how achievable that would be, as I've never played with flow myself, but just adding sessions back in seems like a major opportunity missed. Regards, Upayavira
Re: Discussion of Flow Issues
Ugo Cei wrote: Sylvain Wallez wrote: Stefano Mazzocchi wrote: 1) do we really need the session object? the flow is in fact deprecating the use of sessions for storing stateful data. I would love to *force* people to think into this way by not making the session available to them. We can always add it later if users really push us for it. +1. Moreover, the inadequate use of sessions to store data my completely break what the flow is giving us through continuations. I'm using the flow and I'm using sessions too. The applications I'm currently developing with the flow are composed of many independent flows, each with its own entry point. Consider the case of an e-commerce site. These entry points might be: - search for an item - add item to cart - show cart - delete item from cart - proceed to checkout I don't think I can combine all of these (and many more) in as single flow, held toghether with continuations. But I still have the need to have a user session spanning those operations, and I do this with per-session global variables in the flow. As you might know, global variables in a flowscript are associated with a session when you call cocoon.createSession(). In the above example, the cart, or the user's profile, would be associated with the session. This is something that I don't fully understand : when you call cocoon.createSession(), global variables of the various scripts of a given sitemap are shared through the session. This means, AFAIU, that each user has then its own independent set of global variables. Is this right ? But to what are these global variables attached when cocoon.createSession() hasn't been called ? Moreover, shouldn't this createSession() method be named setSessionScope() or something like that, since it does actually more than simply creating the session ? I am somehow aware that I am abusing sessions here, and that there is a better way, but it's not that easy to follow, probably. If you can show it to me, I'd be glad to abandon sessions, but if you take them away right now, I'm going to be in trouble ;-). Session are always available through the good old request.getSession(). But I'd like to avoid the session to be created implicitly by the flow engine since not every application needs it. Sylvain -- Sylvain Wallez Anyware Technologies http://www.apache.org/~sylvain http://www.anyware-tech.com { XML, Java, Cocoon, OpenSource }*{ Training, Consulting, Projects }
Re: Discussion of Flow Issues
Sylvain Wallez wrote: Ugo Cei wrote: This is something that I don't fully understand : when you call cocoon.createSession(), global variables of the various scripts of a given sitemap are shared through the session. This means, AFAIU, that each user has then its own independent set of global variables. Is this right ? Yes, AFAIU. But to what are these global variables attached when cocoon.createSession() hasn't been called ? I suppose they are relevant only for the current request, thus a new set is created with each request. Session are always available through the good old request.getSession(). But I'd like to avoid the session to be created implicitly by the flow engine since not every application needs it. Sylvain Uhm yes, I could always create a session via the request and call session.setAttribute()/getAttribute() on it. I could avoid global variables and attach objects that I want to persist across requests to that session. This means that instead of doing: var user; function login(username) { user = UserManager.getUser(username); cocoon.createSession(); } function chpasswd(newpasswd) { user.password = newpasswd; user.store(); } I'd have to write: function login(username) { var user = UserManager.getUser(username); var session = request.getSession(true); session.setAttribute(user, user); } function chpasswd(newpasswd) { var user = session.getAttribute(user); user.password = newpasswd; user.store(); } I don't know about you, but I prefer the former. Ugo -- Ugo Cei - Consorzio di Bioingegneria e Informatica Medica P.le Volontari del Sangue, 2 - 27100 Pavia - Italy Phone: +39.0382.525100 - E-mail: [EMAIL PROTECTED]
RE: Discussion of Flow Issues
Stefano Mazzocchi [EMAIL PROTECTED] wrote: Ugo Cei wrote: Sylvain Wallez wrote: I'm using the flow and I'm using sessions too. The applications I'm currently developing with the flow are composed of many independent flows, each with its own entry point. Consider the case of an e-commerce site. These entry points might be: - search for an item - add item to cart - show cart - delete item from cart - proceed to checkout I don't think I can combine all of these (and many more) in as single flow, held toghether with continuations. But I still have the need to have a user session spanning those operations, and I do this with per-session global variables in the flow. As you might know, global variables in a flowscript are associated with a session when you call cocoon.createSession(). In the above example, the cart, or the user's profile, would be associated with the session. I am somehow aware that I am abusing sessions here, and that there is a better way, but it's not that easy to follow, probably. If you can show it to me, I'd be glad to abandon sessions, but if you take them away right now, I'm going to be in trouble ;-). Great, integration between different not-all-flowable parts is a *real* need for sessions in the FOM. This is a long term issue I have to solve also. I think what is happening here is that Ugo is looking for Work flow as opposed to presentation flow; IE; he needs yet another flow layer on top of flow. You can think of graphing out the work flow dependency graph the same way you have a presentation dependency graph. You can solve the problem the same way. It's an abstraction running over another abstraction, but I think we're going to keep running into this as a requirement... So +1 to add it. Anybody against it? Well, no, but I think the real solution is to allow flow layers to be stacked on top of each other as needed, each providing continuations for a particular level of abstraction. However, I haven't yet had the time to start playing with the existing flow so I'm having a hard time coming up with any kind of concrete proposal on how it would be implemented; it's also one of those things that can be done in a 2.2 or 2.3 type time frame if you don't mind having to keep session around for legacy support. Stefano.
Re: Discussion of Flow Issues
Ugo Cei wrote: Sylvain Wallez wrote: Stefano Mazzocchi wrote: 1) do we really need the session object? the flow is in fact deprecating the use of sessions for storing stateful data. I would love to *force* people to think into this way by not making the session available to them. We can always add it later if users really push us for it. +1. Moreover, the inadequate use of sessions to store data my completely break what the flow is giving us through continuations. I'm using the flow and I'm using sessions too. The applications I'm currently developing with the flow are composed of many independent flows, each with its own entry point. Consider the case of an e-commerce site. These entry points might be: - search for an item - add item to cart - show cart - delete item from cart - proceed to checkout I don't think I can combine all of these (and many more) in as single flow, held toghether with continuations. But I still have the need to have a user session spanning those operations, and I do this with per-session global variables in the flow. As you might know, global variables in a flowscript are associated with a session when you call cocoon.createSession(). In the above example, the cart, or the user's profile, would be associated with the session. I am somehow aware that I am abusing sessions here, and that there is a better way, but it's not that easy to follow, probably. If you can show it to me, I'd be glad to abandon sessions, but if you take them away right now, I'm going to be in trouble ;-). You're not abusing sessions. cocoon.createSession() exists exactly for the purpose you mention. Nobody is suggesting that we remove it. What at least I was suggesting, is that because of this (that you can store session state in global JS variables) direct access to the underlying Session should not be needed by the average user of the flow. Right now you have direct access via cocoon.session and cocoon.request.getSession(). Regards, Chris
Re: Discussion of Flow Issues
Upayavira wrote: I am somehow aware that I am abusing sessions here, and that there is a better way, but it's not that easy to follow, probably. If you can show it to me, I'd be glad to abandon sessions, but if you take them away right now, I'm going to be in trouble ;-). Great, integration between different not-all-flowable parts is a *real* need for sessions in the FOM. So +1 to add it. Anybody against it? I haven't had anything to say in this discussion so far, but somehow this deserves a comment... It would seem a shame to me to include sessions purely for 'inter-flow' communication. Given the thorough way you are all thinking about this, it seems a bit of a cop-out solution to just add sessions back in. Why is it a shame? Surely what Ugo needs is the ability to 'modularise' a single flow, in a way that makes it managable? Then you've got one flow (which is all I would say a single application should have, because there's just one interaction with a user), which removes the necessity for sessions (which would be very good), but still allows Ugo to manage a number of different routes through that flow, in an easily managable way. I've no idea how achievable that would be, as I've never played with flow myself, but just adding sessions back in seems like a major opportunity missed. Continuations are used when you have a sequence of related pages, in that case the application state can be stored in local variables within the Continuation. When you simply have jumps to other pages, in the flow that is modeled by top-level function calls. The top-level functions are still part of the same application and share state, however. This is handled in the flow by storing the shared state in javascript global variables, e.g. in Ugo's example: var user; function login(username) { cocoon.createSession(); user = UserManager.getUser(username); sendPage(User.html, user); } function chpasswd(newpasswd) { user.password = newpasswd; user.store(); sendPage(User.html, user); }
Re: Discussion of Flow Issues
Stefano Mazzocchi wrote: Great, integration between different not-all-flowable parts is a *real* need for sessions in the FOM. So +1 to add it. Anybody against it? Stefano. -1 for this reason. As mentioned in other mails, direct access to the session isn't needed in Ugo's case. +1 for a different reason: I think direct access to the session will be needed for backward compatibility with existing Cocoon components (e.g. Portal) that use the session for communication. But this could be encapsulated in a higher level JavaScript API that internally manages the session (like what I did with XMLForm). What do you think? Another possibility is to only expose the session at the Java level (not JavaScript) forcing new JavaScript objects that need access to it to be written in Java. This might prevent abuse. Regards, Chris
Re: Discussion of Flow Issues
Pier Fumagalli wrote: On 17/3/03 20:02, Stefano Mazzocchi [EMAIL PROTECTED] wrote: So, I would go for global - contains global log methods, no properties global doesn't have a meaning in IDL, therefore I created the Script object, which will contain also the reference to the function called from the sitemap... How about calling the class of this object just Flow? That's what it seems to represent: its methods (called by the sitemap) define page flow, and its properties (global variables) represent the shared application state of the pages. Regards, Chris
Re: Discussion of Flow Issues
Christopher Oliver wrote: Stefano Mazzocchi wrote: Great, integration between different not-all-flowable parts is a *real* need for sessions in the FOM. So +1 to add it. Anybody against it? Stefano. -1 for this reason. As mentioned in other mails, direct access to the session isn't needed in Ugo's case. Ok +1 for a different reason: I think direct access to the session will be needed for backward compatibility with existing Cocoon components (e.g. Portal) that use the session for communication. I see. But this could be encapsulated in a higher level JavaScript API that internally manages the session (like what I did with XMLForm). What do you think? Please elaborate more on this. Sounds interesting anyway. I would love to see the session disappear or, at least, provide a better abstraction to it. Another possibility is to only expose the session at the Java level (not JavaScript) forcing new JavaScript objects that need access to it to be written in Java. This might prevent abuse. Hmmm, if you don't get a hook to the ObjectModel, how can you get a java session object from the flow? Stefano.
Re: Discussion of Flow Issues
Christopher Oliver wrote: Pier Fumagalli wrote: On 17/3/03 20:02, Stefano Mazzocchi [EMAIL PROTECTED] wrote: So, I would go for global - contains global log methods, no properties global doesn't have a meaning in IDL, therefore I created the Script object, which will contain also the reference to the function called from the sitemap... How about calling the class of this object just Flow? That's what it seems to represent: its methods (called by the sitemap) define page flow, and its properties (global variables) represent the shared application state of the pages. Regards, Chris +1
Re: Discussion of Flow Issues
Stefano Mazzocchi wrote: Another possibility is to only expose the session at the Java level (not JavaScript) forcing new JavaScript objects that need access to it to be written in Java. This might prevent abuse. Hmmm, if you don't get a hook to the ObjectModel, how can you get a java session object from the flow? What I meant was instead of this: public class JSCocoon extends ScriptableObject { public Session jsGet_session() // expose session to JavaScript { ... } } we could do this: public class JSCocoon extends ScriptableObject { public Session getSession() { // not available in JavaScript } public static Session getSession(Scriptable scope) { Scriptable topLevel = getTopLevelScope(scope); Object obj = getProperty(topLevel, cocoon); return ((JSCocoon)obj).getSession(); } } Then if you need access to a Session you would have to implement a JavaScript object in Java, for example: class MyObject extends ScriptableObject { public String getClassName() {return MyObject;} public void jsFunction_foo() { // I need the session: Session session = JSCocoon.getSession(this); } } Then in javascript you could do this: var obj = new MyObject(); cocoon.session; // undefined obj.foo(); // but foo() uses the session
Re: Discussion of Flow Issues
On 18/3/03 19:06, Christopher Oliver [EMAIL PROTECTED] wrote: global doesn't have a meaning in IDL, therefore I created the Script object, which will contain also the reference to the function called from the sitemap... How about calling the class of this object just Flow? That's what it seems to represent: its methods (called by the sitemap) define page flow, and its properties (global variables) represent the shared application state of the pages. Well, but you never write a Flow... You write a Script for the flow... That was my idea when I wrote it though... Any way you like it guys (I'll just let it be for another few hours to hopefully make you change your mind, but I'm positive with anything)... Pier
Re: Discussion of Flow Issues
On 18/3/03 21:29, Christopher Oliver [EMAIL PROTECTED] wrote: Stefano Mazzocchi wrote: Another possibility is to only expose the session at the Java level (not JavaScript) forcing new JavaScript objects that need access to it to be written in Java. This might prevent abuse. Hmmm, if you don't get a hook to the ObjectModel, how can you get a java session object from the flow? What I meant was instead of this: public class JSCocoon extends ScriptableObject { public Session jsGet_session() // expose session to JavaScript { ... } } we could do this: public class JSCocoon extends ScriptableObject { public Session getSession() { // not available in JavaScript } public static Session getSession(Scriptable scope) { Scriptable topLevel = getTopLevelScope(scope); Object obj = getProperty(topLevel, cocoon); return ((JSCocoon)obj).getSession(); } } Then if you need access to a Session you would have to implement a JavaScript object in Java, for example: class MyObject extends ScriptableObject { public String getClassName() {return MyObject;} public void jsFunction_foo() { // I need the session: Session session = JSCocoon.getSession(this); } } Then in javascript you could do this: var obj = new MyObject(); cocoon.session; // undefined obj.foo(); // but foo() uses the session I like your approach _MUCH_BETTER_... I think we should consider it for most of the stuff we make visible to the flow, rather than passing the real Java instances to Rhino (obviously removing the construction part when needed)... Pier
Re: Discussion of Flow Issues
Pier Fumagalli wrote: On 18/3/03 21:29, Christopher Oliver [EMAIL PROTECTED] wrote: Stefano Mazzocchi wrote: Another possibility is to only expose the session at the Java level (not JavaScript) forcing new JavaScript objects that need access to it to be written in Java. This might prevent abuse. Hmmm, if you don't get a hook to the ObjectModel, how can you get a java session object from the flow? What I meant was instead of this: public class JSCocoon extends ScriptableObject { public Session jsGet_session() // expose session to JavaScript { ... } } we could do this: public class JSCocoon extends ScriptableObject { public Session getSession() { // not available in JavaScript } public static Session getSession(Scriptable scope) { Scriptable topLevel = getTopLevelScope(scope); Object obj = getProperty(topLevel, cocoon); return ((JSCocoon)obj).getSession(); } } Then if you need access to a Session you would have to implement a JavaScript object in Java, for example: class MyObject extends ScriptableObject { public String getClassName() {return MyObject;} public void jsFunction_foo() { // I need the session: Session session = JSCocoon.getSession(this); } } Then in javascript you could do this: var obj = new MyObject(); cocoon.session; // undefined obj.foo(); // but foo() uses the session I like your approach _MUCH_BETTER_... I think we should consider it for most of the stuff we make visible to the flow, rather than passing the real Java instances to Rhino (obviously removing the construction part when needed)... Mmmh, I don't like it much, as AFAIU it will require too much often to write some glue code for things that could be written in JS only... Sylvain -- Sylvain Wallez Anyware Technologies http://www.apache.org/~sylvain http://www.anyware-tech.com { XML, Java, Cocoon, OpenSource }*{ Training, Consulting, Projects }
Re: Discussion of Flow Issues
Sylvain Wallez wrote: Pier Fumagalli wrote: On 18/3/03 21:29, Christopher Oliver [EMAIL PROTECTED] wrote: Stefano Mazzocchi wrote: Another possibility is to only expose the session at the Java level (not JavaScript) forcing new JavaScript objects that need access to it to be written in Java. This might prevent abuse. Hmmm, if you don't get a hook to the ObjectModel, how can you get a java session object from the flow? What I meant was instead of this: public class JSCocoon extends ScriptableObject { public Session jsGet_session() // expose session to JavaScript { ... } } we could do this: public class JSCocoon extends ScriptableObject { public Session getSession() { // not available in JavaScript } public static Session getSession(Scriptable scope) { Scriptable topLevel = getTopLevelScope(scope); Object obj = getProperty(topLevel, cocoon); return ((JSCocoon)obj).getSession(); } } Then if you need access to a Session you would have to implement a JavaScript object in Java, for example: class MyObject extends ScriptableObject { public String getClassName() {return MyObject;} public void jsFunction_foo() { // I need the session: Session session = JSCocoon.getSession(this); } } Then in javascript you could do this: var obj = new MyObject(); cocoon.session; // undefined obj.foo(); // but foo() uses the session I like your approach _MUCH_BETTER_... I think we should consider it for most of the stuff we make visible to the flow, rather than passing the real Java instances to Rhino (obviously removing the construction part when needed)... Mmmh, I don't like it much, as AFAIU it will require too much often to write some glue code for things that could be written in JS only... I think the above method that Chris suggests is fair for sessions (making it a *little* hard, but not too much) but I agree with Sylvain that this is way too much overhead for the remaining part of the FOM. But I have the impression i didn't understand what Pier was implying because I'm sure he would not propose to force people to write that much java gluecode just for everyday FOM usage. Pier, can you elaborate more on what you wanted to say above? TIA Stefano.
Re: Discussion of Flow Issues
On 18/3/03 23:00, Stefano Mazzocchi [EMAIL PROTECTED] wrote: But I have the impression i didn't understand what Pier was implying because I'm sure he would not propose to force people to write that much java gluecode just for everyday FOM usage. Pier, can you elaborate more on what you wanted to say above? TIA For those object on which we want to tightly control the behavior, for example, you want to be able from a flow script to retrieve the cocoon instance, but not to set it (readonly attribute Cocoon cocoon in IDL). I'd settle with writing a bunch of glue-code for our (work) applications, if that allows me to clearly define the boundaries of what flow-script writers can have access to: I can write the glue and have much more flexibility writing my backend in Java knowing that anyway, my team won't be able to mess around with it... Pier
Re: Discussion of Flow Issues
Pier Fumagalli wrote: On 18/3/03 23:00, Stefano Mazzocchi [EMAIL PROTECTED] wrote: But I have the impression i didn't understand what Pier was implying because I'm sure he would not propose to force people to write that much java gluecode just for everyday FOM usage. Pier, can you elaborate more on what you wanted to say above? TIA For those object on which we want to tightly control the behavior, for example, you want to be able from a flow script to retrieve the cocoon instance, but not to set it (readonly attribute Cocoon cocoon in IDL). I'd settle with writing a bunch of glue-code for our (work) applications, if that allows me to clearly define the boundaries of what flow-script writers can have access to: I can write the glue and have much more flexibility writing my backend in Java knowing that anyway, my team won't be able to mess around with it... Right. The goal of the FOM is to make public those methods that are safe from an architectural point of view for script kiddies to mess around with. The more dangerously abused an internal public method is, the harder will be for script kiddies to get it from the flow. This should (hopefully) reduce scripting abuse. Is anybody against this general approach? Stefano.
Re: Discussion of Flow Issues
Christopher Oliver wrote: Sylvain Wallez wrote: I like your approach _MUCH_BETTER_... I think we should consider it for most of the stuff we make visible to the flow, rather than passing the real Java instances to Rhino (obviously removing the construction part when needed)... Mmmh, I don't like it much, as AFAIU it will require too much often to write some glue code for things that could be written in JS only... Sylvain Either way is fine with me. It was just a suggestion. You might want to look at what I had to do to integrate with XMLForm: http://cvs.apache.org/viewcvs.cgi/*checkout*/cocoon-2.1/src/java/org/apache/cocoon/components/flow/javascript/xmlForm.js?rev=1.3content-type=text/plain In order to communicate with XMLFormTransformer and to handle restarting continuations, this script needs access to: cocoon.session cocoon.componentManager cocoon.environment.objectModel cocoon.forwardTo() Why do you need direct access to the objectModel? My 'script kid' alarm is ringing. Stefano.
Re: Discussion of Flow Issues
Stefano Mazzocchi wrote: Christopher Oliver wrote: http://cvs.apache.org/viewcvs.cgi/*checkout*/cocoon-2.1/src/java/org/apache/cocoon/components/flow/javascript/xmlForm.js?rev=1.3content-type=text/plain In order to communicate with XMLFormTransformer and to handle restarting continuations, this script needs access to: cocoon.session cocoon.componentManager cocoon.environment.objectModel cocoon.forwardTo() Why do you need direct access to the objectModel? Only because of the design of XMLForm: it stores the form view in the object model and several of the methods of org.apache.cocoon.component.xmlform.Form require the object model as a parameter. Regardless of the flow, there doesn't appear to be lot of consistency in the way Cocoon components communicate: sometimes they stash stuff in request parameters, sometimes in the session, sometimes in the object model. In any case there seems to be no explicit contract,
Re: Discussion of Flow Issues
Sylvain Wallez wrote: What I suggested in the mail linked above is to use the object model, already used as a communication means between the environment and other components to communicate flow results. This suggestion comes both from the fact that the object model is the natural way for the environment to communicate public information to other components, and from the fact that we can consider flow data as some additional data available in the sitemap when called from a flow script. So we need two more values in the object model Map : one for the value dictionary, and one for the continuation. How does it sound ? I love it, but, as Carsten correctly pointed out, this will make it harder to separate the flow. (I'm basing my reasoning on the anti-pattern assumption that if a module separation requires code preprocessing there is something wrong) 2) Concerns with exposing the componentManager: http://marc.theaimsgroup.com/?l=xml-cocoon-devm=104687345726726w=2 http://marc.theaimsgroup.com/?l=xml-cocoon-devm=104687863701233w=2 I personally do not know what the proper solution here is. Can someone explain the proper use of component managers and make a suggestion on how to solve this? I think that a way to solve this would be to have a direct FOM hook to the cocoon component manager... but this should not allow people to have access to sitemap components, only to those components defined in roles. But I'm thinking out loud here. I'm not sure this FOM thing has been defined compared to the Environment's object model. This was my and Pier's concern: we need to define the FOM with the same care we took to define the rest of the contracts with the Cocoon system and it was not done until we raised the thing. Having you and Vadim discussing this with Chris, Pier and me is a very good thing because it goes toward that community-driven design I was looking for. My POV is that the FOM is the set of objects that are visible as global variables in a flow script. This must include : - the Environment's object model (but not the Environment itself), yes. note also that with javascript we can do very nice syntax-sugar things like cocoon.request.blah would do the same as a much more verbose cocoon.getRequest().getParameter(blah) which would bring us the scriptability and ease-of-use of web scripting solutions (which are so popular because very easy to read and write) with the solidity of a well-defined OO framework. - Avalon-related objects that Java components (as opposed to JavaScript) obtain through the Avalon lifecycle interfaces. These are the Logger, the (Avalon) Context, and the ComponentManager. The logger is available, we just need to define how. I already asked for a direct hook to the component manager. Why would you need access to the context? I don't know if there's a need for a Configuration. I would say no. The flow is not a component - the Redirector, currently available to actions (I consider redirecting as a particular case of a view). Hmmm, I'm not sure: why would you want a redirector when you have the sendPage() method? The FOM also provides some methods not related to any of the above objects such as sendPage(). methods that I want to see removed from a global namespace and placed into the cocoon object for clarity and cognitive scope. 3) Duplication of functionality between VelocityGenerator and FlowVelocityGenerator: http://marc.theaimsgroup.com/?l=xml-cocoon-devm=104673257019781w=2 This is clearly bad, I agree. I think these could be merged back together - the old behavior would apply if the flow context object isn't available. But this probably depends somewhat on the answer to (1). Ok, so you are stating that once we solve 1) we solve 3) as well? Could be ;-) If flow data goes through the object model, publishing the object model to the Velocity engine could solve the problem. Great. [snip] I share your attach-a-method-to-an-object concern, which certainly comes from our heavy Java background. I'm sure it does, but after playing pretty hard with javascript for DHTML, I can tell you that the hardest thing for me to graps is the concept of why everybody uses alert(blah) why they use window.status = blah but never window.alert(blah); and status = blah; In my mind, this means that not many understand that the 'window' object is transparently mapped to the global unnamespaced object but it creates a mess because you could have 'status' defined in your scripts as well. This is why I want a clean unnamespaced object. I would not mind log methods such as info(blah); error(blah); debug(lkj); but that should be it. This is mainly a naming and classification problem : how do we organize these objects available to the JS script ? Should all the FOM be defined as global variables, or available as properties of some classifier objects, e.g. cocoon.request, cocoon.sendPage(), avalon.logger,
Re: Discussion of Flow Issues
On Monday, March 17, 2003, at 08:02 PM, Stefano Mazzocchi wrote: Sylvain Wallez wrote: snip/ So, I would go for global - contains global log methods, no properties Why log methods? I don't understand what is so special about them, that they need to be global? cocoon.log.info(blah); cocoon.log.error(blah); cocoon.log.debug(lkj); make more sense to me, even if they are longer :) cocoon - cocoon methods + component management methods +1 You would use a 'role' identifier to retrieve them? cocoon.request - access to the request +1 cocoon.response - access to the response +0 cocoon.context - access to the context +1 NOTE: 1) do we really need the session object? the flow is in fact deprecating the use of sessions for storing stateful data. I would love to *force* people to think into this way by not making the session available to them. I think that is an interesting idea. Will cause some confusion, but it is true to the concept of Flow. We can always add it later if users really push us for it. 2) do we need access to the response? setting headers is the only thing that comes to mind, but that is potentially abusable, expecially on things like cache headers and such. maybe we should leave this out as well for now. I think we need more resolution of the various ongoing discussions about cleaning up Cocoon's interaction with all aspects of HTTP headers (in-bound and out-bound) before we can decide to take this out of Flow's reach. Ideally, we should be able to take it out. 3) avalon component management should be done thru the 'cocoon' object because it's cocoon, in fact, that provides those components to you. the fact that they are managed internally by avalon doesn't make any difference for joe-flow-user, nor should. +1 What management methods do you envisage? What gets automatically managed? TBH. I don't understand yet when/why you would access components from Flow. What do you think? I am glad this is happening this way :) regards Jeremy
Re: Discussion of Flow Issues
Stefano Mazzocchi wrote: Sylvain Wallez wrote: What I suggested in the mail linked above is to use the object model, already used as a communication means between the environment and other components to communicate flow results. This suggestion comes both from the fact that the object model is the natural way for the environment to communicate public information to other components, and from the fact that we can consider flow data as some additional data available in the sitemap when called from a flow script. So we need two more values in the object model Map : one for the value dictionary, and one for the continuation. How does it sound ? I love it, but, as Carsten correctly pointed out, this will make it harder to separate the flow. (I'm basing my reasoning on the anti-pattern assumption that if a module separation requires code preprocessing there is something wrong) I don't think this will make it difficult to separate it : the object model is a Map which can hold any kind of objects, and instrospection-based accessors such as JXPath don't care about the actual class of objects. So adding flow values to the object model shouldn't be a problem when they are either manipulated abstractly as described above or simply ignored. snip/ I'm not sure this FOM thing has been defined compared to the Environment's object model. This was my and Pier's concern: we need to define the FOM with the same care we took to define the rest of the contracts with the Cocoon system and it was not done until we raised the thing. Having you and Vadim discussing this with Chris, Pier and me is a very good thing because it goes toward that community-driven design I was looking for. Yep. I jumped into this discussion since I felt the need for this community-driven polishing and also to force me to finally go into this nice stuff ;-) My POV is that the FOM is the set of objects that are visible as global variables in a flow script. This must include : - the Environment's object model (but not the Environment itself), yes. note also that with javascript we can do very nice syntax-sugar things like cocoon.request.blah would do the same as a much more verbose cocoon.getRequest().getParameter(blah) which would bring us the scriptability and ease-of-use of web scripting solutions (which are so popular because very easy to read and write) with the solidity of a well-defined OO framework. Yep. I like that too. - Avalon-related objects that Java components (as opposed to JavaScript) obtain through the Avalon lifecycle interfaces. These are the Logger, the (Avalon) Context, and the ComponentManager. The logger is available, we just need to define how. I already asked for a direct hook to the component manager. Why would you need access to the context? Because it can contain some useful data for the flow or Java classes called by the flow such as the work directory (makes me think that a work: protocol would be nice) or the environment context (webapp resources, deployment parameters, etc). I don't know if there's a need for a Configuration. I would say no. The flow is not a component I was wondering if there may be some generic flow programs that could be parameterized through a configuration, but this finally smells FS. So no Configuration. - the Redirector, currently available to actions (I consider redirecting as a particular case of a view). Hmmm, I'm not sure: why would you want a redirector when you have the sendPage() method? To send a redirect directly to the client, without going through the sitemap. Considering the sendPage() method, a redirect() method would be better than a Redirector object. The FOM also provides some methods not related to any of the above objects such as sendPage(). methods that I want to see removed from a global namespace and placed into the cocoon object for clarity and cognitive scope. Me too :-) snip/ In my mind, this means that not many understand that the 'window' object is transparently mapped to the global unnamespaced object but it creates a mess because you could have 'status' defined in your scripts as well. This is why I want a clean unnamespaced object. I would not mind log methods such as info(blah); error(blah); debug(lkj); but that should be it. Even these. Let's attach them to a logger object : log.debug(blah), log.info(foo), etc. This is mainly a naming and classification problem : how do we organize these objects available to the JS script ? Should all the FOM be defined as global variables, or available as properties of some classifier objects, e.g. cocoon.request, cocoon.sendPage(), avalon.logger, avalon.manager ? I personnaly would go for the second choice. Totally! Note, however, that I would like to hide the complexities of Avalon as much as possible. So, I would go for global - contains global log methods, no properties -1 (see above) cocoon - cocoon methods +
Re: Discussion of Flow Issues
Christopher Oliver wrote: Sylvain Wallez wrote: A short explanation about the object model. Cocoon abstracts its runtime environment through the Environment interface. An Environment object gives access to a number of things that are relevant to the pipeline/sitemap engine only and should not be visible from other components to avoid uncontrolled access to data managed by the pipeline/sitemap engine. These include for example the response outpoutstream, the current context prefix (changed by map:mount), etc. To provide those parts of the Environment that are safe to be used by other components and required by them to do their job, the Environment provides a so-called object model (Environment.getObjectModel()), which is a Map of named objects, mainly Request and Response. This Map is passed to every sitemap component during the call to setup(). What objects besides the Request, Response, Session and Context are in the object model? The flow script doesn't use the Response (and if you use XMLForm, it doesn't use the Request either). The Session isn't needed because when you use flow scripts you can store your application state in JavaScript progam variables instead of as session attributes. So what's left? Nothing, you listed them all :-) What I suggested in the mail linked above is to use the object model, already used as a communication means between the environment and other components to communicate flow results. This suggestion comes both from the fact that the object model is the natural way for the environment to communicate public information to other components, and from the fact that we can consider flow data as some additional data available in the sitemap when called from a flow script. So we need two more values in the object model Map : one for the value dictionary, and one for the continuation. How does it sound ? That would work. But as above, now what other objects are in the object model and what are they used for? I'm not sure this FOM thing has been defined compared to the Environment's object model. My POV is that the FOM is the set of objects that are visible as global variables in a flow script. This must include : - the Environment's object model (but not the Environment itself), - Avalon-related objects that Java components (as opposed to JavaScript) obtain through the Avalon lifecycle interfaces. These are the Logger, the (Avalon) Context, and the ComponentManager. I don't know if there's a need for a Configuration. I don't understand this. Can you explain what Avalon-related objects are? Avalon-related objects are those that are made available to components by the Avalon framework through the various lifecycle interface. These are a Logger (LogEnabled interface), an Avalon context (Contextualizable interface), a ComponentManager (Composable interface) and a Configuration (Configurable interface), although this last one doesn't really makes sense for the flow. snip/ So, I would like to propose to remove Global or empty it and move everything over to the Cocoon object. This means that instead of doing stuff like: sendPage(...) I propose to do cocoon.sendPage() which outlines the fact that it's not the flow that sends the page, but it's cocoon that does (control is given back to the sitemap before sending the page). Agree. But for the second reason: I think sendPage() is really an operation of the cocoon. Cool. Seems like we're rapidly converging towards a consensus :-) Sylvain -- Sylvain Wallez Anyware Technologies http://www.apache.org/~sylvain http://www.anyware-tech.com { XML, Java, Cocoon, OpenSource }*{ Training, Consulting, Projects }
Re: Discussion of Flow Issues
On 17/3/03 20:02, Stefano Mazzocchi [EMAIL PROTECTED] wrote: I share your attach-a-method-to-an-object concern, which certainly comes from our heavy Java background. I'm sure it does, but after playing pretty hard with javascript for DHTML, I can tell you that the hardest thing for me to graps is the concept of why everybody uses alert(blah) why they use window.status = blah but never window.alert(blah); and status = blah; In my mind, this means that not many understand that the 'window' object is transparently mapped to the global unnamespaced object but it creates a mess because you could have 'status' defined in your scripts as well. This is why I want a clean unnamespaced object. I would not mind log methods such as info(blah); error(blah); debug(lkj); but that should be it. Well.. The global can also be referred to as this... So you can also write: alert(alert); window.alert(window.alert); this.alert(this.alert); this.window.alert(this.window.alert); That said, I believe that the best way to define global operations and attributes is to define them in a so called script object, whose instance is the one you're going to call from the sitemap... So, cocoon.sendPage() becomes this.cocoon.sendPage()... JavaScript, as Java, allows you to strip out the this Pier
Re: Discussion of Flow Issues
On 17/3/03 20:02, Stefano Mazzocchi [EMAIL PROTECTED] wrote: So, I would go for global - contains global log methods, no properties global doesn't have a meaning in IDL, therefore I created the Script object, which will contain also the reference to the function called from the sitemap... In my mind nothing is global... And it's strengthened by the fact that in JavaScript all the so called globals can be also referenced by preceding them with this... cocoon - cocoon methods + component management methods This is an attribute of Script, so that it can be referenced (in JavaScript) from your function using cocoon. or this.cocoon.. cocoon.request - access to the request Yes... cocoon.response - access to the response Removed as per agreement with Sylvain and your doubts raised further along in your email... cocoon.context - access to the context Yes... (I actually had to mangle the name to contxt as context seems to be an IDL keyword). What do you think? Awesome... Now we have to decide what to expose in context and request... I believe (or just inherit all?)... Now, your personal IDL stenographer at work reflected the changes in the sources... Can you guys please check the IDLDoc output to tell me where I foobared up? Thanks... Pier
Re: Discussion of Flow Issues
Sylvain Wallez wrote: Stefano Mazzocchi wrote: Sylvain Wallez wrote: So we need two more values in the object model Map : one for the value dictionary, and one for the continuation. How does it sound ? I love it, but, as Carsten correctly pointed out, this will make it harder to separate the flow. (I'm basing my reasoning on the anti-pattern assumption that if a module separation requires code preprocessing there is something wrong) I don't think this will make it difficult to separate it : the object model is a Map which can hold any kind of objects, and instrospection-based accessors such as JXPath don't care about the actual class of objects. 1) Helper functions like getContinuation() in ObjectModelHelper are not separatable; 2) FlowVelocityGenerator, it has some clever hack on 130 lines or so specifically for the flow bean (see Hack? I use JXPath to determine the properties of the bean object); 3) jpath logicsheet right now instead of being generic is hardwired to the flow too; ... It's already not easy to separate! I can think of how to resolve issue 1 (dedicated FlowObjectModelHelper: ugly, but works) and 3 (flow logicsheet for flow related stuff; jxpath logicsheet for generic stuff), not sure about 2 though. Extra Velocity generator is not nice. snip/ - the Redirector, currently available to actions (I consider redirecting as a particular case of a view). Hmmm, I'm not sure: why would you want a redirector when you have the sendPage() method? To send a redirect directly to the client, without going through the sitemap. Considering the sendPage() method, a redirect() method would be better than a Redirector object. +1 snip/ So, I would go for global - contains global log methods, no properties -1 (see above) No to global, agree. 1) do we really need the session object? the flow is in fact deprecating the use of sessions for storing stateful data. I would love to *force* people to think into this way by not making the session available to them. We can always add it later if users really push us for it. +1. Moreover, the inadequate use of sessions to store data my completely break what the flow is giving us through continuations. -0: Put session there, don't advertise it. Presence of the session object might facilitate migration from one approach to another, also will allow integration between different parts. Vadim snip/
Re: Discussion of Flow Issues
Stefano Mazzocchi wrote: Christopher Oliver wrote: Here's a summary of some of the recent issues with the Flow for discussion: 1) Storing the flow context object and continuation in environment attributes: http://marc.theaimsgroup.com/?l=xml-cocoon-devm=104673257019781w=2 This seems easy to fix. But I personally don't understand the objectModel. Can someone explain how to properly use it? But I think there is a more fundamental design question here: namely, how should the flow script communicate with generators, transformers, etc? A short explanation about the object model. Cocoon abstracts its runtime environment through the Environment interface. An Environment object gives access to a number of things that are relevant to the pipeline/sitemap engine only and should not be visible from other components to avoid uncontrolled access to data managed by the pipeline/sitemap engine. These include for example the response outpoutstream, the current context prefix (changed by map:mount), etc. To provide those parts of the Environment that are safe to be used by other components and required by them to do their job, the Environment provides a so-called object model (Environment.getObjectModel()), which is a Map of named objects, mainly Request and Response. This Map is passed to every sitemap component during the call to setup(). This is a very good question and I'm not sure I have an answer. Sylvain, what do you think? What I suggested in the mail linked above is to use the object model, already used as a communication means between the environment and other components to communicate flow results. This suggestion comes both from the fact that the object model is the natural way for the environment to communicate public information to other components, and from the fact that we can consider flow data as some additional data available in the sitemap when called from a flow script. So we need two more values in the object model Map : one for the value dictionary, and one for the continuation. How does it sound ? 2) Concerns with exposing the componentManager: http://marc.theaimsgroup.com/?l=xml-cocoon-devm=104687345726726w=2 http://marc.theaimsgroup.com/?l=xml-cocoon-devm=104687863701233w=2 I personally do not know what the proper solution here is. Can someone explain the proper use of component managers and make a suggestion on how to solve this? I think that a way to solve this would be to have a direct FOM hook to the cocoon component manager... but this should not allow people to have access to sitemap components, only to those components defined in roles. But I'm thinking out loud here. I'm not sure this FOM thing has been defined compared to the Environment's object model. My POV is that the FOM is the set of objects that are visible as global variables in a flow script. This must include : - the Environment's object model (but not the Environment itself), - Avalon-related objects that Java components (as opposed to JavaScript) obtain through the Avalon lifecycle interfaces. These are the Logger, the (Avalon) Context, and the ComponentManager. I don't know if there's a need for a Configuration. - the Redirector, currently available to actions (I consider redirecting as a particular case of a view). The FOM also provides some methods not related to any of the above objects such as sendPage(). 3) Duplication of functionality between VelocityGenerator and FlowVelocityGenerator: http://marc.theaimsgroup.com/?l=xml-cocoon-devm=104673257019781w=2 This is clearly bad, I agree. I think these could be merged back together - the old behavior would apply if the flow context object isn't available. But this probably depends somewhat on the answer to (1). Ok, so you are stating that once we solve 1) we solve 3) as well? Could be ;-) If flow data goes through the object model, publishing the object model to the Velocity engine could solve the problem. 4) JavaScript Database API has no business being in the flow We all agree on this. But we need someplace to put useful JavaScript stuff - as part of optional blocks or something like that. yes. In my own use of the flow, I've also noticed the following bugs: - Script reloading is partially broken. Sometimes scripts don't reload properly. This is normal when you are in a continuation - the continuation contains a compiled copy of the script and doesn't see the new reloaded one. But it happens occasionally even in top level calls. - With certain Exceptions the script file names and line numbers are not reported - Cocoon.load() doesn't work I saw some commits of yours on this, is cocoon.load() functional now? I also noticed that it isn't fun to debug Velocity templates. If the generated xml has errors, the XML parser reports the line number of the generated xml document, which isn't preserved anywhere. In that case it would be nice if the Velocity generator saved the
Re: Discussion of Flow Issues
Sylvain Wallez wrote: A short explanation about the object model. Cocoon abstracts its runtime environment through the Environment interface. An Environment object gives access to a number of things that are relevant to the pipeline/sitemap engine only and should not be visible from other components to avoid uncontrolled access to data managed by the pipeline/sitemap engine. These include for example the response outpoutstream, the current context prefix (changed by map:mount), etc. To provide those parts of the Environment that are safe to be used by other components and required by them to do their job, the Environment provides a so-called object model (Environment.getObjectModel()), which is a Map of named objects, mainly Request and Response. This Map is passed to every sitemap component during the call to setup(). What objects besides the Request, Response, Session and Context are in the object model? The flow script doesn't use the Response (and if you use XMLForm, it doesn't use the Request either). The Session isn't needed because when you use flow scripts you can store your application state in JavaScript progam variables instead of as session attributes. So what's left? What I suggested in the mail linked above is to use the object model, already used as a communication means between the environment and other components to communicate flow results. This suggestion comes both from the fact that the object model is the natural way for the environment to communicate public information to other components, and from the fact that we can consider flow data as some additional data available in the sitemap when called from a flow script. So we need two more values in the object model Map : one for the value dictionary, and one for the continuation. How does it sound ? That would work. But as above, now what other objects are in the object model and what are they used for? I'm not sure this FOM thing has been defined compared to the Environment's object model. My POV is that the FOM is the set of objects that are visible as global variables in a flow script. This must include : - the Environment's object model (but not the Environment itself), - Avalon-related objects that Java components (as opposed to JavaScript) obtain through the Avalon lifecycle interfaces. These are the Logger, the (Avalon) Context, and the ComponentManager. I don't know if there's a need for a Configuration. I don't understand this. Can you explain what Avalon-related objects are? - the Redirector, currently available to actions (I consider redirecting as a particular case of a view). Yes. 4) JavaScript Database API has no business being in the flow We all agree on this. But we need someplace to put useful JavaScript stuff - as part of optional blocks or something like that. yes. In my own use of the flow, I've also noticed the following bugs: - Script reloading is partially broken. Sometimes scripts don't reload properly. This is normal when you are in a continuation - the continuation contains a compiled copy of the script and doesn't see the new reloaded one. But it happens occasionally even in top level calls. - With certain Exceptions the script file names and line numbers are not reported - Cocoon.load() doesn't work I saw some commits of yours on this, is cocoon.load() functional now? In preparation for refactoring this stuff, I think I've now got script reloading and Cocoon.load() working. The main objects in the FOM are: 1) Global - indicates methods that are available without object prefix 2) Cocoon - cocoon-related methods that are avalilable with the cocoon. object prefix First of all, is there a reason to have both? I find the concept of prefix-less method calls a little weird coming from the java world. they come out of the blue. Also, there is a lot of duplication between the two since they provide the same methods. this is very bad, IMO. They're not really prefix-less. sendPage() is really the same as this.sendPage() where this identifies the top-level object. But you're right, in my opinion, about the duplication. It makes no sense. So, I would like to propose to remove Global or empty it and move everything over to the Cocoon object. This means that instead of doing stuff like: sendPage(...) I propose to do cocoon.sendPage() which outlines the fact that it's not the flow that sends the page, but it's cocoon that does (control is given back to the sitemap before sending the page). Agree. But for the second reason: I think sendPage() is really an operation of the cocoon.
Re: Discussion of Flow Issues
Christopher Oliver wrote: Here's a summary of some of the recent issues with the Flow for discussion: 1) Storing the flow context object and continuation in environment attributes: http://marc.theaimsgroup.com/?l=xml-cocoon-devm=104673257019781w=2 This seems easy to fix. But I personally don't understand the objectModel. Can someone explain how to properly use it? But I think there is a more fundamental design question here: namely, how should the flow script communicate with generators, transformers, etc? This is a very good question and I'm not sure I have an answer. Sylvain, what do you think? 2) Concerns with exposing the componentManager: http://marc.theaimsgroup.com/?l=xml-cocoon-devm=104687345726726w=2 http://marc.theaimsgroup.com/?l=xml-cocoon-devm=104687863701233w=2 I personally do not know what the proper solution here is. Can someone explain the proper use of component managers and make a suggestion on how to solve this? I think that a way to solve this would be to have a direct FOM hook to the cocoon component manager... but this should not allow people to have access to sitemap components, only to those components defined in roles. But I'm thinking out loud here. 3) Duplication of functionality between VelocityGenerator and FlowVelocityGenerator: http://marc.theaimsgroup.com/?l=xml-cocoon-devm=104673257019781w=2 This is clearly bad, I agree. I think these could be merged back together - the old behavior would apply if the flow context object isn't available. But this probably depends somewhat on the answer to (1). Ok, so you are stating that once we solve 1) we solve 3) as well? 4) JavaScript Database API has no business being in the flow We all agree on this. But we need someplace to put useful JavaScript stuff - as part of optional blocks or something like that. yes. In my own use of the flow, I've also noticed the following bugs: - Script reloading is partially broken. Sometimes scripts don't reload properly. This is normal when you are in a continuation - the continuation contains a compiled copy of the script and doesn't see the new reloaded one. But it happens occasionally even in top level calls. - With certain Exceptions the script file names and line numbers are not reported - Cocoon.load() doesn't work I saw some commits of yours on this, is cocoon.load() functional now? I also noticed that it isn't fun to debug Velocity templates. If the generated xml has errors, the XML parser reports the line number of the generated xml document, which isn't preserved anywhere. In that case it would be nice if the Velocity generator saved the generated xml document somewhere, or at least logged it. I think it makes sense. I also noted a few things looking at the FOM thru the IDL documentation: there is a lot of duplication between the Global and Cocoon objects and I would like to sort it out. - o - The main objects in the FOM are: 1) Global - indicates methods that are available without object prefix 2) Cocoon - cocoon-related methods that are avalilable with the cocoon. object prefix First of all, is there a reason to have both? I find the concept of prefix-less method calls a little weird coming from the java world. they come out of the blue. Also, there is a lot of duplication between the two since they provide the same methods. this is very bad, IMO. So, I would like to propose to remove Global or empty it and move everything over to the Cocoon object. This means that instead of doing stuff like: sendPage(...) I propose to do cocoon.sendPage() which outlines the fact that it's not the flow that sends the page, but it's cocoon that does (control is given back to the sitemap before sending the page). So, no methods come out of the blue. what do you think? Stefano.