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.resource;
20  
21  import java.io.InputStream;
22  import java.net.URL;
23  
24  import javax.faces.application.ProjectStage;
25  import javax.faces.context.FacesContext;
26  
27  import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFWebConfigParam;
28  import org.apache.myfaces.shared.resource.AliasResourceMetaImpl;
29  import org.apache.myfaces.shared.resource.ResourceLoader;
30  import org.apache.myfaces.shared.resource.ResourceMeta;
31  import org.apache.myfaces.shared.resource.ResourceMetaImpl;
32  import org.apache.myfaces.shared.util.ClassUtils;
33  import org.apache.myfaces.shared.util.WebConfigParamUtils;
34  import org.apache.myfaces.shared.renderkit.html.util.ResourceUtils;
35  
36  /**
37   * A resource loader implementation which loads resources from the thread ClassLoader.
38   */
39  public class InternalClassLoaderResourceLoader extends ResourceLoader
40  {
41  
42      /**
43       * If this param is true and the project stage is development mode,
44       * the source javascript files will be loaded separately instead have
45       * all in just one file, to preserve line numbers and make javascript
46       * debugging of the default jsf javascript file more simple.
47       */
48      @JSFWebConfigParam(since = "2.0.1", defaultValue = "false", expectedValues = "true,false", group = "render")
49      public static final String USE_MULTIPLE_JS_FILES_FOR_JSF_UNCOMPRESSED_JS = "org.apache.myfaces.USE_MULTIPLE_JS_FILES_FOR_JSF_UNCOMPRESSED_JS";
50  
51      /**
52       * Define the mode used for jsf.js file:
53       * <ul>
54       * <li>normal : contains everything, including jsf-i18n.js, jsf-experimental.js and jsf-legacy.js</li>
55       * <li>minimal-modern : is the core jsf with a baseline of ie9+, without jsf-i18n.js, jsf-experimental.js and jsf-legacy.js</li>
56       * <li>minimal: which is the same with a baseline of ie6, without jsf-i18n.js, jsf-experimental.js</li>
57       * </ul>
58       * <p>If org.apache.myfaces.USE_MULTIPLE_JS_FILES_FOR_JSF_UNCOMPRESSED_JS param is set to true and project stage
59       * is Development, this param is ignored.</p>
60       */
61      @JSFWebConfigParam(since = "2.0.10,2.1.4", defaultValue = "normal", expectedValues = "normal, minimal-modern, minimal",
62              group = "render")
63      public static final String MYFACES_JSF_MODE = "org.apache.myfaces.JSF_JS_MODE";
64      
65      private final boolean _useMultipleJsFilesForJsfUncompressedJs;
66      private final String _jsfMode;
67      private final boolean _developmentStage;
68  
69      public InternalClassLoaderResourceLoader(String prefix)
70      {
71          super(prefix);
72          _useMultipleJsFilesForJsfUncompressedJs = WebConfigParamUtils.getBooleanInitParameter(FacesContext.getCurrentInstance().getExternalContext(),
73                  USE_MULTIPLE_JS_FILES_FOR_JSF_UNCOMPRESSED_JS, false);
74  
75          _jsfMode = WebConfigParamUtils.getStringInitParameter(FacesContext.getCurrentInstance().getExternalContext(), MYFACES_JSF_MODE, 
76                  ResourceUtils.JSF_MYFACES_JSFJS_NORMAL);
77          _developmentStage = FacesContext.getCurrentInstance().isProjectStage(ProjectStage.Development);
78      }
79  
80      @Override
81      public String getLibraryVersion(String path)
82      {
83          return null;
84      }
85  
86      @Override
87      public InputStream getResourceInputStream(ResourceMeta resourceMeta)
88      {
89          InputStream is;
90          if (getPrefix() != null && !"".equals(getPrefix()))
91          {
92              String name = getPrefix() + '/' + resourceMeta.getResourceIdentifier();
93              is = getClassLoader().getResourceAsStream(name);
94              if (is == null)
95              {
96                  is = this.getClass().getClassLoader().getResourceAsStream(name);
97              }
98              return is;
99          }
100         else
101         {
102             is = getClassLoader().getResourceAsStream(resourceMeta.getResourceIdentifier());
103             if (is == null)
104             {
105                 is = this.getClass().getClassLoader().getResourceAsStream(resourceMeta.getResourceIdentifier());
106             }
107             return is;
108         }
109     }
110 
111     @Override
112     public URL getResourceURL(ResourceMeta resourceMeta)
113     {
114         URL url;
115         if (getPrefix() != null && !"".equals(getPrefix()))
116         {
117             String name = getPrefix() + '/' + resourceMeta.getResourceIdentifier();
118             url = getClassLoader().getResource(name);
119             if (url == null)
120             {
121                 url = this.getClass().getClassLoader().getResource(name);
122             }
123             return url;
124         }
125         else
126         {
127             url = getClassLoader().getResource(resourceMeta.getResourceIdentifier());
128             if (url == null)
129             {
130                 url = this.getClass().getClassLoader().getResource(resourceMeta.getResourceIdentifier());
131             }
132             return url;
133         }
134     }
135 
136     @Override
137     public String getResourceVersion(String path)
138     {
139         return null;
140     }
141 
142     @Override
143     public ResourceMeta createResourceMeta(String prefix, String libraryName, String libraryVersion,
144                                            String resourceName, String resourceVersion)
145     {
146         //handle jsf.js
147         final boolean javaxFacesLib = libraryName != null &&
148         ResourceUtils.JAVAX_FACES_LIBRARY_NAME.equals(libraryName);
149         final boolean javaxFaces = javaxFacesLib &&
150                 ResourceUtils.JSF_JS_RESOURCE_NAME.equals(resourceName);
151 
152         if (javaxFaces)
153         {
154             if (_developmentStage)
155             {
156                 if (_useMultipleJsFilesForJsfUncompressedJs)
157                 {
158                     return new AliasResourceMetaImpl(prefix, libraryName, libraryVersion,
159                             resourceName, resourceVersion, ResourceUtils.JSF_UNCOMPRESSED_JS_RESOURCE_NAME, true);
160                 }
161                 else
162                 {
163                     //normall we would have to take care about the standard jsf.js case also
164                     //but our standard resource loader takes care of it, because this part is only called in debugging mode
165                     //in production only in debugging
166                     return new AliasResourceMetaImpl(prefix, libraryName, libraryVersion, resourceName, resourceVersion, "jsf-uncompressed-full.js", false);
167                 }
168             }
169             else if (_jsfMode.equals(ResourceUtils.JSF_MYFACES_JSFJS_MINIMAL) )
170             {
171                 return new AliasResourceMetaImpl(prefix, libraryName, libraryVersion, resourceName, resourceVersion,
172                         ResourceUtils.JSF_MINIMAL_JS_RESOURCE_NAME, false);
173             }
174             else if (_jsfMode.equals(ResourceUtils.JSF_MYFACES_JSFJS_MINIMAL_MODERN) )
175             {
176                 return new AliasResourceMetaImpl(prefix, libraryName, libraryVersion, resourceName, resourceVersion,
177                         ResourceUtils.JSF_MINIMAL_MODERN_JS_RESOURCE_NAME, false);
178             }
179             else
180             {
181                 return null;
182             }
183         }
184         else if (javaxFacesLib && !_developmentStage && !_jsfMode.equals(ResourceUtils.JSF_MYFACES_JSFJS_NORMAL) &&
185                                    (ResourceUtils.JSF_MYFACES_JSFJS_I18N.equals(resourceName) ||
186                                    ResourceUtils.JSF_MYFACES_JSFJS_EXPERIMENTAL.equals(resourceName) ||
187                                    ResourceUtils.JSF_MYFACES_JSFJS_LEGACY.equals(resourceName)) )
188         {
189             return new ResourceMetaImpl(prefix, libraryName, libraryVersion, resourceName, resourceVersion);
190         }
191         else if (_developmentStage && libraryName != null &&
192                 ResourceUtils.MYFACES_LIBRARY_NAME.equals(libraryName) &&
193                 ResourceUtils.MYFACES_JS_RESOURCE_NAME.equals(resourceName))
194         {
195             //handle the oamSubmit.js
196             return new AliasResourceMetaImpl(prefix, libraryName, libraryVersion,
197                     resourceName, resourceVersion, ResourceUtils.MYFACES_JS_RESOURCE_NAME_UNCOMPRESSED, true);
198         }
199         else if (_developmentStage && libraryName != null && libraryName.startsWith("org.apache.myfaces.core"))
200         {
201             return new ResourceMetaImpl(prefix, libraryName, libraryVersion, resourceName, resourceVersion);
202         }
203         else
204         {
205             return null;
206         }
207     }
208 
209     /**
210      * Returns the ClassLoader to use when looking up resources under the top level package. By default, this is the
211      * context class loader.
212      *
213      * @return the ClassLoader used to lookup resources
214      */
215     protected ClassLoader getClassLoader()
216     {
217         return ClassUtils.getContextClassLoader();
218     }
219 
220     @Override
221     public boolean libraryExists(String libraryName)
222     {
223         if (getPrefix() != null && !"".equals(getPrefix()))
224         {
225             URL url = getClassLoader().getResource(getPrefix() + '/' + libraryName);
226             if (url == null)
227             {
228                 url = this.getClass().getClassLoader().getResource(getPrefix() + '/' + libraryName);
229             }
230             if (url != null)
231             {
232                 return true;
233             }
234         }
235         else
236         {
237             URL url = getClassLoader().getResource(libraryName);
238             if (url == null)
239             {
240                 url = this.getClass().getClassLoader().getResource(libraryName);
241             }
242             if (url != null)
243             {
244                 return true;
245             }
246         }
247         return false;
248     }
249 
250 }