001/* 002 * To change this template, choose Tools | Templates 003 * and open the template in the editor. 004 */ 005package org.kuali.rice.krms.impl.repository; 006 007import java.util.ArrayList; 008import java.util.LinkedHashMap; 009import java.util.List; 010import java.util.Map; 011 012import org.kuali.rice.core.api.exception.RiceIllegalArgumentException; 013import org.kuali.rice.krms.api.repository.NaturalLanguageTree; 014import org.kuali.rice.krms.api.repository.RuleManagementService; 015import org.kuali.rice.krms.api.repository.TranslateBusinessMethods; 016import org.kuali.rice.krms.api.repository.agenda.AgendaDefinition; 017import org.kuali.rice.krms.api.repository.agenda.AgendaItemDefinition; 018import org.kuali.rice.krms.api.repository.language.NaturalLanguageTemplate; 019import org.kuali.rice.krms.api.repository.language.NaturalLanguageTemplaterContract; 020import org.kuali.rice.krms.api.repository.proposition.PropositionDefinition; 021import org.kuali.rice.krms.api.repository.proposition.PropositionParameter; 022import org.kuali.rice.krms.api.repository.proposition.PropositionParameterType; 023import org.kuali.rice.krms.api.repository.proposition.PropositionType; 024import org.kuali.rice.krms.api.repository.rule.RuleDefinition; 025import org.kuali.rice.krms.api.repository.term.TermDefinition; 026import org.kuali.rice.krms.api.repository.term.TermParameterDefinition; 027import org.kuali.rice.krms.api.repository.term.TermRepositoryService; 028 029/** 030 * @author nwright 031 */ 032public 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}