-
Notifications
You must be signed in to change notification settings - Fork 37
/
Rule.java
192 lines (163 loc) · 5.19 KB
/
Rule.java
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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
package com.blueconic.browscap.impl;
import com.blueconic.browscap.Capabilities;
/**
* Instances of this class represent a line of the browscap data. This class is responsible for checking a potential
* match and for supplying the corresponding browser properties.
*/
class Rule {
// The properties of the matching pattern
private final Literal myPrefix;
private final Literal[] mySuffixes;
private final Literal myPostfix;
// The size of the pattern
private final int mySize;
// The browser properties
private final Capabilities myCapabilities;
/**
* Creates a new rule.
* @param prefix The prefix of the matching pattern, potentially <code>null</code>
* @param suffixes The required substrings separated by wildcards, potentially <code>null</code> to indicate no
* wildcards
* @param postfix The postfix of the matching pattern, potentially <code>null</code>
* @param pattern The original string representation of the matching pattern
* @param capabilities The browser properties for this rule
*/
Rule(final Literal prefix, final Literal[] suffixes, final Literal postfix, final String pattern,
final Capabilities capabilities) {
myPrefix = prefix;
mySuffixes = suffixes;
myPostfix = postfix;
myCapabilities = capabilities;
mySize = pattern.length();
}
/**
* Return the prefix.
* @return the prefix, possibly <code>null</code>
*/
Literal getPrefix() {
return myPrefix;
}
/**
* The required substrings separated by wildcards, potentially <code>null</code> to indicate no wildcards
* @return The required substrings.
*/
Literal[] getSuffixes() {
return mySuffixes;
}
/**
* Return the postfix.
* @return the postfix, possibly <code>null</code>
*/
Literal getPostfix() {
return myPostfix;
}
/**
* Tests whether this rule needs a specific string in the useragent to match.
* @return <code>true</code> if this rule can't match without the specific substring, false otherwise.
*/
boolean requires(final String value) {
if (requires(myPrefix, value) || requires(myPostfix, value)) {
return true;
}
if (mySuffixes == null) {
return false;
}
for (final Literal suffix : mySuffixes) {
if (requires(suffix, value)) {
return true;
}
}
return false;
}
private static boolean requires(final Literal literal, final String value) {
return literal != null && literal.requires(value);
}
Capabilities getCapabilities() {
return myCapabilities;
}
int getSize() {
return mySize;
}
final boolean matches(final SearchableString value) {
// Inclusive
final int start;
if (myPrefix == null) {
start = 0;
} else if (value.startsWith(myPrefix)) {
start = myPrefix.getLength();
} else {
return false;
}
// Inclusive
final int end;
if (myPostfix == null) {
end = value.getSize() - 1;
} else if (value.endsWith(myPostfix)) {
end = value.getSize() - 1 - myPostfix.getLength();
} else {
return false;
}
return checkWildCards(value, mySuffixes, start, end);
}
// Static for inline (2x)
static boolean checkWildCards(final SearchableString value, final Literal[] suffixes, final int start,
final int end) {
if (suffixes == null) {
// No wildcards
return start == end + 1;
}
// One wildcard
if (suffixes.length == 0) {
return start <= end + 1;
}
int from = start;
for (final Literal suffix : suffixes) {
final int match = checkWildCard(value, suffix, from);
if (match == -1) {
return false;
}
from = suffix.getLength() + match;
if (from > end + 1) {
return false;
}
}
return true;
}
// Return found index or -1
private static int checkWildCard(final SearchableString value, final Literal suffix, final int start) {
for (final int index : value.getIndices(suffix)) {
if (index >= start) {
return index;
}
}
return -1;
}
/**
* Returns the reconstructed original pattern.
* @return the reconstructed original pattern
*/
String getPattern() {
final StringBuilder result = new StringBuilder();
if (myPrefix != null) {
result.append(myPrefix);
}
if (mySuffixes != null) {
result.append("*");
for (final Literal sub : mySuffixes) {
result.append(sub);
result.append("*");
}
}
if (myPostfix != null) {
result.append(myPostfix);
}
return result.toString();
}
/**
* {@inheritDoc}
*/
@Override
public String toString() {
return getPattern() + " : " + myCapabilities;
}
}