KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > enterprise > tools > jsfext > layout > descriptor > LayoutComponent


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.layout.descriptor;
24
25 import com.sun.enterprise.tools.jsfext.component.ComponentUtil;
26 import com.sun.enterprise.tools.jsfext.component.ChildManager;
27 import com.sun.enterprise.tools.jsfext.el.VariableResolver;
28 import com.sun.enterprise.tools.jsfext.event.AfterCreateEvent;
29 import com.sun.enterprise.tools.jsfext.event.AfterEncodeEvent;
30 import com.sun.enterprise.tools.jsfext.event.BeforeCreateEvent;
31 import com.sun.enterprise.tools.jsfext.event.BeforeEncodeEvent;
32
33 import java.io.IOException JavaDoc;
34 import java.util.ArrayList JavaDoc;
35 import java.util.HashMap JavaDoc;
36 import java.util.List JavaDoc;
37 import java.util.Map JavaDoc;
38
39 import javax.faces.context.FacesContext;
40 import javax.faces.component.UIComponent;
41
42
43 /**
44  * <p> This class defines a <code>LayoutComponent</code>. A
45  * <code>LayoutComponent</code> describes a <code>UIComponent</code> to be
46  * instantiated. The method {@link #getType()} provides a
47  * {@link ComponentType} descriptor that is capable of providing a
48  * {@link com.sun.enterprise.tools.jsfext.component.factory.ComponentFactory}
49  * to perform the actual instantiation. This class also stores properties
50  * and facets (children) to be set on a newly instantiated instance.</p>
51  *
52  * @author Ken Paulsen (ken.paulsen@sun.com)
53  */

