CollectionsUtil.java :  » Workflow-Engines » wfmopen-2.1.1 » de » danet » an » util » Java Open Source

Java Open Source » Workflow Engines » wfmopen 2.1.1 
wfmopen 2.1.1 » de » danet » an » util » CollectionsUtil.java
/*
 * This file is part of the WfMOpen project.
 * Copyright (C) 2001-2003 Danet GmbH (www.danet.de), GS-AN.
 * All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * $Id: CollectionsUtil.java,v 1.4 2006/11/23 20:38:22 mlipp Exp $
 *
 * $Log: CollectionsUtil.java,v $
 * Revision 1.4  2006/11/23 20:38:22  mlipp
 * Minor optimization.
 *
 * Revision 1.3  2006/09/29 12:32:08  drmlipp
 * Consistently using WfMOpen as projct name now.
 *
 * Revision 1.2  2005/09/28 15:09:44  drmlipp
 * Added tracked list.
 *
 * Revision 1.1.1.3  2004/08/18 15:17:34  drmlipp
 * Update to 1.2
 *
 * Revision 1.5  2004/02/25 12:05:38  lipp
 * Added debugging helper for Map.
 *
 * Revision 1.4  2003/09/22 12:32:57  lipp
 * Implemented deadline creation for block activities.
 *
 * Revision 1.3  2003/06/27 08:51:47  lipp
 * Fixed copyright/license information.
 *
 * Revision 1.2  2002/11/05 10:16:49  schlue
 * Tracked map added.
 *
 * Revision 1.1  2002/10/17 14:45:33  lipp
 * Initial version.
 *
 */
package de.danet.an.util;

import java.io.Serializable;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.Set;

/**
 * This class provides some helper methods for the use of the Java
 * collection framework (this includes both collections and maps).
 *
 * @author <a href="mailto:lipp@danet.de"></a>
 * @version $Revision: 1.4 $
 */
public class CollectionsUtil {
    
    private static class TrackedMap implements Map, Serializable {

  /** Backing Map. */
  private Map m;
  /** Modified entries. */
  private Set modifiedEntries = new HashSet ();

  /**
   * Sole constructor for creating a new tracked map.
   * @return new tracked map.
   */  
  public TrackedMap(Map map) {
      m = map;
  }

  /**
   * Return the set of modified entries.
   * @return the modified entries
   */
  Set modifiedEntries () {
            if (modifiedEntries.size() == 0) {
                return Collections.EMPTY_SET;
            }
      Set res = modifiedEntries;
      modifiedEntries = new HashSet ();
      return res;
  }

  // Implementation of the methods from java.util.Map;

  /**
   * Returns the number of key-value mappings in this map. If
   * the map contains more than Integer.MAX_VALUE elements,
   * returns Integer.MAX_VALUE.
   * This method call is delegated to the backing map.
   * @return the number of key-value mappings in this map.  
   */
  public int size() {
      return m.size();
  }
       
  /**
   * Checks if map is empty.
   * This method call is delegated to the backing map.
   * @return true if this map contains no key-value mappings.
   */  
  public boolean isEmpty() {
      return m.isEmpty();
  }

  /**
   * Check if map contains the given key.
   * This method call is delegated to the backing map.
   * @param key key whose presence in this map is to be tested.
   * @return true if this map contains a mapping for the specified key. 
   */  
  public boolean containsKey(Object key) {
      return m.containsKey(key);
  }

  /**
   * Check if given value is part of the map.
   * This method call is delegated to the backing map.
   * @param value value whose presence in this map is to be tested.
   * @return true if this map maps one or more keys to the
   * specified value.
   */  
  public boolean containsValue(Object value) {
      return m.containsValue(value);
  }
  
  /**
   * Returns the value to which this map maps the specified
   * key. Returns null if the map contains no mapping for this
   * key. A return value of null does not necessarily indicate
   * that the map contains no mapping for the key; it's also
   * possible that the map explicitly maps the key to null. The
   * containsKey operation may be used to distinguish these two
   * cases.
   * This method call is delegated to the backing map.
   * @param key key whose associated value is to be returned.
   * @return the value to which this map maps the specified key,
   * or null if the map contains no mapping for this key.
   * @throws ClassCastException if the key is of an
   * inappropriate type for this map.
   * @throws NullPointerException key is null and this map does
   * not not permit null keys.
   */  
  public Object get(Object key) 
      throws ClassCastException, NullPointerException{
      return m.get(key);
  }

