001    package org.hackystat.projectbrowser.page.projectportfolio.detailspanel;
002    
003    import java.io.Serializable;
004    import java.util.ArrayList;
005    import java.util.List;
006    import org.apache.wicket.markup.html.panel.Panel;
007    import org.apache.wicket.model.IModel;
008    import org.apache.wicket.model.Model;
009    import org.hackystat.projectbrowser.page.projectportfolio.detailspanel.chart.MiniBarChart;
010    import org.hackystat.projectbrowser.page.projectportfolio.detailspanel.chart.StreamClassifier;
011    import org.hackystat.projectbrowser.page.projectportfolio.detailspanel.chart.PortfolioCategory;
012    import org.hackystat.projectbrowser.page.projectportfolio.jaxb.Measures.Measure;
013    
014    /**
015     * Configuration for project portfolio measures.
016     * 
017     * @author Shaoxuan Zhang
018     * 
019     */
020    public class PortfolioMeasureConfiguration implements Serializable {
021      /** Support serialization. */
022      private static final long serialVersionUID = -6799287509742157998L;
023      
024      /** The parameter separator. */
025      private static final String PARAMETER_SEPARATOR = ",";
026    
027      /** The name of the measure. */
028      private String measureName;
029      /** The alias of this measure, which will be used as display name. */
030      private String alias;
031      /** If this measure is enabled. */
032      private boolean enabled = true;
033      /** The method to merge multiple streams. */
034      private String merge;
035    
036      /** The data model this measure belongs to. */
037      private final ProjectPortfolioDataModel dataModel;
038    
039      /** This meausre's parameter list. */
040      //private List<String> parameters = new ArrayList<String>();
041      /** The parameters for telemetry analysis. */
042      private final List<IModel> parameters = new ArrayList<IModel>();
043      
044      /** The stream classifier.*/
045      private StreamClassifier streamClassifier;
046    
047      /**
048       * Create an instance.
049       * 
050       * @param name The name of the measure.
051       * @param alias The alias of this measure, which will be used as display name.
052       * @param merge The method to merge multiple streams. Can be sum, avg, min or max.
053       * @param enabled If this measure is enabled.
054       * @param streamClassifier the {@link StreamClassifier} to use, null means no coloring.
055       * @param dataModel The data model this measure belongs to.
056       */
057      public PortfolioMeasureConfiguration(String name, String alias, String merge, boolean enabled,
058          StreamClassifier streamClassifier, ProjectPortfolioDataModel dataModel) {
059        this.measureName = name;
060        this.alias = alias;
061        this.merge = merge;
062        this.enabled = enabled;
063        this.streamClassifier = streamClassifier;
064        this.dataModel = dataModel;
065      }
066      
067      /**
068       * Load configuration from a PortfolioMeasure object.
069       * @param enabled If this measure is enabled.
070       * @param streamClassifier The stream classifier.
071       * @param telemetryParameters The parameters for telemetry analysis.
072       */
073      public void setMeasureConfiguration(boolean enabled, StreamClassifier streamClassifier,
074          String telemetryParameters) {
075        this.setEnabled(enabled);
076        this.streamClassifier = streamClassifier;
077        this.parameters.clear();
078        if (telemetryParameters != null) {
079          for (String parameter : telemetryParameters.split(PARAMETER_SEPARATOR)) {
080            this.parameters.add(new Model(parameter));
081          }
082        }
083      }
084    
085      /**
086       * @return the measureName
087       */
088      public String getName() {
089        return measureName;
090      }
091    
092      /**
093       * @param enabled the enable to set
094       */
095      public void setEnabled(boolean enabled) {
096        this.enabled = enabled;
097      }
098    
099      /**
100       * @return the enable
101       */
102      public boolean isEnabled() {
103        return enabled;
104      }
105    
106      /**
107       * Return the color associated with the given category.
108       * @param category the {@link PortfolioCategory}.
109       * @return Color in String.
110       */
111      public String getColor(PortfolioCategory category) {
112        switch (category) {
113          case GOOD: return getDataModel().getGoodColor();
114          case AVERAGE: return getDataModel().getAverageColor();
115          case POOR: return getDataModel().getPoorColor();
116          case NA: return getDataModel().getNAColor();
117          default: return getDataModel().getFontColor();
118        }
119      }
120      
121      /**
122       * Return the color of the given MiniBarChart.
123       * @param chart the MiniBarChart
124       * @return the color in String
125       */
126      public String getChartColor(MiniBarChart chart) {
127        if (hasClassifier()) {
128          return getColor(this.streamClassifier.getStreamCategory(chart));
129        }
130        else {
131          return getDataModel().getFontColor();
132        }
133      }
134      
135      /**
136       * Return the color according to the value.
137       * The color method is defined in this measure configuration.
138       * @param value the value.
139       * @return the color in String
140       */
141      public String getValueColor(double value) {
142        if (hasClassifier()) {
143          return getColor(this.streamClassifier.getValueCategory(value));
144        }
145        else {
146          if (value < 0) {
147            return getColor(PortfolioCategory.NA);
148          }
149          return getColor(PortfolioCategory.OTHER);
150        }
151      }
152      
153      /**
154       * Return the color for average value or unstable trend.
155       * @return the color
156       */
157      public String getAverageColor() {
158        return dataModel.getAverageColor();
159      }
160    
161      /**
162       * Return the parameters in a single String.
163       * 
164       * @return parameters separated by ',' in a single String.
165       */
166      public String getParamtersString() {
167        if (this.parameters.isEmpty()) {
168          return "";
169        }
170        StringBuffer param = new StringBuffer();
171        for (int i = 0; i < this.parameters.size(); ++i) {
172          IModel model = this.parameters.get(i);
173          if (model != null) {
174            param.append(model.getObject());
175            if (i < this.parameters.size() - 1) {
176              param.append(PARAMETER_SEPARATOR);
177            }
178          }
179        }
180        return param.toString();
181      }
182    
183      /**
184       * @return the parameters
185       */
186      public List<IModel> getParameters() {
187        return this.parameters;
188      }
189    
190      /**
191       * @return the dataModel
192       */
193      public ProjectPortfolioDataModel getDataModel() {
194        return dataModel;
195      }
196    
197      /**
198       * Set the stream classifier according to the given classifier name.
199       * If the colorMethod is null or is equals to the name of {@link streamClassifier}, 
200       * nothing will happen.
201       * Otherwise, it will create a new stream classifier with information saved in UriCache.
202       * @param classifierName the String represents the classifier.
203       */
204      public void setStreamClassifier(String classifierName) {
205        if (classifierName == null || (this.hasClassifier() && 
206            classifierName.equalsIgnoreCase(this.streamClassifier.getName()))) {
207          return;
208        }
209        Measure measure = dataModel.getSavedMeasure(this);
210        if (measure == null) {
211          measure = new Measure();
212        }
213        measure.setClassifierMethod(classifierName);
214        this.setStreamClassifier(ProjectPortfolioDataModel.getClassifier(measure));
215      }
216      
217      /**
218       * @param streamClassifier the streamTrendClassifier to set
219       */
220      public void setStreamClassifier(StreamClassifier streamClassifier) {
221        this.streamClassifier = streamClassifier;
222      }
223    
224      /**
225       * @return the streamTrendClassifier
226       */
227      public StreamClassifier getStreamClassifier() {
228        return streamClassifier;
229      }
230    
231      /**
232       * @param alias the alias to set
233       */
234      public void setAlias(String alias) {
235        this.alias = alias;
236      }
237    
238      /**
239       * @return the alias
240       */
241      public String getAlias() {
242        return alias;
243      }
244    
245      /**
246       * Check if the {@link alias} field is available.
247       * @return true if {@link alias} field is available.
248       */
249      public boolean hasAlias() {
250        return alias != null && alias.length() > 0;
251      }
252      
253      /**
254       * Return the display name of this measure.
255       * If alias is available, alias will be return. Otherwise, measure name will be return.
256       * @return the display name.
257       */
258      public String getDisplayName() {
259        if (this.alias != null && this.alias.length() > 0) {
260          return this.getAlias();
261        }
262        return this.getName();
263      }
264    
265      /**
266       * @param merge the merge to set
267       */
268      public void setMerge(String merge) {
269        this.merge = merge;
270      }
271    
272      /**
273       * @return the merge
274       */
275      public String getMerge() {
276        return merge;
277      }
278      
279      /**
280       * Check if the {@link merge} field is available.
281       * @return true if {@link merge} field is available.
282       */
283      public boolean hasMerge() {
284        return merge != null && merge.length() > 0;
285      }
286    
287      /**
288       * Return the configuration panel of the stream classifer.
289       * @param id the wicket id.
290       * @return the panel.
291       */
292      public Panel getConfigurationPanel(String id) {
293        if (hasClassifier()) {
294          return this.streamClassifier.getConfigurationPanel(id);
295        }
296        Panel panel = new Panel(id);
297        panel.setVisible(false);
298        return panel;
299      }
300    
301      /**
302       * @return the name of the {@link streamClassifier}.
303       */
304      public String getClassiferName() {
305        if (!hasClassifier()) {
306          return "None";
307        }
308        return this.streamClassifier.getName();
309      }
310    
311      /**
312       * Save classifier's setting into the given {@link Measure} instance.
313       * @param measure the given {@link Measure} instance
314       */
315      public void saveClassifierSetting(Measure measure) {
316        if (hasClassifier()) {
317          this.streamClassifier.saveSetting(measure);
318        }
319      }
320    
321      /**
322       * Check if this instance has the stream classifier.
323       * @return true if it has.
324       */
325      public boolean hasClassifier() {
326        return this.streamClassifier != null;
327      }
328    
329    }