001/*
002// This software is subject to the terms of the Eclipse Public License v1.0
003// Agreement, available at the following URL:
004// http://www.eclipse.org/legal/epl-v10.html.
005// You must accept the terms of that agreement to use this software.
006//
007// Copyright (C) 2001-2005 Julian Hyde
008// Copyright (C) 2005-2011 Pentaho and others
009// All Rights Reserved.
010*/
011package mondrian.olap;
012
013import org.apache.log4j.Logger;
014
015import java.util.Locale;
016import java.util.Map;
017
018/**
019 * <code>OlapElementBase</code> is an abstract base class for implementations of
020 * {@link OlapElement}.
021 *
022 * @author jhyde
023 * @since 6 August, 2001
024 */
025public abstract class OlapElementBase
026    implements OlapElement
027{
028    protected String caption = null;
029
030    protected boolean visible = true;
031
032    // cache hash-code because it is often used and elements are immutable
033    private int hash;
034
035    protected OlapElementBase() {
036    }
037
038    protected abstract Logger getLogger();
039
040    public boolean equals(Object o) {
041        return (o == this)
042           || ((o instanceof OlapElement)
043               && equals((OlapElement) o));
044    }
045
046    public boolean equals(OlapElement mdxElement) {
047        return mdxElement != null
048           && getClass() == mdxElement.getClass()
049           && getUniqueName().equalsIgnoreCase(mdxElement.getUniqueName());
050    }
051
052    public int hashCode() {
053        if (hash == 0) {
054            hash = computeHashCode();
055        }
056        return hash;
057    }
058
059    /**
060     * Computes this object's hash code. Called at most once.
061     *
062     * @return hash code
063     */
064    protected int computeHashCode() {
065        return (getClass().hashCode() << 8) ^ getUniqueName().hashCode();
066    }
067
068    public String toString() {
069        return getUniqueName();
070    }
071
072    public Object clone() {
073        return this;
074    }
075
076    /**
077     * Returns the display name of this catalog element.
078     * If no caption is defined, the name is returned.
079     */
080    public String getCaption() {
081        if (caption != null) {
082            return caption;
083        } else {
084            return getName();
085        }
086    }
087
088    /**
089     * Sets the display name of this catalog element.
090     */
091    public void setCaption(String caption) {
092        this.caption = caption;
093    }
094
095    public boolean isVisible() {
096        return visible;
097    }
098
099    public String getLocalized(LocalizedProperty prop, Locale locale) {
100        if (this instanceof Annotated) {
101            Annotated annotated = (Annotated) this;
102            final Map<String, Annotation> annotationMap =
103                annotated.getAnnotationMap();
104            if (!annotationMap.isEmpty()) {
105                String seek = prop.name().toLowerCase() + "." + locale;
106                for (;;) {
107                    for (Map.Entry<String, Annotation> entry
108                        : annotationMap.entrySet())
109                    {
110                        if (entry.getKey().startsWith(seek)) {
111                            return entry.getValue().getValue().toString();
112                        }
113                    }
114
115                    // No match for locale. Is there a match for the parent
116                    // locale? For example, we've just looked for
117                    // 'caption.en_US', now look for 'caption.en'.
118                    final int underscore = seek.lastIndexOf('_');
119                    if (underscore < 0) {
120                        break;
121                    }
122                    seek = seek.substring(0, underscore - 1);
123                }
124            }
125        }
126
127        // No annotation. Fall back to the default caption/description.
128        switch (prop) {
129        case CAPTION:
130            return getCaption();
131        case DESCRIPTION:
132            return getDescription();
133        default:
134            throw Util.unexpected(prop);
135        }
136    }
137}
138
139// End OlapElementBase.java