001    /*
002    // $Id: //open/mondrian-release/3.2/src/main/mondrian/olap/MondrianServerImpl.java#1 $
003    // This software is subject to the terms of the Eclipse Public License v1.0
004    // Agreement, available at the following URL:
005    // http://www.eclipse.org/legal/epl-v10.html.
006    // Copyright (C) 2006-2010 Julian Hyde
007    // All Rights Reserved.
008    // You must accept the terms of that agreement to use this software.
009    */
010    package mondrian.olap;
011    
012    import java.net.URL;
013    import java.io.*;
014    import java.util.regex.Pattern;
015    import java.util.regex.Matcher;
016    import java.util.List;
017    import java.util.Collections;
018    import java.util.Arrays;
019    
020    /**
021     * Implementation of {@link MondrianServer}.
022     *
023     * @author jhyde
024     * @version $Id: //open/mondrian-release/3.2/src/main/mondrian/olap/MondrianServerImpl.java#1 $
025     * @since Jun 25, 2006
026     */
027    class MondrianServerImpl extends MondrianServer {
028        private static MondrianVersion version = null;
029        public static final String[] keywords = new String[] {
030            "$AdjustedProbability", "$Distance", "$Probability",
031            "$ProbabilityStDev", "$ProbabilityStdDeV", "$ProbabilityVariance",
032            "$StDev", "$StdDeV", "$Support", "$Variance",
033            "AddCalculatedMembers", "Action", "After", "Aggregate", "All",
034            "Alter", "Ancestor", "And", "Append", "As", "ASC", "Axis",
035            "Automatic", "Back_Color", "BASC", "BDESC", "Before",
036            "Before_And_After", "Before_And_Self", "Before_Self_After",
037            "BottomCount", "BottomPercent", "BottomSum", "Break", "Boolean",
038            "Cache", "Calculated", "Call", "Case", "Catalog_Name", "Cell",
039            "Cell_Ordinal", "Cells", "Chapters", "Children",
040            "Children_Cardinality", "ClosingPeriod", "Cluster",
041            "ClusterDistance", "ClusterProbability", "Clusters",
042            "CoalesceEmpty", "Column_Values", "Columns", "Content",
043            "Contingent", "Continuous", "Correlation", "Cousin", "Covariance",
044            "CovarianceN", "Create", "CreatePropertySet", "CrossJoin", "Cube",
045            "Cube_Name", "CurrentMember", "CurrentCube", "Custom", "Cyclical",
046            "DefaultMember", "Default_Member", "DESC", "Descendents",
047            "Description", "Dimension", "Dimension_Unique_Name", "Dimensions",
048            "Discrete", "Discretized", "DrillDownLevel",
049            "DrillDownLevelBottom", "DrillDownLevelTop", "DrillDownMember",
050            "DrillDownMemberBottom", "DrillDownMemberTop", "DrillTrough",
051            "DrillUpLevel", "DrillUpMember", "Drop", "Else", "Empty", "End",
052            "Equal_Areas", "Exclude_Null", "ExcludeEmpty", "Exclusive",
053            "Expression", "Filter", "FirstChild", "FirstRowset",
054            "FirstSibling", "Flattened", "Font_Flags", "Font_Name",
055            "Font_size", "Fore_Color", "Format_String", "Formatted_Value",
056            "Formula", "From", "Generate", "Global", "Head", "Hierarchize",
057            "Hierarchy", "Hierary_Unique_name", "IIF", "IsEmpty",
058            "Include_Null", "Include_Statistics", "Inclusive", "Input_Only",
059            "IsDescendant", "Item", "Lag", "LastChild", "LastPeriods",
060            "LastSibling", "Lead", "Level", "Level_Unique_Name", "Levels",
061            "LinRegIntercept", "LinRegR2", "LinRegPoint", "LinRegSlope",
062            "LinRegVariance", "Long", "MaxRows", "Median", "Member",
063            "Member_Caption", "Member_Guid", "Member_Name", "Member_Ordinal",
064            "Member_Type", "Member_Unique_Name", "Members",
065            "Microsoft_Clustering", "Microsoft_Decision_Trees", "Mining",
066            "Model", "Model_Existence_Only", "Models", "Move", "MTD", "Name",
067            "Nest", "NextMember", "Non", "Normal", "Not", "Ntext", "Nvarchar",
068            "OLAP", "On", "OpeningPeriod", "OpenQuery", "Or", "Ordered",
069            "Ordinal", "Pages", "Pages", "ParallelPeriod", "Parent",
070            "Parent_Level", "Parent_Unique_Name", "PeriodsToDate", "PMML",
071            "Predict", "Predict_Only", "PredictAdjustedProbability",
072            "PredictHistogram", "Prediction", "PredictionScore",
073            "PredictProbability", "PredictProbabilityStDev",
074            "PredictProbabilityVariance", "PredictStDev", "PredictSupport",
075            "PredictVariance", "PrevMember", "Probability",
076            "Probability_StDev", "Probability_StdDev", "Probability_Variance",
077            "Properties", "Property", "QTD", "RangeMax", "RangeMid",
078            "RangeMin", "Rank", "Recursive", "Refresh", "Related", "Rename",
079            "Rollup", "Rows", "Schema_Name", "Sections", "Select", "Self",
080            "Self_And_After", "Sequence_Time", "Server", "Session", "Set",
081            "SetToArray", "SetToStr", "Shape", "Skip", "Solve_Order", "Sort",
082            "StdDev", "Stdev", "StripCalculatedMembers", "StrToSet",
083            "StrToTuple", "SubSet", "Support", "Tail", "Text", "Thresholds",
084            "ToggleDrillState", "TopCount", "TopPercent", "TopSum",
085            "TupleToStr", "Under", "Uniform", "UniqueName", "Use", "Value",
086            "Value", "Var", "Variance", "VarP", "VarianceP", "VisualTotals",
087            "When", "Where", "With", "WTD", "Xor",
088        };
089    
090        public MondrianVersion getVersion() {
091            return getVersionStatic();
092        }
093    
094        public List<String> getKeywords() {
095            return Collections.unmodifiableList(Arrays.asList(keywords));
096        }
097    
098        private static synchronized MondrianVersion getVersionStatic() {
099            if (version == null) {
100                final String[] vendorTitleVersion = loadVersionFile();
101                String vendor = vendorTitleVersion[0];
102                final String title = vendorTitleVersion[1];
103                final String versionString = vendorTitleVersion[2];
104                if (false) {
105                    System.out.println(
106                        "vendor=" + vendor
107                        + ", title=" + title
108                        + ", versionString=" + versionString);
109                }
110                int dot1 = versionString.indexOf('.');
111                final int majorVersion =
112                    dot1 < 0
113                    ? 1
114                    : Integer.valueOf(versionString.substring(0, dot1));
115                int dot2 = versionString.indexOf('.', dot1 + 1);
116                final int minorVersion =
117                    dot2 < 0
118                    ? 0
119                    : Integer.valueOf(versionString.substring(dot1 + 1, dot2));
120                version = new MondrianVersion() {
121                    public String getVersionString() {
122                        return versionString;
123                    }
124    
125                    public int getMajorVersion() {
126                        return majorVersion;
127                    }
128    
129                    public int getMinorVersion() {
130                        return minorVersion;
131                    }
132    
133                    public String getProductName() {
134                        return title;
135                    }
136                };
137            }
138            return version;
139        }
140    
141        private static String[] loadVersionFile() {
142            // First, try to read the version info from the package. If the classes
143            // came from a jar, this info will be set from manifest.mf.
144            Package pakkage = MondrianServerImpl.class.getPackage();
145            String implementationVersion = pakkage.getImplementationVersion();
146    
147            // Second, try to read VERSION.txt.
148            String version = null;
149            String title = null;
150            String vendor = null;
151            URL resource =
152                MondrianServerImpl.class.getClassLoader()
153                    .getResource("DefaultRules.xml");
154            if (resource != null) {
155                try {
156                    String path = resource.getPath();
157                    String path2 =
158                        Util.replace(
159                            path, "DefaultRules.xml", "VERSION.txt");
160                    URL resource2 =
161                        new URL(
162                            resource.getProtocol(),
163                            resource.getHost(),
164                            path2);
165                    String versionString = Util.readURL(resource2);
166                    Pattern pattern =
167                        Pattern.compile(
168                            "(?s)Title: (.*)\nVersion: (.*)\nVendor: (.*)\n.*");
169                    Matcher matcher = pattern.matcher(versionString);
170                    if (matcher.matches()) {
171                        int groupCount = matcher.groupCount();
172                        assert groupCount == 3;
173                        title = matcher.group(1);
174                        version = matcher.group(2);
175                        vendor = matcher.group(3);
176                    }
177                } catch (IOException e) {
178                    // ignore exception - it's OK if file is not found
179                    Util.discard(e);
180                }
181            }
182    
183            // Version from jar manifest overrides that from VERSION.txt.
184            if (implementationVersion != null) {
185                version = implementationVersion;
186            }
187            if (version == null) {
188                version = "Unknown version";
189            }
190            return new String[] {vendor, title, version};
191        }
192    }
193    
194    // End MondrianServerImpl.java