package com.idega.block.dataquery.data;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import net.sf.jasperreports.engine.JRDataSource;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JRField;
import com.idega.util.datastructures.SortedHashMatrix;
import com.idega.xml.XMLDocument;
import com.idega.xml.XMLElement;
/**
* <p>Title: idegaWeb</p>
* <p>Description: </p>
* <p>Copyright: Copyright (c) 2003</p>
* <p>Company: idega Software</p>
* @author <a href="thomas@idega.is">Thomas Hilbig</a>
* @version 1.0
* Created on May 27, 2003
*/
public class QueryResult implements JRDataSource {
private static final String QUERY_RESULT = "queryResult";
private static final String DEFINITION = "definition";
private static final String CONTENT = "content";
private static final String DEFAULT_VALUE = "[not found]";
private List fieldOrder = new ArrayList();
private Map fields = new HashMap();
private Map designIdFieldIdMapping = null;
private SortedHashMatrix cells = new SortedHashMatrix();
private Iterator cellIterator = null;
private String currentCellId = null;
private int currentRowNumber = 0;
private int desiredNumberOfRows = -1;
public static QueryResult getInstanceForDocument(XMLDocument document) {
QueryResult instance = new QueryResult();
XMLElement root = document.getRootElement();
// definition
XMLElement definition = root.getChild(DEFINITION);
List fields = QueryResultField.getInstancesForELement(definition);
Iterator fieldIterator = fields.iterator();
while (fieldIterator.hasNext()) {
QueryResultField field = (QueryResultField) fieldIterator.next();
if (field != null) {
instance.addField(field);
}
}
// content
XMLElement content = root.getChild(CONTENT);
List cells = QueryResultCell.getInstancesForELement(content);
Iterator cellIterator = cells.iterator();
while (cellIterator.hasNext()) {
QueryResultCell cell = (QueryResultCell) cellIterator.next();
if (cell != null) {
instance.addCell(cell.getId(), cell.getFieldId(), cell.getValue());
}
}
return instance;
}
public void addField(QueryResultField field) {
String id = field.getId();
this.fields.put(id, field);
// store the order of the fields
if (this.fieldOrder.contains(id)) {
this.fieldOrder.remove(id);
}
this.fieldOrder.add(id);
}
public void addCell(Object id, Object fieldId, Object cellValue) {
this.cells.put(id,fieldId, cellValue);
}
public QueryResultField getField(String id) {
return (QueryResultField) this.fields.get(id);
}
public QueryResultField getFieldByOrderNumber(int orderNumber) {
orderNumber--;
if (orderNumber < 0 || orderNumber >= this.fieldOrder.size()) {
return null;
}
String id = (String) this.fieldOrder.get(orderNumber);
return getField(id);
}
// public String getCell(String id, String fieldId) {
// return (String) cells.get(id, fieldId);
// }
public XMLElement convertToXML() {
XMLElement queryResult = new XMLElement(QUERY_RESULT);
XMLElement definition = new XMLElement(DEFINITION);
XMLElement content = new XMLElement(CONTENT);
Iterator fieldsIterator = this.fieldOrder.iterator();
while (fieldsIterator.hasNext()) {
// store the order of the fields
String id = (String) fieldsIterator.next();
QueryResultField field = (QueryResultField) this.fields.get(id);
XMLElement fieldElement = field.convertToXML();
definition.addContent(fieldElement);
}
Iterator xKeyIterator = this.cells.firstKeySet().iterator();
while (xKeyIterator.hasNext()) {
Object xKey = xKeyIterator.next();
Map yDimension = this.cells.get(xKey);
Iterator yKeyIterator = yDimension.keySet().iterator();
while (yKeyIterator.hasNext()) {
Object yKey = yKeyIterator.next();
Object cellValue = yDimension.get(yKey);
QueryResultCell cell = new QueryResultCell(xKey.toString(), yKey.toString(), cellValue);
XMLElement cellElement = cell.convertToXML();
content.addContent(cellElement);
}
}
queryResult.addContent(definition);
queryResult.addContent(content);
return queryResult;
}
public void mapDesignIdToFieldId(String designId, String fieldId) {
if (this.designIdFieldIdMapping == null) {
this.designIdFieldIdMapping = new HashMap();
}
this.designIdFieldIdMapping.put(designId, fieldId);
}
/** Returns true if there aren't any results stored.
* Even if a QueryResult is empty you can use it as a JRDataSource,
* that is an empty QueryResult causes no errors.
*
* @return true if there aren't any results stored.
*/
public boolean isEmpty() {
return this.cells.isEmpty();
}
public int getNumberOfRows() {
int realNumber = this.cells.sizeOfFirstKeySet();
return (realNumber < this.desiredNumberOfRows || this.desiredNumberOfRows == -1) ? realNumber : this.desiredNumberOfRows;
}
/** @see net.sf.jasperreports.engine.JRDataSource#next()
*
*/
public boolean next() throws JRException {
// the very first time we have to initialize the iterator
if (this.cellIterator == null) {
this.currentRowNumber = 0;
this.cellIterator = this.cells.firstKeySet().iterator();
}
// now ask the iterator
if (this.cellIterator.hasNext()) {
// compare with the behaviour of a result set...
this.currentCellId = (String) this.cellIterator.next();
this.currentRowNumber++;
if (this.currentRowNumber <= this.desiredNumberOfRows || this.desiredNumberOfRows == -1) {
return true;
}
}
return false;
}
public void resetDataSource() {
this.cellIterator = null;
this.currentCellId = null;
this.currentRowNumber = 0;
}
/**
* @see net.sf.jasperreports.engine.JRDataSource#next()
*
*/
public Object getFieldValue(JRField jrField) throws JRException {
String fieldId = jrField.getName();
// if mapping is required use the map
if (this.designIdFieldIdMapping != null) {
// if there is an entry use this one
String id = (String) this.designIdFieldIdMapping.get(fieldId);
if (id != null) {
fieldId = id;
}
}
// fetch the cellValue
Object cellValue = this.cells.get(this.currentCellId, fieldId);
// return the value of the cell
return (cellValue == null ) ? "" : cellValue.toString();
}
public void setDesiredNumberOfRows(int desiredNumberOfRows) {
this.desiredNumberOfRows = desiredNumberOfRows;
}
}