001 /**
002 * Copyright 2005-2012 The Kuali Foundation
003 *
004 * Licensed under the Educational Community License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.opensource.org/licenses/ecl2.php
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016 package org.kuali.rice.krms.controller;
017
018 import org.apache.commons.lang.StringUtils;
019 import org.kuali.rice.core.api.util.tree.Node;
020 import org.kuali.rice.krad.uif.UifParameters;
021 import org.kuali.rice.krad.uif.component.Component;
022 import org.kuali.rice.krad.uif.container.Group;
023 import org.kuali.rice.krad.uif.container.LinkGroup;
024 import org.kuali.rice.krad.uif.element.Action;
025 import org.kuali.rice.krad.uif.field.MessageField;
026 import org.kuali.rice.krad.uif.util.ComponentFactory;
027 import org.kuali.rice.krad.uif.util.ComponentUtils;
028 import org.kuali.rice.krad.util.GlobalVariables;
029 import org.kuali.rice.krad.web.controller.MaintenanceDocumentController;
030 import org.kuali.rice.krad.web.form.MaintenanceDocumentForm;
031 import org.kuali.rice.krad.web.form.UifFormBase;
032 import org.kuali.rice.krms.api.repository.LogicalOperator;
033 import org.kuali.rice.krms.api.repository.proposition.PropositionType;
034 import org.kuali.rice.krms.api.repository.type.KrmsTypeDefinition;
035 import org.kuali.rice.krms.dto.AgendaEditor;
036 import org.kuali.rice.krms.dto.PropositionEditor;
037 import org.kuali.rice.krms.dto.RuleEditor;
038 import org.kuali.rice.krms.dto.RuleManagementWrapper;
039 import org.kuali.rice.krms.dto.RuleTypeInfo;
040 import org.kuali.rice.krms.dto.TemplateInfo;
041 import org.kuali.rice.krms.impl.repository.KrmsRepositoryServiceLocator;
042 import org.kuali.rice.krms.impl.util.KRMSPropertyConstants;
043 import org.kuali.rice.krms.service.RuleViewHelperService;
044 import org.kuali.rice.krms.tree.RuleViewTreeBuilder;
045 import org.kuali.rice.krms.util.AgendaUtilities;
046 import org.kuali.student.enrollment.class1.krms.dto.EnrolPropositionEditor;
047 import org.kuali.student.enrollment.class1.krms.tree.node.KSSimplePropositionEditNode;
048 import org.kuali.student.enrollment.class1.krms.tree.node.KSSimplePropositionNode;
049 import org.kuali.rice.krms.tree.node.RuleEditorTreeNode;
050 import org.kuali.rice.krms.util.PropositionTreeUtil;
051 import org.kuali.rice.krms.util.RuleLogicExpressionParser;
052 import org.kuali.student.enrollment.uif.util.KSControllerHelper;
053 import org.kuali.student.krms.KRMSConstants;
054 import org.springframework.validation.BindingResult;
055 import org.springframework.web.bind.annotation.ModelAttribute;
056 import org.springframework.web.bind.annotation.RequestMapping;
057 import org.springframework.web.servlet.ModelAndView;
058
059 import javax.servlet.http.HttpServletRequest;
060 import javax.servlet.http.HttpServletResponse;
061 import java.util.ArrayList;
062 import java.util.List;
063
064 /**
065 * Controller for the Test UI Page
066 *
067 * @author Kuali Rice Team (rice.collab@kuali.org)
068 */
069 public class RuleEditorController extends MaintenanceDocumentController {
070
071 /*
072 * Method used to invoke the CO inquiry view from Manage Course Offering screen while search input is Course Offering
073 * Code (04a screen)
074 */
075 @RequestMapping(params = "methodToCall=goToRuleView")
076 public ModelAndView goToRuleView(@ModelAttribute("KualiForm") UifFormBase form, @SuppressWarnings("unused") BindingResult result,
077 @SuppressWarnings("unused") HttpServletRequest request, @SuppressWarnings("unused") HttpServletResponse response) throws Exception {
078
079 RuleEditor ruleEditor = AgendaUtilities.retrieveSelectedRuleEditor(form);
080
081 this.getViewHelper(form).refreshInitTrees(ruleEditor);
082
083 form.getActionParameters().put(UifParameters.NAVIGATE_TO_PAGE_ID, "KRMS-RuleMaintenance-Page");
084 return super.navigate(form, result, request, response);
085 }
086
087 @RequestMapping(params = "methodToCall=deleteRule")
088 public ModelAndView deleteRule(@ModelAttribute("KualiForm") UifFormBase form, @SuppressWarnings("unused") BindingResult result,
089 @SuppressWarnings("unused") HttpServletRequest request, @SuppressWarnings("unused") HttpServletResponse response) throws Exception {
090 MaintenanceDocumentForm document = (MaintenanceDocumentForm) form;
091 RuleManagementWrapper ruleWrapper = (RuleManagementWrapper) document.getDocument().getNewMaintainableObject().getDataObject();
092 String ruleKey = document.getActionParamaterValue("ruleKey");
093
094 RuleEditor ruleEditor = AgendaUtilities.getSelectedRuleEditor(ruleWrapper, ruleKey);
095
096 List<AgendaEditor> agendas = ruleWrapper.getAgendas();
097 for (AgendaEditor agenda : agendas) {
098 if (agenda.getRuleEditors().contains(ruleEditor)) {
099 ruleWrapper.getDeletedRuleIds().add(ruleEditor.getId());
100 agenda.getRuleEditors().remove(ruleEditor);
101 }
102 }
103
104 return getUIFModelAndView(document);
105 }
106
107 @RequestMapping(params = "methodToCall=addRule")
108 public ModelAndView addRule(@ModelAttribute("KualiForm") UifFormBase form, @SuppressWarnings("unused") BindingResult result,
109 @SuppressWarnings("unused") HttpServletRequest request, @SuppressWarnings("unused") HttpServletResponse response) throws Exception {
110 RuleEditor ruleEditor = AgendaUtilities.retrieveSelectedRuleEditor(form);
111 ruleEditor.setDummy(false);
112
113 this.getViewHelper(form).refreshInitTrees(ruleEditor);
114
115 form.getActionParameters().put(UifParameters.NAVIGATE_TO_PAGE_ID, "KRMS-RuleMaintenance-Page");
116 return super.navigate(form, result, request, response);
117 }
118
119 @RequestMapping(params = "methodToCall=ajaxRefresh")
120 public ModelAndView ajaxRefresh(@ModelAttribute("KualiForm") UifFormBase form, BindingResult result,
121 HttpServletRequest request, HttpServletResponse response)
122 throws Exception {
123 // call the super method to avoid the agenda tree being reloaded from the db
124 return getUIFModelAndView(form);
125 }
126
127 /**
128 * @param form
129 * @return the {@link org.kuali.rice.krms.impl.ui.AgendaEditor} from the form
130 */
131 protected RuleEditor getRuleEditor(UifFormBase form) {
132 if (form instanceof MaintenanceDocumentForm) {
133 MaintenanceDocumentForm maintenanceDocumentForm = (MaintenanceDocumentForm) form;
134 Object dataObject = maintenanceDocumentForm.getDocument().getNewMaintainableObject().getDataObject();
135
136 if (dataObject instanceof RuleEditor) {
137 return (RuleEditor) dataObject;
138 } else if (dataObject instanceof RuleManagementWrapper) {
139 RuleManagementWrapper wrapper = (RuleManagementWrapper) dataObject;
140 return wrapper.getRuleEditor();
141 }
142 }
143
144 return null;
145 }
146
147 //
148 // Rule Editor Controller methods
149 //
150 @RequestMapping(params = "methodToCall=copyRule")
151 public ModelAndView copyRule(@ModelAttribute("KualiForm") UifFormBase form, BindingResult result,
152 HttpServletRequest request, HttpServletResponse response) throws Exception {
153
154 //TODO: Copy rule to a different Co or AO
155
156 return super.refresh(form, result, request, response);
157 }
158
159 /**
160 * This method starts an edit proposition.
161 */
162 @RequestMapping(params = "methodToCall=goToEditProposition")
163 public ModelAndView goToEditProposition(@ModelAttribute("KualiForm") UifFormBase form, BindingResult result,
164 HttpServletRequest request, HttpServletResponse response) throws Exception {
165
166 RuleViewHelperService viewHelper = this.getViewHelper(form);
167
168 // open the selected node for editing
169 RuleEditor ruleEditor = getRuleEditor(form);
170 String selectedpropKey = ruleEditor.getSelectedKey();
171
172 Node<RuleEditorTreeNode, String> root = ruleEditor.getEditTree().getRootElement();
173 PropositionEditor propositionToToggleEdit = null;
174 boolean newEditMode = true;
175
176 // find parent
177 Node<RuleEditorTreeNode, String> parent = PropositionTreeUtil.findParentPropositionNode(root, selectedpropKey);
178 if (parent != null) {
179 List<Node<RuleEditorTreeNode, String>> children = parent.getChildren();
180 for (int index = 0; index < children.size(); index++) {
181 Node<RuleEditorTreeNode, String> child = children.get(index);
182 if (propKeyMatches(child, selectedpropKey)) {
183 PropositionEditor prop = child.getData().getProposition();
184 propositionToToggleEdit = prop;
185 newEditMode = !prop.isEditMode();
186 break;
187 } else {
188 child.getData().getProposition().setEditMode(false);
189 }
190 }
191 }
192
193 PropositionTreeUtil.resetEditModeOnPropositionTree(ruleEditor);
194 if (propositionToToggleEdit != null) {
195 propositionToToggleEdit.setEditMode(newEditMode);
196 //refresh the tree
197 viewHelper.refreshInitTrees(ruleEditor);
198 }
199
200 PropositionEditor proposition = PropositionTreeUtil.getProposition(ruleEditor);
201 if (!PropositionType.COMPOUND.getCode().equalsIgnoreCase(proposition.getPropositionTypeCode())) {
202
203 String propositionTypeId = proposition.getTypeId();
204 if (propositionTypeId == null) {
205 proposition.setType(null);
206 } else {
207
208 KrmsTypeDefinition type = KrmsRepositoryServiceLocator.getKrmsTypeRepositoryService().getTypeById(propositionTypeId);
209 if (type != null) {
210 proposition.setType(type.getName());
211 }
212 }
213
214 }
215
216 return getUIFModelAndView(form);
217 }
218
219 @RequestMapping(params = "methodToCall=addProposition")
220 public ModelAndView addProposition(@ModelAttribute("KualiForm") UifFormBase form, BindingResult result,
221 HttpServletRequest request, HttpServletResponse response) throws Exception {
222
223 RuleEditor ruleEditor = getRuleEditor(form);
224 String selectedPropKey = ruleEditor.getSelectedKey();
225
226 // find parent
227 Node<RuleEditorTreeNode, String> root = ruleEditor.getEditTree().getRootElement();
228 Node<RuleEditorTreeNode, String> parent = PropositionTreeUtil.findParentPropositionNode(root, selectedPropKey);
229
230 PropositionTreeUtil.resetEditModeOnPropositionTree(ruleEditor);
231 RuleViewHelperService viewHelper = this.getViewHelper(form);
232
233 // add new child at appropriate spot
234 if (parent != null) {
235 List<Node<RuleEditorTreeNode, String>> children = parent.getChildren();
236 for (int index = 0; index < children.size(); index++) {
237 Node<RuleEditorTreeNode, String> child = children.get(index);
238
239 // if our selected node is a simple proposition, add a new one after
240 if (propKeyMatches(child, selectedPropKey)) {
241 // handle special case of adding to a lone simple proposition.
242 // in this case, we need to change the root level proposition to a compound proposition
243 // move the existing simple proposition as the first compound component,
244 // then add a new blank simple prop as the second compound component.
245 PropositionEditor blank = null;
246 if (parent.equals(root) &&
247 (isSimpleNode(child.getNodeType()))) {
248
249 // create a new compound proposition
250 blank = viewHelper.createCompoundPropositionBoStub(child.getData().getProposition(), true);
251 blank.setDescription(KRMSConstants.PROP_COMP_DEFAULT_DESCR);
252 // don't set compound.setEditMode(true) as the Simple Prop in the compound prop is the only prop in edit mode
253 ruleEditor.setProposition(blank);
254 }
255 // handle regular case of adding a simple prop to an existing compound prop
256 else if (!parent.equals(root)){
257
258 // build new Blank Proposition
259 blank = viewHelper.createSimplePropositionBoStub(child.getData().getProposition());
260 //add it to the parent
261 PropositionEditor parentProp = parent.getData().getProposition();
262 parentProp.getCompoundEditors().add(((index / 2) + 1), blank);
263 } else {
264 return getUIFModelAndView(form);
265 }
266 this.getViewHelper(form).refreshInitTrees(ruleEditor);
267 if(blank!=null){
268 ruleEditor.setSelectedKey(blank.getKey());
269 }else{
270 ruleEditor.setSelectedKey(null);
271 }
272 break;
273 }
274 }
275 } else {
276 // special case, if root has no children, add a new simple proposition
277 // todo: how to add compound proposition. - just add another to the firs simple
278 if (root.getChildren().isEmpty()) {
279 PropositionEditor blank = viewHelper.createSimplePropositionBoStub(null);
280 blank.setRuleId(ruleEditor.getId());
281 ruleEditor.setPropId(blank.getId());
282 ruleEditor.setProposition(blank);
283 this.getViewHelper(form).refreshInitTrees(ruleEditor);
284 }
285 }
286 return getUIFModelAndView(form);
287 }
288
289 private boolean propKeyMatches(Node<RuleEditorTreeNode, String> node, String propKey) {
290 if (propKey != null && node != null && node.getData() != null && propKey.equalsIgnoreCase(node.getData().getProposition().getKey())) {
291 return true;
292 }
293 return false;
294 }
295
296 /**
297 * This method return the index of the position of the child that matches the id
298 *
299 * @param parent
300 * @param propKey
301 * @return index if found, -1 if not found
302 */
303 private int findChildIndex(Node<RuleEditorTreeNode, String> parent, String propKey) {
304 int index;
305 List<Node<RuleEditorTreeNode, String>> children = parent.getChildren();
306 for (index = 0; index < children.size(); index++) {
307 Node<RuleEditorTreeNode, String> child = children.get(index);
308 // if our selected node is a simple proposition, add a new one after
309 if (propKeyMatches(child, propKey)) {
310 return index;
311 }
312 }
313 return -1;
314 }
315
316 @RequestMapping(params = "methodToCall=movePropositionUp")
317 public ModelAndView movePropositionUp(@ModelAttribute("KualiForm") UifFormBase form, BindingResult result,
318 HttpServletRequest request, HttpServletResponse response)
319 throws Exception {
320 moveSelectedProposition(form, true);
321
322 return getUIFModelAndView(form);
323 }
324
325 @RequestMapping(params = "methodToCall=movePropositionDown")
326 public ModelAndView movePropositionDown(@ModelAttribute("KualiForm") UifFormBase form, BindingResult result,
327 HttpServletRequest request, HttpServletResponse response)
328 throws Exception {
329 moveSelectedProposition(form, false);
330
331 return getUIFModelAndView(form);
332 }
333
334 private void moveSelectedProposition(UifFormBase form, boolean up) {
335
336 /* Rough algorithm for moving a node up.
337 *
338 * find the following:
339 * node := the selected node
340 * parent := the selected node's parent, its containing node (via when true or when false relationship)
341 * parentsOlderCousin := the parent's level-order predecessor (sibling or cousin)
342 *
343 */
344 RuleEditor ruleEditor = getRuleEditor(form);
345 String selectedPropKey = ruleEditor.getSelectedKey();
346
347 // find parent
348 Node<RuleEditorTreeNode, String> parent = PropositionTreeUtil.findParentPropositionNode(ruleEditor.getEditTree().getRootElement(), selectedPropKey);
349
350 // add new child at appropriate spot
351 if (parent != null) {
352 List<Node<RuleEditorTreeNode, String>> children = parent.getChildren();
353 for (int index = 0; index < children.size(); index++) {
354 Node<RuleEditorTreeNode, String> child = children.get(index);
355 // if our selected node is a simple proposition, add a new one after
356 if (propKeyMatches(child, selectedPropKey) &&
357 (isSimpleNode(child.getNodeType()) || (RuleEditorTreeNode.COMPOUND_NODE_TYPE.equalsIgnoreCase(child.getNodeType())))) {
358
359 //remove it from its current spot
360 PropositionEditor parentProp = parent.getData().getProposition();
361 PropositionEditor workingProp = parentProp.getCompoundEditors().remove(index / 2);
362 if ((index > 0) && up) {
363 parentProp.getCompoundEditors().add((index / 2) - 1, workingProp);
364 } else if ((index < (children.size() - 1) && !up)) {
365 parentProp.getCompoundEditors().add((index / 2) + 1, workingProp);
366 }
367 // redisplay the tree (editMode = true)
368 this.getViewHelper(form).refreshInitTrees(ruleEditor);
369 break;
370 }
371 }
372 }
373 }
374
375 public boolean isSimpleNode(String nodeType) {
376 if (KSSimplePropositionNode.NODE_TYPE.equalsIgnoreCase(nodeType) ||
377 KSSimplePropositionEditNode.NODE_TYPE.equalsIgnoreCase(nodeType)) {
378 return true;
379 }
380 return false;
381 }
382
383 @RequestMapping(params = "methodToCall=movePropositionLeft")
384 public ModelAndView movePropositionLeft(@ModelAttribute("KualiForm") UifFormBase form, BindingResult result,
385 HttpServletRequest request, HttpServletResponse response)
386 throws Exception {
387
388 /* Rough algorithm for moving a node up.
389 *
390 * find the following:
391 * node := the selected node
392 * parent := the selected node's parent, its containing node (via when true or when false relationship)
393 * parentsOlderCousin := the parent's level-order predecessor (sibling or cousin)
394 *
395 */
396 RuleEditor ruleEditor = getRuleEditor(form);
397 String selectedpropKey = ruleEditor.getSelectedKey();
398
399 // find agendaEditor.getAgendaItemLine().getRule().getPropositionTree().getRootElement()parent
400 Node<RuleEditorTreeNode, String> root = ruleEditor.getEditTree().getRootElement();
401 Node<RuleEditorTreeNode, String> parent = PropositionTreeUtil.findParentPropositionNode(root, selectedpropKey);
402 if ((parent != null) && (RuleEditorTreeNode.COMPOUND_NODE_TYPE.equalsIgnoreCase(parent.getNodeType()))) {
403 Node<RuleEditorTreeNode, String> granny = PropositionTreeUtil.findParentPropositionNode(root, parent.getData().getProposition().getKey());
404 if (!granny.equals(root)) {
405 int oldIndex = findChildIndex(parent, selectedpropKey);
406 int newIndex = findChildIndex(granny, parent.getData().getProposition().getKey());
407 if (oldIndex >= 0 && newIndex >= 0) {
408 PropositionEditor prop = parent.getData().getProposition().getCompoundEditors().remove(oldIndex / 2);
409 granny.getData().getProposition().getCompoundEditors().add((newIndex / 2) + 1, prop);
410 this.getViewHelper(form).refreshInitTrees(ruleEditor);
411 }
412 }
413 // TODO: do we allow moving up to the root?
414 // we could add a new top level compound node, with current root as 1st child,
415 // and move the node to the second child.
416
417 }
418 return getUIFModelAndView(form);
419 }
420
421 @RequestMapping(params = "methodToCall=movePropositionRight")
422 public ModelAndView movePropositionRight(@ModelAttribute("KualiForm") UifFormBase form, BindingResult result,
423 HttpServletRequest request, HttpServletResponse response)
424 throws Exception {
425 /* Rough algorithm for moving a node Right
426 * if the selected node is above a compound proposition, move it into the compound proposition as the first child
427 * if the node is above a simple proposition, do nothing.
428 * find the following:
429 * node := the selected node
430 * parent := the selected node's parent, its containing node
431 * nextSibling := the node after the selected node
432 *
433 */
434 RuleEditor ruleEditor = getRuleEditor(form);
435 String selectedpropKey = ruleEditor.getSelectedKey();
436
437 // find parent
438 Node<RuleEditorTreeNode, String> parent = PropositionTreeUtil.findParentPropositionNode(
439 ruleEditor.getEditTree().getRootElement(), selectedpropKey);
440 if (parent != null) {
441 int index = findChildIndex(parent, selectedpropKey);
442 // if we are the last child, do nothing, otherwise
443 if (index >= 0 && index + 1 < parent.getChildren().size()) {
444 Node<RuleEditorTreeNode, String> nextSibling = parent.getChildren().get(index + 2);
445 // if selected node above a compound node, move it into it as first child
446 if (RuleEditorTreeNode.COMPOUND_NODE_TYPE.equalsIgnoreCase(nextSibling.getNodeType())) {
447 // remove selected node from it's current spot
448 PropositionEditor prop = parent.getData().getProposition().getCompoundEditors().remove(index / 2);
449 // add it to it's siblings children
450 nextSibling.getData().getProposition().getCompoundEditors().add(0, prop);
451 this.getViewHelper(form).refreshInitTrees(ruleEditor);
452 }
453 }
454 }
455 return getUIFModelAndView(form);
456 }
457
458 /**
459 * introduces a new compound proposition between the selected proposition and its parent.
460 * Additionally, it puts a new blank simple proposition underneath the compound proposition
461 * as a sibling to the selected proposition.
462 */
463 @RequestMapping(params = "methodToCall=togglePropositionSimpleCompound")
464 public ModelAndView togglePropositionSimpleCompound(@ModelAttribute("KualiForm") UifFormBase form, BindingResult result,
465 HttpServletRequest request, HttpServletResponse response)
466 throws Exception {
467
468 RuleEditor ruleEditor = getRuleEditor(form);
469 String selectedPropKey = ruleEditor.getSelectedKey();
470
471 PropositionTreeUtil.resetEditModeOnPropositionTree(ruleEditor);
472 RuleViewHelperService viewHelper = this.getViewHelper(form);
473
474 if (!StringUtils.isBlank(selectedPropKey)) {
475 // find parent
476 Node<RuleEditorTreeNode, String> parent = PropositionTreeUtil.findParentPropositionNode(
477 ruleEditor.getEditTree().getRootElement(), selectedPropKey);
478 if (parent != null) {
479
480 int index = findChildIndex(parent, selectedPropKey);
481
482 PropositionEditor propBo = parent.getChildren().get(index).getData().getProposition();
483
484 // create a new compound proposition
485 PropositionEditor compound = viewHelper.createCompoundPropositionBoStub(propBo, true);
486 compound.setDescription(KRMSConstants.PROP_COMP_DEFAULT_DESCR);
487 compound.setEditMode(false);
488
489 if (parent.getData() == null) { // SPECIAL CASE: this is the only proposition in the tree
490 ruleEditor.setProposition(compound);
491 } else {
492 PropositionEditor parentBo = parent.getData().getProposition();
493 List<PropositionEditor> siblings = parentBo.getCompoundEditors();
494
495 int propIndex = -1;
496 for (int i = 0; i < siblings.size(); i++) {
497 if (propBo.getKey().equals(siblings.get(i).getKey())) {
498 propIndex = i;
499 break;
500 }
501 }
502
503 parentBo.getCompoundEditors().set(propIndex, compound);
504 compound.getCompoundEditors().get(1).setEditMode(true);
505 ruleEditor.setSelectedKey(compound.getCompoundComponents().get(1).getId());
506 }
507 }
508 }
509
510 viewHelper.refreshInitTrees(ruleEditor);
511 return getUIFModelAndView(form);
512 }
513
514 @RequestMapping(params = "methodToCall=pasteProposition")
515 public ModelAndView pasteProposition(@ModelAttribute("KualiForm") UifFormBase form, BindingResult result,
516 HttpServletRequest request, HttpServletResponse response)
517 throws Exception {
518
519 boolean cutAction = true;
520 RuleEditor ruleEditor = getRuleEditor(form);
521 RuleViewHelperService viewHelper = this.getViewHelper(form);
522
523 // get selected id
524 String selectedPropKey = ruleEditor.getSelectedKey();
525 if (StringUtils.isBlank(selectedPropKey)) {
526 return getUIFModelAndView(form);
527 }
528
529 // get the id to move
530 String movePropKey = ruleEditor.getCutKey();
531 if (StringUtils.isBlank(movePropKey)) {
532 movePropKey = ruleEditor.getCopyKey();
533 cutAction = false;
534 }
535
536 // check if selected and move is not the same
537 if (StringUtils.isNotBlank(movePropKey) && !selectedPropKey.equals(movePropKey)) {
538
539 Node<RuleEditorTreeNode, String> root = ruleEditor.getEditTree().getRootElement();
540 PropositionEditor newParent = getNewParent(viewHelper, ruleEditor, selectedPropKey, root);
541 PropositionEditor oldParent = PropositionTreeUtil.findParentPropositionNode(root, movePropKey).getData().getProposition();
542 PropositionEditor workingProp = null;
543
544 // cut or copy from old
545 if (oldParent != null) {
546 List<PropositionEditor> children = oldParent.getCompoundEditors();
547 for (int index = 0; index < children.size(); index++) {
548 if (movePropKey.equalsIgnoreCase(children.get(index).getKey())) {
549 if (cutAction) {
550 workingProp = oldParent.getCompoundEditors().remove(index);
551 } else {
552 workingProp = viewHelper.copyProposition(oldParent.getCompoundEditors().get(index));
553 }
554 break;
555 }
556 }
557 }
558
559 // add to new and refresh the tree
560 addProposition(selectedPropKey, newParent, workingProp);
561 viewHelper.refreshInitTrees(ruleEditor);
562 }
563
564 // call the super method to avoid the agenda tree being reloaded from the db
565 return getUIFModelAndView(form);
566 }
567
568 private PropositionEditor getNewParent(RuleViewHelperService viewHelper, RuleEditor ruleEditor, String selectedpropKey, Node<RuleEditorTreeNode, String> root) {
569 Node<RuleEditorTreeNode, String> parentNode = PropositionTreeUtil.findParentPropositionNode(root, selectedpropKey);
570 PropositionEditor newParent;
571 if (parentNode.equals(root)) {
572 // special case
573 // build new top level compound proposition,
574 // add existing as first child
575 // then paste cut node as 2nd child
576 newParent = viewHelper.createCompoundPropositionBoStub(
577 root.getChildren().get(0).getData().getProposition(), false);
578 newParent.setEditMode(true);
579 ruleEditor.setProposition(newParent);
580 } else {
581 newParent = parentNode.getData().getProposition();
582 }
583 return newParent;
584 }
585
586 private void addProposition(String selectedpropKey, PropositionEditor newParent, PropositionEditor workingProp) {
587 // add to new
588 if (newParent != null && workingProp != null) {
589 List<PropositionEditor> children = newParent.getCompoundEditors();
590 for (int index = 0; index < children.size(); index++) {
591 if (selectedpropKey.equalsIgnoreCase(children.get(index).getKey())) {
592 children.add(index + 1, workingProp);
593 break;
594 }
595 }
596 }
597 }
598
599 @RequestMapping(params = "methodToCall=deleteProposition")
600 public ModelAndView deleteProposition(@ModelAttribute("KualiForm") UifFormBase form, BindingResult result,
601 HttpServletRequest request, HttpServletResponse response)
602 throws Exception {
603 RuleEditor ruleEditor = getRuleEditor(form);
604 String selectedpropKey = ruleEditor.getSelectedKey();
605 Node<RuleEditorTreeNode, String> root = ruleEditor.getEditTree().getRootElement();
606
607 Node<RuleEditorTreeNode, String> parentNode = PropositionTreeUtil.findParentPropositionNode(root, selectedpropKey);
608
609 // what if it is the root?
610 if (parentNode != null && parentNode.getData() != null) { // it is not the root as there is a parent w/ a prop
611 PropositionEditor parent = parentNode.getData().getProposition();
612 if (parent != null) {
613 List<PropositionEditor> children = (List<PropositionEditor>) parent.getCompoundComponents();
614 for (int index = 0; index < children.size(); index++) {
615 if (selectedpropKey.equalsIgnoreCase(children.get(index).getKey())) {
616 parent.getCompoundComponents().remove(index);
617 break;
618 }
619 }
620 }
621 } else { // no parent, it is the root
622 parentNode.getChildren().clear();
623 ruleEditor.getEditTree().setRootElement(null);
624 ruleEditor.setPropId(null);
625 ruleEditor.setProposition(null);
626 }
627
628 this.getViewHelper(form).refreshInitTrees(ruleEditor);
629 return getUIFModelAndView(form);
630 }
631
632 @RequestMapping(params = "methodToCall=updateCompoundOperator")
633 public ModelAndView updateCompoundOperator(@ModelAttribute("KualiForm") UifFormBase form, BindingResult result,
634 HttpServletRequest request, HttpServletResponse response)
635 throws Exception {
636
637 RuleViewHelperService viewHelper = this.getViewHelper(form);
638 RuleEditor ruleEditor = getRuleEditor(form);
639 String selectedpropKey = ruleEditor.getSelectedKey();
640 Node<RuleEditorTreeNode, String> parentNode = PropositionTreeUtil.findParentPropositionNode(ruleEditor.getEditTree().getRootElement(), selectedpropKey);
641 PropositionEditor parent = parentNode.getData().getProposition();
642
643 PropositionEditor proposition = PropositionTreeUtil.findProposition(parentNode, selectedpropKey);
644 PropositionTreeUtil.setTypeForCompoundOpCode(parent, proposition.getCompoundOpCode());
645 parent.setDescription(viewHelper.resetDescription(parent));
646
647 viewHelper.refreshInitTrees(ruleEditor);
648
649 return getUIFModelAndView(form);
650 }
651
652 @RequestMapping(params = "methodToCall=updateProposition")
653 public ModelAndView updateProposition(@ModelAttribute("KualiForm") UifFormBase form, BindingResult result,
654 HttpServletRequest request, HttpServletResponse response)
655 throws Exception {
656 RuleEditor ruleEditor = getRuleEditor(form);
657 PropositionTreeUtil.resetNewProp((PropositionEditor) ruleEditor.getProposition());
658
659 EnrolPropositionEditor proposition = (EnrolPropositionEditor) PropositionTreeUtil.getProposition(ruleEditor);
660
661 //Resolve term if single course
662 //Reset the description
663 this.getViewHelper(form).resetDescription(proposition);
664
665 //Remove the edit mode
666 PropositionTreeUtil.resetEditModeOnPropositionTree(ruleEditor);
667 this.getViewHelper(form).refreshInitTrees(ruleEditor);
668
669 return getUIFModelAndView(form);
670 }
671
672 @RequestMapping(params = "methodToCall=updateRule")
673 public ModelAndView updateRule(@ModelAttribute("KualiForm") UifFormBase form, BindingResult result,
674 HttpServletRequest request, HttpServletResponse response)
675 throws Exception {
676
677 MaintenanceDocumentForm document = (MaintenanceDocumentForm) form;
678 RuleManagementWrapper ruleWrapper = (RuleManagementWrapper) document.getDocument().getNewMaintainableObject().getDataObject();
679
680 RuleEditor ruleEditor = getRuleEditor(form);
681
682 this.getViewHelper(form).refreshViewTree(ruleEditor);
683 PropositionTreeUtil.resetNewProp((PropositionEditor) ruleEditor.getProposition());
684
685 PropositionTreeUtil.resetEditModeOnPropositionTree(ruleEditor);
686 PropositionEditor proposition = PropositionTreeUtil.getProposition(ruleEditor);
687 this.getViewHelper(form).resetDescription(proposition);
688
689
690 //Replace edited rule with existing rule.
691 for (AgendaEditor agendaEditor : ruleWrapper.getAgendas()) {
692
693 List<RuleEditor> ruleEditors = agendaEditor.getRuleEditors();
694 RuleEditor existingRule = AgendaUtilities.getSelectedRuleEditorByType(ruleEditors, ruleEditor.getTypeId());
695 if (existingRule != null) {
696 ruleEditors.remove(existingRule);
697 }
698 ruleEditors.add(ruleEditor);
699 }
700
701 form.getActionParameters().put(UifParameters.NAVIGATE_TO_PAGE_ID, "KRMS-AgendaMaintenance-Page");
702 return super.navigate(form, result, request, response);
703 }
704
705 @RequestMapping(params = "methodToCall=updatePreview")
706 public ModelAndView updatePreview(@ModelAttribute("KualiForm") UifFormBase form, BindingResult result,
707 HttpServletRequest request, HttpServletResponse response)
708 throws Exception {
709 RuleEditor ruleEditor = getRuleEditor(form);
710 ruleEditor.setSelectedTab("1");
711
712 parseRuleExpression(ruleEditor);
713
714 this.getViewHelper(form).refreshInitTrees(ruleEditor);
715 return getUIFModelAndView(form);
716 }
717
718 @RequestMapping(params = "methodToCall=onTabSelect")
719 public ModelAndView onEditTabSelect(@ModelAttribute("KualiForm") UifFormBase form, BindingResult result,
720 HttpServletRequest request, HttpServletResponse response)
721 throws Exception {
722
723 RuleEditor ruleEditor = getRuleEditor(form);
724 parseRuleExpression(ruleEditor);
725
726 this.getViewHelper(form).refreshInitTrees(ruleEditor);
727 return getUIFModelAndView(form);
728 }
729
730 private void parseRuleExpression(RuleEditor ruleEditor) {
731 RuleLogicExpressionParser ruleLogicExpressionParser = new RuleLogicExpressionParser();
732 ruleLogicExpressionParser.setExpression(ruleEditor.getLogicArea());
733 List<String> propsAlpha = this.getPropositionKeys(new ArrayList<String>(), (PropositionEditor) ruleEditor.getProposition());
734
735 //validate the expression
736 List<String> errorMessages = new ArrayList<String>();
737 boolean validExpression = ruleLogicExpressionParser.validateExpression(errorMessages, propsAlpha);
738
739 //show errors and don't change anything else
740 if (!validExpression) {
741 for (int i = 0; i < errorMessages.size(); i++) {
742 GlobalVariables.getMessageMap().putError("document.newMaintainableObject.dataObject.logicArea", errorMessages.get(i));
743 }
744 // reload page1
745 return;
746 }
747
748 ruleEditor.setProposition(ruleLogicExpressionParser.parseExpressionIntoRule(ruleEditor));
749 }
750
751 private List<String> getPropositionKeys(List<String> propositionKeys, PropositionEditor propositionEditor) {
752 propositionKeys.add(propositionEditor.getKey());
753 if (propositionEditor.getCompoundComponents() != null) {
754 for (PropositionEditor child : propositionEditor.getCompoundEditors()) {
755 this.getPropositionKeys(propositionKeys, child);
756 }
757 }
758 return propositionKeys;
759 }
760
761 @RequestMapping(params = "methodToCall=cancelEditProposition")
762 public ModelAndView cancelEditProposition(@ModelAttribute("KualiForm") UifFormBase form, BindingResult result,
763 HttpServletRequest request, HttpServletResponse response)
764 throws Exception {
765
766 RuleEditor ruleEditor = getRuleEditor(form);
767 PropositionEditor proposition = (PropositionEditor) ruleEditor.getProposition();
768
769 //Reset the editing tree.
770 PropositionTreeUtil.cancelNewProp(proposition);
771 PropositionTreeUtil.resetEditModeOnPropositionTree(ruleEditor);
772 this.getViewHelper(form).refreshInitTrees(ruleEditor);
773
774 return getUIFModelAndView(form);
775 }
776
777 @RequestMapping(params = "methodToCall=cancelEditRule")
778 public ModelAndView cancelEditRule(@ModelAttribute("KualiForm") UifFormBase form, BindingResult result,
779 HttpServletRequest request, HttpServletResponse response)
780 throws Exception {
781
782 RuleEditor ruleEditor = getRuleEditor(form);
783 PropositionEditor proposition = (PropositionEditor) ruleEditor.getProposition();
784
785 //Reset the editing tree.
786 if(proposition!=null){
787 PropositionTreeUtil.cancelNewProp(proposition);
788 }
789 PropositionTreeUtil.resetEditModeOnPropositionTree(ruleEditor);
790
791 form.getActionParameters().put(UifParameters.NAVIGATE_TO_PAGE_ID, "KRMS-AgendaMaintenance-Page");
792 return super.navigate(form, result, request, response);
793 }
794
795 @RequestMapping(params = "methodToCall=updatePropositionType")
796 public ModelAndView updatePropositionType(@ModelAttribute("KualiForm") UifFormBase form, BindingResult result,
797 HttpServletRequest request, HttpServletResponse response)
798 throws Exception {
799
800 PropositionEditor proposition = PropositionTreeUtil.getProposition(this.getRuleEditor(form));
801 configureProposition(form, proposition);
802
803 return getUIFModelAndView(form);
804 }
805
806 private void configureProposition(UifFormBase form, PropositionEditor proposition) {
807
808 if (proposition != null) {
809
810 if (PropositionType.COMPOUND.getCode().equalsIgnoreCase(proposition.getPropositionTypeCode())) {
811 return;
812 }
813
814 String propositionTypeId = proposition.getTypeId();
815 if (propositionTypeId == null) {
816 proposition.setType(null);
817 return;
818 }
819
820 KrmsTypeDefinition type = KrmsRepositoryServiceLocator.getKrmsTypeRepositoryService().getTypeById(propositionTypeId);
821 if (type != null) {
822 proposition.setType(type.getName());
823 }
824 }
825 }
826
827 /**
828 * Test method for a controller that invokes a dialog lightbox.
829 *
830 * @param form - test form
831 * @param result - Spring form binding result
832 * @param request - http request
833 * @param response - http response
834 * @return
835 * @throws Exception
836 */
837 @RequestMapping(params = "methodToCall=compareRules")
838 public ModelAndView compareRules(@ModelAttribute("KualiForm") UifFormBase form, BindingResult result,
839 HttpServletRequest request, HttpServletResponse response) throws Exception {
840
841 MaintenanceDocumentForm document = (MaintenanceDocumentForm) form;
842 Object dataObject = document.getDocument().getNewMaintainableObject().getDataObject();
843 if (dataObject instanceof RuleManagementWrapper) {
844 RuleManagementWrapper ruleWrapper = (RuleManagementWrapper) dataObject;
845 String ruleId = document.getActionParamaterValue("ruleKey");
846 RuleEditor ruleEditor = null;
847 if ((ruleId != null) && (StringUtils.isNotBlank(ruleId))) {
848 //Get a specific ruleEditor based on the ruleId.
849 ruleEditor = AgendaUtilities.getSelectedRuleEditor(ruleWrapper, ruleId);
850 } else {
851 //Get the current editing ruleEditor.
852 ruleEditor = ruleWrapper.getRuleEditor();
853 }
854
855 //Build the compare rule tree
856 ruleWrapper.setCompareTree(this.getViewHelper(form).buildCompareTree(ruleEditor, ruleWrapper.getRefObjectId()));
857
858 }
859
860 // redirect back to client to display lightbox
861 return showDialog("compareRuleLightBox", form, request, response);
862 }
863
864 protected RuleViewHelperService getViewHelper(UifFormBase form) {
865 return (RuleViewHelperService) KSControllerHelper.getViewHelperService(form);
866 }
867 //
868 @RequestMapping(params = "methodToCall=getSelectedKey")
869 public ModelAndView getSelectedKey(@ModelAttribute("KualiForm") UifFormBase form, BindingResult result,
870 HttpServletRequest request, HttpServletResponse response) throws Exception {
871
872 RuleViewHelperService viewHelper = this.getViewHelper(form);
873 String selectedKey = request.getParameter("selectedKey");
874
875 RuleEditor ruleEditor = getRuleEditor(form);
876 String selectedpropKey = selectedKey;
877 ruleEditor.setSelectedKey(selectedpropKey);
878 //this.goToEditProposition()
879 return this.goToEditProposition(form,result, request, response);
880 }
881
882 }