1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.krad.uif.widget;
17
18 import java.util.ArrayList;
19 import java.util.HashMap;
20 import java.util.List;
21 import java.util.Map;
22
23 import org.apache.commons.lang.StringUtils;
24 import org.kuali.rice.krad.bo.DataObjectRelationship;
25 import org.kuali.rice.krad.datadictionary.parse.BeanTag;
26 import org.kuali.rice.krad.datadictionary.parse.BeanTagAttribute;
27 import org.kuali.rice.krad.datadictionary.parse.BeanTags;
28 import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
29 import org.kuali.rice.krad.uif.UifConstants;
30 import org.kuali.rice.krad.uif.UifParameters;
31 import org.kuali.rice.krad.uif.component.BindingInfo;
32 import org.kuali.rice.krad.uif.component.Component;
33 import org.kuali.rice.krad.uif.container.CollectionGroup;
34 import org.kuali.rice.krad.uif.element.Action;
35 import org.kuali.rice.krad.uif.field.InputField;
36 import org.kuali.rice.krad.uif.lifecycle.LifecycleEventListener;
37 import org.kuali.rice.krad.uif.lifecycle.ViewLifecycle;
38 import org.kuali.rice.krad.uif.service.ViewHelperService;
39 import org.kuali.rice.krad.uif.util.ScriptUtils;
40 import org.kuali.rice.krad.uif.util.ViewModelUtils;
41 import org.kuali.rice.krad.uif.view.View;
42 import org.kuali.rice.krad.util.KRADConstants;
43 import org.kuali.rice.krad.util.KRADUtils;
44
45
46
47
48
49
50 @BeanTags({@BeanTag(name = "quickFinder-bean", parent = "Uif-QuickFinder"),
51 @BeanTag(name = "quickFinderByScript-bean", parent = "Uif-QuickFinderByScript"),
52 @BeanTag(name = "collectionQuickFinder-bean", parent = "Uif-CollectionQuickFinder")})
53 public class QuickFinder extends WidgetBase implements LifecycleEventListener {
54 private static final long serialVersionUID = 3302390972815386785L;
55
56
57 private String baseLookupUrl;
58 private String dataObjectClassName;
59 private String viewName;
60
61 private boolean returnByScript;
62 private String readOnlyLookupFields;
63 private String referencesToRefresh;
64 private String lookupCollectionName;
65
66 private Map<String, String> fieldConversions;
67 private Map<String, String> lookupParameters;
68
69 private Action quickfinderAction;
70 private LightBox lightBox;
71
72
73 private Boolean renderReturnLink;
74 private Boolean renderResultActions;
75 private Boolean autoSearch;
76 private Boolean renderLookupCriteria;
77 private Boolean renderCriteriaActions;
78 private Boolean renderMaintenanceLinks;
79 private Boolean multipleValuesSelect;
80
81 public QuickFinder() {
82 super();
83
84 fieldConversions = new HashMap<String, String>();
85 lookupParameters = new HashMap<String, String>();
86 }
87
88
89
90
91
92
93
94
95
96
97 @Override
98 public void performInitialization(Object model) {
99 super.performInitialization(model);
100
101 ViewLifecycle viewLifecycle = ViewLifecycle.getActiveLifecycle();
102 viewLifecycle.registerLifecycleCompleteListener(quickfinderAction, this);
103 }
104
105
106
107
108
109
110
111
112
113
114
115 @Override
116 public void performFinalize(Object model, Component parent) {
117 super.performFinalize(model, parent);
118
119 if (parent.isReadOnly()) {
120 setRender(false);
121 }
122
123 if (!isRender()) {
124 return;
125 }
126
127 View view = ViewLifecycle.getActiveLifecycle().getView();
128
129 if (parent instanceof InputField) {
130 setupForInputField(view, model, (InputField) parent);
131 } else if (parent instanceof CollectionGroup) {
132 setupForCollectionGroup(view, model, (CollectionGroup) parent);
133 }
134
135 setupQuickfinderAction(view, model, parent);
136 }
137
138
139
140
141
142
143
144
145
146 protected void setupForInputField(View view, Object model, InputField inputField) {
147
148 if (StringUtils.isBlank(dataObjectClassName)) {
149 DataObjectRelationship relationship = getRelationshipForField(view, model, inputField);
150
151
152 if (relationship == null) {
153 setRender(false);
154
155 return;
156 }
157
158 dataObjectClassName = relationship.getRelatedClass().getName();
159
160 if ((fieldConversions == null) || fieldConversions.isEmpty()) {
161 generateFieldConversions(relationship);
162 }
163
164 if ((lookupParameters == null) || lookupParameters.isEmpty()) {
165 generateLookupParameters(relationship);
166 }
167 }
168
169
170 updateFieldConversions(inputField.getBindingInfo());
171 updateLookupParameters(inputField.getBindingInfo());
172 updateReferencesToRefresh(inputField.getBindingInfo());
173 }
174
175
176
177
178
179
180
181
182
183
184 protected DataObjectRelationship getRelationshipForField(View view, Object model, InputField field) {
185 String propertyName = field.getBindingInfo().getBindingName();
186
187
188 Object parentObject = ViewModelUtils.getParentObjectForMetadata(view, model, field);
189 Class<?> parentObjectClass = null;
190 if (parentObject != null) {
191 parentObjectClass = parentObject.getClass();
192 }
193
194
195 return KRADServiceLocatorWeb.getLegacyDataAdapter().getDataObjectRelationship(parentObject,
196 parentObjectClass, propertyName, "", true, true, false);
197 }
198
199
200
201
202
203
204 protected void generateFieldConversions(DataObjectRelationship relationship) {
205 fieldConversions = new HashMap<String, String>();
206
207 for (Map.Entry<String, String> entry : relationship.getParentToChildReferences().entrySet()) {
208 String fromField = entry.getValue();
209 String toField = entry.getKey();
210
211 fieldConversions.put(fromField, toField);
212 }
213 }
214
215
216
217
218
219
220 protected void generateLookupParameters(DataObjectRelationship relationship) {
221 lookupParameters = new HashMap<String, String>();
222
223 for (Map.Entry<String, String> entry : relationship.getParentToChildReferences().entrySet()) {
224 String fromField = entry.getKey();
225 String toField = entry.getValue();
226
227 if (relationship.getUserVisibleIdentifierKey() == null || relationship.getUserVisibleIdentifierKey().equals(
228 fromField)) {
229 lookupParameters.put(fromField, toField);
230 }
231 }
232 }
233
234
235
236
237
238
239
240 protected void updateFieldConversions(BindingInfo bindingInfo) {
241 Map<String, String> adjustedFieldConversions = new HashMap<String, String>();
242 for (String fromField : fieldConversions.keySet()) {
243 String toField = fieldConversions.get(fromField);
244 String adjustedToFieldPath = bindingInfo.getPropertyAdjustedBindingPath(toField);
245
246 adjustedFieldConversions.put(fromField, adjustedToFieldPath);
247 }
248
249 this.fieldConversions = adjustedFieldConversions;
250 }
251
252
253
254
255
256
257
258 protected void updateLookupParameters(BindingInfo bindingInfo) {
259 Map<String, String> adjustedLookupParameters = new HashMap<String, String>();
260 for (String fromField : lookupParameters.keySet()) {
261 String toField = lookupParameters.get(fromField);
262 String adjustedFromFieldPath = bindingInfo.getPropertyAdjustedBindingPath(fromField);
263
264 adjustedLookupParameters.put(adjustedFromFieldPath, toField);
265 }
266
267 this.lookupParameters = adjustedLookupParameters;
268 }
269
270
271
272
273
274
275
276 protected void updateReferencesToRefresh(BindingInfo bindingInfo) {
277 List<String> adjustedReferencesToRefresh = new ArrayList<String>();
278
279 if (referencesToRefresh == null) {
280 referencesToRefresh = new String();
281 }
282
283 for (String reference : StringUtils.split(referencesToRefresh, KRADConstants.REFERENCES_TO_REFRESH_SEPARATOR)) {
284 adjustedReferencesToRefresh.add(bindingInfo.getPropertyAdjustedBindingPath(reference));
285 }
286
287 this.referencesToRefresh = StringUtils.join(adjustedReferencesToRefresh,
288 KRADConstants.REFERENCES_TO_REFRESH_SEPARATOR);
289 }
290
291
292
293
294
295
296
297
298
299 protected void setupForCollectionGroup(View view, Object model, CollectionGroup collectionGroup) {
300
301
302 if (StringUtils.isBlank(getDataObjectClassName())) {
303 Class<?> collectionObjectClass = collectionGroup.getCollectionObjectClass();
304
305 boolean isCollectionClassLookupable = KRADServiceLocatorWeb.getViewDictionaryService().isLookupable(
306 collectionObjectClass);
307 if (isCollectionClassLookupable) {
308 setDataObjectClassName(collectionObjectClass.getName());
309
310
311 if ((fieldConversions == null) || fieldConversions.isEmpty()) {
312 List<String> collectionObjectPKFields =
313 KRADServiceLocatorWeb.getLegacyDataAdapter().listPrimaryKeyFieldNames(
314 collectionObjectClass);
315
316 fieldConversions = new HashMap<String, String>();
317 for (String pkField : collectionObjectPKFields) {
318 fieldConversions.put(pkField, pkField);
319 }
320 }
321 } else {
322
323 setRender(false);
324 }
325 }
326
327
328 if (isRender() && StringUtils.isBlank(getLookupCollectionName())) {
329 setLookupCollectionName(collectionGroup.getBindingInfo().getBindingPath());
330 }
331 }
332
333
334
335
336
337
338
339
340
341 protected void setupQuickfinderAction(View view, Object model, Component parent) {
342 quickfinderAction.setId(getId() + UifConstants.IdSuffixes.ACTION);
343
344 if ((lightBox != null) && lightBox.isRender()) {
345 String lightboxScript = UifConstants.JsFunctions.CREATE_LIGHTBOX_POST + "(\"" + quickfinderAction.getId()
346 + "\"," + lightBox.getTemplateOptionsJSString() + "," + returnByScript + ");";
347
348 quickfinderAction.setActionScript(lightboxScript);
349 }
350
351 quickfinderAction.addActionParameter(UifParameters.BASE_LOOKUP_URL, baseLookupUrl);
352 quickfinderAction.addActionParameter(UifParameters.DATA_OBJECT_CLASS_NAME, dataObjectClassName);
353
354 if (!fieldConversions.isEmpty()) {
355 quickfinderAction.addActionParameter(UifParameters.CONVERSION_FIELDS, KRADUtils.buildMapParameterString(
356 fieldConversions));
357 }
358
359 if (!lookupParameters.isEmpty()) {
360 quickfinderAction.addActionParameter(UifParameters.LOOKUP_PARAMETERS, KRADUtils.buildMapParameterString(
361 lookupParameters));
362 }
363
364 addActionParameterIfNotNull(UifParameters.VIEW_NAME, viewName);
365 addActionParameterIfNotNull(UifParameters.READ_ONLY_FIELDS, readOnlyLookupFields);
366 addActionParameterIfNotNull(UifParameters.RENDER_RETURN_LINK, renderReturnLink);
367 addActionParameterIfNotNull(UifParameters.RENDER_RESULT_ACTIONS, renderResultActions);
368 addActionParameterIfNotNull(UifParameters.REFERENCES_TO_REFRESH, referencesToRefresh);
369 addActionParameterIfNotNull(UifParameters.AUTO_SEARCH, autoSearch);
370 addActionParameterIfNotNull(UifParameters.RENDER_LOOKUP_CRITERIA, renderLookupCriteria);
371 addActionParameterIfNotNull(UifParameters.RENDER_CRITERIA_ACTIONS, renderCriteriaActions);
372 addActionParameterIfNotNull(UifParameters.RENDER_MAINTENANCE_LINKS, renderMaintenanceLinks);
373 addActionParameterIfNotNull(UifParameters.MULTIPLE_VALUES_SELECT, multipleValuesSelect);
374 addActionParameterIfNotNull(UifParameters.LOOKUP_COLLECTION_NAME, lookupCollectionName);
375 addActionParameterIfNotNull(UifParameters.QUICKFINDER_ID, getId());
376 }
377
378
379
380
381
382
383
384
385 protected void addActionParameterIfNotNull(String parameterName, Object parameterValue) {
386 if ((parameterValue != null) && StringUtils.isNotBlank(parameterValue.toString())) {
387 quickfinderAction.addActionParameter(parameterName, parameterValue.toString());
388 }
389 }
390
391
392
393
394 @Override
395 public List<Component> getComponentsForLifecycle() {
396 List<Component> components = super.getComponentsForLifecycle();
397
398 components.add(quickfinderAction);
399 components.add(lightBox);
400
401 return components;
402 }
403
404
405
406
407
408
409
410
411 @Override
412 public void processEvent(ViewLifecycle.LifecycleEvent lifecycleEvent, View view, Object model,
413 Component eventComponent) {
414 Action finalQuickfinderAction = (Action) eventComponent;
415
416
417 view.getViewIndex().addPostContextEntry(getId(), UifConstants.PostContextKeys.QUICKFINDER_FOCUS_ID,
418 finalQuickfinderAction.getFocusOnIdAfterSubmit());
419 view.getViewIndex().addPostContextEntry(getId(), UifConstants.PostContextKeys.QUICKFINDER_JUMP_TO_ID,
420 finalQuickfinderAction.getJumpToIdAfterSubmit());
421 }
422
423
424
425
426
427
428
429
430
431
432
433 @BeanTagAttribute(name = "baseLookupUrl")
434 public String getBaseLookupUrl() {
435 return this.baseLookupUrl;
436 }
437
438
439
440
441 public void setBaseLookupUrl(String baseLookupUrl) {
442 this.baseLookupUrl = baseLookupUrl;
443 }
444
445
446
447
448
449
450
451
452
453
454
455 @BeanTagAttribute(name = "dataOjbectClassName")
456 public String getDataObjectClassName() {
457 return this.dataObjectClassName;
458 }
459
460
461
462
463 public void setDataObjectClassName(String dataObjectClassName) {
464 this.dataObjectClassName = dataObjectClassName;
465 }
466
467
468
469
470
471
472
473
474
475
476
477
478 @BeanTagAttribute(name = "viewName")
479 public String getViewName() {
480 return this.viewName;
481 }
482
483
484
485
486 public void setViewName(String viewName) {
487 this.viewName = viewName;
488 }
489
490
491
492
493
494
495
496
497
498
499 public boolean isReturnByScript() {
500 return returnByScript;
501 }
502
503
504
505
506 public void setReturnByScript(boolean returnByScript) {
507 this.returnByScript = returnByScript;
508 }
509
510
511
512
513
514
515
516
517
518
519
520 @BeanTagAttribute(name = "readOnlyLookupFields")
521 public String getReadOnlyLookupFields() {
522 return this.readOnlyLookupFields;
523 }
524
525
526
527
528 public void setReadOnlyLookupFields(String readOnlyLookupFields) {
529 this.readOnlyLookupFields = readOnlyLookupFields;
530 }
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546 @BeanTagAttribute(name = "referencesToRefresh")
547 public String getReferencesToRefresh() {
548 return this.referencesToRefresh;
549 }
550
551
552
553
554 public void setReferencesToRefresh(String referencesToRefresh) {
555 this.referencesToRefresh = referencesToRefresh;
556 }
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576 @BeanTagAttribute(name = "fieldConversions", type = BeanTagAttribute.AttributeType.MAPVALUE)
577 public Map<String, String> getFieldConversions() {
578 return this.fieldConversions;
579 }
580
581
582
583
584 public void setFieldConversions(Map<String, String> fieldConversions) {
585 this.fieldConversions = fieldConversions;
586 }
587
588
589
590
591
592
593
594
595
596
597
598
599
600 @BeanTagAttribute(name = "lookupParameters", type = BeanTagAttribute.AttributeType.MAPVALUE)
601 public Map<String, String> getLookupParameters() {
602 return this.lookupParameters;
603 }
604
605
606
607
608 public void setLookupParameters(Map<String, String> lookupParameters) {
609 this.lookupParameters = lookupParameters;
610 }
611
612
613
614
615
616
617
618
619
620
621 @BeanTagAttribute(name = "renderReturnLink")
622 public Boolean getRenderReturnLink() {
623 return this.renderReturnLink;
624 }
625
626
627
628
629 public void setRenderReturnLink(Boolean renderReturnLink) {
630 this.renderReturnLink = renderReturnLink;
631 }
632
633
634
635
636
637
638
639
640
641
642
643 @BeanTagAttribute(name = "renderResultActions")
644 public Boolean getRenderResultActions() {
645 return renderResultActions;
646 }
647
648
649
650
651 public void setRenderResultActions(Boolean renderResultActions) {
652 this.renderResultActions = renderResultActions;
653 }
654
655
656
657
658
659
660
661
662
663
664 @BeanTagAttribute(name = "autoSearch")
665 public Boolean getAutoSearch() {
666 return this.autoSearch;
667 }
668
669
670
671
672 public void setAutoSearch(Boolean autoSearch) {
673 this.autoSearch = autoSearch;
674 }
675
676
677
678
679
680
681
682
683
684 @BeanTagAttribute(name = "renderLookupCriteria")
685 public Boolean getRenderLookupCriteria() {
686 return this.renderLookupCriteria;
687 }
688
689
690
691
692 public void setRenderLookupCriteria(Boolean renderLookupCriteria) {
693 this.renderLookupCriteria = renderLookupCriteria;
694 }
695
696
697
698
699
700
701 @BeanTagAttribute(name = "renderCriteriaActions")
702 public Boolean getRenderCriteriaActions() {
703 return this.renderCriteriaActions;
704 }
705
706
707
708
709 public void setRenderCriteriaActions(Boolean renderCriteriaActions) {
710 this.renderCriteriaActions = renderCriteriaActions;
711 }
712
713
714
715
716
717
718
719
720
721
722
723
724 @BeanTagAttribute(name = "renderMaintenanceLinks")
725 public Boolean getRenderMaintenanceLinks() {
726 return this.renderMaintenanceLinks;
727 }
728
729
730
731
732 public void setRenderMaintenanceLinks(Boolean renderMaintenanceLinks) {
733 this.renderMaintenanceLinks = renderMaintenanceLinks;
734 }
735
736
737
738
739
740
741
742
743
744
745 @BeanTagAttribute(name = "quickfinderAction", type = BeanTagAttribute.AttributeType.SINGLEBEAN)
746 public Action getQuickfinderAction() {
747 return this.quickfinderAction;
748 }
749
750
751
752
753 public void setQuickfinderAction(Action quickfinderAction) {
754 this.quickfinderAction = quickfinderAction;
755 }
756
757
758
759
760
761
762
763
764
765 @BeanTagAttribute(name = "lightBox", type = BeanTagAttribute.AttributeType.SINGLEBEAN)
766 public LightBox getLightBox() {
767 return lightBox;
768 }
769
770
771
772
773 public void setLightBox(LightBox lightBox) {
774 this.lightBox = lightBox;
775 }
776
777
778
779
780
781
782 @BeanTagAttribute(name = "MultipleValuesSelect")
783 public Boolean getMultipleValuesSelect() {
784 return multipleValuesSelect;
785 }
786
787
788
789
790 public void setMultipleValuesSelect(Boolean multipleValuesSelect) {
791 this.multipleValuesSelect = multipleValuesSelect;
792 }
793
794
795
796
797
798
799
800
801
802
803 @BeanTagAttribute(name = "lookupCollectionName")
804 public String getLookupCollectionName() {
805 return lookupCollectionName;
806 }
807
808
809
810
811 public void setLookupCollectionName(String lookupCollectionName) {
812 this.lookupCollectionName = lookupCollectionName;
813 }
814
815
816
817
818 @Override
819 protected <T> void copyProperties(T component) {
820 super.copyProperties(component);
821
822 QuickFinder quickFinderCopy = (QuickFinder) component;
823
824 quickFinderCopy.setBaseLookupUrl(this.baseLookupUrl);
825 quickFinderCopy.setDataObjectClassName(this.dataObjectClassName);
826 quickFinderCopy.setViewName(this.viewName);
827 quickFinderCopy.setReferencesToRefresh(this.referencesToRefresh);
828
829 if (fieldConversions != null) {
830 quickFinderCopy.setFieldConversions(new HashMap<String, String>(this.fieldConversions));
831 }
832
833 if (lookupParameters != null) {
834 quickFinderCopy.setLookupParameters(new HashMap<String, String>(this.lookupParameters));
835 }
836
837 quickFinderCopy.setReturnByScript(this.returnByScript);
838 quickFinderCopy.setReadOnlyLookupFields(this.readOnlyLookupFields);
839 quickFinderCopy.setRenderReturnLink(this.renderReturnLink);
840 quickFinderCopy.setRenderResultActions(this.renderResultActions);
841 quickFinderCopy.setAutoSearch(this.autoSearch);
842 quickFinderCopy.setRenderLookupCriteria(this.renderLookupCriteria);
843 quickFinderCopy.setRenderCriteriaActions(this.renderCriteriaActions);
844 quickFinderCopy.setRenderMaintenanceLinks(this.renderMaintenanceLinks);
845 quickFinderCopy.setMultipleValuesSelect(this.multipleValuesSelect);
846 quickFinderCopy.setLookupCollectionName(this.lookupCollectionName);
847
848 if (lightBox != null) {
849 quickFinderCopy.setLightBox((LightBox) this.lightBox.copy());
850 }
851
852 if (this.quickfinderAction != null) {
853 quickFinderCopy.setQuickfinderAction((Action) this.quickfinderAction.copy());
854 }
855 }
856 }