[
https://issues.apache.org/jira/browse/TILES-569?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Mck SembWever closed TILES-569.
-------------------------------
Resolution: Won't Fix
This is indeed how OptionsRenderer was first implemented, and how that tutorial
was originally written.
Amongst ~100 developers in house it wasn't so popular.
It made the xml different to read, and contained a lot of duplicate
configuration. Hundreds of lines in the xml repeated the same conditional.
Upgrading the conditional was also painful and error-prone.
For these reasons: readability, configuration-reuse, safety; it was rewritten
so the list of conditions were instead kept in defined lists. When these lists
are well named it allows for more readable configuration. The response in house
was overwhelmingly positive.
Personally I have no interest in going back to that style.
Though I'd be happy to accept any contribution that allows both styles to
co-exist. Here it would be nice to see the underlying mechanism to both styles
using the same code.
> Proposal for conditionals in tiles definitions
> ----------------------------------------------
>
> Key: TILES-569
> URL: https://issues.apache.org/jira/browse/TILES-569
> Project: Tiles
> Issue Type: Improvement
> Components: tiles-core
> Affects Versions: 3.0.1
> Reporter: Marc Ewert
>
> Hi,
> I've recently tried the OptionsRenderer suggested in this tutorial
> [http://tech.finn.no/2012/07/25/the-ultimate-view-tiles-3/4/], but wasn't
> able to succeed. The defined attributes wasn't available for some reason.
> So I took the idea and implemented my own solution. Perhaps it's something
> for the trunk? My syntax is as follows:
> {code}
> <tiles-definitions>
> <definition name="main/*/*" template="/WEB-INF/tiles/_layout/main.jsp">
> <put-attribute name="title"
> value="/WEB-INF/tiles/[{1}/{2}|{1}|_common]/title.jsp"/>
> <put-attribute name="navigation"
> value="/WEB-INF/tiles/[{1}/{2}|{1}|_common]/navigation.jsp"/>
> <put-attribute name="content"
> value="/WEB-INF/tiles/[{1}/{2}|{1}|_common]/content.jsp"/>
> <put-attribute name="footer"
> value="/WEB-INF/tiles/[{1}/{2}|{1}|_common]/footer.jsp"/>
> <put-attribute name="javaScript"
> value="/WEB-INF/tiles/[{1}/{2}|{1}|_common]/javaScript.jsp"/>
> </definition>
> </tiles-definitions>
> {code}
> The renderer searches for patterns like [opt_1|opt_2|...|opt_n] which may
> occur several times in the value partameters. With a backtrack algorithm the
> first matching valid path is searched and rendered.
> I like the compactness of the notation, no need for attribute lists, which
> didn't function in my case.
> Here is my renderer implementation, perhaps you are interested in integrating
> it. The path evaluation eventually has to be refactored. I don't know if
> there is a more elegant way and how costly the current solution is. Perhaps
> there has to be done some caching...
> {code}
> /**
> * Renderer implementation supporting the notation "[CHOICE_1|...|CHOICE_n]"
> in the paths.
> * The first matching path replacement will be choosen.
> */
> public final class ChoiceRenderer implements Renderer {
> private static final Pattern CHOICE_PATTERN =
> Pattern.compile("\\[([^\\]]+)\\]");
> private final Renderer renderer;
> /**
> * Creates a new instance wrapping the given renderer.
> */
> public ChoiceRenderer(Renderer renderer) {
> this.renderer = renderer;
> }
> /**
> * @see
> org.apache.tiles.request.render.Renderer#isRenderable(java.lang.String,
> org.apache.tiles.request.Request)
> */
> @Override
> public boolean isRenderable(String path, Request request) {
> // only the overall format is checked, so no extra handling here
> return this.renderer.isRenderable(path, request);
> }
> /**
> * @see org.apache.tiles.request.render.Renderer#render(java.lang.String,
> org.apache.tiles.request.Request)
> */
> @Override
> public void render(String path, Request request) throws IOException {
> Matcher matcher = CHOICE_PATTERN.matcher(path);
> List<String[]> groups = new ArrayList<String[]>();
> StringBuffer sb = new StringBuffer();
> while (matcher.find()) {
> // adds a pattern to the resulting path, which will be replaced
> by the
> // available choices
> matcher.appendReplacement(sb, "{[" + groups.size() + "]}");
> groups.add(matcher.group(1).split("\\|"));
> }
> matcher.appendTail(sb);
> if (groups.isEmpty()) {
> this.renderer.render(path, request);
> } else {
> backtrackPaths(sb.toString(), request, groups, 0);
> }
> }
> private String backtrackPaths(String pathPattern, Request request,
> List<String[]> groups, int depth)
> throws IOException {
> String matchPath = null;
> String[] parts = groups.get(depth);
> for (int i = 0; i < parts.length; ++i) {
> String path = pathPattern.replace("{[" + depth + "]}", parts[i]);
> if (depth == groups.size() - 1) {
> if (isPathValid(path, request)) {
> // found the first matching choice
> this.renderer.render(path, request);
> matchPath = path;
> break;
> }
> } else {
> matchPath = backtrackPaths(path, request, groups, depth + 1);
> }
> }
> return matchPath;
> }
> // TODO should we use caching here?
> private boolean isPathValid(String path, Request request) {
> boolean rtn = false;
> // apparently the corresponding Renderer method seems to check the
> // path's format only
> if (this.renderer.isRenderable(path, request)) {
> try {
> rtn = request.getApplicationContext().getResource(path) !=
> null;
> } catch (IllegalArgumentException e) {
> // TODO the javadoc states that null will be returned, but
> // instead of it an exception is thrown.
> // Seems to be a bug?!
> boolean throwException = true;
> if (e.getCause() instanceof FileNotFoundException) {
> FileNotFoundException fex = (FileNotFoundException)
> e.getCause();
> throwException = fex.getMessage().indexOf(path) == -1;
> }
> if (throwException) {
> // seems to be a different reason as our searched path
> throw e;
> }
> }
> }
> return rtn;
> }
> }
> {code}
--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira