KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > cocoon > faces > samples > components > components > MapComponent


1 /*
2  * Copyright 2004 Sun Microsystems, Inc. All Rights Reserved.
3  *
4  * Redistribution and use in source and binary forms, with or
5  * without modification, are permitted provided that the following
6  * conditions are met:
7  *
8  * - Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  *
11  * - Redistribution in binary form must reproduce the above
12  * copyright notice, this list of conditions and the following
13  * disclaimer in the documentation and/or other materials
14  * provided with the distribution.
15  *
16  * Neither the name of Sun Microsystems, Inc. or the names of
17  * contributors may be used to endorse or promote products derived
18  * from this software without specific prior written permission.
19  *
20  * This software is provided "AS IS," without a warranty of any
21  * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
22  * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
23  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
24  * EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY
25  * DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT OF OR
26  * RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE OR
27  * ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE
28  * FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT,
29  * SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
30  * CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF
31  * THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS
32  * BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
33  *
34  * You acknowledge that this software is not designed, licensed or
35  * intended for use in the design, construction, operation or
36  * maintenance of any nuclear facility.
37  */

38
39 package org.apache.cocoon.faces.samples.components.components;
40
41
42 import javax.faces.component.UICommand;
43 import javax.faces.context.FacesContext;
44 import javax.faces.el.MethodBinding;
45 import javax.faces.event.AbortProcessingException;
46 import javax.faces.event.ActionEvent;
47 import javax.faces.event.ActionListener;
48 import javax.faces.event.FacesEvent;
49 import javax.faces.event.PhaseId;
50
51 /**
52  * <p>{@link MapComponent} is a JavaServer Faces component that corresponds
53  * to a client-side image map. It can have one or more children of type
54  * {@link AreaComponent}, each representing hot spots, which a user can
55  * click on and mouse over.</p>
56  *
57  * <p>This component is a source of {@link AreaSelectedEvent} events,
58  * which are fired whenever the current area is changed.</p>
59  */

