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