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.rdf.model.RDFWriter;
028 import com.jamonapi.Monitor;
029 import com.jamonapi.MonitorFactory;
030 import org.nlp2rdf.core.ErrorHandling;
031 import org.slf4j.Logger;
032 import org.slf4j.LoggerFactory;
033
034 import javax.servlet.ServletException;
035 import javax.servlet.http.HttpServlet;
036 import javax.servlet.http.HttpServletRequest;
037 import javax.servlet.http.HttpServletResponse;
038 import java.io.*;
039 import java.security.InvalidParameterException;
040
041
042 public abstract class NIFServlet extends HttpServlet {
043 private static Logger log = LoggerFactory.getLogger(NIFServlet.class);
044 private int counter = 0;
045
046 @Override
047 protected void doGet(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws ServletException, IOException {
048 handle(httpServletRequest, httpServletResponse);
049 }
050
051 @Override
052 protected void doPost(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws ServletException, IOException {
053 handle(httpServletRequest, httpServletResponse);
054 }
055
056 public abstract void execute(NIFParameters nifParameters, OntModel diff) throws Exception;
057
058 /**
059 * this method answers GET and POST requests, which are treated the same.
060 * - Validates parameters
061 * - does the work (execute)
062 *
063 * @param httpServletRequest
064 * @param httpServletResponse
065 * @throws ServletException
066 * @throws IOException
067 */
068 private void handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws ServletException, IOException {
069
070 //this is the model that will be filled in the execute method
071 OntModel model = ModelFactory.createOntologyModel(OntModelSpec.OWL_DL_MEM, ModelFactory.createDefaultModel());
072 String requestUrl = httpServletRequest.getRequestURL().toString();
073 NIFParameters nifParameters = null;
074 try {
075
076 //Validate and normalize input
077 Monitor mon = MonitorFactory.getTimeMonitor("NIFParameters.getInstance").start();
078 nifParameters = NIFParameters.getInstance(httpServletRequest);
079 log.debug("NIFParameters Object created: " + logMonitor(mon.stop()));
080
081 //execute the task
082 mon = MonitorFactory.getTimeMonitor("NIFServlet.execute").start();
083
084 execute(nifParameters, model);
085 log.debug("NIF Component executed task: " + logMonitor(mon.stop()));
086 long triplesFromComponent = model.size();
087
088 //output is an inofficial parameter, fully merges input and output
089 long triplesFromInput = 0;
090 if (nifParameters.inputWasRDF() && nifParameters.getOutput().equals("full")) {
091 OntModel inputModel = nifParameters.getInputAsOntModel();
092 //merge
093 model.add(inputModel);
094 triplesFromInput = inputModel.size();
095 }
096
097
098 //write the response
099 write(httpServletResponse, model, nifParameters.getFormat());
100 log.info("output (" + nifParameters.getFormat() + ", " + nifParameters.getOutput() + ") written, triples from input: " + triplesFromInput + ", added by component: " + triplesFromComponent);
101 writeJamonLog();
102
103 } catch (IllegalArgumentException e) {
104 String msg = e.getMessage() + printParameterMap(httpServletRequest);
105 log.error(msg);
106 eu.lod2.nlp2rdf.schema.error.Error fatalerror = ErrorHandling.createError(true, requestUrl, msg, model);
107 fatalerror.addSource(requestUrl);
108 if (nifParameters != null) {
109 write(httpServletResponse, model, nifParameters.getFormat());
110 } else {
111 write(httpServletResponse, model, "rdfxml");
112 }
113
114 } catch (Exception e) {
115 String msg = "An error occured: " + e.getMessage() + printParameterMap(httpServletRequest);
116 log.error(msg, e);
117 eu.lod2.nlp2rdf.schema.error.Error fatalerror = ErrorHandling.createError(true, requestUrl, msg, model);
118 fatalerror.addSource(requestUrl);
119 if (nifParameters != null) {
120 write(httpServletResponse, model, nifParameters.getFormat());
121 } else {
122 write(httpServletResponse, model, "rdfxml");
123 }
124 }
125 }
126
127 protected static String logMonitor(Monitor m) {
128 return "needed: " + m.getLastValue() + " ms. (" + m.getTotal() + " total)";
129 }
130
131 protected void write(HttpServletResponse httpServletResponse, OntModel out, String format) throws IOException {
132 if (format.equalsIgnoreCase("rdfxml")) {
133 write(httpServletResponse, out, "RDF/XML", "application/rdf+xml");
134 } else if (format.equalsIgnoreCase("turtle")) {
135 write(httpServletResponse, out, "TURTLE", "text/rdf+n3");
136 } else if (format.equalsIgnoreCase("n3")) {
137 write(httpServletResponse, out, "N3", "text/rdf+n3");
138 } else if (format.equalsIgnoreCase("ntriples")) {
139 write(httpServletResponse, out, "N-TRIPLE", "text/rdf+n3");
140 } else if (format.equalsIgnoreCase("json")) {
141 throw new InvalidParameterException("There is no JSON output implemented at the moment. Sorry!");
142 }
143
144 }
145
146 protected void write(HttpServletResponse httpServletResponse, OntModel out, String jenaFormat, String contentType) throws IOException {
147 httpServletResponse.setContentType(contentType);
148 httpServletResponse.setCharacterEncoding("UTF-8");
149
150 //there are some problems with dl-learner, if individuals are not typed correctly
151 /*for (ExtendedIterator<Individual> it = out.listIndividuals(); it.hasNext(); ) {
152 it.next().addOntClass(OWL.Thing);
153 }
154 for (ExtendedIterator<ObjectProperty> it = out.listObjectProperties(); it.hasNext(); ) {
155 it.next().addRDFType(OWL.ObjectProperty);
156 }
157 for (ExtendedIterator<DatatypeProperty> it = out.listDatatypeProperties(); it.hasNext(); ) {
158 it.next().addRDFType(OWL.DatatypeProperty);
159 }
160 for (ExtendedIterator<OntClass> it = out.listClasses(); it.hasNext(); ) {
161 it.next().addRDFType(OWL.Class);
162 } */
163
164 out.setNsPrefix("rdf", "http://www.w3.org/1999/02/22-rdf-syntax-ns#");
165 out.setNsPrefix("rdfs", "http://www.w3.org/2000/01/rdf-schema#");
166 out.setNsPrefix("owl", "http://www.w3.org/2002/07/owl#");
167
168
169 out.setNsPrefix("sso", "http://nlp2rdf.lod2.eu/schema/sso/");
170 out.setNsPrefix("str", "http://nlp2rdf.lod2.eu/schema/string/");
171 out.setNsPrefix("topic", "http://nlp2rdf.lod2.eu/schema/topic/");
172 out.setNsPrefix("error", "http://nlp2rdf.lod2.eu/schema/error/");
173
174
175 out.setNsPrefix("olia", "http://purl.org/olia/olia.owl#");
176 out.setNsPrefix("olia-top", "http://purl.org/olia/olia-top.owl#");
177 out.setNsPrefix("olia_system", "http://purl.org/olia/system.owl#");
178
179 out.setNsPrefix("penn", "http://purl.org/olia/penn.owl#");
180 out.setNsPrefix("penn-syntax", "http://purl.org/olia/penn-syntax.owl#");
181 out.setNsPrefix("stanford", "http://purl.org/olia/stanford.owl#");
182
183 out.setNsPrefix("brown", "http://purl.org/olia/brown.owl#");
184
185
186 //this is the printer where the output has to be on
187 PrintWriter pw = httpServletResponse.getWriter();
188 RDFWriter writer = out.getWriter(jenaFormat);
189 writer.setProperty("showXmlDeclaration", "true");
190 //writer.setProperty("showDoctypeDeclaration", "true");
191 writer.write(out, pw, "");
192 pw.close();
193
194
195 }
196
197
198 public static String printParameterMap(HttpServletRequest httpServletRequest) {
199
200 log.error("printing map:\n" +
201 httpServletRequest.getRequestURL() + "\n" +
202 httpServletRequest.getContextPath() + "\n" +
203 httpServletRequest + "\n" +
204 "parameters: " + httpServletRequest.getParameterMap().keySet() + "\n" +
205 "");
206 StringBuffer buf = new StringBuffer();
207 for (Object key : httpServletRequest.getParameterMap().keySet()) {
208 buf.append("\nParameter: " + key + " Values: ");
209 for (String s : httpServletRequest.getParameterValues((String) key)) {
210 buf.append(((s.length() > 200) ? s.substring(0, 200) + "..." : s) + " ");
211 }
212 }
213 return buf.toString();
214 }
215
216 public synchronized void writeJamonLog() {
217 counter++;
218 if (counter % 100 == 0) {
219 try {
220 // Create file
221 FileWriter fstream = new FileWriter("log/jamonlog.html");
222 BufferedWriter out = new BufferedWriter(fstream);
223 out.write(MonitorFactory.getReport());
224 //Close the output stream
225 out.close();
226 } catch (Exception e) {//Catch exception if any
227 //we don't care
228 //System.err.println("Error: " + e.getMessage());
229 }
230 }
231 }
232
233 }