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 org.apache.commons.lang.StringUtils;
19 import org.apache.commons.logging.Log;
20 import org.apache.commons.logging.LogFactory;
21 import org.kuali.rice.krad.datadictionary.DataDictionaryException;
22 import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
23 import org.kuali.rice.krad.uif.UifConstants;
24 import org.kuali.rice.krad.uif.util.ViewModelUtils;
25 import org.kuali.rice.krad.uif.view.View;
26 import org.kuali.rice.krad.uif.service.ViewTypeService;
27 import org.springframework.beans.PropertyValues;
28 import org.springframework.beans.factory.config.BeanDefinition;
29 import org.springframework.beans.factory.support.KualiDefaultListableBeanFactory;
30 import org.kuali.rice.krad.uif.UifConstants.ViewType;
31
32 import java.util.ArrayList;
33 import java.util.HashMap;
34 import java.util.List;
35 import java.util.Map;
36 import java.util.Map.Entry;
37
38
39
40
41
42
43
44
45
46
47
48
49 public class UifDictionaryIndex implements Runnable {
50 private static final Log LOG = LogFactory.getLog(UifDictionaryIndex.class);
51
52 private KualiDefaultListableBeanFactory ddBeans;
53
54
55 private Map<String, String> viewBeanEntriesById;
56
57
58 private Map<String, ViewTypeDictionaryIndex> viewEntriesByType;
59
60
61 private Map<String, UifViewPool> viewPools;
62
63 public UifDictionaryIndex(KualiDefaultListableBeanFactory ddBeans) {
64 this.ddBeans = ddBeans;
65 }
66
67 public void run() {
68 LOG.info("Starting View Index Building");
69 buildViewIndicies();
70 LOG.info("Completed View Index Building");
71 }
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86 public View getViewById(final String viewId) {
87
88 if (viewPools.containsKey(viewId)) {
89 View view = null;
90
91 final UifViewPool viewPool = viewPools.get(viewId);
92 synchronized (viewPool) {
93 if (!viewPool.isEmpty()) {
94 view = viewPool.getViewInstance();
95
96
97 Runnable createView = new Runnable() {
98 public void run() {
99 View newViewInstance = getViewInstanceFromFactory(viewId);
100 viewPool.addViewInstance(newViewInstance);
101 }
102 };
103
104 Thread t = new Thread(createView);
105 t.start();
106
107 return view;
108 } else {
109 LOG.info("Pool size for view with id: "
110 + viewId
111 + " is empty. Considering increasing max pool size.");
112 }
113 }
114 }
115
116
117 return getViewInstanceFromFactory(viewId);
118 }
119
120
121
122
123
124
125
126
127 protected View getViewInstanceFromFactory(String viewId) {
128 String beanName = viewBeanEntriesById.get(viewId);
129 if (StringUtils.isBlank(beanName)) {
130 throw new DataDictionaryException("Unable to find View with id: " + viewId);
131 }
132
133 return ddBeans.getBean(beanName, View.class);
134 }
135
136
137
138
139
140
141
142
143
144
145
146
147 public View getViewByTypeIndex(ViewType viewTypeName, Map<String, String> indexKey) {
148 String index = buildTypeIndex(indexKey);
149
150 ViewTypeDictionaryIndex typeIndex = getTypeIndex(viewTypeName);
151
152 String viewId = typeIndex.get(index);
153 if (StringUtils.isNotBlank(viewId)) {
154 return getViewById(viewId);
155 }
156
157 return null;
158 }
159
160
161
162
163
164
165
166
167
168 public boolean viewByTypeExist(ViewType viewTypeName, Map<String, String> indexKey) {
169 boolean viewExist = false;
170
171 String index = buildTypeIndex(indexKey);
172 ViewTypeDictionaryIndex typeIndex = getTypeIndex(viewTypeName);
173
174 String viewId = typeIndex.get(index);
175 if (StringUtils.isNotBlank(viewId)) {
176 viewExist = true;
177 }
178
179 return viewExist;
180 }
181
182
183
184
185
186
187
188
189
190
191
192
193 public PropertyValues getViewPropertiesById(String viewId) {
194 String beanName = viewBeanEntriesById.get(viewId);
195 if (StringUtils.isBlank(beanName)) {
196 BeanDefinition beanDefinition = ddBeans.getMergedBeanDefinition(beanName);
197
198 return beanDefinition.getPropertyValues();
199 }
200
201 return null;
202 }
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218 public PropertyValues getViewPropertiesByType(ViewType viewTypeName, Map<String, String> indexKey) {
219 String index = buildTypeIndex(indexKey);
220
221 ViewTypeDictionaryIndex typeIndex = getTypeIndex(viewTypeName);
222
223 String beanName = typeIndex.get(index);
224 if (StringUtils.isNotBlank(beanName)) {
225 BeanDefinition beanDefinition = ddBeans.getMergedBeanDefinition(beanName);
226
227 return beanDefinition.getPropertyValues();
228 }
229
230 return null;
231 }
232
233
234
235
236
237
238
239
240
241 public List<View> getViewsForType(ViewType viewTypeName) {
242 List<View> typeViews = new ArrayList<View>();
243
244
245 if (viewEntriesByType.containsKey(viewTypeName.name())) {
246 ViewTypeDictionaryIndex typeIndex = viewEntriesByType.get(viewTypeName.name());
247 for (Entry<String, String> typeEntry : typeIndex.getViewIndex().entrySet()) {
248 View typeView = ddBeans.getBean(typeEntry.getValue(), View.class);
249 typeViews.add(typeView);
250 }
251 } else {
252 throw new DataDictionaryException("Unable to find view index for type: " + viewTypeName);
253 }
254
255 return typeViews;
256 }
257
258
259
260
261
262
263 protected void buildViewIndicies() {
264 viewBeanEntriesById = new HashMap<String, String>();
265 viewEntriesByType = new HashMap<String, ViewTypeDictionaryIndex>();
266 viewPools = new HashMap<String, UifViewPool>();
267
268 String[] beanNames = ddBeans.getBeanNamesForType(View.class);
269 for (int i = 0; i < beanNames.length; i++) {
270 final String beanName = beanNames[i];
271 BeanDefinition beanDefinition = ddBeans.getMergedBeanDefinition(beanName);
272 PropertyValues propertyValues = beanDefinition.getPropertyValues();
273
274 String id = ViewModelUtils.getStringValFromPVs(propertyValues, "id");
275 if (StringUtils.isBlank(id)) {
276 id = beanName;
277 }
278
279 if (viewBeanEntriesById.containsKey(id)) {
280 throw new DataDictionaryException("Two views must not share the same id. Found duplicate id: " + id);
281 }
282 viewBeanEntriesById.put(id, beanName);
283
284 indexViewForType(propertyValues, id);
285
286
287 String poolSizeStr = ViewModelUtils.getStringValFromPVs(propertyValues, "preloadPoolSize");
288 if (StringUtils.isNotBlank(poolSizeStr)) {
289 int poolSize = Integer.parseInt(poolSizeStr);
290 if (poolSize < 1) {
291 continue;
292 }
293
294 final UifViewPool viewPool = new UifViewPool();
295 viewPool.setMaxSize(poolSize);
296 for (int j = 0; j < poolSize; j++) {
297 Runnable createView = new Runnable() {
298 public void run() {
299 View view = (View) ddBeans.getBean(beanName);
300 viewPool.addViewInstance(view);
301 }
302 };
303
304 Thread t = new Thread(createView);
305 t.start();
306 }
307
308 viewPools.put(id, viewPool);
309 }
310 }
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 }