All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.gatein.common.util.Tools Maven / Gradle / Ivy

There is a newer version: 2.2.2.Final
Show newest version
/******************************************************************************
 * JBoss, a division of Red Hat                                               *
 * Copyright 2009, Red Hat Middleware, LLC, and individual                    *
 * contributors as indicated by the @authors tag. See the                     *
 * copyright.txt 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.gatein.common.util;

import org.gatein.common.logging.Logger;
import org.gatein.common.logging.LoggerFactory;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.lang.reflect.Array;
import java.math.BigInteger;
import java.net.URL;
import java.net.URLClassLoader;
import java.net.UnknownHostException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.ResourceBundle;
import java.util.Set;

/**
 * @author Julien Viet
 * @author Thomas Heute
 * @author Boleslaw Dawidowicz
 * @author Chris Laprun
 * @version $Revision: 7377 $
 */
@SuppressWarnings("unchecked")
public class Tools
{

   public static final int DEFAULT_BUFFER_SIZE = 512;

   public static final Logger log = LoggerFactory.getLogger(Tools.class);

   /** 16 chars long VMID. */
   public static final String VMID = VMID();

   private static String VMID()
   {
      try
      {
         BigInteger bi = BigInteger.valueOf(0);
         byte[] address = java.net.InetAddress.getLocalHost().getAddress();
         for (int i = 0; i < 4; i++)
         {
            bi = bi.shiftLeft(8);
            bi = bi.add(BigInteger.valueOf(address[i]));
         }
         bi = bi.shiftLeft(32);
         int code = System.identityHashCode(new Object());
         bi = bi.add(BigInteger.valueOf(code));
         byte[] bytes = bi.toByteArray();
         StringBuffer buffer = new StringBuffer();
         char[] chars = "0123456789ABCDEF".toCharArray();
         for (int i = 0; i < bytes.length; i++)
         {
            buffer.append(chars[(bytes[i] & 0xF0) >> 4]).append(chars[bytes[i] & 0xF]);
         }
         return buffer.toString();
      }
      catch (UnknownHostException e)
      {
         e.printStackTrace(System.err);
         throw new Error("Cannot create VMID");
      }
   }

   public static final Enumeration EMPTY_ENUMERATION = new Enumeration()
   {
      public boolean hasMoreElements()
      {
         return false;
      }

      public Object nextElement()
      {
         throw new NoSuchElementException();
      }
   };

   public static final Iterator EMPTY_ITERATOR = new Iterator()
   {
      public boolean hasNext()
      {
         return false;
      }

      public Object next()
      {
         throw new NoSuchElementException();
      }

      public void remove()
      {
         throw new UnsupportedOperationException();
      }
   };

   public static final ResourceBundle EMPTY_BUNDLE = new ResourceBundle()
   {
      protected Object handleGetObject(String key)
      {
         return null;
      }

      public Enumeration getKeys()
      {
         return EMPTY_ENUMERATION;
      }
   };

   public static  Enumeration emptyEnumeration()
   {
      return (Enumeration)EMPTY_ENUMERATION;
   }

   public static  Iterator emptyIterator()
   {
      return (Iterator)EMPTY_ITERATOR;
   }

   public static  Enumeration toEnumeration(final Iterator iterator)
   {
      if (iterator == null)
      {
         throw new IllegalArgumentException();
      }
      return new Enumeration()
      {
         public boolean hasMoreElements()
         {
            return iterator.hasNext();
         }

         public E nextElement()
         {
            return iterator.next();
         }
      };
   }

   public static  Enumeration toEnumeration(final E[] objects)
   {
      if (objects == null)
      {
         throw new IllegalArgumentException();
      }
      return new Enumeration()
      {
         int index = 0;

         public boolean hasMoreElements()
         {
            return index < objects.length;
         }

         public E nextElement()
         {
            if (index < objects.length)
            {
               return objects[index++];
            }
            else
            {
               throw new NoSuchElementException();
            }
         }
      };
   }

