
com.bigdata.rdf.sail.webapp.client.AcceptHeaderFactory Maven / Gradle / Ivy
Show all versions of bigdata-client Show documentation
/**
Copyright (C) SYSTAP, LLC DBA Blazegraph 2006-2016. All rights reserved.
Contact:
SYSTAP, LLC DBA Blazegraph
2501 Calvert ST NW #106
Washington, DC 20008
[email protected]
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
* Copyright Aduna (http://www.aduna-software.com/) (c) 1997-2007.
*
* Licensed under the Aduna BSD-style license.
*/
/*
* Created on Mar 27, 2012
*/
package com.bigdata.rdf.sail.webapp.client;
import info.aduna.lang.FileFormat;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import org.openrdf.query.resultio.BooleanQueryResultFormat;
import org.openrdf.query.resultio.BooleanQueryResultParserRegistry;
import org.openrdf.query.resultio.TupleQueryResultFormat;
import org.openrdf.query.resultio.TupleQueryResultParserRegistry;
import org.openrdf.rio.RDFFormat;
import org.openrdf.rio.RDFParserRegistry;
/**
* Utility class for generating accept heades modeled on
* {@link RDFFormat#getAcceptParams(Iterable, boolean, RDFFormat)}, but extended
* to handle {@link TupleQueryResultFormat} using the same base quality value.
*
* @author Bryan Thompson
* @version $Id$
*
* TODO Add a parameter for SID support or just specify as the
* preferredFormat when the database is using SIDs (or for any bigdata
* database if we support SIDs in all modes).
*
* TODO It would be nice if the formats indicated their compactness and
* unicode support capability. Given that other things are equal, we
* would prefer a format which was compact and supported unicode.
*/
public class AcceptHeaderFactory {
private static final int defaultQValue = 10;
/**
*
* @param rdfFormats
* @param requireContext
* @param preferredFormat
* @return
*/
public static List getAcceptParams(
final Iterable rdfFormats, //
final boolean requireContext,//
final RDFFormat preferredFormat//
) {
final List acceptParams = new LinkedList();
for (RDFFormat format : rdfFormats) {
// Determine a q-value that reflects the necessity of context
// support and the user specified preference
int qValue = defaultQValue;
if (requireContext && !format.supportsContexts()) {
// Prefer context-supporting formats over pure triple-formats
qValue -= 5;
}
if (preferredFormat != null && !preferredFormat.equals(format)) {
// Prefer specified format over other formats
qValue -= 2;
}
if (!format.supportsNamespaces()) {
// We like reusing namespace prefixes
qValue -= 1;
}
for (String mimeType : format.getMIMETypes()) {
// Default is the bare mime type.
String acceptParam = mimeType;
if (qValue < 10) {
// Annotate with the factional quality score.
acceptParam += ";q=0." + qValue;
}
acceptParams.add(acceptParam);
}
}
return acceptParams;
}
/**
* Return a set of accept header values annotated with quality scores.
*
* @param formats
* The set of formats which can be accepted.
* @param preferredFormat
* The preferred format (optional).
*
* @return The list of accept header values with quality scores.
*/
public static List getAcceptParams(
final Iterable formats,
final T preferredFormat) {
final List acceptParams = new LinkedList();
for (T format : formats) {
// Determine a q-value that reflects the user specified preference
int qValue = defaultQValue;
if (preferredFormat != null && !preferredFormat.equals(format)) {
// Prefer specified format over other formats
qValue -= 2;
}
for (String mimeType : format.getMIMETypes()) {
// Default is the bare mime type
String acceptParam = mimeType;
if (qValue < 10) {
// Annotate with the factional quality score.
acceptParam += ";q=0." + qValue;
}
acceptParams.add(acceptParam);
}
}
return acceptParams;
}
/**
* Return an accept header which establishes a preference pattern for graph
* data. The accept header will not include any formats for which we can not
* discover a parser.
*/
public static String getDefaultGraphAcceptHeader(final boolean requireContext) {
// Copy into a Set.
final Set values = new LinkedHashSet(
RDFFormat.values());
final RDFParserRegistry registry = RDFParserRegistry.getInstance();
final Iterator itr = values.iterator();
while (itr.hasNext()) {
final RDFFormat format = itr.next();
if (registry.get(format) == null) {
/*
* Remove any format for which there is no registered parser.
*/
itr.remove();
}
}
final List list1 = AcceptHeaderFactory.getAcceptParams(values,
requireContext, RDFFormat.BINARY);
return toString(list1);
}
/**
* Return an accept header which establishes a preference pattern for
* solution set data. The accept header will not include any formats for
* which we can not discover a parser.
*
* Note: You CAN NOT just combine the accept headers for boolean results and
* solution sets together because the boolean format overlaps the solution
* set format (they are both [application/sparql-results+xml] so putting
* them together blurs the quality annotations.
*/
public static String getDefaultSolutionsAcceptHeader() {
// Copy into a Set.
final Set values = new LinkedHashSet(
TupleQueryResultFormat.values());
final TupleQueryResultParserRegistry registry = TupleQueryResultParserRegistry
.getInstance();
final Iterator itr = values.iterator();
while (itr.hasNext()) {
final TupleQueryResultFormat format = itr.next();
if (registry.get(format) == null) {
/*
* Remove any format for which there is no registered parser.
*
* Note: For example, the JSON parser does not exist for openrdf
* 2.6.3.
*/
itr.remove();
}
}
final List list2 = AcceptHeaderFactory.getAcceptParams(values,
TupleQueryResultFormat.BINARY);
return toString(list2);
}
/**
* Return an accept header which establishes a preference pattern for
* boolean data. The accept header will not include any formats for
* which we can not discover a parser.
*/
public static String getDefaultBooleanAcceptHeader() {
// Copy into a Set.
final Set values = new LinkedHashSet(
BooleanQueryResultFormat.values());
final BooleanQueryResultParserRegistry registry = BooleanQueryResultParserRegistry
.getInstance();
final Iterator itr = values.iterator();
while (itr.hasNext()) {
final BooleanQueryResultFormat format = itr.next();
if (registry.get(format) == null) {
/*
* Remove any format for which there is no registered parser.
*/
itr.remove();
}
}
final List list3 = AcceptHeaderFactory.getAcceptParams(
values,
BooleanQueryResultFormat.SPARQL);
return toString(list3);
}
/**
* Convert into a comma delimited list.
*
* @param values
* The values.
*
* @return The comma delimited list.
*/
private static String toString(final Iterable values) {
final StringBuilder sb = new StringBuilder();
boolean first = true;
for (String s : values) {
if (first) {
first = false;
} else {
sb.append(",");
}
sb.append(s);
}
final String s = sb.toString();
return s;
}
}