001package org.kuali.rice.krms.util; 002 003import org.apache.commons.lang.StringUtils; 004import org.kuali.rice.krms.api.repository.NaturalLanguageTree; 005import org.kuali.rice.krms.api.repository.RuleManagementService; 006import org.kuali.rice.krms.api.repository.language.NaturalLanguageUsage; 007import org.kuali.rice.krms.api.repository.proposition.PropositionDefinition; 008import org.kuali.rice.krms.api.repository.proposition.PropositionParameter; 009import org.kuali.rice.krms.api.repository.proposition.PropositionParameterContract; 010import org.kuali.rice.krms.api.repository.proposition.PropositionParameterType; 011import org.kuali.rice.krms.api.repository.term.TermDefinition; 012import org.kuali.rice.krms.api.repository.term.TermParameterDefinition; 013import org.kuali.rice.krms.dto.PropositionEditor; 014import org.kuali.rice.krms.dto.TermEditor; 015import org.kuali.rice.krms.tree.AbstractTreeBuilder; 016import org.kuali.student.enrollment.class2.courseoffering.service.decorators.PermissionServiceConstants; 017import org.kuali.student.krms.naturallanguage.util.KsKrmsConstants; 018 019import java.io.Serializable; 020import java.util.ArrayList; 021import java.util.HashMap; 022import java.util.Iterator; 023import java.util.LinkedList; 024import java.util.List; 025import java.util.Map; 026import java.util.Queue; 027 028/** 029 * Created with IntelliJ IDEA. 030 * User: SW 031 * Date: 2013/04/08 032 * Time: 11:41 AM 033 * To change this template use File | Settings | File Templates. 034 */ 035public class NaturalLanguageHelper { 036 037 private RuleManagementService ruleManagementService; 038 039 private Map<String, String> usageMap = new HashMap<String, String>(); 040 041 /** 042 * This method should set the natural language only for the given proposition. It does not 043 * do a recursive call through the tree structure. 044 * 045 * @param proposition 046 * @param usageName 047 */ 048 public void setNaturalLanguageForUsage(PropositionEditor proposition, String usageName){ 049 050 //Setup the Proposition 051 List<PropositionParameter.Builder> parameters = new ArrayList<PropositionParameter.Builder>(); 052 if(proposition.getParameters()!=null){ //Parameters on Compound Propositions could be null. 053 for(PropositionParameterContract parameter : proposition.getParameters()){ 054 PropositionParameter.Builder parmBuilder = PropositionParameter.Builder.create(parameter); 055 056 //Add the edited term. 057 if(parameter.getParameterType().equals(PropositionParameterType.TERM.getCode())){ 058 TermDefinition.Builder termBuilder = TermDefinition.Builder.create(proposition.getTerm()); 059 for (Map.Entry<String, String> entry : proposition.getNlParameters().entrySet()) { 060 termBuilder.getParameters().add(TermParameterDefinition.Builder.create(null, null, entry.getKey(), entry.getValue())); 061 } 062 parmBuilder.setTermValue(termBuilder.build()); 063 } 064 parameters.add(parmBuilder); 065 } 066 } 067 068 //Create the propbuilder but don set compound editors here, we only want to get the nl for current proposition 069 PropositionDefinition.Builder propBuilder = PropositionDefinition.Builder.create(proposition.getId(), 070 proposition.getPropositionTypeCode(), proposition.getRuleId(), proposition.getTypeId(), parameters); 071 072 //Build the tree. 073 TreeIterator nlTree = this.buildNaturalLanguageTree(propBuilder, this.getNaturalLanguageUsageId(usageName)); 074 this.setTranslatedNaturalLanguage(proposition, usageName, nlTree); 075 } 076 077 /** 078 * This method sets the natural language descriptions for the given proposition and all its child propositions as 079 * well. 080 * 081 * @param proposition 082 * @param usageName 083 */ 084 public void setNaturalLanguageTreeForUsage(PropositionEditor proposition, String usageName){ 085 PropositionDefinition.Builder propBuilder = PropositionDefinition.Builder.create(proposition); 086 TreeIterator nlTree = this.buildNaturalLanguageTree(propBuilder, this.getNaturalLanguageUsageId(usageName)); 087 this.setTranslatedNaturalLanguage(proposition, usageName, nlTree); 088 } 089 090 private TreeIterator buildNaturalLanguageTree(PropositionDefinition.Builder propBuilder, String usageId){ 091 NaturalLanguageTree nlTree = this.getRuleManagementService().translateNaturalLanguageTreeForProposition(usageId, propBuilder.build(), "en"); 092 return new TreeIterator(nlTree); 093 } 094 095 private void setTranslatedNaturalLanguage(PropositionEditor proposition, String usageName, TreeIterator nlDescriptions){ 096 if(!nlDescriptions.hasNext()){ 097 return; 098 } 099 100 proposition.getNaturalLanguage().put(usageName, nlDescriptions.next()); 101 102 if (proposition.getCompoundEditors() != null){ 103 for (PropositionEditor child : proposition.getCompoundEditors()){ 104 setTranslatedNaturalLanguage(child, usageName, nlDescriptions); 105 } 106 } 107 } 108 109 private String getNaturalLanguageUsageId(String usageName){ 110 //usageName cannot be null or blank 111 if ((usageName == null) || (StringUtils.isBlank(usageName))){ 112 return null; 113 } 114 115 //Retrieve usageId form map. 116 String usageId = usageMap.get(usageName); 117 if (usageId == null){ 118 119 //Retrieve usage from service if usageId not on map. 120 NaturalLanguageUsage usage = this.getRuleManagementService().getNaturalLanguageUsageByNameAndNamespace(usageName, 121 PermissionServiceConstants.KS_SYS_NAMESPACE); 122 123 //Set the usage id to the map. 124 if (usage != null){ 125 usageId = usage.getId(); 126 usageMap.put(usageName, usageId); 127 } 128 } 129 return usageId; 130 } 131 132 public RuleManagementService getRuleManagementService() { 133 return ruleManagementService; 134 } 135 136 public void setRuleManagementService(RuleManagementService ruleManagementService) { 137 this.ruleManagementService = ruleManagementService; 138 } 139 140 /** 141 * Put the natural language descriptions in a queue and retrieve them in 142 * the same order as the propostion tree. 143 */ 144 protected class TreeIterator implements Serializable, Iterator<String> { 145 146 private Queue<String> nl; 147 148 public TreeIterator(NaturalLanguageTree tree){ 149 nl = new LinkedList<String>(); 150 this.addToStack(tree); 151 } 152 153 private void addToStack(NaturalLanguageTree tree){ 154 if (tree == null){ 155 return; 156 } 157 158 nl.offer(tree.getNaturalLanguage()); 159 if (tree.getChildren() != null){ 160 for (NaturalLanguageTree child : tree.getChildren()){ 161 addToStack(child); 162 } 163 } 164 } 165 166 @Override 167 public boolean hasNext() { 168 return !nl.isEmpty(); 169 } 170 171 @Override 172 public String next() { 173 return nl.poll(); 174 } 175 176 @Override 177 public void remove() { 178 //To change body of implemented methods use File | Settings | File Templates. 179 } 180 } 181}