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 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      private String userAgentString = "";
66  
67      /** The browser name specified in the user agent string. */
68      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      private float browserVersion = (float) 1.0;
75  
76      /**
77       * The browser platform specified in the user agent string.
78       */
79      private String browserPlatform = "unknown";
80  
81      /** Whether or not javascript works in this browser. */
82      private boolean javascriptOK = false;
83  
84      /** Whether or not CSS works in this browser. */
85      private boolean cssOK = false;
86  
87      /** Whether or not file upload works in this browser. */
88      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      {
97          this.userAgentString = userAgentString;
98          parse();
99      }
100 
101     /**
102      * Constructor used to initialize this class.
103      *
104      * @param data The Turbine RunData object.
105      */
106     public BrowserDetector(RunData data)
107     {
108         this.userAgentString = data.getUserAgent();
109         parse();
110     }
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         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         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         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         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         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         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         return userAgentString;
180     }
181 
182     /**
183      * Helper method to initialize this class.
184      */
185     private void parse()
186     {
187         int versionStartIndex = userAgentString.indexOf("/");
188         int versionEndIndex = userAgentString.indexOf(" ");
189 
190         // Get the browser name and version.
191         browserName = userAgentString.substring(0, versionStartIndex);
192         try
193         {
194             // Not all user agents will have a space in the reported
195             // string.
196             String agentSubstring = null;
197             if (versionEndIndex < 0)
198             {
199                 agentSubstring
200                         = userAgentString.substring(versionStartIndex + 1);
201             }
202             else
203             {
204                 agentSubstring = userAgentString
205                         .substring(versionStartIndex + 1, versionEndIndex);
206             }
207             browserVersion = toFloat(agentSubstring);
208         }
209         catch (NumberFormatException e)
210         {
211             // Just use the default value.
212         }
213 
214         // MSIE lies about its name.  Of course...
215         if (userAgentString.indexOf(MSIE) != -1)
216         {
217             // Ex: Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)
218             versionStartIndex = (userAgentString.indexOf(MSIE)
219                     + MSIE.length() + 1);
220             versionEndIndex = userAgentString.indexOf(";", versionStartIndex);
221 
222             browserName = MSIE;
223             try
224             {
225                 browserVersion = toFloat(userAgentString
226                         .substring(versionStartIndex, versionEndIndex));
227             }
228             catch (NumberFormatException e)
229             {
230                 // Just use the default value.
231             }
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         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             versionStartIndex = (userAgentString.indexOf(OPERA)
247                     + OPERA.length() + 1);
248             versionEndIndex = userAgentString.indexOf(" ", versionStartIndex);
249             if (versionEndIndex == -1)
250             {
251                 versionEndIndex = userAgentString.length();
252             }
253 
254             browserName = OPERA;
255             try
256             {
257                 browserVersion = toFloat(userAgentString
258                         .substring(versionStartIndex, versionEndIndex));
259             }
260             catch (NumberFormatException e)
261             {
262                 // Just use the default value.
263             }
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         if ((userAgentString.indexOf("Windows") != -1)
275                 || (userAgentString.indexOf("WinNT") != -1)
276                 || (userAgentString.indexOf("Win98") != -1)
277                 || (userAgentString.indexOf("Win95") != -1))
278         {
279             browserPlatform = WINDOWS;
280         }
281 
282         if (userAgentString.indexOf("Mac") != -1)
283         {
284             browserPlatform = MACINTOSH;
285         }
286 
287         if (userAgentString.indexOf("X11") != -1)
288         {
289             browserPlatform = UNIX;
290         }
291 
292         if (browserPlatform == WINDOWS)
293         {
294             if (browserName.equals(MOZILLA))
295             {
296                 if (browserVersion >= 3.0)
297                 {
298                     javascriptOK = true;
299                     fileUploadOK = true;
300                 }
301                 if (browserVersion >= 4.0)
302                 {
303                     cssOK = true;
304                 }
305             }
306             else if (browserName == MSIE)
307             {
308                 if (browserVersion >= 4.0)
309                 {
310                     javascriptOK = true;
311                     fileUploadOK = true;
312                     cssOK = true;
313                 }
314             }
315             else if (browserName == OPERA)
316             {
317                 if (browserVersion >= 3.0)
318                 {
319                     javascriptOK = true;
320                     fileUploadOK = true;
321                     cssOK = true;
322                 }
323             }
324         }
325         else if (browserPlatform == MACINTOSH)
326         {
327             if (browserName.equals(MOZILLA))
328             {
329                 if (browserVersion >= 3.0)
330                 {
331                     javascriptOK = true;
332                     fileUploadOK = true;
333                 }
334                 if (browserVersion >= 4.0)
335                 {
336                     cssOK = true;
337                 }
338             }
339             else if (browserName == MSIE)
340             {
341                 if (browserVersion >= 4.0)
342                 {
343                     javascriptOK = true;
344                     fileUploadOK = true;
345                 }
346                 if (browserVersion > 4.0)
347                 {
348                     cssOK = true;
349                 }
350             }
351         }
352         else if (browserPlatform == UNIX)
353         {
354             if (browserName.equals(MOZILLA))
355             {
356                 if (browserVersion >= 3.0)
357                 {
358                     javascriptOK = true;
359                     fileUploadOK = true;
360                 }
361                 if (browserVersion >= 4.0)
362                 {
363                     cssOK = true;
364                 }
365             }
366         }
367     }
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         return Float.valueOf(s).floatValue();
378     }
379 
380 }