001    /*
002    // $Id: //open/mondrian/src/main/mondrian/olap/Property.java#30 $
003    // This software is subject to the terms of the Common Public License
004    // Agreement, available at the following URL:
005    // http://www.opensource.org/licenses/cpl.html.
006    // Copyright (C) 2001-2002 Kana Software, Inc.
007    // Copyright (C) 2001-2008 Julian Hyde and others
008    // All Rights Reserved.
009    // You must accept the terms of that agreement to use this software.
010    //
011    // jhyde, 12 September, 2002
012    */
013    
014    package mondrian.olap;
015    
016    import java.util.Map;
017    import java.util.HashMap;
018    
019    /**
020     * <code>Property</code> is the definition of a member property.
021     *
022     * <p>The following properties are mandatory for members:<ul>
023     * <li>{@link #CATALOG_NAME}</li>
024     * <li>{@link #SCHEMA_NAME}</li>
025     * <li>{@link #CUBE_NAME}</li>
026     * <li>{@link #DIMENSION_UNIQUE_NAME}</li>
027     * <li>{@link #HIERARCHY_UNIQUE_NAME}</li>
028     * <li>{@link #LEVEL_UNIQUE_NAME}</li>
029     * <li>{@link #LEVEL_NUMBER}</li>
030     * <li>{@link #MEMBER_UNIQUE_NAME}</li>
031     * <li>{@link #MEMBER_NAME}</li>
032     * <li>{@link #MEMBER_TYPE}</li>
033     * <li>{@link #MEMBER_GUID}</li>
034     * <li>{@link #MEMBER_CAPTION}</li>
035     * <li>{@link #MEMBER_ORDINAL}</li>
036     * <li>{@link #CHILDREN_CARDINALITY}</li>
037     * <li>{@link #PARENT_LEVEL}</li>
038     * <li>{@link #PARENT_UNIQUE_NAME}</li>
039     * <li>{@link #PARENT_COUNT}</li>
040     * <li>{@link #DESCRIPTION}</li>
041     * </ul>
042     *
043     * The following propertiess are mandatory for cells:<ul>
044     * <li>{@link #BACK_COLOR}</li>
045     * <li>{@link #CELL_EVALUATION_LIST}</li>
046     * <li>{@link #CELL_ORDINAL}</li>
047     * <li>{@link #FORE_COLOR}</li>
048     * <li>{@link #FONT_NAME}</li>
049     * <li>{@link #FONT_SIZE}</li>
050     * <li>{@link #FONT_FLAGS}</li>
051     * <li>{@link #FORMAT_STRING}</li>
052     * <li>{@link #FORMATTED_VALUE}</li>
053     * <li>{@link #NON_EMPTY_BEHAVIOR}</li>
054     * <li>{@link #SOLVE_ORDER}</li>
055     * <li>{@link #VALUE}</li>
056     * </ul>
057     *
058     * @version $Id: //open/mondrian/src/main/mondrian/olap/Property.java#30 $
059     * @author jhyde
060     */
061    public class Property extends EnumeratedValues.BasicValue {
062    
063        public enum Datatype {
064            TYPE_STRING,
065            TYPE_NUMERIC,
066            TYPE_BOOLEAN,
067            TYPE_OTHER
068        }
069    
070        /**
071         * For properties which have synonyms, maps from the synonym to the
072         * property.
073         */
074        private static final Map<String, Property> synonyms =
075            new HashMap<String, Property>();
076    
077        /**
078         * Map of upper-case names to property definitions, for case-insensitive
079         * match. Also contains synonyms.
080         */
081        public static final Map<String, Property> mapUpperNameToProperties =
082            new HashMap<String, Property>();
083    
084        public static final int FORMAT_EXP_ORDINAL = 0;
085        /**
086         * Definition of the internal property which
087         * holds the parsed format string (an object of type {@link Exp}).
088         */
089        public static final Property FORMAT_EXP =
090                new Property("$format_exp", Datatype.TYPE_OTHER, FORMAT_EXP_ORDINAL, true, false, false, null);
091    
092        public static final int AGGREGATION_TYPE_ORDINAL = 1;
093        /**
094         * Definition of the internal property which
095         * holds the aggregation type. This is automatically set for stored
096         * measures, based upon their SQL aggregation.
097         */
098        public static final Property AGGREGATION_TYPE =
099                new Property("$aggregation_type", Datatype.TYPE_OTHER, AGGREGATION_TYPE_ORDINAL, true, false, false, null);
100    
101        public static final int NAME_ORDINAL = 2;
102    
103        /**
104         * Definition of the internal property which
105         * holds a member's name.
106         */
107        public static final Property NAME =
108                new Property("$name", Datatype.TYPE_STRING, NAME_ORDINAL, true, false, false, null);
109    
110        public static final int CAPTION_ORDINAL = 3;
111        /**
112         * Definition of the internal property which
113         * holds a member's caption.
114         */
115        public static final Property CAPTION =
116                new Property("$caption", Datatype.TYPE_STRING, CAPTION_ORDINAL, true, false, false, null);
117    
118        public static final int CONTRIBUTING_CHILDREN_ORDINAL = 4;
119        /**
120         * Definition of the internal property which
121         * holds, for a member of a  parent-child hierarchy, a
122         * {@link java.util.List} containing the member's data
123         * member and all of its children (including non-visible children).
124         */
125        public static final Property CONTRIBUTING_CHILDREN =
126                new Property("$contributingChildren", Datatype.TYPE_OTHER, CONTRIBUTING_CHILDREN_ORDINAL, true, false, false, null);
127    
128        public static final int FORMULA_ORDINAL = 5;
129        /**
130         * Definition of the internal property which
131         * returns a calculated member's {@link Formula} object.
132         */
133        public static final Property FORMULA =
134                new Property("$formula", Datatype.TYPE_OTHER, FORMULA_ORDINAL, true, false, false, null);
135    
136        public static final int MEMBER_SCOPE_ORDINAL = 6;
137        /**
138         * Definition of the internal property which
139         * describes whether a calculated member belongs to a query or a cube.
140         */
141        public static final Property MEMBER_SCOPE =
142                new Property("$member_scope", Datatype.TYPE_OTHER, MEMBER_SCOPE_ORDINAL, true, true, false, null);
143    
144        public static final int CATALOG_NAME_ORDINAL = 10;
145        /**
146         * Definition of the property which
147         * holds the name of the current catalog.
148         */
149        public static final Property CATALOG_NAME =
150                new Property("CATALOG_NAME", Datatype.TYPE_STRING, CATALOG_NAME_ORDINAL, false, true, false, "Optional. The name of the catalog to which this member belongs. NULL if the provider does not support catalogs.");
151    
152        public static final int SCHEMA_NAME_ORDINAL = 11;
153        /**
154         * Definition of the property which
155         * holds the name of the current schema.
156         */
157        public static final Property SCHEMA_NAME =
158                new Property("SCHEMA_NAME", Datatype.TYPE_STRING, SCHEMA_NAME_ORDINAL, false, true, false, "Optional. The name of the schema to which this member belongs. NULL if the provider does not support schemas.");
159    
160        public static final int CUBE_NAME_ORDINAL = 12;
161        /**
162         * Definition of the property which
163         * holds the name of the current cube.
164         */
165        public static final Property CUBE_NAME =
166                new Property("CUBE_NAME", Datatype.TYPE_STRING, CUBE_NAME_ORDINAL, false, true, false, "Required. Name of the cube to which this member belongs.");
167    
168        public static final int DIMENSION_UNIQUE_NAME_ORDINAL = 13;
169        /**
170         * Definition of the property which
171         * holds the unique name of the current dimension.
172         */
173        public static final Property DIMENSION_UNIQUE_NAME =
174                new Property("DIMENSION_UNIQUE_NAME", Datatype.TYPE_STRING, DIMENSION_UNIQUE_NAME_ORDINAL, false, true, false, "Required. Unique name of the dimension to which this member belongs. For providers that generate unique names by qualification, each component of this name is delimited.");
175    
176        public static final int HIERARCHY_UNIQUE_NAME_ORDINAL = 14;
177        /**
178         * Definition of the property which
179         * holds the unique name of the current hierarchy.
180         */
181        public static final Property HIERARCHY_UNIQUE_NAME =
182                new Property("HIERARCHY_UNIQUE_NAME", Datatype.TYPE_STRING, HIERARCHY_UNIQUE_NAME_ORDINAL, false, true, false, "Required. Unique name of the hierarchy. If the member belongs to more than one hierarchy, there is one row for each hierarchy to which it belongs. For providers that generate unique names by qualification, each component of this name is delimited.");
183    
184        public static final int LEVEL_UNIQUE_NAME_ORDINAL = 15;
185        /**
186         * Definition of the property which
187         * holds the unique name of the current level.
188         */
189        public static final Property LEVEL_UNIQUE_NAME =
190                new Property("LEVEL_UNIQUE_NAME", Datatype.TYPE_STRING, LEVEL_UNIQUE_NAME_ORDINAL, false, true, false, "Required. Unique name of the level to which the member belongs. For providers that generate unique names by qualification, each component of this name is delimited.");
191    
192        public static final int LEVEL_NUMBER_ORDINAL = 16;
193        /**
194         * Definition of the property which
195         * holds the ordinal of the current level.
196         */
197        public static final Property LEVEL_NUMBER =
198                new Property("LEVEL_NUMBER", Datatype.TYPE_STRING, LEVEL_NUMBER_ORDINAL, false, true, false, "Required. The distance of the member from the root of the hierarchy. The root level is zero.");
199    
200        public static final int MEMBER_ORDINAL_ORDINAL = 17;
201        /**
202         * Definition of the property which
203         * holds the ordinal of the current member.
204         */
205        public static final Property MEMBER_ORDINAL =
206                new Property("MEMBER_ORDINAL", Datatype.TYPE_NUMERIC, MEMBER_ORDINAL_ORDINAL, false, true, false, "Required. Ordinal number of the member. Sort rank of the member when members of this dimension are sorted in their natural sort order. If providers do not have the concept of natural ordering, this should be the rank when sorted by MEMBER_NAME.");
207    
208        public static final int MEMBER_NAME_ORDINAL = 18;
209        /**
210         * Definition of the property which
211         * holds the name of the current member.
212         */
213        public static final Property MEMBER_NAME =
214                new Property("MEMBER_NAME", Datatype.TYPE_STRING, MEMBER_NAME_ORDINAL, false, true, false, "Required. Name of the member.");
215    
216        public static final int MEMBER_UNIQUE_NAME_ORDINAL = 19;
217        /**
218         * Definition of the property which
219         * holds the unique name of the current member.
220         */
221        public static final Property MEMBER_UNIQUE_NAME =
222                new Property("MEMBER_UNIQUE_NAME", Datatype.TYPE_STRING, MEMBER_UNIQUE_NAME_ORDINAL, false, true, false, "Required. Unique name of the member. For providers that generate unique names by qualification, each component of this name is delimited.");
223    
224        public static final int MEMBER_TYPE_ORDINAL = 20;
225        /**
226         * Definition of the property which
227         * holds the type of the member.
228         */
229        public static final Property MEMBER_TYPE =
230                new Property("MEMBER_TYPE", Datatype.TYPE_STRING, MEMBER_TYPE_ORDINAL, false, true, false, "Required. Type of the member. Can be one of the following values: MDMEMBER_TYPE_REGULAR, MDMEMBER_TYPE_ALL, MDMEMBER_TYPE_FORMULA, MDMEMBER_TYPE_MEASURE, MDMEMBER_TYPE_UNKNOWN. MDMEMBER_TYPE_FORMULA takes precedence over MDMEMBER_TYPE_MEASURE. Therefore, if there is a formula (calculated) member on the Measures dimension, it is listed as MDMEMBER_TYPE_FORMULA.");
231    
232        public static final int MEMBER_GUID_ORDINAL = 21;
233        /**
234         * Definition of the property which
235         * holds the GUID of the member
236         */
237        public static final Property MEMBER_GUID =
238                new Property("MEMBER_GUID", Datatype.TYPE_STRING, MEMBER_GUID_ORDINAL, false, true, false, "Optional. Member GUID. NULL if no GUID exists.");
239    
240        public static final int MEMBER_CAPTION_ORDINAL = 22;
241        /**
242         * Definition of the property which
243         * holds the label or caption associated with the member, or the
244         * member's name if no caption is defined.
245         *
246         * <p>"CAPTION" is a synonym for this property.
247         */
248        public static final Property MEMBER_CAPTION =
249                new Property("MEMBER_CAPTION", Datatype.TYPE_STRING, MEMBER_CAPTION_ORDINAL, false, true, false, "Required. A label or caption associated with the member. Used primarily for display purposes. If a caption does not exist, MEMBER_NAME is returned.");
250    
251        public static final int CHILDREN_CARDINALITY_ORDINAL = 23;
252        /**
253         * Definition of the property which holds the
254         * number of children this member has.
255         */
256        public static final Property CHILDREN_CARDINALITY =
257                new Property("CHILDREN_CARDINALITY", Datatype.TYPE_NUMERIC, CHILDREN_CARDINALITY_ORDINAL, false, true, false, "Required. Number of children that the member has. This can be an estimate, so consumers should not rely on this to be the exact count. Providers should return the best estimate possible.");
258    
259        public static final int PARENT_LEVEL_ORDINAL = 24;
260        /**
261         * Definition of the property which holds the
262         * distance from the root of the hierarchy of this member's parent.
263         */
264        public static final Property PARENT_LEVEL =
265                new Property("PARENT_LEVEL", Datatype.TYPE_NUMERIC, PARENT_LEVEL_ORDINAL, false, true, false, "Required. The distance of the member's parent from the root level of the hierarchy. The root level is zero.");
266    
267        public static final int PARENT_UNIQUE_NAME_ORDINAL = 25;
268        /**
269         * Definition of the property which holds the
270         * Name of the current catalog.
271         */
272        public static final Property PARENT_UNIQUE_NAME =
273                new Property("PARENT_UNIQUE_NAME", Datatype.TYPE_STRING, PARENT_UNIQUE_NAME_ORDINAL, false, true, false, "Required. Unique name of the member's parent. NULL is returned for any members at the root level. For providers that generate unique names by qualification, each component of this name is delimited.");
274    
275        public static final int PARENT_COUNT_ORDINAL = 26;
276        /**
277         * Definition of the property which holds the
278         * number of parents that this member has. Generally 1, or 0 for root members.
279         */
280        public static final Property PARENT_COUNT =
281                new Property("PARENT_COUNT", Datatype.TYPE_NUMERIC, PARENT_COUNT_ORDINAL, false, true, false, "Required. Number of parents that this member has.");
282    
283        public static final int DESCRIPTION_ORDINAL = 27;
284        /**
285         * Definition of the property which holds the
286         * description of this member.
287         */
288        public static final Property DESCRIPTION =
289                new Property("DESCRIPTION", Datatype.TYPE_STRING, DESCRIPTION_ORDINAL, false, true, false, "Optional. A human-readable description of the member.");
290    
291        public static final int VISIBLE_ORDINAL = 28;
292        /**
293         * Definition of the internal property which holds the
294         * name of the system property which determines whether to show a member
295         * (especially a measure or calculated member) in a user interface such as
296         * JPivot.
297         */
298        public static final Property VISIBLE =
299                new Property("$visible", Datatype.TYPE_BOOLEAN, VISIBLE_ORDINAL, true, false, false, null);
300    
301        public static final int CELL_FORMATTER_ORDINAL = 29;
302        /**
303         * Definition of the property which holds the
304         * name of the class which formats cell values of this member.
305         *
306         * <p>The class must implement the {@link CellFormatter} interface.
307         *
308         * <p>Despite its name, this is a member property.
309         */
310        public static final Property CELL_FORMATTER =
311                new Property("CELL_FORMATTER", Datatype.TYPE_STRING, CELL_FORMATTER_ORDINAL, false, true, false, "Name of the class which formats cell values of this member.");
312    
313        // Cell properties
314    
315    
316        public static final int BACK_COLOR_ORDINAL = 30;
317        public static final Property BACK_COLOR =
318                new Property("BACK_COLOR", Datatype.TYPE_STRING, BACK_COLOR_ORDINAL, false, false, true, "The background color for displaying the VALUE or FORMATTED_VALUE property. For more information, see FORE_COLOR and BACK_COLOR Contents.");
319    
320        public static final int CELL_EVALUATION_LIST_ORDINAL = 31;
321        public static final Property CELL_EVALUATION_LIST =
322                new Property("CELL_EVALUATION_LIST", Datatype.TYPE_STRING, CELL_EVALUATION_LIST_ORDINAL, false, false, true, "The semicolon-delimited list of evaluated formulas applicable to the cell, in order from lowest to highest solve order. For more information about solve order, see Understanding Pass Order and Solve Order");
323    
324        public static final int CELL_ORDINAL_ORDINAL = 32;
325        public static final Property CELL_ORDINAL =
326                new Property("CELL_ORDINAL", Datatype.TYPE_NUMERIC, CELL_ORDINAL_ORDINAL, false, false, true, "The ordinal number of the cell in the dataset.");
327    
328        public static final int FORE_COLOR_ORDINAL = 33;
329        public static final Property FORE_COLOR =
330                new Property("FORE_COLOR", Datatype.TYPE_STRING, FORE_COLOR_ORDINAL, false, false, true, "The foreground color for displaying the VALUE or FORMATTED_VALUE property. For more information, see FORE_COLOR and BACK_COLOR Contents.");
331    
332        public static final int FONT_NAME_ORDINAL = 34;
333        public static final Property FONT_NAME =
334                new Property("FONT_NAME", Datatype.TYPE_STRING, FONT_NAME_ORDINAL, false, false, true, "The font to be used to display the VALUE or FORMATTED_VALUE property.");
335    
336        public static final int FONT_SIZE_ORDINAL = 35;
337        public static final Property FONT_SIZE =
338                new Property("FONT_SIZE", Datatype.TYPE_STRING, FONT_SIZE_ORDINAL, false, false, true, "Font size to be used to display the VALUE or FORMATTED_VALUE property.");
339    
340        public static final int FONT_FLAGS_ORDINAL = 36;
341        public static final Property FONT_FLAGS =
342                new Property("FONT_FLAGS", Datatype.TYPE_NUMERIC, FONT_FLAGS_ORDINAL, false, false, true, "The bitmask detailing effects on the font. The value is the result of a bitwise OR operation of one or more of the following constants: MDFF_BOLD  = 1, MDFF_ITALIC = 2, MDFF_UNDERLINE = 4, MDFF_STRIKEOUT = 8. For example, the value 5 represents the combination of bold (MDFF_BOLD) and underline (MDFF_UNDERLINE) font effects.");
343    
344    
345        public static final int FORMATTED_VALUE_ORDINAL = 37;
346        /**
347         * Definition of the property which
348         * holds the formatted value of a cell.
349         */
350        public static final Property FORMATTED_VALUE =
351                new Property("FORMATTED_VALUE", Datatype.TYPE_STRING, FORMATTED_VALUE_ORDINAL, false, false, true, "The character string that represents a formatted display of the VALUE property.");
352    
353        public static final int FORMAT_STRING_ORDINAL = 38;
354        /**
355         * Definition of the property which
356         * holds the format string used to format cell values.
357         */
358        public static final Property FORMAT_STRING =
359                new Property("FORMAT_STRING", Datatype.TYPE_STRING, FORMAT_STRING_ORDINAL, false, false, true, "The format string used to create the FORMATTED_VALUE property value. For more information, see FORMAT_STRING Contents.");
360    
361        public static final int NON_EMPTY_BEHAVIOR_ORDINAL = 39;
362        public static final Property NON_EMPTY_BEHAVIOR =
363                new Property("NON_EMPTY_BEHAVIOR", Datatype.TYPE_STRING, NON_EMPTY_BEHAVIOR_ORDINAL, false, false, true, "The measure used to determine the behavior of calculated members when resolving empty cells.");
364    
365        public static final int SOLVE_ORDER_ORDINAL = 40;
366        /**
367         * Definition of the property which
368         * determines the solve order of a calculated member with respect to other
369         * calculated members.
370         */
371        public static final Property SOLVE_ORDER =
372                new Property("SOLVE_ORDER", Datatype.TYPE_NUMERIC, SOLVE_ORDER_ORDINAL, false, false, true, "The solve order of the cell.");
373    
374        public static final int VALUE_ORDINAL = 41;
375        /**
376         * Definition of the property which
377         * holds the value of a cell. Is usually numeric (since most measures are
378         * numeric) but is occasionally another type.
379         *
380         * <p>It is also applicable to members.
381         */
382        public static final Property VALUE =
383                new Property("VALUE", Datatype.TYPE_NUMERIC, VALUE_ORDINAL, false, true, true, "The unformatted value of the cell.");
384    
385        public static final int DATATYPE_ORDINAL = 42;
386        /**
387         * Definition of the property which
388         * holds the datatype of a cell. Valid values are "String",
389         * "Numeric", "Integer". The property's value derives from the
390         * "datatype" attribute of the "Measure" element; if the datatype attribute
391         * is not specified, the datatype is "Numeric" by default, except measures
392         * whose aggregator is "Count", whose datatype is "Integer".
393         */
394        public static final Property DATATYPE =
395                new Property("DATATYPE", Datatype.TYPE_STRING, DATATYPE_ORDINAL, false, false, true, "The datatype of the cell.");
396    
397        public static final int DEPTH_ORDINAL = 43;
398        /**
399         * Definition of the property which
400         * holds the level depth of a member.
401         * Caution: Level depth of members in parent-child hierarchy isn't from their levels.
402         * It's calculated from the underlying data dynamically.
403         */
404        public static final Property DEPTH =
405                new Property("DEPTH", Datatype.TYPE_NUMERIC, DEPTH_ORDINAL, true, true, false, "The level depth of a member");
406    
407        public static final int DISPLAY_INFO_ORDINAL = 44;
408        /**
409         * Definition of the property which
410         * holds the DISPLAY_INFO required by XML/A
411         * Caution: This property's value is calculated base on a specified MDX query, so it's value is dynamical at runtime.
412         */
413        public static final Property DISPLAY_INFO =
414                new Property("DISPLAY_INFO", Datatype.TYPE_NUMERIC, DISPLAY_INFO_ORDINAL, false, true, false, "Display instruction of a member for XML/A");
415    
416         public static final int MEMBER_KEY_ORDINAL = 45;
417        /**
418         * Definition of the property which
419         * holds the member key of the current member.
420         */
421        public static final Property MEMBER_KEY =
422                new Property("MEMBER_KEY", Datatype.TYPE_STRING, MEMBER_KEY_ORDINAL, false, true, false, "Member key.");
423    
424         public static final int KEY_ORDINAL = 46;
425        /**
426         * Definition of the property which
427         * holds the key of the current member.
428         */
429        public static final Property KEY =
430                new Property("KEY", Datatype.TYPE_STRING, KEY_ORDINAL, false, true, false, "Key.");
431    
432        public static final int UNIQUE_NAME_WITHOUT_HIERARCHY_ORDINAL = 47;
433        /**
434         * Definition of the internal property which
435         * describes the unique name of a member minus it's
436         * hierarchy.
437         */
438        public static final Property UNIQUE_NAME_WITHOUT_HIERARCHY =
439                new Property("$unique_name_without_hierarchy", Datatype.TYPE_STRING, UNIQUE_NAME_WITHOUT_HIERARCHY_ORDINAL, true, true, false, null);
440    
441    
442        /**
443         * The various property names which define a format string.
444         */
445        static final String[] FORMAT_PROPERTIES = {
446            "format", "format_string", "FORMAT", FORMAT_STRING.name,
447        };
448    
449        // ~ Data members ---------------------------------------------------------
450    
451        /**
452         * The datatype of the property.
453         */
454        private final Datatype type;
455    
456        /**
457         * Whether the property is internal.
458         */
459        private final boolean internal;
460        private final boolean member;
461        private final boolean cell;
462    
463        private static int nextOrdinal = 100;
464    
465        // ~ Methods --------------------------------------------------------------
466    
467        /**
468         * Creates a property definition. If ordinal is negative, generates a
469         * unique positive ordinal.
470         */
471        protected Property(
472                String name,
473                Datatype type,
474                int ordinal,
475                boolean internal,
476                boolean member,
477                boolean cell,
478                String description) {
479            super(name, ordinal < 0 ? nextOrdinal++ : ordinal, description);
480            this.type = type;
481            this.internal = internal;
482            this.member = member;
483            this.cell = cell;
484        }
485    
486        /**
487         * Returns the datatype of the property.
488         */
489        public Datatype getType() {
490            return type;
491        }
492    
493        public PropertyFormatter getFormatter() {
494            return null;
495        }
496    
497        /**
498         * Returns the caption of this property.
499         */
500        public String getCaption() {
501            return name;
502        }
503    
504        /**
505         * Returns whether this property is for system use only.
506         */
507        public boolean isInternal() {
508            return internal;
509        }
510    
511        /**
512         * Returns whether this property is a standard member property.
513         */
514        public boolean isMemberProperty() {
515            return member;
516        }
517    
518        /**
519         * Returns whether this property is a standard member property.
520         */
521        public boolean isCellProperty() {
522            return cell && ordinal <= VALUE_ORDINAL;
523        }
524    
525        /**
526         * Returns whether this property is standard.
527         */
528        public boolean isStandard() {
529            return ordinal <= VALUE_ORDINAL;
530        }
531    
532    
533        public static final EnumeratedValues<Property> enumeration =
534            new EnumeratedValues<Property>(
535                new Property[] {
536                    FORMAT_EXP,
537                    AGGREGATION_TYPE,
538                    NAME,
539                    CAPTION,
540                    CONTRIBUTING_CHILDREN,
541                    FORMULA,
542                    CATALOG_NAME,
543                    SCHEMA_NAME,
544                    CUBE_NAME,
545                    DIMENSION_UNIQUE_NAME,
546                    HIERARCHY_UNIQUE_NAME,
547                    LEVEL_UNIQUE_NAME,
548                    LEVEL_NUMBER,
549                    MEMBER_UNIQUE_NAME,
550                    MEMBER_NAME,
551                    MEMBER_TYPE,
552                    MEMBER_GUID,
553                    MEMBER_CAPTION,
554                    MEMBER_ORDINAL,
555                    CHILDREN_CARDINALITY,
556                    PARENT_LEVEL,
557                    PARENT_UNIQUE_NAME,
558                    PARENT_COUNT,
559                    DESCRIPTION,
560                    VISIBLE,
561                    CELL_FORMATTER,
562                    BACK_COLOR,
563                    CELL_EVALUATION_LIST,
564                    CELL_ORDINAL,
565                    FORE_COLOR,
566                    FONT_NAME,
567                    FONT_SIZE,
568                    FONT_FLAGS,
569                    FORMAT_STRING,
570                    FORMATTED_VALUE,
571                    NON_EMPTY_BEHAVIOR,
572                    SOLVE_ORDER,
573                    VALUE,
574                    DATATYPE,
575                    MEMBER_KEY,
576                    KEY,
577                    UNIQUE_NAME_WITHOUT_HIERARCHY
578                });
579    
580        static {
581            // Populate synonyms.
582            synonyms.put("CAPTION", MEMBER_CAPTION);
583            synonyms.put("FORMAT", FORMAT_STRING);
584    
585            // Populate map of upper-case property names.
586            for (String propertyName : enumeration.getNames()) {
587                mapUpperNameToProperties.put(
588                    propertyName.toUpperCase(),
589                    enumeration.getValue(propertyName, true));
590            }
591    
592            // Add synonyms.
593            for (Map.Entry<String,Property> entry : synonyms.entrySet()) {
594                mapUpperNameToProperties.put(
595                    entry.getKey().toUpperCase(), entry.getValue());
596            }
597        }
598    
599        /**
600         * Looks up a Property with a given ordinal.
601         * Returns null if not found.
602         */
603        public static Property lookup(int ordinal) {
604            return enumeration.getValue(ordinal);
605        }
606    
607        /**
608         * Looks up a Property with a given name.
609         *
610         * @param name Name of property
611         * @param matchCase Whether to perform case-sensitive match
612         * @return Property with given name, or null if not found.
613         */
614        public static Property lookup(String name, boolean matchCase) {
615            if (matchCase) {
616                Property property = enumeration.getValue(name, false);
617                if (property != null) {
618                    return property;
619                }
620                return synonyms.get(name);
621            } else {
622                // No need to check synonyms separately - the map contains them.
623                return mapUpperNameToProperties.get(name.toUpperCase());
624            }
625        }
626    }
627    
628    // End Property.java