[jboss-svn-commits] JBL Code SVN: r5048 - in labs/jbossrules/trunk/drools-core/src/main/java/org/drools: . common leaps reteoo util

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Wed Jul 12 13:34:07 EDT 2006


Author: mark.proctor at jboss.com
Date: 2006-07-12 13:34:02 -0400 (Wed, 12 Jul 2006)
New Revision: 5048

Added:
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/util/UUID.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/util/UUIDGenerator.java
Modified:
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/RuleBaseFactory.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/AbstractRuleBase.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/InternalRuleBase.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/leaps/LeapsRuleBase.java
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ReteooRuleBase.java
Log:
JBRULES-369 generate RuleBases with a UUID id
-Generated UUIDs with a ripped and inlined version of JUG

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/RuleBaseFactory.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/RuleBaseFactory.java	2006-07-12 17:12:42 UTC (rev 5047)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/RuleBaseFactory.java	2006-07-12 17:34:02 UTC (rev 5048)
@@ -1,5 +1,7 @@
 package org.drools;
 
+import org.drools.util.UUIDGenerator;
+
 /*
  * Copyright 2005 JBoss Inc
  * 
@@ -41,10 +43,10 @@
     public static RuleBase newRuleBase(final int type) {
         switch ( type ) {
             case RuleBase.RETEOO :
-                return new org.drools.reteoo.ReteooRuleBase();
+                return new org.drools.reteoo.ReteooRuleBase( UUIDGenerator.getInstance().generateRandomBasedUUID().toString() );
             case RuleBase.LEAPS :
                 try {
-                    return new org.drools.leaps.LeapsRuleBase();
+                    return new org.drools.leaps.LeapsRuleBase( UUIDGenerator.getInstance().generateRandomBasedUUID().toString() );
                 } catch ( final PackageIntegrationException e ) {
                     throw new IllegalStateException( "Unable to create Leaps engine. Error: " + e.getMessage() );
                 }

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/AbstractRuleBase.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/AbstractRuleBase.java	2006-07-12 17:12:42 UTC (rev 5047)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/AbstractRuleBase.java	2006-07-12 17:34:02 UTC (rev 5048)
@@ -81,15 +81,6 @@
 
     /** Special value when adding to the underlying map. */
     protected static final Object                   PRESENT = new Object();
-
-    // ------------------------------------------------------------
-    // Constructors
-    // ------------------------------------------------------------
-
-    public AbstractRuleBase(final RuleBaseConfiguration config,
-                            final FactHandleFactory factHandleFactory) {
-        this("default", config, factHandleFactory);
-    }
     
     /**
      * Construct.
@@ -100,7 +91,11 @@
     public AbstractRuleBase(final String id,
                             final RuleBaseConfiguration config,
                             final FactHandleFactory factHandleFactory) {
-        this.id = id;
+        if ( id != null ) {
+            this.id = id;
+        } else {
+            this.id  = "default";
+        }
         this.config = (config != null) ? config : new RuleBaseConfiguration();
         this.config.makeImmutable();
         this.factHandleFactory = factHandleFactory;
@@ -181,13 +176,6 @@
     public String getId() {
         return this.id;
     }
-
-    /**
-     * @param id the id to set
-     */
-    public void setId(String id) {
-        this.id = id;
-    }
     
     /**
      * @see RuleBase

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/InternalRuleBase.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/InternalRuleBase.java	2006-07-12 17:12:42 UTC (rev 5047)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/InternalRuleBase.java	2006-07-12 17:34:02 UTC (rev 5048)
@@ -33,12 +33,7 @@
     /**
      * @return the id
      */
-    public String getId();
-
-    /**
-     * @param id the id to set
-     */
-    public void setId(String id);    
+    public String getId();  
     
     public FactHandleFactory newFactHandleFactory();
 

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/leaps/LeapsRuleBase.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/leaps/LeapsRuleBase.java	2006-07-12 17:12:42 UTC (rev 5047)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/leaps/LeapsRuleBase.java	2006-07-12 17:34:02 UTC (rev 5048)
@@ -58,6 +58,7 @@
      */
     public LeapsRuleBase() throws PackageIntegrationException {
         this( null,
+              null,
               new LeapsFactHandleFactory() );
     }
 
@@ -66,6 +67,19 @@
      * 
      * @param rete
      *            The rete network.
