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.custom.stylesheet;
20
21 import java.io.IOException;
22
23 import javax.faces.FacesException;
24 import javax.faces.component.UIComponent;
25 import javax.faces.context.FacesContext;
26 import javax.faces.context.ResponseWriter;
27
28 import org.apache.myfaces.custom.stylesheet.TextResourceFilter.ResourceInfo;
29 import org.apache.myfaces.renderkit.html.util.AddResourceFactory;
30 import org.apache.myfaces.shared_tomahawk.renderkit.RendererUtils;
31 import org.apache.myfaces.shared_tomahawk.renderkit.html.HtmlRenderer;
32
33 /**
34 * @JSFRenderer
35 * renderKitId = "HTML_BASIC"
36 * family = "javax.faces.Output"
37 * type = "org.apache.myfaces.Stylesheet"
38 *
39 * @author mwessendorf (latest modification by $Author: skitching $)
40 * @version $Revision: 671131 $ $Date: 2008-06-24 06:19:43 -0500 (Tue, 24 Jun 2008) $
41 */
42 public class StylesheetRenderer extends HtmlRenderer
43 {
44 public void encodeEnd(FacesContext context, UIComponent component)
45 throws IOException, FacesException
46 {
47
48 if ((context == null) || (component == null))
49 {
50 throw new NullPointerException();
51 }
52 Stylesheet stylesheet = (Stylesheet) component;
53 ResponseWriter writer = context.getResponseWriter();
54
55 String path = stylesheet.getPath();
56
57 if (stylesheet.isInline())
58 {
59 //include as inline css
60
61 if (!path.startsWith("/"))
62 {
63 throw new FacesException("Inline stylesheets require absolute resource path");
64 }
65
66 writer.startElement("style", component);
67 writer.writeAttribute("type", "text/css", null);
68 if (stylesheet.getMedia() != null)
69 {
70 writer.writeAttribute("media", stylesheet.getMedia(), null);
71 }
72
73 Object text;
74 if (stylesheet.isFiltered())
75 {
76 // Load, filter and cache the resource. Then return the cached data.
77 ResourceInfo info = TextResourceFilter.getInstance(context).getOrCreateFilteredResource(context, path);
78 text = info.getText();
79 }
80 else
81 {
82 // Just load the data (not cached)
83 text = RendererUtils.loadResourceFile(context, path);
84 }
85 if (text != null)
86 {
87 writer.writeText(text, null);
88 }
89 writer.endElement("style");
90 }
91 else
92 {
93 //refere as link-element
94 writer.startElement("link", component);
95 writer.writeAttribute("rel", "stylesheet", null);
96 writer.writeAttribute("type", "text/css", null);
97 if (stylesheet.getMedia() != null)
98 {
99 writer.writeAttribute("media", stylesheet.getMedia(), null);
100 }
101
102 String stylesheetPath;
103 if (stylesheet.isFiltered())
104 {
105 if (!path.startsWith("/"))
106 {
107 throw new FacesException("Filtered stylesheets require absolute resource path");
108 }
109
110 // Load, filter and cache the resource
111 TextResourceFilter.getInstance(context).getOrCreateFilteredResource(context, path);
112
113 // Compute a URL that goes via the tomahawk ExtensionsFilter and the
114 // TextResourceFilterProvider to fetch the resource from the cache.
115 //
116 // Unfortunately the getResourceUri(context, Class, String, bool) api below is
117 // really meant for serving resources out of the Tomahawk jarfile, relative to
118 // some class that the resource belongs to. So it only expects to receive
119 // relative paths. We are abusing it here to serve resources out of the
120 // webapp, specified by an absolute path. So here, the leading slash is
121 // stripped off and in the TextResourceFilterProvider a matching hack
122 // puts it back on again. A better solution would be to write a custom
123 // ResourceHandler class and pass that to the getResourceUri method...
124 // TODO: fixme
125 String nastyPathHack = path.substring(1);
126 stylesheetPath = AddResourceFactory.getInstance(context).getResourceUri(
127 context,
128 TextResourceFilterProvider.class,
129 nastyPathHack,
130 true);
131 }
132 else
133 {
134 stylesheetPath = context.getApplication().getViewHandler().getResourceURL(context, path);
135 }
136
137 writer.writeURIAttribute("href", stylesheetPath, "path");
138 writer.endElement("link");
139 }
140 }
141 }