001: /**********************************************************************************
002: * $URL: https://source.sakaiproject.org/svn/metaobj/tags/sakai_2-4-1/metaobj-impl/api-impl/src/java/org/sakaiproject/metaobj/utils/id/guid/Guid.java $
003: * $Id: Guid.java 14225 2006-09-05 17:39:44Z chmaurer@iupui.edu $
004: ***********************************************************************************
005: *
006: * Copyright (c) 2004, 2005, 2006 The Sakai Foundation.
007: *
008: * Licensed under the Educational Community License, Version 1.0 (the "License");
009: * you may not use this file except in compliance with the License.
010: * You may obtain a copy of the License at
011: *
012: * http://www.opensource.org/licenses/ecl1.php
013: *
014: * Unless required by applicable law or agreed to in writing, software
015: * distributed under the License is distributed on an "AS IS" BASIS,
016: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017: * See the License for the specific language governing permissions and
018: * limitations under the License.
019: *
020: **********************************************************************************/package org.sakaiproject.metaobj.utils.id.guid;
021:
022: public class Guid implements java.io.Serializable {
023:
024: private static final int HEX_RADIX = 16;
025: /**
026: * length of a GUID, in bytes (16)
027: */
028: private static final short GUID_LEN = HEX_RADIX;
029: private byte guid[] = new byte[GUID_LEN];
030:
031: public static final byte AUTOGEN_BY_DB = 1;
032: public static final byte NO_AUTOGEN_BY_DB = 2;
033:
034: /**
035: * holds the string representation of this GUID, and is computed during construction,
036: * and when setGuid() is called. Used to optimize toString performance.
037: */
038: private String guidStr;
039:
040: /**
041: * indicates whether to let the database auto-generate the value or not
042: */
043: private boolean dbAutoGen = true;
044:
045: /**
046: * Description: Allocate a new Guid object
047: */
048:
049: public Guid() {
050: boolean bSecureGuid = true;
051: RandomGUID tmpGuid = new RandomGUID(bSecureGuid);
052: guid = fromHexString(tmpGuid.valueAfterMD5);
053: setGuid(guid);
054: tmpGuid = null;
055: }
056:
057: /**
058: * from effective java by joshua bloch
059: * step 1: perform == test
060: * step 2: instanceof test
061: * step 3: cast parameter to type
062: * step 4: check primitives with ==, objects with equals()
063: *
064: * @param o
065: * @return
066: */
067: public boolean equals(Object o) {
068: //1.
069: if (this == o) {
070: return true;
071: }
072: //2.
073: if (!(o instanceof Guid)) {
074: // if o is null, we return here
075: return false;
076: }
077: //3.
078: Guid guid = (Guid) o;
079: //4.
080: if (this .toString().equals(guid.toString())) {
081: return true;
082: }
083:
084: return false;
085: }
086:
087: public int hashCode() {
088: return this .toString().hashCode();
089: }
090:
091: /**
092: * Description: Allocates a new Guid object from the passed in byte array.
093: *
094: * @param inGuid 16 byte array for this GUID
095: * @throws IllegalArgumentException if byte array is not GUID_LEN bytes
096: */
097: public Guid(byte[] inGuid) {
098: setGuid(inGuid);
099: }
100:
101: public Guid(String sGuid) {
102: if ((sGuid != null) && (sGuid.length()) == 32) {
103: guid = fromHexString(sGuid);
104: guidStr = internalToString();
105: } else {
106: throw new IllegalArgumentException(
107: "sGuid is either null or the wrong length");
108: }
109: }
110:
111: public boolean isValidGuid() {
112: return this .guid != null && this .guid.length == GUID_LEN;
113: }
114:
115: /**
116: * Sets GUID to passed in value
117: *
118: * @param inGuid 16-byte array containing raw GUID value
119: * @throws IllegalArgumentException if byte array is not GUID_LEN bytes
120: */
121: public void setGuid(byte[] inGuid) throws IllegalArgumentException {
122:
123: if (inGuid.length == GUID_LEN) {
124: for (int i = 0; i < GUID_LEN; i++) {
125: guid[i] = inGuid[i];
126: }
127: guidStr = internalToString();
128: } else {
129: throw new IllegalArgumentException("GUID Passed in is not "
130: + GUID_LEN + " bytes - it is " + inGuid.length
131: + " bytes");
132: }
133: }
134:
135: /**
136: * Get the raw bytes for this GUID
137: *
138: * @return the raw GUID in a byte array
139: */
140: public byte[] getGuid() {
141: return (byte[]) guid.clone();
142: }
143:
144: public String getString() {
145: return guidStr;
146: }
147:
148: /**
149: * Return string representation of the GUID as a hex value
150: * <p>Example: returns the string 0x8f6eff8344a8e03b125590af6d21e9b2
151: * <p> This can be then passed to a database as a numerical value
152: *
153: * @see internalToString()
154: */
155: public String toString() {
156: return guidStr;
157: }
158:
159: /**
160: * Converts byte array to hex string representation
161: *
162: * @return a new string
163: */
164: // convert byte array to hex string representation
165: private String internalToString() {
166:
167: StringBuffer buf = new StringBuffer();
168: String hexStr;
169: int val;
170: for (int i = 0; i < GUID_LEN; i++) {
171: //Treating each byte as an unsigned value ensures
172: //that we don't str doesn't equal things like 0xFFFF...
173: val = ByteOrder.ubyte2int(guid[i]);
174: hexStr = Integer.toHexString(val);
175: while (hexStr.length() < 2) {
176: hexStr = "0" + hexStr;
177: }
178: buf.append(hexStr);
179: }
180: return buf.toString().toUpperCase();
181:
182: /*
183: Integer tmpInt;
184: String hexChar = "";
185: String hexStr2 = "";
186:
187: for(int i=0; i<guid.length; i++) {
188: tmpInt = new Integer( ((int) guid[i]) & 0x000000FF);
189: hexChar = tmpInt.toHexString(tmpInt.intValue());
190: tmpInt = null;
191: // toHexString strips leading zeroes, so add back in if necessary
192: if (hexChar.length() == 1) {
193: hexChar = "0" + hexChar;
194: }
195: hexStr2 += hexChar;
196: }
197: hexStr2 = "0x" + hexStr2;
198: return hexStr2.toUpperCase();
199: */
200: }
201:
202: /**
203: * Create a GUID bytes from a hex string version.
204: * Throws IllegalArgumentException if sguid is
205: * not of the proper format.
206: */
207: public static byte[] fromHexString(String sguid)
208: throws IllegalArgumentException {
209: byte bytes[] = new byte[GUID_LEN];
210: try {
211: for (int i = 0; i < GUID_LEN; i++) {
212: bytes[i] = (byte) Integer.parseInt(sguid.substring(
213: i * 2, (i * 2) + 2), HEX_RADIX);
214: }
215: return bytes;
216: } catch (NumberFormatException e) {
217: throw new IllegalArgumentException();
218: } catch (IndexOutOfBoundsException e) {
219: throw new IllegalArgumentException();
220: }
221: }
222:
223: public static boolean isValidGuidString(String sGuid) {
224: return (sGuid != null && sGuid.length() == GUID_LEN * 2);
225: }
226:
227: public boolean isDbAutoGen() {
228: return dbAutoGen;
229: }
230:
231: public boolean getDbAutoGen() {
232: return isDbAutoGen();
233: }
234:
235: public void setAutoGen(boolean dbAutoGen) {
236: this.dbAutoGen = dbAutoGen;
237: }
238:
239: }
|