Statistics
| Branch: | Tag: | Revision:

root / src / org / gss_project / gss / server / rest / FastHttpDateFormat.java @ 1206:292dec4eae08

History | View | Annotate | Download (6.2 kB)

1
/*
2
 *  Licensed to the Apache Software Foundation (ASF) under one or more
3
 *  contributor license agreements.  See the NOTICE file distributed with
4
 *  this work for additional information regarding copyright ownership.
5
 *  The ASF licenses this file to You under the Apache License, Version 2.0
6
 *  (the "License"); you may not use this file except in compliance with
7
 *  the License.  You may obtain a copy of the License at
8
 *
9
 *      http://www.apache.org/licenses/LICENSE-2.0
10
 *
11
 *  Unless required by applicable law or agreed to in writing, software
12
 *  distributed under the License is distributed on an "AS IS" BASIS,
13
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
 *  See the License for the specific language governing permissions and
15
 *  limitations under the License.
16
 */
17
package org.gss_project.gss.server.rest;
18

    
19
import java.text.DateFormat;
20
import java.text.ParseException;
21
import java.text.SimpleDateFormat;
22
import java.util.Date;
23
import java.util.Locale;
24
import java.util.TimeZone;
25
import java.util.concurrent.ConcurrentHashMap;
26

    
27
/**
28
 * Utility class to generate HTTP dates.
29
 *
30
 * @author Remy Maucherat
31
 */
32
public final class FastHttpDateFormat {
33

    
34

    
35
    // -------------------------------------------------------------- Variables
36

    
37

    
38
    /**
39
     *
40
     */
41
    protected static final int CACHE_SIZE =
42
        Integer.parseInt(System.getProperty("org.apache.tomcat.util.http.FastHttpDateFormat.CACHE_SIZE", "1000"));
43

    
44

    
45
    /**
46
     * HTTP date format.
47
     */
48
    protected static final SimpleDateFormat format =
49
        new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", Locale.US);
50

    
51

    
52
    /**
53
     * The set of SimpleDateFormat formats to use in getDateHeader().
54
     */
55
    protected static final SimpleDateFormat formats[] = {
56
        new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", Locale.US),
57
        new SimpleDateFormat("EEEEEE, dd-MMM-yy HH:mm:ss zzz", Locale.US),
58
        new SimpleDateFormat("EEE MMMM d HH:mm:ss yyyy", Locale.US)
59
    };
60

    
61

    
62
    /**
63
     *
64
     */
65
    protected final static TimeZone gmtZone = TimeZone.getTimeZone("GMT");
66

    
67

    
68
    /**
69
     * GMT timezone - all HTTP dates are on GMT
70
     */
71
    static {
72

    
73
        format.setTimeZone(gmtZone);
74

    
75
        formats[0].setTimeZone(gmtZone);
76
        formats[1].setTimeZone(gmtZone);
77
        formats[2].setTimeZone(gmtZone);
78

    
79
    }
80

    
81

    
82
    /**
83
     * Instant on which the currentDate object was generated.
84
     */
85
    protected static long currentDateGenerated = 0L;
86

    
87

    
88
    /**
89
     * Current formatted date.
90
     */
91
    protected static String currentDate = null;
92

    
93

    
94
    /**
95
     * Formatter cache.
96
     */
97
    protected static final ConcurrentHashMap<Long, String> formatCache =
98
        new ConcurrentHashMap<Long, String>(CACHE_SIZE);
99

    
100

    
101
    /**
102
     * Parser cache.
103
     */
104
    protected static final ConcurrentHashMap<String, Long> parseCache =
105
        new ConcurrentHashMap<String, Long>(CACHE_SIZE);
106

    
107

    
108
    // --------------------------------------------------------- Public Methods
109

    
110

    
111
    /**
112
     * Get the current date in HTTP format.
113
     * @return the formatted date
114
     */
115
    public static final String getCurrentDate() {
116

    
117
        long now = System.currentTimeMillis();
118
        if (now - currentDateGenerated > 1000)
119
                        synchronized (format) {
120
                if (now - currentDateGenerated > 1000) {
121
                    currentDateGenerated = now;
122
                    currentDate = format.format(new Date(now));
123
                }
124
            }
125
        return currentDate;
126

    
127
    }
128

    
129

    
130
    /**
131
     * Get the HTTP format of the specified date.
132
     * @param value
133
     * @param threadLocalformat
134
     * @return the formatted date
135
     */
136
    public static final String formatDate
137
        (long value, DateFormat threadLocalformat) {
138

    
139
        Long longValue = new Long(value);
140
        String cachedDate = formatCache.get(longValue);
141
        if (cachedDate != null)
142
            return cachedDate;
143

    
144
        String newDate = null;
145
        Date dateValue = new Date(value);
146
        if (threadLocalformat != null) {
147
            newDate = threadLocalformat.format(dateValue);
148
            updateFormatCache(longValue, newDate);
149
        } else
150
                        synchronized (formatCache) {
151
                synchronized (format) {
152
                    newDate = format.format(dateValue);
153
                }
154
                updateFormatCache(longValue, newDate);
155
            }
156
        return newDate;
157

    
158
    }
159

    
160

    
161
    /**
162
     * Try to parse the given date as a HTTP date.
163
     * @param value
164
     * @param threadLocalformats
165
     * @return the date value
166
     */
167
    public static final long parseDate(String value,
168
                                       DateFormat[] threadLocalformats) {
169

    
170
        Long cachedDate = parseCache.get(value);
171
        if (cachedDate != null)
172
            return cachedDate.longValue();
173

    
174
        Long date = null;
175
        if (threadLocalformats != null) {
176
            date = internalParseDate(value, threadLocalformats);
177
            updateParseCache(value, date);
178
        } else
179
                        synchronized (parseCache) {
180
                date = internalParseDate(value, formats);
181
                updateParseCache(value, date);
182
            }
183
        if (date == null)
184
                        return -1L;
185
                return date.longValue();
186

    
187
    }
188

    
189

    
190
    /**
191
     * Parse date with given formatters.
192
     * @param value
193
     * @param theFormats
194
     * @return the date value
195
     */
196
    private static final Long internalParseDate
197
        (String value, DateFormat[] theFormats) {
198
        Date date = null;
199
        for (int i = 0; date == null && i < theFormats.length; i++)
200
                        try {
201
                date = theFormats[i].parse(value);
202
            } catch (ParseException e) {
203
                // Do nothing.
204
            }
205
        if (date == null)
206
                        return null;
207
        return new Long(date.getTime());
208
    }
209

    
210

    
211
    /**
212
     * Update cache.
213
     * @param key
214
     * @param value
215
     */
216
    private static void updateFormatCache(Long key, String value) {
217
        if (value == null)
218
                        return;
219
        if (formatCache.size() > CACHE_SIZE)
220
                        formatCache.clear();
221
        formatCache.put(key, value);
222
    }
223

    
224

    
225
    /**
226
     * Update cache.
227
     * @param key
228
     * @param value
229
     */
230
    private static void updateParseCache(String key, Long value) {
231
        if (value == null)
232
                        return;
233
        if (parseCache.size() > CACHE_SIZE)
234
                        parseCache.clear();
235
        parseCache.put(key, value);
236
    }
237

    
238

    
239
}