KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > enterprise > tools > admingui > tree > MBeanTreeAdaptor


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
24 package com.sun.enterprise.tools.admingui.tree;
25
26 import com.sun.enterprise.tools.admingui.util.MBeanUtil;
27
28 import com.sun.enterprise.tools.jsfext.component.ComponentUtil;
29 import com.sun.enterprise.tools.jsfext.component.factory.basic.TreeAdaptor;
30 import com.sun.enterprise.tools.jsfext.component.factory.basic.TreeAdaptorBase;
31 import com.sun.enterprise.tools.jsfext.util.Util;
32
33 import com.sun.enterprise.tools.jsfext.layout.descriptor.LayoutComponent;
34
35 import java.util.Arrays JavaDoc;
36 import java.util.HashMap JavaDoc;
37 import java.util.List JavaDoc;
38 import java.util.Map JavaDoc;
39 import java.util.Properties JavaDoc;
40
41 import javax.faces.component.UIComponent;
42 import javax.faces.context.FacesContext;
43
44 import javax.management.ObjectName JavaDoc;
45
46
47 /**
48  * <p> The <code>MBeanTreeAdaptor</code> implementation must have a
49  * <code>public static MBeanTreeAdaptor getInstance(FacesContext,
50  * LayoutComponent, UIComponent)</code> method in order to get access to
51  * an instance of the <code>MBeanTreeAdaptor</code> instance.</p>
52  *
53  * <p> This class is used by <code>DynamicTreeNodeFactory</code>.</p>
54  *
55  * @author Ken Paulsen (ken.paulsen@sun.com)
56  */

