/*
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 {
private static final long serialVersionUID = 7652533198394290800L;
/**
* 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.
*
*
*/