1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.krad.datadictionary.uif;
17
18 import java.util.ArrayList;
19 import java.util.HashMap;
20 import java.util.List;
21 import java.util.Map;
22 import java.util.Map.Entry;
23
24 import org.apache.commons.lang.StringUtils;
25 import org.apache.commons.logging.Log;
26 import org.apache.commons.logging.LogFactory;
27 import org.kuali.rice.core.api.config.property.ConfigContext;
28 import org.kuali.rice.krad.datadictionary.DataDictionaryException;
29 import org.kuali.rice.krad.datadictionary.DefaultListableBeanFactory;
30 import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
31 import org.kuali.rice.krad.uif.UifConstants;
32 import org.kuali.rice.krad.uif.UifConstants.ViewType;
33 import org.kuali.rice.krad.uif.service.ViewTypeService;
34 import org.kuali.rice.krad.uif.util.ComponentUtils;
35 import org.kuali.rice.krad.uif.util.ViewModelUtils;
36 import org.kuali.rice.krad.uif.view.View;
37 import org.kuali.rice.krad.util.KRADConstants;
38 import org.springframework.beans.PropertyValues;
39 import org.springframework.beans.factory.config.BeanDefinition;
40
41
42
43
44
45
46
47
48
49
50
51
52 public class UifDictionaryIndex implements Runnable {
53 private static final Log LOG = LogFactory.getLog(UifDictionaryIndex.class);
54
55 private static final int VIEW_CACHE_SIZE = 1000;
56
57 private DefaultListableBeanFactory ddBeans;
58
59
60 private Map<String, String> viewBeanEntriesById;
61
62
63 private Map<String, ViewTypeDictionaryIndex> viewEntriesByType;
64
65
66 protected Map<String,View> viewCache = new HashMap<String, View>(VIEW_CACHE_SIZE);
67
68 public UifDictionaryIndex(DefaultListableBeanFactory ddBeans) {
69 this.ddBeans = ddBeans;
70 }
71
72 @Override
73 public void run() {
74 buildViewIndicies();
75 }
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90 public View getViewById(String viewId) {
91 View cachedView = viewCache.get(viewId);
92 if ( cachedView == null ) {
93 if ( LOG.isDebugEnabled() ) {
94 LOG.debug( "View " + viewId + " not in cache - creating and storing to cache");
95 }
96
97 String beanName = viewBeanEntriesById.get(viewId);
98 if (StringUtils.isBlank(beanName)) {
99 throw new DataDictionaryException("Unable to find View with id: " + viewId);
100 }
101
102 View newView = ddBeans.getBean(beanName, View.class);
103
104 boolean inDevMode = ConfigContext.getCurrentContextConfig().getBooleanProperty(
105 KRADConstants.ConfigParameters.KRAD_DEV_MODE);
106
107 if (!inDevMode) {
108 synchronized (viewCache) {
109 viewCache.put(viewId, newView);
110 }
111 }
112
113 cachedView = newView;
114 } else {
115 if ( LOG.isDebugEnabled() ) {
116 LOG.debug("Pulled view " + viewId + " from Cache. Cloning..." );
117 }
118 }
119
120 View clonedView = ComponentUtils.copy(cachedView);
121
122 return clonedView;
123 }
124
125
126
127
128
129
130
131
132 public View getImmutableViewById(String viewId) {
133
134 View cachedView = viewCache.get(viewId);
135
136
137
138
139 if ( cachedView == null ) {
140 return getViewById(viewId);
141 }
142
143 return cachedView;
144 }
145
146
147
148
149
150
151
152
153
154
155
156
157 public View getViewByTypeIndex(ViewType viewTypeName, Map<String, String> indexKey) {
158 String viewId = getViewIdByTypeIndex(viewTypeName, indexKey);
159 if (StringUtils.isNotBlank(viewId)) {
160 return getViewById(viewId);
161 }
162
163 return null;
164 }
165
166
167
168
169
170
171
172
173
174 public String getViewIdByTypeIndex(ViewType viewTypeName, Map<String, String> indexKey) {
175 String index = buildTypeIndex(indexKey);
176
177 ViewTypeDictionaryIndex typeIndex = getTypeIndex(viewTypeName);
178
179 return typeIndex.get(index);
180 }
181
182
183
184
185
186
187
188
189
190 public boolean viewByTypeExist(ViewType viewTypeName, Map<String, String> indexKey) {
191 boolean viewExist = false;
192
193 String index = buildTypeIndex(indexKey);
194 ViewTypeDictionaryIndex typeIndex = getTypeIndex(viewTypeName);
195
196 String viewId = typeIndex.get(index);
197 if (StringUtils.isNotBlank(viewId)) {
198 viewExist = true;
199 }
200
201 return viewExist;
202 }
203
204
205
206
207
208
209
210
211
212
213
214
215 public PropertyValues getViewPropertiesById(String viewId) {
216 String beanName = viewBeanEntriesById.get(viewId);
217 if (StringUtils.isNotBlank(beanName)) {
218 BeanDefinition beanDefinition = ddBeans.getMergedBeanDefinition(beanName);
219
220 return beanDefinition.getPropertyValues();
221 }
222
223 return null;
224 }
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240 public PropertyValues getViewPropertiesByType(ViewType viewTypeName, Map<String, String> indexKey) {
241 String index = buildTypeIndex(indexKey);
242
243 ViewTypeDictionaryIndex typeIndex = getTypeIndex(viewTypeName);
244
245 String beanName = typeIndex.get(index);
246 if (StringUtils.isNotBlank(beanName)) {
247 BeanDefinition beanDefinition = ddBeans.getMergedBeanDefinition(beanName);
248
249 return beanDefinition.getPropertyValues();
250 }
251
252 return null;
253 }
254
255
256
257
258
259
260
261
262
263 public List<View> getViewsForType(ViewType viewTypeName) {
264 List<View> typeViews = new ArrayList<View>();
265
266
267 if (viewEntriesByType.containsKey(viewTypeName.name())) {
268 ViewTypeDictionaryIndex typeIndex = viewEntriesByType.get(viewTypeName.name());
269 for (Entry<String, String> typeEntry : typeIndex.getViewIndex().entrySet()) {
270 View typeView = ddBeans.getBean(typeEntry.getValue(), View.class);
271 typeViews.add(typeView);
272 }
273 } else {
274 throw new DataDictionaryException("Unable to find view index for type: " + viewTypeName);
275 }
276
277 return typeViews;
278 }
279
280
281
282
283
284
285 protected void buildViewIndicies() {
286 LOG.info("Starting View Index Building");
287
288 viewBeanEntriesById = new HashMap<String, String>();
289 viewEntriesByType = new HashMap<String, ViewTypeDictionaryIndex>();
290
291 String[] beanNames = ddBeans.getBeanNamesForType(View.class);
292 for (String beanName : beanNames) {
293 BeanDefinition beanDefinition = ddBeans.getMergedBeanDefinition(beanName);
294 PropertyValues propertyValues = beanDefinition.getPropertyValues();
295
296 String id = ViewModelUtils.getStringValFromPVs(propertyValues, "id");
297 if (StringUtils.isBlank(id)) {
298 id = beanName;
299 }
300
301 if (viewBeanEntriesById.containsKey(id)) {
302 throw new DataDictionaryException("Two views must not share the same id. Found duplicate id: " + id);
303 }
304
305 viewBeanEntriesById.put(id, beanName);
306
307 indexViewForType(propertyValues, id);
308 }
309
310 LOG.info("Completed View Index Building");
311 }
312
313
314
315
316
317
318
319
320
321
322 protected void indexViewForType(PropertyValues propertyValues, String id) {
323 String viewTypeName = ViewModelUtils.getStringValFromPVs(propertyValues, "viewTypeName");
324 if (StringUtils.isBlank(viewTypeName)) {
325 return;
326 }
327
328 UifConstants.ViewType viewType = ViewType.valueOf(viewTypeName);
329
330 ViewTypeService typeService = KRADServiceLocatorWeb.getViewService().getViewTypeService(viewType);
331 if (typeService == null) {
332
333 return;
334 }
335
336
337 Map<String, String> typeParameters = typeService.getParametersFromViewConfiguration(propertyValues);
338
339
340 String index = buildTypeIndex(typeParameters);
341
342
343 ViewTypeDictionaryIndex typeIndex = getTypeIndex(viewType);
344
345 typeIndex.put(index, id);
346 }
347
348
349
350
351
352
353
354
355
356 protected ViewTypeDictionaryIndex getTypeIndex(UifConstants.ViewType viewType) {
357 ViewTypeDictionaryIndex typeIndex = null;
358
359 if (viewEntriesByType.containsKey(viewType.name())) {
360 typeIndex = viewEntriesByType.get(viewType.name());
361 } else {
362 typeIndex = new ViewTypeDictionaryIndex();
363 viewEntriesByType.put(viewType.name(), typeIndex);
364 }
365
366 return typeIndex;
367 }
368
369
370
371
372
373
374
375 protected String buildTypeIndex(Map<String, String> typeParameters) {
376 String index = "";
377
378 for (String parameterName : typeParameters.keySet()) {
379 if (StringUtils.isNotBlank(index)) {
380 index += "|||";
381 }
382 index += parameterName + "^^" + typeParameters.get(parameterName);
383 }
384
385 return index;
386 }
387
388 }