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