Skip to content
This repository has been archived by the owner on Oct 12, 2021. It is now read-only.

New UniversalResourceSingleProvider to support more RDF formats #76

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
language: java

jdk:
- oraclejdk8
- openjdk8
- openjdk11

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2012 IBM Corporation.
* Copyright (c) 2012, 2018 IBM Corporation and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
Expand All @@ -15,42 +15,61 @@
* Alberto Giammaria - initial API and implementation
* Chris Peters - initial API and implementation
* Gianluca Bernardini - initial API and implementation
* Andrew Berezovskyi - refactoring and new media types
*******************************************************************************/
package org.eclipse.lyo.oslc4j.core.model;

import javax.ws.rs.core.MediaType;

public interface OslcMediaType {

public final static String APPLICATION = "application";
public final static String TEXT = "text";
String APPLICATION_RDF_XML = "application/rdf+xml";
MediaType APPLICATION_RDF_XML_TYPE = MediaType.valueOf(APPLICATION_RDF_XML);

public final static String RDF_XML = "rdf+xml";
public final static String APPLICATION_RDF_XML = APPLICATION + "/" + RDF_XML;
public final static MediaType APPLICATION_RDF_XML_TYPE = new MediaType(APPLICATION, RDF_XML);
String APPLICATION_JSON_LD = "application/ld+json";
MediaType APPLICATION_JSON_LD_TYPE = MediaType.valueOf(APPLICATION_JSON_LD);

public final static String JSON_LD = "ld+json";
public final static String APPLICATION_JSON_LD = APPLICATION + "/" + JSON_LD;
public final static MediaType APPLICATION_JSON_LD_TYPE = new MediaType(APPLICATION, JSON_LD);
String TEXT_TURTLE = "text/turtle";
MediaType TEXT_TURTLE_TYPE = MediaType.valueOf(TEXT_TURTLE);

public final static String APPLICATION_JSON = MediaType.APPLICATION_JSON;
public final static MediaType APPLICATION_JSON_TYPE = MediaType.APPLICATION_JSON_TYPE;
String RDF_JSON_MIME = "application/rdf+json";
MediaType RDF_JSON_MT = MediaType.valueOf(RDF_JSON_MIME);

public final static String APPLICATION_XML = MediaType.APPLICATION_XML;
public final static MediaType APPLICATION_XML_TYPE = MediaType.APPLICATION_XML_TYPE;
String N_TRIPLES_MIME = "application/n-triples";
MediaType N_TRIPLES_MT = MediaType.valueOf(N_TRIPLES_MIME);

public final static String TEXT_XML = MediaType.TEXT_XML;
public final static MediaType TEXT_XML_TYPE = MediaType.TEXT_XML_TYPE;
// OSLC specific serialisations

public final static String TURTLE="turtle";
public final static String TEXT_TURTLE = TEXT + "/" + TURTLE;
public final static MediaType TEXT_TURTLE_TYPE = new MediaType(TEXT, TURTLE);
String APPLICATION_X_OSLC_COMPACT_XML = "application" + "/" + "x-oslc-compact+xml";
MediaType APPLICATION_X_OSLC_COMPACT_XML_TYPE = new MediaType("application",
"x-oslc-compact+xml");

public final static String X_OSLC_COMPACT_XML = "x-oslc-compact+xml";
public final static String APPLICATION_X_OSLC_COMPACT_XML = APPLICATION + "/" + X_OSLC_COMPACT_XML;
public final static MediaType APPLICATION_X_OSLC_COMPACT_XML_TYPE = new MediaType(APPLICATION, X_OSLC_COMPACT_XML);
String APPLICATION_X_OSLC_COMPACT_JSON = "application/x-oslc-compact+json";
MediaType APPLICATION_X_OSLC_COMPACT_JSON_TYPE = new MediaType("application",
"x-oslc-compact+json");

// Non-standard RDF serialisations

String APPLICATION_JSON = MediaType.APPLICATION_JSON;
MediaType APPLICATION_JSON_TYPE = MediaType.APPLICATION_JSON_TYPE;

String APPLICATION_XML = MediaType.APPLICATION_XML;
MediaType APPLICATION_XML_TYPE = MediaType.APPLICATION_XML_TYPE;

String TEXT_XML = MediaType.TEXT_XML;
MediaType TEXT_XML_TYPE = MediaType.TEXT_XML_TYPE;

String RDF_THRIFT_MIME = "application/rdf+thrift";
MediaType RDF_THRIFT_MT = MediaType.valueOf(RDF_THRIFT_MIME);

// Deprecated

@Deprecated String APPLICATION = "application";
@Deprecated String TEXT = "text";
@Deprecated String RDF_XML = "rdf+xml";
@Deprecated String JSON_LD = "ld+json";
@Deprecated String TURTLE = "turtle";
@Deprecated String X_OSLC_COMPACT_XML = "x-oslc-compact+xml";
@Deprecated String X_OSLC_COMPACT_JSON = "x-oslc-compact+json";

public final static String X_OSLC_COMPACT_JSON = "x-oslc-compact+json"; // TODO - Compact media type never defined in the OSLC spec for JSON
public final static String APPLICATION_X_OSLC_COMPACT_JSON = APPLICATION + "/" + X_OSLC_COMPACT_JSON;
public final static MediaType APPLICATION_X_OSLC_COMPACT_JSON_TYPE = new MediaType(APPLICATION, X_OSLC_COMPACT_JSON);
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@
import org.apache.jena.util.FileUtils;
import org.eclipse.lyo.oslc4j.core.OSLC4JConstants;
import org.eclipse.lyo.oslc4j.core.OSLC4JUtils;
import org.eclipse.lyo.oslc4j.core.annotation.OslcNotQueryResult;
import org.eclipse.lyo.oslc4j.core.annotation.OslcResourceShape;
import org.eclipse.lyo.oslc4j.core.exception.MessageExtractor;
import org.eclipse.lyo.oslc4j.core.model.Error;
import org.eclipse.lyo.oslc4j.core.model.OslcMediaType;
Expand All @@ -48,7 +50,7 @@
/**
* @author Russell Boykin, Alberto Giammaria, Chris Peters, Gianluca Bernardini, Andrew Berezovskyi
*/
public abstract class AbstractOslcRdfXmlProvider
public abstract class AbstractOslcRdfXmlProvider extends AbstractRdfProvider
{
private static final Logger log = LoggerFactory.getLogger(AbstractOslcRdfXmlProvider.class.getName
());
Expand Down Expand Up @@ -85,6 +87,21 @@ protected AbstractOslcRdfXmlProvider()
super();
}

protected static boolean isWriteable(final Class<?> type,
final Annotation[] annotations,
final MediaType actualMediaType,
final MediaType ... requiredMediaTypes)
{
if (type.getAnnotation(OslcResourceShape.class) != null ||
type.getAnnotation(OslcNotQueryResult.class) != null)
{
// We do not have annotations when running from the non-web client.
return isCompatible(actualMediaType, requiredMediaTypes);
}

return false;
}

protected void writeTo(final Object[] objects,
final MediaType baseMediaType,
final MultivaluedMap<String, Object> map,
Expand Down Expand Up @@ -280,6 +297,32 @@ private String getSerializationLanguage(final MediaType baseMediaType) {
throw new IllegalArgumentException("Base media type can't be matched to any writer");
}

protected static boolean isReadable(final Class<?> type,
final MediaType actualMediaType,
final MediaType ... requiredMediaTypes)
{
if (type.getAnnotation(OslcResourceShape.class) != null)
{
return isCompatible(actualMediaType, requiredMediaTypes);
}

return false;
}

protected static boolean isCompatible(final MediaType actualMediaType,
final MediaType... requiredMediaTypes)
{
for (final MediaType requiredMediaType : requiredMediaTypes)
{
if (requiredMediaType.isCompatible(actualMediaType))
{
return true;
}
}

return false;
}

protected Object[] readFrom(final Class<?> type,
final MediaType mediaType,
final MultivaluedMap<String, String> map,
Expand Down Expand Up @@ -430,4 +473,17 @@ private boolean isAcceptableMediaType(final MediaType mediaType)
ANNOTATIONS_EMPTY_ARRAY,
mediaType) != null);
}

