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