001/* =========================================================== 002 * JFreeChart : a free chart library for the Java(tm) platform 003 * =========================================================== 004 * 005 * (C) Copyright 2000-present, by David Gilbert 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 * [Oracle and Java are registered trademarks of Oracle and/or its affiliates. 025 * Other names may be trademarks of their respective owners.] 026 * 027 * --------------------------------- 028 * StandardCategoryURLGenerator.java 029 * --------------------------------- 030 * (C) Copyright 2002-present, by Richard Atkinson and Contributors. 031 * 032 * Original Author: Richard Atkinson; 033 * Contributors: David Gilbert; 034 * Cleland Early; 035 * 036 */ 037 038package org.jfree.chart.urls; 039 040import java.io.Serializable; 041import java.io.UnsupportedEncodingException; 042import java.net.URLEncoder; 043import java.util.Objects; 044import org.jfree.chart.util.Args; 045 046import org.jfree.data.category.CategoryDataset; 047 048/** 049 * A URL generator that can be assigned to a 050 * {@link org.jfree.chart.renderer.category.CategoryItemRenderer}. 051 */ 052public class StandardCategoryURLGenerator implements CategoryURLGenerator, 053 Cloneable, Serializable { 054 055 /** For serialization. */ 056 private static final long serialVersionUID = 2276668053074881909L; 057 058 /** Prefix to the URL */ 059 private String prefix = "index.html"; 060 061 /** Series parameter name to go in each URL */ 062 private String seriesParameterName = "series"; 063 064 /** Category parameter name to go in each URL */ 065 private String categoryParameterName = "category"; 066 067 /** 068 * Creates a new generator with default settings. 069 */ 070 public StandardCategoryURLGenerator() { 071 super(); 072 } 073 074 /** 075 * Constructor that overrides default prefix to the URL. 076 * 077 * @param prefix the prefix to the URL ({@code null} not permitted). 078 */ 079 public StandardCategoryURLGenerator(String prefix) { 080 Args.nullNotPermitted(prefix, "prefix"); 081 this.prefix = prefix; 082 } 083 084 /** 085 * Constructor that overrides all the defaults. 086 * 087 * @param prefix the prefix to the URL ({@code null} not permitted). 088 * @param seriesParameterName the name of the series parameter to go in 089 * each URL ({@code null} not permitted). 090 * @param categoryParameterName the name of the category parameter to go in 091 * each URL ({@code null} not permitted). 092 */ 093 public StandardCategoryURLGenerator(String prefix, 094 String seriesParameterName, String categoryParameterName) { 095 096 Args.nullNotPermitted(prefix, "prefix"); 097 Args.nullNotPermitted(seriesParameterName, 098 "seriesParameterName"); 099 Args.nullNotPermitted(categoryParameterName, 100 "categoryParameterName"); 101 this.prefix = prefix; 102 this.seriesParameterName = seriesParameterName; 103 this.categoryParameterName = categoryParameterName; 104 105 } 106 107 /** 108 * Generates a URL for a particular item within a series. 109 * 110 * @param dataset the dataset. 111 * @param series the series index (zero-based). 112 * @param category the category index (zero-based). 113 * 114 * @return The generated URL. 115 */ 116 @Override 117 public String generateURL(CategoryDataset dataset, int series, 118 int category) { 119 String url = this.prefix; 120 Comparable seriesKey = dataset.getRowKey(series); 121 Comparable categoryKey = dataset.getColumnKey(category); 122 boolean firstParameter = !url.contains("?"); 123 url += firstParameter ? "?" : "&"; 124 try { 125 url += this.seriesParameterName + "=" + URLEncoder.encode( 126 seriesKey.toString(), "UTF-8"); 127 url += "&" + this.categoryParameterName + "=" 128 + URLEncoder.encode(categoryKey.toString(), "UTF-8"); 129 } catch (UnsupportedEncodingException ex) { 130 throw new RuntimeException(ex); // this won't happen :) 131 } 132 return url; 133 } 134 135 /** 136 * Returns an independent copy of the URL generator. 137 * 138 * @return A clone. 139 * 140 * @throws CloneNotSupportedException not thrown by this class, but 141 * subclasses (if any) might. 142 */ 143 @Override 144 public Object clone() throws CloneNotSupportedException { 145 // all attributes are immutable, so we can just return the super.clone() 146 // FIXME: in fact, the generator itself is immutable, so cloning is 147 // not necessary 148 return super.clone(); 149 } 150 151 /** 152 * Tests the generator for equality with an arbitrary object. 153 * 154 * @param obj the object ({@code null} permitted). 155 * 156 * @return A boolean. 157 */ 158 @Override 159 public boolean equals(Object obj) { 160 if (obj == this) { 161 return true; 162 } 163 if (!(obj instanceof StandardCategoryURLGenerator)) { 164 return false; 165 } 166 StandardCategoryURLGenerator that = (StandardCategoryURLGenerator) obj; 167 if (!Objects.equals(this.prefix, that.prefix)) { 168 return false; 169 } 170 171 if (!Objects.equals(this.seriesParameterName, 172 that.seriesParameterName)) { 173 return false; 174 } 175 if (!Objects.equals(this.categoryParameterName, 176 that.categoryParameterName)) { 177 return false; 178 } 179 return true; 180 } 181 182 /** 183 * Returns a hash code. 184 * 185 * @return A hash code. 186 */ 187 @Override 188 public int hashCode() { 189 int result; 190 result = (this.prefix != null ? this.prefix.hashCode() : 0); 191 result = 29 * result 192 + (this.seriesParameterName != null 193 ? this.seriesParameterName.hashCode() : 0); 194 result = 29 * result 195 + (this.categoryParameterName != null 196 ? this.categoryParameterName.hashCode() : 0); 197 return result; 198 } 199 200}