egovframework.rte.fdl.idgnr.impl.EgovUUIdGnrService.java Source code

Java tutorial

Introduction

Here is the source code for egovframework.rte.fdl.idgnr.impl.EgovUUIdGnrService.java

Source

/*
 * Copyright 2001-2006 The Apache Software Foundation.
 *
 * Licensed under the Apache License, Version 2.0 (the ";License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS"; BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 * Copyright 2008-2009 MOPAS(Ministry of Public Administration and Security).
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package egovframework.rte.fdl.idgnr.impl;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.StringTokenizer;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.MessageSource;

import egovframework.rte.fdl.cmmn.exception.FdlException;
import egovframework.rte.fdl.idgnr.EgovIdGnrService;
import egovframework.rte.fdl.idgnr.EgovIdGnrStrategy;

/**
 * ID Generation   UUID  ?
 * <p>
 * <b>NOTE</b>: UUID(Universally Unique Identifier)
 *  ? ?  ?  .
 * @author   
 * @since 2009.02.01
 * @version 1.0
 * @see <pre>
 *  == ?(Modification Information) ==
 *   
 *   ?      ?           
 *  -------    --------    ---------------------------
 *   2009.02.01             ?
 * 
 * </pre>
 */
public class EgovUUIdGnrService implements EgovIdGnrService, ApplicationContextAware {

    /**
     * Message Source
     */
    private MessageSource messageSource;

    /**
     * Message Source Injection
     */
    public void setApplicationContext(ApplicationContext applicationContext) {
        this.messageSource = (MessageSource) applicationContext.getBean("messageSource");
    }

    /**
     * Class   
     */
    private static Log logger = LogFactory.getLog(EgovUUIdGnrService.class);

    private static final String ERROR_STRING = "address in the configuration should be a valid IP or MAC Address";

    /**
     * Address Id
     */
    private String mAddressId;

    /**
     * UUID ??  Time Factor? ? ID
     */
    private String mTimeId;

    // ?  Address
    // - PMD error report: Avoid unused private fields
    // such as 'address'
    // private String address;

    /**
     * Loop Counter
     */
    private short mLoopCounter = 0;

    /**
     * BigDecimal ? ? 
     * @return BigDecimal  ID
     * @throws FdlException
     *         ? ??  
     */
    public BigDecimal getNextBigDecimalId() throws FdlException {
        String newId = getNextStringId();
        byte[] bytes = newId.getBytes(); // get 16
        // bytes
        BigDecimal bd = new BigDecimal(0);

        for (int i = 0; i < bytes.length; i++) {
            bd = bd.multiply(new BigDecimal(256));
            bd = bd.add(new BigDecimal(((int) bytes[i]) & 0xFF));
        }

        return bd;
    }

    /**
     * byte ? ? 
     * @return byte  ID
     * @throws FdlException
     *         ? ??  
     */
    public byte getNextByteId() throws FdlException {
        throw new FdlException(messageSource, "error.idgnr.not.supported", new String[] { "Byte" }, null);
    }

    /**
     * int ? ? ?   ?? Exception ?
     * @return int  ID
     * @throws FdlException
     *         ? ??  
     */
    public int getNextIntegerId() throws FdlException {
        throw new FdlException(messageSource, "error.idgnr.not.supported", new String[] { "Integer" }, null);
    }

    /**
     * long ? ? ?   ?? Exception ?
     * @return long  ID
     * @throws FdlException
     *         ? ??  
     */
    public long getNextLongId() throws FdlException {
        throw new FdlException(messageSource, "error.idgnr.not.supported", new String[] { "Long" }, null);
    }

    /**
     * short ? ? ?   ?? Exception ?
     * @return short  ID
     * @throws FdlException
     *         ? ??  
     */
    public short getNextShortId() throws FdlException {
        throw new FdlException(messageSource, "error.idgnr.not.supported", new String[] { "Short" }, null);
    }

    /**
     * String ? ? 
     * @return String  ID
     * @throws FdlException
     *         ? ??  
     */
    public String getNextStringId() throws FdlException {
        return getUUId();
    }

    /**
     *   String ? ? ?   ?? ?
     * ?
     * @param strategy
     *         ?
     * @return String  ID
     * @throws FdlException
     *         ? ??  
     */
    public String getNextStringId(EgovIdGnrStrategy strategy) throws FdlException {
        throw new FdlException(messageSource, "error.idgnr.not.supported", new String[] { "String" }, null);
    }

    /**
     *   String ? ? ?   ?? ?
     * ?
     * @param strategy
     *         String
     * @return String  ID
     * @throws FdlException
     *         ? ??  
     */

