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