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 }