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.language; |
27 | |
|
28 | |
import java.util.ArrayList; |
29 | |
import java.util.Collection; |
30 | |
|
31 | |
import com.mattunderscore.http.headers.HeaderFieldCollectionParser; |
32 | |
import com.mattunderscore.http.headers.HeaderFieldNameVerifier; |
33 | |
import com.mattunderscore.http.headers.UnParsableHeaderException; |
34 | |
|
35 | |
|
36 | |
|
37 | |
|
38 | |
|
39 | |
|
40 | |
|
41 | |
public class LanguageParser implements HeaderFieldCollectionParser<ILanguage>, |
42 | |
HeaderFieldNameVerifier |
43 | |
{ |
44 | |
private static final String HEADER_FIELD_NAME = "Accept-Language"; |
45 | |
|
46 | |
public LanguageParser() |
47 | 70 | { |
48 | 70 | } |
49 | |
|
50 | |
@Override |
51 | |
public boolean isHeaderFieldName(String header) |
52 | |
{ |
53 | 0 | return HEADER_FIELD_NAME.equalsIgnoreCase(header); |
54 | |
} |
55 | |
|
56 | |
@Override |
57 | |
public String getHeaderFieldName() |
58 | |
{ |
59 | 10 | return HEADER_FIELD_NAME; |
60 | |
} |
61 | |
|
62 | |
@Override |
63 | |
public Collection<ILanguage> parseElements(String header) throws UnParsableHeaderException |
64 | |
{ |
65 | 72 | if (header == null) |
66 | |
{ |
67 | 2 | throw new UnParsableHeaderException("Null Pointer."); |
68 | |
} |
69 | 70 | Collection<ILanguage> qL = new ArrayList<ILanguage>(); |
70 | 70 | if ("".equals(header)) |
71 | |
{ |
72 | 2 | return qL; |
73 | |
} |
74 | 68 | String[] types = header.split(",", -1); |
75 | 120 | for (int i = 0; i < types.length; i++) |
76 | |
{ |
77 | 86 | QLanguage lang = parseSingleElement(types[i].trim()); |
78 | 52 | if (lang != null) |
79 | |
{ |
80 | 52 | qL.add(lang); |
81 | |
} |
82 | |
} |
83 | 34 | return qL; |
84 | |
} |
85 | |
|
86 | |
private QLanguage parseSingleElement(String types) throws UnParsableHeaderException |
87 | |
{ |
88 | 86 | if (types == null) |
89 | |
{ |
90 | 0 | throw new UnParsableHeaderException("Null Pointer."); |
91 | |
} |
92 | 86 | if ("".equals(types.trim())) |
93 | |
{ |
94 | 2 | throw new UnParsableHeaderException("Empty string"); |
95 | |
} |
96 | 84 | final String[] langParts = types.trim().split("-"); |
97 | 84 | double qualifier = 1.0; |
98 | 84 | if (langParts.length == 1) |
99 | |
{ |
100 | 38 | String[] lastParts = langParts[0].trim().split(";"); |
101 | 38 | if (lastParts.length == 1) |
102 | |
{ |
103 | 16 | qualifier = 1.0; |
104 | |
} |
105 | 22 | else if (lastParts.length == 2) |
106 | |
{ |
107 | 22 | qualifier = parseQualifier(lastParts[1]); |
108 | |
} |
109 | |
else |
110 | |
{ |
111 | 0 | throw new UnParsableHeaderException("Incorrect number of parts."); |
112 | |
} |
113 | 26 | return new QLanguage(lastParts[0].trim(), "*", qualifier); |
114 | |
} |
115 | 46 | else if (langParts.length == 2) |
116 | |
{ |
117 | 42 | if (langParts[0].contains(";")) |
118 | |
{ |
119 | 2 | throw new UnParsableHeaderException("Semicolon before dash"); |
120 | |
} |
121 | |
else |
122 | |
{ |
123 | 40 | final String[] lastParts = langParts[1].trim().split(";"); |
124 | 40 | if (lastParts.length == 1) |
125 | |
{ |
126 | 10 | qualifier = 1.0; |
127 | |
} |
128 | 30 | else if (lastParts.length == 2) |
129 | |
{ |
130 | 30 | qualifier = parseQualifier(lastParts[1]); |
131 | |
} |
132 | |
else |
133 | |
{ |
134 | 0 | throw new UnParsableHeaderException("Incorrect number of parts."); |
135 | |
} |
136 | 26 | return new QLanguage(langParts[0].trim(), lastParts[0].trim(), qualifier); |
137 | |
} |
138 | |
} |
139 | |
else |
140 | |
{ |
141 | 4 | throw new UnParsableHeaderException("Unparsable language: " + types.trim() + ": " |
142 | |
+ langParts.length); |
143 | |
} |
144 | |
} |
145 | |
|
146 | |
private double parseQualifier(String qualifierString) throws UnParsableHeaderException |
147 | |
{ |
148 | 52 | final String[] qualifierParts = qualifierString.trim().split("="); |
149 | 52 | if (qualifierParts.length == 2) |
150 | |
{ |
151 | 36 | if ("q".equals(qualifierParts[0].trim())) |
152 | |
{ |
153 | |
double qualifier; |
154 | |
try |
155 | |
{ |
156 | 36 | qualifier = Double.parseDouble(qualifierParts[1].trim()); |
157 | |
} |
158 | 4 | catch (NumberFormatException ex) |
159 | |
{ |
160 | 4 | throw new UnParsableHeaderException("Number format excetpion."); |
161 | 32 | } |
162 | 32 | if (qualifier < 0.0 || qualifier > 1.0) |
163 | |
{ |
164 | 6 | throw new UnParsableHeaderException("Invalid qualifier range."); |
165 | |
} |
166 | 26 | return qualifier; |
167 | |
} |
168 | |
else |
169 | |
{ |
170 | 0 | throw new UnParsableHeaderException("Unrecoginsed property"); |
171 | |
} |
172 | |
} |
173 | |
else |
174 | |
{ |
175 | 16 | throw new UnParsableHeaderException("Invalid property"); |
176 | |
} |
177 | |
} |
178 | |
} |