[Struts Wiki] Update of RoughSpots by JasonCarreira
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 JasonCarreira: http://wiki.apache.org/struts/RoughSpots -- 1. Do we want to keep `ModelDriven`? * [Gabe] Absolutely YES! `ModelDriven` allows us to build forms and populate the model without a prefix. It's simple. It also allows for security interceptors to zero in on one method for `ModelDriven` actions to determine what to secure. * [plightbo] I think we should give some serious thought to this. Look around the internal implementation of WebWork/XWork as well as the number of questions that come up on the mailing lists. It's a very confusing thing, especially when interacting with setting or getting values of form fields. + * [jcarreira] yes, it makes the internal implementation more complex, but it makes things easier for the user of the framework in a lot of cases. If people are confused by it, they can choose not to use it. 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? @@ -266, +267 @@ 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. * [plightbo] +1. we should keep this in mind when designing the API. + * [jcarreira] -1 to using the HttpServletRequest... Why do we need it? We've got a nice abstraction with the Maps for parameters, session, and application scopes, I think. Why tie to the servlet API and make a phony one to proxy to Portlets? 1. Add action and method attributes to the submit button tag so users don't have to know about the action:Name and method:name conventions. * [plightbo] We already do this :) @@ -296, +298 @@ * [jcarreira] I think we should have some pre-defined ones for standard things: view vs. CRUD vs. action - do somthing that's not CRUD. We should then use annotations to make it where you can declaratively associate a particular action method with a stereotype which is mapped to an interceptor stack, etc. * [crazybob] C[R]UD isn't a good name because view == [R]etrieve. Let's call it update for the moment. What will the difference be between update and action? * [plightbo] I really don't think having a update and action stack is a good idea. Let's make a single stack and then have the stack behave differently depending on the context in which the action was executed. There are several options (GET vs POST, method names, annotations, etc). + * [jcarreira] I really think this is a bad idea and will lead to great suffering... We put in interceptors to allow people to customize the processing of a request, why move away from that now? I think if we do some thinking we can think of the common use-cases that cover 80+% of the action cases, and make it very easy for an action developer to tag this action as using one of that small number of stereotypical uses. The action will then pick up the configuration set up for that stereotype (which could include things like defaulting the result pages to go to, etc.) == Gabe's Issues == 1. Simpler XML Configuration of actions. Ted mentioned adding wildcard support for action names something like name=view* where the wildcard can then be used elsewhere as a variable. Another idea is allowing one action configuration to extend another or having default action configuration that other action configurations can use. 1. Add the possibility of setting to the OgnlValueStack rather than pushing so we can get rid of using the context for user app variables and reserve it for framework variables. The user then wouldn't need to know anything about the context, just the stack. Also, this allows us to get rid of the '#' sign completely in expressions. Similarly remove the
[Struts Wiki] Update of RoughSpots by JasonCarreira
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 JasonCarreira: http://wiki.apache.org/struts/RoughSpots -- * [jcarreira] We've implemented this at work with WebWork fileupload + DWR + a class that looks at the file as it's uploading to see how big it is on disk * [frankz] Just an opinion, but this seems to me too specific a use case for a framework to encapsulate. I think having an example showing how to do it, perhaps what jcarreira has done at work, would be great, but I for one wouldn't like the framework offering this out of the box... I think it is possible for a framework to be able to do TOO much! * [tm_jee] I think this is pretty use case specific as well, but a progress monitor ui component would be nice. + * [jcarreira] If we agree that supporting file uploads out of the box is important, then this is just a nice feature for that support to let the user know how much of the file has been uploaded, etc. 1. Better error checking for UI tags. The freemarker error message, while great for freemarker users, look like gibberish. People should not be forced to learn freemarker. So in such cases, the tags themselves should check the parameters and report back sane messages, even if that check is duplicated in the templates @@ -280, +281 @@ 1. Specify and simplify Interceptor scope. Currently, you have an Interceptor that calls actionInvocation.invoke() and then returns a different result than actionInvocation.invoke() returns, the actionInvocation.invoke() result will be used anyway. This is confusing and muddies the meaning of the Interceptor API, which IMHO should simply wrap the action not the action all the way through to the end of the result. The reason it's set up the way it is, as I understand it, is so that Interceptors can clean up resources like connections after the result is returned. However, I wonder if we can implement a request based object that can take care of such resources and destroy them at the end of the request rather than using Interceptors in this way. * [crazybob] That was really surprising and confusing to me at first, too. I thought it would have been more intuitive for the result to run after all the interceptors returned. I'm not sure whether we should change it or not. I like the idea of interceptors being able to clean up after results a lot more than I like the idea of an interceptor being able to return a different result. * [Gabe] It is an advantage for Interceptors to be able to clean up at the end of a request, but it isn't great how they do that either. Take for example an action chain. If you have a create connection Interceptor surrounding each of the chained actions, you will open two connections, which besides being wasteful could cause problems with other resource types. I wonder if we can create some sort of request scoped ResourceManager class that can allow Interceptors to create resources or access them if they exist and specify how they should be destroyed at the end of the request. Thus in the connection case, the Interceptor could check if the resource manager had one and if not create it and add it to the resource manager for other objects to use. (Another option of course is an inversion of control approach) + * [jcarreira] Interceptors can still change the result... Implement PreResultListener and in your callback, change the resultCode and voila! The result executed will be changed. The PreResultListener interface lets you register your interceptor to get a callback after the action and before the result is executed. Oh, and on the ConnectionInterceptor - It's just like AOP. You have to check if it's been done already and know not to create a new one or close it on the way out. I do this all the time in AOP interceptors, so why should this be different? Personally, I'd rather use the same connection across all of the actions in a chain than clean it up after each one and use a new one per action. For request scoped resources, take a look at Spring's scoped components. I'm using them at work and they work pretty well (a few issues I'm working through with them notwithstanding). == Tim's Issues == 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. @@ -288, +290 @@ * [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
[Struts Wiki] Update of RoughSpots by JasonCarreira
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 JasonCarreira: http://wiki.apache.org/struts/RoughSpots -- * [Gabe] I've created an XWork JIRA for a solution to the same use case here. [http://jira.opensymphony.com/browse/XW-387] I'd be happy to contribute the code. 1. Allow paths in action names. For example `action name=reports/myreport`. + * [jcarreira] Why do you want this? Isn't this part of the namespace of the action? 1. Enable Java package import in configuration so you don't have to repeat the same package name over and over (like WW1 does). + * [jcarreira] +1 if it can be made sane... It can get confusing. It also makes tool support worse (i.e. IDEA can find it as a fully qualified class name) 1. The ajax support is pitiful. Have a look at how stripes does it. Ajax for validation is trivial and not that impressive, but people are going to want to do real ajax work, and webwork does absolutely nothing to help in that regard. I'd like to for example be able to easily invoke actions and get at some kind of result to display, and have webwork provide at least some of the wiring + * [jcarreira] Well, that's a relatively simple usecase, and I think it IS supported... at least we use it at work? 1. The default theme for the ui tags should be simple. The current stuff is too dumb to get right on the first go, which gives an awful impression. It's NOT intuitive to write: {{{ table ww:textfield label=Enter blah / /table }}} + * [jcarreira] That depends on whether you're using the form tag or not, but agreed... the XHTML theme should be cleaned up and made the default. 1. File upload should support progress notification. Have a look at webwork-multipart on java.net, it's based on the pell parser but has a progress API. + * [jcarreira] We've implemented this at work with WebWork fileupload + DWR + a class that looks at the file as it's uploading to see how big it is on disk 1. Better error checking for UI tags. The freemarker error message, while great for freemarker users, look like gibberish. People should not be forced to learn freemarker. So in such cases, the tags themselves should check the parameters and report back sane messages, even if that check is duplicated in the templates 1. Defaults should be JSP all the way. People know it and like it, despite all the limitations. Allow for other view technologies, but don't force people to learn stuff they don't want to. Learning ww is enough of a pain as it is 1. Get rid of the validation framework. it's stupid and pointless, validate methods are good enough. + * [jcarreira] -1 I take offense at this... It's neither stupid NOR pointless, and we use it extensively. It's the best validation framework I've seen out there, and NO, validate methods are NOT enough. For instance, we define reusable validations for our domain models and use them for both the web front end as well as web services and batch imports. 1. Ditch xwork as a separate project, nobody uses it or cares about it + * [jcarreira] You're kidding, right? We've discussed this already 1. Add java5 support to ognl. It's silly that it still doesn't handle enums (that I know of). + * [jcarreira] +1 this is biting us right now 1. Clean up documentation. Focus on quality not quantity. + * [jcarreira] Didn't you read the book? ;-) == Patrick's issues == @@ -187, +196 @@ * [jcarreira] +1 : Carlos at G**gle had some good ideas for this... basically stuff like if your action method is foo() then you'd have prepareFoo() and validateFoo(), but then I added that the prepare() and validate() methods should be the defaults that we call for all action methods. * [crazybob] Interesting idea. Might be overkill (i.e. at that point, the user should probably create another action class). * [hani] No magic method names. If you want to do that, use annotations so you have a good chance of IDE support dealing with it. For example @Validate/@Prepare etc, with parameters to indicate what request you'd like it involved for, in the case where you need multiples of them + * [jcarreira] I think RoR has shown that convention over configuration is liked by lots of people... these should be straightforward to figure out without annotations. + 1. Don't encourage lots of interceptor stacks. Ideally the normal user should never need to deal with them. It is better to have a larger stack that has optional features that could be turned on through annotations or marker interfaces than to encourage users to build their own stacks. * [jcarreira] I think we should have some pre-defined ones for standard things: view vs. CRUD vs. action - do
[Struts Wiki] Update of RoughSpots by JasonCarreira
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 JasonCarreira: http://wiki.apache.org/struts/RoughSpots -- 1. We don't really need the `Action` interface anymore. Should we get rid of it? It has constant fields for result names. Should we move these to a class named `ResultNames` and encourage users to static import them as needed? + [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 + 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`. 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. @@ -21, +23 @@ 1. Specify `Interceptor` lifecycle. Right now if we apply an interceptor to a single action, we get a new instance every time. If we define an interceptor in a stack, the same instance gets reused. + [jcarreira] A new instance per action configuration, right? Not per-invocation... + 1. Get rid of `AroundInterceptor`. Having `before()` and `after()` methods doesn't make things simpler. It reduces flexibility. We can't return a different result. You can't handle exceptions cleanly. The actual interceptor class doesn't appear in the stack trace (we see `AroundInterceptor` over and over). + + [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. 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 { @@ -32, +38 @@ } }}} + [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... + 1. Is `ValidationAware` a good name? Perhaps `Errors` or `ErrorList` would be a better name. 1. Merge `ActionContext` and `ActionProxy` into `ActionInvocation` (at least from the users' perspective). Better specify what happens during chaining/action tags. + [jcarreira] It __is__ well specified... There are some things that the ActionProxy / ActionInvocation let you do that a merged one doesn't... for instance easily knowing when you're done :-) + 1. Should `ActionInvocation.getResult()` recurse over chain results? Maybe we should have two methods? `getResult()` and `getFinalResult()`. Is there a good use case for this? + + [jcarreira] See the TokenSessionInterceptor and the stuff it does to re-render the same result if you post the form more than once. That was the reason for the complexity in finding the result to execute. It's a nice feature, but I agree it makes the code harder to read. 1. `ActionInvocation.invokeActionOnly()`. Does this need to be public? Sounds dangerous. + [jcarreira] Not sure... This may be part of the same TokenSession stuff... can't remember exactly. + 1. Eliminate non-private fields. Protected fields in `ActionConfig` for example. + [jcarreira] We don't want to allow for extension? + 1. Rename `ActionInvocation` to `Invocation` or `Request`. Shorter is better. + + [jcarreira] Most users don't see these... Let's not change names on a whim, since it will be more work for the power users who already use them. 1. Is `TextProvider` a good name? The JDK refers to these as messages everywhere. 1. Come up with a clean way to separate view actions from update actions. For example, we might have `view()` and `update()` methods in the same action class. Right now XWork has `MethodFilterInterceptor`, but that's not a very clean solution. Do we want validation or the `DefaultWorkflowInterceptor` to run for the `view()` method? One solution is separate interceptor stacks, but it would be nice if there were some first class support for this. We could flag action invocations as view or update (using an enum). We could automatically choose a mode based on whether the request is an HTTP GET or POST. Or we could set the mode based on an annotation on the action method. Or some other way... + + [jcarreira] This is where I think the power of annotations can be
[Struts Wiki] Update of RoughSpots by JasonCarreira
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 JasonCarreira: http://wiki.apache.org/struts/RoughSpots -- [jcarreira] You had me until the abstract class bit... Does it have to be abstract? Also, this limits testability in not-ok-ways... + + == What JDK Version? == + + [jcarreira] We've been using JDK 1.5 on Tomcat 5+ for over a year... Everything we write and wire together is using generics and annotations. + - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]