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 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      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 }