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.api.services.functions;
019
020import org.springframework.stereotype.Component;
021
022import static java.util.UUID.randomUUID;
023
024import java.util.StringJoiner;
025import java.util.stream.IntStream;
026
027/**
028 * Unique value minter that creates hierarchical IDs from a UUID
029 *
030 * @author rdfloyd
031 * @author whikloj
032 */
033@Component
034public class ConfigurableHierarchicalSupplier implements UniqueValueSupplier {
035
036    private static final int DEFAULT_LENGTH = 0;
037    private static final int DEFAULT_COUNT = 0;
038
039    private final int length;
040    private final int count;
041
042
043    /**
044     * Mint a hierarchical identifier with args to control length and count of the pairtree. A length or count of ZERO
045     * will return a non-hierarchical identifier.
046     *
047     * @param desiredLength the desired length of pairtree parts
048     * @param desiredCount the desired number of pairtree parts
049     */
050    public ConfigurableHierarchicalSupplier(final int desiredLength, final int desiredCount) {
051        length = desiredLength;
052        count = desiredCount;
053    }
054
055    /**
056     * Mint a unique identifier by default using defaults
057     *
058     */
059    public ConfigurableHierarchicalSupplier() {
060        length = DEFAULT_LENGTH;
061        count = DEFAULT_COUNT;
062    }
063
064    /**
065     * Mint a unique identifier as a UUID
066     *
067     * @return uuid
068     */
069    @Override
070    public String get() {
071
072        final String s = randomUUID().toString();
073        final String id;
074
075        if (count > 0 && length > 0) {
076            final StringJoiner joiner = new StringJoiner("/", "", "/" + s);
077
078            IntStream.rangeClosed(0, count - 1)
079            .forEach(x -> joiner.add(s.substring(x * length, (x + 1) * length)));
080            id = joiner.toString();
081        } else {
082            id = s;
083        }
084        return id;
085    }
086}