All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.enterprisemath.utils.AlphanumericUniqueCodeGenerator Maven / Gradle / Ivy

Go to download

Collection of utility classes for large scale projects focusing on robust and testable code.

There is a newer version: 4.1.1
Show newest version
package com.enterprisemath.utils;

import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.builder.ToStringBuilder;

/**
 * Code generator which generates alphanumeric codes.
 * Every code is generated with the following schema prefix-XYZ,
 * where prefix is parameter from function, X is static part (can be empty),
 * Y are random characters and Z is part based on the timestamp.
 * 
 * @author radek.hecl
 *
 */
public class AlphanumericUniqueCodeGenerator implements UniqueCodeGenerator {

    /**
     * Builder object.
     */
    public static class Builder {

        /**
         * Static part of the each of generated code.
         */
        private String staticPart;
        
        /**
         * Number of random characters.
         */
        private Integer numRandomCharacters;

        /**
         * Provider for dates.
         */
        private DatesProvider datesProvider;
        
        /**
         * Sets the static part of the each of the generated code.
         * 
         * @param staticPart static part
         * @return this instance
         */
        public Builder setStaticPart(String staticPart) {
            this.staticPart = staticPart;
            return this;
        }
        
        /**
         * Sets number of random characters.
         * 
         * @param numRandomCharacters number of random characters
         * @return this instance
         */
        public Builder setNumRandomCharacters(int numRandomCharacters) {
            this.numRandomCharacters = numRandomCharacters;
            return this;
        }

        /**
         * Sets provider for dates.
         * 
         * @param datesProvider provider for dates
         * @return this instance
         */
        public Builder setDatesProvider(DatesProvider datesProvider) {
            this.datesProvider = datesProvider;
            return this;
        }
        
        /**
         * Builds the result object.
         * 
         * @return created object
         */
        public AlphanumericUniqueCodeGenerator build() {
            return new AlphanumericUniqueCodeGenerator(this);
        }
        
    }

    /**
     * Static part of the each of generated code.
     */
    private String staticPart;

    /**
     * Number of random characters.
     */
    private Integer numRandomCharacters;

    /**
     * Provider for dates.
     */
    private DatesProvider datesProvider;    

    /**
     * Time part which was used for the last time.
     */
    private String lastTimePart = null;
    
    /**
     * Internal object for locking.
     */
    private Lock lock = new ReentrantLock();

    /**
     * Creates new instance.
     * 
     * @param builder builder object
     */
    public AlphanumericUniqueCodeGenerator(Builder builder) {
        staticPart = builder.staticPart;
        numRandomCharacters = builder.numRandomCharacters;
        datesProvider = builder.datesProvider;
        guardInvariants();
    }
    
    /**
     * Guards this object to be consistent. Throws exception if this is not the case.
     */
    private void guardInvariants() {
        ValidationUtils.guardNotNull(staticPart, "staticPart cannot be null");
        ValidationUtils.guardNotNull(numRandomCharacters, "numRandomCharacters cannot be null");
        ValidationUtils.guardNotNegativeInt(numRandomCharacters, "numRandomCharacters cannot be negative");
        ValidationUtils.guardNotNull(datesProvider, "datesProvider cannot be null");
    }
    
    @Override
    public String generateUniqueCode(String prefix) {
        lock.lock();
        try {
            String tm = StringUtils.reverse(Long.toString(datesProvider.now().getTime(), Character.MAX_RADIX).toUpperCase());
            while (tm.equals(lastTimePart)) {
                tm = StringUtils.reverse(Long.toString(datesProvider.now().getTime(), Character.MAX_RADIX).toUpperCase());
            }
            lastTimePart = tm;
            return prefix + "-" + staticPart + RandomStringUtils.randomAlphanumeric(numRandomCharacters).toUpperCase() + tm;
        } finally {
            lock.unlock();
        }
    }

    @Override
    public Set generateUniqueCodes(String prefix, int number) {
        lock.lock();
        try {
            Set res = new HashSet();
            while (res.size() != number) {
                String tm = StringUtils.reverse(Long.toString(datesProvider.now().getTime(), Character.MAX_RADIX).toUpperCase());
                while (tm.equals(lastTimePart)) {
                    tm = StringUtils.reverse(Long.toString(datesProvider.now().getTime(), Character.MAX_RADIX).toUpperCase());
                }
                lastTimePart = tm;
                int currentSize = res.size();
                for (int i = 0; i < number - currentSize; ++i) {
                    res.add(prefix + "-" + staticPart + RandomStringUtils.randomAlphanumeric(numRandomCharacters).toUpperCase() + tm);
                }
            }
            return res;
        } finally {
            lock.unlock();
        }
    }

    
    @Override
    public String toString() {
        return ToStringBuilder.reflectionToString(this);
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy