/* * 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.views.overview; import com.sun.tools.visualvm.application.Application; import com.sun.tools.visualvm.application.jvm.Jvm; import com.sun.tools.visualvm.application.jvm.JvmFactory; import com.sun.tools.visualvm.core.datasource.DataSource; import com.sun.tools.visualvm.core.datasource.Storage; import com.sun.tools.visualvm.core.snapshot.Snapshot; import java.util.ArrayList; import java.util.Collections; import java.util.Enumeration; import java.util.Iterator; import java.util.List; import java.util.Properties; import java.util.StringTokenizer; import org.openide.util.NbBundle; /** * * @author Jiri Sedlacek */ final class ApplicationOverviewModel { private static final String PROP_PREFIX = "ApplicationOverviewModel_"; // NOI18N static final String SNAPSHOT_VERSION = PROP_PREFIX + "version"; // NOI18N private static final String SNAPSHOT_VERSION_DIVIDER = "."; // NOI18N private static final String CURRENT_SNAPSHOT_VERSION_MAJOR = "1"; // NOI18N private static final String CURRENT_SNAPSHOT_VERSION_MINOR = "0"; // NOI18N private static final String CURRENT_SNAPSHOT_VERSION = CURRENT_SNAPSHOT_VERSION_MAJOR + SNAPSHOT_VERSION_DIVIDER + CURRENT_SNAPSHOT_VERSION_MINOR; private static final String PROP_NOT_DEFINED = "<not defined>"; // NOI18N public static final String PROP_BASIC_INFO_SUPPORTED = PROP_PREFIX + "basic_info_supported"; // NOI18N public static final String PROP_SYSTEM_PROPERTIES_SUPPORTED = PROP_PREFIX + "system_properties_supported"; // NOI18N public static final String PROP_PID = PROP_PREFIX + "pid"; // NOI18N public static final String PROP_HOST_NAME = PROP_PREFIX + "host_name"; // NOI18N public static final String PROP_MAIN_CLASS = PROP_PREFIX + "main_class"; // NOI18N public static final String PROP_MAIN_ARGS = PROP_PREFIX + "main_args"; // NOI18N public static final String PROP_VM_ID = PROP_PREFIX + "vm_id"; // NOI18N public static final String PROP_JAVA_HOME = PROP_PREFIX + "java_home"; // NOI18N public static final String PROP_JAVA_VERSION = PROP_PREFIX + "java_version"; // NOI18N public static final String PROP_JAVA_VENDOR = PROP_PREFIX + "java_vendor"; // NOI18N public static final String PROP_JVM_FLAGS = PROP_PREFIX + "jvm_flags"; // NOI18N public static final String PROP_OOME_ENABLED = PROP_PREFIX + "oome_enabled"; // NOI18N public static final String PROP_JVM_ARGS = PROP_PREFIX + "jvm_args"; // NOI18N public static final String PROP_SYSTEM_PROPERTIES = PROP_PREFIX + "system.properties"; // NOI18N private boolean initialized; private DataSource source; private boolean basicInfoSupported; private boolean systemPropertiesSupported; private String pid; private String hostName; private String mainClass; private String mainArgs; private String vmId; private String javaHome; private String javaVersion; private String javaVendor; private String jvmFlags; private String oomeEnabled; private String jvmArgs; private String systemProperties; public static ApplicationOverviewModel create(Application application) { ApplicationOverviewModel model = new ApplicationOverviewModel(); model.initialized = false; model.source = application; return model; } public static ApplicationOverviewModel create(Snapshot snapshot) { ApplicationOverviewModel model = new ApplicationOverviewModel(); model.initialized = false; model.source = snapshot; return model; } public DataSource getSource() { return source; } public boolean basicInfoSupported() { return basicInfoSupported; } public boolean systemPropertiesSupported() { return systemPropertiesSupported; } public String getPid() { return pid; } public String getHostName() { return hostName; } public String getMainClass() { return mainClass; } public String getMainArgs() { return mainArgs; } public String getVmId() { return vmId; } public String getJavaHome() { return javaHome; } public String getJavaVersion() { return javaVersion; } public String getJavaVendor() { return javaVendor; } public String getJvmFlags() { return jvmFlags; } public String oomeEnabled() { if (basicInfoSupported() && source instanceof Application) { Jvm jvm = JvmFactory.getJVMFor((Application)source); oomeEnabled = jvm.isDumpOnOOMEnabled() ? NbBundle.getMessage(ApplicationOverviewModel.class, "LBL_enabled") : NbBundle.getMessage(ApplicationOverviewModel.class, "LBL_disabled"); // NOI18N } return oomeEnabled; } public String getJvmArgs() { return jvmArgs; } public String getSystemProperties() { return systemProperties; } public synchronized void initialize() { if (initialized) return; initialized = true; if (source instanceof Application) initialize((Application)source); else initialize((Snapshot)source); } public void save(Snapshot snapshot) { initialize(); Storage storage = snapshot.getStorage(); setProperty(storage, SNAPSHOT_VERSION, CURRENT_SNAPSHOT_VERSION); setProperty(storage, PROP_BASIC_INFO_SUPPORTED, Boolean.toString(basicInfoSupported)); setProperty(storage, PROP_SYSTEM_PROPERTIES_SUPPORTED, Boolean.toString(systemPropertiesSupported)); setProperty(storage, PROP_PID, pid); setProperty(storage, PROP_HOST_NAME, hostName); setProperty(storage, PROP_MAIN_CLASS, mainClass); setProperty(storage, PROP_MAIN_ARGS, mainArgs); setProperty(storage, PROP_VM_ID, vmId); setProperty(storage, PROP_JAVA_HOME, javaHome); setProperty(storage, PROP_JAVA_VERSION, javaVersion); setProperty(storage, PROP_JAVA_VENDOR, javaVendor); setProperty(storage, PROP_JVM_FLAGS, jvmFlags); setProperty(storage, PROP_OOME_ENABLED, oomeEnabled); setProperty(storage, PROP_JVM_ARGS, jvmArgs); setProperty(storage, PROP_SYSTEM_PROPERTIES, systemProperties); } private void initialize(Snapshot snapshot) { // TODO: if some property cannot be loaded for current snapshot version, FAIL initializing the snapshot! Storage storage = snapshot.getStorage(); basicInfoSupported = Boolean.parseBoolean(getProperty(storage, PROP_BASIC_INFO_SUPPORTED)); systemPropertiesSupported = Boolean.parseBoolean(getProperty(storage, PROP_SYSTEM_PROPERTIES_SUPPORTED)); pid = getProperty(storage, PROP_PID); hostName = getProperty(storage, PROP_HOST_NAME); mainClass = getProperty(storage, PROP_MAIN_CLASS); mainArgs = getProperty(storage, PROP_MAIN_ARGS); vmId = getProperty(storage, PROP_VM_ID); javaHome = getProperty(storage, PROP_JAVA_HOME); javaVersion = getProperty(storage, PROP_JAVA_VERSION); javaVendor = getProperty(storage, PROP_JAVA_VENDOR); jvmFlags = getProperty(storage, PROP_JVM_FLAGS); oomeEnabled = getProperty(storage, PROP_OOME_ENABLED); jvmArgs = getProperty(storage, PROP_JVM_ARGS); systemProperties = getProperty(storage, PROP_SYSTEM_PROPERTIES); } private static void setProperty(Storage storage, String property, String value) { storage.setCustomProperty(property, value == null ? PROP_NOT_DEFINED : value); } private static String getProperty(Storage storage, String property) { String value = storage.getCustomProperty(property); return PROP_NOT_DEFINED.equals(value) ? null : value; } private void initialize(Application application) { Jvm jvm = JvmFactory.getJVMFor(application); source = application; basicInfoSupported = jvm.isBasicInfoSupported(); systemPropertiesSupported = jvm.isGetSystemPropertiesSupported(); int pidInt = application.getPid(); pid = pidInt == Application.UNKNOWN_PID ? NbBundle.getMessage(ApplicationOverviewModel.class, "LBL_unknown") : "" + pidInt; // NOI18N hostName = application.getHost().getHostName(); if (basicInfoSupported) { mainClass = jvm.getMainClass(); if (mainClass == null || "".equals(mainClass)) mainClass = NbBundle.getMessage(ApplicationOverviewModel.class, "LBL_unknown"); // NOI18N mainArgs = jvm.getMainArgs(); if (mainArgs == null) mainArgs = NbBundle.getMessage(ApplicationOverviewModel.class, "LBL_none"); // NOI18N vmId = jvm.getVmName() + " (" + jvm.getVmVersion() + ", " + jvm.getVmInfo() + ")"; // NOI18N javaHome = jvm.getJavaHome(); javaVersion = jvm.getJavaVersion(); javaVendor = jvm.getVmVendor(); jvmFlags = jvm.getJvmFlags(); if (jvmFlags == null || jvmFlags.length() == 0) jvmFlags = NbBundle.getMessage(ApplicationOverviewModel.class, "LBL_none"); // NOI18N oomeEnabled = jvm.isDumpOnOOMEnabled() ? NbBundle.getMessage(ApplicationOverviewModel.class, "LBL_enabled") : NbBundle.getMessage(ApplicationOverviewModel.class, "LBL_disabled"); // NOI18N String jvmArgss = jvm.getJvmArgs(); if (jvmArgss != null) jvmArgs = formatJVMArgs(jvmArgss); } if (systemPropertiesSupported) { Properties jvmProperties = jvm.getSystemProperties(); if (jvmProperties != null) systemProperties = formatSystemProperties(jvmProperties); } } private static String formatJVMArgs(String jvmargs) { String mangledString = " ".concat(jvmargs).replace(" -", "\n"); // NOI18N StringTokenizer tok = new StringTokenizer(mangledString, "\n"); // NOI18N StringBuffer text = new StringBuffer(100); while (tok.hasMoreTokens()) { String arg = tok.nextToken().replace(" ", " "); // NOI18N int equalsSign = arg.indexOf('='); text.append("<b>"); // NOI18N text.append("-"); // NOI18N if (equalsSign != -1) { text.append(arg.substring(0, equalsSign)); text.append("</b>"); // NOI18N text.append(arg.substring(equalsSign)); } else { text.append(arg); text.append("</b>"); // NOI18N } text.append("<br>"); // NOI18N } return text.toString(); } private static String formatSystemProperties(Properties properties) { StringBuilder text = new StringBuilder(200); List keys = new ArrayList(); Enumeration en = properties.propertyNames(); Iterator keyIt; while (en.hasMoreElements()) { keys.add(en.nextElement()); } Collections.sort(keys); keyIt = keys.iterator(); while (keyIt.hasNext()) { String key = (String) keyIt.next(); String val = properties.getProperty(key); if ("line.separator".equals(key) && val != null) { // NOI18N val = val.replace("\n", "\\n"); // NOI18N val = val.replace("\r", "\\r"); // NOI18N } text.append("<b>"); // NOI18N text.append(key); text.append("</b>="); // NOI18N text.append(val); text.append("<br>"); // NOI18N } return expandInvalidXMLChars(text); } private static String expandInvalidXMLChars(CharSequence chars) { StringBuilder text = new StringBuilder(chars.length()); char ch; for (int i = 0; i < chars.length(); i++) { ch = chars.charAt(i); text.append(isValidXMLChar(ch) ? ch : "<0x" + Integer.toHexString(0x10000 | ch).substring(1).toUpperCase() + ">"); // NOI18N } return text.toString(); } private static boolean isValidXMLChar(char ch) { return (ch == 0x9 || ch == 0xA || ch == 0xD || ((ch >= 0x20) && (ch <= 0xD7FF)) || ((ch >= 0xE000) && (ch <= 0xFFFD)) || ((ch >= 0x10000) && (ch <= 0x10FFFF))); } private ApplicationOverviewModel() {} }