001: /*
002: * (c) Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 Hewlett-Packard Development Company, LP
003: * [See end of file]
004: */
005:
006: /** A class to create and recreate UUIDs.
007: * @author Andy Seaborne
008: * @version $Id: JenaUUID.java,v 1.3 2008/01/02 12:06:07 andy_seaborne Exp $
009: * http://www.opengroup.org/onlinepubs/009629399/apdxa.htm
010: */package com.hp.hpl.jena.shared.uuid;
011:
012: import org.apache.commons.logging.Log;
013: import org.apache.commons.logging.LogFactory;
014:
015: // TODO
016: // + Comments and renaming.
017: // ? Move to/from string code here (string <=> pair of longs).
018: // OK but unparse code makes explicit what goes where in the structures
019: // parse/unparseV4 is the generic code.
020:
021: // UUID and factory
022:
023: public abstract class JenaUUID {
024: static final int HEX = 16;
025: static final int Var_NCS = 0;
026: static final int Var_Std = 2; // Same as DCE
027: static final int Var_DCE = 2;
028: static final int Var_MS_GUID = 6;
029: static final int Var_Reserved = 7;
030:
031: abstract public int getVersion();
032:
033: abstract public int getVariant();
034:
035: abstract public long getMostSignificantBits();
036:
037: abstract public long getLeastSignificantBits();
038:
039: protected int _getVersion(long mostSigBits, long leastSigBits) {
040: // int variant = (int)((UUID_V1_Gen.maskVariant & leastSigBits)>>>62) ;
041: // int version = (int)((UUID_V1_Gen.maskVersion & mostSigBits)>>>12) ;
042: int version = (int) Bits.unpack(mostSigBits, 12, 16);
043: return version;
044: }
045:
046: protected int _getVariant(long mostSigBits, long leastSigBits) {
047: int variant = (int) Bits.unpack(leastSigBits, 62, 64);
048: return variant;
049: }
050:
051: protected JenaUUID() {
052: }
053:
054: /** Format as a string - no URI scheme **/
055: public String asString() {
056: return toString();
057: }
058:
059: /** Format as a URI - that is uuid:ABCD */
060: public String asURI() {
061: return "uuid:" + toString();
062: }
063:
064: /** Format as a URN - that is urn:uuid:ABCD */
065: public String asURN() {
066: return "urn:uuid:" + toString();
067: }
068:
069: // ----------------------------------------------------
070: // Factory
071:
072: static UUIDFactory factory = new UUID_V1_Gen();
073:
074: public static void setFactory(UUIDFactory factory) {
075: JenaUUID.factory = factory;
076: }
077:
078: public static UUIDFactory getFactory() {
079: return factory;
080: }
081:
082: /** Create a UUID */
083: public static JenaUUID generate() {
084: return factory.generate();
085: }
086:
087: public static void reset() {
088: factory.reset();
089: }
090:
091: /** The nil UUID */
092: public static JenaUUID nil() {
093: return UUID_nil.getNil();
094: }
095:
096: public static String strNil() {
097: return UUID_nil.getNilString();
098: }
099:
100: public boolean isNil() {
101: return this .equals(nil());
102: } // Or this == UUID_nil.nil because it's a singleton.
103:
104: /** Recreate a UUID from string*/
105: public static JenaUUID parse(String s) {
106: if (s.equals(strNil()))
107: return nil();
108:
109: // Canonical: this works in conjunction with .equals
110: s = s.toLowerCase();
111:
112: if (s.startsWith("urn:"))
113: s = s.substring(4);
114: if (s.startsWith("uuid:"))
115: s = s.substring(5);
116:
117: if (s.length() != 36)
118: throw new FormatException(
119: "UUID string is not 36 chars long: it's "
120: + s.length() + " [" + s + "]");
121:
122: if (s.charAt(8) != '-' || s.charAt(13) != '-'
123: || s.charAt(18) != '-' || s.charAt(23) != '-')
124: throw new FormatException(
125: "String does not have dashes in the right places: "
126: + s);
127:
128: // 00000000-0000-0000-0000-000000000000
129: // ^ ^ ^ ^ ^
130: // Byte: 0 4 6 8 10
131: // Char: 0 9 14 19 24 including hyphens
132:
133: int x = (int) Bits.unpack(s, 19, 23);
134: int variant = (int) (x >>> 14);
135: int version = (int) Bits.unpack(s, 14, 15);
136:
137: if (variant == Var_Std) {
138: switch (version) {
139: case UUID_V1.version:
140: return UUID_V1_Gen.parse$(s);
141: case UUID_V4.version:
142: return UUID_V4_Gen.parse$(s);
143: }
144: LogFactory.getLog(JenaUUID.class).warn(
145: s + " : Unsupported version: " + version);
146: throw new UnsupportedOperationException(
147: "String specifies unsupported UUID version: "
148: + version);
149: }
150:
151: Log log = LogFactory.getLog(JenaUUID.class);
152:
153: switch (variant) {
154: case Var_NCS: // NCS
155: log.warn(s
156: + " : Oh look! An NCS UUID ID. Call the museum.");
157: break;
158: case Var_DCE: // DCE - should have been caught earlier.
159: log
160: .warn(s
161: + " : Oh look! A DCE UUID ID - but we shodul have already handled this");
162: break;
163: case Var_MS_GUID:
164: log.warn(s + " : Microsoft UUID ID.");
165: break;
166: case Var_Reserved:
167: log.warn(s + " : Reserved variant");
168: break;
169: default:
170: log.warn(s + " : Unknown variant: " + variant);
171: break;
172: }
173: throw new UnsupportedOperationException(
174: "String specifies unsupported UUID variant: " + variant);
175: }
176:
177: // ----------------------------------------------------
178: // Worker functions
179:
180: static void toHex(StringBuffer sBuff, long value, int lenBytes) {
181: // Insert in high-low order, by nibble
182: for (int i = 2 * lenBytes - 1; i >= 0; i--) {
183: int shift = 4 * i;
184: int x = (int) (value >>> shift & 0xF);
185: sBuff.append(Character.forDigit(x, 16));
186: }
187: }
188:
189: static public class FormatException extends RuntimeException {
190: public FormatException() {
191: super ();
192: }
193:
194: public FormatException(String msg) {
195: super (msg);
196: }
197: }
198:
199: }
200:
201: /*
202: * (c) Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 Hewlett-Packard Development Company, LP
203: * All rights reserved.
204: *
205: * Redistribution and use in source and binary forms, with or without
206: * modification, are permitted provided that the following conditions
207: * are met:
208: * 1. Redistributions of source code must retain the above copyright
209: * notice, this list of conditions and the following disclaimer.
210: * 2. Redistributions in binary form must reproduce the above copyright
211: * notice, this list of conditions and the following disclaimer in the
212: * documentation and/or other materials provided with the distribution.
213: * 3. The name of the author may not be used to endorse or promote products
214: * derived from this software without specific prior written permission.
215: *
216: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
217: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
218: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
219: * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
220: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
221: * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
222: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
223: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
224: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
225: * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
226: */
|