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  package org.apache.myfaces.custom.outputlinkdynamic;
20  
21  import javax.faces.component.html.HtmlOutputLink;
22  import javax.faces.context.FacesContext;
23  import javax.faces.el.EvaluationException;
24  import javax.faces.el.ValueBinding;
25  
26  import org.apache.myfaces.component.ForceIdAware;
27  import org.apache.myfaces.component.UserRoleAware;
28  import org.apache.myfaces.custom.dynamicResources.ResourceRenderer;
29  import org.apache.myfaces.shared_tomahawk.util.ClassUtils;
30  
31  /**
32   * Extends standard outputLink but links to a dynamically rendered resource (image, file, ...).
33   * 
34   * @JSFComponent
35   *   name = "s:outputLinkDynamic"
36   *   class = "org.apache.myfaces.custom.outputlinkdynamic.OutputLinkDynamic"
37   *   tagClass = "org.apache.myfaces.custom.outputlinkdynamic.OutputLinkDynamicTag"
38   *   
39   * @author Sylvain Vieujot (latest modification by $Author: lu4242 $)
40   *
41   * @version $Revision: 691856 $ $Date: 2008-09-03 21:40:30 -0500 (Wed, 03 Sep 2008) $
42   * 
43   * Warning, this component is far from ready.
44   * It's more a proof of concept right now.
45   * TODO : Remove the need to include .get for the last part of the method expressions : getBytesMethod="#{graphicImageDynamicBean.upImage.getBytes}"
46   * TODO : Make a similar download component to download files 
47   * TODO : Use shorter URLs
48   */
49  
50  public abstract class AbstractOutputLinkDynamic extends HtmlOutputLink
51       implements UserRoleAware, ForceIdAware
52  {
53      
54      public static final String COMPONENT_TYPE = "org.apache.myfaces.OutputLinkDynamic";
55      private static final String DEFAULT_RENDERER_TYPE = "org.apache.myfaces.OutputLinkDynamicRenderer";
56  
57      public AbstractOutputLinkDynamic()
58      {
59          setRendererType(DEFAULT_RENDERER_TYPE);
60      }
61  
62      private Class _resourceRendererClass;
63  
64      public Object saveState(FacesContext context)
65      {
66          Object[] values = new Object[2];
67          values[0] = super.saveState(context);
68          values[1] = _resourceRendererClass;
69          return values;
70      }
71  
72      public void restoreState(FacesContext context, Object state)
73      {
74          Object values[] = (Object[]) state;
75          super.restoreState(context, values[0]);
76          _resourceRendererClass = (Class) values[1];
77      }
78  
79      public void setImageRendererClass(Class resourceRendererClass)
80      {
81          if (resourceRendererClass != null && !ResourceRenderer.class.isAssignableFrom(resourceRendererClass))
82          {
83              throw new IllegalArgumentException(
84                      "resourceRendererClass must be null or a class which implements "
85                              + ResourceRenderer.class.getName());
86          }
87          _resourceRendererClass = resourceRendererClass;
88      }
89  
90      /**
91       *  The class which implements 
92       *  org.apache.myfaces.custom.dynamicResources.ResourceRenderer. The resource 
93       *  renderer is responsible for resource the image. The class must have a 
94       *  default constructor. Any request scoped attribute or managed bean is 
95       *  not available when this resource renderer is instantiated and used. 
96       *  The resource renderer must render the binary data for the resource 
97       *  by using the parameters passed by nested f:param elements and/or 
98       *  using session or application scoped beans.
99       *  
100      * @JSFProperty
101      * @return
102      */
103     public Class getResourceRendererClass()
104     {
105         if (_resourceRendererClass != null)
106         {
107             return _resourceRendererClass;
108         }
109         ValueBinding vb = getValueBinding("resourceRendererClass");
110         if (vb != null)
111         {
112             Object value = vb.getValue(getFacesContext());
113             if (value == null)
114             {
115                 return null;
116             }
117             Class clazz;
118             if (value instanceof Class)
119             {
120                 clazz = (Class) value;
121             }
122             else
123             {
124                 try
125                 {
126                     clazz = ClassUtils.classForName(value.toString());
127                 }
128                 catch (ClassNotFoundException e)
129                 {
130                     throw new EvaluationException("Could not load resourceRendererClass for "
131                             + vb.getExpressionString(), e);
132                 }
133             }
134             if (!ResourceRenderer.class.isAssignableFrom(clazz))
135             {
136                 throw new EvaluationException("Expected value for " + vb.getExpressionString()
137                         + " must be one of null, a fully qualified class name or "
138                         + "an instance of a class which implements "
139                         + ResourceRenderer.class.getName());
140             }
141             return clazz;
142         }
143         return null;
144     }
145     
146     /**
147      * If user is in given role, this component will be rendered 
148      * normally. If not, no hyperlink is rendered but all nested 
149      * tags (=body) are rendered.
150      * 
151      * @JSFProperty
152      * @return
153      */
154     public abstract String getEnabledOnUserRole();
155     
156     public abstract void setEnabledOnUserRole(String userRole);
157 
158     /**
159      *  If user is in given role, this component will be rendered 
160      *  normally. If not, nothing is rendered and the body of this 
161      *  tag will be skipped.
162      * 
163      * @JSFProperty
164      * @return
165      */
166     public abstract String getVisibleOnUserRole();
167     
168     public abstract void setVisibleOnUserRole(String userRole);    
169     
170     /**
171      * If true, this component will force the use of the specified id when rendering.
172      * 
173      * @JSFProperty
174      *   literalOnly = "true"
175      *   defaultValue = "false"
176      *   
177      * @return
178      */
179     public abstract boolean isForceId();
180     
181     public abstract void setForceId(boolean forceId);
182     
183     /**
184      *  If false, this component will not append a '[n]' suffix 
185      *  (where 'n' is the row index) to components that are 
186      *  contained within a "list." This value will be true by 
187      *  default and the value will be ignored if the value of 
188      *  forceId is false (or not specified.)
189      * 
190      * @JSFProperty
191      *   literalOnly = "true"
192      *   defaultValue = "true"
193      *   
194      * @return
195      */
196     public abstract boolean isForceIdIndex();
197     
198     public abstract void setForceIdIndex(boolean forceIdIndex);
199     
200 }