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.camel.ldpath; 019 020import static org.slf4j.LoggerFactory.getLogger; 021 022import org.apache.marmotta.ldclient.api.endpoint.Endpoint; 023import org.apache.marmotta.ldclient.provider.rdf.LinkedDataProvider; 024import org.fcrepo.client.FcrepoHttpClientBuilder; 025import org.fcrepo.client.FcrepoLink; 026 027import java.io.IOException; 028import java.io.UncheckedIOException; 029import java.util.Collections; 030import java.util.List; 031import java.util.Objects; 032import java.util.Optional; 033 034import org.apache.http.client.HttpClient; 035import org.apache.http.client.methods.HttpHead; 036import org.apache.http.Header; 037import org.apache.http.HttpResponse; 038import org.slf4j.Logger; 039 040 041/** 042 * An extension Linked Data provider to support Binary nodes in Fedora. 043 * 044 * @author Mohamed Mohideen Abdul Rasheed 045 */ 046public class FedoraProvider extends LinkedDataProvider { 047 048 private static final Logger LOGGER = getLogger(FedoraProvider.class); 049 050 public static final String PROVIDER_NAME = "Fedora"; 051 052 private final HttpClient httpClient; 053 054 private final String NON_RDF_SOURCE_URI = "http://www.w3.org/ns/ldp#NonRDFSource"; 055 056 /** 057 * FedoraProvider 058 * @param builder FcrepoHttpClientBuilder for building HttpClient 059 */ 060 public FedoraProvider(final FcrepoHttpClientBuilder builder) { 061 Objects.requireNonNull(builder); 062 httpClient = builder.build(); 063 } 064 065 /* 066 * Return the name of this data provider. To be used e.g. in the configuration and in log messages. 067 */ 068 @Override 069 public String getName() { 070 return PROVIDER_NAME; 071 } 072 073 /* 074 * Return the describedBy URL for NonRdfSource resources. Return the resourseUri otherwise. 075 */ 076 @Override 077 public List<String> buildRequestUrl(final String resourceUri, final Endpoint endpoint) { 078 LOGGER.debug("Processing: " + resourceUri); 079 Objects.requireNonNull(resourceUri); 080 try { 081 final Optional<String> nonRdfSourceDescUri = 082 getNonRDFSourceDescribedByUri(resourceUri); 083 if ( nonRdfSourceDescUri.isPresent() ) { 084 return Collections.singletonList(nonRdfSourceDescUri.get()); 085 } 086 } catch (final IOException ex) { 087 throw new UncheckedIOException(ex); 088 } 089 return Collections.singletonList(resourceUri); 090 } 091 092 /* 093 * Get the describedBy Uri if the resource has a NON_RDF_SOURCE_URI link header. 094 */ 095 private Optional<String> getNonRDFSourceDescribedByUri(final String resourceUri) throws IOException { 096 Optional<String> nonRdfSourceDescUri = Optional.empty(); 097 final Header[] links = getLinkHeaders(resourceUri); 098 if ( links != null ) { 099 String descriptionUri = null; 100 boolean isNonRDFSource = false; 101 for ( final Header h : links ) { 102 final FcrepoLink link = new FcrepoLink(h.getValue()); 103 if ( link.getRel().equals("describedby") ) { 104 descriptionUri = link.getUri().toString(); 105 } else if ( link.getUri().toString().contains(NON_RDF_SOURCE_URI)) { 106 isNonRDFSource = true; 107 } 108 } 109 LOGGER.debug("isNonRDFSource: " + isNonRDFSource); 110 if (isNonRDFSource && descriptionUri != null) { 111 nonRdfSourceDescUri = Optional.of(descriptionUri); 112 } 113 } 114 return nonRdfSourceDescUri; 115 } 116 117 /* 118 * Get the link headers for the resource at the given Uri. 119 */ 120 private Header[] getLinkHeaders(final String resourceUri) throws IOException { 121 final HttpHead request = new HttpHead(resourceUri); 122 final HttpResponse response = httpClient.execute(request); 123 LOGGER.debug("Got: " + response.getStatusLine().getStatusCode() + " for HEAD " + resourceUri); 124 return response.getHeaders("Link"); 125 } 126 127}