protected static boolean isOslcQuery(final String parmString)
{
boolean containsOslcParm = false;

final String [] uriParts = parmString.toLowerCase().split("oslc\\.",2);
if (uriParts.length > 1)
{
containsOslcParm = true;
}

return containsOslcParm;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
/*!*****************************************************************************
* Copyright (c) 2019 Andrew Berezovskyi.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v. 1.0 which accompanies this distribution.
*
* The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
*
* Andrew Berezovskyi - initial implementation
*******************************************************************************/
package org.eclipse.lyo.oslc4j.provider.jena;

import java.io.InputStream;
import java.io.OutputStream;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import org.apache.jena.rdf.model.Model;
import org.apache.jena.rdf.model.ModelFactory;
import org.apache.jena.rdf.model.RDFWriter;
import org.apache.jena.riot.Lang;
import org.apache.jena.riot.RDFDataMgr;
import org.apache.jena.riot.RDFFormat;
import org.apache.jena.riot.RDFLanguages;
import org.apache.jena.util.FileUtils;
import org.eclipse.lyo.oslc4j.core.exception.MessageExtractor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* TODO
*
* @since 4.0.0
*/
public class AbstractRdfProvider {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should be an abstract class.


private final static Logger log = LoggerFactory.getLogger(AbstractRdfProvider.class);

protected void writeTo(final boolean queryResult, final Object[] objects,
final MediaType baseMediaType, final MultivaluedMap<String, Object> map,
final OutputStream outputStream) throws WebApplicationException {
String descriptionURI = null;
String responseInfoURI = null;

if (queryResult) {
throw new IllegalArgumentException(
"Query Result resources have to be constructed before marshalling");
}

writeNonQueryObjectsTo(objects, outputStream, baseMediaType);
}

protected void writeNonQueryObjectsTo(final Object[] objects, final OutputStream outputStream,
final MediaType serializationLanguage) {
try {
final Model model = JenaModelHelper.createJenaModel(objects);

RDFWriter writer = getRdfWriter(serializationLanguage.toString(), model);

if (serializationLanguage.equals(FileUtils.langXML) || serializationLanguage.equals(
FileUtils.langXMLAbbrev)) {
// XML (and Jena) default to UTF-8, but many libs default to ASCII, so need
// to set this explicitly
writer.setProperty("showXmlDeclaration", "false");
String xmlDeclaration = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
outputStream.write(xmlDeclaration.getBytes());
}
writer.write(model, outputStream, null);
} catch (final Exception exception) {
log.warn(MessageExtractor.getMessage("ErrorSerializingResource"), exception);
// TODO Andrew@2018-03-03: use another exception
throw new WebApplicationException(exception);
}
}

private RDFWriter getRdfWriter(final String serializationLanguage, final Model model) {
RDFWriter writer = null;
if (serializationLanguage.equals(FileUtils.langXMLAbbrev)) {
// TODO Andrew@2018-05-27: do this for the RDF/XML-ABBREV only iff the users want it
/* Personally, I don't like the idea of maintaining a separate ABBREV writer. I think
we need to start introducing some flags where users can disable legacy functionality
altogether and rely on Jena etc.*/
writer = new RdfXmlAbbreviatedWriter();
} else {
final Lang lang = RDFLanguages.nameToLang(serializationLanguage);
// RDFDataMgr.createGraphWriter(mapLang(lang));
// final Graph graph = model.getGraph();
writer = model.getWriter(lang.getName());
// FIXME Andrew@2018-05-27: what's the purpose of name>lang>name conversion?
}
return writer;
}

private RDFFormat mapLang(final Lang lang) {
// TODO Andrew@2018-05-27: allow configuration from users (compact vs pretty etc)
final RDFFormat rdfFormat = new RDFFormat(lang);
return rdfFormat;
}

/*=== READER ================================*/

protected Object[] readFrom(final Class<?> type, final MediaType mediaType,
final InputStream inputStream) throws WebApplicationException {
final Model model = ModelFactory.createDefaultModel();
RDFDataMgr.read(model, inputStream,
RDFDataMgr.determineLang(null, mediaType.toString(), null));
try {
return JenaModelHelper.unmarshal(model, type);
} catch (final Exception exception) {
// FIXME Andrew@2018-05-27: we shall just stop the JMH blanket of exceptions craziness
throw new RuntimeException(exception);
// throw new WebApplicationException(exception, buildBadRequestResponse(exception,
// mediaType,
// map));
}
}

}
Loading