/*
Wotonomy: OpenStep design patterns for pure Java applications.
Copyright (C) 2001 Intersect Software Corporation
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, see http://www.gnu.org
*/
package net.wotonomy.control;
import java.net.InetAddress;
/**
* EOTemporaryGlobalID is a network-wide unique key.
* This is used by EOEditingContext to construct temporary
* ids when new objects are created.
*
* The specified format of the key is a byte array:
* < Sequence [2], ProcessID [2], Time [4], IP Addr [4] >,
* but because java does not allow access to the process id,
* the timestamp of when this class is first loaded is used
* to simulate a process id.
*
*
* @author michael@mpowers.net
* @author $Author: cgruber $
* @version $Revision: 893 $
*/
public class EOTemporaryGlobalID
extends EOGlobalID
{
/**
* Holds the length in bytes of the key that is generated.
*/
public static final int UniqueBinaryKeyLength = 12;
private static int sequence;
private static byte[] processid; // 2 bytes
private static byte[] ipaddr; // 4 bytes
static // static initializer
{
// init sequence
sequence = 0;
// init processid
processid = new byte[2];
long time = System.currentTimeMillis();
processid[1] = (byte) time;
time = time >> 8;
processid[0] = (byte) time;
// init ipaddr
ipaddr = new byte[4];
try
{
ipaddr = InetAddress.getLocalHost().getAddress();
}
catch ( Exception exc )
{
// could not obtain ip address - use pid twice
ipaddr[0] = processid[0];
ipaddr[1] = processid[1];
ipaddr[2] = processid[0];
ipaddr[3] = processid[1];
}
}
private byte[] key;
private int hashCode;
/**
* Generates a new id with a unique key.
*/
public EOTemporaryGlobalID()
{
key = new byte[UniqueBinaryKeyLength];
// init sequence (important byte first)
key[0] = (byte) ( sequence );
key[1] = (byte) ( sequence >> 8 );
sequence++;
// populate pid (important byte first)
key[2] = processid[1];
key[3] = processid[0];
// init time (important byte first)
long time = System.currentTimeMillis();
key[4] = (byte) time;
time = time >> 8;
key[5] = (byte) time;
time = time >> 8;
key[6] = (byte) time;
time = time >> 8;
key[7] = (byte) time;
// populate ipaddr
key[8] = ipaddr[0];
key[9] = ipaddr[1];
key[10] = ipaddr[2];
key[11] = ipaddr[3];
// use string's hash code
hashCode = new String( key ).hashCode();
}
/**
* Private constructor for cloning.
*/
private EOTemporaryGlobalID( byte[] aKey )
{
// key = aKey; // this might be faster
// make copy of key - might be safer
key = new byte[ UniqueBinaryKeyLength ];
for ( int i = 0; i < UniqueBinaryKeyLength; i++ )
{
key[i] = aKey[i];
}
// use string's hash code
hashCode = new String( aKey ).hashCode();
}
/**
* Returns true.
*/
public boolean isTemporary()
{
return true;
}
/**
* Returns whether the keys are equal.
*/
public boolean equals( Object anObject )
{
if ( ! ( anObject instanceof EOTemporaryGlobalID ) )
return false;
byte[] otherKey = ((EOTemporaryGlobalID)anObject).key;
for ( int i = 0; i < UniqueBinaryKeyLength; i++ )
{
if ( key[i] != otherKey[i] ) return false;
}
return true;
}
/**
* Returns a copy of this object.
*/
public Object clone()
{
// faster than super.clone()
return new EOTemporaryGlobalID( key );
}
public int hashCode()
{
return hashCode;
}
/**
* Returns a string representation of this key.
* This is a 24-character string with each pair
* of characters holding a hexadecimal value that
* is 128 more than the value of the corresponding
* byte (to account for two's complement).
*/
public String toString()
{
String hex;
StringBuffer buffer = new StringBuffer();
for ( int i = 0; i < key.length; i++ )
{
// get string: adjust for two's complement
hex = Integer.toHexString( key[i]+128 );
// pad with zero so we take two characters
if ( hex.length() == 1 ) hex = "0" + hex;
// append hex code
buffer.append( hex );
}
return buffer.toString();
}
}
/*
* $Log$
* Revision 1.1 2006/02/16 13:19:57 cgruber
* Check in all sources in eclipse-friendly maven-enabled packages.
*
* Revision 1.4 2001/04/29 22:02:45 mpowers
* Work on id transposing between editing contexts.
*
* Revision 1.3 2001/02/15 21:13:30 mpowers
* First draft implementation is complete. Now on to debugging.
*
* Revision 1.2 2001/02/14 23:03:02 mpowers
* A near-complete first draft of EOEditingContext.
*
* Revision 1.1 2001/02/13 23:24:29 mpowers
* Implementing more of editing context.
*
*
*/