Coverage Report - org.apache.commons.id.uuid.VersionOneGenerator
 
Classes in this File Line Coverage Branch Coverage Complexity
VersionOneGenerator
91%
29/32
67%
4/6
1.75
 
 1  
 /*
 2  
  * Licensed to the Apache Software Foundation (ASF) under one or more
 3  
  * contributor license agreements.  See the NOTICE file distributed with
 4  
  * this work for additional information regarding copyright ownership.
 5  
  * The ASF licenses this file to You under the Apache License, Version 2.0
 6  
  * (the "License"); you may not use this file except in compliance with
 7  
  * the License.  You may obtain a copy of the License at
 8  
  *
 9  
  *      http://www.apache.org/licenses/LICENSE-2.0
 10  
  *
 11  
  * Unless required by applicable law or agreed to in writing, software
 12  
  * distributed under the License is distributed on an "AS IS" BASIS,
 13  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 14  
  * See the License for the specific language governing permissions and
 15  
  * limitations under the License.
 16  
  */
 17  
 package org.apache.commons.id.uuid;
 18  
 
 19  
 import org.apache.commons.discovery.tools.DiscoverSingleton;
 20  
 import org.apache.commons.id.IdentifierGenerator;
 21  
 import org.apache.commons.id.uuid.clock.OverClockedException;
 22  
 import org.apache.commons.id.uuid.state.Node;
 23  
 
 24  
 /**
 25  
  * Class is responsible for generating version 1 UUID's per RFC 4122.
 26  
  * This class attempts to locate the machine's node identifier
 27  
  * first by attempting to loading the properties file UUID.properties
 28  
  * from the system classpath. If the UUID.properties file does not exist
 29  
  * then the generator will create a node identifier from random information as
 30  
  * defined in the
 31  
  * <a href="ftp://ftp.rfc-editor.org/in-notes/rfc4122.txt">RFC 4122:
 32  
  * A Universally Unique IDentifier (UUID) URN Namespace</a>.
 33  
  *
 34  
  * @author Commons-Id team
 35  
  * @version $Revision: 480488 $ $Date: 2006-11-29 08:57:26 +0000 (Wed, 29 Nov 2006) $
 36  
  *
 37  
  */
 38  
 
 39  
 public final class VersionOneGenerator implements IdentifierGenerator, Constants {
 40  
 
 41  
     /** Positions 10-16: Length of node bytes */
 42  
     private static final int NODE_ID_BYTE_LENGTH = 6;
 43  
 
 44  
     /** Position 8: CLOCK_SEQ_LOW byte */
 45  
     private static final int CLOCK_HI_VARIANT_BYTE8 = 8;
 46  
     /** Position 9: CLOCK_SEQ_HIGH and VARIANT byte */
 47  
     private static final int CLOCK_LOW_BYTE9 = 9;
 48  
     /** Positions 10-16: Start of node bytes */
 49  
     private static final int NODE_ID_BYTE10 = 10;
 50  
 
 51  
     /** The default NodeManager implementation. */
 52  3
     private static final String DEFAULT_NODEMANAGER_IMPL = NodeManagerImpl.class.getName();
 53  
 
 54  
     /** The NodeManager implementation */
 55  
     private NodeManager manager;
 56  
 
 57  
     /** Singleton instance such that only one instance is accessing the static
 58  
      * fields at any time.
 59  
      */
 60  
     private static VersionOneGenerator generator;
 61  
 
 62  
     /**
 63  
      *  <p>Private singleton constructor.</p>
 64  
      */
 65  
     private VersionOneGenerator() {
 66  1
         super();
 67  1
         manager = (NodeManager) DiscoverSingleton.find( NodeManager.class, DEFAULT_NODEMANAGER_IMPL);
 68  1
     }
 69  
 
 70  
     /**
 71  
      * <p>Returns the singleton instance of the version one UUID generator.</p>
 72  
      *
 73  
      * @return the singleton instance of the version one UUID generator.
 74  
      */
 75  
     public static VersionOneGenerator getInstance()  {
 76  1
             if (generator == null) {
 77  1
                 generator = new VersionOneGenerator();
 78  
             }
 79  1
             return generator;
 80  
     }
 81  
     
 82  
     /**
 83  
      * @see org.apache.commons.id.IdentifierGenerator#nextIdentifier()
 84  
      */
 85  
     public Object nextIdentifier() {
 86  0
         return nextUUID();
 87  
     }
 88  
 
 89  
     /**
 90  
      * <p>Returns a new version 1 UUID. The method acts upons static variables
 91  
      * and so should be sychronized.</p>
 92  
      *
 93  
      * @return Returns a new version 1 UUID.
 94  
      */
 95  
     public synchronized UUID nextUUID() {
 96  1
         byte[] rawUUID = new byte[UUID_BYTE_LENGTH];
 97  1
         long time = 0;
 98  1
         short clockSq = 0;
 99  1
         Node node = manager.currentNode();
 100  2
         while (time < 1) {
 101  
             try {
 102  1
                 manager.lockNode(node);
 103  1
                 time = node.getUUIDTime();
 104  1
                 clockSq = node.getClockSequence();
 105  1
                 System.arraycopy(node.getNodeIdentifier(), 0, rawUUID, NODE_ID_BYTE10, NODE_ID_BYTE_LENGTH);
 106  1
                 manager.releaseNode(node);
 107  0
             } catch (OverClockedException e) {
 108  0
                 node = manager.nextAvailableNode();
 109  
             } finally {
 110  1
                 manager.releaseNode(node);
 111  1
             }
 112  1
         }
 113  1
         byte[] timeBytes = Bytes.toBytes(time);
 114  
         //Copy time low
 115  1
         System.arraycopy(timeBytes, TIME_LOW_TS_POS, rawUUID, TIME_LOW_START_POS, TIME_LOW_BYTE_LEN);
 116  
         //Copy time mid
 117  1
         System.arraycopy(timeBytes, TIME_MID_TS_POS, rawUUID, TIME_MID_START_POS, TIME_MID_BYTE_LEN);
 118  
         //Copy time hi
 119  1
         System.arraycopy(timeBytes, TIME_HI_TS_POS, rawUUID, TIME_HI_START_POS, TIME_HI_BYTE_LEN);
 120  
         //Set version
 121  1
         rawUUID[6] |= 0x10; // 0001 0000
 122  
         //Set clock sequence
 123  1
         rawUUID[CLOCK_HI_VARIANT_BYTE8] = (byte) ((clockSq & 0x3F00) >>> 8);
 124  1
         rawUUID[CLOCK_HI_VARIANT_BYTE8] |= 0x80;
 125  1
         rawUUID[CLOCK_LOW_BYTE9] = (byte) (clockSq & 0xFF);
 126  
 
 127  1
         return new UUID(rawUUID);
 128  
     }
 129  
 }