myfaces-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From lu4...@apache.org
Subject svn commit: r906369 - in /myfaces/shared/trunk_4.0.x/core/src: main/java/org/apache/myfaces/shared/renderkit/ main/java/org/apache/myfaces/shared/renderkit/html/ test/java/org/apache/myfaces/shared/renderkit/
Date Thu, 04 Feb 2010 05:23:12 GMT
Author: lu4242
Date: Thu Feb  4 05:23:11 2010
New Revision: 906369

URL: http://svn.apache.org/viewvc?rev=906369&view=rev
Log:
MYFACES-2531 Support for name/library attributes with h:commandButton (Thanks to Martin Koci
for provide this patch)

Added:
    myfaces/shared/trunk_4.0.x/core/src/test/java/org/apache/myfaces/shared/renderkit/RendererUtilsTest.java
Modified:
    myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/RendererUtils.java
    myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlButtonRendererBase.java
    myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlImageRendererBase.java

Modified: myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/RendererUtils.java
URL: http://svn.apache.org/viewvc/myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/RendererUtils.java?rev=906369&r1=906368&r2=906369&view=diff
==============================================================================
--- myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/RendererUtils.java
(original)
+++ myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/RendererUtils.java
Thu Feb  4 05:23:11 2010
@@ -39,6 +39,10 @@
 import javax.el.ValueExpression;
 import javax.faces.FacesException;
 import javax.faces.FactoryFinder;
+import javax.faces.application.FacesMessage;
+import javax.faces.application.ProjectStage;
+import javax.faces.application.Resource;
+import javax.faces.application.ResourceHandler;
 import javax.faces.component.EditableValueHolder;
 import javax.faces.component.NamingContainer;
 import javax.faces.component.UIComponent;
@@ -1163,6 +1167,113 @@
 
         return renderKit.getResponseStateManager();
     }