  /**
   * Associates the specified value with the specified key in
   * this map (optional operation). If the map previously
   * contained a mapping for this key, the old value is
   * replaced.
   * This method call is delegated to the backing map. 
   * @param key key with which the specified value is to be associated.
   * @param value  value to be associated with the specified key.
   * @return previous value associated with specified key, or
   * null if there was no mapping for key. A null return can
   * also indicate that the map previously associated null with
   * the specified key, if the implementation supports null
   * values.
   * @throws UnsupportedOperationException if the put operation
   * is not supported by this map.
   * @throws ClassCastException if the class of the specified
   * key or value prevents it from being stored in this map.
   * @throws IllegalArgumentException if some aspect of this key
   * or value prevents it from being stored in this map.
   * @throws NullPointerException this map does not permit null
   * keys or values, and the specified key or value is null.
   */  
  public Object put(Object key, Object value) 
  throws UnsupportedOperationException, ClassCastException, 
         IllegalArgumentException, NullPointerException {
      Object oldValue = m.put(key, value);
      modifiedEntries.add (key);
      return oldValue;
  }

  /**
   * Removes the mapping for this key from this map if present.
   * This method call is delegated to the backing map.
   * @param key key whose mapping is to be removed from the map.
   * @return previous value associated with specified key, or
   * null if there was no mapping for key. A null return can
   * also indicate that the map previously associated null with
   * the specified key, if the implementation supports null
   * values.
   * @throws UnsupportedOperationException if the remove
   * method is not supported by this map.
   */  
  public Object remove(Object key) throws UnsupportedOperationException {
      Object oldValue = m.remove(key);
      modifiedEntries.add(key);
      return oldValue;
  }

  /**
   * Copies all of the mappings from the specified map to this
   * map. These mappings will replace any mappings that this map
   * had for any of the keys currently in the specified map.
   * This method call is delegated to the backing map.
   * @param t Mappings to be stored in this map.
   * @throws UnsupportedOperationException if the put operation
   * is not supported by this map.
   * @throws ClassCastException if the class of the specified
   * key or value prevents it from being stored in this map.
   * @throws IllegalArgumentException if some aspect of this key
   * or value prevents it from being stored in this map.
   * @throws NullPointerException this map does not permit null
   * keys or values, and the specified key or value is null.
   */  
  public void putAll(Map t)
  throws UnsupportedOperationException, ClassCastException, 
         IllegalArgumentException, NullPointerException {
      m.putAll(t);
      modifiedEntries.addAll (t.keySet());
  }
  
  /**
   * Removes all mappings from this map.
   * This method call is delegated to the backing map.
   * @throws UnsupportedOperationException clear is not
   * supported by this map.
   */  
  public void clear() throws UnsupportedOperationException {
      modifiedEntries.addAll (keySet());
      m.clear();
  }

  /**
   * Returns a set view of the keys contained in this map. The
   * set is backed by the map, so changes to the map are
   * reflected in the set, and vice-versa. If the map is
   * modified while an iteration over the set is in progress,
   * the results of the iteration are undefined. The set
   * supports element removal, which removes the corresponding
   * mapping from the map, via the Iterator.remove, Set.remove,
   * removeAll retainAll, and clear operations. It does not
   * support the add or addAll operations.
   * This method call is delegated to the backing map.
   * @return  set view of the keys contained in this map.
   */  
  public Set keySet() {
      return m.keySet();
  }

  /**
   * Returns a collection view of the values contained in this
   * map. The collection is backed by the map, so changes to the
   * map are reflected in the collection, and vice-versa. If the
   * map is modified while an iteration over the collection is
   * in progress, the results of the iteration are
   * undefined. The collection supports element removal, which
   * removes the corresponding mapping from the map, via the
   * Iterator.remove, Collection.remove, removeAll, retainAll
   * and clear operations. It does not support the add or addAll
   * operations.
   * This method call is delegated to the backing map.
   * @return a collection view of the values contained in this map.
   */  
  public Collection values() {
      return m.values();
  }

  /**
   * Returns a set view of the mappings contained in this
   * map. Each element in the returned set is a Map.Entry. The
   * set is backed by the map, so changes to the map are
   * reflected in the set, and vice-versa. If the map is
   * modified while an iteration over the set is in progress,
   * the results of the iteration are undefined. The set
   * supports element removal, which removes the corresponding
   * mapping from the map, via the Iterator.remove, Set.remove,
   * removeAll, retainAll and clear operations. It does not
   * support the add or addAll operations.
   * This method call is delegated to the backing map.
   * @return a set view of the mappings contained in this map.
   */  
  public Set entrySet() {
      return m.entrySet();
  }

  /**
   * Compares the specified object with this map for
   * equality. Returns true if the given object is also a map
   * and the two Maps represent the same mappings. More
   * formally, two maps t1 and t2 represent the same mappings if
   * t1.entrySet().equals(t2.entrySet()). This ensures that the
   * equals method works properly across different
   * implementations of the Map interface.  This method call is
   * delegated to the backing map.
   * @param o object to be compared for equality with this map.
   * @return true if the specified object is equal to this map.
   */  
  public boolean equals(Object o) {
      return m.equals(o);
  }