+     * @throws PackageIntegrationException
+     */
+    public LeapsRuleBase(final String id) throws PackageIntegrationException {
+        this( id,
+              null,
+              new LeapsFactHandleFactory() );
+    }    
+    
+    /**
+     * Construct.
+     * 
+     * @param rete
+     *            The rete network.
      * @param conflictResolver
      *            The conflict resolver.
      * @param factHandleFactory
@@ -75,9 +89,11 @@
      * @throws PackageIntegrationException
      * @throws Exception
      */
-    public LeapsRuleBase(final RuleBaseConfiguration config,
+    public LeapsRuleBase(final String id,
+                         final RuleBaseConfiguration config,
                          final FactHandleFactory factHandleFactory) {
-        super( config,
+        super( id,
+               config,
                factHandleFactory );
         this.leapsRules = new HashMap();
     }

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ReteooRuleBase.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ReteooRuleBase.java	2006-07-12 17:12:42 UTC (rev 5047)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ReteooRuleBase.java	2006-07-12 17:34:02 UTC (rev 5048)
@@ -74,12 +74,26 @@
         this( null,
               new ReteooFactHandleFactory() );
     }
+    
+    /**
+     * Construct.
+     * 
+     * @param rete
+     *            The rete network.
+     */
+    public ReteooRuleBase(final String  id) {
+        this( id,
+              null,
+              new ReteooFactHandleFactory() );
+    }
+    
 
     /**
      * @param factHandleFactory
      */
-    public ReteooRuleBase(final FactHandleFactory factHandleFactory) {
-        this( null,
+    public ReteooRuleBase(final String id, final FactHandleFactory factHandleFactory) {
+        this( id,
+              null,
               factHandleFactory );
     }
 
@@ -87,7 +101,8 @@
      * @param config
      */
     public ReteooRuleBase(final RuleBaseConfiguration config) {
-        this( config,
+        this( null,
+              config,
               new ReteooFactHandleFactory() );
     }
 
@@ -97,9 +112,11 @@
      * @param rete
      *            The rete network.
      */
-    public ReteooRuleBase(final RuleBaseConfiguration config,
+    public ReteooRuleBase(String id,
+                          final RuleBaseConfiguration config,
                           final FactHandleFactory factHandleFactory) {
-        super( config,
+        super( id,
+               config,
                factHandleFactory );
         this.config = (config != null) ? config : new RuleBaseConfiguration();
         this.config.makeImmutable();

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/util/UUID.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/util/UUID.java	2006-07-12 17:12:42 UTC (rev 5047)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/util/UUID.java	2006-07-12 17:34:02 UTC (rev 5048)
@@ -0,0 +1,569 @@
+/* JUG Java Uuid Generator
+ *
+ * Copyright (c) 2002- Tatu Saloranta, tatu.saloranta at iki.fi
+ *
+ * Licensed under the License specified in the file LICENSE which is
+ * included with the source code.
+ * You may not use this file except in compliance with the License.
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.drools.util;
+
+import java.io.Serializable;
+
+/**
+ * UUID represents Universally Unique Identifiers (aka Global UID in
+ * Windows world). UUIDs are usually generated via UUIDGenerator (or in
+ * case of 'Null UUID', 16 zero bytes, via static method getNullUUID()),
+ * or received from external systems.
+ *
+ * By default class caches the string presentations of UUIDs so that
+ * description is only created the first time it's needed. For memory
+ * stingy applications this caching can be turned off (note though
+ * that if uuid.toString() is never called, desc is never calculated
+ * so only loss is the space allocated for the desc pointer... which
+ * can of course be commented out to save memory).
+ *
+ * Similarly, hash code is calculated when it's needed for the first
+ * time, and from thereon that value is just returned. This means
+ * that using UUIDs as keys should be reasonably efficient.
+ *
+ * UUIDs can be compared for equality, serialized, cloned and even sorted.
+ * Equality is a simple bit-wise comparison. Ordering (for sorting) is done by
+ * first ordering based on type (in the order of numeric values of
+ * types), secondarily by time stamp (only for time-based time stamps),
+ * and finally by straight numeric byte-by-byte comparison (from
+ * most to least significant bytes).
+ */
+
+public class UUID
+    implements Serializable, Cloneable, Comparable
+{
+    private final static String kHexChars = "0123456789abcdefABCDEF";
+
+    public final static byte INDEX_CLOCK_HI = 6;
+    public final static byte INDEX_CLOCK_MID = 4;
+    public final static byte INDEX_CLOCK_LO = 0;
+
+    public final static byte INDEX_TYPE = 6;
+    // Clock seq. & variant are multiplexed...
+    public final static byte INDEX_CLOCK_SEQUENCE = 8;
+    public final static byte INDEX_VARIATION = 8;
+
+    public final static byte TYPE_NULL = 0;
+    public final static byte TYPE_TIME_BASED = 1;
+    public final static byte TYPE_DCE = 2; // Not used
+    public final static byte TYPE_NAME_BASED = 3;
+    public final static byte TYPE_RANDOM_BASED = 4;
+
+    /* 'Standard' namespaces defined (suggested) by UUID specs:
+     */
+    public final static String NAMESPACE_DNS = "6ba7b810-9dad-11d1-80b4-00c04fd430c8";
+    public final static String NAMESPACE_URL = "6ba7b811-9dad-11d1-80b4-00c04fd430c8";
+    public final static String NAMESPACE_OID = "6ba7b812-9dad-11d1-80b4-00c04fd430c8";
+    public final static String NAMESPACE_X500 = "6ba7b814-9dad-11d1-80b4-00c04fd430c8";
+
+    /* By default let's cache desc, can be turned off. For hash code
+     * there's no point in turning it off (since the int is already
+     * part of the instance memory allocation); if you want to save
+     * those 4 bytes (or possibly bit more if alignment is bad) just
+     * comment out hash caching.
+     */
+    private static boolean sDescCaching = true;
+
+    /**
+     * The shared null UUID. Would be nice to do lazy instantiation, but
+     * if the instance really has to be a singleton, that would mean
+     * class-level locking (synchronized getNullUUID()), which would
+     * be some overhead... So let's just bite the bullet the first time
+     * assuming creation of the null UUID (plus wasted space if it's
+     * not needed) can be ignored.
+     */
+    private final static UUID sNullUUID = new UUID();
+
+    private final byte[] mId = new byte[16];
+    // Both string presentation and hash value may be cached...
+    private transient String mDesc = null;
+    private transient int mHashCode = 0;
+
+    /* *** Object creation: *** */
+
+    /**
+     * Default constructor creates a NIL UUID, one that contains all
+     * zeroes
+     *
+     * Note that the clearing of array is actually unnecessary as
+     * JVMs are required to clear up the allocated arrays by default.
+     */
+    public UUID()
+    {
+        /*
+          for (int i = 0; i < 16; ++i) {
+          mId[i] = (byte)0;
+          }
+        */
+    }
+
+    /**
+     * Constructor for cases where you already have the 16-byte binary
+     * representation of the UUID (for example if you save UUIDs binary
+     * takes less than half of space string representation takes).
+     *
+     * @param data array that contains the binary representation of UUID
+     */
+    public UUID(byte[] data)
+    {
+        /* Could call the other constructor... and/or use System.arraycopy.
+         * However, it's likely that those would make this slower to use,
+         * and initialization is really simple as is in any case.
+         */
+        for (int i = 0; i < 16; ++i) {
+            mId[i] = data[i];
+        }
+    }
+
+    /**
+     * Constructor for cases where you already have the binary
+     * representation of the UUID (for example if you save UUIDs binary
+     * takes less than half of space string representation takes) in
+     * a byte array
+     *
+     * @param data array that contains the binary representation of UUID
+     * @param start byte offset where UUID starts
+     */
+    public UUID(byte[] data, int start)
+    {
+        for (int i = 0; i < 16; ++i) {
+            mId[i] = data[start + i];
+        }
+    }
+
+    /**
+     * Protected constructor used by UUIDGenerator
+     *
+     * @param type UUID type
+     * @param data 16 byte UUID contents
+     */
+    UUID(int type, byte[] data)
+    {
+        for (int i = 0; i < 16; ++i) {
+            mId[i] = data[i];
+        }
+        // Type is multiplexed with time_hi:
+        mId[INDEX_TYPE] &= (byte) 0x0F;
+        mId[INDEX_TYPE] |= (byte) (type << 4);
+        // Variant masks first two bits of the clock_seq_hi:
+        mId[INDEX_VARIATION] &= (byte) 0x3F;
+        mId[INDEX_VARIATION] |= (byte) 0x80;
+    }
+
+    /**
+     * Constructor for creating UUIDs from the canonical string
+     * representation
+     *
+     * Note that implementation is optimized for speed, not necessarily
+     * code clarity... Also, since what we get might not be 100% canonical
+     * (see below), let's not yet populate mDesc here.
+     *
+     * @param id String that contains the canonical representation of
+     *   the UUID to build; 36-char string (see UUID specs for details).
+     *   Hex-chars may be in upper-case too; UUID class will always output
+     *   them in lowercase.
+     */
+    public UUID(String id)
+        throws NumberFormatException
+    {
+        if (id == null) {
+            throw new NullPointerException();
+        }
+        if (id.length() != 36) {
+            throw new NumberFormatException("UUID has to be represented by the standard 36-char representation");
+        }
+
+        for (int i = 0, j = 0; i < 36; ++j) {
+            // Need to bypass hyphens:
+            switch (i) {
+            case 8:
+            case 13:
+            case 18:
+            case 23:
+                if (id.charAt(i) != '-') {
+                    throw new NumberFormatException("UUID has to be represented by the standard 36-char representation");
+                }
+                ++i;
+            }
+            int index;
+            char c = id.charAt(i);
+
+            if (c >= '0' && c <= '9') {
+                mId[j] = (byte) ((c - '0') << 4);
+            } else if (c >= 'a' && c <= 'f') {
+                mId[j] = (byte) ((c - 'a' + 10) << 4);
+            } else if (c >= 'A' && c <= 'F') {
+                mId[j] = (byte) ((c - 'A' + 10) << 4);
+            } else {
+                throw new NumberFormatException("Non-hex character '"+c+"'");
+            }
+
+            c = id.charAt(++i);
+
+            if (c >= '0' && c <= '9') {
+                mId[j] |= (byte) (c - '0');
+            } else if (c >= 'a' && c <= 'f') {
+                mId[j] |= (byte) (c - 'a' + 10);
+            } else if (c >= 'A' && c <= 'F') {
+                mId[j] |= (byte) (c - 'A' + 10);
+            } else {
+                throw new NumberFormatException("Non-hex character '"+c+"'");
+            }
+            ++i;
+        }
+    }
+
+    /**
+     * Default cloning behaviour (bitwise copy) is just fine...
+     *
+     * Could clear out cached string presentation, but there's
+     * probably no point in doing that.
+     */
+    public Object clone()
+    {
+        try {
+            return super.clone();
+        } catch (CloneNotSupportedException e) {
+            // shouldn't happen
+            return null;
+        }
+    }
+
+    /* *** Configuration: *** */
+    public static void setDescCaching(boolean state)
+    {
+        sDescCaching = state;
+    }
+
+    /* *** Accessors: *** */
+
+    /**
+     * Accessor for getting the shared null UUID
+     *
+     * @return the shared null UUID
+     */
+    public static UUID getNullUUID()
+    {
+        return sNullUUID;
+    }
+
+    public boolean isNullUUID()
+    {
+        // Assuming null uuid is usually used for nulls:
+        if (this == sNullUUID) {
+            return true;
+        }
+        // Could also check hash code; null uuid has -1 as hash?
+        byte[] data = mId;
+        int i = mId.length;
+        byte zero = (byte) 0;
+        while (--i >= 0) {
+            if (data[i] != zero) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * Returns the UUID type code
+     *
+     * @return UUID type
+     */
+    public int getType()
+    {
+        return (mId[INDEX_TYPE] & 0xFF) >> 4;
+    }
+
+    /**
+     * Returns the UUID as a 16-byte byte array
+     *
+     * @return 16-byte byte array that contains UUID bytes in the network
+     *   byte order
+     */
+    public byte[] asByteArray()
+    {
+        byte[] result = new byte[16];
+        toByteArray(result);
+        return result;
+    }
+
+    /**
+     * Fills in the 16 bytes (from index pos) of the specified byte array
+     * with the UUID contents.
+     *
+     * @param dst Byte array to fill
+     * @param pos Offset in the array
+     */
+    public void toByteArray(byte[] dst, int pos)
+    {
+        byte[] src = mId;
+        for (int i = 0; i < 16; ++i) {
+            dst[pos+i] = src[i];
+        }
+    }
+
+    public void toByteArray(byte[] dst) { toByteArray(dst, 0); }
+
+    /**
+     * 'Synonym' for 'asByteArray'
+     */
+    public byte[] toByteArray() { return asByteArray(); }
+    
+    /* *** Standard methods from Object overridden: *** */
+
+    /**
+     * Could use just the default hash code, but we can probably create
+     * a better identity hash (ie. same contents generate same hash)
+     * manually, without sacrificing speed too much. Although multiplications
+     * with modulos would generate better hashing, let's use just shifts,
+     * and do 2 bytes at a time.
+     *<p>
+     * Of course, assuming UUIDs are randomized enough, even simpler
+     * approach might be good enough?
+     *<p>
+     * Is this a good hash? ... one of these days I better read more about
+     * basic hashing techniques I swear!
+     */
+    private final static int[] kShifts = {
+        3, 7, 17, 21, 29, 4, 9
+    };
+
+    public int hashCode()
+    {
+        if (mHashCode == 0) {
+            // Let's handle first and last byte separately:
+            int result = mId[0] & 0xFF;
+	    
+            result |= (result << 16);
+            result |= (result << 8);
+	    
+            for (int i = 1; i < 15; i += 2) {
+                int curr = (mId[i] & 0xFF) << 8 | (mId[i+1] & 0xFF);
+                int shift = kShifts[i >> 1];
+		
+                if (shift > 16) {
+                    result ^= (curr << shift) | (curr >>> (32 - shift));
+                } else {
+                    result ^= (curr << shift);
+                }
+            }
+
+            // and then the last byte:
+            int last = mId[15] & 0xFF;
+            result ^= (last << 3);
+            result ^= (last << 13);
+
+            result ^= (last << 27);
+            // Let's not accept hash 0 as it indicates 'not hashed yet':
+            if (result == 0) {
+                mHashCode = -1;
+            } else {
+                mHashCode = result;
+            }
+        }
+        return mHashCode;
+    }
+
+    public String toString()
+    {
+        /* Could be synchronized, but there isn't much harm in just taking
+         * our chances (ie. in the worst case we'll form the string more
+         * than once... but result is the same)
+         */
+
+        if (mDesc == null) {
+            StringBuffer b = new StringBuffer(36);
+	    
+            for (int i = 0; i < 16; ++i) {
+                // Need to bypass hyphens:
+                switch (i) {
+                case 4:
+                case 6:
+                case 8:
+                case 10:
+                    b.append('-');
+                }
+                int hex = mId[i] & 0xFF;
+                b.append(kHexChars.charAt(hex >> 4));
+                b.append(kHexChars.charAt(hex & 0x0f));
+            }
+            if (!sDescCaching) {
+                return b.toString();
+            }
+            mDesc = b.toString();
+        }
+        return mDesc;
+    }
+
+    /* *** Comparison methods: *** */
+
+    private final static int[] sTimeCompare = new int[] {
+        INDEX_CLOCK_HI, INDEX_CLOCK_HI + 1,
+        INDEX_CLOCK_MID, INDEX_CLOCK_MID + 1,
+        INDEX_CLOCK_LO, INDEX_CLOCK_LO + 1,
+        INDEX_CLOCK_LO + 2, INDEX_CLOCK_LO + 3,
+    };
+
+    /**
+     * Let's also make UUIDs sortable. This will mostly/only be useful with
+     * time-based UUIDs; they will sorted by time of creation. The order
+     * will be strictly correct with UUIDs produced over one JVM's lifetime;
+     * that is, if more than one JVMs create UUIDs and/or system is rebooted
+     * the order may not be 100% accurate between UUIDs created under
+     * different JVMs.
+     *
+     * For all UUIDs, type is first compared, and UUIDs of different types
+     * are sorted together (ie. null UUID is before all other UUIDs, then
+     * time-based UUIDs etc). If types are the same, time-based UUIDs'
+     * time stamps (including additional clock counter) are compared, so
+     * UUIDs created first are ordered first. For all other types (and for
+     * time-based UUIDs with same time stamp, which should only occur
+     * when comparing a UUID with itself, or with UUIDs created on
+     * different JVMs or external systems) binary comparison is done
+     * over all 16 bytes.
+     *
+     * @param o Object to compare this UUID to; should be a UUID
+     *
+     * @return -1 if this UUID should be ordered before the one passed,
+     *   1 if after, and 0 if they are the same
+     *
+     * @throws ClassCastException if o is not a UUID.
+     */
+    public int compareTo(Object o)
+    {
+        UUID other = (UUID) o;
+
+        int thisType = getType();
+        int thatType = other.getType();
+
+        /* Let's first order by type:
+         */
+        if (thisType > thatType) {
+            return 1;
+        } else if (thisType < thatType) {
+            return -1;
+        }
+
+        /* And for time-based UUIDs let's compare time stamps first,
+         * then the rest... For all other types, we'll just do straight
+         * byte-by-byte comparison.
+         */
+        byte[] thisId = mId;
+        byte[] thatId = other.mId;
+        int i = 0;
+        if (thisType == TYPE_TIME_BASED) {
+            for (; i < 8; ++i) {
+                int index = sTimeCompare[i];
+                int cmp = (((int) thisId[index]) & 0xFF)
+                    - (((int) thatId[index]) & 0xFF);
+                if (cmp != 0) {
+                    return cmp;
+                }
+            }
+            // Let's fall down to full comparison otherwise
+        }
+
+        for (; i < 16; ++i) {
+            int cmp = (((int) thisId[i]) & 0xFF) - (((int) thatId[i]) & 0xFF);
+            if (cmp != 0) {
+                return cmp;
+            }
+        }
+
+        return 0;
+    }
+
+    /**
+     * Checking equality of UUIDs is easy; just compare the 128-bit
+     * number.
+     */
+    public boolean equals(Object o)
+    {
+        if (!(o instanceof UUID)) {
+            return false;
+        }
+        byte[] otherId = ((UUID) o).mId;
+        byte[] thisId = mId;
+        for (int i = 0; i < 16; ++i) {
+            if (otherId[i] != thisId[i]) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Constructs a new UUID instance given the canonical string
+     * representation of an UUID.
+     *
+     * Note that calling this method returns the same result as would
+     * using the matching (1 string arg) constructor.
+     *
+     * @param id Canonical string representation used for constructing
+     *  an UUID instance
+     *
+     * @throws NumberFormatException if 'id' is invalid UUID
+     */
+    public static UUID valueOf(String id)
+        throws NumberFormatException
+    {
+        return new UUID(id);
+    }
+
+    /**
+     * Constructs a new UUID instance given a byte array that contains
+     * the (16 byte) binary representation.
+     *
+     * Note that calling this method returns the same result as would
+     * using the matching constructor
+     *
+     * @param src Byte array that contains the UUID definition
+     * @param start Offset in the array where the UUID starts
+     */
+    public static UUID valueOf(byte[] src, int start)
+    {
+        return new UUID(src, start);
+    }
+
+    /**
+     * Constructs a new UUID instance given a byte array that contains
+     * the (16 byte) binary representation.
+     *
+     * Note that calling this method returns the same result as would
+     * using the matching constructor
+     *
+     * @param src Byte array that contains the UUID definition
+     */
+    public static UUID valueOf(byte[] src)
+    {
+        return new UUID(src);
+    }
+    
+    private void copyFrom(UUID src)
+    {
+        byte[] srcB = src.mId;
+        byte[] dstB = mId;
+	
+        for (int i = 0; i < 16; ++i) {
+            dstB[i] = srcB[i];
+        }
+
+        mDesc = sDescCaching ? src.mDesc : null;
+    }
+
+}

Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/util/UUIDGenerator.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/util/UUIDGenerator.java	2006-07-12 17:12:42 UTC (rev 5047)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/util/UUIDGenerator.java	2006-07-12 17:34:02 UTC (rev 5048)
@@ -0,0 +1,172 @@
+
+/* JUG Java Uuid Generator
+ *
+ * Copyright (c) 2002- Tatu Saloranta, tatu.saloranta at iki.fi
+ *
+ * Licensed under the License specified in the file LICENSE which is
+ * included with the source code.
+ * You may not use this file except in compliance with the License.
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.drools.util;
+
+import java.security.NoSuchAlgorithmException;
+import java.security.MessageDigest;
+import java.security.SecureRandom;
+import java.util.*;
+
+/**
+ * Ripped from JUG
+ * 
+ * @see org.safehaus.jug
+ */
+public final class UUIDGenerator
+{
+    private final static UUIDGenerator sSingleton = new UUIDGenerator();
+
+    /**
+     * Random-generator, used by various UUID-generation methods:
+     */
+    private Random mRnd = null;
+
+    /**
+     * MD5 hasher for name-based digests:
+     */
+    private MessageDigest mHasher = null;
+
+    /*
+    /////////////////////////////////////////////////////
+    // Life-cycle
+    /////////////////////////////////////////////////////
+     */
+
+    /**
+     * Constructor is private to enforce singleton access.
+     */
+    private UUIDGenerator() { }
+
+    /**
+     * Method used for accessing the singleton generator instance.
+     */
+    public static UUIDGenerator getInstance()
+    {
+        return sSingleton;
+    }
+    
+    /*
+    /////////////////////////////////////////////////////
+    // Configuration
+    /////////////////////////////////////////////////////
+     */
+
+
+    /**
+     * Method for getting the shared random number generator used for
+     * generating the UUIDs. This way the initialization cost is only
+     * taken once; access need not be synchronized (or in cases where
+     * it has to, SecureRandom takes care of it); it might even be good
+     * for getting really 'random' stuff to get shared access...
+     */
+    public Random getRandomNumberGenerator()
+    {
+        /* Could be synchronized, but since side effects are trivial
+         * (ie. possibility of generating more than one SecureRandom,
+         * of which all but one are dumped) let's not add synchronization
+         * overhead:
+         */
+        if (mRnd == null) {
+            mRnd = new SecureRandom();
+        }
+        return mRnd;
+    }
+
+    /**
+     * Method that can  be called to specify alternative random
+     * number generator to use. This is usually done to use
+     * implementation that is faster than
+     * {@link SecureRandom} that is used by default.
+     *<p>
+     * Note that to avoid first-time initialization penalty
+     * of using {@link SecureRandom}, this method has to be called
+     * before generating the first random-number based UUID.
+     */
+    public void setRandomNumberGenerator(Random r)
+    {
+        mRnd = r;
+    }
+
+    /* Method for getting the shared message digest (hash) algorithm.
+     * Whether to use the shared one or not depends; using shared instance
+     * adds synchronization overhead (access has to be sync'ed), but
+     * using multiple separate digests wastes memory.
+     */
+    public MessageDigest getHashAlgorithm()
+    {
+        /* Similar to the shared random number generator, it's not necessary
+         * to synchronize initialization. However, use of the hash instance
+         * HAS to be synchronized by the caller to prevent problems with
+         * multiple threads updating digest etc.
+         */
+        if (mHasher == null) {
+            try {
+                mHasher = MessageDigest.getInstance("MD5");
+            } catch (NoSuchAlgorithmException nex) {
+                throw new Error("Couldn't instantiate an MD5 MessageDigest instance: "+nex.toString());
+            }
+        }
+        return mHasher;
+    }
+
+    /*
+    /////////////////////////////////////////////////////
+    // UUID generation methods
+    /////////////////////////////////////////////////////
+     */
+
+    /**
+     * Method for generating (pseudo-)random based UUIDs, using the
+     * default (shared) SecureRandom object.
+     * 
+     * Note that the first time
+     * SecureRandom object is used, there is noticeable delay between
+     * calling the method and getting the reply. This is because SecureRandom
+     * has to initialize itself to reasonably random state. Thus, if you
+     * want to lessen delay, it may be be a good idea to either get the
+     * first random UUID asynchronously from a separate thread, or to
+     * use the other generateRandomBasedUUID passing a previously initialized
+     * SecureRandom instance.
+     *
+     * @return UUID generated using (pseudo-)random based method
+     */
+    public UUID generateRandomBasedUUID()
+    {
+        return generateRandomBasedUUID(getRandomNumberGenerator());
+    }
+
+    /**
+     * Method for generating (pseudo-)random based UUIDs, using the
+     * specified  SecureRandom object. To prevent/avoid delay JDK's
+     * default SecureRandom object causes when first random number
+     * is generated, it may be a good idea to initialize the SecureRandom
+     * instance (on a separate thread for example) when app starts.
+     * 
+     * @param randomGenerator Random number generator to use for getting the
+     *   random number from which UUID will be composed.
+     *
+     * @return UUID generated using (pseudo-)random based method
+     */
+    public UUID generateRandomBasedUUID(Random randomGenerator)
+    {
+        byte[] rnd = new byte[16];
+        
+        randomGenerator.nextBytes(rnd);
+        
+        return new UUID(UUID.TYPE_RANDOM_BASED, rnd);
+    }
+}




More information about the jboss-svn-commits mailing list