View Javadoc

1   /*
2    * To change this template, choose Tools | Templates
3    * and open the template in the editor.
4    */
5   package org.kuali.rice.krms.impl.repository;
6   
7   import java.util.ArrayList;
8   import java.util.LinkedHashMap;
9   import java.util.List;
10  import java.util.Map;
11  
12  import org.kuali.rice.core.api.exception.RiceIllegalArgumentException;
13  import org.kuali.rice.krms.api.repository.NaturalLanguageTree;
14  import org.kuali.rice.krms.api.repository.RuleManagementService;
15  import org.kuali.rice.krms.api.repository.TranslateBusinessMethods;
16  import org.kuali.rice.krms.api.repository.agenda.AgendaDefinition;
17  import org.kuali.rice.krms.api.repository.agenda.AgendaItemDefinition;
18  import org.kuali.rice.krms.api.repository.language.NaturalLanguageTemplate;
19  import org.kuali.rice.krms.api.repository.language.NaturalLanguageTemplaterContract;
20  import org.kuali.rice.krms.api.repository.proposition.PropositionDefinition;
21  import org.kuali.rice.krms.api.repository.proposition.PropositionParameter;
22  import org.kuali.rice.krms.api.repository.proposition.PropositionParameterType;
23  import org.kuali.rice.krms.api.repository.proposition.PropositionType;
24  import org.kuali.rice.krms.api.repository.rule.RuleDefinition;
25  import org.kuali.rice.krms.api.repository.term.TermDefinition;
26  import org.kuali.rice.krms.api.repository.term.TermParameterDefinition;
27  import org.kuali.rice.krms.api.repository.term.TermRepositoryService;
28  
29  /**
30   * @author nwright
31   */
32  public class TranslationUtility implements TranslateBusinessMethods {
33  
34      private RuleManagementService ruleManagementService;
35      private NaturalLanguageTemplaterContract templater;
36  
37      public TranslationUtility(RuleManagementService ruleManagementService,
38              NaturalLanguageTemplaterContract templater) {
39          this.ruleManagementService = ruleManagementService;
40          this.templater = templater;
41      }
42  
43      public RuleManagementService getRuleManagementService() {
44          return ruleManagementService;
45      }
46  
47      public void setRuleManagementService(RuleManagementService ruleManagementService) {
48          this.ruleManagementService = ruleManagementService;
49      }
50  
51      public NaturalLanguageTemplaterContract getTemplater() {
52          return templater;
53      }
54  
55      public void setTemplater(NaturalLanguageTemplaterContract templater) {
56          this.templater = templater;
57      }
58  
59      @Override
60      public String translateNaturalLanguageForObject(String naturalLanguageUsageId, String typeId, String krmsObjectId, String languageCode)
61              throws RiceIllegalArgumentException {
62  
63          PropositionDefinition proposition = null;
64          // TODO: find out what RICE intended for this typeId? Was it supposed to be the Simple Class name?
65          if (typeId.equals("proposition")) {
66              proposition = this.ruleManagementService.getProposition(krmsObjectId);
67              if (proposition == null) {
68                  throw new RiceIllegalArgumentException(krmsObjectId + " is not an Id for a proposition");
69              }
70          } else if (typeId.equals("agenda")) {
71              AgendaDefinition agenda = this.ruleManagementService.getAgenda(krmsObjectId);
72              if (agenda == null) {
73                  throw new RiceIllegalArgumentException(krmsObjectId + " is not an Id for an agenda");
74              }
75              if (agenda.getFirstItemId() == null) {
76                  throw new RiceIllegalArgumentException("Agenda has no first item");
77              }
78              AgendaItemDefinition item = this.ruleManagementService.getAgendaItem(agenda.getFirstItemId());
79              if (item.getRuleId() == null) {
80                  throw new RiceIllegalArgumentException("Only simple agenda's composed of one item that holds a rule is supported at this time");
81              }
82              RuleDefinition rule = this.ruleManagementService.getRule(item.getRuleId());
83              proposition = rule.getProposition();
84              if (proposition == null) {
85                  throw new RiceIllegalArgumentException("The agenda's rule has a proposition that is null");
86              }
87          }
88          String propositionTypeId = proposition.getTypeId();
89          NaturalLanguageTemplate naturalLanguageTemplate =
90                  this.ruleManagementService.findNaturalLanguageTemplateByLanguageCodeTypeIdAndNluId(languageCode,
91                  propositionTypeId,
92                  naturalLanguageUsageId);
93          if (naturalLanguageTemplate == null) {
94              throw new RiceIllegalArgumentException("no template found for " + languageCode
95                      + " " + typeId
96                      + " " + naturalLanguageUsageId);
97          }
98          return this.translateNaturalLanguageForProposition(naturalLanguageUsageId, proposition, languageCode);
99      }
100 
101     @Override
102     public String translateNaturalLanguageForProposition(String naturalLanguageUsageId,
103             PropositionDefinition proposition, String languageCode)
104             throws RiceIllegalArgumentException {
105         NaturalLanguageTemplate naturalLanguageTemplate =
106                 this.ruleManagementService.findNaturalLanguageTemplateByLanguageCodeTypeIdAndNluId(languageCode,
107                 proposition.getTypeId(), naturalLanguageUsageId);
108         if (naturalLanguageTemplate == null) {
109             throw new RiceIllegalArgumentException(languageCode + "." + proposition.getTypeId() + "." + naturalLanguageUsageId);
110         }
111         Map<String, Object> contextMap;
112         if (proposition.getPropositionTypeCode().equals(PropositionType.SIMPLE.getCode())) {
113             contextMap = this.buildSimplePropositionContextMap(proposition);
114         } else {
115             contextMap = this.buildCompoundPropositionContextMap(null, proposition, null);
116         }
117         return templater.translate(naturalLanguageTemplate, contextMap);
118     }
119 
120     @Override
121     public NaturalLanguageTree translateNaturalLanguageTreeForProposition(String naturalLanguageUsageId,
122             PropositionDefinition proposition,
123             String languageCode) throws RiceIllegalArgumentException {
124         NaturalLanguageTemplate naturalLanguageTemplate = null;
125         //Continue if typeid is null, some children may not be initialized yet.
126         if (proposition.getTypeId() != null) {
127             naturalLanguageTemplate = this.ruleManagementService.findNaturalLanguageTemplateByLanguageCodeTypeIdAndNluId(languageCode,
128                     proposition.getTypeId(), naturalLanguageUsageId);
129             if (naturalLanguageTemplate == null) {
130                 throw new RiceIllegalArgumentException(languageCode + "." + proposition.getTypeId() + "." + naturalLanguageUsageId);
131             }
132         }
133 
134         if (proposition.getPropositionTypeCode().equals(PropositionType.SIMPLE.getCode())) {
135             NaturalLanguageTree.Builder tree = NaturalLanguageTree.Builder.create();
136             Map<String, Object> contextMap = this.buildSimplePropositionContextMap(proposition);
137             String naturalLanguage = templater.translate(naturalLanguageTemplate, contextMap);
138             tree.setNaturalLanguage(naturalLanguage);
139             return tree.build();
140         }
141         if (proposition.getPropositionTypeCode().equals(PropositionType.COMPOUND.getCode())) {
142             NaturalLanguageTree.Builder tree = NaturalLanguageTree.Builder.create();
143             Map<String, Object> contextMap = this.buildCompoundPropositionContextMap(naturalLanguageUsageId, proposition, languageCode);
144             String naturalLanguage = templater.translate(naturalLanguageTemplate, contextMap);
145             tree.setNaturalLanguage(naturalLanguage);
146 
147             //Null check because newly created compound propositions should also be translateable.
148             if(proposition.getCompoundComponents()!=null){
149                 List<NaturalLanguageTree> children = new ArrayList<NaturalLanguageTree>();
150                 for (PropositionDefinition child : proposition.getCompoundComponents()) {
151                     children.add(this.translateNaturalLanguageTreeForProposition(naturalLanguageUsageId, child, languageCode));
152                 }
153                 tree.setChildren(children);
154             }
155 
156             return tree.build();
157         }
158         throw new RiceIllegalArgumentException("Unknown proposition type: " + proposition.getPropositionTypeCode());
159     }
160 
161     protected Map<String, Object> buildSimplePropositionContextMap(PropositionDefinition proposition) {
162         if (!proposition.getPropositionTypeCode().equals(PropositionType.SIMPLE.getCode())) {
163             throw new RiceIllegalArgumentException("proposition is not simple " + proposition.getPropositionTypeCode() + " " + proposition.getId() + proposition.getDescription());
164         }
165         Map<String, Object> contextMap = new LinkedHashMap<String, Object>();
166         for (PropositionParameter param : proposition.getParameters()) {
167             if (param.getParameterType().equals(PropositionParameterType.TERM.getCode())) {
168                 if (param.getTermValue() != null) {
169                     for (TermParameterDefinition termParam : param.getTermValue().getParameters()) {
170                         contextMap.put(termParam.getName(), termParam.getValue());
171                     }
172                 } else {
173                     contextMap.put(param.getParameterType(), param.getValue());
174                 }
175             } else {
176                 contextMap.put(param.getParameterType(), param.getValue());
177             }
178         }
179         return contextMap;
180     }
181     public static final String COMPOUND_COMPONENTS = "compoundComponent";
182 
183     protected Map<String, Object> buildCompoundPropositionContextMap(String naturalLanguageUsageId, PropositionDefinition proposition, String languageCode) {
184         if (!proposition.getPropositionTypeCode().equals(PropositionType.COMPOUND.getCode())) {
185             throw new RiceIllegalArgumentException("proposition us not compound " + proposition.getPropositionTypeCode() + " " + proposition.getId() + proposition.getDescription());
186         }
187         Map<String, Object> contextMap = new LinkedHashMap<String, Object>();
188         /*List<String> children = new ArrayList<String>();
189          for (PropositionDefinition param : proposition.getCompoundComponents()) {
190          children.add(this.translateNaturalLanguageForProposition(naturalLanguageUsageId, proposition, languageCode));
191          }
192          contextMap.put(COMPOUND_COMPONENTS, children);*/
193         return contextMap;
194     }
195 
196     protected String translateCompoundProposition(PropositionDefinition proposition, String naturalLanguageUsageId, String languageCode)
197             throws RiceIllegalArgumentException {
198         if (!proposition.getPropositionTypeCode().equals(PropositionType.COMPOUND.getCode())) {
199             throw new RiceIllegalArgumentException("proposition us not compound " + proposition.getPropositionTypeCode() + " " + proposition.getId() + proposition.getDescription());
200         }
201         String compoundNaturalLanguageTypeId = this.calcCompoundNaturalLanguageTypeId(proposition.getCompoundOpCode());
202         // TODO: make sure we cache the AND and OR templates
203         NaturalLanguageTemplate template = this.ruleManagementService.findNaturalLanguageTemplateByLanguageCodeTypeIdAndNluId(languageCode,
204                 compoundNaturalLanguageTypeId, naturalLanguageUsageId);
205         Map<String, Object> contextMap = this.buildCompoundPropositionContextMap(naturalLanguageUsageId, proposition, languageCode);
206         return this.templater.translate(template, contextMap);
207 
208     }
209 
210     protected String calcCompoundNaturalLanguageTypeId(String compoundOpCode) throws RiceIllegalArgumentException {
211         if (compoundOpCode.equals("a")) {
212             return "kuali.compound.proposition.op.code." + "and";
213         }
214         if (compoundOpCode.equals("o")) {
215             return "kuali.compound.proposition.op.code." + "or";
216         }
217         throw new RiceIllegalArgumentException("unsupported compound op code " + compoundOpCode);
218     }
219 
220     protected String translateSimpleProposition(NaturalLanguageTemplate naturalLanguageTemplate,
221             PropositionDefinition proposition)
222             throws RiceIllegalArgumentException {
223         if (!proposition.getPropositionTypeCode().equals(PropositionType.SIMPLE.getCode())) {
224             throw new RiceIllegalArgumentException("proposition not simple " + proposition.getPropositionTypeCode() + " " + proposition.getId() + proposition.getDescription());
225         }
226         Map<String, Object> contextMap = this.buildSimplePropositionContextMap(proposition);
227         return templater.translate(naturalLanguageTemplate, contextMap);
228     }
229 }