001: /* BaseCommand.java
002:
003: {{IS_NOTE
004: Purpose:
005:
006: Description:
007:
008: History:
009: Aug 8, 2007 5:48:27 PM 2007, Created by Dennis.Chen
010: }}IS_NOTE
011:
012: Some code of this file is refer to Apache License Version 2.0
013: the license file is http://www.apache.org/licenses/LICENSE-2.0
014:
015: Copyright (C) 2007 Potix Corporation. All Rights Reserved.
016:
017: {{IS_RIGHT
018: This program is distributed under GPL Version 2.0 in the hope that
019: it will be useful, but WITHOUT ANY WARRANTY.
020: }}IS_RIGHT
021: */
022: package org.zkoss.jsf.zul.impl;
023:
024: import java.util.Map;
025:
026: import javax.faces.component.ActionSource;
027: import javax.faces.component.UIForm;
028: import javax.faces.context.FacesContext;
029: import javax.faces.el.EvaluationException;
030: import javax.faces.el.MethodBinding;
031: import javax.faces.el.ValueBinding;
032: import javax.faces.event.AbortProcessingException;
033: import javax.faces.event.ActionEvent;
034: import javax.faces.event.ActionListener;
035: import javax.faces.event.FacesEvent;
036: import javax.faces.event.PhaseId;
037:
038: import org.zkoss.jsf.zul.impl.BranchComponent;
039:
040: /**
041: * The Base implementation of ActionSource.
042: *
043: * @author Dennis.Chen
044: *
045: */
046: public abstract class BaseCommand extends BranchComponent implements
047: ActionSource {
048:
049: //=== code reference from my faces ====
050: private MethodBinding _action = null;
051:
052: private MethodBinding _actionListener = null;
053:
054: public void setAction(MethodBinding action) {
055: _action = action;
056: }
057:
058: public MethodBinding getAction() {
059: return _action;
060: }
061:
062: public void setActionListener(MethodBinding actionListener) {
063: _actionListener = actionListener;
064: }
065:
066: public MethodBinding getActionListener() {
067: return _actionListener;
068: }
069:
070: public void addActionListener(ActionListener listener) {
071: addFacesListener(listener);
072: }
073:
074: public ActionListener[] getActionListeners() {
075: return (ActionListener[]) getFacesListeners(ActionListener.class);
076: }
077:
078: public void removeActionListener(ActionListener listener) {
079: removeFacesListener(listener);
080: }
081:
082: public void broadcast(FacesEvent event)
083: throws AbortProcessingException {
084: super .broadcast(event);
085:
086: if (event instanceof ActionEvent) {
087: FacesContext context = getFacesContext();
088:
089: MethodBinding actionListenerBinding = getActionListener();
090: if (actionListenerBinding != null) {
091: try {
092: actionListenerBinding.invoke(context,
093: new Object[] { event });
094: } catch (EvaluationException e) {
095: Throwable cause = e.getCause();
096: if (cause != null
097: && cause instanceof AbortProcessingException) {
098: throw (AbortProcessingException) cause;
099: } else {
100: throw e;
101: }
102: }
103: }
104:
105: ActionListener defaultActionListener = context
106: .getApplication().getActionListener();
107: if (defaultActionListener != null) {
108: defaultActionListener
109: .processAction((ActionEvent) event);
110: }
111: }
112: }
113:
114: public void queueEvent(FacesEvent event) {
115: if (event != null && this == event.getSource()
116: && event instanceof ActionEvent) {
117: if (isImmediate()) {
118: event.setPhaseId(PhaseId.APPLY_REQUEST_VALUES);
119: } else {
120: event.setPhaseId(PhaseId.INVOKE_APPLICATION);
121: }
122: }
123: super .queueEvent(event);
124: }
125:
126: private static final boolean DEFAULT_IMMEDIATE = false;
127:
128: private Boolean _immediate = null;
129:
130: public void setImmediate(boolean immediate) {
131: _immediate = Boolean.valueOf(immediate);
132: }
133:
134: public boolean isImmediate() {
135: if (_immediate != null)
136: return _immediate.booleanValue();
137: ValueBinding vb = getValueBinding("immediate");
138: Boolean v = vb != null ? (Boolean) vb
139: .getValue(getFacesContext()) : null;
140: return v != null ? v.booleanValue() : DEFAULT_IMMEDIATE;
141: }
142:
143: public Object saveState(FacesContext context) {
144: Object values[] = new Object[4];
145: values[0] = super .saveState(context);
146: values[1] = saveAttachedState(context, _action);
147: values[2] = saveAttachedState(context, _actionListener);
148: values[3] = _immediate;
149: return values;
150: }
151:
152: public void restoreState(FacesContext context, Object state) {
153: Object values[] = (Object[]) state;
154: super .restoreState(context, values[0]);
155: _action = (MethodBinding) restoreAttachedState(context,
156: values[1]);
157: _actionListener = (MethodBinding) restoreAttachedState(context,
158: values[2]);
159: _immediate = (Boolean) values[3];
160: }
161:
162: //============ ZK implementation==================
163:
164: private static final String PARM_POSTFIX = "_cmd";
165:
166: protected String getJSSubmitMethodName(FacesContext context) {
167: String scriptId = getClientId(context).replaceAll(":", "_");
168: String submitmethod = "submit_" + scriptId;
169: return submitmethod;
170: }
171:
172: protected String getJSSubmitScript(FacesContext context) {
173: UIForm form = getUIForm();
174: String scriptId = getClientId(context).replaceAll(":", "_");
175: String formScriptId = form.getClientId(context).replaceAll(":",
176: "_");
177:
178: StringBuffer sb = new StringBuffer();
179: sb.append("<script>");
180: sb.append("function " + getJSSubmitMethodName(context) + "(){");
181: sb.append("var cid = '" + scriptId + PARM_POSTFIX + "';");
182: sb.append("var form = document.getElementById('" + formScriptId
183: + "');");
184: sb.append("var el = document.createElement('input');");
185: sb.append("el.id = cid;");
186: sb.append("el.name = cid;");
187: sb.append("el.type = 'hidden';");
188: sb.append("el.value = 't';");
189: sb.append("form.appendChild(el);");
190: sb.append("form.submit();");
191: sb.append("}");
192: sb.append("</script>\n");
193:
194: return sb.toString();
195: }
196:
197: /**
198: * check that is there any submitting info in request.
199: */
200: private boolean isSubmitted(FacesContext facesContext) {
201: String scriptId = getClientId(facesContext)
202: .replaceAll(":", "_");
203: Map paramMap = facesContext.getExternalContext()
204: .getRequestParameterMap();
205: return paramMap.containsKey(scriptId + PARM_POSTFIX);
206: }
207:
208: /**
209: * @return return true if there are any action or actionListener register in this component.
210: */
211: protected boolean hasListener() {
212: MethodBinding action = getAction();
213: MethodBinding listener = getActionListener();
214: ActionListener[] als = getActionListeners();
215: if (action != null || listener != null
216: || (als != null && als.length > 0)) {
217: return true;
218: }
219: return false;
220: }
221:
222: /**
223: * Override Method, decode and queue event
224: */
225: public void decode(FacesContext facesContext) {
226: //super.decode must not be called, because value is handled here
227: //there is no reset type in zk component,
228: if (isSubmitted(facesContext)) {
229: queueEvent(new ActionEvent(this));
230: }
231: }
232:
233: }
|