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.modeshape.utils;
019
020import org.apache.jena.graph.Node;
021import org.apache.jena.rdf.model.Resource;
022import org.apache.jena.rdf.model.Statement;
023import org.fcrepo.kernel.api.identifiers.IdentifierConverter;
024import org.fcrepo.kernel.api.models.FedoraResource;
025import org.fcrepo.kernel.api.utils.RelaxedPropertiesHelper;
026import org.slf4j.Logger;
027
028import javax.jcr.Session;
029
030import java.util.ArrayList;
031import java.util.Calendar;
032import java.util.List;
033
034import static org.fcrepo.kernel.api.RdfLexicon.isRelaxed;
035import static org.slf4j.LoggerFactory.getLogger;
036
037/**
038 * A subclass of JcrPropertyStatementListener that intercepts all requests to modify
039 * "relaxed" server-managed triples and provides methods to get those intercepted values.
040 *
041 * A "relaxed" server-managed triple is one that is typically server-managed but for which
042 * the current configuration allows them to be set explicitly under certain circumstances.
043 *
044 * This class behaves exactly like FilteringJcrPropertyStatementListener in the event that
045 * there are no "relaxed" server managed triples.
046 *
047 * @author Mike Durbin
048 */
049public class FilteringJcrPropertyStatementListener extends JcrPropertyStatementListener {
050
051    private static final Logger LOGGER = getLogger(FilteringJcrPropertyStatementListener.class);
052
053    private List<Statement> filteredAddStatements;
054
055    /**
056     * Construct a statement listener within the given session that filters out changes to
057     * any relaxed server managed triples.
058     *
059     * @param idTranslator the id translator
060     * @param session the session
061     * @param topic the topic of the RDF statement
062     */
063    public FilteringJcrPropertyStatementListener(final IdentifierConverter<Resource, FedoraResource> idTranslator,
064                                                 final Session session, final Node topic) {
065        super(idTranslator, session, topic);
066        filteredAddStatements = new ArrayList<>();
067    }
068
069    @Override
070    public void addedStatement(final Statement input) {
071        if (isRelaxed.test(input.getPredicate())) {
072            filteredAddStatements.add(input);
073            LOGGER.trace("The added statement {} was intercepted from the update request.", input);
074        } else {
075            super.addedStatement(input);
076        }
077    }
078
079    @Override
080    public void removedStatement(final Statement input) {
081        if (!isRelaxed.test(input.getPredicate())) {
082            super.removedStatement(input);
083        } else {
084            LOGGER.trace("The removed statement {} was intercepted from the update request.", input);
085        }
086    }
087
088    /**
089     * Gets the created date (if any) that was specified to be applied as part of the statements
090     * made to the model to which this StatementListener is listening.
091     * @return the date that should be set for the CREATED_DATE or null if it should be
092     *         untouched
093     */
094    public Calendar getAddedCreatedDate() {
095        return RelaxedPropertiesHelper.getCreatedDate(filteredAddStatements);
096    }
097
098    /**
099     * Gets the created by user (if any) that was specified to be applied as part of the statements
100     * made to the model to which this StatementListener is listening.
101     * @return the user that should be set for the CREATED_BY or null if it should be
102     *         untouched
103     */
104    public String getAddedCreatedBy() {
105        return RelaxedPropertiesHelper.getCreatedBy(filteredAddStatements);
106    }
107
108    /**
109     * Gets the modified date (if any) that was specified to be applied as part of the statements
110     * made to the model to which this StatementListener is listening.
111     * @return the date that should be set for the LAST_MODIFIED_DATE or null if it should be
112     *         untouched
113     */
114    public Calendar getAddedModifiedDate() {
115        return RelaxedPropertiesHelper.getModifiedDate(filteredAddStatements);
116    }
117
118    /**
119     * Gets the modified by user (if any) that was specified to be applied as part of the statements
120     * made to the model to which this StatementListener is listening.
121     * @return the user that should be set for the MODIFIED_BY or null if it should be
122     *         untouched
123     */
124    public String getAddedModifiedBy() {
125        return RelaxedPropertiesHelper.getModifiedBy(filteredAddStatements);
126    }
127}