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