001    package org.hackystat.telemetry.analyzer.evaluator;
002    
003    import java.util.ArrayList;
004    import java.util.Collections;
005    import java.util.List;
006    
007    import org.hackystat.telemetry.analyzer.language.ast.TelemetryChartDefinition;
008    
009    /**
010     * The evaluation result after resolving a telemetry chart definition. 
011     *
012     * @author (Cedric) Qin Zhang
013     */
014    public class TelemetryChartObject {
015    
016      private TelemetryChartDefinition definition;
017      private List<SubChart> subCharts = new ArrayList<SubChart>();
018      
019      /**
020       * Constructs this instance.
021       * 
022       * @param definition The telemetry chart definition.
023       */
024      TelemetryChartObject(TelemetryChartDefinition definition) {
025        this.definition = definition;
026      }
027      
028      /**
029       * Gets the telemetry chart definition.
030       * 
031       * @return The telemetry chart definiton. 
032       */
033      public TelemetryChartDefinition getTelemetryChartDefinition() {
034        return this.definition;
035      }
036      
037      /**
038       * Adds a sub-chart.
039       * 
040       * @param subChart The sub-chart to be added.
041       */
042      void addSubChart(SubChart subChart) {
043        this.subCharts.add(subChart);
044      }
045      
046      /**
047       * Gets a read-only list of all sub-charts.
048       * 
049       * @return A read-only list containing <code>SubChart</code> objects.
050       */
051      public List<SubChart> getSubCharts() {
052        return Collections.unmodifiableList(this.subCharts);
053      }
054      
055      /**
056       * A telemetry sub chart, consisting of a Y-Axis and a Telemetry Stream.
057       * 
058       * @author (Cedric) Qin ZHANG
059       */
060      public static class SubChart {
061    
062        private YAxis yAxis;
063        private TelemetryStreamsObject streamsObject;
064        
065        /**
066         * Constructs this instance.
067         * @param streamsObject The telemetry streams object.
068         * @param yAxis Y-axis.
069    
070         */
071        SubChart(TelemetryStreamsObject streamsObject, YAxis yAxis) {
072          this.streamsObject = streamsObject;
073          this.yAxis = yAxis;
074        }
075        
076        /**
077         * Gets y-axis object.
078         * 
079         * @return Y-axis object.
080         */
081        public YAxis getYAxis() {
082          return this.yAxis;
083        }
084        
085        /**
086         * Gets telemetry stream object.
087         * 
088         * @return The telemetry stream object.
089         */
090        public TelemetryStreamsObject getTelemetryStreamsObject() {
091          return this.streamsObject;
092        }
093      }
094      
095      /**
096       * A Y-axis, consisting of a label, a boolean indicating if the Axis is an integer, and 
097       * an optional lower bound and upper bound value. 
098       * 
099       * @author (Cedric) Qin ZHANG
100       */
101      public static class YAxis {
102        private String label; 
103        private boolean integerAxis;
104        private Number lowerBound, upperBound;
105        
106        /**
107         * Constructs this instance.
108         * 
109         * @param label Y-axis label.
110         * @param integerAxis True if y-axis is integer axis.
111         * @param lowerBound Y-axis lower bound, use null to enable y-axis autoscale.
112         * @param upperBound Y-axis upper bound, use null to enable y-axis autoscale.
113         */
114        public YAxis(String label, boolean integerAxis, Number lowerBound, Number upperBound) {
115          this.label = label;
116          this.integerAxis = integerAxis;
117          this.lowerBound = lowerBound;
118          this.upperBound = upperBound;
119        }
120        
121        /**
122         * Gets y-axis label.
123         * @return Y-axis label.
124         */
125        public String getLabel() {
126          return this.label;
127        }
128        
129        /**
130         * Determines if y-axis is integer axis.
131         * @return True if y-axis is integer axis.
132         */
133        public boolean isIntegerAxis() {
134          return this.integerAxis;
135        }
136        
137        /**
138         * Determine if y-axis is auto-scaled.
139         * @return True if it is auto-scaled.
140         */
141        public boolean isAutoScaledAxis() {
142          return this.lowerBound == null || this.upperBound == null; 
143        }
144        
145        /**
146         * Gets lower bound in case y-axis is not auto-scaled.
147         * @return The lower bound.
148         */
149        public Number getLowerBound() {
150          return this.lowerBound; 
151        }
152        
153        /**
154         * Gets upper bound in case y-axis is not auto-scaled.
155         * @return The upper bound.
156         */
157        public Number getUpperBound() {
158          return this.upperBound;  
159        }
160    
161        /**
162         * Tests equality of two objects.
163         * @param o another object to be compared with this object.
164         * @return True if they are equal.
165         */
166        @Override
167        public boolean equals(Object o) {
168          if (o instanceof YAxis) {
169            YAxis y = (YAxis) o;
170            return this.label.equals(y.label) && this.integerAxis == y.integerAxis
171                && this.lowerBound == y.lowerBound && this.upperBound == y.upperBound;
172          }
173          return false;
174        }
175    
176        /**
177         * Computes hash code.
178         * @return The hash code.
179         */
180        @Override
181        public int hashCode() {
182          return this.label.hashCode();
183        }
184    
185      }
186    }