001    /*
002     * Sonar, open source software quality management tool.
003     * Copyright (C) 2009 SonarSource SA
004     * mailto:contact AT sonarsource DOT com
005     *
006     * Sonar is free software; you can redistribute it and/or
007     * modify it under the terms of the GNU Lesser General Public
008     * License as published by the Free Software Foundation; either
009     * version 3 of the License, or (at your option) any later version.
010     *
011     * Sonar is distributed in the hope that it will be useful,
012     * but WITHOUT ANY WARRANTY; without even the implied warranty of
013     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
014     * Lesser General Public License for more details.
015     *
016     * You should have received a copy of the GNU Lesser General Public
017     * License along with Sonar; if not, write to the Free Software
018     * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02
019     */
020    package org.sonar.api.charts;
021    
022    import org.apache.commons.lang.StringUtils;
023    import org.apache.commons.lang.text.StrTokenizer;
024    import org.sonar.api.utils.SonarException;
025    
026    import java.io.UnsupportedEncodingException;
027    import java.net.URLDecoder;
028    import java.util.HashMap;
029    import java.util.Locale;
030    import java.util.Map;
031    
032    /**
033     * The class to hold parameters to configure a chart
034     * @since 1.10
035     */
036    public class ChartParameters {
037      private static final String[] EMPTY = new String[0];
038    
039      public static final String PARAM_WIDTH = "w";
040      public static final String PARAM_BACKGROUND_COLOR = "bgc";
041      public static final String PARAM_HEIGHT = "h";
042      public static final int MAX_WIDTH = 700;
043      public static final String PARAM_LOCALE = "locale";
044    
045      public static final int MAX_HEIGHT = 500;
046      public static final int DEFAULT_WIDTH = 200;
047    
048      public static final int DEFAULT_HEIGHT = 200;
049    
050    
051      private Map<String, String> params;
052    
053      /**
054       * Creates a ChartParameter based on a list of parameters
055       * @param params the list of parameters
056       */
057      public ChartParameters(Map<String, String> params) {
058        this.params = params;
059      }
060    
061      /**
062       * Creates a Chartparameter based on a query string with a format key1=value1&key2=value2...
063       *
064       * @param  queryString string
065       */
066      public ChartParameters(String queryString) {
067        this.params = new HashMap<String, String>();
068        String[] groups = StringUtils.split(queryString, "&");
069        for (String group : groups) {
070          String[] keyval = StringUtils.split(group, "=");
071          params.put(keyval[0], keyval[1]);
072        }
073      }
074    
075      /**
076       * Shortcut to getValue with no decoding and no default value
077       * @param key the param ket
078       * @return the value of the param
079       */
080      public String getValue(String key) {
081        return getValue(key, "", false);
082      }
083    
084      /**
085       * Returns the [decoded or not] value of a param from its key or the default value
086       * if id does not exist
087       *
088       * @param key the param ket
089       * @param defaultValue the default value if not exist
090       * @param decode whther the value should be decoded
091       * @return the value of the param
092       */
093    
094      public String getValue(String key, String defaultValue, boolean decode) {
095        String val = params.get(key);
096        if (decode) {
097          val = decode(val);
098        }
099        if (val == null) {
100          val = defaultValue;
101        }
102        return val;
103      }
104    
105      /**
106       * Returns an array of a param values, given its key and the values delimiter
107       *
108       * @param key the param key
109       * @param delimiter the values delimiter
110       * @return the list of vaalues
111       */
112      public String[] getValues(String key, String delimiter) {
113        String value = params.get(key);
114        if (value != null) {
115          return StringUtils.split(value, delimiter);
116        }
117        return EMPTY;
118      }
119    
120      /**
121       * Returns an array of a param values, given its key and the values delimiter
122       * Values can be decoded or not
123       *
124       * @param key the param key
125       * @param delimiter the values delimiter
126       * @param decode whether to decode values
127       * @return the list of vaalues
128       */
129      public String[] getValues(String key, String delimiter, boolean decode) {
130        String value = params.get(key);
131        if (value != null) {
132          if (decode) {
133            value = decode(value);
134          }
135          return new StrTokenizer(value, delimiter).setIgnoreEmptyTokens(false).getTokenArray();
136        }
137        return EMPTY;
138      }
139    
140      /**
141       * Get the chart width
142       *
143       * @return width
144       */
145      public int getWidth() {
146        int width = Integer.parseInt(getValue(PARAM_WIDTH, "" + DEFAULT_WIDTH, false));
147        return Math.min(width, MAX_WIDTH);
148      }
149    
150      /**
151       * Get the chart height
152       *
153       * @return height
154       */
155      public int getHeight() {
156        int height = Integer.parseInt(getValue(PARAM_HEIGHT, "" + DEFAULT_HEIGHT, false));
157        return Math.min(height, MAX_HEIGHT);
158      }
159    
160      /**
161       * Get the Locale
162       *
163       * @return Locale
164       */
165      public Locale getLocale() {
166        String locale = getValue(PARAM_LOCALE);
167        if (StringUtils.isNotBlank(locale)) {
168          return new Locale(locale);
169        }
170        return Locale.ENGLISH;
171      }
172    
173      private String decode(String val) {
174        if (val != null) {
175          try {
176            val = URLDecoder.decode(val, "UTF-8");
177          } catch (UnsupportedEncodingException e) {
178            throw new SonarException("Decoding chart parameter : " + val, e);
179          }
180        }
181        return val;
182      }
183    }