001: package com.calipso.reportgenerator.common;
002:
003: import com.calipso.reportgenerator.reportdefinitions.MetricSourceDefinition;
004: import com.calipso.reportgenerator.reportdefinitions.MetricDefinition;
005: import com.calipso.reportgenerator.reportdefinitions.types.CalculationType;
006: import com.calipso.reportgenerator.reportcalculator.arithmetic.ArithmeticExpression;
007: import com.calipso.reportgenerator.reportcalculator.SharedString;
008: import com.calipso.reportgenerator.reportcalculator.SharedFloat;
009: import com.calipso.reportgenerator.common.LanguageTraslator;
010: import com.calipso.reportgenerator.common.ReportFieldSpec;
011:
012: import java.util.*;
013: import java.math.BigDecimal;
014:
015: /**
016: */
017: public class ReportMetricSpec extends ReportFieldSpec {
018:
019: private boolean visible;
020: private CalculationType aggregateType;
021: private String aggregateFunction;
022: private String groupFooterFunction;
023: private CalculationType groupFooterType;
024: private ArithmeticExpression arithmeticExpression;
025: private Map variableIndexes;
026: private boolean accumulable;
027: private boolean externalCalculated;
028:
029: /**
030: * Constructor de la super clase
031: * @param name
032: */
033: public ReportMetricSpec(String name) {
034: super (name);
035: }
036:
037: /**
038: * Inicializa los valores de los atributos a partir de un MeticSourceDefinition
039: * @param metricSourceDefinition
040: * @param isMultilanguaje
041: * @param localization
042: */
043: public void fillFrom(MetricSourceDefinition metricSourceDefinition,
044: boolean isMultilanguaje, Map localization) {
045: setCaption(resolveCaption(isMultilanguaje, localization,
046: metricSourceDefinition.getDescription()));
047: setCalculated(metricSourceDefinition.getCalculated());
048: setExternalData(metricSourceDefinition.getExternalData());
049: setAggregateFunction(metricSourceDefinition
050: .getAggregateFunction());
051: setAggregateType(metricSourceDefinition.getAggregateType());
052: setGroupFooterFunction(metricSourceDefinition
053: .getGroupFooterFunction());
054: setGroupFooterType(metricSourceDefinition.getGroupFooterType());
055: setExternalCalculated(metricSourceDefinition
056: .getExternalCalculated());
057: setInReportDefinition(true);
058: }
059:
060: /**
061: * Inicializa los valores de los atributos a partir de un MetricDefinition
062: * @param metricDefinition
063: * @param isMultilanguaje
064: * @param localization
065: */
066: public void fillFrom(MetricDefinition metricDefinition,
067: boolean isMultilanguaje, Map localization) {
068: if (metricDefinition.getDescription() != null
069: && !("").equals(metricDefinition.getDescription())) {
070: setCaption(resolveCaption(isMultilanguaje, localization,
071: metricDefinition.getDescription()));
072: }
073: setVisible(metricDefinition.getVisible());
074: setAccumulable(metricDefinition.getAccumulable());
075: }
076:
077: /**
078: * Devuelve verdadero si debe existir una métrica de valores acumulados segun los valores de esta métrica
079: * Se utiliza en los reportes del tipo acumulado.
080: * @return accumulable
081: */
082: public boolean getAccumulable() {
083: return accumulable;
084: }
085:
086: /**
087: * Especificaverdadero si debe existir una métrica de valores acumulados segun los valores de esta métrica
088: * @param accumulable
089: */
090: public void setAccumulable(boolean accumulable) {
091: this .accumulable = accumulable;
092: }
093:
094: /**
095: * Devuelve verdadero si esta métrica debe aparecer visible en la consulta por defecto
096: * @return visible
097: */
098: public boolean getVisible() {
099: return visible;
100: }
101:
102: /**
103: * Especifica si esta métrica debe aparecer visible en la consulta por defecto
104: * @param visible
105: */
106: public void setVisible(boolean visible) {
107: this .visible = visible;
108: }
109:
110: /**
111: * Devuelve la función de agregación (por defecto sumatoria)
112: * @return función de agregación
113: */
114: public String getAggregateFunction() {
115: return aggregateFunction;
116: }
117:
118: /**
119: * Asigna la función con la que se calculan los valores de las métricas calculadas
120: * @param aggregateFunction
121: */
122: public void setAggregateFunction(String aggregateFunction) {
123: this .aggregateFunction = aggregateFunction;
124: }
125:
126: /**
127: *
128: * @return aggregateType
129: */
130: public CalculationType getAggregateType() {
131: return aggregateType;
132: }
133:
134: public void setAggregateType(CalculationType aggregateType) {
135: this .aggregateType = aggregateType;
136: }
137:
138: public String getGroupFooterFunction() {
139: return groupFooterFunction;
140: }
141:
142: public void setGroupFooterFunction(String groupFooterFunction) {
143: this .groupFooterFunction = groupFooterFunction;
144: }
145:
146: public CalculationType getGroupFooterType() {
147: return groupFooterType;
148: }
149:
150: public void setGroupFooterType(CalculationType groupFooterType) {
151: this .groupFooterType = groupFooterType;
152: }
153:
154: /**
155: * Devuelve verdadero si el valor de esta métrica debe ser calculado por proveedor externo del IDataSource
156: * @return externalCalculated
157: */
158: public boolean getExternalCalculated() {
159: return externalCalculated;
160: }
161:
162: /**
163: * Especifica si el valor de esta métrica debe ser calculado por proveedor externo del IDataSource
164: * @param externalCalculated
165: */
166: private void setExternalCalculated(boolean externalCalculated) {
167: this .externalCalculated = externalCalculated;
168: }
169:
170: /**
171: * Devuelve la expresión aritmética en base a la que se deben calcular los valores de la métrica calculada
172: * @return expresión aritmética
173: */
174: protected ArithmeticExpression getExpression() {
175: if (arithmeticExpression == null) {
176: arithmeticExpression = ArithmeticExpression
177: .newFrom(getAggregateFunction());
178: variableIndexes = variableIndexesFrom(arithmeticExpression);
179: }
180: return arithmeticExpression;
181: }
182:
183: /**
184: * Contiene los indices de la/las métricas que intercienen en la expresión de cálculo
185: * @return indices
186: */
187: public Map getVariableIndexes() {
188: return variableIndexes;
189: }
190:
191: /**
192: * Resulve los indices de la/las métricas que intercienen en la expresión de cálculo
193: * @param arithmeticExpression
194: * @return indices
195: */
196: private Map variableIndexesFrom(
197: ArithmeticExpression arithmeticExpression) {
198: Collection variables = new ArrayList();
199: arithmeticExpression.getVariables(variables);
200: Iterator iterator = variables.iterator();
201: Map indexes = new HashMap();
202: while (iterator.hasNext()) {
203: String variable = (String) iterator.next();
204: indexes.put(variable, new Integer(
205: getDataSourceIndexFromName(variable)));
206: }
207: return indexes;
208: }
209:
210: /**
211: * Resuelve el valor de la métrica directamente del IDataSource en las métricas comunes y aplicando la expresion de cálculo
212: * en las métricas calculadas
213: * @param rowValues
214: * @return valor de la métrica
215: */
216: public Object getValue(Object[] rowValues) throws InfoException {
217: if (getCalculated()) {
218: Float aFloat = new Float(getExpression().value(
219: getContext(rowValues)));
220: if ((aFloat.equals(new Float(Float.NaN)))
221: || (aFloat
222: .equals(new Float(Float.POSITIVE_INFINITY)))
223: || (aFloat
224: .equals(new Float(Float.NEGATIVE_INFINITY)))) {
225: return null;
226: } else {
227: return SharedFloat.newFrom(aFloat);
228: }
229: } else {
230: return floatFrom(rowValues[getReportSourceIndex()]);
231: }
232: }
233:
234: public Float getValue(Map context) {
235: return new Float(getExpression().value(context));
236: }
237:
238: /**
239: * Devuelve el contexto con el que se evalúa la expresión del cálculo con los valores de un Row del IDataSource
240: * @param rowValues
241: * @return contexto
242: */
243: private Map getContext(Object[] rowValues) throws InfoException {
244: Map context = new HashMap();
245: fillContext(rowValues, context);
246: return context;
247: }
248:
249: /**
250: * Llena el contexto con el que se evalúa la expresión del cálculo con los valores de un Row del IDataSource
251: * @param values
252: * @param context
253: */
254: private void fillContext(Object[] values, Map context)
255: throws InfoException {
256: Set entries = getVariableIndexes().entrySet();
257: Iterator iterator = entries.iterator();
258: while (iterator.hasNext()) {
259: Map.Entry entry = (Map.Entry) iterator.next();
260: context.put(entry.getKey(),
261: floatFrom(values[((Integer) entry.getValue())
262: .intValue()]));
263: }
264: }
265:
266: /**
267: * devuelve un valor Float a partir del objeto obtenido del IDataSource
268: * @param value
269: * @return Float
270: */
271: private Object floatFrom(Object value) throws InfoException {
272: if (value instanceof Float) {
273: return SharedFloat.newFrom((Float) value);
274: } else if (value instanceof SharedFloat) {
275: return value;//new Float(((SharedFloat)value).floatValue());
276: } else if ((value instanceof String)
277: || (value instanceof SharedString)) {
278: String strValue = value.toString();
279: if (strValue.equalsIgnoreCase("")) {
280: strValue = "0";
281: }
282: return SharedFloat.newFrom(Float.valueOf(strValue.trim()));
283: } else if (value instanceof Integer) {
284: return SharedFloat.newFrom(Float.valueOf(value.toString()));
285: } else if (value instanceof Long) {
286: return SharedFloat.newFrom(Float.valueOf(value.toString()));
287: } else if (value instanceof BigDecimal) {
288: return SharedFloat.newFrom(((BigDecimal) value)
289: .floatValue());
290: } else if (value instanceof Double) {
291: return SharedFloat.newFrom(((Double) value).floatValue());
292: } else if (value instanceof java.sql.Date) {
293: return SharedFloat.newFrom(Float
294: .valueOf((value).toString()));
295: } else if (value == null) {
296: return null;
297: }
298:
299: throw new InfoException(LanguageTraslator.traslate("279"));
300: }
301: }
|