Coverage Report - org.acegisecurity.ui.savedrequest.FastHttpDateFormat
 
Classes in this File Line Coverage Branch Coverage Complexity
FastHttpDateFormat
0% 
0% 
4.8
 
 1  
 /* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
 2  
  *
 3  
  * Licensed under the Apache License, Version 2.0 (the "License");
 4  
  * you may not use this file except in compliance with the License.
 5  
  * You may obtain a copy of the License at
 6  
  *
 7  
  *     http://www.apache.org/licenses/LICENSE-2.0
 8  
  *
 9  
  * Unless required by applicable law or agreed to in writing, software
 10  
  * distributed under the License is distributed on an "AS IS" BASIS,
 11  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 12  
  * See the License for the specific language governing permissions and
 13  
  * limitations under the License.
 14  
  */
 15  
 
 16  
 package org.acegisecurity.ui.savedrequest;
 17  
 
 18  
 import java.text.DateFormat;
 19  
 import java.text.ParseException;
 20  
 import java.text.SimpleDateFormat;
 21  
 
 22  
 import java.util.Date;
 23  
 import java.util.HashMap;
 24  
 import java.util.Locale;
 25  
 import java.util.TimeZone;
 26  
 
 27  
 
 28  
 /**
 29  
  * <p>Utility class to generate HTTP dates.</p>
 30  
  * <p>This class is based on code in Apache Tomcat.</p>
 31  
  *
 32  
  * @author Remy Maucherat
 33  
  * @author Andrey Grebnev
 34  
  * @version $Id: FastHttpDateFormat.java 1784 2007-02-24 21:00:24Z luke_t $
 35  
  */
 36  0
 public class FastHttpDateFormat {
 37  
     //~ Static fields/initializers =====================================================================================
 38  
 
 39  
     /** HTTP date format. */
 40  0
     protected static final SimpleDateFormat format = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", Locale.US);
 41  
 
 42  
     /** The set of SimpleDateFormat formats to use in <code>getDateHeader()</code>. */
 43  0
     protected static final SimpleDateFormat[] formats = {
 44  
             new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", Locale.US),
 45  
             new SimpleDateFormat("EEEEEE, dd-MMM-yy HH:mm:ss zzz", Locale.US),
 46  
             new SimpleDateFormat("EEE MMMM d HH:mm:ss yyyy", Locale.US)
 47  
         };
 48  
 
 49  
     /** GMT timezone - all HTTP dates are on GMT */
 50  0
     protected static final TimeZone gmtZone = TimeZone.getTimeZone("GMT");
 51  
 
 52  
     static {
 53  0
         format.setTimeZone(gmtZone);
 54  
 
 55  0
         formats[0].setTimeZone(gmtZone);
 56  0
         formats[1].setTimeZone(gmtZone);
 57  0
         formats[2].setTimeZone(gmtZone);
 58  
     }
 59  
 
 60  
     /** Instant on which the currentDate object was generated. */
 61  0
     protected static long currentDateGenerated = 0L;
 62  
 
 63  
     /** Current formatted date. */
 64  0
     protected static String currentDate = null;
 65  
 
 66  
     /** Formatter cache. */
 67  0
     protected static final HashMap formatCache = new HashMap();
 68  
 
 69  
     /** Parser cache. */
 70  0
     protected static final HashMap parseCache = new HashMap();
 71  
 
 72  
     //~ Methods ========================================================================================================
 73  
 
 74  
     /**
 75  
      * Formats a specified date to HTTP format. If local format is not <code>null</code>, it's used instead.
 76  
      *
 77  
      * @param value Date value to format
 78  
      * @param threadLocalformat The format to use (or <code>null</code> -- then HTTP format will be used)
 79  
      *
 80  
      * @return Formatted date
 81  
      */
 82  
     public static final String formatDate(long value, DateFormat threadLocalformat) {
 83  0
         String cachedDate = null;
 84  0
         Long longValue = new Long(value);
 85  
 
 86  
         try {
 87  0
             cachedDate = (String) formatCache.get(longValue);
 88  0
         } catch (Exception e) {}
 89  
 
 90  0
         if (cachedDate != null) {
 91  0
             return cachedDate;
 92  
         }
 93  
 
 94  0
         String newDate = null;
 95  0
         Date dateValue = new Date(value);
 96  
 
 97  0
         if (threadLocalformat != null) {
 98  0
             newDate = threadLocalformat.format(dateValue);
 99  
 
 100  0
             synchronized (formatCache) {
 101  0
                 updateCache(formatCache, longValue, newDate);
 102  0
             }
 103  
         } else {
 104  0
             synchronized (formatCache) {
 105  0
                 newDate = format.format(dateValue);
 106  0
                 updateCache(formatCache, longValue, newDate);
 107  0
             }
 108  
         }
 109  
 
 110  0
         return newDate;
 111  
     }
 112  
 
 113  
     /**
 114  
      * Gets the current date in HTTP format.
 115  
      *
 116  
      * @return Current date in HTTP format
 117  
      */
 118  
     public static final String getCurrentDate() {
 119  0
         long now = System.currentTimeMillis();
 120  
 
 121  0
         if ((now - currentDateGenerated) > 1000) {
 122  0
             synchronized (format) {
 123  0
                 if ((now - currentDateGenerated) > 1000) {
 124  0
                     currentDateGenerated = now;
 125  0
                     currentDate = format.format(new Date(now));
 126  
                 }
 127  0
             }
 128  
         }
 129  
 
 130  0
         return currentDate;
 131  
     }
 132  
 
 133  
     /**
 134  
      * Parses date with given formatters.
 135  
      *
 136  
      * @param value The string to parse
 137  
      * @param formats Array of formats to use
 138  
      *
 139  
      * @return Parsed date (or <code>null</code> if no formatter mached)
 140  
      */
 141  
     private static Long internalParseDate(String value, DateFormat[] formats) {
 142  0
         Date date = null;
 143  
 
 144  0
         for (int i = 0; (date == null) && (i < formats.length); i++) {
 145  
             try {
 146  0
                 date = formats[i].parse(value);
 147  0
             } catch (ParseException e) {
 148  
                 ;
 149  0
             }
 150  
         }
 151  
 
 152  0
         if (date == null) {
 153  0
             return null;
 154  
         }
 155  
 
 156  0
         return new Long(date.getTime());
 157  
     }
 158  
 
 159  
     /**
 160  
      * Tries to parse the given date as an HTTP date. If local format list is not <code>null</code>, it's used
 161  
      * instead.
 162  
      *
 163  
      * @param value The string to parse
 164  
      * @param threadLocalformats Array of formats to use for parsing. If <code>null</code>, HTTP formats are used.
 165  
      *
 166  
      * @return Parsed date (or -1 if error occured)
 167  
      */
 168  
     public static final long parseDate(String value, DateFormat[] threadLocalformats) {
 169  0
         Long cachedDate = null;
 170  
 
 171  
         try {
 172  0
             cachedDate = (Long) parseCache.get(value);
 173  0
         } catch (Exception e) {}
 174  
 
 175  0
         if (cachedDate != null) {
 176  0
             return cachedDate.longValue();
 177  
         }
 178  
 
 179  0
         Long date = null;
 180  
 
 181  0
         if (threadLocalformats != null) {
 182  0
             date = internalParseDate(value, threadLocalformats);
 183  
 
 184  0
             synchronized (parseCache) {
 185  0
                 updateCache(parseCache, value, date);
 186  0
             }
 187  
         } else {
 188  0
             synchronized (parseCache) {
 189  0
                 date = internalParseDate(value, formats);
 190  0
                 updateCache(parseCache, value, date);
 191  0
             }
 192  
         }
 193  
 
 194  0
         if (date == null) {
 195  0
             return (-1L);
 196  
         } else {
 197  0
             return date.longValue();
 198  
         }
 199  
     }
 200  
 
 201  
     /**
 202  
      * Updates cache.
 203  
      *
 204  
      * @param cache Cache to be updated
 205  
      * @param key Key to be updated
 206  
      * @param value New value
 207  
      */
 208  
     private static void updateCache(HashMap cache, Object key, Object value) {
 209  0
         if (value == null) {
 210  0
             return;
 211  
         }
 212  
 
 213  0
         if (cache.size() > 1000) {
 214  0
             cache.clear();
 215  
         }
 216  
 
 217  0
         cache.put(key, value);
 218  0
     }
 219  
 }