001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common Development
008: * and Distribution License("CDDL") (collectively, the "License"). You
009: * may not use this file except in compliance with the License. You can obtain
010: * a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
011: * or glassfish/bootstrap/legal/LICENSE.txt. See the License for the specific
012: * language governing permissions and limitations under the License.
013: *
014: * When distributing the software, include this License Header Notice in each
015: * file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
016: * Sun designates this particular file as subject to the "Classpath" exception
017: * as provided by Sun in the GPL Version 2 section of the License file that
018: * accompanied this code. If applicable, add the following below the License
019: * Header, with the fields enclosed by brackets [] replaced by your own
020: * identifying information: "Portions Copyrighted [year]
021: * [name of copyright owner]"
022: *
023: * Contributor(s):
024: *
025: * If you wish your version of this file to be governed by only the CDDL or
026: * only the GPL Version 2, indicate your decision by adding "[Contributor]
027: * elects to include this software in this distribution under the [CDDL or GPL
028: * Version 2] license." If you don't indicate a single choice of license, a
029: * recipient has the option to distribute your version of this file under
030: * either the CDDL, the GPL Version 2 or to extend the choice of license to
031: * its licensees as provided above. However, if you add GPL Version 2 code
032: * and therefore, elected the GPL Version 2 license, then the option applies
033: * only if the new code is made subject to such option by the copyright
034: * holder.
035: */
036:
037: package com.sun.jbi.jsf.util;
038:
039: import com.sun.enterprise.tools.admingui.tree.FilterTreeEvent;
040: import com.sun.enterprise.tools.admingui.util.JMXUtil;
041:
042: import com.sun.jbi.jsf.bean.ListBean;
043: import com.sun.jbi.jsf.util.BeanUtilities;
044: import com.sun.jbi.jsf.util.JBILogger;
045: import com.sun.jbi.ui.common.JBIAdminCommands;
046: import com.sun.jbi.ui.common.JBIComponentInfo;
047: import com.sun.jbi.ui.common.ServiceAssemblyInfo;
048: import com.sun.jbi.ui.common.ServiceUnitInfo;
049: import com.sun.jbi.jsf.util.ServiceUnitInfoWrapper;
050:
051: import com.sun.jsftemplating.component.ComponentUtil;
052: import com.sun.jsftemplating.component.factory.tree.TreeAdaptor;
053: import com.sun.jsftemplating.component.factory.tree.TreeAdaptorBase;
054: import com.sun.jsftemplating.util.Util;
055:
056: import com.sun.jsftemplating.layout.descriptors.LayoutComponent;
057: import com.sun.jsftemplating.layout.event.CommandActionListener;
058:
059: import java.util.ArrayList;
060: import java.util.Arrays;
061: import java.util.HashMap;
062: import java.util.Iterator;
063: import java.util.List;
064: import java.util.logging.Logger;
065: import java.util.Map;
066: import java.util.Properties;
067:
068: import javax.faces.component.ActionSource;
069: import javax.faces.component.UIComponent;
070: import javax.faces.context.FacesContext;
071:
072: /**
073: * <p> The <code>JBITreeAdaptor</code> implementation must have a
074: * <code>public static JBITreeAdaptor getInstance(FacesContext,
075: * LayoutComponent, UIComponent)</code> method in order to get access to
076: * an instance of the <code>JBITreeAdaptor</code> instance.</p>
077: *
078: * <p> This class is used by <code>DynamicTreeNodeFactory</code>.</p>
079: *
080: *
081: */
082: public class JBITreeAdaptor extends TreeAdaptorBase {
083:
084: private static Logger sLog;
085: private JBIAdminCommands mJac = BeanUtilities.getClient();
086:
087: /**
088: * <p> This constructor is not used.</p>
089: */
090: private JBITreeAdaptor() {
091: }
092:
093: /**
094: * <p> This constructor saves the <code>LayoutComponent</code> descriptor
095: * and the <code>UIComponent</code> associated with this
096: * <code>TreeAdaptor</code>. This constructor is used by the
097: * getInstance() method.</p>
098: */
099: protected JBITreeAdaptor(LayoutComponent desc, UIComponent parent) {
100: super (desc, parent);
101: }
102:
103: /**
104: * <p> This method provides access to an <code>JBITreeAdaptor</code>
105: * instance. Each time it is invoked, it returns a new instance.</p>
106: */
107: public static TreeAdaptor getInstance(FacesContext ctx,
108: LayoutComponent desc, UIComponent parent) {
109: return new JBITreeAdaptor(desc, parent);
110: }
111:
112: /**
113: * <p> This method is called shortly after
114: * {@link #getInstance(FacesContext, LayoutComponent, UIComponent)}.
115: * It provides a place for post-creation initialization to take
116: * occur.</p>
117: */
118: public void init() {
119: //initialise the logger
120: sLog = JBILogger.getInstance();
121:
122: // Get the FacesContext
123: FacesContext ctx = FacesContext.getCurrentInstance();
124:
125: // This is the descriptor for this dynamic TreeNode, it contains all
126: // information (options) necessary for this Adaptor
127: LayoutComponent desc = getLayoutComponent();
128:
129: // The parent UIComponent
130: UIComponent parent = getParentUIComponent();
131:
132: // Get the Method Name
133: Object val = desc.getEvaluatedOption(ctx,
134: "treeAdaptorListType", parent);
135: if (val == null) {
136: throw new IllegalArgumentException(
137: "'treeAdaptorListType' must be specified!");
138: }
139: mAdaptorListType = (String) val;
140:
141: setTreeNodeObject(mAdaptorListType);
142: }
143:
144: /** 2/13/2007
145: * <p> Returns child <code>TreeNode</code>s for the given
146: * <code>TreeNode</code> model Object.</p>
147: */
148: public List getChildTreeNodeObjects(Object nodeObject) {
149: sLog.fine("JBITreeAdaptor getChildTreeNodeObjects("
150: + nodeObject + "), mAdaptorListType="
151: + mAdaptorListType);
152:
153: String target = "server";
154: List result = null;
155:
156: if (null != nodeObject) {
157: if (nodeObject.equals(mAdaptorListType)) {
158: ListBean listBean = BeanUtilities.getListBean();
159: String xmlQueryResults;
160:
161: if ("deployments".equals(mAdaptorListType)) {
162: xmlQueryResults = listBean
163: .getListServiceAssemblies();
164: sLog
165: .fine("JBITreeAdaptor getChildTreeNodeObjects(...), xmlQueryResults="
166: + xmlQueryResults);
167: List saInfoList = ServiceAssemblyInfo
168: .readFromXmlTextWithProlog(xmlQueryResults);
169:
170: mChildren = saInfoList.toArray();
171: }
172:
173: else if ("bindingsEngines".equals(mAdaptorListType)) {
174: xmlQueryResults = listBean
175: .getListBindingComponents();
176: sLog
177: .fine("JBITreeAdaptor getChildTreeNodeObjects(...), xmlQueryResults="
178: + xmlQueryResults);
179: List bcCompInfoList = JBIComponentInfo
180: .readFromXmlText(xmlQueryResults);
181:
182: xmlQueryResults = listBean.getListServiceEngines();
183: sLog
184: .fine("JBITreeAdaptor getChildTreeNodeObjects(...), xmlQueryResults="
185: + xmlQueryResults);
186: List seCompInfoList = JBIComponentInfo
187: .readFromXmlText(xmlQueryResults);
188:
189: List operableComponentsList = new ArrayList();
190: operableComponentsList.addAll(bcCompInfoList);
191: operableComponentsList.addAll(seCompInfoList);
192:
193: mChildren = operableComponentsList.toArray();
194: }
195:
196: else if ("libraries".equals(mAdaptorListType)) {
197: xmlQueryResults = listBean.getListSharedLibraries();
198: sLog
199: .fine("JBITreeAdaptor getChildTreeNodeObjects(...), xmlQueryResults="
200: + xmlQueryResults);
201: List slCompInfoList = JBIComponentInfo
202: .readFromXmlText(xmlQueryResults);
203: mChildren = slCompInfoList.toArray();
204: }
205:
206: if (mChildren != null) {
207: sLog
208: .fine("JBITreeAdaptor getChildTreeNodeObjects(...), mChildren.length="
209: + mChildren.length);
210: result = Arrays.asList((Object[]) mChildren);
211: }
212: }
213:
214: else if (nodeObject instanceof ServiceAssemblyInfo) {
215: List suInfoList = new ArrayList();
216: ServiceAssemblyInfo saInfo = (ServiceAssemblyInfo) nodeObject;
217: String saName = saInfo.getName();
218: List infoList = saInfo.getServiceUnitInfoList();
219: Iterator<Object> it2 = infoList.iterator();
220:
221: while (it2.hasNext()) {
222: Object suInfoObject = it2.next();
223: String compName = ((ServiceUnitInfo) suInfoObject)
224: .getTargetName();
225: ServiceUnitInfoWrapper wrapper = new ServiceUnitInfoWrapper(
226: (ServiceUnitInfo) suInfoObject, compName,
227: saName, target);
228: suInfoList.add(wrapper);
229: wrapper.setQueryString("sa");
230: }
231: result = suInfoList;
232: }
233:
234: else if (nodeObject instanceof JBIComponentInfo) {
235: JBIComponentInfo compInfo = (JBIComponentInfo) nodeObject;
236: String compName = compInfo.getName();
237: List saInfoList = null;
238: List suInfoList = new ArrayList();
239:
240: try {
241: String xml = mJac.listServiceAssemblies(compName,
242: target);
243: saInfoList = ServiceAssemblyInfo
244: .readFromXmlTextWithProlog(xml);
245: if (saInfoList != null) {
246: Iterator<Object> it = saInfoList.iterator();
247: while (it.hasNext()) {
248: Object saInfoObject = it.next();
249: String saName = ((ServiceAssemblyInfo) saInfoObject)
250: .getName();
251: List infoList = ((ServiceAssemblyInfo) saInfoObject)
252: .getServiceUnitInfoList();
253: Iterator<Object> it2 = infoList.iterator();
254: while (it2.hasNext()) {
255: Object suInfoObject = it2.next();
256: String tgtName = ((ServiceUnitInfo) suInfoObject)
257: .getTargetName();
258: if (tgtName.equals(compName)) {
259: ServiceUnitInfoWrapper wrapper = new ServiceUnitInfoWrapper(
260: (ServiceUnitInfo) suInfoObject,
261: compName, saName, target);
262: wrapper.setQueryString("comp");
263: suInfoList.add(wrapper);
264: }
265: }
266: }
267: }
268: } catch (com.sun.jbi.ui.common.JBIRemoteException jbiRemoteEx) {
269: sLog
270: .fine("JBITreeAdaptor.getChildTreeNodeObjects(): caught jbiRemoteEx="
271: + jbiRemoteEx);
272: }
273: result = suInfoList;
274: }
275:
276: }
277: sLog.fine("JBITreeAdaptor getChildTreeNodeObjects, result="
278: + result);
279: return result;
280: }
281:
282: /**
283: * <p> This method returns the "options" that should be supplied to the
284: * factory that creates the <code>TreeNode</code> for the given tree
285: * node model object.</p>
286: *
287: * <p> Some useful options for the standard <code>TreeNode</code>
288: * component include:<p>
289: *
290: * <ul><li>text</li>
291: * <li>url</li>
292: * <li>imageURL</li>
293: * <li>target</li>
294: * <li>action<li>
295: * <li>actionListener</li>
296: * <li>expanded</li></ul>
297: *
298: * <p> See Tree / TreeNode component documentation for more details.</p>
299: */
300: public Map<String, Object> getFactoryOptions(Object nodeObject) {
301: Map<String, Object> result = null;
302:
303: if (null != nodeObject) {
304: LayoutComponent desc = getLayoutComponent();
305: result = new HashMap<String, Object>();
306:
307: sLog.fine("JBITreeAdaptor getFactoryOptions (" + nodeObject
308: + "), nodeObject.getClass()="
309: + nodeObject.getClass());
310:
311: if (nodeObject instanceof String) {
312: // This case deals with the top node.
313:
314: // NOTE: All supported options must be handled here,
315: // otherwise they'll be ignored.
316: // NOTE: Options will be evaluated later, do not eval here.
317: setProperty(result, "text", desc.getOption("text"));
318: setProperty(result, "url", desc.getOption("url"));
319: setProperty(result, "imageURL", desc
320: .getOption("imageURL"));
321: setProperty(result, "target", desc.getOption("target"));
322: setProperty(result, "action", desc.getOption("action"));
323:
324: // NOTE: Although actionListener is supported, LH currently
325: // implements this to be the ActionListener of the "turner"
326: // which is inconsistent with "action". We should make use
327: // of the "Handler" feature which provides a "toggle"
328: // CommandEvent.
329: setProperty(result, "actionListener", desc
330: .getOption("actionListener"));
331: setProperty(result, "expanded", desc
332: .getOption("expanded"));
333: sLog
334: .fine("JBITreeAdaptor getFactoryOptions (parent), text="
335: + desc.getOption("text"));
336:
337: } else {
338: // This case deals with the children
339:
340: // NOTE: All supported options must be handled here,
341: // otherwise they'll be ignored
342:
343: // Finish setting the child properties
344: String childName = null;
345: String imageUrlSuffix = null;
346: String type = null;
347: String compType = null;
348: String urlSuffix = "type=";
349: String urlBase = (String) desc
350: .getOption("childURLbase");
351:
352: if (nodeObject instanceof JBIComponentInfo) {
353: JBIComponentInfo compInfo = (JBIComponentInfo) nodeObject;
354: childName = compInfo.getName();
355: type = compInfo.getType();
356: sLog
357: .fine("JBITreeAdaptor getFactoryOptions (child), childName="
358: + childName + ", type=" + type);
359: BeanUtilities.setStringPropertyUsingExpression(
360: childName,
361: "#{sessionScope.serviceAssemblyName}");
362: }
363:
364: else if (nodeObject instanceof ServiceAssemblyInfo) {
365: ServiceAssemblyInfo saInfo = (ServiceAssemblyInfo) nodeObject;
366: childName = saInfo.getName();
367: type = "service-assembly";
368: }
369:
370: else if (nodeObject instanceof ServiceUnitInfoWrapper) {
371: ServiceUnitInfo suInfo = ((ServiceUnitInfoWrapper) nodeObject)
372: .getServiceUnitInfo();
373: childName = suInfo.getName();
374: type = "service-unit";
375:
376: String saName = ((ServiceUnitInfoWrapper) nodeObject)
377: .getServiceAssemblyName();
378: String compName = ((ServiceUnitInfoWrapper) nodeObject)
379: .getComponentName();
380: String qs = ((ServiceUnitInfoWrapper) nodeObject)
381: .getQueryString();
382:
383: compType = ((ServiceUnitInfoWrapper) nodeObject)
384: .getComponentType();
385:
386: String grandChildURLBase = "/jbi/cluster/showServiceUnit.jsf?";
387: if (urlBase.indexOf("cluster") == -1) {
388: grandChildURLBase = "/jbi/pe/showServiceUnit.jsf?";
389: }
390: urlBase = (String) grandChildURLBase + "saname="
391: + saName + "&" + "qs=" + qs + "&"
392: + "compName=" + compName + "&"
393: + "compType=" + compType + "&";
394: }
395:
396: if (null != childName) {
397: setProperty(result, "text", childName);
398: urlSuffix += type + "&name=" + childName;
399: if ("service-assembly".equals(type)) {
400: imageUrlSuffix = "JBIServiceAssembly.gif";
401: } else if ("binding-component".equals(type)) {
402: imageUrlSuffix = "JBIBindingComponent.gif";
403: } else if ("service-engine".equals(type)) {
404: imageUrlSuffix = "JBIServiceEngine.gif";
405: } else if ("shared-library".equals(type)) {
406: imageUrlSuffix = "JBISharedLibrary.gif";
407: } else if ("service-unit".equals(type)) {
408: imageUrlSuffix = "JBISU.gif"; // Generic Service Unit
409: // *** TBD remove comment bars after images have been created.
410: if (compType
411: .equals(JBIConstants.JBI_BINDING_COMPONENT_TYPE)) {
412: //imageUrlSuffix = "JBIBCSU.gif"; // Binding Component Service Unit
413: } else if (compType
414: .equals(JBIConstants.JBI_SERVICE_ENGINE_TYPE)) {
415: //imageUrlSuffix = "JBISESU.gif"; // Service Engine Service Unit
416: }
417: }
418: }
419: String url = urlBase + urlSuffix;
420: sLog.fine("JBITreeAdaptor.getFactoryOptions(...), url="
421: + url + ", imageUrlSuffix=" + imageUrlSuffix);
422: setProperty(result, "url", url);
423: setProperty(result, "imageURL", desc
424: .getOption("childImageURLbase")
425: + imageUrlSuffix);
426: setProperty(result, "target", desc
427: .getOption("childTarget"));
428: setProperty(result, "action", desc
429: .getOption("childAction"));
430: setProperty(result, "expanded", desc
431: .getOption("childExpanded"));
432: sLog
433: .fine("JBITreeAdaptor getFactoryOptions (child), type="
434: + type + ", url=" + url);
435: }
436: }
437:
438: sLog.fine("JBITreeAdaptor getFactoryOptions, result=" + result);
439: return result;
440: }
441:
442: /**
443: * <p> Helper method for setting Properties while avoiding NPE's.</p>
444: */
445: void setProperty(Map props, String key, Object value) {
446: if (value != null) {
447: props.put(key, value);
448: }
449: }
450:
451: /**
452: * <p> This method returns the <code>id</code> for the given tree node
453: * model object.</p>
454: */
455: public String getId(Object nodeObject) {
456: String result = "nullNodeObject";
457:
458: if (null != nodeObject) {
459: result = genId(nodeObject.toString());
460: }
461:
462: return result;
463: }
464:
465: /**
466: * <p> This method generates an ID that is safe for JSF for the given
467: * String. It does not guarantee that the id is unique, it is the
468: * responsibility of the caller to pass in a String that will result
469: * in a UID. All non-ascii characters will be stripped.</p>
470: *
471: * @param uid A non-null String.
472: */
473: private String genId(String uid) {
474: char[] chArr = uid.toCharArray();
475: int len = chArr.length;
476: int newIdx = 0;
477: for (int idx = 0; idx < len; idx++) {
478: char test = chArr[idx];
479: if (Character.isLetterOrDigit(test) || test == '_'
480: || test == '-') {
481: chArr[newIdx++] = test;
482: }
483: }
484: return new String(chArr, 0, newIdx);
485: }
486:
487: /**
488: * <p> This method returns any facets that should be applied to the
489: * <code>TreeNode (comp)</code>. Useful facets for the sun
490: * <code>TreeNode</code> component are: "content" and "image".</p>
491: *
492: * <p> Facets that already exist on <code>comp</code>, or facets that
493: * are directly added to <code>comp</code> do not need to be returned
494: * from this method.</p>
495: *
496: * <p> This implementation directly adds a "content" facet and returns
497: * <code>null</code> from this method.</p>
498: *
499: * @param comp The tree node <code>UIComponent</code>.
500: * @param nodeObject The (model) object representing the tree node.
501: */
502: public Map<String, UIComponent> getFacets(UIComponent comp,
503: Object nodeObject) {
504: return null;
505: }
506:
507: /**
508: * <p> Advanced framework feature which provides better handling for
509: * things such as expanding TreeNodes, beforeEncode, and other
510: * events.</p>
511: *
512: * <p> This method should return a <code>Map</code> of <code>List</code>
513: * of <code>Handler</code> objects. Each <code>List</code> in the
514: * <code>Map</code> should be registered under a key that cooresponds
515: * to to the "event" in which the <code>Handler</code>s should be
516: * invoked.</p>
517: */
518: public Map getHandlersByType(UIComponent comp, Object nodeObject) {
519: return null;
520: }
521:
522: private String mAdaptorListType;
523: Object[] mChildren;
524: private String mNameAtt;
525: }
|