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.dao;
23
24 import java.util.HashSet;
25 import java.util.LinkedHashMap;
26 import java.util.Locale;
27 import java.util.Map;
28 import java.util.Set;
29
30 import org.apache.tiles.Definition;
31 import org.apache.tiles.definition.NoSuchDefinitionException;
32 import org.apache.tiles.request.ApplicationContext;
33 import org.slf4j.Logger;
34 import org.slf4j.LoggerFactory;
35
36
37
38
39
40
41
42
43
44
45
46
47
48 public class ResolvingLocaleUrlDefinitionDAO extends
49 CachingLocaleUrlDefinitionDAO {
50
51
52
53
54 private final Logger log = LoggerFactory.getLogger(ResolvingLocaleUrlDefinitionDAO.class);
55
56 public ResolvingLocaleUrlDefinitionDAO(ApplicationContext applicationContext) {
57 super(applicationContext);
58 }
59
60
61 @Override
62 protected Map<String, Definition> loadParentDefinitions(Locale parentLocale) {
63 return loadRawDefinitionsFromResources(parentLocale);
64 }
65
66 @Override
67 protected Map<String, Definition> loadDefinitions(Locale customizationKey) {
68 Map<String, Definition> localeDefsMap = super.loadDefinitions(customizationKey);
69 Map<String, Definition> defsMap = definitionResolver
70 .storeDefinitionPatterns(copyDefinitionMap(localeDefsMap),
71 customizationKey);
72 resolveInheritances(defsMap, customizationKey);
73 locale2definitionMap.put(customizationKey, defsMap);
74 return defsMap;
75 }
76
77
78 @Override
79 protected Definition getDefinitionFromResolver(String name,
80 Locale customizationKey) {
81 Definition retValue = super.getDefinitionFromResolver(name, customizationKey);
82 if (retValue != null && retValue.getExtends() != null) {
83 Definition parent = getDefinition(retValue.getExtends(), customizationKey);
84 retValue.inherit(parent);
85 }
86
87 return retValue;
88 }
89
90
91
92
93
94
95
96
97
98 protected void resolveInheritances(Map<String, Definition> map, Locale locale) {
99 if (map != null) {
100 Set<String> alreadyResolvedDefinitions = new HashSet<String>();
101 for (Definition definition : map.values()) {
102 resolveInheritance(definition, map, locale,
103 alreadyResolvedDefinitions);
104 }
105 }
106 }
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123 protected void resolveInheritance(Definition definition,
124 Map<String, Definition> definitions, Locale locale,
125 Set<String> alreadyResolvedDefinitions) {
126
127 if (!definition.isExtending()
128 || alreadyResolvedDefinitions.contains(definition.getName())) {
129 return;
130 }
131
132 log.debug("Resolve definition for child name='{}' extends='{}.",
133 definition.getName(), definition.getExtends());
134
135
136 alreadyResolvedDefinitions.add(definition.getName());
137
138
139 Definition parent = definitions.get(definition.getExtends());
140 if (parent == null) {
141 String msg = "Error while resolving definition inheritance: child '"
142 + definition.getName()
143 + "' can't find its ancestor '"
144 + definition.getExtends()
145 + "'. Please check your description file.";
146
147 throw new NoSuchDefinitionException(msg);
148 }
149
150 resolveInheritance(parent, definitions, locale,
151 alreadyResolvedDefinitions);
152
153 definition.inherit(parent);
154 }
155
156
157
158
159
160
161
162
163
164
165 @Override
166 protected Map<String, Definition> copyDefinitionMap(
167 Map<String, Definition> localeDefsMap) {
168 Map<String, Definition> retValue = new LinkedHashMap<String, Definition>(
169 localeDefsMap.size());
170
171 for (Map.Entry<String, Definition> entry : localeDefsMap.entrySet()) {
172 Definition definition = new Definition(entry.getValue());
173 retValue.put(entry.getKey(), definition);
174 }
175
176 return retValue;
177 }
178 }