View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  
20  package org.apache.myfaces.custom.graphicimagedynamic;
21  
22  import java.io.IOException;
23  import java.util.Map;
24  
25  import javax.faces.FacesException;
26  import javax.faces.FactoryFinder;
27  import javax.faces.component.UIComponent;
28  import javax.faces.context.FacesContext;
29  import javax.faces.context.FacesContextFactory;
30  import javax.faces.context.ResponseStream;
31  import javax.faces.context.ResponseWriter;
32  import javax.faces.el.ValueBinding;
33  import javax.faces.lifecycle.Lifecycle;
34  import javax.faces.lifecycle.LifecycleFactory;
35  import javax.servlet.ServletContext;
36  import javax.servlet.http.HttpServletRequest;
37  import javax.servlet.http.HttpServletResponse;
38  
39  import org.apache.commons.logging.Log;
40  import org.apache.commons.logging.LogFactory;
41  import org.apache.myfaces.component.html.util.ParameterResourceHandler;
42  import org.apache.myfaces.custom.graphicimagedynamic.util.GraphicImageDynamicConstants;
43  import org.apache.myfaces.custom.graphicimagedynamic.util.GraphicsImageDynamicHelper;
44  import org.apache.myfaces.custom.graphicimagedynamic.util.ImageContext;
45  import org.apache.myfaces.custom.graphicimagedynamic.util.ImageRenderer;
46  import org.apache.myfaces.custom.graphicimagedynamic.util.ImageResponseStream;
47  import org.apache.myfaces.custom.util.ComponentUtils;
48  import org.apache.myfaces.renderkit.html.ext.HtmlImageRenderer;
49  import org.apache.myfaces.renderkit.html.util.AddResource;
50  import org.apache.myfaces.renderkit.html.util.AddResourceFactory;
51  import org.apache.myfaces.renderkit.html.util.ResourceLoader;
52  import org.apache.myfaces.shared_tomahawk.renderkit.RendererUtils;
53  import org.apache.myfaces.shared_tomahawk.renderkit.html.HTML;
54  import org.apache.myfaces.shared_tomahawk.renderkit.html.HtmlRendererUtils;
55  
56  /**
57   * 
58   * @JSFRenderer
59   *   renderKitId = "HTML_BASIC" 
60   *   family = "javax.faces.Graphic"
61   *   type = "org.apache.myfaces.GraphicImageDynamicRenderer"
62   *
63   * @author Sylvain Vieujot
64   */
65  public class GraphicImageDynamicRenderer extends HtmlImageRenderer implements
66          ResourceLoader {
67      
68      private static final Log log = LogFactory
69              .getLog(GraphicImageDynamicRenderer.class);
70      public static final String RENDERER_TYPE = "org.apache.myfaces.GraphicImageDynamicRenderer";
71  
72      public void encodeEnd(FacesContext context, UIComponent component)
73              throws IOException {
74  
75          GraphicImageDynamic graphicImageDynamic = (GraphicImageDynamic) component;
76          String width = graphicImageDynamic.getWidth();
77          String height = graphicImageDynamic.getHeight();
78          ResponseWriter writer = context.getResponseWriter();
79          Map params = ComponentUtils.getParameterMap(component);
80          Class imageRendererClass = graphicImageDynamic.getImageRendererClass();
81          ValueBinding imageRendererValueBinding = graphicImageDynamic
82                  .getValueBinding("value");
83          AddResource addResource;
84          String url;
85  
86          // render the img HTML element.
87          RendererUtils.checkParamValidity(context, component,
88                  GraphicImageDynamic.class);
89  
90          writer.startElement(HTML.IMG_ELEM, graphicImageDynamic);
91  
92          HtmlRendererUtils.writeIdIfNecessary(writer, graphicImageDynamic,
93                  context);
94          HtmlRendererUtils.renderHTMLAttributes(writer, graphicImageDynamic,
95                  HTML.IMG_PASSTHROUGH_ATTRIBUTES);
96  
97          if (width != null) {
98              params.put(GraphicImageDynamic.WIDTH_PARAM, width);
99          }
100 
101         if (height != null) {
102             params.put(GraphicImageDynamic.HEIGHT_PARAM, height);
103         }
104 
105         if (imageRendererClass != null) {
106             params.put(GraphicImageDynamic.RENDERER_PARAM, imageRendererClass
107                     .getName());
108         }
109 
110         if (imageRendererValueBinding != null) {
111             params.put(GraphicImageDynamic.VALUE_PARAM,
112                     imageRendererValueBinding.getExpressionString());
113         }
114 
115         addResource = AddResourceFactory.getInstance(context);
116         url = context.getExternalContext().encodeResourceURL(
117                 addResource.getResourceUri(context,
118                         new ParameterResourceHandler(this.getClass(), params)));
119         writer.writeAttribute(HTML.SRC_ATTR, url, null);
120 
121         writer.endElement(HTML.IMG_ELEM);
122     }
123 
124     public void decode(FacesContext facesContext, UIComponent component) {
125         super.decode(facesContext, component);
126     }
127 
128     public void serveResource(ServletContext servletContext,
129             HttpServletRequest request, HttpServletResponse response,
130             String resourceUri) throws IOException {
131 
132         // get the facesContext from the servletContext.
133         FacesContextFactory facesContextFactory = (FacesContextFactory) FactoryFinder
134                 .getFactory(FactoryFinder.FACES_CONTEXT_FACTORY);
135         LifecycleFactory lifecycleFactory = (LifecycleFactory) FactoryFinder
136                 .getFactory(FactoryFinder.LIFECYCLE_FACTORY);
137         Lifecycle lifecycle = lifecycleFactory.getLifecycle(ComponentUtils
138                 .getLifecycleId(servletContext));
139         FacesContext facesContext = facesContextFactory.getFacesContext(
140                 servletContext, request, response, lifecycle);
141 
142         facesContext.setResponseStream(new ImageResponseStream(response
143                 .getOutputStream()));
144 
145         // render the image.
146         try {
147 
148             ImageRenderer imageRenderer = null;
149             Map requestMap = facesContext.getExternalContext()
150                     .getRequestParameterMap();
151             Object rendererValue = requestMap
152                     .get(GraphicImageDynamic.RENDERER_PARAM);
153 
154             if (rendererValue != null) {
155                 imageRenderer = GraphicsImageDynamicHelper
156                         .getImageRendererFromClassName(rendererValue.toString());
157             } else {
158                 Object rendererValueBinding = requestMap
159                         .get(GraphicImageDynamic.VALUE_PARAM);
160                 
161                 if (rendererValueBinding != null) {
162                     imageRenderer = GraphicsImageDynamicHelper
163                             .getImageRendererFromValueBinding(facesContext,
164                                     rendererValueBinding.toString());
165                 }
166             }
167 
168             if (imageRenderer == null) {
169                 throw new FacesException(
170                         GraphicImageDynamicConstants.NO_IMAGE_RENDERER_DEFINED);
171             }
172 
173             try {
174                 renderImage(imageRenderer, facesContext);
175             } catch (Exception e) {
176                 throw new FacesException(
177                         GraphicImageDynamicConstants.MSG_COULDNOT_RENDER_IMAGE
178                                 + rendererValue + " : " + e.getMessage(), e);
179             }
180 
181             facesContext.getResponseStream().close();
182         } finally {
183             facesContext.release();
184         }
185     }
186 
187     /**
188      * This method is used for rendering the image.
189      * @param imageRenderer
190      * @param facesContext
191      * @throws Exception
192      */
193     protected void renderImage(ImageRenderer imageRenderer,
194             FacesContext facesContext) throws Exception {
195 
196         ImageContext imageContext = GraphicsImageDynamicHelper
197                 .createImageContext(facesContext, log);
198         imageRenderer.setContext(facesContext, imageContext);
199         HttpServletResponse response = (HttpServletResponse) facesContext
200                 .getExternalContext().getResponse();
201         int contentLength = imageRenderer.getContentLength();
202         String contentType = imageRenderer.getContentType();
203         ResponseStream out = facesContext.getResponseStream();
204 
205         if (contentLength > 0) {
206             response.setContentLength(contentLength);
207         }
208 
209         if (contentType != null && contentType.length() > 0) {
210             response.setContentType(contentType);
211         }
212 
213         try {
214             imageRenderer.renderResource(out);
215         } finally {
216             out.close();
217             facesContext.responseComplete();
218         }
219     }
220 }