org.tdmx.lib.control.service.UniqueIdServiceImpl.java Source code

Java tutorial

Introduction

Here is the source code for org.tdmx.lib.control.service.UniqueIdServiceImpl.java

Source

/*
 * TDMX - Trusted Domain Messaging eXchange
 * 
 * Enterprise B2B messaging between separate corporations via interoperable cloud service providers.
 * 
 * Copyright (C) 2014 Peter Klauser (http://tdmx.org)
 * 
 * This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General
 * Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any
 * later version.
 * 
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
 * details.
 * 
 * You should have received a copy of the GNU Affero General Public License along with this program. If not, see
 * http://www.gnu.org/licenses/.
 */

package org.tdmx.lib.control.service;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;
import org.tdmx.lib.control.domain.MaxValue;

/**
 * The implementation of {@link UniqueIdService}.
 * 
 * @author Peter Klauser
 * 
 */
public class UniqueIdServiceImpl implements UniqueIdService {

    // -------------------------------------------------------------------------
    // PUBLIC CONSTANTS
    // -------------------------------------------------------------------------
    private static final int DIGIT = 10;

    // -------------------------------------------------------------------------
    // PROTECTED AND PRIVATE VARIABLES AND CONSTANTS
    // -------------------------------------------------------------------------
    private static final Logger log = LoggerFactory.getLogger(UniqueIdServiceImpl.class);

    private MaxValueService maxValueService;
    private int batchSize;
    private String maxValueKey;
    private long initialLowValue;

    private final Object syncObject = new Object();
    private long cachedMaxValue = 0;
    private long lastCachedMaxValue = 0;

    // -------------------------------------------------------------------------
    // CONSTRUCTORS
    // -------------------------------------------------------------------------

    // -------------------------------------------------------------------------
    // PUBLIC METHODS
    // -------------------------------------------------------------------------

    public void init() {
        MaxValue mv = getMaxValueService().findById(getMaxValueKey());
        if (mv == null) {
            mv = new MaxValue();
            mv.setKey(getMaxValueKey());
            mv.setValue(getInitialLowValue());
            getMaxValueService().createOrUpdate(mv);
        }
    }

    @Override
    public String getNextId() {
        long result = 0;
        synchronized (syncObject) {
            if (cachedMaxValue == 0 || cachedMaxValue >= lastCachedMaxValue) {
                MaxValue mv = getMaxValueService().increment(getMaxValueKey(), getBatchSize());
                lastCachedMaxValue = mv.getValue();
                cachedMaxValue = mv.getValue() - getBatchSize() + 1;
            } else {
                cachedMaxValue += 1;
            }
            result = cachedMaxValue; // assign
        }
        int checkDigit = calculateCheckDigit(result);
        Long oid = (result * DIGIT) + checkDigit;

        String id = oid.toString();
        log.info("Generated " + getMaxValueKey() + "=" + id);
        return id;
    }

    @Override
    public boolean isValid(String accountId) {
        if (!StringUtils.hasText(accountId)) {
            throw new IllegalArgumentException("missing accountId");
        }
        String oid = accountId;
        char[] chars = oid.toCharArray();
        if (chars.length <= 1) {
            return false;
        }
        int digit = calculateCheckDigit(chars);
        int providedDigit = Character.digit(chars[chars.length - 1], DIGIT);
        return providedDigit == digit;
    }

    // -------------------------------------------------------------------------
    // PROTECTED METHODS
    // -------------------------------------------------------------------------

    // -------------------------------------------------------------------------
    // PRIVATE METHODS
    // -------------------------------------------------------------------------

    private int calculateCheckDigit(long value) {
        String oid = "" + value + " ";
        // note space needed because it is the place of the check digit when we check.
        char[] chars = oid.toCharArray();
        return calculateCheckDigit(chars);
    }

    private int calculateCheckDigit(char[] chars) {
        int oddSum = 0;
        for (int i = 1; i < chars.length - 1; i += 2) {
            oddSum += Character.digit(chars[i], DIGIT);
        }
        int evenSum = 0;
        for (int i = 0; i < chars.length - 1; i += 2) {
            evenSum += Character.digit(chars[i], DIGIT);
        }
        int totalSum = oddSum + evenSum;
        return (DIGIT - (totalSum % DIGIT)) % DIGIT;
    }

    // -------------------------------------------------------------------------
    // PUBLIC ACCESSORS (GETTERS / SETTERS)
    // -------------------------------------------------------------------------

    public MaxValueService getMaxValueService() {
        return maxValueService;
    }

    public void setMaxValueService(MaxValueService maxValueService) {
        this.maxValueService = maxValueService;
    }

    public String getMaxValueKey() {
        return maxValueKey;
    }

    public void setMaxValueKey(String maxValueKey) {
        this.maxValueKey = maxValueKey;
    }

    public int getBatchSize() {
        return batchSize;
    }

    public void setBatchSize(int batchSize) {
        this.batchSize = batchSize;
    }

    public long getInitialLowValue() {
        return initialLowValue;
    }

    public void setInitialLowValue(long initialLowValue) {
        this.initialLowValue = initialLowValue;
    }

}