001 package org.kuali.rice.krms.util;
002
003 import org.apache.commons.lang.StringUtils;
004 import org.kuali.rice.krms.api.repository.NaturalLanguageTree;
005 import org.kuali.rice.krms.api.repository.RuleManagementService;
006 import org.kuali.rice.krms.api.repository.language.NaturalLanguageUsage;
007 import org.kuali.rice.krms.api.repository.proposition.PropositionDefinition;
008 import org.kuali.rice.krms.api.repository.proposition.PropositionParameter;
009 import org.kuali.rice.krms.api.repository.proposition.PropositionParameterContract;
010 import org.kuali.rice.krms.api.repository.proposition.PropositionParameterType;
011 import org.kuali.rice.krms.api.repository.term.TermDefinition;
012 import org.kuali.rice.krms.api.repository.term.TermParameterDefinition;
013 import org.kuali.rice.krms.dto.PropositionEditor;
014 import org.kuali.rice.krms.dto.TermEditor;
015 import org.kuali.rice.krms.tree.AbstractTreeBuilder;
016 import org.kuali.student.enrollment.class2.courseoffering.service.decorators.PermissionServiceConstants;
017 import org.kuali.student.krms.naturallanguage.util.KsKrmsConstants;
018
019 import java.io.Serializable;
020 import java.util.ArrayList;
021 import java.util.HashMap;
022 import java.util.Iterator;
023 import java.util.LinkedList;
024 import java.util.List;
025 import java.util.Map;
026 import 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 */
035 public 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 }