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 import java.util.regex.Matcher;
31 import java.util.regex.Pattern;
32
33 import org.apache.tiles.Definition;
34
35 /***
36 * Matches definition patterns through the use of regular expressions. To allow the use of regular expression,
37 * remember to set the definition name with a tilde (~) as the first character.
38 *
39 * @param <T> The customization key class.
40 * @version $Rev: 823662 $ $Date: 2009-10-09 20:48:03 +0200 (ven, 09 ott 2009) $
41 * @since 2.2.0
42 */
43 public class RegexpPatternDefinitionResolver<T> implements
44 PatternDefinitionResolver<T> {
45
46 /***
47 * Maps a customization key to a pattern mapping list.
48 */
49 private Map<T, List<PatternMapping>> key2patternMappingList = new HashMap<T, List<PatternMapping>>();
50
51 /*** {@inheritDoc} */
52 public Definition resolveDefinition(String name, T customizationKey) {
53 Definition retValue = null;
54 List<PatternMapping> mappings = key2patternMappingList.get(customizationKey);
55 if (mappings != null) {
56 for (PatternMapping mapping : mappings) {
57 Matcher matcher = mapping.pattern.matcher(name);
58 if (matcher.matches()) {
59 int groupCount = matcher.groupCount() + 1;
60 Object[] vars = new Object[groupCount];
61 for (int i = 0; i < groupCount; i++) {
62 vars[i] = matcher.group(i);
63 }
64 retValue = PatternUtil.replacePlaceholders(mapping.definition, name, vars);
65 break;
66 }
67 }
68 }
69 return retValue;
70 }
71
72 /*** {@inheritDoc} */
73 public Map<String, Definition> storeDefinitionPatterns(Map<String, Definition> localeDefsMap,
74 T customizationKey) {
75 List<PatternMapping> patternMappingList = key2patternMappingList.get(customizationKey);
76 if (patternMappingList == null) {
77 patternMappingList = new ArrayList<PatternMapping>();
78 key2patternMappingList.put(customizationKey, patternMappingList);
79 }
80 return addRegexpMappings(localeDefsMap, patternMappingList);
81 }
82
83 /***
84 * Adds the regular expression mappings.
85 *
86 * @param localeDefsMap The map containing the definitions.
87 * @param patternMappingList The list of pattern mapping.
88 * @return The map of the definitions not recognized as containing
89 * definition patterns.
90 */
91 private Map<String, Definition> addRegexpMappings(Map<String, Definition> localeDefsMap,
92 List<PatternMapping> patternMappingList) {
93 Set<String> excludedKeys = new LinkedHashSet<String>();
94 for (Map.Entry<String, Definition> entry : localeDefsMap.entrySet()) {
95 String name = entry.getKey();
96 if (name.startsWith("~")) {
97 patternMappingList.add(new PatternMapping(name.substring(1),
98 new Definition(entry.getValue())));
99 } else {
100 excludedKeys.add(name);
101 }
102 }
103 return PatternUtil.createExtractedMap(localeDefsMap, excludedKeys);
104 }
105
106 /***
107 * Maps a pattern to a definition.
108 *
109 * @version $Rev: 823662 $ $Date: 2009-10-09 20:48:03 +0200 (ven, 09 ott 2009) $
110 * @since 2.2.0
111 */
112 private static final class PatternMapping {
113
114 /***
115 * The pattern.
116 */
117 private Pattern pattern;
118
119 /***
120 * The definition.
121 */
122 private Definition definition;
123
124 /***
125 * Constructor.
126 *
127 * @param regexp The regular expression for the pattern.
128 * @param definition The definition.
129 * @since 2.2.0
130 */
131 private PatternMapping(String regexp, Definition definition) {
132 pattern = Pattern.compile(regexp);
133 this.definition = definition;
134 }
135 }
136 }