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