1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.krad.uif.view;
17
18 import java.io.Serializable;
19 import java.util.HashMap;
20 import java.util.HashSet;
21 import java.util.Map;
22 import java.util.Map.Entry;
23 import java.util.Set;
24
25 import org.apache.commons.lang.StringUtils;
26 import org.apache.log4j.Logger;
27 import org.kuali.rice.krad.uif.component.Component;
28 import org.kuali.rice.krad.uif.container.CollectionGroup;
29 import org.kuali.rice.krad.uif.container.Container;
30 import org.kuali.rice.krad.uif.field.DataField;
31 import org.kuali.rice.krad.uif.util.ComponentUtils;
32 import org.kuali.rice.krad.uif.util.LifecycleElement;
33 import org.kuali.rice.krad.uif.util.ViewCleaner;
34
35
36
37
38
39
40
41 public class ViewIndex implements Serializable {
42 private static final long serialVersionUID = 4700818801272201371L;
43
44 private static final Logger LOG = Logger.getLogger(ViewIndex.class);
45
46 private Map<String, Component> index;
47 private Map<String, DataField> dataFieldIndex;
48
49 private Map<String, CollectionGroup> collectionsIndex;
50 private Map<String, LifecycleElement> lifecycleElementsByPath;
51
52 private Set<String> idsToHoldInIndex;
53 private Set<String> assignedIds;
54
55
56
57
58 public ViewIndex() {
59 index = new HashMap<String, Component>();
60 dataFieldIndex = new HashMap<String, DataField>();
61 collectionsIndex = new HashMap<String, CollectionGroup>();
62 lifecycleElementsByPath = new HashMap<String, LifecycleElement>();
63 idsToHoldInIndex = new HashSet<String>();
64 assignedIds = new HashSet<String>();
65 }
66
67
68
69
70 protected void clearIndex(View view) {
71 index = new HashMap<String, Component>();
72 dataFieldIndex = new HashMap<String, DataField>();
73 collectionsIndex = new HashMap<String, CollectionGroup>();
74 lifecycleElementsByPath = new HashMap<String, LifecycleElement>();
75 }
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99 public void indexComponent(Component component) {
100 if (component == null) {
101 return;
102 }
103
104 synchronized (index) {
105 index.put(component.getId(), component);
106 }
107
108 synchronized (lifecycleElementsByPath) {
109 lifecycleElementsByPath.put(component.getViewPath(), component);
110 }
111
112 if (component instanceof Container) {
113 Container container = (Container) component;
114 if (container.getLayoutManager() != null) {
115 synchronized (lifecycleElementsByPath) {
116 lifecycleElementsByPath.put(container.getLayoutManager().getViewPath(),
117 container.getLayoutManager());
118 }
119 }
120 }
121
122 if (component instanceof DataField) {
123 DataField field = (DataField) component;
124
125 synchronized (dataFieldIndex) {
126 dataFieldIndex.put(field.getBindingInfo().getBindingPath(), field);
127 }
128 } else if (component instanceof CollectionGroup) {
129 CollectionGroup collectionGroup = (CollectionGroup) component;
130
131 synchronized (collectionsIndex) {
132 collectionsIndex.put(collectionGroup.getBindingInfo().getBindingPath(), collectionGroup);
133 }
134 }
135 }
136
137
138
139
140
141 public void clearIndexesAfterRender() {
142
143 for (Component component : index.values()) {
144 if (component == null) {
145 continue;
146 }
147
148 if (component.isDisableSessionPersistence()) {
149 continue;
150 }
151
152
153 if (component.isForceSessionPersistence() || ComponentUtils.canBeRefreshed(component) ||
154 (component instanceof CollectionGroup)) {
155 synchronized (idsToHoldInIndex) {
156 idsToHoldInIndex.add(component.getId());
157 }
158 }
159 }
160
161 Map<String, Component> holdComponentStates = new HashMap<String, Component>();
162 synchronized (index) {
163 for (Entry<String, Component> indexEntry : index.entrySet()) {
164 if (idsToHoldInIndex.contains(indexEntry.getKey())) {
165 Component component = indexEntry.getValue();
166
167 ViewCleaner.cleanComponent(component, this);
168 holdComponentStates.put(indexEntry.getKey(), component);
169 }
170 }
171 }
172 index = holdComponentStates;
173
174 for (CollectionGroup collectionGroup : collectionsIndex.values()) {
175 ViewCleaner.cleanComponent(collectionGroup, this);
176 }
177
178 dataFieldIndex.clear();
179 assignedIds.clear();
180 }
181
182
183
184
185
186
187
188
189 public boolean isIdForRefreshComponent(String componentId) {
190 return idsToHoldInIndex != null && idsToHoldInIndex.contains(componentId);
191 }
192
193
194
195
196
197
198
199 public Component getComponentById(String id) {
200 return index.get(id);
201 }
202
203
204
205
206
207
208
209 public DataField getDataFieldByPath(String propertyPath) {
210 return dataFieldIndex.get(propertyPath);
211 }
212
213
214
215
216
217
218
219
220 public DataField getDataFieldByPropertyName(String propertyName) {
221 DataField dataField = null;
222
223 for (DataField field : dataFieldIndex.values()) {
224 if (StringUtils.equals(propertyName, field.getPropertyName())) {
225 dataField = field;
226 break;
227 }
228 }
229
230 return dataField;
231 }
232
233
234
235
236
237
238 public Set<String> getAllDisplayedPropertyPaths() {
239 Set<String> propertyPaths = new HashSet<String>();
240
241 for (DataField field : dataFieldIndex.values()) {
242 if (field.isRender()) {
243 propertyPaths.add(field.getBindingInfo().getBindingPath());
244 }
245 }
246
247 return propertyPaths;
248 }
249
250 public Map<String, LifecycleElement> getLifecycleElements() {
251 return lifecycleElementsByPath;
252 }
253
254 public LifecycleElement getLifecycleElementByPath(String path) {
255 if ((lifecycleElementsByPath != null) && lifecycleElementsByPath.containsKey(path)) {
256 return lifecycleElementsByPath.get(path);
257 }
258
259 return null;
260 }
261
262
263
264
265
266
267
268 public Map<String, DataField> getDataFieldIndex() {
269 return this.dataFieldIndex;
270 }
271
272
273
274
275
276
277
278 public Map<String, CollectionGroup> getCollectionsIndex() {
279 return this.collectionsIndex;
280 }
281
282
283
284
285
286
287
288 public CollectionGroup getCollectionGroupByPath(String collectionPath) {
289 return collectionsIndex.get(collectionPath);
290 }
291
292
293
294
295
296
297
298 public boolean observeAssignedId(String id) {
299 if (assignedIds.contains(id)) {
300 return false;
301 }
302
303 synchronized (assignedIds) {
304 return assignedIds.add(id);
305 }
306 }
307
308
309
310
311
312
313 public ViewIndex copy() {
314 ViewIndex viewIndexCopy = new ViewIndex();
315
316 if (this.index != null) {
317 Map<String, Component> indexCopy = new HashMap<String, Component>();
318 for (Map.Entry<String, Component> indexEntry : this.index.entrySet()) {
319 if (indexEntry.getValue() instanceof View) {
320 LOG.warn("view reference at " + indexEntry);
321 } else {
322 indexCopy.put(indexEntry.getKey(), (Component) indexEntry.getValue().copy());
323 }
324 }
325
326 viewIndexCopy.index = indexCopy;
327 }
328
329 if (this.dataFieldIndex != null) {
330 Map<String, DataField> dataFieldIndexCopy = new HashMap<String, DataField>();
331 for (Map.Entry<String, DataField> indexEntry : this.dataFieldIndex.entrySet()) {
332 dataFieldIndexCopy.put(indexEntry.getKey(), (DataField) indexEntry.getValue().copy());
333 }
334
335 viewIndexCopy.dataFieldIndex = dataFieldIndexCopy;
336 }
337
338 if (this.collectionsIndex != null) {
339 Map<String, CollectionGroup> collectionsIndexCopy = new HashMap<String, CollectionGroup>();
340 for (Map.Entry<String, CollectionGroup> indexEntry : this.collectionsIndex.entrySet()) {
341 collectionsIndexCopy.put(indexEntry.getKey(), (CollectionGroup) indexEntry.getValue().copy());
342 }
343
344 viewIndexCopy.collectionsIndex = collectionsIndexCopy;
345 }
346
347 return viewIndexCopy;
348 }
349
350 }