001    /*
002    // $Id: //open/mondrian/src/main/mondrian/olap/MondrianServerImpl.java#9 $
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) 2006-2007 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/src/main/mondrian/olap/MondrianServerImpl.java#9 $
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 ? 1 :
113                    Integer.valueOf(versionString.substring(0, dot1));
114                int dot2 = versionString.indexOf('.', dot1 + 1);
115                final int minorVersion =
116                    dot2 < 0 ? 0 :
117                    Integer.valueOf(versionString.substring(dot1 + 1, dot2));
118                version = new MondrianVersion() {
119                    public String getVersionString() {
120                        return versionString;
121                    }
122    
123                    public int getMajorVersion() {
124                        return majorVersion;
125                    }
126    
127                    public int getMinorVersion() {
128                        return minorVersion;
129                    }
130    
131                    public String getProductName() {
132                        return title;
133                    }
134                };
135            }
136            return version;
137        }
138    
139        private static String[] loadVersionFile() {
140            // First, try to read the version info from the package. If the classes
141            // came from a jar, this info will be set from manifest.mf.
142            Package pakkage = MondrianServerImpl.class.getPackage();
143            String implementationVersion = pakkage.getImplementationVersion();
144    
145            // Second, try to read VERSION.txt.
146            String version = null;
147            String title = null;
148            String vendor = null;
149            URL resource =
150                MondrianServerImpl.class.getClassLoader()
151                    .getResource("DefaultRules.xml");
152            if (resource != null) {
153                try {
154                    String path = resource.getPath();
155                    String path2 =
156                        Util.replace(
157                            path, "DefaultRules.xml", "VERSION.txt");
158                    URL resource2 =
159                        new URL(
160                            resource.getProtocol(),
161                            resource.getHost(),
162                            path2);
163                    String versionString = Util.readURL(resource2);
164                    Pattern pattern =
165                        Pattern.compile(
166                            "(?s)Title: (.*)\nVersion: (.*)\nVendor: (.*)\n.*");
167                    Matcher matcher = pattern.matcher(versionString);
168                    if (matcher.matches()) {
169                        int groupCount = matcher.groupCount();
170                        assert groupCount == 3;
171                        title = matcher.group(1);
172                        version = matcher.group(2);
173                        vendor = matcher.group(3);
174                    }
175                } catch (IOException e) {
176                    // ignore exception - it's OK if file is not found
177                    Util.discard(e);
178                }
179            }
180    
181            // Version from jar manifest overrides that from VERSION.txt.
182            if (implementationVersion != null) {
183                version = implementationVersion;
184            }
185            if (version == null) {
186                version = "Unknown version";
187            }
188            return new String[] {vendor, title, version};
189        }
190    }
191    
192    // End MondrianServerImpl.java