/* URN5Namespace.java * * Copyright (c) 2002, Tuomas Lukka * * This file is part of Gzz. * * Gzz 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 of the License, or * (at your option) any later version. * * Gzz 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 Gzz; if not, write to the Free * Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA * * */ /* * Written by Tuomas Lukka */ package org.fenfire.util; import java.util.*; import java.security.SecureRandom; import java.io.*; import java.lang.String; /** A class which is able to generate globally unique URN-5 * identifiers. * URN-5 identifiers are globally unique, nonhierarchical identifiers. *

* The names generated by the same instance share the same "random number" * part and differ only by the "local part". * See http://www.iana.org/assignments/urn-informal/urn-5 *

* The java.security.SecureRandom class is used as a source of random numbers. */ public class URN5Namespace { /** 21 bytes ^= 28 base64 namespace chars */ public static final int NAMESPACECHARS = 28; /** 64 characters for encoding. */ private static String base64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-"; /** The random number generator to use for generating the initial string. */ private static SecureRandom sr; /** Static instance to use when security concerns aren't too high. * The security concerns are that everything using this * in the same session will have the same 'random number' part, * making it obvious that they were created in the same session. */ public static final URN5Namespace instance = new URN5Namespace(); private String namespace; private long nextNumber = 1; /** Generate a sequence of base64 characters * with at least 160 bits of randomness. */ public static synchronized String generateRandomChars() { if(sr == null) sr = new SecureRandom(); StringBuffer chars = new StringBuffer(NAMESPACECHARS); for(int i=0; i 1000) throw new Error("ARGH!"); } while(x < 0 || x > 64); // step around a bug(?) in kaffe chars.append(base64.charAt(x)); } return chars.toString(); } public URN5Namespace() { namespace = generateRandomChars(); } /** Get the base id of the namespace. * This does not generate unique identifiers: this is * simply the prefix of all identifiers generated in this namespace. * Of course, if you create a URN5Namespace, call this method once * and then throw away the object, the result should be random. */ synchronized public String getNamespaceId() { return "urn:urn-5:" + namespace; } synchronized public String generateId() { long num = nextNumber ++; return "urn:urn-5:" + namespace + ":" + num; } /** Get the first part of a Storm data block id. * I.e., something like 'storm:data:abcdef...faq:1:'; * a full data block URI can be formed by * appending the content type (optional) * a comma, and the data. This is used by FakeTextSpan. */ synchronized public String getStormDataBlockId() { long num = nextNumber ++; return "storm:data:" + namespace + ":" + num; } /** If run as a main program, generate and print to * stdout a single urn-5 identifier. */ static public void main(String argv[]) { System.out.println(new URN5Namespace().getNamespaceId()); } }