   public static  Enumeration toEnumeration(final E o)
   {
      return new Enumeration()
      {
         boolean hasMore = true;

         public boolean hasMoreElements()
         {
            return hasMore;
         }

         public E nextElement()
         {
            if (hasMore)
            {
               hasMore = false;
            }
            else
            {
               throw new NoSuchElementException();
            }
            return o;
         }
      };
   }

   public static  Set toSet(Enumeration e)
   {
      if (e == null)
      {
         throw new IllegalArgumentException();
      }
      HashSet set = new HashSet();
      while (e.hasMoreElements())
      {
         set.add(e.nextElement());
      }
      return set;
   }

   public static  Set toSet(E... objects)
   {
      if (objects == null)
      {
         throw new IllegalArgumentException();
      }
      HashSet set = new HashSet();
      for (E object : objects)
      {
         set.add(object);
      }
      return set;
   }

   /**
    * Transforms an iterator into an unordered Set
    *
    * @param iterator The iterator to transform
    * @return A HashSet
    */
   public static  Set toSet(Iterator iterator)
   {
      if (iterator == null)
      {
         throw new IllegalArgumentException();
      }
      return toSet(iterator, false);
   }

   /**
    * Transforms an iterator into a Set
    *
    * @param iterator      The iterator to transform
    * @param preserveOrder true if the set must respect the ordering of the iterator
    * @return a LinkedHashSet if ordered is true, a HashSet otherwise
    */
   public static  Set toSet(Iterator iterator, boolean preserveOrder)
   {
      if (iterator == null)
      {
         throw new IllegalArgumentException();
      }
      Set set;
      if (preserveOrder)
      {
         set = new LinkedHashSet();
      }
      else
      {
         set = new HashSet();
      }
      while (iterator.hasNext())
      {
         set.add(iterator.next());
      }
      return set;
   }

   public static  List toList(Enumeration e)
   {
      if (e == null)
      {
         throw new IllegalArgumentException();
      }
      List list = new ArrayList();
      while (e.hasMoreElements())
      {
         list.add(e.nextElement());
      }
      return list;
   }

   public static  List toList(Iterator iterator)
   {
      if (iterator == null)
      {
         throw new IllegalArgumentException();
      }
      List list = new ArrayList();
      while (iterator.hasNext())
      {
         list.add(iterator.next());
      }
      return list;
   }

   public static  List toList(E... objects)
   {
      if (objects == null)
      {
         throw new IllegalArgumentException();
      }
      List list = new ArrayList(objects.length);
      for (E object : objects)
      {
         list.add(object);
      }
      return list;
   }

   /**
    * Consider remove this method as it cannot be generified.
    *
    * @param i
    * @return
    */
   @Deprecated
   public static Object[] toArray(Iterator i)
   {
      // This method cannot be generified.
      return toList(i).toArray();
   }

   /**
    * Returns a singleton iterator.
    *
    * @param o the singleton object
    * @return the iterator
    */
   public static  Iterator iterator(final E o)
   {
      return new Iterator()
      {
         /** The status of the iterator. */
         boolean done = false;

         public boolean hasNext()
         {
            return !done;
         }

         public E next()
         {
            if (done)
            {
               throw new NoSuchElementException("Already iterated");
            }
            done = true;
            return o;
         }

         public void remove()
         {
            throw new UnsupportedOperationException("read only");
         }
      };
   }

   /**
    * Returns an iterator over the array elements.
    *
    * @param objects the array containing the objects to iterate on
    * @return the iterator
    * @throws IllegalArgumentException if the object array is null or the specified range is not valid
    */
   public static  Iterator iterator(final E... objects) throws IllegalArgumentException
   {
      if (objects == null)
      {
         throw new IllegalArgumentException("No null object array");
      }
      return iterator(objects, 0, objects.length);
   }