57 public class MBeanTreeAdaptor extends TreeAdaptorBase {
58
59     /**
60      * <p> This constructor is not used.</p>
61      */

62     private MBeanTreeAdaptor() {
63     }
64
65     /**
66      * <p> This constructor saves the <code>LayoutComponent</code> descriptor
67      * and the <code>UIComponent</code> associated with this
68      * <code>TreeAdaptor</code>. This constructor is used by the
69      * getInstance() method.</p>
70      */

71     protected MBeanTreeAdaptor(LayoutComponent desc, UIComponent parent) {
72     super(desc, parent);
73     }
74
75     /**
76      * <p> This method provides access to an <code>MBeanTreeAdaptor</code>
77      * instance. Each time it is invoked, it returns a new instance.</p>
78      */

79     public static TreeAdaptor getInstance(FacesContext ctx, LayoutComponent desc, UIComponent parent) {
80     return new MBeanTreeAdaptor(desc, parent);
81     }
82
83     /**
84      * <p> This method is called shortly after
85      * {@link #getInstance(FacesContext, LayoutComponent, UIComponent)}.
86      * It provides a place for post-creation initialization to take
87      * occur.</p>
88      */

89     public void init() {
90     // Get the FacesContext
91
FacesContext ctx = FacesContext.getCurrentInstance();
92
93     // This is the descriptor for this dynamic TreeNode, it contains all
94
// information (options) necessary for this Adaptor
95
LayoutComponent desc = getLayoutComponent();
96
97     // The parent UIComponent
98
UIComponent parent = getParentUIComponent();
99
100     // Get the Object Name
101
Object JavaDoc val = desc.getEvaluatedOption(ctx, "objectName", parent);
102     if (val == null) {
103         throw new IllegalArgumentException JavaDoc(
104             "'objectName' must be specified!");
105     }
106         _objectName = (String JavaDoc) val;
107
108     // Get the Method Name
109
val = desc.getEvaluatedOption(ctx, "methodName", parent);
110     if (val == null) {
111         throw new IllegalArgumentException JavaDoc(
112             "'methodName' must be specified!");
113     }
114     _methodName = (String JavaDoc) val;
115
116     // Get Parameters
117
_paramsArray = null;
118     val = desc.getEvaluatedOption(ctx, "parameters", parent);
119     if (val != null) {
120         if (val instanceof List JavaDoc) {
121         _paramsArray = ((List JavaDoc) val).toArray();
122         } else {
123         _paramsArray = new Object JavaDoc[] {val};
124         }
125     }
126
127     // Get Parameter Types
128
_paramTypesArray = null;
129     val = desc.getEvaluatedOption(ctx, "paramTypes", parent);
130     if (val != null) {
131         if (val instanceof String JavaDoc) {
132         _paramTypesArray = new String JavaDoc[] {(String JavaDoc) val};
133         } else if (val instanceof List JavaDoc) {
134         _paramTypesArray = (String JavaDoc [])
135             ((List JavaDoc<String JavaDoc>) val).toArray(new String JavaDoc[0]);
136         } else {
137         throw new IllegalArgumentException JavaDoc(
138             "'paramTypes' must be a String or a List of types!");
139         }
140     }
141
142     // Get the attribute name for the text (optional)
143
_nameAtt = (String JavaDoc) desc.getEvaluatedOption(
144         ctx, "attributeName", parent);
145     if (_nameAtt != null) {
146         _nameAtt = _nameAtt.trim();
147         if (_nameAtt.length() == 0) {
148         _nameAtt = null;
149         }
150     }
151
152     // Get the method name for the text (optional)
153
_nameMethod = (String JavaDoc) desc.getEvaluatedOption(
154         ctx, "attrNameMethod", parent);
155     if (_nameMethod != null) {
156         _nameMethod = _nameMethod.trim();
157         if (_nameMethod.length() == 0) {
158         _nameMethod = null;
159         }
160     }
161
162     /*
163 FIXME: See "DynamicTreeNode.java -- The code in getChildObjectNames should be
164 FIXME: broken up between this method and the next (getChildTreeNodeObjects).
165 FIXME: This file should only deal w/ the normal MBean use case. WebServices
166 FIXME: should be handled via WebServiceTreeAdaptor (to be written).
167     */

168
169     // The following method should set the "key" to the node containing all
170
// the children... the children will also have keys which must be
171
// retrievable by the next method (getChildTreeNodeObjects)... these
172
// "keys" will be used by the rest of the methods in this file for
173
// getting information about the TreeNode that should be built.
174
setTreeNodeObject(_objectName);
175     }
176
177     /**
178      * <p> Returns child <code>TreeNode</code>s for the given
179      * <code>TreeNode</code> model Object.</p>
180      */

181     public List JavaDoc getChildTreeNodeObjects(Object JavaDoc nodeObject) {
182     if (nodeObject == null) {
183         return null;
184     }
185     if (nodeObject.toString().equals(_objectName)) {
186         // In this implementation _objectName represents the top-level,
187
// we need to find its children here
188
if (_children != null) {
189         return Arrays.asList((Object JavaDoc[])_children);
190         }
191             _children = (Object JavaDoc []) MBeanUtil.invoke(
192         _objectName, _methodName,
193         _paramsArray, _paramTypesArray);
194
195         // Ok, we go the result, provide an event in case we want to
196
// do some filtering
197
FacesContext ctx = FacesContext.getCurrentInstance();
198         Object JavaDoc retVal = getLayoutComponent().dispatchHandlers(
199             ctx, FilterTreeEvent.EVENT_TYPE,
200             new FilterTreeEvent(getParentUIComponent(), _children));
201         if ((retVal != null) && (retVal instanceof Object JavaDoc [])) {
202         // We have a return value, use it instead of the original list
203
_children = (Object JavaDoc []) retVal;
204         }
205     } else {
206         // Currently multiple levels are not implemented
207
return null;
208     }
209
210     return _children != null ? Arrays.asList((Object JavaDoc[])_children):null;
211     }
212
213     /**
214      * <p> This method returns the "options" that should be supplied to the
215      * factory that creates the <code>TreeNode</code> for the given tree
216      * node model object.</p>
217      *
218      * <p> Some useful options for the standard <code>TreeNode</code>
219      * component include:<p>
220      *
221      * <ul><li>text</li>
222      * <li>url</li>
223      * <li>imageURL</li>
224      * <li>target</li>
225      * <li>action<li>
226      * <li>actionListener</li>
227      * <li>expanded</li></ul>
228      *
229      * <p> See Tree / TreeNode component documentation for more details.</p>
230      */

231     public Map JavaDoc getFactoryOptions(Object JavaDoc nodeObject) {
232     if (nodeObject == null) {
233         return null;
234     }
235
236     LayoutComponent desc = getLayoutComponent();
237     Properties JavaDoc props = new Properties JavaDoc();
238     if (nodeObject.toString().equals(_objectName)) {
239         // This case deals with the top node.
240

241         // NOTE: All supported options must be handled here,
242
// otherwise they'll be ignored.
243
// NOTE: Options will be evaluated later, do not eval here.
244
setProperty(props, "text", desc.getOption("text"));
245         setProperty(props, "url", desc.getOption("url"));
246         setProperty(props, "imageURL", desc.getOption("imageURL"));
247         setProperty(props, "target", desc.getOption("target"));
248         setProperty(props, "action", desc.getOption("action"));
249
250         // NOTE: Although actionListener is supported, LH currently
251
// implements this to be the ActionListener of the "turner"
252
// which is inconsistent with "action". We should make use
253
// of the "Handler" feature which provides a "toggle"
254
// CommandEvent.
255
setProperty(props, "actionListener", desc.getOption("actionListener"));
256         setProperty(props, "expanded", desc.getOption("expanded"));
257     } else {
258         // This case deals with the children
259

260         // NOTE: All supported options must be handled here,
261
// otherwise they'll be ignored
262

263 // FIXME: There was a check near here (in DynamicTreeNode.updateKids(...) for
264
// FIXME: isChildValid... figure out how we want to expose an "exludes" list
265
// FIXME: or filter to make this more generalized.
266
if (nodeObject instanceof ObjectName JavaDoc) {
267         if (_nameAtt != null) {
268             setProperty(props, "text",
269             (String JavaDoc) MBeanUtil.getAttribute(
270                 (ObjectName JavaDoc) nodeObject, _nameAtt));
271         } else if (_nameMethod != null) {
272             // This is for monitoring MBeans, they don't have a name
273
// attr, but perhaps a getName() method.
274
setProperty(props, "text", (String JavaDoc) MBeanUtil.invoke(
275             (ObjectName JavaDoc) nodeObject, _nameMethod, null, null));
276         }
277         if (!props.containsKey("text")) {
278             // fallback to the object name
279
setProperty(props, "text", nodeObject.toString());
280         }
281         } else if (nodeObject instanceof String JavaDoc) {
282         setProperty(props, "text", (String JavaDoc) nodeObject);
283 /*
284     FIXME: This is from line #108 - 109 of DynamicTreeNode.java:
285     node.setAttribute("webServiceKey", webServiceKeyMap.get(name));
286     node.setAttribute("webServiceName", name);
287 */

288         } else {
289         throw new RuntimeException JavaDoc("'" + nodeObject
290             + "' Illegal type ("
291             + nodeObject.getClass().getName()
292             + ") for tree processing");
293         }
294
295         // Finish setting the child properties
296
setProperty(props, "url", desc.getOption("childURL"));
297         setProperty(props, "imageURL", desc.getOption("childImageURL"));
298         setProperty(props, "target", desc.getOption("childTarget"));
299         setProperty(props, "action", desc.getOption("childAction"));
300 // We are using "childActionListener" for the hyperlink, not the TreeNode
301
// setProperty(props, "actionListener", desc.getOption("childActionListener"));
302
setProperty(props, "expanded", desc.getOption("childExpanded"));
303     }
304
305     // Return the options
306
return props;
307     }
308
309     /**
310      * <p> Helper method for setting Properties while avoiding NPE's.</p>
311      */

312     private void setProperty(Properties JavaDoc props, String JavaDoc key, Object JavaDoc value) {
313     if (value != null) {
314         props.put(key, value);
315     }
316     }
317
318     /**
319      * <p> This method returns the <code>id</code> for the given tree node
320      * model object.</p>
321      */

322     public String JavaDoc getId(Object JavaDoc nodeObject) {
323     if (nodeObject == null) {
324         return "nullNodeObject";
325     }
326     if (nodeObject.toString().equals(_objectName)) {
327         // Top level can use the ID of the LayoutComponent
328
return getLayoutComponent().getId(
329         FacesContext.getCurrentInstance(), getParentUIComponent());
330     }
331     return genId(nodeObject.toString());
332     }
333
334     /**
335      * <p> This method generates an ID that is safe for JSF for the given
336      * String. It does not guarantee that the id is unique, it is the
337      * responsibility of the caller to pass in a String that will result
338      * in a UID. All non-ascii characters will be stripped.</p>
339      *
340      * @param uid A non-null String.
341      */

342     private String JavaDoc genId(String JavaDoc uid) {
343     char [] chArr = uid.toCharArray();
344     int len = chArr.length;
345     int newIdx = 0;
346     for (int idx=0; idx<len; idx++) {
347         if (Character.isLetter(chArr[idx])) {
348         chArr[newIdx++] = chArr[idx];
349         }
350     }
351     return new String JavaDoc(chArr, 0, newIdx);
352     }
353
354     /**
355      * <p> This method returns any facets that should be applied to the
356      * <code>TreeNode</code> that is created for the given tree node
357      * model object. Useful facets for the standard
358      * <code>TreeNode</code> component are: "content" and "image".</p>
359      */

360     public Map JavaDoc getFacets(UIComponent comp, Object JavaDoc nodeObject) {
361     if (nodeObject.toString().equals(_objectName)) {
362         return null;
363     }
364     LayoutComponent desc = this.getLayoutComponent();
365     Object JavaDoc val = desc.getOption("childActionListener");
366     Map JavaDoc map = null;
367     if (val != null) {
368         // We have an ActionListener, therefor we need to use a facet
369
Properties JavaDoc props = new Properties JavaDoc();
370         props.put("actionListener", val.toString());
371         setProperty(props, "target", desc.getOption("childTarget"));
372         setProperty(props, "text", comp.getAttributes().get("text"));
373
374         // Create Hyperlink
375
UIComponent link = ComponentUtil.getChild(
376             (UIComponent) null, "link",
377             "com.sun.enterprise.tools.jsfext.component.factory.basic.HyperlinkFactory",
378             props);
379
380         // Set href's handlers
381
List JavaDoc handlers = desc.getHandlers("childCommand");
382         if (handlers != null) {
383         link.getAttributes().put("command", handlers);
384         }
385
386         // Create a Facet Map
387
map = new HashMap JavaDoc();
388         map.put("content", link);
389     }
390     return map;
391     }
392
393     /**
394      * <p> Advanced framework feature which provides better handling for
395      * things such as expanding TreeNodes, beforeEncode, and other
396      * events.</p>
397      *
398      * <p> This method should return a <code>Map</code> of <code>List</code>
399      * of <code>Handler</code> objects. Each <code>List</code> in the
400      * <code>Map</code> should be registered under a key that cooresponds
401      * to to the "event" in which the <code>Handler</code>s should be
402      * invoked.</p>
403      */

404     public Map JavaDoc getHandlersByType(UIComponent comp, Object JavaDoc nodeObject) {
405     /* These handlers apply to the TreeNode not the Hyperlink */
406     /*
407     LayoutComponent lc = this.getLayoutComponent();
408     List list = lc.getHandlers("childCommand");
409     if (list != null) {
410         Map m = new HashMap();
411         m.put("command", list);
412         return m;
413     }
414     */

415     return null;
416     }
417
418     /**
419      * <p> This method returns the <code>UIComponent</code> factory class
420      * implementation that should be used to create a
421      * <code>TreeNode</code> for the given tree node model object.</p>
422
423     This method provides a means use different TreeNodeFactories,
424     currently we are using the default which is defined in the superclass,
425     if needed we can change this.
426
427     public String getFactoryClass(Object nodeObject) {
428     return "com.sun.enterprise.tools.jsfext.component.factory.basic.TreeNodeFactory";
429     }
430      */

431
432     /**
433      * The MBean object name.
434      */

435     private String JavaDoc _methodName = null;
436
437     /**
438      * The MBean object name.
439      */

440     private String JavaDoc _objectName = null;
441
442     /**
443      * The MBean method parameters.
444      */

445     private Object JavaDoc[] _paramsArray = null;
446
447     /**
448      * The MBean method parameter types.
449      */

450     private String JavaDoc[] _paramTypesArray= null;
451
452     /**
453      * The name of the attribute which describes the TreeNode name.
454      */

455     private String JavaDoc _nameAtt = null;
456
457     /**
458      * The name of the method which describes the TreeNode name.
459      */

460     private String JavaDoc _nameMethod = null;
461
462     /**
463      * This sub-nodes of the top-level Node.
464      */

465     private Object JavaDoc[] _children = null;
466 }
467
Popular Tags