    001package org.apache.turbine.util;
    002
    003import java.util.HashMap;
    004import java.util.Map;
    005
    006import net.sf.uadetector.OperatingSystem;
    007import net.sf.uadetector.ReadableUserAgent;
    008import net.sf.uadetector.UserAgentStringParser;
    009import net.sf.uadetector.VersionNumber;
    010import net.sf.uadetector.service.UADetectorServiceFactory;
    011
    012/*
    013 * Licensed to the Apache Software Foundation (ASF) under one
    014 * or more contributor license agreements.  See the NOTICE file
    015 * distributed with this work for additional information
    016 * regarding copyright ownership.  The ASF licenses this file
    017 * to you under the Apache License, Version 2.0 (the
    018 * "License"); you may not use this file except in compliance
    019 * with the License.  You may obtain a copy of the License at
    020 *
    021 *   http://www.apache.org/licenses/LICENSE-2.0
    022 *
    023 * Unless required by applicable law or agreed to in writing,
    024 * software distributed under the License is distributed on an
    025 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    026 * KIND, either express or implied.  See the License for the
    027 * specific language governing permissions and limitations
    028 * under the License.
    029 */
    030
    031/**
    032 * This class parses the user agent string and provides getters for
    033 * its parts. It uses UADetector (http://uadetector.sourceforge.net/)
    034 *
    035 * @author <a href="mailto:frank.kim@clearink.com">Frank Y. Kim</a>
    036 * @author <a href="mailto:leon@clearink.com">Leon Atkisnon</a>
    037 * @author <a href="mailto:mospaw@polk-county.com">Chris Mospaw</a>
    038 * @author <a href="mailto:bgriffin@cddb.com">Benjamin Elijah Griffin</a>
    039 * @author <a href="mailto:tv@apache.org">Thomas Vandahl</a>
    040 */
    041public class BrowserDetector
    042{
    043    /** The user agent string. */
    044    private String userAgentString = "";
    045
    046    /** The user agent cache. */
    047    private static volatile Map<String, ReadableUserAgent> userAgentCache =
    048            new HashMap<String, ReadableUserAgent>();
    049
    050    /** The user agent parser */
    051    private static UserAgentStringParser parser =
    052            UADetectorServiceFactory.getCachingAndUpdatingParser();
    053
    054    /** The browser name specified in the user agent string. */
    055    private String browserName = "";
    056
    057    /**
    058     * The browser version specified in the user agent string.  If we
    059     * can't parse the version just assume an old browser.
    060     */
    061    private float browserVersion = (float) 1.0;
    062
    063    /**
    064     * The browser platform specified in the user agent string.
    065     */
    066    private String browserPlatform = "unknown";
    067
    068    /**
    069     * Constructor used to initialize this class.
    070     *
    071     * @param userAgentString A String with the user agent field.
    072     */
    073    public BrowserDetector(String userAgentString)
    074    {
    075        this.userAgentString = userAgentString;
    076        parse();
    077    }
    078
    079    /**
    080     * Constructor used to initialize this class.
    081     *
    082     * @param data The Turbine RunData object.
    083     */
    084    public BrowserDetector(RunData data)
    085    {
    086        this(data.getUserAgent());
    087    }
    088
    089    /**
    090     * The browser name specified in the user agent string.
    091     *
    092     * @return A String with the browser name.
    093     */
    094    public String getBrowserName()
    095    {
    096        return browserName;
    097    }
    098
    099    /**
    100     * The browser platform specified in the user agent string.
    101     *
    102     * @return A String with the browser platform.
    103     */
    104    public String getBrowserPlatform()
    105    {
    106        return browserPlatform;
    107    }
    108
    109    /**
    110     * The browser version specified in the user agent string.
    111     *
    112     * @return A String with the browser version.
    113     */
    114    public float getBrowserVersion()
    115    {
    116        return browserVersion;
    117    }
    118
    119    /**
    120     * The user agent string for this class.
    121     *
    122     * @return A String with the user agent.
    123     */
    124    public String getUserAgentString()
    125    {
    126        return userAgentString;
    127    }
    128
    129    /**
    130     * The user agent for this class.
    131     *
    132     * @return A user agent.
    133     */
    134    public ReadableUserAgent getUserAgent()
    135    {
    136        return userAgentCache.get(userAgentString);
    137    }
    138
    139    /**
    140     * Helper method to initialize this class.
    141     */
    142    private void parse()
    143    {
    144        ReadableUserAgent userAgent = userAgentCache.get(userAgentString);
    145
    146        if (userAgent == null)
    147        {
    148            userAgent = parser.parse(userAgentString);
    149            userAgentCache.put(userAgentString, userAgent);
    150        }
    151
    152        // Get the browser name and version.
    153        browserName = userAgent.getName();
    154        VersionNumber version = userAgent.getVersionNumber();
    155        browserVersion = toFloat(version.toVersionString());
    156
    157        // Try to figure out what platform.
    158        OperatingSystem os = userAgent.getOperatingSystem();
    159        browserPlatform = os.getFamilyName();
    160    }
    161
    162    /**
    163     * Helper method to convert String to a float.
    164     *
    165     * @param s A String.
    166     * @return The String converted to float.
    167     */
    168    private static final float toFloat(String s)
    169    {
    170        return Float.parseFloat(s);
    171    }
    172
    173}