+    
+    /**
+      * Checks for name/library attributes on component and if they are avaliable,
+      * creates {@link Resource} and returns it's path suitable for rendering.
+      * If component doesn't have name/library gets value for attribute named <code>attributeName</code>

+      * returns it processed with {@link CoreRenderer#toResourceUri(FacesContext, Object)}
+      *       
+      * @param facesContext a {@link FacesContext}
+      * @param component a {@link UIComponent}
+      * @param attributeName name of attribute that represents "image", "icon", "source",
... 
+      * 
+      * @since 4.0.1
+      */
+    public static String getIconSrc(final FacesContext facesContext, final UIComponent component,
final String attributeName)
+    {
+
+        // JSF 2.0: if "name" attribute is available, treat as a resource reference.
+        final Map<String, Object> attributes = component.getAttributes();
+        final String resourceName = (String) attributes.get(JSFAttr.NAME_ATTR);
+        if (resourceName != null && (resourceName.length() > 0))
+        {
+
+            final ResourceHandler resourceHandler = facesContext.getApplication().getResourceHandler();
+            final Resource resource;
+            
+            final String libraryName = (String) component.getAttributes().get(JSFAttr.LIBRARY_ATTR);
+            if ((libraryName != null) && (libraryName.length() > 0))
+            {
+                resource = resourceHandler.createResource(resourceName, libraryName);
+            }
+            else
+            {
+                resource = resourceHandler.createResource(resourceName);    
+            }
+            
+            if (resource == null)
+            {
+                // If resourceName/libraryName are set but no resource created -> probably
a typo,
+                // show a message
+                if (ProjectStage.Development.equals(facesContext.getApplication().getProjectStage()))
+                {
+                    String summary = "Unable to find resource: " + resourceName;
+                    if (libraryName != null) {
+                        summary = summary + " from library: " + libraryName;
+                    }
+                    facesContext.addMessage(component.getClientId(facesContext), new FacesMessage(FacesMessage.SEVERITY_WARN,
summary, summary));
+                }
+                // This nice constant is "specified" 13.1.1.2 The Resource API Approach in
Spec as a example
+                // and RI uses it too:
+                return "RES_NOT_FOUND";
+            }
+            else
+            {
+                return resource.getRequestPath();
+            }
+        }
+        else
+        {
+            String value = (String) component.getAttributes().get(attributeName);
+            return toResourceUri(facesContext, value);
+        }
+    }
+    
+    /**
+     * Coerces an object into a resource URI, calling the view-handler.
+     */
+    static public String toResourceUri(FacesContext facesContext, Object o)
+    {
+      if (o == null)
+        return null;
+
+      String uri = o.toString();
+
+      // *** EL Coercion problem ***
+      // If icon or image attribute was declared with #{resource[]} and that expression
+      // evaluates to null (it means ResourceHandler.createResource returns null because
requested resource does not exist)
+      // EL implementation turns null into ""
+      // see http://www.irian.at/blog/blogid/unifiedElCoercion/#unifiedElCoercion
+      if (uri.length() == 0)
+      {
+        return null;
+      }
+
+
+      // With JSF 2.0 url for resources can be done with EL like #{resource['resourcename']}
+      // and such EL after evalution contains context path for the current web application
already,
+      // -> we dont want call viewHandler.getResourceURL()
+      if (uri.contains(ResourceHandler.RESOURCE_IDENTIFIER))
+      {
+        return uri;
+      }
+
+      // Treat two slashes as server-relative
+      if (uri.startsWith("//"))
+      {
+        return uri.substring(1);
+      }
+      else
+      {
+        // If the specified path starts with a "/",
+        // following method will prefix it with the context path for the current web application,
+        // and return the result
+        String resourceURL = facesContext.getApplication().getViewHandler().getResourceURL(facesContext,
uri);
+        return facesContext.getExternalContext().encodeResourceURL(resourceURL);
+      }
+    }
+
 
     /**
      * Special converter for handling submitted values which don't need to be converted.

Modified: myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlButtonRendererBase.java
URL: http://svn.apache.org/viewvc/myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlButtonRendererBase.java?rev=906369&r1=906368&r2=906369&view=diff
==============================================================================
--- myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlButtonRendererBase.java
(original)
+++ myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlButtonRendererBase.java
Thu Feb  4 05:23:11 2010
@@ -122,25 +122,15 @@
         writer.writeAttribute(HTML.ID_ATTR, clientId, org.apache.myfaces.shared.renderkit.JSFAttr.ID_ATTR);
         writer.writeAttribute(HTML.NAME_ATTR, clientId, JSFAttr.ID_ATTR);
 
-        String image = getImage(uiComponent);
+        
 
         ExternalContext externalContext = facesContext.getExternalContext();
 
+        String image = RendererUtils.getIconSrc(facesContext, uiComponent, JSFAttr.IMAGE_ATTR);
         if (image != null)
         {
             writer.writeAttribute(HTML.TYPE_ATTR, HTML.INPUT_TYPE_IMAGE, org.apache.myfaces.shared.renderkit.JSFAttr.TYPE_ATTR);
-            String src;
-            // Check if image attribute already contained resource expression (is resolved
as resource url)
-            if (image.contains(ResourceHandler.RESOURCE_IDENTIFIER))
-            {
-                src = image;
-            }
-            else
-            {
-                src = facesContext.getApplication().getViewHandler().getResourceURL(facesContext,
image);
-            }
-            writer.writeURIAttribute(HTML.SRC_ATTR, externalContext.encodeResourceURL(src),
-                                     org.apache.myfaces.shared.renderkit.JSFAttr.IMAGE_ATTR);
+            writer.writeURIAttribute(HTML.SRC_ATTR, image, org.apache.myfaces.shared.renderkit.JSFAttr.IMAGE_ATTR);
         }
         else
         {

Modified: myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlImageRendererBase.java
URL: http://svn.apache.org/viewvc/myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlImageRendererBase.java?rev=906369&r1=906368&r2=906369&view=diff
==============================================================================
--- myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlImageRendererBase.java
(original)
+++ myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlImageRendererBase.java
Thu Feb  4 05:23:11 2010
@@ -36,6 +36,7 @@
 import javax.faces.context.ResponseWriter;
 
 import org.apache.myfaces.shared.renderkit.JSFAttr;
+import org.apache.myfaces.shared.renderkit.RendererUtils;
 import org.apache.myfaces.shared.renderkit.html.util.JavascriptUtils;
 
 
@@ -58,16 +59,6 @@
 
         ResponseWriter writer = facesContext.getResponseWriter();
 
-        String url;
-        if (uiComponent instanceof HtmlGraphicImage)
-        {
-            url = ((HtmlGraphicImage) uiComponent).getUrl();
-        }
-        else
-        {
-            url = (String) uiComponent.getAttributes().get(JSFAttr.URL_ATTR);
-        }
-
         writer.startElement(HTML.IMG_ELEM, uiComponent);
 
         if (uiComponent instanceof ClientBehaviorHolder 
@@ -81,51 +72,14 @@
             HtmlRendererUtils.writeIdIfNecessary(writer, uiComponent, facesContext);
         }
 
-        if (url != null && url.length() > 0)
+        final String url = RendererUtils.getIconSrc(facesContext, uiComponent, JSFAttr.URL_ATTR);
+        if (url != null)
         {
-            //check to see if this is a resource request.  If so, don't need to run getResourceURL
since it will have already been done
-            String src;
-            if(url.contains(ResourceHandler.RESOURCE_IDENTIFIER))
-            {
-                src = url;
-            }
-            else
-            {
-                src = facesContext.getApplication().getViewHandler().getResourceURL(facesContext,
url);
-            }
-            
-            writer.writeURIAttribute(HTML.SRC_ATTR,
-                    facesContext.getExternalContext().encodeResourceURL(src),
-                    JSFAttr.VALUE_ATTR);
+            writer.writeURIAttribute(HTML.SRC_ATTR, url,JSFAttr.VALUE_ATTR);
         }
         else
         {
-            String resourceName = (String) uiComponent.getAttributes().get (JSFAttr.NAME_ATTR);
-            String libraryName = (String) uiComponent.getAttributes().get (JSFAttr.LIBRARY_ATTR);
-            // JSF 2.0: if "name" attribute is available, treat as a resource reference.
-            
-            if ((resourceName != null) && (resourceName.length() > 0))
-            {
-                Resource resource = null;
-                if ((libraryName != null) && (libraryName.length() > 0))
-                {
-                    resource = facesContext.getApplication().getResourceHandler().createResource
(resourceName, libraryName);
-                }
-                else
-                {
-                    resource = facesContext.getApplication().getResourceHandler().createResource
(resourceName);    
-                }
-                
-                String src = resource.getRequestPath();
-                
-                writer.writeURIAttribute(HTML.SRC_ATTR,
-                    facesContext.getExternalContext().encodeResourceURL(src), JSFAttr.VALUE_ATTR);
-            }
-            
-            else
-            {
-                if (log.isLoggable(Level.WARNING)) log.warning("Graphic with id " + uiComponent.getClientId(facesContext)
+ " has no value (url or name).");
-            }
+          if (log.isLoggable(Level.WARNING)) log.warning("Graphic with id " + uiComponent.getClientId(facesContext)
+ " has no value (url or name).");
         }
 
         /* 

Added: myfaces/shared/trunk_4.0.x/core/src/test/java/org/apache/myfaces/shared/renderkit/RendererUtilsTest.java
URL: http://svn.apache.org/viewvc/myfaces/shared/trunk_4.0.x/core/src/test/java/org/apache/myfaces/shared/renderkit/RendererUtilsTest.java?rev=906369&view=auto
==============================================================================
--- myfaces/shared/trunk_4.0.x/core/src/test/java/org/apache/myfaces/shared/renderkit/RendererUtilsTest.java
(added)
+++ myfaces/shared/trunk_4.0.x/core/src/test/java/org/apache/myfaces/shared/renderkit/RendererUtilsTest.java
Thu Feb  4 05:23:11 2010
@@ -0,0 +1,121 @@
+package org.apache.myfaces.shared.renderkit;
+
+import java.io.StringWriter;
+
+import javax.faces.application.Application;
+import javax.faces.application.ProjectStage;
+import javax.faces.application.Resource;
+import javax.faces.application.ResourceHandler;
+import javax.faces.component.html.HtmlGraphicImage;
+
+import org.apache.myfaces.shared.renderkit.html.HTML;
+import org.apache.myfaces.test.base.AbstractJsfTestCase;
+import org.apache.myfaces.test.mock.MockResponseWriter;
+import org.easymock.classextension.EasyMock;
+
+/**
+ * 
+ * @author markoc
+ */
+public class RendererUtilsTest extends AbstractJsfTestCase {
+
+	private MockResponseWriter writer;
+
+	/**
+	 * ResourceHandler nice easy mock
+	 */
+	ResourceHandler resourceHandlerMock;
+
+	/**
+	 * {@link Application} nice easy mock
+	 */
+	Application applicationMock;
+
+	/**
+	 * A {@link Resource} nice easy mock
+	 */
+	private Resource resourceMock;
+
+	String libraryName = "images";
+
+	String resourceName = "picture.gif";
+
+	String requestPath = "/somePrefix/faces/javax.faces.resource/picture.gif?ln=\"images\"";
+
+	// a Component instance:
+	HtmlGraphicImage graphicImage = new HtmlGraphicImage();
+
+	public RendererUtilsTest(String name) {
+		super(name);
+	}
+
+	protected void setUp() throws Exception {
+		super.setUp();
+
+		writer = new MockResponseWriter(new StringWriter(), null, null);
+		facesContext.setResponseWriter(writer);
+
+		applicationMock = EasyMock.createNiceMock(Application.class);
+		facesContext.setApplication(applicationMock);
+
+		resourceHandlerMock = EasyMock.createNiceMock(ResourceHandler.class);
+		applicationMock.getResourceHandler();
+		EasyMock.expectLastCall().andReturn(resourceHandlerMock);
+		
+		applicationMock.getProjectStage();
+		EasyMock.expectLastCall().andReturn(ProjectStage.Development);
+
+		resourceMock = EasyMock.createNiceMock(Resource.class);
+
+		EasyMock.replay(applicationMock);
+
+		graphicImage.getAttributes().put(JSFAttr.LIBRARY_ATTR, libraryName);
+		graphicImage.getAttributes().put(JSFAttr.NAME_ATTR, resourceName);
+		graphicImage.setId("graphicImageId");
+	}
+
+	protected void tearDown() throws Exception {
+		super.tearDown();
+	}
+
+	/**
+	 * 
+	 */
+	public void testGetIconSrc() {
+
+		// Training a mock:
+		resourceHandlerMock.createResource(resourceName, libraryName);
+		EasyMock.expectLastCall().andReturn(resourceMock);
+		resourceMock.getRequestPath();
+		EasyMock.expectLastCall().andReturn(requestPath);
+		EasyMock.replay(resourceHandlerMock);
+		EasyMock.replay(resourceMock);
+
+		// Tested method :
+		String iconSrc = RendererUtils.getIconSrc(facesContext, graphicImage,
+				HTML.IMG_ELEM);
+
+		assertEquals(
+				"If name or name/library present, source must be obtained from ResourceHandler",
+				requestPath, iconSrc);
+
+	}
+
+	public void testGetIconSrcResourceNotFound() throws Exception {
+		// Training a mock:
+		EasyMock.reset(resourceHandlerMock);
+		resourceHandlerMock.createResource(resourceName, libraryName);
+		EasyMock.expectLastCall().andReturn(null);
+		EasyMock.replay(resourceHandlerMock);
+
+		// Tested method :
+		String iconSrc = RendererUtils.getIconSrc(facesContext, graphicImage,
+				HTML.IMG_ELEM);
+
+		assertEquals("RES_NOT_FOUND", iconSrc);
+		assertTrue("If resource is not found, a Message must be added",
+				facesContext.getMessages(graphicImage.getClientId(facesContext)).hasNext());
+
+	}
+
+}



Mime
View raw message