001 /*
002 * To change this template, choose Tools | Templates
003 * and open the template in the editor.
004 */
005 package org.kuali.rice.krms.impl.repository;
006
007 import java.util.ArrayList;
008 import java.util.LinkedHashMap;
009 import java.util.List;
010 import java.util.Map;
011
012 import org.kuali.rice.core.api.exception.RiceIllegalArgumentException;
013 import org.kuali.rice.krms.api.repository.NaturalLanguageTree;
014 import org.kuali.rice.krms.api.repository.RuleManagementService;
015 import org.kuali.rice.krms.api.repository.TranslateBusinessMethods;
016 import org.kuali.rice.krms.api.repository.agenda.AgendaDefinition;
017 import org.kuali.rice.krms.api.repository.agenda.AgendaItemDefinition;
018 import org.kuali.rice.krms.api.repository.language.NaturalLanguageTemplate;
019 import org.kuali.rice.krms.api.repository.language.NaturalLanguageTemplaterContract;
020 import org.kuali.rice.krms.api.repository.proposition.PropositionDefinition;
021 import org.kuali.rice.krms.api.repository.proposition.PropositionParameter;
022 import org.kuali.rice.krms.api.repository.proposition.PropositionParameterType;
023 import org.kuali.rice.krms.api.repository.proposition.PropositionType;
024 import org.kuali.rice.krms.api.repository.rule.RuleDefinition;
025 import org.kuali.rice.krms.api.repository.term.TermDefinition;
026 import org.kuali.rice.krms.api.repository.term.TermParameterDefinition;
027 import org.kuali.rice.krms.api.repository.term.TermRepositoryService;
028
029 /**
030 * @author nwright
031 */
032 public class TranslationUtility implements TranslateBusinessMethods {
033
034 private RuleManagementService ruleManagementService;
035 private NaturalLanguageTemplaterContract templater;
036
037 public TranslationUtility(RuleManagementService ruleManagementService,
038 NaturalLanguageTemplaterContract templater) {
039 this.ruleManagementService = ruleManagementService;
040 this.templater = templater;
041 }
042
043 public RuleManagementService getRuleManagementService() {
044 return ruleManagementService;
045 }
046
047 public void setRuleManagementService(RuleManagementService ruleManagementService) {
048 this.ruleManagementService = ruleManagementService;
049 }
050
051 public NaturalLanguageTemplaterContract getTemplater() {
052 return templater;
053 }
054
055 public void setTemplater(NaturalLanguageTemplaterContract templater) {
056 this.templater = templater;
057 }
058
059 @Override
060 public String translateNaturalLanguageForObject(String naturalLanguageUsageId, String typeId, String krmsObjectId, String languageCode)
061 throws RiceIllegalArgumentException {
062
063 PropositionDefinition proposition = null;
064 // TODO: find out what RICE intended for this typeId? Was it supposed to be the Simple Class name?
065 if (typeId.equals("proposition")) {
066 proposition = this.ruleManagementService.getProposition(krmsObjectId);
067 if (proposition == null) {
068 throw new RiceIllegalArgumentException(krmsObjectId + " is not an Id for a proposition");
069 }
070 } else if (typeId.equals("agenda")) {
071 AgendaDefinition agenda = this.ruleManagementService.getAgenda(krmsObjectId);
072 if (agenda == null) {
073 throw new RiceIllegalArgumentException(krmsObjectId + " is not an Id for an agenda");
074 }
075 if (agenda.getFirstItemId() == null) {
076 throw new RiceIllegalArgumentException("Agenda has no first item");
077 }
078 AgendaItemDefinition item = this.ruleManagementService.getAgendaItem(agenda.getFirstItemId());
079 if (item.getRuleId() == null) {
080 throw new RiceIllegalArgumentException("Only simple agenda's composed of one item that holds a rule is supported at this time");
081 }
082 RuleDefinition rule = this.ruleManagementService.getRule(item.getRuleId());
083 proposition = rule.getProposition();
084 if (proposition == null) {
085 throw new RiceIllegalArgumentException("The agenda's rule has a proposition that is null");
086 }
087 }
088 String propositionTypeId = proposition.getTypeId();
089 NaturalLanguageTemplate naturalLanguageTemplate =
090 this.ruleManagementService.findNaturalLanguageTemplateByLanguageCodeTypeIdAndNluId(languageCode,
091 propositionTypeId,
092 naturalLanguageUsageId);
093 if (naturalLanguageTemplate == null) {
094 throw new RiceIllegalArgumentException("no template found for " + languageCode
095 + " " + typeId
096 + " " + naturalLanguageUsageId);
097 }
098 return this.translateNaturalLanguageForProposition(naturalLanguageUsageId, proposition, languageCode);
099 }
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 }