001    /*
002     * Copyright (c) Andrey Kuznetsov. All Rights Reserved.
003     *
004     * Redistribution and use in source and binary forms, with or without
005     * modification, are permitted provided that the following conditions are met:
006     *
007     *  o Redistributions of source code must retain the above copyright notice,
008     *    this list of conditions and the following disclaimer.
009     *
010     *  o Redistributions in binary form must reproduce the above copyright notice,
011     *    this list of conditions and the following disclaimer in the documentation
012     *    and/or other materials provided with the distribution.
013     *
014     *  o Neither the name of imagero Andrey Kuznetsov nor the names of
015     *    its contributors may be used to endorse or promote products derived
016     *    from this software without specific prior written permission.
017     *
018     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
019     * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
020     * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
021     * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
022     * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
023     * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
024     * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
025     * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
026     * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
027     * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
028     * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
029     */
030    package com.imagero.util;
031    
032    import java.util.Enumeration;
033    import java.util.Hashtable;
034    
035    /**
036     * HashBag - every key corresponds to multiple values
037     */
038    public class HashBag {
039        private final Hashtable hashtable = new Hashtable();
040    
041        public int size() {
042            return hashtable.size();
043        }
044    
045        public boolean isEmpty() {
046            return hashtable.isEmpty();
047        }
048    
049        public Enumeration keys() {
050            return hashtable.keys();
051        }
052    
053        public Object get(Object key, int index) {
054            Vector list = (Vector) hashtable.get(key);
055            if (list != null) {
056                return list.elementAt(index);
057            }
058            return null;
059        }
060    
061        public void put(Object key, Object value) {
062            Vector list = (Vector) hashtable.get(key);
063            if (list == null) {
064                list = new Vector(1);
065                hashtable.put(key, list);
066            }
067            list.add(value);
068        }
069    
070        /**
071         * removes the key and all corresponding values from HashBag
072         * @param key
073         */
074        public Object[] remove(Object key) {
075            Vector list = (Vector) hashtable.remove(key);
076            if (list == null) {
077                return new Object[0];
078            }
079            Object o [] = new Object[list.size()];
080            for (int i = 0; i < o.length; i++) {
081                o[i] = list.elementAt(i);
082            }
083            return o;
084        }
085    
086        /**
087         * remove Object from HashBag
088         * @param key key to search
089         * @param index index to remove
090         * @return Object
091         */
092        public Object remove(Object key, int index) {
093            Vector list = (Vector) hashtable.get(key);
094            if (list != null) {
095                Object o = list.elementAt(index);
096                list.remove(index);
097                if (list.size() == 0) {
098                    hashtable.remove(key);
099                }
100                return o;
101            }
102            return null;
103        }
104    
105        /**
106         * remove Object from HashBag
107         * @param key key to search
108         * @param obj Object to remove
109         * @return true if <code>obj</code> was found
110         */
111        public boolean remove(Object key, Object obj) {
112            Vector list = (Vector) hashtable.get(key);
113            try {
114                return list.remove(obj);
115            }
116            finally {
117                if (list.size() == 0) {
118                    hashtable.remove(key);
119                }
120            }
121        }
122    
123        /**
124         * get count of objects correspondings to <code>key</code>
125         * @param key
126         */
127        public int getCount(Object key) {
128            Vector list = (Vector) hashtable.get(key);
129            if (list != null) {
130                return list.size();
131            }
132            return 0;
133        }
134    
135        /**
136         * Returns true if HashBag contains the specified element
137         * @param o object to be checked
138         * @return true if the specified element is contained in HashBag.
139         */
140        public boolean contains(Object o) {
141            Enumeration enum = hashtable.keys();
142            while (enum.hasMoreElements()) {
143                Object key = enum.nextElement();
144                Vector v = (Vector) hashtable.get(key);
145                if (v.contains(o)) {
146                    return true;
147                }
148            }
149            return false;
150        }
151    
152        /**
153         * Returns true if HashBag contains the specified element under given key.
154         * @param key key to search
155         * @param o Object to search
156         * @return true if specified element was found
157         */
158        public boolean contains(Object key, Object o) {
159            Vector v = (Vector) hashtable.get(key);
160            if (v.contains(o)) {
161                return true;
162            }
163            return false;
164        }
165    
166    
167    }