001 package org.hackystat.telemetry.analyzer.language.ast; 002 003 import org.hackystat.telemetry.analyzer.language.TelemetryLanguageException; 004 005 /** 006 * Y-axis information in telemetry chart definition. 007 * 008 * @author (Cedric) Qin Zhang 009 */ 010 public class TelemetryChartYAxisDefinition extends TelemetryDefinition { 011 012 /** Chart y-axis should have integer numbers. */ 013 public static final String NUMBER_TYPE_INTEGER = "integer"; 014 /** Chart y-axis should have double number. */ 015 public static final String NUMBER_TYPE_DOUBLE = "double"; 016 /** Chart y-axis have auto-determined number type, either integer or double. */ 017 public static final String NUMBER_TYPE_AUTO = "auto"; 018 019 private Variable[] variables; //List<Variable> 020 021 private Expression labelParameter; //Variable or StringConstant 022 private String numberType; 023 private boolean autoScaled; 024 private Number lowerBound, upperBound; 025 026 /** 027 * Constructs the y-axis definition. Y-axis can be either auto-scaled or fixed-scaled, 028 * depending on whether lower bound and upper bounds are supplied or not. 029 * 030 * @param name The name of this y-axis definition. 031 * @param variables The variables used in the definition. Variables are essentially holding 032 * places so that real value can be swapped in later. 033 * Null is valid if there is no variable used in this definition. 034 * @param labelParameter Either a <code>Variable</code> or a <code>StringConstant</code> for 035 * y-axis label. 036 * @param numberType The axis number type. Use one of the constants in this class. 037 * @param lowerBound Y-axis lower bound. Null is valid i 038 * @param upperBound Y-axis upper bound. 039 * @param textPosition The text position of the definition string in the input. 040 * 041 * @throws TelemetryLanguageException If y-axis number type is unsupported, 042 * or supplied lower and upper bounds are invalid. 043 */ 044 public TelemetryChartYAxisDefinition(String name, Variable[] variables, Expression labelParameter, 045 String numberType, Number lowerBound, Number upperBound, TextPosition textPosition) 046 throws TelemetryLanguageException { 047 super(name, textPosition); 048 this.variables = variables == null ? new Variable[0] : variables; 049 050 //check label parameter 051 if (labelParameter instanceof Variable || labelParameter instanceof StringConstant) { 052 this.labelParameter = labelParameter; 053 } 054 else { 055 throw new TelemetryLanguageException("labelParameter must be of type either Variable " + 056 "or StringConstant."); 057 } 058 059 //check number type 060 if (NUMBER_TYPE_INTEGER.equals(numberType) || NUMBER_TYPE_DOUBLE.equals(numberType) 061 || NUMBER_TYPE_AUTO.equals(numberType)) { 062 this.numberType = numberType; 063 } 064 else { 065 throw new TelemetryLanguageException("Y-Axis number type must be one of integer|double|auto"); 066 } 067 068 //check bounds 069 if (lowerBound == null && upperBound == null) { 070 this.autoScaled = true; 071 this.lowerBound = null; 072 this.upperBound = null; 073 } 074 else if (lowerBound != null && upperBound != null) { 075 if (NUMBER_TYPE_INTEGER.equals(numberType) && 076 ! (lowerBound instanceof Integer && upperBound instanceof Integer)) { 077 throw new TelemetryLanguageException("Upper and lower bound for integer y-axis must be" + 078 "integers."); 079 } 080 if (lowerBound.floatValue() >= upperBound.floatValue()) { 081 throw new TelemetryLanguageException( 082 "Y-Axis lower bound must be smaller than its upper bound."); 083 } 084 this.autoScaled = false; 085 this.lowerBound = lowerBound; 086 this.upperBound = upperBound; 087 } 088 else { 089 throw new TelemetryLanguageException("You must specify both lower and upper bounds, " + 090 "or none of them."); 091 } 092 } 093 094 /** 095 * Gets an array of variables used in the definition. 096 * 097 * @return An array of <code>Varaible</code> objects. If there is no variable used, 098 * then an empty array is returned. 099 */ 100 public Variable[] getVariables() { 101 return this.variables; 102 } 103 104 /** 105 * Gets the y-axis label. 106 * 107 * @return Either a <code>Variable</code> or a <code>StringConstant</code> for y-axis label. 108 */ 109 public Expression getLabelParameter() { 110 return this.labelParameter; 111 } 112 113 /** 114 * Gets the y-axis number type. The return value is one of the number type constant defined 115 * in this class. 116 * 117 * @return Y-axis number type. 118 */ 119 public String getNumberType() { 120 return this.numberType; 121 } 122 123 /** 124 * Determines whether the y-axis is auto-scales. 125 * 126 * @return True if y-axis is auto-scaled. 127 */ 128 public boolean isAutoScale() { 129 return this.autoScaled; 130 } 131 132 /** 133 * Gets the lower bound of the axis. 134 * 135 * @return The lower bound of the axis, or null if the axis is auto-scaled. 136 */ 137 public Number getLowerBound() { 138 return this.lowerBound; 139 } 140 141 /** 142 * Gets the upper bound of the axis. 143 * 144 * @return The upper bound of the axis, or null if the axis is auto-scaled. 145 */ 146 public Number getUpperBound() { 147 return this.upperBound; 148 } 149 }