001: package com.calipso.reportgenerator.reportmanager;
002:
003: import com.calipso.reportgenerator.reportcalculator.*;
004: import com.calipso.reportgenerator.reportdefinitions.types.*;
005: import com.calipso.reportgenerator.reportdefinitions.ReportView;
006: import com.calipso.reportgenerator.common.*;
007: import java.util.*;
008: import java.io.*;
009:
010: import com.calipso.reportgenerator.common.InfoException;
011:
012: /**
013: * Esta clase es la representación de un reporte que se ejecuta, se encarga de obtener los datos solicitados del origen,
014: * resolver los cálculos y devolver el resultado de acuerdo con la query ejecutada
015: */
016:
017: public abstract class Report implements Serializable {
018:
019: private ReportSource reportSource;
020: private Pivot pivot;
021: private ReportData reportData;
022: private ReportSpec reportSpec;
023: private ReportQuery query;
024: private ReportGeneratorConfiguration configuration;
025:
026: /**
027: * Constructor por defecto
028: */
029: public Report() {
030: }
031:
032: /** Inicializa una instancia de <code>Report</code> a partir de una Definición de Reporte y un origen de datos
033: *
034: //* @param reportDefinition
035: * @param reportSource
036: * @throws InfoException
037: */
038: public Report(ReportSpec reportSpec, ReportSource reportSource,
039: ReportGeneratorConfiguration configuration)
040: throws InfoException {
041: if ((reportSpec == null) || (reportSource == null)) {
042: throw new InfoException(LanguageTraslator.traslate("47"));
043: } else {
044: this .configuration = configuration;
045: this .reportSpec = reportSpec;
046: this .reportSource = reportSource;
047: pivot = buildPivot();
048: pivot.setMatrix(getReportSource().getMatrix());
049: }
050: }
051:
052: private Pivot buildPivot() throws InfoException {
053: try {
054: if (reportSource.getMatrix().getClass().getName().endsWith(
055: "DatawarehouseMatrix")) {
056: return (Pivot) Class
057: .forName(
058: "com.calipso.reportgenerator.reportcalculator.DatawarehousePivot")
059: .newInstance();
060: }
061: return new Pivot();
062: } catch (Exception e) {
063: throw new InfoException(LanguageTraslator.traslate("591"),
064: e);
065: }
066: }
067:
068: public ReportSpec getReportSpec() {
069: return reportSpec;
070: }
071:
072: /**
073: * Devuelve el Origen del Reporte
074: * @return devuelve el Origen del Reporte correspondiente
075: */
076: public ReportSource getReportSource() {
077: return reportSource;
078: }
079:
080: /**
081: * Devuelve el Pivot del Reporte, que se encarga de leer la información y llenar la estructura calculada
082: * <code>ReportData</code>
083: * @return
084: */
085:
086: protected Pivot getPivot() {
087: return pivot;
088: }
089:
090: /**
091: * Devuelve la estructura que contiene toda la información calculada a partir de una query
092: * @return
093: */
094: protected ReportData getReportData() {
095: return reportData;
096: }
097:
098: protected void setReportData(ReportData reportData) {
099: this .reportData = reportData;
100: }
101:
102: protected DataVectorBuilder getDataVectorBuilder(
103: DimensionValueNode rowsRoot, DimensionValueNode columnsRoot)
104: throws InfoException {
105: return new DataVectorBuilder(rowsRoot, columnsRoot,
106: getReportData().getQuery(), getReportData(),
107: getReportData().getQuery().isVisibleTotals());
108: }
109:
110: /**
111: * Ejecuta la consulta <code>ReportQuery</code> por defecto segun la información contenida en <code>ReportDefinition</code>
112: * @return
113: */
114:
115: public ReportResult ExecQuery(Map paramValues) throws InfoException {
116: return ExecQuery(getDefaultQuery(paramValues));
117: }
118:
119: public ReportGeneratorConfiguration getConfiguration() {
120: return configuration;
121: }
122:
123: /**
124: * Devuelve la consulta <code>ReportQuery</code> por defecto segun la información contenida en <code>ReportDefinition</code>
125: * @return
126: * @throws InfoException
127: */
128: protected ReportQuery getDefaultQuery() throws InfoException {
129: ReportQuery query = new ReportQuery(getReportSpec());
130: return query;
131: }
132:
133: /**
134: * Devuelve la consulta <code>ReportQuery</code> por defecto segun la información contenida en <code>ReportDefinition</code>
135: * agregándole los valores de parámetros recibidos.
136: * @return
137: * @throws InfoException
138: */
139: protected ReportQuery getDefaultQuery(Map paramValues)
140: throws InfoException {
141: ReportQuery query = new ReportQuery(getReportSpec());
142: query.setParamValues(paramValues);
143: return query;
144: }
145:
146: /**
147: * Devuelve la consulta <code>ReportQuery</code> por defecto segun la información contenida en <code>ReportDefinition</code>
148: * agregándole los valores de parámetros recibidos.
149: * @return
150: * @throws InfoException
151: */
152: protected ReportQuery getDefaultQuery(ReportView reportView)
153: throws InfoException {
154: return new ReportQuery(getReportSpec(), reportView);
155: }
156:
157: /**
158: * Devuelve una Consulta <code>ReportQuery</code> sin métricas visibles y sin dimensiones que agrupan.
159: * @return
160: * @throws InfoException
161: */
162: protected ReportQuery getQuery() throws InfoException {
163: if (query == null) {
164: query = new ReportQuery(getReportSpec(), false);
165: }
166: return query;
167: }
168:
169: protected void setReportQuery(ReportQuery query) {
170: this .query = query;
171: }
172:
173: /**
174: * Retorna un iterador a partir del nombre de una dimension
175: * @param name nombre de la dimension
176: * @return
177: */
178: public Set getDimensionValues(String name) throws InfoException {
179: try {
180: QueryDimension dimension = getQuery()
181: .getQueryDimensionFromName(name);
182: int index = dimension.getIndex();
183:
184: return getReportData().getDimensionValues(index);
185: } catch (Exception e) {
186: throw new InfoException(LanguageTraslator.traslate("89"), e);
187: }
188: }
189:
190: /**
191: * Devuelvel el xml generado para el cubo
192: * @return
193: * @throws InfoException
194: */
195: public abstract String getXml() throws InfoException;
196:
197: /**
198: * Ejecuta una consulta <code>ReportQuery</code> y devuelve un objeto <code>ReportResult</code> que contiene toda la
199: * información involucrada, tanto la que dió como resultado, como la query y los valores de los parámetros que lo
200: * determinaron/
201: * @return
202: * @throws InfoException
203: */
204: public abstract ReportResult ExecQuery(ReportQuery query)
205: throws InfoException;
206:
207: /**
208: * Rellena los valores que debe tener el filtro ranking. Para ello, setea una query que solo
209: * contiene la dimension especificada por el filtro y la metrica que utiliza dicha dimension para
210: * efectuar su ranking (en caso de no haber ninguna especificada ordenara segun lo correspondiente
211: * al tipo de la dimension). Luego ejecuta la query sobre el reporte, tomando todos los filtros
212: * menos los de ranking.
213: * Setea los mejores valores al filtro.
214: * @throws InfoException
215: */
216: protected void fillEnumeration(ReportQuery reportQuery)
217: throws InfoException {
218: //Obtiene los filtros ranking
219: Collection ranking = getFiltersByType(reportSpec,
220: FilterDefinitionFilterTypeType.RANKING);
221: Iterator iterator = ranking.iterator();
222: while (iterator.hasNext()) {
223: Set includes = new TreeSet();
224: //Construye una query por cada filtro ranking
225: ReportQuery query = new ReportQuery(reportQuery
226: .getReportSpec());
227: ReportFilterSpec filter = (ReportFilterSpec) iterator
228: .next();
229: ReportDimensionSpec dimension = reportQuery.getReportSpec()
230: .getDimensionFromName(filter.getDimensionName());
231: //Setea la query con la dimension y metrica correspondiente al filtro
232: query.setUniqueDimension(dimension);
233: query.setUniqueMetricVisible(dimension.getRankMetricName());
234: query.setDimensionRankMetricName(filter.getDimensionName(),
235: dimension.getRankMetricName());
236: //Remueve los filtros ranking del report spec (y por ende de la query)
237: query.removeFilters(ranking);
238: //Ejecuta la query
239: ReportResult result = ExecQuery(query);
240: Collection values = result.getValuesCollection(dimension
241: .getOrder() == DimensionDefinitionOrderType.A);
242: if (!values.isEmpty()) {
243: //Agrega al set los mejores valores
244: includes.addAll(getTopFor(reportQuery, values, filter));
245: }
246: //Vuelve a introducir los filtros ranking en el report spec (y la query)
247: query.addFilters(ranking);
248: //Le llena al filtro los valores a incluir para la dimension
249: reportQuery.getRankingFilter().addTo(includes,
250: dimension.getIndex());
251: }
252: }
253:
254: protected void fillExcludedEnumeration(ReportQuery reportQuery)
255: throws InfoException {
256: //Obtiene los filtros de tipo ExludeGroup
257: Collection exclude = getFiltersByType(reportSpec,
258: FilterDefinitionFilterTypeType.EXCLUDEGROUP);
259: Iterator iterator = exclude.iterator();
260: while (iterator.hasNext()) {
261: Set includes = new TreeSet();
262: //Construye una query por cada filtro ExludeGroup
263: ReportQuery query = new ReportQuery(reportQuery
264: .getReportSpec());
265: ReportFilterSpec filter = (ReportFilterSpec) iterator
266: .next();
267: ReportDimensionSpec dimension = reportQuery.getReportSpec()
268: .getDimensionFromName(filter.getDimensionName());
269: //Setea la query con la dimension y metrica correspondiente al filtro
270: query.setUniqueDimension(dimension);
271: query.setUniqueMetricVisible(dimension.getRankMetricName());
272: query.setDimensionRankMetricName(filter.getDimensionName(),
273: dimension.getRankMetricName());
274: //Remueve los filtros exclude del report spec (y por ende de la query)
275: query.removeFilters(exclude);
276: //Ejecuta la query
277: ReportResult result = ExecQuery(query);
278: //Agrega al set los valores validos segun la operacion definida
279: includes.addAll(getTopFor(result, reportQuery, filter));
280: Collection obligatory = getObligatoryValues(reportQuery,
281: filter);
282: addValues(includes, obligatory);
283: //Vuelve a introducir los filtros exclude en el report spec (y la query)
284: query.addFilters(exclude);
285: //Le llena al filtro los valores a incluir para la dimension
286: reportQuery.getExcludeGroupFilter().addTo(includes,
287: dimension.getIndex());
288: }
289: }
290:
291: private void addValues(Set includes, Collection obligatory) {
292: for (Iterator iterator = obligatory.iterator(); iterator
293: .hasNext();) {
294: Object value = iterator.next();
295: includes.add(value);
296: }
297: }
298:
299: private Collection getObligatoryValues(ReportQuery query,
300: ReportFilterSpec filter) throws InfoException {
301: Object param = FilterOperation.getParam(query, filter,
302: ParameterValueFilterParameterType.OBLIGATORYVALUE);
303: if (param == null) {
304: return new HashSet();
305: }
306: String values = param.toString();
307: ReportDimensionSpec dimension = query.getReportSpec()
308: .getDimensionFromName(filter.getDimensionName());
309: ReportDataSourceSpec dataSource = (ReportDataSourceSpec) query
310: .getReportSpec().getDataSourceSpecs().iterator().next();
311: try {
312: return filter.getValues(ReportFilterBuilder.VARMODE_INDEX,
313: dataSource, dimension, values);
314: } catch (Exception e) {
315: throw new InfoException("85", e);
316: }
317: }
318:
319: /**
320: * Toma los primeros valores de la coleccion. El tope esta especificado por el parametro
321: * correspondiente al filtro.
322: * @param values
323: * @param filter
324: * @return
325: */
326: private Collection getTopFor(ReportQuery reportQuery,
327: Collection values, ReportFilterSpec filter)
328: throws InfoException {
329: Collection result = new Vector();
330: int max;
331: Object o = reportQuery.getParamValues().get(
332: filter.getParamNames().get(0));
333: if (o instanceof SharedInteger) {
334: max = ((SharedInteger) o).intValue();
335: } else if (o instanceof SharedString) {
336: max = Integer.valueOf(((SharedString) o).value())
337: .intValue();
338: } else {
339: try {
340: max = new Integer(o.toString().trim()).intValue();
341: } catch (Exception e) {
342: throw new InfoException(e);
343: }
344: }
345: Iterator iter = values.iterator();
346: for (int i = 0; i < max && iter.hasNext(); i++) {
347: Object ob = iter.next();
348: if (ob instanceof DimensionValueNode) {
349: result.add(((DimensionValueNode) ob).getValue());
350: } else if (ob instanceof Map.Entry) {
351: result.add(((Map.Entry) ((Map.Entry) ob).getValue())
352: .getKey());
353: }
354: }
355: return result;
356: }
357:
358: /**
359: * Obtiene los valores a seleccionar de el resultado, segun la operacion que se realice
360: * @return
361: */
362: private Collection getTopFor(ReportResult reportResult,
363: ReportQuery reportQuery, ReportFilterSpec filter)
364: throws InfoException {
365: FilterOperation filterOperation = FilterOperation.newFrom(
366: reportResult, reportQuery, filter);
367: return filterOperation.operate(reportResult);
368: }
369:
370: /**
371: * Devuelve una coleccion con los filtros de tipo RANKING del report spec
372: * @return filtros tipo ranking
373: * @throws InfoException
374: */
375: public static Collection getFiltersByType(ReportSpec reportSpec,
376: FilterDefinitionFilterTypeType type) throws InfoException {
377: Collection result = new Vector();
378: Iterator iterator = reportSpec.getFilterSpecs().iterator();
379: while (iterator.hasNext()) {
380: ReportFilterSpec current = (ReportFilterSpec) iterator
381: .next();
382: if (current.getFilterType() == type) {
383: result.add(current);
384: }
385: }
386: return result;
387: }
388:
389: }
|