1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
|
/*
@VaadinApache2LicenseForJavaFiles@
*/
package com.vaadin.terminal.gwt.server;
import java.util.Date;
import java.util.Locale;
import com.vaadin.terminal.Terminal;
import com.vaadin.terminal.WrappedRequest;
import com.vaadin.terminal.gwt.client.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.
* @version @VERSION@
*/
public class WebBrowser implements Terminal {
private int screenHeight = 0;
private int screenWidth = 0;
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;
/**
* There is no default-theme for this terminal type.
*
* @return Always returns null.
*/
@Override
public String getDefaultTheme() {
return null;
}
/*
* (non-Javadoc)
*
* @see com.vaadin.terminal.Terminal#getScreenHeight()
*/
@Override
public int getScreenHeight() {
return screenHeight;
}
/*
* (non-Javadoc)
*
* @see com.vaadin.terminal.Terminal#getScreenWidth()
*/
@Override
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 Safari.
*
* @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();
}
/**
* 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 Integer 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 Integer getRawTimezoneOffset() {
return rawTimezoneOffset;
}
/**
* Gets the difference in minutes between the browser's GMT TimeZone and
* DST.
*
* @return the amount of minutes that the TimeZone shifts when DST is in
* effect
*/
public int getDSTSavings() {
return dstSavings;
}
/**
* Determines whether daylight savings 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.
*
* @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 AbstractApplicationServlet/AbstractApplicationPortlet
* 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 = 0;
}
}
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 AbstractApplicationServlet/AbstractApplicationPortlet
* only. Updates all properties in the class according to the given
* information.
*
* @param request
* the wrapped request to read the information from
*/
void updateRequestDetails(WrappedRequest request) {
locale = request.getLocale();
address = request.getRemoteAddr();
secureConnection = request.isSecure();
String agent = request.getHeader("user-agent");
if (agent != null) {
browserApplication = agent;
browserDetails = new VBrowserDetails(agent);
}
if (request.getParameter("sw") != null) {
updateClientSideDetails(request.getParameter("sw"),
request.getParameter("sh"), request.getParameter("tzo"),
request.getParameter("rtzo"), request.getParameter("dstd"),
request.getParameter("dston"),
request.getParameter("curdate"),
request.getParameter("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();
}
}
|