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