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
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041: package org.netbeans.modules.sun.manager.jbi.nodes;
042:
043: import com.sun.esb.management.api.administration.AdministrationService;
044: import com.sun.esb.management.api.deployment.DeploymentService;
045: import com.sun.esb.management.common.ManagementRemoteException;
046: import com.sun.esb.management.common.data.ServiceAssemblyStatisticsData;
047: import com.sun.jbi.ui.common.JBIComponentInfo;
048: import com.sun.jbi.ui.common.ServiceAssemblyInfo;
049: import com.sun.jbi.ui.common.ServiceUnitInfo;
050: import java.awt.Image;
051: import java.util.List;
052: import java.util.Map;
053:
054: import java.util.logging.Logger;
055: import javax.management.Attribute;
056: import javax.management.MBeanAttributeInfo;
057: import javax.swing.Action;
058: import javax.swing.SwingUtilities;
059: import org.netbeans.modules.sun.manager.jbi.GenericConstants;
060: import org.netbeans.modules.sun.manager.jbi.actions.RefreshAction;
061: import org.netbeans.modules.sun.manager.jbi.management.JBIMBeanTaskResultHandler;
062:
063: import org.netbeans.modules.sun.manager.jbi.util.ProgressUI;
064: import org.netbeans.modules.sun.manager.jbi.actions.ShutdownAction;
065: import org.netbeans.modules.sun.manager.jbi.actions.StartAction;
066: import org.netbeans.modules.sun.manager.jbi.actions.StopAction;
067: import org.netbeans.modules.sun.manager.jbi.actions.UndeployAction;
068: import org.netbeans.modules.sun.manager.jbi.management.AppserverJBIMgmtController;
069: import org.netbeans.modules.sun.manager.jbi.management.wrapper.api.PerformanceMeasurementServiceWrapper;
070: import org.netbeans.modules.sun.manager.jbi.management.wrapper.api.RuntimeManagementServiceWrapper;
071: import org.netbeans.modules.sun.manager.jbi.util.Utils;
072: import org.openide.DialogDisplayer;
073: import org.openide.NotifyDescriptor;
074: import org.openide.nodes.Sheet;
075: import org.openide.actions.PropertiesAction;
076: import org.openide.util.NbBundle;
077: import org.openide.util.actions.SystemAction;
078:
079: /**
080: * Node for one JBI Service Assembly.
081: *
082: * @author jqian
083: */
084: public class JBIServiceAssemblyNode extends
085: AppserverJBIMgmtContainerNode implements Startable, Stoppable,
086: Shutdownable, Undeployable {
087:
088: private static final String SERVICE_ASSEMBLY_STATISTICS_SHEET_SET_NAME = "SERVICE_ASSEMBLY_STATISTICS"; // NOI18N
089: private boolean busy;
090:
091: private static Logger logger = Logger
092: .getLogger("org.netbeans.modules.sun.manager.jbi.nodes.JBIServiceAssemblyNode"); // NOI18N
093:
094: /** Creates a new instance of ServiceAssemblyNode */
095: public JBIServiceAssemblyNode(
096: final AppserverJBIMgmtController controller, String name,
097: String description) {
098: super (controller, NodeType.SERVICE_ASSEMBLY);
099:
100: setName(name);
101:
102: setDisplayName(name);
103:
104: // Use HTML version for tooltip.
105: setShortDescription(Utils.getTooltip(description));
106: // Use non-HTML version in the property sheet's description area.
107: setValue("nodeDescription", description); // NOI18N
108: }
109:
110: @Override
111: protected Sheet createSheet() {
112: Sheet sheet = new Sheet();
113:
114: addSheetSet(sheet, GENERAL_SHEET_SET_NAME,
115: "LBL_GENERAL_PROPERTIES", // NOI18N
116: "DSC_GENERAL_PROPERTIES", // NOI18N
117: getGeneralSheetSetProperties());
118:
119: // Augment the general property sheet by adding SA statistics sheet
120: try {
121: addSheetSet(sheet,
122: SERVICE_ASSEMBLY_STATISTICS_SHEET_SET_NAME,
123: "LBL_SERVICE_ASSEMBLY_STATISTICS_PROPERTIES", // NOI18N
124: "DSC_SERVICE_ASSEMBLY_STATISTICS_PROPERTIES", // NOI18N
125: getServiceAssemblyStatisticsSheetSetProperties());
126: } catch (ManagementRemoteException e) {
127: logger.warning(e.getMessage());
128: }
129: return sheet;
130: }
131:
132: private Map<Attribute, MBeanAttributeInfo> getServiceAssemblyStatisticsSheetSetProperties()
133: throws ManagementRemoteException {
134: AppserverJBIMgmtController controller = getAppserverJBIMgmtController();
135: PerformanceMeasurementServiceWrapper perfService = controller
136: .getPerformanceMeasurementServiceWrapper();
137: ServiceAssemblyStatisticsData statistics = perfService
138: .getServiceAssemblyStatistics(getName(), SERVER_TARGET);
139: return Utils.getIntrospectedPropertyMap(statistics, true);
140: }
141:
142: public ServiceAssemblyInfo getAssemblyInfo() {
143: try {
144: return getRuntimeManagementServiceWrapper()
145: .getServiceAssembly(getName(), SERVER_TARGET);
146: } catch (ManagementRemoteException e) {
147: NotifyDescriptor d = new NotifyDescriptor.Message(e
148: .getMessage(), NotifyDescriptor.ERROR_MESSAGE);
149: DialogDisplayer.getDefault().notify(d);
150: }
151:
152: return null;
153: }
154:
155: private String getAssemblyState() {
156: ServiceAssemblyInfo assembly = getAssemblyInfo();
157: return assembly != null ? assembly.getState() : null;
158: }
159:
160: private void clearServiceAssemblyStatusCache() {
161: getRuntimeManagementServiceWrapper()
162: .clearServiceAssemblyStatusCache();
163: }
164:
165: /**
166: *
167: */
168: @Override
169: public Image getIcon(int type) {
170:
171: String baseIconName = IconConstants.SERVICE_ASSEMBLY_ICON;
172:
173: String status = getAssemblyState();
174:
175: String externalBadgeIconName = null;
176: if (busy) {
177: externalBadgeIconName = IconConstants.BUSY_ICON;
178: } else {
179: if (JBIComponentInfo.SHUTDOWN_STATE.equals(status)) {
180: externalBadgeIconName = IconConstants.INSTALLED_ICON;
181: } else if (JBIComponentInfo.STOPPED_STATE.equals(status)) {
182: externalBadgeIconName = IconConstants.STOPPED_ICON;
183: } else if (!JBIComponentInfo.STARTED_STATE.equals(status)) {
184: externalBadgeIconName = IconConstants.UNKNOWN_ICON;
185: }
186: }
187:
188: return Utils.getBadgedIcon(getClass(), baseIconName, null,
189: externalBadgeIconName);
190: }
191:
192: // For now, use the same open for open/closed state
193: @Override
194: public Image getOpenedIcon(int type) {
195: return getIcon(type);
196: }
197:
198: /**
199: * Return the actions associated with the menu drop down seen when
200: * a user right-clicks on a node in the plugin.
201: *
202: * @param boolean true/false
203: * @return An array of Action objects.
204: */
205: @Override
206: public Action[] getActions(boolean flag) {
207: return new SystemAction[] {
208: SystemAction.get(StartAction.class),
209: SystemAction.get(StopAction.class),
210: SystemAction.get(ShutdownAction.Normal.class),
211: SystemAction.get(UndeployAction.Normal.class),
212: null,
213: //SystemAction.get(ShutdownAction.Force.class),
214: SystemAction.get(UndeployAction.Force.class), null,
215: SystemAction.get(PropertiesAction.class),
216: SystemAction.get(RefreshAction.class) };
217: }
218:
219: @Override
220: public void refresh() {
221: // clear the cache first
222: RuntimeManagementServiceWrapper service = getRuntimeManagementServiceWrapper();
223: service.clearServiceAssemblyStatusCache();
224:
225: super .refresh();
226:
227: fireIconChange(); // necessary for the SA node to refresh
228:
229: // Explicitly reset the property sheet (since the property sheet in
230: // AbstractNode is "sticky").
231: setSheet(createSheet());
232: }
233:
234: /**
235: * Return the SheetProperties to be displayed for this JVM.
236: *
237: * @return A java.util.Map containing all JVM properties.
238: */
239: private Map<Attribute, MBeanAttributeInfo> getGeneralSheetSetProperties() {
240: ServiceAssemblyInfo assemblyInfo = getAssemblyInfo();
241: return Utils.getIntrospectedPropertyMap(assemblyInfo, true,
242: MODEL_BEAN_INFO_PACKAGE_NAME);
243: }
244:
245: public Attribute setSheetProperty(String attrName, Object value) {
246: return null;
247: }
248:
249: /**
250: *
251: * @param busy
252: */
253: private void setBusy(boolean busy) {
254: this .busy = busy;
255: fireIconChange();
256: }
257:
258: private void updatePropertySheet() {
259: Sheet sheet = createSheet();
260: setSheet(sheet);
261: firePropertySetsChange(null, null);
262: }
263:
264: //========================== Startable =====================================
265: public boolean canStart() {
266:
267: boolean ret = false;
268:
269: if (!busy) {
270: ServiceAssemblyInfo saInfo = getAssemblyInfo();
271: String assemblyState = (saInfo != null) ? saInfo.getState()
272: : null;
273:
274: if (ServiceAssemblyInfo.STOPPED_STATE.equals(assemblyState)) {
275: ret = true;
276: } else if (ServiceAssemblyInfo.SHUTDOWN_STATE
277: .equals(assemblyState)) {
278: ret = true;
279: } else if (ServiceAssemblyInfo.STARTED_STATE
280: .equals(assemblyState)) {
281: List<ServiceUnitInfo> units = saInfo
282: .getServiceUnitInfoList();
283: if (units != null) {
284: for (ServiceUnitInfo unit : units) {
285: String unitState = unit.getState();
286: if (ServiceAssemblyInfo.STOPPED_STATE
287: .equals(unitState)
288: || ServiceAssemblyInfo.SHUTDOWN_STATE
289: .equals(unitState)) {
290: ret = true;
291: break;
292: }
293: }
294: }
295: }
296: }
297:
298: return ret;
299: }
300:
301: public void start() {
302: RuntimeManagementServiceWrapper mgmtService = getRuntimeManagementServiceWrapper();
303:
304: if (mgmtService == null) {
305: return;
306: }
307:
308: final String assemblyName = getName();
309:
310: String title = NbBundle.getMessage(
311: JBIServiceAssemblyNode.class,
312: "LBL_Starting_Service_Assembly", // NOI18N
313: new Object[] { assemblyName });
314: final ProgressUI progressUI = new ProgressUI(title, false);
315:
316: SwingUtilities.invokeLater(new Runnable() {
317: public void run() {
318: setBusy(true);
319: progressUI.start();
320: }
321: });
322:
323: String result = null;
324: try {
325: result = mgmtService.startServiceAssembly(assemblyName,
326: SERVER_TARGET);
327: } catch (ManagementRemoteException e) {
328: result = e.getMessage();
329: } finally {
330: JBIMBeanTaskResultHandler
331: .showRemoteInvokationResult(
332: GenericConstants.START_SERVICE_ASSEMBLY_OPERATION_NAME,
333: assemblyName, result);
334: }
335:
336: SwingUtilities.invokeLater(new Runnable() {
337: public void run() {
338: clearServiceAssemblyStatusCache();
339: progressUI.finish();
340: setBusy(false);
341: updatePropertySheet();
342: }
343: });
344: }
345:
346: //========================== Stoppable =====================================
347: public boolean canStop() {
348:
349: boolean ret = false;
350:
351: if (!busy) {
352: ServiceAssemblyInfo saInfo = getAssemblyInfo();
353: String assemblyStatus = (saInfo != null) ? saInfo
354: .getState() : null;
355:
356: if (ServiceAssemblyInfo.STARTED_STATE
357: .equals(assemblyStatus)) {
358: ret = true;
359: } else if (ServiceAssemblyInfo.STOPPED_STATE
360: .equals(assemblyStatus)) {
361: List<ServiceUnitInfo> units = saInfo
362: .getServiceUnitInfoList();
363: if (units != null) {
364: for (ServiceUnitInfo unit : units) {
365: String unitState = unit.getState();
366: if (ServiceAssemblyInfo.STARTED_STATE
367: .equals(unitState)) {
368: ret = true;
369: break;
370: }
371: }
372: }
373: }
374: }
375:
376: return ret;
377: }
378:
379: public void stop() {
380: RuntimeManagementServiceWrapper mgmtService = getRuntimeManagementServiceWrapper();
381:
382: if (mgmtService == null) {
383: return;
384: }
385:
386: final String assemblyName = getName();
387:
388: String title = NbBundle.getMessage(
389: JBIServiceAssemblyNode.class,
390: "LBL_Stopping_Service_Assembly", // NOI18N
391: new Object[] { assemblyName });
392: final ProgressUI progressUI = new ProgressUI(title, false);
393:
394: SwingUtilities.invokeLater(new Runnable() {
395: public void run() {
396: setBusy(true);
397: progressUI.start();
398: }
399: });
400:
401: String result = null;
402: try {
403: result = mgmtService.stopServiceAssembly(assemblyName,
404: SERVER_TARGET);
405: } catch (ManagementRemoteException e) {
406: result = e.getMessage();
407: } finally {
408: JBIMBeanTaskResultHandler
409: .showRemoteInvokationResult(
410: GenericConstants.STOP_SERVICE_ASSEMBLY_OPERATION_NAME,
411: assemblyName, result);
412: }
413:
414: SwingUtilities.invokeLater(new Runnable() {
415: public void run() {
416: clearServiceAssemblyStatusCache();
417: progressUI.finish();
418: setBusy(false);
419: updatePropertySheet();
420: }
421: });
422: }
423:
424: //========================== Shutdownable ==================================
425: public boolean canShutdown() {
426:
427: boolean ret = canStop();
428:
429: if (!ret && !busy) {
430: ServiceAssemblyInfo saInfo = getAssemblyInfo();
431: String assemblyStatus = (saInfo != null) ? saInfo
432: .getState() : null;
433:
434: if (ServiceAssemblyInfo.STOPPED_STATE
435: .equals(assemblyStatus)) {
436: ret = true;
437: } else if (ServiceAssemblyInfo.SHUTDOWN_STATE
438: .equals(assemblyStatus)) {
439: List<ServiceUnitInfo> units = saInfo
440: .getServiceUnitInfoList();
441: if (units != null) {
442: for (ServiceUnitInfo unit : units) {
443: String unitState = unit.getState();
444: if (ServiceAssemblyInfo.STARTED_STATE
445: .equals(unitState)
446: || ServiceAssemblyInfo.STOPPED_STATE
447: .equals(unitState)) {
448: ret = true;
449: break;
450: }
451: }
452: }
453: }
454: }
455:
456: return ret;
457: }
458:
459: public void shutdown(boolean force) {
460:
461: if (canStop()) {
462: stop();
463: }
464:
465: RuntimeManagementServiceWrapper mgmtService = getRuntimeManagementServiceWrapper();
466:
467: if (mgmtService == null) {
468: return;
469: }
470:
471: final String assemblyName = getName();
472:
473: String title = NbBundle.getMessage(
474: JBIServiceAssemblyNode.class,
475: "LBL_Shutting_Down_Service_Assembly", // NOI18N
476: new Object[] { assemblyName });
477: final ProgressUI progressUI = new ProgressUI(title, false);
478:
479: SwingUtilities.invokeLater(new Runnable() {
480: public void run() {
481: setBusy(true);
482: progressUI.start();
483: }
484: });
485:
486: String result = null;
487: try {
488: result = mgmtService.shutdownServiceAssembly(assemblyName,
489: force, SERVER_TARGET);
490: } catch (ManagementRemoteException e) {
491: result = e.getMessage();
492: } finally {
493: JBIMBeanTaskResultHandler
494: .showRemoteInvokationResult(
495: GenericConstants.SHUTDOWN_SERVICE_ASSEMBLY_OPERATION_NAME,
496: assemblyName, result);
497: }
498:
499: SwingUtilities.invokeLater(new Runnable() {
500: public void run() {
501: clearServiceAssemblyStatusCache();
502: progressUI.finish();
503: setBusy(false);
504: updatePropertySheet();
505: }
506: });
507: }
508:
509: //========================== Undeployable =================================
510: public boolean canUndeploy() {
511: String assemblyStatus = getAssemblyState();
512: return canShutdown()
513: || !busy
514: && ServiceAssemblyInfo.SHUTDOWN_STATE
515: .equals(assemblyStatus);
516: }
517:
518: public boolean undeploy(boolean force) {
519:
520: // The cached SA status is for performance purpose. The tradeoff is that
521: // the actual SA status is not always correct.
522: // The following cache clearing is not really necessary, but is added
523: // anyway for #111623.
524: clearServiceAssemblyStatusCache();
525:
526: if (canShutdown()) {
527: shutdown(force);
528: }
529:
530: DeploymentService deploymentService = getDeploymentService();
531:
532: if (deploymentService == null) {
533: return false;
534: }
535:
536: final String assemblyName = getName();
537:
538: String title = NbBundle.getMessage(
539: JBIServiceAssemblyNode.class,
540: "LBL_Undeploying_Service_Assembly", // NOI18N
541: new Object[] { assemblyName });
542: final ProgressUI progressUI = new ProgressUI(title, false);
543:
544: SwingUtilities.invokeLater(new Runnable() {
545: public void run() {
546: setBusy(true);
547: progressUI.start();
548: }
549: });
550:
551: boolean success = true;
552: String result = null;
553: try {
554: result = deploymentService.undeployServiceAssembly(
555: assemblyName, force, SERVER_TARGET);
556: } catch (ManagementRemoteException e) {
557: result = e.getMessage();
558: } finally {
559: success = JBIMBeanTaskResultHandler
560: .showRemoteInvokationResult(
561: GenericConstants.UNDEPLOY_SERVICE_ASSEMBLY_OPERATION_NAME,
562: assemblyName, result);
563: }
564:
565: SwingUtilities.invokeLater(new Runnable() {
566: public void run() {
567: clearServiceAssemblyStatusCache();
568: progressUI.finish();
569: setBusy(false);
570: }
571: });
572:
573: return success;
574: }
575:
576: // DnD Support for CASA
577:
578: /*
579: public static final DataFlavor ServiceAssemblyDataFlavor =
580: new DataFlavor(Object.class, "JBIServiceAssemblyDataFlavor" ) { // NOI18N
581: };
582: public Transferable drag() throws IOException {
583: ExTransferable retValue = ExTransferable.create( super.drag() );
584: //add the 'data' into the Transferable
585: try {
586: DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
587: factory.setNamespaceAware(true);
588: DocumentBuilder builder = factory.newDocumentBuilder();
589: // parse SA DD
590: String saDD = getDeploymentDescriptor();
591: final Document saDoc = builder.parse(new InputSource(new StringReader(saDD)));
592: final List<Document> bcsuDocList = new ArrayList<Document>();
593: final List<Document> sesuDocList = new ArrayList<Document>();
594: for (Node child : getChildren().getNodes()) {
595: final String suDD = ((JBIServiceUnitNode) child).getDeploymentDescriptor();
596: // parse SU DD
597: Document suDoc = builder.parse(new InputSource(new StringReader(suDD)));
598: Element services = (Element) suDoc.getElementsByTagName("services").item(0);
599: boolean isBC = services.getAttribute("binding-component").equals("true");
600: if (isBC) {
601: bcsuDocList.add(suDoc);
602: } else {
603: sesuDocList.add(suDoc);
604: }
605: }
606: retValue.put( new ExTransferable.Single(ServiceAssemblyDataFlavor) {
607: protected Object getData() throws IOException, UnsupportedFlavorException {
608: List<Object> ret = new ArrayList<Object>();
609: ret.add("JBIMGR_SA_TRANSFER"); // NOI18N
610: ret.add(saDoc);
611: ret.add(bcsuDocList);
612: ret.add(sesuDocList);
613: return ret;
614: }
615: });
616: } catch (Exception e) {
617: }
618: return retValue;
619: }
620: */
621: public String getDeploymentDescriptor() {
622: String saDD = null;
623:
624: AdministrationService adminService = getAdministrationService();
625:
626: String assemblyName = getName();
627: try {
628: saDD = adminService
629: .getServiceAssemblyDeploymentDescriptor(assemblyName);
630: } catch (ManagementRemoteException e) {
631: e.printStackTrace();
632: }
633:
634: return saDD;
635: }
636: }
|