54 public class LayoutComponent extends LayoutElementBase implements LayoutElement {
55
56     /**
57      * <p> Constructor.</p>
58      */

59     public LayoutComponent(LayoutElement parent, String JavaDoc id, ComponentType type) {
60     super(parent, id);
61     _type = type;
62     }
63
64     /**
65      * <p> Accessor for type.</p>
66      */

67     public ComponentType getType() {
68     return _type;
69     }
70
71     /**
72      * <p> Determines if this component should be created even if there is
73      * already an existing <code>UIComponent</code>. It will "overwrite"
74      * the existing component if this property is true.</p>
75      */

76     public void setOverwrite(boolean value) {
77     _overwrite = value;
78     }
79
80     /**
81      * <p> Determines if this component should be created even if there is
82      * already an existing <code>UIComponent</code>. It will "overwrite"
83      * the existing component if this property is true.</p>
84      */

85     public boolean isOverwrite() {
86     return _overwrite;
87     }
88
89     /**
90      * <p> This method overrides LayoutElementBase.addChildLayoutElement().
91      * Child LayoutElements for LayoutComponent are limited to LayoutFacet
92      * objects. This method ensures that only LayoutFacet objects are
93      * added. If any other types are added, an IllegalArgumentException
94      * will be thrown.</p>
95      *
96      * @param element The LayoutElement to add.
97      *
98      * @throws IllegalArgumentException Thrown if LayoutElement is not a
99      * LayoutFacet
100      */

101     public void addChildLayoutElement(LayoutElement element) {
102     if (!(element instanceof LayoutComponent)
103         && !(element instanceof LayoutFacet)) {
104         throw new IllegalArgumentException JavaDoc("Only LayoutComponent and "
105             + "LayoutFacet LayoutElements may be added as children to "
106             + "a LayoutComponent!");
107     }
108     super.addChildLayoutElement(element);
109     }
110
111     /**
112      * <p> This method adds an option to the LayoutComponent. Options may be
113      * useful in constructing the LayoutComponent.</p>
114      *
115      * @param name The name of the option
116      * @param value The value of the option (may be List or String)
117      */

118     public void addOption(String JavaDoc name, Object JavaDoc value) {
119     _options.put(name, value);
120     }
121
122     /**
123      * <p> This method adds all the options in the given Map to the
124      * LayoutComponent. Options may be useful in constructing the
125      * LayoutComponent.</p>
126      *
127      * @param map The map of options to add.
128      */

129     public void addOptions(Map JavaDoc map) {
130     _options.putAll(map);
131     }
132
133     /**
134      * <p> Accessor method for an option. This method does not evaluate
135      * expressions.</p>
136      *
137      * @param name The option name to retrieve.
138      *
139      * @return The option value (List or String), or null if not found.
140      *
141      * @see #getEvaluatedOption(FacesContext, String, UIComponent)
142      */

143     public Object JavaDoc getOption(String JavaDoc name) {
144     return _options.get(name);
145     }
146
147     /**
148      * <p> Accessor method for an option. This method evaluates our own
149      * expressions (not JSF expressions).</p>
150      *
151      * @param name The option name to retrieve
152      * @param ctx The FacesContext
153      * @param component The UIComponent (may be null)
154      *
155      * @return The option value (List or String), or null if not found.
156      *
157      * @see #getOption(String)
158      */

159     public Object JavaDoc getEvaluatedOption(FacesContext ctx, String JavaDoc name, UIComponent component) {
160     // Get the option value
161
Object JavaDoc value = getOption(name);
162
163     // Invoke our own EL. This is needed b/c JSF's EL is designed for
164
// Bean getters only. It does not get CONSTANTS or pull data from
165
// other sources (such as session, request attributes, etc., etc.)
166
// Resolve our variables now because we cannot depend on the
167
// individual components to do this. We may want to find a way to
168
// make this work as a regular ValueBinding expression... but for
169
// now, we'll just resolve it here.
170
return VariableResolver.resolveVariables(ctx, this, component, value);
171     }
172
173     /**
174      * <p> This method returns true/false based on whether the given option
175      * name has been set.</p>
176      *
177      * @param name The option name to look for.
178      *
179      * @return true/false depending on whether the options exists.
180      */

181     public boolean containsOption(String JavaDoc name) {
182     return _options.containsKey(name);
183     }
184
185     /**
186      * <p> This method sets the Map of options.</p>
187      *
188      * @param options Map of options.
189      */

190     public void setOptions(Map JavaDoc options) {
191     _options = options;
192     }
193
194     /**
195      * <p> This method returns the options as a Map. This method does not
196      * evaluate expressions.</p>
197      *
198      * @return Map of options.
199      */

200     public Map JavaDoc getOptions() {
201     return _options;
202     }
203
204     /**
205      * <p> This method is overriden so that the correct UIComponent can be
206      * passed into the events. This is important so that correct
207      * component is searched for "instance" handlers.</p>
208      *
209      * @param context The <code>FacesContext</code>.
210      * @param component The <code>UIComponent</code>.
211      */

212     public void encode(FacesContext context, UIComponent parent) throws IOException JavaDoc {
213     // If overwrite...
214
if (isOverwrite()) {
215         String JavaDoc id = getId(context, parent);
216         if (parent.getFacets().remove(id) == null) {
217         UIComponent child = ComponentUtil.findChild(parent, id, null);
218         if (child != null) {
219             // Not a facet, try child...
220
parent.getChildren().remove(child);
221         }
222         }
223     }
224
225     // Display this UIComponent
226
// First find the UIComponent
227
UIComponent childComponent = null;
228     if (parent instanceof ChildManager) {
229         // If we have a ChildManager, take advantage of it...
230
childComponent = ((ChildManager) parent).getChild(context, this);
231     } else {
232         // Use local util method for finding / creating child component...
233
childComponent = getChild(context, parent);
234     }
235
236     Object JavaDoc result = dispatchHandlers(context, BEFORE_ENCODE,
237         new BeforeEncodeEvent(childComponent));
238
239     // Render the child UIComponent
240
encodeChild(context, childComponent);
241
242     // Invoke "after" handlers
243
result = dispatchHandlers(context, AFTER_ENCODE,
244         new AfterEncodeEvent(childComponent));
245     }
246
247     /**
248      * <p> Althought this method is part of the interface, it is not used b/c
249      * I overrode the encode() method which calls this method. This
250      * method does nothing except satisfy the compiler.</p>
251      */

252     public boolean encodeThis(FacesContext context, UIComponent parent) throws IOException JavaDoc {
253     return false;
254     }
255
256     /**
257      * <p> This method will find or create a <code>UIComponent</code> as
258      * described by this <code>LayoutComponent</code> descriptor. If the
259      * component already exists as a child or facet, it will be returned.
260      * If it creates a new <code>UIComponent</code>, it will typically be
261      * added to the given parent <code>UIComponent</code> as a facet (this
262      * actually depends on the factory that instantiates the
263      * <code>UIComponent</code>).</p>
264      *
265      * @param context The <code>FacesContext</code>
266      * @param parent The <code>UIComponent</code> to serve as the parent to
267      * search and to store the new <code>UIComponent</code>.
268      *
269      * @return The <code>UIComponent</code> requested (found or newly created)
270      */

271     public UIComponent getChild(FacesContext context, UIComponent parent) throws IOException JavaDoc {
272     UIComponent childComponent = null;
273
274     // First pull off the id from the descriptor
275
String JavaDoc id = this.getId(context, parent);
276     if ((id != null) && !(id.trim().equals(""))) {
277         // We have an id, use it to search for an already-created child
278
childComponent = ComponentUtil.findChild(parent, id, id);
279         if (childComponent != null) {
280         return childComponent;
281         }
282     }
283
284     // No id, or the component hasn't been created. In either case, we
285
// create a new component (moral: always have an id)
286

287     // Invoke "beforeCreate" handlers
288
this.beforeCreate(context, parent);
289
290     // Create UIComponent
291
childComponent =
292         ComponentUtil.createChildComponent(context, this, parent);
293
294     // Invoke "afterCreate" handlers
295
this.afterCreate(context, childComponent);
296
297     // Return the newly created UIComponent
298
return childComponent;
299     }
300
301     /**
302      * <p> This method retrieves the Handlers for the requested type. But
303      * also includes any handlers that are associated with the instance
304      * (i.e. the UIComponent).</p>
305      *
306      * @param type The type of <code>Handler</code>s to retrieve.
307      * @param event The associated <code>UIComponent</code> (or null).
308      *
309      * @return A List of Handlers.
310      */

311     public List JavaDoc getHandlers(String JavaDoc type, UIComponent comp) {
312     // 1st get list of handlers for definition of this LayoutElement
313
List JavaDoc handlers = null;
314
315     // Now check to see if there are any on the UIComponent
316
if (comp != null) {
317         List JavaDoc instHandlers = (List JavaDoc) comp.getAttributes().get(type);
318         if ((instHandlers != null) && (instHandlers.size() > 0)) {
319         // NOTE: Copy b/c this is <i>instance</i> + static
320
// Add the UIComponent instance handlers
321
handlers = new ArrayList JavaDoc(instHandlers);
322
323         List JavaDoc defHandlers = getHandlers(type);
324         if (defHandlers != null) {
325             // Add the LayoutElement "definition" handlers, if any
326
handlers.addAll(getHandlers(type));
327         }
328         }
329     }
330     if (handlers == null) {
331         handlers = getHandlers(type);
332     }
333
334     return handlers;
335     }
336
337     /**
338      * <p> This method is invoked before the Component described by this
339      * LayoutComponent is created. This allows handlers registered for
340      * "beforeCreate" functionality to be invoked.</p>
341      *
342      * @param context The FacesContext
343      *
344      * @return The result of invoking the handlers (null by default)
345      */

346     public Object JavaDoc beforeCreate(FacesContext context, UIComponent parent) {
347     // Invoke "beforeCreate" handlers
348
return dispatchHandlers(
349         context, BEFORE_CREATE, new BeforeCreateEvent(parent));
350     }
351
352     /**
353      * <p> This method is invoked after the Component described by this
354      * LayoutComponent is created. This allows handlers registered for
355      * "afterCreate" functionality to be invoked.</p>
356      *
357      * @param context The FacesContext
358      *
359      * @return The result of invoking the handlers (null by default)
360      */

361     public Object JavaDoc afterCreate(FacesContext context, UIComponent component) {
362     // Invoke "afterCreate" handlers
363
return dispatchHandlers(
364         context, AFTER_CREATE, new AfterCreateEvent(component));
365     }
366
367     /**
368      * <p> This method returns true if the child should be added to the parent
369      * component as a facet. Otherwise, it returns false indicating that
370      * it should exist as a real child. The default is true.</p>
371      *
372      * @return True if the child UIComponent should be added as a facet.
373      */

374     public boolean isFacetChild() {
375     return _isFacetChild;
376     }
377
378     /**
379      * <p> This method sets whether the child <code>UIComponent</code> should
380      * be set as a facet or a real child.</p>
381      *
382      * @param facetChild True if the child <code>UIComponent</code> should
383      * be added as a facet.
384      */

385     public void setFacetChild(boolean facetChild) {
386     _isFacetChild = facetChild;
387     }
388
389     /**
390      * <p> This method returns a flag that indicates if this
391      * <code>LayoutComponent</code> is nested (directly or indirectly)
392      * inside another <code>LayoutComponent</code>. This flag is used
393      * for such purposes as deciding if "instance" handlers are
394      * appropriate.</p>
395      *
396      * @returns <code>true</code> if component is nested.
397      */

398     public boolean isNested() {
399     return _nested;
400     }
401
402     /**
403      * <p> This method sets the nested flag for this
404      * <code>LayoutComponent</code>. This method is commonly only called
405      * from code that constructs the tree of {@link LayoutElement}
406      * components.</p>
407      *
408      * @param value The boolean value.
409      */

410     public void setNested(boolean value) {
411     _nested = value;
412     }
413
414
415     /**
416      * <p> Component type</p>
417      */

418     private ComponentType _type = null;
419
420     /**
421      * <p> Determines if this component should be created even if there is
422      * already an existing <code>UIComponent</code>. It will "overwrite"
423      * the existing component if this property is true.</p>
424      */

425     private boolean _overwrite = false;
426
427     /**
428      * <p> Map of options.</p>
429      */

430     private Map JavaDoc _options = new HashMap JavaDoc();
431
432     /**
433      *
434      */

435     private boolean _isFacetChild = true;
436
437     /**
438      * <p> This is the "type" for handlers to be invoked to handle
439      * "afterCreate" functionality for this element.</p>
440      */

441     public static final String JavaDoc AFTER_CREATE = "afterCreate";
442
443     /**
444      * <p> This is the "type" for handlers to be invoked to handle
445      * "beforeCreate" functionality for this element.</p>
446      */

447     public static final String JavaDoc BEFORE_CREATE = "beforeCreate";
448
449     /**
450      * <p> This defines the property key for specifying the facet name in
451      * which the component should be stored under in its parent
452      * UIComponent.</p>
453      */

454     public static final String JavaDoc FACET_NAME = "_facetName";
455
456     /**
457      * <p> The value of the nested property.</p>
458      */

459     private boolean _nested = false;
460 }
461
Popular Tags