  /**
   * Returns the hash code value for this map. The hash code of
   * a map is defined to be the sum of the hashCodes of each
   * entry in the map's entrySet view. This ensures that
   * t1.equals(t2) implies that t1.hashCode()==t2.hashCode() for
   * any two maps t1 and t2, as required by the general contract
   * of Object.hashCode.
   * This method call is delegated to the backing map.
   * @return the hash code value for this map.
   */  
  public int hashCode() {
      return m.hashCode();
  }
    }

    /**
     * Factory method for creating a new tracked map out of an "ordinary" Map.
     * @param map the backing map for modification tracking.
     * @return a tracked map as a Map.
     */
    public static Map trackedMap (Map map) {
  return new TrackedMap (map);
    }

    /**
     * Check if the given map is a tracked map.
     * @param map the map to be tested
     * @return true if map is tracked, otherwise false.
     */
    public static boolean isTracked (Map map) {
  return (map instanceof TrackedMap);
    }
    
    /**
     * Check if the given map has been modified. The method resets the
     * internal modified flag as it is assumed that after calling this
     * method some synchronization will be done and tracking starts
     * anew.<P>
     *
     * The method throws an <code>IllegalArgumentException</code> if
     * the argument is not a result of {@link #trackedMap
     * <code>trackedMap</code>}, i.e. if <code>isTracked(map) ==
     * false</code>.
     * @param map the backing map for modification tracking.
     * @return true if map has been modified, otherwise false.
     */
    public static boolean hasBeenModified (Map map) {
  if (map instanceof TrackedMap) {
      return ((TrackedMap)map).modifiedEntries().size() > 0;
  }
  throw new IllegalArgumentException ("Not a tracked map.");
    }

    /**
     * Returns the modified entries in the given map. The method
     * resets the internal modified flag as it is assumed that after
     * calling this method some synchronization will be done and
     * tracking starts anew.<P>
     *
     * The method throws an <code>IllegalArgumentException</code> if
     * the argument is not a result of {@link #trackedMap
     * <code>trackedMap</code>}, i.e. if <code>isTracked(map) ==
     * false</code>.
     * @param map the backing map for modification tracking.
     * @return true if map has been modified, otherwise false.
     */
    public static Set modifiedEntries (Map map) {
  if (map instanceof TrackedMap) {
      return ((TrackedMap)map).modifiedEntries();
  }
  throw new IllegalArgumentException ("Not a tracked map.");
    }

    /**
     * Generate a string representation of a map for debugging
     * purposes.
     * @param map the map
     * @return string representation
     */
    public static String toString (Map map) {
  List keys = new ArrayList (map.keySet ());
  try {
      Collections.sort (keys);
  } catch (Throwable e) {
  }
  StringBuffer res = new StringBuffer ("Map[");
  boolean first = true;
  for (Iterator i = keys.iterator (); i.hasNext (); ) {
      String key = (String)i.next();
      if (!first) {
    res.append (",");
      } else {
    first = false;
      }
      res.append (key + "=" + map.get(key));
  }
  res.append ("]");
  return res.toString ();
    }

    public static class TrackedList implements List { 
        /** Backing List. */
        private List l;
        /** Modified entries. */
        private boolean modified = false;
     
        /**
         * Create a new tracked list with the given list as backing list.
         * @param list the list to track.
         */
        public TrackedList (List list) {
            l = list;
        }
        
        /**
         * Check if list has been modified and reset modified flag.
         * @return <code>true</code> if list has been modified.
         */
        public boolean isModified () {
            boolean m = modified;
            modified = false;
            return m;
        }
        
        /* (non-Javadoc)
         * @see java.util.List#add(int, java.lang.Object)
         */
        public void add(int index, Object element) {
            l.add(index, element);
            modified = true;
        }
        
        /* (non-Javadoc)
         * @see java.util.List#add(java.lang.Object)
         */
        public boolean add(Object o) {
            modified = true;
            return l.add(o);
        }
        
        /* (non-Javadoc)
         * @see java.util.List#addAll(java.util.Collection)
         */
        public boolean addAll(Collection c) {
            modified = true;
            return l.addAll(c);
        }
        
        /* (non-Javadoc)
         * @see java.util.List#addAll(int, java.util.Collection)
         */
        public boolean addAll(int index, Collection c) {
            modified = true;
            return l.addAll(index, c);
        }
        
        /* (non-Javadoc)
         * @see java.util.List#clear()
         */
        public void clear() {
            modified = true;
            l.clear();
        }
        
