001: /*
002: * Version: MPL 1.1/GPL 2.0/LGPL 2.1
003: *
004: * "The contents of this file are subject to the Mozilla Public License
005: * Version 1.1 (the "License"); you may not use this file except in
006: * compliance with the License. You may obtain a copy of the License at
007: * http://www.mozilla.org/MPL/
008: *
009: * Software distributed under the License is distributed on an "AS IS"
010: * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
011: * License for the specific language governing rights and limitations under
012: * the License.
013: *
014: * The Original Code is ICEfaces 1.5 open source software code, released
015: * November 5, 2006. The Initial Developer of the Original Code is ICEsoft
016: * Technologies Canada, Corp. Portions created by ICEsoft are Copyright (C)
017: * 2004-2006 ICEsoft Technologies Canada, Corp. All Rights Reserved.
018: *
019: * Contributor(s): _____________________.
020: *
021: * Alternatively, the contents of this file may be used under the terms of
022: * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"
023: * License), in which case the provisions of the LGPL License are
024: * applicable instead of those above. If you wish to allow use of your
025: * version of this file only under the terms of the LGPL License and not to
026: * allow others to use your version of this file under the MPL, indicate
027: * your decision by deleting the provisions above and replace them with
028: * the notice and other provisions required by the LGPL License. If you do
029: * not delete the provisions above, a recipient may use your version of
030: * this file under either the MPL or the LGPL License."
031: *
032: */
033:
034: package com.icesoft.faces.renderkit.dom_html_basic;
035:
036: import com.icesoft.faces.context.DOMContext;
037: import com.icesoft.faces.util.DOMUtils;
038:
039: import org.w3c.dom.Element;
040: import org.w3c.dom.Text;
041:
042: import javax.faces.FacesException;
043: import javax.faces.component.NamingContainer;
044: import javax.faces.component.UICommand;
045: import javax.faces.component.UIComponent;
046: import javax.faces.component.UIViewRoot;
047: import javax.faces.context.FacesContext;
048: import javax.faces.event.ActionEvent;
049:
050: import java.beans.Beans;
051: import java.io.IOException;
052: import java.util.Iterator;
053: import java.util.Map;
054:
055: public class CommandLinkRenderer extends DomBasicRenderer {
056:
057: private static final String HIDDEN_FIELD_NAME = "cl";
058:
059: public void decode(FacesContext facesContext,
060: UIComponent uiComponent) {
061: validateParameters(facesContext, uiComponent, UICommand.class);
062: if (isStatic(uiComponent)) {
063: return;
064: }
065: String commandLinkClientId = uiComponent
066: .getClientId(facesContext);
067: Map requestParameterMap = facesContext.getExternalContext()
068: .getRequestParameterMap();
069: String commonCommandLinkHiddenFieldName = deriveCommonHiddenFieldName(
070: facesContext, (UICommand) uiComponent);
071: String hiddenFieldNameInRequestMap = (String) requestParameterMap
072: .get(commonCommandLinkHiddenFieldName);
073: if (hiddenFieldNameInRequestMap == null
074: || hiddenFieldNameInRequestMap.equals("")
075: || !commandLinkClientId
076: .equals(hiddenFieldNameInRequestMap)) {
077: // this command link did not invoke the submit
078: return;
079: }
080: // this command link caused the submit so queue an event
081: ActionEvent actionEvent = new ActionEvent(uiComponent);
082: uiComponent.queueEvent(actionEvent);
083: }
084:
085: protected static String deriveCommonHiddenFieldName(
086: FacesContext facesContext, UIComponent uiComponent) {
087:
088: if (Beans.isDesignTime()) {
089: return "";
090: }
091:
092: UIComponent parentNamingContainer = findForm(uiComponent);
093: String parentClientId = parentNamingContainer
094: .getClientId(facesContext);
095: String hiddenFieldName = parentClientId
096: + NamingContainer.SEPARATOR_CHAR
097: + UIViewRoot.UNIQUE_ID_PREFIX + HIDDEN_FIELD_NAME;
098: return hiddenFieldName;
099: }
100:
101: public void encodeBegin(FacesContext facesContext,
102: UIComponent uiComponent) throws IOException {
103:
104: validateParameters(facesContext, uiComponent, UICommand.class);
105:
106: DOMContext domContext = DOMContext.attachDOMContext(
107: facesContext, uiComponent);
108:
109: if (!domContext.isInitialized()) {
110: Element root = domContext.createElement("a");
111: domContext.setRootNode(root);
112: setRootElementId(facesContext, root, uiComponent);
113: root.setAttribute("href", "# ");
114: }
115: Element root = (Element) domContext.getRootNode();
116: DOMContext.removeChildren(root);
117: renderLinkText(uiComponent, domContext, root);
118:
119: Map parameterMap = getParameterMap(uiComponent);
120: renderOnClick(facesContext, uiComponent, root, parameterMap);
121:
122: String styleClass = (String) uiComponent.getAttributes().get(
123: "styleClass");
124: if (styleClass != null) {
125: root.setAttribute("class", styleClass);
126: }
127:
128: PassThruAttributeRenderer.renderAttributes(facesContext,
129: uiComponent, new String[] { "onclick" });
130:
131: FormRenderer.addHiddenField(facesContext,
132: deriveCommonHiddenFieldName(facesContext,
133: (UICommand) uiComponent));
134: Iterator parameterKeys = parameterMap.keySet().iterator();
135: while (parameterKeys.hasNext()) {
136: String nextKey = (String) parameterKeys.next();
137: FormRenderer.addHiddenField(facesContext, nextKey);
138: }
139: domContext.stepInto(uiComponent);
140: }
141:
142: /**
143: * @param uiComponent
144: * @param domContext
145: * @param root
146: */
147: private void renderLinkText(UIComponent uiComponent,
148: DOMContext domContext, Element root) {
149: Object currentValue = ((UICommand) uiComponent).getValue();
150: String linkText = null;
151: if (currentValue != null) {
152: linkText = DOMUtils.escapeAnsi(currentValue.toString());
153: }
154: // create a new or update the old text node for the label
155: if (linkText != null && linkText.length() != 0) {
156: Text labelNode = (Text) root.getFirstChild();
157: if (labelNode == null) {
158: labelNode = domContext.getDocument().createTextNode(
159: linkText);
160: root.appendChild(labelNode);
161: } else {
162: labelNode.setData(linkText);
163: }
164: }
165: }
166:
167: /**
168: * @param facesContext
169: * @param uiComponent
170: * @param root
171: * @param parameters
172: */
173: protected void renderOnClick(FacesContext facesContext,
174: UIComponent uiComponent, Element root, Map parameters) {
175: UIComponent uiForm = findForm(uiComponent);
176: if (uiForm == null) {
177: throw new FacesException(
178: "CommandLink must be contained in a form");
179: }
180: String uiFormClientId = uiForm.getClientId(facesContext);
181: Object onClick = uiComponent.getAttributes().get(
182: HTML.ONCLICK_ATTR);
183:
184: //if onClick attribute set by the user, pre append it.
185: if (onClick != null) {
186: onClick = onClick.toString()
187: + ";"
188: + getJavaScriptOnClickString(facesContext,
189: uiComponent, uiFormClientId, parameters);
190: } else {
191: onClick = getJavaScriptOnClickString(facesContext,
192: uiComponent, uiFormClientId, parameters);
193: }
194: root.setAttribute("onclick", onClick.toString()); // replaced command w/component
195: }
196:
197: public void encodeEnd(FacesContext facesContext,
198: UIComponent uiComponent) throws IOException {
199: validateParameters(facesContext, uiComponent, UICommand.class);
200: DOMContext domContext = DOMContext.getDOMContext(facesContext,
201: uiComponent);
202: domContext.stepOver();
203: domContext.streamWrite(facesContext, uiComponent);
204: }
205:
206: private String getJavaScriptOnClickString(
207: FacesContext facesContext, UIComponent uiComponent,
208: String formClientId, Map parameters) {
209: return getJavascriptHiddenFieldSetters(facesContext,
210: (UICommand) uiComponent, formClientId, parameters)
211: + "iceSubmit("
212: + " document.forms['"
213: + formClientId
214: + "']," + " this,event); " + "return false;";
215: }
216:
217: /**
218: * @param facesContext
219: * @param uiCommand
220: * @param formClientId
221: * @param parameters
222: * @return
223: */
224: protected static String getJavascriptHiddenFieldSetters(
225: FacesContext facesContext, UICommand uiCommand,
226: String formClientId, Map parameters) {
227: StringBuffer buffer;
228: buffer = new StringBuffer("document.forms['" + formClientId
229: + "']['");
230: buffer.append(deriveCommonHiddenFieldName(facesContext,
231: uiCommand));
232: buffer.append("'].value='"
233: + uiCommand.getClientId(facesContext) + "';");
234: Iterator parameterKeys = parameters.keySet().iterator();
235: while (parameterKeys.hasNext()) {
236: String nextParamName = (String) parameterKeys.next();
237: Object nextParamValue = parameters.get(nextParamName);
238: buffer.append("document.forms['" + formClientId + "']['");
239: buffer.append(nextParamName);
240: buffer.append("'].value='");
241: buffer.append(nextParamValue);
242: buffer.append("';");
243: }
244: return buffer.toString();
245: }
246:
247: public boolean getRendersChildren() {
248: return true;
249: }
250:
251: public void encodeChildren(FacesContext facesContext,
252: UIComponent uiComponent) throws IOException {
253: validateParameters(facesContext, uiComponent, UICommand.class);
254: Iterator children = uiComponent.getChildren().iterator();
255: while (children.hasNext()) {
256: UIComponent nextChild = (UIComponent) children.next();
257: nextChild.encodeBegin(facesContext);
258: if (nextChild.getRendersChildren()) {
259: nextChild.encodeChildren(facesContext);
260: }
261: nextChild.encodeEnd(facesContext);
262: }
263: }
264: }
|