1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.kuali.rice.krms.impl.repository;
21
22 import java.util.ArrayList;
23 import java.util.LinkedHashMap;
24 import java.util.List;
25 import java.util.Map;
26
27 import org.apache.commons.lang.StringUtils;
28 import org.kuali.rice.core.api.exception.RiceIllegalArgumentException;
29 import org.kuali.rice.krms.api.repository.LogicalOperator;
30 import org.kuali.rice.krms.api.repository.NaturalLanguageTree;
31 import org.kuali.rice.krms.api.repository.RuleManagementService;
32 import org.kuali.rice.krms.api.repository.TranslateBusinessMethods;
33 import org.kuali.rice.krms.api.repository.agenda.AgendaDefinition;
34 import org.kuali.rice.krms.api.repository.agenda.AgendaItemDefinition;
35 import org.kuali.rice.krms.api.repository.language.NaturalLanguageTemplate;
36 import org.kuali.rice.krms.api.repository.language.NaturalLanguageTemplaterContract;
37 import org.kuali.rice.krms.api.repository.proposition.PropositionDefinition;
38 import org.kuali.rice.krms.api.repository.proposition.PropositionParameter;
39 import org.kuali.rice.krms.api.repository.proposition.PropositionParameterType;
40 import org.kuali.rice.krms.api.repository.proposition.PropositionType;
41 import org.kuali.rice.krms.api.repository.rule.RuleDefinition;
42 import org.kuali.rice.krms.api.repository.term.TermDefinition;
43 import org.kuali.rice.krms.api.repository.term.TermParameterDefinition;
44 import org.kuali.rice.krms.api.repository.term.TermRepositoryService;
45
46
47
48
49 public class TranslationUtility implements TranslateBusinessMethods {
50
51 private RuleManagementService ruleManagementService;
52 private TermRepositoryService termRepositoryService;
53 private NaturalLanguageTemplaterContract templater;
54
55 public TranslationUtility(RuleManagementService ruleManagementService, TermRepositoryService termRepositoryService,
56 NaturalLanguageTemplaterContract templater) {
57 this.ruleManagementService = ruleManagementService;
58 this.termRepositoryService = termRepositoryService;
59 this.templater = templater;
60 }
61
62 public RuleManagementService getRuleManagementService() {
63 return ruleManagementService;
64 }
65
66 public void setRuleManagementService(RuleManagementService ruleManagementService) {
67 this.ruleManagementService = ruleManagementService;
68 }
69
70 public NaturalLanguageTemplaterContract getTemplater() {
71 return templater;
72 }
73
74 public void setTemplater(NaturalLanguageTemplaterContract templater) {
75 this.templater = templater;
76 }
77
78 @Override
79 public String translateNaturalLanguageForObject(String naturalLanguageUsageId, String typeId, String krmsObjectId, String languageCode)
80 throws RiceIllegalArgumentException {
81
82
83 if (typeId.equals("agenda")) {
84 AgendaDefinition agenda = this.ruleManagementService.getAgenda(krmsObjectId);
85 if (agenda == null) {
86 throw new RiceIllegalArgumentException(krmsObjectId + " is not an Id for an agenda");
87 }
88 return this.translateNaturalLanguageForAgenda(naturalLanguageUsageId, agenda, languageCode);
89 } else if (typeId.equals("rule")) {
90 RuleDefinition rule = this.ruleManagementService.getRule(krmsObjectId);
91 if (rule == null) {
92 throw new RiceIllegalArgumentException(krmsObjectId + " is not an Id for a rule");
93 }
94 return this.translateNaturalLanguageForRule(naturalLanguageUsageId, rule, languageCode);
95 } else if (typeId.equals("proposition")) {
96 PropositionDefinition proposition = this.ruleManagementService.getProposition(krmsObjectId);
97 if (proposition == null) {
98 throw new RiceIllegalArgumentException(krmsObjectId + " is not an Id for a proposition");
99 }
100 return this.translateNaturalLanguageForProposition(naturalLanguageUsageId, proposition, languageCode);
101 }
102
103 return StringUtils.EMPTY;
104 }
105
106 protected String translateNaturalLanguageForAgenda(String naturalLanguageUsageId, AgendaDefinition agenda, String languageCode) throws RiceIllegalArgumentException {
107 if (agenda.getFirstItemId() == null) {
108 throw new RiceIllegalArgumentException("Agenda has no first item");
109 }
110
111 AgendaItemDefinition item = this.ruleManagementService.getAgendaItem(agenda.getFirstItemId());
112 return translateNaturalLanguageForAgendaItem(naturalLanguageUsageId, item, languageCode);
113 }
114
115 protected String translateNaturalLanguageForAgendaItem(String naturalLanguageUsageId, AgendaItemDefinition item, String languageCode) {
116 if(item==null){
117 return StringUtils.EMPTY;
118 }
119
120 String naturalLanguage = StringUtils.EMPTY;
121 if (item.getRuleId() != null) {
122 RuleDefinition rule = this.ruleManagementService.getRule(item.getRuleId());
123 naturalLanguage += this.translateNaturalLanguageForRule(naturalLanguageUsageId, rule, languageCode);
124 }
125 naturalLanguage += translateNaturalLanguageForAgendaItem(naturalLanguageUsageId, item.getWhenTrue(), languageCode);
126 naturalLanguage += translateNaturalLanguageForAgendaItem(naturalLanguageUsageId, item.getWhenFalse(), languageCode);
127 naturalLanguage += translateNaturalLanguageForAgendaItem(naturalLanguageUsageId, item.getAlways(), languageCode);
128 return naturalLanguage;
129 }
130
131 protected String translateNaturalLanguageForRule(String naturalLanguageUsageId, RuleDefinition rule, String languageCode) throws RiceIllegalArgumentException {
132 if(rule==null){
133 return StringUtils.EMPTY;
134 }
135
136 NaturalLanguageTemplate nlTemplate = ruleManagementService.findNaturalLanguageTemplateByLanguageCodeTypeIdAndNluId(languageCode, rule.getTypeId(), naturalLanguageUsageId);
137 String naturalLanguage = nlTemplate.getTemplate() + " ";
138
139 if(rule.getProposition()!=null){
140 naturalLanguage += this.translateNaturalLanguageForProposition(naturalLanguageUsageId, rule.getProposition(), languageCode);
141 }
142
143 return naturalLanguage;
144 }
145
146 @Override
147 public String translateNaturalLanguageForProposition(String naturalLanguageUsageId,
148 PropositionDefinition proposition, String languageCode)
149 throws RiceIllegalArgumentException {
150 return translateNaturalLanguageForProposition(naturalLanguageUsageId, proposition, languageCode, true) + ". ";
151 }
152
153
154
155
156
157
158
159
160
161
162
163 private String translateNaturalLanguageForProposition(String naturalLanguageUsageId, PropositionDefinition proposition, String languageCode, boolean isRoot) {
164 NaturalLanguageTemplate naturalLanguageTemplate = this.ruleManagementService.findNaturalLanguageTemplateByLanguageCodeTypeIdAndNluId(
165 languageCode, proposition.getTypeId(), naturalLanguageUsageId);
166
167 StringBuilder naturalLanguage = new StringBuilder();
168 if (proposition.getPropositionTypeCode().equals(PropositionType.SIMPLE.getCode())) {
169 if(naturalLanguageTemplate!=null){
170 Map<String, Object> contextMap = this.buildSimplePropositionContextMap(proposition);
171 naturalLanguage.append(templater.translate(naturalLanguageTemplate, contextMap));
172 }
173
174 } else if (proposition.getPropositionTypeCode().equals(PropositionType.COMPOUND.getCode())) {
175 if(naturalLanguageTemplate!=null){
176 Map<String, Object> contextMap = this.buildCompoundPropositionContextMap(naturalLanguageUsageId, proposition, languageCode);
177 naturalLanguage.append(templater.translate(naturalLanguageTemplate, contextMap));
178 }
179
180
181 if(proposition.getCompoundComponents()!=null){
182 String operator = getCompoundSeperator(proposition, isRoot);
183 for (PropositionDefinition child : proposition.getCompoundComponents()) {
184 if(proposition.getCompoundComponents().indexOf(child)!=0){
185 naturalLanguage.append(operator);
186 }
187 naturalLanguage.append(this.translateNaturalLanguageForProposition(naturalLanguageUsageId, child, languageCode, false));
188 }
189 }
190
191 } else {
192 throw new RiceIllegalArgumentException("Unknown proposition type: " + proposition.getPropositionTypeCode());
193 }
194
195 return naturalLanguage.toString();
196 }
197
198 private String getCompoundSeperator(PropositionDefinition proposition, boolean isRoot) {
199 String operator = getCompoundOperator(proposition);
200 if (isRoot){
201 return ". " + StringUtils.capitalize(operator) + " ";
202 }
203 return "; " + operator + " ";
204 }
205
206 private String getCompoundOperator(PropositionDefinition proposition) {
207 String operator = null;
208 if (LogicalOperator.AND.getCode().equalsIgnoreCase(proposition.getCompoundOpCode())) {
209 operator = "and";
210 } else if (LogicalOperator.OR.getCode().equalsIgnoreCase(proposition.getCompoundOpCode())) {
211 operator = "or";
212 }
213 return operator;
214 }
215
216 @Override
217 public NaturalLanguageTree translateNaturalLanguageTreeForProposition(String naturalLanguageUsageId,
218 PropositionDefinition proposition,
219 String languageCode) throws RiceIllegalArgumentException {
220 NaturalLanguageTemplate naturalLanguageTemplate = getNaturalLanguageTemplateForProposition(naturalLanguageUsageId, proposition, languageCode);
221
222 NaturalLanguageTree.Builder tree = NaturalLanguageTree.Builder.create();
223 if (proposition.getPropositionTypeCode().equals(PropositionType.SIMPLE.getCode())) {
224 Map<String, Object> contextMap = this.buildSimplePropositionContextMap(proposition);
225 String naturalLanguage = templater.translate(naturalLanguageTemplate, contextMap);
226 tree.setNaturalLanguage(naturalLanguage);
227
228 } else if (proposition.getPropositionTypeCode().equals(PropositionType.COMPOUND.getCode())) {
229 Map<String, Object> contextMap = this.buildCompoundPropositionContextMap(naturalLanguageUsageId, proposition, languageCode);
230 String naturalLanguage = templater.translate(naturalLanguageTemplate, contextMap);
231 tree.setNaturalLanguage(naturalLanguage);
232
233
234 if(proposition.getCompoundComponents()!=null){
235 List<NaturalLanguageTree> children = new ArrayList<NaturalLanguageTree>();
236 for (PropositionDefinition child : proposition.getCompoundComponents()) {
237 children.add(this.translateNaturalLanguageTreeForProposition(naturalLanguageUsageId, child, languageCode));
238 }
239 tree.setChildren(children);
240 }
241
242 } else {
243 throw new RiceIllegalArgumentException("Unknown proposition type: " + proposition.getPropositionTypeCode());
244 }
245
246 return tree.build();
247 }
248
249 protected NaturalLanguageTemplate getNaturalLanguageTemplateForProposition(String naturalLanguageUsageId, PropositionDefinition proposition, String languageCode) {
250 NaturalLanguageTemplate naturalLanguageTemplate = null;
251
252 if (proposition.getTypeId() != null) {
253 naturalLanguageTemplate = this.ruleManagementService.findNaturalLanguageTemplateByLanguageCodeTypeIdAndNluId(languageCode,
254 proposition.getTypeId(), naturalLanguageUsageId);
255 }
256 return naturalLanguageTemplate;
257 }
258
259 protected Map<String, Object> buildSimplePropositionContextMap(PropositionDefinition proposition) {
260 if (!proposition.getPropositionTypeCode().equals(PropositionType.SIMPLE.getCode())) {
261 throw new RiceIllegalArgumentException("proposition is not simple " + proposition.getPropositionTypeCode() + " " + proposition.getId() + proposition.getDescription());
262 }
263 Map<String, Object> contextMap = new LinkedHashMap<String, Object>();
264 for (PropositionParameter param : proposition.getParameters()) {
265 if (param.getParameterType().equals(PropositionParameterType.TERM.getCode())) {
266 TermDefinition term = param.getTermValue();
267 if ((term == null) && (StringUtils.isNotBlank(param.getValue()))) {
268 term = this.termRepositoryService.getTerm(param.getValue());
269 }
270 if (term != null) {
271 for (TermParameterDefinition termParam : term.getParameters()) {
272 contextMap.put(termParam.getName(), termParam.getValue());
273 }
274 } else {
275 contextMap.put(param.getParameterType(), param.getValue());
276 }
277 } else {
278 contextMap.put(param.getParameterType(), param.getValue());
279 }
280 }
281 return contextMap;
282 }
283
284 protected Map<String, Object> buildCompoundPropositionContextMap(String naturalLanguageUsageId, PropositionDefinition proposition, String languageCode) {
285 if (!proposition.getPropositionTypeCode().equals(PropositionType.COMPOUND.getCode())) {
286 throw new RiceIllegalArgumentException("proposition us not compound " + proposition.getPropositionTypeCode() + " " + proposition.getId() + proposition.getDescription());
287 }
288 return new LinkedHashMap<String, Object>();
289 }
290
291 }