/* * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.sun.tools.visualvm.application; import com.sun.tools.visualvm.application.jvm.Jvm; import com.sun.tools.visualvm.application.jvm.JvmFactory; import com.sun.tools.visualvm.application.type.ApplicationType; import com.sun.tools.visualvm.application.type.ApplicationTypeFactory; import com.sun.tools.visualvm.core.datasource.descriptor.DataSourceDescriptor; import java.awt.Image; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.beans.PropertyChangeSupport; /** * DataSourceDescriptor for Application. * * @author Jiri Sedlacek */ public class ApplicationDescriptor extends DataSourceDescriptor<Application> { private static final String DISPLAY_NAME_PROPERTY = "-Dvisualvm.display.name="; // NOI18N private String name; /** * Creates new instance of Application Descriptor. * * @param application Application described by the descriptor */ protected ApplicationDescriptor(Application application) { this(application, ApplicationTypeFactory.getApplicationTypeFor( application), POSITION_AT_THE_END); } /** * Creates new instance of Application Descriptor. * * @param application Application described by the descriptor * @param preferredPosition preferred position of the Application * * @since VisualVM 1.3 */ protected ApplicationDescriptor(Application application, int preferredPosition) { this(application, ApplicationTypeFactory.getApplicationTypeFor(application), preferredPosition); } private ApplicationDescriptor(final Application application, final ApplicationType type, int preferredPosition) { super(application, resolveApplicationName(application, type), type.getDescription(), type.getIcon(), preferredPosition, EXPAND_ON_FIRST_CHILD); name = super.getName(); type.addPropertyChangeListener(new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent evt) { String propertyName = evt.getPropertyName(); if (ApplicationType.PROPERTY_NAME.equals(propertyName)) { // Name already customized by the user, do not change it if (resolveName(application, null) != null) return; if (supportsRename()) { // Descriptor supports renaming, use setName(), sync name setName((String)evt.getNewValue()); name = ApplicationDescriptor.super.getName(); } else { // Descriptor doesn't support renaming, set name for overriden getName() String oldName = name; name = createGenericName(application, type.getName()); PropertyChangeSupport pcs = ApplicationDescriptor.this.getChangeSupport(); pcs.firePropertyChange(PROPERTY_NAME, oldName, name); } } else if (ApplicationType.PROPERTY_ICON.equals(propertyName)) { setIcon((Image)evt.getNewValue()); } else if (ApplicationType.PROPERTY_DESCRIPTION.equals(propertyName)) { setDescription((String)evt.getNewValue()); } else if (ApplicationType.PROPERTY_VERSION.equals(propertyName)) { // Not supported by ApplicationDescriptor } } }); } public String getName() { if (supportsRename()) return super.getName(); else return name; } public boolean providesProperties() { return true; } /** * Returns Application name if available in Snapshot Storage as PROPERTY_NAME * or user-provided display name defined by JVM argument <code>-Dvisualvm.display.name</code> * (since VisualVM 1.3.4) or generates new name using the provided ApplicationType. * * @param application Application for which to resolve the name * @param type ApplicationType to be used for generating Application name * @return persisted Application name if available or new generated name * * @since VisualVM 1.3 */ protected static String resolveApplicationName(Application application, ApplicationType type) { // Check for persisted displayname (currently only for JmxApplications) String persistedName = resolveName(application, null); if (persistedName != null) return persistedName; // Check for custom name defined by -Dvisualvm.display.name String customName = resolveCustomName(application); if (customName != null) return customName; // Provide generic displayname return createGenericName(application, type.getName()); } private static String resolveCustomName(Application application) { Jvm jvm = JvmFactory.getJVMFor(application); if (jvm.isBasicInfoSupported()) { String args = jvm.getJvmArgs(); int propIndex = args.indexOf(DISPLAY_NAME_PROPERTY); if (propIndex != -1) { // display name propery detected on commandline propIndex += DISPLAY_NAME_PROPERTY.length(); int endIndex = args.indexOf(" ", propIndex); // NOI18N if (endIndex == -1) return args.substring(propIndex); else return args.substring(propIndex, endIndex); } } return null; } private static String createGenericName(Application application, String nameBase) { int pid = application.getPid(); String id = Application.CURRENT_APPLICATION.getPid() == pid || pid == Application.UNKNOWN_PID ? "" : " (pid " + pid + ")"; // NOI18N return nameBase + id; } }