Skip to content
This repository has been archived by the owner on Nov 30, 2023. It is now read-only.

Commit

Permalink
Add jsonld deserialization filter, fix, test
Browse files Browse the repository at this point in the history
  • Loading branch information
birkland committed Mar 9, 2018
1 parent 1424cef commit a6768b6
Show file tree
Hide file tree
Showing 20 changed files with 619 additions and 24 deletions.
7 changes: 7 additions & 0 deletions jsonld-addon-filters/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,13 @@
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.apache.jena</groupId>
<artifactId>jena-core</artifactId>
<version>3.6.0</version>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
* limitations under the License.
*/

package org.dataconservancy.fcrepo.jsonld.compact;
package org.dataconservancy.fcrepo.jsonld;

import static java.util.stream.Stream.concat;

Expand All @@ -30,7 +30,7 @@
*
* @author [email protected]
*/
class ConfigUtil {
public class ConfigUtil {

static final Logger LOG = LoggerFactory.getLogger(ConfigUtil.class);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@
* limitations under the License.
*/

package org.dataconservancy.fcrepo.jsonld.compact;
package org.dataconservancy.fcrepo.jsonld;

import static java.nio.charset.StandardCharsets.UTF_8;
import static org.dataconservancy.fcrepo.jsonld.compact.ConfigUtil.extract;
import static org.dataconservancy.fcrepo.jsonld.compact.ConfigUtil.props;
import static org.dataconservancy.fcrepo.jsonld.ConfigUtil.extract;
import static org.dataconservancy.fcrepo.jsonld.ConfigUtil.props;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@

package org.dataconservancy.fcrepo.jsonld.compact;

import static org.dataconservancy.fcrepo.jsonld.compact.ConfigUtil.getValue;
import static org.dataconservancy.fcrepo.jsonld.compact.JsonldUtil.loadContexts;
import static org.dataconservancy.fcrepo.jsonld.ConfigUtil.getValue;
import static org.dataconservancy.fcrepo.jsonld.JsonldUtil.loadContexts;

import java.io.IOException;
import java.net.MalformedURLException;
Expand All @@ -30,6 +30,7 @@
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
Expand Down Expand Up @@ -82,13 +83,22 @@ public void init(FilterConfig filterConfig) throws ServletException {
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,
ServletException {

LOG.debug("Servicing response");
LOG.debug("Compaction filter is considering response");

LOG.debug("Initial Output Stream: " + response.getOutputStream());
final CompactionWrapper compactionWrapper = new CompactionWrapper((HttpServletResponse) response, compactor,
defaultContext);
chain.doFilter(request, compactionWrapper);
compactionWrapper.getOutputStream().close();
final String method = ((HttpServletRequest) request).getMethod();

if (method.equalsIgnoreCase("GET")) {

LOG.debug("Compaction filter is compacting");
final CompactionWrapper compactionWrapper = new CompactionWrapper((HttpServletResponse) response,
compactor,
defaultContext);
chain.doFilter(request, compactionWrapper);
compactionWrapper.getOutputStream().close();
} else {
LOG.debug("Compaction filter is doing nothing");
chain.doFilter(request, response);
}
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ public void close() throws IOException {

@Override
public void setContentLength(int len) {
LOG.info("Ignoring content length of {}", len);
LOG.debug("Ignoring content length of {}", len);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/*
* Copyright 2017 Johns Hopkins University
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.dataconservancy.fcrepo.jsonld.deserialize;

import static org.dataconservancy.fcrepo.jsonld.JsonldUtil.loadContexts;

import java.io.IOException;
import java.util.Optional;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.github.jsonldjava.core.JsonLdOptions;

/**
* @author [email protected]
*/
public class DeserializationFilter implements Filter {

JsonldNtriplesTranslator translator;

private static final Logger LOG = LoggerFactory.getLogger(DeserializationFilter.class);

@Override
public void init(FilterConfig filterConfig) throws ServletException {
LOG.info("Initializing JSON-LD deserialiation");

final JsonLdOptions options = new JsonLdOptions();

loadContexts(options);

translator = new JsonldNtriplesTranslator();
translator.setOptions(options);
}

/**
* {@inheritDoc}
*/
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,
ServletException {

LOG.debug("Deserialization filter considering the request");

final String method = ((HttpServletRequest) request).getMethod();
final String contentType = Optional.ofNullable(
request.getContentType()).orElse(Optional.ofNullable(((HttpServletRequest) request).getHeader(
"content-type")).orElse(""));

if (("POST".equalsIgnoreCase(method) || "PUT".equalsIgnoreCase(method)) &&
contentType.contains("application/ld+json")) {
LOG.debug("Deserialization filter is deserializing JSON-LD");
chain.doFilter(new DeserializationWrapper((HttpServletRequest) request, translator), response);
} else {
LOG.debug("Deserialization filter is doing nothing: " + method + ", " + contentType);
chain.doFilter(request, response);
}
}

@Override
public void destroy() {

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
/*
* Copyright 2017 Johns Hopkins University
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.dataconservancy.fcrepo.jsonld.deserialize;

import static java.nio.charset.StandardCharsets.UTF_8;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.Collections;
import java.util.Enumeration;

import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;

import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* @author [email protected]
*/
class DeserializationWrapper extends HttpServletRequestWrapper {

private final ServletInputStream originalInputStream;

private final JsonldNtriplesTranslator transltor;

private static final Logger LOG = LoggerFactory.getLogger(DeserializationWrapper.class);

/**
* @param request
*/
public DeserializationWrapper(HttpServletRequest request, JsonldNtriplesTranslator translator) {
super(request);
try {
this.originalInputStream = request.getInputStream();
this.transltor = translator;
} catch (final IOException e) {
throw new RuntimeException(e);
}
}

@Override
public ServletInputStream getInputStream() {

return new ServletInputStream() {

final ByteArrayInputStream translatedOutputStream;

boolean finished = false;

{
try (InputStream in = originalInputStream) {

final String originalBody = IOUtils.toString(
originalInputStream, UTF_8);
LOG.debug("Original content: " + originalBody);

final String translatedBody = transltor.translate(originalBody);
LOG.debug("Translated content: " + translatedBody);
translatedOutputStream = new ByteArrayInputStream(translatedBody.getBytes(UTF_8));

} catch (final IOException e) {
throw new RuntimeException(e);
}
}

@Override
public int read() throws IOException {
final int byt = translatedOutputStream.read();
if (byt == -1) {
finished = true;
}
return byt;
}

@Override
public void setReadListener(ReadListener readListener) {
originalInputStream.setReadListener(readListener);
}

@Override
public boolean isReady() {
return true;
}

@Override
public boolean isFinished() {
return finished;
}

@Override
public void close() throws IOException {
translatedOutputStream.close();
}
};
}

@Override
public String getContentType() {
return "text/turtle";
}

@Override
public String getHeader(String name) {
if (name.equalsIgnoreCase("content-type")) {
return "text/turtle";
} else {
return super.getHeader(name);
}
}

@Override
public Enumeration<String> getHeaders(String name) {
if (name.equalsIgnoreCase("Content-Type")) {
return Collections.enumeration(Arrays.asList("text/turtle"));
} else {
return super.getHeaders(name);
}
}

@Override
public int getContentLength() {
return -1;
}

@Override
public long getContentLengthLong() {
return -1;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
* Copyright 2017 Johns Hopkins University
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.dataconservancy.fcrepo.jsonld.deserialize;

import static com.github.jsonldjava.utils.JsonUtils.fromString;

import java.io.IOException;
import java.net.URI;
import java.util.UUID;

import com.github.jsonldjava.core.JsonLdError;
import com.github.jsonldjava.core.JsonLdOptions;
import com.github.jsonldjava.core.JsonLdProcessor;
import com.github.jsonldjava.core.RDFDatasetUtils;

/**
* @author [email protected]
*/
public class JsonldNtriplesTranslator {

static final String NULL_RELATIVE = "null::" + UUID.randomUUID() + "::";

private JsonLdOptions options = new JsonLdOptions();

public void setOptions(JsonLdOptions options) {
this.options = options;
options.format = "application/nquads";
options.setBase(NULL_RELATIVE);
}

public String translate(String jsonld) {

URI.create(NULL_RELATIVE);
try {
return ((String) JsonLdProcessor.toRDF(fromString(jsonld), RDFDatasetUtils::toNQuads, options))
.replaceAll(NULL_RELATIVE, "");
} catch (JsonLdError | IOException e) {
throw new RuntimeException(e);
}
}
}
Loading

0 comments on commit a6768b6

Please sign in to comment.