cache;
110 |
111 | private boolean osParserEnabled = true;
112 | private boolean deviceParserEnabled = true;
113 | private boolean deviceBrandParserEnabled = true;
114 | private boolean inMemoryEnabled = false;
115 |
116 | /**
117 | * Instantiates a new udger parser with LRU cache with capacity of 10.000 items
118 | *
119 | * @param parserDbData the parser data associated with single DB
120 | */
121 | public UdgerParser(ParserDbData parserDbData) {
122 | this(parserDbData, 10000);
123 | }
124 |
125 | /**
126 | * Instantiates a new udger parser.
127 | *
128 | * @param parserDbData the parser data associated with single DB
129 | * @param cacheCapacity the LRU cache capacity
130 | */
131 | public UdgerParser(ParserDbData parserDbData, int cacheCapacity) {
132 | this.parserDbData = parserDbData;
133 | if (cacheCapacity > 0) {
134 | cache = new LRUCache<>(cacheCapacity);
135 | }
136 | }
137 |
138 | /**
139 | * Instantiates a new udger parser with LRU cache with capacity of 10.000 items
140 | *
141 | * @param parserDbData the parser data associated with single DB
142 | * @param inMemoryEnabled the true for in memory mode
143 | * @param cacheCapacity the LRU cache capacity
144 | */
145 | public UdgerParser(ParserDbData parserDbData, boolean inMemoryEnabled, int cacheCapacity) {
146 | this(parserDbData, cacheCapacity);
147 | this.inMemoryEnabled = inMemoryEnabled;
148 | }
149 |
150 | @Override
151 | public void close() throws IOException {
152 | try {
153 | for (PreparedStatement preparedStmt : preparedStmtMap.values()) {
154 | preparedStmt.close();
155 | }
156 | preparedStmtMap.clear();
157 | if (connection != null && !connection.isClosed()) {
158 | connection.close();
159 | connection = null;
160 | }
161 | if (cache != null) {
162 | cache.clear();
163 | }
164 | regexCache.clear();
165 | } catch (SQLException e) {
166 | throw new IOException(e.getMessage());
167 | }
168 | }
169 |
170 | /**
171 | * Returns true if the sqlite DB connection has not been closed and is still valid.
172 | *
173 | * @param timeoutMillis the timeout millis
174 | * @return true, if is valid
175 | * @throws IOException Signals that an I/O exception has occurred.
176 | */
177 | public boolean isValid(int timeoutMillis) throws IOException {
178 | try {
179 | return connection == null || connection.isValid(timeoutMillis);
180 | } catch (SQLException e) {
181 | throw new IOException("Failed to validate connection within " + timeoutMillis + " millis.", e);
182 | }
183 | }
184 |
185 | /**
186 | * Parses the user agent string and stores results of parsing in UdgerUaResult.
187 | * If the parser was initialized to use an in memory DB, then the DB is not set to read only.
188 | * This does not matter since the connection is internal to this client, as such there are
189 | * no chance of external modifications.
190 | *
191 | * @param uaString the user agent string
192 | * @return the intance of UdgerUaResult storing results of parsing
193 | * @throws SQLException the SQL exception
194 | */
195 | public UdgerUaResult parseUa(String uaString) throws SQLException {
196 |
197 | UdgerUaResult ret;
198 |
199 | if (cache != null) {
200 | ret = cache.get(uaString);
201 | if (ret != null) {
202 | return ret;
203 | }
204 | }
205 |
206 | ret = new UdgerUaResult(uaString);
207 |
208 | prepare();
209 |
210 | ClientInfo clientInfo = clientDetector(uaString, ret);
211 |
212 | if (!"Crawler".equals(ret.getUaClass())) {
213 | if (osParserEnabled) {
214 | osDetector(uaString, ret, clientInfo);
215 | }
216 |
217 | if (deviceParserEnabled) {
218 | deviceDetector(uaString, ret, clientInfo);
219 | }
220 |
221 | if (deviceBrandParserEnabled) {
222 | if (ret.getOsFamilyCode() != null && !ret.getOsFamilyCode().isEmpty()) {
223 | fetchDeviceBrand(uaString, ret);
224 | }
225 | }
226 | }
227 |
228 | if (cache != null) {
229 | cache.put(uaString, ret);
230 | }
231 |
232 | return ret;
233 | }
234 |
235 | /**
236 | * Parses the IP string and stores results of parsing in UdgerIpResult.
237 | *
238 | * @param ipString the IP string
239 | * @return the instance of UdgerIpResult storing results of parsing
240 | * @throws SQLException the SQL exception
241 | * @throws UnknownHostException the unknown host exception
242 | */
243 | public UdgerIpResult parseIp(String ipString) throws SQLException, UnknownHostException {
244 |
245 | UdgerIpResult ret = new UdgerIpResult(ipString);
246 |
247 | InetAddress addr = InetAddress.getByName(ipString);
248 | Long ipv4int = null;
249 | String normalizedIp = null;
250 |
251 | if (addr instanceof Inet4Address) {
252 | ipv4int = 0L;
253 | for (byte b : addr.getAddress()) {
254 | ipv4int = ipv4int << 8 | (b & 0xFF);
255 | }
256 | normalizedIp = addr.getHostAddress();
257 | } else if (addr instanceof Inet6Address) {
258 | normalizedIp = addr.getHostAddress().replaceAll("((?:(?:^|:)0+\\b){2,}):?(?!\\S*\\b\\1:0+\\b)(\\S*)", "::$2");
259 | }
260 |
261 | ret.setIpClassification("Unrecognized");
262 | ret.setIpClassificationCode("unrecognized");
263 |
264 | if (normalizedIp != null) {
265 |
266 | prepare();
267 |
268 | try (ResultSet ipRs = getFirstRow(UdgerSqlQuery.SQL_IP, normalizedIp)) {
269 | if (ipRs != null && ipRs.next()) {
270 | fetchUdgerIp(ipRs, ret);
271 | if (!ID_CRAWLER.equals(ret.getIpClassificationCode())) {
272 | ret.setCrawlerFamilyInfoUrl("");
273 | }
274 | }
275 | }
276 |
277 | if (ipv4int != null) {
278 | ret.setIpVer(4);
279 | ResultSet dataCenterRs = getFirstRow(UdgerSqlQuery.SQL_DATACENTER, ipv4int, ipv4int);
280 | fetchDataCenterAndCloseRs(dataCenterRs, ret);
281 | } else {
282 | ret.setIpVer(6);
283 | int[] ipArray = ip6ToArray((Inet6Address) addr);
284 | ResultSet dataCenterRs = getFirstRow(UdgerSqlQuery.SQL_DATACENTER_RANGE6,
285 | ipArray[0], ipArray[0],
286 | ipArray[1], ipArray[1],
287 | ipArray[2], ipArray[2],
288 | ipArray[3], ipArray[3],
289 | ipArray[4], ipArray[4],
290 | ipArray[5], ipArray[5],
291 | ipArray[6], ipArray[6],
292 | ipArray[7], ipArray[7]
293 | );
294 | fetchDataCenterAndCloseRs(dataCenterRs, ret);
295 | }
296 | }
297 |
298 | return ret;
299 | }
300 |
301 | private void fetchDataCenterAndCloseRs(ResultSet dataCenterRs, UdgerIpResult ret) throws SQLException {
302 | if (dataCenterRs != null) {
303 | try {
304 | if (dataCenterRs.next()) {
305 | fetchDataCenter(dataCenterRs, ret);
306 | }
307 | } finally {
308 | dataCenterRs.close();
309 | }
310 | }
311 | }
312 |
313 | /**
314 | * Checks if is OS parser enabled. OS parser is enabled by default
315 | *
316 | * @return true, if is OS parser enabled
317 | */
318 | public boolean isOsParserEnabled() {
319 | return osParserEnabled;
320 | }
321 |
322 | /**
323 | * Enable/disable the OS parser. OS parser is enabled by default. If enabled following fields
324 | * of UdgerUaResult are processed by the OS parser:
325 | *
326 | * - osFamily, osFamilyCode, OS, osCode, osHomePage, osIcon, osIconBig
327 | * - osFamilyVendor, osFamilyVendorCode, osFamilyVedorHomepage, osInfoUrl
328 | *
329 | *
330 | * If the OSs fields are not necessary then disabling this feature can increase
331 | * the parser's performance.
332 | *
333 | * @param osParserEnabled the true if os parser is to be enabled
334 | */
335 | public void setOsParserEnabled(boolean osParserEnabled) {
336 | this.osParserEnabled = osParserEnabled;
337 | }
338 |
339 | /**
340 | * Checks if is device parser enabled. Device parser is enabled by default
341 | *
342 | * @return true, if device parser is enabled
343 | */
344 | public boolean isDeviceParserEnabled() {
345 | return deviceParserEnabled;
346 | }
347 |
348 | /**
349 | * Enable/disable the device parser. Device parser is enabled by default. If enabled following fields
350 | * of UdgerUaResult are filled by the device parser:
351 | *
352 | * - deviceClass, deviceClassCode, deviceClassIcon
353 | * - deviceClassIconBig, deviceClassInfoUrl
354 | *
355 | *
356 | * If the DEVICEs fields are not necessary then disabling this feature can increase
357 | * the parser's performance.
358 | *
359 | * @param deviceParserEnabled the true if device parser is to be enabled
360 | */
361 | public void setDeviceParserEnabled(boolean deviceParserEnabled) {
362 | this.deviceParserEnabled = deviceParserEnabled;
363 | }
364 |
365 | /**
366 | * Checks if is device brand parser enabled. Device brand parser is enabled by default.
367 | *
368 | * @return true, if device brand parser is enabled
369 | */
370 | public boolean isDeviceBrandParserEnabled() {
371 | return deviceBrandParserEnabled;
372 | }
373 |
374 | /**
375 | * Enable/disable the device brand parser. Device brand parser is enabled by default. If enabled following fields
376 | * of UdgerUaResult are filled by the device brand parser:
377 | *
378 | * - deviceMarketname, deviceBrand, deviceBrandCode, deviceBrandHomepage
379 | * - deviceBrandIcon, deviceBrandIconBig, deviceBrandInfoUrl
380 | *
381 | *
382 | * If the BRANDs fields are not necessary then disabling this feature can increase
383 | * the parser's performance.
384 | *
385 | * @param deviceBrandParserEnabled the true if device brand parser is to be enabled
386 | */
387 | public void setDeviceBrandParserEnabled(boolean deviceBrandParserEnabled) {
388 | this.deviceBrandParserEnabled = deviceBrandParserEnabled;
389 | }
390 |
391 | private static WordDetector createWordDetector(Connection connection, String regexTableName, String wordTableName) throws SQLException {
392 |
393 | Set usedWords = new HashSet<>();
394 |
395 | addUsedWords(usedWords, connection, regexTableName, "word_id");
396 | addUsedWords(usedWords, connection, regexTableName, "word2_id");
397 |
398 | WordDetector result = new WordDetector();
399 |
400 | try (final Statement statement = connection.createStatement();
401 | final ResultSet rs = statement.executeQuery("SELECT * FROM " + wordTableName)) {
402 | if (rs != null) {
403 | while (rs.next()) {
404 | int id = rs.getInt("id");
405 | if (usedWords.contains(id)) {
406 | String word = rs.getString("word").toLowerCase();
407 | result.addWord(id, word);
408 | }
409 | }
410 | }
411 | }
412 | return result;
413 | }
414 |
415 | private static void addUsedWords(Set usedWords, Connection connection, String regexTableName, String wordIdColumn) throws SQLException {
416 | try (Statement statement = connection.createStatement();
417 | ResultSet rs = statement.executeQuery("SELECT " + wordIdColumn + " FROM " + regexTableName)) {
418 | if (rs != null) {
419 | while (rs.next()) {
420 | usedWords.add(rs.getInt(wordIdColumn));
421 | }
422 | }
423 | }
424 | }
425 |
426 | private MatcherWithIdRegString findMatcherIdRegString(String uaString, Set foundClientWords, List list) {
427 | for (IdRegString irs : list) {
428 | if ((irs.wordId1 == 0 || foundClientWords.contains(irs.wordId1)) &&
429 | (irs.wordId2 == 0 || foundClientWords.contains(irs.wordId2))) {
430 | Matcher matcher = irs.pattern.matcher(uaString);
431 | if (matcher.find())
432 | return new MatcherWithIdRegString(matcher, irs);
433 | }
434 | }
435 | return null;
436 | }
437 |
438 | private static List prepareRegexpStruct(Connection connection, String regexpTableName) throws SQLException {
439 | List ret = new ArrayList<>();
440 | try (Statement statement = connection.createStatement();
441 | ResultSet rs = statement.executeQuery("SELECT rowid, regstring, word_id, word2_id FROM " + regexpTableName + " ORDER BY sequence")) {
442 | if (rs != null) {
443 | while (rs.next()) {
444 | IdRegString irs = new IdRegString();
445 | irs.id = rs.getInt("rowid");
446 | irs.wordId1 = rs.getInt("word_id");
447 | irs.wordId2 = rs.getInt("word2_id");
448 | String regex = rs.getString("regstring");
449 | Matcher m = PAT_UNPERLIZE.matcher(regex);
450 | if (m.matches()) {
451 | regex = m.group(1);
452 | }
453 | irs.pattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
454 | ret.add(irs);
455 | }
456 | }
457 | }
458 | return ret;
459 | }
460 |
461 | private ClientInfo clientDetector(String uaString, UdgerUaResult ret) throws SQLException {
462 | ClientInfo clientInfo = new ClientInfo();
463 | try (ResultSet userAgentRs1 = getFirstRow(UdgerSqlQuery.SQL_CRAWLER, uaString)) {
464 | if (userAgentRs1 != null && userAgentRs1.next()) {
465 | fetchUserAgent(userAgentRs1, ret);
466 | clientInfo.classId = 99;
467 | clientInfo.clientId = -1;
468 | } else {
469 | MatcherWithIdRegString mwirs = findMatcherIdRegString(uaString, parserDbData.clientWordDetector.findWords(uaString), parserDbData.clientRegstringList);
470 | if (mwirs != null) {
471 | try (ResultSet userAgentRs2 = getFirstRow(UdgerSqlQuery.SQL_CLIENT, mwirs.irs.id)) {
472 | if (userAgentRs2 != null && userAgentRs2.next()) {
473 | fetchUserAgent(userAgentRs2, ret);
474 | clientInfo.classId = ret.getClassId();
475 | clientInfo.clientId = ret.getClientId();
476 | patchVersions(mwirs.matcher, ret);
477 | }
478 | }
479 | } else {
480 | ret.setUaClass("Unrecognized");
481 | ret.setUaClassCode("unrecognized");
482 | }
483 | }
484 | }
485 | return clientInfo;
486 | }
487 |
488 | private void osDetector(String uaString, UdgerUaResult ret, ClientInfo clientInfo) throws SQLException {
489 | MatcherWithIdRegString mwirs = findMatcherIdRegString(uaString, parserDbData.osWordDetector.findWords(uaString), parserDbData.osRegstringList);
490 | if (mwirs != null) {
491 | try (ResultSet opSysRs = getFirstRow(UdgerSqlQuery.SQL_OS, mwirs.irs.id)) {
492 | if (opSysRs != null && opSysRs.next()) {
493 | fetchOperatingSystem(opSysRs, ret);
494 | }
495 | }
496 | } else {
497 | if (clientInfo.clientId != null && clientInfo.clientId != 0) {
498 | try (ResultSet opSysRs = getFirstRow(UdgerSqlQuery.SQL_CLIENT_OS, clientInfo.clientId.toString())) {
499 | if (opSysRs != null && opSysRs.next()) {
500 | fetchOperatingSystem(opSysRs, ret);
501 | }
502 | }
503 | }
504 | }
505 | }
506 |
507 | private void deviceDetector(String uaString, UdgerUaResult ret, ClientInfo clientInfo) throws SQLException {
508 | MatcherWithIdRegString mwirs = findMatcherIdRegString(uaString, parserDbData.deviceWordDetector.findWords(uaString), parserDbData.deviceRegstringList);
509 | if (mwirs != null) {
510 | try (ResultSet devRs = getFirstRow(UdgerSqlQuery.SQL_DEVICE, mwirs.irs.id)) {
511 | if (devRs != null && devRs.next()) {
512 | fetchDevice(devRs, ret);
513 | }
514 | }
515 | } else {
516 | if (clientInfo.classId != null && clientInfo.classId != -1) {
517 | try (ResultSet devRs = getFirstRow(UdgerSqlQuery.SQL_CLIENT_CLASS, clientInfo.classId.toString())) {
518 | if (devRs != null && devRs.next()) {
519 | fetchDevice(devRs, ret);
520 | }
521 | }
522 | }
523 | }
524 | }
525 |
526 | private void fetchDeviceBrand(String uaString, UdgerUaResult ret) throws SQLException {
527 | PreparedStatement preparedStatement = preparedStmtMap.get(UdgerSqlQuery.SQL_DEVICE_REGEX);
528 | if (preparedStatement == null) {
529 | preparedStatement = connection.prepareStatement(UdgerSqlQuery.SQL_DEVICE_REGEX);
530 | preparedStmtMap.put(UdgerSqlQuery.SQL_DEVICE_REGEX, preparedStatement);
531 | }
532 | preparedStatement.setObject(1, ret.getOsFamilyCode());
533 | preparedStatement.setObject(2, ret.getOsCode());
534 | try (ResultSet devRegexRs = preparedStatement.executeQuery()) {
535 | if (devRegexRs != null) {
536 | while (devRegexRs.next()) {
537 | String devId = devRegexRs.getString("id");
538 | String regex = devRegexRs.getString("regstring");
539 | if (devId != null && regex != null) {
540 | Pattern patRegex = getRegexFromCache(regex);
541 | Matcher matcher = patRegex.matcher(uaString);
542 | if (matcher.find()) {
543 | try (ResultSet devNameListRs = getFirstRow(UdgerSqlQuery.SQL_DEVICE_NAME_LIST, devId, matcher.group(1))) {
544 | if (devNameListRs != null && devNameListRs.next()) {
545 | ret.setDeviceMarketname(devNameListRs.getString("marketname"));
546 | ret.setDeviceBrand(devNameListRs.getString("brand"));
547 | ret.setDeviceBrandCode(devNameListRs.getString("brand_code"));
548 | ret.setDeviceBrandHomepage(devNameListRs.getString("brand_url"));
549 | ret.setDeviceBrandIcon(devNameListRs.getString("icon"));
550 | ret.setDeviceBrandIconBig(devNameListRs.getString("icon_big"));
551 | ret.setDeviceBrandInfoUrl(UDGER_UA_DEV_BRAND_LIST_URL + devNameListRs.getString("brand_code"));
552 | break;
553 | }
554 | }
555 | }
556 | }
557 | }
558 | }
559 | }
560 | }
561 |
562 |
563 | private int[] ip6ToArray(Inet6Address addr) {
564 | int ret[] = new int[8];
565 | byte[] bytes = addr.getAddress();
566 | for (int i = 0; i < 8; i++) {
567 | ret[i] = ((bytes[i * 2] << 8) & 0xff00) | (bytes[i * 2 + 1] & 0xff);
568 | }
569 | return ret;
570 | }
571 |
572 | private void prepare() throws SQLException {
573 | connect();
574 | parserDbData.prepare(connection);
575 | }
576 |
577 | private void connect() throws SQLException {
578 | if (connection == null) {
579 | SQLiteConfig config = new SQLiteConfig();
580 | config.setReadOnly(true);
581 | if (inMemoryEnabled) {
582 | // we cannot use read only for in memory DB since we need to populate this DB from the file.
583 | connection = DriverManager.getConnection("jdbc:sqlite::memory:");
584 | File dbfile = new File(parserDbData.dbFileName);
585 | try (Statement statement = connection.createStatement()) {
586 | statement.executeUpdate("restore from " + dbfile.getPath());
587 | } catch (Exception e) {
588 | LOG.warning("Error re-constructing in memory data base from Db file " + dbfile);
589 | }
590 | } else {
591 | connection = DriverManager.getConnection("jdbc:sqlite:" + parserDbData.dbFileName, config.toProperties());
592 | }
593 | }
594 | }
595 |
596 | private Pattern getRegexFromCache(String regex) {
597 | SoftReference patRegex = regexCache.get(regex);
598 | if (patRegex == null || patRegex.get() == null) {
599 | Matcher m = PAT_UNPERLIZE.matcher(regex);
600 | if (m.matches()) {
601 | regex = m.group(1);
602 | }
603 | patRegex = new SoftReference<>(Pattern.compile(regex, Pattern.CASE_INSENSITIVE | Pattern.DOTALL));
604 | regexCache.put(regex, patRegex);
605 | }
606 | return patRegex.get();
607 | }
608 |
609 | private ResultSet getFirstRow(String query, Object... params) throws SQLException {
610 | PreparedStatement preparedStatement = preparedStmtMap.get(query);
611 | if (preparedStatement == null) {
612 | preparedStatement = connection.prepareStatement(query);
613 | preparedStmtMap.put(query, preparedStatement);
614 | }
615 | for (int i = 0; i < params.length; i++) {
616 | preparedStatement.setObject(i + 1, params[i]);
617 | }
618 | preparedStatement.setMaxRows(1);
619 | return preparedStatement.executeQuery();
620 | }
621 |
622 |
623 | private void fetchUserAgent(ResultSet rs, UdgerUaResult ret) throws SQLException {
624 | ret.setClassId(rs.getInt("class_id"));
625 | ret.setClientId(rs.getInt("client_id"));
626 | ret.setCrawlerCategory(nvl(rs.getString("crawler_category")));
627 | ret.setCrawlerCategoryCode(nvl(rs.getString("crawler_category_code")));
628 | ret.setCrawlerLastSeen(nvl(rs.getString("crawler_last_seen")));
629 | ret.setCrawlerRespectRobotstxt(nvl(rs.getString("crawler_respect_robotstxt")));
630 | ret.setUa(nvl(rs.getString("ua")));
631 | ret.setUaClass(nvl(rs.getString("ua_class")));
632 | ret.setUaClassCode(nvl(rs.getString("ua_class_code")));
633 | ret.setUaEngine(nvl(rs.getString("ua_engine")));
634 | ret.setUaFamily(nvl(rs.getString("ua_family")));
635 | ret.setUaFamilyCode(nvl(rs.getString("ua_family_code")));
636 | ret.setUaFamilyHomepage(nvl(rs.getString("ua_family_homepage")));
637 | ret.setUaFamilyIcon(nvl(rs.getString("ua_family_icon")));
638 | ret.setUaFamilyIconBig(nvl(rs.getString("ua_family_icon_big")));
639 | ret.setUaFamilyInfoUrl(nvl(rs.getString("ua_family_info_url")));
640 | ret.setUaFamilyVendor(nvl(rs.getString("ua_family_vendor")));
641 | ret.setUaFamilyVendorCode(nvl(rs.getString("ua_family_vendor_code")));
642 | ret.setUaFamilyVendorHomepage(nvl(rs.getString("ua_family_vendor_homepage")));
643 | ret.setUaUptodateCurrentVersion(nvl(rs.getString("ua_uptodate_current_version")));
644 | ret.setUaVersion(nvl(rs.getString("ua_version")));
645 | ret.setUaVersionMajor(nvl(rs.getString("ua_version_major")));
646 | }
647 |
648 | private void fetchOperatingSystem(ResultSet rs, UdgerUaResult ret) throws SQLException {
649 | ret.setOsFamily(nvl(rs.getString("os_family")));
650 | ret.setOs(nvl(rs.getString("os")));
651 | ret.setOsCode(nvl(rs.getString("os_code")));
652 | ret.setOsFamilyCode(nvl(rs.getString("os_family_code")));
653 | ret.setOsFamilyVendorHomepage(nvl(rs.getString("os_family_vendor_homepage")));
654 | ret.setOsFamilyVendor(nvl(rs.getString("os_family_vendor")));
655 | ret.setOsFamilyVendorCode(nvl(rs.getString("os_family_vendor_code")));
656 | ret.setOsHomePage(nvl(rs.getString("os_home_page")));
657 | ret.setOsIcon(nvl(rs.getString("os_icon")));
658 | ret.setOsIconBig(nvl(rs.getString("os_icon_big")));
659 | ret.setOsInfoUrl(nvl(rs.getString("os_info_url")));
660 | }
661 |
662 | private void fetchDevice(ResultSet rs, UdgerUaResult ret) throws SQLException {
663 | ret.setDeviceClass(nvl(rs.getString("device_class")));
664 | ret.setDeviceClassCode(nvl(rs.getString("device_class_code")));
665 | ret.setDeviceClassIcon(nvl(rs.getString("device_class_icon")));
666 | ret.setDeviceClassIconBig(nvl(rs.getString("device_class_icon_big")));
667 | ret.setDeviceClassInfoUrl(nvl(rs.getString("device_class_info_url")));
668 | }
669 |
670 | private void patchVersions(Matcher lastPatternMatcher, UdgerUaResult ret) {
671 | if (lastPatternMatcher != null) {
672 | String version = "";
673 | if (lastPatternMatcher.groupCount() >= 1) {
674 | version = lastPatternMatcher.group(1);
675 | if (version == null) {
676 | version = "";
677 | }
678 | }
679 | ret.setUaVersion(version);
680 | String versionSegments[] = version.split("\\.");
681 | if (versionSegments.length > 0) {
682 | ret.setUaVersionMajor(version.split("\\.")[0]);
683 | } else {
684 | ret.setUaVersionMajor("");
685 | }
686 | ret.setUa((ret.getUa() != null ? ret.getUa() : "") + " " + version);
687 | } else {
688 | ret.setUaVersion("");
689 | ret.setUaVersionMajor("");
690 | }
691 | }
692 |
693 | private void fetchUdgerIp(ResultSet rs, UdgerIpResult ret) throws SQLException {
694 | ret.setCrawlerCategory(nvl(rs.getString("crawler_category")));
695 | ret.setCrawlerCategoryCode(nvl(rs.getString("crawler_category_code")));
696 | ret.setCrawlerFamily(nvl(rs.getString("crawler_family")));
697 | ret.setCrawlerFamilyCode(nvl(rs.getString("crawler_family_code")));
698 | ret.setCrawlerFamilyHomepage(nvl(rs.getString("crawler_family_homepage")));
699 | ret.setCrawlerFamilyIcon(nvl(rs.getString("crawler_family_icon")));
700 | ret.setCrawlerFamilyInfoUrl(nvl(rs.getString("crawler_family_info_url")));
701 | ret.setCrawlerFamilyVendor(nvl(rs.getString("crawler_family_vendor")));
702 | ret.setCrawlerFamilyVendorCode(nvl(rs.getString("crawler_family_vendor_code")));
703 | ret.setCrawlerFamilyVendorHomepage(nvl(rs.getString("crawler_family_vendor_homepage")));
704 | ret.setCrawlerLastSeen(nvl(rs.getString("crawler_last_seen")));
705 | ret.setCrawlerName(nvl(rs.getString("crawler_name")));
706 | ret.setCrawlerRespectRobotstxt(nvl(rs.getString("crawler_respect_robotstxt")));
707 | ret.setCrawlerVer(nvl(rs.getString("crawler_ver")));
708 | ret.setCrawlerVerMajor(nvl(rs.getString("crawler_ver_major")));
709 | ret.setIpCity(nvl(rs.getString("ip_city")));
710 | ret.setIpClassification(nvl(rs.getString("ip_classification")));
711 | ret.setIpClassificationCode(nvl(rs.getString("ip_classification_code")));
712 | ret.setIpCountry(nvl(rs.getString("ip_country")));
713 | ret.setIpCountryCode(nvl(rs.getString("ip_country_code")));
714 | ret.setIpHostname(nvl(rs.getString("ip_hostname")));
715 | ret.setIpLastSeen(nvl(rs.getString("ip_last_seen")));
716 | }
717 |
718 | private String nvl(String v) {
719 | return v != null ? v : "";
720 | }
721 |
722 | private void fetchDataCenter(ResultSet rs, UdgerIpResult ret) throws SQLException {
723 | ret.setDataCenterHomePage(nvl(rs.getString("datacenter_homepage")));
724 | ret.setDataCenterName(nvl(rs.getString("datacenter_name")));
725 | ret.setDataCenterNameCode(nvl(rs.getString("datacenter_name_code")));
726 | }
727 |
728 | }
729 |
--------------------------------------------------------------------------------
/src/main/java/org/udger/parser/UdgerSqlQuery.java:
--------------------------------------------------------------------------------
1 | /*
2 | Udger-update - Data updater for udger local and cloud parser
3 |
4 | author The Udger.com Team (info@udger.com)
5 | copyright Copyright (c) Udger s.r.o.
6 | license GNU Lesser General Public License
7 | link https://udger.com/products
8 | */
9 | package org.udger.parser;
10 |
11 | public class UdgerSqlQuery {
12 |
13 | public static final String SQL_CRAWLER =
14 | "SELECT " +
15 | "NULL AS client_id, " +
16 | "NULL AS class_id, " +
17 | "'Crawler' AS ua_class, " +
18 | "'crawler' AS ua_class_code, " +
19 | "name AS ua, " +
20 | "NULL AS ua_engine, " +
21 | "ver AS ua_version, " +
22 | "ver_major AS ua_version_major, " +
23 | "last_seen AS crawler_last_seen, " +
24 | "respect_robotstxt AS crawler_respect_robotstxt, " +
25 | "crawler_classification AS crawler_category, " +
26 | "crawler_classification_code AS crawler_category_code, " +
27 | "NULL AS ua_uptodate_current_version, " +
28 | "family AS ua_family, " +
29 | "family_code AS ua_family_code, " +
30 | "family_homepage AS ua_family_homepage, " +
31 | "family_icon AS ua_family_icon, " +
32 | "NULL AS ua_family_icon_big, " +
33 | "vendor AS ua_family_vendor, " +
34 | "vendor_code AS ua_family_vendor_code, " +
35 | "vendor_homepage AS ua_family_vendor_homepage, " +
36 | "'https://udger.com/resources/ua-list/bot-detail?bot=' || REPLACE(family, ' ', '%20') || '#id' || udger_crawler_list.id AS ua_family_info_url " +
37 | "FROM " +
38 | "udger_crawler_list " +
39 | "LEFT JOIN " +
40 | "udger_crawler_class ON udger_crawler_class.id = udger_crawler_list.class_id " +
41 | "WHERE " +
42 | "ua_string = ?";
43 |
44 | public static final String SQL_CLIENT =
45 | "SELECT " +
46 | "ur.rowid, " +
47 | "client_id AS client_id, " +
48 | "class_id AS class_id, " +
49 | "client_classification AS ua_class, " +
50 | "client_classification_code AS ua_class_code, " +
51 | "name AS ua, " +
52 | "engine AS ua_engine, " +
53 | "NULL AS ua_version, " +
54 | "NULL AS ua_version_major, " +
55 | "NULL AS crawler_last_seen, " +
56 | "NULL AS crawler_respect_robotstxt, " +
57 | "NULL AS crawler_category, " +
58 | "NULL AS crawler_category_code, " +
59 | "uptodate_current_version AS ua_uptodate_current_version, " +
60 | "name AS ua_family, " +
61 | "name_code AS ua_family_code, " +
62 | "homepage AS ua_family_homepage, " +
63 | "icon AS ua_family_icon, " +
64 | "icon_big AS ua_family_icon_big, " +
65 | "vendor AS ua_family_vendor, " +
66 | "vendor_code AS ua_family_vendor_code, " +
67 | "vendor_homepage AS ua_family_vendor_homepage, " +
68 | "'https://udger.com/resources/ua-list/browser-detail?browser=' || REPLACE(name, ' ', '%20') AS ua_family_info_url " +
69 | "FROM " +
70 | "udger_client_regex ur " +
71 | "JOIN " +
72 | "udger_client_list ON udger_client_list.id = ur.client_id " +
73 | "JOIN " +
74 | "udger_client_class ON udger_client_class.id = udger_client_list.class_id " +
75 | "WHERE " +
76 | "ur.rowid=?";
77 |
78 | private static final String OS_COLUMNS =
79 | "family AS os_family, " +
80 | "family_code AS os_family_code, " +
81 | "name AS os, " +
82 | "name_code AS os_code, " +
83 | "homepage AS os_home_page, " +
84 | "icon AS os_icon, " +
85 | "icon_big AS os_icon_big, " +
86 | "vendor AS os_family_vendor, " +
87 | "vendor_code AS os_family_vendor_code, " +
88 | "vendor_homepage AS os_family_vendor_homepage, " +
89 | "'https://udger.com/resources/ua-list/os-detail?os=' || REPLACE(name, ' ', '%20') AS os_info_url ";
90 |
91 | public static final String SQL_OS =
92 | "SELECT " +
93 | "ur.rowid, " +
94 | OS_COLUMNS +
95 | "FROM " +
96 | "udger_os_regex ur " +
97 | "JOIN " +
98 | "udger_os_list ON udger_os_list.id = ur.os_id " +
99 | "WHERE " +
100 | "ur.rowid=?";
101 |
102 | public static final String SQL_CLIENT_OS =
103 | "SELECT " +
104 | OS_COLUMNS +
105 | "FROM " +
106 | "udger_client_os_relation " +
107 | "JOIN " +
108 | "udger_os_list ON udger_os_list.id = udger_client_os_relation.os_id " +
109 | "WHERE " +
110 | "client_id = ?";
111 |
112 | private static final String DEVICE_COLUMNS =
113 | "name AS device_class, " +
114 | "name_code AS device_class_code, " +
115 | "icon AS device_class_icon, " +
116 | "icon_big AS device_class_icon_big, " +
117 | "'https://udger.com/resources/ua-list/device-detail?device=' || REPLACE(name, ' ', '%20') AS device_class_info_url ";
118 |
119 | public static final String SQL_DEVICE =
120 | "SELECT " +
121 | "ur.rowid, " +
122 | DEVICE_COLUMNS +
123 | "FROM " +
124 | "udger_deviceclass_regex ur " +
125 | "JOIN " +
126 | "udger_deviceclass_list ON udger_deviceclass_list.id = ur.deviceclass_id " +
127 | "WHERE " +
128 | "ur.rowid=?"
129 | ;
130 |
131 | public static final String SQL_CLIENT_CLASS =
132 | "SELECT " +
133 | DEVICE_COLUMNS +
134 | "FROM " +
135 | "udger_deviceclass_list " +
136 | "JOIN " +
137 | "udger_client_class ON udger_client_class.deviceclass_id = udger_deviceclass_list.id " +
138 | "WHERE " +
139 | "udger_client_class.id = ?";
140 |
141 | private static final String IP_COLUMNS =
142 | "ip_classification AS ip_classification, " +
143 | "ip_classification_code AS ip_classification_code, " +
144 | "ip_last_seen AS ip_last_seen, " +
145 | "ip_hostname AS ip_hostname, " +
146 | "ip_country AS ip_country, " +
147 | "ip_country_code AS ip_country_code, " +
148 | "ip_city AS ip_city, " +
149 | "name AS crawler_name, " +
150 | "ver AS crawler_ver, " +
151 | "ver_major AS crawler_ver_major, " +
152 | "family AS crawler_family, " +
153 | "family_code AS crawler_family_code, " +
154 | "family_homepage AS crawler_family_homepage, " +
155 | "vendor AS crawler_family_vendor, " +
156 | "vendor_code AS crawler_family_vendor_code, " +
157 | "vendor_homepage AS crawler_family_vendor_homepage, " +
158 | "family_icon AS crawler_family_icon, " +
159 | "'https://udger.com/resources/ua-list/bot-detail?bot=' || REPLACE(family, ' ', '%20') || '#id' || udger_crawler_list.id AS crawler_family_info_url, " +
160 | "last_seen AS crawler_last_seen, " +
161 | "crawler_classification AS crawler_category, " +
162 | "crawler_classification_code AS crawler_category_code, " +
163 | "respect_robotstxt AS crawler_respect_robotstxt ";
164 |
165 | public static final String SQL_IP =
166 | "SELECT " +
167 | IP_COLUMNS +
168 | "FROM " +
169 | "udger_ip_list " +
170 | "JOIN " +
171 | "udger_ip_class ON udger_ip_class.id=udger_ip_list.class_id " +
172 | "LEFT JOIN " +
173 | "udger_crawler_list ON udger_crawler_list.id=udger_ip_list.crawler_id " +
174 | "LEFT JOIN " +
175 | "udger_crawler_class ON udger_crawler_class.id=udger_crawler_list.class_id " +
176 | "WHERE " +
177 | "ip = ? " +
178 | "ORDER BY " +
179 | "sequence";
180 |
181 | private static final String DATACENTER_COLUMNS =
182 | "name AS datacenter_name, " +
183 | "name_code AS datacenter_name_code, " +
184 | "homepage AS datacenter_homepage ";
185 |
186 | public static final String SQL_DATACENTER =
187 | "SELECT " +
188 | DATACENTER_COLUMNS +
189 | "FROM " +
190 | "udger_datacenter_range " +
191 | "JOIN " +
192 | "udger_datacenter_list ON udger_datacenter_range.datacenter_id = udger_datacenter_list.id " +
193 | "WHERE " +
194 | "iplong_from <= ? AND iplong_to >= ?";
195 |
196 | public static final String SQL_DATACENTER_RANGE6 =
197 | "SELECT " +
198 | DATACENTER_COLUMNS +
199 | "FROM " +
200 | "udger_datacenter_range6 " +
201 | "JOIN " +
202 | "udger_datacenter_list ON udger_datacenter_range6.datacenter_id=udger_datacenter_list.id " +
203 | "WHERE " +
204 | "iplong_from0 <= ? AND iplong_to0 >= ? AND " +
205 | "iplong_from1 <= ? AND iplong_to1 >= ? AND " +
206 | "iplong_from2 <= ? AND iplong_to2 >= ? AND " +
207 | "iplong_from3 <= ? AND iplong_to3 >= ? AND " +
208 | "iplong_from4 <= ? AND iplong_to4 >= ? AND " +
209 | "iplong_from5 <= ? AND iplong_to5 >= ? AND " +
210 | "iplong_from6 <= ? AND iplong_to6 >= ? AND " +
211 | "iplong_from7 <= ? AND iplong_to7 >=?";
212 |
213 | public static final String SQL_DEVICE_REGEX =
214 | "SELECT " +
215 | "id," +
216 | "regstring " +
217 | "FROM " +
218 | "udger_devicename_regex " +
219 | "WHERE " +
220 | "os_family_code=? AND (os_code='-all-' OR os_code=?) " +
221 | "ORDER BY sequence";
222 |
223 | public static final String SQL_DEVICE_NAME_LIST =
224 | "SELECT " +
225 | "marketname," +
226 | "brand_code," +
227 | "brand," +
228 | "brand_url," +
229 | "icon," +
230 | "icon_big " +
231 | "FROM " +
232 | "udger_devicename_list " +
233 | "JOIN " +
234 | "udger_devicename_brand ON udger_devicename_brand.id=udger_devicename_list.brand_id " +
235 | "WHERE " +
236 | "regex_id = ? AND code = ?";
237 |
238 | }
239 |
--------------------------------------------------------------------------------
/src/main/java/org/udger/parser/UdgerUaResult.java:
--------------------------------------------------------------------------------
1 | /*
2 | Udger-update - Data updater for udger local and cloud parser
3 |
4 | author The Udger.com Team (info@udger.com)
5 | copyright Copyright (c) Udger s.r.o.
6 | license GNU Lesser General Public License
7 | link https://udger.com/products
8 | */
9 | package org.udger.parser;
10 |
11 | import java.io.Serializable;
12 |
13 | public class UdgerUaResult implements Serializable {
14 |
15 | private static final long serialVersionUID = 1L;
16 |
17 | // UA
18 | private final String uaString;
19 | private Integer clientId;
20 | private Integer classId;
21 | private String uaClass = "";
22 | private String uaClassCode = "";
23 | private String ua = "";
24 | private String uaEngine = "";
25 | private String uaVersion = "";
26 | private String uaVersionMajor = "";
27 | private String crawlerLastSeen = "";
28 | private String crawlerRespectRobotstxt = "";
29 | private String crawlerCategory = "";
30 | private String crawlerCategoryCode = "";
31 | private String uaUptodateCurrentVersion = "";
32 | private String uaFamily = "";
33 | private String uaFamilyCode = "";
34 | private String uaFamilyHomepage = "";
35 | private String uaFamilyIcon = "";
36 | private String uaFamilyIconBig = "";
37 | private String uaFamilyVendor = "";
38 | private String uaFamilyVendorCode = "";
39 | private String uaFamilyVendorHomepage = "";
40 | private String uaFamilyInfoUrl = "";
41 |
42 | // OS
43 | private String osFamily = "";
44 | private String osFamilyCode = "";
45 | private String os = "";
46 | private String osCode = "";
47 | private String osHomePage = "";
48 | private String osIcon = "";
49 | private String osIconBig = "";
50 | private String osFamilyVendor = "";
51 | private String osFamilyVendorCode = "";
52 | private String osFamilyVendorHomepage = "";
53 | private String osInfoUrl = "";
54 |
55 | // DEVICE
56 | private String deviceClass = "";
57 | private String deviceClassCode = "";
58 | private String deviceClassIcon = "";
59 | private String deviceClassIconBig = "";
60 | private String deviceClassInfoUrl = "";
61 |
62 | private String deviceMarketname = "";
63 | private String deviceBrand = "";
64 | private String deviceBrandCode = "";
65 | private String deviceBrandHomepage = "";
66 | private String deviceBrandIcon = "";
67 | private String deviceBrandIconBig = "";
68 | private String deviceBrandInfoUrl = "";
69 |
70 | public UdgerUaResult(String uaString) {
71 | this.uaString = uaString;
72 | }
73 |
74 | public String getUaString() {
75 | return uaString;
76 | }
77 |
78 | public Integer getClientId() {
79 | return clientId;
80 | }
81 | public void setClientId(Integer clientId) {
82 | this.clientId = clientId;
83 | }
84 | public Integer getClassId() {
85 | return classId;
86 | }
87 | public void setClassId(Integer classId) {
88 | this.classId = classId;
89 | }
90 | public String getUaClass() {
91 | return uaClass;
92 | }
93 | public void setUaClass(String uaClass) {
94 | this.uaClass = uaClass;
95 | }
96 | public String getUaClassCode() {
97 | return uaClassCode;
98 | }
99 | public void setUaClassCode(String uaClassCode) {
100 | this.uaClassCode = uaClassCode;
101 | }
102 | public String getUa() {
103 | return ua;
104 | }
105 | public void setUa(String ua) {
106 | this.ua = ua;
107 | }
108 | public String getUaEngine() {
109 | return uaEngine;
110 | }
111 | public void setUaEngine(String uaEngine) {
112 | this.uaEngine = uaEngine;
113 | }
114 | public String getUaVersion() {
115 | return uaVersion;
116 | }
117 | public void setUaVersion(String uaVersion) {
118 | this.uaVersion = uaVersion;
119 | }
120 | public String getUaVersionMajor() {
121 | return uaVersionMajor;
122 | }
123 | public void setUaVersionMajor(String uaVersionMajor) {
124 | this.uaVersionMajor = uaVersionMajor;
125 | }
126 | public String getCrawlerLastSeen() {
127 | return crawlerLastSeen;
128 | }
129 | public void setCrawlerLastSeen(String crawlerLastSeen) {
130 | this.crawlerLastSeen = crawlerLastSeen;
131 | }
132 | public String getCrawlerRespectRobotstxt() {
133 | return crawlerRespectRobotstxt;
134 | }
135 | public void setCrawlerRespectRobotstxt(String crawlerRespectRobotstxt) {
136 | this.crawlerRespectRobotstxt = crawlerRespectRobotstxt;
137 | }
138 | public String getCrawlerCategory() {
139 | return crawlerCategory;
140 | }
141 | public void setCrawlerCategory(String crawlerCategory) {
142 | this.crawlerCategory = crawlerCategory;
143 | }
144 | public String getCrawlerCategoryCode() {
145 | return crawlerCategoryCode;
146 | }
147 | public void setCrawlerCategoryCode(String crawlerCategoryCode) {
148 | this.crawlerCategoryCode = crawlerCategoryCode;
149 | }
150 | public String getUaUptodateCurrentVersion() {
151 | return uaUptodateCurrentVersion;
152 | }
153 | public void setUaUptodateCurrentVersion(String uaUptodateCurrentVersion) {
154 | this.uaUptodateCurrentVersion = uaUptodateCurrentVersion;
155 | }
156 | public String getUaFamily() {
157 | return uaFamily;
158 | }
159 | public void setUaFamily(String uaFamily) {
160 | this.uaFamily = uaFamily;
161 | }
162 | public String getUaFamilyCode() {
163 | return uaFamilyCode;
164 | }
165 | public void setUaFamilyCode(String uaFamilyCode) {
166 | this.uaFamilyCode = uaFamilyCode;
167 | }
168 | public String getUaFamilyHomepage() {
169 | return uaFamilyHomepage;
170 | }
171 | public void setUaFamilyHomepage(String uaFamilyHomepage) {
172 | this.uaFamilyHomepage = uaFamilyHomepage;
173 | }
174 | public String getUaFamilyIcon() {
175 | return uaFamilyIcon;
176 | }
177 | public void setUaFamilyIcon(String uaFamilyIcon) {
178 | this.uaFamilyIcon = uaFamilyIcon;
179 | }
180 | public String getUaFamilyIconBig() {
181 | return uaFamilyIconBig;
182 | }
183 | public void setUaFamilyIconBig(String uaFamilyIconBig) {
184 | this.uaFamilyIconBig = uaFamilyIconBig;
185 | }
186 | public String getUaFamilyVendor() {
187 | return uaFamilyVendor;
188 | }
189 | public void setUaFamilyVendor(String uaFamilyVendor) {
190 | this.uaFamilyVendor = uaFamilyVendor;
191 | }
192 | public String getUaFamilyVendorCode() {
193 | return uaFamilyVendorCode;
194 | }
195 | public void setUaFamilyVendorCode(String uaFamilyVendorCode) {
196 | this.uaFamilyVendorCode = uaFamilyVendorCode;
197 | }
198 | public String getUaFamilyVendorHomepage() {
199 | return uaFamilyVendorHomepage;
200 | }
201 | public void setUaFamilyVendorHomepage(String uaFamilyVendorHomepage) {
202 | this.uaFamilyVendorHomepage = uaFamilyVendorHomepage;
203 | }
204 | public String getUaFamilyInfoUrl() {
205 | return uaFamilyInfoUrl;
206 | }
207 | public void setUaFamilyInfoUrl(String uaFamilyInfoUrl) {
208 | this.uaFamilyInfoUrl = uaFamilyInfoUrl;
209 | }
210 |
211 | public String getOsFamily() {
212 | return osFamily;
213 | }
214 | public void setOsFamily(String osFamily) {
215 | this.osFamily = osFamily;
216 | }
217 | public String getOsFamilyCode() {
218 | return osFamilyCode;
219 | }
220 | public void setOsFamilyCode(String osFamilyCode) {
221 | this.osFamilyCode = osFamilyCode;
222 | }
223 | public String getOs() {
224 | return os;
225 | }
226 | public void setOs(String os) {
227 | this.os = os;
228 | }
229 | public String getOsCode() {
230 | return osCode;
231 | }
232 | public void setOsCode(String osCode) {
233 | this.osCode = osCode;
234 | }
235 | public String getOsHomePage() {
236 | return osHomePage;
237 | }
238 | public void setOsHomePage(String osHomePage) {
239 | this.osHomePage = osHomePage;
240 | }
241 | public String getOsIcon() {
242 | return osIcon;
243 | }
244 | public void setOsIcon(String osIcon) {
245 | this.osIcon = osIcon;
246 | }
247 | public String getOsIconBig() {
248 | return osIconBig;
249 | }
250 | public void setOsIconBig(String osIconBig) {
251 | this.osIconBig = osIconBig;
252 | }
253 | public String getOsFamilyVendor() {
254 | return osFamilyVendor;
255 | }
256 | public void setOsFamilyVendor(String osFamilyVendor) {
257 | this.osFamilyVendor = osFamilyVendor;
258 | }
259 | public String getOsFamilyVendorCode() {
260 | return osFamilyVendorCode;
261 | }
262 | public void setOsFamilyVendorCode(String osFamilyVendorCode) {
263 | this.osFamilyVendorCode = osFamilyVendorCode;
264 | }
265 | public String getOsFamilyVendorHomepage() {
266 | return osFamilyVendorHomepage;
267 | }
268 | public void setOsFamilyVendorHomepage(String osFamilyVendorHomepage) {
269 | this.osFamilyVendorHomepage = osFamilyVendorHomepage;
270 | }
271 | public String getOsInfoUrl() {
272 | return osInfoUrl;
273 | }
274 | public void setOsInfoUrl(String osInfoUrl) {
275 | this.osInfoUrl = osInfoUrl;
276 | }
277 |
278 | public String getDeviceClass() {
279 | return deviceClass;
280 | }
281 | public void setDeviceClass(String deviceClass) {
282 | this.deviceClass = deviceClass;
283 | }
284 | public String getDeviceClassCode() {
285 | return deviceClassCode;
286 | }
287 | public void setDeviceClassCode(String deviceClassCode) {
288 | this.deviceClassCode = deviceClassCode;
289 | }
290 | public String getDeviceClassIcon() {
291 | return deviceClassIcon;
292 | }
293 | public void setDeviceClassIcon(String deviceClassIcon) {
294 | this.deviceClassIcon = deviceClassIcon;
295 | }
296 | public String getDeviceClassIconBig() {
297 | return deviceClassIconBig;
298 | }
299 | public void setDeviceClassIconBig(String deviceClassIconBig) {
300 | this.deviceClassIconBig = deviceClassIconBig;
301 | }
302 | public String getDeviceClassInfoUrl() {
303 | return deviceClassInfoUrl;
304 | }
305 | public void setDeviceClassInfoUrl(String deviceClassInfoUrl) {
306 | this.deviceClassInfoUrl = deviceClassInfoUrl;
307 | }
308 |
309 | public String getDeviceMarketname() {
310 | return deviceMarketname;
311 | }
312 |
313 | public void setDeviceMarketname(String deviceMarketname) {
314 | this.deviceMarketname = deviceMarketname;
315 | }
316 |
317 | public String getDeviceBrand() {
318 | return deviceBrand;
319 | }
320 |
321 | public void setDeviceBrand(String deviceBrand) {
322 | this.deviceBrand = deviceBrand;
323 | }
324 |
325 | public String getDeviceBrandCode() {
326 | return deviceBrandCode;
327 | }
328 |
329 | public void setDeviceBrandCode(String deviceBrandCode) {
330 | this.deviceBrandCode = deviceBrandCode;
331 | }
332 |
333 | public String getDeviceBrandHomepage() {
334 | return deviceBrandHomepage;
335 | }
336 |
337 | public void setDeviceBrandHomepage(String deviceBrandHomepage) {
338 | this.deviceBrandHomepage = deviceBrandHomepage;
339 | }
340 |
341 | public String getDeviceBrandIcon() {
342 | return deviceBrandIcon;
343 | }
344 |
345 | public void setDeviceBrandIcon(String deviceBrandIcon) {
346 | this.deviceBrandIcon = deviceBrandIcon;
347 | }
348 |
349 | public String getDeviceBrandIconBig() {
350 | return deviceBrandIconBig;
351 | }
352 |
353 | public void setDeviceBrandIconBig(String deviceBrandIconBig) {
354 | this.deviceBrandIconBig = deviceBrandIconBig;
355 | }
356 |
357 | public String getDeviceBrandInfoUrl() {
358 | return deviceBrandInfoUrl;
359 | }
360 |
361 | public void setDeviceBrandInfoUrl(String deviceBrandInfoUrl) {
362 | this.deviceBrandInfoUrl = deviceBrandInfoUrl;
363 | }
364 |
365 | @Override
366 | public int hashCode() {
367 | final int prime = 31;
368 | int result = 1;
369 | result = prime * result + ((classId == null) ? 0 : classId.hashCode());
370 | result = prime * result + ((clientId == null) ? 0 : clientId.hashCode());
371 | result = prime * result + ((crawlerCategory == null) ? 0 : crawlerCategory.hashCode());
372 | result = prime * result + ((crawlerCategoryCode == null) ? 0 : crawlerCategoryCode.hashCode());
373 | result = prime * result + ((crawlerLastSeen == null) ? 0 : crawlerLastSeen.hashCode());
374 | result = prime * result + ((crawlerRespectRobotstxt == null) ? 0 : crawlerRespectRobotstxt.hashCode());
375 | result = prime * result + ((deviceBrand == null) ? 0 : deviceBrand.hashCode());
376 | result = prime * result + ((deviceBrandCode == null) ? 0 : deviceBrandCode.hashCode());
377 | result = prime * result + ((deviceBrandHomepage == null) ? 0 : deviceBrandHomepage.hashCode());
378 | result = prime * result + ((deviceBrandIcon == null) ? 0 : deviceBrandIcon.hashCode());
379 | result = prime * result + ((deviceBrandIconBig == null) ? 0 : deviceBrandIconBig.hashCode());
380 | result = prime * result + ((deviceBrandInfoUrl == null) ? 0 : deviceBrandInfoUrl.hashCode());
381 | result = prime * result + ((deviceClass == null) ? 0 : deviceClass.hashCode());
382 | result = prime * result + ((deviceClassCode == null) ? 0 : deviceClassCode.hashCode());
383 | result = prime * result + ((deviceClassIcon == null) ? 0 : deviceClassIcon.hashCode());
384 | result = prime * result + ((deviceClassIconBig == null) ? 0 : deviceClassIconBig.hashCode());
385 | result = prime * result + ((deviceClassInfoUrl == null) ? 0 : deviceClassInfoUrl.hashCode());
386 | result = prime * result + ((deviceMarketname == null) ? 0 : deviceMarketname.hashCode());
387 | result = prime * result + ((os == null) ? 0 : os.hashCode());
388 | result = prime * result + ((osCode == null) ? 0 : osCode.hashCode());
389 | result = prime * result + ((osFamily == null) ? 0 : osFamily.hashCode());
390 | result = prime * result + ((osFamilyCode == null) ? 0 : osFamilyCode.hashCode());
391 | result = prime * result + ((osFamilyVendorHomepage == null) ? 0 : osFamilyVendorHomepage.hashCode());
392 | result = prime * result + ((osFamilyVendor == null) ? 0 : osFamilyVendor.hashCode());
393 | result = prime * result + ((osFamilyVendorCode == null) ? 0 : osFamilyVendorCode.hashCode());
394 | result = prime * result + ((osHomePage == null) ? 0 : osHomePage.hashCode());
395 | result = prime * result + ((osIcon == null) ? 0 : osIcon.hashCode());
396 | result = prime * result + ((osIconBig == null) ? 0 : osIconBig.hashCode());
397 | result = prime * result + ((osInfoUrl == null) ? 0 : osInfoUrl.hashCode());
398 | result = prime * result + ((ua == null) ? 0 : ua.hashCode());
399 | result = prime * result + ((uaClass == null) ? 0 : uaClass.hashCode());
400 | result = prime * result + ((uaClassCode == null) ? 0 : uaClassCode.hashCode());
401 | result = prime * result + ((uaEngine == null) ? 0 : uaEngine.hashCode());
402 | result = prime * result + ((uaFamily == null) ? 0 : uaFamily.hashCode());
403 | result = prime * result + ((uaFamilyCode == null) ? 0 : uaFamilyCode.hashCode());
404 | result = prime * result + ((uaFamilyHomepage == null) ? 0 : uaFamilyHomepage.hashCode());
405 | result = prime * result + ((uaFamilyIcon == null) ? 0 : uaFamilyIcon.hashCode());
406 | result = prime * result + ((uaFamilyIconBig == null) ? 0 : uaFamilyIconBig.hashCode());
407 | result = prime * result + ((uaFamilyInfoUrl == null) ? 0 : uaFamilyInfoUrl.hashCode());
408 | result = prime * result + ((uaFamilyVendor == null) ? 0 : uaFamilyVendor.hashCode());
409 | result = prime * result + ((uaFamilyVendorCode == null) ? 0 : uaFamilyVendorCode.hashCode());
410 | result = prime * result + ((uaFamilyVendorHomepage == null) ? 0 : uaFamilyVendorHomepage.hashCode());
411 | result = prime * result + ((uaString == null) ? 0 : uaString.hashCode());
412 | result = prime * result + ((uaUptodateCurrentVersion == null) ? 0 : uaUptodateCurrentVersion.hashCode());
413 | result = prime * result + ((uaVersion == null) ? 0 : uaVersion.hashCode());
414 | result = prime * result + ((uaVersionMajor == null) ? 0 : uaVersionMajor.hashCode());
415 | return result;
416 | }
417 |
418 | @Override
419 | public boolean equals(Object obj) {
420 | if (this == obj)
421 | return true;
422 | if (obj == null)
423 | return false;
424 | if (getClass() != obj.getClass())
425 | return false;
426 | UdgerUaResult other = (UdgerUaResult) obj;
427 | if (classId == null) {
428 | if (other.classId != null)
429 | return false;
430 | } else if (!classId.equals(other.classId))
431 | return false;
432 | if (clientId == null) {
433 | if (other.clientId != null)
434 | return false;
435 | } else if (!clientId.equals(other.clientId))
436 | return false;
437 | if (crawlerCategory == null) {
438 | if (other.crawlerCategory != null)
439 | return false;
440 | } else if (!crawlerCategory.equals(other.crawlerCategory))
441 | return false;
442 | if (crawlerCategoryCode == null) {
443 | if (other.crawlerCategoryCode != null)
444 | return false;
445 | } else if (!crawlerCategoryCode.equals(other.crawlerCategoryCode))
446 | return false;
447 | if (crawlerLastSeen == null) {
448 | if (other.crawlerLastSeen != null)
449 | return false;
450 | } else if (!crawlerLastSeen.equals(other.crawlerLastSeen))
451 | return false;
452 | if (crawlerRespectRobotstxt == null) {
453 | if (other.crawlerRespectRobotstxt != null)
454 | return false;
455 | } else if (!crawlerRespectRobotstxt.equals(other.crawlerRespectRobotstxt))
456 | return false;
457 | if (deviceBrand == null) {
458 | if (other.deviceBrand != null)
459 | return false;
460 | } else if (!deviceBrand.equals(other.deviceBrand))
461 | return false;
462 | if (deviceBrandCode == null) {
463 | if (other.deviceBrandCode != null)
464 | return false;
465 | } else if (!deviceBrandCode.equals(other.deviceBrandCode))
466 | return false;
467 | if (deviceBrandHomepage == null) {
468 | if (other.deviceBrandHomepage != null)
469 | return false;
470 | } else if (!deviceBrandHomepage.equals(other.deviceBrandHomepage))
471 | return false;
472 | if (deviceBrandIcon == null) {
473 | if (other.deviceBrandIcon != null)
474 | return false;
475 | } else if (!deviceBrandIcon.equals(other.deviceBrandIcon))
476 | return false;
477 | if (deviceBrandIconBig == null) {
478 | if (other.deviceBrandIconBig != null)
479 | return false;
480 | } else if (!deviceBrandIconBig.equals(other.deviceBrandIconBig))
481 | return false;
482 | if (deviceBrandInfoUrl == null) {
483 | if (other.deviceBrandInfoUrl != null)
484 | return false;
485 | } else if (!deviceBrandInfoUrl.equals(other.deviceBrandInfoUrl))
486 | return false;
487 | if (deviceClass == null) {
488 | if (other.deviceClass != null)
489 | return false;
490 | } else if (!deviceClass.equals(other.deviceClass))
491 | return false;
492 | if (deviceClassCode == null) {
493 | if (other.deviceClassCode != null)
494 | return false;
495 | } else if (!deviceClassCode.equals(other.deviceClassCode))
496 | return false;
497 | if (deviceClassIcon == null) {
498 | if (other.deviceClassIcon != null)
499 | return false;
500 | } else if (!deviceClassIcon.equals(other.deviceClassIcon))
501 | return false;
502 | if (deviceClassIconBig == null) {
503 | if (other.deviceClassIconBig != null)
504 | return false;
505 | } else if (!deviceClassIconBig.equals(other.deviceClassIconBig))
506 | return false;
507 | if (deviceClassInfoUrl == null) {
508 | if (other.deviceClassInfoUrl != null)
509 | return false;
510 | } else if (!deviceClassInfoUrl.equals(other.deviceClassInfoUrl))
511 | return false;
512 | if (deviceMarketname == null) {
513 | if (other.deviceMarketname != null)
514 | return false;
515 | } else if (!deviceMarketname.equals(other.deviceMarketname))
516 | return false;
517 | if (os == null) {
518 | if (other.os != null)
519 | return false;
520 | } else if (!os.equals(other.os))
521 | return false;
522 | if (osCode == null) {
523 | if (other.osCode != null)
524 | return false;
525 | } else if (!osCode.equals(other.osCode))
526 | return false;
527 | if (osFamily == null) {
528 | if (other.osFamily != null)
529 | return false;
530 | } else if (!osFamily.equals(other.osFamily))
531 | return false;
532 | if (osFamilyCode == null) {
533 | if (other.osFamilyCode != null)
534 | return false;
535 | } else if (!osFamilyCode.equals(other.osFamilyCode))
536 | return false;
537 | if (osFamilyVendorHomepage == null) {
538 | if (other.osFamilyVendorHomepage != null)
539 | return false;
540 | } else if (!osFamilyVendorHomepage.equals(other.osFamilyVendorHomepage))
541 | return false;
542 | if (osFamilyVendor == null) {
543 | if (other.osFamilyVendor != null)
544 | return false;
545 | } else if (!osFamilyVendor.equals(other.osFamilyVendor))
546 | return false;
547 | if (osFamilyVendorCode == null) {
548 | if (other.osFamilyVendorCode != null)
549 | return false;
550 | } else if (!osFamilyVendorCode.equals(other.osFamilyVendorCode))
551 | return false;
552 | if (osHomePage == null) {
553 | if (other.osHomePage != null)
554 | return false;
555 | } else if (!osHomePage.equals(other.osHomePage))
556 | return false;
557 | if (osIcon == null) {
558 | if (other.osIcon != null)
559 | return false;
560 | } else if (!osIcon.equals(other.osIcon))
561 | return false;
562 | if (osIconBig == null) {
563 | if (other.osIconBig != null)
564 | return false;
565 | } else if (!osIconBig.equals(other.osIconBig))
566 | return false;
567 | if (osInfoUrl == null) {
568 | if (other.osInfoUrl != null)
569 | return false;
570 | } else if (!osInfoUrl.equals(other.osInfoUrl))
571 | return false;
572 | if (ua == null) {
573 | if (other.ua != null)
574 | return false;
575 | } else if (!ua.equals(other.ua))
576 | return false;
577 | if (uaClass == null) {
578 | if (other.uaClass != null)
579 | return false;
580 | } else if (!uaClass.equals(other.uaClass))
581 | return false;
582 | if (uaClassCode == null) {
583 | if (other.uaClassCode != null)
584 | return false;
585 | } else if (!uaClassCode.equals(other.uaClassCode))
586 | return false;
587 | if (uaEngine == null) {
588 | if (other.uaEngine != null)
589 | return false;
590 | } else if (!uaEngine.equals(other.uaEngine))
591 | return false;
592 | if (uaFamily == null) {
593 | if (other.uaFamily != null)
594 | return false;
595 | } else if (!uaFamily.equals(other.uaFamily))
596 | return false;
597 | if (uaFamilyCode == null) {
598 | if (other.uaFamilyCode != null)
599 | return false;
600 | } else if (!uaFamilyCode.equals(other.uaFamilyCode))
601 | return false;
602 | if (uaFamilyHomepage == null) {
603 | if (other.uaFamilyHomepage != null)
604 | return false;
605 | } else if (!uaFamilyHomepage.equals(other.uaFamilyHomepage))
606 | return false;
607 | if (uaFamilyIcon == null) {
608 | if (other.uaFamilyIcon != null)
609 | return false;
610 | } else if (!uaFamilyIcon.equals(other.uaFamilyIcon))
611 | return false;
612 | if (uaFamilyIconBig == null) {
613 | if (other.uaFamilyIconBig != null)
614 | return false;
615 | } else if (!uaFamilyIconBig.equals(other.uaFamilyIconBig))
616 | return false;
617 | if (uaFamilyInfoUrl == null) {
618 | if (other.uaFamilyInfoUrl != null)
619 | return false;
620 | } else if (!uaFamilyInfoUrl.equals(other.uaFamilyInfoUrl))
621 | return false;
622 | if (uaFamilyVendor == null) {
623 | if (other.uaFamilyVendor != null)
624 | return false;
625 | } else if (!uaFamilyVendor.equals(other.uaFamilyVendor))
626 | return false;
627 | if (uaFamilyVendorCode == null) {
628 | if (other.uaFamilyVendorCode != null)
629 | return false;
630 | } else if (!uaFamilyVendorCode.equals(other.uaFamilyVendorCode))
631 | return false;
632 | if (uaFamilyVendorHomepage == null) {
633 | if (other.uaFamilyVendorHomepage != null)
634 | return false;
635 | } else if (!uaFamilyVendorHomepage.equals(other.uaFamilyVendorHomepage))
636 | return false;
637 | if (uaString == null) {
638 | if (other.uaString != null)
639 | return false;
640 | } else if (!uaString.equals(other.uaString))
641 | return false;
642 | if (uaUptodateCurrentVersion == null) {
643 | if (other.uaUptodateCurrentVersion != null)
644 | return false;
645 | } else if (!uaUptodateCurrentVersion.equals(other.uaUptodateCurrentVersion))
646 | return false;
647 | if (uaVersion == null) {
648 | if (other.uaVersion != null)
649 | return false;
650 | } else if (!uaVersion.equals(other.uaVersion))
651 | return false;
652 | if (uaVersionMajor == null) {
653 | if (other.uaVersionMajor != null)
654 | return false;
655 | } else if (!uaVersionMajor.equals(other.uaVersionMajor))
656 | return false;
657 | return true;
658 | }
659 |
660 | @Override
661 | public String toString() {
662 | return "UdgerUaResult [" +
663 | "uaString=" + uaString +
664 | ", clientId=" + clientId +
665 | ", classId=" + classId +
666 | ", uaClass=" + uaClass +
667 | ", uaClassCode=" + uaClassCode +
668 | ", ua=" + ua +
669 | ", uaEngine=" + uaEngine +
670 | ", uaVersion=" + uaVersion +
671 | ", uaVersionMajor=" + uaVersionMajor +
672 | ", crawlerLastSeen=" + crawlerLastSeen +
673 | ", crawlerRespectRobotstxt=" + crawlerRespectRobotstxt +
674 | ", crawlerCategory=" + crawlerCategory +
675 | ", crawlerCategoryCode=" + crawlerCategoryCode +
676 | ", uaUptodateCurrentVersion=" + uaUptodateCurrentVersion +
677 | ", uaFamily=" + uaFamily +
678 | ", uaFamilyCode=" + uaFamilyCode +
679 | ", uaFamilyHomepage=" + uaFamilyHomepage +
680 | ", uaFamilyIcon=" + uaFamilyIcon +
681 | ", uaFamilyIconBig=" + uaFamilyIconBig +
682 | ", uaFamilyVendor=" + uaFamilyVendor +
683 | ", uaFamilyVendorCode=" + uaFamilyVendorCode +
684 | ", uaFamilyVendorHomepage=" + uaFamilyVendorHomepage +
685 | ", uaFamilyInfoUrl=" + uaFamilyInfoUrl +
686 | ", osFamily=" + osFamily +
687 | ", osFamilyCode=" + osFamilyCode +
688 | ", os=" + os +
689 | ", osCode=" + osCode +
690 | ", osHomePage=" + osHomePage +
691 | ", osIcon=" + osIcon +
692 | ", osIconBig=" + osIconBig +
693 | ", osFamilyVendor=" + osFamilyVendor +
694 | ", osFamilyVendorCode=" + osFamilyVendorCode +
695 | ", osFamilyVendorHomepage=" + osFamilyVendorHomepage +
696 | ", osInfoUrl=" + osInfoUrl +
697 | ", deviceClass=" + deviceClass +
698 | ", deviceClassCode=" + deviceClassCode +
699 | ", deviceClassIcon=" + deviceClassIcon +
700 | ", deviceClassIconBig=" + deviceClassIconBig +
701 | ", deviceClassInfoUrl=" + deviceClassInfoUrl +
702 | ", deviceMarketname=" + deviceMarketname +
703 | ", deviceBrand=" + deviceBrand +
704 | ", deviceBrandCode=" + deviceBrandCode +
705 | ", deviceBrandHomepage=" + deviceBrandHomepage +
706 | ", deviceBrandIcon=" + deviceBrandIcon +
707 | ", deviceBrandIconBig=" + deviceBrandIconBig +
708 | ", deviceBrandInfoUrl=" + deviceBrandInfoUrl +
709 | "]";
710 | }
711 |
712 | }
713 |
--------------------------------------------------------------------------------
/src/main/java/org/udger/parser/WordDetector.java:
--------------------------------------------------------------------------------
1 | package org.udger.parser;
2 |
3 | import java.io.Serializable;
4 | import java.util.ArrayList;
5 | import java.util.HashSet;
6 | import java.util.List;
7 | import java.util.Set;
8 | import java.util.logging.Logger;
9 |
10 | public class WordDetector implements Serializable {
11 |
12 | private static final long serialVersionUID = -2123898245391386812L;
13 |
14 | private static final Logger LOG = Logger.getLogger(WordDetector.class.getName());
15 |
16 | private static class WordInfo {
17 | int id;
18 | String word;
19 |
20 | public WordInfo(int id, String word) {
21 | this.id = id;
22 | this.word = word;
23 | }
24 | }
25 |
26 | private static final int ARRAY_DIMENSION = 'z' - 'a';
27 | private static final int ARRAY_SIZE = (ARRAY_DIMENSION + 1) * (ARRAY_DIMENSION + 1);
28 |
29 | private List wordArray[];
30 | private int minWordSize = Integer.MAX_VALUE;
31 |
32 | public WordDetector() {
33 | wordArray = new List[ARRAY_SIZE];
34 | }
35 |
36 | public void addWord(int id, String word) {
37 |
38 | if (word.length() < minWordSize) {
39 | minWordSize = word.length();
40 | }
41 |
42 | String s = word.toLowerCase();
43 | int index = (s.charAt(0) - 'a') * ARRAY_DIMENSION + s.charAt(1) - 'a';
44 | if (index >= 0 && index < ARRAY_SIZE) {
45 | List wList = wordArray[index];
46 | if (wList == null) {
47 | wList = new ArrayList<>();
48 | wordArray[index] = wList;
49 | }
50 | wList.add(new WordInfo(id, s));
51 | } else {
52 | LOG.warning("Index out of hashmap" + id + " : "+ s);
53 | }
54 | }
55 |
56 | public Set findWords(String text) {
57 |
58 | Set ret = new HashSet<>();
59 |
60 | final String s = text.toLowerCase();
61 | final int dimension = 'z' - 'a';
62 | for(int i=0; i < s.length() - (minWordSize - 1); i++) {
63 | final char c1 = s.charAt(i);
64 | final char c2 = s.charAt(i + 1);
65 | if (c1 >= 'a' && c1 <= 'z' && c2 >= 'a' && c2 <= 'z') {
66 | final int index = (c1 - 'a') * dimension + c2 - 'a';
67 | List l = wordArray[index];
68 | if (l != null) {
69 | for (WordInfo wi : l) {
70 | if (s.startsWith(wi.word, i)) {
71 | ret.add(wi.id);
72 | }
73 | }
74 | }
75 | }
76 | }
77 | return ret;
78 | }
79 |
80 | }
81 |
--------------------------------------------------------------------------------
/src/test/java/org/udger/parser/LRUCacheTest.java:
--------------------------------------------------------------------------------
1 | package org.udger.parser;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | public class LRUCacheTest {
8 |
9 | private LRUCache cache = new LRUCache<>(3);
10 |
11 | @Test
12 | public void testLRUCacheRespectCapacity() throws Exception {
13 | for(int i = 0; i < cache.getCapacity() + 1; i++){
14 | cache.put(i,i);
15 | }
16 | assertNull("Expected the first value put into cache to be absent after adding one more than capacity allows.", cache.get(0));
17 | }
18 |
19 | @Test
20 | public void testLRUCacheUpdatesLRUOrder() throws Exception {
21 | for(int i = 0; i < cache.getCapacity(); i++){
22 | cache.put(i,i);
23 | }
24 | assertNotNull("Expected to first put value to be in the cache.", cache.get(0));
25 | cache.put(cache.getCapacity()+1, cache.getCapacity()+1);
26 | assertNull("Expected the first value to have gone to the tail and second value to be removed for the next.", cache.get(1));
27 | }
28 | }
--------------------------------------------------------------------------------
/src/test/java/org/udger/parser/UdgerIpTest.java:
--------------------------------------------------------------------------------
1 | package org.udger.parser;
2 |
3 | import java.io.IOException;
4 | import java.io.InputStream;
5 | import java.net.UnknownHostException;
6 | import java.sql.SQLException;
7 |
8 | import javax.json.JsonArray;
9 | import javax.json.JsonObject;
10 | import javax.json.JsonReader;
11 |
12 | public class UdgerIpTest {
13 |
14 | public static void main(String args[]) {
15 | InputStream is = UdgerUaTest.class.getResourceAsStream("test_ip.json");
16 | JsonReader jr = javax.json.Json.createReader(is);
17 | JsonArray ja = jr.readArray();
18 | UdgerParser up = null;
19 | try {
20 | UdgerParser.ParserDbData parserDbData = new UdgerParser.ParserDbData("udgerdb_v3.dat");
21 | up = new UdgerParser(parserDbData);
22 | for (int i=0; i < ja.size(); i++) {
23 | JsonObject jar = ja.getJsonObject(i);
24 | JsonObject jor = jar.getJsonObject("ret");
25 | String query = jar.getJsonObject("test").getString("teststring");
26 | try {
27 | UdgerIpResult ret = up.parseIp(query);
28 | System.out.print("### Test : " + (i+1) + " - ");
29 | if (checkResult(ret, jor)) {
30 | System.out.println("SUCCEEDED");
31 | } else {
32 | System.out.println("FAILED!");
33 | }
34 | System.out.println("Query: " + query);
35 | // System.out.println("Result: " + ReflectionToStringBuilder.toString(ret, ToStringStyle.MULTI_LINE_STYLE));
36 |
37 | } catch (SQLException e) {
38 | e.printStackTrace();
39 | } catch (UnknownHostException e) {
40 | // TODO Auto-generated catch block
41 | e.printStackTrace();
42 | }
43 | }
44 | } finally {
45 | if (up != null) {
46 | try {
47 | up.close();
48 | } catch (IOException e) {
49 | }
50 | }
51 | }
52 | }
53 |
54 | private static boolean checkResult(UdgerIpResult ret, JsonObject jor) {
55 | boolean result = true;
56 | result = testEqual(jor, "ip_classification_code", ret.getIpClassificationCode()) && result;
57 | result = testEqual(jor, "datacenter_homepage", ret.getDataCenterHomePage()) && result;
58 | result = testEqual(jor, "crawler_respect_robotstxt", ret.getCrawlerRespectRobotstxt()) && result;
59 | result = testEqual(jor, "crawler_family_vendor_code", ret.getCrawlerFamilyVendorCode()) && result;
60 | result = testEqual(jor, "crawler_category", ret.getCrawlerCategory()) && result;
61 | result = testEqual(jor, "crawler_ver_major", ret.getCrawlerVerMajor()) && result;
62 | result = testEqual(jor, "ip_country", ret.getIpCountry()) && result;
63 | result = testEqual(jor, "crawler_ver", ret.getCrawlerVer()) && result;
64 | result = testEqual(jor, "crawler_name", ret.getCrawlerName()) && result;
65 | result = testEqual(jor, "ip_city", ret.getIpCity()) && result;
66 | result = testEqual(jor, "datacenter_name_code", ret.getDataCenterNameCode()) && result;
67 | result = testEqual(jor, "crawler_family_info_url", ret.getCrawlerFamilyInfoUrl()) && result;
68 | result = testEqual(jor, "ip_country_code", ret.getIpCountryCode()) && result;
69 | result = testEqual(jor, "ip_ver", String.valueOf(ret.getIpVer())) && result;
70 | result = testEqual(jor, "ip_classification", ret.getIpClassification()) && result;
71 | result = testEqual(jor, "crawler_family_code", ret.getCrawlerFamilyCode()) && result;
72 | result = testEqual(jor, "crawler_family_icon", ret.getCrawlerFamilyIcon()) && result;
73 | result = testEqual(jor, "crawler_family_homepage", ret.getCrawlerFamilyHomepage()) && result;
74 | result = testEqual(jor, "crawler_family_vendor_homepage", ret.getCrawlerFamilyVendorHomepage()) && result;
75 | result = testEqual(jor, "datacenter_name", ret.getDataCenterName()) && result;
76 | result = testEqual(jor, "ip", ret.getIp()) && result;
77 | result = testEqual(jor, "crawler_family", ret.getCrawlerFamily()) && result;
78 | result = testEqual(jor, "ip_hostname", ret.getIpHostname()) && result;
79 | result = testEqual(jor, "crawler_category_code", ret.getCrawlerCategoryCode()) && result;
80 | result = testEqual(jor, "crawler_family_vendor", ret.getCrawlerFamilyVendor()) && result;
81 | return result;
82 | }
83 |
84 | private static boolean testEqual(JsonObject jor, String test, String ret) {
85 | String expected = jor.getString(test);
86 | if (!expected.equals(ret)) {
87 | System.out.println("Failed \"" + test + "\" : value=" + ret + " expected:" + expected);
88 | return false;
89 | }
90 | return true;
91 | }
92 | }
93 |
--------------------------------------------------------------------------------
/src/test/java/org/udger/parser/UdgerParserChangeDBTest.java:
--------------------------------------------------------------------------------
1 | package org.udger.parser;
2 |
3 | import static org.junit.Assert.assertEquals;
4 |
5 | import java.io.IOException;
6 | import java.net.URL;
7 | import java.sql.SQLException;
8 |
9 | import org.junit.Test;
10 |
11 | public class UdgerParserChangeDBTest {
12 |
13 | @Test
14 | public void testUaString1() throws SQLException, IOException {
15 | String uaQuery = "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:40.0) Gecko/20100101 Firefox/40.0";
16 | URL resource = this.getClass().getClassLoader().getResource("udgerdb_test_v3.dat");
17 | UdgerParser.ParserDbData parserDbData = new UdgerParser.ParserDbData(resource.getFile());
18 | try (UdgerParser parser = new UdgerParser(parserDbData)) {
19 |
20 | UdgerUaResult qr = parser.parseUa(uaQuery);
21 | assertEquals(qr.getUaUptodateCurrentVersion(), "50");
22 | }
23 |
24 | URL resource2 = this.getClass().getClassLoader().getResource("udgerdb_test_v3_switch.dat");
25 | UdgerParser.ParserDbData parserDbData2 = new UdgerParser.ParserDbData(resource2.getFile());
26 | try (UdgerParser parser2 = new UdgerParser(parserDbData2)) {
27 | UdgerUaResult qr2 = parser2.parseUa(uaQuery);
28 | assertEquals(qr2.getUaUptodateCurrentVersion(), "50X");
29 | }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/test/java/org/udger/parser/UdgerParserTest.java:
--------------------------------------------------------------------------------
1 | package org.udger.parser;
2 |
3 | import static org.junit.Assert.assertEquals;
4 | import static org.junit.Assert.fail;
5 |
6 | import java.io.IOException;
7 | import java.net.URL;
8 | import java.net.UnknownHostException;
9 | import java.sql.SQLException;
10 | import java.util.concurrent.ConcurrentLinkedQueue;
11 | import java.util.concurrent.CyclicBarrier;
12 |
13 | import org.junit.After;
14 | import org.junit.Before;
15 | import org.junit.Test;
16 |
17 | public class UdgerParserTest {
18 |
19 | private UdgerParser parser;
20 | private UdgerParser inMemoryParser;
21 | private UdgerParser.ParserDbData parserDbData;
22 |
23 | @Before
24 | public void initialize() throws SQLException {
25 | URL resource = this.getClass().getClassLoader().getResource("udgerdb_test_v3.dat");
26 | parserDbData = new UdgerParser.ParserDbData(resource.getFile());
27 | parser = new UdgerParser(parserDbData);
28 | inMemoryParser = new UdgerParser(parserDbData, true, 0); // no cache
29 | }
30 |
31 | @After
32 | public void close() throws IOException {
33 | parser.close();
34 | }
35 |
36 | @Test
37 | public void testUaString1() throws SQLException {
38 | String uaQuery = "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:40.0) Gecko/20100101 Firefox/40.0";
39 | UdgerUaResult qr = parser.parseUa(uaQuery);
40 | assertEquals(qr.getUa(), "Firefox 40.0");
41 | assertEquals(qr.getOs(), "Windows 10");
42 | assertEquals(qr.getUaFamily(), "Firefox");
43 | }
44 |
45 | @Test
46 | public void testIp() throws SQLException, UnknownHostException {
47 | String ipQuery = "108.61.199.93";
48 | UdgerIpResult qr = parser.parseIp(ipQuery);
49 | assertEquals(qr.getIpClassificationCode(), "crawler");
50 | }
51 |
52 | @Test
53 | public void testUaStringInMemoryParser() throws SQLException {
54 | String uaQuery = "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:40.0) Gecko/20100101 Firefox/40.0";
55 | UdgerUaResult qr = inMemoryParser.parseUa(uaQuery);
56 | assertEquals(qr.getUa(), "Firefox 40.0");
57 | assertEquals(qr.getOs(), "Windows 10");
58 | assertEquals(qr.getUaFamily(), "Firefox");
59 | }
60 |
61 | @Test
62 | public void testIpInMemoryParser() throws SQLException, UnknownHostException {
63 | String ipQuery = "108.61.199.93";
64 | UdgerIpResult qr = inMemoryParser.parseIp(ipQuery);
65 | assertEquals(qr.getIpClassificationCode(), "crawler");
66 | }
67 |
68 | @Test
69 | public void testParserDbDataThreadSafety() throws Throwable {
70 | final int numThreads = 500;
71 | final String uaQuery = "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:40.0) Gecko/20100101 Firefox/40.0";
72 |
73 | final CyclicBarrier gate = new CyclicBarrier(numThreads);
74 | final ConcurrentLinkedQueue failures = new ConcurrentLinkedQueue<>();
75 |
76 | Thread[] threads = new Thread[numThreads];
77 | for (int i = 0; i < numThreads; i++) {
78 | threads[i] = new Thread(new Runnable() {
79 | @Override
80 | public void run() {
81 | UdgerParser threadParser = new UdgerParser(parserDbData);
82 | try {
83 | gate.await();
84 | for (int j = 0; j < 100; j++) {
85 | UdgerUaResult qr = threadParser.parseUa(uaQuery);
86 | assertEquals(qr.getUa(), "Firefox 40.0");
87 | assertEquals(qr.getOs(), "Windows 10");
88 | assertEquals(qr.getUaFamily(), "Firefox");
89 | }
90 | } catch (Throwable t) {
91 | failures.add(t);
92 | }
93 | }
94 | });
95 | threads[i].start();
96 | }
97 |
98 | for (int i = 0; i < numThreads; i++) {
99 | threads[i].join();
100 | }
101 |
102 | if (!failures.isEmpty()) {
103 | for (Throwable throwable : failures) {
104 | throwable.printStackTrace();
105 | }
106 |
107 | fail("Parsing threads failed, see printed exceptions");
108 | }
109 | }
110 | }
111 |
--------------------------------------------------------------------------------
/src/test/java/org/udger/parser/UdgerPerformanceTest.java:
--------------------------------------------------------------------------------
1 | package org.udger.parser;
2 |
3 | import java.io.IOException;
4 | import java.io.InputStream;
5 | import java.sql.SQLException;
6 |
7 | import javax.json.JsonArray;
8 | import javax.json.JsonObject;
9 | import javax.json.JsonReader;
10 |
11 | import org.udger.parser.UdgerParser.ParserDbData;
12 |
13 | public class UdgerPerformanceTest {
14 |
15 | private static JsonArray jsonArray;
16 | private static UdgerParser[] POOL;
17 |
18 | private static void createPool() {
19 | POOL = new UdgerParser[10];
20 | for (int i=0; i<=9; i++) {
21 | POOL[i] = new UdgerParser(new UdgerParser.ParserDbData("udgerdb_v3_" + i + ".dat"));
22 | }
23 | }
24 |
25 | private static void closePool() throws IOException {
26 | for (int i=0; i<=9; i++) {
27 | if (POOL[i] != null) {
28 | POOL[i].close();
29 | }
30 | }
31 | }
32 |
33 | public static void main(String args[]) {
34 | InputStream is = UdgerUaTest.class.getResourceAsStream("test_ua.json");
35 | JsonReader jsonReader = javax.json.Json.createReader(is);
36 | jsonArray = jsonReader.readArray();
37 | UdgerParser.ParserDbData parserDbData = new UdgerParser.ParserDbData("udgerdb_v3.dat");
38 | for (int i=0; i<10; i++) {
39 | System.out.println("### Test : " + (i+1));
40 | testSerial(parserDbData);
41 | }
42 | }
43 |
44 | private static void testSerial(ParserDbData parserDbData) {
45 | UdgerParser up = null;
46 | try {
47 | up = new UdgerParser(parserDbData);
48 | long tm = 0;
49 | for (int j=0; j<100; j++) {
50 | for (int i=0; i < jsonArray.size(); i++) {
51 | JsonObject jar = jsonArray.getJsonObject(i);
52 | String query = jar.getJsonObject("test").getString("teststring");
53 | try {
54 | long prev = System.nanoTime();
55 | UdgerUaResult ret = up.parseUa(query);
56 | tm += System.nanoTime() - prev;
57 | } catch (SQLException e) {
58 | e.printStackTrace();
59 | }
60 | }
61 | }
62 | long numQueries = 100 * jsonArray.size();
63 | System.out.println("TOTAL Queries: " + numQueries + " time : " + tm / 1000000 + "ms AVG : " + 1000000000 * numQueries / (float) tm + "/s");
64 | } finally {
65 | if (up != null) {
66 | try {
67 | up.close();
68 | } catch (IOException e) {
69 | }
70 | }
71 | }
72 | }
73 |
74 | private static void testParallel() {
75 | try {
76 | createPool();
77 | long tm = 0;
78 | System.out.println("TOTAL Queries: " + 100 * jsonArray.size() + " time : " + tm + " AVG : " + 1000 * 100 * jsonArray.size() / (float) tm + "/s");
79 | } finally {
80 | try {
81 | closePool();
82 | } catch (IOException e) {
83 | }
84 | }
85 | }
86 |
87 | }
88 |
--------------------------------------------------------------------------------
/src/test/java/org/udger/parser/UdgerUaTest.java:
--------------------------------------------------------------------------------
1 | package org.udger.parser;
2 |
3 | import java.io.IOException;
4 | import java.io.InputStream;
5 | import java.sql.SQLException;
6 |
7 | import javax.json.JsonArray;
8 | import javax.json.JsonObject;
9 | import javax.json.JsonReader;
10 |
11 | public class UdgerUaTest {
12 |
13 | public static void main(String args[]) throws SQLException {
14 | InputStream is = UdgerUaTest.class.getResourceAsStream("test_ua.json");
15 | JsonReader jr = javax.json.Json.createReader(is);
16 | JsonArray ja = jr.readArray();
17 | UdgerParser up = null;
18 | try {
19 | UdgerParser.ParserDbData parserDbData = new UdgerParser.ParserDbData("udgerdb_v3.dat");
20 | up = new UdgerParser(parserDbData);
21 | for (int i=0; i < ja.size(); i++) {
22 | JsonObject jar = ja.getJsonObject(i);
23 | JsonObject jor = jar.getJsonObject("ret");
24 | String query = jar.getJsonObject("test").getString("teststring");
25 | try {
26 | UdgerUaResult ret = up.parseUa(query);
27 | System.out.print("### Test : " + (i+1) + " - ");
28 | if (checkResult(ret, jor)) {
29 | System.out.println("SUCCEEDED");
30 | } else {
31 | System.out.println("FAILED!");
32 | }
33 | System.out.println("Query: " + query);
34 | // System.out.println("Result: " + ReflectionToStringBuilder.toString(ret, ToStringStyle.MULTI_LINE_STYLE));
35 | } catch (SQLException e) {
36 | e.printStackTrace();
37 | }
38 | }
39 | } finally {
40 | if (up != null) {
41 | try {
42 | up.close();
43 | } catch (IOException e) {
44 | }
45 | }
46 | }
47 | }
48 |
49 | private static boolean checkResult(UdgerUaResult ret, JsonObject jor) {
50 | boolean result = true;
51 | result = testEqual(jor, "ua_engine", ret.getUaEngine()) && result;
52 | result = testEqual(jor, "ua_version", ret.getUaVersion()) && result;
53 | result = testEqual(jor, "ua_family_code", ret.getUaFamilyCode()) && result;
54 | result = testEqual(jor, "ua_family_icon_big", ret.getUaFamilyIconBig()) && result;
55 | result = testEqual(jor, "crawler_category", ret.getCrawlerCategory()) && result;
56 | result = testEqual(jor, "ua_family_icon", ret.getUaFamilyIcon()) && result;
57 | result = testEqual(jor, "ua_family_vendor", ret.getUaFamilyVendor()) && result;
58 | result = testEqual(jor, "ua_family_vendor_code", ret.getUaFamilyVendorCode()) && result;
59 | result = testEqual(jor, "ua_uptodate_current_version", ret.getUaUptodateCurrentVersion()) && result;
60 | result = testEqual(jor, "ua_class_code", ret.getUaClassCode()) && result;
61 | result = testEqual(jor, "ua", ret.getUa()) && result;
62 | result = testEqual(jor, "ua_family", ret.getUaFamily()) && result;
63 | result = testEqual(jor, "ua_family_homepage", ret.getUaFamilyHomepage()) && result;
64 | result = testEqual(jor, "ua_version_major", ret.getUaVersionMajor()) && result;
65 | result = testEqual(jor, "ua_family_info_url", ret.getUaFamilyInfoUrl()) && result;
66 | result = testEqual(jor, "crawler_respect_robotstxt", ret.getCrawlerRespectRobotstxt()) && result;
67 | result = testEqual(jor, "ua_class", ret.getUaClass()) && result;
68 | result = testEqual(jor, "ua_family_vendor_homepage", ret.getUaFamilyVendorHomepage()) && result;
69 | result = testEqual(jor, "crawler_category_code", ret.getCrawlerCategoryCode()) && result;
70 | // result = testEqual(jor, "ua_string", ret.getUserAgent() != null ? ret.getUserAgent().get) && result;
71 |
72 | result = testEqual(jor, "os_family_vendor_homepage", ret.getOsFamilyVendorHomepage()) && result;
73 | result = testEqual(jor, "os_icon_big", ret.getOsIconBig()) && result;
74 | result = testEqual(jor, "os_homepage", ret.getOsHomePage()) && result;
75 | result = testEqual(jor, "os_icon", ret.getOsIcon()) && result;
76 | result = testEqual(jor, "os", ret.getOs()) && result;
77 | result = testEqual(jor, "os_family_code", ret.getOsFamilyCode()) && result;
78 | result = testEqual(jor, "os_family_vendor", ret.getOsFamilyVendor()) && result;
79 | result = testEqual(jor, "os_family_vendor_code", ret.getOsFamilyVendorCode()) && result;
80 | result = testEqual(jor, "os_code", ret.getOsCode()) && result;
81 | result = testEqual(jor, "os_family", ret.getOsFamily()) && result;
82 | result = testEqual(jor, "os_info_url", ret.getOsInfoUrl()) && result;
83 |
84 | result = testEqual(jor, "device_class", ret.getDeviceClass()) && result;
85 | result = testEqual(jor, "device_class_icon_big", ret.getDeviceClassIconBig()) && result;
86 | result = testEqual(jor, "device_class_icon", ret.getDeviceClassIcon()) && result;
87 | result = testEqual(jor, "device_class_info_url", ret.getDeviceClassInfoUrl()) && result;
88 | result = testEqual(jor, "device_class_code", ret.getDeviceClassCode()) && result;
89 |
90 | result = testEqual(jor, "device_marketname", ret.getDeviceMarketname()) && result;
91 | result = testEqual(jor, "device_brand", ret.getDeviceBrand()) && result;
92 | result = testEqual(jor, "device_brand_code", ret.getDeviceBrandCode()) && result;
93 | result = testEqual(jor, "device_brand_homepage", ret.getDeviceBrandHomepage()) && result;
94 | result = testEqual(jor, "device_brand_icon", ret.getDeviceBrandIcon()) && result;
95 | result = testEqual(jor, "device_brand_icon_big", ret.getDeviceBrandIconBig()) && result;
96 | result = testEqual(jor, "device_brand_info_url", ret.getDeviceBrandInfoUrl()) && result;
97 |
98 | return result;
99 | }
100 |
101 | private static boolean testEqual(JsonObject jor, String test, String ret) {
102 | String expected = jor.getString(test);
103 | if (!expected.equals(ret) && expected.startsWith("https://")) {
104 | expected = expected.replaceAll(" ", "%20");
105 | }
106 | if (!expected.equals(ret)) {
107 | System.out.println("Failed \"" + test + "\" : value=" + ret + " expected:" + expected);
108 | return false;
109 | }
110 | return true;
111 | }
112 |
113 | }
114 |
--------------------------------------------------------------------------------
/src/test/java/org/udger/parser/test_ip.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "test": {
4 | "teststring": "108.61.199.93"
5 | },
6 | "ret": {
7 | "ip": "108.61.199.93",
8 | "ip_ver": "4",
9 | "ip_classification": "Crawler",
10 | "ip_classification_code": "crawler",
11 | "ip_hostname": "108.61.199.93.vultr.com",
12 | "ip_country": "Netherlands",
13 | "ip_country_code": "NL",
14 | "ip_city": "Amsterdam",
15 | "crawler_name": "PINGOMETER",
16 | "crawler_ver": "",
17 | "crawler_ver_major": "",
18 | "crawler_family": "PINGOMETER",
19 | "crawler_family_code": "pingometer",
20 | "crawler_family_homepage": "",
21 | "crawler_family_vendor": "Pingometer, LLC",
22 | "crawler_family_vendor_code": "pingometer_llc",
23 | "crawler_family_vendor_homepage": "http:\/\/pingometer.com\/",
24 | "crawler_family_icon": "bot_pingometer.png",
25 | "crawler_family_info_url": "https:\/\/udger.com\/resources\/ua-list\/bot-detail?bot=PINGOMETER#id20112",
26 | "crawler_category": "Site monitor",
27 | "crawler_category_code": "site_monitor",
28 | "crawler_respect_robotstxt": "no",
29 | "datacenter_name": "Choopa, LLC.",
30 | "datacenter_name_code": "choopa",
31 | "datacenter_homepage": "https:\/\/www.choopa.com\/"
32 | }
33 | },
34 | {
35 | "test": {
36 | "teststring": "2a02:598:111::9"
37 | },
38 | "ret": {
39 | "ip": "2a02:598:111::9",
40 | "ip_ver": "6",
41 | "ip_classification": "Crawler",
42 | "ip_classification_code": "crawler",
43 | "ip_hostname": "fulltextrobot-dev-2a02-598-111--9.seznam.cz",
44 | "ip_country": "Czech Republic",
45 | "ip_country_code": "CZ",
46 | "ip_city": "Prague",
47 | "crawler_name": "SeznamBot\/3.2-test1",
48 | "crawler_ver": "3.2-test1",
49 | "crawler_ver_major": "3",
50 | "crawler_family": "SeznamBot",
51 | "crawler_family_code": "seznambot",
52 | "crawler_family_homepage": "http:\/\/napoveda.seznam.cz\/en\/seznambot-intro\/",
53 | "crawler_family_vendor": "Seznam.cz, a.s.",
54 | "crawler_family_vendor_code": "seznam-cz_as",
55 | "crawler_family_vendor_homepage": "http:\/\/onas.seznam.cz\/",
56 | "crawler_family_icon": "seznam.png",
57 | "crawler_family_info_url": "https:\/\/udger.com\/resources\/ua-list\/bot-detail?bot=SeznamBot#id28914",
58 | "crawler_category": "Search engine bot",
59 | "crawler_category_code": "search_engine_bot",
60 | "crawler_respect_robotstxt": "unknown",
61 | "datacenter_name": "Seznam.cz",
62 | "datacenter_name_code": "seznam_cz",
63 | "datacenter_homepage": "http:\/\/onas.seznam.cz\/"
64 | }
65 | },
66 | {
67 | "test": {
68 | "teststring": "2001:41d0:8:d54c::1"
69 | },
70 | "ret": {
71 | "ip": "2001:41d0:8:d54c::1",
72 | "ip_ver": "6",
73 | "ip_classification": "Cgi proxy",
74 | "ip_classification_code": "cgi_proxy",
75 | "ip_hostname": "",
76 | "ip_country": "France",
77 | "ip_country_code": "FR",
78 | "ip_city": "Cachan",
79 | "crawler_name": "",
80 | "crawler_ver": "",
81 | "crawler_ver_major": "",
82 | "crawler_family": "",
83 | "crawler_family_code": "",
84 | "crawler_family_homepage": "",
85 | "crawler_family_vendor": "",
86 | "crawler_family_vendor_code": "",
87 | "crawler_family_vendor_homepage": "",
88 | "crawler_family_icon": "",
89 | "crawler_family_info_url": "",
90 | "crawler_category": "",
91 | "crawler_category_code": "",
92 | "crawler_respect_robotstxt": "",
93 | "datacenter_name": "OVH",
94 | "datacenter_name_code": "ovh",
95 | "datacenter_homepage": "http:\/\/www.ovh.com\/"
96 | }
97 | },
98 | {
99 | "test": {
100 | "teststring": "66.249.64.73"
101 | },
102 | "ret": {
103 | "ip": "66.249.64.73",
104 | "ip_ver": "4",
105 | "ip_classification": "Crawler",
106 | "ip_classification_code": "crawler",
107 | "ip_hostname": "crawl-66-249-64-73.googlebot.com",
108 | "ip_country": "United States",
109 | "ip_country_code": "US",
110 | "ip_city": "Mountain View",
111 | "crawler_name": "Googlebot\/2.1",
112 | "crawler_ver": "2.1",
113 | "crawler_ver_major": "2",
114 | "crawler_family": "Googlebot",
115 | "crawler_family_code": "googlebot",
116 | "crawler_family_homepage": "http:\/\/www.google.com\/bot.html",
117 | "crawler_family_vendor": "Google Inc.",
118 | "crawler_family_vendor_code": "google_inc",
119 | "crawler_family_vendor_homepage": "https:\/\/www.google.com\/about\/company\/",
120 | "crawler_family_icon": "bot_googlebot.png",
121 | "crawler_family_info_url": "https:\/\/udger.com\/resources\/ua-list\/bot-detail?bot=Googlebot#id31",
122 | "crawler_category": "Search engine bot",
123 | "crawler_category_code": "search_engine_bot",
124 | "crawler_respect_robotstxt": "yes",
125 | "datacenter_name": "Google sites",
126 | "datacenter_name_code": "googgle_sites",
127 | "datacenter_homepage": "http:\/\/sites.google.com\/"
128 | }
129 | },
130 | {
131 | "test": {
132 | "teststring": "90.177.52.111"
133 | },
134 | "ret": {
135 | "ip": "90.177.52.111",
136 | "ip_ver": "4",
137 | "ip_classification": "Unrecognized",
138 | "ip_classification_code": "unrecognized",
139 | "ip_hostname": "",
140 | "ip_country": "",
141 | "ip_country_code": "",
142 | "ip_city": "",
143 | "crawler_name": "",
144 | "crawler_ver": "",
145 | "crawler_ver_major": "",
146 | "crawler_family": "",
147 | "crawler_family_code": "",
148 | "crawler_family_homepage": "",
149 | "crawler_family_vendor": "",
150 | "crawler_family_vendor_code": "",
151 | "crawler_family_vendor_homepage": "",
152 | "crawler_family_icon": "",
153 | "crawler_family_info_url": "",
154 | "crawler_category": "",
155 | "crawler_category_code": "",
156 | "crawler_respect_robotstxt": "",
157 | "datacenter_name": "",
158 | "datacenter_name_code": "",
159 | "datacenter_homepage": ""
160 | }
161 | }
162 | ]
--------------------------------------------------------------------------------
/src/test/java/org/udger/parser/test_ua.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "test": {
4 | "teststring": "Mozilla\/5.0 (Windows NT 10.0; WOW64; rv:40.0) Gecko\/20100101 Firefox\/40.0"
5 | },
6 | "ret": {
7 | "ua_string": "Mozilla\/5.0 (Windows NT 10.0; WOW64; rv:40.0) Gecko\/20100101 Firefox\/40.0",
8 | "ua_class": "Browser",
9 | "ua_class_code": "browser",
10 | "ua": "Firefox 40.0",
11 | "ua_version": "40.0",
12 | "ua_version_major": "40",
13 | "ua_uptodate_current_version": "50",
14 | "ua_family": "Firefox",
15 | "ua_family_code": "firefox",
16 | "ua_family_homepage": "http:\/\/www.firefox.com\/",
17 | "ua_family_vendor": "Mozilla Foundation",
18 | "ua_family_vendor_code": "mozilla_foundation",
19 | "ua_family_vendor_homepage": "http:\/\/www.mozilla.org\/",
20 | "ua_family_icon": "firefox.png",
21 | "ua_family_icon_big": "firefox_big.png",
22 | "ua_family_info_url": "https:\/\/udger.com\/resources\/ua-list\/browser-detail?browser=Firefox",
23 | "ua_engine": "Gecko",
24 | "os": "Windows 10",
25 | "os_code": "windows_10",
26 | "os_homepage": "https:\/\/en.wikipedia.org\/wiki\/Windows_10",
27 | "os_icon": "windows10.png",
28 | "os_icon_big": "windows10_big.png",
29 | "os_info_url": "https:\/\/udger.com\/resources\/ua-list\/os-detail?os=Windows 10",
30 | "os_family": "Windows",
31 | "os_family_code": "windows",
32 | "os_family_vendor": "Microsoft Corporation.",
33 | "os_family_vendor_code": "microsoft_corporation",
34 | "os_family_vendor_homepage": "https:\/\/www.microsoft.com\/about\/",
35 | "device_class": "Desktop",
36 | "device_class_code": "desktop",
37 | "device_class_icon": "desktop.png",
38 | "device_class_icon_big": "desktop_big.png",
39 | "device_class_info_url": "https:\/\/udger.com\/resources\/ua-list\/device-detail?device=Desktop",
40 | "device_marketname": "",
41 | "device_brand": "",
42 | "device_brand_code": "",
43 | "device_brand_homepage": "",
44 | "device_brand_icon": "",
45 | "device_brand_icon_big": "",
46 | "device_brand_info_url": "",
47 | "crawler_category": "",
48 | "crawler_category_code": "",
49 | "crawler_respect_robotstxt": ""
50 | }
51 | },
52 | {
53 | "test": {
54 | "teststring": "Mozilla\/5.0 (compatible; SeznamBot\/3.2; +http:\/\/fulltext.sblog.cz\/)"
55 | },
56 | "ret": {
57 | "ua_string": "Mozilla\/5.0 (compatible; SeznamBot\/3.2; +http:\/\/fulltext.sblog.cz\/)",
58 | "ua_class": "Crawler",
59 | "ua_class_code": "crawler",
60 | "ua": "SeznamBot\/3.2",
61 | "ua_version": "3.2",
62 | "ua_version_major": "3",
63 | "ua_uptodate_current_version": "",
64 | "ua_family": "SeznamBot",
65 | "ua_family_code": "seznambot",
66 | "ua_family_homepage": "http:\/\/napoveda.seznam.cz\/en\/seznambot-intro\/",
67 | "ua_family_vendor": "Seznam.cz, a.s.",
68 | "ua_family_vendor_code": "seznam-cz_as",
69 | "ua_family_vendor_homepage": "http:\/\/onas.seznam.cz\/",
70 | "ua_family_icon": "seznam.png",
71 | "ua_family_icon_big": "",
72 | "ua_family_info_url": "https:\/\/udger.com\/resources\/ua-list\/bot-detail?bot=SeznamBot#id12571",
73 | "ua_engine": "",
74 | "os": "",
75 | "os_code": "",
76 | "os_homepage": "",
77 | "os_icon": "",
78 | "os_icon_big": "",
79 | "os_info_url": "",
80 | "os_family": "",
81 | "os_family_code": "",
82 | "os_family_vendor": "",
83 | "os_family_vendor_code": "",
84 | "os_family_vendor_homepage": "",
85 | "device_class": "Unrecognized",
86 | "device_class_code": "unrecognized",
87 | "device_class_icon": "other.png",
88 | "device_class_icon_big": "other_big.png",
89 | "device_class_info_url": "https:\/\/udger.com\/resources\/ua-list\/device-detail?device=Unrecognized",
90 | "device_marketname": "",
91 | "device_brand": "",
92 | "device_brand_code": "",
93 | "device_brand_homepage": "",
94 | "device_brand_icon": "",
95 | "device_brand_icon_big": "",
96 | "device_brand_info_url": "",
97 | "crawler_category": "Search engine bot",
98 | "crawler_category_code": "search_engine_bot",
99 | "crawler_respect_robotstxt": "yes"
100 | }
101 | },
102 | {
103 | "test": {
104 | "teststring": "Mozilla\/5.0 (iPad; CPU OS 7_0 like Mac OS X) AppleWebKit\/537.51.1 (KHTML, like Gecko) Version\/7.0 Mobile\/11A465 Safari\/9537.53"
105 | },
106 | "ret": {
107 | "ua_string": "Mozilla\/5.0 (iPad; CPU OS 7_0 like Mac OS X) AppleWebKit\/537.51.1 (KHTML, like Gecko) Version\/7.0 Mobile\/11A465 Safari\/9537.53",
108 | "ua_class": "Mobile browser",
109 | "ua_class_code": "mobile_browser",
110 | "ua": "Safari mobile 7.0",
111 | "ua_version": "7.0",
112 | "ua_version_major": "7",
113 | "ua_uptodate_current_version": "",
114 | "ua_family": "Safari mobile",
115 | "ua_family_code": "safari_mobile",
116 | "ua_family_homepage": "https:\/\/en.wikipedia.org\/wiki\/Safari_%28web_browser%29",
117 | "ua_family_vendor": "Apple Inc.",
118 | "ua_family_vendor_code": "apple_inc",
119 | "ua_family_vendor_homepage": "http:\/\/www.apple.com\/",
120 | "ua_family_icon": "safari.png",
121 | "ua_family_icon_big": "safari_big.png",
122 | "ua_family_info_url": "https:\/\/udger.com\/resources\/ua-list\/browser-detail?browser=Safari mobile",
123 | "ua_engine": "WebKit",
124 | "os": "iOS 7",
125 | "os_code": "ios_7",
126 | "os_homepage": "https:\/\/en.wikipedia.org\/wiki\/IOS_7",
127 | "os_icon": "iphone.png",
128 | "os_icon_big": "iphone_big.png",
129 | "os_info_url": "https:\/\/udger.com\/resources\/ua-list\/os-detail?os=iOS 7",
130 | "os_family": "iOS",
131 | "os_family_code": "ios",
132 | "os_family_vendor": "Apple Inc.",
133 | "os_family_vendor_code": "apple_inc",
134 | "os_family_vendor_homepage": "http:\/\/www.apple.com\/",
135 | "device_class": "Tablet",
136 | "device_class_code": "tablet",
137 | "device_class_icon": "tablet.png",
138 | "device_class_icon_big": "tablet_big.png",
139 | "device_class_info_url": "https:\/\/udger.com\/resources\/ua-list\/device-detail?device=Tablet",
140 | "device_marketname": "iPad",
141 | "device_brand": "Apple",
142 | "device_brand_code": "apple",
143 | "device_brand_homepage": "http:\/\/www.apple.com\/",
144 | "device_brand_icon": "apple.png",
145 | "device_brand_icon_big": "apple_big.png",
146 | "device_brand_info_url": "https:\/\/udger.com\/resources\/ua-list\/devices-brand-detail?brand=apple",
147 | "crawler_category": "",
148 | "crawler_category_code": "",
149 | "crawler_respect_robotstxt": ""
150 | }
151 | },
152 | {
153 | "test": {
154 | "teststring": "Mozilla\/5.0 (Linux; U; Android 4.0.4; sk-sk; Luna TAB474 Build\/LunaTAB474) AppleWebKit\/534.30 (KHTML, like Gecko) Version\/4.0 Safari\/534.30"
155 | },
156 | "ret": {
157 | "ua_string": "Mozilla\/5.0 (Linux; U; Android 4.0.4; sk-sk; Luna TAB474 Build\/LunaTAB474) AppleWebKit\/534.30 (KHTML, like Gecko) Version\/4.0 Safari\/534.30",
158 | "ua_class": "Mobile browser",
159 | "ua_class_code": "mobile_browser",
160 | "ua": "Android browser 4.0",
161 | "ua_version": "4.0",
162 | "ua_version_major": "4",
163 | "ua_uptodate_current_version": "",
164 | "ua_family": "Android browser",
165 | "ua_family_code": "android_browser",
166 | "ua_family_homepage": "http:\/\/developer.android.com\/reference\/android\/webkit\/package-summary.html",
167 | "ua_family_vendor": "Google Inc.",
168 | "ua_family_vendor_code": "google_inc",
169 | "ua_family_vendor_homepage": "https:\/\/www.google.com\/about\/company\/",
170 | "ua_family_icon": "androidWebkit.png",
171 | "ua_family_icon_big": "androidWebkit_big.png",
172 | "ua_family_info_url": "https:\/\/udger.com\/resources\/ua-list\/browser-detail?browser=Android browser",
173 | "ua_engine": "WebKit",
174 | "os": "Android 4.0.x Ice Cream Sandwich",
175 | "os_code": "android_4",
176 | "os_homepage": "https:\/\/en.wikipedia.org\/wiki\/Android_%28operating_system%29",
177 | "os_icon": "android.png",
178 | "os_icon_big": "android_big.png",
179 | "os_info_url": "https:\/\/udger.com\/resources\/ua-list\/os-detail?os=Android 4.0.x Ice Cream Sandwich",
180 | "os_family": "Android",
181 | "os_family_code": "android",
182 | "os_family_vendor": "Google, Inc.",
183 | "os_family_vendor_code": "google_inc",
184 | "os_family_vendor_homepage": "https:\/\/www.google.com\/about\/company\/",
185 | "device_class": "Tablet",
186 | "device_class_code": "tablet",
187 | "device_class_icon": "tablet.png",
188 | "device_class_icon_big": "tablet_big.png",
189 | "device_class_info_url": "https:\/\/udger.com\/resources\/ua-list\/device-detail?device=Tablet",
190 | "device_marketname": "Luna 10",
191 | "device_brand": "Yarvik",
192 | "device_brand_code": "yarvik",
193 | "device_brand_homepage": "http:\/\/yarvik.com\/",
194 | "device_brand_icon": "yarvik.png",
195 | "device_brand_icon_big": "",
196 | "device_brand_info_url": "https:\/\/udger.com\/resources\/ua-list\/devices-brand-detail?brand=yarvik",
197 | "crawler_category": "",
198 | "crawler_category_code": "",
199 | "crawler_respect_robotstxt": ""
200 | }
201 | },
202 | {
203 | "test": {
204 | "teststring": "Mozilla\/5.0 (Playstation Vita 1.61) AppleWebKit\/531.22.8 (KHTML, like Gecko) Silk\/3.2"
205 | },
206 | "ret": {
207 | "ua_string": "Mozilla\/5.0 (Playstation Vita 1.61) AppleWebKit\/531.22.8 (KHTML, like Gecko) Silk\/3.2",
208 | "ua_class": "Mobile browser",
209 | "ua_class_code": "mobile_browser",
210 | "ua": "PS Vita browser 3.2",
211 | "ua_version": "3.2",
212 | "ua_version_major": "3",
213 | "ua_uptodate_current_version": "",
214 | "ua_family": "PS Vita browser",
215 | "ua_family_code": "ps_vita_browser",
216 | "ua_family_homepage": "",
217 | "ua_family_vendor": "Sony Computer Entertainment",
218 | "ua_family_vendor_code": "sony_computer_entertainment",
219 | "ua_family_vendor_homepage": "http:\/\/www.scei.co.jp\/",
220 | "ua_family_icon": "ps-vita-browser.png",
221 | "ua_family_icon_big": "",
222 | "ua_family_info_url": "https:\/\/udger.com\/resources\/ua-list\/browser-detail?browser=PS Vita browser",
223 | "ua_engine": "WebKit",
224 | "os": "LiveArea",
225 | "os_code": "live_area",
226 | "os_homepage": "https:\/\/en.wikipedia.org\/wiki\/LiveArea",
227 | "os_icon": "ps-vitaLiveArea.png",
228 | "os_icon_big": "",
229 | "os_info_url": "https:\/\/udger.com\/resources\/ua-list\/os-detail?os=LiveArea",
230 | "os_family": "LiveArea",
231 | "os_family_code": "live_area",
232 | "os_family_vendor": "Sony Computer Entertainment",
233 | "os_family_vendor_code": "sony",
234 | "os_family_vendor_homepage": "http:\/\/www.scei.co.jp\/",
235 | "device_class": "Game console",
236 | "device_class_code": "game_console",
237 | "device_class_icon": "console.png",
238 | "device_class_icon_big": "console_big.png",
239 | "device_class_info_url": "https:\/\/udger.com\/resources\/ua-list\/device-detail?device=Game console",
240 | "device_marketname": "Playstation Vita",
241 | "device_brand": "Sony",
242 | "device_brand_code": "sony",
243 | "device_brand_homepage": "http:\/\/www.sony.com\/",
244 | "device_brand_icon": "sony.png",
245 | "device_brand_icon_big": "sony_big.png",
246 | "device_brand_info_url": "https:\/\/udger.com\/resources\/ua-list\/devices-brand-detail?brand=sony",
247 | "crawler_category": "",
248 | "crawler_category_code": "",
249 | "crawler_respect_robotstxt": ""
250 | }
251 | },
252 | {
253 | "test": {
254 | "teststring": "Mozilla\/5.0 (CrKey armv7l 1.4.15250) AppleWebKit\/537.36 (KHTML, like Gecko) Chrome\/31.0.1650.0 Safari\/537.36"
255 | },
256 | "ret": {
257 | "ua_string": "Mozilla\/5.0 (CrKey armv7l 1.4.15250) AppleWebKit\/537.36 (KHTML, like Gecko) Chrome\/31.0.1650.0 Safari\/537.36",
258 | "ua_class": "Browser",
259 | "ua_class_code": "browser",
260 | "ua": "Chrome 31.0.1650.0",
261 | "ua_version": "31.0.1650.0",
262 | "ua_version_major": "31",
263 | "ua_uptodate_current_version": "55",
264 | "ua_family": "Chrome",
265 | "ua_family_code": "chrome",
266 | "ua_family_homepage": "http:\/\/www.google.com\/chrome\/",
267 | "ua_family_vendor": "Google Inc.",
268 | "ua_family_vendor_code": "google_inc",
269 | "ua_family_vendor_homepage": "https:\/\/www.google.com\/about\/company\/",
270 | "ua_family_icon": "chrome.png",
271 | "ua_family_icon_big": "chrome_big.png",
272 | "ua_family_info_url": "https:\/\/udger.com\/resources\/ua-list\/browser-detail?browser=Chrome",
273 | "ua_engine": "WebKit\/Blink",
274 | "os": "Android",
275 | "os_code": "android",
276 | "os_homepage": "https:\/\/en.wikipedia.org\/wiki\/Android_%28operating_system%29",
277 | "os_icon": "android.png",
278 | "os_icon_big": "android_big.png",
279 | "os_info_url": "https:\/\/udger.com\/resources\/ua-list\/os-detail?os=Android",
280 | "os_family": "Android",
281 | "os_family_code": "android",
282 | "os_family_vendor": "Google, Inc.",
283 | "os_family_vendor_code": "google_inc",
284 | "os_family_vendor_homepage": "https:\/\/www.google.com\/about\/company\/",
285 | "device_class": "Smart TV",
286 | "device_class_code": "smart_tv",
287 | "device_class_icon": "smarttv.png",
288 | "device_class_icon_big": "smarttv_big.png",
289 | "device_class_info_url": "https:\/\/udger.com\/resources\/ua-list\/device-detail?device=Smart TV",
290 | "device_marketname": "Chromecast",
291 | "device_brand": "Google",
292 | "device_brand_code": "google",
293 | "device_brand_homepage": "https:\/\/www.google.com\/",
294 | "device_brand_icon": "google.png",
295 | "device_brand_icon_big": "google_big.png",
296 | "device_brand_info_url": "https:\/\/udger.com\/resources\/ua-list\/devices-brand-detail?brand=google",
297 | "crawler_category": "",
298 | "crawler_category_code": "",
299 | "crawler_respect_robotstxt": ""
300 | }
301 | },
302 | {
303 | "test": {
304 | "teststring": "Mozilla\/5.0 (compatible; MSIE 10.0; Windows Phone 8.0; Trident\/6.0; IEMobile\/10.0; ARM; Touch; NOKIA; Lumia 820)"
305 | },
306 | "ret": {
307 | "ua_string": "Mozilla\/5.0 (compatible; MSIE 10.0; Windows Phone 8.0; Trident\/6.0; IEMobile\/10.0; ARM; Touch; NOKIA; Lumia 820)",
308 | "ua_class": "Mobile browser",
309 | "ua_class_code": "mobile_browser",
310 | "ua": "IE Mobile 10.0",
311 | "ua_version": "10.0",
312 | "ua_version_major": "10",
313 | "ua_uptodate_current_version": "",
314 | "ua_family": "IE Mobile",
315 | "ua_family_code": "ie_mobile",
316 | "ua_family_homepage": "https:\/\/en.wikipedia.org\/wiki\/Internet_Explorer_Mobile",
317 | "ua_family_vendor": "Microsoft Corporation.",
318 | "ua_family_vendor_code": "microsoft_corporation",
319 | "ua_family_vendor_homepage": "https:\/\/www.microsoft.com\/about\/",
320 | "ua_family_icon": "iemobile.png",
321 | "ua_family_icon_big": "",
322 | "ua_family_info_url": "https:\/\/udger.com\/resources\/ua-list\/browser-detail?browser=IE Mobile",
323 | "ua_engine": "Trident",
324 | "os": "Windows Phone 8",
325 | "os_code": "windows_phone_8",
326 | "os_homepage": "https:\/\/en.wikipedia.org\/wiki\/Windows_Phone_8",
327 | "os_icon": "windowsPhone8.png",
328 | "os_icon_big": "",
329 | "os_info_url": "https:\/\/udger.com\/resources\/ua-list\/os-detail?os=Windows Phone 8",
330 | "os_family": "Windows",
331 | "os_family_code": "windows",
332 | "os_family_vendor": "Microsoft Corporation.",
333 | "os_family_vendor_code": "microsoft_corporation",
334 | "os_family_vendor_homepage": "https:\/\/www.microsoft.com\/about\/",
335 | "device_class": "Smartphone",
336 | "device_class_code": "smartphone",
337 | "device_class_icon": "phone.png",
338 | "device_class_icon_big": "phone_big.png",
339 | "device_class_info_url": "https:\/\/udger.com\/resources\/ua-list\/device-detail?device=Smartphone",
340 | "device_marketname": "Lumia 820",
341 | "device_brand": "Nokia",
342 | "device_brand_code": "nokia",
343 | "device_brand_homepage": "http:\/\/www.nokia.com\/",
344 | "device_brand_icon": "nokia.png",
345 | "device_brand_icon_big": "nokia_big.png",
346 | "device_brand_info_url": "https:\/\/udger.com\/resources\/ua-list\/devices-brand-detail?brand=nokia",
347 | "crawler_category": "",
348 | "crawler_category_code": "",
349 | "crawler_respect_robotstxt": ""
350 | }
351 | },
352 | {
353 | "test": {
354 | "teststring": "Mozilla\/5.0 (Linux; U; Android 4.0.4; en-us; Glass 1 Build\/IMM76L; XE9) AppleWebKit\/534.30 (KHTML, like Gecko) Version\/4.0 Mobile Safari\/534.30"
355 | },
356 | "ret": {
357 | "ua_string": "Mozilla\/5.0 (Linux; U; Android 4.0.4; en-us; Glass 1 Build\/IMM76L; XE9) AppleWebKit\/534.30 (KHTML, like Gecko) Version\/4.0 Mobile Safari\/534.30",
358 | "ua_class": "Mobile browser",
359 | "ua_class_code": "mobile_browser",
360 | "ua": "Android browser 4.0",
361 | "ua_version": "4.0",
362 | "ua_version_major": "4",
363 | "ua_uptodate_current_version": "",
364 | "ua_family": "Android browser",
365 | "ua_family_code": "android_browser",
366 | "ua_family_homepage": "http:\/\/developer.android.com\/reference\/android\/webkit\/package-summary.html",
367 | "ua_family_vendor": "Google Inc.",
368 | "ua_family_vendor_code": "google_inc",
369 | "ua_family_vendor_homepage": "https:\/\/www.google.com\/about\/company\/",
370 | "ua_family_icon": "androidWebkit.png",
371 | "ua_family_icon_big": "androidWebkit_big.png",
372 | "ua_family_info_url": "https:\/\/udger.com\/resources\/ua-list\/browser-detail?browser=Android browser",
373 | "ua_engine": "WebKit",
374 | "os": "Android 4.0.x Ice Cream Sandwich",
375 | "os_code": "android_4",
376 | "os_homepage": "https:\/\/en.wikipedia.org\/wiki\/Android_%28operating_system%29",
377 | "os_icon": "android.png",
378 | "os_icon_big": "android_big.png",
379 | "os_info_url": "https:\/\/udger.com\/resources\/ua-list\/os-detail?os=Android 4.0.x Ice Cream Sandwich",
380 | "os_family": "Android",
381 | "os_family_code": "android",
382 | "os_family_vendor": "Google, Inc.",
383 | "os_family_vendor_code": "google_inc",
384 | "os_family_vendor_homepage": "https:\/\/www.google.com\/about\/company\/",
385 | "device_class": "Wearable computer",
386 | "device_class_code": "wearable_computer",
387 | "device_class_icon": "wearable.png",
388 | "device_class_icon_big": "wearable_big.png",
389 | "device_class_info_url": "https:\/\/udger.com\/resources\/ua-list\/device-detail?device=Wearable computer",
390 | "device_marketname": "Google Glass",
391 | "device_brand": "Google",
392 | "device_brand_code": "google",
393 | "device_brand_homepage": "https:\/\/www.google.com\/",
394 | "device_brand_icon": "google.png",
395 | "device_brand_icon_big": "google_big.png",
396 | "device_brand_info_url": "https:\/\/udger.com\/resources\/ua-list\/devices-brand-detail?brand=google",
397 | "crawler_category": "",
398 | "crawler_category_code": "",
399 | "crawler_respect_robotstxt": ""
400 | }
401 | },
402 | {
403 | "test": {
404 | "teststring": "Microsoft Office\/16.0 (Windows NT 10.0; Microsoft Outlook 16.0.6326; Pro)"
405 | },
406 | "ret": {
407 | "ua_string": "Microsoft Office\/16.0 (Windows NT 10.0; Microsoft Outlook 16.0.6326; Pro)",
408 | "ua_class": "E-mail client",
409 | "ua_class_code": "email_client",
410 | "ua": "Outlook 2016 ",
411 | "ua_version": "",
412 | "ua_version_major": "",
413 | "ua_uptodate_current_version": "",
414 | "ua_family": "Outlook 2016",
415 | "ua_family_code": "outlook_2016",
416 | "ua_family_homepage": "https:\/\/en.wikipedia.org\/wiki\/Microsoft_Outlook",
417 | "ua_family_vendor": "Microsoft Corporation.",
418 | "ua_family_vendor_code": "microsoft_corporation",
419 | "ua_family_vendor_homepage": "https:\/\/www.microsoft.com\/about\/",
420 | "ua_family_icon": "outlook2016.png",
421 | "ua_family_icon_big": "",
422 | "ua_family_info_url": "https:\/\/udger.com\/resources\/ua-list\/browser-detail?browser=Outlook 2016",
423 | "ua_engine": "",
424 | "os": "Windows 10",
425 | "os_code": "windows_10",
426 | "os_homepage": "https:\/\/en.wikipedia.org\/wiki\/Windows_10",
427 | "os_icon": "windows10.png",
428 | "os_icon_big": "windows10_big.png",
429 | "os_info_url": "https:\/\/udger.com\/resources\/ua-list\/os-detail?os=Windows 10",
430 | "os_family": "Windows",
431 | "os_family_code": "windows",
432 | "os_family_vendor": "Microsoft Corporation.",
433 | "os_family_vendor_code": "microsoft_corporation",
434 | "os_family_vendor_homepage": "https:\/\/www.microsoft.com\/about\/",
435 | "device_class": "Desktop",
436 | "device_class_code": "desktop",
437 | "device_class_icon": "desktop.png",
438 | "device_class_icon_big": "desktop_big.png",
439 | "device_class_info_url": "https:\/\/udger.com\/resources\/ua-list\/device-detail?device=Desktop",
440 | "device_marketname": "",
441 | "device_brand": "",
442 | "device_brand_code": "",
443 | "device_brand_homepage": "",
444 | "device_brand_icon": "",
445 | "device_brand_icon_big": "",
446 | "device_brand_info_url": "",
447 | "crawler_category": "",
448 | "crawler_category_code": "",
449 | "crawler_respect_robotstxt": ""
450 | }
451 | },
452 | {
453 | "test": {
454 | "teststring": "Mozilla\/5.0 (compatible; Googlebot\/2.1; +http:\/\/www.google.com\/bot.html)"
455 | },
456 | "ret": {
457 | "ua_string": "Mozilla\/5.0 (compatible; Googlebot\/2.1; +http:\/\/www.google.com\/bot.html)",
458 | "ua_class": "Crawler",
459 | "ua_class_code": "crawler",
460 | "ua": "Googlebot\/2.1",
461 | "ua_version": "2.1",
462 | "ua_version_major": "2",
463 | "ua_uptodate_current_version": "",
464 | "ua_family": "Googlebot",
465 | "ua_family_code": "googlebot",
466 | "ua_family_homepage": "http:\/\/www.google.com\/bot.html",
467 | "ua_family_vendor": "Google Inc.",
468 | "ua_family_vendor_code": "google_inc",
469 | "ua_family_vendor_homepage": "https:\/\/www.google.com\/about\/company\/",
470 | "ua_family_icon": "bot_googlebot.png",
471 | "ua_family_icon_big": "",
472 | "ua_family_info_url": "https:\/\/udger.com\/resources\/ua-list\/bot-detail?bot=Googlebot#id31",
473 | "ua_engine": "",
474 | "os": "",
475 | "os_code": "",
476 | "os_homepage": "",
477 | "os_icon": "",
478 | "os_icon_big": "",
479 | "os_info_url": "",
480 | "os_family": "",
481 | "os_family_code": "",
482 | "os_family_vendor": "",
483 | "os_family_vendor_code": "",
484 | "os_family_vendor_homepage": "",
485 | "device_class": "Unrecognized",
486 | "device_class_code": "unrecognized",
487 | "device_class_icon": "other.png",
488 | "device_class_icon_big": "other_big.png",
489 | "device_class_info_url": "https:\/\/udger.com\/resources\/ua-list\/device-detail?device=Unrecognized",
490 | "device_marketname": "",
491 | "device_brand": "",
492 | "device_brand_code": "",
493 | "device_brand_homepage": "",
494 | "device_brand_icon": "",
495 | "device_brand_icon_big": "",
496 | "device_brand_info_url": "",
497 | "crawler_category": "Search engine bot",
498 | "crawler_category_code": "search_engine_bot",
499 | "crawler_respect_robotstxt": "yes"
500 | }
501 | },
502 | {
503 | "test": {
504 | "teststring": "PINGOMETER_BOT_(HTTPS:\/\/PINGOMETER.COM)"
505 | },
506 | "ret": {
507 | "ua_string": "PINGOMETER_BOT_(HTTPS:\/\/PINGOMETER.COM)",
508 | "ua_class": "Crawler",
509 | "ua_class_code": "crawler",
510 | "ua": "PINGOMETER",
511 | "ua_version": "",
512 | "ua_version_major": "",
513 | "ua_uptodate_current_version": "",
514 | "ua_family": "PINGOMETER",
515 | "ua_family_code": "pingometer",
516 | "ua_family_homepage": "",
517 | "ua_family_vendor": "Pingometer, LLC",
518 | "ua_family_vendor_code": "pingometer_llc",
519 | "ua_family_vendor_homepage": "http:\/\/pingometer.com\/",
520 | "ua_family_icon": "bot_pingometer.png",
521 | "ua_family_icon_big": "",
522 | "ua_family_info_url": "https:\/\/udger.com\/resources\/ua-list\/bot-detail?bot=PINGOMETER#id20112",
523 | "ua_engine": "",
524 | "os": "",
525 | "os_code": "",
526 | "os_homepage": "",
527 | "os_icon": "",
528 | "os_icon_big": "",
529 | "os_info_url": "",
530 | "os_family": "",
531 | "os_family_code": "",
532 | "os_family_vendor": "",
533 | "os_family_vendor_code": "",
534 | "os_family_vendor_homepage": "",
535 | "device_class": "Unrecognized",
536 | "device_class_code": "unrecognized",
537 | "device_class_icon": "other.png",
538 | "device_class_icon_big": "other_big.png",
539 | "device_class_info_url": "https:\/\/udger.com\/resources\/ua-list\/device-detail?device=Unrecognized",
540 | "device_marketname": "",
541 | "device_brand": "",
542 | "device_brand_code": "",
543 | "device_brand_homepage": "",
544 | "device_brand_icon": "",
545 | "device_brand_icon_big": "",
546 | "device_brand_info_url": "",
547 | "crawler_category": "Site monitor",
548 | "crawler_category_code": "site_monitor",
549 | "crawler_respect_robotstxt": "no"
550 | }
551 | },
552 | {
553 | "test": {
554 | "teststring": "Monogram\/1.3 CFNetwork\/758.2.8 Darwin\/15.0.0"
555 | },
556 | "ret": {
557 | "ua_string": "Monogram\/1.3 CFNetwork\/758.2.8 Darwin\/15.0.0",
558 | "ua_class": "Unrecognized",
559 | "ua_class_code": "unrecognized",
560 | "ua": "",
561 | "ua_version": "",
562 | "ua_version_major": "",
563 | "ua_uptodate_current_version": "",
564 | "ua_family": "",
565 | "ua_family_code": "",
566 | "ua_family_homepage": "",
567 | "ua_family_vendor": "",
568 | "ua_family_vendor_code": "",
569 | "ua_family_vendor_homepage": "",
570 | "ua_family_icon": "",
571 | "ua_family_icon_big": "",
572 | "ua_family_info_url": "",
573 | "ua_engine": "",
574 | "os": "iOS 9",
575 | "os_code": "ios_9",
576 | "os_homepage": "https:\/\/en.wikipedia.org\/wiki\/IOS_9",
577 | "os_icon": "iphone.png",
578 | "os_icon_big": "iphone_big.png",
579 | "os_info_url": "https:\/\/udger.com\/resources\/ua-list\/os-detail?os=iOS 9",
580 | "os_family": "iOS",
581 | "os_family_code": "ios",
582 | "os_family_vendor": "Apple Inc.",
583 | "os_family_vendor_code": "apple_inc",
584 | "os_family_vendor_homepage": "http:\/\/www.apple.com\/",
585 | "device_class": "",
586 | "device_class_code": "",
587 | "device_class_icon": "",
588 | "device_class_icon_big": "",
589 | "device_class_info_url": "",
590 | "device_marketname": "",
591 | "device_brand": "",
592 | "device_brand_code": "",
593 | "device_brand_homepage": "",
594 | "device_brand_icon": "",
595 | "device_brand_icon_big": "",
596 | "device_brand_info_url": "",
597 | "crawler_category": "",
598 | "crawler_category_code": "",
599 | "crawler_respect_robotstxt": ""
600 | }
601 | },
602 | {
603 | "test": {
604 | "teststring": "lorem ipsum dolor sit amet"
605 | },
606 | "ret": {
607 | "ua_string": "lorem ipsum dolor sit amet",
608 | "ua_class": "Unrecognized",
609 | "ua_class_code": "unrecognized",
610 | "ua": "",
611 | "ua_version": "",
612 | "ua_version_major": "",
613 | "ua_uptodate_current_version": "",
614 | "ua_family": "",
615 | "ua_family_code": "",
616 | "ua_family_homepage": "",
617 | "ua_family_vendor": "",
618 | "ua_family_vendor_code": "",
619 | "ua_family_vendor_homepage": "",
620 | "ua_family_icon": "",
621 | "ua_family_icon_big": "",
622 | "ua_family_info_url": "",
623 | "ua_engine": "",
624 | "os": "",
625 | "os_code": "",
626 | "os_homepage": "",
627 | "os_icon": "",
628 | "os_icon_big": "",
629 | "os_info_url": "",
630 | "os_family": "",
631 | "os_family_code": "",
632 | "os_family_vendor": "",
633 | "os_family_vendor_code": "",
634 | "os_family_vendor_homepage": "",
635 | "device_class": "",
636 | "device_class_code": "",
637 | "device_class_icon": "",
638 | "device_class_icon_big": "",
639 | "device_class_info_url": "",
640 | "device_marketname": "",
641 | "device_brand": "",
642 | "device_brand_code": "",
643 | "device_brand_homepage": "",
644 | "device_brand_icon": "",
645 | "device_brand_icon_big": "",
646 | "device_brand_info_url": "",
647 | "crawler_category": "",
648 | "crawler_category_code": "",
649 | "crawler_respect_robotstxt": ""
650 | }
651 | }
652 | ]
--------------------------------------------------------------------------------
/src/test/resources/udgerdb_test_v3.dat:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/udger/udger-java/c055a6d7f23de6e4e1a478386b0b413e2683b99e/src/test/resources/udgerdb_test_v3.dat
--------------------------------------------------------------------------------
/src/test/resources/udgerdb_test_v3_switch.dat:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/udger/udger-java/c055a6d7f23de6e4e1a478386b0b413e2683b99e/src/test/resources/udgerdb_test_v3_switch.dat
--------------------------------------------------------------------------------