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 * Use the following to retrieve the input variable:
046 * if (nifParameters.inputWasText()) {
047 * String text = nifParameters.getInputAsText() ;
048 * }else {
049 * OntModel model = getInputAsOntModel();
050 * }
051 */
052 public class NIFParameters {
053 private static Logger log = LoggerFactory.getLogger(NIFParameters.class);
054
055 //can be String or OntModel
056 private final Object input;
057 private final Map<String, String> parameterMap;
058
059 private final String prefix;
060 private final String uriRecipe;
061 private final int contextLength;
062
063 private final String format;
064
065 //not in nif 1.0 diff or full
066 private final String output;
067
068 public NIFParameters(Object input, Map<String, String> parameterMap, String prefix, String uriRecipe, int contextLength, String format, String output) {
069 this.input = input;
070 this.parameterMap = parameterMap;
071 this.prefix = prefix;
072 this.uriRecipe = uriRecipe;
073 this.contextLength = contextLength;
074 this.format = format;
075 this.output = output;
076 }
077
078 /**
079 * Tests whether the input was text in opposition to inputWasRDF()
080 *
081 * @return true if the input is an instance of String
082 */
083 public boolean inputWasText() {
084 return input instanceof String;
085 }
086
087 /**
088 * Tests whether the input was RDF in opposition to inputWasText()
089 *
090 * @return true if the input is an instance of OntModel
091 */
092 public boolean inputWasRDF() {
093 return input instanceof OntModel;
094 }
095
096 /**
097 * Casts the input var to String
098 *
099 * @return the text of the input variable
100 * @throws ClassCastException
101 */
102 public String getInputAsText() throws ClassCastException {
103 return (String) input;
104 }
105
106 /**
107 * Casts the input var to OntModel
108 *
109 * @return the OntModel from the input variable
110 * @throws ClassCastException
111 */
112 public OntModel getInputAsOntModel() throws ClassCastException {
113 return (OntModel) input;
114 }
115
116
117 /**
118 * Factory method
119 *
120 * @param httpServletRequest
121 * @return
122 */
123 public static NIFParameters getInstance(HttpServletRequest httpServletRequest) {
124 String requestUrl = httpServletRequest.getRequestURL().toString();
125 try {
126
127 //required Parameter input-type
128 String input_type = requiredParameter("input-type", httpServletRequest, "text", "nif-owl");
129
130 if (!isSet("input", httpServletRequest)) {
131 throw new IllegalArgumentException("Missing parameter: input is required. ");
132 }
133 //optional parameters
134 //note that nif=true is intentionally left out here, because it would be too late
135 String prefix = "http://nlp2rdf.lod2.eu/nif/";
136 String format = "rdfxml";
137 String urirecipe = "offset";
138 int contextLength = 10;
139 //this is not in the nif 1.0 spec
140 String output = "full";
141
142 //prefix
143 if (isSet("prefix", httpServletRequest)) {
144 prefix = httpServletRequest.getParameter("prefix");
145 }
146
147 //format
148 if (isSet("format", httpServletRequest)) {
149 format = requiredParameter("format", httpServletRequest, "rdfxml", "turtle", "json", "ntriples", "n3");
150 }
151 //urirecipe
152 if (isSet("urirecipe", httpServletRequest)) {
153 urirecipe = requiredParameter("urirecipe", httpServletRequest, "offset", "context-hash");
154 }
155 //contextLength
156 if (isSet("context-length", httpServletRequest)) {
157 contextLength = Integer.parseInt(httpServletRequest.getParameter("context-length"));
158 }
159 //output
160 if (isSet("output", httpServletRequest)) {
161 output = requiredParameter("output", httpServletRequest, "full", "diff");
162 }
163
164 Object input;
165 //normalize input, i.e. fill the variables for text and model
166 if (input_type.equals("text")) {
167 log.trace("Handling type text");
168 // read the text
169 input = httpServletRequest.getParameter("input");
170 //make a NIF model to work on
171 //URIGenerator uriGenerator = ModelHelper.determineGenerator(urirecipe);
172 //inputModel = new Text2RDF().processAsDocument(prefix, text, new FakeTokenizer(), uriGenerator);
173
174 /**********************
175 * NOTE that parsing another NIF model is a little bit harder than just the output so this reference implementation is not yet complete.
176 * *********************/
177 } else if (input_type.equals("nif-owl")) {
178 // Read the model directly from the input
179 OntModel inputModel = ModelFactory.createOntologyModel(OntModelSpec.OWL_DL_MEM, ModelFactory.createDefaultModel());
180 ByteArrayInputStream bais = new ByteArrayInputStream(httpServletRequest.getParameter("input").getBytes());
181 try {
182 inputModel.read(bais, "");
183 } catch (JenaException e) {
184 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.");
185 }
186 input = inputModel;
187 } else {
188 throw new InvalidParameterException("third way in a binary path: maybe");
189 }
190
191 NIFParameters nifParameters = new NIFParameters(input, copyParameterMap(httpServletRequest), prefix, urirecipe, contextLength, format, output);
192 log.trace("created NIFParameters instance from " + input_type + ": " + nifParameters.toString());
193 return nifParameters;
194
195 } catch (InvalidParameterException ipe) {
196 throw new InvalidParameterException(ipe.getMessage() + getDocumentation(requestUrl));
197 }
198 }
199
200
201 @Override
202 public String toString() {
203 return "NIFParameters{" +
204 "input=" + input +
205 ", parameterMap=" + parameterMap +
206 ", prefix='" + prefix + '\'' +
207 ", uriRecipe='" + uriRecipe + '\'' +
208 ", format='" + format + '\'' +
209 ", output='" + output + '\'' +
210 '}';
211 }
212
213 public Map<String, String> getParameterMap() {
214 return parameterMap;
215 }
216
217 public String getPrefix() {
218 return prefix;
219 }
220
221 public String getUriRecipe() {
222 return uriRecipe;
223 }
224
225 public String getFormat() {
226 return format;
227 }
228
229 public String getOutput() {
230 return output;
231 }
232
233 public int getContextLength() {
234 return contextLength;
235 }
236
237 public static String requiredParameter(String parameterName, HttpServletRequest hsr) {
238
239 if (!isSet(parameterName, hsr)) {
240 throw new IllegalArgumentException("Missing parameter: " + parameterName + " is required. ");
241 }
242 return hsr.getParameter(parameterName);
243 }
244
245 public static String requiredParameter(String parameterName, HttpServletRequest hsr, String... requiredValues) {
246 String value = requiredParameter(parameterName, hsr);
247 if (!oneOf(value, requiredValues)) {
248 throw new InvalidParameterException("Wrong value for parameter " + parameterName + ", value was: " + value + ", but must be one of ( " + StringUtils.join(requiredValues, ", ") + " ) ");
249 }
250 return value;
251 }
252
253
254 public static String getDocumentation(String serviceUrl) {
255 String doc = "";
256 try {
257 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";
258 doc += "\nExample2: \n " + serviceUrl + "?input=" + URLEncoder.encode("That's a lot of nuts! That's a lot of nuts! ", "UTF-8") + "&type=text";
259 } catch (Exception e) {
260 log.error("", e);
261 }
262 return doc;
263 }
264
265 public static boolean oneOf(String value, String... possibleValues) {
266 for (String s : possibleValues) {
267 if (s.equals(value)) {
268 return true;
269 }
270 }
271 return false;
272 }
273
274 public static boolean isSet(String parameterName, HttpServletRequest hsr) {
275 boolean retVal = hsr.getParameterValues(parameterName) != null && hsr.getParameterValues(parameterName).length == 1 && hsr.getParameter(parameterName).length() > 0;
276 if (log.isTraceEnabled()) {
277 log.trace("Parameter " + parameterName + " isSet: " + retVal + " with value: " + hsr.getParameter(parameterName) + ")");
278 }
279 return retVal;
280 }
281
282 public static Map<String, String> copyParameterMap(HttpServletRequest httpServletRequest) {
283 Map<String, String> ret = new HashMap<String, String>();
284 for (Object key : httpServletRequest.getParameterMap().keySet()) {
285 ret.put((String) key, httpServletRequest.getParameter((String) key));
286 }
287 return ret;
288 }
289
290 }