1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.myfaces.renderkit.html;
20
21 import java.io.IOException;
22 import java.util.Map;
23 import java.util.logging.Logger;
24
25 import jakarta.faces.application.FacesMessage;
26 import jakarta.faces.application.ProjectStage;
27 import jakarta.faces.application.Resource;
28 import jakarta.faces.component.UIComponent;
29 import jakarta.faces.context.FacesContext;
30 import jakarta.faces.context.ResponseWriter;
31 import jakarta.faces.event.ComponentSystemEvent;
32 import jakarta.faces.event.ComponentSystemEventListener;
33 import jakarta.faces.event.ListenerFor;
34 import jakarta.faces.event.PostAddToViewEvent;
35 import jakarta.faces.render.Renderer;
36 import jakarta.faces.view.Location;
37
38 import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFRenderer;
39 import org.apache.myfaces.shared.renderkit.JSFAttr;
40 import org.apache.myfaces.shared.renderkit.RendererUtils;
41 import org.apache.myfaces.shared.renderkit.html.HTML;
42 import org.apache.myfaces.shared.renderkit.html.util.ResourceUtils;
43 import org.apache.myfaces.view.facelets.el.CompositeComponentELUtils;
44 import org.apache.myfaces.view.facelets.tag.jsf.ComponentSupport;
45
46
47
48
49
50
51
52
53
54
55
56
57 @JSFRenderer(renderKitId = "HTML_BASIC", family = "jakarta.faces.Output", type = "jakarta.faces.resource.Stylesheet")
58 @ListenerFor(systemEventClass = PostAddToViewEvent.class)
59 public class HtmlStylesheetRenderer extends Renderer implements
60 ComponentSystemEventListener
61 {
62 private static final Logger log = Logger.getLogger(HtmlStylesheetRenderer.class.getName());
63
64 @Override
65 public void processEvent(ComponentSystemEvent event)
66 {
67 if (event instanceof PostAddToViewEvent)
68 {
69 UIComponent component = event.getComponent();
70 FacesContext facesContext = FacesContext.getCurrentInstance();
71
72 Location location = (Location) component.getAttributes().get(CompositeComponentELUtils.LOCATION_KEY);
73 if (location != null)
74 {
75 UIComponent ccParent
76 = CompositeComponentELUtils.getCompositeComponentBasedOnLocation(facesContext, location);
77 if (ccParent != null)
78 {
79 component.getAttributes().put(
80 CompositeComponentELUtils.CC_FIND_COMPONENT_EXPRESSION,
81 ComponentSupport.getFindComponentExpression(facesContext, ccParent));
82 }
83 }
84
85 facesContext.getViewRoot().addComponentResource(facesContext, component, "head");
86 }
87 }
88
89 @Override
90 public boolean getRendersChildren()
91 {
92 return true;
93 }
94
95 @Override
96 public void encodeChildren(FacesContext facesContext, UIComponent component)
97 throws IOException
98 {
99 if (facesContext == null)
100 {
101 throw new NullPointerException("context");
102 }
103 if (component == null)
104 {
105 throw new NullPointerException("component");
106 }
107
108 Map<String, Object> componentAttributesMap = component.getAttributes();
109 String resourceName = (String) componentAttributesMap.get(JSFAttr.NAME_ATTR);
110 boolean hasChildren = component.getChildCount() > 0;
111
112 if (resourceName != null && (!"".equals(resourceName)) )
113 {
114 if (hasChildren)
115 {
116 log.info("Component with resourceName "+ resourceName +
117 " and child components found. Child components will be ignored.");
118 }
119 }
120 else
121 {
122 if (hasChildren)
123 {
124 ResponseWriter writer = facesContext.getResponseWriter();
125 writer.startElement(HTML.STYLE_ELEM, component);
126 writer.writeAttribute(HTML.TYPE_ATTR, HTML.STYLE_TYPE_TEXT_CSS, null);
127 RendererUtils.renderChildren(facesContext, component);
128 writer.endElement(HTML.STYLE_ELEM);
129 }
130 else
131 {
132 if (!facesContext.isProjectStage(ProjectStage.Production))
133 {
134 facesContext.addMessage(component.getClientId(facesContext),
135 new FacesMessage("Component with no name and no body content, so nothing rendered."));
136 }
137 }
138 }
139 }
140
141 @Override
142 public void encodeEnd(FacesContext facesContext, UIComponent component)
143 throws IOException
144 {
145 super.encodeEnd(facesContext, component);
146
147 Map<String, Object> componentAttributesMap = component.getAttributes();
148 String resourceName = (String) componentAttributesMap.get(JSFAttr.NAME_ATTR);
149 String libraryName = (String) componentAttributesMap.get(JSFAttr.LIBRARY_ATTR);
150
151 if (resourceName == null)
152 {
153
154
155
156 return;
157 }
158 if ("".equals(resourceName))
159 {
160 return;
161 }
162
163 String additionalQueryParams = null;
164 int index = resourceName.indexOf('?');
165 if (index >= 0)
166 {
167 additionalQueryParams = resourceName.substring(index + 1);
168 resourceName = resourceName.substring(0, index);
169 }
170
171 Resource resource;
172 if (libraryName == null)
173 {
174 if (ResourceUtils.isRenderedStylesheet(facesContext, libraryName, resourceName))
175 {
176
177 return;
178 }
179 resource = facesContext.getApplication().getResourceHandler()
180 .createResource(resourceName);
181 }
182 else
183 {
184 if (ResourceUtils.isRenderedStylesheet(facesContext, libraryName, resourceName))
185 {
186
187 return;
188 }
189 resource = facesContext.getApplication().getResourceHandler()
190 .createResource(resourceName, libraryName);
191
192 }
193
194 if (resource == null)
195 {
196
197 log.warning("Resource referenced by resourceName "+ resourceName +
198 (libraryName == null ? "" : " and libraryName " + libraryName) +
199 " not found in call to ResourceHandler.createResource."+
200 " It will be silenty ignored.");
201 return;
202 }
203 else
204 {
205 if (ResourceUtils.isRenderedStylesheet(facesContext, resource.getLibraryName(), resource.getResourceName()))
206 {
207
208 return;
209 }
210
211
212 ResourceUtils.markStylesheetAsRendered(facesContext, libraryName, resourceName);
213 ResourceUtils.markStylesheetAsRendered(facesContext, resource.getLibraryName(), resource.getResourceName());
214 ResponseWriter writer = facesContext.getResponseWriter();
215 writer.startElement(HTML.LINK_ELEM, component);
216 writer.writeAttribute(HTML.REL_ATTR, HTML.STYLESHEET_VALUE,null );
217 String media = (String) component.getAttributes().get("media");
218
219 if (media != null)
220 {
221 writer.writeAttribute("media", media ,null );
222 }
223 writer.writeAttribute(HTML.TYPE_ATTR,
224 (resource.getContentType() == null ? HTML.STYLE_TYPE_TEXT_CSS
225 : resource.getContentType()) , null);
226 String path = resource.getRequestPath();
227 if (additionalQueryParams != null)
228 {
229 path = path + ((path.indexOf('?') >= 0) ? "&" : "?") + additionalQueryParams;
230 }
231 writer.writeURIAttribute(HTML.HREF_ATTR,
232 facesContext.getExternalContext().encodeResourceURL(path), null);
233 writer.endElement(HTML.LINK_ELEM);
234 }
235 }
236 }