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 }