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.kernel.api.utils;
007
008import static org.apache.commons.codec.binary.Hex.encodeHexString;
009import static org.slf4j.LoggerFactory.getLogger;
010
011import java.net.URI;
012import java.net.URISyntaxException;
013
014import org.fcrepo.config.DigestAlgorithm;
015import org.fcrepo.kernel.api.exception.RepositoryRuntimeException;
016import org.slf4j.Logger;
017
018/**
019 * Digest helpers to convert digests (checksums) into URI strings
020 * (based loosely on Magnet URIs)
021 * @author Chris Beer
022 * @since Mar 6, 2013
023 */
024public final class ContentDigest {
025
026    private static final Logger LOGGER = getLogger(ContentDigest.class);
027
028    private ContentDigest() {
029    }
030
031    /**
032     * Convert a MessageDigest algorithm and checksum value to a URN
033     * @param algorithm the message digest algorithm
034     * @param value the checksum value
035     * @return URI
036     */
037    public static URI asURI(final String algorithm, final String value) {
038        try {
039            final String scheme = DigestAlgorithm.getScheme(algorithm);
040
041            return new URI(scheme, value, null);
042        } catch (final URISyntaxException unlikelyException) {
043            LOGGER.warn("Exception creating checksum URI: alg={}; value={}",
044                               algorithm, value);
045            throw new RepositoryRuntimeException(unlikelyException.getMessage(), unlikelyException);
046        }
047    }
048
049    /**
050     * Convert a MessageDigest algorithm and checksum byte-array data to a URN
051     * @param algorithm the message digest algorithm
052     * @param data the checksum byte-array data
053     * @return URI
054     */
055    public static URI asURI(final String algorithm, final byte[] data) {
056        return asURI(algorithm, asString(data));
057    }
058
059    /**
060     * Given a digest URI, get the corresponding MessageDigest algorithm
061     * @param digestUri the digest uri
062     * @return MessageDigest algorithm
063     */
064    public static String getAlgorithm(final URI digestUri) {
065        return DigestAlgorithm.fromScheme(digestUri.getScheme() + ":" +
066             digestUri.getSchemeSpecificPart().split(":", 2)[0]).getAlgorithm();
067    }
068
069    private static String asString(final byte[] data) {
070        return encodeHexString(data);
071    }
072
073}