1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.krms.service.impl;
17
18 import org.apache.commons.lang.StringUtils;
19 import org.kuali.rice.core.api.resourceloader.GlobalResourceLoader;
20 import org.kuali.rice.core.api.util.tree.Tree;
21 import org.kuali.rice.krad.uif.UifConstants;
22 import org.kuali.rice.krad.uif.component.Component;
23 import org.kuali.rice.krad.uif.container.Container;
24 import org.kuali.rice.krad.uif.lifecycle.ViewLifecycle;
25 import org.kuali.rice.krad.uif.util.ComponentFactory;
26 import org.kuali.rice.krad.uif.util.ComponentUtils;
27 import org.kuali.rice.krad.uif.view.View;
28 import org.kuali.rice.krad.uif.view.ViewModel;
29 import org.kuali.rice.krad.util.BeanPropertyComparator;
30 import org.kuali.rice.krad.util.GlobalVariables;
31 import org.kuali.rice.krad.util.ObjectUtils;
32 import org.kuali.rice.krad.web.form.MaintenanceDocumentForm;
33 import org.kuali.rice.krms.api.KrmsConstants;
34 import org.kuali.rice.krms.api.repository.LogicalOperator;
35 import org.kuali.rice.krms.api.repository.RuleManagementService;
36 import org.kuali.rice.krms.api.repository.proposition.PropositionType;
37 import org.kuali.rice.krms.api.repository.term.TermDefinition;
38 import org.kuali.rice.krms.api.repository.term.TermRepositoryService;
39 import org.kuali.rice.krms.api.repository.type.KrmsTypeDefinition;
40 import org.kuali.rice.krms.api.repository.type.KrmsTypeRepositoryService;
41 import org.kuali.rice.krms.builder.ComponentBuilder;
42 import org.kuali.rice.krms.dto.PropositionEditor;
43 import org.kuali.rice.krms.dto.PropositionParameterEditor;
44 import org.kuali.rice.krms.dto.RuleEditor;
45 import org.kuali.rice.krms.dto.RuleManagementWrapper;
46 import org.kuali.rice.krms.dto.RuleManager;
47 import org.kuali.rice.krms.dto.TermEditor;
48 import org.kuali.rice.krms.dto.TermParameterEditor;
49 import org.kuali.rice.krms.impl.repository.KrmsRepositoryServiceLocator;
50 import org.kuali.rice.krms.service.TemplateRegistry;
51 import org.kuali.rice.krms.tree.RuleViewTreeBuilder;
52 import org.kuali.rice.krms.tree.node.CompareTreeNode;
53 import org.kuali.rice.krms.tree.RuleCompareTreeBuilder;
54 import org.kuali.rice.krms.tree.RuleEditTreeBuilder;
55 import org.kuali.rice.krms.tree.RulePreviewTreeBuilder;
56 import org.kuali.rice.krms.util.KRMSConstants;
57 import org.kuali.rice.krms.util.NaturalLanguageHelper;
58 import org.kuali.rice.krms.util.PropositionTreeUtil;
59 import org.kuali.rice.krms.dto.TemplateInfo;
60 import org.kuali.rice.krms.service.RuleViewHelperService;
61 import org.kuali.student.common.uif.service.impl.KSViewHelperServiceImpl;
62 import org.kuali.student.r2.core.constants.KSKRMSServiceConstants;
63 import org.springframework.beans.BeanUtils;
64
65 import javax.xml.namespace.QName;
66 import java.util.ArrayList;
67 import java.util.Arrays;
68 import java.util.HashMap;
69 import java.util.List;
70 import java.util.Map;
71
72
73
74
75
76
77 public class RuleViewHelperServiceImpl extends KSViewHelperServiceImpl implements RuleViewHelperService {
78
79 private transient RuleManagementService ruleManagementService;
80 private transient KrmsTypeRepositoryService krmsTypeRepositoryService;
81 private transient TermRepositoryService termRepositoryService;
82
83 private RuleCompareTreeBuilder compareTreeBuilder;
84 private RuleEditTreeBuilder editTreeBuilder;
85 private RulePreviewTreeBuilder previewTreeBuilder;
86 private RuleViewTreeBuilder viewTreeBuilder;
87
88 private NaturalLanguageHelper naturalLanguageHelper;
89
90 private static TemplateRegistry templateRegistry;
91
92 protected RuleEditor getRuleEditor(Object model) {
93 if (model instanceof MaintenanceDocumentForm) {
94 MaintenanceDocumentForm maintenanceDocumentForm = (MaintenanceDocumentForm) model;
95 Object dataObject = maintenanceDocumentForm.getDocument().getNewMaintainableObject().getDataObject();
96
97 if (dataObject instanceof RuleEditor) {
98 return (RuleEditor) dataObject;
99 } else if (dataObject instanceof RuleManager) {
100 RuleManager wrapper = (RuleManager) dataObject;
101 return wrapper.getRuleEditor();
102 }
103 }
104 return null;
105 }
106
107 @Override
108 public TemplateInfo getTemplateForType(String type) {
109 return this.getTemplateRegistry().getTemplateForType(type);
110 }
111
112 @Override
113 public void addCustomContainerComponents(ViewModel model, Container container) {
114 if (KRMSConstants.KRMS_PROPOSITION_DETAILSECTION_ID.equals(container.getId())) {
115 customizePropositionEditSection(model, container);
116 }
117 }
118
119 private void customizePropositionEditSection(Object model, Container container) {
120
121 MaintenanceDocumentForm maintenanceDocumentForm = (MaintenanceDocumentForm) model;
122 Object dataObject = maintenanceDocumentForm.getDocument().getNewMaintainableObject().getDataObject();
123
124 RuleEditor ruleEditor = ((RuleManager) dataObject).getRuleEditor();
125 PropositionEditor propEditor = PropositionTreeUtil.getProposition(ruleEditor);
126
127 List<Component> components = new ArrayList<Component>();
128 if (propEditor != null) {
129
130 TemplateInfo template = this.getTemplateForType(propEditor.getType());
131 if (template != null) {
132
133
134 String objectPath = null;
135 if ((maintenanceDocumentForm.getUpdateComponentId() != null) &&
136 maintenanceDocumentForm.getUpdateComponentId().startsWith(container.getId())) {
137 objectPath = ViewLifecycle.getView().getDefaultBindingObjectPath();
138 }
139
140
141 if (template.getComponentId() != null) {
142 components.add(createComponent(objectPath, propEditor.getBindingPath(), template.getComponentId()));
143 }
144
145
146 if (template.getConstantComponentId() != null) {
147 components.add(createComponent(objectPath, propEditor.getBindingPath(), template.getConstantComponentId()));
148 }
149 }
150 }
151
152
153 if (components.size() == 0) {
154 container.getHeader().setRender(false);
155 }
156
157 container.setItems(components);
158 }
159
160 private Component createComponent(String objectPath, String bindingPath, String componentId) {
161 Component component = ComponentFactory.getNewComponentInstance(componentId);
162 if (objectPath != null) {
163 String nodePath = objectPath + "." + bindingPath;
164 ComponentUtils.pushObjectToContext(component, UifConstants.ContextVariableNames.NODE_PATH, nodePath);
165 }
166 return component;
167 }
168
169
170
171
172
173
174
175 @Override
176 public Boolean validateRule(RuleEditor rule) {
177
178 boolean hasError = false;
179
180
181 PropositionEditor proposition = PropositionTreeUtil.getProposition(rule);
182 if ((proposition != null) && (proposition.isEditMode())) {
183 GlobalVariables.getMessageMap().putErrorForSectionId(KRMSConstants.KRMS_PROPOSITION_DETAILSECTION_ID, KRMSConstants.KRMS_MSG_ERROR_RULE_PREVIEW);
184 hasError = true;
185 }
186
187 return hasError;
188 }
189
190
191
192
193
194
195
196 @Override
197 public Boolean validateProposition(PropositionEditor proposition) {
198
199
200 ComponentBuilder builder = this.getTemplateRegistry().getComponentBuilderForType(proposition.getType());
201 if (builder != null) {
202
203 builder.validate(proposition);
204 }
205
206 if (GlobalVariables.getMessageMap().getErrorMessages().isEmpty()) {
207 return Boolean.TRUE;
208 }
209
210 return Boolean.FALSE;
211 }
212
213
214
215
216
217
218 @Override
219 public void initPropositionEditor(PropositionEditor propositionEditor) {
220 if (PropositionType.SIMPLE.getCode().equalsIgnoreCase(propositionEditor.getPropositionTypeCode())) {
221
222 if (propositionEditor.getType() == null) {
223 KrmsTypeDefinition type = this.getKrmsTypeRepositoryService().getTypeById(propositionEditor.getTypeId());
224 propositionEditor.setType(type.getName());
225 }
226
227 ComponentBuilder builder = this.getTemplateRegistry().getComponentBuilderForType(propositionEditor.getType());
228 if (builder != null) {
229 Map<String, String> termParameters = this.getTermParameters(propositionEditor);
230 builder.resolveTermParameters(propositionEditor, termParameters);
231 }
232 } else {
233 for (PropositionEditor child : propositionEditor.getCompoundEditors()) {
234 initPropositionEditor(child);
235 }
236
237 }
238 }
239
240
241
242
243
244
245 @Override
246 public void finPropositionEditor(PropositionEditor propositionEditor) {
247 if (PropositionType.SIMPLE.getCode().equalsIgnoreCase(propositionEditor.getPropositionTypeCode())) {
248
249
250 TemplateInfo template = this.getTemplateRegistry().getTemplateForType(propositionEditor.getType());
251 PropositionTreeUtil.getOperatorParameter(propositionEditor.getParameters()).setValue(template.getOperator());
252
253 if (!"n".equals(template.getValue())) {
254 PropositionTreeUtil.getConstantParameter(propositionEditor.getParameters()).setValue(template.getValue());
255 }
256
257 if (propositionEditor.getTerm() != null) {
258 TermDefinition.Builder termBuilder = TermDefinition.Builder.create(propositionEditor.getTerm());
259 PropositionTreeUtil.getTermParameter(propositionEditor.getParameters()).setTermValue(termBuilder.build());
260 }
261
262 } else {
263
264
265 for (PropositionEditor child : propositionEditor.getCompoundEditors()) {
266 finPropositionEditor(child);
267 }
268
269 }
270 }
271
272
273
274
275
276
277
278
279 @Override
280 public Map<String, String> getTermParameters(PropositionEditor proposition) {
281
282 Map<String, String> termParameters = new HashMap<String, String>();
283 if (proposition.getTerm() == null) {
284 PropositionParameterEditor termParameter = PropositionTreeUtil.getTermParameter(proposition.getParameters());
285 if (termParameter != null) {
286 proposition.setTerm(new TermEditor(termParameter.getTermValue()));
287 } else {
288 return termParameters;
289 }
290 }
291
292 for (TermParameterEditor parameter : proposition.getTerm().getEditorParameters()) {
293 termParameters.put(parameter.getName(), parameter.getValue());
294 }
295
296 return termParameters;
297 }
298
299
300
301
302
303
304
305 @Override
306 public void resetDescription(PropositionEditor prop) {
307
308
309 if (prop.getType() == null) {
310 prop.setDescription(StringUtils.EMPTY);
311 prop.setTerm(null);
312 prop.getNaturalLanguage().clear();
313 return;
314 }
315
316
317 if (PropositionType.SIMPLE.getCode().equalsIgnoreCase(prop.getPropositionTypeCode())) {
318 Map<String, String> termParameters = null;
319 ComponentBuilder builder = this.getTemplateRegistry().getComponentBuilderForType(prop.getType());
320 if (builder != null) {
321 termParameters = builder.buildTermParameters(prop);
322 }
323
324 List<TermParameterEditor> parameters = new ArrayList<TermParameterEditor>();
325 if (termParameters != null) {
326 for (Map.Entry<String, String> entry : termParameters.entrySet()) {
327
328 TermParameterEditor parameterEditor = null;
329 if (prop.getTerm().getParameters() != null) {
330 for (TermParameterEditor parameter : prop.getTerm().getEditorParameters()) {
331
332 if (entry.getKey().equals(parameter.getName())) {
333 parameterEditor = parameter;
334 parameterEditor.setValue(entry.getValue());
335 break;
336 }
337 }
338 }
339
340
341 if (parameterEditor == null) {
342 parameterEditor = new TermParameterEditor();
343 parameterEditor.setName(entry.getKey());
344 parameterEditor.setValue(entry.getValue());
345 }
346 parameters.add(parameterEditor);
347 }
348 }
349
350 prop.getTerm().setParameters(parameters);
351
352
353 if (prop.getTerm().getSpecification() == null) {
354 String termSpecName = this.getTemplateRegistry().getTermSpecNameForType(prop.getType());
355 prop.getTerm().setSpecification(getTermRepositoryService().getTermSpecificationByNameAndNamespace(termSpecName, KSKRMSServiceConstants.NAMESPACE_CODE));
356 }
357
358 } else {
359 prop.setTerm(null);
360 }
361
362
363 prop.getNaturalLanguage().clear();
364 }
365
366 @Override
367 public void buildActions(RuleEditor ruleEditor) {
368 }
369
370 public void configurePropositionForType(PropositionEditor proposition) {
371
372 if (proposition != null) {
373
374 if (PropositionType.COMPOUND.getCode().equalsIgnoreCase(proposition.getPropositionTypeCode())) {
375 return;
376 }
377
378 String propositionTypeId = proposition.getTypeId();
379 if ((propositionTypeId == null) || (propositionTypeId.isEmpty())) {
380 proposition.setType(null);
381 return;
382 }
383
384 KrmsTypeDefinition type = KrmsRepositoryServiceLocator.getKrmsTypeRepositoryService().getTypeById(propositionTypeId);
385 if (type != null) {
386 proposition.setType(type.getName());
387 }
388
389 if (proposition.getTerm() == null) {
390 proposition.setTerm(new TermEditor());
391 }
392
393 String termSpecName = this.getTemplateRegistry().getTermSpecNameForType(proposition.getType());
394 proposition.getTerm().setSpecification(getTermRepositoryService().getTermSpecificationByNameAndNamespace(termSpecName, KSKRMSServiceConstants.NAMESPACE_CODE));
395
396 ComponentBuilder builder = this.getTemplateRegistry().getComponentBuilderForType(proposition.getType());
397 if (builder != null) {
398 builder.initialize(proposition);
399 }
400
401 }
402 }
403
404 @Override
405 public void refreshInitTrees(RuleEditor rule) {
406
407 if (rule == null) {
408 return;
409 }
410
411
412 rule.setEditTree(this.getEditTreeBuilder().buildTree(rule));
413 rule.setPreviewTree(this.getPreviewTreeBuilder().buildTree(rule));
414 }
415
416
417
418
419
420
421 @Override
422 public void refreshViewTree(RuleEditor rule) {
423
424 if (rule == null) {
425 return;
426 }
427
428
429 rule.setViewTree(this.getViewTreeBuilder().buildTree(rule));
430
431 }
432
433 @Override
434 public Tree<CompareTreeNode, String> buildCompareTree(RuleEditor original, RuleEditor compare) {
435
436
437 return this.getCompareTreeBuilder().buildTree(original, compare);
438
439 }
440
441 @Override
442 public Tree<CompareTreeNode, String> buildMultiViewTree(RuleEditor original, RuleEditor compare) {
443
444
445 return this.getCompareTreeBuilder().buildTree(original, compare);
446
447 }
448
449
450
451
452
453
454
455
456
457
458
459
460 @Override
461 public Boolean compareRules(RuleEditor original) {
462
463
464 RuleEditor compareEditor = original.getParent();
465 if ((compareEditor == null) || (compareEditor.getProposition() == null)) {
466 if (original.getProposition() != null) {
467 return false;
468 } else {
469 return true;
470 }
471 } else if (original.getProposition() == null) {
472 return false;
473 }
474
475
476 if (original.getProposition().getTypeId().equals(compareEditor.getProposition().getTypeId())) {
477 return compareProposition(original.getPropositionEditor(), compareEditor.getPropositionEditor());
478 } else {
479 return false;
480 }
481 }
482
483
484
485
486
487
488
489
490 @Override
491 public Boolean compareProposition(PropositionEditor original, PropositionEditor compare) {
492
493 BeanPropertyComparator propositionComparator = new BeanPropertyComparator(Arrays.asList("typeId"));
494 if (propositionComparator.compare(original, compare) != 0) {
495 return false;
496 }
497
498
499 if (PropositionType.SIMPLE.getCode().equalsIgnoreCase(original.getPropositionTypeCode())) {
500 TermEditor term = new TermEditor(PropositionTreeUtil.getTermParameter(compare.getParameters()).getTermValue());
501 if (!compareTerm(original.getTerm().getEditorParameters(), term.getEditorParameters())) {
502 return false;
503 }
504 }
505
506
507 return compareCompoundProposition(original.getCompoundEditors(), compare.getCompoundEditors());
508 }
509
510
511
512
513
514
515
516
517
518 @Override
519 public Boolean compareTerm(List<TermParameterEditor> original, List<TermParameterEditor> compare) {
520
521
522 int originalSize = original == null ? 0 : original.size();
523 if (originalSize != (compare == null ? 0 : compare.size())) {
524 return false;
525 } else if (originalSize > 0) {
526
527
528 BeanPropertyComparator termComparator = new BeanPropertyComparator(Arrays.asList("name", "value"));
529 for (int index = 0; index < originalSize; index++) {
530 if (termComparator.compare(original.get(index), compare.get(index)) != 0) {
531 return false;
532 }
533 }
534 }
535
536 return true;
537
538 }
539
540
541
542
543
544
545
546
547 @Override
548 public Boolean compareCompoundProposition(List<PropositionEditor> original, List<PropositionEditor> compare) {
549
550
551 int originalSize = original == null ? 0 : original.size();
552 if (originalSize != (compare == null ? 0 : compare.size())) {
553 return false;
554 } else if (originalSize > 0) {
555
556
557 for (int index = 0; index < originalSize; index++) {
558 if (!compareProposition(original.get(index), compare.get(index))) {
559 return false;
560 }
561 }
562 }
563
564 return true;
565 }
566
567
568
569
570
571
572
573
574
575 @Override
576 public PropositionEditor copyProposition(PropositionEditor oldProposition) {
577 try {
578 PropositionEditor newProposition = this.copyPropositionEditor(oldProposition);
579
580
581 return (PropositionEditor) ObjectUtils.deepCopy(newProposition);
582 } catch (Exception e) {
583 return null;
584 }
585 }
586
587
588
589
590
591
592
593
594
595
596 protected PropositionEditor copyPropositionEditor(PropositionEditor oldProposition) {
597 PropositionEditor newProposition;
598 try {
599 newProposition = this.getPropositionEditorClass().newInstance();
600 } catch (Exception e) {
601 newProposition = new PropositionEditor();
602 }
603 BeanUtils.copyProperties(oldProposition, newProposition, new String[]{"key", "id", "term", "parameters", "versionNumber"});
604
605 if (!oldProposition.getPropositionTypeCode().equals("C")) {
606 List<PropositionParameterEditor> propositionParameterEditors = new ArrayList<PropositionParameterEditor>();
607 for (PropositionParameterEditor parm : oldProposition.getParameters()) {
608 PropositionParameterEditor newParm = new PropositionParameterEditor();
609 BeanUtils.copyProperties(parm, newParm, new String[]{"termValue", "id", "versionNumber"});
610 propositionParameterEditors.add(newParm);
611 }
612
613 newProposition.setParameters(propositionParameterEditors);
614
615 TermEditor termEditor = new TermEditor();
616 List<TermParameterEditor> termParameterEditors = new ArrayList<TermParameterEditor>();
617 if (oldProposition.getTerm() != null) {
618 BeanUtils.copyProperties(oldProposition.getTerm(), termEditor, new String[]{"id", "versionNumber", "parameters"});
619 for (TermParameterEditor termParm : oldProposition.getTerm().getEditorParameters()) {
620 TermParameterEditor newTermParm = new TermParameterEditor();
621 BeanUtils.copyProperties(termParm, newTermParm, new String[]{"id", "versionNumber"});
622 termParameterEditors.add(newTermParm);
623 }
624 }
625 termEditor.setParameters(termParameterEditors);
626
627 newProposition.setTerm(termEditor);
628 this.resetDescription(newProposition);
629 }
630
631 if (newProposition.getCompoundEditors() != null) {
632 List<PropositionEditor> props = new ArrayList<PropositionEditor>();
633 for (PropositionEditor prop : newProposition.getCompoundEditors()) {
634 props.add(this.copyPropositionEditor(prop));
635 }
636 newProposition.setCompoundEditors(props);
637 }
638
639
640 return newProposition;
641 }
642
643 @Override
644 public PropositionEditor createCompoundPropositionBoStub(PropositionEditor existing, boolean addNewChild) {
645 try {
646 PropositionEditor compound = PropositionTreeUtil.createCompoundPropositionBoStub(existing, addNewChild, this.getPropositionEditorClass());
647 this.setTypeForCompoundOpCode(compound, LogicalOperator.AND.getCode());
648 return compound;
649 } catch (Exception e) {
650 return null;
651 }
652 }
653
654 @Override
655 public void setTypeForCompoundOpCode(PropositionEditor proposition, String compoundOpCode) {
656
657 if (compoundOpCode.equals(proposition.getCompoundOpCode())) {
658 return;
659 }
660
661
662 proposition.getNaturalLanguage().clear();
663 proposition.setCompoundOpCode(compoundOpCode);
664 }
665
666
667
668
669
670
671
672 @Override
673 public PropositionEditor createSimplePropositionBoStub(PropositionEditor sibling) {
674 try {
675 return PropositionTreeUtil.createSimplePropositionBoStub(sibling, this.getPropositionEditorClass());
676 } catch (Exception e) {
677 return null;
678 }
679 }
680
681
682
683
684
685
686 public Class<? extends PropositionEditor> getPropositionEditorClass() {
687 return PropositionEditor.class;
688 }
689
690 protected RuleManagementService getRuleManagementService() {
691 if (ruleManagementService == null) {
692 ruleManagementService = (RuleManagementService) GlobalResourceLoader.getService(QName.valueOf("ruleManagementService"));
693 }
694 return ruleManagementService;
695 }
696
697 protected RuleCompareTreeBuilder getCompareTreeBuilder() {
698 if (compareTreeBuilder == null) {
699 compareTreeBuilder = new RuleCompareTreeBuilder();
700 }
701 return compareTreeBuilder;
702 }
703
704 protected RuleEditTreeBuilder getEditTreeBuilder() {
705 if (editTreeBuilder == null) {
706 editTreeBuilder = new RuleEditTreeBuilder();
707 }
708 return editTreeBuilder;
709 }
710
711 protected RulePreviewTreeBuilder getPreviewTreeBuilder() {
712 if (previewTreeBuilder == null) {
713 previewTreeBuilder = new RulePreviewTreeBuilder();
714 }
715 return previewTreeBuilder;
716 }
717
718 protected RuleViewTreeBuilder getViewTreeBuilder() {
719 if (viewTreeBuilder == null) {
720 viewTreeBuilder = new RuleViewTreeBuilder();
721 }
722 return viewTreeBuilder;
723 }
724
725 protected NaturalLanguageHelper getNaturalLanguageHelper() {
726 if (naturalLanguageHelper == null) {
727 naturalLanguageHelper = new NaturalLanguageHelper();
728 naturalLanguageHelper.setRuleManagementService(this.getRuleManagementService());
729 }
730 return naturalLanguageHelper;
731 }
732
733 protected TemplateRegistry getTemplateRegistry() {
734 if (templateRegistry == null) {
735 templateRegistry = (TemplateRegistry) GlobalResourceLoader.getService(new QName("http://student.kuali.org/wsdl/templateResolverService", "templateResolverService"));
736 }
737 return templateRegistry;
738 }
739
740 protected KrmsTypeRepositoryService getKrmsTypeRepositoryService() {
741 if (krmsTypeRepositoryService == null) {
742 krmsTypeRepositoryService = (KrmsTypeRepositoryService) GlobalResourceLoader.getService(new QName(KrmsConstants.Namespaces.KRMS_NAMESPACE_2_0, "krmsTypeRepositoryService"));
743 }
744 return krmsTypeRepositoryService;
745 }
746
747 public TermRepositoryService getTermRepositoryService() {
748 if (termRepositoryService == null) {
749 termRepositoryService = (TermRepositoryService) GlobalResourceLoader.getService(new QName(KrmsConstants.Namespaces.KRMS_NAMESPACE_2_0, "termRepositoryService"));
750 }
751 return termRepositoryService;
752 }
753
754 }