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]