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