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.shared_orchestra.renderkit.html;
20  
21  import java.io.IOException;
22  import java.util.Map;
23  
24  import javax.faces.component.UICommand;
25  import javax.faces.component.UIComponent;
26  import javax.faces.component.ValueHolder;
27  import javax.faces.component.html.HtmlCommandButton;
28  import javax.faces.context.ExternalContext;
29  import javax.faces.context.FacesContext;
30  import javax.faces.context.ResponseWriter;
31  import javax.faces.event.ActionEvent;
32  
33  import org.apache.myfaces.shared_orchestra.config.MyfacesConfig;
34  import org.apache.myfaces.shared_orchestra.renderkit.JSFAttr;
35  import org.apache.myfaces.shared_orchestra.renderkit.html.util.FormInfo;
36  import org.apache.myfaces.shared_orchestra.renderkit.html.util.JavascriptUtils;
37  import org.apache.myfaces.shared_orchestra.renderkit.RendererUtils;
38  
39  
40  /**
41   * @author Manfred Geiler (latest modification by $Author: lu4242 $)
42   * @author Thomas Spiegl
43   * @author Anton Koinov
44   * @version $Revision: 633078 $ $Date: 2008-03-03 08:46:28 -0500 (Mon, 03 Mar 2008) $
45   */
46  public class HtmlButtonRendererBase
47      extends HtmlRenderer {
48      private static final String IMAGE_BUTTON_SUFFIX_X = ".x";
49      private static final String IMAGE_BUTTON_SUFFIX_Y = ".y";
50  
51      public static final String ACTION_FOR_LIST = "org.apache.myfaces.ActionForList";
52  
53      public void decode(FacesContext facesContext, UIComponent uiComponent) {
54          org.apache.myfaces.shared_orchestra.renderkit.RendererUtils.checkParamValidity(facesContext, uiComponent, UICommand.class);
55  
56          //super.decode must not be called, because value is handled here
57          if (!isReset(uiComponent) && isSubmitted(facesContext, uiComponent)) {
58              uiComponent.queueEvent(new ActionEvent(uiComponent));
59  
60              org.apache.myfaces.shared_orchestra.renderkit.RendererUtils.initPartialValidationAndModelUpdate(uiComponent, facesContext);
61          }
62      }
63  
64      private static boolean isReset(UIComponent uiComponent) {
65          return "reset".equalsIgnoreCase((String) uiComponent.getAttributes().get(HTML.TYPE_ATTR));
66      }
67  
68      private static boolean isSubmitted(FacesContext facesContext, UIComponent uiComponent) {
69          String clientId = uiComponent.getClientId(facesContext);
70          Map paramMap = facesContext.getExternalContext().getRequestParameterMap();
71          return paramMap.containsKey(clientId) || paramMap.containsKey(clientId + IMAGE_BUTTON_SUFFIX_X) || paramMap.containsKey(clientId + IMAGE_BUTTON_SUFFIX_Y);
72      }
73  
74      public void encodeEnd(FacesContext facesContext, UIComponent uiComponent)
75          throws IOException {
76          org.apache.myfaces.shared_orchestra.renderkit.RendererUtils.checkParamValidity(facesContext, uiComponent, UICommand.class);
77  
78          String clientId = uiComponent.getClientId(facesContext);
79  
80          ResponseWriter writer = facesContext.getResponseWriter();
81  
82          // If we have javascript enabled, and autoscroll is enabled, 
83          // we should write the form submit script
84          // (define oamSetHiddenInput, oamClearHiddenInput, oamSubmitForm)
85          // because oamSetHiddenInput is called on onclick function
86          if (JavascriptUtils.isJavascriptAllowed(facesContext.getExternalContext()))
87          {        
88              if (MyfacesConfig.getCurrentInstance(facesContext.getExternalContext()).isAutoScroll()) {
89                  HtmlRendererUtils.renderFormSubmitScript(facesContext);
90              }
91          }
92          
93          HtmlRendererUtils.renderFormSubmitScript(facesContext);
94  
95          writer.startElement(HTML.INPUT_ELEM, uiComponent);
96  
97          writer.writeAttribute(HTML.ID_ATTR, clientId, org.apache.myfaces.shared_orchestra.renderkit.JSFAttr.ID_ATTR);
98          writer.writeAttribute(HTML.NAME_ATTR, clientId, JSFAttr.ID_ATTR);
99  
100         String image = getImage(uiComponent);
101 
102         ExternalContext externalContext = facesContext.getExternalContext();
103 
104         if (image != null) {
105             writer.writeAttribute(HTML.TYPE_ATTR, HTML.INPUT_TYPE_IMAGE, org.apache.myfaces.shared_orchestra.renderkit.JSFAttr.TYPE_ATTR);
106             String src = facesContext.getApplication().getViewHandler().getResourceURL(
107                 facesContext, image);
108             writer.writeURIAttribute(HTML.SRC_ATTR, externalContext.encodeResourceURL(src),
109                                      org.apache.myfaces.shared_orchestra.renderkit.JSFAttr.IMAGE_ATTR);
110         }
111         else {
112             String type = getType(uiComponent);
113 
114             if (type == null) {
115                 type = HTML.INPUT_TYPE_SUBMIT;
116             }
117             writer.writeAttribute(HTML.TYPE_ATTR, type, org.apache.myfaces.shared_orchestra.renderkit.JSFAttr.TYPE_ATTR);
118             Object value = getValue(uiComponent);
119             if (value != null) {
120                 writer.writeAttribute(org.apache.myfaces.shared_orchestra.renderkit.html.HTML.VALUE_ATTR, value, org.apache.myfaces.shared_orchestra.renderkit.JSFAttr.VALUE_ATTR);
121             }
122         }
123         if (JavascriptUtils.isJavascriptAllowed(externalContext)) {
124             StringBuffer onClick = buildOnClick(uiComponent, facesContext, writer);
125             writer.writeAttribute(HTML.ONCLICK_ATTR, onClick.toString(), null);
126             HtmlRendererUtils.renderHTMLAttributes(writer, uiComponent,
127                                                    HTML.BUTTON_PASSTHROUGH_ATTRIBUTES_WITHOUT_DISABLED_AND_ONCLICK);
128         }
129         else {
130             HtmlRendererUtils.renderHTMLAttributes(writer, uiComponent,
131                                                    HTML.BUTTON_PASSTHROUGH_ATTRIBUTES_WITHOUT_DISABLED);
132         }
133 
134         if (isDisabled(facesContext, uiComponent)) {
135             writer.writeAttribute(HTML.DISABLED_ATTR, Boolean.TRUE, org.apache.myfaces.shared_orchestra.renderkit.JSFAttr.DISABLED_ATTR);
136         }
137 
138         writer.endElement(HTML.INPUT_ELEM);
139 
140         HtmlFormRendererBase.renderScrollHiddenInputIfNecessary(
141             findNestingForm(uiComponent, facesContext).getForm(), facesContext, writer);
142     }
143 
144 
145     protected StringBuffer buildOnClick(UIComponent uiComponent, FacesContext facesContext, ResponseWriter writer)
146         throws IOException {
147         FormInfo formInfo = findNestingForm(uiComponent, facesContext);
148         if (formInfo == null) {
149             throw new IllegalArgumentException("Component " + uiComponent.getClientId(facesContext) + " must be embedded in an form");
150         }
151         String formName = formInfo.getFormName();
152         UIComponent nestingForm = formInfo.getForm();
153 
154         StringBuffer onClick = new StringBuffer();
155         String commandOnClick = (String) uiComponent.getAttributes().get(HTML.ONCLICK_ATTR);
156 
157         if (commandOnClick != null) {
158             onClick.append(commandOnClick);
159             onClick.append(';');
160         }
161 
162         //call the script to clear the form (clearFormHiddenParams_<formName>) method
163         HtmlRendererUtils.appendClearHiddenCommandFormParamsFunctionCall(onClick, formName);
164 
165         if (MyfacesConfig.getCurrentInstance(facesContext.getExternalContext()).isAutoScroll()) {
166             HtmlRendererUtils.appendAutoScrollAssignment(onClick, formName);
167         }
168 
169         //add hidden field for the case there is no commandLink in the form
170         String hiddenFieldName = HtmlRendererUtils.getHiddenCommandLinkFieldName(formInfo);
171         addHiddenCommandParameter(facesContext, nestingForm, hiddenFieldName);
172 
173         //add hidden field for the case there is no commandLink in the form
174         String hiddenFieldNameMyFacesOld = HtmlRendererUtils.getHiddenCommandLinkFieldNameMyfacesOld(formInfo);
175         addHiddenCommandParameter(facesContext, nestingForm, hiddenFieldNameMyFacesOld);
176 
177         return onClick;
178     }
179 
180     protected void addHiddenCommandParameter(FacesContext facesContext, UIComponent nestingForm, String hiddenFieldName) {
181         if (nestingForm != null) {
182             HtmlFormRendererBase.addHiddenCommandParameter(facesContext, nestingForm, hiddenFieldName);
183         }
184     }
185 
186     /**
187      * find nesting form<br />
188      * need to be overrideable to deal with dummyForm stuff in tomahawk.
189      */
190     protected FormInfo findNestingForm(UIComponent uiComponent, FacesContext facesContext) {
191         return RendererUtils.findNestingForm(uiComponent, facesContext);
192     }
193 
194     protected boolean isDisabled(FacesContext facesContext, UIComponent uiComponent) {
195         //TODO: overwrite in extended HtmlButtonRenderer and check for enabledOnUserRole
196         if (uiComponent instanceof HtmlCommandButton) {
197             return ((HtmlCommandButton) uiComponent).isDisabled();
198         }
199         else {
200             return org.apache.myfaces.shared_orchestra.renderkit.RendererUtils.getBooleanAttribute(uiComponent, HTML.DISABLED_ATTR, false);
201         }
202     }
203 
204 
205     private String getImage(UIComponent uiComponent) {
206         if (uiComponent instanceof HtmlCommandButton) {
207             return ((HtmlCommandButton) uiComponent).getImage();
208         }
209         return (String) uiComponent.getAttributes().get(JSFAttr.IMAGE_ATTR);
210     }
211 
212     private String getType(UIComponent uiComponent) {
213         if (uiComponent instanceof HtmlCommandButton) {
214             return ((HtmlCommandButton) uiComponent).getType();
215         }
216         return (String) uiComponent.getAttributes().get(org.apache.myfaces.shared_orchestra.renderkit.JSFAttr.TYPE_ATTR);
217     }
218 
219     private Object getValue(UIComponent uiComponent) {
220         if (uiComponent instanceof ValueHolder) {
221             return ((ValueHolder) uiComponent).getValue();
222         }
223         return uiComponent.getAttributes().get(JSFAttr.VALUE_ATTR);
224     }
225 }