View Javadoc

1   /*
2    * Copyright (c) 2001 - 2005 ivata limited.
3    * All rights reserved.
4    * -----------------------------------------------------------------------------
5    * ivata masks may be redistributed under the GNU General Public
6    * License as published by the Free Software Foundation;
7    * version 2 of the License.
8    *
9    * These programs are free software; you can redistribute them and/or
10   * modify them under the terms of the GNU General Public License
11   * as published by the Free Software Foundation; version 2 of the License.
12   *
13   * These programs are distributed in the hope that they will be useful,
14   * but WITHOUT ANY WARRANTY; without even the implied warranty of
15   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16   *
17   * See the GNU General Public License in the file LICENSE.txt for more
18   * details.
19   *
20   * If you would like a copy of the GNU General Public License write to
21   *
22   * Free Software Foundation, Inc.
23   * 59 Temple Place - Suite 330
24   * Boston, MA 02111-1307, USA.
25   *
26   *
27   * To arrange commercial support and licensing, contact ivata at
28   *                  http://www.ivata.com/contact.jsp
29   * -----------------------------------------------------------------------------
30   * $Log: Browser.java,v $
31   * Revision 1.2  2005/04/09 18:04:17  colinmacleod
32   * Changed copyright text to GPL v2 explicitly.
33   *
34   * Revision 1.1  2005/01/06 23:00:12  colinmacleod
35   * Moved up a version number.
36   * Changed copyright notices to 2005.
37   * Updated the documentation:
38   *   - started working on multiproject:site docu.
39   *   - changed the logo.
40   * Added checkstyle and fixed LOADS of style issues.
41   * Added separate thirdparty subproject.
42   * Added struts (in web), util and webgui (in webtheme) from ivata op.
43   *
44   * Revision 1.3  2004/03/21 21:16:35  colinmacleod
45   * Shortened name to ivata op.
46   *
47   * Revision 1.2  2004/02/01 22:07:31  colinmacleod
48   * Added full names to author tags
49   *
50   * Revision 1.1.1.1  2004/01/27 20:59:38  colinmacleod
51   * Moved ivata op to SourceForge.
52   *
53   * Revision 1.2  2003/10/16 15:43:03  jano
54   * fixing problems with building and some problems with splitting to subprojects
55   *
56   * Revision 1.1.1.1  2003/10/13 20:49:28  colin
57   * Restructured portal into subprojects
58   *
59   * Revision 1.1  2003/02/24 19:33:32  colin
60   * Moved to new project.
61   *
62   * Revision 1.3  2003/02/04 17:43:46  colin
63   * Copyright notice
64   *
65   * Revision 1.2  2003/01/18 20:19:16  colin
66   * improved handling of opera including accurate recognition
67   * (even when opera pretends to be something else) and version numbers
68   *
69   * Revision 1.1  2002/09/16 13:52:48  colin
70   * Added browser class with checking for browser type, (i)frames.
71   * support and JavaScript.
72   * -----------------------------------------------------------------------------
73   */
74  package com.ivata.mask.web.browser;
75  import com.ivata.mask.util.StringHandling;
76  /***
77   * <p>
78   * This class identifies the capabilities of the web browser the client is
79   * using, from the user agent string.
80   * </p>
81   *
82   * <p>
83   * <code>LoginTag</code> creates an instance of this class in the http
84   * session, storing it under the attribute name <i>"browser" </i>.
85   * </p>
86   *
87   * @since ivata masks 0.4 (2002-09-12)
88   * @author Colin MacLeod
89   * <a href='mailto:colin.macleod@ivata.com'>colin.macleod@ivata.com</a>
90   * @version $Revision: 1.2 $
91   */
92  public class Browser {
93      /***
94       * Refer to {@link #getJavaScriptVersion()}.
95       */
96      private String javaScriptVersion = null;
97      /***
98       * Refer to {@link #getType}.
99       */
100     private Integer type;
101     /***
102      * Refer to {@link #getUserAgent}.
103      */
104     private String userAgent = null;
105     /***
106      * Refer to {@link #getVersion}.
107      */
108     private String version = null;
109     /***
110      * <p>
111      * Construct an instance of the browser, using the user agent string
112      * provided to detect the browser's capabilities.
113      * </p>
114      *
115      * @param userAgentParam
116      *            Refer to {@link #getUserAgent()}.
117      * @param javaScriptVersionParam
118      *            Refer to {@link #getJavaScriptVersion()}.
119      */
120     public Browser(final String userAgentParam,
121             final String javaScriptVersionParam) {
122         this.javaScriptVersion = javaScriptVersionParam;
123         // call the setter as it actually handles the browser detection
124         setUserAgent(userAgentParam);
125     }
126     /***
127      * <p>
128      * Detect whether or not the browser can display frames.
129      * </p>
130      *
131      * @return <code>true</code> if the browser can display frames, otherwise
132      *         <code>false</code>.
133      */
134     public final boolean canDisplayFrames() {
135         if (type.equals(BrowserConstants.TYPE_GALEON)
136                 || type.equals(BrowserConstants.TYPE_KONQUEROR)
137                 || type.equals(BrowserConstants.TYPE_LYNX)
138                 || type.equals(BrowserConstants.TYPE_MOZILLA)
139                 || type.equals(BrowserConstants.TYPE_OPERA)) {
140             return true;
141         } else if (type.equals(BrowserConstants.TYPE_INTERNET_EXPLORER)) {
142             return (version.compareTo("3") >= 0);
143         } else if (type.equals(BrowserConstants.TYPE_NETSCAPE)) {
144             return (version.compareTo("2") >= 0);
145         } else {
146             return false;
147         }
148     }
149     /***
150      * <p>
151      * Detect whether or not the browser can display <code>&lt;iframe&bt;</code>
152      * tags.
153      * </p>
154      *
155      * @return <code>true</code> if the browser can display iframes, otherwise
156      *         <code>false</code>.
157      */
158     public final boolean canDisplayIFrames() {
159         if (type.equals(BrowserConstants.TYPE_GALEON)
160                 || type.equals(BrowserConstants.TYPE_MOZILLA)) {
161             return true;
162         } else if (type.equals(BrowserConstants.TYPE_OPERA)) {
163             return (version.compareTo("5") >= 0);
164         } else if (type.equals(BrowserConstants.TYPE_INTERNET_EXPLORER)) {
165             return (version.compareTo("3") >= 0);
166         } else if (type.equals(BrowserConstants.TYPE_NETSCAPE)) {
167             return (version.compareTo("6") >= 0);
168         } else {
169             return false;
170         }
171     }
172     /***
173      * <p>
174      * Detect whether or not the browser can display
175      * <code>&lt;marquee&bt;</code> tags.
176      * </p>
177      *
178      * @return <code>true</code> if the browser can display marquee, otherwise
179      *         <code>false</code>.
180      */
181     public final boolean canDisplayMarquee() {
182         if (type.equals(BrowserConstants.TYPE_GALEON)
183                 || type.equals(BrowserConstants.TYPE_MOZILLA)) {
184             return true;
185         } else if (type.equals(BrowserConstants.TYPE_INTERNET_EXPLORER)) {
186             return (version.compareTo("3") >= 0);
187         } else if (type.equals(BrowserConstants.TYPE_NETSCAPE)) {
188             return (version.compareTo("6") >= 0);
189         } else {
190             return false;
191         }
192     }
193     /***
194      * <p>
195      * A String depicting the version number of the JavaScript this browser
196      * supports if supported, otherwise <code>null</code> if the browser
197      * doesn't support JavaScript.
198      * </p>
199      *
200      * @return the current value of javaScriptVersion.
201      */
202     public String getJavaScriptVersion() {
203         return javaScriptVersion;
204     }
205     /***
206      * <p>
207      * Identifies the make, or type of browser used (such as Mozilla, IE, etc.).
208      * Equates to one of the constants in {@linkBrowserConstants.
209      * </p>
210      *
211      * @return the current value of type.
212      */
213     public Integer getType() {
214         return type;
215     }
216     /***
217      * <p>
218      * Initialized by the constructor, this is the user agent string from the
219      * <code>request.getHeader("User-Agent")</code> value.
220      * </p>
221      *
222      * @return the current value of userAgent.
223      */
224     public String getUserAgent() {
225         return userAgent;
226     }
227     /***
228      * <p>
229      * A string depiction of the browser version number if available and known,
230      * otherwise <code>null</code> if the browser manufacturer could not be
231      * identified.
232      * </p>
233      *
234      * @return the current value of version.
235      */
236     public String getVersion() {
237         return version;
238     }
239     /***
240      * <p>
241      * Detect whether or not this browser is capable of displaying JavaScript,
242      * and has JavaScript enabled.
243      * </p>
244      *
245      * @return <code>true</code> if the browser can display JavaScript,
246      *         otherwise <code>false</code>.
247      */
248     public boolean isJavaScriptEnabled() {
249         return (javaScriptVersion != null);
250     }
251     /***
252      * Refer to {@link #getJavaScriptVersion}.
253      *
254      * @param javaScriptVersionParam
255      *            Refer to {@link #getJavaScriptVersion}.
256      */
257     public final void setJavaScriptVersion(
258             final String javaScriptVersionParam) {
259         this.javaScriptVersion = javaScriptVersionParam;
260     }
261     /***
262      * Refer to {@link #getType}.
263      *
264      * @param typeParam
265      *            Refer to {@link #getType}.
266      */
267     public final void setType(final Integer typeParam) {
268         this.type = typeParam;
269     }
270     /***
271      * Refer to {@link #getUserAgent}.
272      *
273      * @param userAgentParam
274      *            Refer to {@link #getUserAgent}.
275      */
276     public final void setUserAgent(final String userAgentParam) {
277         // convert null to empty string - easier to deal with :-)
278         if (StringHandling.isNullOrEmpty(userAgentParam)) {
279             this.userAgent = "";
280         } else {
281             this.userAgent = userAgentParam;
282         }
283         this.version = null;
284         // first let's find opera - it pretends to be everyone else too!
285         int position;
286         // first let's find opera - it pretends to be everyone else too!
287         int start;
288         // first let's find opera - it pretends to be everyone else too!
289         int end;
290         if ((position = userAgent.indexOf("Opera")) != -1) {
291             this.type = BrowserConstants.TYPE_OPERA;
292             // sometimes there is a slash sometimes just a space after 'Opera'
293             // either way, relative to the start of 'Opera', it is the same
294             start = position + "Opera".length() + 1;
295             end = userAgent.indexOf(" ", start);
296             if ((start != -1) && (end != -1)) {
297                 this.version = userAgent.substring(start, end);
298             }
299         } else if ((position = userAgent.indexOf("Galeon")) != -1) {
300             this.type = BrowserConstants.TYPE_GALEON;
301             start = userAgent.indexOf("/", position);
302             end = userAgent.indexOf(" ", start);
303             if ((start != -1) && (end != -1)) {
304                 this.version = userAgent.substring(++start, end);
305             }
306         } else if (userAgent.indexOf("Gecko") != -1) {
307             // see if it is (old) Netscape
308             if ((position = userAgent.indexOf("Netscape")) != -1) {
309                 this.type = BrowserConstants.TYPE_NETSCAPE;
310                 start = userAgent.indexOf("/", position);
311                 end = userAgent.indexOf(" ", start);
312                 if ((start != -1) && (end != -1)) {
313                     this.version = userAgent.substring(++start, end);
314                 }
315             } else {
316                 // treat all other Gecko browsers as Mozilla
317                 this.type = BrowserConstants.TYPE_MOZILLA;
318                 String rv = "rv:";
319                 start = userAgent.indexOf(rv, position);
320                 end = userAgent.indexOf(")", start);
321                 if ((start != -1) && (end != -1)) {
322                     start += rv.length();
323                     this.version = userAgent.substring(start, end);
324                 } else {
325                     // just default to 0 for Mozilla
326                     this.version = "0";
327                 }
328             }
329         } else if ((userAgent.indexOf("Nav") != -1)
330                 || (userAgent.indexOf("Gold") != -1)
331                 || (userAgent.indexOf("Netscape") != -1)) {
332             // good old fashioned navigator 4.x and earlier
333             this.type = BrowserConstants.TYPE_NETSCAPE;
334         } else if ((position = userAgent.indexOf("MSIE")) != -1) {
335             // Internet Explorer
336             this.type = BrowserConstants.TYPE_INTERNET_EXPLORER;
337             start = userAgent.indexOf(" ", position);
338             end = userAgent.indexOf(";", start);
339             if ((start != -1) && (end != -1)) {
340                 this.version = userAgent.substring(++start, end);
341             } else {
342                 // don't want to let this default to Mozilla number
343                 // unlikely to be < 3.0 anyway!
344                 this.version = "3.0";
345             }
346         } else if (userAgent.indexOf("Konq") != -1) {
347             this.type = BrowserConstants.TYPE_KONQUEROR;
348         } else if (userAgent.indexOf("Lynx") != -1) {
349             this.type = BrowserConstants.TYPE_LYNX;
350         } else if ((userAgent.indexOf("bot") != 1)
351                 || (userAgent.indexOf("Google") != 1)
352                 || (userAgent.indexOf("Slurp") != 1)
353                 || (userAgent.indexOf("Scooter") != 1)
354                 || (userAgent.indexOf("Spider") != 1)
355                 || (userAgent.indexOf("Infoseek") != 1)) {
356             this.type = BrowserConstants.TYPE_ROBOT;
357         } else {
358             this.type = BrowserConstants.TYPE_UNKNOWN;
359         }
360         // if the version wasn't set above, set it to the string after the
361         // first slash, before the first space after that
362         if (this.version == null) {
363             start = userAgent.indexOf("/", position);
364             end = userAgent.indexOf(" ", start);
365             if ((start != -1) && (end != -1)) {
366                 this.version = userAgent.substring(++start, end);
367             } else {
368                 // default the version number to zero for alphanumeric
369                 // comparisons
370                 this.version = "0";
371             }
372         }
373     }
374     /***
375      * Refer to {@link #getVersion()}.
376      *
377      * @param versionParam
378      *            Refer to {@link #getVersion()}.
379      */
380     public final void setVersion(final String versionParam) {
381         this.version = versionParam;
382     }
383 }