View Javadoc

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 534527 2007-05-02 16:10:59Z 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      private String userAgentString = "";
60  
61      /*** The browser name specified in the user agent string. */
62      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      private float browserVersion = (float) 1.0;
69  
70      /***
71       * The browser platform specified in the user agent string.
72       */
73      private String browserPlatform = "unknown";
74  
75      /*** Whether or not javascript works in this browser. */
76      private boolean javascriptOK = false;
77  
78      /*** Whether or not CSS works in this browser. */
79      private boolean cssOK = false;
80  
81      /*** Whether or not file upload works in this browser. */
82      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      {
91          this.userAgentString = userAgentString;
92          parse();
93      }
94  
95      /***
96       * Constructor used to initialize this class.
97       *
98       * @param data The Turbine RunData object.
99       */
100     public BrowserDetector(RunData data)
101     {
102         this.userAgentString = data.getUserAgent();
103         parse();
104     }
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         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         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         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         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         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         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         return userAgentString;
174     }
175 
176     /***
177      * Helper method to initialize this class.
178      */
179     private void parse()
180     {
181         int versionStartIndex = userAgentString.indexOf("/");
182         int versionEndIndex = userAgentString.indexOf(" ");
183 
184         // Get the browser name and version.
185         browserName = userAgentString.substring(0, versionStartIndex);
186         try
187         {
188             // Not all user agents will have a space in the reported
189             // string.
190             String agentSubstring = null;
191             if (versionEndIndex < 0)
192             {
193                 agentSubstring
194                         = userAgentString.substring(versionStartIndex + 1);
195             }
196             else
197             {
198                 agentSubstring = userAgentString
199                         .substring(versionStartIndex + 1, versionEndIndex);
200             }
201             browserVersion = toFloat(agentSubstring);
202         }
203         catch (NumberFormatException e)
204         {
205             // Just use the default value.
206         }
207 
208         // MSIE lies about its name.  Of course...
209         if (userAgentString.indexOf(MSIE) != -1)
210         {
211             // Ex: Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)
212             versionStartIndex = (userAgentString.indexOf(MSIE)
213                     + MSIE.length() + 1);
214             versionEndIndex = userAgentString.indexOf(";", versionStartIndex);
215 
216             browserName = MSIE;
217             try
218             {
219                 browserVersion = toFloat(userAgentString
220                         .substring(versionStartIndex, versionEndIndex));
221             }
222             catch (NumberFormatException e)
223             {
224                 // Just use the default value.
225             }
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         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             versionStartIndex = (userAgentString.indexOf(OPERA)
241                     + OPERA.length() + 1);
242             versionEndIndex = userAgentString.indexOf(" ", versionStartIndex);
243             if (versionEndIndex == -1)
244             {
245                 versionEndIndex = userAgentString.length();
246             }
247 
248             browserName = OPERA;
249             try
250             {
251                 browserVersion = toFloat(userAgentString
252                         .substring(versionStartIndex, versionEndIndex));
253             }
254             catch (NumberFormatException e)
255             {
256                 // Just use the default value.
257             }
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         if ((userAgentString.indexOf("Windows") != -1)
269                 || (userAgentString.indexOf("WinNT") != -1)
270                 || (userAgentString.indexOf("Win98") != -1)
271                 || (userAgentString.indexOf("Win95") != -1))
272         {
273             browserPlatform = WINDOWS;
274         }
275 
276         if (userAgentString.indexOf("Mac") != -1)
277         {
278             browserPlatform = MACINTOSH;
279         }
280 
281         if (userAgentString.indexOf("X11") != -1)
282         {
283             browserPlatform = UNIX;
284         }
285 
286         if (browserPlatform == WINDOWS)
287         {
288             if (browserName.equals(MOZILLA))
289             {
290                 if (browserVersion >= 3.0)
291                 {
292                     javascriptOK = true;
293                     fileUploadOK = true;
294                 }
295                 if (browserVersion >= 4.0)
296                 {
297                     cssOK = true;
298                 }
299             }
300             else if (browserName == MSIE)
301             {
302                 if (browserVersion >= 4.0)
303                 {
304                     javascriptOK = true;
305                     fileUploadOK = true;
306                     cssOK = true;
307                 }
308             }
309             else if (browserName == OPERA)
310             {
311                 if (browserVersion >= 3.0)
312                 {
313                     javascriptOK = true;
314                     fileUploadOK = true;
315                     cssOK = true;
316                 }
317             }
318         }
319         else if (browserPlatform == MACINTOSH)
320         {
321             if (browserName.equals(MOZILLA))
322             {
323                 if (browserVersion >= 3.0)
324                 {
325                     javascriptOK = true;
326                     fileUploadOK = true;
327                 }
328                 if (browserVersion >= 4.0)
329                 {
330                     cssOK = true;
331                 }
332             }
333             else if (browserName == MSIE)
334             {
335                 if (browserVersion >= 4.0)
336                 {
337                     javascriptOK = true;
338                     fileUploadOK = true;
339                 }
340                 if (browserVersion > 4.0)
341                 {
342                     cssOK = true;
343                 }
344             }
345         }
346         else if (browserPlatform == UNIX)
347         {
348             if (browserName.equals(MOZILLA))
349             {
350                 if (browserVersion >= 3.0)
351                 {
352                     javascriptOK = true;
353                     fileUploadOK = true;
354                 }
355                 if (browserVersion >= 4.0)
356                 {
357                     cssOK = true;
358                 }
359             }
360         }
361     }
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         return Float.valueOf(s).floatValue();
372     }
373 
374 }