001/* ======================================
002 * JFreeChart : a free Java chart library
003 * ======================================
004 *
005 * (C) Copyright 2000-2007, 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-2007, by David Basten and Contributors.
031 *
032 * Original Author:  David Basten;
033 * Contributors:     -;
034 *
035 * Changes:
036 * --------
037 * 04-Feb-2004 : Version 1, contributed by David Basten based on 
038 *               CustomXYURLGenerator by Richard Atkinson (added to main source
039 *               tree on 25-May-2004);
040 *
041 */
042package org.jfree.chart.urls;
043
044import java.io.Serializable;
045import java.util.ArrayList;
046import java.util.HashMap;
047import java.util.Iterator;
048import java.util.Map;
049import java.util.Set;
050
051import org.jfree.chart.plot.MultiplePiePlot;
052import org.jfree.data.general.PieDataset;
053import org.jfree.util.PublicCloneable;
054
055/**
056 * A custom URL generator for pie charts.
057 */
058public class CustomPieURLGenerator implements PieURLGenerator, 
059                                              Cloneable, 
060                                              PublicCloneable, 
061                                              Serializable {
062
063    /** For serialization. */
064    private static final long serialVersionUID = 7100607670144900503L;
065
066    /** Storage for the URLs. */
067    private ArrayList urls;
068
069    /**
070     * Creates a new <code>CustomPieURLGenerator</code> instance, initially
071     * empty.  Call {@link #addURLs(Map)} to specify the URL fragments to be
072     * used.
073     */
074    public CustomPieURLGenerator() {
075        this.urls = new ArrayList();
076    }
077
078    /**
079     * Generates a URL fragment.
080     *
081     * @param dataset  the dataset (ignored).
082     * @param key  the item key.
083     * @param pieIndex  the pie index.
084     *
085     * @return A string containing the generated URL.
086     * 
087     * @see #getURL(Comparable, int)
088     */
089    public String generateURL(PieDataset dataset, Comparable key, 
090                              int pieIndex) {
091        return getURL(key, pieIndex);
092    }
093
094    /**
095     * Returns the number of URL maps stored by the renderer.
096     * 
097     * @return The list count.
098     * 
099     * @see #addURLs(Map)
100     */
101    public int getListCount() {
102        return this.urls.size();
103    }
104    
105    /**
106     * Returns the number of URLs in a given map (specified by its position 
107     * in the map list).
108     * 
109     * @param list  the list index (zero based).
110     * 
111     * @return The URL count.
112     * 
113     * @see #getListCount()
114     */
115    public int getURLCount(int list) {
116        int result = 0;
117        Map urlMap = (Map) this.urls.get(list);
118        if (urlMap != null) {
119            result = urlMap.size();
120        }
121        return result;
122    }
123
124    /**
125     * Returns the URL for a section in the specified map.
126     * 
127     * @param key  the key.
128     * @param mapIndex  the map index.
129     * 
130     * @return The URL.
131     */    
132    public String getURL(Comparable key, int mapIndex) {
133        String result = null;
134        if (mapIndex < getListCount()) {
135            Map urlMap = (Map) this.urls.get(mapIndex);
136            if (urlMap != null) {
137                result = (String) urlMap.get(key);
138            }
139        }
140        return result;
141    }
142
143    /**
144     * Adds a map containing <code>(key, URL)</code> mappings where each
145     * <code>key</code> is an instance of <code>Comparable</code> 
146     * (corresponding to the key for an item in a pie dataset) and each 
147     * <code>URL</code> is a <code>String</code> representing a URL fragment.
148     * <br><br>
149     * The map is appended to an internal list...you can add multiple maps
150     * if you are working with, say, a {@link MultiplePiePlot}.
151     * 
152     * @param urlMap  the URLs (<code>null</code> permitted).
153     */
154    public void addURLs(Map urlMap) {
155        this.urls.add(urlMap);
156    }
157    
158    /**
159     * Tests if this object is equal to another.
160     * 
161     * @param o  the other object.
162     * 
163     * @return A boolean.
164     */
165    public boolean equals(Object o) {
166    
167        if (o == this) {
168            return true;
169        }
170        
171        if (o instanceof CustomPieURLGenerator) {
172            CustomPieURLGenerator generator = (CustomPieURLGenerator) o;
173            if (getListCount() != generator.getListCount()) {
174                return false;
175            }
176            Set keySet;
177            for (int pieItem = 0; pieItem < getListCount(); pieItem++) {
178                if (getURLCount(pieItem) != generator.getURLCount(pieItem)) {
179                    return false;
180                }
181                keySet = ((HashMap) this.urls.get(pieItem)).keySet();
182                String key;
183                for (Iterator i = keySet.iterator(); i.hasNext();) {
184                key = (String) i.next();
185                    if (!getURL(key, pieItem).equals(
186                            generator.getURL(key, pieItem))) {
187                        return false;
188                    }
189                }
190            }
191            return true;
192        }
193        return false;
194    }
195
196    /**
197     * Returns a clone of the generator.
198     * 
199     * @return A clone.
200     * 
201     * @throws CloneNotSupportedException if cloning is not supported.
202     */
203    public Object clone() throws CloneNotSupportedException {
204        CustomPieURLGenerator urlGen = new CustomPieURLGenerator();
205        Map map;
206        Map newMap;
207        String key;
208
209        for (Iterator i = this.urls.iterator(); i.hasNext();) {
210            map = (Map) i.next();
211
212            newMap = new HashMap();
213            for (Iterator j = map.keySet().iterator(); j.hasNext();) {
214                key = (String) j.next();
215                newMap.put(key, map.get(key));
216            }
217
218            urlGen.addURLs(newMap);
219            newMap = null;
220        }
221
222        return urlGen;
223    }
224
225}