Coverage Report - org.kuali.student.common.ui.client.widgets.rules.StatementVO
 
Classes in this File Line Coverage Branch Coverage Complexity
StatementVO
0%
0/480
0%
0/434
4.221
 
 1  
 /**
 2  
  * Copyright 2010 The Kuali Foundation Licensed under the
 3  
  * Educational Community License, Version 2.0 (the "License"); you may
 4  
  * not use this file except in compliance with the License. You may
 5  
  * obtain a copy of the License at
 6  
  *
 7  
  * http://www.osedu.org/licenses/ECL-2.0
 8  
  *
 9  
  * Unless required by applicable law or agreed to in writing,
 10  
  * software distributed under the License is distributed on an "AS IS"
 11  
  * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 12  
  * or implied. See the License for the specific language governing
 13  
  * permissions and limitations under the License.
 14  
  */
 15  
 
 16  
 package org.kuali.student.common.ui.client.widgets.rules;
 17  
 
 18  
 import java.io.Serializable;
 19  
 import java.util.ArrayList;
 20  
 import java.util.Collections;
 21  
 import java.util.List;
 22  
 
 23  
 import org.kuali.student.common.ui.client.widgets.table.Node;
 24  
 import org.kuali.student.core.statement.dto.ReqComponentInfo;
 25  
 import org.kuali.student.core.statement.dto.StatementInfo;
 26  
 import org.kuali.student.core.statement.dto.StatementOperatorTypeKey;
 27  
 import org.kuali.student.core.statement.dto.StatementTreeViewInfo;
 28  
 
 29  
 import com.google.gwt.core.client.GWT;
 30  
 import com.google.gwt.user.client.Window;
 31  
 
 32  
 public class StatementVO extends Token implements Serializable {
 33  
 
 34  
     private static final long serialVersionUID = 1L;
 35  
     private StatementInfo statementInfo;       //TODO do we really need this and do we need to duplicate this in sub rules?
 36  0
     private List<ReqComponentVO> reqComponentVOs = new ArrayList<ReqComponentVO>();
 37  0
     private List<StatementVO> statementVOs = new ArrayList<StatementVO>();
 38  
 
 39  
 
 40  
     //TODO remove after refactoring rule table related classes, removing StatementVO
 41  
     public void setStatementTreeViewInfo(StatementTreeViewInfo stmtTreeInfo) {
 42  
         try {
 43  0
             composeStatementVO(stmtTreeInfo, this);
 44  0
         } catch (Exception e) {
 45  0
             Window.alert(e.getMessage());
 46  0
             GWT.log("failed", e);
 47  0
         }
 48  0
     }
 49  
 
 50  
     public StatementTreeViewInfo getStatementTreeViewInfo() {
 51  
 
 52  0
         StatementTreeViewInfo stmtTreeInfo = new StatementTreeViewInfo();
 53  
 
 54  
         try {
 55  0
             composeStatementTreeViewInfo(this, stmtTreeInfo);
 56  0
         } catch (Exception e) {
 57  0
             e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
 58  0
         }
 59  
 
 60  0
         return stmtTreeInfo;
 61  
     }
 62  
 
 63  0
     public StatementVO() {
 64  0
     }
 65  
 
 66  0
     public StatementVO(StatementInfo statementInfo) {
 67  0
         setStatementInfo(statementInfo);
 68  0
     }
 69  
 
 70  
     public void printTree(Node node) {
 71  0
         int level = 0;
 72  
         ReqComponentVO content;
 73  
 //        level++;
 74  
 
 75  0
         if (node == null) {
 76  0
             GWT.log("null node found",null);
 77  0
             return;
 78  
         }
 79  
 
 80  0
         level = node.getDistance(node);
 81  0
         if (node.getUserObject() != null) {
 82  0
             Token token = (Token) node.getUserObject();
 83  
             //content = (ReqComponentVO) token.value;
 84  0
             GWT.log("Node level " + level + ", content: " + token.value,null);
 85  0
         }
 86  0
         else GWT.log("Node user object null, level: " + level, null);
 87  0
         for (int i = 0; i < node.getChildCount(); i++) {
 88  0
             Node child = node.getChildAt(i);
 89  0
             if (child.isLeaf()) {
 90  0
                 Token token = (Token) child.getUserObject();
 91  0
                 content = (ReqComponentVO) child.getUserObject();
 92  0
                 GWT.log("Node level " + child.getDistance(child) + ", content: " + content, null);
 93  0
             } else {
 94  0
                 printTree(child);
 95  
             }
 96  
         }
 97  0
     }
 98  
 
 99  
     /**
 100  
      * Gets the immediate parent statement of reqComponentVO
 101  
      * Example: (a and b) or (c and d) or (e)
 102  
      *     Where the statements are enclosed in brackets.  So in this example there are 3 statements.  Namely (a and b), (c and d), and (e).
 103  
      *     There are 5 requirement components a, b, c, d, and e. If requirement component b is passed in as a parameter, then (a and b)
 104  
      *     is returned.  If e is passed in, then (e) is returned.  If d is is passed in, then (c and d) is returned.
 105  
      * @param reqComponentVO
 106  
      * @return
 107  
      */
 108  
     public StatementVO getEnclosingStatementVO(StatementVO root, ReqComponentVO reqComponentVO) {
 109  0
         return doGetEnclosingStatementVO(root, reqComponentVO);
 110  
     }
 111  
 
 112  
     private StatementVO doGetEnclosingStatementVO(StatementVO statementVO, ReqComponentVO reqComponentVO) {
 113  0
         StatementVO result = null;
 114  0
         List<StatementVO> statementVOs = (statementVO == null)? null : statementVO.getStatementVOs();
 115  0
         List<ReqComponentVO> reqComponentVOs = (statementVO == null)? null : statementVO.getReqComponentVOs();
 116  
 
 117  0
         if (statementVOs != null && !statementVOs.isEmpty()) {
 118  0
             for (StatementVO subStatementVO : statementVOs) {
 119  0
                 List<ReqComponentVO>subStatementReqComponentVOs = subStatementVO.getReqComponentVOs();
 120  0
                 if (subStatementReqComponentVOs.size() == 1) {
 121  0
                     if (subStatementReqComponentVOs.get(0) == reqComponentVO) {
 122  0
                         result = statementVO;
 123  0
                         break;
 124  
                     }
 125  
                 }
 126  
                 else {
 127  0
                     result = doGetEnclosingStatementVO(subStatementVO, reqComponentVO);
 128  
                     // found the enclosing statement exit
 129  0
                     if (result != null) {
 130  0
                         break;
 131  
                     }
 132  
                 }
 133  0
             }
 134  0
         } else if (reqComponentVOs != null && !reqComponentVOs.isEmpty()) {
 135  0
             for (ReqComponentVO leafReqComponentVO : reqComponentVOs) {
 136  0
                 if (leafReqComponentVO == reqComponentVO) {
 137  0
                     result = statementVO;
 138  0
                     break;
 139  
                 }
 140  
             }
 141  
         }
 142  0
         return result;
 143  
     }
 144  
 
 145  
     public StatementVO getParentStatementVO(StatementVO root, StatementVO nodeStatement) {
 146  0
         StatementVO parentStatementVO = null;
 147  0
         if (nodeStatement == root) {
 148  0
             parentStatementVO = null;
 149  
         } else {
 150  0
             parentStatementVO = doGetParentStatementVO(root, nodeStatement);
 151  
         }
 152  0
         return parentStatementVO;
 153  
     }
 154  
 
 155  
     private StatementVO doGetParentStatementVO(StatementVO statementVO, StatementVO nodeStatement) {
 156  0
         StatementVO parentStatementVO = null;
 157  0
         if (statementVO.getStatementVOCount() > 0) {
 158  0
             for (StatementVO childStatementVO : statementVO.getStatementVOs()) {
 159  0
                 if (childStatementVO == nodeStatement) {
 160  0
                     return statementVO;
 161  
                 } else {
 162  0
                     parentStatementVO = doGetParentStatementVO(childStatementVO, nodeStatement);
 163  
                 }
 164  
             }
 165  
         }
 166  0
         return parentStatementVO;
 167  
     }
 168  
 
 169  
     /**
 170  
      * returns the number of leaf requirement componentVO of the this statement
 171  
      * excluding those compound sub statements.
 172  
      * e.g. if this method is called on S1, the return value will be 2.
 173  
      * <pre>
 174  
      *                    S1:OR
 175  
      *           S2:OR    S3:OR   S4:AND
 176  
      *             a        b     c d e
 177  
      * </pre>
 178  
      * @return
 179  
      */
 180  
     /*
 181  
     public int getImmediateChildReqComponentCount() {
 182  
         int result = 0;
 183  
         if (reqComponentVOs != null && !reqComponentVOs.isEmpty()) {
 184  
             result = reqComponentVOs.size();
 185  
         } else if (statementVOs != null && !statementVOs.isEmpty()) {
 186  
             for (StatementVO subStatementVO : statementVOs) {
 187  
                 List<ReqComponentVO> subStatementReqComponentVOs =
 188  
                     subStatementVO.getReqComponentVOs();
 189  
                 if (subStatementReqComponentVOs != null &&
 190  
                         subStatementReqComponentVOs.size() == 1) {
 191  
                     result++;
 192  
                 }
 193  
             }
 194  
         }
 195  
         return result;
 196  
     } */
 197  
 
 198  
     private void validate() {
 199  0
         if (statementVOs != null && !statementVOs.isEmpty() && reqComponentVOs != null && !reqComponentVOs.isEmpty()) {
 200  0
             throw new IllegalStateException("Requirement components and statements can not exist together in a statement");
 201  
         }
 202  0
         checkDuplicateRC(this, new ArrayList<ReqComponentVO>());
 203  0
     }
 204  
 
 205  
     private void checkDuplicateRC(StatementVO statementVO, List<ReqComponentVO> seenRCs) {
 206  0
         if (statementVO.getStatementVOs() != null &&
 207  
                 !statementVO.getStatementVOs().isEmpty()) {
 208  0
             for (StatementVO childStatementVO : statementVO.getStatementVOs()) {
 209  0
                 checkDuplicateRC(childStatementVO, seenRCs);
 210  
             }
 211  
         } else {
 212  0
             if (statementVO.getReqComponentVOs() != null &&
 213  
                     !statementVO.getReqComponentVOs().isEmpty()) {
 214  0
                 for (ReqComponentVO childReqComponent : statementVO.getReqComponentVOs()) {
 215  0
                     if (seenRCs.contains(childReqComponent)) {
 216  0
                         throw new IllegalStateException(
 217  
                                 "statement and sub statements cannot have duplicated components");
 218  
                     } else {
 219  0
                         seenRCs.add(childReqComponent);
 220  
                     }
 221  
                 }
 222  
             }
 223  
         }
 224  0
     }
 225  
 
 226  
     public void addStatementVO(StatementVO statementVO) {
 227  0
         doAddStatementVO(statementVO);
 228  0
         validate();
 229  0
     }
 230  
 
 231  
     private void doAddStatementVO(StatementVO statementVO) {
 232  
         // if there are currently requirement components in this StatementVO
 233  
         // move all the existing requirement components into separate wrapping
 234  
         // StatementVOs
 235  0
         if (reqComponentVOs != null && !reqComponentVOs.isEmpty()) {
 236  0
             List<ReqComponentVO> tempReqComponentVOs = new ArrayList<ReqComponentVO>(reqComponentVOs);
 237  0
             for (ReqComponentVO currReqComponentVO : tempReqComponentVOs) {
 238  0
                 StatementVO wrapStatementVO = new StatementVO(statementInfo);
 239  0
                 wrapStatementVO.addReqComponentVO(currReqComponentVO);
 240  0
                 reqComponentVOs.remove(currReqComponentVO);
 241  0
                 statementVOs.add(wrapStatementVO);
 242  0
             }
 243  
         }
 244  0
         statementVOs.add(statementVO);
 245  0
     }
 246  
 
 247  
     public void addReqComponentVO(ReqComponentVO reqComponentVO) {
 248  0
         doAddReqComponentVO(reqComponentVO);
 249  0
         validate();
 250  0
     }
 251  
 
 252  
     private void doAddReqComponentVO(ReqComponentVO reqComponentVO) {
 253  
         // if there are sub statements in this statement already
 254  
         // add a new sub statement with the same operator as this statement
 255  
         // and a the requirement component
 256  0
         if (statementVOs != null && !statementVOs.isEmpty()) {
 257  0
             StatementInfo newStatementInfo = new StatementInfo();
 258  0
             StatementVO newStatementVO = new StatementVO();
 259  0
             newStatementInfo.setOperator(statementInfo.getOperator());
 260  0
             newStatementVO.setStatementInfo(newStatementInfo);
 261  0
             newStatementVO.getReqComponentVOs().add(reqComponentVO);
 262  0
             statementVOs.add(newStatementVO);
 263  0
         } else {
 264  0
             reqComponentVOs.add(reqComponentVO);
 265  
         }
 266  0
     }
 267  
 
 268  
     public void removeStatementVO(StatementVO statementVO) {
 269  0
         statementVOs.remove(statementVO);
 270  0
         validate();
 271  0
     }
 272  
 
 273  
     public void removeReqComponentVO(ReqComponentVO reqComponentVO) {
 274  0
         doRemoveReqComponentVO(reqComponentVO);
 275  0
         validate();
 276  0
     }
 277  
 
 278  
     private void doRemoveReqComponentVO(ReqComponentVO reqComponentVO) {
 279  0
         if (statementVOs != null && !statementVOs.isEmpty()) {
 280  0
             List<StatementVO> tempStatementVOs = new ArrayList<StatementVO>(statementVOs);
 281  0
             for (StatementVO subStatementVO : tempStatementVOs) {
 282  0
                 List<ReqComponentVO> subStatementReqComponentVOs =
 283  
                     (subStatementVO == null)? null : subStatementVO.getReqComponentVOs();
 284  0
                 if (subStatementReqComponentVOs != null &&
 285  
                         subStatementReqComponentVOs.size() == 1 &&
 286  
                         subStatementReqComponentVOs.get(0) == reqComponentVO) {
 287  0
                     subStatementVO.removeReqComponentVO(reqComponentVO);
 288  
                     // cleans up empty statements with neither statements nor requirement components.
 289  0
                     statementVOs.remove(subStatementVO);
 290  
                 }
 291  0
             }
 292  0
         } else {
 293  0
             reqComponentVOs.remove(reqComponentVO);
 294  
         }
 295  0
     }
 296  
 
 297  
     public StatementInfo getStatementInfo() {
 298  0
         return statementInfo;
 299  
     }
 300  
 
 301  
     public void setStatementInfo(StatementInfo statementInfo) {
 302  0
         this.statementInfo = statementInfo;
 303  0
         this.setType(statementInfo.getOperator() == StatementOperatorTypeKey.OR ? Token.Or : Token.And);
 304  0
     }
 305  
 
 306  
     public List<ReqComponentVO> getReqComponentVOs() {
 307  0
         return reqComponentVOs;
 308  
     }
 309  
 
 310  
     public List<StatementVO> getStatementVOs() {
 311  0
         return statementVOs;
 312  
     }
 313  
 
 314  
     public void clearStatementAndReqComponents() {
 315  0
         if (statementVOs != null) {
 316  0
             statementVOs.clear();
 317  
         }
 318  0
         if (reqComponentVOs != null) {
 319  0
             reqComponentVOs.clear();
 320  
         }
 321  0
     }
 322  
 
 323  
     public void shiftReqComponent(String shiftType, final ReqComponentVO reqComponentVO) {
 324  0
         if (statementVOs != null && !statementVOs.isEmpty()) {
 325  
             // the statementVO that wraps the reqComponentVO
 326  0
             StatementVO reqComponentVOWrap = null;
 327  0
             for (StatementVO currStatementVO : statementVOs) {
 328  0
                 List<ReqComponentVO> currReqComponentVOs = (currStatementVO == null)? null :
 329  
                         currStatementVO.getReqComponentVOs();
 330  0
                 if (currReqComponentVOs != null && currReqComponentVOs.size() == 1 &&
 331  
                         currReqComponentVOs.get(0) == reqComponentVO) {
 332  0
                     reqComponentVOWrap = currStatementVO;
 333  
                 }
 334  0
             }
 335  0
             if (reqComponentVOWrap != null) {
 336  0
                 swapElement(statementVOs, reqComponentVOWrap, shiftType);
 337  
             }
 338  0
         } else if (reqComponentVOs != null && reqComponentVOs.size() > 1) {
 339  0
             swapElement(reqComponentVOs, reqComponentVO, shiftType);
 340  
         }
 341  0
     }
 342  
 
 343  
     private <T> void swapElement(List<T> elements, T element, String direction) {
 344  0
         int elementIndex = 0;
 345  0
         if (elements != null && elements.size() > 1) {
 346  0
             for (T currElement : elements) {
 347  0
                 if (direction != null && direction.equals("RIGHT")) {
 348  0
                     if (currElement == element && elementIndex + 1 < elements.size()) {
 349  0
                         Collections.swap(elements, elementIndex, elementIndex + 1);
 350  0
                         break;
 351  
                     }
 352  0
                 } else if (direction != null && direction.equals("LEFT")) {
 353  0
                     if (currElement == element && elementIndex > 0) {
 354  0
                         Collections.swap(elements, elementIndex, elementIndex - 1);
 355  0
                         break;
 356  
                     }
 357  
                 }
 358  0
                 elementIndex++;
 359  
             }
 360  
         }
 361  0
     }
 362  
 
 363  
     /**
 364  
      * returns A, B, C, ... etc depending on the number of
 365  
      * Requirement components in the list.
 366  
      * @param rcs
 367  
      * @return
 368  
      */
 369  
     private String getNextGuiRCId(List<ReqComponentVO> rcs) {
 370  0
         int charCode = 65; // ASCII code for capitalized A
 371  0
         int newCharCode = -1;
 372  
 
 373  0
         while (newCharCode == -1) {
 374  0
             boolean charUsed = false;
 375  0
             if (rcs != null) {
 376  0
                 for (ReqComponentVO rc : rcs) {
 377  0
                     String currGuiRCId = rc.getGuiReferenceLabelId();
 378  0
                     currGuiRCId = (currGuiRCId == null)? "" : currGuiRCId;
 379  0
                     if (currGuiRCId.equals(Character.toString((char)charCode))) {
 380  0
                         charUsed = true;
 381  0
                         charCode++;
 382  
                     }
 383  0
                 }
 384  
             }
 385  0
             if (!charUsed) {
 386  0
                 newCharCode = charCode;
 387  
             }
 388  0
         }
 389  
 
 390  
         // the next GUI id will be A - Z, and A1, A2, A3 afterwards.
 391  
         String guiRCId;
 392  0
         if (newCharCode < 65 + 26) {
 393  0
             guiRCId = Character.toString((char)newCharCode);
 394  
         } else {
 395  0
             guiRCId = Character.toString((char)(65 + 26));
 396  0
             guiRCId = guiRCId + Integer.toString(newCharCode - 65 + 26 - 1);
 397  
         }
 398  0
         return guiRCId;
 399  
     }
 400  
 
 401  
     private void assignGuiRCId() {
 402  0
         doAssignGuiRCId(this, new ArrayList<ReqComponentVO>());
 403  0
     }
 404  
 
 405  
     private void doAssignGuiRCId(StatementVO statementVO, List<ReqComponentVO> rcs) {
 406  0
         List<StatementVO> statementVOs = statementVO.getStatementVOs();
 407  0
         List<ReqComponentVO> reqComponentVOs = statementVO.getReqComponentVOs();
 408  
 
 409  0
         if (statementVOs != null) {
 410  0
             for (StatementVO childStatementVO : statementVOs) {
 411  0
                 doAssignGuiRCId(childStatementVO, rcs);
 412  
             }
 413  
         }
 414  
 
 415  0
         if (reqComponentVOs != null) {
 416  0
             for (int rcIndex = 0, rcCount = reqComponentVOs.size(); rcIndex < rcCount; rcIndex++) {
 417  0
                 ReqComponentVO childReqComponentVO = reqComponentVOs.get(rcIndex);
 418  0
                 if (childReqComponentVO.getGuiReferenceLabelId() == null ||
 419  
                         childReqComponentVO.getGuiReferenceLabelId().trim().length() == 0) {
 420  0
                     String guiRCId = getNextGuiRCId(rcs);
 421  0
                     childReqComponentVO.setGuiReferenceLabelId(guiRCId);
 422  
                 }
 423  0
                 rcs.add(childReqComponentVO);
 424  
             }
 425  
         }
 426  0
     }
 427  
 
 428  
     public Node getTree() {
 429  0
         Node node = new Node();
 430  0
         assignGuiRCId();
 431  0
         addChildrenNodes(node, this);
 432  0
         return node;
 433  
     }
 434  
 
 435  
     private void addChildrenNodes(Node node, StatementVO statementVO) {
 436  0
         List<StatementVO> statementVOs = statementVO.getStatementVOs();
 437  0
         List<ReqComponentVO> reqComponentVOs = statementVO.getReqComponentVOs();
 438  
 
 439  0
         if (statementVOs != null) {
 440  0
             node.setUserObject(statementVO);
 441  0
             setOperatorNode(node, statementVO);
 442  0
             for (int i = 0; i < statementVOs.size(); i++) {
 443  0
                 StatementVO childStatementVO = statementVOs.get(i);
 444  0
                 childStatementVO.setTokenOperator(true);
 445  0
                 Node childNode = new Node();
 446  0
                 node.addNode(childNode);
 447  0
                 addChildrenNodes(childNode, childStatementVO);
 448  
             }
 449  
         }
 450  
 
 451  0
         if (reqComponentVOs != null) {
 452  0
             for (int rcIndex = 0, rcCount = reqComponentVOs.size(); rcIndex < rcCount; rcIndex++) {
 453  0
                 ReqComponentVO childReqComponentVO = reqComponentVOs.get(rcIndex);
 454  0
                 if (rcCount > 1) {
 455  0
                     node.addNode(new Node(childReqComponentVO));
 456  
                 } else {
 457  0
                     node.setUserObject(childReqComponentVO);
 458  
                 }
 459  
             }
 460  
         }
 461  0
     }
 462  
 
 463  
     private void setOperatorNode(Node node, StatementVO statementVO) {
 464  0
         if (statementVO.getStatementInfo() != null && statementVO.getStatementInfo().getOperator() == StatementOperatorTypeKey.AND) {
 465  0
             statementVO.type = Token.And;
 466  0
             statementVO.value = "and";
 467  0
             node.setUserObject(statementVO);
 468  0
         } else if (statementVO.getStatementInfo() != null && statementVO.getStatementInfo().getOperator() == StatementOperatorTypeKey.OR) {
 469  0
             statementVO.type = Token.Or;
 470  0
             statementVO.value = "or";
 471  0
             node.setUserObject(statementVO);
 472  
         }
 473  0
     }
 474  
 
 475  
     public List<StatementVO> getSelectedStatementVOs() {
 476  0
         List<StatementVO> selectedStatementVOs = new ArrayList<StatementVO>();
 477  0
         return doGetSelectedStatmentVOs(this, selectedStatementVOs);
 478  
     }
 479  
 
 480  
     private List<StatementVO> doGetSelectedStatmentVOs(StatementVO statementVO, List<StatementVO> selectedStatementVOs) {
 481  0
         List<StatementVO> childrenStatementVOs = statementVO.getStatementVOs();
 482  0
         if (statementVO.isCheckBoxOn()) {
 483  0
             selectedStatementVOs.add(statementVO);
 484  
         }
 485  
         // check children
 486  0
         if (childrenStatementVOs != null && !childrenStatementVOs.isEmpty()) {
 487  0
             for (StatementVO childStatementVO : statementVO.getStatementVOs()) {
 488  0
                 doGetSelectedStatmentVOs(childStatementVO, selectedStatementVOs);
 489  
             }
 490  
         }
 491  0
         return selectedStatementVOs;
 492  
     }
 493  
 
 494  
     /**
 495  
      * goes through the entire tree recursively and returns the list of all RCs
 496  
      * @return
 497  
      */
 498  
     public List<ReqComponentVO> getAllReqComponentVOs() {
 499  0
         return doGetAllReqComponentVOs(this, new ArrayList<ReqComponentVO>());
 500  
     }
 501  
 
 502  
     public ReqComponentVO getReqComponentVOByGuiKey(String guiKey) {
 503  0
         ReqComponentVO result = null;
 504  0
         List<ReqComponentVO> allRCs = getAllReqComponentVOs();
 505  0
         for (ReqComponentVO rc : allRCs) {
 506  0
             if (rc.getGuiReferenceLabelId() != null && rc.getGuiReferenceLabelId().equals(guiKey)) {
 507  0
                 result = rc;
 508  0
                 break;
 509  
             }
 510  
         }
 511  0
         return result;
 512  
     }
 513  
 
 514  
     private List<ReqComponentVO> doGetAllReqComponentVOs(StatementVO statementVO,
 515  
             List<ReqComponentVO> allRCs) {
 516  0
         List<ReqComponentVO> childrenReqComponentVOs = statementVO.getReqComponentVOs();
 517  0
         List<StatementVO> childrenStatementVOs = statementVO.getStatementVOs();
 518  0
         if (childrenReqComponentVOs != null && !childrenReqComponentVOs.isEmpty()) {
 519  0
             for (ReqComponentVO childReqComponentVO : childrenReqComponentVOs) {
 520  0
                 allRCs.add(childReqComponentVO);
 521  
             }
 522  
         }
 523  0
         if (childrenStatementVOs != null && !childrenStatementVOs.isEmpty()) {
 524  0
             for (StatementVO childStatementVO : statementVO.getStatementVOs()) {
 525  0
                 doGetAllReqComponentVOs(childStatementVO, allRCs);
 526  
             }
 527  
         }
 528  0
         return allRCs;
 529  
     }
 530  
 
 531  
     public List<ReqComponentVO> getSelectedReqComponentVOs() {
 532  0
         List<ReqComponentVO> selectedReqComponentVOs = new ArrayList<ReqComponentVO>();
 533  0
         return doGetSelectedReqComponentVOs(this, selectedReqComponentVOs);
 534  
     }
 535  
 
 536  
     private List<ReqComponentVO> doGetSelectedReqComponentVOs(StatementVO statementVO, List<ReqComponentVO> selectedReqComponentVOs) {
 537  0
         List<ReqComponentVO> childrenReqComponentVOs = statementVO.getReqComponentVOs();
 538  0
         List<StatementVO> childrenStatementVOs = statementVO.getStatementVOs();
 539  0
         if (childrenReqComponentVOs != null && !childrenReqComponentVOs.isEmpty()) {
 540  0
             for (ReqComponentVO childReqComponentVO : childrenReqComponentVOs) {
 541  0
                 if (childReqComponentVO.isCheckBoxOn()) {
 542  0
                     selectedReqComponentVOs.add(childReqComponentVO);
 543  
                 }
 544  
             }
 545  
         }
 546  0
         if (childrenStatementVOs != null && !childrenStatementVOs.isEmpty()) {
 547  0
             for (StatementVO childStatementVO : statementVO.getStatementVOs()) {
 548  0
                 doGetSelectedReqComponentVOs(childStatementVO, selectedReqComponentVOs);
 549  
             }
 550  
         }
 551  0
         return selectedReqComponentVOs;
 552  
     }
 553  
 
 554  
     public boolean isFirstSelectedReqComp() {
 555  0
         return doIsFirstSelectedReqComp(this);
 556  
     }
 557  
 
 558  
     public boolean doIsFirstSelectedReqComp(StatementVO statementVO) {
 559  0
         List<ReqComponentVO> childrenReqComponentVOs = statementVO.getReqComponentVOs();
 560  0
         boolean isFirst = false;
 561  0
         if (childrenReqComponentVOs != null && !childrenReqComponentVOs.isEmpty()) {
 562  0
             isFirst = true;
 563  0
             for (ReqComponentVO childReqComponentVO : childrenReqComponentVOs) {
 564  0
                 if (childReqComponentVO.isCheckBoxOn()) {
 565  0
                     return isFirst;
 566  
                 }
 567  0
                 isFirst = false;
 568  
             }
 569  
         }
 570  0
         return isFirst;
 571  
     }
 572  
 
 573  
     public boolean isLastSelectedReqComp() {
 574  0
         return doIsLastSelectedReqComp(this);
 575  
     }
 576  
 
 577  
     public boolean doIsLastSelectedReqComp(StatementVO statementVO) {
 578  0
         List<ReqComponentVO> childrenReqComponentVOs = statementVO.getReqComponentVOs();
 579  0
         boolean isLast = false;
 580  0
         if (childrenReqComponentVOs != null && !childrenReqComponentVOs.isEmpty()) {
 581  0
             isLast = true;
 582  0
             for (ReqComponentVO childReqComponentVO : childrenReqComponentVOs) {
 583  0
                 isLast = childReqComponentVO.isCheckBoxOn();
 584  
             }
 585  
         }
 586  0
         return isLast;
 587  
     }
 588  
 
 589  
     public boolean isNodeSelected() {
 590  0
         return ((getSelectedStatementVOs().size() + getSelectedReqComponentVOs().size()) > 0);
 591  
     }
 592  
 
 593  
     public int getNestingDepth() {
 594  0
         return doGetNestingDepth(this);
 595  
     }
 596  
 
 597  
     private int doGetNestingDepth(StatementVO statementVO) {
 598  0
         int depth = 0;
 599  0
         List<StatementVO> statementVOs = getStatementVOs();
 600  0
         if (this == statementVO) {
 601  0
             return depth;
 602  
         }
 603  0
         if (statementVOs != null && !statementVOs.isEmpty()) {
 604  0
             for (StatementVO childStatementVO : statementVOs) {
 605  0
                 depth = depth + doGetNestingDepth(childStatementVO);
 606  
             }
 607  
         }
 608  0
         return depth;
 609  
     }
 610  
 
 611  
     public int getReqComponentVOCount() {
 612  0
         return (reqComponentVOs == null)? 0 : reqComponentVOs.size();
 613  
     }
 614  
 
 615  
     public int getStatementVOCount() {
 616  0
         return (statementVOs == null)? 0 : statementVOs.size();
 617  
     }
 618  
 
 619  
     public int getChildCount() {
 620  0
         return getReqComponentVOCount() + getStatementVOCount();
 621  
     }
 622  
 
 623  
     public boolean isWrapperStatementVO() {
 624  0
         boolean result = false;
 625  0
         if (getReqComponentVOCount() == 1 && getStatementVOCount() == 0) {
 626  0
             result = true;
 627  
         }
 628  0
         return result;
 629  
     }
 630  
 
 631  
     public void addStatementVOs(List<StatementVO> statementVOs) {
 632  0
         if (statementVOs != null && !statementVOs.isEmpty()) {
 633  0
             for (StatementVO s : statementVOs) {
 634  0
                 this.addStatementVO(s);
 635  
             }
 636  
         }
 637  0
     }
 638  
 
 639  
     public void addReqComponentVOs(List<ReqComponentVO> reqComponentVOs) {
 640  0
         if (reqComponentVOs != null && !reqComponentVOs.isEmpty()) {
 641  0
             for (ReqComponentVO rc : reqComponentVOs) {
 642  0
                 this.addReqComponentVO(rc);
 643  
             }
 644  
         }
 645  0
     }
 646  
 
 647  
     /**************************************************************************************************
 648  
      * simplifies statement
 649  
      * @return true if statement has been changed as a result of the call
 650  
      */
 651  
     public boolean simplify() {
 652  0
         boolean structureChanged = false;
 653  0
         structureChanged = structureChanged || doSimplify(this, null);
 654  0
         structureChanged = structureChanged || doCleanupStatementVO(this, null);
 655  0
         structureChanged = structureChanged || doUnwrapRCs(this, 0);
 656  0
         return structureChanged;
 657  
     }
 658  
 
 659  
     private boolean doSimplify(StatementVO statementVO, StatementVO parent) {
 660  0
         boolean structureChanged = false;
 661  0
         StatementOperatorTypeKey op = (statementVO == null || statementVO.getStatementInfo() == null)? null :
 662  
                                         statementVO.getStatementInfo().getOperator();
 663  0
         StatementOperatorTypeKey parentOp = (parent == null || parent.getStatementInfo() == null)? null : parent.getStatementInfo().getOperator();
 664  
 
 665  0
         if (parentOp == op && !statementVO.isWrapperStatementVO()) {
 666  0
             structureChanged = true;
 667  0
             if (statementVO.getReqComponentVOCount() > 0) {
 668  0
                 parent.removeStatementVO(statementVO);
 669  0
                 for (ReqComponentVO rc : statementVO.getReqComponentVOs()) {
 670  0
                     parent.addReqComponentVO(rc);
 671  
                 }
 672  0
             } else if (statementVO.getStatementVOCount() > 0) {
 673  0
                 if (parent != null) {
 674  0
                     parent.removeStatementVO(statementVO);
 675  
                 }
 676  0
                 List<StatementVO> subSs = new ArrayList<StatementVO>(statementVO.getStatementVOs());
 677  0
                 for (StatementVO subS : subSs) {
 678  0
                     doSimplify(subS, statementVO);
 679  
                 }
 680  0
                 parent.addStatementVOs(statementVO.getStatementVOs());
 681  0
             }
 682  0
         } else if (statementVO!=null && statementVO.getStatementVOCount() > 0) {
 683  0
             List<StatementVO> subSs = new ArrayList<StatementVO>(statementVO.getStatementVOs());
 684  0
             for (StatementVO subS : subSs) {
 685  0
                 structureChanged = structureChanged || doSimplify(subS, statementVO);
 686  
             }
 687  
         }
 688  0
         return structureChanged;
 689  
     }
 690  
 
 691  
     private boolean doCleanupStatementVO(StatementVO statementVO, StatementVO parent) {
 692  0
         boolean structureChanged = false;
 693  0
         if (statementVO.getStatementVOCount() == 0 && statementVO.getReqComponentVOCount() == 0) {
 694  0
             if (parent != null) {
 695  0
                 parent.removeStatementVO(statementVO);
 696  0
                 structureChanged = true;
 697  
             }
 698  0
         } else if (statementVO.getStatementVOCount() > 0) {
 699  0
             for (StatementVO subS : statementVO.getStatementVOs()) {
 700  0
                 structureChanged = structureChanged || doCleanupStatementVO(subS, statementVO);
 701  
             }
 702  
         }
 703  0
         return structureChanged;
 704  
     }
 705  
 
 706  
     private boolean doUnwrapRCs(StatementVO statementVO, int level) {
 707  0
         boolean structureChanged = false;
 708  0
         List<ReqComponentVO> wrappedRCs = new ArrayList<ReqComponentVO>();
 709  0
         if (statementVO.getStatementVOCount() > 0) {
 710  0
             List<StatementVO> subSs = new ArrayList<StatementVO>(statementVO.getStatementVOs());
 711  0
             for (StatementVO subS : subSs) {
 712  0
                 if (!subS.isWrapperStatementVO()) {
 713  0
                     structureChanged = structureChanged || doUnwrapRCs(subS, level + 1);
 714  
                 }
 715  
             }
 716  
 
 717  0
             for (StatementVO subS : subSs) {
 718  0
                 if (subS.isWrapperStatementVO()) {
 719  0
                     wrappedRCs.add(subS.getReqComponentVOs().get(0));
 720  
                 }
 721  
             }
 722  0
             if (wrappedRCs != null && wrappedRCs.size() == statementVO.getChildCount()) {
 723  0
                 structureChanged = true;
 724  0
                 for (StatementVO subS : subSs) {
 725  0
                     statementVO.removeStatementVO(subS);
 726  
                 }
 727  0
                 for (ReqComponentVO wrappedRC : wrappedRCs) {
 728  0
                     statementVO.addReqComponentVO(wrappedRC);
 729  
                 }
 730  
             }
 731  
         }
 732  0
         return structureChanged;
 733  
     }
 734  
 
 735  
     /*************************************************************************************************/
 736  
 
 737  
     public String getPrintableStatement() {
 738  0
         return doConvertToExpression(new StringBuilder(), this, true).toString();
 739  
     }
 740  
 
 741  
     public String convertToExpression() {
 742  0
         assignGuiRCId();
 743  0
         return doConvertToExpression(new StringBuilder(), this, false).toString();
 744  
     }
 745  
 
 746  
     private StringBuilder doConvertToExpression(StringBuilder inSbResult,
 747  
             StatementVO statementVO,
 748  
             boolean extraBrackets) {
 749  0
         List<StatementVO> currStatementVOs = (statementVO == null)? null : statementVO.getStatementVOs();
 750  0
         List<ReqComponentVO> currReqComponentVOs = (statementVO == null)? null : statementVO.getReqComponentVOs();
 751  0
         if (currStatementVOs != null && !currStatementVOs.isEmpty()) {
 752  0
             int statementCounter = 0;
 753  0
             for (StatementVO childStatementVO : statementVO.getStatementVOs()) {
 754  0
                 if (statementCounter > 0) {
 755  0
                     StatementOperatorTypeKey operator = (statementVO == null ||
 756  
                                 statementVO.getStatementInfo() == null)? null :
 757  
                                     statementVO.getStatementInfo().getOperator();
 758  0
                     inSbResult.append(" " + operator + " ");
 759  
                 }
 760  0
                 if (extraBrackets || !childStatementVO.isWrapperStatementVO()) {
 761  0
                     inSbResult.append("(");
 762  
                 }
 763  0
                 inSbResult.append(doConvertToExpression(new StringBuilder(), childStatementVO,
 764  
                         extraBrackets).toString());
 765  0
                 if (extraBrackets || !childStatementVO.isWrapperStatementVO()) {
 766  0
                     inSbResult.append(")");
 767  
                 }
 768  0
                 statementCounter++;
 769  
             }
 770  0
         } else if (currReqComponentVOs != null && !currReqComponentVOs.isEmpty()) {
 771  0
             int rcCounter = 0;
 772  0
             for (ReqComponentVO childReqComponentInfo : currReqComponentVOs) {
 773  0
                 if (rcCounter > 0) {
 774  0
                     if(statementVO != null &&
 775  
                        statementVO.getStatementInfo() != null &&
 776  
                        statementVO.getStatementInfo().getOperator() != null) {
 777  0
                                 StatementOperatorTypeKey operator = statementVO.getStatementInfo().getOperator();
 778  0
                             inSbResult.append(" " + operator.toString().toLowerCase() + " ");
 779  
                     }
 780  
                 }
 781  0
                 inSbResult.append(childReqComponentInfo.getGuiReferenceLabelId());
 782  0
                 rcCounter++;
 783  
             }
 784  
         }
 785  0
         return inSbResult;
 786  
     }
 787  
 
 788  
     public void clearSelections() {
 789  0
         doClearSelections(this);
 790  0
     }
 791  
 
 792  
     private void doClearSelections(StatementVO statementVO) {
 793  0
         statementVO.setCheckBoxOn(false);
 794  0
         if (statementVO.getStatementVOCount() > 0) {
 795  0
             for (StatementVO childS : statementVO.getStatementVOs()) {
 796  0
                 doClearSelections(childS);
 797  
             }
 798  0
         } else if (statementVO.getReqComponentVOCount() > 0) {
 799  0
             for (ReqComponentVO rc : statementVO.getReqComponentVOs()) {
 800  0
                 rc.setCheckBoxOn(false);
 801  
             }
 802  
         }
 803  0
     }
 804  
 
 805  
     public boolean isSimple() {
 806  0
         boolean simple = false;
 807  0
         if (getStatementVOCount() == 0 && getReqComponentVOCount() <= 1) {
 808  0
             simple = true;
 809  
         }
 810  0
         return simple;
 811  
     }
 812  
 
 813  
     public boolean isEmpty() {
 814  0
         boolean simple = false;
 815  0
         if (getStatementVOCount() == 0 && getReqComponentVOCount() == 0) {
 816  0
             simple = true;
 817  
         }
 818  0
         return simple;
 819  
     }
 820  
 
 821  
     public String composeStatementTreeViewInfo(StatementVO statementVO, StatementTreeViewInfo statementTreeViewInfo) throws Exception {
 822  0
         String rc = "";
 823  0
         List<StatementVO> statementVOs = statementVO.getStatementVOs();
 824  0
         List<ReqComponentVO> reqComponentVOs = statementVO.getReqComponentVOs();
 825  
 
 826  0
         if ((statementVOs != null) && (reqComponentVOs != null) && (statementVOs.size() > 0) && (reqComponentVOs.size() > 0))
 827  
         {
 828  0
             return "Internal error: found both Statements and Requirement Components on the same level of boolean expression";
 829  
         }
 830  
 
 831  0
         statementVO.setFieldsTo(statementTreeViewInfo);
 832  
 
 833  0
         if ((statementVOs != null) && (statementVOs.size() > 0)) {
 834  
             // retrieve all statements
 835  0
             List<StatementTreeViewInfo> subStatementTVInfos = new ArrayList<StatementTreeViewInfo>();
 836  0
             for (StatementVO statement : statementVOs) {
 837  0
                 StatementTreeViewInfo subStatementTVInfo = new StatementTreeViewInfo();
 838  0
                 statement.setFieldsTo(subStatementTVInfo);
 839  0
                 rc = composeStatementTreeViewInfo(statement, subStatementTVInfo); // inside set the children of this statementTreeViewInfo
 840  0
                 subStatementTVInfos.add(subStatementTVInfo);
 841  0
             }
 842  0
             statementTreeViewInfo.setStatements(subStatementTVInfos);
 843  0
         } else {
 844  
             // retrieve all req. component LEAFS
 845  0
             List<ReqComponentInfo> reqComponentList = new ArrayList<ReqComponentInfo>();
 846  0
             for (ReqComponentVO reqComponent : reqComponentVOs) {
 847  0
                 ReqComponentInfo newReqComp = RulesUtil.clone(reqComponent.getReqComponentInfo());
 848  0
                 reqComponentList.add(newReqComp);
 849  0
             }
 850  0
             statementTreeViewInfo.setReqComponents(reqComponentList);
 851  
         }
 852  
 
 853  0
         return rc;
 854  
     }
 855  
 
 856  
     private void setFieldsTo(final StatementTreeViewInfo stvInfo) {
 857  0
         stvInfo.setAttributes(getStatementInfo().getAttributes());
 858  0
         stvInfo.setDesc(getStatementInfo().getDesc());
 859  0
         stvInfo.setId(getStatementInfo().getId());
 860  0
         stvInfo.setMetaInfo(getStatementInfo().getMetaInfo());
 861  0
         stvInfo.setName(getStatementInfo().getName());
 862  0
         stvInfo.setOperator(getStatementInfo().getOperator());
 863  0
         stvInfo.setState(getStatementInfo().getState());
 864  0
         stvInfo.setType(getStatementInfo().getType());
 865  0
     }
 866  
 
 867  
     public String composeStatementVO(StatementTreeViewInfo statementTreeViewInfo, StatementVO statementVO) throws Exception {
 868  0
         String rc = "";
 869  0
         List<StatementTreeViewInfo> statements = statementTreeViewInfo.getStatements();
 870  0
         List<ReqComponentInfo> reqComponentInfos = statementTreeViewInfo.getReqComponents();
 871  
 
 872  0
         if ((statements != null) && (reqComponentInfos != null) && (statements.size() > 0) && (reqComponentInfos.size() > 0))
 873  
         {
 874  0
             return "Internal error: found both Statements and Requirement Components on the same level of boolean expression";
 875  
         }
 876  
 
 877  0
         statementVO.setFields(statementTreeViewInfo);
 878  0
         statementVO.setTokenOperator(true);
 879  
 
 880  0
         if ((statements != null) && (statements.size() > 0)) {
 881  
             // retrieve all statements
 882  0
             List<StatementVO> newStatementList = new ArrayList<StatementVO>();
 883  0
             for (StatementTreeViewInfo statement : statements) {
 884  0
                 StatementVO newStatementVO = new StatementVO();
 885  0
                 newStatementVO.setFields(statement);
 886  0
                 newStatementVO.getStatementInfo().setId("123");
 887  0
                 rc = composeStatementVO(statement, newStatementVO); // inside set the children of this statementTreeViewInfo
 888  0
                 newStatementList.add(newStatementVO);
 889  0
             }
 890  0
             statementVO.statementVOs = newStatementList;
 891  0
         } else if ((reqComponentInfos != null) && (reqComponentInfos.size() > 0)) {
 892  
             // retrieve all req. component LEAFS
 893  0
             List<ReqComponentVO> reqComponentList = new ArrayList<ReqComponentVO>();
 894  0
             for (ReqComponentInfo reqComponent : reqComponentInfos) {
 895  0
                 ReqComponentVO newReqComp = new ReqComponentVO();
 896  0
                 newReqComp.setReqComponentInfo(RulesUtil.clone(reqComponent));
 897  0
                 reqComponentList.add(newReqComp);
 898  0
             }
 899  0
             statementVO.reqComponentVOs = reqComponentList;
 900  
         }
 901  
 
 902  0
         return rc;
 903  
     }
 904  
 
 905  
     private void setFields(final StatementTreeViewInfo statementTreeViewInfo) {
 906  0
         statementInfo = new StatementInfo();
 907  0
         getStatementInfo().setAttributes(statementTreeViewInfo.getAttributes());
 908  0
         getStatementInfo().setDesc(statementTreeViewInfo.getDesc());
 909  0
         getStatementInfo().setId(statementTreeViewInfo.getId());
 910  0
         getStatementInfo().setMetaInfo(statementTreeViewInfo.getMetaInfo());
 911  0
         getStatementInfo().setName(statementTreeViewInfo.getName());
 912  0
         getStatementInfo().setOperator(statementTreeViewInfo.getOperator());
 913  0
         getStatementInfo().setState(statementTreeViewInfo.getState());
 914  0
         getStatementInfo().setType(statementTreeViewInfo.getType());
 915  0
     }
 916  
 
 917  
     @Override
 918  
     public String toString() {
 919  0
         StringBuilder sbResult = new StringBuilder();
 920  0
         sbResult.append(value);
 921  0
         return sbResult.toString();
 922  
     }
 923  
 
 924  
     @Override
 925  
     public boolean equals(Object obj) {
 926  0
         return this == obj;
 927  
     }
 928  
 
 929  
 }