2009/05/20 - Apache Shale has been retired.

For more information, please explore the Attic.

View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to you under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  
18  package org.apache.shale.remoting.impl;
19  
20  import java.lang.reflect.Method;
21  import java.net.URL;
22  import java.util.ResourceBundle;
23  import javax.faces.context.FacesContext;
24  import org.apache.commons.logging.Log;
25  import org.apache.commons.logging.LogFactory;
26  import org.apache.shale.remoting.Constants;
27  import org.apache.shale.remoting.Processor;
28  
29  /***
30   * <p>Implementation of {@link Processor} which serves resources from the
31   * web application's static resources.  View identifiers shoud be a fully
32   * qualified path, beginning with a slash ("/") character (for example,
33   * <code>/org/apache/shale/remoting/MyResource.css</code>).</p>
34   */
35  public class WebResourceProcessor extends AbstractResourceProcessor {
36  
37  
38      // ------------------------------------------------------------ Constructors
39  
40  
41      // ------------------------------------------------------ Instance Variables
42  
43  
44      /***
45       * <p><code>ResourceBundle</code> containing our localized messages.</p>
46       */
47      private ResourceBundle bundle = ResourceBundle.getBundle("org.apache.shale.remoting.Bundle");
48  
49  
50      /***
51       * <p>Log instance for this class.</p>
52       */
53      private transient Log log = null;
54  
55  
56      // -------------------------------------------------------------- Properties
57  
58  
59      /***
60       * <p>Force our default excludes list to be included.</p>
61       *
62       * @param excludes Application specified excludes list
63       */
64      public void setExcludes(String excludes) {
65  
66          if ((excludes != null) && (excludes.length() > 0)) {
67              super.setExcludes(Constants.WEBAPP_RESOURCES_EXCLUDES_DEFAULT
68                                + "," + excludes);
69          } else {
70              super.setExcludes(Constants.WEBAPP_RESOURCES_EXCLUDES_DEFAULT);
71          }
72  
73      }
74  
75  
76      // -------------------------------------------------------- Abstract Methods
77  
78  
79      /*** {@inheritDoc} */
80      protected URL getResourceURL(FacesContext context, String resourceId) {
81  
82          // Disallow access to resources in reserved directories
83          String resourceIdUpper = resourceId.toUpperCase();
84          if (resourceIdUpper.startsWith("/WEB-INF") || resourceIdUpper.startsWith("/META-INF")) {
85              if (log().isWarnEnabled()) {
86                  log().warn(bundle.getString("resource.refuse"));
87                  log().warn(resourceId);
88              }
89              return null;
90          }
91  
92          // Disallow access to JSP and JSP fragment sources
93          if (resourceIdUpper.endsWith(".JSP") || resourceIdUpper.endsWith(".JSPF")) {
94              if (log().isWarnEnabled()) {
95                  log().warn(bundle.getString("resource.refuse"));
96                  log().warn(resourceId);
97              }
98              return null;
99          }
100 
101         // Call getResource() on the ServletContext or PortletContext instance
102         Object ctxt = context.getExternalContext().getContext();
103         try {
104             Method method =
105                     ctxt.getClass().getMethod("getResource",
106                                                new Class[] { String.class });
107             URL url = (URL) method.invoke(ctxt, new Object[] { resourceId });
108             if (log.isDebugEnabled()) {
109                 log.debug("getResource(" + resourceId + ") --> " + url);
110             }
111             return url;
112         } catch (Exception e) {
113             if (log().isErrorEnabled()) {
114                 log().error(bundle.getString("resource.exception"), e);
115                 log().error(resourceId);
116             }
117             return null;
118         }
119 
120     }
121 
122 
123 
124     // --------------------------------------------------------- Private Methods
125 
126 
127 
128     /***
129      * <p>Return the <code>Log</code> instance to use, creating one if needed.</p>
130      */
131     private Log log() {
132 
133         if (this.log == null) {
134             log = LogFactory.getLog(WebResourceProcessor.class);
135         }
136         return log;
137 
138     }
139 
140 
141 }