/* * Copyright 2008 Thomas Fach, Ralf Joachim * * 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 org.castor.cpa.persistence.sql.keygen; import java.net.InetAddress; import java.sql.Connection; import java.sql.Types; import java.text.DecimalFormat; import java.util.StringTokenizer; import org.castor.core.util.Messages; import org.exolab.castor.jdo.PersistenceException; import org.exolab.castor.mapping.MappingException; import org.exolab.castor.persist.spi.PersistenceFactory; /** * UUID key generator. * * @see UUIDKeyGeneratorFactory * @author <a href="mailto:thomas DOT fach AT publica DOT de">Thomas Fach</a> * @author <a href="mailto:bruce DOT snyder AT gmail DOT com">Bruce Snyder</a> * @author <a href="mailto:ralf DOT joachim AT syscon DOT eu">Ralf Joachim</a> * @version $Revision$ $Date: 2006-04-10 16:39:24 -0600 (Mon, 10 Apr 2006) $ */ public final class UUIDKeyGenerator extends AbstractBeforeKeyGenerator { //----------------------------------------------------------------------------------- /** Format for IP-Address. */ private static final DecimalFormat IP_FORMAT = new DecimalFormat("000"); /** Format used for time. */ private static final DecimalFormat TIME_FORMAT = new DecimalFormat("0000000000000"); /** Format used for counter. */ private static final DecimalFormat COUNTER_FORMAT = new DecimalFormat("00000"); /** Maximum valid value for counter. */ private static final long COUNTER_MAX = 99999; /** Static counter variable. */ private static long _staticCounter = 0; /** Variable to store host address. */ private String _hostAddress; //----------------------------------------------------------------------------------- /** * Initialize the UUID key generator. * @param factory Instance of PersistenceFactory to be used. * @param sqlType SqlType variable to determine type. * @throws MappingException An exception indicating an invalid mapping error. */ public UUIDKeyGenerator(final PersistenceFactory factory, final int sqlType) throws MappingException { super(factory); if ((sqlType != Types.CHAR) && (sqlType != Types.VARCHAR) && (sqlType != Types.LONGVARCHAR)) { String msg = Messages.format("mapping.keyGenSQLType", getClass().getName(), new Integer(sqlType)); throw new MappingException(msg); } initHostAddress(); } /** Method to initialize hostAddress variable on construction of this object. * @throws MappingException MappingException An exception indicating an invalid mapping error. */ private void initHostAddress() throws MappingException { try { String host = InetAddress.getLocalHost().getHostAddress(); StringBuffer sb = new StringBuffer(); StringTokenizer st = new StringTokenizer(host, "."); while (st.hasMoreTokens()) { sb.append(IP_FORMAT.format(new Integer(st.nextToken()))); } _hostAddress = sb.toString(); } catch (Exception ex) { throw new MappingException(Messages.format( "persist.keyGenSQL", getClass().getName(), ex.toString()), ex); } } //----------------------------------------------------------------------------------- /** * {@inheritDoc} */ public Object generateKey(final Connection conn, final String tableName, final String primKeyName) throws PersistenceException { StringBuffer sb = new StringBuffer(); // getting IP (fixed length: 12 character) sb.append(_hostAddress); // getting currentTimeMillis (fixed length: 13 character) sb.append(TIME_FORMAT.format(System.currentTimeMillis())); // getting static counter (fixed length: 5 character) if (_staticCounter >= COUNTER_MAX) { _staticCounter = 0; } _staticCounter++; sb.append(COUNTER_FORMAT.format(_staticCounter)); return sb.toString(); } /** * {@inheritDoc} */ public boolean isInSameConnection() { return true; } //----------------------------------------------------------------------------------- }