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

📄 quax.java

📁 OLAP 的客户端代码
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
      if (findChildrenCall(uti.funCallArg(oExp, i), level + 1))
        return true;
    }
    return false;
  }

  // ==========
  // Expand
  // ==========

  /**
   * check, whether a member in a specific position path can be expanded
   * 
   * @param pathMembers
   *          position path to be expanded
   */
  public boolean canExpand(Member[] pathMembers) {
    int iDim = pathMembers.length - 1;

    // we only allow expand / collapse for a dimension
    //  left of a "sticky topcount"
    if (!allowNavigate(iDim, false))
      return false;

    // first check the cache
    List li = Arrays.asList(pathMembers);
    if (canExpandPosMap.containsKey(li)) {
      Boolean bCanExpand = (Boolean) canExpandPosMap.get(li);
      return bCanExpand.booleanValue();
    }

    // loop over Position Tree
    //  reject expansion, if the axis already contains child-positions
    boolean childFound = checkChildPosition(pathMembers);

    // cache the result
    Boolean bool = new Boolean(!childFound);
    canExpandPosMap.put(li, bool);

    return !childFound;
  }

  /**
   * expand position path
   * 
   * @param mPath
   */
  public void expand(Member[] mPath) {

    if (qubonMode) {
      resolveUnions();
      if (logger.isDebugEnabled()) {
        logger.debug("expand after resolveUnions " + this.toString());
      }
    }

    int iDim = mPath.length - 1;

    // update the position member tree
    //  assume mPath = (Product.Drink,Time.2003,Customers.USA)
    //  1. find the node N1 for (Product.Drink,Time.2003)
    //  2. add the child node Customers.USA.Children to the node N1
    //
    // if the node N1 for (Product.Drink,Time.2003) was not found:
    // we look for a matching node and find for instance
    // node N2 = (Product.AllProducts.Children,Time.2003)
    // here, we cannot append Customers.USA.Children as a child node.
    // we add a new branch
    // (Product.Drink,Time.2003,Customers.USA.Children) to the tree.

    TreeNode bestNode = findBestNode(mPath);
    int bestNodeIndex = bestNode.getLevel() - 1;

    // add branch at startNode
    // example
    // dimensions: Product,MaritalStatus,Gender,Customer
    // mPath to Drill Down = (Product.AllProducts, MaritalStatus.M,
    // Gender.AllGender)
    // MaritalStatus.AllMaritalStatus was drilled down so best match is
    // (Product.AllProducts)
    // add the branch from MaritalStatus to this node giving
    // (Product.AllProducts,MaritalStatus.M,Gender.AllGender.children)
    // for the Customer Dimension, add all nodes matching
    // (Product.AllProducts, MaritalStatus.M, Gender.AllGender, * )

    List tailNodeList;
    if (mPath.length < nDimension) {
      tailNodeList = collectTailNodes(posTreeRoot, mPath);
    } else {
      tailNodeList = Collections.EMPTY_LIST;
    }

    TreeNode newNode;
    Object oMember = uti.objForMember(mPath[iDim]);
    Object fChildren = uti.createFunCall("Children", new Object[] { oMember},
        QuaxUti.FUNTYPE_PROPERTY);
    TreeNode parent = bestNode;

    // if bestNode is matching mPath[iDim]
    //  we will add the children Funcall to its parent
    // otherwise create path from bestNode to mPath[iDim-1] and
    //  add the children FunCall there
    if (bestNodeIndex == iDim) {
      parent = bestNode.getParent();
    } else {
      for (int i = bestNodeIndex + 1; i < mPath.length - 1; i++) {
        oMember = uti.objForMember(mPath[i]);
        newNode = new TreeNode(oMember);
        parent.addChildNode(newNode);
        parent = newNode;
      }
    }

    // any dimension left and including iDim will *not* be excluded from
    // hierarchize
    int n = nDimension - iDim - 1;
    if (n < nHierExclude)
      nHierExclude = n;

    newNode = new TreeNode(fChildren);
    parent.addChildNode(newNode);
    if (mPath.length < nDimension) {
      for (Iterator iter = tailNodeList.iterator(); iter.hasNext();) {
        TreeNode tailNode = (TreeNode) iter.next();
        newNode.addChildNode(tailNode.deepCopy());
      }
    }

    if (logger.isDebugEnabled()) {
      logger.debug("after expand " + this.toString());
    }

    qubonMode = false;
    hierarchizeNeeded = true;
    changed(this, false);
  }

  /**
   * check, whether a member can be expanded
   * 
   * @param monMember
   *          member to be expanded
   */
  public boolean canExpand(Member member) {

    // we only allow expand / collapse for a dimension
    //  left of a "sticky topcount"
    if (!allowNavigate(member, false))
      return false;

    // first check the cache
    if (canExpandMemberMap.containsKey(member)) {
      Boolean bCanExpand = (Boolean) canExpandMemberMap.get(member);
      return bCanExpand.booleanValue();
    }

    // loop over Position Tree
    //  reject expansion, if the axis already contains children of member
    boolean b = !findMemberChild(member);

    // cache the result
    Boolean bool = new Boolean(b);
    canExpandMemberMap.put(member, bool);

    return b;
  }

  /**
   * expand member all over position tree
   * 
   * @param mPath
   */
  public void expand(final Member member) {

    if (qubonMode) {
      resolveUnions();
      if (logger.isDebugEnabled()) {
        logger.debug("expand after resolveUnions " + this.toString());
      }
    }

    // old stuff, always hierarchize everything
    nHierExclude = 0;

    final int iDim = this.dimIdx(uti.dimForMember(member));
    final List nodesForMember = new ArrayList();

    // update the position member tree
    //  wherever we find monMember, expand it
    //  collect all nodes for monMember in workList
    posTreeRoot.walkChildren(new TreeNodeCallback() {

      /**
       * callback find node matching member Path exactly
       */
      public int handleTreeNode(TreeNode node) {
        int iDimNode = node.getLevel() - 1;
        if (iDimNode < iDim)
          return TreeNodeCallback.CONTINUE; // we are below iDim,
        // don't care

        // iDimNode == iDim
        //  node Exp must contain children of member[iDim]
        Object oExp = node.getReference();
        if (uti.isMember(oExp)) {
          if (uti.equalMember(oExp, member))
            nodesForMember.add(node);
        } else {
          // must be FunCall
          if (isMemberInFunCall(oExp, member, iDim))
            nodesForMember.add(node);
        }
        return TreeNodeCallback.CONTINUE_SIBLING; // continue next
        // sibling
      }
    });

    // add children of member to each node in list
    Object oMember = uti.objForMember(member);
    Object fChildren = uti.createFunCall("Children", new Object[] { oMember},
        QuaxUti.FUNTYPE_PROPERTY);
    for (Iterator iter = nodesForMember.iterator(); iter.hasNext();) {
      TreeNode node = (TreeNode) iter.next();
      TreeNode newNode = new TreeNode(fChildren);
      for (Iterator iterator = node.getChildren().iterator(); iterator.hasNext();) {
        TreeNode child = (TreeNode) iterator.next();
        newNode.addChildNode(child.deepCopy());
      }
      TreeNode parent = node.getParent();
      parent.addChildNode(newNode);
    }

    if (logger.isDebugEnabled()) {
      logger.debug("after expand member " + this.toString());
    }

    hierarchizeNeeded = true;
    changed(this, false);
  }

  // ==========
  // Collapse
  // ==========

  /**
   * check, whether a member path can be collapsed this is true if there is a child position path
   * 
   * @param pathMembers
   *          position path to be collapsed
   */
  public boolean canCollapse(Member[] pathMembers) {

    int iDim = pathMembers.length - 1;

    // we only allow expand / collapse for a dimension
    //  left of a "sticky topcount"
    if (!allowNavigate(iDim, false))
      return false;

    // first check the cache
    List li = Arrays.asList(pathMembers);
    if (canCollapsePosMap.containsKey(li)) {
      Boolean bCanCollapse = (Boolean) canCollapsePosMap.get(li);
      return bCanCollapse.booleanValue();
    }

    // loop over Position Tree
    //  collapse is possible, if the axis already contains child-positions
    boolean childFound = checkChildPosition(pathMembers);

    // cache the result
    Boolean bool = new Boolean(childFound);
    canCollapsePosMap.put(li, bool);

    return childFound;
  }

  /**
   * remove child positions of mPath from position tree
   * 
   * @param mPath
   *          member path to be collapsed
   */
  public void collapse(final Member[] mPath) {

    if (qubonMode) {
      resolveUnions();
      if (logger.isDebugEnabled()) {
        logger.debug("collapse after resolveUnions " + this.toString());
      }
    }

    final int iDim = mPath.length - 1;

    // determine FunCall nodes to be split
    final List[] splitLists = new List[mPath.length];
    for (int i = 0; i < splitLists.length; i++) {
      splitLists[i] = new ArrayList();
    }

    posTreeRoot.walkChildren(new TreeNodeCallback() {

      /**
       * callback Find child paths of member path. Collect FunCall nodes above in List. We have a
       * list for any dimension, so that we can avoid dependency conflicts when we split the
       * FunCalls.
       */
      public int handleTreeNode(TreeNode node) {
        // check, whether this node matches mPath
        Object oExp = node.getReference();
        int idi = node.getLevel() - 1;
        if (idi < iDim) {
          if (uti.isMember(oExp)) {
            if (uti.equalMember(oExp, mPath[idi]))
              return TreeNodeCallback.CONTINUE;
            else
              return TreeNodeCallback.CONTINUE_SIBLING;
          } else {
            // Funcall
            if (isMemberInFunCall(oExp, mPath[idi], idi))
              return TreeNodeCallback.CONTINUE;
            else
              return TreeNodeCallback.CONTINUE_SIBLING;
          }
        }
        //idi == iDim
        // oExp *must* be descendant of mPath[iDim] to get deleted
        boolean found = false;
        if (uti.isMember(oExp)) {
          // Member
          if (uti.checkDescendantO(mPath[iDim], oExp)) {
            found = true;
          }
        } else {
          // FunCall
          if (isChildOfMemberInFunCall(oExp, mPath[iDim], iDim))
            found = true;
        }

        if (found) {
          // add this node and all parent nodes, if they are funcalls,
          // to split list
          int level = node.getLevel();
          TreeNode currentNode = node;
          while (level > 0) {
            Object o = currentNode.getReference();
            if (!uti.isMember(o)) {
              // Funcall
              if (!splitLists[level - 1].contains(currentNode))
                splitLists[level - 1].add(currentNode);
            }
            currentNode = currentNode.getParent();
            level = currentNode.getLevel();
          }
        }
        return TreeNodeCallback.CONTINUE_SIBLING;
      } // handleTreeNode
    });

    // split all FunCall nodes collected in worklist
    //  start with higher levels to avoid dependency conflicts
    for (int i = splitLists.length - 1; i >= 0; i--) {
      for (Iterator iter = splitLists[i].iterator(); iter.hasNext();) {
        TreeNode n = (TreeNode) iter.next();
        splitFunCall(n, mPath[i], i);
      }
    }

    // remove child Paths of mPath from position tree
    //  collect nodes to be deleted
    final List removeList = new ArrayList();
    posTreeRoot.walkChildren(new TreeNodeCallback() {
      /**
       * callback remove child nodes of member path, first collect nodes in workList
       */
      public int handleTreeNode(TreeNode node) {
        // check, whether this node matches mPath
        Object oExp = node.getReference();
        int idi = node.getLevel() - 1;
        if (idi < iDim) {
          if (uti.isMember(oExp)) {
            if (uti.equalMember(oExp, mPath[idi]))
              return TreeNodeCallback.CONTINUE;
            else
              return TreeNodeCallback.CONTINUE_SIBLING;
          } else {
            // FunCall
            // cannot match as we just did the split of FunCalls 
            return TreeNodeCallback.CONTINUE_SIBLING;
          }
        } else if (idi == iDim) {
          // *must* be descendant of mPath[iDim] to get deleted
          if (!uti.isMember(oExp)) {
            // FunCall
            if (uti.isFunCallTo(oExp, "Children")) {
              Object oMember = uti.funCallArg(oExp, 0);
              if (uti.objForMember(mPath[iDim]).equals(oMember)
                  || uti.checkDescendantO(mPath[iDim], oMember))
                removeList.add(node); // add to delete list
            } else if (uti.isFunCallTo(oExp, "{}")) {
              // set of members may be there as result of split,
              //  we will remove any descendant member from the set.
              // if the set is empty thereafter, we will add the node

⌨️ 快捷键说明

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