001 /***************************************************************************/
002 /* Copyright (C) 2010-2011, Sebastian Hellmann */
003 /* Note: If you need parts of NLP2RDF in another licence due to licence */
004 /* incompatibility, please mail hellmann@informatik.uni-leipzig.de */
005 /* */
006 /* This file is part of NLP2RDF. */
007 /* */
008 /* NLP2RDF is free software; you can redistribute it and/or modify */
009 /* it under the terms of the GNU General Public License as published by */
010 /* the Free Software Foundation; either version 3 of the License, or */
011 /* (at your option) any later version. */
012 /* */
013 /* NLP2RDF is distributed in the hope that it will be useful, */
014 /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
015 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
016 /* GNU General Public License for more details. */
017 /* */
018 /* You should have received a copy of the GNU General Public License */
019 /* along with this program. If not, see <http://www.gnu.org/licenses/>. */
020 /***************************************************************************/
021
022 package org.nlp2rdf.webservice;
023
024 import com.hp.hpl.jena.ontology.OntModel;
025 import com.hp.hpl.jena.ontology.OntModelSpec;
026 import com.hp.hpl.jena.rdf.model.ModelFactory;
027 import com.hp.hpl.jena.shared.JenaException;
028 import eu.lod2.nlp2rdf.schema.str.Document;
029 import org.apache.commons.lang.StringUtils;
030 import org.slf4j.Logger;
031 import org.slf4j.LoggerFactory;
032
033 import javax.servlet.http.HttpServletRequest;
034 import java.io.ByteArrayInputStream;
035 import java.net.URLEncoder;
036 import java.security.InvalidParameterException;
037 import java.util.HashMap;
038 import java.util.List;
039 import java.util.Map;
040
041 /**
042 * User: Sebastian Hellmann
043 * See http://nlp2rdf.org/nif-1-0#toc-parameters
044 * A simple wrapper for the common options in NIF Services
045 * Almost fully implements
046 */
047 public class NIFParameters {
048 private static Logger log = LoggerFactory.getLogger(NIFParameters.class);
049
050 //the plain text as is
051 private final String text;
052 //the RDF that was sent with the request
053 private final OntModel inputModel;
054 private final Map<String, String> parameterMap;
055
056 private final String prefix;
057 private final String uriRecipe;
058 private final String format;
059
060 //not in nif 1.0 diff or full
061 private final String output;
062
063
064 public NIFParameters(String text, String prefix, String output, String uriRecipe, String format, OntModel inputModel, Map<String, String> parameterMap) {
065 this.text = text;
066 this.prefix = prefix;
067 this.output = output;
068 this.uriRecipe = uriRecipe;
069 this.format = format;
070 this.inputModel = inputModel;
071 this.parameterMap = parameterMap;
072 }
073
074
075 /**
076 * Factory method
077 *
078 * @param httpServletRequest
079 * @return
080 */
081 public static NIFParameters getInstance(HttpServletRequest httpServletRequest) {
082 String requestUrl = httpServletRequest.getRequestURL().toString();
083 try {
084
085 //required Parameter input-type
086 String input_type = requiredParameter("input-type", httpServletRequest, "text", "nif-owl");
087 String input = requiredParameter("input", httpServletRequest);
088
089 //optional parameters
090 //note that nif=true is intentionally left out here, because it would be too late
091 String prefix = "http://nlp2rdf.lod2.eu/nif/";
092 String format = "rdfxml";
093 String urirecipe = "offset";
094 //this is not in the nif 1.0 spec
095 String output = "full";
096
097 //the data variables
098 OntModel inputModel = ModelFactory.createOntologyModel(OntModelSpec.OWL_DL_MEM, ModelFactory.createDefaultModel());
099 String text = null;
100
101
102 //prefix
103 if (isSet("prefix", httpServletRequest)) {
104 prefix = httpServletRequest.getParameter("prefix");
105 }
106
107 //format
108 if (isSet("format", httpServletRequest)) {
109 format = requiredParameter("format", httpServletRequest, "rdfxml", "turtle", "json", "ntriples", "n3");
110 }
111
112 //urirecipe
113 if (isSet("urirecipe", httpServletRequest)) {
114 urirecipe = requiredParameter("urirecipe", httpServletRequest, "offset", "context-hash");
115 }
116
117
118 //output
119 if (isSet("output", httpServletRequest)) {
120 output = requiredParameter("output", httpServletRequest, "full", "diff");
121 }
122
123 //normalize input, i.e. fill the variables for text and model
124 if (input_type.equals("text")) {
125 log.trace("Handling type text");
126 // read the text
127 text = httpServletRequest.getParameter("input");
128 //make a NIF model to work on
129 //URIGenerator uriGenerator = ModelHelper.determineGenerator(urirecipe);
130 //inputModel = new Text2RDF().processAsDocument(prefix, text, new OpenNLPTokenizer(), uriGenerator);
131
132 /**********************
133 * NOTE that parsing another NIF model is a little bit harder than just the output so this reference implementation is not yet complete.
134 * *********************/
135 } else if (input_type.equals("nif-owl")) {
136 // Read the model directly from the input
137
138 ByteArrayInputStream bais = new ByteArrayInputStream(httpServletRequest.getParameter("input").getBytes());
139 try {
140 inputModel.read(bais, "");
141 } catch (JenaException e) {
142 throw new InvalidParameterException("Jena could not read the presented nif-owl in RDF/XML format.\nFor the conversion of text \"input-type=text\" has to be set.");
143 }
144 //Validate
145 List<Document> l = Document.list(inputModel);
146 if (inputModel.isEmpty()) {
147 throw new InvalidParameterException("The presented nif-owl representation must not be empty: no Document found. ");
148 } else if (l.isEmpty()) {
149 throw new InvalidParameterException("The presented nif-owl representation does not contain a document uri. ");
150 }
151 //TODO this is badly implemented, alternatively it could contain a sourceUrl
152 if (!l.get(0).existsSourceString()) {
153 throw new InvalidParameterException("The presented nif-owl representation does not contain a Document with a sourceString property. ");
154 }
155 // read the text
156 text = l.get(0).getSourceString();
157 }
158
159 NIFParameters nifParameters = new NIFParameters(text, prefix, output, urirecipe, format, inputModel, copyParameterMap(httpServletRequest));
160 log.trace("created NIFParameters instance from " + input_type + ": " + nifParameters.toString());
161 return nifParameters;
162
163 } catch (InvalidParameterException ipe) {
164 throw new InvalidParameterException(ipe.getMessage() + getDocumentation(requestUrl));
165 }
166 }
167
168
169 @Override
170 public String toString() {
171 return "NIFParameters{" +
172 "text='" + text + '\'' +
173 ", inputModel size=" + inputModel.size() +
174 ", prefix='" + prefix + '\'' +
175 ", uriRecipe='" + uriRecipe + '\'' +
176 ", format='" + format + '\'' +
177 ", output='" + output + '\'' +
178 ", parameterMap=" + parameterMap +
179 '}';
180 }
181
182 public String getText() {
183 return text;
184 }
185
186 public OntModel getInputModel() {
187 return inputModel;
188 }
189
190 public Map<String, String> getParameterMap() {
191 return parameterMap;
192 }
193
194 public String getPrefix() {
195 return prefix;
196 }
197
198 public String getUriRecipe() {
199 return uriRecipe;
200 }
201
202 public String getFormat() {
203 return format;
204 }
205
206 public String getOutput() {
207 return output;
208 }
209
210 public static String requiredParameter(String parameterName, HttpServletRequest hsr) {
211
212 if (!isSet(parameterName, hsr)) {
213 throw new IllegalArgumentException("Missing parameter: " + parameterName + " is required. ");
214 }
215 return hsr.getParameter(parameterName);
216 }
217
218 public static String requiredParameter(String parameterName, HttpServletRequest hsr, String... requiredValues) {
219 String value = requiredParameter(parameterName, hsr);
220 if (!oneOf(value, requiredValues)) {
221 throw new InvalidParameterException("Wrong value for parameter " + parameterName + ", value was: " + value + ", but must be one of ( " + StringUtils.join(requiredValues, ", ") + " ) ");
222 }
223 return value;
224 }
225
226
227 public static String getDocumentation(String serviceUrl) {
228 String doc = "";
229 try {
230 doc = "\nExample1: \n " + serviceUrl + "?input=" + URLEncoder.encode("That's a lot of nuts! That'll be four bucks, baby! You want fries with that? ", "UTF-8") + "&type=text";
231 doc += "\nExample2: \n " + serviceUrl + "?input=" + URLEncoder.encode("That's a lot of nuts! That's a lot of nuts! ", "UTF-8") + "&type=text";
232 } catch (Exception e) {
233 log.error("", e);
234 }
235 return doc;
236 }
237
238 public static boolean oneOf(String value, String... possibleValues) {
239 for (String s : possibleValues) {
240 if (s.equals(value)) {
241 return true;
242 }
243 }
244 return false;
245 }
246
247 public static boolean isSet(String parameterName, HttpServletRequest hsr) {
248 boolean retVal = hsr.getParameterValues(parameterName) != null && hsr.getParameterValues(parameterName).length == 1 && hsr.getParameter(parameterName).length() > 0;
249 if (log.isTraceEnabled()) {
250 log.trace("Parameter " + parameterName + " isSet: " + retVal + " with value: " + hsr.getParameter(parameterName) + ")");
251 }
252 return retVal;
253 }
254
255 public static Map<String, String> copyParameterMap(HttpServletRequest httpServletRequest) {
256 Map<String, String> ret = new HashMap<String, String>();
257 for (Object key : httpServletRequest.getParameterMap().keySet()) {
258 ret.put((String) key, httpServletRequest.getParameter((String) key));
259 }
260 return ret;
261 }
262
263 }