   /**
    * Returns an iterator over the array elements within the specified range. The range is considered as valid if the
    * from argument is greater or equals than zero, the to argument is lesser or equals than array size and the from
    * argument is lesser or equals to the to argument.
    *
    * @param objects the array containing the objects to iterate on
    * @param from    the inclusive start index
    * @param to      the exclusive stop index
    * @return the iterator
    * @throws IllegalArgumentException if the object array is null or the specified range is not valid or if the range
    *                                  is not valid
    */
   public static  Iterator iterator(final E[] objects, final int from, final int to) throws IllegalArgumentException
   {
      if (objects == null)
      {
         throw new IllegalArgumentException("No null object array");
      }
      if (from > to || from < 0 || to > objects.length)
      {
         throw new IllegalArgumentException("Invalid range [" + from + "," + to + "] for array of length " + objects.length);
      }
      return new Iterator()
      {
         /** . */
         int index = from;

         public boolean hasNext()
         {
            return index < to;
         }

         public E next()
         {
            if (index >= to)
            {
               throw new NoSuchElementException("Index is greater than the array length");
            }
            return objects[index++];
         }

         public void remove()
         {
            throw new UnsupportedOperationException("read only");
         }
      };
   }

   public static int computeStringHash(int hash, String s)
   {
      char[] chars = s.toCharArray();
      int length = chars.length;
      for (int i = 0; i < length; i++)
      {
         char c = chars[i];
         hash = 31 * hash + c;
      }
      return hash;
   }

   /**
    * Computes an md5 hash of a string.
    *
    * @param text the hashed string
    * @return the string hash
    * @throws NullPointerException if text is null
    */
   public static byte[] md5(String text)
   {
      // arguments check
      if (text == null)
      {
         throw new NullPointerException("null text");
      }

      try
      {
         MessageDigest md = MessageDigest.getInstance("MD5");
         md.update(text.getBytes());
         return md.digest();
      }
      catch (NoSuchAlgorithmException e)
      {
         log.error("Cannot find MD5 algorithm", e);
         throw new RuntimeException("Cannot find MD5 algorithm");
      }
   }

   /**
    * Computes an md5 hash and returns the result as a string in hexadecimal format.
    *
    * @param text the hashed string
    * @return the string hash
    * @throws NullPointerException if text is null
    */
   public static String md5AsHexString(String text)
   {
      return toHexString(md5(text));
   }

   /**
    * Computes a hash with specified algorighm and returns the result as a string in hexadecimal format
    *
    * @param text
    * @param algorithm
    * @param encoding
    * @return
    * @throws NoSuchAlgorithmException
    */
   public static String hashAndEncodeString(String text, String algorithm, String encoding) throws NoSuchAlgorithmException
   {
      // arguments check
      if (text == null)
      {
         throw new NullPointerException("null text");
      }
      if (algorithm == null)
      {
         throw new NullPointerException("null algorithm");
      }
      if (encoding == null)
      {
         throw new NullPointerException("null encoding");
      }

      MessageDigest md = MessageDigest.getInstance(algorithm);
      md.update(text.getBytes());
      byte[] encoded = md.digest();

      if ("HEX".equalsIgnoreCase(encoding))
      {
         return toHexString(encoded);
      }
      //TODO: add base64 support here
      else
      {
         throw new IllegalArgumentException("Not supported encoding: " + encoding);
      }

   }


   /**
    * Returns a string in the hexadecimal format.
    *
    * @param bytes the converted bytes
    * @return the hexadecimal string representing the bytes data
    * @throws IllegalArgumentException if the byte array is null
    */
   public static String toHexString(byte[] bytes)
   {
      if (bytes == null)
      {
         throw new IllegalArgumentException("byte array must not be null");
      }
      StringBuffer hex = new StringBuffer(bytes.length * 2);
      for (int i = 0; i < bytes.length; i++)
      {
         hex.append(Character.forDigit((bytes[i] & 0XF0) >> 4, 16));
         hex.append(Character.forDigit((bytes[i] & 0X0F), 16));
      }
      return hex.toString();
   }