        /* (non-Javadoc)
         * @see java.util.List#contains(java.lang.Object)
         */
        public boolean contains(Object o) {
            return l.contains(o);
        }
        
        /* (non-Javadoc)
         * @see java.util.List#containsAll(java.util.Collection)
         */
        public boolean containsAll(Collection c) {
            return l.containsAll(c);
        }
        
        /* (non-Javadoc)
         * @see java.util.List#equals(java.lang.Object)
         */
        public boolean equals(Object o) {
            return l.equals(o);
        }
        
        /* (non-Javadoc)
         * @see java.util.List#get(int)
         */
        public Object get(int index) {
            return l.get(index);
        }
        
        /* (non-Javadoc)
         * @see java.util.List#hashCode()
         */
        public int hashCode() {
            return l.hashCode();
        }
        
        /* (non-Javadoc)
         * @see java.util.List#indexOf(java.lang.Object)
         */
        public int indexOf(Object o) {
            return l.indexOf(o);
        }
        
        /* (non-Javadoc)
         * @see java.util.List#isEmpty()
         */
        public boolean isEmpty() {
            return l.isEmpty();
        }
        
        /* (non-Javadoc)
         * @see java.util.List#iterator()
         */
        public Iterator iterator() {
            return l.iterator();
        }
        
        /* (non-Javadoc)
         * @see java.util.List#lastIndexOf(java.lang.Object)
         */
        public int lastIndexOf(Object o) {
            return l.lastIndexOf(o);
        }
        
        /* (non-Javadoc)
         * @see java.util.List#listIterator()
         */
        public ListIterator listIterator() {
            return l.listIterator();
        }
        
        /* (non-Javadoc)
         * @see java.util.List#listIterator(int)
         */
        public ListIterator listIterator(int index) {
            return l.listIterator(index);
        }
        
        /* (non-Javadoc)
         * @see java.util.List#remove(int)
         */
        public Object remove(int index) {
            modified = true;
            return l.remove(index);
        }
        
        /* (non-Javadoc)
         * @see java.util.List#remove(java.lang.Object)
         */
        public boolean remove(Object o) {
            modified = true;
            return l.remove(o);
        }
        
        /* (non-Javadoc)
         * @see java.util.List#removeAll(java.util.Collection)
         */
        public boolean removeAll(Collection c) {
            modified = true;
            return l.removeAll(c);
        }
        
        /* (non-Javadoc)
         * @see java.util.List#retainAll(java.util.Collection)
         */
        public boolean retainAll(Collection c) {
            modified = true;
            return l.retainAll(c);
        }
        
        /* (non-Javadoc)
         * @see java.util.List#set(int, java.lang.Object)
         */
        public Object set(int index, Object element) {
            modified = true;
            return l.set(index, element);
        }
        
        /* (non-Javadoc)
         * @see java.util.List#size()
         */
        public int size() {
            return l.size();
        }
        
        /* (non-Javadoc)
         * @see java.util.List#subList(int, int)
         */
        public List subList(int fromIndex, int toIndex) {
            return l.subList(fromIndex, toIndex);
        }
        
        /* (non-Javadoc)
         * @see java.util.List#toArray()
         */
        public Object[] toArray() {
            return l.toArray();
        }
        
        /* (non-Javadoc)
         * @see java.util.List#toArray(java.lang.Object[])
         */
        public Object[] toArray(Object[] a) {
            return l.toArray(a);
        }

        public String toString() {
            return l.toString();
        }
    }    

    /**
     * Factory method for creating a new tracked list out of an "ordinary" List.
     * @param list the backing list for modification tracking.
     * @return a tracked list as a List.
     */
    public static List trackedList (List list) {
        return new TrackedList (list);
    }

    /**
     * Check if the given list is a tracked list.
     * @param list the list to be tested
     * @return true if list is tracked, otherwise false.
     */
    public static boolean isTracked (List list) {
        return (list instanceof TrackedList);
    }

    /**
     * Check if the given list has been modified. The method resets the
     * internal modified flag as it is assumed that after calling this
     * method some synchronization will be done and tracking starts
     * anew.<P>
     *
     * The method throws an <code>IllegalArgumentException</code> if
     * the argument is not a result of {@link #trackedList
     * <code>trackedList</code>}, i.e. if <code>isTracked(list) ==
     * false</code>.
     * @param list the list to be checked.
     * @return true if list has been modified, otherwise false.
     */
    public static boolean hasBeenModified (List list) {
        if (list instanceof TrackedList) {
            return ((TrackedList)list).isModified ();
        }
        throw new IllegalArgumentException ("Not a tracked list.");
    }
}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.