com.phloc.web.useragent.UserAgent Maven / Gradle / Ivy
/**
* Copyright (C) 2006-2015 phloc systems
* http://www.phloc.com
* office[at]phloc[dot]com
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.phloc.web.useragent;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import com.phloc.commons.ValueEnforcer;
import com.phloc.commons.string.ToStringGenerator;
import com.phloc.commons.version.Version;
import com.phloc.web.useragent.browser.BrowserInfo;
import com.phloc.web.useragent.browser.BrowserInfoIE;
import com.phloc.web.useragent.browser.BrowserInfoMobile;
import com.phloc.web.useragent.browser.BrowserInfoSpider;
import com.phloc.web.useragent.browser.EBrowserType;
import com.phloc.web.useragent.browser.MobileBrowserManager;
import com.phloc.web.useragent.spider.WebSpiderInfo;
import com.phloc.web.useragent.spider.WebSpiderManager;
/**
* Default implementation of the {@link IUserAgent} interface.
*
* @author Philip Helger
*/
final class UserAgent implements IUserAgent
{
private static final String GECKO_SEARCH_STRING = "Gecko";
private static final String LYNX_SEARCH_STRING = "Lynx";
private static final String CHROME_SEARCH_STRING = "Chrome";
private static final String VERSION_SEARCH_STRING = "Version";
private static final String SAFARI_SEARCH_STRING = "Safari";
private static final String OPERA_SEARCH_STRING = "Opera";
private static final String FIREFOX_SEARCH_STRING = "Firefox";
private static final String IE_SEARCH_STRING = "MSIE";
private static final String IE_TRIDENT_SEARCH_STRING = "Trident/";
private static final String IE_RV_SEARCH_STRING = "rv:";
private static final String KONQUEROR_PREFIX = "Konqueror/";
private static final String [] GECKO_VARIANTS = new String [] { "GranParadiso",
"Fedora",
"Namoroka",
"Netscape",
"K-Meleon",
"WebThumb" };
private static final int IE_VERSION_IN_COMPATIBILITY_MODE = 7;
private final String m_sFullUserAgent;
private final UserAgentElementList m_aElements;
private BrowserInfo m_aInfoFirefox;
private BrowserInfoIE m_aInfoIE;
private BrowserInfo m_aInfoOpera;
private BrowserInfo m_aInfoSafari;
private BrowserInfo m_aInfoChrome;
private BrowserInfo m_aInfoLynx;
private BrowserInfo m_aInfoKonqueror;
private BrowserInfo m_aInfoGeckoBased;
private BrowserInfo m_aInfoWebKitBased;
private BrowserInfoMobile m_aInfoMobile;
private BrowserInfoSpider m_aInfoWebSpider;
private BrowserInfo m_aInfoApplication;
public UserAgent (@Nonnull final String sFullUserAgent, @Nonnull final UserAgentElementList aElements)
{
m_sFullUserAgent = ValueEnforcer.notNull (sFullUserAgent, "FullUserAgent");
m_aElements = ValueEnforcer.notNull (aElements, "Elements");
}
@Nonnull
public String getAsString ()
{
return m_sFullUserAgent;
}
@Nullable
public BrowserInfo getBrowserInfo ()
{
if (getInfoFirefox ().isIt ())
return getInfoFirefox ();
if (getInfoIE ().isIt ())
return getInfoIE ();
if (getInfoOpera ().isIt ())
return getInfoOpera ();
if (getInfoSafari ().isIt ())
return getInfoSafari ();
if (getInfoChrome ().isIt ())
return getInfoChrome ();
if (getInfoLynx ().isIt ())
return getInfoLynx ();
if (getInfoKonqueror ().isIt ())
return getInfoKonqueror ();
if (getInfoGeckoBased ().isIt ())
return getInfoGeckoBased ();
if (getInfoWebKitBased ().isIt ())
return getInfoWebKitBased ();
if (getInfoMobile ().isIt ())
return getInfoMobile ();
if (getInfoWebSpider ().isIt ())
return getInfoWebSpider ();
if (getInfoApplication ().isIt ())
return getInfoApplication ();
return null;
}
@Nonnull
public BrowserInfo getInfoFirefox ()
{
if (m_aInfoFirefox == null)
{
// Example:
// Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2)
// Gecko/20100115 Firefox/3.6
String sVersionFirefox = m_aElements.getPairValue (FIREFOX_SEARCH_STRING);
if (sVersionFirefox == null)
{
// Example2:
// Mozilla/5.0 (Windows; U; Windows NT 5.1; de; rv:1.9.1.4)
// Gecko/20091016 Boersenfegers Firefox 3.5.4
sVersionFirefox = m_aElements.getStringValueFollowing (FIREFOX_SEARCH_STRING);
}
if (sVersionFirefox == null)
m_aInfoFirefox = BrowserInfo.IS_IT_NOT;
else
m_aInfoFirefox = new BrowserInfo (EBrowserType.FIREFOX, new Version (sVersionFirefox));
}
return m_aInfoFirefox;
}
@Nonnull
public BrowserInfoIE getInfoIE ()
{
if (m_aInfoIE == null)
{
// Example:
// IE7:
// Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; SLCC2; .NET CLR
// 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0;
// Tablet PC 2.0)
// IE8:
// Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0; SLCC2;
// .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media
// Center PC 6.0; Tablet PC 2.0)
// IE8 compatibility view:
// Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; Trident/4.0; SLCC2;
// .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media
// Center PC 6.0; Tablet PC 2.0)
// IE 11:
// Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; MALC; rv:11.0) like
// Gecko
String sInfoIE = m_aElements.getListItemStartingWith (IE_SEARCH_STRING);
final String sTrident = m_aElements.getListItemStartingWith (IE_TRIDENT_SEARCH_STRING);
// Negative Example:
// Mozilla/4.0 (compatible; MSIE 6.0; X11; Linux i686; en) Opera 9.63
if (m_aElements.containsString (OPERA_SEARCH_STRING))
sInfoIE = null;
if (sInfoIE == null)
{
// IE 11 special handling - no MSIE any more
if (sTrident != null)
{
// "Trident/" must be present and "rv:" indicates the vesion number
final String sRV = m_aElements.getListItemStartingWith (IE_RV_SEARCH_STRING);
if (sRV != null)
{
final Version aVersion = new Version (sRV.substring (IE_RV_SEARCH_STRING.length ()));
m_aInfoIE = new BrowserInfoIE (aVersion, false);
}
else
m_aInfoIE = BrowserInfoIE.IS_IT_NOT;
}
else
m_aInfoIE = BrowserInfoIE.IS_IT_NOT;
}
else
{
// IE Compatibility Mode check
// http://blogs.msdn.com/b/ie/archive/2010/03/23/introducing-ie9-s-user-agent-string.aspx
final Version aVersion = new Version (sInfoIE.substring (IE_SEARCH_STRING.length ()).trim ());
final boolean bIsIECompatibilityMode = aVersion.getMajor () == IE_VERSION_IN_COMPATIBILITY_MODE &&
sTrident != null;
m_aInfoIE = new BrowserInfoIE (aVersion, bIsIECompatibilityMode);
}
}
return m_aInfoIE;
}
@Nonnull
public BrowserInfo getInfoOpera ()
{
if (m_aInfoOpera == null)
{
// Example:
// Opera/9.64 (Windows NT 6.1; U; en) Presto/2.1.1
String sVersionOpera = m_aElements.getPairValue (OPERA_SEARCH_STRING);
if (sVersionOpera != null)
{
// Special case:
// Opera/9.80 (Windows NT 5.1; U; hu) Presto/2.2.15 Version/10.10
final String sVersion = m_aElements.getPairValue (VERSION_SEARCH_STRING);
if (sVersion != null)
sVersionOpera = sVersion;
}
else
{
// Example:
// Mozilla/4.0 (compatible; MSIE 6.0; X11; Linux i686; en) Opera 9.63
sVersionOpera = m_aElements.getStringValueFollowing (OPERA_SEARCH_STRING);
}
if (sVersionOpera == null)
m_aInfoOpera = BrowserInfo.IS_IT_NOT;
else
m_aInfoOpera = new BrowserInfo (EBrowserType.OPERA, new Version (sVersionOpera));
}
return m_aInfoOpera;
}
@Nonnull
public BrowserInfo getInfoSafari ()
{
if (m_aInfoSafari == null)
{
// Example:
// Mozilla/5.0 (Windows; U; Windows NT 6.1; de-DE) AppleWebKit/531.21.8
// (KHTML, like Gecko) Version/4.0.4 Safari/531.21.10
final String sSafari = m_aElements.getPairValue (SAFARI_SEARCH_STRING);
final String sVersion = sSafari == null ? null : m_aElements.getPairValue (VERSION_SEARCH_STRING);
if (sVersion == null)
m_aInfoSafari = BrowserInfo.IS_IT_NOT;
else
m_aInfoSafari = new BrowserInfo (EBrowserType.SAFARI, new Version (sVersion));
}
return m_aInfoSafari;
}
@Nonnull
public BrowserInfo getInfoChrome ()
{
if (m_aInfoChrome == null)
{
// Example:
// Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/532.9
// (KHTML, like Gecko) Chrome/5.0.317.2 Safari/532.9
final String sSafari = m_aElements.getPairValue (SAFARI_SEARCH_STRING);
final String sVersion = sSafari == null ? null : m_aElements.getPairValue (CHROME_SEARCH_STRING);
if (sVersion == null)
m_aInfoChrome = BrowserInfo.IS_IT_NOT;
else
m_aInfoChrome = new BrowserInfo (EBrowserType.CHROME, new Version (sVersion));
}
return m_aInfoChrome;
}
@Nonnull
public BrowserInfo getInfoLynx ()
{
if (m_aInfoLynx == null)
{
// Example:
// Lynx/2.8.3rel.1 libwww-FM/2.14FM
final String sVersion = m_aElements.getPairValue (LYNX_SEARCH_STRING);
if (sVersion == null)
m_aInfoLynx = BrowserInfo.IS_IT_NOT;
else
m_aInfoLynx = new BrowserInfo (EBrowserType.LYNX, new Version (sVersion));
}
return m_aInfoLynx;
}
@Nonnull
public BrowserInfo getInfoKonqueror ()
{
if (m_aInfoKonqueror == null)
{
// Example:
// Mozilla/5.0 (compatible; Konqueror/3.4; FreeBSD; en_US) KHTML/3.4.0
// (like Gecko)
final String sVersion = m_aElements.getListItemStartingWith (KONQUEROR_PREFIX);
if (sVersion == null)
m_aInfoKonqueror = BrowserInfo.IS_IT_NOT;
else
m_aInfoKonqueror = new BrowserInfo (EBrowserType.KONQUEROR,
new Version (sVersion.substring (KONQUEROR_PREFIX.length ())));
}
return m_aInfoKonqueror;
}
@Nonnull
public BrowserInfo getInfoGeckoBased ()
{
if (m_aInfoGeckoBased == null)
{
// Example:
// Mozilla/5.0 (Windows; U; Windows NT 5.1; de-AT; rv:1.7.12)
// Gecko/20050915
String sVersionGecko = m_aElements.getPairValue (GECKO_SEARCH_STRING);
if (sVersionGecko == null && m_sFullUserAgent.contains (GECKO_SEARCH_STRING))
{
// Examples:
// Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.11) Gecko
// GranParadiso/3.0.11
// Mozilla/5.0 (Windows; U; Win98; en-US; rv:1.4) Gecko Netscape/7.1
// (ax)
// Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1.17pre) Gecko
// K-Meleon/1.6.0
for (final String sVariant : GECKO_VARIANTS)
{
sVersionGecko = m_aElements.getPairValue (sVariant);
if (sVersionGecko != null)
break;
}
}
// If we already have FireFox, no need for generic Gecko detection
if (sVersionGecko == null || getInfoFirefox ().isIt ())
m_aInfoGeckoBased = BrowserInfo.IS_IT_NOT;
else
m_aInfoGeckoBased = new BrowserInfo (EBrowserType.GECKO, new Version (sVersionGecko));
}
return m_aInfoGeckoBased;
}
@Nonnull
public BrowserInfo getInfoWebKitBased ()
{
if (m_aInfoWebKitBased == null)
{
// Example:
// Mozilla/5.0 (Windows; U; Windows NT 6.0; de-AT) AppleWebKit/532.4
// (KHTML, like Gecko) QtWeb Internet Browser/3.3 http://www.QtWeb.net
final String sVersionWebKit = m_aElements.getPairValue ("AppleWebKit");
// If we already have Safari or Chrome, no need for generic WebKit
// detection
if (sVersionWebKit == null || getInfoSafari ().isIt () || getInfoChrome ().isIt ())
m_aInfoWebKitBased = BrowserInfo.IS_IT_NOT;
else
m_aInfoWebKitBased = new BrowserInfo (EBrowserType.WEBKIT, new Version (sVersionWebKit));
}
return m_aInfoWebKitBased;
}
@Nonnull
public BrowserInfoMobile getInfoMobile ()
{
if (m_aInfoMobile == null)
{
final String sVersion = MobileBrowserManager.getFromUserAgent (m_sFullUserAgent);
if (sVersion == null)
m_aInfoMobile = BrowserInfoMobile.IS_IT_NOT;
else
m_aInfoMobile = new BrowserInfoMobile (sVersion);
}
return m_aInfoMobile;
}
@Nonnull
public BrowserInfoSpider getInfoWebSpider ()
{
if (m_aInfoWebSpider == null)
{
final WebSpiderInfo aWebSpiderInfo = WebSpiderManager.getInstance ().getWebSpiderFromUserAgent (m_sFullUserAgent);
if (aWebSpiderInfo == null)
m_aInfoWebSpider = BrowserInfoSpider.IS_IT_NOT;
else
m_aInfoWebSpider = new BrowserInfoSpider (aWebSpiderInfo);
}
return m_aInfoWebSpider;
}
@Nonnull
public BrowserInfo getInfoApplication ()
{
if (m_aInfoApplication == null)
{
final String sApp = ApplicationUserAgentManager.getFromUserAgent (m_sFullUserAgent);
if (sApp == null)
m_aInfoApplication = BrowserInfoSpider.IS_IT_NOT;
else
m_aInfoApplication = new BrowserInfo (EBrowserType.APPLICATION, new Version (0));
}
return m_aInfoApplication;
}
@Override
public String toString ()
{
return new ToStringGenerator (this).append ("string", m_sFullUserAgent)
.append ("infos", m_aElements)
.append ("Firefox", getInfoFirefox ())
.append ("IE", getInfoIE ())
.append (OPERA_SEARCH_STRING, getInfoOpera ())
.append (SAFARI_SEARCH_STRING, getInfoSafari ())
.append (CHROME_SEARCH_STRING, getInfoChrome ())
.append (GECKO_SEARCH_STRING, getInfoGeckoBased ())
.append ("Mobile", getInfoMobile ())
.append ("WebSpider", getInfoWebSpider ())
.toString ();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy