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.renderkit.html.util;
20  
21  import javax.faces.context.FacesContext;
22  
23  /**
24   * A ResourceHandler which always generates URLs that trigger the
25   * MyfacesResourceLoader to load resources from the classpath
26   * relative to some Tomahawk class.
27   * <p>
28   * This is intended to support loading of Tomahawk resources only;
29   * applications which wish to use the Tomahawk AddResources framework
30   * for loading resources from elsewhere should implement their own
31   * ResourceHandler class.
32   * 
33   * @author Mathias Broekelmann
34   */
35  public class MyFacesResourceHandler implements ResourceHandler
36  {
37      private final Class _myfacesCustomComponent;
38      private final String _resource;
39  
40      /**
41       * Constructor.
42       * 
43       * @param myfacesCustomComponent is a class that must be in package
44       *   org.apache.myfaces.custom. The resource to be served will be
45       *   located relative to this class in the classpath. Note that code
46       *   wishing to serve resources from other locations in the classpath
47       *   must write a custom ResourceHandler implementation.
48       *   
49       * @param resourceName is the name of a file that can be found in dir
50       *  "resource/{resourceName} relative to the location of the specified
51       *  component class in the classpath. Because the resource is always
52       *  relative to a class file, it must never begin with a slash. 
53       */
54      public MyFacesResourceHandler(Class myfacesCustomComponent, String resourceName)
55      {
56          validateCustomComponent(myfacesCustomComponent);
57          _myfacesCustomComponent = myfacesCustomComponent;
58          _resource = resourceName;
59      }
60      
61      /**
62       * Return a Class object which can decode the url generated by this
63       * class in the getResourceUri method and use that info to locate
64       * the resource data represented by this object.
65       * 
66       * @see ResourceHandler#getResourceLoaderClass()
67       */
68      public Class getResourceLoaderClass()
69      {
70          return MyFacesResourceLoader.class;
71      }
72  
73      /**
74       * Verify that the base class for the resource lookup is in the 
75       * org.apache.myfaces.custom package.
76       * 
77       * @param myfacesCustomComponent is the base component for the lookup.
78       * @throws IllegalArgumentException if the class is not in the expected package. 
79       */
80      protected void validateCustomComponent(Class myfacesCustomComponent)
81      {
82          if (!myfacesCustomComponent.getName().startsWith(
83                  MyFacesResourceLoader.ORG_APACHE_MYFACES_CUSTOM + "."))
84          {
85              throw new IllegalArgumentException(
86                      "expected a myfaces custom component class in package "
87                              + MyFacesResourceLoader.ORG_APACHE_MYFACES_CUSTOM);
88          }
89      }
90  
91      /**
92       * Return a URL that the browser can later submit to retrieve the resource
93       * handled by this instance.
94       * <p>
95       * The emitted URL is of form:
96       * <pre>
97       *   {partial.class.name}/{resourceName}
98       * </pre>
99       * where partial.class.name is the name of the base class specified in the
100      * constructor, and resourceName is the resource specified in the constructor.
101      * 
102      * @see org.apache.myfaces.shared.renderkit.html.util.ResourceHandler#getResourceUri(javax.faces.context.FacesContext)
103      */
104     public String getResourceUri(FacesContext context)
105     {
106         String className = _myfacesCustomComponent.getName();
107         StringBuffer sb = new StringBuffer();
108         sb.append(className.substring(
109             MyFacesResourceLoader.ORG_APACHE_MYFACES_CUSTOM.length() + 1));
110         sb.append("/");
111         if (_resource != null)
112         {
113             if (_resource.startsWith("/"))
114             {
115                 throw new IllegalArgumentException(
116                     "Tomahawk resources are always relative to the associated class." +
117                     " Absolute resource paths are not allowed: " + _resource);
118             }
119             sb.append(_resource);
120         }
121         return sb.toString();
122     }
123 }