    public String getNextStringId(String strategyId) throws FdlException {
        throw new FdlException(messageSource, "error.idgnr.not.supported", new String[] { "String" }, null);
    }

    /**
     * Config ? ? Address 
     * @param address
     *        Config ? ? address 
     * @throws FdlException
     *         IP  ?? 
     */
    public void setAddress(String address) throws FdlException {

        // this.address = address;
        byte[] addressBytes = new byte[6];

        if (null == address) {
            logger.warn("IDGeneration Service : Using a random number as the "
                    + "base for id's.  This is not the best method for many "
                    + "purposes, but may be adequate in some circumstances."
                    + " Consider using an IP or ethernet (MAC) address if " + "available. ");
            for (int i = 0; i < 6; i++) {
                addressBytes[i] = (byte) (255 * Math.random());
            }
        } else {
            if (address.indexOf(".") > 0) {
                // we should have an IP
                StringTokenizer stok = new StringTokenizer(address, ".");
                if (stok.countTokens() != 4) {
                    throw new FdlException(ERROR_STRING);
                }

                addressBytes[0] = (byte) 255;
                addressBytes[1] = (byte) 255;
                int i = 2;
                try {
                    while (stok.hasMoreTokens()) {
                        addressBytes[i++] = Integer.valueOf(stok.nextToken(), 16).byteValue();
                    }
                } catch (Exception e) {
                    throw new FdlException(ERROR_STRING);
                }
            } else if (address.indexOf(":") > 0) {
                // we should have a MAC
                StringTokenizer stok = new StringTokenizer(address, ":");
                if (stok.countTokens() != 6) {
                    throw new FdlException(ERROR_STRING);
                }
                int i = 0;
                try {
                    while (stok.hasMoreTokens()) {
                        addressBytes[i++] = Integer.valueOf(stok.nextToken(), 16).byteValue();
                    }
                } catch (Exception e) {
                    throw new FdlException(ERROR_STRING);
                }
            } else {
                throw new FdlException(ERROR_STRING);
            }
        }
        mAddressId = Base64.encode(addressBytes);

    }

    /**
     * UUID 
     * @return String unique id
     */
    private String getUUId() {
        byte[] bytes6 = new byte[6];

        long timeNow = System.currentTimeMillis();

        timeNow = (int) timeNow & 0xFFFFFFFF;

        byte[] bytes4 = new byte[4];

        toFixSizeByteArray(new BigInteger(String.valueOf(timeNow)), bytes4);
        bytes6[0] = bytes4[0];
        bytes6[1] = bytes4[1];
        bytes6[2] = bytes4[2];
        bytes6[3] = bytes4[3];

        short counter;
        synchronized (this) {
            counter = getLoopCounter();
        }

        byte[] bytes2 = new byte[2];

        toFixSizeByteArray(new BigInteger(String.valueOf(counter)), bytes2);
        bytes6[4] = bytes2[0];
        bytes6[5] = bytes2[1];

        mTimeId = Base64.encode(bytes6);

        return (mAddressId + mTimeId).replace('+', '_').replace('/', '@');
    }

    /**
     * Get the counter value as a signed short
     * @original Get the counter value as a signed
     *           short
     * @return short loop count
     */
    private short getLoopCounter() {
        return mLoopCounter++;
    }

    /**
     * @original This method transforms Java BigInteger
     *           type into a fix size byte array
     *           containing the two's-complement
     *           representation of the integer. The
     *           byte array will be in big-endian
     *           byte-order: the most significant byte
     *           is in the zeroth element. If the
     *           destination array is shorter then the
     *           BigInteger.toByteArray(), the the less
     *           significant bytes will be copy only.
     *           If the destination array is longer
     *           then the BigInteger.toByteArray(),
     *           destination will be left padded with
     *           zeros.
     * @param bigInt
     *        Java BigInteger type
     * @param destination
     *        destination array
     */
    private void toFixSizeByteArray(BigInteger bigInt, byte[] destination) {
        // Prepare the destination
        for (int i = 0; i < destination.length; i++) {
            destination[i] = 0x00;
        }

        // Convert the BigInt to a byte array
        byte[] source = bigInt.toByteArray();

        // Copy only the fix size length
        if (source.length <= destination.length) {
            for (int i = 0; i < source.length; i++) {
                destination[destination.length - source.length + i] = source[i];
            }
        } else {
            for (int i = 0; i < destination.length; i++) {
                destination[i] = source[source.length - destination.length + i];
            }
        }
    }
}