/**
* Copyright (c) 2000-2017 Liferay, Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.liferay.faces.util.render.internal;
import java.util.Iterator;
import javax.faces.context.FacesContext;
import javax.faces.render.RenderKit;
import javax.faces.render.RenderKitFactory;
import com.liferay.faces.util.application.ApplicationUtil;
import com.liferay.faces.util.context.FacesRequestContext;
/**
* <p>Since liferay-faces-util.jar!META-INF/faces-config.xml specifies <code>
* <before><others/></before></code>, the factories in this module can only decorate those provided by
* the JSF implementation. As a result, factories registered by Non-Liferay/3rd-Party component suites like ICEfaces,
* PrimeFaces, and RichFaces will end up decorating the factories registered by this module.</p>
*
* <p>However, in order to ensure that scripts contained in {@link FacesRequestContext#getScripts()} are encoded before
* the closing <code></body></code> element, {@link BodyRendererUtilImpl} needs to decorate body renderers
* provided by any of the aforementioned component suites. This could be accomplished in one of two ways:
*
* <ol>
* <li>The {@link RenderKitUtilImpl} class from this module could exist in a separate module that specifies
* <after><others/></after></code> and the separate module would register an HTML_BASIC <code>
* render-kit</code>.</li>
* <li>The {@link RenderKitUtilImpl} class could remain in this module, but this module would have to register a
* <code>render-kit-factory</code> in order to programatically control the {@link RenderKit} delegation chain and
* wrapping of renderers. But the only reason why this works is because <strong>none</strong> of the aforementioned
* component suites register a <code>render-kit-factory</code>.</li>
* </ol>
*
* For the sake of minimizing the number of modules, the second option has been implemented.</p>
*
* <p><strong>Note:</strong> liferay-faces-bridge-impl.jar!META-INF/faces-config.xml also specifies a <code>
* render-kit-factory</code> that will decorate this one.</p>
*
* @author Kyle Stiemann
*/
public class RenderKitFactoryUtilImpl extends RenderKitFactory {
// Private Data Members
private RenderKitFactory wrappedRenderKitFactory;
public RenderKitFactoryUtilImpl(RenderKitFactory renderKitFactory) {
this.wrappedRenderKitFactory = renderKitFactory;
}
@Override
public void addRenderKit(String renderKitId, RenderKit renderKit) {
wrappedRenderKitFactory.addRenderKit(renderKitId, renderKit);
}
@Override
public RenderKit getRenderKit(FacesContext facesContext, String renderKitId) {
RenderKit renderKit = wrappedRenderKitFactory.getRenderKit(facesContext, renderKitId);
// FACES-2615 Only Add the RenderKit to the delegation chain when the application is not starting up or
// shutting down.
if ("HTML_BASIC".equals(renderKitId) && !ApplicationUtil.isStartupOrShutdown(facesContext)) {
return new RenderKitUtilImpl(renderKit);
}
else {
return renderKit;
}
}
@Override
public Iterator<String> getRenderKitIds() {
return wrappedRenderKitFactory.getRenderKitIds();
}
@Override
public RenderKitFactory getWrapped() {
return wrappedRenderKitFactory;
}
}