Esempio n. 1
0
  private void advance() throws OLAPException {
    switch (currentState) {
      case STATE_INIT:
      case STATE_ROW_EDGE:
        if (rowGroups.size() > 0) {
          // TODO how to skip dummy groups?

          // process row dimension header column if available
          for (int i = groupIndex; i < rowGroups.size(); i++) {
            EdgeGroup group = (EdgeGroup) rowGroups.get(i);

            groupIndex++;

            dimensionIndex = group.dimensionIndex;
            levelIndex = group.levelIndex;
            currentState = STATE_ROW_EDGE;
            return;
          }
        }

        // process vertical measure header column if available
        if (mCount > 0 && isVerticalMeasure && !isHideMeasureHeader) {
          for (int i = 0; i < mCount; i++) {
            MeasureViewHandle mv = crosstabItem.getMeasure(i);

            if (mv.getHeader() != null) {
              currentState = STATE_MEASURE_HEADER;
              return;
            }
          }
        } else if (rowGroups.size() == 0 && groupIndex == 0 && crosstabItem.getHeader() != null) {
          // mark the flag as we only check once.
          groupIndex++;

          boolean hasHeaderContent = false;
          for (int i = 0; i < crosstabItem.getHeaderCount(); i++) {
            CrosstabCellHandle cell = crosstabItem.getHeader(i);

            if (cell.getContents().size() > 0) {
              hasHeaderContent = true;
              break;
            }
          }

          if (hasHeaderContent) {
            // in case it has no row edge but has non-empty header
            // cell, we produce a dummy row edge event to output the
            // crosstab header.

            dimensionIndex = -1;
            levelIndex = -1;
            currentState = STATE_ROW_EDGE;
            return;
          }
        }

      case STATE_MEASURE_HEADER:

        // check if need processing grandtotal_before
        inProcessingGrandTotalBefore =
            columnGroups.size() > 0
                && columnEdgeCursor != null
                && crosstabItem.getGrandTotal(COLUMN_AXIS_TYPE) != null
                && GRAND_TOTAL_LOCATION_BEFORE.equals(
                    crosstabItem.getCrosstabView(COLUMN_AXIS_TYPE).getGrandTotalLocation());

      case STATE_PENDING_CHECK_COLUMN_EDGE:
        if (!inProcessingGrandTotalBefore && columnGroups.size() > 0 && columnEdgeCursor != null) {
          columnDimensionCursors = columnEdgeCursor.getDimensionCursor();

          columnEdgeCursor.beforeFirst();
          hasNext = columnEdgeCursor.next();
          columnProcessed = false;

          groupIndex = 0;
          measureIndex = -1;

          tmpStartGroupIndex = 0;
          tmpEndGroupIndex = lastColumnGroupIndex;
        }

      case STATE_COLUMN_TOTAL_BEFORE:
      case STATE_COLUMN_TOTAL_AFTER:
      case STATE_COLUMN_EDGE:
        if (!inProcessingGrandTotalBefore && columnGroups.size() > 0 && columnEdgeCursor != null) {
          while (hasNext) {
            if (mCount > 0 || !IGNORE_TOTAL_COLUMN_WITHOUT_MEASURE) {
              // check header
              for (int i = tmpStartGroupIndex; i < columnGroups.size(); i++) {
                EdgeGroup group = (EdgeGroup) columnGroups.get(i);

                if (!GroupUtil.isLeafOrDummyGroup(columnDimensionCursors, i)) {
                  DimensionCursor dc = (DimensionCursor) columnDimensionCursors.get(i);

                  if (dc.getEdgeStart() == columnEdgeCursor.getPosition()) {
                    // process leading subtoal column if
                    // available
                    LevelViewHandle lv =
                        crosstabItem
                            .getDimension(COLUMN_AXIS_TYPE, group.dimensionIndex)
                            .getLevel(group.levelIndex);

                    if (lv.getAggregationHeader() != null
                        && AGGREGATION_HEADER_LOCATION_BEFORE.equals(
                            lv.getAggregationHeaderLocation())) {
                      if (mCount > 0 && !isVerticalMeasure) {
                        for (int m = measureIndex + 1; m < mCount; m++) {
                          if (GroupUtil.hasTotalContent(
                              crosstabItem,
                              COLUMN_AXIS_TYPE,
                              group.dimensionIndex,
                              group.levelIndex,
                              m)) {
                            tmpStartGroupIndex = i;

                            dimensionIndex = group.dimensionIndex;
                            levelIndex = group.levelIndex;
                            measureIndex = m;
                            currentState = STATE_COLUMN_TOTAL_BEFORE;
                            return;
                          }
                        }

                        // reset measure index
                        measureIndex = -1;
                      } else if (GroupUtil.hasTotalContent(
                          crosstabItem,
                          COLUMN_AXIS_TYPE,
                          group.dimensionIndex,
                          group.levelIndex,
                          -1)) {
                        tmpStartGroupIndex = i + 1;

                        dimensionIndex = group.dimensionIndex;
                        levelIndex = group.levelIndex;
                        currentState = STATE_COLUMN_TOTAL_BEFORE;
                        return;
                      }
                    }
                  }
                }
              }

              // set to skip later header check
              tmpStartGroupIndex = columnGroups.size();
            }

            // reset measure index
            if (currentState != STATE_COLUMN_EDGE && currentState != STATE_COLUMN_TOTAL_AFTER) {
              measureIndex = -1;
            }

            // check column
            if (!columnProcessed) {
              // add data columns per edge tuple
              if (mCount > 0 && !isVerticalMeasure) {
                for (int m = measureIndex + 1; m < mCount; m++) {
                  measureIndex = m;
                  currentState = STATE_COLUMN_EDGE;
                  return;
                }
              } else if (measureIndex == -1) {
                measureIndex--;
                currentState = STATE_COLUMN_EDGE;
                return;
              }

              columnProcessed = true;
            }

            if (mCount > 0 || !IGNORE_TOTAL_COLUMN_WITHOUT_MEASURE) {
              // reset measure index
              if (currentState != STATE_COLUMN_TOTAL_AFTER) {
                measureIndex = -1;
              }

              // check footer
              for (int i = tmpEndGroupIndex; i >= 0; i--) {
                EdgeGroup group = (EdgeGroup) columnGroups.get(i);

                if (!GroupUtil.isLeafOrDummyGroup(columnDimensionCursors, i)) {
                  DimensionCursor dc = (DimensionCursor) columnDimensionCursors.get(i);

                  if (dc.getEdgeEnd() == columnEdgeCursor.getPosition()) {
                    // process trailing subtoal column
                    // if
                    // available
                    LevelViewHandle lv =
                        crosstabItem
                            .getDimension(COLUMN_AXIS_TYPE, group.dimensionIndex)
                            .getLevel(group.levelIndex);

                    if (lv.getAggregationHeader() != null
                        && AGGREGATION_HEADER_LOCATION_AFTER.equals(
                            lv.getAggregationHeaderLocation())) {
                      if (mCount > 0 && !isVerticalMeasure) {
                        for (int m = measureIndex + 1; m < mCount; m++) {
                          if (GroupUtil.hasTotalContent(
                              crosstabItem,
                              COLUMN_AXIS_TYPE,
                              group.dimensionIndex,
                              group.levelIndex,
                              m)) {
                            tmpEndGroupIndex = i;

                            dimensionIndex = group.dimensionIndex;
                            levelIndex = group.levelIndex;
                            measureIndex = m;
                            currentState = STATE_COLUMN_TOTAL_AFTER;
                            return;
                          }
                        }

                        // reset measure index
                        measureIndex = -1;
                      } else if (GroupUtil.hasTotalContent(
                          crosstabItem,
                          COLUMN_AXIS_TYPE,
                          group.dimensionIndex,
                          group.levelIndex,
                          -1)) {
                        tmpEndGroupIndex = i - 1;

                        dimensionIndex = group.dimensionIndex;
                        levelIndex = group.levelIndex;
                        currentState = STATE_COLUMN_TOTAL_AFTER;
                        return;
                      }
                    }
                  }
                }
              }
            }

            hasNext = columnEdgeCursor.next();

            // reset temp index
            columnProcessed = false;

            tmpStartGroupIndex = 0;
            tmpEndGroupIndex = lastColumnGroupIndex;

            measureIndex = -1;
          }

          // check if grandtotal already processed, otherwise, this is
          // already the end of column edge
          if (crosstabItem.getGrandTotal(COLUMN_AXIS_TYPE) != null
              && GRAND_TOTAL_LOCATION_BEFORE.equals(
                  crosstabItem.getCrosstabView(COLUMN_AXIS_TYPE).getGrandTotalLocation())) {
            currentState = STATE_END;
            return;
          }
        }

        // reset measure index
        measureIndex = -1;

      case STATE_GRAND_TOTAL:
        if (columnGroups.size() > 0 && columnEdgeCursor != null) {
          // process grand total column
          if (crosstabItem.getGrandTotal(COLUMN_AXIS_TYPE) != null) {
            if (mCount > 0 || !IGNORE_TOTAL_COLUMN_WITHOUT_MEASURE) {
              if (mCount > 0 && !isVerticalMeasure) {
                for (int i = measureIndex + 1; i < mCount; i++) {
                  if (GroupUtil.hasTotalContent(crosstabItem, COLUMN_AXIS_TYPE, -1, -1, i)) {
                    measureIndex = i;
                    currentState = STATE_GRAND_TOTAL;
                    return;
                  }
                }
              } else if (currentState != STATE_GRAND_TOTAL) {
                if (GroupUtil.hasTotalContent(crosstabItem, COLUMN_AXIS_TYPE, -1, -1, -1)) {
                  currentState = STATE_GRAND_TOTAL;
                  return;
                }
              }
            }

            // check if this is grandtotal_before, then forward the
            // processing to column edge
            if (inProcessingGrandTotalBefore) {
              inProcessingGrandTotalBefore = false;

              currentState = STATE_PENDING_CHECK_COLUMN_EDGE;
              return;
            }
          }

          currentState = STATE_END;
          return;
        }

      case STATE_MEASURE:

        // process measure columns in case no column edge defined
        if (!isVerticalMeasure) {
          for (int i = measureIndex + 1; i < mCount; i++) {
            measureIndex = i;
            currentState = STATE_MEASURE;
            return;
          }
        } else if (measureIndex == -1 && mCount > 0) {
          measureIndex--;
          currentState = STATE_MEASURE;
          return;
        }

        currentState = STATE_END;
        return;
    }
  }