KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > enterprise > tools > jsfext > event > CommandActionListener


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the License). You may not use this file except in
5  * compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * https://glassfish.dev.java.net/public/CDDLv1.0.html or
9  * glassfish/bootstrap/legal/CDDLv1.0.txt.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * Header Notice in each file and include the License file
15  * at glassfish/bootstrap/legal/CDDLv1.0.txt.
16  * If applicable, add the following below the CDDL Header,
17  * with the fields enclosed by brackets [] replaced by
18  * you own identifying information:
19  * "Portions Copyrighted [year] [name of copyright owner]"
20  *
21  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
22  */

23 package com.sun.enterprise.tools.jsfext.event;
24
25 import com.sun.enterprise.tools.jsfext.layout.LayoutDefinitionManager;
26 import com.sun.enterprise.tools.jsfext.layout.descriptor.ComponentType;
27 import com.sun.enterprise.tools.jsfext.layout.descriptor.LayoutComponent;
28 import com.sun.enterprise.tools.jsfext.layout.descriptor.LayoutDefinition;
29 import com.sun.enterprise.tools.jsfext.layout.descriptor.LayoutElement;
30
31 import java.io.IOException JavaDoc;
32 import java.util.EventObject JavaDoc;
33 import java.util.Iterator JavaDoc;
34 import java.util.List JavaDoc;
35
36 import javax.faces.component.UIComponent;
37 import javax.faces.component.UIViewRoot;
38 import javax.faces.context.FacesContext;
39 import javax.faces.event.ActionEvent;
40
41
42 /**
43  * <p> The purpose of this class is to provide an <code>ActionListener</code>
44  * that can delegate to handlers (that are likely defined via XML). It is
45  * safe to register this class as a managed bean at the Application
46  * scope.</p>
47  *
48  * @author Ken Paulsen (ken.paulsen@sun.com)
49  */

