[Struts Wiki] Update of RoughSpots by DonBrown
Dear Wiki user, You have subscribed to a wiki page or wiki category on Struts Wiki for change notification. The following page has been changed by DonBrown: http://wiki.apache.org/struts/RoughSpots -- I'm new around here, so be nice ;) I probably have a lot less WW experience than most, so I apologize in advance if I'm flat out wrong about some of the things here. 1. How does WW help the user with state management? As far as I can tell, if I want to keep a 'user' object around I have to interact with the map returned by ActionContext.getSession(). Actions should in general have a type-safe and transparent way to do this, e.g. by subclassing ActionContext and providing getUser()/setUser() which store the user in session. This allows for re-working of the storage strategy (e.g. write a cookie and lookup the user each time) without affecting actions. - * [crazybob] I prefer an injection-based approach. You can use the `ScopeInterceptor` to pull an object off the session and pass it to your action. Or you can use Spring to inject session-scoped objects into your action (though I would avoid Spring personally). - * [jcarreira] I can attest that the Spring scoped components work well with WebWork. It's what we use at work for maintaining session or request state. 1. In tandem with the previous point, since Actions are already stateful, it'd be nice to have the ActionContext injected into the Action. One benefit is when a newbie developer needs it, the linkage is obvious (they don't have to a priori know about the ActionContext, they're being handed in it on a platter). If the developer can subclass ActionContext, it would also encourage them to implement a base action which accepts the context inject and leveraging the fact that JDK 1.5 allows co-variant returns, also write a getContext() method that returns the down-casted type; they wouldn't have to do ((MyActionContext) ActionContext.getContext()).getUser() for example, just getContext().getUser(). * [frankz] This might well address the issue of !ActionContext being !ThreadLocal. If it was injected, it wouldn't need to be !ThreadLocal to get the same basic effect, and maybe more importantly, it wouldn't automatically be available to helper classes as it is as a !ThreadLocal. That would address my concern about inappropriate usage of !ActionContext. * [jcarreira] I think this is a bad idea, in general. Actions should specify the exact things they need and have them supplied, not just ask for the world (the ActionContext is the world the action lives in). + * [mrdon] While I agree more specific is generally better, I like the idea of the user being able to subclass ActionContext for their particular application. Tapestry has the Visit object (I think that's the name) I've always liked. + - 1. HTML analog tags should stick to HTML attributes. I dont' mean they shouldn't have more functionality, but the attributes should be identical where possible, and they shouldn't do things like render a label and an input. Keeping them more like regular HTML tags makes them easier to ramp up on, and more non-developer friendly + 1. HTML analog tags should stick to HTML attributes. I don't mean they shouldn't have more functionality, but the attributes should be identical where possible, and they shouldn't do things like render a label and an input. Keeping them more like regular HTML tags makes them easier to ramp up on, and more non-developer friendly * [MJ] I see the following options when it comes to tags. (1) Use plain HTML + implicit scoped variables like actionName, actionAddress, etc. to create dynamic values; this looks pretty compact with JSP 2.0. (2) Use 1:1 relation between WW tags and HTML tags. (3) Use 1:M relation between WW tags and HTML tags, like to create data entry form or a table. (4) Use non-HTML-looking tags + more abstract attributes + media attribute, thus creating something like JSF renderer for different media. Choosing between (1) and (2) I prefer the first one. - * I'd encourage people to give the ww: tags a spin... they're really much more powerful than the JSTL or previous struts tags and you don't need so many tags to do things. On being closer to HTML attributes, do you have some examples? + * [jcarreira] I'd encourage people to give the ww: tags a spin... they're really much more powerful than the JSTL or previous struts tags and you don't need so many tags to do things. On being closer to HTML attributes, do you have some examples? + * [mrdon] +1 for aligning attributes with HTML attributes 1. Actions should return concrete objects, not symbolic results. Symbolic results might have been optimal when you had one event/method per action and the outcomes were always whole-page views, but they get in the way now. When you
[Struts Wiki] Update of RoughSpots by DonBrown
Dear Wiki user, You have subscribed to a wiki page or wiki category on Struts Wiki for change notification. The following page has been changed by DonBrown: http://wiki.apache.org/struts/RoughSpots -- 1. Do we want to keep `ModelDriven`? 1. Do we want `ValidationAware` (or its equivalent) to take message keys or actual messages. It takes the actual messages in WW2. `ActionMessages` in Struts takes keys. I'm a fan of keys; we would no longer need `TextProvider`. Pat suggested we take keys, and in the event that we don't find a message for the given key, pass the key along as the message. I think I'd rather fail fast. + * [mrdon] Keys are fine, as long as you can do parameter replacement easily enough later. Not all apps need L18N, so I'm kinda against the fail fast. Perhaps in devMode, we add a clear warning? 1. Craig McC mentioned that we might want to use this in a portlet. Does this mean I should completely abstract us from `HttpServletRequest`/`PortletRequest`? + * [mrdon] +1, at least in some form. This was the goal of the generic ActionContext, I believe. Cocoon has been struggling with the same issue, and they are leaning towards implementing the HttpServletRequest, et al with a portlet impl to solve this problem. They used to have this generic Environment api, but they are in the process of giving that up, I believe, favoring this servlet api approach. I wonder if we shouldn't find out more about their results and adopt them. == Patrick's issues == - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
[Struts Wiki] Update of RoughSpots by DonBrown
Dear Wiki user, You have subscribed to a wiki page or wiki category on Struts Wiki for change notification. The following page has been changed by DonBrown: http://wiki.apache.org/struts/RoughSpots -- * [frankz] +1. This is one area where I personally think Struts had it right and we've seen frameworks getting it wrong subsequently. !ActionForward I believe is the right concept, even if the realization might not be optimal. I think the difference between return ok; and return new ActionResult(ok); is pretty minimal, but the later opens up a lot of possibilities being a true object that can have behaviors and properties and such. * [crazybob] There's no reason we can't support both `String` and `Result` return types for action methods. I think we should encourage `String` though. Can you provide some example use cases for when `String` isn't enough? * [frankz] A few that come to mind... the ability to choose between redirect and forward based on decisions made in code (you could argue that you can have two result's defined, one with type redirect and one with type forward, but then that starts to clutter the config file I think)... the ability to add parameters to a forwarded result (i.e., if you wanted to forward to another action, how can you add parameters just by returning a String? Well, unless the processor expects and can deal with a query string appended I support)... the ability to add an anchor name to the response... the opportunity to include additional objects in the response (i.e., what if you had some sort of ViewSupport object that the presentation can make use of... it might be more intuitive to add it to a Result than to directly add it as a request attribute, and that also makes for better abstraction from the servlet API). I'm sure there's more, and I'm sure there are ways to accomplish most of these things without returning an object, but I think the clarity of the resultant code is greater by returning a Result object, and it opens up possibilities I can't think of (i.e., functionality encapsulated in that object independant of tbe interceptor stack). - + * [mrdon] For further reading: http://forums.opensymphony.com/thread.jspa?threadID=23621tstart=45 == Nice to haves == 1. Inheritance is not a good way to reuse code between actions. One work around is to use the strategy pattern to swap in different implementations of interfaces like `ValidationAware`. It would be nice if the framework had built-in support for mixins using cglib or Dynaop. For example, instead of extending a class that implements `ValidationAware`, SAF could extend an action class at runtime and implement the `ValidationAware` methods by delegating them to another object (a mixin): {{{ - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
[Struts Wiki] Update of RoughSpots by DonBrown
Dear Wiki user, You have subscribed to a wiki page or wiki category on Struts Wiki for change notification. The following page has been changed by DonBrown: http://wiki.apache.org/struts/RoughSpots -- * [jcarreira] I'm not sure about this... The Action interface is kind of just a marker interface, but at least it gives us SOMETHING to point users to * [crazybob] I'll buy that. We do need to move the constants out and encourage users to use static import (Effective Java Item 17). * [plightbo] Related to this, I would encourage us to try to find a solution (using Bob's mix-in suggestion below, or possibly just taking advantage of the value stack) that would make ActionSupport much simpler. This would encourage using POJOs more. + * [mrdon] Regardless whether we remove Action or not, I like the idea of moving the result constants out. 1. Only put classes in root package that most users need to know about. For example, most don't need to know about `Default*` or `ObjectFactory`. * [plightbo] +1 on this - sounds like Bob has a good handle on what it takes to make a nice API. I'll defer to him on this. + * [mrdon] +1 1. Only make classes/members public if we're willing to guarantee future compatibility. Everything else should be package-private or excluded from the Javadocs. * [plightbo] + 1 again. + * [mrdon] This I don't agree with. From a framework developer, I understand the logic, but from a user, it is arrogant. I think we should allow people to extend Struts in ways we haven't imagined, and restricting access like this says, We know more than you and will force you to do it our way. 1. Remove `destroy()` and `init()` from `Interceptor`. They don't make much sense until the interceptor lifecycle is specified (see next item). I've never needed them, yet it's a pain to implement empty methods every time I implement an interceptor. Users can use the constructor/finalizer or we can create additional lifecycle interfaces. @@ -45, +48 @@ * [jcarreira] The idea was that people would forget to do invocation.invoke() and be confused... Easier for users just to implement a before() method when that's all they need. I agree on the stack traces though. * [crazybob] It's kind of hard to forget to call `invocation.invoke()`; you have to return something. ;) Interceptors are already an expert feature anyway. * [plightbo] Big +1. + * [mrdon] +1 as well 1. Try to get rid of thread locals: `ActionContext` and `ServletActionContext`. At least make them package-private. Sometimes interceptors need access to the servlet API. In this case, they should implement a servlet-aware interceptor interface. For example: {{{ class MyInterceptor implements HttpInterceptor { @@ -58, +62 @@ * [jcarreira] These 2 are orthogonal... Getting rid of ThreadLocals is problematic. I think we'd end up breaking 90% of old WebWork apps if we did, and it's still not clear that everything could be covered if we did... I like the idea though, and Patrick and I really wanted to do this out of the gate, but backwards compatibility with WebWork 1.x at a macro-level made us think otherwise... * [crazybob] Interceptors need access to the servlet API. They shouldn't have to call a `ThreadLocal` if we can avoid it and they shouldn't need to cast. We shouldn't worry about breaking old WebWork apps (see new opening paragraphs). Let's get it right the first time around because we will not be able to fix it later. * [plightbo] By running our interceptors and other objects through the same factories and lifecycle managers that the action classes go through, this should be a non issue. + * [mrdon] This I'd like to see. I've found myself using these objects so often in wierd little places, I'd be loath to remove them unless we could prove 100% that their information can be retrieved elsewhere. 1. Is `ValidationAware` a good name? Perhaps `Errors` or `ErrorList` would be a better name. @@ -83, +88 @@ * [jcarreira] We don't want to allow for extension? * [crazybob] Extension through interfaces and methods? Yes. Public/protected fields? Absolutely not! + * [mrdon] I dunno, are you planning to make protected getters/setters for every field? I've found protected fields to be invaluable when extending frameworks (again, subscribing to the believe we should let the user do what they want and not artifically restrict them). I do wish you could declare the fields _only_ available to subclasses and not to the whole package. 1. Rename `ActionInvocation` to `Invocation` or `Request`. Shorter is better. @@ -92, +98 @@ 1. Is `TextProvider` a good name? The JDK refers to these as messages everywhere. * [plightbo] The name doesn't bother me, but the implementation is far