Coverage Report - org.kuali.rice.krms.impl.repository.RuleRepositoryServiceImpl
 
Classes in this File Line Coverage Branch Coverage Complexity
RuleRepositoryServiceImpl
0%
0/92
0%
0/42
3.636
 
 1  
 /**
 2  
  * Copyright 2005-2011 The Kuali Foundation
 3  
  *
 4  
  * Licensed under the Educational Community License, Version 2.0 (the "License");
 5  
  * you may not use this file except in compliance with the License.
 6  
  * You may obtain a copy of the License at
 7  
  *
 8  
  * http://www.opensource.org/licenses/ecl2.php
 9  
  *
 10  
  * Unless required by applicable law or agreed to in writing, software
 11  
  * distributed under the License is distributed on an "AS IS" BASIS,
 12  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 13  
  * See the License for the specific language governing permissions and
 14  
  * limitations under the License.
 15  
  */
 16  
 package org.kuali.rice.krms.impl.repository;
 17  
 
 18  
 import org.apache.commons.lang.StringUtils;
 19  
 import org.kuali.rice.core.api.criteria.CriteriaLookupService;
 20  
 import org.kuali.rice.core.api.criteria.GenericQueryResults;
 21  
 import org.kuali.rice.core.api.criteria.Predicate;
 22  
 import org.kuali.rice.core.api.criteria.QueryByCriteria;
 23  
 import org.kuali.rice.krad.service.BusinessObjectService;
 24  
 import org.kuali.rice.krad.service.KRADServiceLocator;
 25  
 import org.kuali.rice.krms.api.repository.RuleRepositoryService;
 26  
 import org.kuali.rice.krms.api.repository.agenda.AgendaTreeDefinition;
 27  
 import org.kuali.rice.krms.api.repository.agenda.AgendaTreeRuleEntry;
 28  
 import org.kuali.rice.krms.api.repository.agenda.AgendaTreeSubAgendaEntry;
 29  
 import org.kuali.rice.krms.api.repository.context.ContextDefinition;
 30  
 import org.kuali.rice.krms.api.repository.context.ContextSelectionCriteria;
 31  
 import org.kuali.rice.krms.api.repository.rule.RuleDefinition;
 32  
 import org.kuali.rice.krms.impl.util.KrmsImplConstants.PropertyNames;
 33  
 
 34  
 import java.util.ArrayList;
 35  
 import java.util.Collections;
 36  
 import java.util.List;
 37  
 import java.util.Map;
 38  
 
 39  
 import static org.kuali.rice.core.api.criteria.PredicateFactory.*;
 40  
 
 41  
 /**
 42  
  *
 43  
  */
 44  0
 public class RuleRepositoryServiceImpl implements RuleRepositoryService {
 45  
     protected BusinessObjectService businessObjectService;
 46  
     private CriteriaLookupService criteriaLookupService;
 47  
         
 48  
         /**
 49  
          * This overridden method ...
 50  
          * 
 51  
          * @see org.kuali.rice.krms.api.repository.RuleRepositoryService#selectContext(org.kuali.rice.krms.api.repository.context.ContextSelectionCriteria)
 52  
          */
 53  
     @Override
 54  
     public ContextDefinition selectContext(
 55  
                     ContextSelectionCriteria contextSelectionCriteria) {
 56  0
             if (contextSelectionCriteria == null){
 57  0
                     throw new IllegalArgumentException("selection criteria is null");
 58  
             }
 59  0
             if (StringUtils.isBlank(contextSelectionCriteria.getNamespaceCode())){
 60  0
                     throw new IllegalArgumentException("selection criteria namespaceCode is null or blank");
 61  
             }
 62  0
             QueryByCriteria queryCriteria = buildQuery(contextSelectionCriteria);
 63  0
         GenericQueryResults<ContextBo> results = getCriteriaLookupService().lookup(ContextBo.class, queryCriteria);
 64  
 
 65  0
             List<ContextBo> resultBos = results.getResults();
 66  
 
 67  
             //assuming 1 ?
 68  0
             ContextDefinition result = null;
 69  0
             if (resultBos != null) {
 70  0
                     if (resultBos.size() == 1) {
 71  0
                             ContextBo bo = resultBos.iterator().next();
 72  0
                             return ContextBo.to(bo);
 73  
                     }
 74  0
                     else throw new IllegalArgumentException("ambiguous qualifiers");
 75  
             }
 76  0
             return result;
 77  
     }
 78  
 
 79  
         @Override
 80  
         public AgendaTreeDefinition getAgendaTree(String agendaId) {
 81  0
                 if (StringUtils.isBlank(agendaId)){
 82  0
                     throw new IllegalArgumentException("agenda id is null or blank");
 83  
             }
 84  
                 // Get agenda items from db, then build up agenda tree structure
 85  0
                 AgendaBo agendaBo = getBusinessObjectService().findBySinglePrimaryKey(AgendaBo.class, agendaId);
 86  0
                 String agendaItemId = agendaBo.getFirstItemId();
 87  
                 
 88  
                 // walk thru the agenda items, building an agenda tree definition Builder along the way
 89  0
                 AgendaTreeDefinition.Builder myBuilder = AgendaTreeDefinition.Builder.create();
 90  0
                 myBuilder.setAgendaId( agendaId );
 91  0
                 myBuilder = walkAgendaItemTree(agendaItemId, myBuilder);
 92  
                 
 93  
                 // build the agenda tree and return it
 94  0
                 return myBuilder.build();
 95  
         }
 96  
         
 97  
         @Override
 98  
         public List<AgendaTreeDefinition> getAgendaTrees(List<String> agendaIds) {
 99  0
                 List<AgendaTreeDefinition> agendaTrees = new ArrayList<AgendaTreeDefinition>();
 100  0
                 for (String agendaId : agendaIds){
 101  0
                         agendaTrees.add( getAgendaTree(agendaId) );
 102  
                 }
 103  0
         return Collections.unmodifiableList(agendaTrees);                
 104  
         }
 105  
         
 106  
         @Override
 107  
         public RuleDefinition getRule(String ruleId) {
 108  0
                 if (StringUtils.isBlank(ruleId)){
 109  0
                         return null;                        
 110  
                 }
 111  0
                 RuleBo bo = getBusinessObjectService().findBySinglePrimaryKey(RuleBo.class, ruleId);
 112  0
                 return RuleBo.to(bo);
 113  
         }
 114  
         
 115  
         @Override
 116  
         public List<RuleDefinition> getRules(List<String> ruleIds) {
 117  0
         if (ruleIds == null) throw new IllegalArgumentException("ruleIds must not be null");
 118  
 
 119  
         // Fetch BOs
 120  0
         List<RuleBo> bos = null;
 121  0
         if (ruleIds.size() == 0) {
 122  0
             bos = Collections.emptyList();
 123  
         } else {
 124  0
             QueryByCriteria.Builder qBuilder = QueryByCriteria.Builder.create();
 125  0
             List<Predicate> pList = new ArrayList<Predicate>();
 126  0
             qBuilder.setPredicates(in("id", ruleIds.toArray()));
 127  0
             GenericQueryResults<RuleBo> results = getCriteriaLookupService().lookup(RuleBo.class, qBuilder.build());
 128  
 
 129  0
                 bos = results.getResults();
 130  
             }
 131  
 
 132  
         // Translate BOs
 133  0
         ArrayList<RuleDefinition> rules = new ArrayList<RuleDefinition>();
 134  0
         for (RuleBo bo : bos) {
 135  0
             RuleDefinition rule = RuleBo.to(bo);
 136  0
             rules.add(rule);
 137  0
         }
 138  0
         return Collections.unmodifiableList(rules);
 139  
         }
 140  
 
 141  
         /**
 142  
          * Recursive method to create AgendaTreeDefinition builder
 143  
          *         
 144  
          *  
 145  
          */
 146  
         private AgendaTreeDefinition.Builder walkAgendaItemTree(String agendaItemId, AgendaTreeDefinition.Builder builder){
 147  
                 //TODO: prevent circular, endless looping
 148  0
                 if (StringUtils.isBlank(agendaItemId)){
 149  0
                         return null;
 150  
                 }
 151  
                 // Get AgendaItem Business Object from database
 152  
                 // NOTE: if we read agendaItem one at a time from db.   Could consider linking in OJB and getting all at once
 153  0
                 AgendaItemBo agendaItemBo = getBusinessObjectService().findBySinglePrimaryKey(AgendaItemBo.class, agendaItemId);
 154  
                 
 155  
                 // If Rule  
 156  
                 // TODO: validate that only either rule or subagenda, not both
 157  0
                 if (!StringUtils.isBlank( agendaItemBo.getRuleId() )){
 158  
                         // setup new rule entry builder
 159  0
                         AgendaTreeRuleEntry.Builder ruleEntryBuilder = AgendaTreeRuleEntry.Builder
 160  
                                         .create(agendaItemBo.getId(), agendaItemBo.getRuleId());
 161  0
                         ruleEntryBuilder.setRuleId( agendaItemBo.getRuleId() );
 162  0
                         ruleEntryBuilder.setAgendaItemId( agendaItemBo.getId() );
 163  0
                         if (agendaItemBo.getWhenTrueId() != null){
 164  
                                 // Go follow the true branch, creating AgendaTreeDefinintion Builder for the
 165  
                                 // true branch level
 166  0
                                 AgendaTreeDefinition.Builder myBuilder = AgendaTreeDefinition.Builder.create();
 167  0
                                 myBuilder.setAgendaId( agendaItemBo.getAgendaId() );
 168  0
                                 ruleEntryBuilder.setIfTrue( walkAgendaItemTree(agendaItemBo.getWhenTrueId(),myBuilder));
 169  
                         }
 170  0
                         if (agendaItemBo.getWhenFalseId() != null){
 171  
                                 // Go follow the false branch, creating AgendaTreeDefinintion Builder 
 172  0
                                 AgendaTreeDefinition.Builder myBuilder = AgendaTreeDefinition.Builder.create();
 173  0
                                 myBuilder.setAgendaId( agendaItemBo.getAgendaId() );
 174  0
                                 ruleEntryBuilder.setIfFalse( walkAgendaItemTree(agendaItemBo.getWhenFalseId(), myBuilder));
 175  
                         }
 176  
                         // Build the Rule Entry and add it to the AgendaTreeDefinition builder
 177  0
                         builder.addRuleEntry( ruleEntryBuilder.build() );
 178  
                 }
 179  
                 // if SubAgenda and a sub agenda tree entry
 180  0
                 if (!StringUtils.isBlank(agendaItemBo.getSubAgendaId())) {
 181  0
                         AgendaTreeSubAgendaEntry.Builder subAgendaEntryBuilder = 
 182  
                                 AgendaTreeSubAgendaEntry.Builder.create(agendaItemBo.getId(), agendaItemBo.getSubAgendaId());
 183  0
                         builder.addSubAgendaEntry( subAgendaEntryBuilder.build() );
 184  
                         }
 185  
 
 186  
                 // if this agenda item has an "After Id", follow that branch
 187  0
                 if (!StringUtils.isBlank( agendaItemBo.getAlwaysId() )){
 188  0
                         builder = walkAgendaItemTree( agendaItemBo.getAlwaysId(), builder);
 189  
                         
 190  
                 }
 191  0
                 return builder;
 192  
         }
 193  
         
 194  
         /**
 195  
          * 
 196  
          * This method converts a {@link ContextSelectionCriteria} object into a
 197  
          * {@link QueryByCriteria} object with the proper predicates for AttributeBo properties.
 198  
          * 
 199  
          * @param selectionCriteria
 200  
          * @return 
 201  
          */
 202  
         private QueryByCriteria buildQuery( ContextSelectionCriteria selectionCriteria ){
 203  
                 Predicate p;
 204  0
                 QueryByCriteria.Builder qBuilder = QueryByCriteria.Builder.create();
 205  0
             List<Predicate> pList = new ArrayList<Predicate>();
 206  0
             if (selectionCriteria.getNamespaceCode() != null){
 207  0
                     p = equal(PropertyNames.Context.NAMESPACE, selectionCriteria.getNamespaceCode());
 208  0
                     pList.add(p);
 209  
             }
 210  0
             if (selectionCriteria.getName() != null){
 211  0
                     p = equal(PropertyNames.Context.NAME, selectionCriteria.getName());
 212  0
                     pList.add(p);
 213  
             }
 214  0
             if (selectionCriteria.getContextQualifiers() != null){
 215  0
                     for (Map.Entry<String, String> entry : selectionCriteria.getContextQualifiers().entrySet()){
 216  0
                             p = and(equal(PropertyNames.Context.ATTRIBUTE_BOS
 217  
                                             + "." + PropertyNames.BaseAttribute.ATTRIBUTE_DEFINITION
 218  
                                             + "." + PropertyNames.KrmsAttributeDefinition.NAME, entry.getKey()),
 219  
                                     equal(PropertyNames.Context.ATTRIBUTE_BOS
 220  
                                             + "." + PropertyNames.BaseAttribute.VALUE, entry.getValue()));
 221  0
                             pList.add(p);
 222  
                     }
 223  
             }
 224  0
              Predicate[] preds = new Predicate[pList.size()];
 225  0
              pList.toArray(preds);
 226  0
             qBuilder.setPredicates(and(preds)); 
 227  0
                 return qBuilder.build();
 228  
         }
 229  
 
 230  
         /**
 231  
      * Sets the businessObjectService property.
 232  
      *
 233  
      * @param businessObjectService The businessObjectService to set.
 234  
      */
 235  
     public void setBusinessObjectService(final BusinessObjectService businessObjectService) {
 236  0
         this.businessObjectService = businessObjectService;
 237  0
     }
 238  
 
 239  
     protected BusinessObjectService getBusinessObjectService() {
 240  0
                 if ( businessObjectService == null ) {
 241  
             // TODO: inject this instead
 242  0
                         businessObjectService = KRADServiceLocator.getBusinessObjectService();
 243  
                 }
 244  0
                 return businessObjectService;
 245  
         }
 246  
     
 247  
     /**
 248  
      * Sets the criteriaLookupService attribute value.
 249  
      *
 250  
      * @param criteriaLookupService The criteriaLookupService to set.
 251  
      */
 252  
     public void setCriteriaLookupService(final CriteriaLookupService criteriaLookupService) {
 253  0
         this.criteriaLookupService = criteriaLookupService;
 254  0
     }
 255  
 
 256  
     protected CriteriaLookupService getCriteriaLookupService() {
 257  0
         return criteriaLookupService;
 258  
     }
 259  
     
 260  
 }