diff --git a/wise-webapp/src/main/java/com/wisemapping/filter/UserAgent.java b/wise-webapp/src/main/java/com/wisemapping/filter/UserAgent.java
index f5aa06b3..2563f4e0 100644
--- a/wise-webapp/src/main/java/com/wisemapping/filter/UserAgent.java
+++ b/wise-webapp/src/main/java/com/wisemapping/filter/UserAgent.java
@@ -1,343 +1,344 @@
-/*
-* Copyright [2011] [wisemapping]
-*
-* Licensed under WiseMapping Public License, Version 1.0 (the "License").
-* It is basically the Apache License, Version 2.0 (the "License") plus the
-* "powered by wisemapping" text requirement on every single page;
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the license at
-*
-* http://www.wisemapping.org/license
-*
-* 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.wisemapping.filter;
-
-import org.apache.commons.logging.LogFactory;
-
-import javax.servlet.http.HttpServletRequest;
-import java.io.Serializable;
-
-public class UserAgent implements Serializable {
- public static final String USER_AGENT_HEADER = "User-Agent";
- private int versionMajor = -1;
- private int versionVariation = -1;
- private Product product;
- private OS os;
- private final org.apache.commons.logging.Log logger = LogFactory.getLog(UserAgent.class.getName());
- private boolean hasGCFInstalled = false;
-
- public static void main(final String argv[]) {
- UserAgent explorer = UserAgent.create("Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)");
-// UserAgent firefox = UserAgent.create("Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.5) Gecko/20050302 Firefox/0.9.6");
- UserAgent safari = UserAgent.create("iCab/2.9.5 (Macintosh; U; PPC; Mac OS X)");
- UserAgent opera = UserAgent.create("Opera/9.21 (Windows NT 5.1; U; en)");
-
-
- UserAgent firefox = UserAgent.create("Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.5) Gecko/20050302 Firefox/1.9.6");
- assert firefox.isBrowserSupported();
-
-
- firefox = UserAgent.create("Mozilla/5.0 (Windows; U; Windows NT 5.1; de; rv:1.8.1.7) Gecko/20070914 Firefox/2.0.0.7 Creative ZENcast v1.02.08 FirePHP/0.0.5.13");
- assert firefox.isBrowserSupported();
-
- firefox = UserAgent.create("Mozilla/5.0 (X11; U; Linux i686; es-ES; rv:1.8.0.12) Gecko/20070731 Ubuntu/dapper-security Firefox/1.5.0.12");
- assert firefox.isBrowserSupported();
-
- firefox = UserAgent.create("'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.7) Gecko/20070914 firefox 2.0'");
- assert firefox.isBrowserSupported();
-
- firefox = UserAgent.create("Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.8.1.12) Gecko/20080129 Iceweasel/2.0.0.12 (Debian-2.0.0.12-0etch1)");
- assert firefox.isBrowserSupported();
-
- }
-
-
- public boolean isVersionGreatedOrEqualThan(final int mayor, final int variation) {
- return this.versionMajor > mayor || (mayor == this.versionMajor && this.versionVariation >= variation);
- }
-
- public boolean isVersionLessThan(final int mayor) {
- return this.versionMajor < mayor;
- }
-
- public int getVersionMajor() {
- return versionMajor;
- }
-
- public int getVersionVariation() {
- return versionVariation;
- }
-
- public Product getProduct() {
- return product;
- }
-
- public OS getOs() {
- return os;
- }
-
- public enum Product {
- EXPLORER, FIREFOX, CAMINO, NETSCAPE, OPERA, SAFARI, CHROME, KONQUEOR, KMELEON, MOZILLA, LYNX, ROBOT, WEB_CRAWLER
- }
-
- public enum OS {
- WINDOWS, LINUX, MAC, KNOWN
- }
-
-
- private UserAgent(final String header) {
- parse(header);
- }
-
- private void parse(String userAgentHeader) {
- // Format ApplicationName/ApplicationVersion ();
-
- try {
- int detailStart = userAgentHeader.indexOf('(');
- int detailEnd = userAgentHeader.indexOf(')');
-
- // Parse base format = application (productDetails) productAddition
- String application = userAgentHeader.substring(0, detailStart);
- application = application.trim();
-
- String productDetails = userAgentHeader.substring(detailStart + 1, detailEnd);
- productDetails = productDetails.trim();
-
- String productAddition = userAgentHeader.substring(detailEnd + 1, userAgentHeader.length());
- productAddition = productAddition.trim();
-
- this.os = parseOS(productDetails);
-
- if (userAgentHeader.contains("Googlebot")) {
- //"Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)"
- this.product = Product.WEB_CRAWLER;
-
- } else if (userAgentHeader.contains("MSIE")) {
- // Explorer Browser : http://msdn2.microsoft.com/en-us/library/ms537503.aspx
- // Format: Mozilla/MozVer (compatible; MSIE IEVer[; Provider]; Platform[; Extension]*) [Addition]
- // SampleTest: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; Google Wireless Transcoder;)
-
- // Parse version ...
- int index = productDetails.indexOf("MSIE") + 4;
- int lastIndex = productDetails.indexOf(';', index);
-
- final String versionStr = productDetails.substring(index + 1, lastIndex);
- parseVersion(versionStr);
-
- // Explorer Parse ...
- this.product = Product.EXPLORER;
- this.hasGCFInstalled = productDetails.contains("chromeframe");
- } else if (userAgentHeader.contains("iCab") || userAgentHeader.contains("Safari")) {
- // Safari:
- //Formats: Mozilla/5.0 (Windows; U; Windows NT 5.1; en) AppleWebKit/522.13.1 (KHTML, like Gecko) Version/3.0.2 Safari/522.13.1
- //Chrome:
- //Formats: "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_4; en-US) AppleWebKit/534.7 (KHTML, like Gecko) Chrome/7.0.517.44 Safari/534.7"
- String versionStr = "";
- if (userAgentHeader.contains("Chrome")) {
- this.product = Product.CHROME;
- versionStr = userAgentHeader.substring(userAgentHeader.indexOf("Chrome") + 7, userAgentHeader.lastIndexOf(" "));
- } else {
- this.product = Product.SAFARI;
- versionStr = userAgentHeader.substring(userAgentHeader.indexOf("Version") + 8, userAgentHeader.lastIndexOf(" "));
- }
-
- parseVersion(versionStr);
-
- } else if (userAgentHeader.contains("Konqueror")) {
- this.product = Product.KONQUEOR;
- } else if (userAgentHeader.contains("KMeleon")) {
- this.product = Product.KMELEON;
- } else if (userAgentHeader.contains("Gecko")) {
- // Firefox/Mozilla/Camino:
- // Mozilla/MozVer (Platform; Security; SubPlatform; Language; rv:Revision[; Extension]*) Gecko/GeckVer [Product/ProdVer]
- // SampleTest: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.5) Gecko/20050302 Firefox/0.9.6
- // Mozilla/5.0 (Windows; U; Windows NT 5.1; de; rv:1.8.1.7) Gecko/20070914 Firefox/2.0.0.7 Creative ZENcast v1.02.08 FirePHP/0.0.5.13
- // 'Mozilla/5.0 (Windows; U; Windows NT 5.1; es-ES; rv:1.7.12) Gecko/20050915'
- // 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.7) Gecko/20070914 firefox 2.0'
- // 'Mozilla/5.0 (X11; U; Linux i686 (x86_64); en-US; rv:1.8.1.6) Gecko/20060601 Firefox/2.0.0.6 (Ubuntu-edgy)'
- // 'Mozilla/5.0 (X11; U; Linux i686; es-ES; rv:1.8.0.12) Gecko/20070731 Ubuntu/dapper-security Firefox/1.5.0.12'
- // "Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.8.1.12) Gecko/20080129 Iceweasel/2.0.0.12 (Debian-2.0.0.12-0etch1)
-
- // Remove gecko string
- // Debian Firefox is remamed to iceweasel.
- productAddition = productAddition.replace("Iceweasel", "firefox");
-
-
- productAddition = productAddition.substring(productAddition.indexOf(' ') + 1);
- productAddition = productAddition.toLowerCase();
- String prodDesc = null;
- if (productAddition.contains("firefox")) {
- this.product = Product.FIREFOX;
- prodDesc = "firefox";
- } else if (productAddition.contains("netscape")) {
- this.product = Product.NETSCAPE;
- prodDesc = "netscape";
- } else if (productAddition.contains("camino")) {
- this.product = Product.CAMINO;
- prodDesc = "camino";
- } else {
- this.product = Product.MOZILLA;
- // @todo: How it can get the mozilla vesion?
- }
-
- // Now, parse product version ...
- if (prodDesc != null) {
- int sI = productAddition.indexOf(prodDesc) + prodDesc.length() + 1;
- int eI = productAddition.indexOf(' ', sI);
- if (eI == -1) {
- eI = productAddition.length();
- }
-
- final String productVersion = productAddition.substring(sI, eI);
- parseVersion(productVersion);
-
- }
-
- } else if (userAgentHeader.contains("Opera")) {
- // Opera:
- // Samples: Opera/9.0 (Windows NT 5.1; U; en)
- // Opera/8.5 (Macintosh; PPC Mac OS X; U; en)
- // Mozilla/5.0 (Macintosh; PPC Mac OS X; U; en) Opera 8.5
- // Mozilla/4.0 (compatible; MSIE 6.0; Mac_PowerPC Mac OS X; en) Opera 8.5
- // Opera/9.21 (Windows NT 5.1; U; en)
- this.product = Product.OPERA;
- String productVersion;
- if (application.startsWith("Opera")) {
- productVersion = application.substring(application.indexOf('/') + 1, application.length());
-
- } else {
- productVersion = productAddition.substring(application.lastIndexOf(' ') + 1, application.length());
- }
- parseVersion(productVersion);
-
- } else if (userAgentHeader.contains("4.7")) {
- this.product = Product.NETSCAPE;
- } else if (userAgentHeader.contains("Lynx")) {
- this.product = Product.LYNX;
- } else {
- // It's a robot ..
- for (String botAgent : botAgents) {
- if (userAgentHeader.contains(botAgent)) {
- // set a key in the session, so the next time we don't have to manually
- // detect the robot again
- this.product = Product.ROBOT;
- break;
- }
- }
- logger.info("UserAgent could not be detected: '" + userAgentHeader + "'");
- }
- } catch (Throwable e) {
- logger.error("Could not detect the browser based on the user agent: '" + userAgentHeader + "'");
- // Mark as an unsupported browser...
- this.product = Product.ROBOT;
- }
- }
-
- private OS parseOS(String details) {
- OS result;
- if (details.contains("Windows"))
- result = OS.WINDOWS;
- else if (details.contains("Mac") || details.contains("Macintosh"))
- result = OS.MAC;
- else if (details.contains("X11"))
- result = OS.LINUX;
- else
- result = OS.KNOWN;
- return result;
- }
-
- public static UserAgent create(final HttpServletRequest request) {
- final String userAgent = request.getHeader(USER_AGENT_HEADER);
- return new UserAgent(userAgent);
- }
-
-
- public static UserAgent create(final String userAgent) {
- return new UserAgent(userAgent);
- }
-
- private void parseVersion(final String version) {
- final int index = version.indexOf('.');
- final String vm = version.substring(0, index);
- final String vv = version.substring(index + 1, version.length());
- this.versionMajor = Integer.parseInt(vm);
- char c = vv.charAt(0);
- this.versionVariation = Integer.valueOf(String.valueOf(c));
- }
-
- /**
- * All known robot user-agent headers (list can be found
- * here).
- *
- * NOTE: To avoid bad detection:
- *
- *
- * - Robots with ID of 2 letters only were removed
- * - Robot called "webs" were removed
- * - directhit was changed in direct_hit (its real id)
- *
- */
- private static final String[] botAgents = {
- "acme.spider", "ahoythehomepagefinder", "alkaline", "appie", "arachnophilia",
- "architext", "aretha", "ariadne", "aspider", "atn.txt", "atomz", "auresys",
- "backrub", "bigbrother", "bjaaland", "blackwidow", "blindekuh", "bloodhound",
- "brightnet", "bspider", "cactvschemistryspider", "calif", "cassandra",
- "cgireader", "checkbot", "churl", "cmc", "collective", "combine", "conceptbot",
- "core", "cshkust", "cusco", "cyberspyder", "deweb", "dienstspider", "diibot",
- "direct_hit", "dnabot", "download_express", "dragonbot", "dwcp", "ebiness",
- "eit", "emacs", "emcspider", "esther", "evliyacelebi", "fdse", "felix",
- "ferret", "fetchrover", "fido", "finnish", "fireball", "fish", "fouineur",
- "francoroute", "freecrawl", "funnelweb", "gazz", "gcreep", "getbot", "geturl",
- "golem", "googlebot", "grapnel", "griffon", "gromit", "gulliver", "hambot",
- "harvest", "havindex", "hometown", "wired-digital", "htdig", "htmlgobble",
- "hyperdecontextualizer", "ibm", "iconoclast", "ilse", "imagelock", "incywincy",
- "informant", "infoseek", "infoseeksidewinder", "infospider", "inspectorwww",
- "intelliagent", "iron33", "israelisearch", "javabee", "jcrawler", "jeeves",
- "jobot", "joebot", "jubii", "jumpstation", "katipo", "kdd", "kilroy",
- "ko_yappo_robot", "labelgrabber.txt", "larbin", "legs", "linkscan",
- "linkwalker", "lockon", "logo_gif", "lycos", "macworm", "magpie", "mediafox",
- "merzscope", "meshexplorer", "mindcrawler", "moget", "momspider", "monster",
- "motor", "muscatferret", "mwdsearch", "myweb", "netcarta", "netmechanic",
- "netscoop", "newscan-online", "nhse", "nomad", "northstar", "nzexplorer",
- "occam", "octopus", "orb_search", "packrat", "pageboy", "parasite", "patric",
- "perignator", "perlcrawler", "phantom", "piltdownman", "pioneer", "pitkow",
- "pjspider", "pka", "plumtreewebaccessor", "poppi", "portalb", "puu", "python",
- "raven", "rbse", "resumerobot", "rhcs", "roadrunner", "robbie", "robi",
- "roverbot", "safetynetrobot", "scooter", "search_au", "searchprocess",
- "senrigan", "sgscout", "shaggy", "shaihulud", "sift", "simbot", "site-valet",
- "sitegrabber", "sitetech", "slurp", "smartspider", "snooper", "solbot",
- "spanner", "speedy", "spider_monkey", "spiderbot", "spiderman", "spry",
- "ssearcher", "suke", "sven", "tach_bw", "tarantula", "tarspider", "tcl",
- "techbot", "templeton", "titin", "titan", "tkwww", "tlspider", "ucsd",
- "udmsearch", "urlck", "valkyrie", "victoria", "visionsearch", "voyager",
- "vwbot", "w3index", "w3m2", "wanderer", "webbandit", "webcatcher", "webcopy",
- "webfetcher", "webfoot", "weblayers", "weblinker", "webmirror", "webmoose",
- "webquest", "webreader", "webreaper", "websnarf", "webspider", "webvac",
- "webwalk", "webwalker", "webwatch", "wget", "whowhere", "wmir", "wolp",
- "wombat", "worm", "wwwc", "wz101", "xget", "nederland.zoek"
- };
-
- public boolean isBrowserSupported() {
- // Is it a supported browser ?.
- final UserAgent.Product product = this.getProduct();
- boolean result = product == UserAgent.Product.FIREFOX && this.isVersionGreatedOrEqualThan(12, 0);
- result = result || product == UserAgent.Product.EXPLORER && this.isVersionGreatedOrEqualThan(7, 0) && this.getOs() == UserAgent.OS.WINDOWS;
- result = result || product == UserAgent.Product.OPERA && this.isVersionGreatedOrEqualThan(11, 0);
- result = result || product == UserAgent.Product.CHROME && this.isVersionGreatedOrEqualThan(19, 0);
- result = result || product == UserAgent.Product.SAFARI && this.isVersionGreatedOrEqualThan(5, 0);
- result = result || product == Product.WEB_CRAWLER;
-
- return result;
- }
-
- public boolean needsGCF() {
- final UserAgent.Product product = this.getProduct();
- return product == UserAgent.Product.EXPLORER && this.isVersionLessThan(9) && this.getOs() == UserAgent.OS.WINDOWS && !this.hasGCFInstalled;
- }
-}
+/*
+* Copyright [2011] [wisemapping]
+*
+* Licensed under WiseMapping Public License, Version 1.0 (the "License").
+* It is basically the Apache License, Version 2.0 (the "License") plus the
+* "powered by wisemapping" text requirement on every single page;
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the license at
+*
+* http://www.wisemapping.org/license
+*
+* 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.wisemapping.filter;
+
+import org.apache.commons.logging.LogFactory;
+
+import javax.servlet.http.HttpServletRequest;
+import java.io.Serializable;
+
+public class UserAgent implements Serializable {
+ public static final String USER_AGENT_HEADER = "User-Agent";
+ private int versionMajor = -1;
+ private int versionVariation = -1;
+ private Product product;
+ private OS os;
+ private final org.apache.commons.logging.Log logger = LogFactory.getLog(UserAgent.class.getName());
+ private boolean hasGCFInstalled = false;
+
+ public static void main(final String argv[]) {
+ UserAgent explorer = UserAgent.create("Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)");
+// UserAgent firefox = UserAgent.create("Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.5) Gecko/20050302 Firefox/0.9.6");
+ UserAgent safari = UserAgent.create("iCab/2.9.5 (Macintosh; U; PPC; Mac OS X)");
+ UserAgent opera = UserAgent.create("Opera/9.21 (Windows NT 5.1; U; en)");
+
+
+ UserAgent firefox = UserAgent.create("Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.5) Gecko/20050302 Firefox/1.9.6");
+ assert firefox.isBrowserSupported();
+
+
+ firefox = UserAgent.create("Mozilla/5.0 (Windows; U; Windows NT 5.1; de; rv:1.8.1.7) Gecko/20070914 Firefox/2.0.0.7 Creative ZENcast v1.02.08 FirePHP/0.0.5.13");
+ assert firefox.isBrowserSupported();
+
+ firefox = UserAgent.create("Mozilla/5.0 (X11; U; Linux i686; es-ES; rv:1.8.0.12) Gecko/20070731 Ubuntu/dapper-security Firefox/1.5.0.12");
+ assert firefox.isBrowserSupported();
+
+ firefox = UserAgent.create("'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.7) Gecko/20070914 firefox 2.0'");
+ assert firefox.isBrowserSupported();
+
+ firefox = UserAgent.create("Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.8.1.12) Gecko/20080129 Iceweasel/2.0.0.12 (Debian-2.0.0.12-0etch1)");
+ assert firefox.isBrowserSupported();
+
+ }
+
+
+ public boolean isVersionGreatedOrEqualThan(final int mayor, final int variation) {
+ return this.versionMajor > mayor || (mayor == this.versionMajor && this.versionVariation >= variation);
+ }
+
+ public boolean isVersionLessThan(final int mayor) {
+ return this.versionMajor < mayor;
+ }
+
+ public int getVersionMajor() {
+ return versionMajor;
+ }
+
+ public int getVersionVariation() {
+ return versionVariation;
+ }
+
+ public Product getProduct() {
+ return product;
+ }
+
+ public OS getOs() {
+ return os;
+ }
+
+ public enum Product {
+ EXPLORER, FIREFOX, CAMINO, NETSCAPE, OPERA, SAFARI, CHROME, KONQUEOR, KMELEON, MOZILLA, LYNX, ROBOT, WEB_CRAWLER
+ }
+
+ public enum OS {
+ WINDOWS, LINUX, MAC, KNOWN
+ }
+
+
+ private UserAgent(final String header) {
+ parse(header);
+ }
+
+ private void parse(String userAgentHeader) {
+ // Format ApplicationName/ApplicationVersion ();
+
+ try {
+ int detailStart = userAgentHeader.indexOf('(');
+ int detailEnd = userAgentHeader.indexOf(')');
+
+ // Parse base format = application (productDetails) productAddition
+ String application = userAgentHeader.substring(0, detailStart);
+ application = application.trim();
+
+ String productDetails = userAgentHeader.substring(detailStart + 1, detailEnd);
+ productDetails = productDetails.trim();
+
+ String productAddition = userAgentHeader.substring(detailEnd + 1, userAgentHeader.length());
+ productAddition = productAddition.trim();
+
+ this.os = parseOS(productDetails);
+
+ if (userAgentHeader.contains("Googlebot") || userAgentHeader.contains("Mediapartners-Google")) {
+ //"Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)"
+ // Mediapartners-Google -> Add sense robot
+ this.product = Product.WEB_CRAWLER;
+
+ } else if (userAgentHeader.contains("MSIE")) {
+ // Explorer Browser : http://msdn2.microsoft.com/en-us/library/ms537503.aspx
+ // Format: Mozilla/MozVer (compatible; MSIE IEVer[; Provider]; Platform[; Extension]*) [Addition]
+ // SampleTest: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; Google Wireless Transcoder;)
+
+ // Parse version ...
+ int index = productDetails.indexOf("MSIE") + 4;
+ int lastIndex = productDetails.indexOf(';', index);
+
+ final String versionStr = productDetails.substring(index + 1, lastIndex);
+ parseVersion(versionStr);
+
+ // Explorer Parse ...
+ this.product = Product.EXPLORER;
+ this.hasGCFInstalled = productDetails.contains("chromeframe");
+ } else if (userAgentHeader.contains("iCab") || userAgentHeader.contains("Safari")) {
+ // Safari:
+ //Formats: Mozilla/5.0 (Windows; U; Windows NT 5.1; en) AppleWebKit/522.13.1 (KHTML, like Gecko) Version/3.0.2 Safari/522.13.1
+ //Chrome:
+ //Formats: "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_4; en-US) AppleWebKit/534.7 (KHTML, like Gecko) Chrome/7.0.517.44 Safari/534.7"
+ String versionStr = "";
+ if (userAgentHeader.contains("Chrome")) {
+ this.product = Product.CHROME;
+ versionStr = userAgentHeader.substring(userAgentHeader.indexOf("Chrome") + 7, userAgentHeader.lastIndexOf(" "));
+ } else {
+ this.product = Product.SAFARI;
+ versionStr = userAgentHeader.substring(userAgentHeader.indexOf("Version") + 8, userAgentHeader.lastIndexOf(" "));
+ }
+
+ parseVersion(versionStr);
+
+ } else if (userAgentHeader.contains("Konqueror")) {
+ this.product = Product.KONQUEOR;
+ } else if (userAgentHeader.contains("KMeleon")) {
+ this.product = Product.KMELEON;
+ } else if (userAgentHeader.contains("Gecko")) {
+ // Firefox/Mozilla/Camino:
+ // Mozilla/MozVer (Platform; Security; SubPlatform; Language; rv:Revision[; Extension]*) Gecko/GeckVer [Product/ProdVer]
+ // SampleTest: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.5) Gecko/20050302 Firefox/0.9.6
+ // Mozilla/5.0 (Windows; U; Windows NT 5.1; de; rv:1.8.1.7) Gecko/20070914 Firefox/2.0.0.7 Creative ZENcast v1.02.08 FirePHP/0.0.5.13
+ // 'Mozilla/5.0 (Windows; U; Windows NT 5.1; es-ES; rv:1.7.12) Gecko/20050915'
+ // 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.7) Gecko/20070914 firefox 2.0'
+ // 'Mozilla/5.0 (X11; U; Linux i686 (x86_64); en-US; rv:1.8.1.6) Gecko/20060601 Firefox/2.0.0.6 (Ubuntu-edgy)'
+ // 'Mozilla/5.0 (X11; U; Linux i686; es-ES; rv:1.8.0.12) Gecko/20070731 Ubuntu/dapper-security Firefox/1.5.0.12'
+ // "Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.8.1.12) Gecko/20080129 Iceweasel/2.0.0.12 (Debian-2.0.0.12-0etch1)
+
+ // Remove gecko string
+ // Debian Firefox is remamed to iceweasel.
+ productAddition = productAddition.replace("Iceweasel", "firefox");
+
+
+ productAddition = productAddition.substring(productAddition.indexOf(' ') + 1);
+ productAddition = productAddition.toLowerCase();
+ String prodDesc = null;
+ if (productAddition.contains("firefox")) {
+ this.product = Product.FIREFOX;
+ prodDesc = "firefox";
+ } else if (productAddition.contains("netscape")) {
+ this.product = Product.NETSCAPE;
+ prodDesc = "netscape";
+ } else if (productAddition.contains("camino")) {
+ this.product = Product.CAMINO;
+ prodDesc = "camino";
+ } else {
+ this.product = Product.MOZILLA;
+ // @todo: How it can get the mozilla vesion?
+ }
+
+ // Now, parse product version ...
+ if (prodDesc != null) {
+ int sI = productAddition.indexOf(prodDesc) + prodDesc.length() + 1;
+ int eI = productAddition.indexOf(' ', sI);
+ if (eI == -1) {
+ eI = productAddition.length();
+ }
+
+ final String productVersion = productAddition.substring(sI, eI);
+ parseVersion(productVersion);
+
+ }
+
+ } else if (userAgentHeader.contains("Opera")) {
+ // Opera:
+ // Samples: Opera/9.0 (Windows NT 5.1; U; en)
+ // Opera/8.5 (Macintosh; PPC Mac OS X; U; en)
+ // Mozilla/5.0 (Macintosh; PPC Mac OS X; U; en) Opera 8.5
+ // Mozilla/4.0 (compatible; MSIE 6.0; Mac_PowerPC Mac OS X; en) Opera 8.5
+ // Opera/9.21 (Windows NT 5.1; U; en)
+ this.product = Product.OPERA;
+ String productVersion;
+ if (application.startsWith("Opera")) {
+ productVersion = application.substring(application.indexOf('/') + 1, application.length());
+
+ } else {
+ productVersion = productAddition.substring(application.lastIndexOf(' ') + 1, application.length());
+ }
+ parseVersion(productVersion);
+
+ } else if (userAgentHeader.contains("4.7")) {
+ this.product = Product.NETSCAPE;
+ } else if (userAgentHeader.contains("Lynx")) {
+ this.product = Product.LYNX;
+ } else {
+ // It's a robot ..
+ for (String botAgent : botAgents) {
+ if (userAgentHeader.contains(botAgent)) {
+ // set a key in the session, so the next time we don't have to manually
+ // detect the robot again
+ this.product = Product.ROBOT;
+ break;
+ }
+ }
+ logger.info("UserAgent could not be detected: '" + userAgentHeader + "'");
+ }
+ } catch (Throwable e) {
+ logger.error("Could not detect the browser based on the user agent: '" + userAgentHeader + "'");
+ // Mark as an unsupported browser...
+ this.product = Product.ROBOT;
+ }
+ }
+
+ private OS parseOS(String details) {
+ OS result;
+ if (details.contains("Windows"))
+ result = OS.WINDOWS;
+ else if (details.contains("Mac") || details.contains("Macintosh"))
+ result = OS.MAC;
+ else if (details.contains("X11"))
+ result = OS.LINUX;
+ else
+ result = OS.KNOWN;
+ return result;
+ }
+
+ public static UserAgent create(final HttpServletRequest request) {
+ final String userAgent = request.getHeader(USER_AGENT_HEADER);
+ return new UserAgent(userAgent);
+ }
+
+
+ public static UserAgent create(final String userAgent) {
+ return new UserAgent(userAgent);
+ }
+
+ private void parseVersion(final String version) {
+ final int index = version.indexOf('.');
+ final String vm = version.substring(0, index);
+ final String vv = version.substring(index + 1, version.length());
+ this.versionMajor = Integer.parseInt(vm);
+ char c = vv.charAt(0);
+ this.versionVariation = Integer.valueOf(String.valueOf(c));
+ }
+
+ /**
+ * All known robot user-agent headers (list can be found
+ * here).
+ *
+ * NOTE: To avoid bad detection:
+ *
+ *
+ * - Robots with ID of 2 letters only were removed
+ * - Robot called "webs" were removed
+ * - directhit was changed in direct_hit (its real id)
+ *
+ */
+ private static final String[] botAgents = {
+ "acme.spider", "ahoythehomepagefinder", "alkaline", "appie", "arachnophilia",
+ "architext", "aretha", "ariadne", "aspider", "atn.txt", "atomz", "auresys",
+ "backrub", "bigbrother", "bjaaland", "blackwidow", "blindekuh", "bloodhound",
+ "brightnet", "bspider", "cactvschemistryspider", "calif", "cassandra",
+ "cgireader", "checkbot", "churl", "cmc", "collective", "combine", "conceptbot",
+ "core", "cshkust", "cusco", "cyberspyder", "deweb", "dienstspider", "diibot",
+ "direct_hit", "dnabot", "download_express", "dragonbot", "dwcp", "ebiness",
+ "eit", "emacs", "emcspider", "esther", "evliyacelebi", "fdse", "felix",
+ "ferret", "fetchrover", "fido", "finnish", "fireball", "fish", "fouineur",
+ "francoroute", "freecrawl", "funnelweb", "gazz", "gcreep", "getbot", "geturl",
+ "golem", "googlebot", "grapnel", "griffon", "gromit", "gulliver", "hambot",
+ "harvest", "havindex", "hometown", "wired-digital", "htdig", "htmlgobble",
+ "hyperdecontextualizer", "ibm", "iconoclast", "ilse", "imagelock", "incywincy",
+ "informant", "infoseek", "infoseeksidewinder", "infospider", "inspectorwww",
+ "intelliagent", "iron33", "israelisearch", "javabee", "jcrawler", "jeeves",
+ "jobot", "joebot", "jubii", "jumpstation", "katipo", "kdd", "kilroy",
+ "ko_yappo_robot", "labelgrabber.txt", "larbin", "legs", "linkscan",
+ "linkwalker", "lockon", "logo_gif", "lycos", "macworm", "magpie", "mediafox",
+ "merzscope", "meshexplorer", "mindcrawler", "moget", "momspider", "monster",
+ "motor", "muscatferret", "mwdsearch", "myweb", "netcarta", "netmechanic",
+ "netscoop", "newscan-online", "nhse", "nomad", "northstar", "nzexplorer",
+ "occam", "octopus", "orb_search", "packrat", "pageboy", "parasite", "patric",
+ "perignator", "perlcrawler", "phantom", "piltdownman", "pioneer", "pitkow",
+ "pjspider", "pka", "plumtreewebaccessor", "poppi", "portalb", "puu", "python",
+ "raven", "rbse", "resumerobot", "rhcs", "roadrunner", "robbie", "robi",
+ "roverbot", "safetynetrobot", "scooter", "search_au", "searchprocess",
+ "senrigan", "sgscout", "shaggy", "shaihulud", "sift", "simbot", "site-valet",
+ "sitegrabber", "sitetech", "slurp", "smartspider", "snooper", "solbot",
+ "spanner", "speedy", "spider_monkey", "spiderbot", "spiderman", "spry",
+ "ssearcher", "suke", "sven", "tach_bw", "tarantula", "tarspider", "tcl",
+ "techbot", "templeton", "titin", "titan", "tkwww", "tlspider", "ucsd",
+ "udmsearch", "urlck", "valkyrie", "victoria", "visionsearch", "voyager",
+ "vwbot", "w3index", "w3m2", "wanderer", "webbandit", "webcatcher", "webcopy",
+ "webfetcher", "webfoot", "weblayers", "weblinker", "webmirror", "webmoose",
+ "webquest", "webreader", "webreaper", "websnarf", "webspider", "webvac",
+ "webwalk", "webwalker", "webwatch", "wget", "whowhere", "wmir", "wolp",
+ "wombat", "worm", "wwwc", "wz101", "xget", "nederland.zoek"
+ };
+
+ public boolean isBrowserSupported() {
+ // Is it a supported browser ?.
+ final UserAgent.Product product = this.getProduct();
+ boolean result = product == UserAgent.Product.FIREFOX && this.isVersionGreatedOrEqualThan(12, 0);
+ result = result || product == UserAgent.Product.EXPLORER && this.isVersionGreatedOrEqualThan(7, 0) && this.getOs() == UserAgent.OS.WINDOWS;
+ result = result || product == UserAgent.Product.OPERA && this.isVersionGreatedOrEqualThan(11, 0);
+ result = result || product == UserAgent.Product.CHROME && this.isVersionGreatedOrEqualThan(19, 0);
+ result = result || product == UserAgent.Product.SAFARI && this.isVersionGreatedOrEqualThan(5, 0);
+ result = result || product == Product.WEB_CRAWLER;
+
+ return result;
+ }
+
+ public boolean needsGCF() {
+ final UserAgent.Product product = this.getProduct();
+ return product == UserAgent.Product.EXPLORER && this.isVersionLessThan(9) && this.getOs() == UserAgent.OS.WINDOWS && !this.hasGCFInstalled;
+ }
+}