   /**
    * Returns a byte array converted from the hexadecimal format.
    *
    * @param hex the string to convert
    * @return the byte array corresponding
    * @throws IllegalArgumentException if the string is null or does not have the good format
    */
   public static byte[] fromHexString(String hex)
   {
      if (hex == null)
      {
         throw new IllegalArgumentException("Hex string must not be null");
      }
      if (hex.length() % 2 == 1)
      {
         throw new IllegalArgumentException("Hex string length is not even : " + hex.length());
      }
      int index = 0;
      byte[] bytes = new byte[hex.length() / 2];
      for (int i = 0; i < bytes.length; i++)
      {
         char chigh = hex.charAt(index++);
         int high = Character.digit(chigh, 16);
         if (high == -1)
         {
            throw new IllegalArgumentException("Hex string contains a bad char : " + chigh);
         }
         char clow = hex.charAt(index++);
         int low = Character.digit(clow, 16);
         if (low == -1)
         {
            throw new IllegalArgumentException("Hex string contains a bad char : " + clow);
         }
         byte value = (byte)((high << 4) + low);
         bytes[i] = value;
      }
      return bytes;
   }

   /**
    *
    */
   public static String generateTemporaryHash(String value, long time)
   {
      if (value == null)
      {
         throw new IllegalArgumentException("id must not be null");
      }

      Calendar calendar = Calendar.getInstance();
      calendar.setTimeInMillis(time);
      calendar.set(Calendar.MINUTE, 0);
      calendar.set(Calendar.SECOND, 0);
      calendar.set(Calendar.MILLISECOND, 0);
      return md5AsHexString(value + calendar.getTimeInMillis());
   }

   /**
    *
    */
   public static boolean confirmTemporaryHash(String hash, String value, long time)
   {
      if (hash == null)
      {
         return false;
      }
      if (value == null)
      {
         throw new IllegalArgumentException("value must not be null");
      }

      Calendar calendar = Calendar.getInstance();
      calendar.setTimeInMillis(time);
      calendar.set(Calendar.MINUTE, 0);
      calendar.set(Calendar.SECOND, 0);
      calendar.set(Calendar.MILLISECOND, 0);
      String expected = md5AsHexString(value + calendar.getTimeInMillis());
      if (expected.equals(hash))
      {
         return true;
      }
      calendar.add(Calendar.HOUR_OF_DAY, -1);
      expected = md5AsHexString(value + calendar.getTimeInMillis());
      return expected.equals(hash);
   }

   public static String getShortNameOf(Class clazz)
   {
      return clazz.getSimpleName();
   }

   public static String getPackageOf(Class clazz)
   {
      String name = clazz.getName();
      int index = name.lastIndexOf('.');
      if (index != -1)
      {
         name = name.substring(0, index);
      }
      else
      {
         name = "";
      }
      return name;
   }

   public static String buildClassLoaderInfo(ClassLoader loader)
   {
      if (loader == null)
      {
         throw new IllegalArgumentException("no loader");
      }
      StringBuffer buffer = new StringBuffer();
      buffer.append("ClassLoader[Name=").append(loader.getClass().getName());
      buffer.append(",HashCode=").append(loader.hashCode());
      buffer.append(",IdentityHashCode=").append(System.identityHashCode(loader));
      if (loader instanceof URLClassLoader)
      {
         URLClassLoader urlLoader = (URLClassLoader)loader;
         URL[] urls = urlLoader.getURLs();
         for (int i = 0; i < urls.length; i++)
         {
            URL url = urls[i];
            buffer.append(",URL(").append(i).append(")=").append(url);
         }
      }
      try
      {
         Class uclClass = Thread.currentThread().getContextClassLoader().loadClass("org.jboss.mx.loading.UnifiedClassLoader");
         Class loaderClass = loader.getClass();
         if (uclClass.isAssignableFrom(loaderClass))
         {
            URL url = (URL)loaderClass.getMethod("getURL", new Class[0]).invoke(loader, new Object[0]);
            buffer.append(",GetURL=").append(url);
         }
      }
      catch (Exception e)
      {
         log.error("Cannot get UCL infos", e);
      }
      buffer.append("]");
      return buffer.toString();
   }

   public static String dumpClassLoaderHierarchyInfo(ClassLoader loader)
   {
      StringWriter writer = new StringWriter();
      dumpClassLoaderHierarchyInfo(writer, loader);
      return writer.toString();
   }