60
61 public class MapComponent extends UICommand {
62
63
64     // ------------------------------------------------------ Instance Variables
65

66
67     private String JavaDoc current = null;
68
69     private MethodBinding action = null;
70     private MethodBinding actionListener = null;
71     private boolean immediate = false;
72     private boolean immediateSet = false;
73
74
75
76     // --------------------------------------------------------------Constructors
77

78     public MapComponent() {
79         super();
80         addDefaultActionListener(getFacesContext());
81     }
82
83
84     // -------------------------------------------------------------- Properties
85

86
87     /**
88      * <p>Return the alternate text label for the currently selected
89      * child {@link AreaComponent}.</p>
90      */

91     public String JavaDoc getCurrent() {
92         return (this.current);
93     }
94
95
96     /**
97      * <p>Set the alternate text label for the currently selected child.
98      * If this is different from the previous value, fire an
99      * {@link AreaSelectedEvent} to interested listeners.</p>
100      *
101      * @param current The new alternate text label
102      */

103     public void setCurrent(String JavaDoc current) {
104
105         String JavaDoc previous = this.current;
106         this.current = current;
107
108         // Fire an {@link AreaSelectedEvent} if appropriate
109
if ((previous == null) && (current == null)) {
110             return;
111         } else if ((previous != null) && (current != null) &&
112             (previous.equals(current))) {
113             return;
114         } else {
115             this.queueEvent(new AreaSelectedEvent(this));
116         }
117
118     }
119
120
121     /**
122      * <p>Return the component family for this component.</p>
123      */

124     public String JavaDoc getFamily() {
125
126         return ("Map");
127
128     }
129
130     // ----------------------------------------------------- Event Methods
131

132     private static Class JavaDoc signature[] = {AreaSelectedEvent.class};
133
134
135     /**
136      * <p>In addition to to the default <code>UIComponentBase#broadcast</code>
137      * processing, pass the {@link ActionEvent} being broadcast to the
138      * method referenced by <code>actionListener</code> (if any).</p>
139      *
140      * @param event {@link FacesEvent} to be broadcast
141      *
142      * @throws AbortProcessingException Signal the JavaServer Faces
143      * implementation that no further processing on the current event
144      * should be performed
145      * @throws IllegalArgumentException if the implementation class
146      * of this {@link FacesEvent} is not supported by this component
147      * @throws IllegalStateException if PhaseId.ANY_PHASE is passed
148      * for the phase identifier
149      * @throws NullPointerException if <code>event</code> is
150      * <code>null</code>
151      */

152     public void broadcast(FacesEvent event) throws AbortProcessingException {
153
154         // Perform standard superclass processing
155
super.broadcast(event);
156
157         // Notify the specified action listener method (if any)
158
MethodBinding mb = getActionListener();
159         if (mb != null) {
160             if ((isImmediate() &&
161                 event.getPhaseId().equals(PhaseId.APPLY_REQUEST_VALUES)) ||
162                 (!isImmediate() &&
163                 event.getPhaseId().equals(PhaseId.INVOKE_APPLICATION))) {
164                 FacesContext context = getFacesContext();
165                 mb.invoke(context, new Object JavaDoc[]{event});
166             }
167         }
168
169     }
170
171
172     /**
173      * <p>Intercept <code>queueEvent</code> and mark the phaseId for the
174      * event to be <code>PhaseId.APPLY_REQUEST_VALUES</code> if the
175      * <code>immediate</code> flag is true,
176      * <code>PhaseId.INVOKE_APPLICATION</code> otherwise.</p>
177      */

178
179     public void queueEvent(FacesEvent e) {
180         if (e instanceof ActionEvent) {
181             if (isImmediate()) {
182                 e.setPhaseId(PhaseId.APPLY_REQUEST_VALUES);
183             } else {
184                 e.setPhaseId(PhaseId.INVOKE_APPLICATION);
185             }
186         }
187         super.queueEvent(e);
188     }
189
190     // ----------------------------------------------------- StateHolder Methods
191

192
193     /**
194      * <p>Return the state to be saved for this component.</p>
195      *
196      * @param context <code>FacesContext</code> for the current request
197      */

198     public Object JavaDoc saveState(FacesContext context) {
199         removeDefaultActionListener(context);
200         Object JavaDoc values[] = new Object JavaDoc[6];
201         values[0] = super.saveState(context);
202         values[1] = current;
203         values[2] = saveAttachedState(context, action);
204         values[3] = saveAttachedState(context, actionListener);
205         values[4] = immediate ? Boolean.TRUE : Boolean.FALSE;
206         values[5] = immediateSet ? Boolean.TRUE : Boolean.FALSE;
207         addDefaultActionListener(context);
208         return (values);
209     }
210
211
212     /**
213      * <p>Restore the state for this component.</p>
214      *
215      * @param context <code>FacesContext</code> for the current request
216      * @param state State to be restored
217      *
218      * @throws IOException if an input/output error occurs
219      */

220     public void restoreState(FacesContext context, Object JavaDoc state) {
221         removeDefaultActionListener(context);
222         Object JavaDoc values[] = (Object JavaDoc[]) state;
223         super.restoreState(context, values[0]);
224         current = (String JavaDoc) values[1];
225         action = (MethodBinding) restoreAttachedState(context, values[2]);
226         actionListener = (MethodBinding) restoreAttachedState(context,
227                                                               values[3]);
228         immediate = ((Boolean JavaDoc) values[4]).booleanValue();
229         immediateSet = ((Boolean JavaDoc) values[5]).booleanValue();
230         addDefaultActionListener(context);
231     }
232
233     // ----------------------------------------------------- Private Methods
234

235     // Add the default action listener
236
private void addDefaultActionListener(FacesContext context) {
237         ActionListener listener =
238             context.getApplication().getActionListener();
239         addActionListener(listener);
240     }
241
242
243     // Remove the default action listener
244
private void removeDefaultActionListener(FacesContext context) {
245         removeActionListener(context.getApplication().getActionListener());
246     }
247
248 }
249
Popular Tags