001: package com.calipso.reportgenerator.reportmanager;
002:
003: import com.calipso.reportgenerator.common.*;
004: import com.calipso.reportgenerator.reportcalculator.*;
005: import com.calipso.reportgenerator.reportdefinitions.types.ReportDataType;
006: import com.calipso.common.DateEx;
007:
008: import java.io.File;
009: import java.io.InputStream;
010: import java.io.FileInputStream;
011: import java.util.List;
012: import java.util.ArrayList;
013:
014: import org.xml.sax.InputSource;
015: import org.w3c.dom.*;
016: import org.apache.poi.hssf.usermodel.HSSFCell;
017: import com.calipso.reportgenerator.reportcalculator.IDataSource;
018: import com.calipso.reportgenerator.common.InfoException;
019:
020: /**
021: * Resuelve la obtención de los datos desde un Xml y los devuelve en un objeto <code>IDataSource</code>
022: * Se encarga de obtener el Xml según el Url del DataSourceDefinition, parsear el texto Xml utilizando la información
023: * contenida en el ReportSourceDefinition, ejecutarle los pre-filtros y agregar los registros resultantes en el
024: * objeto <code>DataSource</code>.
025: */
026: public class XmlReportDataSource extends ReportDataSource {
027:
028: private String url;
029: private IDataSource dataSource;
030:
031: public XmlReportDataSource(ReportSpec reportSpec,
032: ReportDataSourceSpec dataSourceSpec,
033: ReportGeneratorConfiguration managerConfiguration) {
034: super (reportSpec, dataSourceSpec);
035: super .setGeneratorConfiguration(managerConfiguration);
036: }
037:
038: /**
039: * Método que inicializa el objeto. Asigna la dirección URL
040: */
041: protected void initialize() {
042: url = getReportDataSourceSpec().getExpression();
043: }
044:
045: /**
046: * Parsea el XML. Crea el Parser y lo instancia desde la dirección URL
047: */
048: private void loadFromXml(Matrix matrix) throws InfoException {
049: org.apache.xerces.parsers.DOMParser parser = new org.apache.xerces.parsers.DOMParser();
050: try {
051: File file = new File(url);
052: InputStream in = new FileInputStream(file);
053: InputSource source = new InputSource(in);
054: parser.parse(source);
055: } catch (Exception e) {
056: throw new InfoException(LanguageTraslator.traslate("100"),
057: e);
058: }
059: Document document = parser.getDocument();
060: loadXmlDocument(document, matrix);
061: }
062:
063: /**
064: * Busca el elemento raiz del XML y comienza a recorrer las filas
065: * @param document
066: */
067: private void loadXmlDocument(Document document, Matrix matrix)
068: throws InfoException {
069: Node rootNode = FindElement(document, "DataSource");
070: loadRowList(rootNode, matrix);
071: }
072:
073: /**
074: * Busca el nodo correspondiente a las filas y las recorre.
075: * @param node
076: */
077: private void loadRowList(Node node, Matrix matrix)
078: throws InfoException {
079: Node rowsNode = FindElement(node, "Rows");
080: if (rowsNode != null) {
081: loadRows(rowsNode, matrix);
082: }
083: }
084:
085: /**
086: * Recorre cada fila y llena una row y la agrega al datasource.
087: * @param node
088: */
089: private void loadRows(Node node, Matrix matrix)
090: throws InfoException {
091: try {
092: if (node != null) {
093: Node childNode;
094: NodeList children = node.getChildNodes();
095: if (children != null) {
096: for (int i = 0; i < children.getLength(); i++) {
097: childNode = children.item(i);
098: if (childNode.getNodeType() == Node.ELEMENT_NODE) {
099: NamedNodeMap attributes = childNode
100: .getAttributes();
101: Object[] row = getRow(attributes);
102: //int size = getReportSpec().getDataSourceIndexes().size();
103: try {
104: if ((getFilter() == null)
105: || ((getFilter() != null) && (getFilter()
106: .matches(row)))) {
107: matrix.add(row);
108: }
109: } catch (InfoException e) {
110: throw new InfoException(
111: LanguageTraslator
112: .traslate("101"), e);
113: }
114: }
115: }
116: }
117: }
118: } catch (OutOfMemoryError e) {
119: throw new InfoException(LanguageTraslator.traslate("326"),
120: e);
121: }
122: }
123:
124: private Object[] getRow(NamedNodeMap attributes)
125: throws InfoException {
126: int dimCount = getReportSpec().getDimensionsByIndex().size();
127: int colNum = dimCount
128: + getReportSpec().getMetricsByIndex().size();
129: Object[] collection = new Object[colNum];
130: //for(int i = row.getFirstCellNum() ; i < row.getLastCellNum() ; i++) {
131: for (int i = 0, j = 0; i < (colNum); i++) {
132: //HSSFCell cell = row.getCell((short)j);
133: if (i < dimCount) {
134: //Es dimension
135: ReportDimensionSpec dimension = getReportSpec()
136: .getDimensionFromIndex(i);
137: if (dimension.getCalculated()) {
138: collection[i] = dimension.getValue(collection,
139: getReportDataSourceSpec());
140: } else {
141: collection[i] = getValueForDimension(attributes
142: .item(j).getNodeValue(), dimension,
143: collection, i);
144: j++;
145: }
146: } else {
147: //Es metrica
148: ReportMetricSpec metric = getReportSpec()
149: .getMetricFromIndex(i - dimCount);
150: if (metric.getCalculated()) {
151: collection[i] = metric.getValue(collection);
152: } else {
153: collection[i] = getValueForMetric(attributes
154: .item(j).getNodeValue(), metric,
155: collection, i);
156: j++;
157: }
158: }
159: }
160: return collection;
161: }
162:
163: /*private void addNonCalculatedRow(List row, String nodeValue, int index, int dataType) throws InfoException{
164: switch(dataType){
165: case ReportDataType.DATETIME_TYPE:
166: row.add(index, SharedDate.newFrom(new DateEx(nodeValue, getReportDataSourceSpec().getDateTimePattern())));
167: break;
168: case ReportDataType.DATE_TYPE:
169: row.add(index, SharedDate.newFrom(new DateEx(nodeValue, getReportDataSourceSpec().getDatePattern())));
170: break;
171: case ReportDataType.STRING_TYPE:
172: row.add(index, SharedString.newFrom(nodeValue));
173: break;
174: case ReportDataType.FLOAT_TYPE:
175: row.add(index, SharedFloat.newFrom(new Float(nodeValue)));
176: break;
177: case ReportDataType.INTEGER_TYPE:
178: row.add(index, SharedInteger.newFrom(new Integer(nodeValue)));
179: break;
180: case ReportDataType.BOOLEAN_TYPE:
181: row.add(index, Boolean.valueOf(nodeValue));
182: }
183: }*/
184:
185: /**
186: * Busca un elemento en el xml por nombre a partir de un nodo
187: * @param node Nodo origen
188: * @param rootName nodo a buscar
189: * @return
190: */
191: private static Node FindElement(Node node, String rootName) {
192: Node resNode = null;
193:
194: if (node.getNodeName().compareTo(rootName) == 0) {
195: resNode = node;
196: }
197:
198: if (resNode == null) {
199: NodeList children = node.getChildNodes();
200: if (children != null) {
201: for (int i = 0; i < children.getLength(); i++) {
202: if (resNode == null) {
203: resNode = FindElement(children.item(i),
204: rootName);
205: }
206: }
207: }
208: }
209: return resNode;
210: }
211:
212: /**
213: * Crea el datasource y lo llena
214: * @return
215: * @throws InfoException
216: */
217: public IDataSource getDataSource(Matrix matrix)
218: throws InfoException {
219: //if (dataSource == null) {
220: //dataSource = newDataSource();
221: loadFromXml(matrix);
222: //}
223: return dataSource;
224: }
225:
226: /**
227: * Asigna el modo de uso de las variables
228: * @return
229: */
230: public int getFilterVarMode() {
231: return ReportFilterBuilder.VARMODE_DATAINDEX;
232: }
233:
234: }
|