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.kernel.impl.models;
019
020import static org.slf4j.LoggerFactory.getLogger;
021
022import javax.inject.Inject;
023
024import org.fcrepo.kernel.api.ContainmentIndex;
025import org.fcrepo.kernel.api.Transaction;
026import org.fcrepo.kernel.api.TransactionUtils;
027import org.fcrepo.kernel.api.exception.RepositoryRuntimeException;
028import org.fcrepo.kernel.api.identifiers.FedoraId;
029import org.fcrepo.kernel.api.models.ResourceHeaders;
030import org.fcrepo.kernel.api.models.ResourceHelper;
031import org.fcrepo.persistence.api.PersistentStorageSession;
032import org.fcrepo.persistence.api.PersistentStorageSessionManager;
033import org.fcrepo.persistence.api.exceptions.PersistentItemNotFoundException;
034import org.fcrepo.persistence.api.exceptions.PersistentStorageException;
035import org.fcrepo.persistence.common.ResourceHeadersImpl;
036import org.slf4j.Logger;
037import org.springframework.beans.factory.annotation.Autowired;
038import org.springframework.beans.factory.annotation.Qualifier;
039import org.springframework.stereotype.Component;
040
041/**
042 * Utility class for helper methods.
043 * @author whikloj
044 * @since 6.0.0
045 */
046@Component
047public class ResourceHelperImpl implements ResourceHelper {
048
049    private static final Logger LOGGER = getLogger(ResourceHeadersImpl.class);
050
051    @Inject
052    private PersistentStorageSessionManager persistentStorageSessionManager;
053
054    @Autowired
055    @Qualifier("containmentIndex")
056    private ContainmentIndex containmentIndex;
057
058    @Override
059    public boolean isGhostNode(final Transaction transaction, final FedoraId resourceId) {
060        if (!doesResourceExist(transaction, resourceId, true)) {
061            return containmentIndex.hasResourcesStartingWith(TransactionUtils.openTxId(transaction), resourceId);
062        }
063        return false;
064    }
065
066    @Override
067    public boolean doesResourceExist(final Transaction transaction, final FedoraId fedoraId,
068                                     final boolean includeDeleted) {
069        final String transactionId = TransactionUtils.openTxId(transaction);
070        if (fedoraId.isRepositoryRoot()) {
071            // Root always exists.
072            return true;
073        }
074        if (!(fedoraId.isMemento() || fedoraId.isAcl())) {
075            // containment index doesn't handle versions and only tells us if the resource (not acl) is there,
076            // so don't bother checking for them.
077            return containmentIndex.resourceExists(transactionId, fedoraId, includeDeleted);
078        } else {
079
080            final PersistentStorageSession psSession = getSession(transactionId);
081
082            try {
083                // Resource ID for metadata or ACL contains their individual endopoints (ie. fcr:metadata, fcr:acl)
084                final ResourceHeaders headers = psSession.getHeaders(fedoraId, fedoraId.getMementoInstant());
085                return !headers.isDeleted();
086            } catch (final PersistentItemNotFoundException e) {
087                // Object doesn't exist.
088                return false;
089            } catch (final PersistentStorageException e) {
090                // Other error, pass along.
091                throw new RepositoryRuntimeException(e.getMessage(), e);
092            }
093        }
094    }
095
096    /**
097     * Get a session for this interaction.
098     *
099     * @param transactionId The supplied transaction id.
100     * @return a storage session.
101     */
102    private PersistentStorageSession getSession(final String transactionId) {
103        final PersistentStorageSession session;
104        if (transactionId == null) {
105            session = persistentStorageSessionManager.getReadOnlySession();
106        } else {
107            session = persistentStorageSessionManager.getSession(transactionId);
108        }
109        return session;
110    }
111}