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.statechangednotifier;
20  
21  import java.io.IOException;
22  
23  import javax.faces.component.UIComponent;
24  import javax.faces.component.UIInput;
25  import javax.faces.component.UIOutput;
26  import javax.faces.context.FacesContext;
27  import javax.faces.context.ResponseWriter;
28  import javax.faces.convert.ConverterException;
29  import javax.faces.FacesException;
30  
31  import org.apache.commons.lang.StringUtils;
32  import org.apache.myfaces.custom.dojo.DojoConfig;
33  import org.apache.myfaces.custom.dojo.DojoUtils;
34  import org.apache.myfaces.renderkit.html.util.AddResource;
35  import org.apache.myfaces.renderkit.html.util.AddResourceFactory;
36  
37  import org.apache.myfaces.shared_tomahawk.renderkit.JSFAttr;
38  import org.apache.myfaces.shared_tomahawk.renderkit.RendererUtils;
39  import org.apache.myfaces.shared_tomahawk.renderkit.html.HTML;
40  import org.apache.myfaces.shared_tomahawk.renderkit.html.HtmlRenderer;
41  import org.apache.myfaces.shared_tomahawk.renderkit.html.HtmlRendererUtils;
42  import org.apache.myfaces.shared_tomahawk.renderkit.html.util.FormInfo;
43  
44  
45  /**
46   * 
47   * @JSFRenderer
48   *   renderKitId = "HTML_BASIC" 
49   *   family = "javax.faces.Input"
50   *   type = "org.apache.myfaces.StateChangedNotifierRenderer"
51   * 
52   * @author Bruno Aranda (latest modification by $Author: lu4242 $)
53   * @version $Revision: 659874 $ $Date: 2006-04-02 22:03:33 +0200 (So, 02 Apr
54   *          2006) $
55   */
56  public class StateChangedNotifierRenderer extends HtmlRenderer {
57  
58      public void decode(FacesContext facesContext, UIComponent component) {
59          RendererUtils.checkParamValidity(facesContext, component, null);
60  
61          if (component instanceof UIInput) {
62              HtmlRendererUtils.decodeUIInput(facesContext, component);
63          } else {
64              throw new IllegalArgumentException("Unsupported component class " + component.getClass().getName());
65          }
66      }
67  
68      public void encodeEnd(FacesContext facesContext, UIComponent uiComponent) throws IOException {
69          RendererUtils.checkParamValidity(facesContext, uiComponent, StateChangedNotifier.class);
70  
71          StateChangedNotifier notifier = (StateChangedNotifier) uiComponent;
72  
73          if (notifier.getDisabled() != null) {
74  
75              if (notifier.getDisabled().booleanValue())
76                  return;
77          }
78  
79          renderInitialization(facesContext, uiComponent, notifier);
80  
81          encodeJavascript(facesContext, notifier);
82          //We have to render on our own to avoid dependencies into myfaces-impl
83          renderInputHidden(facesContext, uiComponent);
84  
85      }
86  
87      public Object getConvertedValue(FacesContext facesContext, UIComponent uiComponent, Object submittedValue) throws ConverterException {
88          RendererUtils.checkParamValidity(facesContext, uiComponent, UIOutput.class);
89  
90          return RendererUtils.getConvertedUIOutputValue(facesContext, (UIOutput) uiComponent, submittedValue);
91      }
92  
93      private void encodeJavascript(FacesContext facesContext, StateChangedNotifier notifier) {
94          String notifierClientId = notifier.getClientId(facesContext);
95  
96          String replacedClientId = notifierClientId.replaceAll(":", "_");
97          String initFunctionName = "init_" + replacedClientId;
98  
99          FormInfo formInfo   = RendererUtils.findNestingForm(notifier,facesContext);
100         if(formInfo == null)
101             throw new FacesException("StateChangedNotifier must be embedded in a form.");
102 
103         String formId = formInfo.getFormName();
104 
105         String notifierVar = replacedClientId + "Notifier";
106 
107         StringBuffer sb = new StringBuffer();
108         sb.append("dojo.addOnLoad(window, '" + initFunctionName + "');\n");
109         sb.append("function " + initFunctionName + "() {\n");
110         sb.append(notifierVar + " = new org_apache_myfaces_StateChangedNotifier('" + notifierVar + "','" + formId + "','" + notifierClientId + "','" + notifier.getConfirmationMessage() + "',");
111 
112         String excludedCommandIds = notifier.getExcludedIds();
113 
114         if (excludedCommandIds != null) {
115             sb.append("'" + excludedCommandIds + "');\n");
116         } else {
117             sb.append("'');\n");
118         }
119 
120         sb.append("setTimeout('" + replacedClientId + "Notifier.prepareNotifier()',500);\n");
121 
122         sb.append("}\n");
123 
124         AddResource addResource = AddResourceFactory.getInstance(facesContext);
125         addResource.addInlineScriptAtPosition(facesContext, AddResource.HEADER_BEGIN, sb.toString());
126     }
127 
128     private void renderInitialization(FacesContext facesContext, UIComponent uiComponent, StateChangedNotifier notifier)
129         throws IOException {
130         String javascriptLocation = (String) notifier.getAttributes().get(JSFAttr.JAVASCRIPT_LOCATION);
131         DojoUtils.addMainInclude(facesContext, uiComponent, javascriptLocation, new DojoConfig());
132         DojoUtils.addRequire(facesContext, uiComponent, "dojo.widget.Dialog");
133         DojoUtils.addRequire(facesContext, uiComponent, "dojo.event.*");
134 
135         // DojoUtils.addRequire(facesContext, "dojo.xml.Parse");
136 
137         writeDialog(facesContext, uiComponent);
138 
139         AddResource addResource = AddResourceFactory.getInstance(facesContext);
140 
141         if (!DojoUtils.isInlineScriptSet(facesContext, "stateChangedNotifier.js"))
142             addResource.addJavaScriptHere(facesContext, StateChangedNotifierRenderer.class, "stateChangedNotifier.js");
143 
144         String styleLocation = (String) uiComponent.getAttributes().get(JSFAttr.STYLE_LOCATION);
145 
146         // we need a style def for the dialog system
147         if (StringUtils.isNotBlank(styleLocation)) {
148             addResource.addStyleSheet(facesContext, AddResource.HEADER_BEGIN, styleLocation + "/default.css");
149         } else {
150             addResource.addStyleSheet(facesContext, AddResource.HEADER_BEGIN, StateChangedNotifierRenderer.class, "css/default.css");
151         }
152     }
153 
154     private void renderInputHidden(FacesContext facesContext, UIComponent uiComponent) throws IOException {
155         RendererUtils.checkParamValidity(facesContext, uiComponent, UIInput.class);
156 
157         ResponseWriter writer = facesContext.getResponseWriter();
158 
159         writer.startElement(HTML.INPUT_ELEM, uiComponent);
160         writer.writeAttribute(HTML.TYPE_ATTR, HTML.INPUT_TYPE_HIDDEN, null);
161 
162         String clientId = uiComponent.getClientId(facesContext);
163         writer.writeAttribute(HTML.ID_ATTR, clientId, null);
164         writer.writeAttribute(HTML.NAME_ATTR, clientId, null);
165 
166         String value = RendererUtils.getStringValue(facesContext, uiComponent);
167 
168         if (value != null) {
169             writer.writeAttribute(HTML.VALUE_ATTR, value, JSFAttr.VALUE_ATTR);
170         }
171 
172         writer.endElement(HTML.INPUT_ELEM);
173     }
174 
175     /**
176      * dialog definition this one is needed for the dojoized dialog
177      *
178      * @param facesContext
179      * @param uiComponent
180      * @throws IOException
181      */
182     private void writeDialog(FacesContext facesContext, UIComponent uiComponent) throws IOException {
183         /*
184          * <div id="form1__idJsp1Notifier_Dialog" style="position:absolute;
185          * visibility: hidden;"> <div id="form1__idJsp1Notifier_Dialog_Content">
186          * values have changed do you really want to <br> submit the values
187          * </div> <input type="button" id="form1__idJsp1Notifier_Dialog_Yes"
188          * value="yes" /> <input type="button"
189          * id="form1__idJsp1Notifier_Dialog_No" value="no" /> </div>
190          */
191 
192         String notifierClientId = uiComponent.getClientId(facesContext);
193         String replacedClientId = notifierClientId.replaceAll(":", "_");
194         String dialogVar        = replacedClientId + "Notifier_Dialog";
195         String yesText          = (String) uiComponent.getAttributes().get("yesText");
196         String noText           = (String) uiComponent.getAttributes().get("noText");
197 
198         yesText = (yesText == null) ? "Yes" : yesText;
199         noText  = (noText == null) ? "No" : noText;
200 
201         ResponseWriter writer = facesContext.getResponseWriter();
202         writer.startElement(HTML.DIV_ELEM, uiComponent);
203         writer.writeAttribute(HTML.ID_ATTR, dialogVar, null);
204         writer.writeAttribute(HTML.STYLE_ATTR, "position:absolute; visibility: hidden;", null);
205         writer.startElement(HTML.DIV_ELEM, uiComponent);
206         writer.writeAttribute(HTML.ID_ATTR, dialogVar + "_Content", null);
207         writer.endElement(HTML.DIV_ELEM);
208         writer.write(HTML.NBSP_ENTITY);
209         writer.startElement(HTML.INPUT_ELEM, uiComponent);
210         writer.writeAttribute(HTML.TYPE_ATTR, HTML.BUTTON_ELEM, null);
211         writer.writeAttribute(HTML.ID_ATTR, dialogVar + "_Yes", null);
212         writer.writeAttribute(HTML.VALUE_ATTR, yesText, null);
213         writer.endElement(HTML.INPUT_ELEM);
214         writer.write(HTML.NBSP_ENTITY);
215         writer.startElement(HTML.INPUT_ELEM, uiComponent);
216         writer.writeAttribute(HTML.TYPE_ATTR, "button", null);
217         writer.writeAttribute(HTML.ID_ATTR, dialogVar + "_No", null);
218         writer.writeAttribute(HTML.VALUE_ATTR, noText, null);
219         writer.endElement(HTML.INPUT_ELEM);
220         writer.endElement(HTML.DIV_ELEM);
221         writer.write(HTML.NBSP_ENTITY);
222     }
223 }