com.vaadin.shared.VBrowserDetails Maven / Gradle / Ivy
/*
* Copyright 2000-2014 Vaadin Ltd.
*
* 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.vaadin.shared;
import java.io.Serializable;
/**
* Class that parses the user agent string from the browser and provides
* information about the browser. Used internally by
* {@link com.vaadin.client.BrowserInfo} and
* {@link com.vaadin.server.WebBrowser}. Should not be used directly.
*
* @author Vaadin Ltd.
* @since 6.3
*/
public class VBrowserDetails implements Serializable {
private boolean isGecko = false;
private boolean isWebKit = false;
private boolean isPresto = false;
private boolean isTrident = false;
private boolean isChromeFrameCapable = false;
private boolean isChromeFrame = false;
private boolean isSafari = false;
private boolean isChrome = false;
private boolean isFirefox = false;
private boolean isOpera = false;
private boolean isIE = false;
private boolean isEdge = false;
private boolean isPhantomJS = false;
private boolean isWindowsPhone;
private boolean isIPad;
private boolean isIPhone;
private OperatingSystem os = OperatingSystem.UNKNOWN;
public enum OperatingSystem {
UNKNOWN, WINDOWS, MACOSX, LINUX, IOS, ANDROID;
}
private float browserEngineVersion = -1;
private int browserMajorVersion = -1;
private int browserMinorVersion = -1;
private int osMajorVersion = -1;
private int osMinorVersion = -1;
/**
* Create an instance based on the given user agent.
*
* @param userAgent
* User agent as provided by the browser.
*/
public VBrowserDetails(String userAgent) {
userAgent = userAgent.toLowerCase();
// browser engine name
isGecko = userAgent.indexOf("gecko") != -1
&& userAgent.indexOf("webkit") == -1
&& userAgent.indexOf("trident/") == -1;
isPresto = userAgent.indexOf(" presto/") != -1;
isTrident = userAgent.indexOf("trident/") != -1;
isWebKit = !isTrident && userAgent.indexOf("applewebkit") != -1;
// browser name
isChrome = userAgent.indexOf(" chrome/") != -1;
isOpera = userAgent.indexOf("opera") != -1;
isIE = userAgent.indexOf("msie") != -1 && !isOpera
&& (userAgent.indexOf("webtv") == -1);
// IE 11 no longer contains MSIE in the user agent
isIE = isIE || isTrident;
isSafari = !isChrome && !isIE && userAgent.indexOf("safari") != -1;
isFirefox = userAgent.indexOf(" firefox/") != -1;
isPhantomJS = userAgent.indexOf("phantomjs/") != -1;
if (userAgent.indexOf(" edge/") != -1) {
isEdge = true;
isChrome = false;
isOpera = false;
isIE = false;
isSafari = false;
isFirefox = false;
isWebKit = false;
isGecko = false;
}
// chromeframe
isChromeFrameCapable = userAgent.indexOf("chromeframe") != -1;
isChromeFrame = isChromeFrameCapable && !isChrome;
// Rendering engine version
try {
if (isGecko) {
int rvPos = userAgent.indexOf("rv:");
if (rvPos >= 0) {
String tmp = userAgent.substring(rvPos + 3);
tmp = tmp.replaceFirst("(\\.[0-9]+).+", "$1");
browserEngineVersion = Float.parseFloat(tmp);
}
} else if (isWebKit) {
String tmp = userAgent
.substring(userAgent.indexOf("webkit/") + 7);
tmp = tmp.replaceFirst("([0-9]+)[^0-9].+", "$1");
browserEngineVersion = Float.parseFloat(tmp);
} else if (isIE) {
int tridentPos = userAgent.indexOf("trident/");
if (tridentPos >= 0) {
String tmp = userAgent.substring(tridentPos
+ "Trident/".length());
tmp = tmp.replaceFirst("([0-9]+\\.[0-9]+).*", "$1");
browserEngineVersion = Float.parseFloat(tmp);
}
} else if (isEdge) {
browserEngineVersion = 0;
}
} catch (Exception e) {
// Browser engine version parsing failed
System.err.println("Browser engine version parsing failed for: "
+ userAgent);
}
// Browser version
try {
if (isIE) {
if (userAgent.indexOf("msie") == -1) {
// IE 11+
int rvPos = userAgent.indexOf("rv:");
if (rvPos >= 0) {
String tmp = userAgent.substring(rvPos + 3);
tmp = tmp.replaceFirst("(\\.[0-9]+).+", "$1");
parseVersionString(tmp);
}
} else {
String ieVersionString = userAgent.substring(userAgent
.indexOf("msie ") + 5);
ieVersionString = safeSubstring(ieVersionString, 0,
ieVersionString.indexOf(";"));
parseVersionString(ieVersionString);
}
} else if (isFirefox) {
int i = userAgent.indexOf(" firefox/") + 9;
parseVersionString(safeSubstring(userAgent, i, i + 5));
} else if (isChrome) {
int i = userAgent.indexOf(" chrome/") + 8;
parseVersionString(safeSubstring(userAgent, i, i + 5));
} else if (isSafari) {
int i = userAgent.indexOf(" version/") + 9;
parseVersionString(safeSubstring(userAgent, i, i + 5));
} else if (isOpera) {
int i = userAgent.indexOf(" version/");
if (i != -1) {
// Version present in Opera 10 and newer
i += 9; // " version/".length
} else {
i = userAgent.indexOf("opera/") + 6;
}
parseVersionString(safeSubstring(userAgent, i, i + 5));
} else if (isEdge) {
int i = userAgent.indexOf(" edge/") + 6;
parseVersionString(safeSubstring(userAgent, i, i + 8));
}
} catch (Exception e) {
// Browser version parsing failed
System.err.println("Browser version parsing failed for: "
+ userAgent);
}
// Operating system
if (userAgent.contains("windows ")) {
os = OperatingSystem.WINDOWS;
isWindowsPhone = userAgent.contains("windows phone");
} else if (userAgent.contains("android")) {
os = OperatingSystem.ANDROID;
parseAndroidVersion(userAgent);
} else if (userAgent.contains("linux")) {
os = OperatingSystem.LINUX;
} else if (userAgent.contains("macintosh")
|| userAgent.contains("mac osx")
|| userAgent.contains("mac os x")) {
isIPad = userAgent.contains("ipad");
isIPhone = userAgent.contains("iphone");
if (isIPad || userAgent.contains("ipod") || isIPhone) {
os = OperatingSystem.IOS;
parseIOSVersion(userAgent);
} else {
os = OperatingSystem.MACOSX;
}
}
}
private void parseAndroidVersion(String userAgent) {
// Android 5.1;
if (!userAgent.contains("android")) {
return;
}
String osVersionString = safeSubstring(userAgent,
userAgent.indexOf("android ") + "android ".length(),
userAgent.length());
osVersionString = safeSubstring(osVersionString, 0,
osVersionString.indexOf(";"));
String[] parts = osVersionString.split("\\.");
parseOsVersion(parts);
}
private void parseIOSVersion(String userAgent) {
// OS 5_1 like Mac OS X
if (!userAgent.contains("os ") || !userAgent.contains(" like mac")) {
return;
}
String osVersionString = safeSubstring(userAgent,
userAgent.indexOf("os ") + 3, userAgent.indexOf(" like mac"));
String[] parts = osVersionString.split("_");
parseOsVersion(parts);
}
private void parseOsVersion(String[] parts) {
osMajorVersion = -1;
osMinorVersion = -1;
if (parts.length >= 1) {
try {
osMajorVersion = Integer.parseInt(parts[0]);
} catch (Exception e) {
}
}
if (parts.length >= 2) {
try {
osMinorVersion = Integer.parseInt(parts[1]);
} catch (Exception e) {
}
// Some Androids report version numbers as "2.1-update1"
if (osMinorVersion == -1 && parts[1].contains("-")) {
try {
osMinorVersion = Integer.parseInt(parts[1].substring(0,
parts[1].indexOf('-')));
} catch (Exception ee) {
}
}
}
}
private void parseVersionString(String versionString) {
int idx = versionString.indexOf('.');
if (idx < 0) {
idx = versionString.length();
}
browserMajorVersion = Integer.parseInt(safeSubstring(versionString, 0,
idx));
int idx2 = versionString.indexOf('.', idx + 1);
if (idx2 < 0) {
idx2 = versionString.length();
}
try {
browserMinorVersion = Integer.parseInt(safeSubstring(versionString,
idx + 1, idx2).replaceAll("[^0-9].*", ""));
} catch (NumberFormatException e) {
// leave the minor version unmodified (-1 = unknown)
}
}
private String safeSubstring(String string, int beginIndex, int endIndex) {
if (beginIndex < 0) {
beginIndex = 0;
}
if (endIndex < 0 || endIndex > string.length()) {
endIndex = string.length();
}
return string.substring(beginIndex, endIndex);
}
/**
* Tests if the browser is Firefox.
*
* @return true if it is Firefox, false otherwise
*/
public boolean isFirefox() {
return isFirefox;
}
/**
* Tests if the browser is using the Gecko engine
*
* @return true if it is Gecko, false otherwise
*/
public boolean isGecko() {
return isGecko;
}
/**
* Tests if the browser is using the WebKit engine
*
* @return true if it is WebKit, false otherwise
*/
public boolean isWebKit() {
return isWebKit;
}
/**
* Tests if the browser is using the Presto engine
*
* @return true if it is Presto, false otherwise
*/
public boolean isPresto() {
return isPresto;
}
/**
* Tests if the browser is using the Trident engine
*
* @since 7.1.7
* @return true if it is Trident, false otherwise
*/
public boolean isTrident() {
return isTrident;
}
/**
* Tests if the browser is Safari.
*
* @return true if it is Safari, false otherwise
*/
public boolean isSafari() {
return isSafari;
}
/**
* Tests if the browser is Chrome.
*
* @return true if it is Chrome, false otherwise
*/
public boolean isChrome() {
return isChrome;
}
/**
* Tests if the browser is capable of running ChromeFrame.
*
* @return true if it has ChromeFrame, false otherwise
*/
public boolean isChromeFrameCapable() {
return isChromeFrameCapable;
}
/**
* Tests if the browser is running ChromeFrame.
*
* @return true if it is ChromeFrame, false otherwise
*/
public boolean isChromeFrame() {
return isChromeFrame;
}
/**
* Tests if the browser is Opera.
*
* @return true if it is Opera, false otherwise
*/
public boolean isOpera() {
return isOpera;
}
/**
* Tests if the browser is Internet Explorer.
*
* @return true if it is Internet Explorer, false otherwise
*/
public boolean isIE() {
return isIE;
}
/**
* Tests if the browser is Edge.
*
* @return true if it is Edge, false otherwise
*/
public boolean isEdge() {
return isEdge;
}
/**
* Tests if the browser is PhantomJS.
*
* @return true if it is PhantomJS, false otherwise
*/
public boolean isPhantomJS() {
return isPhantomJS;
}
/**
* Returns the version of the browser engine. For WebKit this is an integer
* e.g., 532.0. For gecko it is a float e.g., 1.8 or 1.9.
*
* @return The version of the browser engine
*/
public float getBrowserEngineVersion() {
return browserEngineVersion;
}
/**
* Returns the browser major version e.g., 3 for Firefox 3.5, 4 for Chrome
* 4, 8 for Internet Explorer 8.
*
* Note that Internet Explorer 8 and newer will return the document mode so
* IE8 rendering as IE7 will return 7.
*
*
* @return The major version of the browser.
*/
public final int getBrowserMajorVersion() {
return browserMajorVersion;
}
/**
* Returns the browser minor version e.g., 5 for Firefox 3.5.
*
* @see #getBrowserMajorVersion()
*
* @return The minor version of the browser, or -1 if not known/parsed.
*/
public final int getBrowserMinorVersion() {
return browserMinorVersion;
}
/**
* Sets the version for IE based on the documentMode. This is used to return
* the correct the correct IE version when the version from the user agent
* string and the value of the documentMode property do not match.
*
* @param documentMode
* The current document mode
*/
public void setIEMode(int documentMode) {
browserMajorVersion = documentMode;
browserMinorVersion = 0;
}
/**
* Tests if the browser is run on Windows.
*
* @return true if run on Windows, false otherwise
*/
public boolean isWindows() {
return os == OperatingSystem.WINDOWS;
}
/**
* Tests if the browser is run on Windows Phone.
*
* @return true if run on Windows Phone, false otherwise
* @since 7.3.2
*/
public boolean isWindowsPhone() {
return isWindowsPhone;
}
/**
* Tests if the browser is run on Mac OSX.
*
* @return true if run on Mac OSX, false otherwise
*/
public boolean isMacOSX() {
return os == OperatingSystem.MACOSX;
}
/**
* Tests if the browser is run on Linux.
*
* @return true if run on Linux, false otherwise
*/
public boolean isLinux() {
return os == OperatingSystem.LINUX;
}
/**
* Tests if the browser is run on Android.
*
* @return true if run on Android, false otherwise
*/
public boolean isAndroid() {
return os == OperatingSystem.ANDROID;
}
/**
* Tests if the browser is run in iOS.
*
* @return true if run in iOS, false otherwise
*/
public boolean isIOS() {
return os == OperatingSystem.IOS;
}
/**
* Tests if the browser is run on iPhone.
*
* @return true if run on iPhone, false otherwise
* @since 7.3.3
*/
public boolean isIPhone() {
return isIPhone;
}
/**
* Tests if the browser is run on iPad.
*
* @return true if run on iPad, false otherwise
* @since 7.3.3
*/
public boolean isIPad() {
return isIPad;
}
/**
* Returns the major version of the operating system. Currently only
* supported for mobile devices (iOS/Android)
*
* @return The major version or -1 if unknown
*/
public int getOperatingSystemMajorVersion() {
return osMajorVersion;
}
/**
* Returns the minor version of the operating system. Currently only
* supported for mobile devices (iOS/Android)
*
* @return The minor version or -1 if unknown
*/
public int getOperatingSystemMinorVersion() {
return osMinorVersion;
}
/**
* Checks if the browser is so old that it simply won't work with a Vaadin
* application. NOTE that the browser might still be capable of running
* Crome Frame, so you might still want to check
* {@link #isChromeFrameCapable()} if this returns true.
*
* @return true if the browser won't work, false if not the browser is
* supported or might work
*/
public boolean isTooOldToFunctionProperly() {
// Check Trident version to detect compatibility mode
if (isIE() && getBrowserMajorVersion() < 8
&& getBrowserEngineVersion() < 4) {
return true;
}
// Webkit 533 in Safari 4.1+, Android 2.2+, iOS 4+
if (isSafari() && getBrowserEngineVersion() < 533) {
return true;
}
if (isFirefox() && getBrowserMajorVersion() < 4) {
return true;
}
if (isOpera() && getBrowserMajorVersion() < 11) {
return true;
}
return false;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy