KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > enhydra > barracuda > core > comp > BAction


1 /*
2  * Copyright (C) 2003 Christian Cryder [christianc@granitepeaks.com]
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * $Id: BAction.java,v 1.33 2004/02/01 05:16:27 christianc Exp $
19  */

20 package org.enhydra.barracuda.core.comp;
21
22 import java.io.*;
23 import java.net.*;
24 import java.util.*;
25
26 import org.apache.log4j.*;
27 import org.w3c.dom.*;
28 import org.w3c.dom.html.*;
29
30 import org.enhydra.barracuda.core.comp.renderer.*;
31 import org.enhydra.barracuda.core.comp.renderer.html.*;
32 import org.enhydra.barracuda.core.event.*;
33 import org.enhydra.barracuda.core.event.events.*;
34 import org.enhydra.barracuda.core.util.http.URLRewriter;
35
36
37 /**
38  * A BAction component is a component that you can use to catch
39  * client side events. It can be used to render <a>, <form>, <button>,
40  * <input>, and <select> elements. It allow you to specify a specific
41  * action to be generated, or can simply default to what's in the
42  * template markup. You can also add event listeners directly to the
43  * component, and only those particular listeners will be notified when
44  * the event actually occurs on the client.
45  *
46  * <p>In most cases you will not actually need to bind the component
47  * to a view in order to use it--if you return it from a model, this
48  * will be done for you automatically. If however, you intend to use
49  * the component <em>standalone</em> (ie. manually attaching it to a
50  * specific node in the DOM) or <em>inline</em> (ie. in a toString()),
51  * then you MUST BIND IT TO A VIEW before rendering, or an error will
52  * be generated.
53  */

