Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||
BrowserDetector |
|
| 3.909090909090909;3,909 |
1 | package org.apache.turbine.util; | |
2 | ||
3 | /* | |
4 | * Licensed to the Apache Software Foundation (ASF) under one | |
5 | * or more contributor license agreements. See the NOTICE file | |
6 | * distributed with this work for additional information | |
7 | * regarding copyright ownership. The ASF licenses this file | |
8 | * to you under the Apache License, Version 2.0 (the | |
9 | * "License"); you may not use this file except in compliance | |
10 | * with the License. You may obtain a copy of the License at | |
11 | * | |
12 | * http://www.apache.org/licenses/LICENSE-2.0 | |
13 | * | |
14 | * Unless required by applicable law or agreed to in writing, | |
15 | * software distributed under the License is distributed on an | |
16 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | |
17 | * KIND, either express or implied. See the License for the | |
18 | * specific language governing permissions and limitations | |
19 | * under the License. | |
20 | */ | |
21 | ||
22 | /** | |
23 | * This class parses the user agent string and sets javasciptOK and | |
24 | * cssOK following the rules described below. If you want to check | |
25 | * for specific browsers/versions then use this class to parse the | |
26 | * user agent string and use the accessor methods in this class. | |
27 | * | |
28 | * JavaScriptOK means that the browser understands JavaScript on the | |
29 | * same level the Navigator 3 does. Specifically, it can use named | |
30 | * images. This allows easier rollovers. If a browser doesn't do | |
31 | * this (Nav 2 or MSIE 3), then we just assume it can't do any | |
32 | * JavaScript. Referencing images by load order is too hard to | |
33 | * maintain. | |
34 | * | |
35 | * CSSOK is kind of sketchy in that Nav 4 and MSIE work differently, | |
36 | * but they do seem to have most of the functionality. MSIE 4 for the | |
37 | * Mac has buggy CSS support, so we let it do JavaScript, but no CSS. | |
38 | * | |
39 | * Ported from Leon's PHP code at | |
40 | * http://www.working-dogs.com/freetrade by Frank. | |
41 | * | |
42 | * @author <a href="mailto:frank.kim@clearink.com">Frank Y. Kim</a> | |
43 | * @author <a href="mailto:leon@clearink.com">Leon Atkisnon</a> | |
44 | * @author <a href="mailto:mospaw@polk-county.com">Chris Mospaw</a> | |
45 | * @author <a href="mailto:bgriffin@cddb.com">Benjamin Elijah Griffin</a> | |
46 | * @version $Id: BrowserDetector.java 1706239 2015-10-01 13:18:35Z tv $ | |
47 | */ | |
48 | public class BrowserDetector | |
49 | { | |
50 | /** Internet Explorer */ | |
51 | public static final String MSIE = "MSIE"; | |
52 | /** Opera */ | |
53 | public static final String OPERA = "Opera"; | |
54 | /** Mozilla, Firefox and friends */ | |
55 | public static final String MOZILLA = "Mozilla"; | |
56 | ||
57 | /** Running on Windows */ | |
58 | public static final String WINDOWS = "Windows"; | |
59 | /** Running on Unix */ | |
60 | public static final String UNIX = "Unix"; | |
61 | /** Running on Mac OS X */ | |
62 | public static final String MACINTOSH = "Macintosh"; | |
63 | ||
64 | /** The user agent string. */ | |
65 | 5 | private String userAgentString = ""; |
66 | ||
67 | /** The browser name specified in the user agent string. */ | |
68 | 5 | private String browserName = ""; |
69 | ||
70 | /** | |
71 | * The browser version specified in the user agent string. If we | |
72 | * can't parse the version just assume an old browser. | |
73 | */ | |
74 | 5 | private float browserVersion = (float) 1.0; |
75 | ||
76 | /** | |
77 | * The browser platform specified in the user agent string. | |
78 | */ | |
79 | 5 | private String browserPlatform = "unknown"; |
80 | ||
81 | /** Whether or not javascript works in this browser. */ | |
82 | 5 | private boolean javascriptOK = false; |
83 | ||
84 | /** Whether or not CSS works in this browser. */ | |
85 | 5 | private boolean cssOK = false; |
86 | ||
87 | /** Whether or not file upload works in this browser. */ | |
88 | 5 | private boolean fileUploadOK = false; |
89 | ||
90 | /** | |
91 | * Constructor used to initialize this class. | |
92 | * | |
93 | * @param userAgentString A String with the user agent field. | |
94 | */ | |
95 | public BrowserDetector(String userAgentString) | |
96 | 5 | { |
97 | 5 | this.userAgentString = userAgentString; |
98 | 5 | parse(); |
99 | 5 | } |
100 | ||
101 | /** | |
102 | * Constructor used to initialize this class. | |
103 | * | |
104 | * @param data The Turbine RunData object. | |
105 | */ | |
106 | public BrowserDetector(RunData data) | |
107 | 0 | { |
108 | 0 | this.userAgentString = data.getUserAgent(); |
109 | 0 | parse(); |
110 | 0 | } |
111 | ||
112 | /** | |
113 | * Whether or not CSS works in this browser. | |
114 | * | |
115 | * @return True if CSS works in this browser. | |
116 | */ | |
117 | public boolean isCssOK() | |
118 | { | |
119 | 0 | return cssOK; |
120 | } | |
121 | ||
122 | /** | |
123 | * Whether or not file upload works in this browser. | |
124 | * | |
125 | * @return True if file upload works in this browser. | |
126 | */ | |
127 | public boolean isFileUploadOK() | |
128 | { | |
129 | 0 | return fileUploadOK; |
130 | } | |
131 | ||
132 | /** | |
133 | * Whether or not Javascript works in this browser. | |
134 | * | |
135 | * @return True if Javascript works in this browser. | |
136 | */ | |
137 | public boolean isJavascriptOK() | |
138 | { | |
139 | 0 | return javascriptOK; |
140 | } | |
141 | ||
142 | /** | |
143 | * The browser name specified in the user agent string. | |
144 | * | |
145 | * @return A String with the browser name. | |
146 | */ | |
147 | public String getBrowserName() | |
148 | { | |
149 | 5 | return browserName; |
150 | } | |
151 | ||
152 | /** | |
153 | * The browser platform specified in the user agent string. | |
154 | * | |
155 | * @return A String with the browser platform. | |
156 | */ | |
157 | public String getBrowserPlatform() | |
158 | { | |
159 | 5 | return browserPlatform; |
160 | } | |
161 | ||
162 | /** | |
163 | * The browser version specified in the user agent string. | |
164 | * | |
165 | * @return A String with the browser version. | |
166 | */ | |
167 | public float getBrowserVersion() | |
168 | { | |
169 | 5 | return browserVersion; |
170 | } | |
171 | ||
172 | /** | |
173 | * The user agent string for this class. | |
174 | * | |
175 | * @return A String with the user agent. | |
176 | */ | |
177 | public String getUserAgentString() | |
178 | { | |
179 | 0 | return userAgentString; |
180 | } | |
181 | ||
182 | /** | |
183 | * Helper method to initialize this class. | |
184 | */ | |
185 | private void parse() | |
186 | { | |
187 | 5 | int versionStartIndex = userAgentString.indexOf("/"); |
188 | 5 | int versionEndIndex = userAgentString.indexOf(" "); |
189 | ||
190 | // Get the browser name and version. | |
191 | 5 | browserName = userAgentString.substring(0, versionStartIndex); |
192 | try | |
193 | { | |
194 | // Not all user agents will have a space in the reported | |
195 | // string. | |
196 | 5 | String agentSubstring = null; |
197 | 5 | if (versionEndIndex < 0) |
198 | { | |
199 | 0 | agentSubstring |
200 | = userAgentString.substring(versionStartIndex + 1); | |
201 | } | |
202 | else | |
203 | { | |
204 | 5 | agentSubstring = userAgentString |
205 | .substring(versionStartIndex + 1, versionEndIndex); | |
206 | } | |
207 | 5 | browserVersion = toFloat(agentSubstring); |
208 | } | |
209 | 0 | catch (NumberFormatException e) |
210 | { | |
211 | // Just use the default value. | |
212 | 5 | } |
213 | ||
214 | // MSIE lies about its name. Of course... | |
215 | 5 | if (userAgentString.indexOf(MSIE) != -1) |
216 | { | |
217 | // Ex: Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt) | |
218 | 3 | versionStartIndex = (userAgentString.indexOf(MSIE) |
219 | + MSIE.length() + 1); | |
220 | 3 | versionEndIndex = userAgentString.indexOf(";", versionStartIndex); |
221 | ||
222 | 3 | browserName = MSIE; |
223 | try | |
224 | { | |
225 | 3 | browserVersion = toFloat(userAgentString |
226 | .substring(versionStartIndex, versionEndIndex)); | |
227 | } | |
228 | 0 | catch (NumberFormatException e) |
229 | { | |
230 | // Just use the default value. | |
231 | 3 | } |
232 | ||
233 | // PHP code | |
234 | // $Browser_Name = "MSIE"; | |
235 | // $Browser_Version = strtok("MSIE"); | |
236 | // $Browser_Version = strtok(" "); | |
237 | // $Browser_Version = strtok(";"); | |
238 | } | |
239 | ||
240 | // Opera isn't completely honest, either... | |
241 | // Modificaton by Chris Mospaw <mospaw@polk-county.com> | |
242 | 5 | if (userAgentString.indexOf(OPERA) != -1) |
243 | { | |
244 | // Ex: Mozilla/4.0 (Windows NT 4.0;US) Opera 3.61 [en] | |
245 | // Ex: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; en) Opera 8.02 | |
246 | 2 | versionStartIndex = (userAgentString.indexOf(OPERA) |
247 | + OPERA.length() + 1); | |
248 | 2 | versionEndIndex = userAgentString.indexOf(" ", versionStartIndex); |
249 | 2 | if (versionEndIndex == -1) |
250 | { | |
251 | 1 | versionEndIndex = userAgentString.length(); |
252 | } | |
253 | ||
254 | 2 | browserName = OPERA; |
255 | try | |
256 | { | |
257 | 2 | browserVersion = toFloat(userAgentString |
258 | .substring(versionStartIndex, versionEndIndex)); | |
259 | } | |
260 | 0 | catch (NumberFormatException e) |
261 | { | |
262 | // Just use the default value. | |
263 | 2 | } |
264 | ||
265 | // PHP code | |
266 | // $Browser_Name = "Opera"; | |
267 | // $Browser_Version = strtok("Opera"); | |
268 | // $Browser_Version = strtok("/"); | |
269 | // $Browser_Version = strtok(";"); | |
270 | } | |
271 | ||
272 | ||
273 | // Try to figure out what platform. | |
274 | 5 | if ((userAgentString.indexOf("Windows") != -1) |
275 | || (userAgentString.indexOf("WinNT") != -1) | |
276 | || (userAgentString.indexOf("Win98") != -1) | |
277 | || (userAgentString.indexOf("Win95") != -1)) | |
278 | { | |
279 | 5 | browserPlatform = WINDOWS; |
280 | } | |
281 | ||
282 | 5 | if (userAgentString.indexOf("Mac") != -1) |
283 | { | |
284 | 0 | browserPlatform = MACINTOSH; |
285 | } | |
286 | ||
287 | 5 | if (userAgentString.indexOf("X11") != -1) |
288 | { | |
289 | 0 | browserPlatform = UNIX; |
290 | } | |
291 | ||
292 | 5 | if (browserPlatform == WINDOWS) |
293 | { | |
294 | 5 | if (browserName.equals(MOZILLA)) |
295 | { | |
296 | 1 | if (browserVersion >= 3.0) |
297 | { | |
298 | 1 | javascriptOK = true; |
299 | 1 | fileUploadOK = true; |
300 | } | |
301 | 1 | if (browserVersion >= 4.0) |
302 | { | |
303 | 1 | cssOK = true; |
304 | } | |
305 | } | |
306 | 4 | else if (browserName == MSIE) |
307 | { | |
308 | 2 | if (browserVersion >= 4.0) |
309 | { | |
310 | 2 | javascriptOK = true; |
311 | 2 | fileUploadOK = true; |
312 | 2 | cssOK = true; |
313 | } | |
314 | } | |
315 | 2 | else if (browserName == OPERA) |
316 | { | |
317 | 2 | if (browserVersion >= 3.0) |
318 | { | |
319 | 2 | javascriptOK = true; |
320 | 2 | fileUploadOK = true; |
321 | 2 | cssOK = true; |
322 | } | |
323 | } | |
324 | } | |
325 | 0 | else if (browserPlatform == MACINTOSH) |
326 | { | |
327 | 0 | if (browserName.equals(MOZILLA)) |
328 | { | |
329 | 0 | if (browserVersion >= 3.0) |
330 | { | |
331 | 0 | javascriptOK = true; |
332 | 0 | fileUploadOK = true; |
333 | } | |
334 | 0 | if (browserVersion >= 4.0) |
335 | { | |
336 | 0 | cssOK = true; |
337 | } | |
338 | } | |
339 | 0 | else if (browserName == MSIE) |
340 | { | |
341 | 0 | if (browserVersion >= 4.0) |
342 | { | |
343 | 0 | javascriptOK = true; |
344 | 0 | fileUploadOK = true; |
345 | } | |
346 | 0 | if (browserVersion > 4.0) |
347 | { | |
348 | 0 | cssOK = true; |
349 | } | |
350 | } | |
351 | } | |
352 | 0 | else if (browserPlatform == UNIX) |
353 | { | |
354 | 0 | if (browserName.equals(MOZILLA)) |
355 | { | |
356 | 0 | if (browserVersion >= 3.0) |
357 | { | |
358 | 0 | javascriptOK = true; |
359 | 0 | fileUploadOK = true; |
360 | } | |
361 | 0 | if (browserVersion >= 4.0) |
362 | { | |
363 | 0 | cssOK = true; |
364 | } | |
365 | } | |
366 | } | |
367 | 5 | } |
368 | ||
369 | /** | |
370 | * Helper method to convert String to a float. | |
371 | * | |
372 | * @param s A String. | |
373 | * @return The String converted to float. | |
374 | */ | |
375 | private static final float toFloat(String s) | |
376 | { | |
377 | 10 | return Float.valueOf(s).floatValue(); |
378 | } | |
379 | ||
380 | } |