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.http.api; 019 020import com.google.common.annotations.VisibleForTesting; 021import org.apache.jena.graph.Node; 022import org.apache.jena.rdf.model.Resource; 023import org.apache.commons.lang3.StringUtils; 024import org.fcrepo.http.commons.AbstractResource; 025import org.fcrepo.http.commons.api.rdf.HttpResourceConverter; 026import org.fcrepo.http.commons.session.HttpSession; 027import org.fcrepo.kernel.api.exception.SessionMissingException; 028import org.fcrepo.kernel.api.exception.TombstoneException; 029import org.fcrepo.kernel.api.identifiers.IdentifierConverter; 030import org.fcrepo.kernel.api.models.FedoraResource; 031import org.fcrepo.kernel.api.models.Tombstone; 032import org.slf4j.Logger; 033 034import java.net.URI; 035import java.security.Principal; 036import java.util.regex.Pattern; 037import javax.inject.Inject; 038import javax.ws.rs.core.Context; 039import javax.ws.rs.core.HttpHeaders; 040import javax.ws.rs.core.SecurityContext; 041import javax.ws.rs.core.UriInfo; 042 043import static org.fcrepo.kernel.api.observer.OptionalValues.BASE_URL; 044import static org.fcrepo.kernel.api.observer.OptionalValues.USER_AGENT; 045import static org.slf4j.LoggerFactory.getLogger; 046 047/** 048 * @author cabeer 049 * @since 10/5/14 050 */ 051abstract public class FedoraBaseResource extends AbstractResource { 052 053 private static final Logger LOGGER = getLogger(FedoraBaseResource.class); 054 055 static final String JMS_BASEURL_PROP = "fcrepo.jms.baseUrl"; 056 057 private static final Pattern TRAILING_SLASH_REGEX = Pattern.compile("/+$"); 058 059 @Inject 060 protected HttpSession session; 061 062 @Context 063 protected SecurityContext securityContext; 064 065 protected IdentifierConverter<Resource, FedoraResource> idTranslator; 066 067 protected IdentifierConverter<Resource, FedoraResource> translator() { 068 if (idTranslator == null) { 069 idTranslator = new HttpResourceConverter(session(), 070 uriInfo.getBaseUriBuilder().clone().path(FedoraLdp.class)); 071 } 072 073 return idTranslator; 074 } 075 076 /** 077 * This is a helper method for using the idTranslator to convert this resource into an associated Jena Node. 078 * 079 * @param resource to be converted into a Jena Node 080 * @return the Jena node 081 */ 082 protected Node asNode(final FedoraResource resource) { 083 return translator().reverse().convert(resource).asNode(); 084 } 085 086 /** 087 * Get the FedoraResource for the resource at the external path 088 * @param externalPath the external path 089 * @return the fedora resource at the external path 090 */ 091 @VisibleForTesting 092 public FedoraResource getResourceFromPath(final String externalPath) { 093 final Resource resource = translator().toDomain(externalPath); 094 final FedoraResource fedoraResource = translator().convert(resource); 095 096 if (fedoraResource instanceof Tombstone) { 097 final String resourceURI = TRAILING_SLASH_REGEX.matcher(resource.getURI()).replaceAll(""); 098 throw new TombstoneException(fedoraResource, resourceURI + "/fcr:tombstone"); 099 } 100 101 return fedoraResource; 102 } 103 104 /** 105 * Set the baseURL for JMS events. 106 * @param uriInfo the uri info 107 * @param headers HTTP headers 108 **/ 109 protected void setUpJMSInfo(final UriInfo uriInfo, final HttpHeaders headers) { 110 try { 111 String baseURL = getBaseUrlProperty(uriInfo); 112 if (baseURL.length() == 0) { 113 baseURL = uriInfo.getBaseUri().toString(); 114 } 115 LOGGER.debug("setting baseURL = " + baseURL); 116 session.getFedoraSession().addSessionData(BASE_URL, baseURL); 117 if (!StringUtils.isBlank(headers.getHeaderString("user-agent"))) { 118 session.getFedoraSession().addSessionData(USER_AGENT, headers.getHeaderString("user-agent")); 119 } 120 } catch (final Exception ex) { 121 LOGGER.warn("Error setting baseURL", ex.getMessage()); 122 } 123 } 124 125 /** 126 * Produce a baseURL for JMS events using the system property fcrepo.jms.baseUrl of the form http[s]://host[:port], 127 * if it exists. 128 * 129 * @param uriInfo used to build the base url 130 * @return String the base Url 131 */ 132 private String getBaseUrlProperty(final UriInfo uriInfo) { 133 final String propBaseURL = System.getProperty(JMS_BASEURL_PROP, ""); 134 if (propBaseURL.length() > 0 && propBaseURL.startsWith("http")) { 135 final URI propBaseUri = URI.create(propBaseURL); 136 if (propBaseUri.getPort() < 0) { 137 return uriInfo.getBaseUriBuilder().port(-1).uri(propBaseUri).toString(); 138 } 139 return uriInfo.getBaseUriBuilder().uri(propBaseUri).toString(); 140 } 141 return ""; 142 } 143 144 private HttpSession session() { 145 if (session == null) { 146 throw new SessionMissingException("Invalid session"); 147 } 148 return session; 149 } 150 151 protected String getUserPrincipal() { 152 final Principal p = securityContext.getUserPrincipal(); 153 return p == null ? null : p.getName(); 154 } 155}