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