/** * Helios, OpenSource Monitoring * Brought to you by the Helios Development Group * * Copyright 2007, Helios Development Group and individual contributors * as indicated by the @author tags. See the copyright.txt file in the * distribution for a full listing of individual contributors. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. * */ package org.helios.apmrouter.util; import java.lang.reflect.Array; import java.util.*; /** * <p>Title: BitMaskedEnum</p> * <p>Description: Support interface for bit masked enums</p> * <p>Company: Helios Development Group LLC</p> * @author Whitehead (nwhitehead AT heliosdev DOT org) * <p><code>org.helios.apmrouter.util.BitMaskedEnum</code></p> */ public interface BitMaskedEnum { /** An all zeroes bit mask template */ public static final String BITS = "0000000000000000000000000000000000000000000000000000000000000000"; /** * <p>Title: DecodeMapPopulator</p> * <p>Description: </p> * <p>Company: Helios Development Group LLC</p> * @author Whitehead (nwhitehead AT heliosdev DOT org) * <p><code>org.helios.apmrouter.util.BitMaskedEnum.DecodeMapPopulator</code></p> */ public static class Support { /** * Generates a long decode map for the passed enum type based on the ordinal * @param offset A constant value to add to each enums ordinals for situations * where we're tracking a code that is an offset off the ordinal * @param enums An array of the enum items * @return a map of the enum items keyed by the bit mask */ public static <E extends Enum<E>> Map<Long, E> generateLongMap(int offset, E...enums) { if(enums.length>Long.SIZE) throw new IllegalArgumentException("Invalid number of enums for a long bitmask [" + enums.length + "]. Max allowble is [" + Long.SIZE + "]"); Map<Long, E> map = new HashMap<Long, E>(enums.length); for(E e: enums) { long mask = Long.parseLong("1" + BITS.substring(0, e.ordinal()+offset), 2); map.put(mask, e); } return Collections.unmodifiableMap(map); } /** * Generates a long decode map for the passed enum type based on the ordinal * where we're tracking a code that is an offset off the ordinal * @param enums An array of the enum items * @return a map of the enum items keyed by the bit mask */ public static <E extends Enum<E>> Map<Long, E> generateLongMap(E...enums) { return generateLongMap(0, enums); } /** * Generates an int mask decode map for the passed enum type based on the ordinal * @param offset A constant value to add to each enums ordinals for situations * where we're tracking a code that is an offset off the ordinal * @param enums An array of the enum items * @return a map of the enum items keyed by the bit mask */ public static <E extends Enum<E>> Map<Integer, E> generateIntMaskMap(int offset, E...enums) { if(enums.length>Integer.SIZE) throw new IllegalArgumentException("Invalid number of enums for an integer bitmask [" + enums.length + "]. Max allowble is [" + Integer.SIZE + "]"); Map<Integer, E> map = new HashMap<Integer, E>(enums.length); for(E e: enums) { int mask = Integer.parseInt("1" + BITS.substring(0, e.ordinal()+offset), 2); map.put(mask, e); } return Collections.unmodifiableMap(map); } /** * Generates a byte mask decode map for the passed enum type based on the ordinal * @param offset A constant value to add to each enums ordinals for situations * where we're tracking a code that is an offset off the ordinal * @param enums An array of the enum items * @return a map of the enum items keyed by the bit mask */ public static <E extends Enum<E>> Map<Byte, E> generateByteMaskMap(byte offset, E...enums) { if(enums.length>Byte.SIZE) throw new IllegalArgumentException("Invalid number of enums for a byte bitmask [" + enums.length + "]. Max allowble is [" + Byte.SIZE + "]"); Map<Byte, E> map = new HashMap<Byte, E>(enums.length); for(E e: enums) { byte mask = Byte.parseByte("1" + BITS.substring(0, e.ordinal()+offset), 2); map.put(mask, e); } return Collections.unmodifiableMap(map); } /** * Generates an byte mask decode map for the passed enum type based on the ordinal * @param enums An array of the enum items * @return a map of the enum items keyed by the bit mask */ public static <E extends Enum<E>> Map<Byte, E> generateByteMaskMap(E...enums) { return generateByteMaskMap((byte)0, enums); } /** * Generates asimple ordinal decode map for the passed enum type based on the ordinal * @param offset A constant value to add to each enums ordinals for situations * where we're tracking a code that is an offset off the ordinal * @param enums An array of the enum items * @return a map of the enum items keyed by the ordinal */ public static <E extends Enum<E>> Map<Integer, E> generateIntOrdinalMap(int offset, E...enums) { if(enums.length>Integer.SIZE) throw new IllegalArgumentException("Invalid number of enums for an integer bitmask [" + enums.length + "]. Max allowble is [" + Integer.SIZE + "]"); Map<Integer, E> map = new HashMap<Integer, E>(enums.length); for(E e: enums) { int mask = e.ordinal()+offset; map.put(mask, e); } return Collections.unmodifiableMap(map); } /** * Generates asimple ordinal decode map for the passed enum type based on the ordinal * @param offset A constant value to add to each enums ordinals for situations * where we're tracking a code that is an offset off the ordinal * @param enums An array of the enum items * @return a map of the enum items keyed by the ordinal */ public static <E extends Enum<E>> Map<Byte, E> generateByteOrdinalMap(byte offset, E...enums) { if(enums.length>Byte.SIZE) throw new IllegalArgumentException("Invalid number of enums for an byte bitmask [" + enums.length + "]. Max allowble is [" + Byte.SIZE + "]"); Map<Byte, E> map = new HashMap<Byte, E>(enums.length); for(E e: enums) { byte mask = (byte) (((byte)e.ordinal())+offset); map.put(mask, e); } return Collections.unmodifiableMap(map); } /** * Generates a simple ordinal decode map for the passed enum type based on the ordinal * @param enums An array of the enum items * @return a map of the enum items keyed by the ordinal */ public static <E extends Enum<E>> Map<Byte, E> generateByteOrdinalMap(E...enums) { return generateByteOrdinalMap((byte)0, enums); } /** * Generates a simple ordinal decode map for the passed enum type based on the ordinal * @param enums An array of the enum items * @return a map of the enum items keyed by the ordinal */ public static <E extends Enum<E>> Map<Integer, E> generateIntOrdinalMap(E...enums) { return generateIntOrdinalMap(0, enums); } /** * Generates an int mask decode map for the passed enum type based on the ordinal * @param enums An array of the enum items * @return a map of the enum items keyed by the bit mask */ public static <E extends Enum<E>> Map<Integer, E> generateIntMaskMap(E...enums) { return generateIntMaskMap(0, enums); } /** * Generates a short bitmask decode map for the passed enum type based on the ordinal * @param offset A constant value to add to each enums ordinals for situations * where we're tracking a code that is an offset off the ordinal * @param enums An array of the enum items * @return a map of the enum items keyed by the bit mask */ public static <E extends Enum<E>> Map<Short, E> generateShortMaskMap(short offset, E...enums) { if(enums.length>Short.SIZE) throw new IllegalArgumentException("Invalid number of enums for a short bitmask [" + enums.length + "]. Max allowble is [" + Short.SIZE + "]"); Map<Short, E> map = new HashMap<Short, E>(enums.length); for(E e: enums) { short mask = Short.parseShort("1" + BITS.substring(0, e.ordinal()+offset), 2); map.put(mask, e); } return Collections.unmodifiableMap(map); } /** * Generates a short decode map for the passed enum type based on the ordinal * @param enums An array of the enum items * @return a map of the enum items keyed by the bit mask */ public static <E extends Enum<E>> Map<Short, E> generateShortMaskMap(E...enums) { return generateShortMaskMap((short)0, enums); } /** * Generates a simple ordinal decode map for the passed enum type based on the ordinal * @param offset A constant value to add to each enums ordinals for situations * where we're tracking a code that is an offset off the ordinal * @param enums An array of the enum items * @return a map of the enum items keyed by the ordinal */ public static <E extends Enum<E>> Map<Short, E> generateShortOrdinalMap(short offset, E...enums) { if(enums.length>Short.SIZE) throw new IllegalArgumentException("Invalid number of enums for a short bitmask [" + enums.length + "]. Max allowble is [" + Short.SIZE + "]"); Map<Short, E> map = new HashMap<Short, E>(enums.length); for(E e: enums) { map.put((short)(e.ordinal()+offset), e); } return Collections.unmodifiableMap(map); } /** * Generates a simple ordinal decode map for the passed enum type based on the ordinal * @param enums An array of the enum items * @return a map of the enum items keyed by the ordinal */ public static <E extends Enum<E>> Map<Short, E> generateShortOrdinalMap(E...enums) { return generateShortOrdinalMap((short)0, enums); } /** * Generates a byte decode map for the passed enum type based on the ordinal * @param offset A constant value to add to each enums ordinals for situations * where we're tracking a code that is an offset off the ordinal * @param enums An array of the enum items * @return a map of the enum items keyed by the bit mask */ public static <E extends Enum<E>> Map<Byte, E> generateByteMap(byte offset, E...enums) { if(enums.length>Byte.SIZE) throw new IllegalArgumentException("Invalid number of enums for a byte bitmask [" + enums.length + "]. Max allowble is [" + Byte.SIZE + "]"); Map<Byte, E> map = new HashMap<Byte, E>(enums.length); for(E e: enums) { byte mask = Byte.parseByte("1" + BITS.substring(0, e.ordinal()+offset), 2); map.put(mask, e); } return Collections.unmodifiableMap(map); } /** * Generates a byte decode map for the passed enum type based on the ordinal * @param enums An array of the enum items * @return a map of the enum items keyed by the bit mask */ public static <E extends Enum<E>> Map<Byte, E> generateByteMap(E...enums) { return generateByteMap((byte)0, enums); } // =============================================================================== // BitMask generators // =============================================================================== /** * Generates the bitmask for the passed enum entry * @param e the enum entry * @return the bitmask */ public static <E extends Enum<E>> long getLongBitMask(E e) { return getBitMask(0L, e); } /** * Generates the bitmask for the passed enum entry * @param offset A constant value to add to each enums ordinals for situations * where we're tracking a code that is an offset off the ordinal * @param e the enum entry * @return the bitmask */ public static <E extends Enum<E>> long getBitMask(long offset, E e) { return Long.parseLong("1" + BITS.substring(0, (int)(e.ordinal()+offset)), 2); } /** * Generates the bitmask for the passed enum entry * @param e the enum entry * @return the bitmask */ public static <E extends Enum<E>> int getIntBitMask(E e) { return getBitMask(0, e); } /** * Generates the bitmask for the passed enum entry * @param offset A constant value to add to each enums ordinals for situations * where we're tracking a code that is an offset off the ordinal * @param e the enum entry * @return the bitmask */ public static <E extends Enum<E>> int getBitMask(int offset, E e) { return Integer.parseInt("1" + BITS.substring(0, e.ordinal()+offset), 2); } /** * Generates the short bitmask for the passed enum entry * @param e the enum entry * @return the bitmask */ public static <E extends Enum<E>> short getShortBitMask(E e) { return getBitMask((short)0, e); } /** * Generates the short bitmask for the passed enum entry * @param offset A constant value to add to each enums ordinals for situations * where we're tracking a code that is an offset off the ordinal * @param e the enum entry * @return the bitmask */ public static <E extends Enum<E>> short getBitMask(short offset, E e) { return Short.parseShort("1" + BITS.substring(0, e.ordinal()+offset), 2); } /** * Generates the byte bitmask for the passed enum entry * @param e the enum entry * @return the bitmask */ public static <E extends Enum<E>> byte getByteBitMask(E e) { return getBitMask((byte)0, e); } /** * Generates the bitmask for the passed enum entry * @param offset A constant value to add to each enums ordinals for situations * where we're tracking a code that is an offset off the ordinal * @param e the enum entry * @return the bitmask */ public static <E extends Enum<E>> byte getBitMask(byte offset, E e) { return Byte.parseByte("1" + BITS.substring(0, e.ordinal()+offset), 2); } } /** * <p>Title: ShortBitMaskOperations</p> * <p>Description: Defines the bit mask operations for an <code>short</code> based bit masked enum</p> * <p>Company: Helios Development Group LLC</p> * @author Whitehead (nwhitehead AT heliosdev DOT org) * <p><code>org.helios.apmrouter.util.BitMaskedEnum.ShortBitMaskOperations</code></p> * @param <E> The expected type of the enum */ public static interface ShortBitMaskOperations<E extends Enum<E>> { /** * Returns the enum that has the passed ordinal. * Throws a runtime exception if the ordinal is invalid * @param ordinal The ordinal to get the enum for * @return the matched enum */ public E forOrdinal(short ordinal); /** * Returns the enum that has the passed code. * If the enum does not support a seperate code, this call should * simply delegate to {@link #forOrdinal(short)}. * Throws a runtime exception if the ordinal is invalid * @param code The code to get the enum for * @return the matched enum */ public E forCode(Number code); /** * Determines if the passed mask is enabled for this enum entry * @param mask the mask to test * @return true if the passed mask is enabled for this enum state, false otherwise */ public boolean isEnabled(short mask); /** * Returns the mask for this enum entry * @return the mask for this enum entry */ public short getMask(); /** * Enables the passed mask for this socket state and returns it * @param mask The mask to modify * @return the modified mask */ public short enable(short mask); /** * Disables the passed mask for this socket state and returns it * @param mask The mask to modify * @return the modified mask */ public short disable(short mask); } /** * <p>Title: IntBitMaskOperations</p> * <p>Description: Defines the bit mask operations for an <code>int</code> based bit masked enum</p> * <p>Company: Helios Development Group LLC</p> * @author Whitehead (nwhitehead AT heliosdev DOT org) * <p><code>org.helios.apmrouter.util.BitMaskedEnum.IntBitMaskOperations</code></p> * @param <E> The expected type of the enum */ public static interface IntBitMaskOperations<E extends Enum<E>> { /** * Returns the enum that has the passed ordinal. * Throws a runtime exception if the ordinal is invalid * @param ordinal The ordinal to get the enum for * @return the matched enum */ public E forOrdinal(int ordinal); /** * Returns the enum that has the passed code. * If the enum does not support a seperate code, this call should * simply delegate to {@link #forOrdinal(int)}. * Throws a runtime exception if the ordinal is invalid * @param code The code to get the enum for * @return the matched enum */ public E forCode(Number code); /** * Determines if the passed mask is enabled for this enum entry * @param mask the mask to test * @return true if the passed mask is enabled for this enum state, false otherwise */ public boolean isEnabled(int mask); /** * Returns the mask for this enum entry * @return the mask for this enum entry */ public int getMask(); /** * Enables the passed mask for this socket state and returns it * @param mask The mask to modify * @return the modified mask */ public int enable(int mask); /** * Disables the passed mask for this socket state and returns it * @param mask The mask to modify * @return the modified mask */ public int disable(int mask); } /** * <p>Title: ShortBitMaskSupport</p> * <p>Description: Bit mask operation implementations for an <code>short</code> based bit masked enum</p> * <p>Company: Helios Development Group LLC</p> * @author Whitehead (nwhitehead AT heliosdev DOT org) * <p><code>org.helios.apmrouter.util.BitMaskedEnum.ShortBitMaskSupport</code></p> */ public static class ShortBitMaskSupport { /** * Converts the passed ordinals or codes to their decoded enums and returns an array of unique enums represented therein * @param eInstance A bit mask operatons instance * @param ordinals The oridnals or codes to decode * @return an array of enums */ @SuppressWarnings("unchecked") public static <E extends ShortBitMaskOperations<?>> E[] decode(ShortBitMaskOperations<?> eInstance, short...ordinals) { Class<?> eType = eInstance.getClass(); if(ordinals==null || ordinals.length<1) { return (E[])Array.newInstance(eType, 0); } Set<E> decodes = new HashSet<E>(ordinals.length); for(short ordinal: ordinals) { E decode = (E)eInstance.forOrdinal(ordinal); if(decode!=null) { decodes.add(decode); } } return (E[])Array.newInstance(eType, decodes.size()); } /** * Accepts the passed state and enables or disables the passed enums on it * @param initial The initial state code * @param enable true to enable, false to disable * @param enums The enums to enable or disable * @return the modified state code */ public static <E extends ShortBitMaskOperations<?>> short mask(short initial, final boolean enable, E...enums) { short mask = initial; if(enums!=null) { for(E en: enums) { if(en==null) continue; mask = enable ? (short) (en.getMask() | mask) : (short) (en.getMask() & ~mask); } } return mask; } } /** * <p>Title: IntBitMaskSupport</p> * <p>Description: Bit mask operation implementations for an <code>int</code> based bit masked enum</p> * <p>Company: Helios Development Group LLC</p> * @author Whitehead (nwhitehead AT heliosdev DOT org) * <p><code>org.helios.apmrouter.util.BitMaskedEnum.IntBitMaskSupport</code></p> */ public static class IntBitMaskSupport { /** * Converts the passed ordinals or codes to their decoded enums and returns an array of unique enums represented therein * @param eInstance A bit mask operatons instance * @param ordinals The oridnals or codes to decode * @return an array of enums */ @SuppressWarnings("unchecked") public static <E extends IntBitMaskOperations<?>> E[] decode(IntBitMaskOperations<?> eInstance, int...ordinals) { Class<?> eType = eInstance.getClass(); if(ordinals==null || ordinals.length<1) { return (E[])Array.newInstance(eType, 0); } Set<E> decodes = new HashSet<E>(ordinals.length); for(int ordinal: ordinals) { E decode = (E)eInstance.forOrdinal(ordinal); if(decode!=null) { decodes.add(decode); } } return (E[])Array.newInstance(eType, decodes.size()); } /** * Accepts the passed state and enables or disables the passed enums on it * @param initial The initial state code * @param enable true to enable, false to disable * @param enums The enums to enable or disable * @return the modified state code */ public static <E extends IntBitMaskOperations<?>> int mask(int initial, final boolean enable, E...enums) { int mask = initial; if(enums!=null) { for(E en: enums) { if(en==null) continue; mask = enable ? (int) (en.getMask() | mask) : (int) (en.getMask() & ~mask); } } return mask; } } /** * <p>Title: ByteBitMaskOperations</p> * <p>Description: Defines the bit mask operations for an <code>byte</code> based bit masked enum</p> * <p>Company: Helios Development Group LLC</p> * @author Whitehead (nwhitehead AT heliosdev DOT org) * <p><code>org.helios.apmrouter.util.BitMaskedEnum.ByteBitMaskOperations</code></p> * @param <E> The expected type of the enum */ public static interface ByteBitMaskOperations<E extends Enum<E>> { /** * Returns the enum that has the passed ordinal. * Throws a runtime exception if the ordinal is invalid * @param ordinal The ordinal to get the enum for * @return the matched enum */ public E forOrdinal(byte ordinal); /** * Returns the enum that has the passed code. * If the enum does not support a seperate code, this call should * simply delegate to {@link #forOrdinal(byte)}. * Throws a runtime exception if the ordinal is invalid * @param code The code to get the enum for * @return the matched enum */ public E forCode(Number code); /** * Determines if the passed mask is enabled for this enum entry * @param mask the mask to test * @return true if the passed mask is enabled for this enum state, false otherwise */ public boolean isEnabled(byte mask); /** * Returns the mask for this enum entry * @return the mask for this enum entry */ public byte getMask(); /** * Enables the passed mask for this socket state and returns it * @param mask The mask to modify * @return the modified mask */ public byte enable(byte mask); /** * Disables the passed mask for this socket state and returns it * @param mask The mask to modify * @return the modified mask */ public byte disable(byte mask); } /** * <p>Title: ByteBitMaskSupport</p> * <p>Description: Bit mask operation implementations for an <code>byte</code> based bit masked enum</p> * <p>Company: Helios Development Group LLC</p> * @author Whitehead (nwhitehead AT heliosdev DOT org) * <p><code>org.helios.apmrouter.util.BitMaskedEnum.ByteBitMaskSupport</code></p> */ public static class ByteBitMaskSupport { /** * Converts the passed ordinals or codes to their decoded enums and returns an array of unique enums represented therein * @param eInstance A bit mask operatons instance * @param ordinals The oridnals or codes to decode * @return an array of enums */ @SuppressWarnings("unchecked") public static <E extends ByteBitMaskOperations<?>> E[] decode(ByteBitMaskOperations<?> eInstance, byte...ordinals) { Class<?> eType = eInstance.getClass(); if(ordinals==null || ordinals.length<1) { return (E[])Array.newInstance(eType, 0); } Set<E> decodes = new HashSet<E>(ordinals.length); for(byte ordinal: ordinals) { E decode = (E)eInstance.forOrdinal(ordinal); if(decode!=null) { decodes.add(decode); } } return (E[])Array.newInstance(eType, decodes.size()); } /** * Accepts the passed state and enables or disables the passed enums on it * @param initial The initial state code * @param enable true to enable, false to disable * @param enums The enums to enable or disable * @return the modified state code */ public static <E extends ByteBitMaskOperations<?>> byte mask(byte initial, final boolean enable, E...enums) { byte mask = initial; if(enums!=null) { for(E en: enums) { if(en==null) continue; mask = enable ? (byte) (en.getMask() | mask) : (byte) (en.getMask() & ~mask); } } return mask; } } }