diff --git a/src/org/olap4j/driver/xmla/XmlaOlap4jCellSet.java b/src/org/olap4j/driver/xmla/XmlaOlap4jCellSet.java index 0061f1e..9bd800a 100644 --- a/src/org/olap4j/driver/xmla/XmlaOlap4jCellSet.java +++ b/src/org/olap4j/driver/xmla/XmlaOlap4jCellSet.java @@ -35,7 +35,9 @@ * @version $Id$ * @since May 24, 2007 */ -abstract class XmlaOlap4jCellSet implements CellSet { +abstract class XmlaOlap4jCellSet implements CellSet +{ + final XmlaOlap4jStatement olap4jStatement; protected boolean closed; private XmlaOlap4jCellSetMetaData metaData; @@ -270,10 +272,13 @@ void populate() throws OlapException { propertyValues.clear(); final int cellOrdinal = Integer.valueOf(cell.getAttribute("CellOrdinal")); - // todo: convert to type based on attribute - final String value = stringElement(cell, "Value"); + + // Get the value casted correctly. + final Object value = this.getTypedValue(cell); + final String formattedValue = stringElement(cell, "FmtValue"); final String formatString = stringElement(cell, "FormatString"); + Olap4jUtil.discard(formatString); for (Element element : childElements(cell)) { String tag = element.getLocalName(); @@ -294,7 +299,67 @@ void populate() throws OlapException { } } + + + /** + * + *

The value type has to conform to XSD definitions of + * the XML element. See http://books.xmlschemata.org/relaxng/relax-CHP-19.html + * for a full list of possible data types. + * + *

Not all types are supported for now. Those not supported fall back + * to Strings. Most numeric types are. No dates yet are supported. + * + *

If any exception is encountered, it returns null. + * + * @param cell The cell of which we want the casted object. + * @return The object with a correct value. + */ + private Object getTypedValue(Element cell) + { + try + { + Element elm = findChild(cell, MDDATASET_NS, "Value"); + + // The object type is contained in xsi:type attribute. + String type = elm.getAttribute("xsi:type"); + + if ( type.equals( "xsd:int" ) ) + return XmlaOlap4jUtil.intElement(cell, "Value"); + + else if ( type.equals( "xsd:integer" ) ) + return XmlaOlap4jUtil.integerElement(cell, "Value"); + + else if ( type.equals( "xsd:double" ) ) + return XmlaOlap4jUtil.doubleElement(cell, "Value"); + + else if ( type.equals( "xsd:float" ) ) + return XmlaOlap4jUtil.floatElement(cell, "Value"); + + else if ( type.equals( "xsd:long" ) ) + return XmlaOlap4jUtil.longElement(cell, "Value"); + + else if ( type.equals( "xsd:boolean" ) ) + return XmlaOlap4jUtil.booleanElement(cell, "Value"); + + else + return XmlaOlap4jUtil.stringElement(cell, "Value"); + } + + catch (Exception e) + { + System.out.println(e.getMessage()); + e.printStackTrace(); + return null; + } + } + + + + + + /** * Creates metadata for a cell set, given the DOM of the XMLA result. * * @param root Root node of XMLA result diff --git a/src/org/olap4j/driver/xmla/XmlaOlap4jUtil.java b/src/org/olap4j/driver/xmla/XmlaOlap4jUtil.java index b9ef511..ab3ba86 100644 --- a/src/org/olap4j/driver/xmla/XmlaOlap4jUtil.java +++ b/src/org/olap4j/driver/xmla/XmlaOlap4jUtil.java @@ -169,6 +169,10 @@ static Element findChild(Element element, String ns, String tag) { return null; } + + + + static String stringElement(Element row, String name) { final NodeList childNodes = row.getChildNodes(); for (int i = 0; i < childNodes.getLength(); i++) { @@ -180,16 +184,38 @@ static String stringElement(Element row, String name) { return null; } - static int integerElement(Element row, String name) { - final String value = stringElement(row, name); - return Integer.valueOf(value); + static Integer integerElement(Element row, String name) + { + return Integer.valueOf( stringElement(row, name) ); + } + + static int intElement(Element row, String name) + { + return integerElement(row, name).intValue(); + } + + static Double doubleElement(Element row, String name) + { + return Double.valueOf( stringElement(row, name) ); } - static boolean booleanElement(Element row, String name) { - final String value = stringElement(row, name); - return "true".equals(value); + static boolean booleanElement(Element row, String name) + { + return "true".equals( stringElement(row, name) ); } + static Float floatElement(Element row, String name) + { + return Float.valueOf( stringElement(row, name) ); + } + + static long longElement(Element row, String name) + { + return Long.valueOf( stringElement(row, name) ).longValue(); + } + + + static List childElements(Element memberNode) { final List list = new ArrayList(); final NodeList childNodes = memberNode.getChildNodes();