001/*
002// Licensed to Julian Hyde under one or more contributor license
003// agreements. See the NOTICE file distributed with this work for
004// additional information regarding copyright ownership.
005//
006// Julian Hyde licenses this file to you under the Apache License,
007// Version 2.0 (the "License"); you may not use this file except in
008// compliance with the License. You may obtain a copy of the License at:
009//
010// http://www.apache.org/licenses/LICENSE-2.0
011//
012// Unless required by applicable law or agreed to in writing, software
013// distributed under the License is distributed on an "AS IS" BASIS,
014// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015// See the License for the specific language governing permissions and
016// limitations under the License.
017*/
018package org.olap4j.metadata;
019
020import org.olap4j.OlapException;
021import org.olap4j.mdx.ParseTreeNode;
022
023import java.util.List;
024
025/**
026 * <code>Member</code> is a data value in an OLAP Dimension.
027 *
028 * @author jhyde
029 * @since Aug 22, 2006
030 */
031public interface Member extends MetadataElement {
032    /**
033     * Returns the children of this Member, indexed by name.
034     *
035     * <p>If access-control is in place, the list does not contain inaccessible
036     * children.
037     *
038     * <p>If the member has no children, returns an empty list: the result is
039     * never null.
040     *
041     * <p>The caller should assume that the list is immutable;
042     * if the caller modifies the list, behavior is undefined.</p>
043     *
044     * @see org.olap4j.OlapDatabaseMetaData#getMembers
045     *
046     * @return children of this member
047     *
048     * @throws OlapException if database error occurs
049     */
050    NamedList<? extends Member> getChildMembers() throws OlapException;
051
052    /**
053     * Returns the number of children this Member has.
054     *
055     * <p>This method has the same effect as
056     * <code>getChildMembers().size()</code>, but is typically less expensive.
057     *
058     * @return number of children
059     *
060     * @throws OlapException if database error occurs
061     */
062    int getChildMemberCount() throws OlapException;
063
064    /**
065     * Returns the parent of this Member, or null if it has no parent.
066     *
067     * @return Parent member, or null if member has no parent
068     */
069    Member getParentMember();
070
071    /**
072     * Returns the Level of this Member.
073     *
074     * <p>Never returns null.</p>
075     *
076     * @return Level which this Member belongs to
077     */
078    Level getLevel();
079
080    /**
081     * Returns the Hierarchy of this Member.
082     *
083     * <p>Never returns null.
084     * Result is always the same as <code>getLevel().getHierarchy()</code>.
085     *
086     * @return Hierarchy which this Member belongs to
087     */
088    Hierarchy getHierarchy();
089
090    /**
091     * Returns the Dimension of this Member.
092     *
093     * <p>Never returns null. Result is always the same as
094     * <code>getLevel().getHierarchy().getDimension()</code>.
095     *
096     * @return Dimension which this Member belongs to
097     */
098    Dimension getDimension();
099
100    /**
101     * Returns the type of this Member.
102     *
103     * <p>Never returns null.</p>
104     *
105     * @return What kind of member this is
106     */
107    Type getMemberType();
108
109    /**
110     * Returns whether this Member represents the aggregation of all members
111     * in its Dimension.
112     *
113     * <p>An 'all' member is always the root of its Hierarchy; that is,
114     * its parent member is the null member, and
115     * {@link Hierarchy#getRootMembers()} returns the 'all'
116     * member and no others. Some hierarchies do not have an 'all' member.
117     *
118     * @see Hierarchy#hasAll()
119     *
120     * @return whether this Member is the 'all' member of its Dimension
121     */
122    boolean isAll();
123
124    /**
125     * Enumeration of types of members.
126     *
127     * <p>The values are as specified by XMLA,
128     * plus the additional {@link #NULL} value not used by XMLA.
129     * For example, XMLA specifies <code>MDMEMBER_TYPE_REGULAR</code> with
130     * ordinal 1, which corresponds to value {@link #REGULAR}.
131     *
132     * <p>The {@link #FORMULA} value takes precedence over {@link #MEASURE}.
133     * For example, if there is a formula (calculated) member on the Measures
134     * dimension, it is listed as <code>FORMULA</code>.
135     */
136    enum Type {
137        UNKNOWN(0),
138        REGULAR(1),
139        ALL(2),
140        MEASURE(3),
141        FORMULA(4),
142        /**
143         * Indicates that this member is its hierarchy's NULL member (such as is
144         * returned by the expression
145         * <code>[Gender]&#46;[All Gender]&#46;PrevMember</code>, for example).
146         */
147        NULL(5);
148
149        private Type(int ordinal) {
150            assert ordinal == ordinal();
151        }
152    }
153
154    /**
155     * Returns whether <code>member</code> is equal to, a child of, or a
156     * descendent of this Member.
157     *
158     * @param member Member
159     * @return Whether the given Member is a descendent of this Member
160     */
161    boolean isChildOrEqualTo(Member member);
162
163    /**
164     * Returns whether this member is calculated using a formula.
165     *
166     * <p>Examples of calculated members include
167     * those defined using a <code>WITH MEMBER</code> clause in an MDX query
168     * ({@link #getMemberType()} will return {@link Type#FORMULA} for these),
169     *  or a calculated member defined in a cube.
170     *
171     * @return Whether this Member is calculated
172     *
173     * @see #isCalculatedInQuery()
174     */
175    boolean isCalculated();
176
177    /**
178     * Returns the solve order of this member in a formula.
179     *
180     * @return solve order of this Member
181     */
182    int getSolveOrder();
183
184    /**
185     * Expression by which this member is derived, if it is a calculated
186     * member. If the member is not calulated, returns null.
187     *
188     * @return expression for this member
189     */
190    ParseTreeNode getExpression();
191
192    /**
193     * Returns array of all members which are ancestor to <code>this</code>.
194     *
195     * @return ancestor Members
196     */
197    List<Member> getAncestorMembers();
198
199    /**
200     * Returns whether this member is computed from a <code>WITH MEMBER</code>
201     * clause in an MDX query. (Calculated members can also be calculated in a
202     * cube.)
203     *
204     * @return Whether this member is calculated in a query
205     *
206     * @see #isCalculated()
207     */
208    boolean isCalculatedInQuery();
209
210    /**
211     * Returns the value of a given property.
212     *
213     * <p>Returns null if the property is not set.</p>
214     *
215     * <p>Every member has certain system properties such as "name" and
216     * "caption" (the full list is described in the
217     * {@link org.olap4j.metadata.Property.StandardMemberProperty}
218     * enumeration), as well as extra properties defined for its Level
219     * (see {@link Level#getProperties()}).</p>
220     *
221     * @param property Property
222     *
223     * @return formatted value of the given property
224     *
225     * @see #getPropertyFormattedValue(Property)
226     *
227     * @throws OlapException if database error occurs
228     */
229    Object getPropertyValue(Property property) throws OlapException;
230
231    /**
232     * Returns the formatted value of a given property.
233     *
234     * <p>Returns null if the property is not set.</p>
235     *
236     * <p>Every member has certain system properties such as "name" and
237     * "caption" (the full list is described in the
238     * {@link org.olap4j.metadata.Property.StandardMemberProperty}
239     * enumeration), as well as extra properties defined for its Level
240     * (see {@link Level#getProperties()}).</p>
241     *
242     * @param property Property
243     *
244     * @return formatted value of the given property
245     *
246     * @see #getPropertyValue(Property)
247     *
248     * @throws OlapException if database error occurs
249     */
250    String getPropertyFormattedValue(Property property) throws OlapException;
251
252    /**
253     * Sets a property of this member to a given value.
254     *
255     * <p>Every member has certain system properties such as "name" and
256     * "caption" (the full list is described in the
257     * {@link org.olap4j.metadata.Property.StandardMemberProperty}
258     * enumeration), as well as extra properties defined for its Level
259     * (see {@link Level#getProperties()}).</p>
260     *
261     * @param property property
262     *
263     * @param value Property value
264     *
265     * @throws OlapException if the value not valid for this property
266     *   (for example, a String value assigned to a Boolean property)
267     */
268    void setProperty(Property property, Object value) throws OlapException;
269
270    /**
271     * Returns the definitions of the properties this member may have.
272     *
273     * <p>For many providers, properties are defined against a Level, so result
274     * of this method will be identical to
275     * <code>member.getLevel().{@link Level#getProperties() getProperties}()</code>.
276     *
277     * @return properties of this Member
278     */
279    NamedList<Property> getProperties();
280
281    /**
282     * Returns the ordinal of the member.
283     *
284     * @return ordinal of this Member
285     */
286    int getOrdinal();
287
288    /**
289     * Returns whether this member is 'hidden', as per the rules which define
290     * a ragged hierarchy.
291     *
292     * @return whether this member is a hidden member of a ragged hierarchy
293     */
294    boolean isHidden();
295
296    /**
297     * Returns the depth of this member.
298     *
299     * <p>In regular hierarchies, this is as the same as the level's depth,
300     * but in parent-child and ragged hierarchies the value may be
301     * different.</p>
302     *
303     * @return depth of this Member
304     */
305    int getDepth();
306
307    /**
308     * Returns the system-generated data member that is associated with a
309     * non-leaf member of a dimension.
310     *
311     * <p>Returns this member if this member is a leaf member, or if the
312     * non-leaf member does not have an associated data member.</p>
313     *
314     * @return system-generated data member
315     */
316    Member getDataMember();
317
318    /**
319     * Enumeration of tree operations which can be used when querying
320     * members.
321     *
322     * <p>Some of the values are as specified by XMLA.
323     * For example, XMLA specifies MDTREEOP_CHILDREN with ordinal 1,
324     * which corresponds to the value {@link #CHILDREN}.
325     *
326     * @see org.olap4j.OlapDatabaseMetaData#getMembers
327     */
328    public enum TreeOp implements XmlaConstant {
329        /**
330         * Tree operation which returns only the immediate children.
331         */
332        CHILDREN(
333            1,
334            "Tree operation which returns only the immediate children."),
335
336        /**
337         * Tree operation which returns members on the same level.
338         */
339        SIBLINGS(
340            2,
341            "Tree operation which returns members on the same level."),
342
343        /**
344         * Tree operation which returns only the immediate parent.
345         */
346        PARENT(
347            4,
348            "Tree operation which returns only the immediate parent."),
349
350        /**
351         * Tree operation which returns itself in the list of returned rows.
352         */
353        SELF(
354            8,
355            "Tree operation which returns itself in the list of returned "
356            + "rows."),
357
358        /**
359         * Tree operation which returns all of the descendants.
360         */
361        DESCENDANTS(
362            16,
363            "Tree operation which returns all of the descendants."),
364
365        /**
366         * Tree operation which returns all of the ancestors.
367         */
368        ANCESTORS(
369            32,
370            "Tree operation which returns all of the ancestors.");
371
372        private final int xmlaOrdinal;
373        private String description;
374
375        private static final Dictionary<TreeOp> DICTIONARY =
376            DictionaryImpl.forClass(TreeOp.class);
377
378        /**
379         * Per {@link org.olap4j.metadata.XmlaConstant}, returns a dictionary
380         * of all values of this enumeration.
381         *
382         * @return Dictionary of all values
383         */
384        public static Dictionary<TreeOp> getDictionary() {
385            return DICTIONARY;
386        }
387
388        private TreeOp(int xmlaOrdinal, String description) {
389            this.xmlaOrdinal = xmlaOrdinal;
390            this.description = description;
391        }
392
393        public String xmlaName() {
394            return "MDTREEOP_" + name();
395        }
396
397        public String getDescription() {
398            return description;
399        }
400
401        public int xmlaOrdinal() {
402            return xmlaOrdinal;
403        }
404    }
405}
406
407// End Member.java