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.MalformedURLException;
23  import java.net.URL;
24  import java.util.Iterator;
25  import java.util.Set;
26  import javax.faces.application.ResourceHandler;
27  import javax.faces.application.ResourceVisitOption;
28  
29  import javax.faces.context.FacesContext;
30  import org.apache.myfaces.shared.resource.ExternalContextResourceLoaderIterator;
31  import org.apache.myfaces.shared.resource.ResourceLoader;
32  import org.apache.myfaces.shared.resource.ResourceMeta;
33  import org.apache.myfaces.shared.resource.ResourceMetaImpl;
34  import org.apache.myfaces.shared.util.WebConfigParamUtils;
35  import org.apache.myfaces.util.SkipMatchIterator;
36  
37  /**
38   * A resource loader implementation which loads resources from the webapp root.
39   * It uses the methods on ExternalContext for handle resources.
40   * 
41   */
42  public class RootExternalContextResourceLoader extends ResourceLoader
43  {
44      private static final String CONTRACTS = "contracts";
45      
46      private static final String RESOURCES = "resources";
47      
48      private String contractsDirectory = null;
49      
50      private String resourcesDirectory = null;
51  
52      public RootExternalContextResourceLoader()
53      {
54          super("");
55          FacesContext facesContext = FacesContext.getCurrentInstance();
56          contractsDirectory = WebConfigParamUtils.getStringInitParameter(facesContext.getExternalContext(), 
57                  ResourceHandler.WEBAPP_CONTRACTS_DIRECTORY_PARAM_NAME, CONTRACTS);
58          contractsDirectory = contractsDirectory.startsWith("/") ? contractsDirectory : '/'+contractsDirectory;
59          
60          resourcesDirectory = WebConfigParamUtils.getStringInitParameter(facesContext.getExternalContext(), 
61              ResourceHandler.WEBAPP_RESOURCES_DIRECTORY_PARAM_NAME, RESOURCES);
62          resourcesDirectory = resourcesDirectory.startsWith("/") ? resourcesDirectory : '/'+resourcesDirectory;
63      }
64  
65      protected Set<String> getResourcePaths(String path)
66      {
67          String correctedPath = path.startsWith("/") ? path : '/' + path;
68  
69          return FacesContext.getCurrentInstance().getExternalContext().getResourcePaths(correctedPath);
70      }
71  
72      @Override
73      public String getResourceVersion(String path)
74      {
75          return null;
76      }
77  
78      @Override
79      public String getLibraryVersion(String path)
80      {
81          return null;
82      }
83  
84      //@Override
85      public URL getResourceURL(String resourceId)
86      {
87          try
88          {
89              String correctedResourceId = resourceId.startsWith("/") ? resourceId : "/"+resourceId;
90  
91              return FacesContext.getCurrentInstance().getExternalContext().getResource(
92                  correctedResourceId);
93  
94          }
95          catch (MalformedURLException e)
96          {
97              return null;
98          }
99      }
100     
101     @Override
102     public URL getResourceURL(ResourceMeta resourceMeta)
103     {
104         if (resourceMeta.getLocalePrefix() != null)
105         {
106             // the webapp root folder cannot be localized, 
107             // but if the resource lives in /contracts/[contract-name] it can be.
108             return null;
109         }
110         return getResourceURL(resourceMeta.getResourceIdentifier());
111     }
112 
113     @Override
114     public InputStream getResourceInputStream(ResourceMeta resourceMeta)
115     {
116         String resourceId = resourceMeta.getResourceIdentifier();
117         String correctedResourceId = resourceId.startsWith("/") ? resourceId : "/"+resourceId;
118 
119         return FacesContext.getCurrentInstance().getExternalContext().getResourceAsStream(correctedResourceId);
120     }
121 
122     @Override
123     public ResourceMeta createResourceMeta(String prefix, String libraryName, String libraryVersion,
124                                            String resourceName, String resourceVersion)
125     {
126         return new ResourceMetaImpl(prefix, libraryName, libraryVersion, resourceName, resourceVersion);
127     }
128 
129     @Override
130     public boolean libraryExists(String libraryName)
131     {
132         //No library can be created in root resolver
133         return false;
134     }
135     
136     @Override
137     public Iterator<String> iterator(FacesContext facesContext, 
138             String path, int maxDepth, ResourceVisitOption... options)
139     {
140         String basePath = path;
141         
142         if (getPrefix() != null)
143         {
144             basePath = getPrefix() + '/' + (path.startsWith("/") ? path.substring(1) : path);
145         }
146         
147         return new RootExternalContextResourceLoaderIterator(
148                 new ExternalContextResourceLoaderIterator(facesContext, basePath, maxDepth, options), 
149                     this.contractsDirectory, this.resourcesDirectory);
150     }
151     
152     private static class RootExternalContextResourceLoaderIterator extends SkipMatchIterator<String>
153     {
154         private String contractsDirectory;
155         private String resourcesDirectory;
156         
157         public RootExternalContextResourceLoaderIterator(Iterator delegate, String contractsDirectory, 
158                 String resourcesDirectory)
159         {
160             super(delegate);
161             this.contractsDirectory = contractsDirectory;
162             this.resourcesDirectory = resourcesDirectory;
163         }
164 
165         @Override
166         protected boolean match(String instance)
167         {
168             return instance.startsWith(contractsDirectory) || instance.startsWith(resourcesDirectory);
169         }
170     }
171 }