blob: 1e9f8daaa6809003784913f5d2ed692209aeb013 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.jena.fuseki.servlets;
import static org.apache.jena.riot.WebContent.*;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.jena.atlas.web.MediaType;
import org.apache.jena.fuseki.DEF;
import org.apache.jena.fuseki.Fuseki;
import org.apache.jena.fuseki.system.ConNeg;
import org.apache.jena.fuseki.system.FusekiNetLib;
import org.apache.jena.query.Dataset;
import org.apache.jena.query.DatasetFactory;
import org.apache.jena.rdf.model.Model;
import org.apache.jena.riot.Lang;
import org.apache.jena.riot.RDFDataMgr;
import org.apache.jena.riot.RDFLanguages;
import org.apache.jena.riot.WebContent;
import org.apache.jena.shared.JenaException;
import org.apache.jena.web.HttpSC;
public class ResponseDataset
{
// Short names for "output="
private static final String contentOutputJSONLD = "json-ld";
private static final String contentOutputJSONRDF = "json-rdf";
private static final String contentOutputJSON = "json";
private static final String contentOutputXML = "xml";
private static final String contentOutputText = "text";
private static final String contentOutputTTL = "ttl";
private static final String contentOutputNT = "nt";
private static final String contentOutputTriG = "trig";
private static final String contentOutputNQuads = "n-quads";
public static Map<String,String> shortNamesModel = new HashMap<>();
static {
// Some short names. keys are lowercase.
ResponseOps.put(shortNamesModel, contentOutputJSONLD, contentTypeJSONLD);
ResponseOps.put(shortNamesModel, contentOutputJSONRDF, contentTypeRDFJSON);
ResponseOps.put(shortNamesModel, contentOutputJSON, contentTypeJSONLD);
ResponseOps.put(shortNamesModel, contentOutputXML, contentTypeRDFXML);
ResponseOps.put(shortNamesModel, contentOutputText, contentTypeTurtle);
ResponseOps.put(shortNamesModel, contentOutputTTL, contentTypeTurtle);
ResponseOps.put(shortNamesModel, contentOutputNT, contentTypeNTriples);
ResponseOps.put(shortNamesModel, contentOutputNQuads, WebContent.contentTypeNQuads);
ResponseOps.put(shortNamesModel, contentOutputTriG, WebContent.contentTypeTriG);
}
public static void doResponseModel(HttpAction action, Model model) {
Dataset ds = DatasetFactory.create(model);
ResponseDataset.doResponseDataset(action, ds);
}
public static void doResponseDataset(HttpAction action, Dataset dataset) {
HttpServletRequest request = action.request;
HttpServletResponse response = action.response;
String mimeType = null; // Header request type
MediaType i = ConNeg.chooseContentType(request, DEF.constructOffer, DEF.acceptTurtle);
if ( i != null )
mimeType = i.getContentType();
String outputField = ResponseOps.paramOutput(request, shortNamesModel);
if ( outputField != null )
mimeType = outputField;
String writerMimeType = mimeType;
if ( mimeType == null ) {
Fuseki.actionLog.warn("Can't find MIME type for response");
String x = FusekiNetLib.getAccept(request);
String msg;
if ( x == null )
msg = "No Accept: header";
else
msg = "Accept: " + x + " : Not understood";
ServletOps.error(HttpSC.NOT_ACCEPTABLE_406, msg);
}
String contentType = mimeType;
String charset = charsetUTF8;
String forceAccept = ResponseOps.paramForceAccept(request);
if ( forceAccept != null ) {
contentType = forceAccept;
charset = charsetUTF8;
}
Lang lang = RDFLanguages.contentTypeToLang(contentType);
if ( lang == null )
ServletOps.errorBadRequest("Can't determine output content type: "+contentType);
try {
ResponseOps.setHttpResponse(action, contentType, charset);
response.setStatus(HttpSC.OK_200);
ServletOutputStream out = response.getOutputStream();
try {
if ( RDFLanguages.isQuads(lang) )
RDFDataMgr.write(out, dataset, lang);
else
RDFDataMgr.write(out, dataset.getDefaultModel(), lang);
out.flush();
} catch (JenaException ex) {
// Some RDF/XML data is unwritable. All we can do is pretend it's a bad
// request (inappropriate content type).
if ( lang.equals(Lang.RDFXML) )
ServletOps.errorBadRequest("Failed to write output in RDF/XML: "+ex.getMessage());
else
ServletOps.errorOccurred("Failed to write output: "+ex.getMessage(), ex);
}
}
catch (ActionErrorException ex) { throw ex; }
catch (Exception ex) {
action.log.info("Exception while writing the response model: "+ex.getMessage(), ex);
ServletOps.errorOccurred("Exception while writing the response model: "+ex.getMessage(), ex);
}
}
}