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.services;
019
020import com.google.common.annotations.VisibleForTesting;
021import org.fcrepo.kernel.api.RdfLexicon;
022import org.fcrepo.kernel.api.Transaction;
023import org.fcrepo.kernel.api.exception.RepositoryRuntimeException;
024import org.fcrepo.kernel.api.identifiers.FedoraId;
025import org.fcrepo.kernel.api.operations.VersionResourceOperationFactory;
026import org.fcrepo.kernel.api.services.VersionService;
027import org.fcrepo.persistence.api.PersistentStorageSessionManager;
028import org.fcrepo.persistence.api.exceptions.PersistentStorageException;
029import org.springframework.stereotype.Component;
030
031import javax.inject.Inject;
032
033/**
034 * Implementation of {@link VersionService}
035 *
036 * @author dbernstein
037 */
038@Component
039public class VersionServiceImpl extends AbstractService implements VersionService {
040
041    @Inject
042    private PersistentStorageSessionManager psManager;
043
044    @Inject
045    private VersionResourceOperationFactory versionOperationFactory;
046
047    @Override
048    public void createVersion(final Transaction transaction, final FedoraId fedoraId, final String userPrincipal) {
049        final var session = psManager.getSession(transaction.getId());
050        final var operation = versionOperationFactory.createBuilder(fedoraId)
051                .userPrincipal(userPrincipal)
052                .build();
053
054        lockArchivalGroupResource(transaction, session, fedoraId);
055        final var headers = session.getHeaders(fedoraId, null);
056        if (RdfLexicon.FEDORA_NON_RDF_SOURCE_DESCRIPTION_URI.equals(headers.getInteractionModel())) {
057            transaction.lockResource(fedoraId.asBaseId());
058        }
059        if (RdfLexicon.NON_RDF_SOURCE.toString().equals(headers.getInteractionModel())) {
060            transaction.lockResource(fedoraId.asDescription());
061        }
062        transaction.lockResource(fedoraId);
063
064        try {
065            session.persist(operation);
066            recordEvent(transaction.getId(), fedoraId, operation);
067        } catch (final PersistentStorageException e) {
068            throw new RepositoryRuntimeException(String.format("Failed to create new version of %s",
069                    fedoraId.getResourceId()), e);
070        }
071    }
072
073    @VisibleForTesting
074    void setPsManager(final PersistentStorageSessionManager psManager) {
075        this.psManager = psManager;
076    }
077
078    @VisibleForTesting
079    void setVersionOperationFactory(final VersionResourceOperationFactory versionOperationFactory) {
080        this.versionOperationFactory = versionOperationFactory;
081    }
082
083}