001/*
002 * Copyright 2015 DuraSpace, Inc.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package org.fcrepo.http.api;
017
018import com.fasterxml.jackson.databind.ObjectMapper;
019import com.fasterxml.jackson.databind.node.ObjectNode;
020import com.google.common.annotations.VisibleForTesting;
021import com.hp.hpl.jena.graph.Node;
022import com.hp.hpl.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.kernel.api.exception.SessionMissingException;
027import org.fcrepo.kernel.api.exception.TombstoneException;
028import org.fcrepo.kernel.api.identifiers.IdentifierConverter;
029import org.fcrepo.kernel.api.models.FedoraResource;
030import org.fcrepo.kernel.api.models.Tombstone;
031import org.slf4j.Logger;
032
033import javax.inject.Inject;
034import javax.jcr.Session;
035import javax.jcr.observation.ObservationManager;
036import javax.ws.rs.core.HttpHeaders;
037import javax.ws.rs.core.UriInfo;
038
039import static org.slf4j.LoggerFactory.getLogger;
040
041/**
042 * @author cabeer
043 * @since 10/5/14
044 */
045abstract public class FedoraBaseResource extends AbstractResource {
046
047    private static final Logger LOGGER = getLogger(FedoraBaseResource.class);
048
049    @Inject
050    protected Session session;
051
052    protected IdentifierConverter<Resource, FedoraResource> idTranslator;
053
054    protected IdentifierConverter<Resource, FedoraResource> translator() {
055        if (idTranslator == null) {
056            idTranslator = new HttpResourceConverter(session(),
057                    uriInfo.getBaseUriBuilder().clone().path(FedoraLdp.class));
058        }
059
060        return idTranslator;
061    }
062
063    /**
064     * This is a helper method for using the idTranslator to convert this resource into an associated Jena Node.
065     *
066     * @param resource to be converted into a Jena Node
067     * @return the Jena node
068     */
069    protected Node asNode(final FedoraResource resource) {
070        return translator().reverse().convert(resource).asNode();
071    }
072
073    /**
074     * Get the FedoraResource for the resource at the external path
075     * @param externalPath the external path
076     * @return the fedora resource at the external path
077     */
078    @VisibleForTesting
079    public FedoraResource getResourceFromPath(final String externalPath) {
080        final Resource resource = translator().toDomain(externalPath);
081        final FedoraResource fedoraResource = translator().convert(resource);
082
083        if (fedoraResource instanceof Tombstone) {
084            throw new TombstoneException(fedoraResource, resource.getURI() + "/fcr:tombstone");
085        }
086
087        return fedoraResource;
088    }
089
090    /**
091     * Set the baseURL for JMS events.
092     * @param uriInfo the uri info
093     * @param headers HTTP headers
094     **/
095    protected void setUpJMSInfo(final UriInfo uriInfo, final HttpHeaders headers) {
096        try {
097            String baseURL = getBaseUrlProperty();
098            if (baseURL.length() == 0) {
099                baseURL = uriInfo.getBaseUri().toString();
100            }
101            LOGGER.debug("setting baseURL = " + baseURL);
102            final ObservationManager obs = session().getWorkspace().getObservationManager();
103            final ObjectMapper mapper = new ObjectMapper();
104            final ObjectNode json = mapper.createObjectNode();
105            json.put("baseURL", baseURL);
106            if (!StringUtils.isBlank(headers.getHeaderString("user-agent"))) {
107                json.put("userAgent", headers.getHeaderString("user-agent"));
108            }
109            obs.setUserData(mapper.writeValueAsString(json));
110        } catch (final Exception ex) {
111            LOGGER.warn("Error setting baseURL", ex.getMessage());
112        }
113    }
114
115    /**
116     * Produce a baseURL for JMS events using the system property fcrepo.jms.baseUrl of the form http[s]://host[:port],
117     * if it exists.
118     *
119     * @return String the base Url
120     */
121    protected String getBaseUrlProperty() {
122        final String propBaseURL = System.getProperty("fcrepo.jms.baseUrl", "");
123        if (propBaseURL.length() > 0 && propBaseURL.startsWith("http")) {
124            return uriInfo.getBaseUriBuilder().uri(propBaseURL).toString();
125        }
126        return "";
127    }
128
129    protected Session session() {
130        if (session == null) {
131            throw new SessionMissingException("Invalid session");
132        }
133        return session;
134    }
135}