1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package org.apache.tiles.definition.pattern;
23
24 import java.util.ArrayList;
25 import java.util.HashMap;
26 import java.util.LinkedHashSet;
27 import java.util.List;
28 import java.util.Map;
29 import java.util.Set;
30
31 import org.apache.tiles.Definition;
32 import org.apache.tiles.util.WildcardHelper;
33
34 /***
35 * Uses wildcards syntax to match definition names and its parameters.
36 *
37 * @param <T> The type of the customization key.
38 * @version $Rev: 823662 $ $Date: 2009-10-09 20:48:03 +0200 (ven, 09 ott 2009) $
39 * @since 2.2.0
40 */
41 public class WildcardPatternDefinitionResolver<T> implements
42 PatternDefinitionResolver<T> {
43
44 /***
45 * Stores patterns depending on the locale they refer to.
46 *
47 * @since 2.2.0
48 */
49 private Map<T, List<WildcardMapping>> localePatternPaths =
50 new HashMap<T, List<WildcardMapping>>();
51
52 /***
53 * An object that helps in resolving definitions with wildcards.
54 *
55 * @since 2.2.0
56 */
57 private WildcardHelper wildcardHelper = new WildcardHelper();
58
59 /*** {@inheritDoc} */
60 public Definition resolveDefinition(String name, T customizationKey) {
61 Definition retValue = null;
62 if (localePatternPaths.containsKey(customizationKey)) {
63 retValue = resolveWildcardDefinition(localePatternPaths
64 .get(customizationKey), name);
65 }
66 return retValue;
67 }
68
69 /*** {@inheritDoc} */
70 public Map<String, Definition> storeDefinitionPatterns(Map<String, Definition> localeDefsMap,
71 T customizationKey) {
72 List<WildcardMapping> lpaths = localePatternPaths
73 .get(customizationKey);
74 if (lpaths == null) {
75 lpaths = new ArrayList<WildcardMapping>();
76 localePatternPaths.put(customizationKey, lpaths);
77 }
78
79 return addWildcardPaths(lpaths, localeDefsMap);
80 }
81
82 /***
83 * Adds wildcard paths that are stored inside a normal definition map.
84 *
85 * @param paths The list containing the currently stored paths.
86 * @param defsMap The definition map to parse.
87 * @return The map of the definitions not recognized as containing
88 * definition patterns.
89 */
90 private Map<String, Definition> addWildcardPaths(List<WildcardMapping> paths,
91 Map<String, Definition> defsMap) {
92 Set<String> excludedKeys = new LinkedHashSet<String>();
93 for (Map.Entry<String, Definition> de : defsMap.entrySet()) {
94 String key = de.getKey();
95 if (key.indexOf('*') != -1) {
96 paths.add(new WildcardMapping(key,
97 new Definition(de.getValue())));
98 } else {
99 excludedKeys.add(key);
100 }
101 }
102 return PatternUtil.createExtractedMap(defsMap, excludedKeys);
103 }
104
105 /***
106 * Try to resolve a wildcard definition.
107 *
108 * @param paths The list containing the currently stored paths.
109 * @param name The name of the definition to resolve.
110 * @return A definition, if found, or <code>null</code> if not.
111 */
112 private Definition resolveWildcardDefinition(
113 List<WildcardMapping> paths, String name) {
114 Definition d = null;
115
116 for (WildcardMapping wm : paths) {
117 List<String> vars = wildcardHelper.match(name, wm.getPattern());
118 if (vars != null) {
119 d = PatternUtil.replacePlaceholders(wm.getDefinition(), name, vars.toArray());
120 break;
121 }
122 }
123
124 return d;
125 }
126
127 /***
128 * Maps a pattern with a definition in cache.
129 *
130 * @since 2.2.0
131 */
132 private class WildcardMapping {
133
134 /***
135 * The compiled pattern.
136 */
137 private int[] pattern;
138
139 /***
140 * The definition that matches the pattern.
141 */
142 private Definition definition;
143
144 /***
145 * Constructor.
146 *
147 * @param pattern The compiled pattern.
148 * @param definition A definition that matches the pattern.
149 *
150 * @since 2.2.0
151 */
152 public WildcardMapping(String pattern, Definition definition) {
153 this.pattern = wildcardHelper.compilePattern(pattern);
154 this.definition = definition;
155 }
156
157 /***
158 * Returns the definition.
159 *
160 * @return The definition.
161 * @since 2.2.0
162 */
163 public Definition getDefinition() {
164 return definition;
165 }
166
167 /***
168 * Returns the compiled pattern.
169 *
170 * @return The pattern.
171 * @since 2.2.0
172 */
173 public int[] getPattern() {
174 return pattern;
175 }
176 }
177 }