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 | |
package com.mattunderscore.http.headers.useragent.parser; |
27 | |
|
28 | |
import static com.mattunderscore.http.headers.useragent.parser.ParsingUtils.nextElement; |
29 | |
import static com.mattunderscore.http.headers.useragent.parser.ParsingUtils.nextElementStart; |
30 | |
|
31 | |
import com.mattunderscore.http.headers.useragent.details.application.Chrome; |
32 | |
import com.mattunderscore.http.headers.useragent.details.application.Chromium; |
33 | |
import com.mattunderscore.http.headers.useragent.details.application.Epiphany; |
34 | |
import com.mattunderscore.http.headers.useragent.details.application.Firefox; |
35 | |
import com.mattunderscore.http.headers.useragent.details.application.Iceweasel; |
36 | |
import com.mattunderscore.http.headers.useragent.details.application.LikeFirefox; |
37 | |
import com.mattunderscore.http.headers.useragent.details.application.Opera; |
38 | |
import com.mattunderscore.http.headers.useragent.details.application.Safari; |
39 | |
import com.mattunderscore.http.headers.useragent.details.application.SafariBased; |
40 | |
import com.mattunderscore.http.headers.useragent.details.platform.BlackBerryOS; |
41 | |
import com.mattunderscore.http.headers.useragent.details.platform.Gecko; |
42 | |
import com.mattunderscore.http.headers.useragent.details.platform.LayoutEngine; |
43 | |
import com.mattunderscore.http.headers.useragent.details.platform.LikeGecko; |
44 | |
import com.mattunderscore.http.headers.useragent.details.platform.Presto; |
45 | |
|
46 | |
|
47 | |
|
48 | |
|
49 | |
|
50 | |
|
51 | |
class DesktopBrowserParser implements TokensParser |
52 | |
{ |
53 | 6 | private final AdditionalOSParser osParser = new AdditionalOSParser(); |
54 | |
|
55 | |
DesktopBrowserParser() |
56 | 6 | { |
57 | 6 | } |
58 | |
|
59 | |
|
60 | |
|
61 | |
|
62 | |
|
63 | |
@Override |
64 | |
public void parseTokens(final ParsingState state) |
65 | |
{ |
66 | 46 | String remainingHeader = state.getRemaining(); |
67 | 212 | while (!"".equals(remainingHeader)) |
68 | |
{ |
69 | 170 | String oldHeader = remainingHeader; |
70 | 170 | if (remainingHeader.startsWith("AppleWebKit")) |
71 | |
{ |
72 | 12 | String version = nextElement(remainingHeader.substring(12)); |
73 | 12 | state.addDetail(new LayoutEngine("AppleWebKit",version)); |
74 | 12 | remainingHeader = remainingHeader.substring(12 + version.length()); |
75 | 12 | } |
76 | 158 | else if (remainingHeader.startsWith("KHTML")) |
77 | |
{ |
78 | 12 | if ("/".equals(remainingHeader.substring(5,6))) |
79 | |
{ |
80 | 0 | String version = nextElement(remainingHeader.substring(6)); |
81 | 0 | state.addDetail(new LayoutEngine("KHTML",version)); |
82 | 0 | remainingHeader = remainingHeader.substring(6 + version.length()); |
83 | 0 | } |
84 | |
else |
85 | |
{ |
86 | 12 | state.addDetail(new LayoutEngine("KHTML","like")); |
87 | 12 | remainingHeader = remainingHeader.substring(6); |
88 | |
} |
89 | |
} |
90 | 146 | else if (remainingHeader.startsWith("like")) |
91 | |
{ |
92 | 16 | remainingHeader = remainingHeader.substring(5); |
93 | 16 | if (remainingHeader.startsWith("Gecko")) |
94 | |
{ |
95 | 12 | state.addDetail(new LikeGecko()); |
96 | 12 | remainingHeader = remainingHeader.substring(5); |
97 | |
} |
98 | 4 | else if (remainingHeader.startsWith("Firefox")) |
99 | |
{ |
100 | 4 | String version = nextElement(remainingHeader.substring(8)); |
101 | 4 | state.addDetail(new LikeFirefox(version)); |
102 | 4 | remainingHeader = remainingHeader.substring(8 + version.length()); |
103 | 4 | } |
104 | |
} |
105 | 130 | else if (remainingHeader.startsWith("Gecko")) |
106 | |
{ |
107 | 8 | String trail = nextElement(remainingHeader.substring(6)); |
108 | 8 | String rv = state.getValue("rv"); |
109 | 8 | if (rv != null) |
110 | |
{ |
111 | 8 | state.addDetail(new Gecko(rv,trail)); |
112 | 8 | remainingHeader = remainingHeader.substring(6 + trail.length()); |
113 | |
} |
114 | |
else |
115 | |
{ |
116 | 0 | state.addDetail(new Gecko()); |
117 | 0 | remainingHeader = remainingHeader.substring(6); |
118 | |
} |
119 | 8 | } |
120 | 122 | else if (remainingHeader.startsWith("Presto")) |
121 | |
{ |
122 | 6 | String version = nextElement(remainingHeader.substring(7)); |
123 | 6 | state.addDetail(new Presto(version)); |
124 | 6 | remainingHeader = remainingHeader.substring(7 + version.length()); |
125 | 6 | } |
126 | 116 | else if (remainingHeader.startsWith("Chrome")) |
127 | |
{ |
128 | 6 | String version = nextElement(remainingHeader.substring(7)); |
129 | 6 | state.addDetail(new Chrome(version)); |
130 | 6 | remainingHeader = remainingHeader.substring(7 + version.length()); |
131 | 6 | if (remainingHeader.startsWith(" Safari")) |
132 | |
{ |
133 | 6 | String buildNumber = nextElement(remainingHeader.substring(8)); |
134 | 6 | state.addDetail(new SafariBased(buildNumber)); |
135 | 6 | remainingHeader = remainingHeader.substring(8 + buildNumber.length()); |
136 | |
} |
137 | 6 | } |
138 | 110 | else if (remainingHeader.startsWith("Chromium")) |
139 | |
{ |
140 | 0 | String version = nextElement(remainingHeader.substring(9)); |
141 | 0 | state.addDetail(new Chromium(version)); |
142 | 0 | remainingHeader = remainingHeader.substring(9 + version.length()); |
143 | 0 | } |
144 | 110 | else if (remainingHeader.startsWith("Iceweasel")) |
145 | |
{ |
146 | 4 | String version = nextElement(remainingHeader.substring(10)); |
147 | 4 | state.addDetail(new Iceweasel(version)); |
148 | 4 | remainingHeader = remainingHeader.substring(10 + version.length()); |
149 | 4 | } |
150 | 106 | else if (remainingHeader.startsWith("Epiphany")) |
151 | |
{ |
152 | 4 | String version = nextElement(remainingHeader.substring(9)); |
153 | 4 | state.addDetail(new Epiphany(version)); |
154 | 4 | remainingHeader = remainingHeader.substring(9 + version.length()); |
155 | 4 | } |
156 | 102 | else if (remainingHeader.startsWith("Opera")) |
157 | |
{ |
158 | 0 | String version = nextElement(remainingHeader.substring(6)); |
159 | 0 | if (!"9.80".equals(version)) |
160 | |
{ |
161 | 0 | state.addDetail(new Opera(version)); |
162 | 0 | remainingHeader = remainingHeader.substring(6 + version.length()); |
163 | 0 | state.setOperaSet(true); |
164 | |
} |
165 | |
else |
166 | |
{ |
167 | 0 | state.setOperaClaim(version); |
168 | 0 | remainingHeader = remainingHeader.substring(6 + version.length()); |
169 | |
} |
170 | 0 | } |
171 | 102 | else if (remainingHeader.startsWith("Firefox")) |
172 | |
{ |
173 | 4 | String version = nextElement(remainingHeader.substring(8)); |
174 | 4 | state.addDetail(new Firefox(version)); |
175 | 4 | remainingHeader = remainingHeader.substring(8 + version.length()); |
176 | 4 | } |
177 | 98 | else if (remainingHeader.startsWith("Safari")) |
178 | |
{ |
179 | 2 | if (state.isBlackBerry()) |
180 | |
{ |
181 | 2 | String buildNumber = nextElement(remainingHeader.substring(7)); |
182 | 2 | state.addDetail(new SafariBased(buildNumber)); |
183 | 2 | remainingHeader = remainingHeader.substring(7 + buildNumber.length()); |
184 | 2 | } |
185 | |
else |
186 | |
{ |
187 | 0 | String version = state.getValue("Version"); |
188 | 0 | String buildNumber = nextElement(remainingHeader.substring(7)); |
189 | 0 | if (version != null) |
190 | |
{ |
191 | 0 | state.addDetail(new Safari(version,buildNumber)); |
192 | |
} |
193 | |
else |
194 | |
{ |
195 | 0 | state.addDetail(new SafariBased(buildNumber)); |
196 | |
} |
197 | 0 | remainingHeader = remainingHeader.substring(7 + buildNumber.length()); |
198 | 0 | } |
199 | |
} |
200 | 96 | else if (remainingHeader.startsWith("Version")) |
201 | |
{ |
202 | 8 | String version = nextElement(remainingHeader.substring(8)); |
203 | 8 | if (state.getOperaClaim() != null) |
204 | |
{ |
205 | 2 | state.addDetail(new Opera(version,state.getOperaClaim())); |
206 | 2 | remainingHeader = remainingHeader.substring(8 + version.length()); |
207 | 2 | state.setOperaSet(true); |
208 | |
} |
209 | 6 | else if (state.isBlackBerry()) |
210 | |
{ |
211 | 2 | state.addDetail(new BlackBerryOS(version)); |
212 | 2 | remainingHeader = remainingHeader.substring(8 + version.length()); |
213 | |
} |
214 | |
else |
215 | |
{ |
216 | 4 | state.addKeyValuePair("Version", version); |
217 | 4 | remainingHeader = remainingHeader.substring(8 + version.length()); |
218 | |
} |
219 | 8 | } |
220 | |
else |
221 | |
{ |
222 | |
|
223 | 88 | state.setRemaining(remainingHeader); |
224 | 88 | osParser.parseToken(state); |
225 | 88 | remainingHeader = state.getRemaining(); |
226 | |
} |
227 | |
|
228 | |
|
229 | 170 | if (oldHeader.equals(remainingHeader)) |
230 | |
{ |
231 | 88 | int nextElement = nextElementStart(remainingHeader); |
232 | 88 | if (nextElement == 0) |
233 | |
{ |
234 | 78 | remainingHeader = remainingHeader.substring(1); |
235 | |
} |
236 | 10 | else if (nextElement != -1) |
237 | |
{ |
238 | 6 | remainingHeader = remainingHeader.substring(nextElement); |
239 | |
} |
240 | |
else |
241 | |
{ |
242 | 4 | return; |
243 | |
} |
244 | |
} |
245 | 166 | remainingHeader = remainingHeader.trim(); |
246 | 166 | } |
247 | 42 | state.setRemaining(remainingHeader); |
248 | 42 | return; |
249 | |
} |
250 | |
} |