⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 resultbase.java

📁 OLAP 的客户端代码
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/*
 * ====================================================================
 * This software is subject to the terms of the Common Public License
 * Agreement, available at the following URL:
 *   http://www.opensource.org/licenses/cpl.html .
 * Copyright (C) 2003-2004 TONBELLER AG.
 * All Rights Reserved.
 * You must accept the terms of that agreement to use this software.
 * ====================================================================
 *
 * 
 */
package com.tonbeller.jpivot.olap.query;

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;

import com.tonbeller.jpivot.core.Model;
import com.tonbeller.jpivot.olap.model.Axis;
import com.tonbeller.jpivot.olap.model.Cell;
import com.tonbeller.jpivot.olap.model.Member;
import com.tonbeller.jpivot.olap.model.Position;
import com.tonbeller.jpivot.olap.model.Result;
import com.tonbeller.jpivot.olap.model.Visitor;
import com.tonbeller.jpivot.util.CubeIndexIterator;

/**
 * base class for both Mondrian and XMLA result
 */
public abstract class ResultBase implements Result {

  private static String[] specialProps = { "arrow"};

  protected List axesList;

  protected List aCells;

  protected Axis slicer;

  protected Model model;

  boolean overflow = false;

  // c'tor
  public ResultBase(Model model) {
    aCells = new ArrayList();
    axesList = new ArrayList();
    this.model = model;
  }

  /**
   * After the result was gotten, handle special measures, which are
   * "invisible". Their meaning is a property for "another" cell, eg.
   * [Measures].[Unit Sales_arrow] is the "arrow" property for
   * [Measures].[Unit Sales]
   */
  void processSpecialProps() {
  }

  /**
   * @see com.tonbeller.jpivot.olap.model.Result#getAxes()
   */
  public abstract Axis[] getAxes();

  /**
   * Returns the slicer.
   * 
   * @return Slicer Axis
   * @see com.tonbeller.jpivot.olap.model.Result#getSlicer()
   */
  public Axis getSlicer() {
    return slicer;
  }

  /**
   * Returns the cells.
   * 
   * @return List of cells
   * @see com.tonbeller.jpivot.olap.model.Result#getCells()
   */
  public List getCells() {
    return aCells;
  }

  /**
   * perform hierarchize not resorting siblings under parent
   * 
   * this method is not fully tested we cannot use Result hierarchize, because
   * by Quax navigation the prerequisits are not given Example (Customers
   * Products): if by Quax navigation (CA, Drink) USA.children is split into
   * {OR, WA) * Drink {CA} * { Drink + Drink.Children) CA would then come
   * later in the result. Therefore : MDX hierarchize is needed
   */
  public void hierarchize(int iAxis) {
    List posList = ((Axis) axesList.get(iAxis)).getPositions();
    int nDim = axesList.size();
    int indexForAxis = nDim - 1 - iAxis;
    int[] ni = new int[nDim];
    int[] iFull = new int[nDim];
    for (int i = 0; i < nDim; i++) {
      ni[i] = ((Axis) axesList.get(i)).getPositions().size() - 1;
    }
    int[] iSlice = new int[nDim - 1];
    CubeIndexIterator cubit = null;
    if (nDim > 1) {
      full2slice(ni, iSlice, iAxis);
      cubit = new CubeIndexIterator(iSlice, false);
    }

    // assign the cells
    // c00 c01 c02 ... c0n
    // c10 c11 c12 ... c1n
    // ...
    // cm0 cm1 cm2 ... cmn
    // cell ordinal of cell [i,k] = c[i*(n+1) +k]
    // n+1 = position size of axis 0 (columns)
    // m+1 = position size of axis 1 (rows)
    // iAxis=0 position=0 : c00, c10, ... cm0
    // iAxis=0 position=1 : c01, c11, ... cm1
    // iAxis=1 position=0 : c00, c01, ... c0n
    // iAxis=1 position=1 : c10, c11, ... c1n

    // for each position of iAxis we will get the slice
    //  of cells for the "other" axes

    int iPos = 0;
    int nDimension = 0;
    for (Iterator iter = posList.iterator(); iter.hasNext(); iPos++) {
      PositionBase pos = (PositionBase) iter.next();
      if (nDimension == 0)
        nDimension = pos.getMembers().length;
      pos.number = iPos;
      if (pos.cellList == null)
        pos.cellList = new ArrayList();
      else
        pos.cellList.clear();
      if (nDim > 1) {
        cubit.reset();
        while (true) {
          int[] iCurrent = cubit.next();
          if (iCurrent == null)
            break;
          slice2full(iCurrent, iFull, indexForAxis, iPos);
          int ii = lindex(iFull, ni);
          pos.cellList.add(aCells.get(ii));
        }
      } else {
        // nDim <= 1
        pos.cellList.add(aCells.get(iPos));
      }
    }

    // sort
    posList = sortPosList(posList, 0, nDim);

    // rewrite cell list
    int nc = aCells.size();
    aCells.clear();
    for (int i = 0; i < nc; i++)
      aCells.add(null);
    iPos = 0;
    for (Iterator iter = posList.iterator(); iter.hasNext(); iPos++) {
      PositionBase posBase = (PositionBase) iter.next();
      if (nDim > 1) {
        cubit.reset();
        for (Iterator iterator = posBase.cellList.iterator(); iterator.hasNext();) {
          Object cellObj = iterator.next();
          int[] iCurrent = cubit.next();
          if (iCurrent == null)
            break;
          slice2full(iCurrent, iFull, indexForAxis, iPos);
          int ii = lindex(iFull, ni);
          aCells.set(ii, cellObj);
        }
      } else {
        // nDim <= 1
        Object cellObj = posBase.cellList.get(0);
        aCells.set(iPos, cellObj);
      }
      posBase.cellList.clear();
    }

  }

