View Javadoc

1   package org.kuali.rice.krms.util;
2   
3   import org.kuali.rice.core.api.util.tree.Node;
4   import org.kuali.rice.krms.api.repository.LogicalOperator;
5   import org.kuali.rice.krms.api.repository.proposition.PropositionType;
6   import org.kuali.rice.krms.api.repository.type.KrmsTypeDefinition;
7   import org.kuali.rice.krms.dto.PropositionEditor;
8   import org.kuali.rice.krms.dto.PropositionParameterEditor;
9   import org.kuali.rice.krms.dto.RuleEditor;
10  import org.kuali.rice.krms.impl.repository.KrmsRepositoryServiceLocator;
11  import org.kuali.rice.krms.tree.node.RuleEditorTreeNode;
12  import org.kuali.student.enrollment.class2.courseoffering.service.decorators.PermissionServiceConstants;
13  
14  import java.util.ArrayList;
15  import java.util.Arrays;
16  import java.util.List;
17  
18  /**
19   * Created with IntelliJ IDEA.
20   * User: SW
21   * Date: 2012/12/03
22   * Time: 4:39 PM
23   * To change this template use File | Settings | File Templates.
24   */
25  public class PropositionTreeUtil {
26  
27      public static void setTypeForCompoundOpCode(PropositionEditor proposition, String compoundOpCode) {
28          proposition.setCompoundOpCode(compoundOpCode);
29          if (LogicalOperator.AND.getCode().equalsIgnoreCase(compoundOpCode)) {
30              proposition.setType("kuali.krms.proposition.type.compound.and");
31          } else if (LogicalOperator.OR.getCode().equalsIgnoreCase(compoundOpCode)) {
32              proposition.setType("kuali.krms.proposition.type.compound.or");
33          }
34          try {
35              KrmsTypeDefinition type = KrmsRepositoryServiceLocator.getKrmsTypeRepositoryService().getTypeByName(PermissionServiceConstants.KS_SYS_NAMESPACE, proposition.getType());
36              proposition.setTypeId(type.getId());
37          } catch (Exception e) {
38              //ignore if service not available.
39          }
40  
41      }
42  
43      public static Node<RuleEditorTreeNode, String> findParentPropositionNode(Node<RuleEditorTreeNode, String> currentNode, String selectedPropKey) {
44          Node<RuleEditorTreeNode, String> bingo = null;
45          if (selectedPropKey != null) {
46              // if it's in children, we have the parent
47              List<Node<RuleEditorTreeNode, String>> children = currentNode.getChildren();
48              for (Node<RuleEditorTreeNode, String> child : children) {
49                  RuleEditorTreeNode dataNode = child.getData();
50                  if (selectedPropKey.equalsIgnoreCase(dataNode.getProposition().getKey())) {
51                      return currentNode;
52                  }
53              }
54  
55              // if not found check grandchildren
56              for (Node<RuleEditorTreeNode, String> kid : children) {
57                  bingo = findParentPropositionNode(kid, selectedPropKey);
58                  if (bingo != null) {
59                      break;
60                  }
61              }
62          }
63          return bingo;
64      }
65  
66      /**
67       * @return the {@link org.kuali.rice.krms.impl.repository.PropositionBo} from the form
68       */
69      public static PropositionEditor getProposition(RuleEditor ruleEditor) {
70  
71          if (ruleEditor != null) {
72              String selectedPropKey = ruleEditor.getSelectedKey();
73              return findProposition(ruleEditor.getEditTree().getRootElement(), selectedPropKey);
74          }
75  
76          return null;
77      }
78  
79      public static PropositionEditor findProposition(Node<RuleEditorTreeNode, String> currentNode, String selectedPropKey) {
80  
81          if (selectedPropKey == null) {
82              return null;
83          } else if (selectedPropKey.isEmpty()) {
84              return currentNode.getChildren().get(0).getData().getProposition();
85          }
86  
87          // if it's in children, we have the parent
88          for (Node<RuleEditorTreeNode, String> child : currentNode.getChildren()) {
89              PropositionEditor proposition = child.getData().getProposition();
90              if (selectedPropKey.equalsIgnoreCase(proposition.getKey())) {
91                  return proposition;
92              } else if ("S".equals(proposition.getPropositionTypeCode()) && proposition.isEditMode()) {
93                  return proposition;
94              } else if (!proposition.isEditMode()) {
95                  // if not found check grandchildren
96                  proposition = findProposition(child, selectedPropKey);
97                  if (proposition != null) {
98                      return proposition;
99                  }
100             }
101         }
102 
103         return null;
104     }
105 
106     /**
107      * Find and return the node containing the proposition that is in currently in edit mode
108      *
109      * @param node the node to start searching from (typically the root)
110      * @return the node that is currently being edited, if any.  Otherwise, null.
111      */
112     public static Node<RuleEditorTreeNode, String> findEditedProposition(Node<RuleEditorTreeNode, String> node) {
113         Node<RuleEditorTreeNode, String> result = null;
114         if (node.getData() != null && node.getData().getProposition() != null && node.getData().getProposition()
115                 .isEditMode()) {
116             result = node;
117         } else {
118             for (Node<RuleEditorTreeNode, String> child : node.getChildren()) {
119                 result = findEditedProposition(child);
120                 if (result != null) {
121                     break;
122                 }
123             }
124         }
125         return result;
126     }
127 
128     public static void resetEditModeOnPropositionTree(RuleEditor ruleEditor) {
129         Node<RuleEditorTreeNode, String> root = ruleEditor.getEditTree().getRootElement();
130         resetEditModeOnPropositionTree(root);
131     }
132 
133     /**
134      * disable edit mode for all Nodes beneath and including the passed in Node
135      *
136      * @param currentNode
137      */
138     public static void resetEditModeOnPropositionTree(Node<RuleEditorTreeNode, String> currentNode) {
139         if (currentNode.getData() != null) {
140             RuleEditorTreeNode dataNode = currentNode.getData();
141             dataNode.getProposition().setEditMode(false);
142         }
143         List<Node<RuleEditorTreeNode, String>> children = currentNode.getChildren();
144         for (Node<RuleEditorTreeNode, String> child : children) {
145             resetEditModeOnPropositionTree(child);
146         }
147     }
148 
149     public static Node<RuleEditorTreeNode, String> findPropositionTreeNode(Node<RuleEditorTreeNode, String> currentNode, String selectedPropId) {
150         Node<RuleEditorTreeNode, String> bingo = null;
151         if (currentNode.getData() != null) {
152             RuleEditorTreeNode dataNode = currentNode.getData();
153             if (selectedPropId.equalsIgnoreCase(dataNode.getProposition().getId())) {
154                 return currentNode;
155             }
156         }
157 
158         for (Node<RuleEditorTreeNode, String> child : currentNode.getChildren()) {
159             bingo = findPropositionTreeNode(child, selectedPropId);
160             if (bingo != null) break;
161         }
162         return bingo;
163     }
164 
165     public static String configureLogicExpression(PropositionEditor proposition) {
166         // Depending on the type of proposition (simple/compound), and the editMode,
167         // Create a treeNode of the appropriate type for the node and attach it to the
168         // sprout parameter passed in.
169         // If the prop is a compound proposition, calls itself for each of the compoundComponents
170         String logicExpression = proposition.getKey();
171         if (PropositionType.COMPOUND.getCode().equalsIgnoreCase(proposition.getPropositionTypeCode())) {
172             logicExpression += "(";
173             boolean first = true;
174             for (PropositionEditor child : proposition.getCompoundEditors()) {
175                 // add an opcode node in between each of the children.
176                 if (!first) {
177                     if (LogicalOperator.AND.getCode().equalsIgnoreCase(proposition.getCompoundOpCode())) {
178                         logicExpression += " AND ";
179                     } else if (LogicalOperator.OR.getCode().equalsIgnoreCase(proposition.getCompoundOpCode())) {
180                         logicExpression += " OR ";
181                     }
182                 }
183                 first = false;
184                 // call to build the childs node
185                 logicExpression += configureLogicExpression(child);
186             }
187             logicExpression += ")";
188         }
189         return logicExpression;
190     }
191 
192     /**
193      * This method creates a partially populated Simple PropositionBo with
194      * three parameters:  a term type paramter (value not assigned)
195      * a operation parameter
196      * a constant parameter (value set to empty string)
197      * The returned PropositionBo has an generatedId. The type code and ruleId properties are assigned the
198      * same value as the sibling param passed in.
199      * Each PropositionParameter has the id generated, and type, sequenceNumber,
200      * propId default values set. The value is set to "".
201      *
202      * @param sibling -
203      * @return a PropositionBo partially populated.
204      */
205     public static PropositionEditor createSimplePropositionBoStub(PropositionEditor sibling, Class<? extends PropositionEditor> propClass) throws IllegalAccessException, InstantiationException {
206         // create a simple proposition Bo
207         PropositionEditor prop = propClass.newInstance();
208         prop.setPropositionTypeCode(PropositionType.SIMPLE.getCode());
209         prop.setNewProp(true);
210         prop.setEditMode(true);
211         if (sibling != null) {
212             prop.setRuleId(sibling.getRuleId());
213         }
214 
215         prop.setParameters(createParameterList());
216 
217         return prop;
218     }
219 
220     public static List<PropositionParameterEditor> createParameterList() {
221         // create blank proposition parameters
222         PropositionParameterEditor pTerm = new PropositionParameterEditor("T", new Integer("0"));
223         PropositionParameterEditor pOp = new PropositionParameterEditor("O", new Integer("2"));
224         PropositionParameterEditor pConst = new PropositionParameterEditor("C", new Integer("1"));
225 
226         return Arrays.asList(pTerm, pConst, pOp);
227     }
228 
229     public static PropositionEditor createCompoundPropositionBoStub(PropositionEditor existing, boolean addNewChild, Class<? extends PropositionEditor> propClass) throws InstantiationException, IllegalAccessException {
230         // create a simple proposition Bo
231         PropositionEditor prop = createCompoundPropositionBoStub(existing, propClass);
232 
233         if (addNewChild) {
234             PropositionEditor newProp = createSimplePropositionBoStub(existing, propClass);
235             prop.getCompoundEditors().add(newProp);
236             prop.setEditMode(false); // set the parent edit mode back to null or we end up with 2 props in edit mode
237         }
238 
239         return prop;
240     }
241 
242     public static PropositionEditor createCompoundPropositionBoStub(PropositionEditor existing, Class<? extends PropositionEditor> propClass) throws IllegalAccessException, InstantiationException {
243         // create a simple proposition Bo
244         PropositionEditor prop = propClass.newInstance();
245         prop.setNewProp(true);
246         prop.setPropositionTypeCode(PropositionType.COMPOUND.getCode());
247         prop.setRuleId(existing.getRuleId());
248         prop.setCompoundOpCode(LogicalOperator.AND.getCode());  // default to and
249         prop.setDescription("");
250         prop.setEditMode(true);
251 
252         List<PropositionEditor> components = new ArrayList<PropositionEditor>();
253         components.add(existing);
254         prop.setCompoundEditors(components);
255         return prop;
256     }
257 
258     public static void cancelNewProp(PropositionEditor proposition) {
259         int i = 0;
260         if (proposition.getCompoundEditors() != null) {
261             while (i < proposition.getCompoundEditors().size()) {
262                 PropositionEditor child = proposition.getCompoundEditors().get(i);
263                 if (child.isNewProp()) {
264                     proposition.getCompoundEditors().remove(child);
265                     continue;
266                 } else {
267                     cancelNewProp(child);
268                 }
269                 i++;
270             }
271         }
272     }
273 
274     public static void resetNewProp(PropositionEditor proposition) {
275         if (proposition.getCompoundEditors() != null) {
276             for (PropositionEditor child : proposition.getCompoundEditors()) {
277                 child.setNewProp(false);
278                 resetNewProp(child);
279             }
280         }
281     }
282 }