Java tutorial
/* * 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]; } } } }