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 */ 018 019package org.fcrepo.persistence.ocfl.impl; 020 021import org.fcrepo.kernel.api.operations.CreateVersionResourceOperation; 022import org.fcrepo.kernel.api.operations.ResourceOperation; 023import org.fcrepo.kernel.api.operations.ResourceOperationType; 024import org.fcrepo.persistence.api.exceptions.PersistentItemConflictException; 025import org.fcrepo.persistence.api.exceptions.PersistentStorageException; 026import org.fcrepo.persistence.common.ResourceHeaderUtils; 027import org.fcrepo.persistence.ocfl.api.FedoraToOcflObjectIndex; 028import org.fcrepo.storage.ocfl.CommitType; 029import org.slf4j.Logger; 030import org.slf4j.LoggerFactory; 031 032/** 033 * Persister for creating a new OCFL version of a resource. The new version is not created until the session 034 * is committed. 035 * 036 * @author pwinckles 037 */ 038public class CreateVersionPersister extends AbstractPersister { 039 040 private static final Logger LOG = LoggerFactory.getLogger(CreateVersionPersister.class); 041 042 protected CreateVersionPersister(final FedoraToOcflObjectIndex index) { 043 super(CreateVersionResourceOperation.class, ResourceOperationType.UPDATE, index); 044 } 045 046 @Override 047 public void persist(final OcflPersistentStorageSession session, final ResourceOperation operation) 048 throws PersistentStorageException { 049 050 final var resourceId = operation.getResourceId(); 051 LOG.debug("creating new version of <{}> in session <{}>", resourceId, session); 052 053 final var archivalGroupId = findArchivalGroupInAncestry(resourceId, session); 054 055 if (archivalGroupId.isPresent() && !archivalGroupId.get().equals(resourceId)) { 056 throw new PersistentItemConflictException( 057 String.format("Resource <%s> is contained in Archival Group <%s> and cannot be versioned directly." 058 + " Version the Archival Group instead.", resourceId, archivalGroupId)); 059 } 060 061 final var ocflMapping = getMapping(operation.getTransaction(), resourceId); 062 final var ocflObjectSession = session.findOrCreateSession(ocflMapping.getOcflObjectId()); 063 064 // Touching the last modified date is necessary so that resource that do not have any outstanding changes are 065 // still versioned 066 final var headers = new ResourceHeadersAdapter(ocflObjectSession.readHeaders(resourceId.getResourceId())) 067 .asKernelHeaders(); 068 ResourceHeaderUtils.touchMementoCreateHeaders(headers); 069 070 ocflObjectSession.writeHeaders(new ResourceHeadersAdapter(headers).asStorageHeaders()); 071 // The version is not actually created until the session is committed 072 ocflObjectSession.commitType(CommitType.NEW_VERSION); 073 } 074 075}