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