2 * Copyright (c) 2001-2007 Sun Microsystems, Inc. All rights reserved.
4 * The Sun Project JXTA(TM) Software License
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met:
9 * 1. Redistributions of source code must retain the above copyright notice,
10 * this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright notice,
13 * this list of conditions and the following disclaimer in the documentation
14 * and/or other materials provided with the distribution.
16 * 3. The end-user documentation included with the redistribution, if any, must
17 * include the following acknowledgment: "This product includes software
18 * developed by Sun Microsystems, Inc. for JXTA(TM) technology."
19 * Alternately, this acknowledgment may appear in the software itself, if
20 * and wherever such third-party acknowledgments normally appear.
22 * 4. The names "Sun", "Sun Microsystems, Inc.", "JXTA" and "Project JXTA" must
23 * not be used to endorse or promote products derived from this software
24 * without prior written permission. For written permission, please contact
25 * Project JXTA at http://www.jxta.org.
27 * 5. Products derived from this software may not be called "JXTA", nor may
28 * "JXTA" appear in their name, without prior written permission of Sun.
30 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
31 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
32 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SUN
33 * MICROSYSTEMS OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
34 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
35 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
36 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
37 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
38 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
39 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
41 * JXTA is a registered trademark of Sun Microsystems, Inc. in the United
42 * States and other countries.
44 * Please see the license information page at :
45 * <http://www.jxta.org/project/www/license.html> for instructions on use of
46 * the license in source files.
48 * ====================================================================
50 * This software consists of voluntary contributions made by many individuals
51 * on behalf of Project JXTA. For more information on Project JXTA, please see
52 * http://www.jxta.org.
54 * This license is based on the BSD license adopted by the Apache Foundation.
57 package net.jxta.impl.id.UUID;
60 import java.io.InputStream;
61 import java.security.MessageDigest;
63 import java.io.IOException;
64 import java.security.ProviderException;
65 import java.security.NoSuchAlgorithmException;
69 * An implementation of the {@link net.jxta.codat.CodatID} ID Type.
71 public class CodatID extends net.jxta.codat.CodatID {
74 * size of a SHA1 hash. I would use MessageDigest.getDigestLength, but
75 * possible exceptions make it difficult to do.
77 protected final static int hashSize = 20;
80 * Location of the group id in the byte array.
82 protected final static int groupIdOffset = 0;
85 * Location of the randomly chosen portion of the id within the byte array.
87 protected final static int idOffset = CodatID.groupIdOffset + IDFormat.uuidSize;
90 * Location of the hash value portion of the id within the byte array.
92 protected final static int codatHashOffset = CodatID.idOffset + IDFormat.uuidSize;
95 * Location of the beginning of pad (unused space) within the byte array.
97 protected final static int padOffset = CodatID.codatHashOffset + CodatID.hashSize;
102 protected final static int padSize = IDFormat.flagsOffset - CodatID.padOffset;
107 protected IDBytes id;
110 * Internal constructor
112 protected CodatID() {
114 id = new IDBytes(IDFormat.flagCodatID);
118 * Initializes contents from provided bytes.
120 * @param id the ID data
122 protected CodatID(IDBytes id) {
127 protected CodatID(UUID groupUUID, UUID idUUID) {
130 id.longIntoBytes(CodatID.groupIdOffset, groupUUID.getMostSignificantBits());
131 id.longIntoBytes(CodatID.groupIdOffset + 8, groupUUID.getLeastSignificantBits());
133 id.longIntoBytes(CodatID.idOffset, idUUID.getMostSignificantBits());
134 id.longIntoBytes(CodatID.idOffset + 8, idUUID.getLeastSignificantBits());
138 * See {@link net.jxta.id.IDFactory.Instantiator#newCodatID(net.jxta.peergroup.PeerGroupID)}.
140 public CodatID(PeerGroupID groupID) {
141 this(groupID.getUUID(), UUIDFactory.newUUID());
145 * See {@link net.jxta.id.IDFactory.Instantiator#newCodatID(net.jxta.peergroup.PeerGroupID,byte[])}.
147 public CodatID(PeerGroupID groupID, byte[] seed) {
150 UUID groupUUID = groupID.getUUID();
152 id.longIntoBytes(CodatID.groupIdOffset, groupUUID.getMostSignificantBits());
153 id.longIntoBytes(CodatID.groupIdOffset + 8, groupUUID.getLeastSignificantBits());
155 System.arraycopy(seed, 0, id.bytes, CodatID.idOffset, Math.min(IDFormat.uuidSize, seed.length));
157 // make it a valid UUID
158 id.bytes[CodatID.idOffset + 6] &= 0x0f;
159 id.bytes[CodatID.idOffset + 6] |= 0x40; /* version 4 */
160 id.bytes[CodatID.idOffset + 8] &= 0x3f;
161 id.bytes[CodatID.idOffset + 8] |= 0x80; /* IETF variant */
162 id.bytes[CodatID.idOffset + 10] &= 0x3f;
163 id.bytes[CodatID.idOffset + 10] |= 0x80; /* multicast bit */
167 * See {@link net.jxta.id.IDFactory.Instantiator#newCodatID(net.jxta.peergroup.PeerGroupID,InputStream)}.
169 public CodatID(PeerGroupID groupID, InputStream in) throws IOException {
176 * See {@link net.jxta.id.IDFactory.Instantiator#newCodatID(net.jxta.peergroup.PeerGroupID,InputStream)}.
178 public CodatID(PeerGroupID groupID, byte[] seed, InputStream in) throws IOException {
188 public boolean equals(Object target) {
189 if (this == target) {
193 if (target instanceof CodatID) {
194 CodatID codatTarget = (CodatID) target;
196 return id.equals(codatTarget.id);
206 public int hashCode() {
207 return id.hashCode();
214 public String getIDFormat() {
215 return IDFormat.INSTANTIATOR.getSupportedIDFormat();
222 public Object getUniqueValue() {
223 return getIDFormat() + "-" + (String) id.getUniqueValue();
230 public net.jxta.id.ID getPeerGroupID() {
231 UUID groupUUID = new UUID(id.bytesIntoLong(CodatID.groupIdOffset), id.bytesIntoLong(CodatID.groupIdOffset + 8));
233 PeerGroupID groupID = new PeerGroupID(groupUUID);
235 // convert to the generic world PGID as necessary
236 return IDFormat.translateToWellKnown(groupID);
243 public boolean isStatic() {
244 for (int eachHashByte = CodatID.codatHashOffset; eachHashByte < (CodatID.padOffset); eachHashByte++) {
245 if (0 != id.bytes[eachHashByte]) {
254 * Calculates the SHA-1 hash of a stream.
256 * @param in The InputStream.
258 protected void setHash(InputStream in) throws IOException {
259 MessageDigest dig = null;
262 dig = MessageDigest.getInstance("SHA-1");
263 } catch (NoSuchAlgorithmException caught) {
268 throw new ProviderException("SHA-1 digest algorithm not found");
273 byte[] chunk = new byte[1024];
277 int read = in.read(chunk);
283 dig.update(chunk, 0, read);
289 byte[] result = dig.digest();
291 System.arraycopy(result, 0, id.bytes, CodatID.codatHashOffset, CodatID.hashSize);