Skip to content

Commit 9fd9e21

Browse files
authored
Merge pull request #3 from blueconic/master_pullreq2
Merge pull request 2
2 parents b1825ba + 71a5a2b commit 9fd9e21

14 files changed

+1546
-78
lines changed

README.md

+18-4
Original file line numberDiff line numberDiff line change
@@ -20,20 +20,19 @@ In short, this is how our algorithm works:
2020

2121
## Notes
2222
* Although this library is very fast, implementing a cache is advisable. Since cache strategies differ per usecase, this library doesn't ship with one out of the box.
23-
* The followings BrowsCap fields are available:
23+
* All BrowsCap fields are available by configuration, but the following fields are loaded by default:
2424
* browser (e.g. Chrome)
2525
* browserType (e.g. Browser or Application)
2626
* browserMajorVersion (e.g. 61 in case of Chrome)
2727
* deviceType (e.g. Mobile Phone, Desktop, Tablet, Console, TV Device)
2828
* platform (e.g. Android, iOS, Win7, Win8, Win10)
2929
* platformVersion (e.g. 4.2, 10 depending on what the platform is)
30-
* The fields are not configurable.
30+
* The fields _are_ configurable by specifying a list of BrowsCapFields in the constructor of the UserAgentParser.
3131
* The CSV file is read in a streaming way, so it's processed line by line. This makes it more memory efficient than loading the whole into memory first.
3232
* 1000+ user agents are tested in the unit tests.
3333

3434
## Future
3535
Possible new features we're thinking of (and are not yet present):
36-
* Make the fields configurable and let Capabilities return a Map containing the given fields
3736
* Auto-update the BrowsCap CSV
3837

3938
## Maven
@@ -43,21 +42,32 @@ Add this to the dependencies in your pom.xml.
4342
<dependency>
4443
<groupId>com.blueconic</groupId>
4544
<artifactId>browscap-java</artifactId>
46-
<version>1.0.4</version>
45+
<version>1.1.0</version>
4746
</dependency>
4847
```
4948

5049
## Usage
5150
```java
51+
import com.blueconic.browscap.BrowsCapField;
5252
import com.blueconic.browscap.Capabilities;
5353
import com.blueconic.browscap.ParseException;
5454
import com.blueconic.browscap.UserAgentParser;
5555
import com.blueconic.browscap.UserAgentService;
5656

5757
// ... class definition
5858

59+
// create a parser with the default fields
5960
final UserAgentParser parser = new UserAgentService().loadParser(); // handle IOException and ParseException
6061

62+
// or create a parser with a custom defined field list
63+
// the list of available fields can be seen inthe BrowsCapField enum
64+
final UserAgentParser parser =
65+
new UserAgentService().loadParser(Arrays.asList(BrowsCapField.BROWSER, BrowsCapField.BROWSER_TYPE,
66+
BrowsCapField.BROWSER_MAJOR_VERSION,
67+
BrowsCapField.DEVICE_TYPE, BrowsCapField.PLATFORM, BrowsCapField.PLATFORM_VERSION,
68+
BrowsCapField.RENDERING_ENGINE_VERSION, BrowsCapField.RENDERING_ENGINE_NAME,
69+
BrowsCapField.PLATFORM_MAKER, BrowsCapField.RENDERING_ENGINE_MAKER));
70+
6171
// It's also possible to supply your own ZIP file by supplying a correct path to a ZIP file in the constructor.
6272
// This can be used when a new BrowsCap version is released which is not yet bundled in this package.
6373
// final UserAgentParser parser = new UserAgentService("E:\\anil\\browscap.zip").loadParser();
@@ -66,13 +76,17 @@ final UserAgentParser parser = new UserAgentService().loadParser(); // handle IO
6676
final String userAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.81 Safari/537.36";
6777
final Capabilities capabilities = parser.parse(userAgent);
6878

