/**
* License Agreement.
*
* JBoss RichFaces - Ajax4jsf Component Library
*
* Copyright (C) 2007 Exadel, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License version 2.1 as published by the Free Software Foundation.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package org.ajax4jsf.component;
import static org.ajax4jsf.resource.InternetResource.RESOURCE_URI_PREFIX;
import java.io.IOException;
import java.util.Collections;
import java.util.List;
import javax.faces.component.UIComponent;
import javax.faces.component.UIComponentBase;
import javax.faces.context.FacesContext;
import org.richfaces.javascript.AjaxScript;
import org.ajax4jsf.renderkit.HeaderResourceProducer2;
import org.ajax4jsf.renderkit.ProducerContext;
import org.ajax4jsf.renderkit.RendererBase;
import org.ajax4jsf.renderkit.RendererUtils.HTML;
import org.ajax4jsf.resource.InternetResource;
import org.ajax4jsf.resource.InternetResourceBuilder;
import org.ajax4jsf.resource.ResourceNotFoundException;
import org.ajax4jsf.tests.AbstractAjax4JsfTestCase;
import com.gargoylesoftware.htmlunit.html.HtmlLink;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
import com.gargoylesoftware.htmlunit.html.HtmlScript;
/**
* @author Nick Belaevski
* @since 3.3.0
*/
public class LoadResourceComponentTest extends AbstractAjax4JsfTestCase {
private String componentJs;
private String componentXcss;
private String userJs;
private String userXcss;
/**
* @param name
*/
public LoadResourceComponentTest(String name) {
super(name);
}
private void registerResource(String path) {
InternetResourceBuilder resourceBuilder = InternetResourceBuilder.getInstance();
try {
resourceBuilder.getResource(path);
} catch (ResourceNotFoundException e) {
resourceBuilder.createResource(null, path);
}
}
@Override
public void setUp() throws Exception {
super.setUp();
renderKit.addRenderer(ResourceDependentComponent.COMPONENT_FAMILY, ResourceDependentComponent.COMPONENT_TYPE,
new ResourceDependentComponentRenderer());
String resourcePackage = getClass().getPackage().getName().replace('.', '/') + "/";
componentJs = resourcePackage + "component.js";
componentXcss = resourcePackage + "component.xcss";
userJs = resourcePackage + "user.js";
userXcss = resourcePackage + "user.xcss";
registerResource(componentJs);
registerResource(userJs);
registerResource(componentXcss);
registerResource(userXcss);
}
@Override
public void tearDown() throws Exception {
super.tearDown();
componentJs = null;
userJs = null;
componentXcss = null;
userXcss = null;
}
private UIResource createLoadScriptComponent() {
return (UIResource) application.createComponent("org.ajax4jsf.LoadScript");
}
private UIResource createLoadStyleComponent() {
return (UIResource) application.createComponent("org.ajax4jsf.LoadStyle");
}
private List<HtmlScript> selectScriptsBySrc(HtmlPage page, String src) throws Exception {
return Collections.checkedList(page.getByXPath("//script[@src[contains(string(.), '" + src + "')]]"),
HtmlScript.class);
}
private List<HtmlLink> selectStylesByHhref(HtmlPage page, String src) throws Exception {
return Collections.checkedList(
page.getByXPath(
"//link[@type = 'text/css'][@rel = 'stylesheet'][@href[contains(string(.), '" + src
+ "')]]"), HtmlLink.class);
}
protected UIResource createAndAddScriptResource(Object src) {
UIResource scriptComponent = createLoadScriptComponent();
scriptComponent.setSrc(src);
facesContext.getViewRoot().getChildren().add(scriptComponent);
return scriptComponent;
}
protected UIResource createAndAddStyleResource(Object src) {
UIResource styleComponent = createLoadStyleComponent();
styleComponent.setSrc(src);
facesContext.getViewRoot().getChildren().add(styleComponent);
return styleComponent;
}
public void testRenderScript() throws Exception {
createAndAddScriptResource(RESOURCE_URI_PREFIX + userJs);
createAndAddScriptResource(RESOURCE_URI_PREFIX + componentJs).setRendered(false);
HtmlPage page = renderView();
List<HtmlScript> scripts;
scripts = selectScriptsBySrc(page, userJs);
assertEquals(1, scripts.size());
scripts = selectScriptsBySrc(page, componentJs);
assertEquals(0, scripts.size());
}
public void testRenderScriptResource() throws Exception {
InternetResourceBuilder resourceBuilder = InternetResourceBuilder.getInstance();
createAndAddScriptResource(resourceBuilder.getResourceForKey(userJs));
createAndAddScriptResource(resourceBuilder.getResourceForKey(componentJs)).setRendered(false);
HtmlPage page = renderView();
List<HtmlScript> scripts;
scripts = selectScriptsBySrc(page, userJs);
assertEquals(1, scripts.size());
scripts = selectScriptsBySrc(page, componentJs);
assertEquals(1, scripts.size());
}
public void testRenderStyle() throws Exception {
createAndAddStyleResource(RESOURCE_URI_PREFIX + userXcss);
createAndAddStyleResource(RESOURCE_URI_PREFIX + componentXcss).setRendered(false);
HtmlPage page = renderView();
List<HtmlLink> styles;
HtmlLink userLink;
styles = selectStylesByHhref(page, userXcss);
assertEquals(1, styles.size());
userLink = styles.get(0);
assertEquals("user", userLink.getClassAttribute());
assertEquals("", userLink.getMediaAttribute());
styles = selectStylesByHhref(page, componentXcss);
assertEquals(0, styles.size());
}
public void testRenderStyleResource() throws Exception {
InternetResourceBuilder resourceBuilder = InternetResourceBuilder.getInstance();
createAndAddStyleResource(resourceBuilder.getResourceForKey(userXcss));
createAndAddStyleResource(resourceBuilder.getResourceForKey(componentXcss)).setRendered(false);
UIResource styleComponent = createLoadStyleComponent();
styleComponent.setSrc(InternetResourceBuilder.getInstance().getResourceForKey(userXcss));
facesContext.getViewRoot().getChildren().add(styleComponent);
HtmlPage page = renderView();
List<HtmlLink> styles;
HtmlLink userLink;
styles = selectStylesByHhref(page, userXcss);
assertEquals(1, styles.size());
userLink = styles.get(0);
assertEquals("user", userLink.getClassAttribute());
assertEquals("", userLink.getMediaAttribute());
styles = selectStylesByHhref(page, componentXcss);
assertEquals(1, styles.size());
userLink = styles.get(0);
assertEquals("user", userLink.getClassAttribute());
assertEquals("", userLink.getMediaAttribute());
}
public void testRenderMedia() throws Exception {
createAndAddStyleResource(RESOURCE_URI_PREFIX + userXcss).getAttributes().put(HTML.media_ATTRIBUTE,
"screen print");
HtmlPage page = renderView();
List<HtmlLink> styles = selectStylesByHhref(page, userXcss);
assertEquals(1, styles.size());
HtmlLink userLink = styles.get(0);
assertEquals("user", userLink.getClassAttribute());
assertEquals("screen print", userLink.getMediaAttribute());
}
public void testRenderOverridenScript() throws Exception {
List<UIComponent> childrenList = facesContext.getViewRoot().getChildren();
UIResource userJsComponent = createLoadScriptComponent();
userJsComponent.setSrc(RESOURCE_URI_PREFIX + userJs);
childrenList.add(userJsComponent);
InternetResourceBuilder resourceBuilder = InternetResourceBuilder.getInstance();
childrenList.add(new ResourceDependentComponent(true, resourceBuilder.getResourceForKey(componentJs),
resourceBuilder.getResourceForKey(userJs)));
UIResource componentJsComponent = createLoadScriptComponent();
componentJsComponent.setSrc(RESOURCE_URI_PREFIX + componentJs);
childrenList.add(componentJsComponent);
HtmlPage page = renderView();
List<HtmlScript> userScripts = selectScriptsBySrc(page, userJs);
assertEquals(1, userScripts.size());
List<HtmlScript> componentScripts = selectScriptsBySrc(page, componentJs);
assertEquals(1, componentScripts.size());
}
public void testRenderOverridenStyle() throws Exception {
List<UIComponent> childrenList = facesContext.getViewRoot().getChildren();
UIResource userXcssComponent = createLoadStyleComponent();
userXcssComponent.setSrc(RESOURCE_URI_PREFIX + userXcss);
childrenList.add(userXcssComponent);
InternetResourceBuilder resourceBuilder = InternetResourceBuilder.getInstance();
childrenList.add(new ResourceDependentComponent(false, resourceBuilder.getResourceForKey(componentXcss),
resourceBuilder.getResourceForKey(userXcss)));
UIResource componentXcssComponent = createLoadStyleComponent();
componentXcssComponent.setSrc(RESOURCE_URI_PREFIX + componentXcss);
childrenList.add(componentXcssComponent);
HtmlPage page = renderView();
List<HtmlLink> styles = selectStylesByHhref(page, userXcss);
assertEquals(2, styles.size());
assertEquals("component", styles.get(0).getClassAttribute());
assertEquals("user", styles.get(1).getClassAttribute());
styles = selectStylesByHhref(page, componentXcss);
assertEquals(2, styles.size());
assertEquals("component", styles.get(0).getClassAttribute());
assertEquals("user", styles.get(1).getClassAttribute());
}
public void testRenderOverridenAjaxScript() throws Exception {
UIResource userComponent = createLoadScriptComponent();
userComponent.setSrc(RESOURCE_URI_PREFIX + "/org/ajax4jsf/javascript/scripts/AJAX.js");
List<UIComponent> childrenList = facesContext.getViewRoot().getChildren();
childrenList.add(userComponent);
childrenList.add(new ResourceDependentComponent(true, new AjaxScript()));
HtmlPage page = renderView();
List<HtmlScript> scripts = selectScriptsBySrc(page, "AjaxScript");
assertEquals(1, scripts.size());
scripts = selectScriptsBySrc(page, "AJAX.js");
// TODO change to 0 after related issue resolution
assertEquals(1, scripts.size());
}
}
class ResourceDependentComponent extends UIComponentBase {
static String COMPONENT_TYPE = "org.ajax4jsf.component.Test$ResourceDependentComponent";
static String COMPONENT_FAMILY = COMPONENT_TYPE;
private InternetResource[] resources;
private boolean useScripts;
public ResourceDependentComponent(boolean useScripts, InternetResource... resources) {
this.useScripts = useScripts;
this.resources = resources;
}
@Override
public String getFamily() {
return COMPONENT_FAMILY;
}
@Override
public String getRendererType() {
return COMPONENT_TYPE;
}
public InternetResource[] getScripts() {
return useScripts ? resources : null;
}
public InternetResource[] getStyles() {
return useScripts ? null : resources;
}
}
class ResourceDependentComponentRenderer extends RendererBase implements HeaderResourceProducer2 {
@Override
protected Class<? extends UIComponent> getComponentClass() {
return ResourceDependentComponent.class;
}
public void encodeToHead(FacesContext context, UIComponent component, ProducerContext pc) throws IOException {
ResourceDependentComponent resourceDependentComponent = (ResourceDependentComponent) component;
if (pc.isProcessScripts()) {
InternetResource[] scripts = resourceDependentComponent.getScripts();
if (scripts != null) {
for (InternetResource script : scripts) {
script.encode(context, null);
}
}
}
if (pc.isProcessStyles()) {
InternetResource[] styles = resourceDependentComponent.getStyles();
if (styles != null) {
for (InternetResource script : styles) {
script.encode(context, null);
}
}
}
}
}