54 public class BAction extends BComponent {
55
56     //public vars
57
protected static final Logger logger = Logger.getLogger(BAction.class.getName());
58
59     //private vars
60
protected ControlEvent actionEvent = null;
61     protected String JavaDoc actionUrl = null;
62     protected List listeners = null;
63     protected Map params = null;
64     protected Collection scriptFunctions = null; //ideally, implementation should provide Set-like functionality
65
protected boolean disableBackButton = false;
66     protected boolean disableFormLocking = false; //saw_082603_2
67

68     //--------------- Constructors -------------------------------
69
/**
70      * Public noargs constructor
71      */

72     public BAction() {}
73
74     /**
75      * Public constructor which creates the component and binds it
76      * to a view. Also allows you to specify that a custom url be fired.
77      *
78      * @param iactionUrl the action url to be fired
79      */

80     public BAction(String JavaDoc iactionUrl) {
81         if (iactionUrl!=null) this.setAction(iactionUrl);
82     }
83
84     /**
85      * Public constructor which creates the component and binds it
86      * to a view. Also allows you to specify that a custom event be fired.
87      *
88      * @param iactionEvent the action event to be fired
89      */

90     public BAction(ControlEvent iactionEvent) {
91         if (iactionEvent!=null) this.setAction(iactionEvent);
92     }
93
94
95     //--------------- Renderer -----------------------------------
96
/**
97      * Default component renderer factory registrations
98      */

99     static {
100         HTMLRendererFactory rfHTML = new HTMLRendererFactory();
101         installRendererFactory(rfHTML, BAction.class, HTMLElement.class);
102     }
103
104     /**
105      * HTML RendererFactory
106      */

107     static class HTMLRendererFactory implements RendererFactory {
108         public Renderer getInstance() {return new HTMLActionRenderer();}
109     }
110
111
112     //--------------- BAction ------------------------------------
113
/**
114      * Set the action to be fired by this component.
115      *
116      * @param iactionUrl the URL representing the action to be fired
117      */

118     public void setAction(String JavaDoc iactionUrl) {
119         this.actionUrl = iactionUrl;
120         this.invalidate();
121     }
122
123     /**
124      * Set the action to be fired by this component.
125      *
126      * @param iactionEvent the event to be fired by this component
127      */

128     public void setAction(ControlEvent iactionEvent) {
129         this.actionEvent = iactionEvent;
130         this.invalidate();
131     }
132
133     //csc_041403.1 - added
134
/**
135      * Check for an existing action
136      *
137      * @return true if either the action (either URL or Event) has been set
138      */

139     public boolean hasAction() {
140         return (this.actionUrl!=null || this.actionEvent!=null || (this.listeners!=null && this.listeners.size()>0));
141     }
142
143     /**
144      * Get the action to be fired by this component. The action
145      * will either be the URL or the Event that backs this component
146      *
147      * @param vc the ViewContext that determines the context of the action
148      * @return a string representing the action to be fired by this component
149      */

150     public String JavaDoc getAction(ViewContext vc) {
151         return this.getAction(vc, false);
152     }
153
154     //csc_101701.1 - this method (with additional parameter) added
155
/**
156      * Get the action to be fired by this component. The action
157      * will either be the URL or the Event that backs this component
158      *
159      * @param vc the ViewContext that determines the context of the action
160      * @param preventRewriting this should be set to true only if you want to
161      * prevent URLRewriting from taking place. As a developer, you
162      * will probably never need to do this, unless to need to further
163      * modify the action prior to finally encoding it (HTMLActionRenderer
164      * does this)
165      * @return a string representing the action to be fired by this component
166      */

167     public String JavaDoc getAction(ViewContext vc, boolean preventRewriting) {
168         StringBuffer JavaDoc sb = new StringBuffer JavaDoc(200);
169         String JavaDoc sep = "?";
170
171         //build the base action
172
if (this.actionUrl!=null) {
173             //from the url
174
if (preventRewriting) sb.append(this.actionUrl);
175             else sb.append(URLRewriter.encodeURL(vc, this.actionUrl)); //take into account the need for URL rewriting
176
} else {
177             //from the event
178
if (this.actionEvent==null) this.setAction(new ActionEvent());
179
180 //csc_010404_1_start
181
// if (preventRewriting) sb.append(this.actionEvent.getEventIDWithExtension());
182
// else sb.append(URLRewriter.encodeURL(vc, this.actionEvent.getEventIDWithExtension())); //take into account the need for URL rewriting
183
String JavaDoc url = this.actionEvent.getEventURL();
184             if (preventRewriting) sb.append(url);
185             else sb.append(URLRewriter.encodeURL(vc, url)); //take into account the need for URL rewriting
186
sep = ((url.indexOf("?")>-1) ? "&" : "?");
187 //csc_010404_1_end
188

189             //now, see if we have event listeners
190
if (this.listeners!=null && this.listeners.size()>0) {
191                 Iterator it = this.listeners.iterator();
192                 while (it.hasNext()) {
193                     ListenerFactory lf = (ListenerFactory) it.next();
194                     sb.append(sep).append(BaseEvent.EVENT_ID).append("=").append(lf.getListenerID());
195                     sep = "&";
196                 }
197             }
198         }
199
200         //finally add any custom params
201
if (this.params!=null && this.params.size()>0) {
202             Iterator it = this.params.keySet().iterator();
203             while (it.hasNext()) {
204                 Object JavaDoc key = it.next();
205                 Object JavaDoc val = this.params.get(key);
206                 if (key!=null && val!=null) {
207                     if (val instanceof String JavaDoc[]) {
208                         String JavaDoc [] vals = (String JavaDoc [])val;
209                         for (int i = 0; i < vals.length; i++) {
210                             sb.append(sep);
211                             sb.append(URLEncoder.encode(key.toString()));
212                             sb.append("=");
213                             sb.append(URLEncoder.encode(vals[i].toString()));
214                             sep = "&";
215                         }
216                     } else {
217                         sb.append(sep);
218                         sb.append(URLEncoder.encode(key.toString()));
219                         sb.append("=");
220                         sb.append(URLEncoder.encode(val.toString()));
221                     }
222                 }
223                 sep = "&";
224             }
225         }
226         return sb.toString();
227     }
228
229     /**
230      * Set any associated params
231      */

232     public void setParam(String JavaDoc key, String JavaDoc val) {
233 // if (this.params==null) this.params = new HashMap(10);
234
if (this.params==null) this.params = new TreeMap();
235         this.params.put(key, val);
236     }
237
238     //dbr_012202.2 - added
239
/**
240      * Set any associated list of params
241      */

242     public void setParam(String JavaDoc key, String JavaDoc[] val) {
243 // if (this.params==null) this.params = new HashMap(10);
244
if (this.params==null) this.params = new TreeMap();
245         this.params.put(key, val);
246     }
247
248     /**
249      * Get any associated params
250      */

251     public Map getParams() {
252         return this.params;
253     }
254
255     /**
256      * stores a Set of client-side script functions for use by the
257      * {@link org.enhydra.barracuda.core.comp.renderer.html.HTMLActionRenderer}
258      * . These script functions are javascript function names. The
259      * constraints for these functions is that they take a form element as an
260      * argument (or no arguments) and that it returns a boolean. These
261      * functions are called in the order given and can be used for custom
262      * client-side form validation.
263      *
264      * @since 1.2
265      * @param functionName the name of the javascript function with no
266      * parenthasis
267      */

268     public void addScriptFunction(String JavaDoc functionName) {
269         if (this.scriptFunctions==null) this.scriptFunctions = new ArrayList(5); //jrk_20030501 - I'd rather use j2sdk1.4+ LinkedHashSet here to preserve original added order!!!
270
if (!this.scriptFunctions.contains(functionName)) { //unnecessary if using a LinkedHashSet
271
this.scriptFunctions.add(functionName);
272         }
273     }
274
275     /**
276      * provides access any custom script functions added to a BAction component
277      *
278      * @since 1.2
279      * @see #addScriptFunction(String)
280      * @return a Set of script functions or null if none added
281      */

282     public Collection getScriptFunctions() {
283         return this.scriptFunctions;
284     }
285
286     /**
287      * Set disable back button (only works if your client supports
288      * Javascript)
289      *
290      * @param idisableBackButton true if we want the back button disabled
291      */

292     public void setDisableBackButton(boolean idisableBackButton) {
293         this.disableBackButton = idisableBackButton;
294     }
295
296     /**
297      * Get disable back button
298      *
299      * @return true if we want the back button disabled
300      */

301     public boolean getDisableBackButton() {
302         return this.disableBackButton;
303     }
304
305     /**
306      * Set disable form locking
307      *
308      * @param idisableFormLocking <tt>true</tt> to disable locking the form elements during submit.
309      * @since saw_082603_2
310      */

311     public void setDisableFormLocking(boolean idisableFormLocking) {
312         this.disableFormLocking = idisableFormLocking;
313     }
314
315     /**
316      * Get disable form locking
317      *
318      * @return <tt>true</tt> if we want to disable locking the form elements during submit.
319      * @since saw_082603_2
320      */

321     public boolean getDisableFormLocking() {
322         return this.disableFormLocking;
323     }
324
325     /**
326      * Add an event listener to this component.
327      *
328      * @param lf the event listener to be added
329      */

330     public void addEventListener(ListenerFactory lf) {
331         if (lf==null) return;
332         if (this.listeners==null) this.listeners = new ArrayList(5);
333         this.listeners.add(lf);
334         this.invalidate();
335     }
336
337     /**
338      * Remove an event listener from this component
339      *
340      * @param lf the event listener to be removed
341      */

342     public void removeEventListener(ListenerFactory lf) {
343         if (lf==null) return;
344         if (this.listeners==null) return;
345         this.listeners.remove(lf);
346         this.invalidate();
347     }
348 }
349
Popular Tags