001: package com.calipso.reportgenerator.reportmanager;
002:
003: import com.calipso.reportgenerator.common.InfoException;
004:
005: import java.io.StringWriter;
006: import java.io.IOException;
007: import java.util.Map;
008: import java.util.Iterator;
009:
010: import org.w3c.dom.Element;
011: import org.w3c.dom.Document;
012: import org.w3c.dom.Node;
013: import org.apache.xerces.dom.DocumentImpl;
014: import org.apache.xml.serialize.OutputFormat;
015: import org.apache.xml.serialize.XMLSerializer;
016: import com.calipso.reportgenerator.reportcalculator.DataTreeNode; //import com.calipso.reportgenerator.reportcalculator.CubeFloat;
017: import com.calipso.reportgenerator.reportcalculator.DataTreeSubItem;
018: import com.calipso.reportgenerator.reportcalculator.SharedFloat;
019: import com.calipso.reportgenerator.common.*;
020:
021: /**
022: * Esta clase se encarga de generar el XML de salida
023: * para un reporte de tipo estatico. Result.xml
024: */
025:
026: public class StaticReportXmlWriter implements ReportXmlWriter {
027: private ReportData reportData;
028: private ReportSpec reportSpec;
029: private Map paramValues;
030: private Document document;
031:
032: /**
033: * Inicializa una instancia de <code>StaticReportXmlWriter</code>
034: * @param reportData
035: * @param reportSpec
036: * @param paramValues
037: */
038: public StaticReportXmlWriter(ReportData reportData,
039: ReportSpec reportSpec, Map paramValues) {
040: this .reportData = reportData;
041: this .reportSpec = reportSpec;
042: this .paramValues = paramValues;
043: }
044:
045: /**
046: * Devuelve la instancia de <code>ReportData</code> asociado a la
047: * instancia de <code>StaticReportXmlWriter</code>
048: * @return
049: */
050: public ReportData getReportData() {
051: return reportData;
052: }
053:
054: /**
055: * Devuelve la instancia de <code>StaticReportData</code> asociado a la
056: * instancia de <code>StaticReportXmlWriter</code>
057: * @return
058: */
059: public StaticReportData getStaticReportData() {
060: return (StaticReportData) getReportData();
061: }
062:
063: /**
064: * Devuelve la instancia de <code>ReportSpec</code> asociado a la
065: * instancia de <code>StaticReportXmlWriter</code>
066: * @return
067: */
068: public ReportSpec getReportSpec() {
069: return reportSpec;
070: }
071:
072: /**
073: * Devuelve un conjunto de datos que representa
074: * los valores de los parametros
075: * @return
076: */
077: public Map getParamValues() {
078: return paramValues;
079: }
080:
081: /**
082: * Crea un nuevo documento para comenzar la escritura a XML.
083: */
084: private void startDocument() {
085: document = new DocumentImpl();
086: }
087:
088: /*private Element createRoot() {
089: Element root;
090: root = createElement("Result");
091: document.appendChild(root);
092: String reportDefName = getReportSpec().getDescription();
093: root.setAttribute("ReportRefinition", reportDefName);
094: return root;
095: } */
096:
097: /**
098: * Genera el arbol que representa el XML de salida.
099: * @return
100: * @throws InfoException
101: */
102: public StringWriter getXml() throws InfoException {
103: try {
104: //Element repElem, root;
105: startDocument();
106: //root = createRoot();
107: DataTreeNode dataTreeNode = getStaticReportData()
108: .getDataTree().getRoot();
109: dataTreeNode.setValue(getReportSpec().getDescription());
110: generateNode(dataTreeNode, document);
111: return getStream();
112: } catch (Exception e) {
113: throw new InfoException(LanguageTraslator.traslate("99"));
114: }
115: }
116:
117: /**
118: * Genera un nodo XML a partir de un <code>DataTreeNode</code>.
119: * @param dataTreeNode
120: * @param parent
121: */
122: private void generateNode(DataTreeNode dataTreeNode, Node parent) {
123: Node element = createNodeElement(getTagName(dataTreeNode
124: .getDimensionIndex()), dataTreeNode.getValue());
125: parent.appendChild(element);
126: fillMetrics(dataTreeNode, element);
127: fillSubItems(dataTreeNode, element);
128: fillSubNodes(dataTreeNode, element);
129: }
130:
131: /**
132: * Obtiene la descripcion a mostrar para un nodo del XML a partir
133: * de un indice.
134: * @param dimensionIndex
135: * @return
136: */
137: private String getTagName(int dimensionIndex) {
138: if (dimensionIndex >= 0) {
139: return ((ReportDimensionSpec) reportSpec
140: .getDimensionsByIndex().get(dimensionIndex))
141: .getName();
142: } else {
143: return "Report";
144: }
145: }
146:
147: /**
148: * Genera nodos hijos en base a un nodo padre siempre que el diccionario
149: * de hijos que tiene el padre tenga informacion.
150: * @param dataTreeNode
151: * @param parent
152: */
153: private void fillSubNodes(DataTreeNode dataTreeNode, Node parent) {
154: Iterator iterator = dataTreeNode.getSubNodes().values()
155: .iterator();
156: while (iterator.hasNext()) {
157: DataTreeNode current = (DataTreeNode) iterator.next();
158: generateNode(current, parent);
159: }
160: }
161:
162: /**
163: * Genera los nodos para un nodo del XML siempre y cuando
164: * la lista subItems del nodo contenga informacion.
165: * @param dataTreeNode
166: * @param element
167: */
168: private void fillSubItems(DataTreeNode dataTreeNode, Node element) {
169: int[] dims = getStaticReportData().getDataTree().getQuery()
170: .getNoGroupDimensions();
171: int[] mets = getStaticReportData().getDataTree().getQuery()
172: .getMetrics();
173: int[] accmets = getStaticReportData().getDataTree().getQuery()
174: .getAccumulableMetrics();
175:
176: for (int i = 0; i < dataTreeNode.getSubItems().size(); i++) {
177: DataTreeSubItem subItem = (DataTreeSubItem) dataTreeNode
178: .getSubItems().get(i);
179: Element item = createNodeElement("Item", String.valueOf(i));
180: element.appendChild(item);
181: for (int j = 0; j < dims.length; j++) {
182: int dim = dims[j];
183: String value = subItem.getNonGroupingDimensionValues()[j];
184: if (value != null && !value.equals("")) {
185: item.setAttribute(getTagName(dim), value);
186: }
187: }
188: for (int j = 0; j < mets.length; j++) {
189: SharedFloat value = subItem.getMetricValues()[j];
190: item.setAttribute(getMetricNameFromIndex(j), value
191: .toString());
192: }
193:
194: for (int j = 0; j < accmets.length; j++) {
195: SharedFloat value = subItem
196: .getAccumulableMetricValues()[j];
197: item.setAttribute(getMetricNameFromIndex(subItem
198: .getMetricIndex(j))
199: + "_ACC", value.toString());
200: }
201:
202: }
203: }
204:
205: /*private void fillNoGroupingValues(DataTreeNode dataTreeNode, Node element) {
206: int[] dims = getStaticReportData().getDataTree().getQuery().getNoGroupDimensions();
207: int[] mets = getStaticReportData().getDataTree().getQuery().getMetrics();
208: for (int i = 0; i < dataTreeNode.getSubItems().size(); i++) {
209: DataTreeSubItem subItem = (DataTreeSubItem) dataTreeNode.getSubItems().get(i);
210: Element item = createNodeElement("Item", "");
211: element.appendChild(item);
212: for (int j = 0; j < dims.length; j++) {
213: int dim = dims[j];
214: String value = subItem.getNonGroupingDimensionValues()[j];
215: if (value != null && !value.equals("")) {
216: item.setAttribute(getTagName(dim), value);
217: }
218: }
219: for (int j = 0; j < mets.length; j++) {
220: int met = mets[j];
221: CubeFloat value = subItem.getMetricValues()[j];
222: item.setAttribute(getMetricNameFromIndex(met), value.toString());
223: }
224: }
225: } */
226:
227: /**
228: * Genera los atributos para un nodo del XML siempre y cuando
229: * la lista subItems del nodo contenga informacion.
230: * @param dataTreeNode
231: * @param element
232: */
233: private void fillMetrics(DataTreeNode dataTreeNode, Node element) {
234: //int[] mets = getStaticReportData().getDataTree().getQuery().getMetrics();
235: Object[] metrics = dataTreeNode.getMetrics();
236: for (int i = 0; i < metrics.length; i++) {
237: SharedFloat metric = (SharedFloat) metrics[i];
238: ((Element) element).setAttribute(getMetricNameFromIndex(i),
239: metric.toString());
240: }
241:
242: //int[] accmets = getStaticReportData().getDataTree().getQuery().getAccumulableMetrics();
243: /*Object[] accmetrics = dataTreeNode.getAccumulableMetrics();
244: for (int i = 0; i < accmetrics.length; i++) {
245: CubeFloat accmetric = (CubeFloat) accmetrics[i];
246: ((Element) element).setAttribute(getMetricNameFromIndex(i), accmetric.toString());
247: } */
248:
249: }
250:
251: /**
252: * Devuelve el nombre de una metrica a partir de un indice.
253: * @param metricIndex
254: * @return
255: */
256: private String getMetricNameFromIndex(int metricIndex) {
257:
258: return ((ReportMetricSpec) reportSpec.getMetricsByIndex().get(
259: metricIndex)).getName();
260: // return ((QueryMetric) reportData.getQuery().getMetrics().get(metric)).getName();
261: }
262:
263: /**
264: * Serializa a disco el archivo XML de salida.
265: * @return
266: * @throws IOException
267: */
268: private StringWriter getStream() throws IOException {
269: OutputFormat format = new OutputFormat(document, "ISO-8859-1",
270: true);
271: StringWriter stringOut = new StringWriter();
272: XMLSerializer serial = new XMLSerializer(stringOut, format);
273: serial.asDOMSerializer();
274: Element elem = document.getDocumentElement();
275: if (elem != null) {
276: serial.serialize(elem);
277: }
278: return stringOut;
279: }
280:
281: /**
282: * Crea y retorna un nodo con las descripciones pasadas por parametro.
283: * @param tagName
284: * @param value
285: * @return
286: */
287: private Element createNodeElement(String tagName, String value) {
288: Element newElem;
289: newElem = document.createElement(tagName);
290: newElem.setAttribute("Value", value);
291: return newElem;
292: }
293:
294: }
|