Coverage report

  %line %branch
org.apache.turbine.util.db.UUIdGenerator
0% 
0% 

 1  
 package org.apache.turbine.util.db;
 2  
 
 3  
 /*
 4  
  * Copyright 2001-2005 The Apache Software Foundation.
 5  
  *
 6  
  * Licensed under the Apache License, Version 2.0 (the "License")
 7  
  * you may not use this file except in compliance with the License.
 8  
  * You may obtain a copy of the License at
 9  
  *
 10  
  *     http://www.apache.org/licenses/LICENSE-2.0
 11  
  *
 12  
  * Unless required by applicable law or agreed to in writing, software
 13  
  * distributed under the License is distributed on an "AS IS" BASIS,
 14  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 15  
  * See the License for the specific language governing permissions and
 16  
  * limitations under the License.
 17  
  */
 18  
 
 19  
 import java.io.ByteArrayOutputStream;
 20  
 import java.io.OutputStream;
 21  
 
 22  
 import java.util.StringTokenizer;
 23  
 
 24  
 import javax.mail.internet.MimeUtility;
 25  
 
 26  
 import org.apache.commons.lang.StringUtils;
 27  
 
 28  
 import org.apache.commons.logging.Log;
 29  
 import org.apache.commons.logging.LogFactory;
 30  
 
 31  
 import org.apache.turbine.Turbine;
 32  
 import org.apache.turbine.TurbineConstants;
 33  
 
 34  
 import org.apache.turbine.util.TurbineException;
 35  
 
 36  
 /**
 37  
  * <p>This class generates universally unique id's in the form of a String.
 38  
  * The id has three parts.  The first is supposed to be location dependent.
 39  
  * The preferred location parameter is an ethernet (MAC) address, but an IP
 40  
  * can be used as well.  if none is supplied a Math.random generated number
 41  
  * will be used.  This part of the key will be 48 bits in length.
 42  
  * The second part of the key is time related and will be the lower 48 bits
 43  
  * of the long used to signify the time since Jan. 1, 1970.  This will
 44  
  * cause key rollover in the year 6429.
 45  
  * The preceding 12 bytes are Base64 encoded with the characters / and *
 46  
  * replaced by _ (underscore) and - (dash).  Resulting in 16 characters.
 47  
  * Finally a counter is used to hand out 4095 keys in between each
 48  
  * timestamp.
 49  
  * The resulting id is a String of 18 characters including:
 50  
  * a-z,A-Z,0-9, and the previously mentioned - and _.</p>
 51  
  *
 52  
  * <p>Note this class does not save any state information, so it is important
 53  
  * that time only moves forward to keep the integrity of the ids.  We
 54  
  * might want to consider saving some state info.</p>
 55  
  *
 56  
  * <p>To specify the MAC/Ethernet address, add a uuid.address= property to the
 57  
  * TurbineResources.properties file.</p>
 58  
  *
 59  
  * @author <a href="mailto:jmcnally@collab.net">John D. McNally</a>
 60  
  * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a>
 61  
  * @version $Id: UUIdGenerator.java 264152 2005-08-29 14:50:22Z henning $
 62  
  * @deprecated Use the Unique ID Service
 63  
  */
 64  
 public class UUIdGenerator
 65  
 {
 66  
     /** Logging */
 67  0
     private static Log log = LogFactory.getLog(UUIdGenerator.class);
 68  
 
 69  
     private static final String errorString = "uuid.address property in "
 70  
             + "TurbineResources.properties should be a valid IP\n "
 71  
             + "e.g. 18.2.3.100, or an ethernet address e.g. "
 72  
             + "AE:10:3E:de:f5:77 uuid.address was ";
 73  
 
 74  0
     private byte[] address = new byte[6];
 75  0
     private String baseId = null;
 76  0
     private int counter = 0;
 77  
 
 78  
     /**
 79  
      * Constructor
 80  
      */
 81  
     public UUIdGenerator() throws TurbineException
 82  0
     {
 83  0
         String addr =
 84  
             Turbine.getConfiguration().getString(TurbineConstants.UUID_ADDRESS_KEY);
 85  
 
 86  0
         if (StringUtils.isEmpty(addr))
 87  
         {
 88  0
             log.info("UUIdGenerator is using a random number as the "
 89  
                     + "base for id's.  This is not the best method for many "
 90  
                     + "purposes, but may be adequate in some circumstances."
 91  
                     + " Consider using an IP or ethernet (MAC) address if "
 92  
                     + "available. Edit TurbineResources.properties file and "
 93  
                     + "add a uuid.address= property.");
 94  
 
 95  0
             for (int i = 0; i < 6; i++)
 96  
             {
 97  0
                 address[i] = (byte) (255 * Math.random());
 98  
             }
 99  
         }
 100  
         else
 101  
         {
 102  0
             if (addr.indexOf(".") > 0)
 103  
             {
 104  
                 // we should have an IP
 105  0
                 StringTokenizer stok = new StringTokenizer(addr, ".");
 106  0
                 if (stok.countTokens() != 4)
 107  
                 {
 108  0
                     throw new TurbineException(errorString + addr);
 109  
                 }
 110  
                 // this is meant to insure that id's made from ip addresses
 111  
                 // will not conflict with MAC id's. I think MAC addresses
 112  
                 // will never have the highest bit set.  Though this should
 113  
                 // be investigated further.
 114  0
                 address[0] = (byte) 255;
 115  0
                 address[1] = (byte) 255;
 116  0
                 int i = 2;
 117  
                 try
 118  
                 {
 119  0
                     while (stok.hasMoreTokens())
 120  
                     {
 121  0
                         address[i++] =
 122  
                                 Integer.valueOf(stok.nextToken(),
 123  
                                         16).byteValue();
 124  
                     }
 125  
                 }
 126  0
                 catch (Exception e)
 127  
                 {
 128  0
                     throw new TurbineException(errorString + addr, e);
 129  0
                 }
 130  
             }
 131  0
             else if (addr.indexOf(":") > 0)
 132  
             {
 133  
                 // we should have a MAC
 134  0
                 StringTokenizer stok = new StringTokenizer(addr, ":");
 135  0
                 if (stok.countTokens() != 6)
 136  
                 {
 137  0
                     throw new TurbineException(errorString + addr);
 138  
                 }
 139  0
                 int i = 0;
 140  
                 try
 141  
                 {
 142  0
                     while (stok.hasMoreTokens())
 143  
                     {
 144  0
                         address[i++] = Byte.parseByte(stok.nextToken(), 16);
 145  
                     }
 146  
                 }
 147  0
                 catch (Exception e)
 148  
                 {
 149  0
                     throw new TurbineException(errorString + addr, e);
 150  0
                 }
 151  
             }
 152  
             else
 153  
             {
 154  0
                 throw new TurbineException(errorString + addr);
 155  
             }
 156  
         }
 157  0
     }
 158  
 
 159  
     /**
 160  
      * Generates the new base id
 161  
      */
 162  
     private void generateNewBaseId() throws Exception
 163  
     {
 164  0
         long now = System.currentTimeMillis();
 165  0
         byte[] nowBytes = org.apache.java.lang.Bytes.toBytes(now);
 166  0
         ByteArrayOutputStream bas = null;
 167  0
         OutputStream encodedStream = null;
 168  
         try
 169  
         {
 170  0
             bas = new ByteArrayOutputStream(16);
 171  0
             encodedStream = MimeUtility.encode(bas, "base64");
 172  0
             encodedStream.write(nowBytes);
 173  0
             baseId = bas.toString("ISO-8859-1"); // or maybe "US-ASCII"?
 174  0
             baseId = baseId.replace('/', '_');
 175  0
             baseId = baseId.replace('*', '-');
 176  0
         }
 177  
         finally
 178  
         {
 179  0
             if (bas != null)
 180  
             {
 181  0
                 bas.close();
 182  
             }
 183  0
             if (encodedStream != null)
 184  
             {
 185  0
                 encodedStream.close();
 186  
             }
 187  0
         }
 188  0
     }
 189  
 
 190  
     /**
 191  
      * Gets the id
 192  
      * @return the 18 character id
 193  
      */
 194  
     public String getId() throws Exception
 195  
     {
 196  0
         int index = ++counter;
 197  0
         if (index > 4095)
 198  
         {
 199  0
             synchronized (this)
 200  
             {
 201  0
                 if (counter > 4095)
 202  
                 {
 203  0
                     generateNewBaseId();
 204  0
                     counter = 0;
 205  
                 }
 206  
                 else
 207  
                 {
 208  0
                     index = ++counter;
 209  
                 }
 210  0
             }
 211  
         }
 212  0
         StringBuffer idbuf = new StringBuffer(18);
 213  0
         idbuf.append(baseId);
 214  0
         idbuf.append(countChar[index / 64]);
 215  0
         idbuf.append(countChar[index % 64]);
 216  0
         return idbuf.toString();
 217  
     }
 218  
 
 219  
     /**
 220  
      * characters used in the ID
 221  
      */
 222  0
     private static final char[] countChar =
 223  
             {
 224  
                 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L',
 225  
                 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
 226  
                 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
 227  
                 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
 228  
                 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7',
 229  
                 '8', '9', '-', '_'
 230  
             };
 231  
 }
 232  
 

This report is generated by jcoverage, Maven and Maven JCoverage Plugin.