I'm writing a search engine to explore multiple search algorithms. The web portion floats on Struts 2.1.6 and Tiles 2.2.2. It's currently a complete mess, so below I've factored out a simplified version to focus on the exact problem I'm having.
The normal flow through the site is this:
- Searchform splash. Select a search algorithm and enter search parameters.
- Submit the form. The algorithm selection sets the action the form is submitted to.
- Results page. Includes a copy of the searchform at the top (the same searchform jsp code is used in both the splash and results).
The Problem: I want to add a search form variant. Variant 2 would submit to some of the same search algorithms as Variant 1, with the same results page, but of course I want the Variant 2 searchform to show up at the top for consistency. The new flow would be:
- Select a searchform. For Vanilla, goto 2. For Crazy, goto 3.
- Select a search algorithm from {A, B, C} and enter search parameters. Goto 4.
- Select a search algorithm from {B, C, D, E} and enter search parameters. Goto 4.
- Submit. Chain (using Struts "chain" resulttype**) to the appropriate search action for the selected algorithm.
- Display results. Include a copy of {Vanilla | Crazy} search form.
** The switch to "chain" is to allow more automated passing of algorithm parameters. The old way used hidden fields and was a huge pain to maintain with redirects, as you'll see in the struts.xml below.
So for the single variant I have something like this:
struts.xml:
<action name="SearchPage" class="nies.actions.search.SearchForm">
<result name="input">/Search.jsp</result>
</action>
<!-- List of available search algorithms to fill 'searcher' param above: -->
<action name="AlgorithmA" class="nies.actions.search.AlgorithmA">
<result name="success" type="tiles">Results</result>
<result name="input"type="redirectAction">
<param name="actionName">SearchPage</param>
<param name="namespace">/</param>
<param name="searchAlgorithm">AlgorithmA</param>
</result>
</action>
<action name="AlgorithmB" class="nies.actions.search.AlgorithmB">
<result name="success" type="tiles">Results</result>
<result name="input" type="redirectAction">
<param name="actionName">SearchPage</param>
<param name="namespace">/</param>
<param name="searchAlgorithm">AlgorithmB</param>
</result>
</action>
<action name="AlgorithmC" class="nies.actions.search.AlgorithmC">
<result name="success" type="tiles">Results</result>
<result name="input" type="redirectAction">
<param name="actionName">SearchPage</param>
<param name="namespace">/</param>
<param name="searchAlgorithm">AlgorithmC</param>
</result>
</action>
So what I plan to add is this:
struts.xml:
<action name="CrazySearchPage" class="nies.actions.search.CrazySearchForm">
<result name="input">/CrazySearch.jsp</result>
<result name="success" type="chain">${searcher}</result>
</action>
(probably switching the search input display for both search pages to tiles to save copypasta) (and nuking all the input redirect param crap for the search algorithms, since chaining automatically keeps those values on the stack)
...but now I'm hosed, because the chained actions shared by both SearchPage and CrazySearchPage all display in the Results tile:
tiles.xml:
<tiles-definitions>
<definition name="Results" template="/resultsTemplate.jsp">
<put-attribute name="tabPane" value="/resultsEagerTabPane.jsp"/>
</definition>
...
And the Results tile includes the regular searchform code used in the regular SearchPage:
resultsTemplate.jsp:
<%@ taglib prefix="s" uri="/struts-tags" %>
<%@ taglib prefix="tiles" uri="http://tiles.apache.org/tags-tiles" %>
<html>
<head>
<title><s:property value="query.queryString"/></title>
</head>
<body>
...
<div id="searchform">
<tiles:insertTemplate template="/searchform.jsp" flush="true"/>
</div>
...
I want to believe that by switching
<tiles:insertTemplate template="/searchform.jsp" flush="true"/>
to
<tiles:insertAttribute name="searchform" flush="true"/>
I can then either (1) make a new tile for CrazyResults that passes in the appropriate searchform jsp, or (B) find some way to pass in the tiles attribute based on which *SearchPage runs.
The problem with (1) is that the chained algorithm actions already go to the regular Results tile, and I don't want to disallow those algorithms from the regular SearchPage just so I can use them on the CrazySearchPage. I suppose I could define a duplicate set of algorithm actions for use by the CrazySearchPage, that call the same class with a different name and a different result, but this makes a mess in struts.xml and my other configuration files (I have extensive display settings associated with each action name).
The problem with (B) is that I've yet to find enough tiles documentation to tell me whether this is possible or not and how to do it. Struts and Tiles don't appear to talk to each other directly, they just pass notes.