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.mint;
019
020import static com.codahale.metrics.MetricRegistry.name;
021import static java.util.UUID.randomUUID;
022
023import java.util.stream.IntStream;
024import java.util.StringJoiner;
025
026import org.fcrepo.metrics.RegistryService;
027import org.fcrepo.kernel.api.services.functions.HierarchicalIdentifierSupplier;
028
029import com.codahale.metrics.Timer;
030
031/**
032 * PID minter that creates hierarchical IDs for a UUID
033 *
034 * @author awoods
035 */
036public class UUIDPathMinter implements HierarchicalIdentifierSupplier {
037
038    static final Timer timer = RegistryService.getInstance().getMetrics().timer(
039            name(UUIDPathMinter.class, "mint"));
040
041    private final int length;
042
043    private final int count;
044
045    /**
046     * Configure the path minter using some reasonable defaults for the length
047     * and count of the branch nodes
048     */
049    public UUIDPathMinter() {
050        this(DEFAULT_LENGTH, DEFAULT_COUNT);
051    }
052
053    /**
054     * Configure the path minter for the length of the keys and depth of the
055     * branch node prefix
056     *
057     * @param length how long the branch node identifiers should be
058     * @param count how many branch nodes should be inserted
059     */
060    public UUIDPathMinter(final int length, final int count) {
061        super();
062        this.length = length;
063        this.count = count;
064    }
065
066    /**
067     * Mint a unique identifier as a UUID
068     *
069     * @return uuid
070     */
071    @Override
072    public String get() {
073
074        try (final Timer.Context context = timer.time()) {
075            final String s = randomUUID().toString();
076
077            if (length == 0 || count == 0) {
078                return s;
079            }
080
081            final StringJoiner joiner = new StringJoiner("/", "", "/" + s);
082            IntStream.rangeClosed(0, count - 1)
083                     .forEach(x -> joiner.add(s.substring(x * length, (x + 1) * length)));
084
085            return joiner.toString();
086        }
087    }
088}