   public static void dumpClassLoaderHierarchyInfo(Writer writer, ClassLoader loader)
   {
      if (writer == null)
      {
         throw new IllegalArgumentException("no writer");
      }
      if (loader == null)
      {
         throw new IllegalArgumentException("no loader");
      }

      //
      PrintWriter pw = null;
      if (writer instanceof PrintWriter)
      {
         pw = (PrintWriter)writer;
      }
      else
      {
         pw = new PrintWriter(writer);
      }

      pw.println("");
      while (loader != null)
      {
         pw.println(buildClassLoaderInfo(loader));
         loader = loader.getParent();
      }
      pw.print("");
      pw.flush();
   }

   /**
    * Append an object to an array of objects. The original array is not modified. The returned array will be of the
    * same component type of the provided array and its first n elements where n is the size of the provided array will
    * be the elements of the provided array. The last element of the array will be the provided object to append.
    *
    * @param array the array to augment
    * @param o     the object to append
    * @return a new array
    * @throws IllegalArgumentException if the array is null
    * @throws ClassCastException       if the appended object class prevents it from being added to the array
    */
   public static  E[] appendTo(E[] array, E o) throws IllegalArgumentException, ClassCastException
   {
      if (array == null)
      {
         throw new IllegalArgumentException();
      }

      //
      Class componentType = array.getClass().getComponentType();
      if (o != null && !componentType.isAssignableFrom(o.getClass()))
      {
         throw new ClassCastException("Object with class " + o.getClass().getName() + " cannot be casted to class " + componentType.getName());
      }

      //
      E[] copy = (E[])Array.newInstance(componentType, array.length + 1);
      System.arraycopy(array, 0, copy, 0, array.length);
      copy[array.length] = o;

      //
      return copy;
   }

   /**
    * Return true if 
  • o1 is null and o2 is null
  • o1 is not null and the invocation of * equals(Object o) on o1 wit o2 as argument returns true
* * @param o1 the first argument * @param o2 the second argument * @return if arguments are equals according to the semantic defined by the method contract */ public static boolean safeEquals(Object o1, Object o2) { if (o1 == null) { return o2 == null; } else { return o1.equals(o2); } } /** * Determines if value is contained in array. *

* todo: correct this method contract in order to make it more reusable, it looks like for now like a method which * has a contract convenient only for some kind of callers. *

*

  1. null value should be accepted (or the method should be called isContainedInButNotForNullValue ?)
  2. *
  3. null array should not be accepted (or the method should be called isContainedInExceptIfThePassedArrayIsNull * ?)
* * @param value * @param array * @return * @since 2.4.2 */ public static boolean isContainedIn(Object value, Object[] array) { if (value == null) { return false; } // if (array != null) { for (Object anArray : array) { if (value.equals(anArray)) { return true; } } } return false; } /** * Attempt to cast the value argument to the provided type argument. If the value argument type is assignable to the * provided type, the value is returned, otherwise if it is not or the value is null, null is returned. *

* todo: Move that to common package. * * @param value the value to cast * @param type the type to downcast * @return the casted value or null */ public static T safeCast(Object value, Class type) { if (value == null) { return null; } else { if (type.isAssignableFrom(value.getClass())) { return type.cast(value); } else { return null; } } } public static MultiValuedPropertyMap emptyMultiValuedPropertyMap() { return new MultiValuedPropertyMap() { public T getValue(String key) throws IllegalArgumentException { if (key == null) { throw new IllegalArgumentException("Key cannot be null"); } return null; } public List getValues(String key) throws IllegalArgumentException { if (key == null) { throw new IllegalArgumentException("Key cannot be null"); } return null; } public void addValue(String key, T value) throws IllegalArgumentException { throw new UnsupportedOperationException(); } public void setValue(String key, T value) throws IllegalArgumentException { throw new UnsupportedOperationException(); } public Set keySet() { return Collections.emptySet(); } public int size() { return 0; } public void clear() { throw new UnsupportedOperationException(); } public void append(MultiValuedPropertyMap appended) throws IllegalArgumentException { throw new UnsupportedOperationException(); } }; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy