1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.krms.impl.ui;
17
18 import java.util.ArrayList;
19 import java.util.Collections;
20 import java.util.HashMap;
21 import java.util.List;
22 import java.util.Map;
23
24 import javax.servlet.http.HttpServletRequest;
25 import javax.servlet.http.HttpServletResponse;
26
27 import org.apache.commons.collections.CollectionUtils;
28 import org.apache.commons.lang.StringUtils;
29 import org.kuali.rice.core.api.criteria.QueryByCriteria;
30 import org.kuali.rice.core.api.criteria.QueryResults;
31 import org.kuali.rice.core.api.uif.RemotableAttributeError;
32 import org.kuali.rice.core.api.util.KeyValue;
33 import org.kuali.rice.core.api.util.tree.Node;
34 import org.kuali.rice.krad.data.KradDataServiceLocator;
35 import org.kuali.rice.krad.maintenance.MaintenanceDocument;
36 import org.kuali.rice.krad.maintenance.MaintenanceDocumentController;
37 import org.kuali.rice.krad.service.KRADServiceLocator;
38 import org.kuali.rice.krad.uif.UifParameters;
39 import org.kuali.rice.krad.util.GlobalVariables;
40 import org.kuali.rice.krad.util.KRADUtils;
41 import org.kuali.rice.krad.web.form.DocumentFormBase;
42 import org.kuali.rice.krad.web.form.MaintenanceDocumentForm;
43 import org.kuali.rice.krad.web.form.UifFormBase;
44 import org.kuali.rice.krms.api.KrmsApiServiceLocator;
45 import org.kuali.rice.krms.api.engine.expression.ComparisonOperatorService;
46 import org.kuali.rice.krms.api.repository.LogicalOperator;
47 import org.kuali.rice.krms.api.repository.operator.CustomOperator;
48 import org.kuali.rice.krms.api.repository.proposition.PropositionParameterType;
49 import org.kuali.rice.krms.api.repository.proposition.PropositionType;
50 import org.kuali.rice.krms.api.repository.rule.RuleDefinition;
51 import org.kuali.rice.krms.api.repository.term.TermDefinition;
52 import org.kuali.rice.krms.api.repository.term.TermResolverDefinition;
53 import org.kuali.rice.krms.api.repository.term.TermSpecificationDefinition;
54 import org.kuali.rice.krms.api.repository.type.KrmsAttributeDefinition;
55 import org.kuali.rice.krms.impl.repository.ActionBo;
56 import org.kuali.rice.krms.impl.repository.AgendaBo;
57 import org.kuali.rice.krms.impl.repository.AgendaItemBo;
58 import org.kuali.rice.krms.impl.repository.ContextBoService;
59 import org.kuali.rice.krms.impl.repository.FunctionBoService;
60 import org.kuali.rice.krms.impl.repository.KrmsAttributeDefinitionService;
61 import org.kuali.rice.krms.impl.repository.KrmsRepositoryServiceLocator;
62 import org.kuali.rice.krms.impl.repository.PropositionBo;
63 import org.kuali.rice.krms.impl.repository.PropositionParameterBo;
64 import org.kuali.rice.krms.impl.repository.RepositoryBoIncrementer;
65 import org.kuali.rice.krms.impl.repository.RuleBo;
66 import org.kuali.rice.krms.impl.repository.RuleBoService;
67 import org.kuali.rice.krms.impl.repository.TermBo;
68 import org.kuali.rice.krms.impl.rule.AgendaEditorBusRule;
69 import org.kuali.rice.krms.impl.util.KRMSPropertyConstants;
70 import org.kuali.rice.krms.impl.util.KrmsImplConstants;
71 import org.kuali.rice.krms.impl.util.KrmsServiceLocatorInternal;
72 import org.springframework.stereotype.Controller;
73 import org.springframework.validation.BindingResult;
74 import org.springframework.web.bind.annotation.ModelAttribute;
75 import org.springframework.web.bind.annotation.RequestMapping;
76 import org.springframework.web.bind.annotation.RequestMethod;
77 import org.springframework.web.bind.annotation.RequestParam;
78 import org.springframework.web.bind.annotation.ResponseBody;
79 import org.springframework.web.servlet.ModelAndView;
80
81
82
83
84
85 @Controller
86 @RequestMapping(value = org.kuali.rice.krms.impl.util.KrmsImplConstants.WebPaths.AGENDA_EDITOR_PATH)
87 public class AgendaEditorController extends MaintenanceDocumentController {
88
89 private static final RepositoryBoIncrementer agendaIdIncrementer = new RepositoryBoIncrementer(AgendaBo.AGENDA_SEQ_NAME);
90 private static final RepositoryBoIncrementer agendaItemIdIncrementer = new RepositoryBoIncrementer(AgendaItemBo.AGENDA_ITEM_SEQ_NAME);
91 private static final RepositoryBoIncrementer ruleIdIncrementer = new RepositoryBoIncrementer(RuleBo.RULE_SEQ_NAME);
92
93
94
95
96
97
98
99 @Override
100 @RequestMapping(params = "methodToCall=route")
101 public ModelAndView route(DocumentFormBase form) {
102
103 ModelAndView modelAndView;
104 MaintenanceDocumentForm maintenanceForm = (MaintenanceDocumentForm) form;
105 AgendaEditor agendaEditor = ((AgendaEditor) maintenanceForm.getDocument().getNewMaintainableObject().getDataObject());
106 agendaEditor.setSelectedAgendaItemId("");
107 agendaEditor.setDisableButtons(true);
108 modelAndView = super.route(form);
109
110 return modelAndView;
111 }
112
113
114
115
116
117
118 @RequestMapping(params = "methodToCall=" + "refresh")
119 @Override
120 public ModelAndView refresh(UifFormBase form) {
121 ModelAndView modelAndView = super.refresh(form);
122
123
124 MaintenanceDocumentForm maintenanceForm = (MaintenanceDocumentForm) form;
125 AgendaEditor agendaEditor = ((AgendaEditor) maintenanceForm.getDocument().getNewMaintainableObject().getDataObject());
126 AgendaEditorBusRule rule = new AgendaEditorBusRule();
127 if (rule.validContext(agendaEditor) && rule.validAgendaName(agendaEditor)) {
128
129 if (!StringUtils.equals(agendaEditor.getOldContextId(), agendaEditor.getAgenda().getContextId())) {
130 agendaEditor.setOldContextId(agendaEditor.getAgenda().getContextId());
131
132 String namespace = "";
133 if (!StringUtils.isBlank(agendaEditor.getAgenda().getContextId())) {
134 namespace = getContextBoService().getContextByContextId(agendaEditor.getAgenda().getContextId()).getNamespace();
135 }
136
137 for (AgendaItemBo agendaItem : agendaEditor.getAgenda().getItems()) {
138 agendaItem.getRule().setNamespace(namespace);
139 for (ActionBo action : agendaItem.getRule().getActions()) {
140 action.setNamespace(namespace);
141 }
142 }
143 }
144 }
145 return modelAndView;
146 }
147
148 @Override
149 public ModelAndView setupMaintenanceEdit(MaintenanceDocumentForm form) {
150
151
152 form.setPageId(null);
153 return super.setupMaintenanceEdit(form);
154 }
155
156
157
158
159 @RequestMapping(params = "methodToCall=" + "goToAddRule")
160 public ModelAndView goToAddRule(UifFormBase form) throws Exception {
161 AgendaEditor agendaEditorForBusRuleChecks = getAgendaEditor(form);
162 AgendaEditorBusRule rule = new AgendaEditorBusRule();
163 if (rule.validContext(agendaEditorForBusRuleChecks) && rule.validAgendaName(agendaEditorForBusRuleChecks)) {
164 setAgendaItemLine(form, null);
165 AgendaEditor agendaEditor = getAgendaEditor(form);
166 agendaEditor.setAddRuleInProgress(true);
167 form.getActionParameters().put(UifParameters.NAVIGATE_TO_PAGE_ID, "AgendaEditorView-AddRule-Page");
168
169 return super.navigate(form);
170 }
171
172 return super.navigate(form);
173 }
174
175
176
177
178
179
180
181
182
183 private void setAgendaItemLine(UifFormBase form, AgendaItemBo agendaItem) {
184 AgendaEditor agendaEditor = getAgendaEditor(form);
185 if (agendaItem == null) {
186 RuleBo rule = new RuleBo();
187 rule.setId(ruleIdIncrementer.getNewId());
188 if (StringUtils.isBlank(agendaEditor.getAgenda().getContextId())) {
189 rule.setNamespace("");
190 } else {
191 rule.setNamespace(getContextBoService().getContextByContextId(agendaEditor.getAgenda().getContextId()).getNamespace());
192 }
193 agendaItem = new AgendaItemBo();
194 agendaItem.setRule(rule);
195 agendaEditor.setAgendaItemLine(agendaItem);
196 } else {
197 agendaEditor.setAgendaItemLine(KradDataServiceLocator.getDataObjectService().copyInstance(agendaItem));
198 }
199
200
201 if (agendaItem.getRule().getActions().isEmpty()) {
202 ActionBo actionBo = new ActionBo();
203 actionBo.setTypeId("");
204 actionBo.setNamespace(agendaItem.getRule().getNamespace());
205 actionBo.setRule(agendaItem.getRule());
206 actionBo.setSequenceNumber(1);
207 agendaEditor.setAgendaItemLineRuleAction(actionBo);
208 } else {
209 agendaEditor.setAgendaItemLineRuleAction(agendaItem.getRule().getActions().get(0));
210 }
211
212 agendaEditor.setCustomRuleActionAttributesMap(agendaEditor.getAgendaItemLineRuleAction().getAttributes());
213 agendaEditor.setCustomRuleAttributesMap(agendaEditor.getAgendaItemLine().getRule().getAttributes());
214 }
215
216
217
218
219
220
221
222 private String getSelectedAgendaItemId(UifFormBase form) {
223 AgendaEditor agendaEditor = getAgendaEditor(form);
224 return agendaEditor.getSelectedAgendaItemId();
225 }
226
227
228
229
230
231
232
233 private void setCutAgendaItemId(UifFormBase form, String cutAgendaItemId) {
234 AgendaEditor agendaEditor = getAgendaEditor(form);
235 agendaEditor.setCutAgendaItemId(cutAgendaItemId);
236 }
237
238
239
240
241
242
243
244 private String getCutAgendaItemId(UifFormBase form) {
245 AgendaEditor agendaEditor = getAgendaEditor(form);
246 return agendaEditor.getCutAgendaItemId();
247 }
248
249
250
251
252 @RequestMapping(params = "methodToCall=" + "goToEditRule")
253 public ModelAndView goToEditRule(UifFormBase form) throws Exception {
254
255 AgendaEditor agendaEditor = getAgendaEditor(form);
256 AgendaEditorBusRule rule = new AgendaEditorBusRule();
257
258
259 agendaEditor.clearDeletedPropositionIdsFromRule();
260
261 if (rule.validContext(agendaEditor) && rule.validAgendaName(agendaEditor)) {
262 agendaEditor.setAddRuleInProgress(false);
263
264 AgendaItemBo firstItem = getFirstAgendaItem(agendaEditor.getAgenda());
265 String selectedItemId = agendaEditor.getSelectedAgendaItemId();
266 AgendaItemBo node = getAgendaItemById(firstItem, selectedItemId);
267
268 preprocessCustomOperators(node.getRule().getProposition(), getCustomOperatorValueMap(form));
269
270 setAgendaItemLine(form, node);
271
272 form.getActionParameters().put(UifParameters.NAVIGATE_TO_PAGE_ID, "AgendaEditorView-EditRule-Page");
273
274 return super.navigate(form);
275 }
276
277 return super.navigate(form);
278 }
279
280
281
282
283
284
285
286
287
288 protected Map<String,String> getCustomOperatorValueMap(UifFormBase form) {
289 List<KeyValue> allPropositionOpCodes = new PropositionOpCodeValuesFinder().getKeyValues(form);
290
291
292 Map<String, String> functionIdToCustomOpCodeMap = new HashMap<String, String>();
293 for (KeyValue opCode : allPropositionOpCodes) {
294 if (opCode.getKey().startsWith(KrmsImplConstants.CUSTOM_OPERATOR_PREFIX)) {
295 CustomOperator customOperator = getCustomOperatorUiTranslator().getCustomOperator(opCode.getKey());
296 functionIdToCustomOpCodeMap.put(customOperator.getOperatorFunctionDefinition().getId(), opCode.getKey());
297 }
298 }
299
300 return functionIdToCustomOpCodeMap;
301 }
302
303
304
305
306
307
308
309
310 protected void preprocessCustomOperators(PropositionBo proposition, Map<String, String> customOperatorValuesMap) {
311 if (proposition == null) { return; }
312
313 if (proposition.getParameters() != null && proposition.getParameters().size() > 0) {
314 for (PropositionParameterBo param : proposition.getParameters()) {
315 if (PropositionParameterType.FUNCTION.getCode().equals(param.getParameterType())) {
316
317 String convertedValue = customOperatorValuesMap.get(param.getValue());
318 if (!StringUtils.isEmpty(convertedValue)) {
319 param.setValue(convertedValue);
320 }
321 }
322 }
323 } else if (proposition.getCompoundComponents() != null && proposition.getCompoundComponents().size() > 0) {
324 for (PropositionBo childProposition : proposition.getCompoundComponents()) {
325
326 preprocessCustomOperators(childProposition, customOperatorValuesMap);
327 }
328 }
329 }
330
331
332
333
334 @RequestMapping(params = "methodToCall=" + "addRule")
335 public ModelAndView addRule(UifFormBase form) throws Exception {
336
337 AgendaEditor agendaEditor = getAgendaEditor(form);
338 AgendaBo agenda = agendaEditor.getAgenda();
339 AgendaItemBo newAgendaItem = agendaEditor.getAgendaItemLine();
340
341 if (!validateProposition(newAgendaItem.getRule().getProposition(), newAgendaItem.getRule().getNamespace())) {
342 form.getActionParameters().put(UifParameters.NAVIGATE_TO_PAGE_ID, "AgendaEditorView-AddRule-Page");
343
344 return super.navigate(form);
345 }
346
347 newAgendaItem.getRule().setAttributes(agendaEditor.getCustomRuleAttributesMap());
348
349
350
351 RuleDefinition existingRule = getRuleBoService().getRuleByRuleId( newAgendaItem.getRuleId() );
352
353 if (existingRule != null) {
354 GlobalVariables.getMessageMap().putError("AgendaEditorView-AddRule-Page",
355 "error.rule.unsavedCopyRule");
356 return super.navigate(form);
357 }
358
359 updateRuleAction(agendaEditor);
360
361 if (agenda.getItems() == null) {
362 agenda.setItems(new ArrayList<AgendaItemBo>());
363 }
364
365 AgendaEditorBusRule rule = new AgendaEditorBusRule();
366 MaintenanceDocumentForm maintenanceForm = (MaintenanceDocumentForm) form;
367 MaintenanceDocument document = maintenanceForm.getDocument();
368
369 if (rule.processAgendaItemBusinessRules(document)) {
370 newAgendaItem.setId(agendaItemIdIncrementer.getNewId());
371 newAgendaItem.setAgendaId(getCreateAgendaId(agenda));
372
373 if (agenda.getFirstItemId() == null) {
374 agenda.setFirstItem(newAgendaItem);
375 agenda.setFirstItemId(newAgendaItem.getId());
376 } else {
377
378 String selectedAgendaItemId = getSelectedAgendaItemId(form);
379
380 if (StringUtils.isBlank(selectedAgendaItemId)) {
381
382 AgendaItemBo node = getFirstAgendaItem(agenda);
383 while (node.getAlways() != null) {
384 node = node.getAlways();
385 }
386 node.setAlwaysId(newAgendaItem.getId());
387 node.setAlways(newAgendaItem);
388 } else {
389
390 AgendaItemBo firstItem = getFirstAgendaItem(agenda);
391 AgendaItemBo node = getAgendaItemById(firstItem, selectedAgendaItemId);
392 newAgendaItem.setAlwaysId(node.getAlwaysId());
393 newAgendaItem.setAlways(node.getAlways());
394 node.setAlwaysId(newAgendaItem.getId());
395 node.setAlways(newAgendaItem);
396 }
397 }
398
399 agenda.getItems().add(newAgendaItem);
400 agendaEditor.setAddRuleInProgress(false);
401 form.getActionParameters().put(UifParameters.NAVIGATE_TO_PAGE_ID, "AgendaEditorView-Agenda-Page");
402 } else {
403 form.getActionParameters().put(UifParameters.NAVIGATE_TO_PAGE_ID, "AgendaEditorView-AddRule-Page");
404 }
405
406 return super.navigate(form);
407 }
408
409
410
411
412
413
414
415
416
417 private boolean validateProposition(PropositionBo proposition, String namespace) {
418 boolean result = true;
419
420 if (proposition != null) {
421
422 if (StringUtils.isBlank(proposition.getDescription())) {
423 GlobalVariables.getMessageMap().putError(KRMSPropertyConstants.Rule.PROPOSITION_TREE_GROUP_ID,
424 "error.rule.proposition.missingDescription");
425 result &= false;
426 }
427
428 if (StringUtils.isBlank(proposition.getCompoundOpCode())) {
429
430
431 result &= validateSimpleProposition(proposition, namespace);
432
433 } else {
434
435 List<PropositionBo> compoundComponents = proposition.getCompoundComponents();
436
437 if (!CollectionUtils.isEmpty(proposition.getParameters())) {
438 GlobalVariables.getMessageMap().putError(KRMSPropertyConstants.Rule.PROPOSITION_TREE_GROUP_ID,
439 "error.rule.proposition.compound.invalidParameter", proposition.getDescription());
440 result &= false;
441 }
442
443
444 if (!CollectionUtils.isEmpty(compoundComponents)) {
445 for (PropositionBo childProp : compoundComponents) {
446 result &= validateProposition(childProp, namespace);
447 }
448 }
449 }
450 }
451
452 return result;
453 }
454
455
456
457
458
459
460
461
462 private boolean validateSimpleProposition(PropositionBo proposition, String namespace) {
463 boolean result = true;
464
465 if (!CollectionUtils.isEmpty(proposition.getCompoundComponents())) {
466 GlobalVariables.getMessageMap().putError(KRMSPropertyConstants.Rule.PROPOSITION_TREE_GROUP_ID,
467 "error.rule.proposition.simple.hasChildren", proposition.getDescription());
468 result &= false;
469 }
470
471 if (CollectionUtils.isEmpty(proposition.getParameters())) {
472 result &= false;
473
474 return result;
475 }
476
477 String propConstant = null;
478 if (proposition.getParameters().get(1) != null) {
479 propConstant = proposition.getParameters().get(1).getValue();
480 }
481 String operatorCode = null;
482 if (proposition.getParameters().get(2) != null) {
483 operatorCode = proposition.getParameters().get(2).getValue();
484 }
485
486 String termId = null;
487 if (proposition.getParameters().get(0) != null) {
488 termId = proposition.getParameters().get(0).getValue();
489 }
490
491
492 if (StringUtils.isBlank(termId)) {
493 GlobalVariables.getMessageMap().putErrorWithoutFullErrorPath(KRMSPropertyConstants.Rule.PROPOSITION_TREE_GROUP_ID,
494 "error.rule.proposition.simple.blankField", proposition.getDescription(), "Term");
495 result &= false;
496 } else {
497 result = validateTerm(proposition, namespace);
498 }
499
500 if (StringUtils.isBlank(operatorCode)) {
501 GlobalVariables.getMessageMap().putErrorWithoutFullErrorPath(KRMSPropertyConstants.Rule.PROPOSITION_TREE_GROUP_ID,
502 "error.rule.proposition.simple.blankField", proposition.getDescription(), "Operator");
503 result &= false;
504
505
506 return result;
507 }
508
509 if (StringUtils.isBlank(propConstant) && !operatorCode.endsWith("null")) {
510 GlobalVariables.getMessageMap().putErrorForSectionId(KRMSPropertyConstants.Rule.PROPOSITION_TREE_GROUP_ID,
511 "error.rule.proposition.simple.blankField", proposition.getDescription(), "Value");
512 result &= false;
513 } else if (operatorCode.endsWith("null")) {
514 if (propConstant != null) {
515 proposition.getParameters().get(1).setValue(null);
516 }
517 } else if (!StringUtils.isBlank(termId)) {
518
519 String termType = lookupTermType(termId);
520
521 if (operatorCode.startsWith(KrmsImplConstants.CUSTOM_OPERATOR_PREFIX)) {
522 CustomOperator customOperator = getCustomOperatorUiTranslator().getCustomOperator(operatorCode);
523 List<RemotableAttributeError> errors = customOperator.validateOperandClasses(termType, String.class.getName());
524
525 if (!CollectionUtils.isEmpty(errors)) {
526 for (RemotableAttributeError error : errors) {
527 GlobalVariables.getMessageMap().putError(KRMSPropertyConstants.Rule.PROPOSITION_TREE_GROUP_ID,
528 error.getMessage(), proposition.getDescription(), termType);
529 }
530
531 result &= false;
532 }
533 } else {
534 ComparisonOperatorService comparisonOperatorService = KrmsApiServiceLocator.getComparisonOperatorService();
535 if (comparisonOperatorService.canCoerce(termType, propConstant)) {
536 if (comparisonOperatorService.coerce(termType, propConstant) == null) {
537 GlobalVariables.getMessageMap().putError(KRMSPropertyConstants.Rule.PROPOSITION_TREE_GROUP_ID,
538 "error.rule.proposition.simple.invalidValue", proposition.getDescription(), propConstant);
539 result &= false;
540 }
541 }
542 }
543 }
544
545 return result;
546 }
547
548
549
550
551
552
553
554
555 private boolean validateTerm(PropositionBo proposition, String namespace) {
556 boolean result = true;
557
558 String termId = proposition.getParameters().get(0).getValue();
559 if (termId.startsWith(KrmsImplConstants.PARAMETERIZED_TERM_PREFIX)) {
560
561
562
563 if (StringUtils.isBlank(proposition.getNewTermDescription())) {
564 GlobalVariables.getMessageMap().putErrorWithoutFullErrorPath(KRMSPropertyConstants.Rule.PROPOSITION_TREE_GROUP_ID,
565 "error.rule.proposition.simple.emptyTermName", proposition.getDescription());
566 result &= false;
567 } else {
568
569 Map<String, String> critMap = new HashMap<String, String>();
570
571 critMap.put("description", proposition.getNewTermDescription());
572 critMap.put("specification.namespace", namespace);
573 QueryByCriteria criteria = QueryByCriteria.Builder.andAttributes(critMap).build();
574
575 QueryResults<TermBo> matchingTerms =
576 KRADServiceLocator.getDataObjectService().findMatching(TermBo.class, criteria);
577
578 if (!CollectionUtils.isEmpty(matchingTerms.getResults())) {
579
580 GlobalVariables.getMessageMap().putWarningWithoutFullErrorPath(KRMSPropertyConstants.Rule.PROPOSITION_TREE_GROUP_ID,
581 "warning.rule.proposition.simple.duplicateTermName", proposition.getDescription());
582 }
583 }
584
585 String termSpecificationId = termId.substring(KrmsImplConstants.PARAMETERIZED_TERM_PREFIX.length());
586
587 TermResolverDefinition termResolverDefinition =
588 AgendaEditorMaintainable.getSimplestTermResolver(termSpecificationId, namespace);
589
590 if (termResolverDefinition == null) {
591 GlobalVariables.getMessageMap().putErrorWithoutFullErrorPath(KRMSPropertyConstants.Rule.PROPOSITION_TREE_GROUP_ID,
592 "error.rule.proposition.simple.invalidTerm", proposition.getDescription());
593 result &= false;
594 } else {
595 List<String> parameterNames = new ArrayList<String>(termResolverDefinition.getParameterNames());
596 Collections.sort(parameterNames);
597 for (String parameterName : parameterNames) {
598 if (!proposition.getTermParameters().containsKey(parameterName) ||
599 StringUtils.isBlank(proposition.getTermParameters().get(parameterName))) {
600 GlobalVariables.getMessageMap().putErrorWithoutFullErrorPath(KRMSPropertyConstants.Rule.PROPOSITION_TREE_GROUP_ID,
601 "error.rule.proposition.simple.missingTermParameter", proposition.getDescription());
602 result &= false;
603 break;
604 }
605 }
606 }
607
608 } else {
609
610 TermDefinition termDefinition = KrmsRepositoryServiceLocator.getTermBoService().getTerm(termId);
611 if (termDefinition == null) {
612 GlobalVariables.getMessageMap().putErrorWithoutFullErrorPath(KRMSPropertyConstants.Rule.PROPOSITION_TREE_GROUP_ID,
613 "error.rule.proposition.simple.invalidTerm", proposition.getDescription());
614 } else if (!namespace.equals(termDefinition.getSpecification().getNamespace())) {
615 GlobalVariables.getMessageMap().putErrorWithoutFullErrorPath(KRMSPropertyConstants.Rule.PROPOSITION_TREE_GROUP_ID,
616 "error.rule.proposition.simple.invalidTerm", proposition.getDescription());
617 }
618 }
619 return result;
620 }
621
622
623
624
625
626
627 private String lookupTermType(String key) {
628 TermSpecificationDefinition termSpec = null;
629 if (key.startsWith(KrmsImplConstants.PARAMETERIZED_TERM_PREFIX)) {
630 String termSpecificationId = key.substring(KrmsImplConstants.PARAMETERIZED_TERM_PREFIX.length());
631 termSpec = KrmsRepositoryServiceLocator.getTermBoService().getTermSpecificationById(termSpecificationId);
632 } else {
633 TermDefinition term = KrmsRepositoryServiceLocator.getTermBoService().getTerm(key);
634 if (term != null) {
635 termSpec = term.getSpecification();
636 }
637 }
638 if (termSpec != null) {
639 return termSpec.getType();
640 } else {
641 return null;
642 }
643 }
644
645
646
647
648
649 private String getCreateAgendaId(AgendaBo agenda) {
650 if (agenda.getId() == null) {
651 agenda.setId(agendaIdIncrementer.getNewId());
652 }
653
654 return agenda.getId();
655 }
656
657 private void updateRuleAction(AgendaEditor agendaEditor) {
658 agendaEditor.getAgendaItemLine().getRule().setActions(new ArrayList<ActionBo>());
659 if (StringUtils.isNotBlank(agendaEditor.getAgendaItemLineRuleAction().getTypeId())) {
660 agendaEditor.getAgendaItemLineRuleAction().setAttributes(agendaEditor.getCustomRuleActionAttributesMap());
661 agendaEditor.getAgendaItemLine().getRule().getActions().add(agendaEditor.getAgendaItemLineRuleAction());
662 }
663 }
664
665
666
667
668
669
670
671 private Map<String, KrmsAttributeDefinition> buildAttributeDefinitionMap(String actionTypeId) {
672 KrmsAttributeDefinitionService attributeDefinitionService =
673 KrmsRepositoryServiceLocator.getKrmsAttributeDefinitionService();
674
675
676 Map<String, KrmsAttributeDefinition> attributeDefinitionMap = new HashMap<String, KrmsAttributeDefinition>();
677
678 List<KrmsAttributeDefinition> attributeDefinitions =
679 attributeDefinitionService.findAttributeDefinitionsByType(actionTypeId);
680
681 for (KrmsAttributeDefinition attributeDefinition : attributeDefinitions) {
682 attributeDefinitionMap.put(attributeDefinition.getName(), attributeDefinition);
683 }
684 return attributeDefinitionMap;
685 }
686
687
688
689
690 @RequestMapping(params = "methodToCall=" + "editRule")
691 public ModelAndView editRule(UifFormBase form) throws Exception {
692 AgendaEditor agendaEditor = getAgendaEditor(form);
693
694 AgendaItemBo firstItem = getFirstAgendaItem(agendaEditor.getAgenda());
695 AgendaItemBo node = getAgendaItemById(firstItem, getSelectedAgendaItemId(form));
696 AgendaItemBo agendaItemLine = agendaEditor.getAgendaItemLine();
697
698 if (!validateProposition(agendaItemLine.getRule().getProposition(), agendaItemLine.getRule().getNamespace())) {
699 form.getActionParameters().put(UifParameters.NAVIGATE_TO_PAGE_ID, "AgendaEditorView-EditRule-Page");
700
701 return super.navigate(form);
702 }
703
704 agendaItemLine.getRule().setAttributes(agendaEditor.getCustomRuleAttributesMap());
705 updateRuleAction(agendaEditor);
706
707 AgendaEditorBusRule rule = new AgendaEditorBusRule();
708 MaintenanceDocumentForm maintenanceForm = (MaintenanceDocumentForm) form;
709 MaintenanceDocument document = maintenanceForm.getDocument();
710 if (rule.processAgendaItemBusinessRules(document)) {
711 node.setRule(agendaItemLine.getRule());
712 form.getActionParameters().put(UifParameters.NAVIGATE_TO_PAGE_ID, "AgendaEditorView-Agenda-Page");
713 } else {
714 form.getActionParameters().put(UifParameters.NAVIGATE_TO_PAGE_ID, "AgendaEditorView-EditRule-Page");
715 }
716
717
718 agendaEditor.applyDeletedPropositionIdsFromRule();
719
720 return super.navigate(form);
721 }
722
723
724
725
726
727
728 private AgendaItemInstanceChildAccessor getLastChildsAlwaysAccessor(AgendaItemInstanceChildAccessor instanceAccessor) {
729 AgendaItemBo next = instanceAccessor.getChild();
730 if (next == null) {
731 return instanceAccessor;
732 }
733 while (next.getAlways() != null) { next = next.getAlways(); };
734 return new AgendaItemInstanceChildAccessor(AgendaItemChildAccessor.always, next);
735 }
736
737
738
739
740
741
742 private AgendaItemInstanceChildAccessor getInstanceAccessorToChild(AgendaItemBo parent, String agendaItemId) {
743
744
745 for (AgendaItemChildAccessor levelOrderChildAccessor : AgendaItemChildAccessor.children) {
746
747 AgendaItemBo next = levelOrderChildAccessor.getChild(parent);
748
749
750 if (next != null && agendaItemId.equals(next.getId())) {
751 return new AgendaItemInstanceChildAccessor(levelOrderChildAccessor, parent);
752 }
753
754
755 while (next != null && next.getAlwaysId() != null) {
756 if (next.getAlwaysId().equals(agendaItemId)) {
757 return new AgendaItemInstanceChildAccessor(AgendaItemChildAccessor.always, next);
758 }
759
760 next = next.getAlways();
761 }
762 }
763
764 return null;
765 }
766
767 @RequestMapping(params = "methodToCall=" + "ajaxRefresh")
768 public ModelAndView ajaxRefresh(@ModelAttribute("KualiForm") UifFormBase form, BindingResult result,
769 HttpServletRequest request, HttpServletResponse response)
770 throws Exception {
771
772 return getModelAndView(form);
773 }
774
775 @RequestMapping(params = "methodToCall=" + "ajaxMoveUp")
776 public ModelAndView ajaxMoveUp(@ModelAttribute("KualiForm") UifFormBase form, BindingResult result,
777 HttpServletRequest request, HttpServletResponse response)
778 throws Exception {
779 moveSelectedSubtreeUp(form);
780
781
782 return getModelAndView(form);
783 }
784
785
786
787
788
789
790
791 @RequestMapping(params = "methodToCall=" + "ajaxValidRuleName", method=RequestMethod.GET)
792 public @ResponseBody boolean ajaxValidRuleName(@RequestParam String name, @RequestParam String namespace) {
793 return (getRuleBoService().getRuleByNameAndNamespace(name, namespace) != null);
794 }
795
796
797
798
799
800
801 private void moveSelectedSubtreeUp(UifFormBase form) {
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822 AgendaEditor agendaEditor = getAgendaEditor(form);
823
824 AgendaItemBo firstItem = getFirstAgendaItem(agendaEditor.getAgenda());
825
826 String selectedItemId = agendaEditor.getSelectedAgendaItemId();
827 AgendaItemBo node = getAgendaItemById(firstItem, selectedItemId);
828 AgendaItemBo parent = getParent(firstItem, selectedItemId);
829 AgendaItemBo parentsOlderCousin = (parent == null) ? null : getNextOldestOfSameGeneration(firstItem, parent);
830
831 StringBuilder ruleEditorMessage = new StringBuilder();
832 AgendaItemChildAccessor childAccessor = getOldestChildAccessor(node, parent);
833 if (childAccessor != null) {
834 if (childAccessor == AgendaItemChildAccessor.whenFalse) {
835
836 AgendaItemInstanceChildAccessor youngestWhenTrueSiblingInsertionPoint =
837 getLastChildsAlwaysAccessor(new AgendaItemInstanceChildAccessor(AgendaItemChildAccessor.whenTrue, parent));
838 youngestWhenTrueSiblingInsertionPoint.setChild(node);
839 AgendaItemChildAccessor.whenFalse.setChild(parent, node.getAlways());
840 AgendaItemChildAccessor.always.setChild(node, null);
841
842 ruleEditorMessage.append("Moved ").append(node.getRule().getName()).append(" up ");
843 ruleEditorMessage.append("to last position in When TRUE group of ").append(parent.getRule().getName());
844 } else if (parentsOlderCousin != null) {
845
846 AgendaItemInstanceChildAccessor youngestWhenFalseSiblingInsertionPoint =
847 getLastChildsAlwaysAccessor(new AgendaItemInstanceChildAccessor(AgendaItemChildAccessor.whenFalse, parentsOlderCousin));
848 youngestWhenFalseSiblingInsertionPoint.setChild(node);
849 AgendaItemChildAccessor.whenTrue.setChild(parent, node.getAlways());
850 AgendaItemChildAccessor.always.setChild(node, null);
851 ruleEditorMessage.append("Moved ").append(node.getRule().getName()).append(" up ");
852 ruleEditorMessage.append("to When FALSE group of ").append(parentsOlderCousin.getRule().getName());
853 }
854 } else if (!selectedItemId.equals(firstItem.getId())) {
855
856 AgendaItemBo bogusRootNode = null;
857 if (parent == null) {
858
859 bogusRootNode = new AgendaItemBo();
860 AgendaItemChildAccessor.whenTrue.setChild(bogusRootNode, firstItem);
861 parent = bogusRootNode;
862 }
863
864
865 AgendaItemInstanceChildAccessor accessorToSelectedNode = getInstanceAccessorToChild(parent, node.getId());
866 AgendaItemBo olderSibling = accessorToSelectedNode.getInstance();
867 AgendaItemInstanceChildAccessor accessorToOlderSibling = getInstanceAccessorToChild(parent, olderSibling.getId());
868
869 accessorToOlderSibling.setChild(node);
870 accessorToSelectedNode.setChild(node.getAlways());
871 AgendaItemChildAccessor.always.setChild(node, olderSibling);
872
873 ruleEditorMessage.append("Moved ").append(node.getRule().getName()).append(" up ");
874
875 if (bogusRootNode != null) {
876
877 agendaEditor.getAgenda().setFirstItemId(bogusRootNode.getWhenTrueId());
878 agendaEditor.getAgenda().setFirstItem(bogusRootNode.getWhenTrue());
879 ruleEditorMessage.append(" to ").append(getFirstAgendaItem(agendaEditor.getAgenda()).getRule().getName()).append(" When TRUE group");
880 } else {
881 ruleEditorMessage.append(" within its sibling group, above " + olderSibling.getRule().getName());
882 }
883 }
884 agendaEditor.setRuleEditorMessage(ruleEditorMessage.toString());
885 }
886
887 @RequestMapping(params = "methodToCall=" + "ajaxMoveDown")
888 public ModelAndView ajaxMoveDown(@ModelAttribute("KualiForm") UifFormBase form, BindingResult result,
889 HttpServletRequest request, HttpServletResponse response)
890 throws Exception {
891 moveSelectedSubtreeDown(form);
892
893
894 return getModelAndView(form);
895 }
896
897
898
899
900
901
902 private void moveSelectedSubtreeDown(UifFormBase form) {
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923 AgendaEditor agendaEditor = getAgendaEditor(form);
924
925 AgendaItemBo firstItem = getFirstAgendaItem(agendaEditor.getAgenda());
926
927 String selectedItemId = agendaEditor.getSelectedAgendaItemId();
928 AgendaItemBo node = getAgendaItemById(firstItem, selectedItemId);
929 AgendaItemBo parent = getParent(firstItem, selectedItemId);
930 AgendaItemBo parentsYoungerCousin = (parent == null) ? null : getNextYoungestOfSameGeneration(firstItem, parent);
931
932 StringBuilder ruleEditorMessage = new StringBuilder();
933 if (node.getAlways() == null && parent != null) {
934
935 if (parent.getWhenTrue() != null && isSiblings(parent.getWhenTrue(), node)) {
936
937 AgendaItemInstanceChildAccessor accessorToSelectedNode = getInstanceAccessorToChild(parent, node.getId());
938 accessorToSelectedNode.setChild(null);
939
940 AgendaItemBo parentsFirstChild = parent.getWhenFalse();
941 AgendaItemChildAccessor.whenFalse.setChild(parent, node);
942 AgendaItemChildAccessor.always.setChild(node, parentsFirstChild);
943
944 ruleEditorMessage.append("Moved ").append(node.getRule().getName()).append(" down ");
945 ruleEditorMessage.append("to first child under When FALSE group of ").append(parent.getRule().getName());
946 } else if (parentsYoungerCousin != null) {
947
948 AgendaItemInstanceChildAccessor accessorToSelectedNode = getInstanceAccessorToChild(parent, node.getId());
949 accessorToSelectedNode.setChild(null);
950
951 AgendaItemBo parentsYoungerCousinsFirstChild = parentsYoungerCousin.getWhenTrue();
952 AgendaItemChildAccessor.whenTrue.setChild(parentsYoungerCousin, node);
953 AgendaItemChildAccessor.always.setChild(node, parentsYoungerCousinsFirstChild);
954
955 ruleEditorMessage.append("Moved ").append(node.getRule().getName()).append(" down ");
956 ruleEditorMessage.append("to first child under When TRUE group of ").append(parentsYoungerCousin.getRule().getName());
957 }
958 } else if (node.getAlways() != null) {
959
960 AgendaItemBo bogusRootNode = null;
961 if (parent == null) {
962
963
964 bogusRootNode = new AgendaItemBo();
965 AgendaItemChildAccessor.whenFalse.setChild(bogusRootNode, firstItem);
966 parent = bogusRootNode;
967 }
968
969
970 AgendaItemInstanceChildAccessor accessorToSelectedNode = getInstanceAccessorToChild(parent, node.getId());
971 AgendaItemBo youngerSibling = node.getAlways();
972 accessorToSelectedNode.setChild(youngerSibling);
973 AgendaItemChildAccessor.always.setChild(node, youngerSibling.getAlways());
974 AgendaItemChildAccessor.always.setChild(youngerSibling, node);
975
976 if (bogusRootNode != null) {
977
978 agendaEditor.getAgenda().setFirstItemId(bogusRootNode.getWhenFalseId());
979 agendaEditor.getAgenda().setFirstItem(bogusRootNode.getWhenFalse());
980 }
981 ruleEditorMessage.append("Moved ").append(node.getRule().getName()).append(" down ");
982 ruleEditorMessage.append(" within its sibling group, below ").append(youngerSibling.getRule().getName());
983 }
984 agendaEditor.setRuleEditorMessage(ruleEditorMessage.toString());
985 }
986
987 @RequestMapping(params = "methodToCall=" + "ajaxMoveLeft")
988 public ModelAndView ajaxMoveLeft(@ModelAttribute("KualiForm") UifFormBase form, BindingResult result,
989 HttpServletRequest request, HttpServletResponse response)
990 throws Exception {
991
992 moveSelectedSubtreeLeft(form);
993
994
995 return getModelAndView(form);
996 }
997
998
999
1000
1001
1002
1003 private void moveSelectedSubtreeLeft(UifFormBase form) {
1004
1005
1006
1007
1008
1009 AgendaEditor agendaEditor = getAgendaEditor(form);
1010
1011 AgendaItemBo firstItem = getFirstAgendaItem(agendaEditor.getAgenda());
1012
1013 String selectedItemId = agendaEditor.getSelectedAgendaItemId();
1014 AgendaItemBo node = getAgendaItemById(firstItem, selectedItemId);
1015 AgendaItemBo parent = getParent(firstItem, selectedItemId);
1016
1017 if (parent != null) {
1018 AgendaItemInstanceChildAccessor accessorToSelectedNode = getInstanceAccessorToChild(parent, node.getId());
1019 accessorToSelectedNode.setChild(node.getAlways());
1020 AgendaItemChildAccessor.always.setChild(node, parent.getAlways());
1021 AgendaItemChildAccessor.always.setChild(parent, node);
1022
1023 StringBuilder ruleEditorMessage = new StringBuilder();
1024 ruleEditorMessage.append("Moved ").append(node.getRule().getName()).append(" left to be a sibling of its parent ").append(parent.getRule().getName());
1025 agendaEditor.setRuleEditorMessage(ruleEditorMessage.toString());
1026 }
1027 }
1028
1029 @RequestMapping(params = "methodToCall=" + "ajaxMoveRight")
1030 public ModelAndView ajaxMoveRight(@ModelAttribute("KualiForm") UifFormBase form, BindingResult result,
1031 HttpServletRequest request, HttpServletResponse response)
1032 throws Exception {
1033
1034 moveSelectedSubtreeRight(form);
1035
1036
1037 return getModelAndView(form);
1038 }
1039
1040
1041
1042
1043
1044
1045 private void moveSelectedSubtreeRight(UifFormBase form) {
1046
1047
1048
1049
1050
1051
1052
1053 AgendaEditor agendaEditor = getAgendaEditor(form);
1054
1055 AgendaItemBo firstItem = getFirstAgendaItem(agendaEditor.getAgenda());
1056
1057 String selectedItemId = agendaEditor.getSelectedAgendaItemId();
1058 AgendaItemBo node = getAgendaItemById(firstItem, selectedItemId);
1059 AgendaItemBo parent = getParent(firstItem, selectedItemId);
1060
1061 AgendaItemBo bogusRootNode = null;
1062 if (parent == null) {
1063
1064 bogusRootNode = new AgendaItemBo();
1065 AgendaItemChildAccessor.whenFalse.setChild(bogusRootNode, firstItem);
1066 parent = bogusRootNode;
1067 }
1068
1069 AgendaItemInstanceChildAccessor accessorToSelectedNode = getInstanceAccessorToChild(parent, node.getId());
1070 AgendaItemBo olderSibling = (accessorToSelectedNode.getInstance() == parent) ? null : accessorToSelectedNode.getInstance();
1071
1072 StringBuilder ruleEditorMessage = new StringBuilder();
1073 if (olderSibling != null) {
1074 accessorToSelectedNode.setChild(node.getAlways());
1075 AgendaItemInstanceChildAccessor yougestWhenFalseSiblingInsertionPoint =
1076 getLastChildsAlwaysAccessor(new AgendaItemInstanceChildAccessor(AgendaItemChildAccessor.whenFalse, olderSibling));
1077 yougestWhenFalseSiblingInsertionPoint.setChild(node);
1078 AgendaItemChildAccessor.always.setChild(node, null);
1079
1080 ruleEditorMessage.append("Moved ").append(node.getRule().getName()).append(" right to ");
1081 ruleEditorMessage.append(olderSibling.getRule().getName()).append(" When FALSE group.");
1082 } else if (node.getAlways() != null) {
1083 accessorToSelectedNode.setChild(node.getAlways());
1084 AgendaItemBo childsWhenTrue = node.getAlways().getWhenTrue();
1085 AgendaItemChildAccessor.whenTrue.setChild(node.getAlways(), node);
1086 AgendaItemChildAccessor.always.setChild(node, childsWhenTrue);
1087
1088 ruleEditorMessage.append("Moved ").append(node.getRule().getName()).append(" right to ");
1089 if (childsWhenTrue != null) {
1090 ruleEditorMessage.append(childsWhenTrue.getRule().getName()).append(" When TRUE group");
1091 }
1092 }
1093
1094 if (bogusRootNode != null) {
1095
1096 agendaEditor.getAgenda().setFirstItemId(bogusRootNode.getWhenFalseId());
1097 agendaEditor.getAgenda().setFirstItem(bogusRootNode.getWhenFalse());
1098 ruleEditorMessage.append(getFirstAgendaItem(agendaEditor.getAgenda()).getRule().getName()).append(" When TRUE group");
1099 }
1100 agendaEditor.setRuleEditorMessage(ruleEditorMessage.toString());
1101 }
1102
1103
1104
1105
1106
1107
1108
1109
1110 private boolean isSiblings(AgendaItemBo cousin1, AgendaItemBo cousin2) {
1111 if (cousin1.equals(cousin2))
1112 {
1113 return true;
1114 }
1115
1116
1117 AgendaItemBo candidate = cousin2;
1118 while (null != (candidate = candidate.getAlways())) {
1119 if (candidate.equals(cousin1)) {
1120 return true;
1121 }
1122 }
1123
1124 candidate = cousin1;
1125 while (null != (candidate = candidate.getAlways())) {
1126 if (candidate.equals(cousin2)) {
1127 return true;
1128 }
1129 }
1130 return false;
1131 }
1132
1133
1134
1135
1136
1137
1138
1139 private AgendaItemChildAccessor getOldestChildAccessor(
1140 AgendaItemBo child, AgendaItemBo parent) {
1141 AgendaItemChildAccessor levelOrderChildAccessor = null;
1142
1143 if (parent != null) {
1144 for (AgendaItemChildAccessor childAccessor : AgendaItemChildAccessor.children) {
1145 if (child.equals(childAccessor.getChild(parent))) {
1146 levelOrderChildAccessor = childAccessor;
1147 break;
1148 }
1149 }
1150 }
1151 return levelOrderChildAccessor;
1152 }
1153
1154
1155
1156
1157
1158
1159
1160 private AgendaItemBo getFirstAgendaItem(AgendaBo agenda) {
1161 AgendaItemBo firstItem = null;
1162 if (agenda != null && agenda.getItems() != null) {
1163 for (AgendaItemBo agendaItem : agenda.getItems()) {
1164 if (agenda.getFirstItemId().equals(agendaItem.getId())) {
1165 firstItem = agendaItem;
1166 break;
1167 }
1168 }
1169 }
1170 return firstItem;
1171 }
1172
1173
1174
1175
1176
1177
1178 private AgendaItemBo getNextYoungestOfSameGeneration(AgendaItemBo root, AgendaItemBo agendaItem) {
1179
1180 int genNumber = getAgendaItemGenerationNumber(0, root, agendaItem.getId());
1181 List<AgendaItemBo> genList = new ArrayList<AgendaItemBo>();
1182 buildAgendaItemGenerationList(genList, root, 0, genNumber);
1183
1184 int itemIndex = genList.indexOf(agendaItem);
1185 if (genList.size() > itemIndex + 1) {
1186 return genList.get(itemIndex + 1);
1187 }
1188
1189 return null;
1190 }
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200 private int getAgendaItemGenerationNumber(int currentLevel, AgendaItemBo node, String agendaItemId) {
1201 int result = -1;
1202 if (agendaItemId.equals(node.getId())) {
1203 result = currentLevel;
1204 } else {
1205 for (AgendaItemChildAccessor childAccessor : AgendaItemChildAccessor.linkedNodes) {
1206 AgendaItemBo child = childAccessor.getChild(node);
1207 if (child != null) {
1208 int nextLevel = currentLevel;
1209
1210 if (childAccessor != AgendaItemChildAccessor.always) {
1211 nextLevel = currentLevel +1;
1212 }
1213 result = getAgendaItemGenerationNumber(nextLevel, child, agendaItemId);
1214 if (result != -1) {
1215 break;
1216 }
1217 }
1218 }
1219 }
1220 return result;
1221 }
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231 private void buildAgendaItemGenerationList(List<AgendaItemBo> genList, AgendaItemBo node, int currentLevel, int generation) {
1232 if (currentLevel == generation) {
1233 genList.add(node);
1234 }
1235
1236 if (currentLevel > generation) {
1237 return;
1238 }
1239
1240 for (AgendaItemChildAccessor childAccessor : AgendaItemChildAccessor.linkedNodes) {
1241 AgendaItemBo child = childAccessor.getChild(node);
1242 if (child != null) {
1243 int nextLevel = currentLevel;
1244
1245 if (childAccessor != AgendaItemChildAccessor.always) {
1246 nextLevel = currentLevel +1;
1247 }
1248 buildAgendaItemGenerationList(genList, child, nextLevel, generation);
1249 }
1250 }
1251 }
1252
1253
1254
1255
1256
1257
1258 private AgendaItemBo getNextOldestOfSameGeneration(AgendaItemBo root, AgendaItemBo agendaItem) {
1259
1260 int genNumber = getAgendaItemGenerationNumber(0, root, agendaItem.getId());
1261 List<AgendaItemBo> genList = new ArrayList<AgendaItemBo>();
1262 buildAgendaItemGenerationList(genList, root, 0, genNumber);
1263
1264 int itemIndex = genList.indexOf(agendaItem);
1265 if (itemIndex >= 1) {
1266 return genList.get(itemIndex - 1);
1267 }
1268
1269 return null;
1270 }
1271
1272
1273
1274
1275
1276
1277 private AgendaItemBo getParent(AgendaItemBo root, String agendaItemId) {
1278 return getParentHelper(root, null, agendaItemId);
1279 }
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289 private AgendaItemBo getParentHelper(AgendaItemBo node, AgendaItemBo levelOrderParent, String agendaItemId) {
1290 AgendaItemBo result = null;
1291 if (agendaItemId.equals(node.getId())) {
1292 result = levelOrderParent;
1293 } else {
1294 for (AgendaItemChildAccessor childAccessor : AgendaItemChildAccessor.linkedNodes) {
1295 AgendaItemBo child = childAccessor.getChild(node);
1296 if (child != null) {
1297
1298 AgendaItemBo lop = (childAccessor == AgendaItemChildAccessor.always) ? levelOrderParent : node;
1299 result = getParentHelper(child, lop, agendaItemId);
1300 if (result != null) {
1301 break;
1302 }
1303 }
1304 }
1305 }
1306 return result;
1307 }
1308
1309
1310
1311
1312 private AgendaItemBo getAgendaItemById(AgendaItemBo node, String agendaItemId) {
1313 if (node == null) {
1314 throw new IllegalArgumentException("node must be non-null");
1315 }
1316
1317 AgendaItemBo result = null;
1318
1319 if (agendaItemId.equals(node.getId())) {
1320 result = node;
1321 } else {
1322 for (AgendaItemChildAccessor childAccessor : AgendaItemChildAccessor.linkedNodes) {
1323 AgendaItemBo child = childAccessor.getChild(node);
1324 if (child != null) {
1325 result = getAgendaItemById(child, agendaItemId);
1326 if (result != null) {
1327 break;
1328 }
1329 }
1330 }
1331 }
1332 return result;
1333 }
1334
1335
1336
1337
1338
1339 private AgendaEditor getAgendaEditor(UifFormBase form) {
1340 MaintenanceDocumentForm maintenanceForm = (MaintenanceDocumentForm) form;
1341 return ((AgendaEditor)maintenanceForm.getDocument().getDocumentDataObject());
1342 }
1343
1344 @RequestMapping(params = "methodToCall=" + "ajaxDelete")
1345 public ModelAndView ajaxDelete(@ModelAttribute("KualiForm") UifFormBase form, BindingResult result,
1346 HttpServletRequest request, HttpServletResponse response)
1347 throws Exception {
1348
1349 deleteSelectedSubtree(form);
1350
1351
1352 return getModelAndView(form);
1353 }
1354
1355 private void deleteSelectedSubtree(UifFormBase form) {
1356 AgendaEditor agendaEditor = getAgendaEditor(form);
1357 AgendaItemBo firstItem = getFirstAgendaItem(agendaEditor.getAgenda());
1358
1359 if (firstItem != null) {
1360 String agendaItemSelected = agendaEditor.getSelectedAgendaItemId();
1361 AgendaItemBo selectedItem = getAgendaItemById(firstItem, agendaItemSelected);
1362
1363
1364 if (agendaItemSelected.equals(firstItem.getId())) {
1365 agendaEditor.getAgenda().setFirstItemId(firstItem.getAlwaysId());
1366 agendaEditor.getAgenda().setFirstItem(firstItem.getAlways());
1367 } else {
1368 deleteAgendaItem(firstItem, agendaItemSelected);
1369 }
1370
1371 StringBuilder ruleEditorMessage = new StringBuilder();
1372 ruleEditorMessage.append("Deleted ").append(selectedItem.getRule().getName());
1373
1374 if (selectedItem.getWhenTrue() != null) {
1375 removeAgendaItem(agendaEditor.getAgenda().getItems(), selectedItem.getWhenTrue());
1376 ruleEditorMessage.append(" and its When TRUE ").append(selectedItem.getWhenTrue().getRule().getName());
1377 }
1378 if (selectedItem.getWhenFalse() != null) {
1379 removeAgendaItem(agendaEditor.getAgenda().getItems(), selectedItem.getWhenFalse());
1380 ruleEditorMessage.append(" and its When FALSE ").append(selectedItem.getWhenFalse().getRule().getName());
1381 }
1382 agendaEditor.getAgenda().getItems().remove(selectedItem);
1383 agendaEditor.setRuleEditorMessage(ruleEditorMessage.toString());
1384 }
1385 }
1386
1387 private void deleteAgendaItem(AgendaItemBo root, String agendaItemIdToDelete) {
1388 if (deleteAgendaItem(root, AgendaItemChildAccessor.whenTrue, agendaItemIdToDelete) ||
1389 deleteAgendaItem(root, AgendaItemChildAccessor.whenFalse, agendaItemIdToDelete) ||
1390 deleteAgendaItem(root, AgendaItemChildAccessor.always, agendaItemIdToDelete))
1391 {
1392 ;
1393 }
1394 }
1395
1396 private boolean deleteAgendaItem(AgendaItemBo agendaItem, AgendaItemChildAccessor childAccessor, String agendaItemIdToDelete) {
1397 if (agendaItem == null || childAccessor.getChild(agendaItem) == null) {
1398 return false;
1399 }
1400 if (agendaItemIdToDelete.equals(childAccessor.getChild(agendaItem).getId())) {
1401
1402 AgendaItemBo grandchildToKeep = childAccessor.getChild(agendaItem).getAlways();
1403 childAccessor.setChild(agendaItem, grandchildToKeep);
1404 return true;
1405 } else {
1406 AgendaItemBo child = childAccessor.getChild(agendaItem);
1407
1408 for (AgendaItemChildAccessor nextChildAccessor : AgendaItemChildAccessor.linkedNodes) {
1409 if (deleteAgendaItem(child, nextChildAccessor, agendaItemIdToDelete)) {
1410 return true;
1411 }
1412 }
1413 }
1414 return false;
1415 }
1416
1417
1418
1419
1420
1421
1422 private void removeAgendaItem(List<AgendaItemBo> items, AgendaItemBo removeAgendaItem) {
1423 if (removeAgendaItem.getWhenTrue() != null) {
1424 removeAgendaItem(items, removeAgendaItem.getWhenTrue());
1425 }
1426 if (removeAgendaItem.getWhenFalse() != null) {
1427 removeAgendaItem(items, removeAgendaItem.getWhenFalse());
1428 }
1429 if (removeAgendaItem.getAlways() != null) {
1430 removeAgendaItem(items, removeAgendaItem.getAlways());
1431 }
1432 items.remove(removeAgendaItem);
1433 }
1434
1435 @RequestMapping(params = "methodToCall=" + "ajaxCut")
1436 public ModelAndView ajaxCut(@ModelAttribute("KualiForm") UifFormBase form, BindingResult result,
1437 HttpServletRequest request, HttpServletResponse response) throws Exception {
1438
1439 AgendaEditor agendaEditor = getAgendaEditor(form);
1440
1441 AgendaItemBo firstItem = getFirstAgendaItem(agendaEditor.getAgenda());
1442 String selectedItemId = agendaEditor.getSelectedAgendaItemId();
1443
1444 AgendaItemBo selectedAgendaItem = getAgendaItemById(firstItem, selectedItemId);
1445 setCutAgendaItemId(form, selectedItemId);
1446
1447 StringBuilder ruleEditorMessage = new StringBuilder();
1448 ruleEditorMessage.append("Marked ").append(selectedAgendaItem.getRule().getName()).append(" for cutting.");
1449 agendaEditor.setRuleEditorMessage(ruleEditorMessage.toString());
1450
1451 return getModelAndView(form);
1452 }
1453
1454 @RequestMapping(params = "methodToCall=" + "ajaxPaste")
1455 public ModelAndView ajaxPaste(@ModelAttribute("KualiForm") UifFormBase form, BindingResult result,
1456 HttpServletRequest request, HttpServletResponse response) throws Exception {
1457
1458 AgendaEditor agendaEditor = getAgendaEditor(form);
1459
1460 AgendaItemBo firstItem = getFirstAgendaItem(agendaEditor.getAgenda());
1461 String selectedItemId = agendaEditor.getSelectedAgendaItemId();
1462
1463 String agendaItemId = getCutAgendaItemId(form);
1464 if (StringUtils.isNotBlank(selectedItemId) && StringUtils.isNotBlank(agendaItemId)) {
1465 StringBuilder ruleEditorMessage = new StringBuilder();
1466 AgendaItemBo node = getAgendaItemById(firstItem, agendaItemId);
1467 AgendaItemBo orgRefNode = getReferringNode(firstItem, agendaItemId);
1468 AgendaItemBo newRefNode = getAgendaItemById(firstItem, selectedItemId);
1469
1470 if (isSameOrChildNode(node, newRefNode)) {
1471
1472
1473 ruleEditorMessage.append("Cannot paste ").append(node.getRule().getName()).append(" to itself.");
1474 } else {
1475
1476 if (orgRefNode == null) {
1477 agendaEditor.getAgenda().setFirstItemId(node.getAlwaysId());
1478 agendaEditor.getAgenda().setFirstItem(node.getAlways());
1479 } else {
1480
1481
1482 if (node.getId().equals(orgRefNode.getWhenTrueId())) {
1483 orgRefNode.setWhenTrueId(node.getAlwaysId());
1484 orgRefNode.setWhenTrue(node.getAlways());
1485 } else if(node.getId().equals(orgRefNode.getWhenFalseId())) {
1486 orgRefNode.setWhenFalseId(node.getAlwaysId());
1487 orgRefNode.setWhenFalse(node.getAlways());
1488 } else {
1489 orgRefNode.setAlwaysId(node.getAlwaysId());
1490 orgRefNode.setAlways(node.getAlways());
1491 }
1492 }
1493
1494
1495 node.setAlwaysId(newRefNode.getAlwaysId());
1496 node.setAlways(newRefNode.getAlways());
1497 newRefNode.setAlwaysId(node.getId());
1498 newRefNode.setAlways(node);
1499
1500 ruleEditorMessage.append(" Pasted ").append(node.getRule().getName());
1501 ruleEditorMessage.append(" to ").append(newRefNode.getRule().getName());
1502 agendaEditor.setRuleEditorMessage(ruleEditorMessage.toString());
1503
1504 }
1505 setCutAgendaItemId(form, null);
1506 }
1507
1508
1509
1510 return getModelAndView(form);
1511 }
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522 private boolean isSameOrChildNode(AgendaItemBo node, AgendaItemBo newParent) {
1523 return isSameOrChildNodeHelper(node, newParent, AgendaItemChildAccessor.children);
1524 }
1525
1526 private boolean isSameOrChildNodeHelper(AgendaItemBo node, AgendaItemBo newParent, AgendaItemChildAccessor[] childAccessors) {
1527 boolean result = false;
1528 if (newParent == null || node == null) {
1529 return false;
1530 }
1531 if (StringUtils.equals(node.getId(), newParent.getId())) {
1532 result = true;
1533 } else {
1534 for (AgendaItemChildAccessor childAccessor : childAccessors) {
1535 AgendaItemBo child = childAccessor.getChild(node);
1536 if (child != null) {
1537 result = isSameOrChildNodeHelper(child, newParent, AgendaItemChildAccessor.linkedNodes);
1538 if (result == true) {
1539 break;
1540 }
1541 }
1542 }
1543 }
1544 return result;
1545 }
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556 private AgendaItemBo getReferringNode(AgendaItemBo root, String agendaItemId) {
1557 return getReferringNodeHelper(root, null, agendaItemId);
1558 }
1559
1560 private AgendaItemBo getReferringNodeHelper(AgendaItemBo node, AgendaItemBo referringNode, String agendaItemId) {
1561 AgendaItemBo result = null;
1562 if (agendaItemId.equals(node.getId())) {
1563 result = referringNode;
1564 } else {
1565 for (AgendaItemChildAccessor childAccessor : AgendaItemChildAccessor.linkedNodes) {
1566 AgendaItemBo child = childAccessor.getChild(node);
1567 if (child != null) {
1568 result = getReferringNodeHelper(child, node, agendaItemId);
1569 if (result != null) {
1570 break;
1571 }
1572 }
1573 }
1574 }
1575 return result;
1576 }
1577
1578 private FunctionBoService getFunctionBoService() {
1579 return KrmsRepositoryServiceLocator.getFunctionBoService();
1580 }
1581
1582
1583
1584
1585 private ContextBoService getContextBoService() {
1586 return KrmsRepositoryServiceLocator.getContextBoService();
1587 }
1588
1589
1590
1591
1592 private RuleBoService getRuleBoService() {
1593 return KrmsRepositoryServiceLocator.getRuleBoService();
1594 }
1595
1596 private CustomOperatorUiTranslator getCustomOperatorUiTranslator() {
1597 return KrmsServiceLocatorInternal.getCustomOperatorUiTranslator();
1598 }
1599
1600
1601
1602
1603
1604 private static class AgendaItemInstanceChildAccessor {
1605
1606 private final AgendaItemChildAccessor accessor;
1607 private final AgendaItemBo instance;
1608
1609 public AgendaItemInstanceChildAccessor(AgendaItemChildAccessor accessor, AgendaItemBo instance) {
1610 this.accessor = accessor;
1611 this.instance = instance;
1612 }
1613
1614 public void setChild(AgendaItemBo child) {
1615 accessor.setChild(instance, child);
1616 }
1617
1618 public AgendaItemBo getChild() {
1619 return accessor.getChild(instance);
1620 }
1621
1622 public AgendaItemBo getInstance() { return instance; }
1623 }
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653 protected static class AgendaItemChildAccessor {
1654
1655 private enum Child { WHEN_TRUE, WHEN_FALSE, ALWAYS };
1656
1657 private static final AgendaItemChildAccessor whenTrue = new AgendaItemChildAccessor(Child.WHEN_TRUE);
1658 private static final AgendaItemChildAccessor whenFalse = new AgendaItemChildAccessor(Child.WHEN_FALSE);
1659 private static final AgendaItemChildAccessor always = new AgendaItemChildAccessor(Child.ALWAYS);
1660
1661
1662
1663
1664 private static final AgendaItemChildAccessor [] linkedNodes = { whenTrue, whenFalse, always };
1665
1666
1667
1668
1669 private static final AgendaItemChildAccessor [] children = { whenTrue, whenFalse };
1670
1671 private final Child whichChild;
1672
1673 private AgendaItemChildAccessor(Child whichChild) {
1674 if (whichChild == null) {
1675 throw new IllegalArgumentException("whichChild must be non-null");
1676 }
1677 this.whichChild = whichChild;
1678 }
1679
1680
1681
1682
1683 public AgendaItemBo getChild(AgendaItemBo parent) {
1684 switch (whichChild) {
1685 case WHEN_TRUE: return parent.getWhenTrue();
1686 case WHEN_FALSE: return parent.getWhenFalse();
1687 case ALWAYS: return parent.getAlways();
1688 default: throw new IllegalStateException();
1689 }
1690 }
1691
1692
1693
1694
1695 public void setChild(AgendaItemBo parent, AgendaItemBo child) {
1696 switch (whichChild) {
1697 case WHEN_TRUE:
1698 parent.setWhenTrue(child);
1699 parent.setWhenTrueId(child == null ? null : child.getId());
1700 break;
1701 case WHEN_FALSE:
1702 parent.setWhenFalse(child);
1703 parent.setWhenFalseId(child == null ? null : child.getId());
1704 break;
1705 case ALWAYS:
1706 parent.setAlways(child);
1707 parent.setAlwaysId(child == null ? null : child.getId());
1708 break;
1709 default: throw new IllegalStateException();
1710 }
1711 }
1712 }
1713
1714
1715
1716 @RequestMapping(params = "methodToCall=" + "copyRule")
1717 public ModelAndView copyRule(@ModelAttribute("KualiForm") UifFormBase form, BindingResult result,
1718 HttpServletRequest request, HttpServletResponse response) throws Exception {
1719
1720 AgendaEditor agendaEditor = getAgendaEditor(form);
1721 String name = agendaEditor.getCopyRuleName();
1722 String namespace = agendaEditor.getNamespace();
1723
1724
1725 final String copyRuleNameErrorPropertyName = "AgendaEditorView-AddRule-Page";
1726 if (StringUtils.isBlank(name)) {
1727 GlobalVariables.getMessageMap().putError(copyRuleNameErrorPropertyName, "error.rule.missingCopyRuleName");
1728 return super.refresh(form);
1729 }
1730
1731 RuleDefinition oldRuleDefinition = getRuleBoService().getRuleByNameAndNamespace(name, namespace);
1732
1733 if (oldRuleDefinition == null) {
1734 GlobalVariables.getMessageMap().putError(copyRuleNameErrorPropertyName, "error.rule.invalidCopyRuleName", namespace + ":" + name);
1735 return super.refresh(form);
1736 }
1737
1738 RuleBo oldRule = RuleBo.from(oldRuleDefinition);
1739 RuleBo newRule = RuleBo.copyRule(oldRule);
1740 agendaEditor.getAgendaItemLine().setRule( newRule );
1741
1742 if (!newRule.getActions().isEmpty()) {
1743 agendaEditor.setAgendaItemLineRuleAction( newRule.getActions().get(0));
1744 }
1745 return super.refresh(form);
1746 }
1747
1748
1749
1750
1751
1752 @RequestMapping(params = "methodToCall=" + "goToEditProposition")
1753 public ModelAndView goToEditProposition(@ModelAttribute("KualiForm") UifFormBase form, BindingResult result,
1754 HttpServletRequest request, HttpServletResponse response) throws Exception {
1755
1756
1757 AgendaEditor agendaEditor = getAgendaEditor(form);
1758 RuleBo rule = agendaEditor.getAgendaItemLine().getRule();
1759 String selectedPropId = agendaEditor.getSelectedPropositionId();
1760
1761 Node<RuleTreeNode,String> root = rule.getPropositionTree().getRootElement();
1762 PropositionBo propositionToToggleEdit = null;
1763 boolean newEditMode = true;
1764
1765
1766 Node<RuleTreeNode,String> parent = findParentPropositionNode( root, selectedPropId);
1767 if (parent != null){
1768 List<Node<RuleTreeNode,String>> children = parent.getChildren();
1769 for( int index=0; index< children.size(); index++){
1770 Node<RuleTreeNode,String> child = children.get(index);
1771 if (propIdMatches(child, selectedPropId)){
1772 PropositionBo prop = child.getData().getProposition();
1773 propositionToToggleEdit = prop;
1774 newEditMode = !prop.getEditMode();
1775 break;
1776 } else {
1777 child.getData().getProposition().setEditMode(false);
1778 }
1779 }
1780 }
1781
1782 resetEditModeOnPropositionTree(root);
1783 if (propositionToToggleEdit != null) {
1784 propositionToToggleEdit.setEditMode(newEditMode);
1785
1786 rule.refreshPropositionTree(null);
1787 }
1788
1789 return getModelAndView(form);
1790 }
1791
1792
1793
1794
1795
1796
1797 protected Node<RuleTreeNode,String> getLastSimpleNode(List<Node<RuleTreeNode,String>> grandChildren) {
1798 int lastIndex = grandChildren.size() - 1;
1799 Node<RuleTreeNode,String> lastSimpleNode = grandChildren.get(lastIndex);
1800
1801
1802 while (!(SimplePropositionNode.NODE_TYPE.equalsIgnoreCase(lastSimpleNode.getNodeType())
1803 || SimplePropositionEditNode.NODE_TYPE.equalsIgnoreCase(lastSimpleNode.getNodeType())
1804 ) && lastIndex >= 0) {
1805 lastSimpleNode = grandChildren.get(lastIndex);
1806 lastIndex--;
1807 }
1808
1809 return lastSimpleNode;
1810 }
1811
1812
1813
1814
1815
1816
1817
1818
1819 protected String getDefaultAddLocationPropositionId(Node<RuleTreeNode, String> root) {
1820 List<Node<RuleTreeNode,String>> children = root.getChildren();
1821 String selectedId = "";
1822
1823
1824
1825
1826 if (children.size() != 0) {
1827 Node<RuleTreeNode,String> child = children.get(0);
1828 List<Node<RuleTreeNode,String>> grandChildren = child.getChildren();
1829
1830
1831 if (grandChildren.size() != 0) {
1832 Node<RuleTreeNode,String> lastSimpleNode = getLastSimpleNode(grandChildren);
1833 selectedId = lastSimpleNode.getData().getProposition().getId();
1834 } else {
1835
1836
1837 selectedId = child.getData().getProposition().getId();
1838 }
1839 }
1840
1841 return selectedId;
1842 }
1843
1844 @RequestMapping(params = "methodToCall=" + "addProposition")
1845 public ModelAndView addProposition(@ModelAttribute("KualiForm") UifFormBase form, BindingResult result,
1846 HttpServletRequest request, HttpServletResponse response) throws Exception {
1847
1848 AgendaEditor agendaEditor = getAgendaEditor(form);
1849 RuleBo rule = agendaEditor.getAgendaItemLine().getRule();
1850 String selectedPropId = agendaEditor.getSelectedPropositionId();
1851
1852
1853 Node<RuleTreeNode,String> root = agendaEditor.getAgendaItemLine().getRule().getPropositionTree().getRootElement();
1854
1855
1856
1857 if (StringUtils.isEmpty(selectedPropId)) {
1858 selectedPropId = getDefaultAddLocationPropositionId(root);
1859 }
1860
1861
1862 Node<RuleTreeNode,String> parent = findParentPropositionNode( root, selectedPropId);
1863
1864 resetEditModeOnPropositionTree(root);
1865
1866
1867 if (parent != null){
1868 List<Node<RuleTreeNode,String>> children = parent.getChildren();
1869 for( int index=0; index< children.size(); index++){
1870 Node<RuleTreeNode,String> child = children.get(index);
1871
1872
1873 if (propIdMatches(child, selectedPropId)){
1874
1875
1876
1877
1878 if (parent == root &&
1879 (SimplePropositionNode.NODE_TYPE.equalsIgnoreCase(child.getNodeType()) ||
1880 SimplePropositionEditNode.NODE_TYPE.equalsIgnoreCase(child.getNodeType()))){
1881
1882
1883 PropositionBo compound = PropositionBo.createCompoundPropositionBoStub(child.getData().getProposition(), true);
1884 compound.setDescription("New Compound Proposition");
1885
1886 rule.setProposition(compound);
1887 rule.refreshPropositionTree(null);
1888 }
1889
1890 else if(SimplePropositionNode.NODE_TYPE.equalsIgnoreCase(child.getNodeType()) ||
1891 SimplePropositionEditNode.NODE_TYPE.equalsIgnoreCase(child.getNodeType())){
1892
1893
1894 PropositionBo blank = PropositionBo.createSimplePropositionBoStub(child.getData().getProposition(),PropositionType.SIMPLE.getCode());
1895
1896 PropositionBo parentProp = parent.getData().getProposition();
1897 parentProp.getCompoundComponents().add(((index/2)+1), blank);
1898
1899 rule.refreshPropositionTree(true);
1900 }
1901
1902 break;
1903 }
1904 }
1905 } else {
1906
1907
1908 if (root.getChildren().isEmpty()){
1909 PropositionBo blank = PropositionBo.createSimplePropositionBoStub(null,PropositionType.SIMPLE.getCode());
1910 blank.setRuleId(rule.getId());
1911 rule.setProposition(blank);
1912 rule.setProposition(blank);
1913 rule.refreshPropositionTree(true);
1914 }
1915 }
1916 return getModelAndView(form);
1917 }
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927 private void addOpCodeNode(Node currentNode, PropositionBo prop, int index){
1928 String opCodeLabel = "";
1929
1930 if (LogicalOperator.AND.getCode().equalsIgnoreCase(prop.getCompoundOpCode())){
1931 opCodeLabel = "AND";
1932 } else if (LogicalOperator.OR.getCode().equalsIgnoreCase(prop.getCompoundOpCode())){
1933 opCodeLabel = "OR";
1934 }
1935 Node<RuleTreeNode, String> aNode = new Node<RuleTreeNode, String>();
1936 aNode.setNodeLabel("");
1937 aNode.setNodeType("ruleTreeNode compoundOpCodeNode");
1938 aNode.setData(new CompoundOpCodeNode(prop));
1939 currentNode.insertChildAt(index, aNode);
1940 }
1941
1942
1943 private boolean propIdMatches(Node<RuleTreeNode, String> node, String propId){
1944 if (propId!=null && node != null && node.getData() != null && propId.equalsIgnoreCase(node.getData().getProposition().getId())) {
1945 return true;
1946 }
1947 return false;
1948 }
1949
1950
1951
1952
1953
1954 private void resetEditModeOnPropositionTree(Node<RuleTreeNode, String> currentNode){
1955 if (currentNode.getData() != null){
1956 RuleTreeNode dataNode = currentNode.getData();
1957 dataNode.getProposition().setEditMode(false);
1958 }
1959 List<Node<RuleTreeNode,String>> children = currentNode.getChildren();
1960 for( Node<RuleTreeNode,String> child : children){
1961 resetEditModeOnPropositionTree(child);
1962 }
1963 }
1964
1965 private Node<RuleTreeNode, String> findPropositionTreeNode(Node<RuleTreeNode, String> currentNode, String selectedPropId){
1966 Node<RuleTreeNode,String> bingo = null;
1967 if (currentNode.getData() != null){
1968 RuleTreeNode dataNode = currentNode.getData();
1969 if (selectedPropId.equalsIgnoreCase(dataNode.getProposition().getId())){
1970 return currentNode;
1971 }
1972 }
1973 List<Node<RuleTreeNode,String>> children = currentNode.getChildren();
1974 for( Node<RuleTreeNode,String> child : children){
1975 bingo = findPropositionTreeNode(child, selectedPropId);
1976 if (bingo != null) {
1977 break;
1978 }
1979 }
1980 return bingo;
1981 }
1982
1983 private Node<RuleTreeNode, String> findParentPropositionNode(Node<RuleTreeNode, String> currentNode, String selectedPropId){
1984 Node<RuleTreeNode,String> bingo = null;
1985 if (selectedPropId != null) {
1986
1987 List<Node<RuleTreeNode,String>> children = currentNode.getChildren();
1988 for( Node<RuleTreeNode,String> child : children){
1989 RuleTreeNode dataNode = child.getData();
1990 if (selectedPropId.equalsIgnoreCase(dataNode.getProposition().getId())) {
1991 return currentNode;
1992 }
1993 }
1994
1995
1996 for( Node<RuleTreeNode,String> kid : children){
1997 bingo = findParentPropositionNode(kid, selectedPropId);
1998 if (bingo != null) {
1999 break;
2000 }
2001 }
2002 }
2003 return bingo;
2004 }
2005
2006
2007
2008
2009
2010
2011
2012 private int findChildIndex(Node<RuleTreeNode,String> parent, String propId){
2013 int index;
2014 List<Node<RuleTreeNode,String>> children = parent.getChildren();
2015 for(index=0; index< children.size(); index++){
2016 Node<RuleTreeNode,String> child = children.get(index);
2017
2018 if (propIdMatches(child, propId)){
2019 return index;
2020 }
2021 }
2022 return -1;
2023 }
2024
2025 @RequestMapping(params = "methodToCall=" + "movePropositionUp")
2026 public ModelAndView movePropositionUp(@ModelAttribute("KualiForm") UifFormBase form, BindingResult result,
2027 HttpServletRequest request, HttpServletResponse response)
2028 throws Exception {
2029 moveSelectedProposition(form, true);
2030
2031 return getModelAndView(form);
2032 }
2033
2034 @RequestMapping(params = "methodToCall=" + "movePropositionDown")
2035 public ModelAndView movePropositionDown(@ModelAttribute("KualiForm") UifFormBase form, BindingResult result,
2036 HttpServletRequest request, HttpServletResponse response)
2037 throws Exception {
2038 moveSelectedProposition(form, false);
2039
2040 return getModelAndView(form);
2041 }
2042
2043 private void moveSelectedProposition(UifFormBase form, boolean up) {
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053 AgendaEditor agendaEditor = getAgendaEditor(form);
2054 RuleBo rule = agendaEditor.getAgendaItemLine().getRule();
2055 String selectedPropId = agendaEditor.getSelectedPropositionId();
2056
2057
2058 Node<RuleTreeNode,String> parent = findParentPropositionNode(rule.getPropositionTree().getRootElement(), selectedPropId);
2059
2060
2061 if (parent != null){
2062 List<Node<RuleTreeNode,String>> children = parent.getChildren();
2063 for( int index=0; index< children.size(); index++){
2064 Node<RuleTreeNode,String> child = children.get(index);
2065
2066 if (propIdMatches(child, selectedPropId)){
2067 if(SimplePropositionNode.NODE_TYPE.equalsIgnoreCase(child.getNodeType()) ||
2068 SimplePropositionEditNode.NODE_TYPE.equalsIgnoreCase(child.getNodeType()) ||
2069 RuleTreeNode.COMPOUND_NODE_TYPE.equalsIgnoreCase(child.getNodeType()) ){
2070
2071 if (((index > 0) && up) || ((index <(children.size() - 1)&& !up))){
2072
2073 PropositionBo parentProp = parent.getData().getProposition();
2074 PropositionBo workingProp = parentProp.getCompoundComponents().remove(index/2);
2075 if (up){
2076 parentProp.getCompoundComponents().add((index/2)-1, workingProp);
2077 }else{
2078 parentProp.getCompoundComponents().add((index/2)+1, workingProp);
2079 }
2080
2081
2082
2083 boolean editMode = (SimplePropositionEditNode.NODE_TYPE.equalsIgnoreCase(child.getNodeType()));
2084 rule.refreshPropositionTree(editMode);
2085 }
2086 }
2087
2088 break;
2089 }
2090 }
2091 }
2092 }
2093
2094 @RequestMapping(params = "methodToCall=" + "movePropositionLeft")
2095 public ModelAndView movePropositionLeft(@ModelAttribute("KualiForm") UifFormBase form, BindingResult result,
2096 HttpServletRequest request, HttpServletResponse response)
2097 throws Exception {
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107 AgendaEditor agendaEditor = getAgendaEditor(form);
2108 RuleBo rule = agendaEditor.getAgendaItemLine().getRule();
2109 String selectedPropId = agendaEditor.getSelectedPropositionId();
2110
2111
2112 Node<RuleTreeNode,String> root = rule.getPropositionTree().getRootElement();
2113 Node<RuleTreeNode,String> parent = findParentPropositionNode(root, selectedPropId);
2114 if ((parent != null) && (RuleTreeNode.COMPOUND_NODE_TYPE.equalsIgnoreCase(parent.getNodeType()))){
2115 Node<RuleTreeNode,String> granny = findParentPropositionNode(root,parent.getData().getProposition().getId());
2116 if (granny != root){
2117 int oldIndex = findChildIndex(parent, selectedPropId);
2118 int newIndex = findChildIndex(granny, parent.getData().getProposition().getId());
2119 if (oldIndex >= 0 && newIndex >= 0){
2120 PropositionBo prop = parent.getData().getProposition().getCompoundComponents().remove(oldIndex/2);
2121 granny.getData().getProposition().getCompoundComponents().add((newIndex/2)+1, prop);
2122 rule.refreshPropositionTree(false);
2123 }
2124 } else {
2125
2126
2127
2128 }
2129 }
2130 return getModelAndView(form);
2131 }
2132
2133 @RequestMapping(params = "methodToCall=" + "movePropositionRight")
2134 public ModelAndView movePropositionRight(@ModelAttribute("KualiForm") UifFormBase form, BindingResult result,
2135 HttpServletRequest request, HttpServletResponse response)
2136 throws Exception {
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146 AgendaEditor agendaEditor = getAgendaEditor(form);
2147 RuleBo rule = agendaEditor.getAgendaItemLine().getRule();
2148 String selectedPropId = agendaEditor.getSelectedPropositionId();
2149
2150
2151 Node<RuleTreeNode,String> parent = findParentPropositionNode(
2152 rule.getPropositionTree().getRootElement(), selectedPropId);
2153 if (parent != null){
2154 int index = findChildIndex(parent, selectedPropId);
2155
2156 if (index >= 0 && index+1 < parent.getChildren().size()){
2157 Node<RuleTreeNode,String> child = parent.getChildren().get(index);
2158 Node<RuleTreeNode,String> nextSibling = parent.getChildren().get(index+2);
2159
2160 if(RuleTreeNode.COMPOUND_NODE_TYPE.equalsIgnoreCase(nextSibling.getNodeType()) ){
2161
2162 PropositionBo prop = parent.getData().getProposition().getCompoundComponents().remove(index/2);
2163
2164 nextSibling.getData().getProposition().getCompoundComponents().add(0, prop);
2165 rule.refreshPropositionTree(false);
2166 }
2167 }
2168 }
2169 return getModelAndView(form);
2170 }
2171
2172
2173
2174
2175
2176
2177 @RequestMapping(params = "methodToCall=" + "togglePropositionSimpleCompound")
2178 public ModelAndView togglePropositionSimpleCompound(@ModelAttribute("KualiForm") UifFormBase form, BindingResult result,
2179 HttpServletRequest request, HttpServletResponse response)
2180 throws Exception {
2181
2182 AgendaEditor agendaEditor = getAgendaEditor(form);
2183 RuleBo rule = agendaEditor.getAgendaItemLine().getRule();
2184 String selectedPropId = agendaEditor.getSelectedPropositionId();
2185
2186 resetEditModeOnPropositionTree(rule.getPropositionTree().getRootElement());
2187
2188 if (!StringUtils.isBlank(selectedPropId)) {
2189
2190 Node<RuleTreeNode,String> parent = findParentPropositionNode(
2191 rule.getPropositionTree().getRootElement(), selectedPropId);
2192 if (parent != null){
2193
2194 int index = findChildIndex(parent, selectedPropId);
2195
2196 PropositionBo propBo = parent.getChildren().get(index).getData().getProposition();
2197
2198
2199 PropositionBo compound = PropositionBo.createCompoundPropositionBoStub(propBo, true);
2200 compound.setDescription("New Compound Proposition");
2201 compound.setEditMode(false);
2202
2203 if (parent.getData() == null) {
2204 rule.setProposition(compound);
2205 } else {
2206 PropositionBo parentBo = parent.getData().getProposition();
2207 List<PropositionBo> siblings = parentBo.getCompoundComponents();
2208
2209 int propIndex = -1;
2210 for (int i=0; i<siblings.size(); i++) {
2211 if (propBo.getId().equals(siblings.get(i).getId())) {
2212 propIndex = i;
2213 break;
2214 }
2215 }
2216
2217 parentBo.getCompoundComponents().set(propIndex, compound);
2218 }
2219 }
2220 }
2221
2222 agendaEditor.getAgendaItemLine().getRule().refreshPropositionTree(true);
2223 return getModelAndView(form);
2224 }
2225
2226 @RequestMapping(params = "methodToCall=" + "cutProposition")
2227 public ModelAndView cutProposition(@ModelAttribute("KualiForm") UifFormBase form, BindingResult result,
2228 HttpServletRequest request, HttpServletResponse response)
2229 throws Exception {
2230
2231 AgendaEditor agendaEditor = getAgendaEditor(form);
2232 String selectedPropId = agendaEditor.getSelectedPropositionId();
2233 agendaEditor.setCutPropositionId(selectedPropId);
2234
2235 return getModelAndView(form);
2236 }
2237
2238 @RequestMapping(params = "methodToCall=" + "pasteProposition")
2239 public ModelAndView pasteProposition(@ModelAttribute("KualiForm") UifFormBase form, BindingResult result,
2240 HttpServletRequest request, HttpServletResponse response)
2241 throws Exception {
2242
2243 AgendaEditor agendaEditor = getAgendaEditor(form);
2244 RuleBo rule = agendaEditor.getAgendaItemLine().getRule();
2245
2246
2247 String cutPropId = agendaEditor.getCutPropositionId();
2248 String selectedPropId = agendaEditor.getSelectedPropositionId();
2249
2250 if (StringUtils.isNotBlank(selectedPropId) && selectedPropId.equals(cutPropId)) {
2251
2252 } else {
2253
2254
2255 Node<RuleTreeNode, String> root = rule.getPropositionTree().getRootElement();
2256
2257 if (StringUtils.isNotBlank(selectedPropId) && StringUtils.isNotBlank(cutPropId)) {
2258 Node<RuleTreeNode,String> parentNode = findParentPropositionNode(root, selectedPropId);
2259 PropositionBo newParent;
2260 if (parentNode == root){
2261
2262
2263
2264
2265 newParent = PropositionBo.createCompoundPropositionBoStub2(
2266 root.getChildren().get(0).getData().getProposition());
2267 newParent.setEditMode(true);
2268 rule.setProposition(newParent);
2269 } else {
2270 newParent = parentNode.getData().getProposition();
2271 }
2272 PropositionBo oldParent = findParentPropositionNode(root, cutPropId).getData().getProposition();
2273
2274 PropositionBo workingProp = null;
2275
2276 if (oldParent != null){
2277 List <PropositionBo> children = oldParent.getCompoundComponents();
2278 for( int index=0; index< children.size(); index++){
2279 if (cutPropId.equalsIgnoreCase(children.get(index).getId())){
2280 workingProp = oldParent.getCompoundComponents().remove(index);
2281 break;
2282 }
2283 }
2284 }
2285
2286
2287 if (newParent != null && workingProp != null){
2288 List <PropositionBo> children = newParent.getCompoundComponents();
2289 for( int index=0; index< children.size(); index++){
2290 if (selectedPropId.equalsIgnoreCase(children.get(index).getId())){
2291 children.add(index+1, workingProp);
2292 break;
2293 }
2294 }
2295 }
2296
2297
2298 rule.refreshPropositionTree(false);
2299 }
2300 }
2301 agendaEditor.setCutPropositionId(null);
2302
2303 return getModelAndView(form);
2304 }
2305
2306 @RequestMapping(params = "methodToCall=" + "deleteProposition")
2307 public ModelAndView deleteProposition(@ModelAttribute("KualiForm") UifFormBase form, BindingResult result,
2308 HttpServletRequest request, HttpServletResponse response)
2309 throws Exception {
2310 AgendaEditor agendaEditor = getAgendaEditor(form);
2311 String selectedPropId = agendaEditor.getSelectedPropositionId();
2312 Node<RuleTreeNode, String> root = agendaEditor.getAgendaItemLine().getRule().getPropositionTree().getRootElement();
2313
2314 Node<RuleTreeNode, String> parentNode = findParentPropositionNode(root, selectedPropId);
2315
2316
2317 if (parentNode != null && parentNode.getData() != null) {
2318 PropositionBo parent = parentNode.getData().getProposition();
2319 if (parent != null){
2320 List <PropositionBo> children = parent.getCompoundComponents();
2321 for( int index=0; index< children.size(); index++){
2322 if (selectedPropId.equalsIgnoreCase(children.get(index).getId())){
2323 parent.getCompoundComponents().remove(index);
2324 break;
2325 }
2326 }
2327 }
2328 } else {
2329 if (KRADUtils.isNotNull(parentNode)) {
2330 parentNode.getChildren().clear();
2331 agendaEditor.getAgendaItemLine().getRule().getPropositionTree().setRootElement(null);
2332 agendaEditor.getAgendaItemLine().getRule().setProposition(null);
2333 } else {
2334 GlobalVariables.getMessageMap().putError(KRMSPropertyConstants.Rule.PROPOSITION_TREE_GROUP_ID,
2335 "error.rule.proposition.noneHighlighted");
2336 }
2337 }
2338
2339 agendaEditor.getDeletedPropositionIdsFromRule().add(selectedPropId);
2340 agendaEditor.getAgendaItemLine().getRule().refreshPropositionTree(false);
2341
2342 return getModelAndView(form);
2343 }
2344
2345 @RequestMapping(params = "methodToCall=" + "updateCompoundOperator")
2346 public ModelAndView updateCompoundOperator(@ModelAttribute("KualiForm") UifFormBase form, BindingResult result,
2347 HttpServletRequest request, HttpServletResponse response)
2348 throws Exception {
2349
2350 AgendaEditor agendaEditor = getAgendaEditor(form);
2351 RuleBo rule = agendaEditor.getAgendaItemLine().getRule();
2352 rule.refreshPropositionTree(false);
2353
2354 return getModelAndView(form);
2355 }
2356
2357 }