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.tomahawk.resource;
20  
21  import java.net.URL;
22  import java.util.Locale;
23  import java.util.MissingResourceException;
24  import java.util.ResourceBundle;
25  
26  import javax.faces.application.Resource;
27  import javax.faces.application.ResourceHandler;
28  import javax.faces.context.FacesContext;
29  
30  import org.apache.myfaces.shared_tomahawk.resource.ResourceHandlerCache.ResourceValue;
31  import org.apache.myfaces.shared_tomahawk.resource.ResourceHandlerCache;
32  import org.apache.myfaces.shared_tomahawk.resource.ResourceHandlerSupport;
33  import org.apache.myfaces.shared_tomahawk.resource.ResourceImpl;
34  import org.apache.myfaces.shared_tomahawk.resource.ResourceLoader;
35  import org.apache.myfaces.shared_tomahawk.resource.ResourceMeta;
36  import org.apache.myfaces.shared_tomahawk.util.ClassUtils;
37  
38  public class UncompressedResourceHandlerWrapper extends javax.faces.application.ResourceHandlerWrapper
39  {
40      private ResourceHandler _delegate;
41      
42      private ResourceHandlerSupport _resourceHandlerSupport;
43  
44      private ResourceHandlerCache _resourceHandlerCache;
45      
46      public UncompressedResourceHandlerWrapper(ResourceHandler delegate)
47      {
48          super();
49          _delegate = delegate;
50      }
51  
52      @Override
53      public Resource createResource(String resourceName)
54      {
55          return createResource(resourceName, null);
56      }
57  
58      @Override
59      public Resource createResource(String resourceName, String libraryName)
60      {
61          return createResource(resourceName, libraryName, null);
62      }
63  
64      public Resource createResource(String resourceName, String libraryName,
65              String contentType)
66      {
67          Resource resource = null;
68          
69          // There will be no resource loaders if ProjectStage != Development
70          if (getResourceHandlerSupport().getResourceLoaders().length > 0)
71          {
72              if (contentType == null)
73              {
74                  //Resolve contentType using ExternalContext.getMimeType
75                  contentType = FacesContext.getCurrentInstance().getExternalContext().getMimeType(resourceName);
76              }
77              
78              final String localePrefix = getLocalePrefixForLocateResource();
79              
80              if(getResourceLoaderCache().containsResource(resourceName, libraryName, contentType, localePrefix))
81              {
82                  ResourceValue resourceValue = getResourceLoaderCache().getResource(resourceName, libraryName, contentType, localePrefix);
83                  resource = new ResourceImpl(resourceValue.getResourceMeta(), resourceValue.getResourceLoader(),
84                          getResourceHandlerSupport(), contentType);
85              }
86              else
87              {
88                  for (ResourceLoader loader : getResourceHandlerSupport()
89                          .getResourceLoaders())
90                  {
91                      ResourceMeta resourceMeta = deriveResourceMeta(loader,
92                              resourceName, libraryName);
93          
94                      if (resourceMeta != null)
95                      {
96                          resource = new ResourceImpl(resourceMeta, loader,
97                                  getResourceHandlerSupport(), contentType);
98                          
99                          getResourceLoaderCache().putResource(resourceName, libraryName, contentType, localePrefix, resourceMeta, loader);
100                         break;
101                     }
102                 }
103             }
104             if (resource != null)
105             {
106                 return resource;
107             }
108         }
109         return getWrapped().createResource(resourceName, libraryName, contentType);
110     }
111     
112     /**
113      * This method try to create a ResourceMeta for a specific resource
114      * loader. If no library, or resource is found, just return null,
115      * so the algorithm in createResource can continue checking with the 
116      * next registered ResourceLoader. 
117      */
118     protected ResourceMeta deriveResourceMeta(ResourceLoader resourceLoader,
119             String resourceName, String libraryName)
120     {
121         String localePrefix = getLocalePrefixForLocateResource();
122         String resourceVersion = null;
123         String libraryVersion = null;
124         ResourceMeta resourceId = null;
125         
126         //1. Try to locate resource in a localized path
127         if (localePrefix != null)
128         {
129             if (null != libraryName)
130             {
131                 String pathToLib = localePrefix + '/' + libraryName;
132                 libraryVersion = resourceLoader.getLibraryVersion(pathToLib);
133 
134                 if (null != libraryVersion)
135                 {
136                     String pathToResource = localePrefix + '/'
137                             + libraryName + '/' + libraryVersion + '/'
138                             + resourceName;
139                     resourceVersion = resourceLoader
140                             .getResourceVersion(pathToResource);
141                 }
142                 else
143                 {
144                     String pathToResource = localePrefix + '/'
145                             + libraryName + '/' + resourceName;
146                     resourceVersion = resourceLoader
147                             .getResourceVersion(pathToResource);
148                 }
149 
150                 if (!(resourceVersion != null && ResourceLoader.VERSION_INVALID.equals(resourceVersion)))
151                 {
152                     resourceId = resourceLoader.createResourceMeta(localePrefix, libraryName,
153                             libraryVersion, resourceName, resourceVersion);
154                 }
155             }
156             else
157             {
158                 resourceVersion = resourceLoader
159                         .getResourceVersion(localePrefix + '/'+ resourceName);
160                 if (!(resourceVersion != null && ResourceLoader.VERSION_INVALID.equals(resourceVersion)))
161                 {               
162                     resourceId = resourceLoader.createResourceMeta(localePrefix, null, null,
163                             resourceName, resourceVersion);
164                 }
165             }
166 
167             if (resourceId != null)
168             {
169                 URL url = resourceLoader.getResourceURL(resourceId);
170                 if (url == null)
171                 {
172                     resourceId = null;
173                 }
174             }            
175         }
176         
177         //2. Try to localize resource in a non localized path
178         if (resourceId == null)
179         {
180             if (null != libraryName)
181             {
182                 libraryVersion = resourceLoader.getLibraryVersion(libraryName);
183 
184                 if (null != libraryVersion)
185                 {
186                     String pathToResource = (libraryName + '/' + libraryVersion
187                             + '/' + resourceName);
188                     resourceVersion = resourceLoader
189                             .getResourceVersion(pathToResource);
190                 }
191                 else
192                 {
193                     String pathToResource = (libraryName + '/'
194                             + resourceName);
195                     resourceVersion = resourceLoader
196                             .getResourceVersion(pathToResource);
197                 }
198 
199                 if (!(resourceVersion != null && ResourceLoader.VERSION_INVALID.equals(resourceVersion)))
200                 {               
201                     resourceId = resourceLoader.createResourceMeta(null, libraryName,
202                             libraryVersion, resourceName, resourceVersion);
203                 }
204             }
205             else
206             {
207                 resourceVersion = resourceLoader
208                         .getResourceVersion(resourceName);
209                 
210                 if (!(resourceVersion != null && ResourceLoader.VERSION_INVALID.equals(resourceVersion)))
211                 {               
212                     resourceId = resourceLoader.createResourceMeta(null, null, null,
213                             resourceName, resourceVersion);
214                 }
215             }
216 
217             if (resourceId != null)
218             {
219                 URL url = resourceLoader.getResourceURL(resourceId);
220                 if (url == null)
221                 {
222                     resourceId = null;
223                 }
224             }            
225         }
226         
227         return resourceId;
228     }
229     
230     protected String getLocalePrefixForLocateResource()
231     {
232         String localePrefix = null;
233         FacesContext context = FacesContext.getCurrentInstance();
234 
235         String bundleName = context.getApplication().getMessageBundle();
236 
237         if (null != bundleName)
238         {
239             Locale locale = context.getApplication().getViewHandler()
240                     .calculateLocale(context);
241 
242             ResourceBundle bundle = ResourceBundle
243                     .getBundle(bundleName, locale, ClassUtils.getContextClassLoader());
244 
245             if (bundle != null)
246             {
247                 try
248                 {
249                     localePrefix = bundle.getString(ResourceHandler.LOCALE_PREFIX);
250                 }
251                 catch (MissingResourceException e)
252                 {
253                     // Ignore it and return null
254                 }
255             }
256         }
257         return localePrefix;
258     }
259 
260     
261     @Override
262     public ResourceHandler getWrapped()
263     {
264         return _delegate;
265     }
266     
267     /**
268      * @param resourceHandlerSupport
269      *            the resourceHandlerSupport to set
270      */
271     public void setResourceHandlerSupport(
272             ResourceHandlerSupport resourceHandlerSupport)
273     {
274         _resourceHandlerSupport = resourceHandlerSupport;
275     }
276 
277     /**
278      * @return the resourceHandlerSupport
279      */
280     protected ResourceHandlerSupport getResourceHandlerSupport()
281     {
282         if (_resourceHandlerSupport == null)
283         {
284             _resourceHandlerSupport = new UncompressedResourceHandlerSupport();
285         }
286         return _resourceHandlerSupport;
287     }
288     
289     private ResourceHandlerCache getResourceLoaderCache()
290     {
291         if (_resourceHandlerCache == null)
292             _resourceHandlerCache = new ResourceHandlerCache();
293         return _resourceHandlerCache;
294     }
295 }