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.impl.operations;
019
020import static org.fcrepo.kernel.api.RdfLexicon.CREATED_BY;
021import static org.fcrepo.kernel.api.RdfLexicon.CREATED_DATE;
022import static org.fcrepo.kernel.api.RdfLexicon.LAST_MODIFIED_BY;
023import static org.fcrepo.kernel.api.RdfLexicon.LAST_MODIFIED_DATE;
024import static org.fcrepo.kernel.api.RdfLexicon.SERVER_MANAGED_PROPERTIES_MODE;
025
026import java.time.Instant;
027import java.util.Date;
028
029import org.apache.jena.rdf.model.Model;
030import org.apache.jena.rdf.model.Property;
031import org.apache.jena.rdf.model.Resource;
032import org.fcrepo.kernel.api.RdfStream;
033import org.fcrepo.kernel.api.identifiers.FedoraId;
034import org.fcrepo.kernel.api.operations.RdfSourceOperationBuilder;
035
036/**
037 * Abstract builder for interacting with an Rdf Source Operation Builder
038 * @author bseeger
039 */
040public abstract class AbstractRdfSourceOperationBuilder implements RdfSourceOperationBuilder {
041
042    /**
043     * Holds the stream of user's triples.
044     */
045    protected RdfStream tripleStream;
046
047    /**
048     * String of the resource ID.
049     */
050    protected final FedoraId resourceId;
051
052    /**
053     * The interaction model of this resource, null in case of update.
054     */
055    protected final String interactionModel;
056
057    /**
058     * Principal of the user performing the operation
059     */
060    protected String userPrincipal;
061
062    protected String lastModifiedBy;
063
064    protected String createdBy;
065
066    protected Instant lastModifiedDate;
067
068    protected Instant createdDate;
069
070    protected AbstractRdfSourceOperationBuilder(final FedoraId rescId, final String model) {
071        resourceId = rescId;
072        interactionModel = model;
073    }
074
075    @Override
076    public RdfSourceOperationBuilder userPrincipal(final String userPrincipal) {
077        this.userPrincipal = userPrincipal;
078        return this;
079    }
080
081    @Override
082    public RdfSourceOperationBuilder triples(final RdfStream triples) {
083        this.tripleStream = triples;
084        return this;
085    }
086
087    @Override
088    public RdfSourceOperationBuilder relaxedProperties(final Model model) {
089        // Has no affect if the server is not in relaxed mode
090        if (model != null && isRelaxed()) {
091            final var resc = model.getResource(resourceId.getResourceId());
092            final var createdDateVal = getPropertyAsInstant(resc, CREATED_DATE);
093            if (createdDateVal != null) {
094                this.createdDate = createdDateVal;
095            }
096            final var createdByVal = getStringProperty(resc, CREATED_BY);
097            if (createdByVal != null) {
098                this.createdBy = createdByVal;
099            }
100            final var modifiedDate = getPropertyAsInstant(resc, LAST_MODIFIED_DATE);
101            if (modifiedDate != null) {
102                this.lastModifiedDate = modifiedDate;
103            }
104            final var modifiedBy = getStringProperty(resc, LAST_MODIFIED_BY);
105            if (modifiedBy != null) {
106                this.lastModifiedBy = modifiedBy;
107            }
108        }
109
110        return this;
111    }
112
113    private static String getStringProperty(final Resource resc, final Property property) {
114        if (resc.hasProperty(property)) {
115            return resc.getProperty(property).getString();
116        }
117
118        return null;
119    }
120
121    private static Instant getPropertyAsInstant(final Resource resc, final Property property) {
122        if (resc.hasProperty(property)) {
123            final var propObj = resc.getProperty(property).getObject();
124
125            if (propObj.isLiteral()) {
126                final var literalValue = propObj.asLiteral().getValue();
127                if (literalValue instanceof Date) {
128                    return ((Date) literalValue).toInstant();
129                }
130            }
131        }
132
133        return null;
134    }
135
136    private static boolean isRelaxed() {
137        return "relaxed".equals(System.getProperty(SERVER_MANAGED_PROPERTIES_MODE));
138    }
139}