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;
022import org.fcrepo.kernel.api.exception.MalformedRdfException;
023import org.fcrepo.kernel.api.exception.RepositoryRuntimeException;
024import org.fcrepo.kernel.api.identifiers.FedoraId;
025import org.fcrepo.kernel.api.operations.RdfSourceOperationFactory;
026import org.fcrepo.kernel.api.operations.ResourceOperation;
027import org.fcrepo.kernel.api.services.ReplacePropertiesService;
028import org.fcrepo.persistence.api.PersistentStorageSession;
029import org.fcrepo.persistence.api.PersistentStorageSessionManager;
030import org.fcrepo.persistence.api.exceptions.PersistentStorageException;
031import org.springframework.stereotype.Component;
032
033import javax.inject.Inject;
034
035import static org.fcrepo.kernel.api.rdf.DefaultRdfStream.fromModel;
036
037/**
038 * This class mediates update operations between the kernel and persistent storage layers
039 * @author bseeger
040 */
041@Component
042public class ReplacePropertiesServiceImpl extends AbstractService implements ReplacePropertiesService {
043
044    @Inject
045    private PersistentStorageSessionManager psManager;
046
047    @Inject
048    private RdfSourceOperationFactory factory;
049
050    @Override
051    public void perform(final String txId,
052                        final String userPrincipal,
053                        final FedoraId fedoraId,
054                        final Model inputModel) throws MalformedRdfException {
055        try {
056            final PersistentStorageSession pSession = this.psManager.getSession(txId);
057
058            final var headers = pSession.getHeaders(fedoraId, null);
059            final var interactionModel = headers.getInteractionModel();
060
061            ensureValidDirectContainer(fedoraId, interactionModel, inputModel);
062            ensureValidACLAuthorization(inputModel);
063
064            final ResourceOperation updateOp = factory.updateBuilder(fedoraId)
065                .relaxedProperties(inputModel)
066                .userPrincipal(userPrincipal)
067                .triples(fromModel(inputModel.createResource(fedoraId.getFullId()).asNode(), inputModel))
068                .build();
069
070            pSession.persist(updateOp);
071            updateReferences(txId, fedoraId, userPrincipal, inputModel);
072            membershipService.resourceModified(txId, fedoraId);
073            recordEvent(txId, fedoraId, updateOp);
074        } catch (final PersistentStorageException ex) {
075            throw new RepositoryRuntimeException(String.format("failed to replace resource %s",
076                  fedoraId), ex);
077        }
078    }
079}