View Javadoc
1   package org.kuali.student.enrollment.class2.population.rule;
2   
3   import org.kuali.rice.core.api.criteria.PredicateFactory;
4   import org.kuali.rice.core.api.criteria.QueryByCriteria;
5   import org.kuali.rice.core.api.resourceloader.GlobalResourceLoader;
6   import org.kuali.rice.krad.maintenance.MaintenanceDocument;
7   import org.kuali.rice.krad.util.GlobalVariables;
8   import org.kuali.student.common.uif.rule.KsMaintenanceDocumentRuleBase;
9   import org.kuali.student.enrollment.class2.population.dto.PopulationWrapper;
10  import org.kuali.student.enrollment.class2.population.util.PopulationConstants;
11  import org.kuali.student.r2.common.dto.ContextInfo;
12  import org.kuali.student.common.util.security.ContextUtils;
13  import org.kuali.student.r2.core.constants.PopulationServiceConstants;
14  import org.kuali.student.r2.core.population.dto.PopulationInfo;
15  import org.kuali.student.r2.core.population.service.PopulationService;
16  
17  import javax.xml.namespace.QName;
18  import java.util.List;
19  
20  /**
21   * This class does business validation for Populations
22   *
23   * @author Kuali Student Team
24   */
25  public class PopulationWrapperRule extends KsMaintenanceDocumentRuleBase {
26      private transient PopulationService populationService;
27  
28  
29  
30      /**
31       * Main entry for validating populations.
32       *
33       * @param document
34       * @return if this document contains valid population information
35       */
36      @Override
37      protected boolean processCustomRouteDocumentBusinessRules(MaintenanceDocument document) {
38  
39          boolean isValid = super.processCustomRouteDocumentBusinessRules(document);
40          PopulationWrapper newWrapper = (PopulationWrapper) document.getNewMaintainableObject().getDataObject();
41          //Rule:  population Name has to be unique for creating a new population
42          if (document.isNew()) {
43              isValid &= populationNameUniqueCheck(newWrapper);
44          }
45          else if(document.isEdit()){
46              PopulationWrapper oldWrapper = (PopulationWrapper) document.getOldMaintainableObject().getDataObject(); 
47              if (!oldWrapper.getPopulationInfo().getName().equalsIgnoreCase(newWrapper.getPopulationInfo().getName())) {
48                  isValid &= populationNameUniqueCheck(newWrapper);
49              }             
50          }
51  
52          String operationType = newWrapper.getPopulationRuleInfo().getTypeKey();
53          //Rule:
54          //by Union - must select at least 2 DIFFERENT populations in order to create
55          //by Intersection - must select at least 2 DIFFERENT populations in order to create
56          if (operationType.equals(PopulationServiceConstants.POPULATION_RULE_TYPE_UNION_KEY)){
57              isValid &= needTwoChildPopulations(newWrapper, "Union" );
58          }
59          else if (operationType.equals(PopulationServiceConstants.POPULATION_RULE_TYPE_INTERSECTION_KEY)){
60  
61              isValid &= needTwoChildPopulations(newWrapper, "Intersection" );
62          }
63          else if (operationType.equals(PopulationServiceConstants.POPULATION_RULE_TYPE_EXCLUSION_KEY)){
64              //Rule:
65              //by Exclusion - must select one reference population and at least one other DIFFERENT population in order to create
66              isValid &= checkReferenceAndChildPopulations(newWrapper);
67          }
68          return isValid;
69      }
70  
71      protected boolean checkReferenceAndChildPopulations(PopulationWrapper wrapper){
72          boolean isValid  = true;
73          List<PopulationInfo> populationInfoList = wrapper.getChildPopulations();
74          String referenceId = wrapper.getReferencePopulation().getId();
75          if(populationInfoList == null || populationInfoList.isEmpty()){
76              isValid = false;
77              GlobalVariables.getMessageMap().putError("document.newMaintainableObject.dataObject.operationType",
78                      PopulationConstants.POPULATION_MSG_ERROR_NEED_ONE_POPULATIONS, "Exclusion");
79          }else{
80              // the ref population cannot be in the  source populations.
81              if(this.containsPopulation(populationInfoList,referenceId)){
82                  isValid = false;
83                  GlobalVariables.getMessageMap().putError("document.newMaintainableObject.dataObject.operationType",
84                          PopulationConstants.POPULATION_MSG_ERROR_REF_NOT_ALLOWED_IN_SOURCE_POPULATIONS, "Exclusion");
85              }
86  
87              if(populationInfoList.size() > 1 ){     //Two or more
88                  if(this.hasDuplicates(populationInfoList)){
89                      isValid = false;
90                      GlobalVariables.getMessageMap().putError("document.newMaintainableObject.dataObject.operationType",
91                              PopulationConstants.POPULATION_MSG_ERROR_NEED_TWO_DIFFERENT_POPULATIONS, "Exclusion");
92                  }
93              }
94          }
95  
96          return isValid;
97      }
98  
99      protected boolean containsPopulation(List<PopulationInfo> populationInfoList, String populationId){
100         if(populationInfoList!=null){
101             for(PopulationInfo population : populationInfoList){
102                 if(population.getId().equalsIgnoreCase(populationId)){
103                     return true;
104                 }
105             }
106         }
107         return false;
108     }
109 
110     protected boolean hasDuplicates(List<PopulationInfo> populationInfoList){
111         //Compare and make sure there is no duplication
112         for (int i= 0; i < populationInfoList.size(); i++) {
113             for (int j= 0; j < populationInfoList.size(); j++) {
114                 if (i != j && populationInfoList.get(i).getId().equals(populationInfoList.get(j).getId())){
115                     return true;
116                 }
117             }
118         }
119         return false;
120     }
121 
122     /**
123      * Validates that a wrapper has at least two unique child populations
124      * @param wrapper
125      * @param operation PoplulationType type key (union,intersection/exclusion)
126      * @return
127      */
128     protected boolean needTwoChildPopulations (PopulationWrapper wrapper, String operation){
129         boolean isValid  = true;
130         List<PopulationInfo> populationInfoList = wrapper.getChildPopulations();
131 
132         if(populationInfoList.size() > 1 ){     //Two or more
133             for (PopulationInfo populationInfo: populationInfoList) {
134                 int duplicateCntr = 0;
135                 for (PopulationInfo populationInfo1: populationInfoList) {
136                     if (populationInfo.getId().equals(populationInfo1.getId())){
137                         duplicateCntr++;
138                     }
139                     if ( duplicateCntr > 1 ) {   //No duplicates
140                         isValid = false;
141                         break;
142                     }
143                 }
144                 if ( !isValid ){
145                     break;
146                 }
147             }
148         } else {
149             isValid = false;
150         }
151         if ( !isValid ){
152             GlobalVariables.getMessageMap().putError("document.newMaintainableObject.dataObject.operationType",
153                     PopulationConstants.POPULATION_MSG_ERROR_NEED_TWO_DIFFERENT_POPULATIONS, operation);
154         }
155 
156         return isValid;
157     }
158 
159     /**
160      * Validates that the population name has not already been used
161      * @param wrapper
162      * @return if the population name is unique for the application
163      */
164     protected boolean populationNameUniqueCheck(PopulationWrapper wrapper){
165         boolean isNameUnique = true;
166 
167         String popName = wrapper.getPopulationInfo().getName();
168 
169         QueryByCriteria.Builder qbcBuilder = QueryByCriteria.Builder.create();
170         qbcBuilder.setPredicates(PredicateFactory.equal("name", popName));
171         QueryByCriteria criteria = qbcBuilder.build();
172         ContextInfo context = ContextUtils.getContextInfo();
173         try {
174             List<PopulationInfo> populationInfoList = getPopulationService().searchForPopulations(criteria, context);
175             if (populationInfoList.size()>0){
176                 putFieldError(PopulationConstants.PopulationWrapper.POPULATION_NAME, PopulationConstants.POPULATION_MSG_ERROR_NAME_IS_NOT_UNIQUE, popName);
177                 isNameUnique = false;
178             }                 
179         } catch (Exception e) {
180             throw new RuntimeException("PopulationWrapperRule exception. ", e);
181         }
182         return isNameUnique;
183     }
184 
185     private PopulationService getPopulationService() {
186         if(populationService == null) {
187             populationService = (PopulationService) GlobalResourceLoader.getService(new QName(PopulationServiceConstants.NAMESPACE, "PopulationService"));
188         }
189         return populationService;
190     }
191     
192 }