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