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.binaryID;
60 import java.io.InputStream;
63 import java.security.SecureRandom;
64 import java.util.Random;
65 import java.util.logging.Level;
66 import java.util.logging.Logger;
68 import java.io.IOException;
69 import java.net.MalformedURLException;
70 import java.net.URISyntaxException;
71 import java.net.UnknownServiceException;
73 import net.jxta.peergroup.PeerGroupID;
77 * ID Factory for the binary ID type. All identifiers in this type are prefixed by "binaryid".
79 * @author Daniel Brookshier <a HREF="mailto:turbogeek@cluck.com">turbogeek@cluck.com</a>
82 public final class Instantiator implements net.jxta.id.IDFactory.URIInstantiator {
85 * LOG object for this class.
87 private final static transient Logger LOG = Logger.getLogger(Instantiator.class.getName());
92 final static String BinaryIDEncoded = "binaryid";
95 * Random generator used for ID creation where a seed (idValue) is not provided.
97 private static final Random randNumGenerator = new SecureRandom();
102 public String getSupportedIDFormat() {
103 return BinaryIDEncoded;
109 public net.jxta.id.ID fromURL(URL source) throws MalformedURLException, UnknownServiceException {
111 // check the protocol
112 if (!net.jxta.id.ID.URIEncodingName.equalsIgnoreCase(source.getProtocol())) {
113 throw new UnknownServiceException("URI protocol type was not as expected.");
116 String encoded = source.getFile();
118 int colonAt = encoded.indexOf(':');
120 // There's a colon right?
122 throw new UnknownServiceException("URN namespace was missing.");
125 // check the namespace
126 if (!net.jxta.id.ID.URNNamespace.equalsIgnoreCase(encoded.substring(0, colonAt))) {
127 throw new UnknownServiceException("URN namespace was not as expected.");
130 // skip the namespace portion and the colon
131 encoded = encoded.substring(colonAt + 1);
134 return fromURNNamespaceSpecificPart(encoded);
135 } catch (URISyntaxException failed) {
136 MalformedURLException failure = new MalformedURLException("Failure parsing URL");
138 failure.initCause(failed);
147 public net.jxta.id.ID fromURI(URI source) throws URISyntaxException {
149 // check the protocol
150 if (!net.jxta.id.ID.URIEncodingName.equalsIgnoreCase(source.getScheme())) {
151 throw new URISyntaxException(source.toString(), "URI scheme was not as expected.");
154 String decoded = source.getSchemeSpecificPart();
156 int colonAt = decoded.indexOf(':');
158 // There's a colon right?
160 throw new URISyntaxException(source.toString(), "URN namespace was missing.");
163 // check the namespace
164 if (!net.jxta.id.ID.URNNamespace.equalsIgnoreCase(decoded.substring(0, colonAt))) {
165 throw new URISyntaxException(source.toString()
167 "URN namespace was not as expected. (" + net.jxta.id.ID.URNNamespace + "!=" + decoded.substring(0, colonAt)
171 // skip the namespace portion and the colon
172 decoded = decoded.substring(colonAt + 1);
174 return fromURNNamespaceSpecificPart(decoded);
180 public net.jxta.id.ID fromURNNamespaceSpecificPart(String encoded) throws URISyntaxException {
181 int dashAt = encoded.indexOf('-');
183 // there's a dash, right?
185 throw new URISyntaxException(encoded, "URN Encodingtype was missing.");
188 if (!encoded.substring(0, dashAt).equals(BinaryIDEncoded)) {
189 throw new URISyntaxException(encoded
191 "JXTA id format was not as expected. Should have been BinaryIDEncoded found:" + encoded.substring(0, dashAt));
195 encoded = encoded.substring(dashAt + 1);
196 // check that the length is long enough
197 if (encoded.length() < 1) {
198 throw new URISyntaxException(encoded, "URN does not contain enough chars. Must have at least one byte");
200 BinaryID id = new BinaryID(encoded);
201 net.jxta.id.ID result = null;
205 case BinaryID.flagCodatID:
206 result = new CodatBinaryID(encoded);
209 case BinaryID.flagPeerGroupID:
210 result = new PeerGroupBinaryID(encoded);
211 if (PeerGroupID.worldPeerGroupID.equals(result)) {
212 result = net.jxta.peergroup.PeerGroupID.worldPeerGroupID;
216 case BinaryID.flagPeerID:
217 result = new PeerBinaryID(encoded);
220 case BinaryID.flagPipeID:
221 result = new PipeBinaryID(encoded);
224 case BinaryID.flagModuleClassID:
225 result = new ModuleClassBinaryID(encoded);
228 case BinaryID.flagModuleSpecID:
229 result = new ModuleSpecBinaryID(encoded);
233 throw new URISyntaxException(encoded, "jxta ID type not recognized");
240 * Utility to create a random array of bits to be used when a random value is required.
242 private byte[] randomID() {
243 byte[] randBuf16 = new byte[16];
245 randNumGenerator.nextBytes(randBuf16);
253 * @throws UnsupportedOperationException This form is not supported. Use CODAT from UUID package instead.
255 public net.jxta.codat.CodatID newCodatID(final net.jxta.peergroup.PeerGroupID groupID) {
256 PeerGroupID parentGroupID = (PeerGroupID) IDFormat.translateFromWellKnown(groupID);
258 return new net.jxta.impl.id.binaryID.CodatBinaryID(parentGroupID, randomID(), false);
259 // throw new UnsupportedOperationException("This form is not supported. Use CODAT from UUID package instead.");
265 * @throws UnsupportedOperationException This form is not supported. Use CODAT from UUID package instead.
267 public net.jxta.codat.CodatID newCodatID(final net.jxta.peergroup.PeerGroupID groupID, byte[] seed) {
268 PeerGroupID parentGroupID = (PeerGroupID) IDFormat.translateFromWellKnown(groupID);
270 return new net.jxta.impl.id.binaryID.CodatBinaryID(parentGroupID, seed, false);
276 * @throws UnsupportedOperationException This form is not supported. Use CODAT from UUID package instead.
278 public net.jxta.codat.CodatID newCodatID(final net.jxta.peergroup.PeerGroupID groupID, InputStream in) throws IOException {
279 PeerGroupID parentGroupID = (PeerGroupID) IDFormat.translateFromWellKnown(groupID);
281 return new net.jxta.impl.id.binaryID.CodatBinaryID(parentGroupID, randomID(), false);
287 * @throws UnsupportedOperationException This form is not supported. Use CODAT from UUID package instead.
289 public net.jxta.codat.CodatID newCodatID(final net.jxta.peergroup.PeerGroupID groupID, byte[] idValue, InputStream in) throws IOException {
290 PeerGroupID parentGroupID = (PeerGroupID) IDFormat.translateFromWellKnown(groupID);
292 return new net.jxta.impl.id.binaryID.CodatBinaryID(parentGroupID, idValue, false);
298 public net.jxta.peer.PeerID newPeerID(final net.jxta.peergroup.PeerGroupID groupID) {
299 LOG.log(Level.SEVERE, "random peer created", new RuntimeException());
300 PeerGroupID parentGroupID = (PeerGroupID) IDFormat.translateFromWellKnown(groupID);
302 return new net.jxta.impl.id.binaryID.PeerBinaryID(parentGroupID, randomID(), false);
308 public net.jxta.peer.PeerID newPeerID(final net.jxta.peergroup.PeerGroupID groupID, byte[] idValue) {
309 PeerGroupID parentGroupID = (PeerGroupID) IDFormat.translateFromWellKnown(groupID);
311 return new net.jxta.impl.id.binaryID.PeerBinaryID(parentGroupID, idValue, false);
317 public net.jxta.peergroup.PeerGroupID newPeerGroupID() {
318 return net.jxta.id.IDFactory.newPeerGroupID(randomID());
324 public net.jxta.peergroup.PeerGroupID newPeerGroupID(byte[] idValue) {
325 return new PeerGroupBinaryID(idValue, false);
331 public net.jxta.peergroup.PeerGroupID newPeerGroupID(net.jxta.peergroup.PeerGroupID parent) {
332 LOG.log(Level.SEVERE, "random peergroup created", new RuntimeException());
333 PeerGroupID parentGroupID = (PeerGroupID) IDFormat.translateFromWellKnown(parent);
335 return net.jxta.id.IDFactory.newPeerGroupID(parentGroupID, randomID());
341 public net.jxta.peergroup.PeerGroupID newPeerGroupID(net.jxta.peergroup.PeerGroupID parent, byte[] idValue) {
342 PeerGroupID parentGroupID = (PeerGroupID) IDFormat.translateFromWellKnown(parent);
344 return new PeerGroupBinaryID(parentGroupID, idValue, false);
350 public net.jxta.pipe.PipeID newPipeID(final net.jxta.peergroup.PeerGroupID groupID) {
351 PeerGroupID parentGroupID = (PeerGroupID) IDFormat.translateFromWellKnown(groupID);
353 return net.jxta.id.IDFactory.newPipeID(parentGroupID, randomID());
359 public net.jxta.pipe.PipeID newPipeID(final net.jxta.peergroup.PeerGroupID groupID, byte[] idValue) {
360 PeerGroupID peerGroupID = (PeerGroupID) IDFormat.translateFromWellKnown(groupID);
362 return new PipeBinaryID(peerGroupID, idValue, false);
368 * @throws UnsupportedOperationException This form is not supported because a binary ID is meant to be created with a random ID.
370 public net.jxta.platform.ModuleClassID newModuleClassID() {
371 throw new UnsupportedOperationException(
372 "This form is not supported because a binary ID is meant to be created with a random ID. Use UUID package instead.");
378 * @throws UnsupportedOperationException This form is not supported because a binary ID is meant to be created with a random ID.
380 public net.jxta.platform.ModuleClassID newModuleClassID(final net.jxta.platform.ModuleClassID classID) {
381 throw new UnsupportedOperationException(
382 "This form is not supported because a binary ID is meant to be created with a random ID. Use UUID package instead.");
388 * @throws UnsupportedOperationException This form is not supported because a binary ID is meant to be created with a random ID. Use UUID instead.
390 public net.jxta.platform.ModuleSpecID newModuleSpecID(final net.jxta.platform.ModuleClassID classID) {
391 throw new UnsupportedOperationException(
392 "This form is not supported because a binary ID is meant to be created with a random ID. Use UUID package instead.");