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 615328 2008-01-25 20:25:05Z tv $ | |
47 | */ | |
48 | public class BrowserDetector | |
49 | { | |
50 | public static final String MSIE = "MSIE"; | |
51 | public static final String OPERA = "Opera"; | |
52 | public static final String MOZILLA = "Mozilla"; | |
53 | ||
54 | public static final String WINDOWS = "Windows"; | |
55 | public static final String UNIX = "Unix"; | |
56 | public static final String MACINTOSH = "Macintosh"; | |
57 | ||
58 | /** The user agent string. */ | |
59 | 10 | private String userAgentString = ""; |
60 | ||
61 | /** The browser name specified in the user agent string. */ | |
62 | 10 | private String browserName = ""; |
63 | ||
64 | /** | |
65 | * The browser version specified in the user agent string. If we | |
66 | * can't parse the version just assume an old browser. | |
67 | */ | |
68 | 10 | private float browserVersion = (float) 1.0; |
69 | ||
70 | /** | |
71 | * The browser platform specified in the user agent string. | |
72 | */ | |
73 | 10 | private String browserPlatform = "unknown"; |
74 | ||
75 | /** Whether or not javascript works in this browser. */ | |
76 | 10 | private boolean javascriptOK = false; |
77 | ||
78 | /** Whether or not CSS works in this browser. */ | |
79 | 10 | private boolean cssOK = false; |
80 | ||
81 | /** Whether or not file upload works in this browser. */ | |
82 | 10 | private boolean fileUploadOK = false; |
83 | ||
84 | /** | |
85 | * Constructor used to initialize this class. | |
86 | * | |
87 | * @param userAgentString A String with the user agent field. | |
88 | */ | |
89 | public BrowserDetector(String userAgentString) | |
90 | 10 | { |
91 | 10 | this.userAgentString = userAgentString; |
92 | 10 | parse(); |
93 | 10 | } |
94 | ||
95 | /** | |
96 | * Constructor used to initialize this class. | |
97 | * | |
98 | * @param data The Turbine RunData object. | |
99 | */ | |
100 | public BrowserDetector(RunData data) | |
101 | 0 | { |
102 | 0 | this.userAgentString = data.getUserAgent(); |
103 | 0 | parse(); |
104 | 0 | } |
105 | ||
106 | /** | |
107 | * Whether or not CSS works in this browser. | |
108 | * | |
109 | * @return True if CSS works in this browser. | |
110 | */ | |
111 | public boolean isCssOK() | |
112 | { | |
113 | 0 | return cssOK; |
114 | } | |
115 | ||
116 | /** | |
117 | * Whether or not file upload works in this browser. | |
118 | * | |
119 | * @return True if file upload works in this browser. | |
120 | */ | |
121 | public boolean isFileUploadOK() | |
122 | { | |
123 | 0 | return fileUploadOK; |
124 | } | |
125 | ||
126 | /** | |
127 | * Whether or not Javascript works in this browser. | |
128 | * | |
129 | * @return True if Javascript works in this browser. | |
130 | */ | |
131 | public boolean isJavascriptOK() | |
132 | { | |
133 | 0 | return javascriptOK; |
134 | } | |
135 | ||
136 | /** | |
137 | * The browser name specified in the user agent string. | |
138 | * | |
139 | * @return A String with the browser name. | |
140 | */ | |
141 | public String getBrowserName() | |
142 | { | |
143 | 10 | return browserName; |
144 | } | |
145 | ||
146 | /** | |
147 | * The browser platform specified in the user agent string. | |
148 | * | |
149 | * @return A String with the browser platform. | |
150 | */ | |
151 | public String getBrowserPlatform() | |
152 | { | |
153 | 10 | return browserPlatform; |
154 | } | |
155 | ||
156 | /** | |
157 | * The browser version specified in the user agent string. | |
158 | * | |
159 | * @return A String with the browser version. | |
160 | */ | |
161 | public float getBrowserVersion() | |
162 | { | |
163 | 10 | return browserVersion; |
164 | } | |
165 | ||
166 | /** | |
167 | * The user agent string for this class. | |
168 | * | |
169 | * @return A String with the user agent. | |
170 | */ | |
171 | public String getUserAgentString() | |
172 | { | |
173 | 0 | return userAgentString; |
174 | } | |
175 | ||
176 | /** | |
177 | * Helper method to initialize this class. | |
178 | */ | |
179 | private void parse() | |
180 | { | |
181 | 10 | int versionStartIndex = userAgentString.indexOf("/"); |
182 | 10 | int versionEndIndex = userAgentString.indexOf(" "); |
183 | ||
184 | // Get the browser name and version. | |
185 | 10 | browserName = userAgentString.substring(0, versionStartIndex); |
186 | try | |
187 | { | |
188 | // Not all user agents will have a space in the reported | |
189 | // string. | |
190 | 10 | String agentSubstring = null; |
191 | 10 | if (versionEndIndex < 0) |
192 | { | |
193 | 0 | agentSubstring |
194 | = userAgentString.substring(versionStartIndex + 1); | |
195 | } | |
196 | else | |
197 | { | |
198 | 10 | agentSubstring = userAgentString |
199 | .substring(versionStartIndex + 1, versionEndIndex); | |
200 | } | |
201 | 10 | browserVersion = toFloat(agentSubstring); |
202 | } | |
203 | 0 | catch (NumberFormatException e) |
204 | { | |
205 | // Just use the default value. | |
206 | 10 | } |
207 | ||
208 | // MSIE lies about its name. Of course... | |
209 | 10 | if (userAgentString.indexOf(MSIE) != -1) |
210 | { | |
211 | // Ex: Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt) | |
212 | 6 | versionStartIndex = (userAgentString.indexOf(MSIE) |
213 | + MSIE.length() + 1); | |
214 | 6 | versionEndIndex = userAgentString.indexOf(";", versionStartIndex); |
215 | ||
216 | 6 | browserName = MSIE; |
217 | try | |
218 | { | |
219 | 6 | browserVersion = toFloat(userAgentString |
220 | .substring(versionStartIndex, versionEndIndex)); | |
221 | } | |
222 | 0 | catch (NumberFormatException e) |
223 | { | |
224 | // Just use the default value. | |
225 | 6 | } |
226 | ||
227 | // PHP code | |
228 | // $Browser_Name = "MSIE"; | |
229 | // $Browser_Version = strtok("MSIE"); | |
230 | // $Browser_Version = strtok(" "); | |
231 | // $Browser_Version = strtok(";"); | |
232 | } | |
233 | ||
234 | // Opera isn't completely honest, either... | |
235 | // Modificaton by Chris Mospaw <mospaw@polk-county.com> | |
236 | 10 | if (userAgentString.indexOf(OPERA) != -1) |
237 | { | |
238 | // Ex: Mozilla/4.0 (Windows NT 4.0;US) Opera 3.61 [en] | |
239 | // Ex: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; en) Opera 8.02 | |
240 | 4 | versionStartIndex = (userAgentString.indexOf(OPERA) |
241 | + OPERA.length() + 1); | |
242 | 4 | versionEndIndex = userAgentString.indexOf(" ", versionStartIndex); |
243 | 4 | if (versionEndIndex == -1) |
244 | { | |
245 | 2 | versionEndIndex = userAgentString.length(); |
246 | } | |
247 | ||
248 | 4 | browserName = OPERA; |
249 | try | |
250 | { | |
251 | 4 | browserVersion = toFloat(userAgentString |
252 | .substring(versionStartIndex, versionEndIndex)); | |
253 | } | |
254 | 0 | catch (NumberFormatException e) |
255 | { | |
256 | // Just use the default value. | |
257 | 4 | } |
258 | ||
259 | // PHP code | |
260 | // $Browser_Name = "Opera"; | |
261 | // $Browser_Version = strtok("Opera"); | |
262 | // $Browser_Version = strtok("/"); | |
263 | // $Browser_Version = strtok(";"); | |
264 | } | |
265 | ||
266 | ||
267 | // Try to figure out what platform. | |
268 | 10 | if ((userAgentString.indexOf("Windows") != -1) |
269 | || (userAgentString.indexOf("WinNT") != -1) | |
270 | || (userAgentString.indexOf("Win98") != -1) | |
271 | || (userAgentString.indexOf("Win95") != -1)) | |
272 | { | |
273 | 10 | browserPlatform = WINDOWS; |
274 | } | |
275 | ||
276 | 10 | if (userAgentString.indexOf("Mac") != -1) |
277 | { | |
278 | 0 | browserPlatform = MACINTOSH; |
279 | } | |
280 | ||
281 | 10 | if (userAgentString.indexOf("X11") != -1) |
282 | { | |
283 | 0 | browserPlatform = UNIX; |
284 | } | |
285 | ||
286 | 10 | if (browserPlatform == WINDOWS) |
287 | { | |
288 | 10 | if (browserName.equals(MOZILLA)) |
289 | { | |
290 | 2 | if (browserVersion >= 3.0) |
291 | { | |
292 | 2 | javascriptOK = true; |
293 | 2 | fileUploadOK = true; |
294 | } | |
295 | 2 | if (browserVersion >= 4.0) |
296 | { | |
297 | 2 | cssOK = true; |
298 | } | |
299 | } | |
300 | 8 | else if (browserName == MSIE) |
301 | { | |
302 | 4 | if (browserVersion >= 4.0) |
303 | { | |
304 | 4 | javascriptOK = true; |
305 | 4 | fileUploadOK = true; |
306 | 4 | cssOK = true; |
307 | } | |
308 | } | |
309 | 4 | else if (browserName == OPERA) |
310 | { | |
311 | 4 | if (browserVersion >= 3.0) |
312 | { | |
313 | 4 | javascriptOK = true; |
314 | 4 | fileUploadOK = true; |
315 | 4 | cssOK = true; |
316 | } | |
317 | } | |
318 | } | |
319 | 0 | else if (browserPlatform == MACINTOSH) |
320 | { | |
321 | 0 | if (browserName.equals(MOZILLA)) |
322 | { | |
323 | 0 | if (browserVersion >= 3.0) |
324 | { | |
325 | 0 | javascriptOK = true; |
326 | 0 | fileUploadOK = true; |
327 | } | |
328 | 0 | if (browserVersion >= 4.0) |
329 | { | |
330 | 0 | cssOK = true; |
331 | } | |
332 | } | |
333 | 0 | else if (browserName == MSIE) |
334 | { | |
335 | 0 | if (browserVersion >= 4.0) |
336 | { | |
337 | 0 | javascriptOK = true; |
338 | 0 | fileUploadOK = true; |
339 | } | |
340 | 0 | if (browserVersion > 4.0) |
341 | { | |
342 | 0 | cssOK = true; |
343 | } | |
344 | } | |
345 | } | |
346 | 0 | else if (browserPlatform == UNIX) |
347 | { | |
348 | 0 | if (browserName.equals(MOZILLA)) |
349 | { | |
350 | 0 | if (browserVersion >= 3.0) |
351 | { | |
352 | 0 | javascriptOK = true; |
353 | 0 | fileUploadOK = true; |
354 | } | |
355 | 0 | if (browserVersion >= 4.0) |
356 | { | |
357 | 0 | cssOK = true; |
358 | } | |
359 | } | |
360 | } | |
361 | 10 | } |
362 | ||
363 | /** | |
364 | * Helper method to convert String to a float. | |
365 | * | |
366 | * @param s A String. | |
367 | * @return The String converted to float. | |
368 | */ | |
369 | private static final float toFloat(String s) | |
370 | { | |
371 | 20 | return Float.valueOf(s).floatValue(); |
372 | } | |
373 | ||
374 | } |