xmlamediator.java

来自「数据仓库展示程序」· Java 代码 · 共 827 行 · 第 1/3 页

JAVA
827
字号
                    row[i] = rs.getObject(i+1);
                }
                rows.add(row);
            }
        }

        public void unparse(SAXHandler saxHandler) throws SAXException {
            String[] encodedHeader = new String[header.length];
            for (int i = 0; i < header.length; i++) {
                // replace " " with "_x0020_" in column headers,
                // otherwise will generate a badly-formatted xml doc.
                encodedHeader[i] = header[i].replaceAll(" ", "_x0020_");
            }

            for (Iterator it = rows.iterator(); it.hasNext();) {
                Object[] row = (Object[])it.next();
                saxHandler.startElement("row");
                for (int i = 0; i < row.length; i++) {
                    saxHandler.startElement(encodedHeader[i]);
                    Object value = row[i];
                    if (value == null) {
                        saxHandler.characters("<null>");
                    } else {
                        if (value instanceof Number)
                            saxHandler.characters(normalizeNumricString(row[i].toString()));
                        else
                            saxHandler.characters(row[i].toString());
                    }
                    saxHandler.endElement();
                }
                saxHandler.endElement(); // row
            }
        }
    }

    private MDDataSet executeQuery(String statement, Properties properties) {
        final String formatName = properties.getProperty(PropertyDefinition.Format.name);
        Enumeration.Format format = Enumeration.Format.getValue(formatName);
        final String axisFormatName = properties.getProperty(PropertyDefinition.AxisFormat.name);
        Enumeration.AxisFormat axisFormat = Enumeration.AxisFormat.getValue(axisFormatName);
        final Connection connection = getConnection(properties);
        final Query query = connection.parseQuery(statement);
        final Result result = connection.execute(query);
        return new MDDataSet(result, format, axisFormat);
    }

    static class MDDataSet {
        private final Result result;
        private final Enumeration.Format format;
        private final Enumeration.AxisFormat axisFormat;
        private static final String[] cellProps = new String[] {
            "Value",
            "FmtValue",
            "FormatString"};
        private static final String[] cellPropLongs = new String[] {
            Property.VALUE.name,
            Property.FORMATTED_VALUE.name,
            Property.FORMAT_STRING.name};
        private static final String[] props = new String[] {
            "UName",
            "Caption",
            "LName",
            "LNum",
            "DisplayInfo"};
        private static final String[] propLongs = new String[] {
            Property.MEMBER_UNIQUE_NAME.name,
            Property.MEMBER_CAPTION.name,
            Property.LEVEL_UNIQUE_NAME.name,
            Property.LEVEL_NUMBER.name,
            "DISPLAY_INFO"};
        private static final String[] realPropLongs = new String[] {
            Property.MEMBER_UNIQUE_NAME.name,
            Property.MEMBER_CAPTION.name,
            Property.LEVEL_UNIQUE_NAME.name,
            Property.LEVEL_NUMBER.name,
            Property.CHILDREN_CARDINALITY.name};

        public MDDataSet(Result result, Enumeration.Format format, Enumeration.AxisFormat axisFormat) {
            this.result = result;
            this.format = format;
            this.axisFormat = axisFormat;
        }

        public void unparse(SAXHandler saxHandler) throws SAXException {
            if (format != Enumeration.Format.Multidimensional) {
                throw new UnsupportedOperationException("<Format>: only 'Multidimensional' currently supported");
            }
            olapInfo(saxHandler);
            axes(saxHandler);
            cellData(saxHandler);
        }

        private void olapInfo(SAXHandler saxHandler) throws SAXException {
            saxHandler.startElement("OlapInfo");
            saxHandler.startElement("CubeInfo");
            saxHandler.startElement("Cube");
            saxHandler.startElement("CubeName");
            saxHandler.characters(result.getQuery().getCube().getName());
            saxHandler.endElement();
            saxHandler.endElement();
            saxHandler.endElement(); // CubeInfo
            // -----------
            saxHandler.startElement("AxesInfo");
            final Axis[] axes = result.getAxes();
            axisInfo(saxHandler, result.getSlicerAxis(), "SlicerAxis");
            for (int i = 0; i < axes.length; i++) {
                axisInfo(saxHandler, axes[i], "Axis"+i);
            }
            saxHandler.endElement(); // AxesInfo
            // -----------
            saxHandler.startElement("CellInfo");
            saxHandler.element("Value", new String[] {
                "name", "VALUE"});
            saxHandler.element("FmtValue", new String[] {
                "name", "FORMATTED_VALUE"});
            saxHandler.element("FormatString", new String[] {
                "name", "FORMAT_STRING"});
            saxHandler.endElement(); // CellInfo
            // -----------
            saxHandler.endElement(); // OlapInfo
        }

        private void axisInfo(SAXHandler saxHandler, Axis axis, String axisName) throws SAXException {
            saxHandler.startElement("AxisInfo", new String[] {
                    "name", axisName});
                Hierarchy[] hierarchies;
                if (axis.positions.length > 0) {
                    final Position position = axis.positions[0];
                    hierarchies = new Hierarchy[position.members.length];
                    for (int j = 0; j < position.members.length; j++) {
                        Member member = position.members[j];
                        hierarchies[j] = member.getHierarchy();
                    }
                } else {
                    hierarchies = new Hierarchy[0];
                    //final QueryAxis queryAxis = this.result.getQuery().axes[i];
                    // todo:
                }
                for (int j = 0; j < hierarchies.length; j++) {
                    saxHandler.startElement("HierarchyInfo", new String[] {
                        "name", hierarchies[j].getName()});
                    for (int k = 0; k < props.length; k++) {
                        saxHandler.element(props[k], new String[] {
                            "name", hierarchies[j].getUniqueName() + ".[" + propLongs[k] + "]"});
                    }
                    saxHandler.endElement(); // HierarchyInfo
                }
                saxHandler.endElement(); // AxisInfo
        }

        private void axes(SAXHandler saxHandler) throws SAXException {
            if (axisFormat != Enumeration.AxisFormat.TupleFormat) {
                throw new UnsupportedOperationException("<AxisFormat>: only 'TupleFormat' currently supported");
            }
            saxHandler.startElement("Axes");
            axis(saxHandler, result.getSlicerAxis(), "SlicerAxis");
            final Axis[] axes = result.getAxes();
            for (int i = 0; i < axes.length; i++) {
                axis(saxHandler, axes[i], "Axis" + i);
            }
            saxHandler.endElement(); // Axes
        }

        private void axis(SAXHandler saxHandler, Axis axis, String axisName) throws SAXException {
            saxHandler.startElement("Axis", new String[] {
                    "name", axisName});
                saxHandler.startElement("Tuples");
                Position[] positions = axis.positions;
                for (int j = 0; j < positions.length; j++) {
                    Position position = positions[j];
                    saxHandler.startElement("Tuple");
                    for (int k = 0; k < position.members.length; k++) {
                        Member member = position.members[k];
                        saxHandler.startElement("Member", new String[] {
                            "Hierarchy", member.getHierarchy().getName()});
                        for (int m = 0; m < props.length; m++) {
                            final Object value = member.getPropertyValue(realPropLongs[m]);
                            if (value != null) {
                                saxHandler.startElement(props[m]); // UName
                                if (realPropLongs[m].equals(Property.CHILDREN_CARDINALITY.name)) { // DisplayInfo
                                    int displayInfo = calculateDisplayInfo((j == 0 ? null : positions[j-1]),
                                            (j+1 == positions.length ? null : positions[j+1]),
                                            member, k, ((Integer)value).intValue());
                                    saxHandler.characters(Integer.toString(displayInfo));
                                } else {
                                    saxHandler.characters(value.toString());
                                }
                                saxHandler.endElement(); // UName
                            }
                        }
                        saxHandler.endElement(); // Member
                    }
                    saxHandler.endElement(); // Tuple
                }
                saxHandler.endElement(); // Tuples
                saxHandler.endElement(); // Axis
        }

        private int calculateDisplayInfo(Position prevPosition, Position nextPosition,
                Member currentMember, int memberOrdinal, int childrenCount) {
            int displayInfo = 0xffff & childrenCount;

            if (nextPosition != null) {
                String currentUName = currentMember.getUniqueName();
                String nextParentUName = nextPosition.members[memberOrdinal].getParentUniqueName();
                displayInfo |= (currentUName.equals(nextParentUName) ? 0x10000 : 0);
            }
            if (prevPosition != null) {
                String currentParentUName = currentMember.getParentUniqueName();
                String prevParentUName = prevPosition.members[memberOrdinal].getParentUniqueName();
                displayInfo |= (currentParentUName != null && currentParentUName.equals(prevParentUName) ? 0x20000 : 0);
            }
            return displayInfo;
        }

        private void cellData(SAXHandler saxHandler) throws SAXException {
            saxHandler.startElement("CellData");
            final int axisCount = result.getAxes().length;
            int[] pos = new int[axisCount];
            int[] cellOrdinal = new int[] {0};

            if (axisCount == 0) { // For MDX like: SELECT FROM Sales
                emitCell(saxHandler, result.getCell(pos), cellOrdinal[0]);
            } else {
                recurse(saxHandler, pos, axisCount - 1, cellOrdinal);
            }

            saxHandler.endElement(); // CellData
        }


        private void recurse(SAXHandler saxHandler, int[] pos, int axis, int[] cellOrdinal) throws SAXException {
            final int axisLength = result.getAxes()[axis].positions.length;
            for (int i = 0; i < axisLength; i++) {
                pos[axis] = i;
                if (axis == 0) {
                    final Cell cell = result.getCell(pos);
                    emitCell(saxHandler, cell, cellOrdinal[0]++);
                } else {
                    recurse(saxHandler, pos, axis - 1, cellOrdinal);
                }
            }
        }


        private void emitCell(SAXHandler saxHandler, Cell cell, int ordinal) throws SAXException {
            saxHandler.startElement("Cell", new String[] {
                    "CellOrdinal", Integer.toString(ordinal)});
            for (int i = 0; i < cellProps.length; i++) {
                String cellPropLong = cellPropLongs[i];
                final Object value =
                    cell.getPropertyValue(cellPropLong);


                // Deduce the XML datatype from the declared datatype
                // of the measure, if present. (It comes from the
                // "datatype" attribute of the "Measure" element.) If
                // not present, use the value type to guess.
                //
                // The value type depends upon the RDBMS and the JDBC
                // driver, so it tends to produce inconsistent results
                // between platforms.
                String valueType;
                String datatype = (String)
                    cell.getPropertyValue(Property.DATATYPE.getName());
                if (datatype != null) {
                    if (datatype.equals("Integer")) {
                        valueType = "xsd:int";
                    } else if (datatype.equals("Numeric")) {
                        valueType = "xsd:double";
                    } else {
                        valueType = "xsd:string";
                    }
                } else if (value instanceof Integer || value instanceof Long) {
                    valueType = "xsd:int";
                } else if (value instanceof Double || value instanceof BigDecimal) {

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?