79+
// the default fields have getters
6980
final String browser = capabilities.getBrowser();
7081
final String browserType = capabilities.getBrowserType();
7182
final String browserMajorVersion = capabilities.getBrowserMajorVersion();
7283
final String deviceType = capabilities.getDeviceType();
7384
final String platform = capabilities.getPlatform();
7485
final String platformVersion = capabilities.getPlatformVersion();
7586

87+
// the custom defined fields are available through a Map
88+
final String renderingEngineMaker = capabilities.getValues().get(BrowsCapField.RENDERING_ENGINE_MAKER);
89+
7690
// do something with the values
7791

7892
```

pom.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<groupId>com.blueconic</groupId>
55
<artifactId>browscap-java</artifactId>
66
<packaging>jar</packaging>
7-
<version>1.0.4</version>
7+
<version>1.1.0</version>
88
<name>browscap-java</name>
99
<description>A blazingly fast and memory efficient Java client on top of the BrowsCap CSV source files.</description>
1010

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
package com.blueconic.browscap;
2+
3+
public enum BrowsCapField {
4+
IS_MASTER_PARENT("is_master_parent"),
5+
IS_LITE_MODE("is_lite_mode"),
6+
PARENT("parent"),
7+
COMMENT("comment"),
8+
BROWSER("browser"),
9+
BROWSER_TYPE("browser_type"),
10+
BROWSER_BITS("browser_bits"),
11+
BROWSER_MAKER("browser_maker"),
12+
BROWSER_MODUS("browser_modus"),
13+
BROWSER_VERSION("browser_version"),
14+
BROWSER_MAJOR_VERSION("browser_major_version"),
15+
BROWSER_MINOR_VERSION("browser_minor_version"),
16+
PLATFORM("platform"),
17+
PLATFORM_VERSION("platform_version"),
18+
PLATFORM_DESCRIPTION("platform_description"),
19+
PLATFORM_BITS("platform_bits"),
20+
PLATFORM_MAKER("platform_maker"),
21+
IS_ALPHA("is_alpha"),
22+
IS_BETA("is_beta"),
23+
IS_WIN16("is_win16"),
24+
IS_WIN32("is_win32"),
25+
IS_WIN64("is_win64"),
26+
IS_IFRAMES("is_iframes"),
27+
IS_FRAMES("is_frames"),
28+
IS_TABLES("is_tables"),
29+
IS_COOKIES("is_cookies"),
30+
IS_BACKGROUND_SOUNDS("is_background_sounds"),
31+
IS_JAVASCRIPT("is_javascript"),
32+
IS_VBSCRIPT("is_vbscript"),
33+
IS_JAVA_APPLETS("is_java_applets"),
34+
IS_ACTIVEX_CONTROLS("is_activex_controls"),
35+
IS_MOBILE_DEVICES("is_mobile_device"),
36+
IS_TABLET("is_tablet"),
37+
IS_SYNDICATION_READER("is_syndication_reader"),
38+
IS_CRAWLER("is_crawler"),
39+
IS_FAKE("is_fake"),
40+
IS_ANONYMIZED("is_anonymized"),
41+
IS_MODIFIED("is_modified"),
42+
CSS_VERSION("css_version"),
43+
AOL_VERSION("aol_version"),
44+
DEVICE_NAME("device_name"),
45+
DEVICE_MAKER("device_maker"),
46+
DEVICE_TYPE("device_type"),
47+
DEVICE_POINTING_METHOD("device_pointing_method"),
48+
DEVICE_CODE_NAME("device_code_name"),
49+
DEVICE_BRAND_NAME("device_brand_name"),
50+
RENDERING_ENGINE_NAME("rendering_engine_name"),
51+
RENDERING_ENGINE_VERSION("rendering_engine_version"),
52+
RENDERING_ENGINE_DESCRIPTION("rendering_engine_description"),
53+
RENDERING_ENGINE_MAKER("rendering_engine_maker");
54+
55+
private final String myField;
56+
57+
/**
58+
* @param the browscap field identifier
59+
*/
60+
private BrowsCapField(final String fieldIdentifier) {
61+
this.myField = fieldIdentifier;
62+
}
63+
64+
/*
65+
* (non-Javadoc)
66+
* @see java.lang.Enum#toString()
67+
*/
68+
@Override
69+
public String toString() {
70+
return myField;
71+
}
72+
}

src/main/java/com/blueconic/browscap/Capabilities.java

+8
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package com.blueconic.browscap;
22

3+
import java.util.Map;
4+
35
public interface Capabilities {
46
String UNKNOWN_BROWSCAP_VALUE = "Unknown";
57

@@ -39,4 +41,10 @@ public interface Capabilities {
3941
*/
4042
String getDeviceType();
4143

44+
/**
45+
* Returns the Map of values with the fields passed to the parser while loading
46+
* @return the map of values
47+
*/
48+
Map<BrowsCapField, String> getValues();
49+
4250
}

src/main/java/com/blueconic/browscap/UserAgentService.java

+21-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
import java.io.IOException;
88
import java.io.InputStream;
99
import java.io.InputStreamReader;
10+
import java.util.Arrays;
11+
import java.util.List;
1012
import java.util.zip.ZipEntry;
1113
import java.util.zip.ZipInputStream;
1214

@@ -16,6 +18,10 @@
1618
* Service that manages the creation of user agent parsers. In the feature, this might be expanded so it also supports
1719
*/
1820
public class UserAgentService {
21+
public static final List<BrowsCapField> DEFAULT_FIELDS =
22+
Arrays.asList(BrowsCapField.BROWSER, BrowsCapField.BROWSER_TYPE, BrowsCapField.BROWSER_MAJOR_VERSION,
23+
BrowsCapField.DEVICE_TYPE, BrowsCapField.PLATFORM, BrowsCapField.PLATFORM_VERSION);
24+
1925
// The version of the browscap file this bundle depends on
2026
public static final int BUNDLED_BROWSCAP_VERSION = 6026;
2127
private String myZipFilePath;
@@ -38,6 +44,20 @@ public UserAgentService(final String zipFilePath) {
3844
* @return the user agent parser
3945
*/
4046
public UserAgentParser loadParser() throws IOException, ParseException {
47+
return createParserWithFields(DEFAULT_FIELDS);
48+
}
49+
50+
/**
51+
* Returns a parser based on the bundled BrowsCap version
52+
* @param fields list
53+
* @return the user agent parser
54+
*/
55+
public UserAgentParser loadParser(final List<BrowsCapField> fields) throws IOException, ParseException {
56+
return createParserWithFields(fields);
57+
}
58+
59+
private UserAgentParser createParserWithFields(final List<BrowsCapField> fields)
60+
throws IOException, ParseException, FileNotFoundException {
4161
// http://browscap.org/version-number
4262
try (final InputStream zipStream = getCsvFileStream();
4363
final ZipInputStream zipIn = new ZipInputStream(zipStream)) {
@@ -46,7 +66,7 @@ public UserAgentParser loadParser() throws IOException, ParseException {
4666
// look for the first file that isn't a directory
4767
// that should be a BrowsCap .csv file
4868
if (!entry.isDirectory()) {
49-
return new UserAgentFileParser().parse(new InputStreamReader(zipIn, UTF_8));
69+
return new UserAgentFileParser().parse(new InputStreamReader(zipIn, UTF_8), fields);
5070
} else {
5171
throw new IOException(
5272
"Unable to find the BrowsCap CSV file in the ZIP file");
Original file line numberDiff line numberDiff line change
@@ -1,84 +1,89 @@
11
package com.blueconic.browscap.impl;
22

3+
import java.util.Collections;
4+
import java.util.HashMap;
5+
import java.util.Map;
6+
7+
import com.blueconic.browscap.BrowsCapField;
38
import com.blueconic.browscap.Capabilities;
49

510
class CapabilitiesImpl implements Capabilities {
6-
public final static Capabilities DEFAULT = new CapabilitiesImpl("Default Browser", "Default Browser",
7-
UNKNOWN_BROWSCAP_VALUE,
8-
UNKNOWN_BROWSCAP_VALUE,
9-
UNKNOWN_BROWSCAP_VALUE,
10-
UNKNOWN_BROWSCAP_VALUE);
11+
public final static Capabilities DEFAULT = new CapabilitiesImpl(Collections.emptyMap());
1112

12-
private final String myBrowser;
13-
private final String myBrowserType;
14-
private final String myBrowserMajorVersion;
15-
private final String myDeviceType;
16-
private final String myPlatform;
17-
private final String myPlatformVersion;
13+
private final Map<BrowsCapField, String> myValues = new HashMap<>();
1814

19-
public CapabilitiesImpl(final String browser, final String browserType, final String browserMajorVersion,
20-
final String deviceType, final String platform, final String platformVersion) {
15+
public CapabilitiesImpl(
16+
final Map<BrowsCapField, String> values) {
17+
// default values first, for backwards compatibility
18+
myValues.put(BrowsCapField.BROWSER, "Default Browser");
19+
myValues.put(BrowsCapField.BROWSER_TYPE, "Default Browser");
20+
myValues.put(BrowsCapField.BROWSER_MAJOR_VERSION, UNKNOWN_BROWSCAP_VALUE);
21+
myValues.put(BrowsCapField.DEVICE_TYPE, UNKNOWN_BROWSCAP_VALUE);
22+
myValues.put(BrowsCapField.PLATFORM, UNKNOWN_BROWSCAP_VALUE);
23+
myValues.put(BrowsCapField.PLATFORM_VERSION, UNKNOWN_BROWSCAP_VALUE);
2124

22-
myBrowser = browser;
23-
myBrowserType = browserType;
24-
myBrowserMajorVersion = browserMajorVersion;
25-
myDeviceType = deviceType;
26-
myPlatform = platform;
27-
myPlatformVersion = platformVersion;
25+
myValues.putAll(values);
2826
}
2927

3028
/**
3129
* {@inheritDoc}
3230
*/
3331
@Override
3432
public String getBrowser() {
35-
return myBrowser;
33+
return myValues.get(BrowsCapField.BROWSER);
3634
}
3735

3836
/**
3937
* {@inheritDoc}
4038
*/
4139
@Override
4240
public String getBrowserType() {
43-
return myBrowserType;
41+
return myValues.get(BrowsCapField.BROWSER_TYPE);
4442
}
4543

4644
/**
4745
* {@inheritDoc}
4846
*/
4947
@Override
5048
public String getBrowserMajorVersion() {
51-
return myBrowserMajorVersion;
49+
return myValues.get(BrowsCapField.BROWSER_MAJOR_VERSION);
5250
}
5351

5452
/**
5553
* {@inheritDoc}
5654
*/
5755
@Override
5856
public String getPlatform() {
59-
return myPlatform;
57+
return myValues.get(BrowsCapField.PLATFORM);
6058
}
6159

6260
/**
6361
* {@inheritDoc}
6462
*/
6563
@Override
6664
public String getPlatformVersion() {
67-
return myPlatformVersion;
65+
return myValues.get(BrowsCapField.PLATFORM_VERSION);
6866
}
6967

7068
/**
7169
* {@inheritDoc}
7270
*/
7371
@Override
7472
public String getDeviceType() {
75-
return myDeviceType;
73+
return myValues.get(BrowsCapField.DEVICE_TYPE);
74+
}
75+
76+
/**
77+
* {@inheritDoc}
78+
*/
79+
@Override
80+
public Map<BrowsCapField, String> getValues() {
81+
return myValues;
7682
}
7783

7884
@Override
7985
public String toString() {
80-
return "Capabilities{browser='" + myBrowser + "', browserType='" + myBrowserType + "', browserMajorVersion='"
81-
+ myBrowserMajorVersion + "', deviceType='" + myDeviceType + "', platform='" + myPlatform
82-
+ "', platformVersion='" + myPlatformVersion + '}';
86+
return "CapabilitiesImpl [myValues=" + myValues + "]";
8387
}
88+
8489
}

0 commit comments

Comments
 (0)