Coverage Report - org.kuali.rice.krms.impl.provider.repository.RepositoryToEngineTranslatorImpl
 
Classes in this File Line Coverage Branch Coverage Complexity
RepositoryToEngineTranslatorImpl
0%
0/113
0%
0/62
3
 
 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.provider.repository;
 17  
 
 18  
 import java.util.ArrayList;
 19  
 import java.util.HashMap;
 20  
 import java.util.List;
 21  
 import java.util.Map;
 22  
 
 23  
 import org.kuali.rice.krms.api.engine.TermResolver;
 24  
 import org.kuali.rice.krms.api.repository.RepositoryDataException;
 25  
 import org.kuali.rice.krms.api.repository.RuleRepositoryService;
 26  
 import org.kuali.rice.krms.api.repository.action.ActionDefinition;
 27  
 import org.kuali.rice.krms.api.repository.agenda.AgendaDefinition;
 28  
 import org.kuali.rice.krms.api.repository.agenda.AgendaTreeDefinition;
 29  
 import org.kuali.rice.krms.api.repository.agenda.AgendaTreeEntryDefinition;
 30  
 import org.kuali.rice.krms.api.repository.agenda.AgendaTreeRuleEntry;
 31  
 import org.kuali.rice.krms.api.repository.agenda.AgendaTreeSubAgendaEntry;
 32  
 import org.kuali.rice.krms.api.repository.context.ContextDefinition;
 33  
 import org.kuali.rice.krms.api.repository.proposition.PropositionDefinition;
 34  
 import org.kuali.rice.krms.api.repository.rule.RuleDefinition;
 35  
 import org.kuali.rice.krms.api.repository.term.TermResolverDefinition;
 36  
 import org.kuali.rice.krms.api.repository.type.KrmsTypeRepositoryService;
 37  
 import org.kuali.rice.krms.framework.engine.Action;
 38  
 import org.kuali.rice.krms.framework.engine.Agenda;
 39  
 import org.kuali.rice.krms.framework.engine.AgendaTree;
 40  
 import org.kuali.rice.krms.framework.engine.AgendaTreeEntry;
 41  
 import org.kuali.rice.krms.framework.engine.BasicAgenda;
 42  
 import org.kuali.rice.krms.framework.engine.BasicAgendaTree;
 43  
 import org.kuali.rice.krms.framework.engine.BasicAgendaTreeEntry;
 44  
 import org.kuali.rice.krms.framework.engine.BasicContext;
 45  
 import org.kuali.rice.krms.framework.engine.Context;
 46  
 import org.kuali.rice.krms.framework.engine.Proposition;
 47  
 import org.kuali.rice.krms.framework.engine.Rule;
 48  
 import org.kuali.rice.krms.framework.engine.SubAgenda;
 49  
 import org.kuali.rice.krms.framework.type.TermResolverTypeService;
 50  
 import org.kuali.rice.krms.impl.repository.TermBoService;
 51  
 import org.kuali.rice.krms.impl.type.KrmsTypeResolver;
 52  
 import org.springframework.util.CollectionUtils;
 53  
 
 54  
 /**
 55  
  * TODO... 
 56  
  * 
 57  
  * @author Kuali Rice Team (rice.collab@kuali.org)
 58  
  *
 59  
  */
 60  0
 public class RepositoryToEngineTranslatorImpl implements RepositoryToEngineTranslator {
 61  
 
 62  
         private RuleRepositoryService ruleRepositoryService;
 63  
         private KrmsTypeRepositoryService typeRepositoryService;
 64  
         private KrmsTypeResolver typeResolver;
 65  
         private TermBoService termBoService;
 66  
         
 67  
         @Override
 68  
         public Context translateContextDefinition(ContextDefinition contextDefinition) {
 69  0
                 if (contextDefinition == null) {
 70  0
                         return null;
 71  
                 }
 72  0
                 List<Agenda> agendas = new ArrayList<Agenda>();
 73  0
                 for (AgendaDefinition agendaDefinition : contextDefinition.getAgendas()) {
 74  0
                         Agenda agenda = translateAgendaDefinition(agendaDefinition);
 75  0
                         agendas.add(agenda);
 76  0
                 }
 77  
                 
 78  0
                 List<TermResolverDefinition> termResolverDefs = 
 79  
                         termBoService.getTermResolversByNamespace(contextDefinition.getNamespace());
 80  
                 
 81  0
                 List<TermResolver<?>> termResolvers = new ArrayList<TermResolver<?>>();
 82  
 
 83  0
                 if (!CollectionUtils.isEmpty(termResolverDefs)) for (TermResolverDefinition termResolverDef : termResolverDefs) {
 84  0
                         if (termResolverDef != null) {
 85  0
                                 TermResolver<?> termResolver = translateTermResolver(termResolverDef);
 86  0
                                 if (termResolver != null) termResolvers.add(termResolver);
 87  0
                         }
 88  
                 }
 89  
                 
 90  0
                 return new BasicContext(agendas, termResolvers); 
 91  
         }
 92  
 
 93  
         /**
 94  
          * This method translates a {@link TermResolverDefinition} into a {@link TermResolver}
 95  
          * 
 96  
          * @param termResolverDef
 97  
          * @return
 98  
          */
 99  
         private TermResolver<?> translateTermResolver(TermResolverDefinition termResolverDef) {
 100  0
                 if (termResolverDef == null) {
 101  0
                         throw new IllegalArgumentException("termResolverDef must not be null");
 102  
                 }
 103  0
                 TermResolverTypeService termResolverTypeService = 
 104  
                         typeResolver.getTermResolverTypeService(termResolverDef);
 105  
                 
 106  0
                 TermResolver<?> termResolver = termResolverTypeService.loadTermResolver(termResolverDef);
 107  
                 // TODO: log warning when termResolver comes back null? or throw exception?
 108  0
                 return termResolver;
 109  
         }
 110  
         
 111  
         @Override
 112  
         public Agenda translateAgendaDefinition(AgendaDefinition agendaDefinition) {
 113  
 
 114  
             // TODO: this limits an agenda to a single event.  Is that good enough?
 115  0
                 return new BasicAgenda(agendaDefinition.getAttributes(), new LazyAgendaTree(agendaDefinition, this));
 116  
         }
 117  
                 
 118  
         @Override
 119  
         public AgendaTree translateAgendaDefinitionToAgendaTree(AgendaDefinition agendaDefinition) {
 120  0
                 AgendaTreeDefinition agendaTreeDefinition = ruleRepositoryService.getAgendaTree(agendaDefinition.getId());
 121  0
                 return translateAgendaTreeDefinition(agendaTreeDefinition);
 122  
         }
 123  
         
 124  
         @Override
 125  
         public AgendaTree translateAgendaTreeDefinition(AgendaTreeDefinition agendaTreeDefinition) {
 126  
         
 127  0
                 List<String> ruleIds = new ArrayList<String>();
 128  0
                 List<String> subAgendaIds = new ArrayList<String>();
 129  0
                 for (AgendaTreeEntryDefinition entryDefinition : agendaTreeDefinition.getEntries()) {
 130  0
                         if (entryDefinition instanceof AgendaTreeRuleEntry) {
 131  0
                                 ruleIds.add(((AgendaTreeRuleEntry)entryDefinition).getRuleId());
 132  0
                         } else if (entryDefinition instanceof AgendaTreeSubAgendaEntry) {
 133  0
                                 subAgendaIds.add(((AgendaTreeSubAgendaEntry)entryDefinition).getSubAgendaId());
 134  
                         } else {
 135  0
                                 throw new IllegalStateException("Encountered invalid agenda tree entry definition class, did not understand type: " + entryDefinition);
 136  
                         }
 137  
                 }
 138  
                 
 139  0
                 Map<String, Rule> rules = loadRules(ruleIds);
 140  0
                 Map<String, SubAgenda> subAgendas = loadSubAgendas(subAgendaIds);
 141  
                 
 142  0
                 List<AgendaTreeEntry> entries = new ArrayList<AgendaTreeEntry>();
 143  
         
 144  0
                 for (AgendaTreeEntryDefinition entryDefinition : agendaTreeDefinition.getEntries()) {
 145  0
                         if (entryDefinition instanceof AgendaTreeRuleEntry) {
 146  0
                                 AgendaTreeRuleEntry ruleEntry = (AgendaTreeRuleEntry)entryDefinition;
 147  0
                                 AgendaTree ifTrue = null;
 148  0
                                 AgendaTree ifFalse = null;
 149  0
                                 if (ruleEntry.getIfTrue() != null) {
 150  0
                                         ifTrue = translateAgendaTreeDefinition(ruleEntry.getIfTrue());
 151  
                                 }
 152  0
                                 if (ruleEntry.getIfTrue() != null) {
 153  0
                                         ifFalse = translateAgendaTreeDefinition(ruleEntry.getIfFalse());
 154  
                                 }
 155  0
                                 Rule rule = rules.get(ruleEntry.getRuleId());
 156  0
                                 if (rule == null) {
 157  0
                                         throw new IllegalStateException("Failed to locate rule with id: " + ruleEntry.getRuleId());
 158  
                                 }
 159  0
                                 BasicAgendaTreeEntry agendaTreeEntry = new BasicAgendaTreeEntry(rule, ifTrue, ifFalse);
 160  0
                                 entries.add(agendaTreeEntry);
 161  0
                         } else if (entryDefinition instanceof AgendaTreeSubAgendaEntry) {
 162  0
                                 AgendaTreeSubAgendaEntry subAgendaEntry = (AgendaTreeSubAgendaEntry)entryDefinition;
 163  0
                                 SubAgenda subAgenda = subAgendas.get(subAgendaEntry.getSubAgendaId());
 164  0
                                 if (subAgenda == null) {
 165  0
                                         throw new IllegalStateException("Failed to locate sub agenda with id: " + subAgendaEntry.getSubAgendaId());
 166  
                                 }
 167  0
                                 BasicAgendaTreeEntry agendaTreeEntry = new BasicAgendaTreeEntry(subAgenda, null, null);
 168  0
                                 entries.add(agendaTreeEntry);
 169  0
                         } else {
 170  0
                                 throw new IllegalStateException("Encountered invalid agenda tree entry class, did not understand type: " + entryDefinition);
 171  
                         }
 172  
                 }
 173  0
                 return new BasicAgendaTree(entries);
 174  
         }
 175  
         
 176  
         protected Map<String, Rule> loadRules(List<String> ruleIds) {
 177  0
                 List<RuleDefinition> ruleDefinitions = ruleRepositoryService.getRules(ruleIds);
 178  0
                 validateRuleDefinitions(ruleIds, ruleDefinitions);
 179  0
                 Map<String, Rule> rules = new HashMap<String, Rule>();
 180  0
                 for (RuleDefinition ruleDefinition : ruleDefinitions) {
 181  0
                         rules.put(ruleDefinition.getId(), translateRuleDefinition(ruleDefinition));
 182  
                 }
 183  0
                 return rules;
 184  
         }
 185  
         
 186  
         /**
 187  
          * Ensures that there is a rule definition for every rule id in the original list.
 188  
          */
 189  
         private void validateRuleDefinitions(List<String> ruleIds, List<RuleDefinition> ruleDefinitions) {
 190  0
                 if (ruleIds.size() != ruleDefinitions.size()) {
 191  0
                         Map<String, RuleDefinition> indexedRuleDefinitions = indexRuleDefinitions(ruleDefinitions);
 192  0
                         for (String ruleId : ruleIds) {
 193  0
                                 if (!indexedRuleDefinitions.containsKey(ruleId)) {
 194  0
                                         throw new RepositoryDataException("Failed to locate a rule with id '" + ruleId + "' in the repository.");
 195  
                                 }
 196  
                         }
 197  
                 }
 198  0
         }
 199  
         
 200  
         private Map<String, RuleDefinition> indexRuleDefinitions(List<RuleDefinition> ruleDefinitions) {
 201  0
                 Map<String, RuleDefinition> ruleDefinitionMap = new HashMap<String, RuleDefinition>();
 202  0
                 for (RuleDefinition ruleDefinition : ruleDefinitions) {
 203  0
                         ruleDefinitionMap.put(ruleDefinition.getId(), ruleDefinition);
 204  
                 }
 205  0
                 return ruleDefinitionMap;
 206  
         }
 207  
         
 208  
         protected Map<String, SubAgenda> loadSubAgendas(List<String> subAgendaIds) {
 209  0
                 List<AgendaTreeDefinition> subAgendaDefinitions = ruleRepositoryService.getAgendaTrees(subAgendaIds);
 210  0
                 validateSubAgendaDefinitions(subAgendaIds, subAgendaDefinitions);
 211  0
                 Map<String, SubAgenda> subAgendas = new HashMap<String, SubAgenda>();
 212  0
                 for (AgendaTreeDefinition subAgendaDefinition : subAgendaDefinitions) {
 213  0
                         subAgendas.put(subAgendaDefinition.getAgendaId(), translateAgendaTreeDefinitionToSubAgenda(subAgendaDefinition));
 214  
                 }
 215  0
                 return subAgendas;
 216  
         }
 217  
         
 218  
         /**
 219  
          * Ensures that there is a rule definition for every rule id in the original list.
 220  
          */
 221  
         private void validateSubAgendaDefinitions(List<String> subAgendaIds, List<AgendaTreeDefinition> subAgendaDefinitions) {
 222  0
                 if (subAgendaIds.size() != subAgendaDefinitions.size()) {
 223  0
                         Map<String, AgendaTreeDefinition> indexedSubAgendaDefinitions = indexSubAgendaDefinitions(subAgendaDefinitions);
 224  0
                         for (String subAgendaId : subAgendaIds) {
 225  0
                                 if (!indexedSubAgendaDefinitions.containsKey(subAgendaId)) {
 226  0
                                         throw new RepositoryDataException("Failed to locate an agenda with id '" + subAgendaId + "' in the repository.");
 227  
                                 }
 228  
                         }
 229  
                 }
 230  0
         }
 231  
         
 232  
         private Map<String, AgendaTreeDefinition> indexSubAgendaDefinitions(List<AgendaTreeDefinition> subAgendaDefinitions) {
 233  0
                 Map<String, AgendaTreeDefinition> subAgendaDefinitionMap = new HashMap<String, AgendaTreeDefinition>();
 234  0
                 for (AgendaTreeDefinition subAgendaDefinition : subAgendaDefinitions) {
 235  0
                         subAgendaDefinitionMap.put(subAgendaDefinition.getAgendaId(), subAgendaDefinition);
 236  
                 }
 237  0
                 return subAgendaDefinitionMap;
 238  
         }
 239  
         
 240  
         @Override
 241  
         public Rule translateRuleDefinition(RuleDefinition ruleDefinition) {
 242  0
                 List<Action> actions = new ArrayList<Action>();
 243  0
                 if (ruleDefinition.getActions() != null) {
 244  0
                         for (ActionDefinition actionDefinition : ruleDefinition.getActions()) {
 245  0
                                 actions.add(translateActionDefinition(actionDefinition));
 246  
                         }
 247  
                 }
 248  0
         return new LazyRule(ruleDefinition, typeResolver);
 249  
         }
 250  
         
 251  
         @Override
 252  
         public Proposition translatePropositionDefinition(PropositionDefinition propositionDefinition) {
 253  0
                 return new LazyProposition(propositionDefinition, typeResolver);
 254  
         }
 255  
         
 256  
         @Override
 257  
         public Action translateActionDefinition(ActionDefinition actionDefinition) {
 258  0
                 if (actionDefinition.getTypeId() == null) {
 259  0
                         throw new RepositoryDataException("Given ActionDefinition does not have a typeId, actionId was: " + actionDefinition.getId());
 260  
                 }
 261  0
                 return new LazyAction(actionDefinition, typeResolver);
 262  
         }
 263  
 
 264  
     @Override
 265  
     public List<Action> translateActionDefinitions(List<ActionDefinition> actionDefinitions) {
 266  0
         List<Action> actions = new ArrayList<Action>();
 267  0
         for (ActionDefinition actionDefinition : actionDefinitions) {
 268  0
             actions.add(translateActionDefinition(actionDefinition));
 269  
         }
 270  0
         return actions;
 271  
     }
 272  
 
 273  
     @Override
 274  
         public SubAgenda translateAgendaTreeDefinitionToSubAgenda(AgendaTreeDefinition subAgendaDefinition) {
 275  0
                 return new SubAgenda(translateAgendaTreeDefinition(subAgendaDefinition));
 276  
         }
 277  
         
 278  
         /**
 279  
          * @param ruleRepositoryService the ruleRepositoryService to set
 280  
          */
 281  
         public void setRuleRepositoryService(
 282  
                         RuleRepositoryService ruleRepositoryService) {
 283  0
                 this.ruleRepositoryService = ruleRepositoryService;
 284  0
         }
 285  
         
 286  
         /**
 287  
          * @param termBoService the termBoService to set
 288  
          */
 289  
         public void setTermBoService(TermBoService termBoService) {
 290  0
                 this.termBoService = termBoService;
 291  0
         }
 292  
         
 293  
         /**
 294  
          * @param typeRepositoryService the typeRepositoryService to set
 295  
          */
 296  
         public void setTypeRepositoryService(
 297  
                         KrmsTypeRepositoryService typeRepositoryService) {
 298  0
                 this.typeRepositoryService = typeRepositoryService;
 299  0
         }
 300  
         
 301  
         /**
 302  
          * @param typeResolver the typeResolver to set
 303  
          */
 304  
         public void setTypeResolver(KrmsTypeResolver typeResolver) {
 305  0
                 this.typeResolver = typeResolver;
 306  0
         }
 307  
 
 308  
 }