util.java

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

JAVA
1,344
字号
     * "[part1].[part2]". If the names contain "]" they are escaped as "]]".
     */
    public static String implode(String[] names) {
        StringBuffer sb = new StringBuffer(64);
        for (int i = 0; i < names.length; i++) {
            if (i > 0) {
                sb.append(".");
            }
            quoteMdxIdentifier(names[i], sb);
        }
        return sb.toString();
    }

    public static String makeFqName(String name) {
        return quoteMdxIdentifier(name);
    }

    public static String makeFqName(OlapElement parent, String name) {
        if (parent == null) {
            return Util.quoteMdxIdentifier(name);
        } else {
            StringBuffer buf = new StringBuffer(64);
            buf.append(parent.getUniqueName());
            buf.append('.');
            Util.quoteMdxIdentifier(name, buf);
            return buf.toString();
        }
    }

    public static String makeFqName(String parentUniqueName, String name) {
        if (parentUniqueName == null) {
            return quoteMdxIdentifier(name);
        } else {
            StringBuffer buf = new StringBuffer(64);
            buf.append(parentUniqueName);
            buf.append('.');
            Util.quoteMdxIdentifier(name, buf);
            return buf.toString();
        }
    }


    /**
     * Resolves a name such as
     * '[Products]&#46;[Product Department]&#46;[Produce]' by resolving the
     * components ('Products', and so forth) one at a time.
     *
     * @param schemaReader Schema reader, supplies access-control context
     * @param parent Parent element to search in
     * @param names Exploded compound name, such as {"Products",
     *   "Product Department", "Produce"}
     * @param failIfNotFound If the element is not found, determines whether
     *   to return null or throw an error
     * @param category Type of returned element, a {@link Category} value;
     *   {@link Category#Unknown} if it doesn't matter.
     * @pre parent != null
     * @post !(failIfNotFound && return == null)
     * @see #explode
     */
    public static OlapElement lookupCompound(
        SchemaReader schemaReader,
        OlapElement parent,
        String[] names,
        boolean failIfNotFound,
        int category) {

        Util.assertPrecondition(parent != null, "parent != null");

        if (LOGGER.isDebugEnabled()) {
            StringBuffer buf = new StringBuffer(64);
            buf.append("Util.lookupCompound: ");
            buf.append("parent.name=");
            buf.append(parent.getName());
            buf.append(", category=");
            buf.append(Category.instance.getName(category));
            buf.append(", names=");
            quoteMdxIdentifier(names, buf);
            LOGGER.debug(buf.toString());
        }

        // First look up a member from the cache of calculated members
        // (cubes and queries both have them).
        switch (category) {
        case Category.Member:
        case Category.Unknown:
            Member member = schemaReader.getCalculatedMember(names);
            if (member != null) {
                return member;
            }
        }
        // Likewise named set.
        switch (category) {
        case Category.Set:
        case Category.Unknown:
            NamedSet namedSet = schemaReader.getNamedSet(names);
            if (namedSet != null) {
                return namedSet;
            }
        }

        // Now resolve the name one part at a time.
        for (int i = 0; i < names.length; i++) {
            String name = names[i];
            final OlapElement child = schemaReader.getElementChild(parent, name);
            if (child == null) {
                if (LOGGER.isDebugEnabled()) {
                    StringBuffer buf = new StringBuffer(64);
                    buf.append("Util.lookupCompound: ");
                    buf.append("parent.name=");
                    buf.append(parent.getName());
                    buf.append(" has no child with name=");
                    buf.append(name);
                    LOGGER.debug(buf.toString());
                }

                if (failIfNotFound) {
                    throw MondrianResource.instance().MdxChildObjectNotFound.ex(
                        name, parent.getQualifiedName());
                } else {
                    return null;
                }
            }
            parent = child;
        }
        if (LOGGER.isDebugEnabled()) {
            StringBuffer buf = new StringBuffer(64);
            buf.append("Util.lookupCompound: ");
            buf.append("found child.name=");
            buf.append(parent.getName());
            buf.append(", child.class=");
            buf.append(parent.getClass().getName());
            LOGGER.debug(buf.toString());
        }

        switch (category) {
        case Category.Dimension:
            if (parent instanceof Dimension) {
                return parent;
            } else if (parent instanceof Hierarchy) {
                return parent.getDimension();
            } else if (failIfNotFound) {
                throw Util.newError("Can not find dimension '" + implode(names) + "'");
            } else {
                return null;
            }
        case Category.Hierarchy:
            if (parent instanceof Hierarchy) {
                return parent;
            } else if (parent instanceof Dimension) {
                return parent.getHierarchy();
            } else if (failIfNotFound) {
                throw Util.newError("Can not find hierarchy '" + implode(names) + "'");
            } else {
                return null;
            }
        case Category.Level:
            if (parent instanceof Level) {
                return parent;
            } else if (failIfNotFound) {
                throw Util.newError("Can not find level '" + implode(names) + "'");
            } else {
                return null;
            }
        case Category.Member:
            if (parent instanceof Member) {
                return parent;
            } else if (failIfNotFound) {
                throw MondrianResource.instance().MdxCantFindMember.ex(implode(names));
            } else {
                return null;
            }
        case Category.Unknown:
            assertPostcondition(parent != null, "return != null");
            return parent;
        default:
            throw newInternal("Bad switch " + category);
        }
    }

    public static OlapElement lookup(Query q, String[] nameParts) {
        return (OlapElement) lookup(q, nameParts, false);
    }

    /**
     * Converts an identifier into an expression by resolving its parts into
     * an OLAP object (dimension, hierarchy, level or member) within the
     * context of a query.
     *
     * <p>If <code>allowProp</code> is true, also allows property references
     * from valid members, for example
     * <code>[Measures].[Unit Sales].FORMATTED_VALUE</code>.
     * In this case, the result will be a {@link FunCall}.
     *
     * @param q Query expression belongs to
     * @param nameParts Parts of the identifier
     * @param allowProp Whether to allow property references
     * @return OLAP object or property reference
     */
    public static Exp lookup(
            Query q, String[] nameParts, boolean allowProp) {

        // First, look for a calculated member defined in the query.
        final String fullName = quoteMdxIdentifier(nameParts);
        // Look for any kind of object (member, level, hierarchy,
        // dimension) in the cube. Use a schema reader without restrictions.
        final SchemaReader schemaReader = q.getSchemaReader(false);
        OlapElement olapElement = schemaReader.lookupCompound(
            q.getCube(), nameParts, false, Category.Unknown);
        if (olapElement != null) {
            Role role = q.getConnection().getRole();
            if (!role.canAccess(olapElement)) {
                olapElement = null;
            }
        }
        if (olapElement == null) {
            if (allowProp &&
                    nameParts.length > 1) {
                String[] namePartsButOne = new String[nameParts.length - 1];
                System.arraycopy(nameParts, 0,
                        namePartsButOne, 0,
                        nameParts.length - 1);
                final String propertyName = nameParts[nameParts.length - 1];
                olapElement = schemaReader.lookupCompound(
                        q.getCube(), namePartsButOne, false, Category.Member);
                if (olapElement != null &&
                        isValidProperty((Member) olapElement, propertyName)) {
                    return new FunCall(
                            propertyName, Syntax.Property, new Exp[] {
                                olapElement});
                }
            }

            throw MondrianResource.instance().MdxChildObjectNotFound.ex(
                    fullName, q.getCube().getQualifiedName());
        }
        return olapElement;
    }

    /**
     * Finds a root member of a hierarchy with a given name.
     *
     * @param hierarchy
     * @param memberName
     * @return Member, or null if not found
     */
    public static Member lookupHierarchyRootMember(SchemaReader reader,
                                                   Hierarchy hierarchy,
                                                   String memberName) {
        // Lookup member at first level.
        Member[] rootMembers = reader.getHierarchyRootMembers(hierarchy);
        for (int i = 0; i < rootMembers.length; i++) {
            if (rootMembers[i].getName().equalsIgnoreCase(memberName)) {
                return rootMembers[i];
            }
        }
        // If the first level is 'all', lookup member at second level. For
        // example, they could say '[USA]' instead of '[(All
        // Customers)].[USA]'.
        return (rootMembers.length == 1 && rootMembers[0].isAll())
            ? lookupMemberChildByName(reader, rootMembers[0], memberName)
            : null;
    }

    /**
     * Finds a named level in this hierarchy. Returns null if there is no
     * such level.
     */
    public static Level lookupHierarchyLevel(Hierarchy hierarchy, String s) {
        final Level[] levels = hierarchy.getLevels();
        for (int i = 0; i < levels.length; i++) {
            if (levels[i].getName().equalsIgnoreCase(s)) {
                return levels[i];
            }
        }
        return null;
    }


    /**
     * Finds a child of a member with a given name.
     */
    public static Member lookupMemberChildByName(
            SchemaReader reader, Member member, String memberName) {
        Member[] children = reader.getMemberChildren(member);
        // TODO: Linear search may be a performance problem.
        for (int i = 0; i < children.length; i++){
            final Member child = children[i];
            if (Util.equals(child.getName(), memberName)) {
                return child;
            }
        }
        return null;
    }

    /**
     * Finds the zero based ordinal of a Member among its siblings.
     */
    public static int getMemberOrdinalInParent(SchemaReader reader,
                                               Member member) {
        Member parent = member.getParentMember();
        Member[] siblings =  (parent == null)
            ? reader.getHierarchyRootMembers(member.getHierarchy())
            : reader.getMemberChildren(parent);

        for (int i = 0; i < siblings.length; i++) {
            if (siblings[i] == member) {
                return i;
            }
        }
        throw Util.newInternal(
                "could not find member " + member + " amongst its siblings");
    }

    /**
     * returns the first descendant on the level underneath parent.
     * If parent = [Time].[1997] and level = [Time].[Month], then
     * the member [Time].[1997].[Q1].[1] will be returned
     */
    public static Member getFirstDescendantOnLevel(SchemaReader reader,
                                                   Member parent,
                                                   Level level) {
        Member m = parent;
        while (m.getLevel() != level) {
            Member[] children = reader.getMemberChildren(m);
            m = children[0];
        }
        return m;
    }

    /**
     * Returns whether a string is null or empty.
     */
    public static boolean isEmpty(String s) {
        return (s == null) || (s.length() == 0);
    }

⌨️ 快捷键说明

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