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