shikeying
2024-01-11 3b67e947e36133e2a40eb2737b15ea375e157ea0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
package com.walker.web.agent;
 
import com.walker.web.agent.impl.UserAgentFileParser;
 
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Collection;
import java.util.Set;
import java.util.stream.Stream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
 
import static java.nio.charset.StandardCharsets.UTF_8;
import static java.util.stream.Collectors.toSet;
 
public class UserAgentService {
 
    // The version of the browscap file this bundle depends on
    public static final int BUNDLED_BROWSCAP_VERSION = 6001002;
    private String myZipFilePath;
    private InputStream myZipFileStream;
 
    public UserAgentService() {
        // Default
    }
 
    /**
     * Creates a user agent service based on the Browscap CSV file in the given ZIP file
     * @param zipFilePath the zip file should contain the csv file. It will load the given zip file instead of the
     *            bundled one
     */
    public UserAgentService(final String zipFilePath) {
        myZipFilePath = zipFilePath;
    }
 
    /**
     * Creates a user agent service based on the Browscap CSV file in the given ZIP InputStream
     * @param zipFileStream the zip InputStream should contain the csv file. It will load the given zip InputStream
     *            instead of the bundled zip file
     */
    public UserAgentService(final InputStream zipFileStream) {
        myZipFileStream = zipFileStream;
    }
 
    /**
     * Returns a parser based on the bundled BrowsCap version
     * @return the user agent parser
     */
    public UserAgentParser loadParser() throws IOException, ParseException {
 
        // Use all default fields
        final Set<BrowsCapField> defaultFields =
                Stream.of(BrowsCapField.values()).filter(BrowsCapField::isDefault).collect(toSet());
 
        return createParserWithFields(defaultFields);
    }
 
    /**
     * Returns a parser based on the bundled BrowsCap version
     * @param fields list
     * @return the user agent parser
     */
    public UserAgentParser loadParser(final Collection<BrowsCapField> fields) throws IOException, ParseException {
        return createParserWithFields(fields);
    }
 
    private UserAgentParser createParserWithFields(final Collection<BrowsCapField> fields)
            throws IOException, ParseException {
        // http://browscap.org/version-number
        try (final InputStream zipStream = getCsvFileStream();
             final ZipInputStream zipIn = new ZipInputStream(zipStream)) {
            // look for the first file that isn't a directory and a .csv
            // that should be a BrowsCap .csv file
            ZipEntry entry = null;
            do {
                entry = zipIn.getNextEntry();
            } while (!(entry == null || entry.getName().endsWith(".csv")));
            if (!(entry == null || entry.isDirectory())) {
                return UserAgentFileParser.parse(new InputStreamReader(zipIn, UTF_8), fields);
            } else {
                throw new IOException(
                        "Unable to find the BrowsCap CSV file in the ZIP file");
            }
        }
    }
 
    /**
     * Returns the bundled ZIP file name
     * @return CSV file name
     */
    public static String getBundledCsvFileName() {
        return "browscap-" + BUNDLED_BROWSCAP_VERSION + ".zip";
    }
 
    /**
     * Returns the InputStream to the CSV file. This is either the bundled ZIP file or the one passed in the
     * constructor.
     * @return
     * @throws FileNotFoundException
     */
    private InputStream getCsvFileStream() throws FileNotFoundException {
        if (myZipFileStream == null) {
            if (myZipFilePath == null) {
                final String csvFileName = getBundledCsvFileName();
                return getClass().getClassLoader().getResourceAsStream(csvFileName);
            } else {
                return new FileInputStream(myZipFilePath);
            }
        } else {
            return myZipFileStream;
        }
    }
}