001 002/* 003 * Licensed to DuraSpace under one or more contributor license agreements. 004 * See the NOTICE file distributed with this work for additional information 005 * regarding copyright ownership. 006 * 007 * DuraSpace licenses this file to you under the Apache License, 008 * Version 2.0 (the "License"); you may not use this file except in 009 * compliance with the License. You may obtain a copy of the License at 010 * 011 * http://www.apache.org/licenses/LICENSE-2.0 012 * 013 * Unless required by applicable law or agreed to in writing, software 014 * distributed under the License is distributed on an "AS IS" BASIS, 015 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 016 * See the License for the specific language governing permissions and 017 * limitations under the License. 018 */ 019package org.fcrepo.kernel.impl.services; 020 021import org.apache.jena.rdf.model.Model; 022 023import org.fcrepo.kernel.api.RdfLexicon; 024import org.fcrepo.kernel.api.Transaction; 025import org.fcrepo.kernel.api.exception.MalformedRdfException; 026import org.fcrepo.kernel.api.exception.RepositoryRuntimeException; 027import org.fcrepo.kernel.api.identifiers.FedoraId; 028import org.fcrepo.kernel.api.operations.RdfSourceOperationFactory; 029import org.fcrepo.kernel.api.operations.ResourceOperation; 030import org.fcrepo.kernel.api.services.ReplacePropertiesService; 031import org.fcrepo.persistence.api.PersistentStorageSession; 032import org.fcrepo.persistence.api.PersistentStorageSessionManager; 033import org.fcrepo.persistence.api.exceptions.PersistentStorageException; 034import org.springframework.stereotype.Component; 035 036import javax.inject.Inject; 037 038import static org.fcrepo.kernel.api.rdf.DefaultRdfStream.fromModel; 039 040/** 041 * This class mediates update operations between the kernel and persistent storage layers 042 * @author bseeger 043 */ 044@Component 045public class ReplacePropertiesServiceImpl extends AbstractService implements ReplacePropertiesService { 046 047 @Inject 048 private PersistentStorageSessionManager psManager; 049 050 @Inject 051 private RdfSourceOperationFactory factory; 052 053 @Override 054 public void perform(final Transaction tx, 055 final String userPrincipal, 056 final FedoraId fedoraId, 057 final Model inputModel) throws MalformedRdfException { 058 try { 059 final PersistentStorageSession pSession = this.psManager.getSession(tx); 060 061 final var headers = pSession.getHeaders(fedoraId, null); 062 final var interactionModel = headers.getInteractionModel(); 063 064 ensureValidDirectContainer(fedoraId, interactionModel, inputModel); 065 ensureValidACLAuthorization(inputModel); 066 067 final ResourceOperation updateOp = factory.updateBuilder(tx, fedoraId, 068 fedoraPropsConfig.getServerManagedPropsMode()) 069 .relaxedProperties(inputModel) 070 .userPrincipal(userPrincipal) 071 .triples(fromModel(inputModel.createResource(fedoraId.getFullId()).asNode(), inputModel)) 072 .build(); 073 074 lockArchivalGroupResource(tx, pSession, fedoraId); 075 tx.lockResource(fedoraId); 076 if (RdfLexicon.FEDORA_NON_RDF_SOURCE_DESCRIPTION_URI.equals(interactionModel)) { 077 tx.lockResource(fedoraId.asBaseId()); 078 } 079 080 pSession.persist(updateOp); 081 updateReferences(tx, fedoraId, userPrincipal, inputModel); 082 membershipService.resourceModified(tx, fedoraId); 083 searchIndex.addUpdateIndex(tx, pSession.getHeaders(fedoraId, null)); 084 recordEvent(tx, fedoraId, updateOp); 085 } catch (final PersistentStorageException ex) { 086 throw new RepositoryRuntimeException(String.format("failed to replace resource %s", 087 fedoraId), ex); 088 } 089 } 090}