  /**
   * 
   * @param posList
   * @param iDim
   * @param nDim
   * @return
   */
  private List sortPosList(List posList, final int iDim, int nDim) {

    printPosList(posList, new PrintWriter(System.out), "Start sortPosList " + iDim);

    if (posList.size() < 2)
      return posList;

    // collect members and assign first occurrence prio
    final Map firstOcc = new HashMap();
    int k = 0;
    for (Iterator iter = posList.iterator(); iter.hasNext(); k++) {
      PositionBase posb = (PositionBase) iter.next();
      posb.parent = null;
      Member m = posb.getMembers()[iDim];
      if (!firstOcc.containsKey(m))
        firstOcc.put(m, new Integer(k));
    }

    // first step
    // sort by level and original position to assure
    //  that any child follows its parent
    Collections.sort(posList, new Comparator() {
      public int compare(Object o1, Object o2) {
        // compare two positions
        Position pos1 = (Position) o1;
        Position pos2 = (Position) o2;
        Member a1 = pos1.getMembers()[iDim];
        Member a2 = pos2.getMembers()[iDim];

        // if it is on different level, the descendant is higher
        // otherwise - decide by original index
        int level1 = ((MDXLevel) a1.getLevel()).getDepth();
        int level2 = ((MDXLevel) a2.getLevel()).getDepth();
        if (level1 == level2) {
          return ((PositionBase) pos1).number - ((PositionBase) pos2).number;
        } else {
          return level1 - level2;
        }
      }
    });

    // second step
    // establish parent child dependencies
    int i = 0;
    Outerloop: for (Iterator iter = posList.iterator(); iter.hasNext(); i++) {
      PositionBase posb = (PositionBase) iter.next();
      if (!iter.hasNext())
        break;
      MDXMember m = (MDXMember) posb.getMembers()[iDim];
      int iLevel = ((MDXLevel) m.getLevel()).getDepth();
      ListIterator lit = posList.listIterator(i + 1);
      InnerLoop: while (lit.hasNext()) {
        PositionBase posb2 = (PositionBase) lit.next();
        if (posb2.parent != null)
          continue;
        MDXMember m2 = (MDXMember) posb2.getMembers()[iDim];
        int iLevel2 = ((MDXLevel) m2.getLevel()).getDepth();
        if (iLevel2 <= iLevel)
          continue InnerLoop;
        if (iLevel2 > iLevel + 1)
          break InnerLoop;
        // here iLevel2 = iLevel +1
        if (m.getUniqueName().equals(m2.getParentUniqueName()))
          posb2.parent = posb;
      }
    }

    // third step
    // sort by hierarchy and member first ocurrence
    Collections.sort(posList, new Comparator() {
      public int compare(Object o1, Object o2) {
        // compare two positions
        PositionBase pos1 = (PositionBase) o1;
        PositionBase pos2 = (PositionBase) o2;
        Member a1 = pos1.getMembers()[iDim];
        Member a2 = pos2.getMembers()[iDim];
        if (a1.equals(a2)) { return pos1.number - pos2.number; }

        // if a1 and a2 are descendant, the descendant is higher
        int level1 = ((MDXLevel) a1.getLevel()).getDepth();
        int level2 = ((MDXLevel) a2.getLevel()).getDepth();
        PositionBase par1 = null;
        PositionBase par2 = null;
        PositionBase parb = null;
        if (level1 < level2) {
          // a2 is possibly descendant of a1
          parb = pos2;
          for (int j = 0; j < level2 - level1; j++) {
            if (parb != null)
              parb = parb.parent;
          }
          if (parb != null) {
            Member ab = parb.getMembers()[iDim];
            if (ab.equals(a1))
              return -1; // a2 is descendant of a1, a2 is higher
          }
          par1 = pos1;
          par2 = parb;
        } else if (level1 > level2) {
          // a1 is possibly descendant of a2
          parb = pos1;
          for (int j = 0; j < level1 - level2; j++) {
            if (parb != null)
              parb = parb.parent;
          }
          if (parb != null) {
            Member ab = parb.getMembers()[iDim];
            if (ab.equals(a2))
              return 1; // a1 is descendant of a2, a1 is higher
          }
          par1 = parb;
          par2 = pos2;

        } else {
          // level1 = level2
          par1 = pos1;
          par2 = pos2;
        }
        // pos1 and pos2 are on equal level
        if (par1 == null || par2 == null)
          return pos1.number - pos2.number; // should not occur
        // go up until we come to a common ancestor or null
        Member apar1 = par1.getMembers()[iDim];
        Member apar2 = par2.getMembers()[iDim];
        PositionBase p1 = par1.parent;
        PositionBase p2 = par2.parent;
        while (p1 != null && p2 != null) {
          Member ap1 = p1.getMembers()[iDim];
          Member ap2 = p2.getMembers()[iDim];
          if (ap1.equals(ap2))
            break;
          par1 = p1;
          par2 = p2;
          p1 = par1.parent;
          p2 = par2.parent;
          if (p1 == null || p2 == null)
            break;
          apar1 = ap1;
          apar2 = ap2;
        }

        int retcode = ((Integer) firstOcc.get(apar1)).intValue()
            - ((Integer) firstOcc.get(apar2)).intValue();

        return retcode;
      }

⌨️ 快捷键说明

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