001    package org.hackystat.telemetry.analyzer.language.ast;
002    
003    import java.util.ArrayList;
004    import java.util.List;
005    
006    import org.hackystat.telemetry.analyzer.language.TelemetryLanguageException;
007    
008    /**
009     * Telemetry chart definition. A chart contains one or more telemetry streams.
010     * 
011     * @author (Cedric) Qin ZHANG
012     * @version $Id$
013     */
014    public class TelemetryChartDefinition extends TelemetryDefinition {
015    
016      private String title;
017      private String docString;
018      private Variable[] variables;
019      private List<SubChartDefinition> subChartDefinitions; 
020    
021      /**
022       * Constructs this instance.
023       * 
024       * @param name The name of the chart.
025       * @param docString The doc string of the chart. The chart title is extracted from the doc string.
026       * @param variables The variables used in the expression. Variables are essentially holding
027       *        places so that real value can be swapped in when the expression is evaluated.
028       *        Null is valid if there is no variable used in this definition.
029       * @param subChartDefinitions A list of <code>TelemetryChartDefinition.SubChartDefinition</code> 
030       *        objects, referring to the sub charts that should be contained in this chart.
031       * @param textPosition The text position of the definition string in the input.
032       * 
033       * @throws TelemetryLanguageException If the variable array contains duplicated variable 
034       *         declaration or does not declare all variables needed by the referred telemetry
035       *         streams.
036       */
037      public TelemetryChartDefinition(String name, String docString, Variable[] variables, 
038          List<SubChartDefinition> subChartDefinitions, TextPosition textPosition) 
039      throws TelemetryLanguageException {
040        
041        super(name, textPosition);
042        
043        this.docString = docString == null ? "" : docString;
044        int commaIndex = this.docString.indexOf('.');
045        this.title = commaIndex >= 0 ? this.docString.substring(0, commaIndex) : this.docString;
046        
047        this.variables = variables == null ? new Variable[0] : variables;
048        this.subChartDefinitions = subChartDefinitions == null ? 
049            new ArrayList<SubChartDefinition>() : subChartDefinitions;
050    
051        // check whether all variable has unique name or not.
052    //    TreeSet varNames = new TreeSet();
053    //    for (Iterator i = this.variables.iterator(); i.hasNext();) {
054    //      String varName = ((Variable) i.next()).getName();
055    //      if (varNames.contains(varName)) {
056    //        throw new Exception("Duplicated variable name declaration.");
057    //      }
058    //      else {
059    //        varNames.add(varName);
060    //      }
061    //    }
062    
063        // check whether all templates used in chartDefs are declared
064    //    for (Iterator i = this.streamsRefs.iterator(); i.hasNext();) {
065    //      NameReference ref = (NameReference) i.next();
066    //      for (Iterator j = ref.getParameters().iterator(); j.hasNext();) {
067    //        Object param = j.next();
068    //        if (param instanceof TemplatedParameter) {
069    //          if (!set.contains(param)) {
070    //            throw new Exception("Undeclared parameter '"
071    //                + ((TemplatedParameter) param).getTemplateName() + "' used.");
072    //          }
073    //        }
074    //      }
075    //    }
076      }
077      
078      /**
079       * Gets the title of the chart.
080       * 
081       * @return The chart title.
082       */
083      public String getTitle() {
084        return this.title;
085      }
086      
087      /**
088       * Gets the doc string for the chart.
089       * 
090       * @return The doc string.
091       */
092      public String getDocString() {
093        return this.docString;
094      }
095    
096      /**
097       * Gets an array of variables used in the definition.
098       * 
099       * @return An array of <code>Variable</code> objects. If there is no variable used,
100       *         then an empty array is returned.
101       */
102      public Variable[] getVariables() {
103        return this.variables;
104      }
105    
106      /**
107       * Gets all sub-charts in this chart.
108       * 
109       * @return A list of <code>TelemetryChartDefinition.SubChartDefinition</code> objects.
110       */
111      public List<SubChartDefinition> getSubCharts() {
112        return this.subChartDefinitions;
113      }
114      
115      /**
116       * Sub-chart definition. A telemetry chart can contain one or more sub-charts, with each sub-chart
117       * having its own axis.
118       *  
119       * @author (Cedric) Qin ZHANG
120       * @version $Id$
121       */
122      public static class SubChartDefinition {
123        private StreamsReference streamsReference;
124        private YAxisReference yAxsisReference;
125        
126        /**
127         * Constructs this instance.
128         * @param streamsReference A reference to streams definition.
129         * @param yAxisReference A reference to y-axis definition.
130         */
131        public SubChartDefinition(StreamsReference streamsReference, YAxisReference yAxisReference) {
132          this.streamsReference = streamsReference;
133          this.yAxsisReference = yAxisReference;
134        }
135        
136        /**
137         * Gets the reference to streams definition.
138         * @return The reference to streams definition.
139         */
140        public StreamsReference getStreamsReference() {
141          return this.streamsReference;
142        }
143        
144        /**
145         * Gets the reference to y-axis definition.
146         * @return The reference to y-axis definition.
147         */
148        public YAxisReference getYAxisReference() {
149          return this.yAxsisReference;
150        }
151      }
152    }