/*
// Licensed to Julian Hyde under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// Julian Hyde licenses this file to you under the Apache License,
// Version 2.0 (the "License"); you may not use this file except in
// compliance with the License. You may obtain a copy of the License at:
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
*/
package org.olap4j.metadata;

import org.olap4j.OlapException;
import org.olap4j.mdx.IdentifierSegment;

import java.util.*;

/**
 * Central metadata object for representation of multidimensional data.
 *
 * <p>A Cube belongs to a {@link Schema}, and is described by a list of
 * {@link Dimension}s and a list of {@link Measure}s. It may also have one or
 * more {@link NamedSet}s.
 *
 * @see org.olap4j.metadata.Cube#getMeasures()
 *
 * @author jhyde
 * @since Aug 22, 2006
 */
public interface Cube extends MetadataElement {
    /**
     * Returns the {@link Schema} this Cube belongs to.
     *
     * @return Schema this Cube belongs to
     */
    Schema getSchema();

    /**
     * Returns a list of {@link Dimension} objects in this Cube.
     *
     * <p>The caller should assume that the list is immutable;
     * if the caller modifies the list, behavior is undefined.</p>
     *
     * @see org.olap4j.OlapDatabaseMetaData#getDimensions(String,String,String,String)
     *
     * @return list of Dimensions
     */
    NamedList<Dimension> getDimensions();

    /**
     * Returns a list of {@link Hierarchy} objects in this Cube.
     *
     * <p>The caller should assume that the list is immutable;
     * if the caller modifies the list, behavior is undefined.</p>
     *
     * @see org.olap4j.OlapDatabaseMetaData#getHierarchies(String, String, String, String, String)
     *
     * @return list of Dimensions
     */
    NamedList<Hierarchy> getHierarchies();

    /**
     * Returns a list of {@link Measure} objects in this Cube.
     *
     * <p>The list includes both stored and calculated members, and (unlike
     * the {@link org.olap4j.OlapDatabaseMetaData#getMeasures} method or the
     * MDSCHEMA_MEASURES XMLA request) is sorted by ordinal.
     *
     * @see org.olap4j.OlapDatabaseMetaData#getMeasures(String,String,String,String,String)
     *
     * @return list of Measures
     */
    List<Measure> getMeasures();

    /**
     * Returns a list of {@link NamedSet} objects in this Cube.
     *
     * <p>The caller should assume that the list is immutable;
     * if the caller modifies the list, behavior is undefined.</p>
     *
     * @see org.olap4j.OlapDatabaseMetaData#getSets(String,String,String,String)
     *
     * @return list of NamedSets
     */
    NamedList<NamedSet> getSets();

    /**
     * Returns a collection of {@link java.util.Locale} objects for which this
     * <code>Cube</code> has been localized.
     *
     * <p>Consider the following use case. Suppose one cube is available in
     * English and French, and in French and Spanish, and both are shown in same
     * portal. Clients typically say that seeing reports in a mixture of
     * languages is confusing; the portal would figure out the best common
     * language, in this case French. This method allows the client to choose
     * the most appropriate locale.</p>
     *
     * <p>The list is advisory: a client is free to choose another locale,
     * in which case, the server will probably revert to the base locale for
     * locale-specific behavior such as captions and formatting.</p>
     *
     * @see Schema#getSupportedLocales
     *
     * @return List of locales for which this <code>Cube</code> has been
     * localized
     */
    Collection<Locale> getSupportedLocales();

    /**
     * Finds a member in the current Cube based upon its fully-qualified name.
     * Returns the member, or null if there is no member with this name.
     *
     * <p>The fully-qualified name starts with the name of the dimension,
     * followed by the name of a root member, and continues with the name of
     * each successive member on the path from the root member. If a member's
     * name is unique within its level, preceding member name can be omitted.
     *
     * <p>For example, {@code "[Product].[Food]"} and
     * {@code "[Product].[All Products].[Food]"}
     * are both valid ways to locate the "Food" member of the "Product"
     * dimension.
     *
     * <p>The name is represented as a list of {@link IdentifierSegment}
     * objects. There are some common ways to create such a list. If you have an
     * identifier, call
     * {@link org.olap4j.mdx.IdentifierNode#parseIdentifier(String)}
     * to parse the string into an identifier, then
     * {@link org.olap4j.mdx.IdentifierNode#getSegmentList()}. For example,
     *
     * <blockquote><code>Member member = cube.lookupMember(<br/>
     * &nbsp;&nbsp;IdentifierNode.parseIdentifier(
     * "[Product].[Food]").getSegmentList())</code></blockquote>
     *
     * <p>If you have an array of names, call
     * {@link org.olap4j.mdx.IdentifierNode#ofNames(String...)}. For example,
     *
     * <blockquote><code>Member member = cube.lookupMember(<br/>
     * &nbsp;&nbsp;IdentifierNode.parseIdentifier(
     * "[Product].[Food]").getSegmentList())</code></blockquote>
     *
     * @param nameParts Components of the fully-qualified member name
     *
     * @return member with the given name, or null if not found
     *
     * @throws OlapException if error occurs
     */
    Member lookupMember(List<IdentifierSegment> nameParts) throws OlapException;

    /**
     * Finds a collection of members in the current Cube related to a given
     * member.
     *
     * <p>The method first looks up a member with the given fully-qualified
     * name as for {@link #lookupMember(java.util.List)}, then applies the set
     * of tree-operations to find related members.
     *
     * <p>The returned collection is sorted by level number then by member
     * ordinal. If no member is found with the given name, the collection is
     * empty.
     *
     * <p>For example,
     *
     * <blockquote><pre>
     * <code>lookupMembers(
     *     EnumSet.of(TreeOp.ANCESTORS, TreeOp.CHILDREN),
     *     "Time", "1997", "Q2")</code>
     * </pre></blockquote>
     *
     * returns
     *
     * <blockquote><pre><code>
     * [Time].[1997]
     * [Time].[1997].[Q2].[4]
     * [Time].[1997].[Q2].[5]
     * [Time].[1997].[Q2].[6]
     * </code></pre></blockquote>
     *
     * <p>The fully-qualified name starts with the name of the dimension,
     * followed by the name of a root member, and continues with the name of
     * each successive member on the path from the root member. If a member's
     * name is unique within its level, preceding member name can be omitted.
     *
     * <p>For example,
     * <code>lookupMember("Product", "Food")</code>
     * and
     * <code>lookupMember("Product", "All Products", "Food")</code>
     * are both valid ways to locate the "Food" member of the "Product"
     * dimension.
     *
     * @param nameParts Components of the fully-qualified member name
     *
     * @param treeOps Collection of tree operations to travel relative to
     * given member in order to create list of members
     *
     * @return collection of members related to the given member, or empty
     * set if the member is not found
     *
     * @throws OlapException if error occurs
     */
    List<Member> lookupMembers(
        Set<Member.TreeOp> treeOps,
        List<IdentifierSegment> nameParts) throws OlapException;

    /**
     * Tells whether or not drill through operations are
     * possible in this cube.
     * @return True if drillthrough is enabled, false otherwise.
     */
    boolean isDrillThroughEnabled();
}

// End Cube.java
