/* * 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.conneg.ConNeg; import org.apache.jena.fuseki.conneg.WebLib; 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<String, String>() ; 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 = WebLib.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 { ResponseResultSet.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) ; } } }