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