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