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 }