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