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.sparql.resultset.ResultsFormat.FMT_UNKNOWN;
019import static java.util.Collections.singletonList;
020import static org.fcrepo.transform.http.responses.ResultSetStreamingOutput.getResultsFormat;
021import static org.slf4j.LoggerFactory.getLogger;
022
023import java.io.OutputStream;
024import java.lang.annotation.Annotation;
025import java.lang.reflect.Type;
026
027import javax.ws.rs.core.MediaType;
028import javax.ws.rs.core.MultivaluedMap;
029import javax.ws.rs.ext.MessageBodyWriter;
030import javax.ws.rs.ext.Provider;
031
032import org.slf4j.Logger;
033import org.springframework.stereotype.Component;
034
035import com.hp.hpl.jena.query.QueryExecution;
036import com.hp.hpl.jena.query.ResultSet;
037
038/**
039 * Helper for writing QueryExecutions results out in a variety
040 * of serialization formats.
041 *
042 * @author cbeer
043 */
044@Provider
045@Component
046public class QueryExecutionProvider implements MessageBodyWriter<QueryExecution> {
047
048    private static final Logger LOGGER = getLogger(QueryExecutionProvider.class);
049
050    private static final ResultSetStreamingOutput resultSetStreamingOutput = new ResultSetStreamingOutput();
051
052    @Override
053    public void writeTo(final QueryExecution qexec, final Class<?> type,
054            final Type genericType, final Annotation[] annotations,
055            final MediaType mediaType,
056            final MultivaluedMap<String, Object> httpHeaders,
057            final OutputStream entityStream) {
058
059        LOGGER.debug("Writing a response for: {} with MIMEtype: {}", qexec,
060                        mediaType);
061
062        // add standard headers
063        httpHeaders.put("Content-type", singletonList((Object) mediaType.toString()));
064
065        try {
066            final ResultSet resultSet = qexec.execSelect();
067
068            resultSetStreamingOutput.writeTo(resultSet, type, genericType,
069                    annotations, mediaType, httpHeaders, entityStream);
070        } finally {
071            qexec.close();
072        }
073    }
074
075    @Override
076    public boolean isWriteable(final Class<?> type, final Type genericType,
077            final Annotation[] annotations, final MediaType mediaType) {
078
079        // we can return a result for any MIME type that Jena can serialize
080        final Boolean appropriateResultType =
081            getResultsFormat(mediaType) != FMT_UNKNOWN;
082        return appropriateResultType
083                && (QueryExecution.class.isAssignableFrom(type) || QueryExecution.class
084                        .isAssignableFrom(genericType.getClass()));
085    }
086
087    @Override
088    public long getSize(final QueryExecution rdf, final Class<?> type,
089            final Type genericType, final Annotation[] annotations,
090            final MediaType mediaType) {
091        // we don't know in advance how large the result might be
092        return -1;
093    }
094
095}