View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.myfaces.commons.resourcehandler.resource;
20  
21  import java.io.File;
22  import java.io.IOException;
23  import java.net.JarURLConnection;
24  import java.net.URL;
25  import java.net.URLConnection;
26  import java.text.ParseException;
27  import java.text.SimpleDateFormat;
28  import java.util.Date;
29  import java.util.Locale;
30  import java.util.TimeZone;
31  
32  public class ResourceLoaderUtils
33  {
34      // TODO: In tomcat and jetty it is implemented a Flyweight pattern when converting
35      // date headers. For now it is better keep this stuff simple.
36      private static final String HTTP_RESPONSE_DATE_HEADER =
37          "EEE, dd MMM yyyy HH:mm:ss zzz";
38      
39      private static final String[] HTTP_REQUEST_DATE_HEADER = {
40              "EEE, dd MMM yyyy HH:mm:ss zzz", "EEEEEE, dd-MMM-yy HH:mm:ss zzz",
41              "EEE MMMM d HH:mm:ss yyyy" };
42      
43      private static TimeZone __GMT = TimeZone.getTimeZone("GMT");
44  
45      public static String formatDateHeader(long value)
46      {
47          SimpleDateFormat format = new SimpleDateFormat(
48                  HTTP_RESPONSE_DATE_HEADER,
49                  Locale.US);
50          format.setTimeZone(__GMT);
51          return format.format(new Date(value));
52      }
53      
54      public static Long parseDateHeader(String value)
55      {
56          Date date = null;
57          for (int i = 0; (date == null) && (i < HTTP_REQUEST_DATE_HEADER.length); i++)
58          {
59              try
60              {
61                  SimpleDateFormat format = new SimpleDateFormat(
62                          HTTP_REQUEST_DATE_HEADER[i], Locale.US);
63                  format.setTimeZone(__GMT);
64                  date = format.parse(value);
65              }
66              catch (ParseException e)
67              {
68                  ;
69              }
70          }
71          if (date == null)
72          {
73              return null;
74          }
75          return new Long(date.getTime());
76      }
77      
78      //Taken from trinidad URLUtils
79      public static long getResourceLastModified(URL url) throws IOException
80      {
81          if ("file".equals(url.getProtocol()))
82          {
83              String externalForm = url.toExternalForm();
84              // Remove the "file:"
85              File file = new File(externalForm.substring(5));
86  
87              return file.lastModified();
88          }
89          else
90          {
91              return getResourceLastModified(url.openConnection());
92          }
93      }
94  
95      //Taken from trinidad URLUtils
96      public static long getResourceLastModified(URLConnection connection) throws IOException
97      {
98          long modified;
99          if (connection instanceof JarURLConnection)
100         {
101             // The following hack is required to work-around a JDK bug.
102             // getLastModified() on a JAR entry URL delegates to the actual JAR file
103             // rather than the JAR entry.
104             // This opens internally, and does not close, an input stream to the JAR
105             // file.
106             // In turn, you cannot close it by yourself, because it's internal.
107             // The work-around is to get the modification date of the JAR file
108             // manually,
109             // and then close that connection again.
110 
111             URL jarFileUrl = ((JarURLConnection) connection).getJarFileURL();
112             URLConnection jarFileConnection = jarFileUrl.openConnection();
113 
114             try
115             {
116                 modified = jarFileConnection.getLastModified();
117             }
118             finally
119             {
120                 try
121                 {
122                     jarFileConnection.getInputStream().close();
123                 }
124                 catch (Exception exception)
125                 {
126                     // Ignored
127                 }
128             }
129         }
130         else
131         {
132             modified = connection.getLastModified();
133         }
134 
135         return modified;
136     }
137 }