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

📄 quax.java

📁 OLAP 的客户端代码
💻 JAVA
📖 第 1 页 / 共 5 页
字号:

  /**
   * split Funcall to node and complement
   */
  private void splitFunCall(TreeNode nFunCall, Member member, int iHier) {

    Object oExp = nFunCall.getReference();

    // it is possible (if the split member is of dimension to be collapsed),
    //  that this funcall does not contain member.
    // Then - there is nothing to split.
    if (!isMemberInFunCall(oExp, member, nFunCall.getLevel() - 1))
      return; // nothing to split
    Object oComplement = createComplement(oExp, member, iHier); // can be null
    if (oComplement == null) {
      // this means, that the set resolves to a single member,
      // mPath[iDimNode]
      nFunCall.setReference(uti.objForMember(member));
      // nothing to split
      return;
    }

    //  split the Funcall
    TreeNode newNodeComplement = new TreeNode(oComplement);
    TreeNode newNodeMember = new TreeNode(uti.objForMember(member));
    // add the children
    for (Iterator iter = nFunCall.getChildren().iterator(); iter.hasNext();) {
      TreeNode nChild = (TreeNode) iter.next();
      newNodeComplement.addChildNode(nChild.deepCopy());
      newNodeMember.addChildNode(nChild.deepCopy());
    }

    TreeNode nInsert = nFunCall.getParent();
    nFunCall.remove();
    nInsert.addChildNode(newNodeComplement);
    nInsert.addChildNode(newNodeMember);
  } // splitFuncall

  /**
   * remove Children node
   * 
   * @param nodeToRemove
   */
  private void removePathToNode(TreeNode nodeToRemove) {
    if (nodeToRemove.getParent().getChildren().size() > 1) {
      // this node has siblings, just remove it
      nodeToRemove.remove();
    } else {
      // no siblings, remove the first parent node having siblings
      TreeNode parent = nodeToRemove.getParent();
      while (parent.getParent().getChildren().size() == 1) {
        parent = parent.getParent();
      }
      if (parent.getLevel() > 0) // should always be true
        parent.remove();
    }
  }

  /**
   * generate Exp for all nodes of dimension iDimension
   * 
   * @param iDimension
   * @return Exp for all nodes
   */
  public Object genExpForDim(int iDimension) {
    // if we got a generate function on this hier, preserve it
    if (generateIndex >= 0 && generateIndex == iDimension && generateMode > CalcSet.SIMPLE) {
      TreeNode topCountNode = (TreeNode) posTreeRoot.getChildren().get(0);
      for (int i = 0; i < generateIndex; i++) {
        // the path to the topcount node at generateIndex does not
        // matter
        List children = topCountNode.getChildren();
        topCountNode = (TreeNode) children.get(0);
      }
      Object topcount = topCountNode.getReference();
      SetExp setexp = new SetExp(generateMode, topcount, hiers[iDimension]);
      return setexp;
    }
    List funCallList = collectFunCalls(iDimension);
    List memberList = collectMembers(iDimension);
    cleanupMemberList(funCallList, memberList, iDimension);

    if (funCallList.size() == 0 && memberList.size() == 1)
      return memberList.get(0); // single member only

    Object mSet = null;
    if (memberList.size() > 0) {
      Object[] aExp = memberList.toArray(new Object[0]);
      mSet = uti.createFunCall("{}", aExp, QuaxUti.FUNTYPE_BRACES);
    }
    if (funCallList.size() == 0)
      return mSet;

    if (funCallList.size() == 1 && mSet == null)
      return funCallList.get(0);

    Object set;
    int start;
    if (mSet != null) {
      set = mSet;
      start = 0;
    } else {
      set = funCallList.get(0);
      start = 1;
    }
    for (int j = start; j < funCallList.size(); j++) {
      set = uti.createFunCall("Union", new Object[] { set, funCallList.get(j)},
          QuaxUti.FUNTYPE_FUNCTION);
    }
    return set;
  }

  /**
   * create drillup expression for dimension
   * 
   * @param iDim
   *          dimension to be drilled up
   * @return
   */
  private Object drillupExp(int iDim, Hierarchy hier) {

    // the drillup logic is:
    //  for all members of this dimension find the deepest level.
    //  find the members of this deepest level
    //  find the grandfathers of those deepest members
    //  drill up goes to the children of those grandfathers.
    // special cases:
    //  the deepest level has all members (level.members)
    //    the drillup goes to parent_level.members

    final int[] maxLevel = new int[1];
    maxLevel[0] = 0;

    List drillupList = collectDrillup(iDim, maxLevel);
    Object expForHier = null;
    if (maxLevel[0] == 0) {
      // drillup goes to top level members
      //  we generate an explicit member set rather than level.members
      //  usually, this is a single member "All xy"
      expForHier = uti.topLevelMembers(hier, false);
    } else {
      if (drillupList.size() == 1) {
        expForHier = drillupList.get(0);
      } else {
        // more than 1 set expression , need union
        for (Iterator iter = drillupList.iterator(); iter.hasNext();) {
          Object oExp = iter.next();
          if (expForHier == null)
            expForHier = oExp;
          else {
            expForHier = uti.createFunCall("Union", new Object[] { expForHier, oExp},
                QuaxUti.FUNTYPE_FUNCTION);
          }
        }
      }
    }
    return expForHier;
  }

  /**
   * collect drillup Exps of dimension i
   * 
   * @param iDim
   */
  private List collectDrillup(final int iDim, final int[] maxLevel) {
    final List drillupList = new ArrayList();
    posTreeRoot.walkChildren(new TreeNodeCallback() {

      /**
       * callback collect GrandFathers of deepest for dimension workInt
       */
      public int handleTreeNode(TreeNode node) {
        int iDimNode = node.getLevel() - 1;
        if (iDimNode < iDim)
          return TreeNodeCallback.CONTINUE;
        // iDimNode == workInt
        Object oExp = node.getReference();
        if (!uti.isMember(oExp)) {
          // FunCall
          addFunCallToDrillup(drillupList, oExp, maxLevel);
        } else {
          // member
          Member m = uti.memberForObj(oExp);
          uti.addMemberUncles(drillupList, m, maxLevel);
        } // member
        return TreeNodeCallback.CONTINUE_SIBLING;
      } // handlePositionTreeNode
    });
    return drillupList;
  }

  /**
   * collect Funcalls of dimension iDim
   * 
   * @param iDim
   */
  private List collectFunCalls(final int iDim) {
    if (posTreeRoot == null)
      return Collections.EMPTY_LIST;
    final List funCallList = new ArrayList();
    posTreeRoot.walkChildren(new TreeNodeCallback() {

      /**
       * callback collect Funcalls of dimension workInt
       */
      public int handleTreeNode(TreeNode node) {
        int iDimNode = node.getLevel() - 1;
        if (iDimNode < iDim)
          return TreeNodeCallback.CONTINUE;
        // iDimNode == workInt
        Object oExp = node.getReference();
        if (!uti.isMember(oExp)) {
          // FunCall
          // need unique representation in order to avoid doubles
          String unique = uti.funString(oExp).toString();
          if (!funCallList.contains(unique)) {
            funCallList.add(oExp);
            funCallList.add(unique);
          }
        }
        return TreeNodeCallback.CONTINUE_SIBLING;
      } // handlePositionTreeNode
    });

    // remove the unique strings, which were just added to avoid doubles
    for (Iterator iter = funCallList.iterator(); iter.hasNext();) {
      Object element = iter.next();
      if (element instanceof String)
        iter.remove();
    }

    return funCallList;
  }

  /**
   * remove members from member list being in FunCall list
   * 
   * @param funCallList
   * @param memberList
   */
  private void cleanupMemberList(List funCallList, List memberList, int iDim) {
    if (funCallList.size() > 0 && memberList.size() > 0) {
      MemberLoop: for (Iterator itMem = memberList.iterator(); itMem.hasNext();) {
        Object oMember = itMem.next();
        Member m = uti.memberForObj(oMember);
        for (Iterator itFun = funCallList.iterator(); itFun.hasNext();) {
          Object oFun = itFun.next();
          if (isMemberInFunCall(oFun, m, iDim)) {
            itMem.remove();
            continue MemberLoop;
          }
        }
      } // MemberLoop
    }
  }

  /**
   * collect Members of dimension iDim
   * 
   * @param iDim
   * @param fList
   */
  List collectMembers(final int iDim) {
    if (posTreeRoot == null)
      return Collections.EMPTY_LIST;
    final List memberList = new ArrayList();
    posTreeRoot.walkChildren(new TreeNodeCallback() {

      /**
       * callback collect Funcalls of dimension workInt
       */
      public int handleTreeNode(TreeNode node) {
        int iDimNode = node.getLevel() - 1;
        if (iDimNode < iDim)
          return TreeNodeCallback.CONTINUE;
        // iDimNode == workInt
        Object oExp = node.getReference();
        if (uti.isMember(oExp) && !memberList.contains(oExp))
          memberList.add(oExp);
        return TreeNodeCallback.CONTINUE_SIBLING;
      } // handlePositionTreeNode
    });
    return memberList;
  }

  /**
   * add a Funcall to Drillup list
   * 
   * @param f
   */
  private void addFunCallToDrillup(List list, Object oFun, int[] maxLevel) {
    if (uti.isFunCallTo(oFun, "Union")) {
      for (int i = 0; i < 2; i++) {
        Object fExp = uti.funCallArg(oFun, i);
        addFunCallToDrillup(list, fExp, maxLevel);
      }
    } else if (uti.isFunCallTo(oFun, "{}")) {
      // set of members
      for (int i = 0; i < uti.funCallArgCount(oFun); i++) {
        Object oMember = uti.funCallArg(oFun, i);
        Member m = uti.memberForObj(oMember);
        uti.addMemberUncles(list, m, maxLevel);
      }
    } else if (uti.isFunCallTo(oFun, "Children")) {
      Object oMember = uti.funCallArg(oFun, 0);
      Member m = uti.memberForObj(oMember);
      uti.addMemberSiblings(list, m, maxLevel);
    } else if (uti.isFunCallTo(oFun, "Descendants")) {
      Object oMember = uti.funCallArg(oFun, 0);
      Member m = uti.memberForObj(oMember);
      Object oLevel = uti.funCallArg(oFun, 1);
      Level lev = uti.LevelForObj(oLevel);
      int level = uti.levelDepthForMember(m);
      int levlev = ((MDXLevel) lev).getDepth();
      if (levlev == level + 1)
        uti.addMemberSiblings(list, m, maxLevel); // same as children
      else if (levlev == level + 2)
        uti.addMemberChildren(list, m, maxLevel); // m *is* grandfather
      else {
        // add descendants of parent level
        Level parentLevel = uti.getParentLevel(lev);
        uti.addMemberDescendants(list, m, parentLevel, maxLevel);
      }
    } else if (uti.isFunCallTo(oFun, "Members")) {
      // add parent level members
      Object oLevel = uti.funCallArg(oFun, 0);
      Level lev = uti.LevelForObj(oLevel);
      int levlev = ((MDXLevel) lev).getDepth();
      if (levlev == 0)
        return; // cannot drill up
      Level parentLevel = uti.getParentLevel(lev);
      uti.addLevelMembers(list, parentLevel, maxLevel);
    } else {
      // must be Top/Bottom Function with arg[0] being base set
      Object oFun2 = uti.funCallArg(oFun, 0);
      addFunCallToDrillup(list, oFun2, maxLevel); // do not have a better
      // solution
    }
  }

  /**
   * add FunCall to list
   * 
   * @param f
   * @param list
   */
  private void funToList(Object oFun, List list) {
    if (uti.isFunCallTo(oFun, "Union")) {
      Object oArg0 = uti.funCallArg(oFun, 0);
      Object oArg1 = uti.funCallArg(oFun, 1);
      funToList(oArg0, list);
      funToList(oArg1, list);
    } else if (uti.isFunCallTo(oFun, "{}")) {
      for (int i = 0; i < uti.funCallArgCount(oFun); i++) {
        // member sets are resolved to single members
        Object oMember = uti.funCallArg(oFun, i);
        list.add(oMember);
      }
    } else {
      list.add(oFun);
    }
  }

  // ==========
  // Utility
  // ==========

  /**
   * hierarchize the query axis position array
   */
  // this code is not working
  public void hierarchizePositions(final Member[][] aPosMem) {

    final int nDimension = aPosMem[0].length;
    final Map[] firstOccurrences = new HashMap[nDimension];
    for (int i = 0; i < nDimension; i++) {
      firstOccurrences[i] = new HashMap();
    }
    for (int i = 0; i < aPosMem.length; i++) {
      for (int j = 0; j < nDimension; j++) {
        // String uName = aPosMem[i][j].getUniqueName();
        if (!firstOccurrences[j].containsKey(aPosMem[i][j])) {
          firstOccurrences[j].put(aPosMem[i][j], new Integer(i));
        }
      } // j
    } //i

    Arrays.sort(aPosMem, new Comparator() {
      public int compare(Object o1, Object o2) {
        // compare two position member arrays
        Member[] a1 = (Member[]) o1;
        Member[] a2 = (Member[]) o2;

        DimensionLoop: for (int i = 0; i < a1.length; i++) {
          if (a1[i].equals(a2[i]))
            continue DimensionLoop;
          // first difference at dimension index i
          // if it is on different level, the descendant is higher
          // otherwise - decide by first occurrence
          int level1 = ((MDXLevel) a1[i].getLevel()).getDepth();
          int level2 = ((MDXLevel) a1[i].getLevel()).getDepth();
          if (level1 == level2) {
            int first1 = ((Integer) firstOccurrences[i].get(a1[i])).intValu

⌨️ 快捷键说明

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