##### Coverage Report - org.apache.turbine.util.BrowserDetector

Classes in this File | Line Coverage | Branch Coverage | Complexity
BrowserDetector |
63% | 59/93
34% | 20/58
| 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 |  |
     }