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