001 /** 002 * Copyright 2010 The Kuali Foundation Licensed under the 003 * Educational Community License, Version 2.0 (the "License"); you may 004 * not use this file except in compliance with the License. You may 005 * obtain a copy of the License at 006 * 007 * http://www.osedu.org/licenses/ECL-2.0 008 * 009 * Unless required by applicable law or agreed to in writing, 010 * software distributed under the License is distributed on an "AS IS" 011 * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 012 * or implied. See the License for the specific language governing 013 * permissions and limitations under the License. 014 */ 015 016 package org.kuali.rice.krms.impl.repository.language; 017 018 import org.apache.commons.lang.StringUtils; 019 import org.apache.velocity.exception.VelocityException; 020 import org.kuali.rice.krms.api.repository.language.NaturalLanguageTemplate; 021 import org.kuali.rice.krms.api.repository.language.NaturalLanguageTemplaterContract; 022 import org.kuali.rice.krms.api.repository.proposition.PropositionParameterType; 023 import org.kuali.rice.krms.api.repository.term.TermDefinitionContract; 024 import org.kuali.rice.krms.api.repository.type.KrmsTypeDefinitionContract; 025 import org.kuali.rice.krms.api.repository.type.KrmsTypeRepositoryService; 026 import org.kuali.rice.krms.impl.repository.KrmsTypeRepositoryServiceImpl; 027 import org.kuali.rice.krms.impl.repository.TermBoService; 028 import org.kuali.rice.krms.impl.repository.TermBoServiceImpl; 029 import org.kuali.student.common.util.VelocityTemplateEngine; 030 import org.kuali.student.r2.core.krms.naturallanguage.TermParameterTypes; 031 import org.kuali.student.r2.common.exceptions.DoesNotExistException; 032 import org.kuali.student.r2.common.exceptions.OperationFailedException; 033 import org.kuali.student.r2.core.krms.naturallanguage.Context; 034 import org.kuali.student.r2.core.krms.naturallanguage.ContextRegistry; 035 import org.slf4j.Logger; 036 import org.slf4j.LoggerFactory; 037 038 import java.util.HashMap; 039 import java.util.List; 040 import java.util.Map; 041 042 /** 043 * This class translates requirement components into a specific 044 * natural language. This class is not thread safe. 045 */ 046 public class PropositionNaturalLanguageTemplater implements NaturalLanguageTemplaterContract { 047 /** 048 * SLF4J logging framework 049 */ 050 private final static Logger logger = LoggerFactory.getLogger(PropositionNaturalLanguageTemplater.class); 051 052 private ContextRegistry<Context> contextRegistry; 053 054 private KrmsTypeRepositoryService krmsTypeRepositoryService = new KrmsTypeRepositoryServiceImpl(); 055 056 /** 057 * Relational operator token. 058 */ 059 public final static String OPERATOR_TOKEN = "relationalOperator"; 060 /** 061 * An integer value token. 062 */ 063 public final static String CONSTANT_VALUE_TOKEN = "intValue"; 064 065 /** 066 * Velocity template engine. 067 */ 068 private VelocityTemplateEngine templateEngine = new VelocityTemplateEngine(); 069 070 071 /** 072 * Constructs a new proposition natural language templater. 073 */ 074 public PropositionNaturalLanguageTemplater() { 075 } 076 077 078 /** 079 * Sets the template context registry. 080 * 081 * @param contextRegistry Template context registry 082 */ 083 public void setContextRegistry(final ContextRegistry<Context> contextRegistry) { 084 this.contextRegistry = contextRegistry; 085 } 086 087 public String translate(NaturalLanguageTemplate naturalLanguageTemplate, Map<String, Object> parametersMap) { 088 089 if (naturalLanguageTemplate == null) { 090 return StringUtils.EMPTY; 091 } 092 093 Map<String, Object> contextMap = null; 094 try { 095 contextMap = buildContextMap(naturalLanguageTemplate.getTypeId(), parametersMap); 096 } catch (Exception e) { 097 e.printStackTrace(); //TODO hand back to service. 098 } 099 100 try { 101 String nl = this.templateEngine.evaluate(contextMap, naturalLanguageTemplate.getTemplate()); 102 if (logger.isInfoEnabled()) { 103 logger.info("nl=" + nl); 104 } 105 return nl; 106 } catch (VelocityException e) { 107 String msg = "Generating template for proposition failed: template='" + naturalLanguageTemplate.getTemplate() + "', contextMap=" + contextMap; 108 logger.error(msg, e); 109 //TODO hand back to service throw new Exception(msg); 110 } 111 return "Error"; 112 } 113 114 /** 115 * Builds a proposition type context map. 116 * 117 * @param typeId the natural language template id 118 * @param parametersMap map containing the proposition parameter types and their values 119 * @throws java.lang.Exception Creating context map failed 120 */ 121 private Map<String, Object> buildContextMap(String typeId, Map<String, Object> parametersMap) throws Exception { 122 123 Map<String, Object> contextMap = new HashMap<String, Object>(); 124 //Add proposition constant to contextMap. 125 if (parametersMap.containsKey(PropositionParameterType.CONSTANT.getCode())) { 126 contextMap.put(CONSTANT_VALUE_TOKEN, (String) parametersMap.get(PropositionParameterType.CONSTANT.getCode())); 127 } 128 //Add proposition operator to contextMap. 129 if (parametersMap.containsKey(PropositionParameterType.OPERATOR.getCode())) { 130 contextMap.put(OPERATOR_TOKEN, (String) parametersMap.get(PropositionParameterType.OPERATOR.getCode())); 131 } 132 //Access type service to retrieve type name. 133 KrmsTypeDefinitionContract type = getKrmsTypeRepositoryService().getTypeById(typeId); 134 List<Context> contextList = this.contextRegistry.get(type.getName()); 135 if (contextList == null || contextList.isEmpty()) { 136 return contextMap; 137 } 138 139 for (Context context : contextList) { 140 Map<String, Object> cm = context.createContextMap(parametersMap, new org.kuali.student.r2.common.dto.ContextInfo()); // KS contextInfo is not passed through here 141 contextMap.putAll(cm); 142 } 143 144 if (logger.isInfoEnabled()) { 145 logger.info("contextMap=" + contextMap); 146 } 147 return contextMap; 148 } 149 150 151 private KrmsTypeRepositoryService getKrmsTypeRepositoryService() { 152 return krmsTypeRepositoryService; 153 } 154 155 public void setKrmsTypeRepositoryService(KrmsTypeRepositoryService krmsTypeRepositoryService) { 156 this.krmsTypeRepositoryService = krmsTypeRepositoryService; 157 } 158 159 }