public Device build(UserAgent userAgent, int confidenceTreshold) { ArrayList<Device> foundDevices = new ArrayList<Device>(); for (String step1Token : orderedRules.keySet()) { if (userAgent.getCompleteUserAgent().matches("(?i).*" + step1Token + ".*")) { Map<String, String> step1Compliant = (Map<String, String>) orderedRules.get(step1Token); for (String step2token : step1Compliant.keySet()) { Device d = elaborateTwoStepDeviceWithToken(userAgent, step1Token, step2token); if (d != null) { if (d.getConfidence() > confidenceTreshold) { return d; } else { if (d.getConfidence() > 0) { foundDevices.add(d); } } } } } } if (foundDevices.size() > 0) { Collections.sort(foundDevices, Collections.reverseOrder()); return foundDevices.get(0); } return null; }
private Device elaborateTwoStepDeviceWithToken( UserAgent userAgent, String step1Token, String step2Token) { int maxLittleTokensDistance = 4; int maxBigTokensDistance = 8; int confidence; String originalToken = step2Token; String looseToken = step2Token.replaceAll("[ _/-]", ".?"); if (userAgent.getCompleteUserAgent().matches("(?i).*" + step2Token + ".*")) { confidence = 100; } else if (userAgent.getCompleteUserAgent().matches("(?i).*" + looseToken + ".*")) { step2Token = looseToken; confidence = 90; } else { return null; } Matcher result = Pattern.compile( "(?i)(?:(?:.*" + step1Token + "(.*?)" + step2Token + ".*)|(?:.*" + step2Token + "(.*?)" + step1Token + ".*))") .matcher(userAgent.getCompleteUserAgent()); if (result.matches()) { // test for case sensitive match Matcher bestResult = Pattern.compile( "(?:(?:.*" + step1Token + "(.*?)" + step2Token + ".*)|(?:.*" + step2Token + "(.*?)" + step1Token + ".*))") .matcher(userAgent.getCompleteUserAgent()); if (bestResult.matches()) { result = bestResult; } else { confidence -= 20; } String betweenTokens = result.group(1); String s2 = result.group(2); if (s2 != null && (betweenTokens == null || betweenTokens.length() > s2.length())) { betweenTokens = s2; } int betweenTokensLength = betweenTokens.length(); if (step2Token.length() > 3) { if (betweenTokensLength > maxBigTokensDistance) { confidence -= 10; } String deviceId = ((Map<String, String>) orderedRules.get(step1Token)).get(originalToken); if (devices.containsKey(deviceId)) { Device retDevice = (Device) devices.get(deviceId).clone(); retDevice.setConfidence(confidence); return retDevice; } } if ((betweenTokensLength < maxLittleTokensDistance) || (betweenTokensLength < maxBigTokensDistance && (step2Token.length() < 6 || !anyLetter.matcher(step2Token).matches()))) { if (betweenTokensLength <= 1) { if (!looseSymbols.matcher(betweenTokens).matches()) { confidence -= 20; } } else { confidence -= 40; } confidence -= (betweenTokensLength * 4); String deviceId = ((Map<String, String>) orderedRules.get(step1Token)).get(originalToken); if (devices.containsKey(deviceId)) { Device retDevice = (Device) devices.get(deviceId).clone(); retDevice.setConfidence(confidence); return retDevice; } } } return null; }