001: /*
002: * <copyright>
003: *
004: * Copyright 1997-2004 BBNT Solutions, LLC
005: * under sponsorship of the Defense Advanced Research Projects
006: * Agency (DARPA).
007: *
008: * You can redistribute this software and/or modify it under the
009: * terms of the Cougaar Open Source License as published on the
010: * Cougaar Open Source Website (www.cougaar.org).
011: *
012: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
013: * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
014: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
015: * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
016: * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
017: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
018: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
019: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
020: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
021: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
022: * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
023: *
024: * </copyright>
025: */
026:
027: package org.cougaar.core.util;
028:
029: import java.io.Externalizable;
030: import java.io.IOException;
031: import java.io.ObjectInput;
032: import java.io.ObjectOutput;
033:
034: /**
035: * A globally <i>U</i>nique object <i>ID</i>entifier generated by
036: * the {@link org.cougaar.core.service.UIDService}.
037: * <p>
038: * Although the details of this implementation are subject to change,
039: * developers may want to know more about the design to aid
040: * debugging: UIDs are currently implemented as an "AGENT/COUNTER"
041: * pair, where the initial COUNTER is the JVM startTime.
042: * <p>
043: * Compare to {@link java.rmi.server.UID}, which can block to prevent
044: * the COUNTER from growing faster than one-per-millisecond. Also
045: * note that it may be better to use a JVM-instance-specific OWNER
046: * (e.g. IP_ADDR+JVM_PID) instead of the AGENT, in case duplicate
047: * agents are created.
048: */
049: public final class UID implements Externalizable, Comparable {
050: private String owner;
051: private long id;
052:
053: /** No argument constructor is only for use by serialization! */
054: public UID() {
055: }
056:
057: /** @deprecated Use toUID(String) or UID(String, long) */
058: public UID(String uid) {
059: // duplicate some of "toUID(String)"
060: int l = uid.indexOf('/');
061: if (l == -1)
062: throw new IllegalArgumentException("String \"" + uid
063: + "\" is not a valid UID pattern");
064: owner = uid.substring(0, l).intern();
065: try {
066: id = Long.parseLong(uid.substring(l + 1));
067: } catch (NumberFormatException ex) {
068: throw new IllegalArgumentException("String \"" + uid
069: + "\" is not a valid UID pattern");
070: }
071: }
072:
073: public UID(String owner, long id) {
074: this .owner = owner.intern();
075: this .id = id;
076: }
077:
078: public String getOwner() {
079: return owner;
080: }
081:
082: public long getId() {
083: return id;
084: }
085:
086: public boolean equals(UID other) {
087: return (other != null && owner == other.owner && id == other.id);
088: }
089:
090: /*
091: public boolean equals(String otheruid) {
092: return (uid == otheruid || uid.equals(otheruid));
093: }
094: */
095:
096: public boolean equals(Object other) {
097: if (this == other)
098: return true;
099: if (other instanceof UID) {
100: UID o = (UID) other;
101: return (owner == o.owner && id == o.id);
102: } else {
103: return false;
104: }
105: }
106:
107: public int compareTo(Object other) {
108: if (this == other)
109: return 0;
110:
111: if (other instanceof UID) {
112: UID o = (UID) other;
113: String oo = o.owner;
114: long oid = o.id;
115: /* compare first by string order with owners, then by id */
116: int c1 = owner.compareTo(oo);
117: if (c1 == 0) {
118: if (id == oid)
119: return 0;
120: return (id > oid) ? 1 : -1;
121: } else {
122: return c1;
123: }
124: } else {
125: /* if they aren't both UIDs than the ordering is undefined. */
126: return -1;
127: }
128: }
129:
130: public int hashCode() {
131: return owner.hashCode() + ((int) id);
132: }
133:
134: /**
135: * Convert a UID into a String.
136: * <p>
137: * One should <u>not</u> assume a readable format for
138: * this String, or that it has a guaranteed format!
139: *
140: * @see #toUID(String)
141: */
142: public String toString() {
143: /* Ugh! but we really don't want to keep these around! */
144: return owner + "/" + id;
145: }
146:
147: /**
148: * Parse the given String into a UID object useful for doing searches and comparisons.
149: * <p>
150: * The String's format should match <tt>UID.toString()</tt>.
151: * <p>
152: * There is no guarantee that this UID will be valid or
153: * has been assigned to an Object in the society.
154: *
155: * @see #toString()
156: */
157: public static UID toUID(String uid) {
158: String tOwner;
159: long tId;
160: try {
161: int l = uid.indexOf('/');
162: if (l == -1) {
163: throw new IllegalArgumentException("String \"" + uid
164: + "\" is not a valid UID pattern");
165: }
166: tOwner = uid.substring(0, l);
167: tId = Long.parseLong(uid.substring(l + 1));
168: } catch (NumberFormatException ex) {
169: throw new IllegalArgumentException("String \"" + uid
170: + "\" is not a valid UID pattern");
171: }
172: return new UID(tOwner, tId);
173: }
174:
175: // for user interface, follow beans pattern
176: /** @deprecated Use getOwner and getID */
177: public String getUID() {
178: return toString();
179: }
180:
181: public void writeExternal(ObjectOutput out) throws IOException {
182: out.writeObject(owner);
183: out.writeLong(id);
184: }
185:
186: public void readExternal(ObjectInput in) throws IOException {
187: try {
188: owner = (String) in.readObject();
189: if (owner != null)
190: owner = owner.intern();
191: id = in.readLong();
192: } catch (Exception e) {
193: throw new IOException(e.toString());
194: }
195: }
196: }
|