Talking to Patrick offline about the "!" handling, we had a discussion of the direction we wanted to see things go. We were talking about our thoughts for reducing configuration. He favored a single interceptor stack method with annotations to specify parts to work or not work. My feeling is that this looses some of the power of implementing interceptors and interceptor stacks in the first place, and still leaves us with needing to specify (somehow) results, etc.
My idea was one I've touched on briefly before, but I wanted to write it up in a bit more detail now. The idea is simple: In most apps, 90+% of actions will fall into one of a few "types" which will have very similar configuration. If we can pull these commonalities out into what I was calling "architypes", then we can just specify which archetype an action is, perhaps via an annotation, and not need any further configuration for that action. As an example, here's a set of CRUD actions from our app: <package name="country" extends="orgListers, crud" namespace="/country"> <action name="listCountry" class="com.eplus.app.country.action.CountryCrudAction" method="list"> <interceptor-ref name="listStack"/> <result name="CRUD-list" type="freemarker">/template/eplus/metaDataList.ftl</result> </action> <action name="editCountry" class="com.eplus.app.country.action.CountryCrudAction"> <interceptor-ref name="editStack"/> </action> <action name="saveCountry" class="com.eplus.app.country.action.CountryCrudAction" method="save"> <interceptor-ref name="crudStack"/> </action> <action name="deleteCountry" class="com.eplus.app.country.action.CountryCrudAction" method="delete"> <interceptor-ref name="crudStack"/> </action> <action name="importCountry" class="importCountryAction"> <interceptor-ref name="importStartStack"/> <param name="successRedirectAction">/country/listCountry.action</param> <result name="success" type="freemarker">/template/eplus/files/fileUpload.ftl</result> </action> </package> These configurations are largely the same across all entities in our app. They don't have to specify many results because these are mostly defined in a parent package as global results which are parameterized by the entity name: <global-results> <!-- input is needed for when validation fails. --> <result name="input" type="freemarker">/template/eplus/${simpleName}_Crud.ftl</result> <result name="CRUD-create" type="freemarker">/template/eplus/${simpleName}_Crud.ftl</result> <result name="CRUD-edit" type="freemarker">/template/eplus/${simpleName}_Crud.ftl</result> <result name="CRUD-list" type="freemarker">/template/eplus/${simpleName}_List.ftl</result> <result name="CRUD-entityCreated" type="redirect">list${simpleName}.action</result> <result name="CRUD-entitySaved" type="redirect">list${simpleName}.action</result> <result name="CRUD-entityDeleted" type="redirect">list${simpleName}.action</result> </global-results> If we were to define archetypes, the results could likewise be specified globally, and could also have the corresponding interceptor stack associated. Then the method could look like this: @ActionArchetype(type = "list", name="listCountry") String list() { ... } Depending on how we wanted to do this, we could have the dispatcher, or some other class that runs at startup, look through the whole classpath for classes with these annotations and auto-register them. The only configuration left is to set up the archetypes and any special actions which don't fit in one of these common buckets. We retain the power of customized interceptor stacks for different functions without the pain of manual configuration (which isn't even that bad when they're mostly cut-and-paste of the same thing, but still). Thoughts? I'm probably not going to have time to implement this for the next few months, but Patrick thought I should throw the idea out there, so here it is... --------------------------------------------------------------------- Posted via Jive Forums http://forums.opensymphony.com/thread.jspa?threadID=41559&messageID=82945#82945 --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]