8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package com.sun.webkit.network;
27
28 import java.text.ParseException;
29 import java.util.Calendar;
30 import java.util.Collections;
31 import java.util.Date;
32 import java.util.HashMap;
33 import java.util.Locale;
34 import java.util.Map;
35 import java.util.TimeZone;
36 import java.util.logging.Level;
37 import java.util.logging.Logger;
38 import java.util.regex.Matcher;
39 import java.util.regex.Pattern;
40
41 /**
42 * An RFC 6265-compliant date parser.
43 */
44 final class DateParser {
45
46 private static final Logger logger =
47 Logger.getLogger(DateParser.class.getName());
48
49 private static final Pattern DELIMITER_PATTERN = Pattern.compile(
50 "[\\x09\\x20-\\x2F\\x3B-\\x40\\x5B-\\x60\\x7B-\\x7E]+");
51 private static final Pattern TIME_PATTERN = Pattern.compile(
52 "(\\d{1,2}):(\\d{1,2}):(\\d{1,2})(?:[^\\d].*)*");
53 private static final Pattern DAY_OF_MONTH_PATTERN = Pattern.compile(
54 "(\\d{1,2})(?:[^\\d].*)*");
55 private static final Pattern YEAR_PATTERN = Pattern.compile(
56 "(\\d{2,4})(?:[^\\d].*)*");
57 private static final Map<String,Integer> MONTH_MAP;
58 static {
59 Map<String,Integer> map = new HashMap<String,Integer>(12);
60 map.put("jan", 0);
61 map.put("feb", 1);
62 map.put("mar", 2);
63 map.put("apr", 3);
64 map.put("may", 4);
65 map.put("jun", 5);
66 map.put("jul", 6);
67 map.put("aug", 7);
72 MONTH_MAP = Collections.unmodifiableMap(map);
73 }
74
75
76 /**
77 * The private default constructor. Ensures non-instantiability.
78 */
79 private DateParser() {
80 throw new AssertionError();
81 }
82
83
84 /**
85 * Parses a given date string as required by RFC 6265.
86 * @param date the string to parse
87 * @return the difference, measured in milliseconds, between the parsed
88 * date and midnight, January 1, 1970 UTC
89 * @throws ParseException if {@code date} cannot be parsed
90 */
91 static long parse(String date) throws ParseException {
92 logger.log(Level.FINEST, "date: [{0}]", date);
93
94 Time time = null;
95 Integer dayOfMonth = null;
96 Integer month = null;
97 Integer year = null;
98 String[] tokens = DELIMITER_PATTERN.split(date, 0);
99 for (String token : tokens) {
100 if (token.length() == 0) {
101 continue;
102 }
103
104 Time timeTmp;
105 if (time == null && (timeTmp = parseTime(token)) != null) {
106 time = timeTmp;
107 continue;
108 }
109
110 Integer dayOfMonthTmp;
111 if (dayOfMonth == null
112 && (dayOfMonthTmp = parseDayOfMonth(token)) != null)
139 if (time == null || dayOfMonth == null || month == null || year == null
140 || dayOfMonth < 1 || dayOfMonth > 31
141 || year < 1601
142 || time.hour > 23
143 || time.minute > 59
144 || time.second > 59)
145 {
146 throw new ParseException("Error parsing date", 0);
147 }
148
149 Calendar calendar = Calendar.getInstance(
150 TimeZone.getTimeZone("UTC"), Locale.US);
151 calendar.setLenient(false);
152 calendar.clear();
153 calendar.set(year, month, dayOfMonth,
154 time.hour, time.minute, time.second);
155
156 try {
157 long result = calendar.getTimeInMillis();
158 if (logger.isLoggable(Level.FINEST)) {
159 logger.log(Level.FINEST, "result: [{0}]",
160 new Date(result).toString());
161 }
162 return result;
163 } catch (Exception ex) {
164 ParseException pe = new ParseException("Error parsing date", 0);
165 pe.initCause(ex);
166 throw pe;
167 }
168 }
169
170 /**
171 * Parses a token as a time string.
172 */
173 private static Time parseTime(String token) {
174 Matcher matcher = TIME_PATTERN.matcher(token);
175 if (matcher.matches()) {
176 return new Time(
177 Integer.parseInt(matcher.group(1)),
178 Integer.parseInt(matcher.group(2)),
179 Integer.parseInt(matcher.group(3)));
180 } else {
|
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package com.sun.webkit.network;
27
28 import com.sun.javafx.logging.PlatformLogger;
29 import com.sun.javafx.logging.PlatformLogger.Level;
30
31 import java.text.ParseException;
32 import java.util.Calendar;
33 import java.util.Collections;
34 import java.util.Date;
35 import java.util.HashMap;
36 import java.util.Locale;
37 import java.util.Map;
38 import java.util.TimeZone;
39 import java.util.regex.Matcher;
40 import java.util.regex.Pattern;
41
42 /**
43 * An RFC 6265-compliant date parser.
44 */
45 final class DateParser {
46
47 private static final PlatformLogger logger =
48 PlatformLogger.getLogger(DateParser.class.getName());
49
50 private static final Pattern DELIMITER_PATTERN = Pattern.compile(
51 "[\\x09\\x20-\\x2F\\x3B-\\x40\\x5B-\\x60\\x7B-\\x7E]+");
52 private static final Pattern TIME_PATTERN = Pattern.compile(
53 "(\\d{1,2}):(\\d{1,2}):(\\d{1,2})(?:[^\\d].*)*");
54 private static final Pattern DAY_OF_MONTH_PATTERN = Pattern.compile(
55 "(\\d{1,2})(?:[^\\d].*)*");
56 private static final Pattern YEAR_PATTERN = Pattern.compile(
57 "(\\d{2,4})(?:[^\\d].*)*");
58 private static final Map<String,Integer> MONTH_MAP;
59 static {
60 Map<String,Integer> map = new HashMap<String,Integer>(12);
61 map.put("jan", 0);
62 map.put("feb", 1);
63 map.put("mar", 2);
64 map.put("apr", 3);
65 map.put("may", 4);
66 map.put("jun", 5);
67 map.put("jul", 6);
68 map.put("aug", 7);
73 MONTH_MAP = Collections.unmodifiableMap(map);
74 }
75
76
77 /**
78 * The private default constructor. Ensures non-instantiability.
79 */
80 private DateParser() {
81 throw new AssertionError();
82 }
83
84
85 /**
86 * Parses a given date string as required by RFC 6265.
87 * @param date the string to parse
88 * @return the difference, measured in milliseconds, between the parsed
89 * date and midnight, January 1, 1970 UTC
90 * @throws ParseException if {@code date} cannot be parsed
91 */
92 static long parse(String date) throws ParseException {
93 logger.finest("date: [{0}]", date);
94
95 Time time = null;
96 Integer dayOfMonth = null;
97 Integer month = null;
98 Integer year = null;
99 String[] tokens = DELIMITER_PATTERN.split(date, 0);
100 for (String token : tokens) {
101 if (token.length() == 0) {
102 continue;
103 }
104
105 Time timeTmp;
106 if (time == null && (timeTmp = parseTime(token)) != null) {
107 time = timeTmp;
108 continue;
109 }
110
111 Integer dayOfMonthTmp;
112 if (dayOfMonth == null
113 && (dayOfMonthTmp = parseDayOfMonth(token)) != null)
140 if (time == null || dayOfMonth == null || month == null || year == null
141 || dayOfMonth < 1 || dayOfMonth > 31
142 || year < 1601
143 || time.hour > 23
144 || time.minute > 59
145 || time.second > 59)
146 {
147 throw new ParseException("Error parsing date", 0);
148 }
149
150 Calendar calendar = Calendar.getInstance(
151 TimeZone.getTimeZone("UTC"), Locale.US);
152 calendar.setLenient(false);
153 calendar.clear();
154 calendar.set(year, month, dayOfMonth,
155 time.hour, time.minute, time.second);
156
157 try {
158 long result = calendar.getTimeInMillis();
159 if (logger.isLoggable(Level.FINEST)) {
160 logger.finest("result: [{0}]", new Date(result).toString());
161 }
162 return result;
163 } catch (Exception ex) {
164 ParseException pe = new ParseException("Error parsing date", 0);
165 pe.initCause(ex);
166 throw pe;
167 }
168 }
169
170 /**
171 * Parses a token as a time string.
172 */
173 private static Time parseTime(String token) {
174 Matcher matcher = TIME_PATTERN.matcher(token);
175 if (matcher.matches()) {
176 return new Time(
177 Integer.parseInt(matcher.group(1)),
178 Integer.parseInt(matcher.group(2)),
179 Integer.parseInt(matcher.group(3)));
180 } else {
|