commons-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From bay...@apache.org
Subject svn commit: r1149058 - in /commons/proper/lang/trunk/src: main/java/org/apache/commons/lang3/EnumUtils.java site/changes/changes.xml test/java/org/apache/commons/lang3/EnumUtilsTest.java
Date Thu, 21 Jul 2011 08:00:33 GMT
Author: bayard
Date: Thu Jul 21 08:00:28 2011
New Revision: 1149058

URL: http://svn.apache.org/viewvc?rev=1149058&view=rev
Log:
Adding Nelson Carpentier's patch adding an EnumSet to bit vector (and back again) to EnumUtils.
LANG-730

Modified:
    commons/proper/lang/trunk/src/main/java/org/apache/commons/lang3/EnumUtils.java
    commons/proper/lang/trunk/src/site/changes/changes.xml
    commons/proper/lang/trunk/src/test/java/org/apache/commons/lang3/EnumUtilsTest.java

Modified: commons/proper/lang/trunk/src/main/java/org/apache/commons/lang3/EnumUtils.java
URL: http://svn.apache.org/viewvc/commons/proper/lang/trunk/src/main/java/org/apache/commons/lang3/EnumUtils.java?rev=1149058&r1=1149057&r2=1149058&view=diff
==============================================================================
--- commons/proper/lang/trunk/src/main/java/org/apache/commons/lang3/EnumUtils.java (original)
+++ commons/proper/lang/trunk/src/main/java/org/apache/commons/lang3/EnumUtils.java Thu Jul
21 08:00:28 2011
@@ -21,6 +21,7 @@ import java.util.Arrays;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.EnumSet;
 
 /**
  * <p>Utility library to provide helper methods for Java enums.</p>
@@ -114,4 +115,66 @@ public class EnumUtils {
         }
     }
 
+    /**
+     * <p>Creates a long bit vector representation of the given subset of an Enum.</p>
+     *
+     * <p>This generates a value that is usable by {@link EnumUtils#processBitVector}.</p>
+     *
+     * <p>Do not use this method if you have more than 64 values in your Enum, as this
+     * would create a value greater than a long can hold.</p>
+     *
+     * @param enumClass the class of the enum we are working with, not null
+     * @param set       the set of enum values we want to convert
+     * @param <E>       the type of the enumeration
+     * @return a long whose binary value represents the given set of enum values.
+     */
+    public static <E extends Enum<E>> long generateBitVector(Class<E> enumClass,
EnumSet<E> set) {
+        if (enumClass == null) {
+            throw new IllegalArgumentException("EnumClass must be defined.");
+        }
+        final E[] constants = enumClass.getEnumConstants();
+        if (constants != null && constants.length > 64) {
+            throw new IllegalArgumentException("EnumClass is too big to be stored in a 64-bit
value.");
+        }
+        long total = 0;
+        if (set != null) {
+            if (constants != null && constants.length > 0) {
+                for (E constant : constants) {
+                    if (set.contains(constant)) {
+                        total += Math.pow(2, constant.ordinal());
+                    }
+                }
+            }
+        }
+        return total;
+    }
+
+    /**
+     * <p>Convert a long value created by {@link EnumUtils#generateBitVector} into
the set of
+     * enum values that it represents.</p>
+     *
+     * <p>If you store this value, beware any changes to the enum that would affect
ordinal values.</p>
+     * @param enumClass the class of the enum we are working with, not null
+     * @param value     the long value representation of a set of enum values
+     * @param <E>       the type of the enumeration
+     * @return a set of enum values
+     */
+    public static <E extends Enum<E>> EnumSet<E> processBitVector(Class<E>
enumClass, long value) {
+        if (enumClass == null) {
+            throw new IllegalArgumentException("EnumClass must be defined.");
+        }
+        final E[] constants = enumClass.getEnumConstants();
+        if (constants != null && constants.length > 64) {
+            throw new IllegalArgumentException("EnumClass is too big to be stored in a 64-bit
value.");
+        }
+        final EnumSet results = EnumSet.noneOf(enumClass);
+        if (constants != null && constants.length > 0) {
+            for (E constant : constants) {
+                if ((value & (1 << constant.ordinal())) != 0) {
+                    results.add(constant);
+                }
+            }
+        }
+        return results;
+    }
 }

Modified: commons/proper/lang/trunk/src/site/changes/changes.xml
URL: http://svn.apache.org/viewvc/commons/proper/lang/trunk/src/site/changes/changes.xml?rev=1149058&r1=1149057&r2=1149058&view=diff
==============================================================================
--- commons/proper/lang/trunk/src/site/changes/changes.xml (original)
+++ commons/proper/lang/trunk/src/site/changes/changes.xml Thu Jul 21 08:00:28 2011
@@ -21,6 +21,10 @@
   </properties>
   <body>
 
+  <release version="3.0.1" date="Unreleased" description="Next 3.x release">  
+    <action type="add" issue="LANG-730">EnumSet -> bit vector</action>
+  </release>
+
   <release version="3.0" date="2011-07-18" description="Backwards incompatible update
of Commons Lang to Java 5">  
     <action type="fix" issue="LANG-720">StringEscapeUtils.escapeXml(input) outputs
wrong results when an input contains characters in Supplementary Planes.</action>
     <action type="update" issue="LANG-718">build.xml Java 1.5+ updates.</action>

Modified: commons/proper/lang/trunk/src/test/java/org/apache/commons/lang3/EnumUtilsTest.java
URL: http://svn.apache.org/viewvc/commons/proper/lang/trunk/src/test/java/org/apache/commons/lang3/EnumUtilsTest.java?rev=1149058&r1=1149057&r2=1149058&view=diff
==============================================================================
--- commons/proper/lang/trunk/src/test/java/org/apache/commons/lang3/EnumUtilsTest.java (original)
+++ commons/proper/lang/trunk/src/test/java/org/apache/commons/lang3/EnumUtilsTest.java Thu
Jul 21 08:00:28 2011
@@ -18,6 +18,7 @@
  */
 package org.apache.commons.lang3;
 
+import java.util.EnumSet;
 import java.util.List;
 import java.util.Map;
 
@@ -89,8 +90,69 @@ public class EnumUtilsTest extends TestC
         }
     }
 
