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}