123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557 |
- /*
- * Copyright 2000-2016 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.server;
-
- import java.io.Serializable;
- import java.util.Date;
- import java.util.Locale;
- import java.util.TimeZone;
-
- import com.vaadin.shared.VBrowserDetails;
-
- /**
- * Class that provides information about the web browser the user is using.
- * Provides information such as browser name and version, screen resolution and
- * IP address.
- *
- * @author Vaadin Ltd.
- */
- public class WebBrowser implements Serializable {
-
- private int screenHeight = -1;
- private int screenWidth = -1;
- private String browserApplication = null;
- private Locale locale;
- private String address;
- private boolean secureConnection;
- private int timezoneOffset = 0;
- private int rawTimezoneOffset = 0;
- private int dstSavings;
- private boolean dstInEffect;
- private boolean touchDevice;
-
- private VBrowserDetails browserDetails;
- private long clientServerTimeDelta;
-
- /**
- * Gets the height of the screen in pixels. This is the full screen
- * resolution and not the height available for the application.
- *
- * @return the height of the screen in pixels.
- */
- public int getScreenHeight() {
- return screenHeight;
- }
-
- /**
- * Gets the width of the screen in pixels. This is the full screen
- * resolution and not the width available for the application.
- *
- * @return the width of the screen in pixels.
- */
- public int getScreenWidth() {
- return screenWidth;
- }
-
- /**
- * Get the browser user-agent string.
- *
- * @return The raw browser userAgent string
- */
- public String getBrowserApplication() {
- return browserApplication;
- }
-
- /**
- * Gets the IP-address of the web browser. If the application is running
- * inside a portlet, this method will return null.
- *
- * @return IP-address in 1.12.123.123 -format
- */
- public String getAddress() {
- return address;
- }
-
- /** Get the default locate of the browser. */
- public Locale getLocale() {
- return locale;
- }
-
- /** Is the connection made using HTTPS? */
- public boolean isSecureConnection() {
- return secureConnection;
- }
-
- /**
- * Tests whether the user is using Firefox.
- *
- * @return true if the user is using Firefox, false if the user is not using
- * Firefox or if no information on the browser is present
- */
- public boolean isFirefox() {
- if (browserDetails == null) {
- return false;
- }
-
- return browserDetails.isFirefox();
- }
-
- /**
- * Tests whether the user is using Internet Explorer.
- *
- * @return true if the user is using Internet Explorer, false if the user is
- * not using Internet Explorer or if no information on the browser
- * is present
- */
- public boolean isIE() {
- if (browserDetails == null) {
- return false;
- }
-
- return browserDetails.isIE();
- }
-
- /**
- * Tests whether the user is using Edge.
- *
- * @since 7.5.3
- * @return true if the user is using Edge, false if the user is not using
- * Edge or if no information on the browser is present
- */
- public boolean isEdge() {
- if (browserDetails == null) {
- return false;
- }
-
- return browserDetails.isEdge();
- }
-
- /**
- * Tests whether the user is using Safari. Note that Chrome on iOS is not
- * detected as Safari but as Chrome although the underlying browser engine
- * is the same.
- *
- * @return true if the user is using Safari, false if the user is not using
- * Safari or if no information on the browser is present
- */
- public boolean isSafari() {
- if (browserDetails == null) {
- return false;
- }
-
- return browserDetails.isSafari();
- }
-
- /**
- * Tests whether the user is using Opera.
- *
- * @return true if the user is using Opera, false if the user is not using
- * Opera or if no information on the browser is present
- */
- public boolean isOpera() {
- if (browserDetails == null) {
- return false;
- }
-
- return browserDetails.isOpera();
- }
-
- /**
- * Tests whether the user is using Chrome.
- *
- * @return true if the user is using Chrome, false if the user is not using
- * Chrome or if no information on the browser is present
- */
- public boolean isChrome() {
- if (browserDetails == null) {
- return false;
- }
-
- return browserDetails.isChrome();
- }
-
- /**
- * Tests whether the user is using Chrome Frame.
- *
- * @return true if the user is using Chrome Frame, false if the user is not
- * using Chrome or if no information on the browser is present
- */
- public boolean isChromeFrame() {
- if (browserDetails == null) {
- return false;
- }
-
- return browserDetails.isChromeFrame();
- }
-
- /**
- * Tests whether the user's browser is Chrome Frame capable.
- *
- * @return true if the user can use Chrome Frame, false if the user can not
- * or if no information on the browser is present
- */
- public boolean isChromeFrameCapable() {
- if (browserDetails == null) {
- return false;
- }
-
- return browserDetails.isChromeFrameCapable();
- }
-
- /**
- * Gets the major version of the browser the user is using.
- *
- * <p>
- * Note that Internet Explorer in IE7 compatibility mode might return 8 in
- * some cases even though it should return 7.
- * </p>
- *
- * @return The major version of the browser or -1 if not known.
- */
- public int getBrowserMajorVersion() {
- if (browserDetails == null) {
- return -1;
- }
-
- return browserDetails.getBrowserMajorVersion();
- }
-
- /**
- * Gets the minor version of the browser the user is using.
- *
- * @see #getBrowserMajorVersion()
- *
- * @return The minor version of the browser or -1 if not known.
- */
- public int getBrowserMinorVersion() {
- if (browserDetails == null) {
- return -1;
- }
-
- return browserDetails.getBrowserMinorVersion();
- }
-
- /**
- * Tests whether the user is using Linux.
- *
- * @return true if the user is using Linux, false if the user is not using
- * Linux or if no information on the browser is present
- */
- public boolean isLinux() {
- return browserDetails.isLinux();
- }
-
- /**
- * Tests whether the user is using Mac OS X.
- *
- * @return true if the user is using Mac OS X, false if the user is not
- * using Mac OS X or if no information on the browser is present
- */
- public boolean isMacOSX() {
- return browserDetails.isMacOSX();
- }
-
- /**
- * Tests whether the user is using Windows.
- *
- * @return true if the user is using Windows, false if the user is not using
- * Windows or if no information on the browser is present
- */
- public boolean isWindows() {
- return browserDetails.isWindows();
- }
-
- /**
- * Tests whether the user is using Windows Phone.
- *
- * @return true if the user is using Windows Phone, false if the user is not
- * using Windows Phone or if no information on the browser is
- * present
- * @since 7.3.2
- */
- public boolean isWindowsPhone() {
- return browserDetails.isWindowsPhone();
- }
-
- /**
- * Tests if the browser is run on Android.
- *
- * @return true if run on Android false if the user is not using Android or
- * if no information on the browser is present
- */
- public boolean isAndroid() {
- return browserDetails.isAndroid();
- }
-
- /**
- * Tests if the browser is run in iOS.
- *
- * @return true if run in iOS false if the user is not using iOS or if no
- * information on the browser is present
- */
- public boolean isIOS() {
- return browserDetails.isIOS();
- }
-
- /**
- * Tests if the browser is run on IPhone.
- *
- * @return true if run on IPhone false if the user is not using IPhone or if
- * no information on the browser is present
- * @since 7.3.3
- */
- public boolean isIPhone() {
- return browserDetails.isIPhone();
- }
-
- /**
- * Tests if the browser is run on IPad.
- *
- * @return true if run on IPad false if the user is not using IPad or if no
- * information on the browser is present
- * @since 7.3.3
- */
- public boolean isIPad() {
- return browserDetails.isIPad();
- }
-
- /**
- * Returns the browser-reported TimeZone offset in milliseconds from GMT.
- * This includes possible daylight saving adjustments, to figure out which
- * TimeZone the user actually might be in, see
- * {@link #getRawTimezoneOffset()}.
- *
- * @see WebBrowser#getRawTimezoneOffset()
- * @return timezone offset in milliseconds, 0 if not available
- */
- public int getTimezoneOffset() {
- return timezoneOffset;
- }
-
- /**
- * Returns the browser-reported TimeZone offset in milliseconds from GMT
- * ignoring possible daylight saving adjustments that may be in effect in
- * the browser.
- * <p>
- * You can use this to figure out which TimeZones the user could actually be
- * in by calling {@link TimeZone#getAvailableIDs(int)}.
- * </p>
- * <p>
- * If {@link #getRawTimezoneOffset()} and {@link #getTimezoneOffset()}
- * returns the same value, the browser is either in a zone that does not
- * currently have daylight saving time, or in a zone that never has daylight
- * saving time.
- * </p>
- *
- * @return timezone offset in milliseconds excluding DST, 0 if not available
- */
- public int getRawTimezoneOffset() {
- return rawTimezoneOffset;
- }
-
- /**
- * Returns the offset in milliseconds between the browser's GMT TimeZone and
- * DST.
- *
- * @return the number of milliseconds that the TimeZone shifts when DST is
- * in effect
- */
- public int getDSTSavings() {
- return dstSavings;
- }
-
- /**
- * Returns whether daylight saving time (DST) is currently in effect in the
- * region of the browser or not.
- *
- * @return true if the browser resides at a location that currently is in
- * DST
- */
- public boolean isDSTInEffect() {
- return dstInEffect;
- }
-
- /**
- * Returns the current date and time of the browser. This will not be
- * entirely accurate due to varying network latencies, but should provide a
- * close-enough value for most cases. Also note that the returned Date
- * object uses servers default time zone, not the clients.
- * <p>
- * To get the actual date and time shown in the end users computer, you can
- * do something like:
- *
- * <pre>
- * WebBrowser browser = ...;
- * SimpleTimeZone timeZone = new SimpleTimeZone(browser.getTimezoneOffset(), "Fake client time zone");
- * DateFormat format = DateFormat.getDateTimeInstance();
- * format.setTimeZone(timeZone);
- * myLabel.setValue(format.format(browser.getCurrentDate()));
- * </pre>
- *
- * @return the current date and time of the browser.
- * @see #isDSTInEffect()
- * @see #getDSTSavings()
- * @see #getTimezoneOffset()
- */
- public Date getCurrentDate() {
- return new Date(new Date().getTime() + clientServerTimeDelta);
- }
-
- /**
- * @return true if the browser is detected to support touch events
- */
- public boolean isTouchDevice() {
- return touchDevice;
- }
-
- /**
- * For internal use by VaadinServlet/VaadinPortlet only. Updates all
- * properties in the class according to the given information.
- *
- * @param sw
- * Screen width
- * @param sh
- * Screen height
- * @param tzo
- * TimeZone offset in minutes from GMT
- * @param rtzo
- * raw TimeZone offset in minutes from GMT (w/o DST adjustment)
- * @param dstSavings
- * the difference between the raw TimeZone and DST in minutes
- * @param dstInEffect
- * is DST currently active in the region or not?
- * @param curDate
- * the current date in milliseconds since the epoch
- * @param touchDevice
- */
- void updateClientSideDetails(String sw, String sh, String tzo, String rtzo,
- String dstSavings, String dstInEffect, String curDate,
- boolean touchDevice) {
- if (sw != null) {
- try {
- screenHeight = Integer.parseInt(sh);
- screenWidth = Integer.parseInt(sw);
- } catch (final NumberFormatException e) {
- screenHeight = screenWidth = -1;
- }
- }
- if (tzo != null) {
- try {
- // browser->java conversion: min->ms, reverse sign
- timezoneOffset = -Integer.parseInt(tzo) * 60 * 1000;
- } catch (final NumberFormatException e) {
- timezoneOffset = 0; // default gmt+0
- }
- }
- if (rtzo != null) {
- try {
- // browser->java conversion: min->ms, reverse sign
- rawTimezoneOffset = -Integer.parseInt(rtzo) * 60 * 1000;
- } catch (final NumberFormatException e) {
- rawTimezoneOffset = 0; // default gmt+0
- }
- }
- if (dstSavings != null) {
- try {
- // browser->java conversion: min->ms
- this.dstSavings = Integer.parseInt(dstSavings) * 60 * 1000;
- } catch (final NumberFormatException e) {
- this.dstSavings = 0; // default no savings
- }
- }
- if (dstInEffect != null) {
- this.dstInEffect = Boolean.parseBoolean(dstInEffect);
- }
- if (curDate != null) {
- try {
- long curTime = Long.parseLong(curDate);
- clientServerTimeDelta = curTime - new Date().getTime();
- } catch (final NumberFormatException e) {
- clientServerTimeDelta = 0;
- }
- }
- this.touchDevice = touchDevice;
-
- }
-
- /**
- * For internal use by VaadinServlet/VaadinPortlet only. Updates all
- * properties in the class according to the given information.
- *
- * @param request
- * the Vaadin request to read the information from
- */
- public void updateRequestDetails(VaadinRequest request) {
- locale = request.getLocale();
- address = request.getRemoteAddr();
- secureConnection = request.isSecure();
- // Headers are case insensitive according to the specifiation but are
- // case sensitive in Weblogic portal...
- String agent = request.getHeader("User-Agent");
-
- if (agent != null) {
- browserApplication = agent;
- browserDetails = new VBrowserDetails(agent);
- }
-
- if (request.getParameter("v-sw") != null) {
- updateClientSideDetails(request.getParameter("v-sw"),
- request.getParameter("v-sh"), request.getParameter("v-tzo"),
- request.getParameter("v-rtzo"),
- request.getParameter("v-dstd"),
- request.getParameter("v-dston"),
- request.getParameter("v-curdate"),
- request.getParameter("v-td") != null);
- }
- }
-
- /**
- * Checks if the browser is so old that it simply won't work with a Vaadin
- * application. Can be used to redirect to an alternative page, show
- * alternative content or similar.
- *
- * When this method returns true chances are very high that the browser
- * won't work and it does not make sense to direct the user to the Vaadin
- * application.
- *
- * @return true if the browser won't work, false if not the browser is
- * supported or might work
- */
- public boolean isTooOldToFunctionProperly() {
- if (browserDetails == null) {
- // Don't know, so assume it will work
- return false;
- }
-
- return browserDetails.isTooOldToFunctionProperly();
- }
-
- /**
- * Checks if the browser supports ECMAScript 6, based on the user agent.
- *
- * @return <code>true</code> if the browser supports ES6, <code>false</code>
- * otherwise.
- */
- public boolean isEs6Supported() {
- if (browserDetails == null) {
- // Don't know, so assume no
- return false;
- }
- return browserDetails.isEs6Supported();
-
- }
- }
|