1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.myfaces.application;
20
21 import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFWebConfigParam;
22 import org.apache.myfaces.shared.resource.ResourceHandlerCache;
23 import org.apache.myfaces.shared.resource.ResourceHandlerCache.ResourceValue;
24 import org.apache.myfaces.shared.resource.ResourceHandlerSupport;
25 import org.apache.myfaces.shared.resource.ResourceImpl;
26 import org.apache.myfaces.shared.resource.ResourceLoader;
27 import org.apache.myfaces.shared.resource.ResourceMeta;
28 import org.apache.myfaces.shared.resource.ResourceValidationUtils;
29 import org.apache.myfaces.shared.util.ClassUtils;
30 import org.apache.myfaces.shared.util.ExternalContextUtils;
31 import org.apache.myfaces.shared.util.StringUtils;
32 import org.apache.myfaces.shared.util.WebConfigParamUtils;
33
34 import javax.faces.application.Resource;
35 import javax.faces.application.ResourceHandler;
36 import javax.faces.application.ResourceWrapper;
37 import javax.faces.context.ExternalContext;
38 import javax.faces.context.FacesContext;
39 import javax.servlet.http.HttpServletResponse;
40 import java.io.IOException;
41 import java.io.InputStream;
42 import java.io.OutputStream;
43 import java.util.List;
44 import java.util.Locale;
45 import java.util.Map;
46 import java.util.MissingResourceException;
47 import java.util.ResourceBundle;
48 import java.util.logging.Level;
49 import java.util.logging.Logger;
50 import java.util.regex.Pattern;
51 import org.apache.myfaces.shared.resource.ContractResource;
52 import org.apache.myfaces.shared.resource.ContractResourceLoader;
53 import org.apache.myfaces.shared.resource.ResourceCachedInfo;
54
55
56
57
58
59
60
61
62 public class ResourceHandlerImpl extends ResourceHandler
63 {
64
65 private static final String IS_RESOURCE_REQUEST = "org.apache.myfaces.IS_RESOURCE_REQUEST";
66
67 private ResourceHandlerSupport _resourceHandlerSupport;
68
69 private ResourceHandlerCache _resourceHandlerCache;
70
71
72 private static final Logger log = Logger.getLogger(ResourceHandlerImpl.class.getName());
73
74
75
76
77 @JSFWebConfigParam(since="2.1.6, 2.0.12", defaultValue="false",
78 expectedValues="true, false", group="resources")
79 public static final String INIT_PARAM_STRICT_JSF_2_ALLOW_SLASH_LIBRARY_NAME =
80 "org.apache.myfaces.STRICT_JSF_2_ALLOW_SLASH_LIBRARY_NAME";
81 public static final boolean INIT_PARAM_STRICT_JSF_2_ALLOW_SLASH_LIBRARY_NAME_DEFAULT = false;
82
83
84
85
86
87
88 @JSFWebConfigParam(since="2.1.10, 2.0.16", defaultValue="2048", group="resources")
89 public static final String INIT_PARAM_RESOURCE_BUFFER_SIZE = "org.apache.myfaces.RESOURCE_BUFFER_SIZE";
90 public static final int INIT_PARAM_RESOURCE_BUFFER_SIZE_DEFAULT = 2048;
91
92 public static final Pattern LIBRARY_VERSION_CHECKER = Pattern.compile("\\p{Digit}+(_\\p{Digit}*)*");
93 public static final Pattern RESOURCE_VERSION_CHECKER = Pattern.compile("\\p{Digit}+(_\\p{Digit}*)*\\..*");
94
95 private Boolean _allowSlashLibraryName;
96 private int _resourceBufferSize = -1;
97
98 private String[] _excludedResourceExtensions;
99
100 @Override
101 public Resource createResource(String resourceName)
102 {
103 return createResource(resourceName, null);
104 }
105
106 @Override
107 public Resource createResource(String resourceName, String libraryName)
108 {
109 return createResource(resourceName, libraryName, null);
110 }
111
112 @Override
113 public Resource createResource(String resourceName, String libraryName,
114 String contentType)
115 {
116 Resource resource = null;
117
118 if (resourceName == null || resourceName.length() == 0)
119 {
120 return null;
121 }
122 if (resourceName.charAt(0) == '/')
123 {
124
125
126
127 resourceName = resourceName.substring(1);
128 }
129 if (!ResourceValidationUtils.isValidResourceName(resourceName))
130 {
131 return null;
132 }
133 if (libraryName != null && !ResourceValidationUtils.isValidLibraryName(
134 libraryName, isAllowSlashesLibraryName()))
135 {
136 return null;
137 }
138 FacesContext facesContext = FacesContext.getCurrentInstance();
139 if (contentType == null)
140 {
141
142 contentType = facesContext.getExternalContext().getMimeType(resourceName);
143 }
144
145 final String localePrefix = getLocalePrefixForLocateResource(facesContext);
146 final List<String> contracts = facesContext.getResourceLibraryContracts();
147 String contractPreferred = getContractNameForLocateResource(facesContext);
148 ResourceValue resourceValue = null;
149
150
151
152
153
154
155
156
157
158
159
160
161 if (contractPreferred != null)
162 {
163 resourceValue = getResourceLoaderCache().getResource(
164 resourceName, libraryName, contentType, localePrefix, contractPreferred);
165 }
166 if (resourceValue == null && !contracts.isEmpty())
167 {
168
169 for (String contract : contracts)
170 {
171 resourceValue = getResourceLoaderCache().getResource(
172 resourceName, libraryName, contentType, localePrefix, contract);
173 if (resourceValue != null)
174 {
175 break;
176 }
177 }
178 }
179
180 if (resourceValue == null)
181 {
182
183 resourceValue = getResourceLoaderCache().getResource(resourceName, libraryName, contentType, localePrefix);
184 }
185
186 if(resourceValue != null)
187 {
188 resource = new ResourceImpl(resourceValue.getResourceMeta(), resourceValue.getResourceLoader(),
189 getResourceHandlerSupport(), contentType,
190 resourceValue.getCachedInfo() != null ? resourceValue.getCachedInfo().getURL() : null,
191 resourceValue.getCachedInfo() != null ? resourceValue.getCachedInfo().getRequestPath() : null);
192 }
193 else
194 {
195 boolean resolved = false;
196
197 if (contractPreferred != null)
198 {
199 for (ContractResourceLoader loader : getResourceHandlerSupport().getContractResourceLoaders())
200 {
201 ResourceMeta resourceMeta = deriveResourceMeta(loader, resourceName, libraryName,
202 localePrefix, contractPreferred);
203 if (resourceMeta != null)
204 {
205 resource = new ResourceImpl(resourceMeta, loader,
206 getResourceHandlerSupport(), contentType);
207
208
209 getResourceLoaderCache().putResource(resourceName, libraryName, contentType,
210 localePrefix, contractPreferred, resourceMeta, loader,
211 new ResourceCachedInfo(resource.getURL(), resource.getRequestPath()));
212 resolved = true;
213 break;
214 }
215 }
216 }
217 if (!resolved && !contracts.isEmpty())
218 {
219 for (ContractResourceLoader loader :
220 getResourceHandlerSupport().getContractResourceLoaders())
221 {
222 for (String contract : contracts)
223 {
224 ResourceMeta resourceMeta = deriveResourceMeta(
225 loader, resourceName, libraryName,
226 localePrefix, contract);
227 if (resourceMeta != null)
228 {
229 resource = new ResourceImpl(resourceMeta, loader,
230 getResourceHandlerSupport(), contentType);
231
232
233 getResourceLoaderCache().putResource(
234 resourceName, libraryName, contentType,
235 localePrefix, contract, resourceMeta, loader,
236 new ResourceCachedInfo(resource.getURL(), resource.getRequestPath()));
237 resolved = true;
238 break;
239 }
240 }
241 }
242 }
243 if (!resolved)
244 {
245 for (ResourceLoader loader : getResourceHandlerSupport().getResourceLoaders())
246 {
247 ResourceMeta resourceMeta = deriveResourceMeta(
248 loader, resourceName, libraryName, localePrefix);
249
250 if (resourceMeta != null)
251 {
252 resource = new ResourceImpl(
253 resourceMeta, loader, getResourceHandlerSupport(), contentType);
254
255
256 getResourceLoaderCache().putResource(resourceName, libraryName, contentType,
257 localePrefix, null, resourceMeta, loader,
258 new ResourceCachedInfo(resource.getURL(), resource.getRequestPath()));
259 break;
260 }
261 }
262 }
263 }
264 return resource;
265 }
266
267 protected ResourceMeta deriveResourceMeta(ContractResourceLoader resourceLoader,
268 String resourceName, String libraryName, String localePrefix, String contractName)
269 {
270 String resourceVersion = null;
271 String libraryVersion = null;
272 ResourceMeta resourceId = null;
273
274
275 if (localePrefix != null)
276 {
277 if (null != libraryName)
278 {
279 String pathToLib = localePrefix + '/' + libraryName;
280 libraryVersion = resourceLoader.getLibraryVersion(pathToLib, contractName);
281
282 if (null != libraryVersion)
283 {
284 String pathToResource = localePrefix + '/'
285 + libraryName + '/' + libraryVersion + '/'
286 + resourceName;
287 resourceVersion = resourceLoader
288 .getResourceVersion(pathToResource, contractName);
289 }
290 else
291 {
292 String pathToResource = localePrefix + '/'
293 + libraryName + '/' + resourceName;
294 resourceVersion = resourceLoader
295 .getResourceVersion(pathToResource, contractName);
296 }
297
298 if (!(resourceVersion != null && ResourceLoader.VERSION_INVALID.equals(resourceVersion)))
299 {
300 resourceId = resourceLoader.createResourceMeta(localePrefix, libraryName,
301 libraryVersion, resourceName, resourceVersion, contractName);
302 }
303 }
304 else
305 {
306 resourceVersion = resourceLoader
307 .getResourceVersion(localePrefix + '/'+ resourceName, contractName);
308 if (!(resourceVersion != null && ResourceLoader.VERSION_INVALID.equals(resourceVersion)))
309 {
310 resourceId = resourceLoader.createResourceMeta(localePrefix, null, null,
311 resourceName, resourceVersion, contractName);
312 }
313 }
314
315 if (resourceId != null && !resourceLoader.resourceExists(resourceId))
316 {
317 resourceId = null;
318 }
319 }
320
321
322 if (resourceId == null)
323 {
324 if (null != libraryName)
325 {
326 libraryVersion = resourceLoader.getLibraryVersion(libraryName, contractName);
327
328 if (null != libraryVersion)
329 {
330 String pathToResource = (libraryName + '/' + libraryVersion
331 + '/' + resourceName);
332 resourceVersion = resourceLoader
333 .getResourceVersion(pathToResource, contractName);
334 }
335 else
336 {
337 String pathToResource = (libraryName + '/'
338 + resourceName);
339 resourceVersion = resourceLoader
340 .getResourceVersion(pathToResource, contractName);
341 }
342
343 if (!(resourceVersion != null && ResourceLoader.VERSION_INVALID.equals(resourceVersion)))
344 {
345 resourceId = resourceLoader.createResourceMeta(null, libraryName,
346 libraryVersion, resourceName, resourceVersion, contractName);
347 }
348 }
349 else
350 {
351 resourceVersion = resourceLoader
352 .getResourceVersion(resourceName, contractName);
353
354 if (!(resourceVersion != null && ResourceLoader.VERSION_INVALID.equals(resourceVersion)))
355 {
356 resourceId = resourceLoader.createResourceMeta(null, null, null,
357 resourceName, resourceVersion, contractName);
358 }
359 }
360
361 if (resourceId != null && !resourceLoader.resourceExists(resourceId))
362 {
363 resourceId = null;
364 }
365 }
366
367 return resourceId;
368 }
369
370
371
372
373
374
375
376 protected ResourceMeta deriveResourceMeta(ResourceLoader resourceLoader,
377 String resourceName, String libraryName, String localePrefix)
378 {
379 String resourceVersion = null;
380 String libraryVersion = null;
381 ResourceMeta resourceId = null;
382
383
384 if (localePrefix != null)
385 {
386 if (null != libraryName)
387 {
388 String pathToLib = localePrefix + '/' + libraryName;
389 libraryVersion = resourceLoader.getLibraryVersion(pathToLib);
390
391 if (null != libraryVersion)
392 {
393 String pathToResource = localePrefix + '/'
394 + libraryName + '/' + libraryVersion + '/'
395 + resourceName;
396 resourceVersion = resourceLoader
397 .getResourceVersion(pathToResource);
398 }
399 else
400 {
401 String pathToResource = localePrefix + '/'
402 + libraryName + '/' + resourceName;
403 resourceVersion = resourceLoader
404 .getResourceVersion(pathToResource);
405 }
406
407 if (!(resourceVersion != null && ResourceLoader.VERSION_INVALID.equals(resourceVersion)))
408 {
409 resourceId = resourceLoader.createResourceMeta(localePrefix, libraryName,
410 libraryVersion, resourceName, resourceVersion);
411 }
412 }
413 else
414 {
415 resourceVersion = resourceLoader
416 .getResourceVersion(localePrefix + '/'+ resourceName);
417 if (!(resourceVersion != null && ResourceLoader.VERSION_INVALID.equals(resourceVersion)))
418 {
419 resourceId = resourceLoader.createResourceMeta(localePrefix, null, null,
420 resourceName, resourceVersion);
421 }
422 }
423
424 if (resourceId != null && !resourceLoader.resourceExists(resourceId))
425 {
426 resourceId = null;
427 }
428 }
429
430
431 if (resourceId == null)
432 {
433 if (null != libraryName)
434 {
435 libraryVersion = resourceLoader.getLibraryVersion(libraryName);
436
437 if (null != libraryVersion)
438 {
439 String pathToResource = (libraryName + '/' + libraryVersion
440 + '/' + resourceName);
441 resourceVersion = resourceLoader
442 .getResourceVersion(pathToResource);
443 }
444 else
445 {
446 String pathToResource = (libraryName + '/'
447 + resourceName);
448 resourceVersion = resourceLoader
449 .getResourceVersion(pathToResource);
450 }
451
452 if (!(resourceVersion != null && ResourceLoader.VERSION_INVALID.equals(resourceVersion)))
453 {
454 resourceId = resourceLoader.createResourceMeta(null, libraryName,
455 libraryVersion, resourceName, resourceVersion);
456 }
457 }
458 else
459 {
460 resourceVersion = resourceLoader
461 .getResourceVersion(resourceName);
462
463 if (!(resourceVersion != null && ResourceLoader.VERSION_INVALID.equals(resourceVersion)))
464 {
465 resourceId = resourceLoader.createResourceMeta(null, null, null,
466 resourceName, resourceVersion);
467 }
468 }
469
470 if (resourceId != null && !resourceLoader.resourceExists(resourceId))
471 {
472 resourceId = null;
473 }
474 }
475
476 return resourceId;
477 }
478
479 @Override
480 public String getRendererTypeForResourceName(String resourceName)
481 {
482 if (resourceName.endsWith(".js"))
483 {
484 return "javax.faces.resource.Script";
485 }
486 else if (resourceName.endsWith(".css"))
487 {
488 return "javax.faces.resource.Stylesheet";
489 }
490 return null;
491 }
492
493
494
495
496
497
498
499 @Override
500 public void handleResourceRequest(FacesContext facesContext) throws IOException
501 {
502
503
504 String resourceBasePath = getResourceHandlerSupport()
505 .calculateResourceBasePath(facesContext);
506
507 if (resourceBasePath == null)
508 {
509
510
511
512
513 return;
514 }
515
516
517
518
519
520
521 ExternalContext extContext = facesContext.getExternalContext();
522 Object response = extContext.getResponse();
523 HttpServletResponse httpServletResponse = ExternalContextUtils.getHttpServletResponse(response);
524 if (httpServletResponse == null)
525 {
526 throw new IllegalStateException("Could not obtain an instance of HttpServletResponse.");
527 }
528
529 if (isResourceIdentifierExcluded(facesContext, resourceBasePath))
530 {
531 httpServletResponse.setStatus(HttpServletResponse.SC_NOT_FOUND);
532 return;
533 }
534
535 String resourceName = null;
536 if (resourceBasePath.startsWith(ResourceHandler.RESOURCE_IDENTIFIER))
537 {
538 resourceName = resourceBasePath
539 .substring(ResourceHandler.RESOURCE_IDENTIFIER.length() + 1);
540
541 if (resourceBasePath != null && !ResourceValidationUtils.isValidResourceName(resourceName))
542 {
543 httpServletResponse.setStatus(HttpServletResponse.SC_NOT_FOUND);
544 return;
545 }
546 }
547 else
548 {
549
550 httpServletResponse.setStatus(HttpServletResponse.SC_NOT_FOUND);
551 return;
552 }
553
554 String libraryName = facesContext.getExternalContext()
555 .getRequestParameterMap().get("ln");
556
557 if (libraryName != null && !ResourceValidationUtils.isValidLibraryName(
558 libraryName, isAllowSlashesLibraryName()))
559 {
560 httpServletResponse.setStatus(HttpServletResponse.SC_NOT_FOUND);
561 return;
562 }
563
564 Resource resource = null;
565 if (libraryName != null)
566 {
567
568 resource = facesContext.getApplication().getResourceHandler().createResource(resourceName, libraryName);
569 }
570 else
571 {
572 resource = facesContext.getApplication().getResourceHandler().createResource(resourceName);
573 }
574
575 if (resource == null)
576 {
577 httpServletResponse.setStatus(HttpServletResponse.SC_NOT_FOUND);
578 return;
579 }
580
581 if (!resource.userAgentNeedsUpdate(facesContext))
582 {
583 httpServletResponse.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
584 return;
585 }
586
587 httpServletResponse.setContentType(_getContentType(resource, facesContext.getExternalContext()));
588
589 Map<String, String> headers = resource.getResponseHeaders();
590
591 for (Map.Entry<String, String> entry : headers.entrySet())
592 {
593 httpServletResponse.setHeader(entry.getKey(), entry.getValue());
594 }
595
596
597 extContext.setResponseBufferSize(this.getResourceBufferSize());
598
599
600 try
601 {
602 InputStream in = resource.getInputStream();
603 OutputStream out = httpServletResponse.getOutputStream();
604
605 byte[] buffer = new byte[this.getResourceBufferSize()];
606
607 try
608 {
609 int count = pipeBytes(in, out, buffer);
610
611 if (!httpServletResponse.isCommitted())
612 {
613 httpServletResponse.setContentLength(count);
614 }
615 }
616 finally
617 {
618 try
619 {
620 in.close();
621 }
622 finally
623 {
624 out.close();
625 }
626 }
627 }
628 catch (IOException e)
629 {
630
631 if (isConnectionAbort(e))
632 {
633 log.log(Level.INFO,"Connection was aborted while loading resource " + resourceName
634 + " with library " + libraryName);
635 }
636 else
637 {
638 if (log.isLoggable(Level.WARNING))
639 {
640 log.log(Level.WARNING,"Error trying to load and send resource " + resourceName
641 + " with library " + libraryName + " :"
642 + e.getMessage(), e);
643 }
644 httpServletResponse.setStatus(HttpServletResponse.SC_NOT_FOUND);
645 }
646 }
647
648
649
650
651
652
653
654
655 }
656
657 private static boolean isConnectionAbort(IOException e)
658 {
659 return e.getClass().getCanonicalName().equals("org.apache.catalina.connector.ClientAbortException");
660 }
661
662
663
664
665
666 private static int pipeBytes(InputStream in, OutputStream out, byte[] buffer)
667 throws IOException
668 {
669 int count = 0;
670 int length;
671
672 while ((length = (in.read(buffer))) >= 0)
673 {
674 out.write(buffer, 0, length);
675 count += length;
676 }
677 return count;
678 }
679
680 @Override
681 public boolean isResourceRequest(FacesContext facesContext)
682 {
683
684
685
686 Boolean value = (Boolean) facesContext.getAttributes().get(IS_RESOURCE_REQUEST);
687
688 if (value == null)
689 {
690 String resourceBasePath = getResourceHandlerSupport()
691 .calculateResourceBasePath(facesContext);
692
693 value = resourceBasePath != null
694 && resourceBasePath.startsWith(ResourceHandler.RESOURCE_IDENTIFIER);
695 facesContext.getAttributes().put(IS_RESOURCE_REQUEST, value);
696 }
697 return value;
698 }
699
700 protected String getLocalePrefixForLocateResource()
701 {
702 return getLocalePrefixForLocateResource(FacesContext.getCurrentInstance());
703 }
704
705 protected String getLocalePrefixForLocateResource(FacesContext context)
706 {
707 String localePrefix = null;
708 boolean isResourceRequest = context.getApplication().getResourceHandler().isResourceRequest(context);
709
710 if (isResourceRequest)
711 {
712 localePrefix = context.getExternalContext().getRequestParameterMap().get("loc");
713
714 if (localePrefix != null)
715 {
716 if (!ResourceValidationUtils.isValidLocalePrefix(localePrefix))
717 {
718 return null;
719 }
720 return localePrefix;
721 }
722 }
723
724 String bundleName = context.getApplication().getMessageBundle();
725
726 if (null != bundleName)
727 {
728 Locale locale = null;
729
730 if (isResourceRequest || context.getViewRoot() == null)
731 {
732 locale = context.getApplication().getViewHandler()
733 .calculateLocale(context);
734 }
735 else
736 {
737 locale = context.getViewRoot().getLocale();
738 }
739
740 try
741 {
742 ResourceBundle bundle = ResourceBundle
743 .getBundle(bundleName, locale, ClassUtils.getContextClassLoader());
744
745 if (bundle != null)
746 {
747 if (bundle.containsKey(ResourceHandler.LOCALE_PREFIX))
748 {
749 localePrefix = bundle.getString(ResourceHandler.LOCALE_PREFIX);
750 }
751 }
752 }
753 catch (MissingResourceException e)
754 {
755
756 }
757 }
758 return localePrefix;
759 }
760
761 protected String getContractNameForLocateResource(FacesContext context)
762 {
763 String contractName = null;
764 boolean isResourceRequest = context.getApplication().getResourceHandler().isResourceRequest(context);
765
766 if (isResourceRequest)
767 {
768 contractName = context.getExternalContext().getRequestParameterMap().get("con");
769 }
770
771
772 if (contractName == null)
773 {
774 contractName = (String) context.getAttributes().get(ContractResource.CONTRACT_SELECTED);
775 }
776
777
778 if (contractName != null &&
779 !ResourceValidationUtils.isValidContractName(contractName))
780 {
781 return null;
782 }
783 return contractName;
784 }
785
786 protected boolean isResourceIdentifierExcluded(FacesContext context, String resourceIdentifier)
787 {
788 if (_excludedResourceExtensions == null)
789 {
790 String value = WebConfigParamUtils.getStringInitParameter(context.getExternalContext(),
791 RESOURCE_EXCLUDES_PARAM_NAME,
792 RESOURCE_EXCLUDES_DEFAULT_VALUE);
793
794 _excludedResourceExtensions = StringUtils.splitShortString(value, ' ');
795 }
796
797 for (int i = 0; i < _excludedResourceExtensions.length; i++)
798 {
799 if (resourceIdentifier.endsWith(_excludedResourceExtensions[i]))
800 {
801 return true;
802 }
803 }
804 return false;
805 }
806
807
808
809
810
811
812
813 @Override
814 public boolean libraryExists(String libraryName)
815 {
816 FacesContext facesContext = FacesContext.getCurrentInstance();
817 String localePrefix = getLocalePrefixForLocateResource(facesContext);
818 final List<String> contracts = facesContext.getResourceLibraryContracts();
819
820 String pathToLib = null;
821 Boolean libraryFound = null;
822 if (libraryName != null && !ResourceValidationUtils.isValidLibraryName(
823 libraryName, isAllowSlashesLibraryName()))
824 {
825 return false;
826 }
827
828 if (localePrefix != null)
829 {
830
831 pathToLib = localePrefix + '/' + libraryName;
832
833 libraryFound = getResourceLoaderCache().libraryExists(pathToLib);
834 if (libraryFound != null)
835 {
836 return libraryFound.booleanValue();
837 }
838 }
839 libraryFound = getResourceLoaderCache().libraryExists(libraryName);
840 if (libraryFound != null)
841 {
842 return libraryFound.booleanValue();
843 }
844
845 if (localePrefix != null)
846 {
847 if (!contracts.isEmpty())
848 {
849 for (String contract : contracts)
850 {
851 for (ContractResourceLoader loader : getResourceHandlerSupport()
852 .getContractResourceLoaders())
853 {
854 if (loader.libraryExists(pathToLib, contract))
855 {
856 getResourceLoaderCache().confirmLibraryExists(pathToLib);
857 return true;
858 }
859 }
860 }
861 }
862
863 for (ResourceLoader loader : getResourceHandlerSupport()
864 .getResourceLoaders())
865 {
866 if (loader.libraryExists(pathToLib))
867 {
868 getResourceLoaderCache().confirmLibraryExists(pathToLib);
869 return true;
870 }
871 }
872 }
873
874
875 if (!contracts.isEmpty())
876 {
877 for (String contract : contracts)
878 {
879 for (ContractResourceLoader loader : getResourceHandlerSupport()
880 .getContractResourceLoaders())
881 {
882 if (loader.libraryExists(libraryName, contract))
883 {
884 getResourceLoaderCache().confirmLibraryExists(libraryName);
885 return true;
886 }
887 }
888 }
889 }
890
891 for (ResourceLoader loader : getResourceHandlerSupport()
892 .getResourceLoaders())
893 {
894 if (loader.libraryExists(libraryName))
895 {
896 getResourceLoaderCache().confirmLibraryExists(libraryName);
897 return true;
898 }
899 }
900
901 if (localePrefix != null)
902 {
903
904 getResourceLoaderCache().confirmLibraryNotExists(pathToLib);
905 }
906 else
907 {
908 getResourceLoaderCache().confirmLibraryNotExists(libraryName);
909 }
910 return false;
911 }
912
913
914
915
916
917 public void setResourceHandlerSupport(
918 ResourceHandlerSupport resourceHandlerSupport)
919 {
920 _resourceHandlerSupport = resourceHandlerSupport;
921 }
922
923
924
925
926 protected ResourceHandlerSupport getResourceHandlerSupport()
927 {
928 if (_resourceHandlerSupport == null)
929 {
930 _resourceHandlerSupport = new DefaultResourceHandlerSupport();
931 }
932 return _resourceHandlerSupport;
933 }
934
935 private ResourceHandlerCache getResourceLoaderCache()
936 {
937 if (_resourceHandlerCache == null)
938 {
939 _resourceHandlerCache = new ResourceHandlerCache();
940 }
941 return _resourceHandlerCache;
942 }
943
944 private String _getContentType(Resource resource, ExternalContext externalContext)
945 {
946 String contentType = resource.getContentType();
947
948
949 if (contentType == null || contentType.length() == 0)
950 {
951 String resourceName = getWrappedResourceName(resource);
952
953 if (resourceName != null)
954 {
955 contentType = externalContext.getMimeType(resourceName);
956 }
957 }
958
959 return contentType;
960 }
961
962
963
964
965
966
967
968
969 private String getWrappedResourceName(Resource resource)
970 {
971 String resourceName = resource.getResourceName();
972 if (resourceName != null)
973 {
974 return resourceName;
975 }
976
977 if (resource instanceof ResourceWrapper)
978 {
979 return getWrappedResourceName(((ResourceWrapper) resource).getWrapped());
980 }
981
982 return null;
983 }
984
985 protected boolean isAllowSlashesLibraryName()
986 {
987 if (_allowSlashLibraryName == null)
988 {
989 _allowSlashLibraryName = WebConfigParamUtils.getBooleanInitParameter(
990 FacesContext.getCurrentInstance().getExternalContext(),
991 INIT_PARAM_STRICT_JSF_2_ALLOW_SLASH_LIBRARY_NAME,
992 INIT_PARAM_STRICT_JSF_2_ALLOW_SLASH_LIBRARY_NAME_DEFAULT);
993 }
994 return _allowSlashLibraryName;
995 }
996
997 protected int getResourceBufferSize()
998 {
999 if (_resourceBufferSize == -1)
1000 {
1001 _resourceBufferSize = WebConfigParamUtils.getIntegerInitParameter(
1002 FacesContext.getCurrentInstance().getExternalContext(),
1003 INIT_PARAM_RESOURCE_BUFFER_SIZE,
1004 INIT_PARAM_RESOURCE_BUFFER_SIZE_DEFAULT);
1005 }
1006 return _resourceBufferSize;
1007 }
1008
1009 @Override
1010 public Resource createResourceFromId(String resourceId)
1011 {
1012 Resource resource = null;
1013
1014 if (resourceId == null)
1015 {
1016 throw new NullPointerException();
1017 }
1018
1019
1020
1021 if (!ResourceValidationUtils.isValidResourceId(resourceId))
1022 {
1023 return null;
1024 }
1025
1026 FacesContext facesContext = FacesContext.getCurrentInstance();
1027 final List<String> contracts = facesContext.getResourceLibraryContracts();
1028 String contractPreferred = getContractNameForLocateResource(facesContext);
1029 ResourceValue resourceValue = null;
1030
1031
1032
1033
1034
1035
1036
1037
1038 if (contractPreferred != null)
1039 {
1040 resourceValue = getResourceLoaderCache().getResource(
1041 resourceId, contractPreferred);
1042 }
1043 if (resourceValue == null && !contracts.isEmpty())
1044 {
1045
1046 for (String contract : contracts)
1047 {
1048 resourceValue = getResourceLoaderCache().getResource(resourceId, contract);
1049 if (resourceValue != null)
1050 {
1051 break;
1052 }
1053 }
1054 }
1055 if (resourceValue == null)
1056 {
1057
1058 resourceValue = getResourceLoaderCache().getResource(resourceId);
1059 }
1060
1061 if(resourceValue != null)
1062 {
1063
1064 String contentType = facesContext.getExternalContext().getMimeType(
1065 resourceValue.getResourceMeta().getResourceName());
1066
1067 resource = new ResourceImpl(resourceValue.getResourceMeta(), resourceValue.getResourceLoader(),
1068 getResourceHandlerSupport(), contentType,
1069 resourceValue.getCachedInfo() != null ? resourceValue.getCachedInfo().getURL() : null,
1070 resourceValue.getCachedInfo() != null ? resourceValue.getCachedInfo().getRequestPath() : null);
1071 }
1072 else
1073 {
1074 boolean resolved = false;
1075 if (contractPreferred != null)
1076 {
1077 for (ContractResourceLoader loader : getResourceHandlerSupport().getContractResourceLoaders())
1078 {
1079 ResourceMeta resourceMeta = deriveResourceMeta(
1080 facesContext, loader, resourceId, contractPreferred);
1081 if (resourceMeta != null)
1082 {
1083 String contentType = facesContext.getExternalContext().getMimeType(
1084 resourceMeta.getResourceName());
1085
1086 resource = new ResourceImpl(resourceMeta, loader,
1087 getResourceHandlerSupport(), contentType);
1088
1089
1090 getResourceLoaderCache().putResource(resourceId, resourceMeta, loader,
1091 new ResourceCachedInfo(resource.getURL(), resource.getRequestPath()));
1092
1093 resolved = true;
1094 break;
1095 }
1096 }
1097 }
1098 if (!resolved && !contracts.isEmpty())
1099 {
1100 for (ContractResourceLoader loader :
1101 getResourceHandlerSupport().getContractResourceLoaders())
1102 {
1103 for (String contract : contracts)
1104 {
1105 ResourceMeta resourceMeta = deriveResourceMeta(
1106 facesContext, loader, resourceId, contract);
1107 if (resourceMeta != null)
1108 {
1109 String contentType = facesContext.getExternalContext().getMimeType(
1110 resourceMeta.getResourceName());
1111
1112 resource = new ResourceImpl(resourceMeta, loader,
1113 getResourceHandlerSupport(), contentType);
1114
1115
1116 getResourceLoaderCache().putResource(resourceId, resourceMeta, loader,
1117 new ResourceCachedInfo(resource.getURL(), resource.getRequestPath()));
1118
1119 resolved = true;
1120 break;
1121 }
1122 }
1123 }
1124 }
1125 if (!resolved)
1126 {
1127 for (ResourceLoader loader : getResourceHandlerSupport().getResourceLoaders())
1128 {
1129 ResourceMeta resourceMeta = deriveResourceMeta(facesContext, loader, resourceId);
1130
1131 if (resourceMeta != null)
1132 {
1133 String contentType = facesContext.getExternalContext().getMimeType(
1134 resourceMeta.getResourceName());
1135
1136 resource = new ResourceImpl(resourceMeta, loader, getResourceHandlerSupport(), contentType);
1137
1138
1139 getResourceLoaderCache().putResource(resourceId, resourceMeta, loader,
1140 new ResourceCachedInfo(resource.getURL(), resource.getRequestPath()));
1141 break;
1142 }
1143 }
1144 }
1145 }
1146 return resource;
1147 }
1148
1149 protected ResourceMeta deriveResourceMeta(FacesContext context, ResourceLoader resourceLoader,
1150 String resourceId)
1151 {
1152 ResourceMeta resourceMeta = null;
1153 String token = null;
1154 String localePrefix = null;
1155 String libraryName = null;
1156 String libraryVersion = null;
1157 String resourceName = null;
1158 String resourceVersion = null;
1159
1160
1161
1162
1163
1164
1165
1166
1167 int lastSlash = resourceId.lastIndexOf('/');
1168 if (lastSlash < 0)
1169 {
1170
1171 resourceName = resourceId;
1172 }
1173 else
1174 {
1175 token = resourceId.substring(lastSlash+1);
1176 if (RESOURCE_VERSION_CHECKER.matcher(token).matches())
1177 {
1178 int secondLastSlash = resourceId.lastIndexOf('/', lastSlash-1);
1179 if (secondLastSlash < 0)
1180 {
1181 secondLastSlash = 0;
1182 }
1183
1184 String rnToken = resourceId.substring(secondLastSlash+1, lastSlash);
1185 int lastPoint = rnToken.lastIndexOf('.');
1186
1187 if (lastPoint >= 0)
1188 {
1189 String ext = rnToken.substring(lastPoint);
1190 if (token.endsWith(ext))
1191 {
1192
1193 resourceVersion = token.substring(0,token.length()-ext.length());
1194 }
1195 }
1196 }
1197
1198
1199 int start = 0;
1200 int firstSlash = resourceId.indexOf('/');
1201
1202
1203 String bundleName = context.getApplication().getMessageBundle();
1204
1205 if (null != bundleName)
1206 {
1207 token = resourceId.substring(start, firstSlash);
1208
1209 Locale locale = _LocaleUtils.deriveLocale(token);
1210
1211
1212
1213 if (locale != null && _LocaleUtils.isAvailableLocale(locale))
1214 {
1215 localePrefix = token;
1216 start = firstSlash+1;
1217 }
1218 }
1219
1220
1221 firstSlash = resourceId.indexOf('/', start);
1222 if (firstSlash < 0)
1223 {
1224
1225 resourceName = resourceId.substring(start);
1226 }
1227 else
1228 {
1229
1230 token = resourceId.substring(start, firstSlash);
1231 int minResourceNameSlash = (resourceVersion != null) ?
1232 resourceId.lastIndexOf('/', lastSlash-1) : lastSlash;
1233
1234 if (start < minResourceNameSlash)
1235 {
1236 libraryName = token;
1237 start = firstSlash+1;
1238
1239
1240 firstSlash = resourceId.indexOf('/', start);
1241 if (firstSlash >= 0)
1242 {
1243 token = resourceId.substring(start, firstSlash);
1244 if (LIBRARY_VERSION_CHECKER.matcher(token).matches())
1245 {
1246 libraryVersion = token;
1247 start = firstSlash+1;
1248 }
1249 }
1250 }
1251
1252 firstSlash = resourceId.indexOf('/', start);
1253 if (firstSlash < 0)
1254 {
1255
1256 resourceName = resourceId.substring(start);
1257 }
1258 else
1259 {
1260
1261 if (resourceVersion != null)
1262 {
1263 resourceName = resourceId.substring(start,lastSlash);
1264 }
1265 else
1266 {
1267
1268 resourceName = resourceId.substring(start);
1269 }
1270 }
1271 }
1272 }
1273
1274
1275 if (resourceName == null)
1276 {
1277 return null;
1278 }
1279 if (!ResourceValidationUtils.isValidResourceName(resourceName))
1280 {
1281 return null;
1282 }
1283
1284 if (libraryName != null && !ResourceValidationUtils.isValidLibraryName(
1285 libraryName, isAllowSlashesLibraryName()))
1286 {
1287 return null;
1288 }
1289
1290
1291 if (localePrefix != null && localePrefix.length() == 0)
1292 {
1293 localePrefix = null;
1294 }
1295 if (libraryName != null && libraryName.length() == 0)
1296 {
1297 libraryName = null;
1298 }
1299 if (libraryVersion != null && libraryVersion.length() == 0)
1300 {
1301 libraryVersion = null;
1302 }
1303 if (resourceName != null && resourceName.length() == 0)
1304 {
1305 resourceName = null;
1306 }
1307 if (resourceVersion != null && resourceVersion.length() == 0)
1308 {
1309 resourceVersion = null;
1310 }
1311
1312 resourceMeta = resourceLoader.createResourceMeta(
1313 localePrefix, libraryName, libraryVersion, resourceName, resourceVersion);
1314
1315 if (resourceMeta != null &&
1316 !resourceLoader.resourceExists(resourceMeta))
1317 {
1318 resourceMeta = null;
1319 }
1320
1321 return resourceMeta;
1322 }
1323
1324 protected ResourceMeta deriveResourceMeta(FacesContext context, ContractResourceLoader resourceLoader,
1325 String resourceId, String contractName)
1326 {
1327 ResourceMeta resourceMeta = null;
1328 String token = null;
1329 String localePrefix = null;
1330 String libraryName = null;
1331 String libraryVersion = null;
1332 String resourceName = null;
1333 String resourceVersion = null;
1334
1335
1336
1337
1338
1339
1340
1341
1342 int lastSlash = resourceId.lastIndexOf('/');
1343 if (lastSlash < 0)
1344 {
1345
1346 resourceName = resourceId;
1347 }
1348 else
1349 {
1350 token = resourceId.substring(lastSlash+1);
1351 if (RESOURCE_VERSION_CHECKER.matcher(token).matches())
1352 {
1353 int secondLastSlash = resourceId.lastIndexOf('/', lastSlash-1);
1354 if (secondLastSlash < 0)
1355 {
1356 secondLastSlash = 0;
1357 }
1358
1359 String rnToken = resourceId.substring(secondLastSlash+1, lastSlash);
1360 int lastPoint = rnToken.lastIndexOf('.');
1361
1362 if (lastPoint >= 0)
1363 {
1364 String ext = rnToken.substring(lastPoint);
1365 if (token.endsWith(ext))
1366 {
1367
1368 resourceVersion = token.substring(0,token.length()-ext.length());
1369 }
1370 }
1371 }
1372
1373
1374 int start = 0;
1375 int firstSlash = resourceId.indexOf('/');
1376
1377
1378 String bundleName = context.getApplication().getMessageBundle();
1379
1380 if (null != bundleName)
1381 {
1382 token = resourceId.substring(start, firstSlash);
1383
1384 Locale locale = _LocaleUtils.deriveLocale(token);
1385
1386
1387
1388 if (locale != null && _LocaleUtils.isAvailableLocale(locale))
1389 {
1390 localePrefix = token;
1391 start = firstSlash+1;
1392 }
1393 }
1394
1395
1396 firstSlash = resourceId.indexOf('/', start);
1397 if (firstSlash < 0)
1398 {
1399
1400 resourceName = resourceId.substring(start);
1401 }
1402 else
1403 {
1404
1405 token = resourceId.substring(start, firstSlash);
1406 int minResourceNameSlash = (resourceVersion != null) ?
1407 resourceId.lastIndexOf('/', lastSlash-1) : lastSlash;
1408
1409 if (start < minResourceNameSlash)
1410 {
1411 libraryName = token;
1412 start = firstSlash+1;
1413
1414
1415 firstSlash = resourceId.indexOf('/', start);
1416 if (firstSlash >= 0)
1417 {
1418 token = resourceId.substring(start, firstSlash);
1419 if (LIBRARY_VERSION_CHECKER.matcher(token).matches())
1420 {
1421 libraryVersion = token;
1422 start = firstSlash+1;
1423 }
1424 }
1425 }
1426
1427 firstSlash = resourceId.indexOf('/', start);
1428 if (firstSlash < 0)
1429 {
1430
1431 resourceName = resourceId.substring(start);
1432 }
1433 else
1434 {
1435
1436 if (resourceVersion != null)
1437 {
1438 resourceName = resourceId.substring(start,lastSlash);
1439 }
1440 else
1441 {
1442
1443 resourceName = resourceId.substring(start);
1444 }
1445 }
1446 }
1447 }
1448
1449
1450 if (resourceName == null)
1451 {
1452 return null;
1453 }
1454 if (!ResourceValidationUtils.isValidResourceName(resourceName))
1455 {
1456 return null;
1457 }
1458
1459 if (libraryName != null && !ResourceValidationUtils.isValidLibraryName(
1460 libraryName, isAllowSlashesLibraryName()))
1461 {
1462 return null;
1463 }
1464
1465
1466 if (localePrefix != null && localePrefix.length() == 0)
1467 {
1468 localePrefix = null;
1469 }
1470 if (libraryName != null && libraryName.length() == 0)
1471 {
1472 libraryName = null;
1473 }
1474 if (libraryVersion != null && libraryVersion.length() == 0)
1475 {
1476 libraryVersion = null;
1477 }
1478 if (resourceName != null && resourceName.length() == 0)
1479 {
1480 resourceName = null;
1481 }
1482 if (resourceVersion != null && resourceVersion.length() == 0)
1483 {
1484 resourceVersion = null;
1485 }
1486
1487 resourceMeta = resourceLoader.createResourceMeta(
1488 localePrefix, libraryName, libraryVersion, resourceName, resourceVersion, contractName);
1489
1490 if (resourceMeta != null &&
1491 !resourceLoader.resourceExists(resourceMeta))
1492 {
1493 resourceMeta = null;
1494 }
1495
1496 return resourceMeta;
1497 }
1498
1499 protected ResourceMeta deriveViewResourceMeta(FacesContext context, ResourceLoader resourceLoader,
1500 String resourceName, String localePrefix)
1501 {
1502 ResourceMeta resourceMeta = null;
1503 String resourceVersion = null;
1504
1505
1506 if (localePrefix != null)
1507 {
1508 resourceVersion = resourceLoader
1509 .getResourceVersion(localePrefix + '/'+ resourceName);
1510 if (!(resourceVersion != null && ResourceLoader.VERSION_INVALID.equals(resourceVersion)))
1511 {
1512 resourceMeta = resourceLoader.createResourceMeta(localePrefix, null, null,
1513 resourceName, resourceVersion);
1514 }
1515
1516 if (resourceMeta != null && !resourceLoader.resourceExists(resourceMeta))
1517 {
1518 resourceMeta = null;
1519 }
1520 }
1521
1522
1523 if (resourceMeta == null)
1524 {
1525 resourceVersion = resourceLoader
1526 .getResourceVersion(resourceName);
1527 if (!(resourceVersion != null && ResourceLoader.VERSION_INVALID.equals(resourceVersion)))
1528 {
1529 resourceMeta = resourceLoader.createResourceMeta(null, null, null,
1530 resourceName, resourceVersion);
1531 }
1532
1533 if (resourceMeta != null && !resourceLoader.resourceExists(resourceMeta))
1534 {
1535 resourceMeta = null;
1536 }
1537 }
1538
1539 return resourceMeta;
1540 }
1541
1542 protected ResourceMeta deriveViewResourceMeta(FacesContext context, ContractResourceLoader resourceLoader,
1543 String resourceName, String localePrefix, String contractName)
1544 {
1545 ResourceMeta resourceMeta = null;
1546 String resourceVersion = null;
1547
1548
1549 if (localePrefix != null)
1550 {
1551 resourceVersion = resourceLoader
1552 .getResourceVersion(localePrefix + '/'+ resourceName, contractName);
1553 if (!(resourceVersion != null && ResourceLoader.VERSION_INVALID.equals(resourceVersion)))
1554 {
1555 resourceMeta = resourceLoader.createResourceMeta(localePrefix, null, null,
1556 resourceName, resourceVersion, contractName);
1557 }
1558
1559 if (resourceMeta != null && !resourceLoader.resourceExists(resourceMeta))
1560 {
1561 resourceMeta = null;
1562 }
1563 }
1564
1565
1566 if (resourceMeta == null)
1567 {
1568 resourceVersion = resourceLoader
1569 .getResourceVersion(resourceName, contractName);
1570 if (!(resourceVersion != null && ResourceLoader.VERSION_INVALID.equals(resourceVersion)))
1571 {
1572 resourceMeta = resourceLoader.createResourceMeta(null, null, null,
1573 resourceName, resourceVersion, contractName);
1574 }
1575
1576 if (resourceMeta != null && !resourceLoader.resourceExists(resourceMeta))
1577 {
1578 resourceMeta = null;
1579 }
1580 }
1581
1582 return resourceMeta;
1583 }
1584
1585 @Override
1586 public Resource createViewResource(FacesContext facesContext, String resourceName)
1587 {
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609 Resource resource = null;
1610
1611 if (resourceName == null)
1612 {
1613 throw new NullPointerException();
1614 }
1615 if (resourceName.charAt(0) == '/')
1616 {
1617
1618
1619
1620 resourceName = resourceName.substring(1);
1621 }
1622
1623
1624
1625 if (!ResourceValidationUtils.isValidViewResource(resourceName))
1626 {
1627 return null;
1628 }
1629 final String localePrefix = getLocalePrefixForLocateResource(facesContext);
1630 String contentType = facesContext.getExternalContext().getMimeType(resourceName);
1631 final List<String> contracts = facesContext.getResourceLibraryContracts();
1632 String contractPreferred = getContractNameForLocateResource(facesContext);
1633 ResourceValue resourceValue = null;
1634
1635
1636
1637
1638
1639
1640
1641
1642 if (contractPreferred != null)
1643 {
1644 resourceValue = getResourceLoaderCache().getViewResource(
1645 resourceName, contentType, localePrefix, contractPreferred);
1646 }
1647 if (resourceValue == null && !contracts.isEmpty())
1648 {
1649
1650 for (String contract : contracts)
1651 {
1652 resourceValue = getResourceLoaderCache().getViewResource(
1653 resourceName, contentType, localePrefix, contract);
1654 if (resourceValue != null)
1655 {
1656 break;
1657 }
1658 }
1659 }
1660 if (resourceValue == null)
1661 {
1662
1663 resourceValue = getResourceLoaderCache().getViewResource(
1664 resourceName, contentType, localePrefix);
1665 }
1666
1667 if(resourceValue != null)
1668 {
1669 resource = new ResourceImpl(resourceValue.getResourceMeta(), resourceValue.getResourceLoader(),
1670 getResourceHandlerSupport(), contentType,
1671 resourceValue.getCachedInfo() != null ? resourceValue.getCachedInfo().getURL() : null, null);
1672 }
1673 else
1674 {
1675 boolean resolved = false;
1676 if (contractPreferred != null)
1677 {
1678 for (ContractResourceLoader loader : getResourceHandlerSupport().getContractResourceLoaders())
1679 {
1680 ResourceMeta resourceMeta = deriveViewResourceMeta(
1681 facesContext, loader, resourceName, localePrefix, contractPreferred);
1682 if (resourceMeta != null)
1683 {
1684 resource = new ResourceImpl(resourceMeta, loader,
1685 getResourceHandlerSupport(), contentType);
1686
1687
1688 getResourceLoaderCache().putViewResource(
1689 resourceName, contentType, localePrefix, contractPreferred, resourceMeta, loader,
1690 new ResourceCachedInfo(resource.getURL(), null));
1691
1692 resolved = true;
1693 break;
1694 }
1695 }
1696 }
1697 if (!resolved && !contracts.isEmpty())
1698 {
1699 for (ContractResourceLoader loader :
1700 getResourceHandlerSupport().getContractResourceLoaders())
1701 {
1702 for (String contract : contracts)
1703 {
1704 ResourceMeta resourceMeta = deriveViewResourceMeta(
1705 facesContext, loader, resourceName, localePrefix, contract);
1706 if (resourceMeta != null)
1707 {
1708 resource = new ResourceImpl(resourceMeta, loader,
1709 getResourceHandlerSupport(), contentType);
1710
1711
1712 getResourceLoaderCache().putViewResource(
1713 resourceName, contentType, localePrefix, contract, resourceMeta, loader,
1714 new ResourceCachedInfo(resource.getURL(), null));
1715
1716 resolved = true;
1717 break;
1718 }
1719 }
1720 }
1721 }
1722 if (!resolved)
1723 {
1724
1725
1726
1727
1728 for (ResourceLoader loader : getResourceHandlerSupport().getViewResourceLoaders())
1729 {
1730 ResourceMeta resourceMeta = deriveViewResourceMeta(
1731 facesContext, loader, resourceName, localePrefix);
1732
1733 if (resourceMeta != null)
1734 {
1735 resource = new ResourceImpl(resourceMeta, loader, getResourceHandlerSupport(), contentType);
1736
1737
1738 getResourceLoaderCache().putViewResource(
1739 resourceName, contentType, localePrefix, resourceMeta, loader,
1740 new ResourceCachedInfo(resource.getURL(), null));
1741 break;
1742 }
1743 }
1744 }
1745 }
1746 return resource;
1747 }
1748
1749 }