001    /* ======================================
002     * JFreeChart : a free Java chart library
003     * ======================================
004     *
005     * (C) Copyright 2000-2006, by Object Refinery Limited and Contributors.
006     *
007     * Project Info:  http://www.jfree.org/jfreechart/index.html
008     *
009     * This library is free software; you can redistribute it and/or modify it 
010     * under the terms of the GNU Lesser General Public License as published by 
011     * the Free Software Foundation; either version 2.1 of the License, or 
012     * (at your option) any later version.
013     *
014     * This library is distributed in the hope that it will be useful, but 
015     * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
016     * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 
017     * License for more details.
018     *
019     * You should have received a copy of the GNU Lesser General Public
020     * License along with this library; if not, write to the Free Software
021     * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, 
022     * USA.  
023     *
024     * [Java is a trademark or registered trademark of Sun Microsystems, Inc. 
025     * in the United States and other countries.]
026     *
027     * --------------------------
028     * CustomPieURLGenerator.java
029     * --------------------------
030     * (C) Copyright 2004-2006, by David Basten and Contributors.
031     *
032     * Original Author:  David Basten;
033     * Contributors:     -;
034     *
035     * $Id: CustomPieURLGenerator.java,v 1.3.2.2 2006/11/24 11:05:02 mungady Exp $
036     *
037     * Changes:
038     * --------
039     * 04-Feb-2004 : Version 1, contributed by David Basten based on 
040     *               CustomXYURLGenerator by Richard Atkinson (added to main source
041     *               tree on 25-May-2004);
042     *
043     */
044    package org.jfree.chart.urls;
045    
046    import java.io.Serializable;
047    import java.util.ArrayList;
048    import java.util.HashMap;
049    import java.util.Iterator;
050    import java.util.Map;
051    import java.util.Set;
052    
053    import org.jfree.chart.plot.MultiplePiePlot;
054    import org.jfree.data.general.PieDataset;
055    import org.jfree.util.PublicCloneable;
056    
057    /**
058     * A custom URL generator for pie charts.
059     */
060    public class CustomPieURLGenerator implements PieURLGenerator, 
061                                                  Cloneable, 
062                                                  PublicCloneable, 
063                                                  Serializable {
064    
065        /** For serialization. */
066        private static final long serialVersionUID = 7100607670144900503L;
067    
068        /** Storage for the URLs. */
069        private ArrayList urls;
070    
071        /**
072         * Creates a new <code>CustomPieURLGenerator</code> instance, initially
073         * empty.  Call {@link #addURLs(Map)} to specify the URL fragments to be
074         * used.
075         */
076        public CustomPieURLGenerator() {
077            this.urls = new ArrayList();
078        }
079    
080        /**
081         * Generates a URL fragment.
082         *
083         * @param dataset  the dataset (ignored).
084         * @param key  the item key.
085         * @param pieIndex  the pie index.
086         *
087         * @return A string containing the generated URL.
088         * 
089         * @see #getURL(Comparable, int)
090         */
091        public String generateURL(PieDataset dataset, Comparable key, 
092                                  int pieIndex) {
093            return getURL(key, pieIndex);
094        }
095    
096        /**
097         * Returns the number of URL maps stored by the renderer.
098         * 
099         * @return The list count.
100         * 
101         * @see #addURLs(Map)
102         */
103        public int getListCount() {
104            return this.urls.size();
105        }
106        
107        /**
108         * Returns the number of URLs in a given map (specified by its position 
109         * in the map list).
110         * 
111         * @param list  the list index (zero based).
112         * 
113         * @return The URL count.
114         * 
115         * @see #getListCount()
116         */
117        public int getURLCount(int list) {
118            int result = 0;
119            Map urlMap = (Map) this.urls.get(list);
120            if (urlMap != null) {
121                result = urlMap.size();
122            }
123            return result;
124        }
125    
126        /**
127         * Returns the URL for a section in the specified map.
128         * 
129         * @param key  the key.
130         * @param mapIndex  the map index.
131         * 
132         * @return The URL.
133         */    
134        public String getURL(Comparable key, int mapIndex) {
135            String result = null;
136            if (mapIndex < getListCount()) {
137                Map urlMap = (Map) this.urls.get(mapIndex);
138                if (urlMap != null) {
139                    result = (String) urlMap.get(key);
140                }
141            }
142            return result;
143        }
144    
145        /**
146         * Adds a map containing <code>(key, URL)</code> mappings where each
147         * <code>key</code> is an instance of <code>Comparable</code> 
148         * (corresponding to the key for an item in a pie dataset) and each 
149         * <code>URL</code> is a <code>String</code> representing a URL fragment.
150         * <br><br>
151         * The map is appended to an internal list...you can add multiple maps
152         * if you are working with, say, a {@link MultiplePiePlot}.
153         * 
154         * @param urlMap  the URLs (<code>null</code> permitted).
155         */
156        public void addURLs(Map urlMap) {
157            this.urls.add(urlMap);
158        }
159        
160        /**
161         * Tests if this object is equal to another.
162         * 
163         * @param o  the other object.
164         * 
165         * @return A boolean.
166         */
167        public boolean equals(Object o) {
168        
169            if (o == this) {
170                return true;
171            }
172            
173            if (o instanceof CustomPieURLGenerator) {
174                CustomPieURLGenerator generator = (CustomPieURLGenerator) o;
175                if (getListCount() != generator.getListCount()) {
176                    return false;
177                }
178                Set keySet;
179                for (int pieItem = 0; pieItem < getListCount(); pieItem++) {
180                    if (getURLCount(pieItem) != generator.getURLCount(pieItem)) {
181                        return false;
182                    }
183                    keySet = ((HashMap) this.urls.get(pieItem)).keySet();
184                    String key;
185                    for (Iterator i = keySet.iterator(); i.hasNext();) {
186                    key = (String) i.next();
187                        if (!getURL(key, pieItem).equals(
188                                generator.getURL(key, pieItem))) {
189                            return false;
190                        }
191                    }
192                }
193                return true;
194            }
195            return false;
196        }
197    
198        /**
199         * Returns a clone of the generator.
200         * 
201         * @return A clone.
202         * 
203         * @throws CloneNotSupportedException if cloning is not supported.
204         */
205        public Object clone() throws CloneNotSupportedException {
206            CustomPieURLGenerator urlGen = new CustomPieURLGenerator();
207            Map map;
208            Map newMap;
209            String key;
210    
211            for (Iterator i = this.urls.iterator(); i.hasNext();) {
212                map = (Map) i.next();
213    
214                newMap = new HashMap();
215                for (Iterator j = map.keySet().iterator(); j.hasNext();) {
216                    key = (String) j.next();
217                    newMap.put(key, map.get(key));
218                }
219    
220                urlGen.addURLs(newMap);
221                newMap = null;
222            }
223    
224            return urlGen;
225        }
226    
227    }