50 public class CommandActionListener implements java.io.Serializable JavaDoc {
51
52     /**
53      * <p> Constructor.</p>
54      *
55      * @param component The <code>UIComponent</code> associated with this
56      * <code>EventObject</code>.
57      */

58     public CommandActionListener() {
59     super();
60     }
61
62     /**
63      * <p> This is an ActionListener that delegates to handlers to process
64      * the action.</p>
65      */

66     public void invokeCommandHandlers(ActionEvent event) {
67     // Get the UIComponent source associated w/ this command
68
UIComponent command = (UIComponent) event.getSource();
69     if (command == null) {
70         throw new IllegalArgumentException JavaDoc(
71             "Action invoked, however, no source was given!");
72     }
73
74     // Get the FacesContext
75
FacesContext context = FacesContext.getCurrentInstance();
76
77     // Look on the UIComponent for the CommandHandlers
78
LayoutElement desc = null;
79     List JavaDoc handlers = (List JavaDoc) command.getAttributes().get(COMMAND_HANDLERS);
80     if ((handlers != null) && (handlers.size() > 0)) {
81         // This is needed for components that don't have corresponding
82
// LayoutElements, it is also useful for dynamically defining
83
// Handlers (advanced and not recommended unless you have a good
84
// reason). May also happen if "id" for any component in
85
// hierarchy is not a simple String.
86

87         // No parent (null) or ComponentType, just pass (null)
88
desc = new LayoutComponent(
89         (LayoutElement) null, command.getId(), (ComponentType) null);
90         desc.setHandlers(CommandEvent.EVENT_TYPE, handlers);
91     } else {
92         // Attempt to find LayoutElement based on command's client id
93
// "desc" may be null
94
String JavaDoc viewId = getViewId(command);
95         desc = findLayoutElementByClientId(
96             context, viewId, command.getClientId(context));
97         if (desc == null) {
98         // Do a brute force search for the LE
99
desc = findLayoutElementById(context, viewId, command.getId());
100         }
101     }
102
103     // If We still don't have a desc, we're stuck
104
if (desc == null) {
105         throw new IllegalArgumentException JavaDoc(
106         "Unable to locate handlers for '"
107         + command.getClientId(context) + "'.");
108     }
109
110     // Dispatch the Handlers from the LayoutElement
111
desc.dispatchHandlers(context, CommandEvent.EVENT_TYPE, event);
112     }
113
114     /**
115      * <p> This method returns the viewId of the ViewRoot given a UIComponent
116      * that is part of that ViewRoot.</p>
117      */

118     public static String JavaDoc getViewId(UIComponent comp) {
119     String JavaDoc result = null;
120     while ((comp != null) && !(comp instanceof UIViewRoot)) {
121         // Searching for the UIViewRoot...
122
comp = comp.getParent();
123     }
124     if (comp != null) {
125         // Found the UIViewRoot, get its "ViewId"
126
result = ((UIViewRoot) comp).getViewId();
127     }
128     // Return the result (or null)
129
return result;
130     }
131
132     /**
133      * <p> This method searches for the LayoutComponent that matches the given
134      * client ID. Although this is often possible, it won't work all the
135      * time. This is because there is no way to ensure a 1-to-1 mapping
136      * between the UIComponent and the LayoutComponent tree. A given
137      * LayoutComponent may create multiple UIComponent, the
138      * LayoutComponent tree may itself be dynamic, and the UIComponent
139      * tree may change after it is initially created from the
140      * LayoutComponent tree. For these reasons, this method may fail. In
141      * these circumstances, it is critical to store the necessary
142      * information with the UIComponent itself.</p>
143      */

144     public static LayoutElement findLayoutElementByClientId(FacesContext ctx, String JavaDoc layoutDefKey, String JavaDoc clientId) {
145     LayoutElement result = null;
146     try {
147         result =
148         findLayoutElementByClientId(
149             LayoutDefinitionManager.getManager(ctx).
150             getLayoutDefinition(layoutDefKey), clientId);
151     } catch (IOException JavaDoc ex) {
152         // FIXME: Report a low priority warning, returning null is fine
153
}
154     return result;
155     }
156
157     public static LayoutElement findLayoutElementByClientId(LayoutDefinition def, String JavaDoc clientId) {
158 // FIXME: TBD...
159
// FIXME: Walk LE tree, ignore non-LayoutComponent entries (this may cause a problem itself b/c of conditional statements & loops)
160
return null;
161     }
162
163     /**
164      * <p> This method simply searches the LayoutElement tree using the given
165      * id. As soon as it matches any LayoutElement in the tree w/ the
166      * given id, it returns it. This method does *not* respect
167      * NamingContainers as the only information given to this method is a
168      * simple "id".</p>
169      */

170     public static LayoutElement findLayoutElementById(FacesContext ctx, String JavaDoc layoutDefKey, String JavaDoc id) {
171     // Sanity check
172
if (id == null) {
173         return null;
174     }
175
176     LayoutElement result = null;
177     try {
178         result = findLayoutElementById(
179             LayoutDefinitionManager.getManager(ctx).
180             getLayoutDefinition(layoutDefKey), id);
181     } catch (IOException JavaDoc ex) {
182         // FIXME: Report a low priority warning, returning null is fine
183
}
184     return result;
185     }
186
187     /**
188      * <p> This method does not evaluate the id field of the LayoutElement
189      * when checking for a match, this means it will not find values where
190      * the LayoutComponent's id must be evaulated. Store the handlers on
191      * the UIComponent in this case.</p>
192      */

193     public static LayoutElement findLayoutElementById(LayoutElement elt, String JavaDoc id) {
194     // First check to see if the given LayoutElement is it
195
if (elt.getUnevaluatedId().equals(id)) {
196         return elt;
197     }
198
199     // Iterate over children and recurse (depth first)
200
LayoutElement child = null;
201     Iterator JavaDoc it = elt.getChildLayoutElements().iterator();
202     while (it.hasNext()) {
203         child = (LayoutElement) it.next();
204         if (child instanceof LayoutComponent) {
205         child = findLayoutElementById(child, id);
206         if (child != null) {
207             return child;
208         }
209         }
210     }
211     return null;
212     }
213
214     /**
215      * <p> Attribute name on a UIComponent which may store handlers for a
216      * CommandEvent. ("commandHandlers")</p>
217      */

218     public static final String JavaDoc COMMAND_HANDLERS = "command";
219 }
220
Popular Tags