001/* 002 * Licensed to DuraSpace under one or more contributor license agreements. 003 * See the NOTICE file distributed with this work for additional information 004 * regarding copyright ownership. 005 * 006 * DuraSpace licenses this file to you under the Apache License, 007 * Version 2.0 (the "License"); you may not use this file except in 008 * compliance with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.fcrepo.transform.http.responses; 019 020import static com.hp.hpl.jena.query.ResultSetFormatter.output; 021import static com.hp.hpl.jena.query.ResultSetFormatter.toModel; 022import static com.hp.hpl.jena.sparql.resultset.ResultsFormat.FMT_RDF_NT; 023import static com.hp.hpl.jena.sparql.resultset.ResultsFormat.FMT_RDF_TTL; 024import static com.hp.hpl.jena.sparql.resultset.ResultsFormat.FMT_RDF_XML; 025import static com.hp.hpl.jena.sparql.resultset.ResultsFormat.FMT_RS_BIO; 026import static com.hp.hpl.jena.sparql.resultset.ResultsFormat.FMT_RS_CSV; 027import static com.hp.hpl.jena.sparql.resultset.ResultsFormat.FMT_RS_JSON; 028import static com.hp.hpl.jena.sparql.resultset.ResultsFormat.FMT_RS_TSV; 029import static com.hp.hpl.jena.sparql.resultset.ResultsFormat.FMT_RS_XML; 030import static com.hp.hpl.jena.sparql.resultset.ResultsFormat.FMT_UNKNOWN; 031import static org.apache.jena.riot.RDFLanguages.contentTypeToLang; 032import static org.apache.jena.riot.WebContent.contentTypeNTriples; 033import static org.apache.jena.riot.WebContent.contentTypeRDFXML; 034import static org.apache.jena.riot.WebContent.contentTypeResultsBIO; 035import static org.apache.jena.riot.WebContent.contentTypeResultsJSON; 036import static org.apache.jena.riot.WebContent.contentTypeResultsXML; 037import static org.apache.jena.riot.WebContent.contentTypeTextCSV; 038import static org.apache.jena.riot.WebContent.contentTypeTextTSV; 039import static org.apache.jena.riot.WebContent.contentTypeTurtle; 040import static org.apache.jena.riot.WebContent.contentTypeTurtleAlt1; 041import static org.apache.jena.riot.WebContent.contentTypeTurtleAlt2; 042 043import java.io.OutputStream; 044import java.lang.annotation.Annotation; 045import java.lang.reflect.Type; 046 047import javax.ws.rs.Produces; 048import javax.ws.rs.core.MediaType; 049import javax.ws.rs.core.MultivaluedMap; 050import javax.ws.rs.ext.MessageBodyWriter; 051import javax.ws.rs.ext.Provider; 052 053import org.apache.jena.riot.Lang; 054 055import com.hp.hpl.jena.query.ResultSet; 056import com.hp.hpl.jena.rdf.model.Model; 057import com.hp.hpl.jena.sparql.resultset.ResultsFormat; 058 059/** 060 * Stream the results of a SPARQL Query 061 * 062 * @author cbeer 063 */ 064@Provider 065@Produces({contentTypeTextTSV, contentTypeTextCSV, contentTypeResultsJSON, 066 contentTypeResultsXML, contentTypeResultsBIO, contentTypeTurtle, 067 contentTypeNTriples, contentTypeRDFXML}) 068public class ResultSetStreamingOutput implements MessageBodyWriter<ResultSet> { 069 070 071 072 @Override 073 public boolean isWriteable(final Class<?> type, 074 final Type genericType, 075 final Annotation[] annotations, 076 final MediaType mediaType) { 077 final ResultsFormat resultsFormat = getResultsFormat(mediaType); 078 079 if (resultsFormat == FMT_UNKNOWN) { 080 final Lang format = contentTypeToLang(mediaType.toString()); 081 082 return format != null; 083 } 084 return true; 085 } 086 087 @Override 088 public long getSize(final ResultSet resultSet, 089 final Class<?> type, 090 final Type genericType, 091 final Annotation[] annotations, 092 final MediaType mediaType) { 093 return -1; 094 } 095 096 @Override 097 public void writeTo(final ResultSet resultSet, 098 final Class<?> type, 099 final Type genericType, 100 final Annotation[] annotations, 101 final MediaType mediaType, 102 final MultivaluedMap<String, Object> httpHeaders, 103 final OutputStream entityStream) { 104 final ResultsFormat resultsFormat = getResultsFormat(mediaType); 105 106 if (resultsFormat == FMT_UNKNOWN) { 107 final String format = contentTypeToLang(mediaType.toString()).getName().toUpperCase(); 108 final Model model = toModel(resultSet); 109 model.write(entityStream, format); 110 } else { 111 output(entityStream, resultSet, resultsFormat); 112 } 113 } 114 115 /** 116 * Map the HTTP MediaType to a SPARQL ResultsFormat 117 * @param mediaType the media type 118 * @return SPARQL {@link ResultsFormat} for the given {@link MediaType} 119 */ 120 public static ResultsFormat getResultsFormat(final MediaType mediaType) { 121 switch (mediaType.toString()) { 122 case contentTypeTextTSV: 123 return FMT_RS_TSV; 124 125 case contentTypeTextCSV: 126 return FMT_RS_CSV; 127 128 case contentTypeResultsJSON: 129 return FMT_RS_JSON; 130 131 case contentTypeResultsXML: 132 return FMT_RS_XML; 133 134 case contentTypeResultsBIO: 135 return FMT_RS_BIO; 136 137 case contentTypeTurtle: 138 case contentTypeTurtleAlt1: 139 case contentTypeTurtleAlt2: 140 return FMT_RDF_TTL; 141 142 case contentTypeNTriples: 143 return FMT_RDF_NT; 144 145 case contentTypeRDFXML: 146 return FMT_RDF_XML; 147 default: 148 return FMT_UNKNOWN; 149 } 150 } 151}