+    public void test_generateBitVector_nullClass() {
+        try {
+            EnumUtils.generateBitVector(null, EnumSet.of(Traffic.RED));
+        } catch (IllegalArgumentException ex) {
+            // ok
+        }
+    }
+
+    public void test_generateBitVector_longClass() {
+        try {
+            EnumUtils.generateBitVector(TooMany.class, EnumSet.of(TooMany.A1));
+        } catch (IllegalArgumentException ex) {
+            // ok
+        }
+    }
+
+    public void test_generateBitVector() {
+        assertEquals(0L, EnumUtils.generateBitVector(Traffic.class, null));
+        assertEquals(0L, EnumUtils.generateBitVector(Traffic.class, EnumSet.noneOf(Traffic.class)));
+        assertEquals(1L, EnumUtils.generateBitVector(Traffic.class, EnumSet.of(Traffic.RED)));
+        assertEquals(2L, EnumUtils.generateBitVector(Traffic.class, EnumSet.of(Traffic.AMBER)));
+        assertEquals(4L, EnumUtils.generateBitVector(Traffic.class, EnumSet.of(Traffic.GREEN)));
+        assertEquals(3L, EnumUtils.generateBitVector(Traffic.class, EnumSet.of(Traffic.RED,
Traffic.AMBER)));
+        assertEquals(5L, EnumUtils.generateBitVector(Traffic.class, EnumSet.of(Traffic.RED,
Traffic.GREEN)));
+        assertEquals(6L, EnumUtils.generateBitVector(Traffic.class, EnumSet.of(Traffic.AMBER,
Traffic.GREEN)));
+        assertEquals(7L, EnumUtils.generateBitVector(Traffic.class, EnumSet.of(Traffic.RED,
Traffic.AMBER, Traffic.GREEN)));
+    }
+
+    public void test_processBitVector_nullClass() {
+        final Class<Traffic> empty = null;
+        try {
+            EnumUtils.processBitVector(empty, 0L);
+        } catch (IllegalArgumentException ex) {
+            // ok
+        }
+    }
+
+    public void test_processBitVector_longClass() {
+        try {
+            EnumUtils.processBitVector(TooMany.class, 0L);
+        } catch (IllegalArgumentException ex) {
+            // ok
+        }
+    }
+
+    public void test_processBitVector() {
+        assertEquals(EnumSet.noneOf(Traffic.class), EnumUtils.processBitVector(Traffic.class,
0L));
+        assertEquals(EnumSet.of(Traffic.RED), EnumUtils.processBitVector(Traffic.class, 1L));
+        assertEquals(EnumSet.of(Traffic.AMBER), EnumUtils.processBitVector(Traffic.class,
2L));
+        assertEquals(EnumSet.of(Traffic.RED, Traffic.AMBER), EnumUtils.processBitVector(Traffic.class,
3L));
+        assertEquals(EnumSet.of(Traffic.GREEN), EnumUtils.processBitVector(Traffic.class,
4L));
+        assertEquals(EnumSet.of(Traffic.RED, Traffic.GREEN), EnumUtils.processBitVector(Traffic.class,
5L));
+        assertEquals(EnumSet.of(Traffic.AMBER, Traffic.GREEN), EnumUtils.processBitVector(Traffic.class,
6L));
+        assertEquals(EnumSet.of(Traffic.RED, Traffic.AMBER, Traffic.GREEN), EnumUtils.processBitVector(Traffic.class,
7L));
+    }
 }
 
 enum Traffic {
     RED, AMBER, GREEN
 }
+
+enum TooMany{
+    A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,
+    A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1;
+
+}



Mime
View raw message