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.persistence.common;
019
020import java.net.URI;
021import java.time.Instant;
022import java.time.ZonedDateTime;
023import java.util.Collection;
024
025import org.fcrepo.kernel.api.identifiers.FedoraId;
026import org.fcrepo.kernel.api.models.ResourceHeaders;
027
028import org.apache.commons.codec.digest.DigestUtils;
029
030/**
031 * Helper utilities for populate resource headers
032 *
033 * @author bbpennel
034 */
035public class ResourceHeaderUtils {
036
037    /**
038     * Private constructor
039     */
040    private ResourceHeaderUtils() {
041    }
042
043    /**
044     * Construct and populate minimal headers expected for a new resource
045     *
046     * @param parentId identifier of the parent
047     * @param fedoraId identifier of the new resource
048     * @param interactionModel interaction model of the resource
049     * @return new resource headers object
050     */
051    public static ResourceHeadersImpl newResourceHeaders(final FedoraId parentId, final FedoraId fedoraId,
052                                                         final String interactionModel) {
053        final ResourceHeadersImpl headers = new ResourceHeadersImpl();
054        headers.setHeadersVersion(ResourceHeaders.V1_0);
055        headers.setId(fedoraId);
056        headers.setParent(parentId);
057        headers.setInteractionModel(interactionModel);
058
059        return headers;
060    }
061
062    /**
063     * Update creation headers to the current state
064     *
065     * @param headers headers object to update
066     * @param userPrincipal user principal performing the change
067     */
068    public static void touchCreationHeaders(final ResourceHeadersImpl headers, final String userPrincipal) {
069        touchCreationHeaders(headers, userPrincipal, null);
070    }
071
072    /**
073     * Update creation headers to the current state.
074     *
075     * @param headers headers object to update
076     * @param userPrincipal user principal performing the change
077     * @param createdDate time created. Defaults to now if not provided.
078     */
079    public static void touchCreationHeaders(final ResourceHeadersImpl headers, final String userPrincipal,
080            final Instant createdDate) {
081        final Instant instant;
082        if (createdDate == null) {
083            final ZonedDateTime now = ZonedDateTime.now();
084            instant = now.toInstant();
085        } else {
086            instant = createdDate;
087        }
088        headers.setCreatedDate(instant);
089        headers.setCreatedBy(userPrincipal);
090        headers.setMementoCreatedDate(instant);
091    }
092
093    /**
094     * Update modification headers to the current state
095     *
096     * @param headers headers object to update
097     * @param userPrincipal user principal performing the change
098     */
099    public static void touchModificationHeaders(final ResourceHeadersImpl headers, final String userPrincipal) {
100        touchModificationHeaders(headers, userPrincipal, null);
101    }
102
103    /**
104     * Update modification headers to the current state
105     *
106     * @param headers headers object to update
107     * @param userPrincipal user principal performing the change
108     * @param modifiedDate modified time. Defaults to now if not provided.
109     */
110    public static void touchModificationHeaders(final ResourceHeadersImpl headers, final String userPrincipal,
111            final Instant modifiedDate) {
112        final Instant instant;
113        if (modifiedDate == null) {
114            final ZonedDateTime now = ZonedDateTime.now();
115            instant = now.toInstant();
116        } else {
117            instant = modifiedDate;
118        }
119        headers.setLastModifiedDate(instant);
120        headers.setLastModifiedBy(userPrincipal);
121        touchMementoCreateHeaders(headers, instant);
122
123        final String stateToken = DigestUtils.md5Hex(String.valueOf(instant.toEpochMilli())).toUpperCase();
124        headers.setStateToken(stateToken);
125    }
126
127    /**
128     * Update the mementoCreatedDate header
129     * @param headers headers object to update.
130     * @param versionDate time this version is created.
131     */
132    public static void touchMementoCreateHeaders(final ResourceHeadersImpl headers, final Instant versionDate) {
133        final Instant instant;
134        if (versionDate == null) {
135            final ZonedDateTime now = ZonedDateTime.now();
136            instant = now.toInstant();
137        } else {
138            instant = versionDate;
139        }
140        headers.setMementoCreatedDate(instant);
141    }
142
143    public static void touchMementoCreateHeaders(final ResourceHeadersImpl headers) {
144        touchMementoCreateHeaders(headers, null);
145    }
146
147    /**
148     * Populate general binary resource headers
149     *
150     * @param headers headers object to update
151     * @param mimetype mimetype
152     * @param filename filename
153     * @param filesize filesize
154     * @param digests digests
155     */
156    public static void populateBinaryHeaders(final ResourceHeadersImpl headers, final String mimetype,
157            final String filename, final long filesize, final Collection<URI> digests) {
158        headers.setMimeType(mimetype);
159        headers.setDigests(digests);
160        headers.setFilename(filename);
161        headers.setContentSize(filesize);
162    }
163
164    /**
165     * Populate external binary related headers
166     *
167     * @param headers headers object to update
168     * @param externalUrl url of external binary content
169     * @param externalHandling handling for the external content
170     */
171    public static void populateExternalBinaryHeaders(final ResourceHeadersImpl headers,
172            final String externalUrl, final String externalHandling) {
173        headers.setExternalHandling(externalHandling);
174        headers.setExternalUrl(externalUrl);
175    }
176}