001: package com.calipso.reportgenerator.reportmanager;
002:
003: import com.calipso.reportgenerator.reportdefinitions.types.DataSourceDefinitionSourceTypeType;
004: import com.calipso.reportgenerator.reportcalculator.*;
005: import com.calipso.reportgenerator.common.*;
006: import com.calipso.reportgenerator.services.DataSourceDefinitionConnectionString;
007: import com.calipso.common.DateEx;
008:
009: import java.util.*;
010: import java.text.DateFormat;
011: import java.text.SimpleDateFormat;
012: import java.io.Serializable;
013:
014: import com.calipso.reportgenerator.reportcalculator.IDataSource;
015: import com.calipso.reportgenerator.common.InfoException;
016:
017: /**
018: * Esta clase se crea a partir de un ReportSourceDefinition y es la
019: * responsable de aplicar los filtros necesarios a partir de un
020: * ReportDataSource, también tiene la responsabilidad de componer la
021: * query, cargar el Pivot y ejecutar el cálculo.
022: */
023:
024: public class ReportSource implements Serializable {
025:
026: private Matrix matrix;
027: private List filterDefinitions;
028: private Date lastExecution;
029: private Map paramValues;
030: private ReportGeneratorConfiguration reportGeneratorConfiguration;
031: private ReportSpec reportSpec;
032:
033: /**
034: * Inicializa una instancia a partir de su definición (ReportSpec)
035:
036: * @param reportSpec
037: * @param reportGeneratorConfiguration
038: * @param init
039: * @throws InfoException
040: */
041:
042: private ReportSource(ReportSpec reportSpec,
043: ReportGeneratorConfiguration reportGeneratorConfiguration,
044: boolean init) throws InfoException {
045: if ((reportSpec == null)
046: || (reportGeneratorConfiguration == null)) {
047: throw new InfoException(LanguageTraslator.traslate("42"));
048: } else {
049: this .reportSpec = reportSpec;
050: this .reportGeneratorConfiguration = reportGeneratorConfiguration;
051: this .lastExecution = null;
052: this .paramValues = null;
053: if (init) {
054: initializeContents();
055: }
056: }
057: }
058:
059: /**
060: * Inicializa una instancia a partir de un ReportSpec
061: * @param reportSpec
062: * @param reportGeneratorConfiguration
063: * @throws InfoException
064: */
065:
066: public ReportSource(ReportSpec reportSpec,
067: ReportGeneratorConfiguration reportGeneratorConfiguration)
068: throws InfoException {
069: this (reportSpec, reportGeneratorConfiguration, true);
070: }
071:
072: /**
073: * Inicializa una instancia a partir de un ReportSpec, y la matriz con la
074: * información, en caso que haya sido pre-procesada.
075: * @param reportSpec
076: * @param matrix
077: * @param reportGeneratorConfiguration
078: * @throws InfoException
079: */
080: public ReportSource(ReportSpec reportSpec, Matrix matrix,
081: ReportGeneratorConfiguration reportGeneratorConfiguration)
082: throws InfoException {
083: this (reportSpec, reportGeneratorConfiguration, false);
084: if (matrix == null) {
085: throw new InfoException(LanguageTraslator.traslate("43"));
086: } else {
087: this .matrix = matrix;
088: initializeContents();
089: }
090: }
091:
092: /**
093: * Inicializa una instancia a partir de un ReportSpec, y los valores de los pre-filtros, este constructor
094: * solo debe utilizarse para reportes no cacheados
095: * @param reportSpec
096: * @param paramValues
097: * @param reportGeneratorConfiguration
098: * @throws InfoException
099: */
100: public ReportSource(ReportSpec reportSpec, Map paramValues,
101: ReportGeneratorConfiguration reportGeneratorConfiguration)
102: throws InfoException {
103: this (reportSpec, reportGeneratorConfiguration, false);
104: this .paramValues = paramValues;
105: initializeContents();
106: }
107:
108: /**
109: * Inicializa una instancia a partir de un ReposrSourceDefinition, y la matriz con la
110: * información, en caso que haya sido pre-procesada y la fecha de última ejecución.
111: * Este constructor se utiliza para reportes incrementales.
112: * @param reportSpec
113: * @param matrix
114: * @param lastExecution
115: * @param reportGeneratorConfiguration
116: * @throws InfoException
117: */
118: public ReportSource(ReportSpec reportSpec, Matrix matrix,
119: Date lastExecution,
120: ReportGeneratorConfiguration reportGeneratorConfiguration)
121: throws InfoException {
122: this (reportSpec, reportGeneratorConfiguration, false);
123: this .matrix = matrix;
124: this .lastExecution = lastExecution;
125: initializeContents();
126: }
127:
128: /**
129: * Inicializa los contenidos
130: * En los cubos no cacheados, ejecuta todos los DataSources
131: * En el caso de los cacheados, ejecutalos DataSources solo cuando el reporte no fue pre-procesado o cuando ya no está
132: * vigente.
133: * En el caso de los incrementales, siempre ejecuta los DataSource con un filtro compuesto a partir del valor de
134: * <code>lastExecution</code>
135: * @throws InfoException Si se produce un error al llenar la matriz
136: */
137: private void initializeContents() throws InfoException {
138: fillFromSources(matrix);
139: }
140:
141: /**
142: * Devuelve la matriz de datos resultante de la ejecución de los DataSources. Es una matriz de dos dimensiones que se
143: * utilizará para obtener los distintos reportes.
144: * @return la matriz
145: */
146: public Matrix getMatrix() {
147: return matrix;
148: }
149:
150: /**
151: * Sirve para inicializar la matriz con valores pre-procesados
152: * @param matrix
153: */
154:
155: public void setMatrix(Matrix matrix) {
156: this .matrix = matrix;
157: }
158:
159: /**
160: * Devuelve un objeto capaz de resolver un origen de datos, en este método se devuelve el objeto apropiado según el
161: * tipo de origen de datos (XML, OQL, etc).
162: * @param dataSourceSpec
163: * @return
164: * @throws InfoException
165: */
166: private ReportDataSource newReportDataSourceFrom(
167: ReportDataSourceSpec dataSourceSpec) throws InfoException {
168: try {
169: ReportDataSource reportDataSource;
170: switch (dataSourceSpec.getSourceType().getType()) {
171: case DataSourceDefinitionSourceTypeType.XML_TYPE:
172: ReportManagerLogger.debug(LanguageTraslator
173: .traslate("204"));
174: reportDataSource = new XmlReportDataSource(
175: getReportSpec(), dataSourceSpec,
176: getReportGeneratorConfiguration());
177: break;
178: case DataSourceDefinitionSourceTypeType.SQL_TYPE:
179: ReportManagerLogger.debug(LanguageTraslator
180: .traslate("202"));
181: reportDataSource = new SQLReportDataSource(
182: getReportSpec(), dataSourceSpec,
183: getReportGeneratorConfiguration(),
184: new DataSourceDefinitionConnectionString(
185: dataSourceSpec
186: .getExternalConnectionValues()));
187: break;
188: /* case DataSourceDefinitionSourceTypeType.CALC_TYPE: //todo revisar la implementacion
189: ReportManagerLogger.debug(LanguageTraslator.traslate("203"));
190: reportDataSource = new OOCalcReportDataSource(getReportSpec(), dataSourceSpec, getReportGeneratorConfiguration());
191: break;*/
192: case DataSourceDefinitionSourceTypeType.EXCEL_TYPE:
193: ReportManagerLogger.debug(LanguageTraslator
194: .traslate("317"));
195: reportDataSource = new ExcelReportDataSource(
196: getReportSpec(), dataSourceSpec,
197: getReportGeneratorConfiguration());
198: break;
199: default:
200: reportDataSource = null;
201: }
202: if (reportDataSource != null) {
203: reportDataSource.setFilter(getCubeFilter(
204: reportDataSource.getFilterVarMode(),
205: dataSourceSpec));
206: }
207: return reportDataSource;
208: } catch (Exception e) {
209: throw new InfoException(LanguageTraslator.traslate("44"), e);
210: }
211: }
212:
213: /**
214: * Ejecuta todos los orígenes de datos para llenar la lista de registros (<code>rows</code>)de la Matriz.
215: * @param matrix
216: * @throws InfoException
217: */
218: private void fillFromSources(Matrix matrix) throws InfoException {
219: ReportManagerLogger.debug(LanguageTraslator.traslate("201"));
220: if (matrix == null) {
221: matrix = DataSourceBuilder.buildMatrix(
222: getReportGeneratorConfiguration(), getReportSpec());
223: }
224: boolean incremental = !getReportSpec()
225: .getIncrementalDimension().equals("");
226: boolean cached = getReportSpec().getCached()
227: || getReportSpec().getDatawarehouseSaved();
228: boolean empty = /*matrix==null ||*/matrix.isEmpty();
229: if (incremental || !cached || empty) {
230: Iterator iterator = getReportSpec().getDataSourceSpecs()
231: .iterator();
232: while (iterator.hasNext()) {
233: if (/*matrix!=null &&*/isFull(matrix.size()))
234: return;
235: ReportDataSourceSpec dataSourceSpec = (ReportDataSourceSpec) iterator
236: .next();
237: ReportDataSource reportDataSource = newReportDataSourceFrom(dataSourceSpec);
238: System.out.println("Comienzo carga" + new Date());
239: /*IDataSource dataSource = */reportDataSource
240: .getDataSource(matrix);
241: System.out.println("Fin carga" + new Date());
242: /*Matrix sourceMatrix = getMatrix(dataSource);
243: if(sourceMatrix!=null){
244: //Si se puede obtener una matrix del data source se la utiliza
245: matrix = fillMatrix(matrix, sourceMatrix);
246: }else{
247: //Sino, se construye una matrix para llenar
248: if(matrix == null){
249: matrix = DataSourceBuilder.buildMatrix(getReportGeneratorConfiguration(), getReportSpec());
250: }
251: fillRows(dataSource, matrix, dataSourceSpec);
252: }*/
253: }
254: }
255: this .matrix = matrix;
256: }
257:
258: /*private Matrix getMatrix(IDataSource dataSource) {
259: if(dataSource instanceof Matrix){
260: return (Matrix)dataSource;
261: }
262: return null;
263: }
264:
265: private Matrix fillMatrix(Matrix matrix, Matrix sourceMatrix) throws InfoException{
266: if(matrix==null){
267: matrix = sourceMatrix;
268: }else{
269: matrix.addAll(sourceMatrix);
270: }
271: return matrix;
272: }*/
273:
274: /**
275: * Ejecuta un origen de datos y agrega las filas que da como resultado a la lista de filas de la Matriz.
276: * @param dataSource
277: * @param matrix
278: * @throws InfoException
279: */
280: private void fillRows(IDataSource dataSource, Matrix matrix,
281: ReportDataSourceSpec dataSourceSpec) throws InfoException {
282: int rowSize = getDimensionsCount() + getMetricsCount();
283: try {
284: if (dataSource != null) {
285: for (int i = 0; i < dataSource.getRowCount(); i++) {
286: if (isFull(matrix.size()))
287: return;
288: Object[] row = new Object[rowSize];
289: fillRow(row, dataSource, i, dataSourceSpec);
290: matrix.add(row);
291: }
292: }
293: } catch (Exception e) {
294: throw new InfoException(LanguageTraslator.traslate("45"), e);
295: }
296: }
297:
298: /**
299: * Determina si se ha alcanzado el número máximo de registros
300: * @param rowCount
301: * @return true si se alcanzo el número máximo de registros
302: */
303:
304: private boolean isFull(int rowCount) {
305: return getMaxRowCount() > 0 ? getMaxRowCount() <= rowCount
306: : false;
307: }
308:
309: /**
310: * Devuelve el número máximo de líneas a procesar, un valor menor o igual a 0 determina que un origen de reporte no
311: * tiene límite de registros.
312: * @return número máximo de líneas a procesar
313: */
314: private int getMaxRowCount() {
315: return getReportSpec().getSourceMaxRowCount();
316: }
317:
318: /**
319: * Devuelve una Dimensión a partir de su nombre
320: * @param name
321: * @return Dimensión
322: */
323: public ReportDimensionSpec getDimensionfromName(String name) {
324: return getReportSpec().getDimensionFromName(name);
325: }
326:
327: /**
328: * Devuelve una métrica a partir de su nombre
329: * @param name
330: * @return métrica
331: */
332: public ReportMetricSpec getMetricFromName(String name) {
333: return getReportSpec().getMetricFromName(name);
334: }
335:
336: /**
337: * Llena un registro de la <code>Matrix</code> a partir de un registro del <code>DataSource</code>
338: * @param row registro de la <code>Matrix</code> a llenar
339: * @param dataSource objeto que contiene los registros obtenidos de un origen de datos (<code>ReportDataSource</code>)
340: * @param index índice del registro del <code>DataSource</code> con el que se llenará el registro de la <code>Matrix</code>
341: * @param dataSourceSpec DataSourceSpec de donde se obtienen los datos
342: * @throws InfoException
343: */
344: private void fillRow(Object[] row, IDataSource dataSource,
345: int index, ReportDataSourceSpec dataSourceSpec)
346: throws InfoException {
347: try {
348: List dimensions = getReportSpec().getDimensionsByIndex();
349: Iterator dimensionsIter = dimensions.iterator();
350: while (dimensionsIter.hasNext()) {
351: ReportDimensionSpec dimensionSpec = (ReportDimensionSpec) dimensionsIter
352: .next();
353: row[dimensionSpec.getReportSourceIndex()] = dimensionSpec
354: .getValue(dataSource.getRowValues(index)
355: .toArray(), dataSourceSpec);
356: }
357:
358: List metrics = getReportSpec().getMetricsByIndex();
359: Iterator metricsIter = metrics.iterator();
360: while (metricsIter.hasNext()) {
361: ReportMetricSpec metricSpec = (ReportMetricSpec) metricsIter
362: .next();
363: row[metricSpec.getReportSourceIndex()] = metricSpec
364: .getValue(dataSource.getRowValues(index)
365: .toArray());
366: }
367: } catch (Exception e) {
368: throw new InfoException(LanguageTraslator.traslate("46"), e);
369: }
370: }
371:
372: /**
373: * Devuelve la cantidad de Dimensiones
374: * @return cantidad de Dimensiones
375: */
376:
377: private int getDimensionsCount() {
378: return getReportSpec().getDimensionSpecs().size();
379: }
380:
381: /**
382: * Devuelve la cantidad de Métricas
383: * @return cantidad de Métricas
384: */
385: private int getMetricsCount() {
386: return getReportSpec().getMetricSpecs().size();
387: }
388:
389: /**
390: * Crea los pre-filtros a partir de las <code>FilterDefinitions</code> del <code>ReportSourceDefinition</code>
391: * @param reportDataSourceSpec
392: * @return lista de pre-filtros
393: */
394: protected List getFilterDefinitions(
395: ReportDataSourceSpec reportDataSourceSpec) {
396: if (filterDefinitions == null) {
397: filterDefinitions = new ArrayList();
398:
399: ReportFilter incFilter = getIncrementalFilter(reportDataSourceSpec);
400: if (incFilter != null) {
401: filterDefinitions.add(incFilter);
402: }
403: ReportFilter maxRowsFilter = getMaxRowsFilter();
404: if (maxRowsFilter != null) {
405: filterDefinitions.add(maxRowsFilter);
406: }
407: Collection filterSpecs = getReportSpec()
408: .getPreFilterSpecs();
409: for (Iterator iterator = filterSpecs.iterator(); iterator
410: .hasNext();) {
411: ReportFilterSpec reportFilterSpec = (ReportFilterSpec) iterator
412: .next();
413: ReportFilter reportFilter = new ReportFilter(
414: reportFilterSpec);
415: filterDefinitions.add(reportFilter);
416: }
417: }
418: return filterDefinitions;
419: }
420:
421: public ReportSpec getReportSpec() {
422: return reportSpec;
423: }
424:
425: /**
426: * Crea un filtro del tipo "mayor que" tomando como parámetro la fecha de última ejecución y aplicado sobre
427: * la dimension <code>incrementalDimension</code>, este filtro es el que resuelve el cálculo incremental de reportes
428: * @return filtro
429: */
430: private ReportFilter getIncrementalFilter(
431: ReportDataSourceSpec reportDataSourceSpec) {
432: ReportFilter incFilter = null;
433: ReportFilterSpec incFilterSpec = getReportSpec()
434: .getIncrementalFilterSpec(getLastExecution());
435: if (incFilterSpec != null) {
436: incFilter = new ReportFilter(incFilterSpec);
437: getParamValues().put("INCREMENTALVALUE",
438: SharedDate.newFrom(new DateEx(getLastExecution())));//getDateString(getLastExecution(), reportDataSourceSpec));
439: }
440: return incFilter;
441: }
442:
443: private ReportFilter getMaxRowsFilter() {
444: ReportFilter maxRowsFilter = null;
445: ReportFilterSpec maxRowsFilterSpec = getReportSpec()
446: .getSourceMaxRowsFilterSpec();
447: if (maxRowsFilterSpec != null) {
448: maxRowsFilter = new ReportFilter(maxRowsFilterSpec);
449: }
450: return maxRowsFilter;
451: }
452:
453: /**
454: * Devuelve los valores de los parámetros de pre-filtros
455: * @return valores de parametros para los pre-filtros
456: */
457: private Map getParamValues() {
458: if (paramValues == null) {
459: paramValues = new HashMap();
460: }
461: return paramValues;
462: }
463:
464: /**
465: * Se utiliza para obtener el valor de la fecha para le filtro incremental
466: * @param date
467: * @return valor de fecha en prefiltro incremental
468: */
469: private String getDateString(Date date,
470: ReportDataSourceSpec reportDataSourceSpec) {
471: int dataType = getReportSpec().getDimensionFromName(
472: getReportSpec().getIncrementalDimension())
473: .getDataType().getType();
474: DateFormat dateFormat = new SimpleDateFormat(
475: reportDataSourceSpec.getPattern(dataType));
476: return dateFormat.format(date);
477: }
478:
479: /* Formato de la fecha,
480: * Nota: este método está resuelto de manera provisoria, esta información será leída de archivos de configuración
481: *
482: * @return
483:
484: public String getDatePattern() {
485: return getReportSpec().getDatePattern();
486: }*/
487:
488: /**
489: * Utiliza la información de los FilterDefinitions para construir un filtro que pueden utilizar los ReportDataSource
490: * @param mode
491: * @return ExpressionCubeFilter
492: */
493: protected ExpressionCubeFilter getCubeFilter(int mode,
494: ReportDataSourceSpec dataSourceSpec) throws InfoException {
495: ExpressionCubeFilter cubeFilter;
496: Map currentParamValues = new HashMap();
497: List filterDefs = getFilterDefinitions(dataSourceSpec);
498: currentParamValues = ReportFilterBuilder.mergeParamValues(
499: currentParamValues, getReportSpec()
500: .getParamValues(true));
501: currentParamValues = ReportFilterBuilder.mergeParamValues(
502: currentParamValues, getParamValues());
503: ReportFilterBuilder filterBuilder = new ReportFilterBuilder(
504: filterDefs, currentParamValues, mode);
505: cubeFilter = filterBuilder.getCubeFilter(getReportSpec(),
506: dataSourceSpec);
507: return cubeFilter;
508: }
509:
510: /**
511: * Devuelve la fecha de la última ejecución del reporte.
512: * @return fecha de la última ejecución del reporte
513: */
514: public Date getLastExecution() {
515: return lastExecution;
516: }
517:
518: /**
519: * Especifica la fecha del al última ejecución del reporte.
520: * @param lastExecution
521: */
522:
523: public void setLastExecution(Date lastExecution) {
524: this .lastExecution = lastExecution;
525: }
526:
527: /**
528: * Devuelve la configuración del report generator
529: * @return configuración del report generator
530: */
531: public ReportGeneratorConfiguration getReportGeneratorConfiguration() {
532: return reportGeneratorConfiguration;
533: }
534: }
|