/** * 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); } } } } }