001
002/*
003 * The contents of this file are subject to the license and copyright
004 * detailed in the LICENSE and NOTICE files at the root of the source
005 * tree.
006 */
007package org.fcrepo.kernel.impl.services;
008
009import static org.fcrepo.kernel.api.RdfCollectors.toModel;
010
011import java.util.Optional;
012
013import javax.inject.Inject;
014
015import org.fcrepo.kernel.api.Transaction;
016import org.fcrepo.kernel.api.auth.ACLHandle;
017import org.fcrepo.kernel.api.exception.AccessDeniedException;
018import org.fcrepo.kernel.api.exception.ItemNotFoundException;
019import org.fcrepo.kernel.api.exception.MalformedRdfException;
020import org.fcrepo.kernel.api.exception.RepositoryRuntimeException;
021import org.fcrepo.kernel.api.identifiers.FedoraId;
022import org.fcrepo.kernel.api.services.ReplacePropertiesService;
023import org.fcrepo.kernel.api.services.UpdatePropertiesService;
024import org.fcrepo.persistence.api.PersistentStorageSessionManager;
025import org.fcrepo.persistence.api.exceptions.PersistentItemNotFoundException;
026import org.fcrepo.persistence.api.exceptions.PersistentStorageException;
027import org.springframework.stereotype.Component;
028
029import org.apache.jena.rdf.model.Model;
030import org.apache.jena.update.UpdateAction;
031import org.apache.jena.update.UpdateFactory;
032import org.apache.jena.update.UpdateRequest;
033
034import com.github.benmanes.caffeine.cache.Cache;
035
036/**
037 * This class implements the update properties operation.
038 *
039 * @author dbernstein
040 */
041@Component
042public class UpdatePropertiesServiceImpl extends AbstractService implements UpdatePropertiesService {
043
044    @Inject
045    private ReplacePropertiesService replacePropertiesService;
046
047    @Inject
048    private PersistentStorageSessionManager persistentStorageSessionManager;
049
050    @Inject
051    private Cache<String, Optional<ACLHandle>> authHandleCache;
052
053    @Override
054    public void updateProperties(final Transaction tx, final String userPrincipal,
055                                 final FedoraId fedoraId, final String sparqlUpdateStatement)
056            throws MalformedRdfException, AccessDeniedException {
057        try {
058            final var psession = persistentStorageSessionManager.getSession(tx);
059            final var triples = psession.getTriples(fedoraId, null);
060            final Model model = triples.collect(toModel());
061            final UpdateRequest request = UpdateFactory.create(sparqlUpdateStatement, fedoraId.getFullId());
062            UpdateAction.execute(request, model);
063            replacePropertiesService.perform(tx, userPrincipal, fedoraId, model);
064            if (fedoraId.isAcl()) {
065                // Flush ACL cache on any ACL creation/update/deletion.
066                authHandleCache.invalidateAll();
067            }
068        } catch (final PersistentItemNotFoundException ex) {
069            throw new ItemNotFoundException(ex.getMessage(), ex);
070        } catch (final PersistentStorageException ex) {
071            throw new RepositoryRuntimeException(ex.getMessage(), ex);
072        }
073
074    }
075}