--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.carbide.extensions.memspy/build.properties Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,18 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+#
+bin.includes = feature.xml,\
+ license.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.carbide.extensions.memspy/feature.xml Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<feature
+ id="com.nokia.carbide.extensions.memspy"
+ label="Carbide.c++ Extensions - MemSpy"
+ version="1.6.0"
+ provider-name="Nokia"
+ plugin="com.nokia.s60tools.memspy">
+
+ <description>
+ MemSpy tool is used for analysing memory state and chances of s60 device over time.
+ </description>
+
+ <copyright>
+ Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+ All rights reserved. License: http://www.eclipse.org/legal/epl-v10.html.
+ </copyright>
+
+ <license url="license.txt">
+ Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+All rights reserved.
+This component and the accompanying materials are made available
+under the terms of "Eclipse Public License v1.0"
+which accompanies this distribution, and is available
+at the URL "http://www.eclipse.org/legal/epl-v10.html".
+ </license>
+
+
+ <requires>
+ <import plugin="org.eclipse.ui"/>
+ <import plugin="org.eclipse.core.runtime"/>
+ <import plugin="org.eclipse.ui.console"/>
+ <import plugin="org.eclipse.cdt.core"/>
+ <import plugin="org.eclipse.ui.ide"/>
+ <import plugin="org.eclipse.core.resources"/>
+ <import plugin="com.nokia.carbide.cdt.builder"/>
+ <import plugin="com.nokia.s60tools.ui" version="1.2.1" match="greaterOrEqual"/>
+ <import plugin="com.nokia.s60tools.util" version="1.1.12" match="greaterOrEqual"/>
+ <import plugin="com.nokia.s60tools.sdk" version="1.1.6" match="greaterOrEqual"/>
+ </requires>
+
+ <plugin
+ id="com.nokia.s60tools.heapanalyser"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="com.nokia.s60tools.memspy.help"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="com.nokia.s60tools.memspy"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="com.nokia.s60tools.swmtanalyser"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="com.nokia.s60tools.swmtanalyser.thirdpartysources"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+
+</feature>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.carbide.extensions.memspy/license.txt Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,6 @@
+Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+All rights reserved.
+This component and the accompanying materials are made available
+under the terms of "Eclipse Public License v1.0"
+which accompanies this distribution, and is available
+at the URL "http://www.eclipse.org/legal/epl-v10.html".
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.heapanalyser/.classpath Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.heapanalyser/.settings/org.eclipse.jdt.core.prefs Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,7 @@
+#Tue Jan 27 09:55:50 EET 2009
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5
Binary file sysperfana/memspyext/com.nokia.s60tools.heapanalyser/Binaries/DbgEntSymbol.plugin.dll has changed
Binary file sysperfana/memspyext/com.nokia.s60tools.heapanalyser/Binaries/HeapAnalyser.exe has changed
Binary file sysperfana/memspyext/com.nokia.s60tools.heapanalyser/Binaries/HeapComparisonLib.dll has changed
Binary file sysperfana/memspyext/com.nokia.s60tools.heapanalyser/Binaries/HeapComparisonUiLib.dll has changed
Binary file sysperfana/memspyext/com.nokia.s60tools.heapanalyser/Binaries/HeapCtrlLib.dll has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.heapanalyser/Binaries/HeapDataJavaScriptLib.js Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,137 @@
+/*
+* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are met:
+*
+* - Redistributions of source code must retain the above copyright notice,
+* this list of conditions and the following disclaimer.
+* - Redistributions in binary form must reproduce the above copyright notice,
+* this list of conditions and the following disclaimer in the documentation
+* and/or other materials provided with the distribution.
+* - Neither the name of Nokia Corporation nor the names of its contributors
+* may be used to endorse or promote products derived from this software
+* without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+* POSSIBILITY OF SUCH DAMAGE.
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+var info = document.createElement("div");
+var header = document.createElement("div");
+var body = document.createElement("div");
+
+function initialize()
+{
+ info.style.position="absolute";
+ info.style.visibility='hidden';
+
+ setGeneralStyle(header);
+
+ header.style.fontWeight='bold';
+ header.style.color='#4B7A98';
+ header.style.background='#D5EBF9';
+
+ setGeneralStyle(body);
+
+ body.style.borderTop='0px';
+ body.style.color='#1B4966';
+ body.style.background='#FFFFFF';
+
+ info.appendChild(header);
+ info.appendChild(body);
+
+ document.body.appendChild(info);
+}
+
+function setGeneralStyle(elm)
+{
+ elm.style.fontFamily='arial';
+ elm.style.fontSize='10';
+ elm.style.padding='2';
+ elm.style.border='1px solid #A5CFE9';
+}
+
+function showInfo(title, text, width)
+{
+ header.innerHTML = title;
+ body.innerHTML = text;
+
+ if ( width )
+ {
+ header.style.width = width + "px";
+ body.style.width = width + "px";
+ }
+ else
+ {
+ header.style.width = '180px';
+ body.style.width = '180px';
+ }
+
+ info.style.visibility = 'visible';
+}
+
+function hideInfo()
+{
+ info.style.visibility = 'hidden';
+}
+
+function mouseMove(e)
+{
+ if ( info.style.visibility == 'visible' )
+ {
+ var evt;
+
+ e?evt=e:evt=event;
+
+ var x, y;
+
+ if ( !evt.pageX )
+ x = evt.x + document.body.scrollLeft;
+ else
+ x = evt.pageX;
+
+ info.style.left = x + 15;
+
+ if ( !evt.pageY )
+ y = evt.y + document.body.scrollTop;
+ else
+ y = evt.pageY;
+
+ info.style.top = y + 15;
+ }
+}
+
+function showMainFormCell( txt )
+{
+ var currentURL = parent.MainWindow.location.toString();
+ var hashPos = currentURL.indexOf('#');
+
+ if ( hashPos >= 0 )
+ {
+ var hashArray = currentURL.split("#");
+ currentURL = hashArray[ 0 ];
+ }
+
+ var newURL = currentURL + '#Cell_' + txt;
+
+ parent.MainWindow.location = newURL;
+}
\ No newline at end of file
Binary file sysperfana/memspyext/com.nokia.s60tools.heapanalyser/Binaries/HeapLib.dll has changed
Binary file sysperfana/memspyext/com.nokia.s60tools.heapanalyser/Binaries/HeapUiLib.dll has changed
Binary file sysperfana/memspyext/com.nokia.s60tools.heapanalyser/Binaries/Microsoft.Office.Interop.Excel.dll has changed
Binary file sysperfana/memspyext/com.nokia.s60tools.heapanalyser/Binaries/Microsoft.Vbe.Interop.dll has changed
Binary file sysperfana/memspyext/com.nokia.s60tools.heapanalyser/Binaries/SLPluginMap.plugin.dll has changed
Binary file sysperfana/memspyext/com.nokia.s60tools.heapanalyser/Binaries/SLPluginObey.plugin.dll has changed
Binary file sysperfana/memspyext/com.nokia.s60tools.heapanalyser/Binaries/SLPluginSymbol.plugin.dll has changed
Binary file sysperfana/memspyext/com.nokia.s60tools.heapanalyser/Binaries/SLPluginZip.plugin.dll has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.heapanalyser/Binaries/SupportingLibraries.txt Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,43 @@
+ZedGraph (c) John Champion
+==========================
+http://zedgraph.org/wiki/index.php?title=ZedGraph_License
+
+ZedGraph is licensed under the Lesser or Library General Public License.
+
+
+
+
+
+
+
+XPTable (c) Mathew Hall
+=======================
+http://www.codeproject.com/cs/miscctrl/XPTable.asp
+http://sourceforge.net/projects/xptable/
+
+/*
+ * Copyright © 2005, Mathew Hall
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ */
+
Binary file sysperfana/memspyext/com.nokia.s60tools.heapanalyser/Binaries/SymbianDebugLib.dll has changed
Binary file sysperfana/memspyext/com.nokia.s60tools.heapanalyser/Binaries/SymbianDebugLibUi.dll has changed
Binary file sysperfana/memspyext/com.nokia.s60tools.heapanalyser/Binaries/SymbianExcelLib.dll has changed
Binary file sysperfana/memspyext/com.nokia.s60tools.heapanalyser/Binaries/SymbianStructuresLib.dll has changed
Binary file sysperfana/memspyext/com.nokia.s60tools.heapanalyser/Binaries/SymbianSymbolLib.plugin.dll has changed
Binary file sysperfana/memspyext/com.nokia.s60tools.heapanalyser/Binaries/SymbianTree.dll has changed
Binary file sysperfana/memspyext/com.nokia.s60tools.heapanalyser/Binaries/SymbianUtils.dll has changed
Binary file sysperfana/memspyext/com.nokia.s60tools.heapanalyser/Binaries/SymbianUtilsUi.dll has changed
Binary file sysperfana/memspyext/com.nokia.s60tools.heapanalyser/Binaries/SymbianWizardLib.dll has changed
Binary file sysperfana/memspyext/com.nokia.s60tools.heapanalyser/Binaries/SymbianXmlInputLib.dll has changed
Binary file sysperfana/memspyext/com.nokia.s60tools.heapanalyser/Binaries/SymbianZipLib.dll has changed
Binary file sysperfana/memspyext/com.nokia.s60tools.heapanalyser/Binaries/XPTable.dll has changed
Binary file sysperfana/memspyext/com.nokia.s60tools.heapanalyser/Binaries/ZedGraph.dll has changed
Binary file sysperfana/memspyext/com.nokia.s60tools.heapanalyser/Binaries/office.dll has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.heapanalyser/META-INF/MANIFEST.MF Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,12 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Carbide.c++ Extensions - Heapanalyser Plug-in
+Bundle-SymbolicName: com.nokia.s60tools.heapanalyser
+Bundle-Version: 1.6.0
+Bundle-Activator: com.nokia.s60tools.heapanalyser.HeapAnalyserPlugin
+Bundle-Vendor: Nokia
+Require-Bundle: org.eclipse.core.runtime,
+ com.nokia.s60tools.util;bundle-version="1.1.12"
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Bundle-ActivationPolicy: lazy
+Export-Package: com.nokia.s60tools.heapanalyser.interfaces;x-friends:="com.nokia.s60tools.memspy"
Binary file sysperfana/memspyext/com.nokia.s60tools.heapanalyser/OSS/zedgraph_source_v515.zip has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.heapanalyser/about.html Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,22 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
+<html>
+<head>
+<title>About</title>
+<meta http-equiv=Content-Type content="text/html; charset=ISO-8859-1">
+</head>
+<body lang="EN-US">
+<h2>About This Content</h2>
+
+<p>Dec 11, 2009</p>
+
+<h3>Copyright</h3>
+
+<p>
+
+<p>Copyright © 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.<br>
+License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.</p>
+
+<p>
+
+</body>
+</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.heapanalyser/build.properties Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,24 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+#
+javacSource=1.5
+javacTarget=1.5
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ Binaries/,\
+ about.html
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.heapanalyser/src/com/nokia/s60tools/heapanalyser/HeapAnalyserPlugin.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,98 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+
+package com.nokia.s60tools.heapanalyser;
+
+import java.io.File;
+import java.net.URL;
+
+import org.eclipse.core.runtime.FileLocator;
+import org.eclipse.core.runtime.Plugin;
+import org.osgi.framework.BundleContext;
+
+/**
+ * The activator class controls the plug-in life cycle
+ */
+public class HeapAnalyserPlugin extends Plugin {
+
+ /**
+ * The plug-in ID for Heap Analyser.
+ */
+ public static final String PLUGIN_ID = "com.nokia.s60tools.heapanalyser";
+
+ private String pluginInstallPath = "";
+
+ // The shared instance
+ private static HeapAnalyserPlugin plugin;
+
+ /**
+ * The constructor
+ */
+ public HeapAnalyserPlugin() {
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.core.runtime.Plugins#start(org.osgi.framework.BundleContext)
+ */
+ public void start(BundleContext context) throws Exception {
+ super.start(context);
+ plugin = this;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.core.runtime.Plugin#stop(org.osgi.framework.BundleContext)
+ */
+ public void stop(BundleContext context) throws Exception {
+ plugin = null;
+ super.stop(context);
+ }
+
+ /**
+ * Returns the shared instance
+ *
+ * @return the shared instance
+ */
+ public static HeapAnalyserPlugin getDefault() {
+ return plugin;
+ }
+
+ /**
+ * Returns the path where this plugin is installed
+ * @return the path where this plugin is installed
+ */
+ public static String getPluginInstallPath() {
+ try {
+ if ("".equals(plugin.pluginInstallPath)) {
+ // URL to the plugin's root ("/")
+ URL relativeURL = plugin.getBundle().getEntry("/");
+ // Converting into local path
+ URL localURL = FileLocator.toFileURL(relativeURL);
+ // Getting install location in correct form
+ File f = new File(localURL.getPath());
+ plugin.pluginInstallPath = f.getAbsolutePath();
+ }
+ return plugin.pluginInstallPath;
+ } catch (Exception e) {
+ return "";
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.heapanalyser/src/com/nokia/s60tools/heapanalyser/interfaces/HeapAnalyserLauncher.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,175 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+
+package com.nokia.s60tools.heapanalyser.interfaces;
+
+import java.io.File;
+
+import com.nokia.s60tools.heapanalyser.HeapAnalyserPlugin;
+import com.nokia.s60tools.util.debug.DbgUtility;
+
+/**
+ * Class with static variables and helper method to launch Heap Analyser.
+ */
+public class HeapAnalyserLauncher {
+
+ /// Indicates an unspecified or general error
+ public static final int KErrCommandLineGeneral = -1;
+
+ /// Indicates that one or more mandatory command line arguments was omitted
+ public static final int KErrCommandLineArgumentsMissing = -2;
+
+ /// Indicates that an input command was not supported or valid
+ public static final int KErrCommandLineInvalidCommand = -3;
+
+ /// Indicates that the specified input file was not found
+ public static final int KErrCommandLineArgumentsFileNotFound = -4;
+
+ /// Indicates a fatal problem when attempting to read the input file
+ public static final int KErrCommandLineArgumentsFileInvalid = -5;
+
+ /// Indicates source file(s) were not found or specified
+ public static final int KErrCommandLineSourceFileNotFound = -6;
+
+ /// Indicates debug meta data was omitted from the inputs
+ public static final int KErrCommandLineDebugMetaDataMissing = -7;
+
+ /// Occurs if Heap Analyser cannot find a handler for the specified command
+ /// line arguments.
+ public static final int KErrCommandLineUINotAvailable = -8;
+
+ /// The requested analysis type is not supported
+ public static final int KErrCommandLineAnalysisTypeNotSupported = -9;
+
+ /// The specified analysis thread name is invalid
+ public static final int KErrCommandLineAnalysisThreadNameInvalid = -10;
+
+ /// The specified output data is invalid
+ public static final int KErrCommandLineAnalysisOutputInvalid = -11;
+
+ /// The specified output data is invalid
+ public static final int KErrCommandLineLaunchingFailed = -12;
+
+
+ private static final String EXE_FOLDER = "Binaries";
+ private static final String COMMAND_LINE_COMMAND = " -input ";
+
+ /**
+ * Launch Heap Analyser application.
+ * @param configurationFilePath
+ * @return {@link Process#exitValue()} or {@link HeapAnalyserLauncher#KErrCommandLineLaunchingFailed}
+ * if an exception occurs.
+ */
+ public static int launchHeapAnalyser( String configurationFilePath ){
+ String workingDirectory = getHeapAnalyserPath();
+ String heapAnalyserCommand = workingDirectory + "HeapAnalyser.exe";
+
+ // surround file paths with quotation marks so that spaces in file names wont cause failure.
+ heapAnalyserCommand = surroundWithQuotation( heapAnalyserCommand );
+ configurationFilePath = surroundWithQuotation( configurationFilePath );
+
+ String commandLineCommand = heapAnalyserCommand + COMMAND_LINE_COMMAND + configurationFilePath;
+
+ int returnValue = 0;
+
+ File file = new File(workingDirectory);
+
+ // execute HeapAnalyser.exe
+ try {
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "Starting Heap Analyser: " + commandLineCommand); //$NON-NLS-N$
+ Process p = Runtime.getRuntime().exec(commandLineCommand, null, file);
+ p.waitFor();
+ returnValue = p.exitValue();
+ }
+ catch (Exception e) {
+ return KErrCommandLineLaunchingFailed;
+ }
+
+ return returnValue;
+
+
+ }
+
+ /**
+ * Gets the path where HeapAnalyserConsole.exe is located
+ * @return the path where HeapAnalyserConsole.exe is located
+ */
+ private static String getHeapAnalyserPath() {
+ String heapAnalyserExePath = HeapAnalyserPlugin.getPluginInstallPath();
+ if (!heapAnalyserExePath.endsWith(File.separator)){
+ heapAnalyserExePath += File.separator;
+ }
+ heapAnalyserExePath += EXE_FOLDER + File.separator;
+ return heapAnalyserExePath;
+ }
+
+ private static String surroundWithQuotation( String text ){
+ String retVal = "\"";
+ retVal = retVal + text + retVal;
+ return retVal;
+ }
+
+ /**
+ * Gets HeapAnalyser launcher error message.
+ */
+ public static String getErrorMessage(int returnValue ){
+ switch(returnValue){
+ case HeapAnalyserLauncher.KErrCommandLineLaunchingFailed:{
+ return "MemSpy was unable to start analysing imported files.";
+ }
+ case HeapAnalyserLauncher.KErrCommandLineGeneral:{
+ return "Unspecified or general error";
+ }
+ case HeapAnalyserLauncher.KErrCommandLineArgumentsMissing:{
+ return "An error occurred when starting Heap Analyser.(Command line argument missing)";
+ }
+ case HeapAnalyserLauncher.KErrCommandLineInvalidCommand:{
+ return "An error occurred when starting Heap Analyser.(Input command not specified)";
+ }
+ case HeapAnalyserLauncher.KErrCommandLineArgumentsFileNotFound:{
+ return "An error occurred when starting Heap Analyser.(Input.xml file not found)";
+ }
+ case HeapAnalyserLauncher.KErrCommandLineArgumentsFileInvalid:{
+ return "An error occurred when starting Heap Analyser.(Unable to read input file. Perhaps your symbol or map files are moved/renamed. )";
+ }
+ case HeapAnalyserLauncher.KErrCommandLineSourceFileNotFound:{
+ return "An error occurred when starting Heap Analyser.(Unable to read source file)";
+ }
+ case HeapAnalyserLauncher.KErrCommandLineDebugMetaDataMissing:{
+ return "An error occurred when starting Heap Analyser.(Symbol files were not found)";
+ }
+ case HeapAnalyserLauncher.KErrCommandLineUINotAvailable:{
+ return "An error occurred when starting Heap Analyser.(Command line UI not available)";
+ }
+ case HeapAnalyserLauncher.KErrCommandLineAnalysisTypeNotSupported:{
+ return "An error occurred when starting Heap Analyser.(Analysis type not supported)";
+ }
+ case HeapAnalyserLauncher.KErrCommandLineAnalysisThreadNameInvalid:{
+ return "An error occurred when starting Heap Analyser.(Thread name invalid)";
+ }
+ case HeapAnalyserLauncher.KErrCommandLineAnalysisOutputInvalid:{
+ return "An error occurred when starting Heap Analyser.(Output file invalid)";
+ }
+ default:
+ return "An unknown error occurred when starting Heap Analyser. "
+ + "Check software prerequisites from release notes "
+ + "(e.g. check correct version of .NET framework is installed).";
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/META-INF/MANIFEST.MF Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,6 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Carbide.c++ Extensions - MemSpy Help Plug-in
+Bundle-SymbolicName: com.nokia.s60tools.memspy.help;singleton:=true
+Bundle-Version: 1.6.0
+Bundle-Vendor: Nokia
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/about.html Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,19 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
+<html>
+<head>
+<title>About</title>
+<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
+</head>
+<body>
+
+<h2>About This Content</h2>
+<p>April 21, 2010</p>
+
+<h3>Copyright</h3>
+
+<p>Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.<br>
+License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.<p>
+
+</body>
+</html>
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/book.css Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,184 @@
+/*
+ Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+ All rights reserved.
+ License: http://www.eclipse.org/legal/epl-v10.html
+*/
+
+/* Add whitespace around entire display to avoid crowding edges of view */
+/* 20070523-Removed top margin size to close gap between location breadcrumbs and page title */
+html {
+ margin: 2px 10px 10px 10px;
+ }
+
+/* Set default font to serif style, 12-pt and plain */
+body, p, table {
+ font-family: Verdana, Helvetica, Arial, sans-serif;
+ font-size: 13px;
+ font-weight: normal;
+}
+
+/* Use sans-serif fonts for all title styles */
+h1, h2, h3, h4, h5, h6, strong, em {
+ font-family: Verdana, Helvetica, Arial, sans-serif;
+ color: #000000;
+ }
+
+h1 { font-size:20px }
+h2 { font-size:18px }
+h3 { font-size:16px }
+h4 { font-size:14px }
+h5 { font-size:13px }
+h6 { font-size:12px }
+
+/* For headlines at the top of a view, add space */
+/* 20090224-changed green fade to gold header image */
+h1, h2, h3 {
+ background-image: url(html/images/gold_header.png);
+ background-repeat: no-repeat;
+ padding:10px 0px 10px 12px;
+ }
+
+li {
+ margin-bottom:8px;
+ margin-top:8px;
+ }
+
+/* Footer includes space and a gray line above the company logo */
+#footer {
+ padding-top:10px;
+ margin-top:20px;
+ border-top:1px solid #999;
+ font-family: Helvetica, sans-serif;
+ font-size: 11px;
+ color:#333;
+ }
+
+.listing {
+ font-family: "Courier New", Courier, mono;
+ color: #000000;
+ background-color: #FFFFCC;
+ margin: 5px 0px;
+ }
+
+.code, pre {
+ font-family: "Courier New", Courier, mono;
+ font-size: 13px;
+ color: #000000;
+ }
+
+.step {
+ /* background-color: #EEE; */
+ /* margin: 10px 0px; */
+ /* color: #111; */
+ /* border-bottom:2px solid #EEE; */
+ }
+
+.substep {
+ background-color: #EEE;
+ }
+
+
+/* Figure/Listing/Table titles are centered and gray */
+p.table {
+ color: #999;
+ font-weight: bold;
+ padding-top: 5px;
+ }
+
+table {
+ border: solid #999 1px;
+ table-layout: auto;
+ font-size: 13px;
+ }
+
+td, th {
+ border: solid #999 1px;
+ padding: 5px;
+ vertical-align:top;
+ }
+
+/* 20070522-replaced gray with green background to match gradiant color for title */
+th {
+ background-color:#FFC550; /* background-color:#acd79b;
+ background-color:#999;
+ color:#FFF; */
+ }
+
+div.ol.p {
+ margin-left: 3em;
+ }
+
+/* Make all ordered/unordered list items appear in bold gray */
+div ol > li, div ul > li {
+ font-weight:bold;
+ color: #333;
+ }
+
+div ol > p, div ul > p, div li > p {
+ font-weight:normal;
+ }
+
+/* Make all H4 and H5 items appear in bold gray against a light green background */
+div h5, div h4 {
+ padding:5px 0px 5px 12px;
+ background-color:#FDCB2F;
+ /* background-color: #EEE; */
+ font-weight:bold;
+ color: #000000;
+ }
+
+
+/* Notes stand out using a light top & bottom borders with dark gray text */
+p.note {
+ /* color: #03C; */
+ /* background-color: #FFFF99; */
+ color: #333;
+ padding: 5px;
+ margin-left: 1em;
+ margin-right: 1em;
+ border-top: solid #BBB thin;
+ border-bottom: solid #BBB thin;
+ }
+
+
+/* Figure/Listing/Table titles are centered and gray */
+p.figure {
+ color: #333;
+ text-align: center;
+ font-weight: bold;
+ }
+
+/* highly visible red background and white text for things that need fixing before release */
+/* SHOULD NOT BE PRESENT IN RELEASED PRODUCTS */
+.fix {
+ background-color: red;
+ font-weight: bold;
+ color: white;
+ }
+
+.question {
+ font-style:italic;
+ font-weight:bold;
+ color: #555;
+ }
+
+.titleSmall {
+ font-family: Helvetica, sans-serif;
+ font-size: 11px;
+ }
+
+
+.plain {
+ font-family: Helvetica, sans-serif;
+ font-size: 12px;
+ font-style: normal;
+ line-height: normal;
+ font-weight: normal;
+ font-variant: normal;
+ color: #000000;
+ text-decoration: none;
+ }
+
+a:link { color: #0033CC }
+a:visited { color: #555555 }
+a:hover { color: #0033CC }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/build.properties Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,26 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+#
+output.. = bin/
+bin.includes = plugin.xml,\
+ META-INF/,\
+ .,\
+ html/,\
+ about.html,\
+ book.css,\
+ build.properties
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/concepts/concepts.htm Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,25 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
+<title>Concepts</title>
+<link href="../../book.css" type="text/css" rel="StyleSheet">
+</head>
+<body>
+
+<h2>Concepts</h2>
+<p>The following concepts provide information on MemSpy
+terminology, technologies, and processes:</p>
+<ul>
+<li><a href="memspy.htm">MemSpy and MemSpy Launcher S60 applications</a></li>
+<li><a href="heap_dump.htm">Heap dump</a></li>
+<li><a href="swmt_log.htm">System Wide Memory Tracking log</a></li>
+<li><a href="heap_analyser.htm">Heap Analyser</a></li>
+<li><a href="swmtanalyser.htm">SWMT Analyser</a></li>
+<li><a href="files.htm">Symbol files, Map files, and Image files</a></li>
+</ul>
+
+<div id="footer">Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.
+License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.</div>
+</body>
+</html>
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/concepts/files.htm Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,30 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
+<title>Symbol and Map files</title>
+<link href="../../book.css" type="text/css" rel="StyleSheet">
+</head>
+<body>
+
+<h2>Symbol and Map files</h2>
+<p>In the MemSpy Import Wizard, you have to define at least one symbol file. Defining map files is optional.</p>
+
+<h4>Symbol files</h4>
+<p>When you create an image, symbol files are generated automatically. Symbol files contain the binary structure of an image, which is needed for producing an analysis file. You can find a symbol file for example from <i>\epoc32\rombuild\<device>\core.</i></p>
+<p>After defining symbol files, you can also define map files.</p>
+
+<h4>Map files</h4>
+<p>If you want to define map files, you can select the <b>Map files folder</b> option to define the location of map files, or you can select <b>MapFiles.zip</b> option if you want to provide a ZIP file containing the map files. If you choose the <b>SDK Map files folder</b> option, the MemSpy Import Wizard checks which SDKs you have installed in Carbide.c++, and lists the directories of each SDK which contain map files. Choose the directory you want. If you do not want to define any map files, select the <b>No map files</b> option.</p>
+
+<h5>Related task</h5>
+<ul>
+<li><a href="..\tasks\view_heap.htm">Importing and analyzing heap dump files</a></li>
+<li><a href="..\tasks\compare_two_heaps.htm">Importing and comparing two heap dump files</a></li>
+<li><a href="..\tasks\view_swmt_log.htm">Importing and analyzing System Wide Memory Tracking log files</a></li>
+</ul>
+
+<div id="footer">Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.
+License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.</div>
+</body>
+</html>
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/concepts/heap_analyser.htm Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,40 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+<head>
+ <meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
+ <title>Heap Analyser</title>
+ <link href="../../book.css" type="text/css" rel="stylesheet">
+</head>
+
+<body>
+<h2>Heap Analyser</h2>
+
+<p>Heap Analyser is a PC side tool for graphically displaying and analyzing
+heap dumps produced by the MemSpy S60 application and imported to PC with the
+MemSpy Carbide.c++ Extension. Heap Analyser is automatically started after you
+import a heap dump file with the MemSpy Carbide.c++ Extension.</p>
+
+<h5>Related references</h5>
+<ul>
+ <li><a href="../reference/prerequisites_for_HA.htm">Prerequisites for using
+ Heap Analyser</a></li>
+ <li><a href="../reference/HA_data_analysis.htm">Data Analysis with Heap
+ Analyser</a></li>
+ <li><a href="../reference/saving_HA_reports.htm">Saving Heap Analyser
+ Reports</a></li>
+</ul>
+
+<h5>Related tasks</h5>
+<ul>
+ <li><a href="..\tasks\view_heap.htm">Importing and analyzing heap dump
+ files</a></li>
+ <li><a href="..\tasks\compare_two_heaps.htm">Importing and comparing two heap
+ dump files</a></li>
+</ul>
+
+<div id="footer">
+Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies). All rights
+reserved. License: <a
+href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.</div>
+</body>
+</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/concepts/heap_dump.htm Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,27 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
+<title>Heap Dump</title>
+<link href="../../book.css" type="text/css" rel="stylesheet">
+</head>
+<body>
+
+<h2>Heap Dump</h2>
+<p>A Heap Dump is a log file that contains actual data contents of a specific heap. Heap Dumps can be read and analysed with the Heap Analyser tool.</p>
+
+<h5>Related concepts</h5>
+<ul>
+<li><a href="heap_analyser.htm">Heap Analyser</a></li>
+</ul>
+
+<h5>Related tasks</h5>
+<ul>
+<li><a href="..\tasks\view_heap.htm">Importing and analyzing heap dump files</a></li>
+<li><a href="..\tasks\compare_two_heaps.htm">Importing and comparing two heap dump files</a></li>
+</ul>
+
+<div id="footer">Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.
+License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.</div>
+</body>
+</html>
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/concepts/memspy.htm Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,18 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
+<title>MemSpy and MemSpy Launcher S60 applications</title>
+<link href="../../book.css" type="text/css" rel="stylesheet">
+</head>
+<body>
+
+<h2>MemSpy and MemSpy Launcher S60 applications</h2>
+<p>The MemSpy S60 application tracks various subsystems that directly or indirectly contribute to overall system memory usage and provides information about the changes in these subsystems at specified time intervals.</p>
+<p>The memory tracing functionality of MemSpy can be targeted at a specific thread to analyze the memory changes that occur during the life cycle of the thread.</p>
+<p>The MemSpy Launcher S60 application listens to TraceCore for activation messages from the MemSpy Carbide.c++ Extension. After receiving an activation message, MemSpy Launcher commands MemSpy.</p>
+
+<div id="footer">Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.
+License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.</div>
+</body>
+</html>
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/concepts/swmt_log.htm Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,21 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
+<title>System Wide Memory Tracking log</title>
+<link href="../../book.css" type="text/css" rel="stylesheet">
+</head>
+<body>
+
+<h2>System Wide Memory Tracking log</h2>
+<p>A System Wide Memory Tracker log file contains information about system wide memory status changes over time.</p>
+
+<h5>Related tasks</h5>
+<ul>
+<li><a href="../tasks/view_swmt_log.htm">Importing and analyzing System Wide Memory Tracking log files</a></li>
+</ul>
+
+<div id="footer">Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.
+License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.</div>
+</body>
+</html>
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/concepts/swmtanalyser.htm Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,22 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
+<title>SWMT Analyser</title>
+<link href="../../book.css" type="text/css" rel="stylesheet">
+</head>
+<body>
+
+<h2>SWMT Analyser</h2>
+<p>SWMT Analyser is a Carbide.c++ Extension for analyzing System Wide Memory Tracking logs produced by the MemSpy S60 application and imported to PC with the MemSpy Carbide.c++ Extension. SWMT Analyzer is launched automatically after you import a SWMT log file using the MemSpy Carbide.c++ Extension.</p>
+
+<h5>Related tasks</h5>
+<ul>
+<li><a href="../tasks/view_swmt_log.htm">Importing and analyzing System Wide Memory Tracking log files</a></li>
+<li><a href="../tasks/use_swmt_analyser.htm">Using SWMT Analyser</a></li>
+</ul>
+
+<div id="footer">Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.
+License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.</div>
+</body>
+</html>
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/contexts.xml Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?NLS TYPE="org.eclipse.help.contexts"?>
+<contexts>
+
+ <context id="MEMSPY_HELP_MAIN_VIEW">
+ <description>MemSpy Main View</description>
+ <topic label="Table of Contents" href="html/toc.htm" />
+ </context>
+
+ <context id="MEMSPY_HELP_IMPORT_SELECT_ACTION">
+ <description>MemSpy Tasks</description>
+ <topic label="Tasks" href="html/tasks/tasks.htm" />
+ </context>
+
+ <context id="MEMSPY_HELP_IMPORT_HEAP">
+ <description>Importing and analyzing heap dump files</description>
+ <topic label="Importing and analyzing heap dump files" href="html/tasks/view_heap.htm" />
+ </context>
+
+ <context id="MEMSPY_HELP_IMPORT_SYMBOLS">
+ <description>Symbol and Map files</description>
+ <topic label="Symbol and Map files" href="html/concepts/files.htm" />
+ </context>
+
+ <context id="MEMSPY_HELP_IMPORT_COMPARE">
+ <description>Importing and comparing two heap dump files</description>
+ <topic label="Importing and comparing two heap dump files" href="html/tasks/compare_two_heaps.htm" />
+ </context>
+
+ <context id="MEMSPY_HELP_IMPORT_SWMT">
+ <description>Importing and analyzing System Wide Memory Tracking log files</description>
+ <topic label="Importing and analyzing System Wide Memory Tracking log files" href="html/tasks/view_swmt_log.htm" />
+ </context>
+
+ <context id="MEMSPY_HELP_IMPORT_SWMT_CATEGORIES_DIALOG">
+ <description>Setting System Wide Memory Tracking tracked categories</description>
+ <topic label="Setting System Wide Memory Tracking tracked categories" href="html/tasks/view_swmt_log.htm#set_tracked_categories" />
+ </context>
+
+ <context id="MEMSPY_HELP_IMPORT_CONNECTION_SETTINGS">
+ <description>Configuring connection settings</description>
+ <topic label="Configuring connection settings" href="html/tasks/connection_settings.htm" />
+ </context>
+ <context id="MEMSPY_SWMT_REPORT_GENERATION_WIZARD">
+ <description>Generating PDF reports</description>
+ <topic label="Generating PDF reports" href="html/tasks/generate_pdf_report.htm" />
+ </context>
+
+<!-- The context's id can be accessed from the source code
+ in the following way.
+
+ Define a class storing the context ID constants at
+ source code level:
+
+ public class AppDepHelpContextIDs {
+ ...
+ public static final String APPDEP_COMPONENT_LIST_VIEW =
+ APPDEP_HELP_PROJECT_PLUGIN_ID
+ +".APPDEP_COMPONENT_LIST_VIEW";
+ ...
+ }
+
+ // Somewhere in the code there is a UI item
+ // the context help will be bound to.
+ private TableViewer listItemsViewer;
+ ...
+ // Binding context help ID into the control happens with SetHelp-method.
+ // The first parameter must be a sub class of org.eclipse.swt.widgets.Control.
+ PlatformUI.getWorkbench().getHelpSystem().setHelp(listItemsViewer.getControl(),
+ AppDepHelpContextIDs.APPDEP_COMPONENT_LIST_VIEW);
+
+ -->
+
+</contexts>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/gettingstarted/GS_index.htm Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,21 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
+<title>Getting started</title>
+<link href="../../book.css" type="text/css" rel="stylesheet">
+</head>
+<body>
+
+<h2>Getting started</h2>
+<p> The information in this section will help you get started quickly using the basic features of the MemSpy Extension for Carbide.c++.</p><p>Topics in this section include: </p>
+<ul>
+<li><a href="overview.htm">Overview</a></li>
+<li><a href="prerequisites.htm">Prerequisites for use</a></li>
+<li><a href="walk_through.htm">Basic walk-through</a></li>
+</ul>
+
+<div id="footer">Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.
+License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.</div>
+</body>
+</html>
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/gettingstarted/overview.htm Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,36 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
+<title>Overview</title>
+<link href="../../book.css" type="text/css" rel="stylesheet">
+</head>
+<body>
+
+<h2>Overview</h2>
+<p>The MemSpy Carbide.c++ Extension is a tool for importing heap dumps and System Wide Memory Tracking logs from a device to a PC for analysis with Heap Analyser or SWMT Analyser. The MemSpy S60 application is used to track memory usage in a device at specified time intervals and produce the heap dump and SWMT log files.</p><p>By using the MemSpy S60 application and Carbide.c++ extension you can analyze:</p>
+<ul>
+<li>how much RAM a process or thread is using,</li>
+<li>how much stack each thread has,</li>
+<li>which objects are active for a given thread,</li>
+<li>which files are open in a system or which files have been opened by a thread,</li>
+<li>what is the device RAM / ROM configuration,</li>
+<li>which servers are running (with which sessions),</li>
+<li>what memory chunks exist,</li>
+<li>how to track heap memory changes over time, and</li>
+<li>which bitmaps are loaded by the font and bitmap server.</li>
+</ul>
+
+<h5>Related concepts</h5>
+<ul>
+<li><a href="../concepts/memspy.htm">MemSpy S60 application</a></li>
+<li><a href="../concepts/heap_dump.htm">Heap dump</a></li>
+<li><a href="../concepts/swmt_log.htm">System Wide Memory Tracking log</a></li>
+<li><a href="../concepts/heap_analyser.htm">Heap Analyser</a></li>
+<li><a href="../concepts/swmtanalyser.htm">SWMT Analyser</a></li>
+</ul>
+
+<div id="footer">Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.
+License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.</div>
+</body>
+</html>
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/gettingstarted/prerequisites.htm Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,23 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
+<title>Prerequisites for use</title>
+<link href="../../book.css" type="text/css" rel="stylesheet">
+</head>
+<body>
+
+<h2>Prerequisites for use</h2>
+<p>Before you start using MemSpy, check the following items:</p>
+
+<p>If you are importing log files from a disk, there are no prerequisites.</p>
+<p>If you are importing log files from a target device, check that you have a TraceCore connection from the target device to the PC.</p>
+
+<p>The MemSpy connection to a target device uses the MemSpy Launcher application that runs in the background in the device. The Launcher application is delivered with the MemSpy Carbide.c++ Extension as an RnD signed SIS file that is located in the <i>plugins\com.nokia.s60tools.memspy.trace_X.Y.Z\Launcher.binaries</i> folder in the Carbide.c++ installation folder in which X.Y.Z is plugin version number.</p>
+
+<p>In addition, note that USB tracing requires that you have a tracing application such as <b>TraceCoreUserApp</b> or <b>TraceSwitch</b> installed in your target device.</p>
+
+<div id="footer">Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.
+License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.</div>
+</body>
+</html>
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/gettingstarted/walk_through.htm Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,45 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+<head>
+ <meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
+ <title>Basic walk-through</title>
+ <link href="../../book.css" type="text/css" rel="stylesheet">
+</head>
+
+<body>
+<h3>Basic walk-through</h3>
+
+<p>You can begin importing and analyzing heap dump and SWMT log files by
+activating the <b>MemSpy Import Wizard</b>. Select <b>Carbide > MemSpy</b>
+and then take the following steps:</p>
+<ol>
+ <li>Select an action (<a href="../tasks/view_heap.htm">Importing and
+ analyzing heap dump files</a>, <a
+ href="../tasks/compare_two_heaps.htm">Importing and comparing two heap dump
+ files</a>, or <a href="../tasks/view_swmt_log.htm">Importing and analyzing
+ System Wide Memory Tracking log files</a>.</li>
+ <li>Select files to be imported and analyzed or compared. If you are
+ comparing two heap dumps, define the reporting settings.</li>
+ <li>When importing heap dumps, define the location of symbol and map files.
+ <p>If the heap dumps are large, increase the buffer size in the tracing
+ application such as <b>TraceCoreUserApp</b> or <b>TraceSwitch</b>.</p>
+ </li>
+ <li>Start analyzing the files.</li>
+</ol>
+
+<p>When the files have been imported, they will be displayed in the
+<b>MemSpy</b> tab in the Carbide.c++ Tabbed View Area, and if you imported a
+single heap dump file or SWMT log files, <a
+href="../reference/heap_analyser_overview.htm">Heap Analyser</a> or <a
+href="../tasks/use_swmt_analyser.htm">SWMT Analyser</a> application will be
+automatically launched for analyzing the files.</p>
+
+<p>You can launch the MemSpy Import Wizard also by selecting <b>File >
+Import > Carbide Extensions > MemSpy</b>.</p>
+
+<div id="footer">
+Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies). All rights
+reserved. License: <a
+href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.</div>
+</body>
+</html>
Binary file sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/Analyse_Heap.png has changed
Binary file sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/Compare_2_Heaps.png has changed
Binary file sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/Launch_SWMT.png has changed
Binary file sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/Memspy_16.png has changed
Binary file sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/SWMT_Analyser_PDF_options.png has changed
Binary file sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/SWMT_Analyser_graph.png has changed
Binary file sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/Thumbs.db has changed
Binary file sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/about_cpp.png has changed
Binary file sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/background_carbide.jpg has changed
Binary file sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/brandmark_cpp.gif has changed
Binary file sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/connection_01.png has changed
Binary file sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/connection_platsim.png has changed
Binary file sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/connection_usb.png has changed
Binary file sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/gold_header.png has changed
Binary file sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/green_fade_left_68_165_28.png has changed
Binary file sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/ha_cell_list.png has changed
Binary file sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/ha_cell_size_distributions.png has changed
Binary file sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/ha_graphs_allocated_cell_size.png has changed
Binary file sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/ha_graphs_associated_binary.png has changed
Binary file sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/ha_graphs_cell_overhead.png has changed
Binary file sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/ha_graphs_free_cell_size.png has changed
Binary file sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/ha_graphs_size_by_cell_index.png has changed
Binary file sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/ha_heap_view.png has changed
Binary file sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/ha_heap_view_cell_length.png has changed
Binary file sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/ha_heap_view_isolation.png has changed
Binary file sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/ha_heap_view_object_type.png has changed
Binary file sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/ha_heap_view_parent_binary.png has changed
Binary file sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/ha_heap_view_pervasiveness.png has changed
Binary file sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/ha_objects.png has changed
Binary file sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/ha_relationships.png has changed
Binary file sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/import_heap_device.png has changed
Binary file sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/import_heap_filesystem.png has changed
Binary file sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/import_swmt_1.png has changed
Binary file sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/import_swmt_2.png has changed
Binary file sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/import_swmt_3.png has changed
Binary file sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/output_in_excel.png has changed
Binary file sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/images/test_results_zip.png has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/index.xml Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,87 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?NLS TYPE="org.eclipse.help.index"?>
+
+ <!-- INDEX INSTRUCTIONS
+
+ Use the index.xml file to define the index entries for the plugin's
+ help contents. In Eclipse 3.2 and beyond an Index tab appears in the Help
+ viewer making it possible for user to more easily locate subjects of
+ interest to them.
+
+ In brief, every file used in the help documentation should have at least one
+ associated index entry for it. Ideally, it's simple to make two entries per
+ page by simply re-wording the subject slightly. For example, a view could
+ be indexed twice like this, 1) Breakpoint view, and 2) Views/Breakpoint.
+
+ See ??? for details on creating indexes.
+
+ -->
+
+<index>
+
+ <!-- AAAAAAAA -->
+
+ <!-- BBBBBBBB -->
+
+ <!-- CCCCCCCC -->
+
+ <!-- DDDDDDDD -->
+
+ <!-- EEEEEEEE -->
+
+ <!-- FFFFFFFF -->
+
+ <!-- GGGGGGGG -->
+
+ <!-- HHHHHHHH -->
+
+ <!-- IIIIIIII -->
+
+ <!-- JJJJJJJJ -->
+
+ <!-- KKKKKKKK -->
+
+ <!-- LLLLLLLL -->
+
+ <entry keyword="Legal" >
+ <topic href="html/legal.htm" />
+ </entry>
+
+ <!-- MMMMMMMM -->
+
+ <!-- NNNNNNNN -->
+
+ <!-- OOOOOOOO -->
+ <entry keyword="Overview" >
+ <topic href="html/Getting_Started/overview.htm" />
+ </entry>
+
+ <!-- PPPPPPPP -->
+
+ <!-- QQQQQQQQ -->
+
+ <!-- RRRRRRRR -->
+ <entry keyword="Release Notes" >
+ <topic href="html/release_notes.htm" />
+ </entry>
+
+ <!-- SSSSSSSS -->
+
+ <!-- TTTTTTTT -->
+
+ <!-- UUUUUUUU -->
+
+ <!-- VVVVVVVV -->
+
+ <!-- WWWWWWWW -->
+ <entry keyword="Basic walk-through" >
+ <topic href="html/Getting_Started/walk_through.htm" />
+ </entry>
+
+ <!-- XXXXXXXX -->
+
+ <!-- YYYYYYYY -->
+
+ <!-- ZZZZZZZZ -->
+
+</index>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/legal.htm Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,748 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
+<title>License Information</title>
+<link href="../book.css" type="text/css" rel="stylesheet">
+</head>
+
+<body>
+<h1>License Information</h1>
+
+<h2>COPYRIGHTS</h2>
+<p>Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. This component and the accompanying materials are made available under the terms of "Eclipse Public License v1.0" which accompanies this distribution and is available at the URL <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.</p>
+<p>Initial Contributors:<br>
+Nokia Corporation - initial contribution</p>
+
+<h2>NOTICES</h2>
+
+<p>Copyright (c) 2005 Sun Microsystems, Inc. All Rights Reserved.</p>
+<p>Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:</p>
+<ul>
+<li>Redistribution of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.</li>
+<li>Redistribution in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in
+the documentation and/or other materials provided with the
+distribution.</li>
+</ul>
+
+<p>Neither the name of Sun Microsystems, Inc. or the names of
+contributors may be used to endorse or promote products derived
+from this software without specific prior written permission.</p>
+<p>This software is provided "AS IS," without a warranty of any
+kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+EXCLUDED. SUN MIDROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES. </p>
+<p>You acknowledge that this software is not designed or intended for
+use in the design, construction, operation or maintenance of any
+nuclear facility.</p>
+
+<p>----</p>
+
+<p>Copyright (c) 1988-1997 Sam Leffler<br>
+Copyright (c) 1991-1997 Silicon Graphics, Inc.</p>
+
+<p>Permission to use, copy, modify, distribute, and sell this software and
+its documentation for any purpose is hereby granted without fee, provided
+that (i) the above copyright notices and this permission notice appear in
+all copies of the software and related documentation, and (ii) the names of
+Sam Leffler and Silicon Graphics may not be used in any advertising or
+publicity relating to the software without the specific, prior written
+permission of Sam Leffler and Silicon Graphics.</p>
+<p>THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.</p>
+<p>IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
+ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
+LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+OF THIS SOFTWARE.</p>
+
+<p>----</p>
+
+<p>COPYRIGHT AND PERMISSION NOTICE</p>
+<p>Copyright (C) 1991-2007 Unicode, Inc. All rights reserved. Distributed under
+the Terms of Use in http://www.unicode.org/copyright.html.</p>
+
+<p>Permission is hereby granted, free of charge, to any person obtaining a copy
+of the Unicode data files and any associated documentation (the "Data Files")
+or Unicode software and any associated documentation (the "Software") to deal
+in the Data Files or Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, and/or sell copies
+of the Data Files or Software, and to permit persons to whom the Data Files
+or Software are furnished to do so, provided that (a) the above copyright
+notice(s) and this permission notice appear with all copies of the Data Files
+or Software, (b) both the above copyright notice(s) and this permission notice
+appear in associated documentation, and (c) there is clear notice in each
+modified Data File or in the Software as well as in the documentation associated
+with the Data File(s) or Software that the data or software has been modified.</p>
+<p>THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
+IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE BE
+LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY
+DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+CONNECTION WITH THE USE OR PERFORMANCE OF THE DATA FILES OR SOFTWARE.</p>
+
+<p>Except as contained in this notice, the name of a copyright holder shall not
+be used in advertising or otherwise to promote the sale, use or other dealings
+in these Data Files or Software without prior written authorization of the
+copyright holder.</p>
+
+
+<h3>Mozilla Public License Version 1.1</h3>
+
+ <h5 id="section-1">1. Definitions.</h5>
+ <dl>
+ <dt id="section-1.0.1">1.0.1. "Commercial Use"
+ <dd>means distribution or otherwise making the Covered Code available to a third party.
+ <dt id="section-1.1">1.1. "Contributor"
+ <dd>means each entity that creates or contributes to the creation of Modifications.
+ <dt id="section-1.2">1.2. "Contributor Version"
+ <dd>means the combination of the Original Code, prior Modifications used by a Contributor,
+ and the Modifications made by that particular Contributor.
+ <dt id="section-1.3">1.3. "Covered Code"
+ <dd>means the Original Code or Modifications or the combination of the Original Code and
+ Modifications, in each case including portions thereof.
+ <dt id="section-1.4">1.4. "Electronic Distribution Mechanism"
+ <dd>means a mechanism generally accepted in the software development community for the
+ electronic transfer of data.
+ <dt id="section-1.5">1.5. "Executable"
+ <dd>means Covered Code in any form other than Source Code.
+ <dt id="section-1.6">1.6. "Initial Developer"
+ <dd>means the individual or entity identified as the Initial Developer in the Source Code
+ notice required by <a href="#exhibit-a">Exhibit A</a>.
+ <dt id="section-1.7">1.7. "Larger Work"
+ <dd>means a work which combines Covered Code or portions thereof with code not governed
+ by the terms of this License.
+ <dt id="section-1.8">1.8. "License"
+ <dd>means this document.
+ <dt id="section-1.8.1">1.8.1. "Licensable"
+ <dd>means having the right to grant, to the maximum extent possible, whether at the
+ time of the initial grant or subsequently acquired, any and all of the rights
+ conveyed herein.
+ <dt id="section-1.9">1.9. "Modifications"
+ <dd>
+ means any addition to or deletion from the substance or structure of either the
+ Original Code or any previous Modifications. When Covered Code is released as a
+ series of files, a Modification is:
+ <ol type="a">
+ <li id="section-1.9-a">Any addition to or deletion from the contents of a file
+ containing Original Code or previous Modifications.
+ <li id="section-1.9-b">Any new file that contains any part of the Original Code or
+ previous Modifications.
+ </ol>
+ <dt id="section-1.10">1.10. "Original Code"
+ <dd>means Source Code of computer software code which is described in the Source Code
+ notice required by <a href="#exhibit-a">Exhibit A</a> as Original Code, and which,
+ at the time of its release under this License is not already Covered Code governed
+ by this License.
+ <dt id="section-1.10.1">1.10.1. "Patent Claims"
+ <dd>means any patent claim(s), now owned or hereafter acquired, including without
+ limitation, method, process, and apparatus claims, in any patent Licensable by
+ grantor.
+ <dt id="section-1.11">1.11. "Source Code"
+ <dd>means the preferred form of the Covered Code for making modifications to it,
+ including all modules it contains, plus any associated interface definition files,
+ scripts used to control compilation and installation of an Executable, or source
+ code differential comparisons against either the Original Code or another well known,
+ available Covered Code of the Contributor's choice. The Source Code can be in a
+ compressed or archival form, provided the appropriate decompression or de-archiving
+ software is widely available for no charge.
+ <dt id="section-1.12">1.12. "You" (or "Your")
+ <dd>means an individual or a legal entity exercising rights under, and complying with
+ all of the terms of, this License or a future version of this License issued under
+ <a href="#section-6.1">Section 6.1.</a> For legal entities, "You" includes any entity
+ which controls, is controlled by, or is under common control with You. For purposes of
+ this definition, "control" means (a) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or otherwise, or (b)
+ ownership of more than fifty percent (50%) of the outstanding shares or beneficial
+ ownership of such entity.
+ </dl>
+
+ <h5 id="section-2">2. Source Code License.</h5>
+ <h5 id="section-2.1">2.1. The Initial Developer Grant.</h5>
+ <p>The Initial Developer hereby grants You a world-wide, royalty-free, non-exclusive
+ license, subject to third party intellectual property claims:
+ <ol type="a">
+ <li id="section-2.1-a">under intellectual property rights (other than patent or
+ trademark) Licensable by Initial Developer to use, reproduce, modify, display, perform,
+ sublicense and distribute the Original Code (or portions thereof) with or without
+ Modifications, and/or as part of a Larger Work; and
+ <li id="section-2.1-b">under Patents Claims infringed by the making, using or selling
+ of Original Code, to make, have made, use, practice, sell, and offer for sale, and/or
+ otherwise dispose of the Original Code (or portions thereof).
+ <li id="section-2.1-c">the licenses granted in this Section 2.1
+ (<a href="#section-2.1-a">a</a>) and (<a href="#section-2.1-b">b</a>) are effective on
+ the date Initial Developer first distributes Original Code under the terms of this
+ License.
+ <li id="section-2.1-d">Notwithstanding Section 2.1 (<a href="#section-2.1-b">b</a>)
+ above, no patent license is granted: 1) for code that You delete from the Original Code;
+ 2) separate from the Original Code; or 3) for infringements caused by: i) the
+ modification of the Original Code or ii) the combination of the Original Code with other
+ software or devices.
+ </ol>
+
+ <h5 id="section-2.2">2.2. Contributor Grant.</h5>
+ <p>Subject to third party intellectual property claims, each Contributor hereby grants You
+ a world-wide, royalty-free, non-exclusive license
+ <ol type="a">
+ <li id="section-2.2-a">under intellectual property rights (other than patent or trademark)
+ Licensable by Contributor, to use, reproduce, modify, display, perform, sublicense and
+ distribute the Modifications created by such Contributor (or portions thereof) either on
+ an unmodified basis, with other Modifications, as Covered Code and/or as part of a Larger
+ Work; and
+ <li id="section-2.2-b">under Patent Claims infringed by the making, using, or selling of
+ Modifications made by that Contributor either alone and/or in combination with its
+ Contributor Version (or portions of such combination), to make, use, sell, offer for
+ sale, have made, and/or otherwise dispose of: 1) Modifications made by that Contributor
+ (or portions thereof); and 2) the combination of Modifications made by that Contributor
+ with its Contributor Version (or portions of such combination).
+ <li id="section-2.2-c">the licenses granted in Sections 2.2
+ (<a href="#section-2.2-a">a</a>) and 2.2 (<a href="#section-2.2-b">b</a>) are effective
+ on the date Contributor first makes Commercial Use of the Covered Code.
+ <li id="section-2.2-d">Notwithstanding Section 2.2 (<a href="#section-2.2-b">b</a>)
+ above, no patent license is granted: 1) for any code that Contributor has deleted from
+ the Contributor Version; 2) separate from the Contributor Version; 3) for infringements
+ caused by: i) third party modifications of Contributor Version or ii) the combination of
+ Modifications made by that Contributor with other software (except as part of the
+ Contributor Version) or other devices; or 4) under Patent Claims infringed by Covered Code
+ in the absence of Modifications made by that Contributor.
+ </ol>
+
+ <h5 id="section-3">3. Distribution Obligations.</h5>
+ <h5 id="section-3.1">3.1. Application of License.</h5>
+ <p>The Modifications which You create or to which You contribute are governed by the terms
+ of this License, including without limitation Section <a href="#section-2.2">2.2</a>. The
+ Source Code version of Covered Code may be distributed only under the terms of this License
+ or a future version of this License released under Section <a href="#section-6.1">6.1</a>,
+ and You must include a copy of this License with every copy of the Source Code You
+ distribute. You may not offer or impose any terms on any Source Code version that alters or
+ restricts the applicable version of this License or the recipients' rights hereunder.
+ However, You may include an additional document offering the additional rights described in
+ Section <a href="#section-3.5">3.5</a>.
+
+ <h5 id="section-3.2">3.2. Availability of Source Code.</h5>
+ <p>Any Modification which You create or to which You contribute must be made available in
+ Source Code form under the terms of this License either on the same media as an Executable
+ version or via an accepted Electronic Distribution Mechanism to anyone to whom you made an
+ Executable version available; and if made available via Electronic Distribution Mechanism,
+ must remain available for at least twelve (12) months after the date it initially became
+ available, or at least six (6) months after a subsequent version of that particular
+ Modification has been made available to such recipients. You are responsible for ensuring
+ that the Source Code version remains available even if the Electronic Distribution
+ Mechanism is maintained by a third party.
+
+ <h5 id="section-3.3">3.3. Description of Modifications.</h5>
+ <p>You must cause all Covered Code to which You contribute to contain a file documenting the
+ changes You made to create that Covered Code and the date of any change. You must include a
+ prominent statement that the Modification is derived, directly or indirectly, from Original
+ Code provided by the Initial Developer and including the name of the Initial Developer in
+ (a) the Source Code, and (b) in any notice in an Executable version or related documentation
+ in which You describe the origin or ownership of the Covered Code.
+
+ <h5 id="section-3.4">3.4. Intellectual Property Matters</h5>
+ <h5 id="section-3.4-a">(a) Third Party Claims</h5>
+ <p>If Contributor has knowledge that a license under a third party's intellectual property
+ rights is required to exercise the rights granted by such Contributor under Sections
+ <a href="#section-2.1">2.1</a> or <a href="#section-2.2">2.2</a>, Contributor must include a
+ text file with the Source Code distribution titled "LEGAL" which describes the claim and the
+ party making the claim in sufficient detail that a recipient will know whom to contact. If
+ Contributor obtains such knowledge after the Modification is made available as described in
+ Section <a href="#section-3.2">3.2</a>, Contributor shall promptly modify the LEGAL file in
+ all copies Contributor makes available thereafter and shall take other steps (such as
+ notifying appropriate mailing lists or newsgroups) reasonably calculated to inform those who
+ received the Covered Code that new knowledge has been obtained.
+
+ <h5 id="section-3.4-b">(b) Contributor APIs</h5>
+ <p>If Contributor's Modifications include an application programming interface and Contributor
+ has knowledge of patent licenses which are reasonably necessary to implement that
+ <abbr>API</abbr>, Contributor must also include this information in the
+ <strong class="very-strong">legal</strong> file.
+
+ <h5 id="section-3.4-c">(c) Representations.</h5>
+ <p>Contributor represents that, except as disclosed pursuant to Section 3.4
+ (<a href="#section-3.4-a">a</a>) above, Contributor believes that Contributor's Modifications
+ are Contributor's original creation(s) and/or Contributor has sufficient rights to grant the
+ rights conveyed by this License.
+
+ <h5 id="section-3.5">3.5. Required Notices.</h5>
+ <p>You must duplicate the notice in <a href="#exhibit-a">Exhibit A</a> in each file of the
+ Source Code. If it is not possible to put such notice in a particular Source Code file due to
+ its structure, then You must include such notice in a location (such as a relevant directory)
+ where a user would be likely to look for such a notice. If You created one or more
+ Modification(s) You may add your name as a Contributor to the notice described in
+ <a href="#exhibit-a">Exhibit A</a>. You must also duplicate this License in any documentation
+ for the Source Code where You describe recipients' rights or ownership rights relating to
+ Covered Code. You may choose to offer, and to charge a fee for, warranty, support, indemnity
+ or liability obligations to one or more recipients of Covered Code. However, You may do so
+ only on Your own behalf, and not on behalf of the Initial Developer or any Contributor. You
+ must make it absolutely clear than any such warranty, support, indemnity or liability
+ obligation is offered by You alone, and You hereby agree to indemnify the Initial Developer
+ and every Contributor for any liability incurred by the Initial Developer or such Contributor
+ as a result of warranty, support, indemnity or liability terms You offer.
+
+ <h5 id="section-3.6">3.6. Distribution of Executable Versions.</h5>
+ <p>You may distribute Covered Code in Executable form only if the requirements of Sections
+ <a href="#section-3.1">3.1</a>, <a href="#section-3.2">3.2</a>,
+ <a href="#section-3.3">3.3</a>, <a href="#section-3.4">3.4</a> and
+ <a href="#section-3.5">3.5</a> have been met for that Covered Code, and if You include a
+ notice stating that the Source Code version of the Covered Code is available under the terms
+ of this License, including a description of how and where You have fulfilled the obligations
+ of Section <a href="#section-3.2">3.2</a>. The notice must be conspicuously included in any
+ notice in an Executable version, related documentation or collateral in which You describe
+ recipients' rights relating to the Covered Code. You may distribute the Executable version of
+ Covered Code or ownership rights under a license of Your choice, which may contain terms
+ different from this License, provided that You are in compliance with the terms of this
+ License and that the license for the Executable version does not attempt to limit or alter the
+ recipient's rights in the Source Code version from the rights set forth in this License. If
+ You distribute the Executable version under a different license You must make it absolutely
+ clear that any terms which differ from this License are offered by You alone, not by the
+ Initial Developer or any Contributor. You hereby agree to indemnify the Initial Developer and
+ every Contributor for any liability incurred by the Initial Developer or such Contributor as
+ a result of any such terms You offer.
+
+ <h5 id="section-3.7">3.7. Larger Works.</h5>
+ <p>You may create a Larger Work by combining Covered Code with other code not governed by the
+ terms of this License and distribute the Larger Work as a single product. In such a case,
+ You must make sure the requirements of this License are fulfilled for the Covered Code.
+
+ <h5 id="section-4">4. Inability to Comply Due to Statute or Regulation.</h5>
+ <p>If it is impossible for You to comply with any of the terms of this License with respect to
+ some or all of the Covered Code due to statute, judicial order, or regulation then You must:
+ (a) comply with the terms of this License to the maximum extent possible; and (b) describe
+ the limitations and the code they affect. Such description must be included in the
+ <strong class="very-strong">legal</strong> file described in Section
+ <a href="#section-3.4">3.4</a> and must be included with all distributions of the Source Code.
+ Except to the extent prohibited by statute or regulation, such description must be
+ sufficiently detailed for a recipient of ordinary skill to be able to understand it.
+
+ <h5 id="section-5">5. Application of this License.</h5>
+ <p>This License applies to code to which the Initial Developer has attached the notice in
+ <a href="#exhibit-a">Exhibit A</a> and to related Covered Code.
+
+ <h5 id="section-6">6. Versions of the License.</h5>
+ <h5 id="section-6.1">6.1. New Versions</h5>
+ <p>Netscape Communications Corporation ("Netscape") may publish revised and/or new versions
+ of the License from time to time. Each version will be given a distinguishing version number.
+
+ <h5 id="section-6.2">6.2. Effect of New Versions</h5>
+ <p>Once Covered Code has been published under a particular version of the License, You may
+ always continue to use it under the terms of that version. You may also choose to use such
+ Covered Code under the terms of any subsequent version of the License published by Netscape.
+ No one other than Netscape has the right to modify the terms applicable to Covered Code
+ created under this License.
+
+ <h5 id="section-6.3">6.3. Derivative Works</h5>
+ <p>If You create or use a modified version of this License (which you may only do in order to
+ apply it to code which is not already Covered Code governed by this License), You must (a)
+ rename Your license so that the phrases "Mozilla", "MOZILLAPL", "MOZPL", "Netscape", "MPL",
+ "NPL" or any confusingly similar phrase do not appear in your license (except to note that
+ your license differs from this License) and (b) otherwise make it clear that Your version of
+ the license contains terms which differ from the Mozilla Public License and Netscape Public
+ License. (Filling in the name of the Initial Developer, Original Code or Contributor in the
+ notice described in <a href="#exhibit-a">Exhibit A</a> shall not of themselves be deemed to
+ be modifications of this License.)
+
+ <h5 id="section-7">7. <strong class="very-strong">Disclaimer of warranty</strong></h5>
+ <p><strong>Covered code is provided under this license on an "as is"
+ basis, without warranty of any kind, either expressed or implied, including, without
+ limitation, warranties that the covered code is free of defects, merchantable, fit for a
+ particular purpose or non-infringing. The entire risk as to the quality and performance of
+ the covered code is with you. Should any covered code prove defective in any respect, you
+ (not the initial developer or any other contributor) assume the cost of any necessary
+ servicing, repair or correction. This disclaimer of warranty constitutes an essential part
+ of this license. No use of any covered code is authorized hereunder except under this
+ disclaimer.</strong>
+
+ <h5 id="section-8">8. Termination</h5>
+ <p id="section-8.1">8.1. This License and the rights granted hereunder will terminate
+ automatically if You fail to comply with terms herein and fail to cure such breach
+ within 30 days of becoming aware of the breach. All sublicenses to the Covered Code which
+ are properly granted shall survive any termination of this License. Provisions which, by
+ their nature, must remain in effect beyond the termination of this License shall survive.
+ <p id="section-8.2">8.2. If You initiate litigation by asserting a patent infringement
+ claim (excluding declatory judgment actions) against Initial Developer or a Contributor
+ (the Initial Developer or Contributor against whom You file such action is referred to
+ as "Participant") alleging that:
+ <ol type="a">
+ <li id="section-8.2-a">such Participant's Contributor Version directly or indirectly
+ infringes any patent, then any and all rights granted by such Participant to You under
+ Sections <a href="#section-2.1">2.1</a> and/or <a href="#section-2.2">2.2</a> of this
+ License shall, upon 60 days notice from Participant terminate prospectively, unless if
+ within 60 days after receipt of notice You either: (i) agree in writing to pay
+ Participant a mutually agreeable reasonable royalty for Your past and future use of
+ Modifications made by such Participant, or (ii) withdraw Your litigation claim with
+ respect to the Contributor Version against such Participant. If within 60 days of
+ notice, a reasonable royalty and payment arrangement are not mutually agreed upon in
+ writing by the parties or the litigation claim is not withdrawn, the rights granted by
+ Participant to You under Sections <a href="#section-2.1">2.1</a> and/or
+ <a href="#section-2.2">2.2</a> automatically terminate at the expiration of the 60 day
+ notice period specified above.
+ <li id="section-8.2-b">any software, hardware, or device, other than such Participant's
+ Contributor Version, directly or indirectly infringes any patent, then any rights
+ granted to You by such Participant under Sections 2.1(<a href="#section-2.1-b">b</a>)
+ and 2.2(<a href="#section-2.2-b">b</a>) are revoked effective as of the date You first
+ made, used, sold, distributed, or had made, Modifications made by that Participant.
+ </ol>
+
+ <p id="section-8.3">8.3. If You assert a patent infringement claim against Participant
+ alleging that such Participant's Contributor Version directly or indirectly infringes
+ any patent where such claim is resolved (such as by license or settlement) prior to the
+ initiation of patent infringement litigation, then the reasonable value of the licenses
+ granted by such Participant under Sections <a href="#section-2.1">2.1</a> or
+ <a href="#section-2.2">2.2</a> shall be taken into account in determining the amount or
+ value of any payment or license.
+ <p id="section-8.4">8.4. In the event of termination under Sections
+ <a href="#section-8.1">8.1</a> or <a href="#section-8.2">8.2</a> above, all end user
+ license agreements (excluding distributors and resellers) which have been validly
+ granted by You or any distributor hereunder prior to termination shall survive
+ termination.
+
+ <h5 id="section-9">9. <strong class="very-strong">Limitation of liability</strong></h5>
+ <p><strong>Under no circumstances and under no legal theory, whether
+ tort (including negligence), contract, or otherwise, shall you, the initial developer,
+ any other contributor, or any distributor of covered code, or any supplier of any of
+ such parties, be liable to any person for any indirect, special, incidental, or
+ consequential damages of any character including, without limitation, damages for loss
+ of goodwill, work stoppage, computer failure or malfunction, or any and all other
+ commercial damages or losses, even if such party shall have been informed of the
+ possibility of such damages. This limitation of liability shall not apply to liability
+ for death or personal injury resulting from such party's negligence to the extent
+ applicable law prohibits such limitation. Some jurisdictions do not allow the exclusion
+ or limitation of incidental or consequential damages, so this exclusion and limitation
+ may not apply to you.</strong>
+
+ <h5 id="section-10">10. <abbr title="United States">U.S.</abbr> government end users</h5>
+ <p>The Covered Code is a "commercial item," as that term is defined in 48
+ <abbr>C.F.R.</abbr> 2.101 (<abbr title="October">Oct.</abbr> 1995), consisting of
+ "commercial computer software" and "commercial computer software documentation," as such
+ terms are used in 48 <abbr>C.F.R.</abbr> 12.212 (<abbr title="September">Sept.</abbr>
+ 1995). Consistent with 48 <abbr>C.F.R.</abbr> 12.212 and 48 <abbr>C.F.R.</abbr>
+ 227.7202-1 through 227.7202-4 (June 1995), all <abbr>U.S.</abbr> Government End Users
+ acquire Covered Code with only those rights set forth herein.
+
+ <h5 id="section-11">11. Miscellaneous</h5>
+ <p>This License represents the complete agreement concerning subject matter hereof. If
+ any provision of this License is held to be unenforceable, such provision shall be
+ reformed only to the extent necessary to make it enforceable. This License shall be
+ governed by California law provisions (except to the extent applicable law, if any,
+ provides otherwise), excluding its conflict-of-law provisions. With respect to
+ disputes in which at least one party is a citizen of, or an entity chartered or
+ registered to do business in the United States of America, any litigation relating to
+ this License shall be subject to the jurisdiction of the Federal Courts of the
+ Northern District of California, with venue lying in Santa Clara County, California,
+ with the losing party responsible for costs, including without limitation, court
+ costs and reasonable attorneys' fees and expenses. The application of the United
+ Nations Convention on Contracts for the International Sale of Goods is expressly
+ excluded. Any law or regulation which provides that the language of a contract
+ shall be construed against the drafter shall not apply to this License.
+
+ <h5 id="section-12">12. Responsibility for claims</h5>
+ <p>As between Initial Developer and the Contributors, each party is responsible for
+ claims and damages arising, directly or indirectly, out of its utilization of rights
+ under this License and You agree to work with Initial Developer and Contributors to
+ distribute such responsibility on an equitable basis. Nothing herein is intended or
+ shall be deemed to constitute any admission of liability.
+
+ <h5 id="section-13">13. Multiple-licensed code</h5>
+ <p>Initial Developer may designate portions of the Covered Code as
+ "Multiple-Licensed". "Multiple-Licensed" means that the Initial Developer permits
+ you to utilize portions of the Covered Code under Your choice of the <abbr>MPL</abbr>
+ or the alternative licenses, if any, specified by the Initial Developer in the file
+ described in <a href="#exhibit-a">Exhibit A</a>.
+
+ <h5 id="exhibit-a">Exhibit A - Mozilla Public License.</h5>
+ <pre>"The contents of this file are subject to the Mozilla Public License
+Version 1.1 (the "License"); you may not use this file except in
+compliance with the License. You may obtain a copy of the License at
+http://www.mozilla.org/MPL/
+
+Software distributed under the License is distributed on an "AS IS"
+basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+License for the specific language governing rights and limitations
+under the License.
+
+The Original Code is ______________________________________.
+
+The Initial Developer of the Original Code is ________________________.
+Portions created by ______________________ are Copyright (C) ______
+_______________________. All Rights Reserved.
+
+Contributor(s): ______________________________________.
+
+Alternatively, the contents of this file may be used under the terms
+of the _____ license (the "[___] License"), in which case the
+provisions of [______] License are applicable instead of those
+above. If you wish to allow use of your version of this file only
+under the terms of the [____] License and not to allow others to use
+your version of this file under the MPL, indicate your decision by
+deleting the provisions above and replace them with the notice and
+other provisions required by the [___] License. If you do not delete
+the provisions above, a recipient may use your version of this file
+under either the MPL or the [___] License."</pre>
+
+ <p>NOTE: The text of this Exhibit A may differ slightly from the text of
+ the notices in the Source Code files of the Original Code. You should
+ use the text of this Exhibit A rather than the text found in the
+ Original Code Source Code for Your Modifications.</p>
+<p></p>
+
+<h3>Apache License</h3>
+<p align="center">Apache License<br />
+Version 2.0, January 2004<br />
+<a href="http://www.apache.org/licenses/">http://www.apache.org/licenses/</a>
+</p>
+<p>
+TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+</p>
+<p><b><a name="definitions">1. Definitions</a></b>.</p>
+<p>
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+</p>
+<p>
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+</p>
+<p>
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+</p>
+<p>
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+</p>
+<p>
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+</p>
+<p>
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+</p>
+
+<p>
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+</p>
+<p>
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+</p>
+<p>
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+</p>
+<p>
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+</p>
+<p><b><a name="copyright">2. Grant of Copyright License</a></b>.
+Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+</p>
+<p><b><a name="patent">3. Grant of Patent License</a></b>.
+Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+</p>
+<p><b><a name="redistribution">4. Redistribution</a></b>.
+You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+<ol type="a">
+<li>You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+<br /> <br /></li>
+
+<li>You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+<br /> <br /></li>
+
+<li>You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+<br /> <br /></li>
+
+<li>If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.</li>
+</ol>
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+</p>
+<p><b><a name="contributions">5. Submission of Contributions</a></b>.
+Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+</p>
+<p><b><a name="trademarks">6. Trademarks</a></b>.
+This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+</p>
+<p><b><a name="no-warranty">7. Disclaimer of Warranty</a></b>.
+Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+</p>
+<p><b><a name="no-liability">8. Limitation of Liability</a></b>.
+In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+</p>
+<p><b><a name="additional">9. Accepting Warranty or Additional Liability</a></b>.
+While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+</p>
+<p>
+END OF TERMS AND CONDITIONS
+</p>
+</div>
+
+<h4 id="apply">
+ APPENDIX: How to apply the Apache License to your work
+</h4>
+<div class="section-content">
+<p>
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+</p>
+<div class="source"><code>
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+</code>
+</div>
+
+
+
+<div id="footer">Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.
+License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.</div>
+</body>
+</html>
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/reference/HA_data_analysis.htm Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,40 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+<head>
+ <meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
+ <meta http-equiv="content-style-type" content="text/css">
+ <meta name="lastupdated" content="06/17/05 11:09:43">
+ <title>Data Analysis with Heap Analyser</title>
+ <link href="../../book.css" type="text/css" rel="StyleSheet">
+</head>
+
+<body>
+<h2>Data Analysis with Heap Analyser</h2>
+
+<p>When analysing a single heap dump, Heap Analyser displays information about
+the heap visually. The information is divided into six tabbed views:</p>
+<ul>
+ <li><a href="heap_view.htm">Heap View</a></li>
+ <li><a href="cell_list.htm">Cell List</a></li>
+ <li><a href="objects.htm">Objects</a></li>
+ <li><a href="relationships.htm">Relationships</a></li>
+ <li><a href="cell_size.htm">Cell Size Distributions</a></li>
+ <li><a href="graphs.htm">Graphs</a></li>
+</ul>
+
+<p></p>
+
+<p><strong>Tip</strong>: Tooltips are displayed when you hover over a View Type
+selection. They give a very basic overview of the purpose of each view type.</p>
+
+<p><strong>Note</strong>: The <strong>Cell List</strong>,
+<strong>Objects</strong>, <strong>Relationships</strong>, and <strong>Cell Size
+Distributions</strong> tabs present much the same information as the
+<strong>Heap View</strong>, only in simple list or table form.</p>
+
+<div id="footer">
+Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies). All rights
+reserved. License: <a
+href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.</div>
+</body>
+</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/reference/associated_binary.htm Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,32 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+<head>
+ <meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
+ <title>Associated Binary</title>
+ <link href="../../book.css" type="text/css" rel="stylesheet">
+</head>
+
+<body>
+<h2>Associated Binary</h2>
+
+<p>The Associated Binary view is an alternative statistical representation of
+the Parent Binary Heap View, in the style of the Objects tab. This view can
+offer a quick way to establish which module is the greatest contributor to heap
+allocation when aggregating all that module’s defined classes.</p>
+
+<p><img src="../images/ha_graphs_associated_binary.png"></p>
+
+<h5>Related references</h5>
+<ul>
+ <li><a href="size_by_cell_index.htm">Size by Cell Index</a></li>
+ <li><a href="free_cell_size.htm">Free Cell Size and Allocated Cell
+ Size</a></li>
+ <li><a href="cell_overhead.htm">Cell Overhead</a></li>
+</ul>
+
+<div id="footer">
+Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies). All rights
+reserved. License: <a
+href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.</div>
+</body>
+</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/reference/cell_lenght.htm Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,32 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+<head>
+ <meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
+ <title>Cell Lenght</title>
+ <link href="../../book.css" type="text/css" rel="stylesheet">
+</head>
+
+<body>
+<h2>Cell Lenght </h2>
+
+<p>The Cell Length view is much like the <strong>Object Type</strong> in terms
+of labelling, but it differs based on the allocated length of each object with
+the intent to make it easier to quickly pick out the largest objects.</p>
+
+<p><img src="../images/ha_heap_view_cell_length.png"></p>
+
+<h5>Related references</h5>
+<ul>
+ <li><a href="cell_type.htm">Cell Type</a></li>
+ <li><a href="object_type.htm">Object Type</a></li>
+ <li><a href="parent_binary.htm">Parent Binary</a></li>
+ <li><a href="isolation.htm">Isolation and Pervasiveness</a></li>
+ <li><a href="HA_data_analysis.htm">Data analysis with Heap Analyser</a></li>
+</ul>
+
+<div id="footer">
+Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies). All rights
+reserved. License: <a
+href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.</div>
+</body>
+</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/reference/cell_list.htm Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,30 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+<head>
+ <meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
+ <title>Cell List</title>
+ <link href="../../book.css" type="text/css" rel="stylesheet">
+</head>
+
+<body>
+<h2>Cell List</h2>
+
+<p>In the Cell List view, you can display a simple tabular representation of
+all the cells in the heap displaying cell number, status (allocated/free),
+address, length, and type when known. Double-clicking on a cell takes you to
+its representation in the <strong>Heap View</strong>. The drop down box allows
+you to filter by type.</p>
+
+<p><img src="../images/ha_cell_list.png"></p>
+
+<h5>Related references</h5>
+<ul>
+ <li><a href="HA_data_analysis.htm">Data analysis with Heap Analyser</a></li>
+</ul>
+
+<div id="footer">
+Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies). All rights
+reserved. License: <a
+href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.</div>
+</body>
+</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/reference/cell_overhead.htm Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,31 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+<head>
+ <meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
+ <title>Cell Overhead</title>
+ <link href="../../book.css" type="text/css" rel="stylesheet">
+</head>
+
+<body>
+<h2>Cell Overhead</h2>
+
+<p>Cell Overhead is a graphical representation of the space costs for the
+heap’s book-keeping data. The smaller the objects in the heap are on
+average, the greater the book-keeping data overheap will be as a percentage.</p>
+
+<p><img src="../images/ha_graphs_cell_overhead.png"></p>
+
+<h5>Related references</h5>
+<ul>
+ <li><a href="size_by_cell_index.htm">Size by Cell Index</a></li>
+ <li><a href="free_cell_size.htm">Free Cell Size and Allocated Cell
+ Size</a></li>
+ <li><a href="associated_binary.htm">Associated Binary</a></li>
+</ul>
+
+<div id="footer">
+Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies). All rights
+reserved. License: <a
+href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.</div>
+</body>
+</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/reference/cell_size.htm Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,28 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+<head>
+ <meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
+ <title>Cell Size Distributions</title>
+ <link href="../../book.css" type="text/css" rel="stylesheet">
+</head>
+
+<body>
+<h2>Cell Size Distributions</h2>
+
+<p>The Cell Size Distributions view displays a type-independent statistical
+breakdown of the heap by cell size, both for free and allocated cells. This
+view can be useful e.g. when evaluating heap fragmentation issues.</p>
+
+<p><img src="../images/ha_cell_size_distributions.png"></p>
+
+<h5>Related references</h5>
+<ul>
+ <li><a href="HA_data_analysis.htm">Data analysis with Heap Analyser</a></li>
+</ul>
+
+<div id="footer">
+Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies). All rights
+reserved. License: <a
+href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.</div>
+</body>
+</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/reference/cell_type.htm Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,74 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+<head>
+ <meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
+ <title>Cell Type</title>
+ <link href="../../book.css" type="text/css" rel="stylesheet">
+</head>
+
+<body>
+<h2>Cell Type</h2>
+
+<p>The Cell Type view is a low-level view of the layout of the heap. It is
+useful for getting a quick feel for fragmentation, for example, but the other
+views are more commonly used.</p>
+
+<p><img src="../images/ha_heap_view.png"></p>
+
+<p>The Cell Type view breaks down the heap into word-sized (4 byte) blocks,
+each represented by a coloured square. The following colour-coding is applied
+to each related group of words for easy identification:</p>
+<ul>
+ <li><strong>White</strong>: Contains a header word, used by the heap
+ allocator for book-keeping.</li>
+ <li><strong>Red/Orange</strong>: Contains the data of an allocated object
+ whose class has been identified via its vtable pointer.</li>
+ <li><strong>Yellow</strong>: Contains the data of a heap-allocated
+ descriptor.</li>
+ <li><strong>Purple/Brown</strong>: Contains the data of an allocated object
+ whose type cannot be identified, usually a raw data buffer.</li>
+ <li><strong>Blue</strong>: A free area of the heap that does not currently
+ contain an allocated object.</li>
+</ul>
+
+<p>The colour fade between the start and end of a group of words makes it
+easier for you to pick out the beginning and the end of cells.</p>
+
+<p>If you highlight a cell by hovering the mouse over it (the whole of the
+associated cell is highlighted), you get a pop-up summary of its contents as a
+tool-tip. You can also right-click to bring up a context menu of options.</p>
+
+<p>If you click on a cell to select it, or navigate to it using the cursor keys
+or the <strong>Previous / Next</strong> buttons, or search for it by address in
+the <strong>Search</strong> box, then that cell will be selected and you will
+get a summary in the <strong>Information</strong> box below.</p>
+<ul>
+ <li><strong>Address</strong> is the start of the cell, including book-keeping
+ info.</li>
+ <li><strong>Payload</strong> is the address range of the actual data stored
+ in the cell.</li>
+ <li><strong>Nesting level</strong> and <strong>Allocation number</strong>
+ info for a cell are only maintained by the debug (UDEB) version of RHeap,
+ and rarely used as a result.</li>
+</ul>
+
+<p>If you double-click on a cell, a floating memory inspector window will be
+displayed, showing you the cell contents. Cells that contain references to
+other memory locations are highlighted. Double-clicking a highlighted value
+jumps to the referenced location.</p>
+
+<h5>Related references</h5>
+<ul>
+ <li><a href="object_type.htm">Object Type</a></li>
+ <li><a href="parent_binary.htm">Parent Binary</a></li>
+ <li><a href="cell_lenght.htm">Cell Lenght</a></li>
+ <li><a href="isolation.htm">Isolation and Pervasiveness</a></li>
+ <li><a href="HA_data_analysis.htm">Data analysis with Heap Analyser</a></li>
+</ul>
+
+<div id="footer">
+Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies). All rights
+reserved. License: <a
+href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.</div>
+</body>
+</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/reference/free_cell_size.htm Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,32 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+<head>
+ <meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
+ <title>Free Cell Size and Allocated Cell Size</title>
+ <link href="../../book.css" type="text/css" rel="stylesheet">
+</head>
+
+<body>
+<h2>Free Cell Size and Allocated Cell Size</h2>
+
+<p>The Free Cell Size and Allocated Cell Size graphs display graphical
+representations of free cell fragmentation and allocated cell size distribution
+respectively.</p>
+
+<p><img src="../images/ha_graphs_free_cell_size.png"></p>
+
+<p><img src="../images/ha_graphs_allocated_cell_size.png"></p>
+
+<h5>Related references</h5>
+<ul>
+ <li><a href="size_by_cell_index.htm">Size by Cell Index</a></li>
+ <li><a href="cell_overhead.htm">Cell Overhead</a></li>
+ <li><a href="associated_binary.htm">Associated Binary</a></li>
+</ul>
+
+<div id="footer">
+Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies). All rights
+reserved. License: <a
+href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.</div>
+</body>
+</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/reference/graphs.htm Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,31 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+<head>
+ <meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
+ <title>Graphs</title>
+ <link href="../../book.css" rel="stylesheet" type="text/css">
+</head>
+
+<body>
+<h2>Graphs</h2>
+
+<p>The Graphs view yields a course-grain statistical breakdown of the behaviour
+and representation efficiency of the heap. It can be useful for identifying
+problematic allocation patterns, bad interactions between allocation patterns
+and the RHeap free cell reuse algorithms, and also the effectiveness of changes
+to heap algorithms and client allocation patterns. See the following sections
+for more details:</p>
+<ul>
+ <li><a href="size_by_cell_index.htm">Size by Cell Index</a></li>
+ <li><a href="free_cell_size.htm">Free Cell Size and Allocated Cell
+ Size</a></li>
+ <li><a href="cell_overhead.htm">Cell Overhead</a></li>
+ <li><a href="associated_binary.htm">Associated Binary</a></li>
+</ul>
+
+<div id="footer">
+Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies). All rights
+reserved. License: <a
+href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.</div>
+</body>
+</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/reference/heap_analyser_overview.htm Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,50 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+<head>
+ <meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
+ <title>Overview</title>
+ <link href="../../book.css" type="text/css" rel="stylesheet">
+</head>
+
+<body>
+<h2>Heap Analyser overview</h2>
+
+<p>Heap Analyser is PC application used to graphically inspect and analyse
+Symbian OS heap objects. It is the PC-side complement to the heap capture
+technology of <strong>MemSpy</strong> and <strong>MemSpy Carbide.c++
+Extension</strong>. Use MemSpy or MemSpy Carbide Extension to capture heap
+data, and then Heap Analyser to display and analyse the contents.</p>
+
+<p>Heap Analyser contains the following features:</p>
+<ul>
+ <li>Full graphical rendering of heap</li>
+ <li>Includes object names, parent binary, cell age (fragmentation)</li>
+ <li>Heap statistics</li>
+ <li>Graphing</li>
+ <li>"Save as Zip" feature for sharing your heap information with others (e.g.
+ error reports)</li>
+ <li>HTML output</li>
+</ul>
+
+<h5>Related references</h5>
+<ul>
+ <li><a href="prerequisites_for_HA.htm">Prerequisites for using Heap
+ Analyser</a></li>
+ <li><a href="HA_data_analysis.htm">Data Analysis with Heap Analyser</a></li>
+ <li><a href="saving_HA_reports.htm">Saving Heap Analyser reports</a> </li>
+</ul>
+
+<h5>Related tasks</h5>
+<ul>
+ <li><a href="../tasks/view_heap.htm">Importing and analyzing heap dump
+ files</a></li>
+ <li><a href="../tasks/compare_two_heaps.htm">Importing and comparing two heap
+ dump files</a></li>
+</ul>
+
+<div id="footer">
+Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies). All rights
+reserved. License: <a
+href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.</div>
+</body>
+</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/reference/heap_view.htm Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,29 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+<head>
+ <meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
+ <title>Heap View</title>
+ <link href="../../book.css" rel="stylesheet" type="text/css">
+</head>
+
+<body>
+<h2>Heap View</h2>
+
+<p>In the Heap View, you can view information about the header and contents of
+individual cell heaps. You can also search heaps by address or allocation
+number. Double-clicking a cell displays detailed stack information. See the
+following sections for more details:</p>
+<ul>
+ <li><a href="cell_type.htm">Cell Type</a></li>
+ <li><a href="object_type.htm">Object Type</a></li>
+ <li><a href="parent_binary.htm">Parent Binary</a></li>
+ <li><a href="cell_lenght.htm">Cell Lenght</a></li>
+ <li><a href="isolation.htm">Isolation and Pervasiveness</a></li>
+</ul>
+
+<div id="footer">
+Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies). All rights
+reserved. License: <a
+href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.</div>
+</body>
+</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/reference/isolation.htm Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,55 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+<head>
+ <meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
+ <title>Isolation and Pervasiveness</title>
+ <link href="../../book.css" type="text/css" rel="stylesheet">
+</head>
+
+<body>
+<h2>Isolation and Pervasiveness</h2>
+
+<p>The Isolation and Pervasiveness views are about highlighting reference
+density.</p>
+
+<p>The <strong>Isolation</strong> view shades objects from cold (blue) to hot
+(more red) based on how “popular” they are with other objects. The
+actual incoming reference count is also displayed in the box at the start of
+each object. Darkest blue objects with a red zero count indicate objects that
+have no references at all within the heap itself. That does not necessarily
+mean they are orphans that have been leaked; they could be referenced from the
+stack or from static variables instead. However, if you do think you may have a
+memory leak then these zero count objects are a good place to start looking.</p>
+
+<p><img src="../images/ha_heap_view_isolation.png"></p>
+
+<p>The <strong>Pervasiveness</strong> view is the inverse of the Isolation
+view. In Pervasiveness view, objects are shaded from cold (blue) to hot (more
+red) based on how many other objects they are “interested” in. The
+actual outgoing reference count is also displayed in the box at the start of
+the object. The other highlighted boxes within cells are the actual locations
+of the potential outgoing references Heap Analyser has identified. As pure data
+datatypes with no outgoing references, descriptors are distinguished in yellow
+here. If you have a memory leak, bright red objects may be worth investigating
+as the potential home to an abnormally large number of references. For example,
+the buffer object within a large array of pointers may be highlighted in this
+view, and in some cases could be the source of a leak e.g. due to forgetting to
+delete objects from the array when they’re no longer needed.</p>
+
+<p><img src="../images/ha_heap_view_pervasiveness.png"></p>
+
+<h5>Related references</h5>
+<ul>
+ <li><a href="cell_type.htm">Cell Type</a></li>
+ <li><a href="object_type.htm">Object Type</a></li>
+ <li><a href="parent_binary.htm">Parent Binary</a></li>
+ <li><a href="cell_lenght.htm">Cell Lenght</a></li>
+ <li><a href="HA_data_analysis.htm">Data analysis with Heap Analyser</a></li>
+</ul>
+
+<div id="footer">
+Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies). All rights
+reserved. License: <a
+href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.</div>
+</body>
+</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/reference/object_type.htm Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,79 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+<head>
+ <meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
+ <title>Object Type</title>
+ <link href="../../book.css" type="text/css" rel="stylesheet">
+</head>
+
+<body>
+<h2>Object Type </h2>
+
+<p>The Object Type view presents the objects on the heap and their position
+within it, just as in the <strong>Cell Type</strong> view, but by tagging them
+with their C++ type name so that you can easily recognize the objects from your
+own code. Determining an object’s type for display is usually possible
+for the majority of objects in the heap, but not for them all. An
+object’s type can usually be determined if</p>
+<ul>
+ <li>it is an instance of a C++ class with at least one (directly defined or
+ inherited) virtual function, or</li>
+ <li>it is a descriptor.</li>
+</ul>
+
+<p>If the object type cannot be determined, but there is a unique referrer for
+the object type, or if all referrers are of the same known type, <em>[Part of
+XXX]</em> is displayed, where XXX is the type of the referrer.</p>
+
+<p>Otherwise, <em>[Unknown]</em> is displayed.</p>
+
+<p>A virtual function in a class means each instance of that class will contain
+a vtable pointer. The vtable pointer can be used, in combination with the
+symbolic information provided at startup, to determine the name of the class
+associated with the vtable for presentation. Symbian’s CBase defines a
+virtual destructor, so all conventional C-prefixed classes in Symbian will have
+a vtable and so be identifiable in this way.</p>
+
+<p>There are a number of possibilities, but an <em>[Unknown]</em> or <em>[Part
+of XXX]</em> object is typically either a raw (non-descriptor) data buffer, or
+sometimes a T-class allocated on the heap. Because such an object is often
+owned and encapsulated by an identifiable C-class, one effective strategy for
+identifying objects, which type cannot be determined, is to use the incoming
+reference information Heap Analyser constructs. If an otherwise unknown object
+type has this reference information, it is displayed in the view as <em>[Part
+of XXX]</em>, where XXX is the type of the referrer. In addition, if you
+right-click an <em></em>object and select <strong>Go to…</strong> >
+<strong>Incoming reference</strong>, the context menu will display the types of
+the objects that refer to the <em></em>object. In fact there are a number of
+ways of visualizing object reference relationships available from the
+right-click context menu, including drawing the link relationships between
+objects as an overlay of dotted lines (right click and select
+<strong>Relationships…</strong> > <strong>Incoming</strong> >
+<strong>Breadcrumbs</strong>).</p>
+
+<p>Colours are chosen arbitrarily on a type-by-type basis in this view, with
+the exception of descriptors (Yellow), <em>[Unknown]</em> and <em>[Part of
+XXX]</em> (Red), and free space (Blue). The colour allocation can be viewed and
+refined by clicking <strong>Set Filters</strong>. This filter settings panel is
+also useful for focusing down on just object types of particular interest;
+click <strong>Enable None</strong>, then selectively enable just the types you
+are interested in. To get an overview, select <strong>View</strong> >
+<strong>Size</strong> > <strong>Small</strong>.</p>
+
+<p><img src="../images/ha_heap_view_object_type.png"></p>
+
+<h5>Related references</h5>
+<ul>
+ <li><a href="cell_type.htm">Cell Type</a></li>
+ <li><a href="parent_binary.htm">Parent Binary</a></li>
+ <li><a href="cell_lenght.htm">Cell Lenght</a></li>
+ <li><a href="isolation.htm">Isolation and Pervasiveness</a></li>
+ <li><a href="HA_data_analysis.htm">Data analysis with Heap Analyser</a></li>
+</ul>
+
+<div id="footer">
+Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies). All rights
+reserved. License: <a
+href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.</div>
+</body>
+</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/reference/objects.htm Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,29 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+<head>
+ <meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
+ <title>Objects</title>
+ <link href="../../book.css" type="text/css" rel="stylesheet">
+</head>
+
+<body>
+<h2>Objects</h2>
+
+<p>The Objects view breaks down the identified objects in the heap
+statistically by type. This is the quickest way to determine which types of
+objects are dominating allocated memory. Note that this tab cannot represent
+<em>[Unknown]</em> objects..</p>
+
+<p><img src="../images/ha_objects.png"></p>
+
+<h5>Related references</h5>
+<ul>
+ <li><a href="HA_data_analysis.htm">Data analysis with Heap Analyser</a></li>
+</ul>
+
+<div id="footer">
+Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies). All rights
+reserved. License: <a
+href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.</div>
+</body>
+</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/reference/parent_binary.htm Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,46 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+<head>
+ <meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
+ <title>Parent Binary</title>
+ <link href="../../book.css" type="text/css" rel="stylesheet">
+</head>
+
+<body>
+<h2>Parent Binary</h2>
+
+<p>The Parent Binary view is effectively the same as the <strong>Object
+Type</strong> view, except that instead of displaying each object’s type,
+it displays the name of the object file that defined that type’s
+<em>vtable</em>.</p>
+
+<p>What this view does not do is record the logical allocation point of an
+object, since that is simply not recoverable from the information available.
+For example, if some of your own code contains a <em>CFoo::NewL()</em> where
+<em>CFoo</em> is imported from a dll, then it will be an object file in the dll
+that is displayed for the resulting allocated cell, not the object file
+containing the call to <em>NewL</em>.</p>
+
+<p>This view can be useful to quickly find a module that is contributing into a
+heap objects that are unexpectedly large, or that you do not expect to be
+there.</p>
+
+<p></p>
+
+<p><img src="../images/ha_heap_view_parent_binary.png"></p>
+
+<h5>Related references</h5>
+<ul>
+ <li><a href="cell_type.htm">Cell Type</a></li>
+ <li><a href="object_type.htm">Object Type</a></li>
+ <li><a href="cell_lenght.htm">Cell Lenght</a></li>
+ <li><a href="isolation.htm">Isolation and Pervasiveness</a></li>
+ <li><a href="HA_data_analysis.htm">Data analysis with Heap Analyser</a></li>
+</ul>
+
+<div id="footer">
+Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies). All rights
+reserved. License: <a
+href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.</div>
+</body>
+</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/reference/prerequisites_for_HA.htm Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,33 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+<head>
+ <meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
+ <title>Prerequisites for using Heap Analyser</title>
+ <link href="../../book.css" type="text/css" rel="stylesheet">
+</head>
+
+<body>
+<h2>Prerequisites for using Heap Analyser</h2>
+
+<p>Heap Analyser is distributed together with the MemSpy Carbide.c++ Extension
+in the SymSEE delivery.</p>
+
+<p>Heap Analyser requires the Microsoft .NET Framework v2.0.50727 or newer. You
+can download the .NET Framework 2.0 installation package from <a
+href="http://www.microsoft.com/downloads/details.aspx?familyid=0856eacb-4362-4b0d-8edd-aab15c5e04f5&displaylang=en">http://www.microsoft.com/downloads/details.aspx?familyid=0856eacb-4362-4b0d-8edd-aab15c5e04f5&displaylang=en</a>.</p>
+
+<p>The Compare functionality requires also Microsoft Office Excel 2003 or
+newer.</p>
+
+<h5>Related references</h5>
+<ul>
+ <li><a href="heap_analyser_overview.htm">Heap Analyser Overview</a></li>
+ <li><a href="HA_data_analysis.htm">Data Analysis with Heap Analyser</a></li>
+</ul>
+
+<div id="footer">
+Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies). All rights
+reserved. License: <a
+href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.</div>
+</body>
+</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/reference/references.htm Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,26 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+<head>
+ <meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
+ <meta http-equiv="content-style-type" content="text/css">
+ <meta name="lastupdated" content="06/17/05 11:09:43">
+ <title>References</title>
+ <link href="../../book.css" type="text/css" rel="StyleSheet">
+</head>
+
+<body>
+<h2>References</h2>
+
+<p>The following references are available for this tool:</p>
+<ul>
+ <li><a href="toolbar.htm">Toolbar</a></li>
+ <li><a href="troubleshooting.htm">Troubleshooting</a></li>
+ <li><a href="heap_analyser_overview.htm">Heap Analyser overview</a></li>
+</ul>
+
+<div id="footer">
+Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies). All rights
+reserved. License: <a
+href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.</div>
+</body>
+</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/reference/relationships.htm Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,28 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+<head>
+ <meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
+ <title>Relationships</title>
+ <link href="../../book.css" type="text/css" rel="stylesheet">
+</head>
+
+<body>
+<h2>Relationships</h2>
+
+<p>The Relationships view is like Cell List, but when you select a cell from
+the Cells table, its incoming and outgoing references can be viewed in the
+bottom half of the view.</p>
+
+<p><img src="../images/ha_relationships.png"></p>
+
+<h5>Related references</h5>
+<ul>
+ <li><a href="HA_data_analysis.htm">Data analysis with Heap Analyser</a></li>
+</ul>
+
+<div id="footer">
+Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies). All rights
+reserved. License: <a
+href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.</div>
+</body>
+</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/reference/saving_HA_reports.htm Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,41 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+<head>
+ <meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
+ <title>Saving Heap Analyser reports</title>
+ <link href="../../book.css" type="text/css" rel="stylesheet">
+</head>
+
+<body>
+<h2>Saving Heap Analyser reports</h2>
+
+<p>In Heap Analyser, you can save heap dump logs to several formats for further
+analysis.</p>
+
+<p>Select <strong>File</strong> > <strong>Save As</strong>, and then one of
+the file formats:</p>
+<ul>
+ <li><strong>As Zip</strong> creates a zip file that contains the source data,
+ and the complete heap in comma-separated Excel (CSV) and text format (see
+ figure below).
+ <p><img src="../images/test_results_zip.png"></p>
+ </li>
+ <li><strong>As CSV</strong> creates a comma-separated Excel file (CSV) of the
+ complete heap </li>
+ <li><strong>As Text</strong> creates a text file of the complete heap.</li>
+ <li><strong>As HTML</strong> creates four HTML files that represent the heap.
+ Open the file <em>index.htm</em> to inspect details.</li>
+</ul>
+
+<h5>Related references</h5>
+<ul>
+ <li><a href="../reference/HA_data_analysis.htm">Data Analysis with Heap
+ Analyser</a></li>
+</ul>
+
+<div id="footer">
+Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies). All rights
+reserved. License: <a
+href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.</div>
+</body>
+</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/reference/size_by_cell_index.htm Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,33 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+<head>
+ <meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
+ <title>Size by Cell Index</title>
+ <link href="../../book.css" type="text/css" rel="stylesheet">
+</head>
+
+<body>
+<h2>Size by Cell Index</h2>
+
+<p>The Size by Cell Index graph displays a cell’s position in the heap
+set against its size. An uneven distribution here may tell you something about
+the phases and allocation patterns of the program under investigation. Note,
+though, that while often aligned to a degree, a cell’s index is not an
+indicator of age along the execution timeline due to cell re-use.</p>
+
+<p><img src="../images/ha_graphs_size_by_cell_index.png"></p>
+
+<h5>Related references</h5>
+<ul>
+ <li><a href="free_cell_size.htm">Free Cell Size and Allocated Cell
+ Size</a></li>
+ <li><a href="cell_overhead.htm">Cell Overhead</a></li>
+ <li><a href="associated_binary.htm">Associated Binary</a></li>
+</ul>
+
+<div id="footer">
+Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies). All rights
+reserved. License: <a
+href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.</div>
+</body>
+</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/reference/toolbar.htm Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,55 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <title>Toolbar</title>
+ <link href="../../book.css" rel="stylesheet" type="text/css">
+</head>
+
+<body>
+
+<h2>Toolbar</h2>
+<p>The toolbar in the MemSpy view contains the following icons:</p>
+
+<table width="615" border="1" cellspacing="1" cellpadding="2">
+<colgroup>
+<col width="149*">
+<col width="456*">
+</colgroup>
+
+<tbody>
+<tr>
+<th align="center">Button</th>
+<th align="center">Description</th>
+</tr>
+
+<tr>
+<td><img src="../images/Launch_SWMT.png" alt="Launch SWMT Analyser"></td>
+<td>Launch SWMT Analyser.</td>
+</tr>
+
+<tr>
+<td><img src="../images/Compare_2_Heaps.png" alt="Compare 2 heaps"></td>
+<td>Compare two selected files, or import a file and compare it to a selected file.
+</td>
+</tr>
+
+<tr>
+<td><img src="../images/Analyse_Heap.png" alt="Analyse heap"></td>
+<td>Launch Heap Analyser and analyse the selected file(s).</td>
+</tr>
+
+<tr>
+<td><img src="../images/Memspy_16.png" alt="Launch MemSpy import"></td>
+<td>Launch MemSpy Import Wizard.</td>
+</tr>
+
+</tbody>
+</table>
+
+<div id="footer">Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.
+License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.</div>
+
+</body>
+</html>
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/reference/troubleshooting.htm Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,115 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+<head>
+ <meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
+ <title>Troubleshooting</title>
+ <link href="../../book.css" type="text/css" rel="stylesheet">
+</head>
+
+<body>
+<h2>Troubleshooting</h2>
+
+<h3 name="memspy_trb">MemSpy</h3>
+
+<p>The MemSpy> Carbide.c++ Extension error messages are listed below:</p>
+
+<table width="615" border="1" cellspacing="1" cellpadding="2">
+ <colgroup><col width="250*">
+ <col width="356*">
+ </colgroup>
+ <tbody>
+ <tr>
+ <th>Message</th>
+ <th align="center">Description</th>
+ </tr>
+ <tr>
+ <td><i>MemSpy extension was unable to receive response from MemSpy
+ S60-application.</i></td>
+ <td>The target device does not respond to requests sent from the MemSpy
+ Carbide.c++ Extension. Restart the target device. If you are using an
+ USB connection, make sure you have activated trace sending in
+ TraceSwitch or TraceCoreUserApp.</td>
+ </tr>
+ <tr>
+ <td><i>MemSpy s60-application was not found from your device.</i></td>
+ <td>Your device has MemSpy Launcher, but not MemSpy S60 application
+ installed. Install MemSpy S60 application to the device and restart the
+ device.</td>
+ </tr>
+ <tr>
+ <td><i>Received log files are corrupt.</i></td>
+ <td>The heap dump or SWMT log files are missing lines. If you are using
+ an USB connection, increase the buffer size in TraceSwitch or
+ TraceCoreUserApp.</td>
+ </tr>
+ <tr>
+ <td><i>No Heap Found.</i></td>
+ <td>The selected thread is missing, probably because it has terminated.
+ Reload the thread list. If this does not help, restart the device. </td>
+ </tr>
+ <tr>
+ <td><i>Selected heap's heap type is wrong (needs to be Symbian OS
+ RHeap).</i></td>
+ <td>The heap of the selected thread is not supported, and the heap dump
+ cannot be retrieved by MemSpy.</td>
+ </tr>
+ <tr>
+ <td><i>Invalid heap dump file. The file doesn't contain any threads with
+ binary data information.</i></td>
+ <td>The file you are trying to import does not contain any threads with
+ binary data information, or contains a binary data error. The file will
+ not be imported.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h3 name="swmt_analyser_trb">SWMT Analyser</h3>
+
+<p>The SWMT Analyser error messages are listed below:</p>
+
+<table width="615" border="1" cellspacing="1" cellpadding="2">
+ <colgroup><col width="250*">
+ <col width="356*">
+ </colgroup>
+ <tbody>
+ <tr>
+ <th>Message</th>
+ <th align="center">Description</th>
+ </tr>
+ <tr>
+ <td><i>xyz.xls file is already exists and opened, could not overwrite.
+ Please close it and try again.</i></td>
+ <td>The Excel XLS file is already opened in the target folder.<br>
+ Close the Excel file and try exporting to Excel again.</td>
+ </tr>
+ <tr>
+ <td><i>Invalid order of the log files. The selected files must be in
+ consecutive order and must start from the cycle 1.</i></td>
+ <td>The selected files in the MemSpy view are not in consecutive order,
+ starting from cycle 1.<br>
+ Select the log files and make sure that they are in consecutive order
+ and starting from cycle 1.</td>
+ </tr>
+ <tr>
+ <td><i>This is a delta file. It does not contain the complete
+ information. Do you still want to continue?</i></td>
+ <td>You tried to open a single file which has a cycle number other than
+ 1.<br>
+ Click <b>Yes</b> to continue, or <b>No</b> to cancel.</td>
+ </tr>
+ <tr>
+ <td><i>The file is invalid.</i></td>
+ <td>SWMT Analyser cannot read the data from the log file. This may occur
+ if there are typos or other manual edits in the log file.<br>
+ Please check the filename and the line number shown in the error
+ message, and act accordingly.</td>
+ </tr>
+ </tbody>
+</table>
+
+<div id="footer">
+Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies). All rights
+reserved. License: <a
+href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.</div>
+</body>
+</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/release_notes.htm Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,210 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+ <meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
+ <title>Release Notes</title>
+ <link href="../book.css" type="text/css" rel="stylesheet">
+ <style type="text/css">
+ </style>
+</head>
+
+<body>
+<h2>Release Notes</h2>
+
+<h4>MemSpy Carbide.c++ Extension – Version 1.6.0</h4>
+
+<p>Released 21st April 2010</p>
+<ul>
+ <li><a href="#description">Product description</a></li>
+ <li><a href="#features">Main features</a></li>
+ <li><a href="#newfeatures">What's new</a></li>
+ <li><a href="#installation">Installation notes</a></li>
+ <li><a href="#requirements">System requirements</a></li>
+ <li><a href="#compissues">Compatibility issues</a></li>
+ <li><a href="#issues">Known issues</a></li>
+</ul>
+
+<h3><a name="description"></a>Product description</h3>
+
+<p>The MemSpy extension for Carbide.c++ is a tool for importing heap dumps and
+System Wide Memory Tracking logs from a device to PC and analyzing them.</p>
+
+<p>MemSpy can be started either by selecting <b>Carbide > MemSpy</b>, or
+from <b>File > Import > Carbide Extensions > MemSpy</b>.</p>
+
+<h3><a name="features"></a>Main features</h3>
+<ul>
+ <li>Importing heap dump and SWMT log files either from a file or from a
+ target via TraceViewer connection.</li>
+ <li>Heap Analyser for heap dump file analysis and comparison.</li>
+ <li>SWMT Analyser for SWMT log file analysis.</li>
+</ul>
+
+<h3><a name="newfeatures"></a>What's new</h3>
+<ul>
+ <li><strong>Feature</strong>: Added checking for invalid heap dump files that
+ do not contain any threads with binary data information, or contain a
+ binary data error. </li>
+ <li><strong>Feature</strong>: In Heap Analyser's Object type view: If there
+ is a unique referrer for the object type, or if all referrers are of the
+ same known type, the object is no longer named [Unknown] but instead [Part
+ of XXX] is now displayed, where XXX is the type of the referrer. </li>
+ <li><strong>Fix</strong>: Corrected some paths in exported HTML files to use
+ JavaScript functions and display tooltips also in Heap Data and Cell
+ Associations sections.</li>
+ <li>Change: Heap Analyser documentation has been integrated to the MemSpy
+ Help in Carbide. </li>
+</ul>
+
+<h3><a name="installation"></a>Installation notes</h3>
+<ul>
+ <li>N/A</li>
+</ul>
+
+<h3><a name="requirements"></a>System requirements</h3>
+
+<p>Basic requirements:</p>
+<ul>
+ <li>Windows 2000, Windows XP</li>
+ <li>Carbide.c++.</li>
+ <li>Minimum SDK build PC.</li>
+ <li>Normal SDK build PC.</li>
+</ul>
+
+<p>Additional requirements:</p>
+<ul>
+ <li>TraceViewer Carbide.c++ Extension</li>
+ <li>.NET Framework v2.0.50727 or newer is needed for Heap Analyser
+ functionalities</li>
+</ul>
+
+<h3><a name="compissues"></a>Compatibility issues</h3>
+<ul>
+ <li>N/A</li>
+</ul>
+
+<h3><a name="issues"></a>Known issues</h3>
+<ul>
+ <li>N/A</li>
+</ul>
+
+<h3>Version history</h3>
+
+<h5>Version 1.5.0 – 11th December 2009</h5>
+<ul>
+ <li>Feature: Added possibility to receive <b>Heap Dump</b>s when fetching
+ <b>SWMT</b> logs from device.</li>
+ <li>Feature: Added profiles for <b>SWMT Tracked Categories</b>.</li>
+ <li>Feature: Added the <b>Copy</b> context menu to graphs in <b>SWMT
+ Analyser</b>.</li>
+ <li>Feature: Added the <b>Copy</b> context menu to <b>SWMT Analyser</b>'s
+ data tables.</li>
+ <li>Change: PDF report layout improved in <b>SWMT Analyser</b>'s
+ <b>Analysis</b> tab.</li>
+ <li>Change: Graphs are drawn only when a thread/chunk is alive in <b>SWMT
+ Analyser</b>.</li>
+ <li>Change: <b>Close MemSpy Symbian Agent Between Cycles</b> has been moved
+ to <b>Custom Categories and Advanced Options</b> dialog.</li>
+ <li>Change: Harmonized <b>Advanced filter options...</b> drop-down list item
+ and <b>Customized options...</b> button to use similar wording; these are
+ now using <b>Custom filter</b> and <b>Set Custom filter</b>.</li>
+ <li>Change: Improved error handling in S60 MemSpy launching
+ functionality.</li>
+ <li>Fix: The heap compare functionality does not work if the workstation's
+ regional settings are set to other than English issue is now fixed.</li>
+</ul>
+
+<h5>Version 1.4.0 – 5th October 2009</h5>
+<ul>
+ <li>Feature: Added the checkbox <b>Close MemSpy Symbian agent between
+ cycles</b> to the <b>System Wide Memory Tracking Wizard</b> which makes
+ possible to get full SWMT snapshot for each data fetch cycle (instead of
+ getting only delta information).</li>
+ <li>Feature: Added the <b>Copy</b> context menu to <b>SWMT Analyser</b>'s
+ data tables in the <b>Graphs</b> tab.</li>
+ <li>Change: X-axis time units in SWMT graphs has been adjusted to match the
+ analyzed/shown time interval.</li>
+ <li>Change: The usage of an incompatible version of MemSpy Launcher is now
+ detected and an error-specific message is shown instead of a generic error
+ message.</li>
+ <li>Change: The <b>Zoom In</b>/<b>Zoom Out</b> context menu items are now
+ disabled in the SWMT graph context menu in case the maximum/minimum zoom
+ factor is achieved.</li>
+ <li>Fix: The Issue of showing just an empty dialog when launching of
+ HeapAnalyser.exe fails because of missing .NET framework is now fixed.</li>
+ <li>Fix: The <b>Tracked Categories</b> group should be disabled after the
+ first SWMT cycle is fetched from device issue is now fixed.</li>
+ <li>Fix: The data table contents is not updated when the filter string search
+ match type is changed between 'Contains' and 'Starts with' issue is now
+ fixed.</li>
+</ul>
+
+<h5>Version 1.3.0 – 19th August 2009</h5>
+<ul>
+ <li>Feature: Added option to save the <b>SWMT Analyser</b> graph as image
+ into a local file system.</li>
+ <li>Feature: Added option to generate PDF report for the issues found with
+ <b>SWMT Analyser</b>.</li>
+ <li>Feature: Added provision to view the <b>SWMT Analyser</b> graph for the
+ selected issues in the analysis tab itself.</li>
+ <li>Feature: Provided advanced filter options to filter the issues found with
+ <b>SWMT Analyser</b>.</li>
+ <li>Feature: Added support for analysing <b>SWMT Analyser</b> log files even
+ if they do not have consecutive cycle numbers. i.e., now the log files will
+ be ordered based on the time of the cycle. Note however that cycle1 must be
+ available for the analysis.</li>
+ <li>Feature: Added possibility to select tracked SWMT categories in <b>System
+ Wide Memory Tracking Wizard</b>.</li>
+</ul>
+
+<h5>Version 1.2.1 – 14th August 2009</h5>
+<ul>
+ <li>Fix: Heap Analyser export-to-excel crashed when using Microsoft Office
+ 2007 Excel issue is now fixed.</li>
+ <li>Fix: Maximum wait time for getting SWMT logs from device is too tight
+ issue is now fixed.</li>
+ <li>Fix: MemSpy S60 Launcher application installation fails because invalid
+ path name issue is now fixed.</li>
+</ul>
+
+<h5>Version 1.2.0 – 24th June 2009</h5>
+<ul>
+ <li>Feature: Added a new tab in the SWMT Analyser Editor View for
+ representing the exported data in a graphical format.</li>
+ <li>Feature: Added functionality to SWMT Analyser to analyse log data using
+ graphs</li>
+ <li>Feature: Added a new tab <b>Analysis</b> in the SWMT Analyser Editor view
+ for displaying issues found in analysis.</li>
+ <li>Change: Added thread list filtering based on the thread name into
+ <b>Import Heap Wizard</b> page.</li>
+</ul>
+
+<h5>Version 1.1.0 – 9th April 2009</h5>
+<ul>
+ <li>Feature: Added new tab for SWMT Analyser Editor View to represent the
+ exported data in graphical format.</li>
+ <li>Feature: Added functionality to SWMT Analyser to analyse log data using
+ graphs.</li>
+</ul>
+
+<h5>Version 1.0.0 – 16th February 2009</h5>
+
+<p>The first version.</p>
+
+<div id="footer">
+Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies). All rights
+reserved.<br>
+This component and the accompanying materials are made available <br>
+under the terms of "Eclipse Public License v1.0" <br>
+which accompanies this distribution and is available <br>
+at the URL <a
+href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
+<br>
+<br>
+Initial Contributors:<br>
+Nokia Corporation - initial contribution <br>
+<br>
+Contributors:<br>
+Description: </div>
+</body>
+</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/tasks/analyse_data_using_graphs.htm Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,38 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
+<title>Using SWMT Analyser</title>
+<link href="../../book.css" type="text/css" rel="stylesheet">
+</head>
+<body>
+
+<h2>Analysing data using graphs</h2>
+<p>SWMT Analyser represents the log data in a graphical format for the selected events and elements on the <b>Graphs</b> tab. The <b>Graphs</b> tab contains two tabs called <b>Events</b> and <b>Graphed items</b>.</p>
+
+<ul>
+ <li>
+ <p>The <b>Events</b> tab contains a list of events and a list of elements for each event. Events are grouped into categories such as <b>Chunks</b>, <b>Disks</b>, <b>Files</b>, <b>Heap</b>, <b>HPAS</b>, <b>RAM</b> and <b>System_info</b>. Select <b>All_events</b> to view all event types.</p>
+ <p>When you select an event from the list, a list of elements for the selected event will be displayed on the list on the right side of the window. The appropriate tab will be enabled and all other tabs will be disabled. Note that you can select elements from only one list at a time, and you can search elements by using the filter text. Each selected element is represented with an assigned colour on the graph.</p>
+ <p>Note that raw text data from the list on the right side of the window can be selected and copied to the clipboard by using the <b>Copy</b> context menu item.</p>
+ <p>At each event selection change, the element selections and graphs will be cleared. All the selected and plotted graphs will be moved to <b>Graphed items</b> tab.</p>
+ </li>
+ <li>
+ <p>The <b>Graphed items</b> tab contains a list of graph items that were previously drawn in the <b>Events</b> tab. The graphed items have four properties called <b>Colour</b>, <b>Element name</b>, <b>Event selected</b> and <b>Element type</b>. The graph will be plotted for the selected items, and all these items will be selected by default.</p>
+ </li>
+</ul>
+<p><img src="..\images\SWMT_Analyser_graph.png"></p>
+
+<h5>Related tasks</h5>
+<ul>
+<li><a href="view_issues_on_the_analysis_tab.htm">Viewing issues on the Analysis tab</a></li>
+<li><a href="understanding_excel_data.htm">Understanding the Excel data</a></li>
+<li><a href="generate_pdf_report.htm">Generating PDF reports</a></li>
+<li><a href="../reference/troubleshooting.htm#swmt_analyser_trb">Troubleshooting SWMT Analyser</a></li>
+<li><a href="connection_settings.htm">Configuring connection settings</a></li>
+</ul>
+
+<div id="footer">Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.
+License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.</div>
+</body>
+</html>
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/tasks/compare_two_heaps.htm Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,68 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+<head>
+ <meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
+ <title>Importing and comparing two heap dump files</title>
+ <link href="../../book.css" type="text/css" rel="stylesheet">
+</head>
+
+<body>
+<h2>Importing and comparing two heap dump files</h2>
+<ol>
+ <li>Click the <img src="../images/Memspy_16.png"> icon to start the MemSpy
+ Import Wizard.</li>
+ <li>Select to <b>Import heap and compare logs with Heap Analyser</b>, and
+ click <b>Next</b>.</li>
+ <li><p>Select whether to get the heap dumps <b>From File System</b> or
+ <b>From Device via TraceViewer</b>, and select the heap dump files to
+ import and compare.</p>
+ <ul>
+ <li>If you selected <b>From File System</b>, define the first heap dump
+ file location and then a heap, and click <b>Next</b>. Select the second
+ file and heap in the same way, and click <b>Next</b>. Note that you can
+ only compare two dumps from the same thread.</li>
+ <li>If you selected <b>From Device via TraceViewer</b>, click
+ <b>Load/Refresh Thread List</b> to get a thread list from the device,
+ select the first heap to compare, click <b>Get Selected Heap Now</b>,
+ and click <b>Next</b>. Similarly, select the second heap to compare,
+ and click <b>Next</b>.<br>
+ You can also filter the thread list by using the <b>Starts with</b> and
+ <b>Contains</b> selections.</li>
+ </ul>
+ <p>If this fails, click <b>Connection Settings</b> and configure connection
+ settings.</p>
+ </li>
+ <li>Define an output file location and name for the report file, and click
+ <b>Next</b>. The report is an MS Excel sheet (XLS) file.</li>
+ <li>Define the location of symbol and map files. You have to define at least
+ one symbol file. Defining map files is optional. For more information, see
+ <a href="../concepts/files.htm">Symbol and Map files</a>.</li>
+ <li>Click <b>Finish</b>. A MemSpy tab appears in the Carbide.c++ Tabbed View
+ Area with a file list populated.</li>
+ <li>A confirmation dialog opens, asking if you want to view the generated
+ file in Excel. See the figure below for an example of the outfile in
+ Excel.</li>
+</ol>
+<img src="../images/output_in_excel.png">
+<h5>Related references</h5>
+<ul>
+ <li><a href="../reference/HA_data_analysis.htm">Data analysis with Heap
+ Analyser</a></li>
+</ul>
+
+<h5>Related tasks</h5>
+<ul>
+ <li><a href="connection_settings.htm">Configuring connection settings</a></li>
+</ul>
+
+<h5>Related concepts</h5>
+<ul>
+ <li><a href="../concepts/files.htm">Symbol and Map files</a></li>
+</ul>
+
+<div id="footer">
+Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies). All rights
+reserved. License: <a
+href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.</div>
+</body>
+</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/tasks/connection_settings.htm Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,58 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
+<title>Configuring connection settings</title>
+<link href="../../book.css" type="text/css" rel="stylesheet"></head>
+<body>
+
+<h2>Configuring connection settings</h2>
+<p>If the connection to the target device fails, check and configure your connections settings:</p>
+<ol>
+<li>In the step 1 of the <b>MemSpy Import Wizard</b>, click <b>Connection
+Settings</b>. This takes you to the connection settings of the <b>TraceViewer Carbide.c++ Extension</b>.</li>
+<li>In <b>Use connection</b>, select an existing connection to use and click <b>OK</b>, or click <b>New...</b> to create a new connection or <b>Edit</b> to edit an existing one. Follow the next steps if you selected to create a new connection or to edit an existing one.</li>
+<li>In <b>Connection name</b>, enter a unique name for this connection.
+<p>In <b>Connection type</b>, select a connection method:</p>
+<ul>
+<li><b>PlatSim</b> if you are using a PlatSim connection between the PC and the target device.</li>
+<li><b>TCP/IP Musti</b> if you are using an XTI connection between the PC and the
+target device.</li>
+<li><b>USB</b> if you are using a USB cable connection between the PC and
+the target device.</li>
+</ul>
+<p>Click <b>Next</b>.
+<p><img src="..\images\connection_01.png"></p></li>
+
+<li><p>Modify the connection settings:</p>
+<ul>
+<li>For <b>PlatSim</b> and <b>TCP/IP Musti</b>: define the IP address to connect to and the OS to be used.
+<p><img src="..\images\connection_platsim.png"></li>
+
+<li><p>For <b>USB</b>: define the serial port used for USB connection on your PC (such as COM1) amd the OS to be used. To find out the port:</p>
+<ol type="1">
+<li>Connect your phone to the PC using a USB cable and the Nokia PC Suite
+application.</li>
+<li>(Optional) If you connect for the first time, install the necessary drivers
+to your phone.</li>
+<li>In <b>Windows</b>, check the correct serial port from the <b>Device Manager
+</b> in the <b>Control Panel</b>. Select <b>Ports (COM & LPT)</b>, and
+locate an item similar to <b>Series 60 Nokia S60 Phone USB (COMX)</b>, where
+X means the port to connect to.</li>
+</ol>
+<p><img src="..\images\connection_usb.png"></p>
+</li></ul></li>
+<li>Click <b>OK</b> to save and exit.</li>
+</ol>
+
+<h5>Related tasks</h5>
+<ul>
+<li><a href="view_heap.htm">Importing and analyzing heap dump files</a></li>
+<li><a href="compare_two_heaps.htm">Importing and comparing two heap dump files</a></li>
+<li><a href="view_swmt_log.htm">Importing and analyzing System Wide Memory Tracking log files</a></li>
+</ul>
+
+<div id="footer">Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.
+License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.</div>
+</body>
+</html>
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/tasks/generate_pdf_report.htm Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,38 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
+<title>Using SWMT Analyser</title>
+<link href="../../book.css" type="text/css" rel="stylesheet">
+</head>
+<body>
+
+<h2>Generating PDF reports</h2>
+<ol>
+<li>Go to the <b>Analysis</b> tab and click <b>Generate report</b>. This opens the <b>Create Report</b> dialog where you can select report options.</li>
+<li>Select the type of report to be created:
+<ul>
+<li>If you select to <b>Create report for the selected issues</b> option, the report will contain a graph for the selected issues, and the graph area in the analysis tab is captured and written to the PDF file. Expand the graph area to get a clear graph. If no issues are selected in the Analysis tab, an error message will be displayed explaining that you need to select some issues in the analysis view.</li>
+<li>If you select to <b>Create overview report</b>, a graph and only the overview of all the types of issues will be captured and written to the PDF file.</li>
+</ul>
+</li>
+<li>(Optional) Enter comments that will appear at the end of the PDF report.</li>
+<li>Enter a file path for the report file.</li>
+<li>Click <b>Finish</b>.
+<p><img src="..\images\SWMT_Analyser_PDF_options.png"></p>
+</li>
+</ol>
+
+<h5>Related tasks</h5>
+<ul>
+<li><a href="analyse_data_using_graphs.htm">Analysing data using graphs</a></li>
+<li><a href="view_issues_on_the_analysis_tab.htm">Viewing issues on the Analysis tab</a></li>
+<li><a href="understanding_excel_data.htm">Understanding the Excel data</a></li>
+<li><a href="../reference/troubleshooting.htm#swmt_analyser_trb">Troubleshooting SWMT Analyser</a></li>
+<li><a href="connection_settings.htm">Configuring connection settings</a></li>
+</ul>
+
+<div id="footer">Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.
+License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.</div>
+</body>
+</html>
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/tasks/tasks.htm Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,30 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
+<meta http-equiv="content-style-type" content="text/css">
+<title>Tasks</title>
+<link href="../../book.css" type="text/css" rel="StyleSheet"></head>
+<body>
+
+<h2>Tasks</h2>
+<p>The following tasks are available for the MemSpy Carbide.c++ Extension:</p>
+<ul>
+<li><a href="view_heap.htm">Importing and analyzing heap dump files</a></li>
+<li><a href="compare_two_heaps.htm">Importing and comparing two heap dump files</a></li>
+<li><a href="view_swmt_log.htm">Importing and analyzing System Wide Memory Tracking log files</a></li>
+<li><a href="use_swmt_analyser.htm">Using SWMT Analyser</a>
+<ul>
+<li><a href="analyse_data_using_graphs.htm">Analysing data using graphs</a></li>
+<li><a href="view_issues_on_the_analysis_tab.htm">Viewing issues on the Analysis tab</a></li>
+<li><a href="understanding_excel_data.htm">Understanding the Excel data</a></li>
+<li><a href="generate_pdf_report.htm">Generating PDF reports</a></li>
+</ul>
+</li>
+<li><a href="connection_settings.htm">Configuring connection settings</a></li>
+</ul>
+
+<div id="footer">Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.
+License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.</div>
+</body>
+</html>
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/tasks/understanding_excel_data.htm Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,161 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
+<title>Using SWMT Analyser</title>
+<link href="../../book.css" type="text/css" rel="stylesheet">
+</head>
+<body>
+
+<h2>Understanding the Excel data</h2>
+<p>Because reading and analyzing SWMT log files is difficult, SWMT Analyser tool can write the log file data to an Excel sheet in an appropriate manner so that you can easily understand and analyse the data.</p>
+<p>Excel contains different worksheets to represent various data such as heap-chunks, non heap-chunks, RAM and disk memory, and total heap size.</p>
+
+<p>The Excel tabs and the information displayed in them are explained in the following table.</p>
+
+<table width="615" border="1" cellspacing="1" cellpadding="2">
+<colgroup>
+<col width="149*">
+<col width="456*"></colgroup>
+<tbody>
+<tr>
+<th align="center">Tab</th>
+<th align="center">Description</th>
+</tr>
+
+<tr>
+<td><p>Overview</p></td>
+<td>
+<ul>
+<li>Cycle numbers, that is, numbers of selected log files to export, Time Period and Time Duration.</li>
+<li>Total delta of various fields like Heap Size, Free Cell Count, Allocated Cell Count, Free Space, Allocated Space, Slack Space, Total files, and Total P&S Handles for all the threads.</li>
+<li>Status of each thread in the last cycle and delta of various attributes for each thread.</li>
+</ul>
+<p><b>Note</b>: Stack size will be displayed for all threads which are alive.</p>
+</td>
+</tr>
+
+<tr>
+<td><p>RAM and Disk Memory</p></td>
+<td>
+<ul>
+<li>Specifies the amount of used RAM and disk memory of all drives in bytes and for each cycle in seconds.</li>
+<li>Shows how the used memory varies between RAM and other drives in each cycle.</li>
+</ul>
+</td>
+</tr>
+
+<tr>
+<td><p>Non-Heap Chunk Size</p></td>
+<td>
+<ul>
+<li>Specifies the non-heap chunk sizes for all the threads that contain heap in bytes and for each cycle in seconds.</li>
+<li>Shows the difference between the first and the last cycle value.</li>
+</ul>
+</td>
+</tr>
+
+<tr>
+<td><p>Global Chunk Size</p></td>
+<td>
+<ul>
+<li>Specifies the global chunk sizes for all the threads that contain heap in bytes and for each cycle in seconds.</li>
+<li>Shows the difference between the first and the last cycle value.</li>
+</ul>
+</td>
+</tr>
+
+<tr>
+<td><p>Total Heap Size</p></td>
+<td>
+<ul>
+<li>Specifies the heap sizes for each thread and for each cycle.</li>
+<li>Shows the difference between the first and the last cycle value.</p>
+</ul>
+</td>
+</tr>
+
+<tr>
+<td><p>Total Heap Allocated Space</p></td>
+<td>
+<ul>
+<li>Specifies the toal heap allocated space for each thread in bytes and for each cycle in seconds.</li>
+<li>Shows the difference between the first and the last cycle value.</li>
+</ul>
+</td>
+</tr>
+
+<tr>
+<td><p>Total Heap Free Space</p></td>
+<td>
+<ul>
+<li>Specifies the toal heap free space for each thread in bytes and for each cycle in seconds.</li>
+<li>Shows the difference between the first and the last cycle value.</li>
+</ul>
+</td>
+</tr>
+
+<tr>
+<td><p>Allocated Heap Cell Count</p></td>
+<td>
+<ul>
+<li>Specifies the allocated heap cell count for each thread in bytes and for each cycle in seconds.</li>
+<li>Shows the difference between the first and the last cycle value.</li>
+</ul>
+</td>
+</tr>
+
+<tr>
+<td><p>Free Heap Cell Count</p></td>
+<td>
+<ul>
+<li>Specifies the free heap cell count for each thread in bytes and for each cycle in seconds.</li>
+<li>Shows the difference between first and the last cycle value.</li>
+</ul>
+</td>
+</tr>
+
+<tr>
+<td><p>Slack Space Size</p></td>
+<td>
+<ul>
+<li>Specifies the free slack size for each thread in bytes and for each cycle in seconds.</li>
+<li>Shows the difference between first and the last cycle value.</li>
+</ul>
+</td>
+</tr>
+
+<tr>
+<td><p>Largest Allocated Cell Size in Heap</p></td>
+<td>
+<ul>
+<li>Specifies the largest allocated cell size in heap for each thread in bytes and for each cycle in seconds.</li>
+<li>Shows the difference between the first and the last cycle value.</li>
+</ul>
+</td>
+</tr>
+
+<tr>
+<td><p>Largest Free Cell Size in Heap</p></td>
+<td>
+<ul>
+<li>Specifies the largest free cell size in heap for each thread in bytes and for each cycle in seconds.</li>
+<li>Shows the difference between the first and the last cycle value.</li>
+</ul>
+</td>
+</tr>
+</table>
+
+<h5>Related tasks</h5>
+<ul>
+<li><a href="analyse_data_using_graphs.htm">Analysing data using graphs</a></li>
+<li><a href="view_issues_on_the_analysis_tab.htm">Viewing issues on the Analysis tab</a></li>
+<li><a href="generate_pdf_report.htm">Generating PDF reports</a></li>
+<li><a href="../reference/troubleshooting.htm#swmt_analyser_trb">Troubleshooting SWMT Analyser</a></li>
+<li><a href="connection_settings.htm">Configuring connection settings</a></li>
+</ul>
+
+<div id="footer">Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.
+License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.</div>
+</body>
+</html>
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/tasks/use_swmt_analyser.htm Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,59 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
+<title>Using SWMT Analyser</title>
+<link href="../../book.css" type="text/css" rel="stylesheet">
+</head>
+<body>
+
+<h2>Using SWMT Analyser</h2>
+<p>You can start the tool in any of the following ways:</p>
+<ul>
+<li>When you finish the <b>SWMT Wizard</b>, that is, when logs are imported to the MemSpy Carbide.c++ Extension from the MemSpy S60 application.</li>
+<li>In the MemSpy Carbide.c++ Extension, select the SWMT log files you want to analyse and click <b>Launch SWMT Analyser</b>, or right-click the SWMT log files and select <b>Analyse with SWMT Analyser</b>.</li>
+</ul>
+
+<h5>Preconditions</h5>
+<p>If more than one files are selected, check that the following requirements are met:</p>
+<ul>
+<li>All the selected log files must be generated on the same device.</li>
+<li><b>ROM Version</b> and <b>ROM Checksum</b> must be the same for all the selected log files.</li>
+<li>The cycle number of the first log file must be 1.</li>
+</ul>
+
+<p>SWMT Analyser will open in Carbide.c++ with two tabs called <b>Overview</b> and <b>Graphs</b>. In addition, an <b>Analysis</b> tab will be displayed only when there are issues found in the analysis. The Graphs tab will be displayed only when you have more than one file selected. When you have only one file selected, the Overview tab is displayed with the following information:</p>
+
+<ul>
+<li>Properties of the selected log files:
+ <ul>
+ <li>Number of cycles.</li>
+ <li>Time period (time of the first cycle and time of the last cycle).</li>
+ <li>Time duration (time difference between the first and the last cycle).</li>
+ </ul>
+</li>
+<li>ROM details of the log files:
+ <ul>
+ <li>ROM Checksum</li>
+ <li>ROM Version</li>
+ </ul>
+</li>
+<li>Export options. You can export the combined log file data into an Excel sheet. There are two options for exporting the log files. You can export either all selected log files or only the selected number of cycles.</li>
+<li>Analysis overview. The Overview page list the top 5 issues found in analysis.</li>
+</ul>
+
+
+<h5>Related tasks</h5>
+<ul>
+<li><a href="analyse_data_using_graphs.htm">Analysing data using graphs</a></li>
+<li><a href="view_issues_on_the_analysis_tab.htm">Viewing issues on the Analysis tab</a></li>
+<li><a href="understanding_excel_data.htm">Understanding the Excel data</a></li>
+<li><a href="generate_pdf_report.htm">Generating PDF reports</a></li>
+<li><a href="../reference/troubleshooting.htm#swmt_analyser_trb">Troubleshooting SWMT Analyser</a></li>
+<li><a href="connection_settings.htm">Configuring connection settings</a></li>
+</ul>
+
+<div id="footer">Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.
+License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.</div>
+</body>
+</html>
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/tasks/view_heap.htm Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,66 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+<head>
+ <meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
+ <title>Importing and analyzing heap dump files</title>
+ <link href="../../book.css" type="text/css" rel="stylesheet">
+</head>
+
+<body>
+<h2>Importing and analyzing heap dump files</h2>
+<ol>
+ <li>Click the <img src="../images/Memspy_16.png"> icon to start the MemSpy
+ Import Wizard.</li>
+ <li>Select to <b>Import heap and analyse log with Heap Analyser</b>, and
+ click <b>Next</b>.</li>
+ <li><p>Select whether to get the heap dumps <b>From File System</b> or
+ <b>From Device via TraceViewer</b>, select file(s) to import, and click
+ <b>Next</b>.</p>
+ <ul>
+ <li>If you selected <b>From File System</b>, define the heap dump file
+ location and then a heap.
+ <p><img src="..\images\import_heap_filesystem.png"></p>
+ </li>
+ <li>If you selected <b>From Device via TraceViewer</b>, click
+ <b>Load/Refresh Thread List</b> to get a thread list from the device,
+ select a heap, and click <b>Get Selected Heap Now</b>.<br>
+ You can also filter the thread list by using the <b>Starts with</b> and
+ <b>Contains</b> selections.
+ <p><img src="..\images\import_heap_device.png"></p>
+ </li>
+ </ul>
+ <p>If this fails, click <b>Connection Settings</b> and configure connection
+ settings.</p>
+ </li>
+ <li>Define the location of symbol and map files. You have to define at least
+ one symbol file. Defining map files is optional. For more information, see
+ <a href="../concepts/files.htm">Symbol and Map files</a>.</li>
+ <li>Click <b>Finish</b>. A <b>MemSpy</b> tab appears in the Carbide.c++
+ Tabbed View Area with a file list populated, and <b>Heap Analyser</b> is
+ launched if you selected to import only one file. For more information, see
+ <a href="../reference/HA_data_analysis.htm">Data analysis with Heap
+ Analyser</a>.</li>
+</ol>
+
+<h5>Related references</h5>
+<ul>
+ <li><a href="../reference/HA_data_analysis.htm">Data analysis with Heap
+ Analyser</a></li>
+</ul>
+
+<h5>Related tasks</h5>
+<ul>
+ <li><a href="connection_settings.htm">Configuring connection settings</a></li>
+</ul>
+
+<h5>Related concepts</h5>
+<ul>
+ <li><a href="../concepts/files.htm">Symbol and Map files</a></li>
+</ul>
+
+<div id="footer">
+Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies). All rights
+reserved. License: <a
+href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.</div>
+</body>
+</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/tasks/view_issues_on_the_analysis_tab.htm Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,45 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
+<title>Using SWMT Analyser</title>
+<link href="../../book.css" type="text/css" rel="stylesheet">
+</head>
+<body>
+
+<h2>Viewing issues on the Analysis tab</h2>
+<p>SWMT Analyser tool will analyse the data internally and list the issues found. The issues will be displayed in a tree format in three groups: <b>RAM and Disk Memory</b>, <b>Threads</b>, and <b>SystemData</b>.</p>
+<p>The tool internally analyses some events for items such as RAM, Disks, Threads, Chunks and etc. The analysis finds the growth of these events based on some calculations and uses that as the growing factor. All issues displayed in the Analysis tab would be sorted in the descending order of the growing factor by default.</p>
+<p>Each issue has four fields:</p>
+<ul>
+<li><b>Thread/Chunk/Item name</b>: Name of the item that the issue is related to.</li>
+<li><b>Event name</b>: Name of the event.</li>
+<li><b>Delta</b>: Difference between the first and the last cycle values.</li>
+<li><b>Severity</b>: Shows <b>red</b> if the growing factor is high, <b>yellow</b> if the growing factor is normal, and <b>green</b> if the growing factor is low. There is one dropdown to filter the issues based on its type like All, High, Normal, Low.
+Severity column can be sorted and issues will be ordered by their growing factor.</li>
+</ul>
+
+<p>A graph illustrating the checked issues will be automatically displayed on the top of the <b>Analysis</b> tab.</p>
+
+<p>You can filter the issues by using the <b>Severity dropdown</b> or Select <b>Custom filter</b> in the drop-down menu.<p>
+<p>You can save a graph as an image by using the <b>Save graph…</b> option in the context menu of the graph.</p>
+
+<p>Note that the <b>Overview</b> tab will also display the top 5 issues.</p>
+<p>If the thread dies and restarts again then that would be treated as separate instances, those thread instances will be respresented like 'thread_name(01)' and 'thread_name(02)'.
+For example, assume that there are 100 cycles and a thread starts at cycle 1 and dies at cycle 10. And the same thread starts again at cycle 20. Then this thread will be considered as having two instances.
+And those instances will be shown as 'thread_name(01)' and 'thread_name(02)' in Analysis tab. However, in Graphs tab this will be shown as single thread with 'thread_name'.</p>
+
+
+<h5>Related tasks</h5>
+<ul>
+<li><a href="analyse_data_using_graphs.htm">Analysing data using graphs</a></li>
+<li><a href="understanding_excel_data.htm">Understanding the Excel data</a></li>
+<li><a href="generate_pdf_report.htm">Generating PDF reports</a></li>
+<li><a href="../reference/troubleshooting.htm#swmt_analyser_trb">Troubleshooting SWMT Analyser</a></li>
+<li><a href="connection_settings.htm">Configuring connection settings</a></li>
+</ul>
+
+<div id="footer">Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.
+License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.</div>
+</body>
+</html>
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/tasks/view_swmt_log.htm Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,68 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+<head>
+ <meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
+ <title>Importing and analyzing System Wide Memory Tracking log files</title>
+ <link href="../../book.css" type="text/css" rel="stylesheet">
+</head>
+
+<body>
+<h2>Importing and analyzing System Wide Memory Tracking log files</h2>
+<ol>
+ <li>Click the <img src="../images/Memspy_16.png"> icon to start the MemSpy
+ Import Wizard.</li>
+ <li>Select to <b>Import System Wide Memory Tracking logs and analyse them
+ with SWMT Analyser</b>, and click <b>Next</b>.</li>
+ <li><p>Select whether to get the SWMT log files <b>From File System</b> or
+ <b>From Device via TraceViewer</b>.</p>
+ <p><img src="../images/import_swmt_1.png"></p>
+ <ul>
+ <li>If you selected <b>From File System</b>, define the SWMT log file
+ location and then a log file, and click <b>Next</b>.</li>
+ <li><p>If you selected <b>From Device via TraceViewer</b>, click <b>Get
+ SWMT Log Now</b> to get an SWMT log file from the device. After this
+ you can set a timer interval to get log files automatically at defined
+ intervals. Select the interval and click <b>Start Timer</b>. Note that
+ each log added with a timer or by clicking <b>Get SWMT Log Now</b>
+ contains only changes since the last received log. To stop the timer,
+ click <b>Stop Timer</b>. </p>
+ <p><img src="../images/import_swmt_2.png"></p>
+ </li>
+ <li>In <b>Tracked Categories and Advanced Options</b>, select a
+ predefined set of categories, or select <b>Custom Categories and
+ Advanced Options</b> and click <b>Edit</b>. In the <b>Advanded
+ Options</b>, you can select categories for SWMT logging and customise
+ the logging options.
+ <p>To stop the S60 MemSpy application in the target device between log
+ cycles, select the option <b>Close MemSpy Symbian Agent Between
+ Cycles</b>. Closing the agent between cycles makes it possible to get
+ full SWMT snapshot for each data fetch cycle (instead of getting only
+ delta information).</p>
+ <p>To include in the SWMT log cycle heap dumps for later analysis in
+ <b>Heap Analyser</b>, select the option <b>Get Heap Dumps for Threads
+ to Analyse with Heap Analyser</b>. </p>
+ To use a thread heap filter, type the filter name (such as <i>Akn</i>)
+ in the <b>Heap Data Thread Filter</b> field.
+ <p><img src="../images/import_swmt_3.png"></p>
+ </li>
+ </ul>
+ <p>If the connection to the target device fails, click <b>Connection
+ Settings</b> and configure connection settings.</p>
+ </li>
+ <li>Click <b>Finish</b>. A <b>MemSpy</b> tab appears in the Carbide.c++
+ Tabbed View Area with a file list populated. The received log files appear
+ in the file list.</li>
+</ol>
+
+<h5>Related tasks</h5>
+<ul>
+ <li><a href="use_swmt_analyser.htm">Using SWMT Analyser</a></li>
+ <li><a href="connection_settings.htm">Configuring connection settings</a></li>
+</ul>
+
+<div id="footer">
+Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies). All rights
+reserved. License: <a
+href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.</div>
+</body>
+</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/tocConcepts.xml Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?NLS TYPE="org.eclipse.help.toc"?>
+
+<toc label="Concepts">
+
+ <topic label="MemSpy S60 application" href="html/concepts/memspy.htm"/>
+ <topic label="Heap Dump" href="html/concepts/heap_dump.htm"/>
+ <topic label="System Wide Memory Tracking log" href="html/concepts/swmt_log.htm"/>
+ <topic label="Heap Analyser" href="html/concepts/heap_analyser.htm"/>
+ <topic label="SWMT Analyser" href="html/concepts/swmtanalyser.htm"/>
+ <topic label="Symbol and Map files" href="html/concepts/files.htm"/>
+
+</toc>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/tocGettingStarted.xml Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?NLS TYPE="org.eclipse.help.toc"?>
+
+<toc label="Getting started">
+
+ <topic label="Overview" href="html/gettingstarted/overview.htm"/>
+ <topic label="Prerequisites for use" href="html/gettingstarted/prerequisites.htm"/>
+ <topic label="Basic walk-through" href="html/gettingstarted/walk_through.htm"/>
+
+</toc>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/tocReference.xml Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?NLS TYPE="org.eclipse.help.toc"?>
+
+<toc label="Reference">
+
+ <topic label="Toolbar" href="html/reference/toolbar.htm"/>
+ <topic label="Troubleshooting" href="html/reference/troubleshooting.htm"/>
+ <topic href="html/reference/heap_analyser_overview.htm" label="Heap Analyser">
+ <topic href="html/reference/prerequisites_for_HA.htm" label="Prerequisites for Using Heap Analyser">
+ </topic>
+ <topic href="html/reference/HA_data_analysis.htm" label="Data analysis with Heap Analyser">
+ <topic href="html/reference/heap_view.htm" label="Heap View">
+ <topic href="html/reference/cell_type.htm" label="Cell Type">
+ </topic>
+ <topic href="html/reference/object_type.htm" label="Object type">
+ </topic>
+ <topic href="html/reference/parent_binary.htm" label="Parent Binary">
+ </topic>
+ <topic href="html/reference/cell_lenght.htm" label="Cell Length">
+ </topic>
+ <topic href="html/reference/isolation.htm" label="Isolation and Pervasiveness">
+ </topic>
+ </topic>
+ <topic href="html/reference/cell_list.htm" label="Cell List">
+ </topic>
+ <topic href="html/reference/objects.htm" label="Objects">
+ </topic>
+ <topic href="html/reference/relationships.htm" label="Relationships">
+ </topic>
+ <topic href="html/reference/cell_size.htm" label="Cell Size Distributions">
+ </topic>
+ <topic href="html/reference/graphs.htm" label="Graphs">
+ <topic href="html/reference/size_by_cell_index.htm" label="Size by Cell Index">
+ </topic>
+ <topic href="html/reference/free_cell_size.htm" label="Free Cell Size and Allocated Cell Size">
+ </topic>
+ <topic href="html/reference/cell_overhead.htm" label="Cell Overhead">
+ </topic>
+ <topic href="html/reference/associated_binary.htm" label="Associated Binary">
+ </topic>
+ </topic>
+ </topic>
+ <topic href="html/reference/saving_HA_reports.htm" label="Saving Heap Analyser reports">
+ </topic>
+ </topic>
+
+</toc>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/tocTasks.xml Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?NLS TYPE="org.eclipse.help.toc"?>
+
+<toc label="Tasks">
+ <topic label="Importing and analyzing heap dump files" href="html/tasks/view_heap.htm"/>
+ <topic label="Importing and comparing two heap dump files" href="html/tasks/compare_two_heaps.htm"/>
+ <topic label="Importing and analyzing System Wide Memory Tracking log files" href="html/tasks/view_swmt_log.htm"/>
+ <topic label="Using SWMT Analyser" href="html/tasks/use_swmt_analyser.htm">
+ <topic label="Analysing data using graphs" href="html/tasks/analyse_data_using_graphs.htm"/>
+ <topic label="Viewing issues on the Analysis tab" href="html/tasks/view_issues_on_the_analysis_tab.htm"/>
+ <topic label="Understanding the Excel data" href="html/tasks/understanding_excel_data.htm"/>
+ <topic label="Generating PDF reports" href="html/tasks/generate_pdf_report.htm"/>
+ </topic>
+ <topic label="Configuring connection settings" href="html/tasks/connection_settings.htm"/>
+</toc>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/tool.htm Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,32 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <title>Carbide.c++ User Guide</title>
+ <link href="../book.css" rel="stylesheet" type="text/css">
+ <style>
+ table, td, th { border: 0px none #FFF; }
+ </style>
+</head>
+
+<body background="images/background_carbide.jpg" >
+<p> </p>
+<table width="530" border="0" align="center" cellpadding="0" cellspacing="5" bgcolor="#FFFFFF" >
+ <tr>
+ <td width="215"><img src="images/about_cpp.png" width="225" height="200"></td>
+ <td width="294" valign="bottom"><p align="right"><b><img src="images/brandmark_cpp.gif" width="106" height="52"></b></p>
+ <p> </p>
+ <p> </p>
+ <p> </p>
+ <p class="titleSmall">Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. <br>
+ License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a></p>
+ </td>
+ </tr>
+ <tr>
+ <td colspan="2"><h1 align="center">MemSpy User Guide </h1>
+ <p align="center" class="titleSmall">Version 1.6.0; April, 2010</p></td>
+ </tr>
+</table>
+</body>
+</html>
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/html/toolTOC.xml Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?NLS TYPE="org.eclipse.help.toc"?>
+
+<toc label="MemSpy" link_to="../com.nokia.carbide.help.common/carbideHelpTOC.xml#anchorCarbideFeature">
+ <topic label="MemSpy" href="html/tool.htm">
+
+ <topic label="Release Notes" href="html/release_notes.htm"/>
+
+ <topic label="Getting started" href="html/gettingstarted/GS_index.htm">
+ <link toc="html/tocGettingStarted.xml"/>
+ </topic>
+
+ <topic label="Concepts" href="html/concepts/concepts.htm">
+ <link toc="html/tocConcepts.xml"/>
+ </topic>
+
+ <topic label="Tasks" href="html/tasks/tasks.htm">
+ <link toc="html/tocTasks.xml"/>
+ </topic>
+
+ <topic label="Reference" href="html/reference/references.htm">
+ <link toc="html/tocReference.xml"/>
+ </topic>
+
+ <topic label="Legal" href="html/legal.htm"/>
+
+ </topic>
+
+</toc>
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy.help/plugin.xml Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.0"?>
+<plugin>
+ <extension point="org.eclipse.help.toc">
+ <toc file="html/toolTOC.xml" primary="true"/>
+ <toc file="html/tocConcepts.xml" primary="false"/>
+ <toc file="html/tocGettingStarted.xml" primary="false"/>
+ <toc file="html/tocTasks.xml" primary="false"/>
+ <toc file="html/tocReference.xml" primary="false"/>
+ </extension>
+
+ <extension point="org.eclipse.help.index">
+ <index file="html/index.xml"/>
+ </extension>
+
+ <extension point="org.eclipse.help.contexts">
+ <contexts file="html/contexts.xml" plugin="com.nokia.s60tools.memspy.help"/>
+ </extension>
+</plugin>
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/.classpath Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/.settings/org.eclipse.jdt.core.prefs Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,7 @@
+#Tue Jul 07 08:43:46 EEST 2009
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/META-INF/MANIFEST.MF Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,22 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Carbide.c++ Extensions - MemSpy
+Bundle-SymbolicName: com.nokia.s60tools.memspy;singleton:=true
+Bundle-Version: 1.6.0
+Bundle-Activator: com.nokia.s60tools.memspy.plugin.MemSpyPlugin
+Bundle-Vendor: Nokia
+Require-Bundle: org.eclipse.ui,
+ org.eclipse.core.runtime,
+ com.nokia.s60tools.ui;bundle-version="1.5.0",
+ com.nokia.s60tools.sdk;bundle-version="1.2.1",
+ com.nokia.s60tools.heapanalyser;bundle-version="1.0.0",
+ com.nokia.s60tools.util;bundle-version="1.1.12",
+ com.nokia.s60tools.swmtanalyser;bundle-version="1.0.0",
+ org.eclipse.core.resources;bundle-version="3.4.1"
+Bundle-ActivationPolicy: lazy
+Export-Package: com.nokia.s60tools.memspy.export,
+ com.nokia.s60tools.memspy.interfaces;x-friends:="com.nokia.s60tools.memspy.tests",
+ com.nokia.s60tools.memspy.model;x-friends:="com.nokia.s60tools.memspy.tests"
+Import-Package: org.eclipse.core.filesystem,
+ org.eclipse.ui.ide
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/about.html Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,22 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
+<html>
+<head>
+<title>About</title>
+<meta http-equiv=Content-Type content="text/html; charset=ISO-8859-1">
+</head>
+<body lang="EN-US">
+<h2>About This Content</h2>
+
+<p>Dec 11, 2009</p>
+
+<h3>Copyright</h3>
+
+<p>
+
+<p>Copyright © 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.<br>
+License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.</p>
+
+<p>
+
+</body>
+</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/about.ini Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,45 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+#
+#
+#
+# about.ini
+# contains information about a feature
+# java.io.Properties file (ISO 8859-1 with "\" escapes)
+# "%key" are externalized strings defined in about.properties
+# This file does not need to be translated.
+
+# Property "aboutText" contains blurb for "About" dialog (translated)
+# This text is shown in Feature Details -dialog when feature is selected.
+aboutText=%productBlurb
+
+# Property "windowImage" contains path to window icon (16x16)
+# needed for primary features only
+
+# Property "featureImage" contains path to feature image (32x32)
+# Not using this in here because we do not want the icon to
+# show on about dialog. Only using aboutText above.
+#featureImage=icons/appdep.png
+
+# Property "aboutImage" contains path to product image (500x330 or 115x164)
+# needed for primary features only
+
+# Property "appName" contains name of the application (translated)
+# needed for primary features only
+
+# Property "welcomePerspective" contains the id of the perspective in which the
+# welcome page is to be opened.
+# optional
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/about.mappings Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,25 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+#
+#
+# about.mappings
+# contains fill-ins for about.properties
+# java.io.Properties file (ISO 8859-1 with "\" escapes)
+# This file does not need to be translated.
+
+# The following should contain the build version.
+# e.g. "0=20020612"
+0=0
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/about.properties Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,31 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+#
+# about.properties
+# contains externalized strings for about.ini
+# java.io.Properties file (ISO 8859-1 with "\" escapes)
+# fill-ins are supplied by about.mappings
+# This file should be translated.
+
+productBlurb=Carbide.c++ Extensions - MemSpy \n\
+\n\
+Version: 1.6\n\
+Build id: {0}\n\
+\n\
+\n\
+Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.\n\
+License: "http://www.eclipse.org/legal/epl-v10.html".\n\
+\n\
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/build.properties Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,13 @@
+javacSource=1.5
+javacTarget=1.5
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ plugin.xml,\
+ bin/,\
+ icons/,\
+ about.html,\
+ about.ini,\
+ about.mappings,\
+ about.properties
Binary file sysperfana/memspyext/com.nokia.s60tools.memspy/icons/Analyse_Heap.png has changed
Binary file sysperfana/memspyext/com.nokia.s60tools.memspy/icons/Compare_2_Heaps.png has changed
Binary file sysperfana/memspyext/com.nokia.s60tools.memspy/icons/Export_To_html.png has changed
Binary file sysperfana/memspyext/com.nokia.s60tools.memspy/icons/Heap_Dump_File.png has changed
Binary file sysperfana/memspyext/com.nokia.s60tools.memspy/icons/Launch_SWMT.png has changed
Binary file sysperfana/memspyext/com.nokia.s60tools.memspy/icons/Memspy_16.png has changed
Binary file sysperfana/memspyext/com.nokia.s60tools.memspy/icons/Memspy_45.png has changed
Binary file sysperfana/memspyext/com.nokia.s60tools.memspy/icons/SWMT_Log_File.png has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/plugin.xml Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.2"?>
+<plugin>
+ <extension
+ point="org.eclipse.ui.actionSets">
+ <actionSet
+ description="MemSpy"
+ id="com.nokia.s60tools.memspy.actionSet"
+ label="MemSpy"
+ visible="true">
+ <menu
+ id="com.nokia.carbide.cpp.ui.CarbideMenu"
+ label="&Carbide">
+ <separator
+ name="com.nokia.s60tools.ToolsMenuGroup">
+ </separator>
+ </menu>
+ <action
+ class="com.nokia.s60tools.memspy.ui.actions.ToolbarShortcutAction"
+ icon="icons/Memspy_16.png"
+ id="com.nokia.s60tools.memspy.ui.actions.ToolbarShortcutAction"
+ label="MemSpy"
+ menubarPath="com.nokia.carbide.cpp.ui.CarbideMenu/CarbideExtensions"
+ tooltip="MemSpy">
+ </action>
+
+ </actionSet>
+ </extension>
+
+
+ <extension
+ point="org.eclipse.ui.views">
+ <category
+ name="Carbide Extensions"
+ id="com.nokia.s60tools">
+ </category>
+ <view
+ name="MemSpy"
+ icon="icons/Memspy_16.png"
+ category="com.nokia.s60tools"
+ class="com.nokia.s60tools.memspy.ui.views.MemSpyMainView"
+ id="com.nokia.s60tools.memspy.ui.views.MemSpyMainView">
+ </view>
+ </extension>
+
+ <extension
+ id="com.nokia.s60tools.memspy.preferences"
+ point="org.eclipse.core.runtime.preferences">
+ <initializer
+ class="com.nokia.s60tools.memspy.preferences.MemSpyPreferenceInitializer">
+ </initializer>
+ </extension>
+
+ <extension-point id="traceprovider" name="Trace Data Provider" schema="schema/traceprovider.exsd"/>
+
+</plugin>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/schema/traceprovider.exsd Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,98 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="com.nokia.s60tools.memspy" xmlns="http://www.w3.org/2001/XMLSchema">
+<annotation>
+ <appInfo>
+ <meta.schema plugin="com.nokia.s60tools.memspy" id="traceprovider" name="MemSpy Trace Data Provider"/>
+ </appInfo>
+ <documentation>
+ This extension point can be used to provide trace data for MemSpy.
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <annotation>
+ <appInfo>
+ <meta.element />
+ </appInfo>
+ </annotation>
+ <complexType>
+ <sequence>
+ <element ref="traceprovider"/>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appInfo>
+ <meta.attribute translatable="true"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="traceprovider">
+ <complexType>
+ <attribute name="class" type="string" use="required">
+ <annotation>
+ <documentation>
+ Trace provider instance's class implementing ITraceProvider interface
+ </documentation>
+ <appInfo>
+ <meta.attribute kind="java" basedOn=":com.nokia.s60tools.memspy.export.ITraceProvider"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ <attribute name="providerName" type="string" use="required">
+ <annotation>
+ <documentation>
+ Name of the trace provider instance
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="since"/>
+ </appInfo>
+ <documentation>
+ 1.6.0
+ </documentation>
+ </annotation>
+
+
+
+
+ <annotation>
+ <appInfo>
+ <meta.section type="copyright"/>
+ </appInfo>
+ <documentation>
+ Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+All rights reserved.
+This component and the accompanying materials are made available
+under the terms of "Eclipse Public License v1.0"
+which accompanies this distribution, and is available
+at the URL "http://www.eclipse.org/legal/epl-v10.html".
+ </documentation>
+ </annotation>
+
+</schema>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/common/Product.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,45 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+package com.nokia.s60tools.memspy.common;
+
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+/**
+ * Class for getting properties from product.properties file, located in same package.
+ */
+public class Product {
+ private static final String BUNDLE_NAME = "com.nokia.s60tools.memspy.common.product"; //$NON-NLS-1$
+
+ private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle
+ .getBundle(BUNDLE_NAME);
+
+ private Product() {
+ }
+ /**
+ * @param key to product.properties -file
+ * @return a String from product.properties -file
+ */
+ public static String getString(String key) {
+ try {
+ return RESOURCE_BUNDLE.getString(key);
+ } catch (MissingResourceException e) {
+ return '!' + key + '!';
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/common/ProductInfoRegistry.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,59 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+package com.nokia.s60tools.memspy.common;
+
+/**
+ * This class stores product information such as product name,
+ * version, console view name etc.
+ * The idea is to have the product information in one place.
+ */
+public class ProductInfoRegistry {
+
+
+ /**
+ * @return Returns the Console window name.
+ */
+ public static String getConsoleWindowName() {
+ return getProductName() + " " + Product.getString("ProductInfoRegistry.Console_Window_Name_Postfix"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ /**
+ * @return Returns the Product name.
+ */
+ public static String getProductName() {
+ return Product.getString("ProductInfoRegistry.Product_Name"); //$NON-NLS-1$
+ }
+
+ /**
+ * @return Returns the images directory.
+ */
+ public static String getImagesDirectoryName() {
+ return Product.getString("ProductInfoRegistry.Images_Directory"); //$NON-NLS-1$
+ }
+
+ /**
+ * @return Returns the required MemSpy Launcher data version.
+ */
+ public static int getRequiredMemSpyLauncherDataVersion() {
+ String versionStr = Product.getString("ProductInfoRegistry.Required_MemSpyLauncherS60DataVersion"); //$NON-NLS-1$
+ int version = Integer.parseInt(versionStr);
+ return version;
+ }
+
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/common/product.properties Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,22 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+#
+
+ProductInfoRegistry.Product_Name=MemSpy
+ProductInfoRegistry.Console_Window_Name_Postfix=Console
+ProductInfoRegistry.Images_Directory=icons
+#For Required_MemSpyLauncherS60DataVersion use format 'n' e.g. =1
+ProductInfoRegistry.Required_MemSpyLauncherS60DataVersion=1
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/containers/SWMTLogInfo.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,97 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+
+package com.nokia.s60tools.memspy.containers;
+
+import java.util.Date;
+
+/**
+ *
+ * class SWMTLogInfo
+ * SWMTLogInfo class that contains info from one System Wide Memory Tracking log file or directory.
+ *
+ */
+public class SWMTLogInfo {
+
+ /**
+ * Enum about what type the log is
+ */
+ public enum SWMTLogType{ DEVICE, FILE };
+ private SWMTLogType type;
+
+ // Path of file
+ private String path;
+
+ // Date when file has been imported.
+ private Date date;
+
+ /**
+ * SWMTLogInfo.
+ * constructor.
+ */
+ public SWMTLogInfo(){
+ }
+
+
+ /**
+ * Get the log type
+ * @return type
+ */
+ public SWMTLogType getType() {
+ return type;
+ }
+ /**
+ * Set the log type
+ * @param type
+ */
+ public void setType(SWMTLogType type) {
+ this.type = type;
+ }
+ /**
+ * Get file path where log file is located
+ * @return path
+ */
+ public String getPath() {
+ return path;
+ }
+ /**
+ * Set file path where log file is located
+ * @param path
+ */
+ public void setPath(String path) {
+ this.path = path;
+ }
+ /**
+ * Get date when log file is created
+ * @return date
+ */
+ public Date getDate() {
+ return date;
+ }
+ /**
+ * Set date when log file is created
+ * @param date
+ */
+ public void setDate(Date date) {
+ this.date = date;
+ }
+
+
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/containers/ThreadInfo.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,191 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+
+package com.nokia.s60tools.memspy.containers;
+
+import java.util.Date;
+
+
+
+
+/**
+ * threadInfo
+ * thread info from one thread
+ */
+public class ThreadInfo {
+
+ /**
+ * Enum about what type the log is
+ */
+ public enum HeapDumpType{ DEVICE, FILE };
+ private HeapDumpType type;
+
+ // Name of the thread
+ private String threadName;
+
+ // ID-number of thread
+ private String threadID;
+
+ // File path of file
+ private String threadFilePath;
+
+ // Date when file has been imported.
+ private Date date;
+
+ // Status when heap from thread has been imported,
+ // or "-" if it has not been imported.
+ private String status;
+
+
+ /**
+ * ThreadInfo
+ * constructor
+ */
+ public ThreadInfo(){
+ threadName = "";
+ threadID = "";
+ threadFilePath = "";
+ date = new Date();
+ status = "-";
+ }
+
+ /**
+ * Private constructor for clone method. Status is set as empty.
+ * @param threadName Name of the thread
+ * @param threadID ID-number of thread
+ * @param threadFilePath File path of file
+ * @param date Date when file has been imported.
+ * @param type Enum of which type info.
+ */
+ private ThreadInfo(String threadName, String threadID, String threadFilePath, Date date, HeapDumpType type){
+ this.threadName = threadName;
+ this.threadID = threadID;
+ this.threadFilePath = threadFilePath;
+ this.date = date;
+ this.type = type;
+
+ this.status = "-";
+ }
+
+ /**
+ * Clone this object.
+ * @return New {@link ThreadInfo} object made from this ThreadInfo. Status is as default value.
+ */
+ public ThreadInfo clone() {
+ ThreadInfo clone = new ThreadInfo(threadName, threadID, threadFilePath, date, type);
+ return clone;
+ }
+
+
+ /**
+ * Get thread name
+ * @return thread name
+ */
+ public String getThreadName() {
+ return threadName;
+ }
+
+ /**
+ * Set thread name
+ * @param threadName
+ */
+ public void setThreadName(String threadName) {
+ this.threadName = threadName;
+ }
+
+ /**
+ * Get thread id
+ * @return thread id
+ */
+ public String getThreadID() {
+ return threadID;
+ }
+
+ /**
+ * Set thread id
+ * @param threadID
+ */
+ public void setThreadID(String threadID) {
+ this.threadID = threadID;
+ }
+
+ /**
+ * Get date
+ * @return date
+ */
+ public Date getDate() {
+ return date;
+ }
+
+ /**
+ * Set date when log was created
+ * @param date
+ */
+ public void setDate(Date date) {
+ this.date = date;
+ }
+
+ /**
+ * Get absolute file path where log file is located
+ * @return file path
+ */
+ public String getThreadFilePath() {
+ return threadFilePath;
+ }
+
+ /**
+ * Set absolute file path where log file is located
+ * @param threadFilePath
+ */
+ public void setThreadFilePath(String threadFilePath) {
+ this.threadFilePath = threadFilePath;
+ }
+
+ /**
+ * Get the type of this log
+ * @return type
+ */
+ public HeapDumpType getType() {
+ return type;
+ }
+
+ /**
+ * Set the type of this log
+ * @param type
+ */
+ public void setType(HeapDumpType type) {
+ this.type = type;
+ }
+
+ /**
+ * Get status
+ * @return status
+ */
+ public String getStatus() {
+ return status;
+ }
+
+ /**
+ * Set status
+ * @param status
+ */
+ public void setStatus(String status) {
+ this.status = status;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/export/ITraceClientNotificationsIf.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,41 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+package com.nokia.s60tools.memspy.export;
+
+/**
+ * Callback interface reporting trace related error information from trace source side.
+ */
+public interface ITraceClientNotificationsIf {
+
+ /**
+ * Notifies informative message from trace source.
+ * @param message message
+ */
+ public void notifyInformation(String message);
+
+ /**
+ * Notifies warning from trace source.
+ * @param message message
+ */
+ public void notifyWarning(String message);
+
+ /**
+ * Notifies error from trace source.
+ * @param message message
+ */
+ public void notifyError(String message);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/export/ITraceDataProcessor.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,29 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+package com.nokia.s60tools.memspy.export;
+
+/**
+ * Data processor interfacing for handling trace output data from device.
+ */
+public interface ITraceDataProcessor {
+
+ /**
+ * Handles a single trace data line.
+ * @param traceDataLine trade data line
+ */
+ public void processDataLine(String traceDataLine);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/export/ITraceProvider.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,86 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+package com.nokia.s60tools.memspy.export;
+
+/**
+ * Interface for binding external trace data providers for MemSpy.
+ * Only a single trace data provider instance at a time is supported.
+ * In case more that a single trace data providers are available
+ * the selection among them is undeterministic.
+ */
+public interface ITraceProvider {
+
+ /**
+ * Connects to trace source.
+ * @param traceClient Client to send information about changes in connectivity status and errors etc.
+ * @return <code>true</code> on success, otherwise <code>false</code>
+ */
+ public boolean connectTraceSource(ITraceClientNotificationsIf traceClient);
+
+ /**
+ * Disconnects to trace source.
+ */
+ public void disconnectTraceSource();
+
+ /**
+ * Sends current usage context-specific integer data to launcher.
+ * Integer data can contain values that can be expressed with 10 bytes
+ * i.e. only 10 lower bytes are taken into account when setting data.
+ * @param integerData integer data to be sent
+ * @return <code>false</code> if failed to send integer data, otherwise <code>true</code>
+ */
+ public boolean sendIntData(int integerData);
+
+ /**
+ * Sends current usage context-specific string message to launcher.
+ * @param stringData string data to send
+ * @return <code>true</code> on success, otherwise <code>false</code>
+ */
+ boolean sendStringData( String stringData);
+
+ /**
+ * Activates trace with given group ID.
+ * @param traceGroupID trace group ID
+ * @return <code>true</code> on success, otherwise <code>false</code>
+ */
+ boolean activateTrace(String traceGroupID);
+
+ /**
+ * Starts trace data listening
+ * @param dataProcessor data processor that further handles trace data at MemSpy side.
+ * @return <code>true</code> in case data processor is registered properly, otherwise <code>false</code>
+ */
+ public boolean startListenTraceData(ITraceDataProcessor dataProcessor);
+
+ /**
+ * Stops trace data listening
+ */
+ public void stopListenTraceData();
+
+ /**
+ * Gets preference page ID for the user trace source.
+ * @return preference page ID for the user trace source
+ */
+ public String getTraceSourcePreferencePageId();
+
+ /**
+ * Gets current connections display name.
+ * @return current connections display name
+ */
+ public String getDisplayNameForCurrentConnection();
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/files/HeapDumpFile.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,71 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+
+package com.nokia.s60tools.memspy.files;
+
+/**
+ * class HeapDumpFile.
+ * This class represents one Heap Dump.
+ */
+
+public class HeapDumpFile extends MemSpyFile {
+
+ /* path of XML-file*/
+ private String xmlPath;
+
+ /**
+ * HeapDumpFile.
+ * constructor
+ * @param filePath files path
+ * @param xmlPath xml files path
+ */
+ public HeapDumpFile( String filePath, String xmlPath ) {
+ super(filePath);
+ this.xmlPath = xmlPath;
+ }
+
+ /**
+ * Read's file variables from file that is defined in filePath
+ * @param folder folder where files are searched
+ * @return New HeapDumpFile
+ */
+ static public HeapDumpFile read( String folder ){
+
+ String xmlPath = findFile(folder, "xml");
+ String heapPath = findFile(folder, "txt");
+
+ if ( xmlPath == null || heapPath == null ){
+ return null;
+ }
+ HeapDumpFile heapFile = new HeapDumpFile( heapPath, xmlPath );
+ heapFile.doRead();
+ heapFile.setFileType("Heap Dump");
+ return heapFile;
+ }
+
+ /**
+ * Get XML file path
+ * @return path of xml-file
+ */
+ public String getXmlPath() {
+ return xmlPath;
+ }
+
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/files/MemSpyFile.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,209 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+package com.nokia.s60tools.memspy.files;
+
+import java.io.File;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+
+import org.xml.sax.helpers.DefaultHandler;
+
+import com.nokia.s60tools.memspy.model.MemSpyFileOperations;
+
+/**
+ * This is a base class for all MemSpy file types.
+ *
+ */
+public class MemSpyFile extends DefaultHandler{
+
+ /* files path */
+ protected String filePath = "";
+
+ /* files name */
+ protected String fileName = "";
+
+ /* time code from file */
+ protected String time = "";
+
+ /* date time code from file */
+ private Date dateTime = null;
+
+ /* type of the file */
+ protected String fileType = "";
+
+ /**
+ * MemSpyFile.
+ * constructor
+ * @param filePath Path of file
+ */
+ public MemSpyFile( String filePath ){
+ this.filePath = filePath;
+ }
+
+ /**
+ * doRead.
+ * Read's file variables from file that is defined in filePath
+ */
+ public void doRead(){
+ File f = new File(filePath);
+
+ //if file exists
+ if (f.exists() && f.isFile()) {
+
+ //Get date
+ Date date = new Date(f.lastModified());
+ setDateTime(date);
+ SimpleDateFormat formatter = new SimpleDateFormat ( MemSpyFileOperations.DATEFORMAT );
+ time = formatter.format(date);
+
+ // get File name
+ fileName = f.getName();
+ } else {
+ fileName = "";
+ }
+ }
+
+ /**
+ * findFiles.
+ * Finds all files with defined extension.
+ * @param folder folder where from files are searched
+ * @param extension file extension
+ * @return arraylist that contains found file names
+ */
+ protected static ArrayList<String> findFiles(String folder, String extension) {
+
+ ArrayList<String> retVal = new ArrayList<String>();
+ if ( !extension.startsWith(".") ){
+ extension = "." + extension;
+ }
+ File cFolder = new File(folder);
+ if (cFolder.isDirectory() && cFolder.exists()) {
+ File[] files = cFolder.listFiles();
+ if (files != null) {
+ for (int i = 0; i < files.length; i++) {
+ File file = files[i];
+ if (file.getName().endsWith(extension)) {
+ retVal.add( file.getAbsolutePath() );
+ }
+ }
+ }
+ }
+
+ return retVal;
+ }
+
+ /**
+ * findFile
+ * Finds file with defined extension.
+ * @param folder folder where file is searched
+ * @param extension file extension
+ * @return fileName
+ */
+ protected static String findFile(String folder, String extension) {
+ if ( !extension.startsWith(".") ){
+ extension = "." + extension;
+ }
+ File cFolder = new File(folder);
+ if (cFolder.isDirectory() && cFolder.exists()) {
+ File[] files = cFolder.listFiles();
+ if (files != null) {
+ for (int i = 0; i < files.length; i++) {
+ File file = files[i];
+ if (file.getName().endsWith(extension)) {
+ return file.getAbsolutePath();
+ }
+ }
+ }
+ }
+
+ return null;
+ }
+
+
+
+ /**
+ * Get file name
+ * @return file name
+ */
+ public String getFileName() {
+ return fileName;
+ }
+ /**
+ * Set file name
+ * @param fileName
+ */
+ public void setFileName(String fileName) {
+ this.fileName = fileName;
+ }
+ /**
+ * Get time when log file was created
+ * @return time
+ */
+ public String getTime() {
+ return time;
+ }
+ /**
+ * Set time when log file was created
+ * @param time
+ */
+ public void setTime(String time) {
+ this.time = time;
+ }
+ /**
+ * Get type of log file
+ * @return type
+ */
+ public String getFileType() {
+ return fileType;
+ }
+ /**
+ * Set type of log file
+ * @param fileType
+ */
+ public void setFileType(String fileType) {
+ this.fileType = fileType;
+ }
+
+ /**
+ * Get absolute file path
+ * @return file path
+ */
+ public String getFilePath() {
+ return filePath;
+ }
+
+ /**
+ * Set date time
+ * @param dateTime the dateTime to set
+ */
+ private void setDateTime(Date dateTime) {
+ this.dateTime = dateTime;
+ }
+
+ /**
+ * Get date time read from file
+ * @return the dateTime
+ */
+ public Date getDateTime() {
+ return dateTime;
+ }
+
+
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/files/SWMTFile.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,64 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+
+package com.nokia.s60tools.memspy.files;
+
+import java.util.ArrayList;
+
+/**
+ * class SWMTFile.
+ * This class represents one System Wide Memory Tracking log.
+ */
+
+public class SWMTFile extends MemSpyFile {
+
+
+
+ /**
+ * SWMTFile.
+ * Constructor
+ * @param filePath path of file
+ */
+ private SWMTFile(String filePath) {
+ super(filePath);
+ }
+
+ /**
+ * read.
+ * Reads searches swmt-file from given folder
+ * @param folder
+ * @return new SWMTFile
+ */
+ static public SWMTFile read( String folder ){
+
+ ArrayList<String> filePaths = findFiles(folder, "txt");
+ String xmlFile = findFile(folder, "xml");
+
+
+ if ( filePaths.size() == 0 || xmlFile != null ){
+ return null;
+ }
+ SWMTFile swmtFile = new SWMTFile( filePaths.get(0) );
+ swmtFile.doRead();
+ swmtFile.setFileType("SWMT-Log");
+ return swmtFile;
+ }
+
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/interfaces/IAnalyseHeapJobListener.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,44 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+
+package com.nokia.s60tools.memspy.interfaces;
+
+
+/**
+ * IAnalyseHeapJobListener.
+ * interface for Heap Analyser launcher listener.
+ */
+public interface IAnalyseHeapJobListener {
+
+ /**
+ * heapAnalyserFinished.
+ * Methot that is called when Heap Aanalyser finishes
+ * @param returnValue return value of Heap Analyser
+ */
+ public void heapAnalyserFinished(final int returnValue);
+
+ /**
+ * heapAnalyserFinished.
+ * Methot that is called when Heap Aanalyser finishes
+ * @param returnValue return value of Heap Analyser
+ * @param outputFilePath file path of output file
+ */
+ public void heapAnalyserFinished(final int returnValue, String outputFilePath);
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/interfaces/IMemSpyTraceListener.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,115 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+
+package com.nokia.s60tools.memspy.interfaces;
+
+import com.nokia.s60tools.memspy.containers.SWMTLogInfo;
+
+
+/**
+ * interface MemSpyTraceListener
+ * MemSpy trace listener interface that all MemSpy Trace listeners implement
+ *
+ */
+
+public interface IMemSpyTraceListener {
+
+ /**
+ * MemSpy Launchers actions.
+ */
+ public enum LauncherAction{
+ START_MEMSPY_THREAD_LIST,
+ GET_THREAD_LIST,
+ GET_HEAP_DUMP,
+ SWMT_UPDATE,
+ TIMED_SWMT_UPDATE
+ };
+
+ /**
+ * Launch error types.
+ */
+ public enum LauncherErrorType{
+
+ // The order of 4 first launcher error enumerators should not be changed because the error codes
+ // sent from launcher side must match enumerator ordinals.
+
+ GENERAL_LAUNCHER_ERROR, // This is general launcher error when there is no error code, only error description.
+ MEMSPY_NOT_RUNNING, // error code/ordinal=1, MemSpy is not running on device as should have been at the state of execution
+ MEMSPY_NOT_FOUND, // error code/ordinal=2, MemSpywas not installed on device
+ HEAP_NOT_FOUND, // error code/ordinal=3, Requested heap was not found from device
+
+ // Ordinals of other errors are not used as error codes at launcher side,
+ // and therefore they can be freely re-organized if needed.
+
+ HEAP_TYPE_WRONG, //
+ NO_ANSWER_FROM_DEVICE, //
+ DUMPED_TRACES, //
+ ACTIVATION, // Activation of MemSpy functionality via MemSpyLauncher has failed
+ FILE, //
+ CATEGORIES_NOT_SUPPORTED, // MemSpy installed on the device does not support setting of custom categories
+ TOO_OLD_MEMSPY_LAUNCHER_DATAVERSION // MemSpyLauncher installed supports only older data version
+ };
+
+ public final static String ERROR_HEAP_TYPE = "Selected heap's heap type is wrong(needs to be Symbian OS RHeap).";
+ public final static String ERROR_NO_RESPONSE = "MemSpy extension was unable to receive response from MemSpy S60-application.";
+ public final static String ERROR_POSSIBLE_REASONS = "Following reason(s) might be causing this problem: ";
+ public final static String ERROR_MEMSPY = "MemSpy Error";
+ public final static String ERROR_USB_TRACE_ENABLED = "\n- Trace data sending is not activated from your TraceSwitch application.";
+ public final static String ERROR_INSTALL_MEMSPY_LAUNCHER = "\n- MemSpy Launcher application is not installed in your device, or the installed launcher version is not up-to-date.\n\n(Installing MemSpy Launcher requires that Nokia PC suite is found from this computer and device is connected with usb-cable.) ";
+ public final static String ERROR_CONNECTION_BROKEN = "\n- Network connection between workstation and Musti box does not work properly.";
+ public final static String ERROR_MEMSPY_NOT_RUNNING = "MemSpy is not running on device. MemSpy will be restarted when you perform next operation. ";
+ public final static String ERROR_MEMSPY_NOT_FOUND = "MemSpy s60-application was not found from your device.";
+ public final static String ERROR_HEAP_NOT_FOUND = "Requested heap not found from device.( Perhaps thread has been terminated after loading of thread list, try reloading thread list. )";
+ public final static String ERROR_DUMPED_TRACES = "Received Heap Dump/SWMT-log is corrupted. See help for more information.";
+ public final static String ERROR_SWMT_NEEDS_RESET = "\n\nSince last imported log was missed, logs cannot be imported anymore before removing all logs.";
+ public final static String ERROR_ACTIVATION_NOT_SUCCESFUL = "Unable to send activation messages to TraceCore. Check connection settings.";
+ public final static String ERROR_FILE_OPERATIONS_NOT_SUCCESSFUL= "MemSpy was unable to write data to hard drive. Please make sure that MemSpy has sufficient user rights to Carbide's workspace.";
+ public final static String ERROR_CONNECTION = "Cannot connect to trace. Check connection settings.";
+ public final static String ERROR_CATEGORIES_NOT_SUPPORTED = "SWMT category setting feature is not supported by the MemSpy installed on the device and will be disabled for the rest of the session. Re-run the operation without category support.";
+ public final static String ERROR_TOO_OLD_MEMSPY_LAUNCHER_VERSION = "Installed launcher version is not up-to-date.\n\n(Installing MemSpy Launcher requires that Nokia PC suite is found from this computer and device is connected with usb-cable.";
+ public static final String ERROR_GENERAL_LAUNCHER_ERROR = "An unexpected error occurred in launcher component. See console log for detailed error information.";
+ public final static String ERROR_SEE_CONSOLE_LOG = "\n\nSee console log for additional error information.";
+ public final static String ERROR_LAUNCHER_ERROR_DETAILS = "S60 MemSpy Launcher error details: ";
+
+ /**
+ * deviceError.
+ * method that is called whenever errors occur.
+ * @param error error code
+ */
+ public void deviceError( LauncherErrorType error );
+
+ /**
+ * operationFinished.
+ * @param action which action was finished
+ */
+ public void operationFinished( LauncherAction action );
+
+ /**
+ * operationFinished.
+ * @param action which action was finished
+ * @param swmtLog that was received
+ */
+ public void operationFinished( LauncherAction action, SWMTLogInfo swmtLogInfo, boolean timerRunning );
+
+ /**
+ * startedReceivingSWMTLog.
+ * notification that is sent to interface when swmtReceiving is started.
+ */
+ public void startedReceivingSWMTLog();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/interfaces/INewMemSpyFilesObserver.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,43 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+
+package com.nokia.s60tools.memspy.interfaces;
+
+/**
+ * interface INewMemSpyFilesObserver.
+ * interface for MemSpy file observer.
+ *
+ */
+
+public interface INewMemSpyFilesObserver {
+
+ /**
+ * memSpyFilesUpdated.
+ * Method that is called when MemSPy file scan is complete.
+ */
+ public void memSpyFilesUpdated();
+
+ /**
+ * setOutputFilePath.
+ * sets output file's path
+ * @param outputFilePath new outputFilePath
+ */
+ public void setOutputFilePath(String outputFilePath);
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/model/AnalyseHeapJob.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,112 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+
+package com.nokia.s60tools.memspy.model;
+
+
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.Job;
+
+import com.nokia.s60tools.heapanalyser.interfaces.HeapAnalyserLauncher;
+import com.nokia.s60tools.memspy.interfaces.IAnalyseHeapJobListener;
+
+
+/**
+ * This class is responsible for launching Heap Analyser and waiting for it to stop.
+ * If Heap Analyser returns with and error code, error code is passed to job listener
+ */
+public class AnalyseHeapJob extends Job {
+
+
+ /* path of the configuration file */
+ private String configurationFile;
+
+ /* path of output file */
+ private String analyseOutputFile;
+
+ /* Job listener(MemSpy main view */
+ private IAnalyseHeapJobListener listener;
+
+ /**
+ * Constructor
+ * @param name Name of the process
+ * @param listener listener that is notified if errors occur.
+ */
+ public AnalyseHeapJob(String name, IAnalyseHeapJobListener listener ) {
+ super(name);
+ this.listener = listener;
+ analyseOutputFile = null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime.IProgressMonitor)
+ */
+ protected IStatus run(IProgressMonitor arg0) {
+
+ // launch heap analyser and wait for it to stop
+ int retVal = HeapAnalyserLauncher.launchHeapAnalyser( configurationFile );
+
+ // if output file was generated return it as attchment to main view.
+ if( analyseOutputFile != null ){
+ listener.heapAnalyserFinished( retVal, analyseOutputFile );
+ }
+ else{
+ listener.heapAnalyserFinished( retVal );
+ }
+
+ return Status.OK_STATUS;
+ }
+
+ /**
+ * Launches Heap Analyser.
+ */
+ public void refresh() {
+ try {
+ setPriority(Job.LONG);
+ setUser(false);
+ schedule(100);
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ } finally {
+ }
+ }
+
+
+ /**
+ * setter for configurationFiles path
+ * @param configurationFile
+ */
+ public void setConfigurationFile(String configurationFile) {
+ this.configurationFile = configurationFile;
+ }
+
+ /**
+ * setAnalyseOutputFile.
+ * @param analyseOutputFile file path of analyse file output.
+ */
+ public void setAnalyseOutputFile(String analyseOutputFile) {
+ this.analyseOutputFile = analyseOutputFile;
+ }
+
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/model/AnalyserXMLGenerator.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,574 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+
+package com.nokia.s60tools.memspy.model;
+
+import java.io.BufferedWriter;
+import java.io.IOException;
+
+/**
+ * AnalyserXMLGenerator.
+ * XML file generator that writes configuration XML-files for Heap Analyser and
+ * Crash Analyser based on parameters it has received.
+ *
+ * AnalyserXMLGenerator can be used for example like this:
+ * <PRE>
+ * AnalyserXMLGenerator generator = new AnalyserXMLGenerator(XMLGeneratorAction.ANALYSE_HEAP, "c:\\temp\\source.txt", "c:\\directory\\", null, null, "thread", "c:\\temp\\output.xls", null, null);
+ * File filename = new File("c:\\temp\\testxml.xml");
+ * BufferedWriter writer = null;
+ * try {
+ * writer = new BufferedWriter(new FileWriter(filename));
+ * generator.GenerateXML(writer);
+ * } catch (IOException e) {
+ * e.printStackTrace();
+ * }
+ * finally {
+ * try {
+ * if (writer != null) {
+ * writer.flush();
+ * writer.close();
+ * }
+ * }
+ * catch (IOException ex) {
+ * ex.printStackTrace();
+ * return false;
+ * }
+ * }
+ * </PRE>
+ */
+
+public class AnalyserXMLGenerator {
+
+ /**
+ * Enumeration for Heap Analyser actions
+ */
+ public enum XMLGeneratorAction {
+ ANALYSE_HEAP, COMPARE_HEAPS, ANALYSE_CRASH_SUMMARY, ANALYSE_CRASH_FULL
+ }
+
+ private XMLGeneratorAction XMLAction;
+ private String[] XMLSourceFile;
+ private String XMLSourceDirectory;
+ private String[] XMLDebugMetaDataFile = null;
+ private String XMLDebugMetaDataDirectory;
+ private String XMLThreadName;
+ private String XMLExtension;
+ private String XMLAnalyseFileOutput;
+ private String XMLAnalyseDirectoryOutput;
+
+
+ //Commands for XML
+
+ private final static String COMMAND_VIEWER = "Viewer";
+ private final static String COMMAND_COMPARE_HEAPS = "CompareTwoHeaps";
+ private final static String COMMAND_SUMMARY = "Summary";
+ private final static String COMMAND_FULL_ANALYSIS = "Full";
+
+ // XML-tags
+
+ private final static String CRASH_ANALYSER_START = "<crash_analysis>";
+ private final static String CRASH_ANALYSER_END = "</crash_analysis>";
+
+ private final static String HEAP_ANALYSER_START = "<heap_analysis>";
+ private final static String HEAP_ANALYSER_END = "</heap_analysis>";
+
+ private final static String SOURCE_START = " <category name=\"source\">";
+ private final static String SOURCE_END = " </category>";
+
+ private final static String DEBUG_META_DATA_START = " <category name=\"debug_meta_data\">";
+ private final static String DEBUG_META_DATA_END = " </category>";
+
+ private final static String FILE_START = " <file name=\"";
+ private final static String FILE_END = "\"/>";
+
+ private final static String DIRECTORY_START = " <directory name=\"";
+ private final static String DIRECTORY_END = "\"/>";
+
+ private final static String PARAMETERS_START = " <category name=\"parameters\">";
+ private final static String PARAMETERS_END = " </category>";
+
+ private final static String THREAD_START = " <command name=\"thread\">";
+ private final static String THREAD_END = "</command>";
+
+ private final static String COMMAND_START = " <command name=\"analysis_type\">";
+ private final static String COMMAND_END = "</command>";
+
+ private final static String OUTPUT_START = " <category name=\"output\">";
+ private final static String OUTPUT_END = " </category>";
+
+ private final static String EXTENSION_START = " <extension name=\"";
+ private final static String EXTENSION_END = "\"/>";
+
+
+
+ /**
+ * XMLGenerator()
+ * Constructor
+ */
+ public AnalyserXMLGenerator() {
+
+ XMLAction = null;
+ XMLSourceFile = null;
+ XMLSourceDirectory = null;
+ XMLDebugMetaDataFile = null;
+ XMLDebugMetaDataDirectory = null;
+ XMLThreadName = null;
+ XMLAnalyseFileOutput = null;
+ XMLExtension = null;
+
+ }
+
+ /**
+ * AnalyserXMLGenerator()
+ * Constructor for XMLGenerator
+ *
+ * @param action
+ * @param sourceFile file that is added into <source> -section under <file> -tag
+ * @param sourceDirectory directory that is added into <source> -section under <Directory> -tag
+ * @param debugMetaDataFile file that is added into <debug_meta_data> -section under <file> -tag
+ * @param debugMetaDataDirectory directory that is added into <debug_meta_data> -section under <Directory> -tag
+ * @param threadName thread name that is added into <parameters> -section under <thread> -tag
+ * @param extension extension text that is is added into <parameters> -section under <extension> -tag
+ * @param analyseFileOutput file name that is added into <output> -section under <file> -tag
+ * @param analyseDirectoryOutput file name that is added into <output> -section under <directory> -tag
+ */
+
+ public AnalyserXMLGenerator( XMLGeneratorAction action,
+ String[] sourceFile,
+ String sourceDirectory,
+ String[] debugMetaDataFile,
+ String debugMetaDataDirectory,
+ String threadName,
+ String analyseFileOutput,
+ String analyseDirectoryOutput,
+ String extension ) {
+
+ XMLAction = action;
+ XMLSourceFile = sourceFile;
+ XMLSourceDirectory = sourceDirectory;
+ XMLDebugMetaDataFile = debugMetaDataFile;
+ XMLDebugMetaDataDirectory = debugMetaDataDirectory;
+ XMLThreadName = threadName;
+ XMLAnalyseFileOutput = analyseFileOutput;
+ XMLAnalyseDirectoryOutput = analyseDirectoryOutput;
+ XMLExtension = extension;
+ }
+
+ /**
+ * GenerateXML()
+ * Writes XML file.
+ * @param writer BufferedWriter stream where XML is written.
+ * @throws IOException if something goes when writing to stream
+ */
+
+ public void GenerateXML( BufferedWriter writer ) throws IOException{
+
+
+ if( XMLAction != null ) {
+ // Begin XML
+ switch( XMLAction ){
+ case ANALYSE_CRASH_FULL:
+ case ANALYSE_CRASH_SUMMARY:
+ writer.write(CRASH_ANALYSER_START);
+ break;
+ case ANALYSE_HEAP:
+ case COMPARE_HEAPS:
+ writer.write(HEAP_ANALYSER_START);
+ break;
+ default:
+ break;
+ }
+
+ writer.newLine();
+ writer.newLine();
+ }
+ // Write Sources
+ this.writeSource(writer);
+
+
+ // Write debug meta data
+ this.writeDebugMetaData(writer);
+
+ // Write parameters
+ this.writeParameters(writer);
+
+ // Write output location
+ this.writeOutput(writer);
+
+ // End XML
+ if( XMLAction != null ) {
+ switch(XMLAction){
+ case ANALYSE_CRASH_SUMMARY:
+ case ANALYSE_CRASH_FULL:
+ writer.write(CRASH_ANALYSER_END);
+ break;
+ case ANALYSE_HEAP:
+ case COMPARE_HEAPS:
+ writer.write(HEAP_ANALYSER_END);
+ break;
+ default:
+ break;
+ }
+ writer.newLine();
+ }
+
+
+ }
+
+ /**
+ * writeSource()
+ * Writes source - parameters
+ * @param writer BufferedWriter stream where XML is written.
+ */
+ private void writeSource( BufferedWriter writer ) throws IOException{
+
+
+ // Start Source definition
+ writer.write(SOURCE_START);
+ writer.newLine();
+
+ if( XMLSourceFile != null ){
+ // File Definition
+ for(int i = 0; i < XMLSourceFile.length; i++ ){
+ writer.write( FILE_START );
+ writer.write( XMLSourceFile[i] );
+ writer.write( FILE_END );
+ writer.newLine();
+ }
+ }
+ if( XMLSourceDirectory != null ) {
+ writer.write( DIRECTORY_START );
+ writer.write( XMLSourceDirectory );
+ writer.write( DIRECTORY_END );
+ writer.newLine();
+ }
+
+ // End Source definition
+ writer.write(SOURCE_END);
+ writer.newLine();
+ writer.newLine();
+ }
+
+ /**
+ * writeDebugMetaData()
+ * Writes debug_meta_data - parameters
+ * @param writer BufferedWriter stream where XML is written.
+ * @throws IOException
+ */
+ private void writeDebugMetaData( BufferedWriter writer ) throws IOException{
+ // Start Debug meta data definition
+
+ if( XMLDebugMetaDataFile != null ||
+ XMLDebugMetaDataDirectory != null ){
+
+ writer.write(DEBUG_META_DATA_START);
+ writer.newLine();
+
+ // File Definition
+ if( XMLDebugMetaDataFile != null ){
+ for(int i = 0; i < XMLDebugMetaDataFile.length; i++ ){
+ writer.write( FILE_START );
+ writer.write( XMLDebugMetaDataFile[i] );
+ writer.write( FILE_END );
+ writer.newLine();
+ }
+ }
+ if( XMLDebugMetaDataDirectory != null ) {
+ writer.write( DIRECTORY_START );
+ writer.write( XMLDebugMetaDataDirectory );
+ writer.write( DIRECTORY_END );
+ writer.newLine();
+ }
+
+ // End Debug meta data definition
+ writer.write(DEBUG_META_DATA_END);
+ writer.newLine();
+ writer.newLine();
+ }
+ }
+
+
+
+ /**
+ * writeParameters(
+ * Writes parameters - parameters
+ * @param writer BufferedWriter stream where XML is written.
+ * @throws IOException
+ */
+
+ private void writeParameters( BufferedWriter writer ) throws IOException {
+
+ if( XMLThreadName != null || XMLAction != null || XMLExtension != null){
+
+
+ // Start parameter definition
+ writer.write(PARAMETERS_START);
+ writer.newLine();
+
+
+ if( XMLThreadName != null ){
+ // Add thread info
+ writer.write( THREAD_START );
+ writer.write( XMLThreadName );
+ writer.write( THREAD_END );
+ writer.newLine();
+
+ }
+
+ if( XMLAction != null ){
+ // Command
+
+ writer.write(COMMAND_START);
+
+ // Begin XML
+ switch(XMLAction){
+ case ANALYSE_CRASH_SUMMARY:
+ writer.write(COMMAND_SUMMARY);
+ break;
+ case ANALYSE_CRASH_FULL:
+ writer.write(COMMAND_FULL_ANALYSIS);
+ break;
+ case ANALYSE_HEAP:
+ writer.write(COMMAND_VIEWER);
+ break;
+ case COMPARE_HEAPS:
+ writer.write(COMMAND_COMPARE_HEAPS);
+ break;
+ default:
+ break;
+ }
+ writer.write(COMMAND_END);
+ writer.newLine();
+ }
+
+ if( XMLExtension != null ){
+ // extension
+ writer.write( EXTENSION_START );
+ writer.write( XMLExtension );
+ writer.write( EXTENSION_END );
+ writer.newLine();
+ }
+
+
+
+ // End parameter definition
+ writer.write(PARAMETERS_END);
+ writer.newLine();
+ writer.newLine();
+ }
+
+
+ }
+
+
+ /**
+ * Writes output - parameters
+ * @param writer BufferedWriter stream where XML is written.
+ * @throws IOException
+ */
+ private void writeOutput( BufferedWriter writer ) throws IOException{
+
+ if( XMLAnalyseFileOutput != null || XMLAnalyseDirectoryOutput != null ){
+ writer.write(OUTPUT_START);
+ writer.newLine();
+
+ // Output file
+ if( XMLAnalyseFileOutput != null ){
+ writer.write(FILE_START);
+ writer.write(XMLAnalyseFileOutput);
+ writer.write(FILE_END);
+ writer.newLine();
+ }
+ // Output directory
+ if( XMLAnalyseDirectoryOutput != null ) {
+ writer.write(DIRECTORY_START);
+ writer.write(XMLAnalyseDirectoryOutput);
+ writer.write(DIRECTORY_END);
+ writer.newLine();
+ }
+
+ writer.write(OUTPUT_END);
+ writer.newLine();
+ writer.newLine();
+
+
+ }
+ }
+
+
+
+
+
+ /**
+ * Get file name parameters
+ * @return XMLSourceFile
+ */
+ public String[] getXMLSourceFile() {
+ return XMLSourceFile;
+ }
+
+ /**
+ * Set file name parameters
+ * @param sourceFile the XMLSourceFile to set
+ */
+ public void setXMLSourceFile(String[] sourceFile) {
+ XMLSourceFile = sourceFile;
+ }
+
+ /**
+ * Get symbol or map files
+ * @return XMLDebugMetaDataFile
+ */
+ public String[] getXMLDebugMetaDataFile() {
+ return XMLDebugMetaDataFile;
+ }
+
+ /**
+ * Set symbol or map files
+ * @param XMLDebugMetaDataFile to set
+ */
+ public void setXMLDebugMetaDataFile(String[] debugMetaDataFile) {
+ XMLDebugMetaDataFile = debugMetaDataFile;
+ }
+
+ /**
+ * Check if XMLDebugMetaDataFile has been set
+ * @return XMLDebugMetaDataFile
+ */
+ public boolean hasXMLDebugMetaDataFile() {
+ boolean isXMLSet = XMLDebugMetaDataFile!=null;
+ if(isXMLSet){
+ isXMLSet = XMLDebugMetaDataFile.length > 0;
+ }
+ return isXMLSet;
+ }
+
+ /**
+ * Get thread parameter
+ * @return XMLThreadName
+ */
+ public String getXMLThreadName() {
+ return XMLThreadName;
+ }
+
+ /**
+ * Set thread parameter
+ * @param XMLThreadName to set
+ */
+ public void setXMLThreadName(String threadName) {
+ XMLThreadName = threadName;
+ }
+
+ /**
+ * Get analyse output file
+ * @return XMLAnalyseFileOutput
+ */
+ public String getXMLAnalyseFileOutput() {
+ return XMLAnalyseFileOutput;
+ }
+
+ /**
+ * Set analyse output file
+ * @param XMLAnalyseFileOutput to set
+ */
+ public void setXMLAnalyseFileOutput(String analysefileOutput) {
+ XMLAnalyseFileOutput = analysefileOutput;
+ }
+
+ /**
+ * Get current action
+ * @return XMLAction
+ */
+ public XMLGeneratorAction getXMLAction() {
+ return XMLAction;
+ }
+
+ /**
+ * Set action
+ * @param action the XMLGeneratorAction to set
+ */
+ public void setXMLAction(XMLGeneratorAction action) {
+ XMLAction = action;
+ }
+
+ /**
+ * Get directory parameter
+ * @return XMLSourceDirectory
+ */
+ public String getXMLSourceDirectory() {
+ return XMLSourceDirectory;
+ }
+
+ /**
+ * Set directory parameter
+ * @param XMLSourceDirectory to set
+ */
+ public void setXMLSourceDirectory(String sourceDirectory) {
+ XMLSourceDirectory = sourceDirectory;
+ }
+
+ /**
+ * Get debug metadata directory. In UI it's shown as Map file folder.
+ * @return XMLDebugMetaDataDirectory
+ */
+ public String getXMLDebugMetaDataDirectory() {
+ return XMLDebugMetaDataDirectory;
+ }
+
+ /**
+ * Set debug metadata directory. In UI it's shown as Map file folder.
+ * @param XMLDebugMetaDataDirectory to set
+ */
+ public void setXMLDebugMetaDataDirectory(String debugMetaDataDirectory) {
+ XMLDebugMetaDataDirectory = debugMetaDataDirectory;
+ }
+
+ /**
+ * Get extension parameter
+ * @return XMLExtension
+ */
+ public String getXMLExtension() {
+ return XMLExtension;
+ }
+
+ /**
+ * Set extension parameter
+ * @param extension the XMLExtension to set
+ */
+ public void setXMLExtension(String extension) {
+ XMLExtension = extension;
+ }
+
+ /**
+ * Get output directory
+ * @return XMLAnalyseDirectoryOutput
+ */
+ public String getXMLAnalyseDirectoryOutput() {
+ return XMLAnalyseDirectoryOutput;
+ }
+
+ /**
+ * Set output directory
+ * @param analyseDirectoryOutput the XMLAnalyseDirectoryOutput to set
+ */
+ public void setXMLAnalyseDirectoryOutput(String analyseDirectoryOutput) {
+ XMLAnalyseDirectoryOutput = analyseDirectoryOutput;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/model/AnalyserXMLParser.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,140 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+
+package com.nokia.s60tools.memspy.model;
+
+import java.io.BufferedReader;
+import java.util.ArrayList;
+
+
+/**
+ * class AnalyserXMLParser.
+ * class that parses symbol and thread name information from debug configuration file.
+ *
+ */
+
+public class AnalyserXMLParser {
+
+ static final String DEBUG_META_DATA_START_TAG = "<category name=\"debug_meta_data\">";
+ static final String DEBUG_META_DATA_END_TAG = "</category>";
+ static final String THREAD_TAG = "<command name=\"thread\">";
+ static final String FILE_NAME = "file name";
+ static final String DIRECTORY_NAME = "directory name";
+
+
+ /**
+ * Add wanted lines from given input to XML generator and returns the generator.
+ * @param reader
+ * @return XML generator
+ */
+ public static AnalyserXMLGenerator parseXML( BufferedReader reader ){
+ AnalyserXMLGenerator retVal = new AnalyserXMLGenerator();
+
+ boolean readingDebugMetaData = false;
+ ArrayList<String> debugMetaDataFiles = new ArrayList<String>();
+ String debugMetaDataDirectory = null;
+ String threadName = "";
+
+ try{
+ String line = "";
+
+ // Go thru file in loop and search for lines that contain debugMetaData -text.
+ // If text is found, save meta data file information into AnalyserXMLGenerator-object.
+
+ while( reader.ready() ){
+
+ line = reader.readLine();
+
+ if( line == null){
+ break;
+ }
+
+ // Search for debug meta data start and end tags.
+ if( line.contains(DEBUG_META_DATA_START_TAG) ){
+ readingDebugMetaData = true;
+ }
+ else if( line.contains(DEBUG_META_DATA_END_TAG) ){
+ readingDebugMetaData = false;
+ }
+
+ // if between debug meta data start and end tags, search for debug meta data info.
+ if( readingDebugMetaData ){
+ if(line.contains(FILE_NAME)){
+ debugMetaDataFiles.add( getMetaDataInfo(line) );
+ }
+ if(line.contains(DIRECTORY_NAME)){
+ debugMetaDataDirectory = getMetaDataInfo(line);
+ }
+ }
+
+ // search for thread name tag.
+ if( line.contains(THREAD_TAG) ){
+ threadName = getThreadName(line);
+ }
+ }
+
+ }
+ catch (Exception e){
+ e.printStackTrace();
+ return null;
+ }
+
+ if(threadName.equals("") ){
+ return null;
+ }
+
+ // check that thread name and at least one symbol file was found.
+ if( debugMetaDataFiles.size() != 0 ){
+ // set found data into AnalyserXMLGenerator-object.
+ retVal.setXMLDebugMetaDataFile(debugMetaDataFiles.toArray(new String [debugMetaDataFiles.size()]));
+ }
+
+ if( !threadName.equals("")){
+ retVal.setXMLDebugMetaDataDirectory(debugMetaDataDirectory);
+ }
+ retVal.setXMLThreadName(threadName);
+
+ return retVal;
+
+ }
+
+ /**
+ * getMetaDataInfo.
+ * @param line String that is parsed
+ * @return string between quotation marks
+ */
+ private static String getMetaDataInfo( String line ) {
+ int firstIndex = line.indexOf("\"") + 1 ;
+ int secondIndex = line.indexOf(("\""), firstIndex );
+ return line.substring(firstIndex, secondIndex);
+ }
+
+
+ /**
+ * getThreadName.
+ * @param line String that is parsed
+ * @return string between threas tags
+ */
+ private static String getThreadName(String line){
+ int firstIndex = line.indexOf("=\"thread\">") + 10;
+ int secondIndex = line.indexOf("</command>");
+ return line.substring(firstIndex, secondIndex);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/model/CategoryProfile.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,115 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+package com.nokia.s60tools.memspy.model;
+
+import java.util.Iterator;
+import java.util.List;
+
+import com.nokia.s60tools.memspy.ui.dialogs.SWMTCategoryEntry;
+
+/**
+ * Class for one Category Profile
+ */
+public class CategoryProfile {
+
+ private String name;
+
+ private int categories = 0;
+
+ /**
+ * Create a new Category Profile
+ * @param name Profile name
+ */
+ public CategoryProfile(String name) {
+ this.setName(name);
+ }
+
+ /**
+ *
+ * @param name Profile name
+ * @param categories Categories for profile
+ */
+ public CategoryProfile(String name, int categories) {
+ this.categories = categories;
+ this.setName(name);
+ }
+
+ /**
+ * Get profile name
+ * @return the name
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Set profile name
+ * @param name the name to set
+ */
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ /**
+ * Add one or more category to categories
+ * @param categories the categories to set
+ */
+ public void addCategory(int category) {
+ categories = categories & category;
+ }
+
+ /**
+ * Get categories
+ * @return the categories
+ */
+ public int getCategories() {
+ return categories;
+ }
+
+ /**
+ * Get all SWMT categories for this profile
+ * @return the categories
+ */
+ public List<SWMTCategoryEntry> getCategoryEntrys() {
+
+ SWMTCategorys cat = SWMTCategorys.getInstance();
+ List<SWMTCategoryEntry> categoryEntries = cat.getCategoryEntries(getCategories());
+
+ return categoryEntries;
+ }
+
+ /**
+ * Get names of the Categories added to this profile.
+ * @return list of Category names
+ */
+ public String [] getCategoryEntryNames(){
+ List<SWMTCategoryEntry> categoryEntrys = getCategoryEntrys();
+ if(categoryEntrys.isEmpty()){
+ return new String[0];
+ }
+ String[] names = new String[categoryEntrys.size()];
+ int i = 0;
+ for (Iterator<SWMTCategoryEntry> iterator = categoryEntrys.iterator(); iterator.hasNext();) {
+ SWMTCategoryEntry entry = (SWMTCategoryEntry) iterator
+ .next();
+ names[i] = entry.getCategoryName();
+ i++;
+ }
+ return names;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/model/ImportEngine.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,391 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+
+package com.nokia.s60tools.memspy.model;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.ArrayList;
+
+import com.nokia.s60tools.memspy.containers.SWMTLogInfo;
+import com.nokia.s60tools.memspy.containers.ThreadInfo;
+import com.nokia.s60tools.memspy.containers.SWMTLogInfo.SWMTLogType;
+import com.nokia.s60tools.memspy.model.AnalyserXMLGenerator.XMLGeneratorAction;
+import com.nokia.s60tools.memspy.ui.views.MemSpyMainView;
+
+/**
+ * Class that is used when importing MemSpy data.
+ * ImportEngine takes care of copying files into predefined file structure that Main View is able to read.
+ */
+public class ImportEngine {
+
+ /* MemSpy's Main View */
+ private MemSpyMainView view;
+
+ /**
+ * Import Engine constructor.
+ * @param view MemSpy's main view
+ */
+ public ImportEngine( MemSpyMainView view ){
+ this.view = view;
+ }
+
+ /**
+ * Imports Heap Dump file(s) and starts heap analyser if only one file was imported. Method also shows
+ * error message if some of operations was not successful.
+ * @param importedHeaps list of imported files
+ * @param symbols symbol information that is used.
+ * @return true, if importing was successful.
+ */
+ public boolean importAndAnalyseHeap( ArrayList<ThreadInfo> importedHeaps, AnalyserXMLGenerator xmlGenerator, boolean startHeapAnalyser ){
+ return importAndAnalyseHeap( importedHeaps, xmlGenerator, startHeapAnalyser, true);
+ }
+
+ /**
+ * Imports Heap Dump file(s) and starts heap analyser if only one file was imported. Method also shows
+ * error message if some of operations was not successful.
+ * @param importedHeaps list of imported files
+ * @param symbols symbol information that is used.
+ * @param deleteTempFiles if temp files and folder should be deleted after import
+ * @return true, if importing was successful.
+ */
+ public boolean importAndAnalyseHeap( ArrayList<ThreadInfo> importedHeaps, AnalyserXMLGenerator xmlGenerator, boolean startHeapAnalyser, boolean deleteTempFiles ){
+
+ boolean importFailed = false;
+
+ // Set xmlGenerators action type correct.
+ xmlGenerator.setXMLAction( XMLGeneratorAction.ANALYSE_HEAP );
+ String fileName = "";
+ for ( ThreadInfo threadInfo : importedHeaps ){
+ fileName = this.moveHeapToImportedFolder( threadInfo );
+ if( fileName != null ){
+ // save new filepath into threadInfo-variable.
+ threadInfo.setThreadFilePath( fileName );
+
+ if( !generateViewConfigurationFile( fileName, threadInfo.getThreadName(), xmlGenerator) ){
+ importFailed = true;
+ }
+
+ }
+ else{
+ importFailed = true;
+ }
+ }
+
+ // if importing was failed, show error message.
+ if( importFailed ){
+ view.showErrorMessage( MemSpyMainView.ERROR_IMPORT_HEADER, MemSpyMainView.ERROR_HEAP_IMPORT_FAILED );
+ return false;
+ }
+
+ // Start heap analyser if only one heap was imported.
+ if( importedHeaps.size() == 1 && startHeapAnalyser ){
+
+ // get configuration files path
+ String analyserFileOutput = importedHeaps.get(0).getThreadFilePath().substring( 0, fileName.lastIndexOf("\\") + 1);
+ analyserFileOutput = analyserFileOutput + "configuration.xml";
+
+ // launch Heap Analyser
+ view.launchHeapAnalyser( analyserFileOutput, null, xmlGenerator.getXMLThreadName(), true );
+
+ }
+
+
+ // Refresh main view so that newly imported files are shown.
+ view.refreshContentAndViewAsync();
+
+ // delete temp folder
+ if(deleteTempFiles){
+ MemSpyFileOperations.deleteTempMemSpyFiles();
+ }
+
+ return true;
+ }
+
+ /**
+ * Move imported heap from temporary file into import directory
+ * @param threadInfo imported heap
+ * @return true if file operations were successful
+ */
+
+ private String moveHeapToImportedFolder( ThreadInfo threadInfo ){
+
+ // Get new file name for imported file.
+ String newFileName = MemSpyFileOperations.getFileNameForHeapDump( threadInfo.getThreadFilePath() );
+
+ if( newFileName == null ){
+ return null;
+ }
+
+ // Move heap dump from temp folder into Heap Dumps-folder
+ if( MemSpyFileOperations.moveFile(new File(threadInfo.getThreadFilePath()), new File(newFileName)) ){
+ return newFileName;
+ }
+ else{
+ return null;
+ }
+ }
+
+ /**
+ * Starts comparing two heap dump files.
+ * @param firstHeap first heap dump
+ * @param secondHeap second heap dump
+ */
+ public void compareHeaps( ThreadInfo firstHeap, ThreadInfo secondHeap, AnalyserXMLGenerator xmlGenerator, String output ){
+
+ boolean importFailed = false;
+
+ // get file paths of heap dumps.
+ String firstHeapFile = firstHeap.getThreadFilePath();
+ String secondHeapFile = secondHeap.getThreadFilePath();
+
+ if( firstHeapFile != null && secondHeapFile != null ){
+
+ // generate compare heaps configuration file.
+ xmlGenerator.setXMLAnalyseFileOutput( output );
+ if( this.generateCompareConfigurationFile( new String[]{ firstHeapFile, secondHeapFile}, firstHeap.getThreadName(), xmlGenerator) ){
+
+ // launch Heap Analyser
+ view.launchHeapAnalyser( MemSpyFileOperations.getCompareConfigurationFilePath(), xmlGenerator.getXMLAnalyseFileOutput(), xmlGenerator.getXMLThreadName(), false );
+ }
+ else{
+ importFailed = true;
+ }
+ }
+ if( importFailed ){
+ view.showErrorMessage( MemSpyMainView.ERROR_IMPORT_HEADER, MemSpyMainView.ERROR_HEAP_IMPORT_FAILED);
+ }
+
+ }
+
+
+ /**
+ * Imports SystemWide Memory Tracking logs and starts swmt viewer.
+ * @param importedLogs imported swmt logs.
+ */
+ public void importSWMTLogs( final ArrayList<SWMTLogInfo> importedLogs ){
+ importSWMTLogs( importedLogs, true);
+ }
+
+ /**
+ * Imports SystemWide Memory Tracking logs and starts swmt viewer.
+ * @param importedLogs imported swmt logs.
+ * @param deleteTempFiles if temp files and folder should be deleted after import
+ */
+ public void importSWMTLogs( final ArrayList<SWMTLogInfo> importedLogs, boolean deleteTempFiles){
+
+ boolean isImportedFromDevice = false;
+ boolean importFailed = false;
+
+ // check if files were imported from device.
+ if( importedLogs.size() > 0 ){
+ if (importedLogs.get(0).getType() == SWMTLogType.DEVICE ){
+ isImportedFromDevice = true;
+ }
+ }
+
+ ArrayList<String> directories = new ArrayList<String>();
+
+ // If files were imported from device, move those files into imported directory.
+ if( isImportedFromDevice ){
+
+ for( SWMTLogInfo swmtLogInfo : importedLogs){
+
+ // Get next free directory
+ String directory = MemSpyFileOperations.getNextFreeDirectory();
+ directory = MemSpyFileOperations.addSlashToEnd( directory );
+
+ // Add directory to arraylist
+ directories.add( directory );
+
+ if( !MemSpyFileOperations.copyFileToDirectory( swmtLogInfo.getPath(), directory ) ){
+
+ // if operations fail show error message and remove all imported files.
+ importFailed = true;
+ MemSpyFileOperations.deleteDir( new File( directory ) );
+ break;
+ }
+ }
+ }
+ else{// if importing log from file system, copy files into imported directory
+
+ for( SWMTLogInfo swmtLogInfo : importedLogs){
+
+ // if file
+ if( swmtLogInfo.getType() == SWMTLogType.FILE ){
+
+ // Get next free directory
+ String directory = MemSpyFileOperations.getNextFreeDirectory();
+ directory = MemSpyFileOperations.addSlashToEnd( directory );
+
+ // Add directory to arraylist
+ directories.add( directory );
+
+ if( !MemSpyFileOperations.copyFileToDirectory( swmtLogInfo.getPath(), directory ) ){
+
+ // if operation fails show error message and remove all imported files.
+ importFailed = true;
+ MemSpyFileOperations.deleteDir( new File( directory ) );
+ break;
+ }
+ }
+
+
+ }
+
+ }
+ // if error occurred show error message
+ if( importFailed ){
+ view.showErrorMessage( MemSpyMainView.ERROR_IMPORT_HEADER, MemSpyMainView.ERROR_SWMT_IMPORT_FAILED);
+ }
+ else{
+ // Get ArrayList of imported files.
+ ArrayList<String> files = new ArrayList<String>();
+ try{
+ for( String item : directories ){
+ // Get filename from Log file from each directory that is saved into directories-ArrayList.
+ File directory = new File(item);
+ String fileName = directory.list()[0];
+ fileName = item + fileName;
+ files.add( fileName );
+ }
+ view.launchSWMTAnalyser( files );
+
+ }
+ catch( Exception e ){
+ view.showErrorMessage( MemSpyMainView.ERROR_IMPORT_HEADER, MemSpyMainView.ERROR_LAUNCH_SWMT_ANALYSER );
+ }
+
+ }
+
+ // Refresh main view so that newly imported files are shown.
+ view.refreshContentAndViewAsync();
+
+ // delete temp folder
+ if(deleteTempFiles){
+ MemSpyFileOperations.deleteTempMemSpyFiles();
+ }
+
+
+
+
+ }
+
+
+ /**
+ * Uses AnalyserXMLGenerator to generate configuration file for viewing heap with Heap Analyser
+ * @param name of the source file
+ * @param threadName thread's name
+ * @param xmlGenerator XML generator that is used.
+ * @return true if file was generated successfully
+ */
+ public boolean generateViewConfigurationFile( String fileName, String threadName, AnalyserXMLGenerator xmlGenerator ){
+
+ xmlGenerator.setXMLAction(XMLGeneratorAction.ANALYSE_HEAP);
+ xmlGenerator.setXMLSourceFile( new String[]{ fileName } );
+ xmlGenerator.setXMLThreadName( threadName );
+
+ // get filenames path
+ String analyserFileOutput = fileName.substring( 0, fileName.lastIndexOf("\\") + 1);
+ analyserFileOutput = analyserFileOutput + "configuration.xml";
+
+ // generate xml-file
+
+ File filename = new File( analyserFileOutput );
+ BufferedWriter writer = null;
+
+ try {
+ // Construct FileWriter and print xml into that stream
+ writer = new BufferedWriter(new FileWriter(filename));
+ xmlGenerator.GenerateXML(writer);
+ }
+ catch (IOException e) {
+
+ e.printStackTrace();
+ return false;
+ }
+ finally {
+ try {
+ if (writer != null) {
+ writer.flush();
+ writer.close();
+ return true;
+ }
+ }
+ catch (IOException ex) {
+ ex.printStackTrace();
+ return false;
+ }
+
+ }
+ return false;
+ }
+
+ /**
+ * Uses AnalyserXMLGenerator to generate configuration file for comparing two heap's with Heap Analyser
+ * @param fileName names of the source files.
+ * @param threadName thread's name
+ * @param xmlGenerator XML generator that is used.
+ * @return true if file was generated successfully
+ */
+ public boolean generateCompareConfigurationFile( String[] fileName, String threadName, AnalyserXMLGenerator xmlGenerator ){
+ xmlGenerator.setXMLAction(XMLGeneratorAction.COMPARE_HEAPS);
+ xmlGenerator.setXMLSourceFile( fileName );
+ xmlGenerator.setXMLThreadName( threadName );
+
+ String analyserFileOutput = MemSpyFileOperations.getCompareConfigurationFilePath();
+
+ // generate xml-file
+ File filename = new File( analyserFileOutput );
+
+
+ BufferedWriter writer = null;
+
+ try {
+ // Construct FileWriter and print xml into that stream
+ writer = new BufferedWriter(new FileWriter(filename));
+ xmlGenerator.GenerateXML(writer);
+ }
+ catch (IOException e) {
+
+ e.printStackTrace();
+ return false;
+ }
+ finally {
+ try {
+ if (writer != null) {
+ writer.flush();
+ writer.close();
+ return true;
+ }
+ }
+ catch (IOException ex) {
+ ex.printStackTrace();
+ return false;
+ }
+
+ }
+ return false;
+
+ }
+
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/model/MemSpyFileBundle.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,414 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+package com.nokia.s60tools.memspy.model;
+
+
+import java.io.File;
+import java.util.Date;
+
+import com.nokia.s60tools.memspy.files.HeapDumpFile;
+import com.nokia.s60tools.memspy.files.SWMTFile;
+
+/**
+ * MemSpyBundle class bundles up one folder under MemSpy plugin's folder. I.e. one
+ * MemSpyFileBundle is one row in MainView. A Bundle can contain an Heap Dump file or
+ *
+ * SWMT-log file. All of the file listed above are found e.g. from
+ * c:\my_carbide_workspace\.metadata\.plugins\com.nokia.s60tools.memspy\ImportedFiles[bundle folder]
+ *
+ * Bundle can also be a waiting bundle, so that 'Loading files. Please wait' row can be shown in MainView.
+ *
+ */
+public class MemSpyFileBundle {
+
+ public static final int INDEX_FILE_TYPE = 0;
+ public static final int INDEX_FILE_NAME = 1;
+ public static final int INDEX_TIME = 2;
+
+
+ /*
+ * Heap Dump file
+ */
+ private HeapDumpFile heapDumpFile = null;
+
+ /*
+ * SWMT-log file
+ */
+ private SWMTFile swmtFile = null;
+
+ /**
+ * Bundle name for an empty or waiting bundle
+ */
+ private String bundleName = "";
+
+ /**
+ * Folder where all bundle's files can be found from
+ */
+ private String bundleFolder = "";
+
+ /**
+ * If true, bundle is an empty or waiting bundle
+ */
+ private boolean emptyFile = false;
+
+ /**
+ * Used for creating an empty or waiting bundle
+ * @param empty If <code>true</code>, an empty bundle is created. If <code>false</code>, a waiting bundle is created.
+ */
+ public MemSpyFileBundle(boolean empty) {
+ if (empty)
+ bundleName = "No Crash Files Found.";
+ else
+ bundleName = "Loading files. Please wait.";
+ emptyFile = true;
+ }
+
+ /**
+ * Creates a bundle from folder
+ * @param folder Bundle folder. Bundle's file will be read from here.
+ */
+ public MemSpyFileBundle( String folder ) {
+ bundleFolder = MemSpyFileOperations.addSlashToEnd(folder);
+
+ heapDumpFile = HeapDumpFile.read( folder );
+ swmtFile = SWMTFile.read( folder );
+
+ }
+
+ /**
+ * Create dummy bundle.
+ * @param folder where files are searched.
+ * @return returns new bundle.
+ */
+ public static MemSpyFileBundle createDummyBundle(String folder) {
+ return new MemSpyFileBundle(folder);
+ }
+
+ /**
+ * MainView can use this to get description for each column in the grid
+ * @param index index of the column
+ * @return value for asked column
+ */
+ public String getText(int index) {
+ String retval = "";
+ switch (index) {
+ case INDEX_TIME:
+ retval = this.getTime();
+ break;
+
+ case INDEX_FILE_NAME:
+ retval = this.getFileName();
+ break;
+
+ case INDEX_FILE_TYPE:
+ retval = this.getFileType();
+ break;
+
+ default:
+ break;
+ }
+
+ return retval;
+ }
+
+ /**
+ * Get file type.
+ * @return type of file.
+ */
+ public String getFileType() {
+ if (emptyFile)
+ return bundleName;
+
+ String retval = "";
+
+ if ( this.heapDumpFile != null) {
+ retval = heapDumpFile.getFileType();
+ }
+
+ if( swmtFile != null ){
+ retval = this.swmtFile.getFileType();
+ }
+
+ return retval;
+ }
+
+
+ /**
+ * Returns the file name for this bundle. File name depends on what types
+ * of files this bundle contains (or if this bundle is an empty or waiting bundle).
+ *
+ * @return the file name for this bundle.
+ */
+ public String getFileName() {
+ if (emptyFile)
+ return bundleName;
+
+ String retval = "";
+
+ if ( this.heapDumpFile != null) {
+ retval = heapDumpFile.getFileName();
+ }
+ else if( swmtFile != null ){
+ retval = this.swmtFile.getFileName();
+ }
+
+ return retval;
+ }
+
+ /**
+ * Get the Cycle number from FileName.
+ * E.g. if file name is: "MemSpy SWMT-log 12.08.2009 08-40-22 Cycle 3"
+ * will return '3'.
+ *
+ * @return the cycle number from file name for this bundle, or -1 if can't found.
+ */
+ public int getCycleNumberFromFileName() {
+ int retval = -1;
+ if (emptyFile){
+ return retval;
+ }
+
+ String fileName = "";
+
+ if ( this.heapDumpFile != null) {
+ fileName = heapDumpFile.getFileName();
+ }
+ else if( swmtFile != null ){
+ fileName = this.swmtFile.getFileName();
+ }
+
+ if(fileName != null && fileName.indexOf(MemSpyFileOperations.CYCLE) != -1){
+ int index = fileName.indexOf(MemSpyFileOperations.CYCLE);
+ String cycle = fileName.substring((index + MemSpyFileOperations.CYCLE.length())).trim();
+ cycle = cycle.substring(0, cycle.indexOf('.'));
+ try {
+ retval = Integer.parseInt(cycle);
+ } catch (NumberFormatException e) {
+ e.printStackTrace();
+ retval = -1;
+ }
+ }
+
+ return retval;
+ }
+
+ /**
+ * Get Time
+ * @return time of file creation.
+ */
+ public String getTime() {
+ if (emptyFile)
+ return "";
+ String retval = "";
+
+ if( heapDumpFile != null ){
+ retval = this.heapDumpFile.getTime();
+ }
+ else if( swmtFile != null ){
+ retval = this.swmtFile.getTime();
+ }
+
+
+ return retval;
+ }
+
+ /**
+ * Get time as long
+ * @return time of file creation as long.
+ */
+ public long getTimeAsLong(){
+ long time = -1;
+ Date date = null;
+ if( heapDumpFile != null ){
+ date = this.heapDumpFile.getDateTime();
+ }
+ else if( swmtFile != null ){
+ date = this.swmtFile.getDateTime();
+ }
+
+ if(date != null){
+ time = date.getTime();
+ }
+
+ return time;
+ }
+
+
+ /**
+ * Get XML file.
+ * @return XML-files path
+ */
+ public String getXMLFilePath() {
+ if( heapDumpFile != null ){
+ return this.heapDumpFile.getXmlPath();
+ }
+ else{
+ return null;
+ }
+ }
+
+ /**
+ * Get file path.
+ * @return Files complete path.
+ */
+ public String getFilePath(){
+ if (emptyFile)
+ return "";
+ String retval = "";
+
+ if( heapDumpFile != null ){
+ retval = this.heapDumpFile.getFilePath();
+ }
+
+ if( swmtFile != null ){
+ retval = this.swmtFile.getFilePath();
+ }
+
+
+ return retval;
+ }
+
+
+ /**
+ * Returns whether this is an empty or waiting bundle.
+ * @return true if bundle is empty or waiting, false if not.
+ */
+ public boolean isEmpty() {
+ return emptyFile;
+ }
+
+
+
+ /**
+ * Returns whether this bundle contains any files.
+ * @return true if bundle contains files, false if not
+ */
+ public boolean hasFiles() {
+ if ( heapDumpFile != null || swmtFile != null )
+ return true;
+
+ return false;
+ }
+
+
+
+ /**
+ * Tests whether this bundle still exists in the drive.
+ * If bundle is empty or waiting, true is always returned.
+ *
+ * @return <code>true</code> if bundle exists, <code>false</code> if not.
+ */
+ public boolean exists() {
+ if (isEmpty())
+ return true;
+
+ try {
+ File f = new File(bundleFolder);
+ if (f.isDirectory() && f.exists())
+ return true;
+ } catch (Exception e) {
+ return false;
+ }
+
+ return false;
+ }
+
+
+
+ /**
+ * Returns this bundle's folder
+ * @return bundle's folder or empty
+ */
+ protected String getBundleFolder() {
+ return bundleFolder;
+ }
+
+
+ /**
+ * Has this bundle a SWMT log file.
+ * @return <code>true</code> if this bundle has SWMT-log <code>false</code> otherwise.
+ */
+ public boolean hasSWMTLogFile(){
+ if( swmtFile != null ){
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Has this bundle a heap dump file
+ * @return <code>true</code> if this bundle has Heap Dump <code>false</code> otherwise.
+ */
+ public boolean hasHeapDumpFile(){
+
+ if( heapDumpFile != null ){
+ return true;
+
+ }
+ return false;
+
+ }
+
+ /**
+ * Deletes this bundle. I.e deletes all files under this
+ * bundle's folder and finally deletes the bundle folder.
+ */
+ public boolean delete() {
+ if (!"".equals(bundleFolder)) {
+ return !MemSpyFileOperations.deleteDir( new File( bundleFolder ) );
+ }
+ else{
+ return false;
+ }
+
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see java.lang.Object#toString()
+ */
+ public String toString(){
+ if(swmtFile != null){
+ return swmtFile.getFilePath();
+ }
+ else{
+ return null;
+ }
+ }
+
+ /**
+ * Checks if bundles are equal. Two bundles are equal if
+ * their bundleFolder is the same.
+ */
+ public boolean equals(Object other) {
+ if (this == other)
+ return true;
+
+ if (!(other instanceof MemSpyFileBundle))
+ return false;
+
+ MemSpyFileBundle othr = (MemSpyFileBundle)other;
+ if (bundleFolder.compareToIgnoreCase(othr.getBundleFolder()) == 0)
+ return true;
+ return false;
+ }
+
+
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/model/MemSpyFileManager.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,207 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+package com.nokia.s60tools.memspy.model;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.ILock;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.swt.widgets.Display;
+
+import com.nokia.s60tools.memspy.interfaces.INewMemSpyFilesObserver;
+
+
+/**
+ * This class is responsible for providing MemSpy files to MainView's content provider.
+ * This class read workspace specific files from disk and prepares them for main view.
+ */
+public class MemSpyFileManager extends Job {
+ private List<MemSpyFileBundle> memSpyFiles = null;
+ private INewMemSpyFilesObserver filesObserver = null;
+ private ILock accessLock = null;
+ private boolean restart = false;
+ private boolean jobRunning = false;
+
+
+ /**
+ * Constructor.
+ * @param observer, which is notified when reading is finished.
+ */
+ public MemSpyFileManager( INewMemSpyFilesObserver observer ) {
+ super("MemSpy - Reading Files");
+ filesObserver = observer;
+ memSpyFiles = null;
+ accessLock = Job.getJobManager().newLock();
+ }
+
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime.IProgressMonitor)
+ */
+ protected IStatus run(IProgressMonitor monitor) {
+ accessLock.acquire();
+ try {
+ jobRunning = true;
+ if (memSpyFiles == null) {
+ memSpyFiles = new ArrayList<MemSpyFileBundle>();
+ } else {
+
+ // remove no longer existing files
+ for (int i = 0; i < memSpyFiles.size(); i++) {
+ MemSpyFileBundle file = memSpyFiles.get(i);
+ if (!file.exists()) {
+ memSpyFiles.remove(i);
+ i--;
+ }
+ }
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ } finally {
+ accessLock.release();
+ }
+
+ //get directory
+ File cFilesFolder = new File( MemSpyFileOperations.getImportedDirectory() );
+
+ if (cFilesFolder.exists() && cFilesFolder.isDirectory()) {
+
+ // get folders and files in imported directory
+ File[] folders = cFilesFolder.listFiles();
+ if (folders != null) {
+ for (int j = 0; j < folders.length; j++) {
+ File cFolder = folders[j];
+ if (cFolder.isDirectory()) {
+ accessLock.acquire();
+ try {
+
+ MemSpyFileBundle dummy = MemSpyFileBundle.createDummyBundle(cFolder.getAbsolutePath());
+ if (!memSpyFiles.contains(dummy)) {
+ accessLock.release();
+ MemSpyFileBundle bundle = new MemSpyFileBundle(cFolder.getAbsolutePath());
+ if (bundle.hasFiles()) {
+ accessLock.acquire();
+ memSpyFiles.add(bundle);
+ }
+ }
+ else {
+ accessLock.release();
+ MemSpyFileBundle bundle = new MemSpyFileBundle(cFolder.getAbsolutePath());
+ if (bundle.hasFiles()) {
+ accessLock.acquire();
+ memSpyFiles.remove(dummy);
+ memSpyFiles.add(bundle);
+ }
+ }
+ }
+ catch (Exception e) {
+ e.printStackTrace();
+ }
+ finally {
+ accessLock.release();
+ }
+ }
+ }
+ }
+ }
+
+ filesObserver.memSpyFilesUpdated();
+
+ accessLock.acquire();
+ if (restart) {
+ restart = false;
+ accessLock.release();
+ reSchedule();
+ }
+ else {
+ jobRunning = false;
+ accessLock.release();
+ }
+
+ return Status.OK_STATUS;
+ }
+
+ /**
+ * Re schelude this job
+ * @see Job#schedule()
+ */
+ void reSchedule() {
+ Runnable refreshRunnable = new Runnable(){
+ public void run(){
+ schedule(100);
+ }
+ };
+
+ Display.getDefault().asyncExec(refreshRunnable);
+ }
+
+ /**
+ * Get all MemSpy files for main view to use
+ * @return files
+ */
+ public MemSpyFileBundle[] getmemSpyFiles() {
+ // files have not yet been read, start reading process
+ if (memSpyFiles == null) {
+ if(jobRunning == false){
+ jobRunning = true;
+ setPriority(Job.LONG);
+ setUser(false);
+ schedule(100);
+ }
+ MemSpyFileBundle[] cFiles = new MemSpyFileBundle[1];
+ cFiles[0] = new MemSpyFileBundle(false);
+ return cFiles;
+ }
+ else{
+ return memSpyFiles.toArray(new MemSpyFileBundle[memSpyFiles.size()]);
+ }
+
+ }
+
+
+ /**
+ * Refresh content. Reads files from disk again.
+ * @see MemSpyFileManager#run(IProgressMonitor)
+ */
+ public void refresh() {
+
+ accessLock.acquire();
+ try {
+ if (jobRunning) {
+ restart = true;
+ } else {
+ setPriority(Job.LONG);
+ setUser(false);
+ schedule(100);
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ } finally {
+ accessLock.release();
+ }
+ }
+
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/model/MemSpyFileNameFilter.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,42 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+
+package com.nokia.s60tools.memspy.model;
+
+import java.io.File;
+import java.io.FilenameFilter;
+
+/**
+ * File name filter for MemSpy log files(*.log, *.txt)
+ */
+public class MemSpyFileNameFilter implements FilenameFilter{
+
+ /* (non-Javadoc)
+ * @see java.io.FilenameFilter#accept(java.io.File, java.lang.String)
+ */
+ public boolean accept(File dir, String name) {
+ if( name.endsWith(".txt") || name.endsWith(".log") ){
+ return true;
+ }
+ else{
+ return false;
+ }
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/model/MemSpyFileOperations.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,372 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+
+package com.nokia.s60tools.memspy.model;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Platform;
+
+import com.nokia.s60tools.memspy.plugin.MemSpyPlugin;
+
+/**
+ * Utilities for handling MemSpy specific file operation
+ */
+public class MemSpyFileOperations {
+
+ private static final String TEMP = "\\Temp";
+
+ /**
+ * Cycle
+ */
+ public static final String CYCLE = "Cycle";
+
+ /**
+ * Date format "dd.MM.yyyy HH:mm:ss"
+ */
+ public final static String DATEFORMAT = "dd.MM.yyyy HH:mm:ss";
+
+ private final static String SWMT_LOG_TEXT = "MemSpy SWMT-log";
+ private final static String CONFIGURATION_DIRECTORY_NAME = "ConfigurationFiles";
+ private final static String IMPORTED_DIRECTORY_NAME = "ImportedData";
+
+
+ /**
+ * Generates file name for new temporary heap dump file based on threads name and current time
+ * @param threadName Name of the thread
+ * @param date date when log has been imported
+ * @return new file name
+ */
+ public static String getFileNameForTempHeapDump( String threadName, Date date){
+
+
+ // Format the current time.
+ SimpleDateFormat formatter = new SimpleDateFormat ( DATEFORMAT );
+ String dateString = formatter.format(date);
+ String threadFileName = threadName + " " + dateString + ".txt" ;
+
+ // replace :'s with -'s as :'s cannot be on file names.
+ threadFileName = threadFileName.replace(':', '-');
+
+ //String folder = Platform.getConfigurationLocation().getURL().getFile() + "memspy\\Temp";
+ String folder = MemSpyFileOperations.getPluginWorkingLocation() + TEMP;
+
+ // create directory if needed
+ File file1 = new File(folder);
+ if( !file1.exists() ){
+ if( !file1.mkdirs() ){
+ return null;
+ }
+ }
+
+ // combine directory and filename
+ String filePath = folder + "\\"+ threadFileName;
+ return filePath;
+ }
+
+
+
+
+ /**
+ * Copies file into another location
+ * @param inputFile input file where file is currently found
+ * @param outputFile output file where file is copied
+ * @return true if file operations were successful
+ */
+ public static boolean copyFile( File inputFile, File outputFile ){
+ FileReader in;
+ try {
+
+ // create file reader and writer
+ in = new FileReader(inputFile);
+ FileWriter out = new FileWriter(outputFile);
+ int c;
+
+ // Read line from input file and write it into output file.
+ while ((c = in.read()) != -1){
+ out.write(c);
+ }
+
+ // close files
+ in.close();
+ out.close();
+ }
+ catch (FileNotFoundException e) {
+ return false;
+ }
+ catch (IOException e) {
+ return false;
+ }
+ return true;
+
+ }
+
+
+ /**
+ * Moves file into another location
+ * @param inputFile input file where file is currently found
+ * @param outputFile output file where file is moved
+ * @return <code>true</code> if file operations were successful <code>false</code> otherwise.
+ * @see File#renameTo(File)
+ */
+ public static boolean moveFile(File inputFile, File outputFile ){
+
+ // Move file into new directory
+ return inputFile.renameTo(outputFile);
+ }
+
+
+ /**
+ * Generates file name for new heap dump file based on threads name and current time
+ * @param currentFileName current temporary file name
+ * @return new file name
+ */
+ public static String getFileNameForHeapDump(String currentFileName){
+
+ // Get Filename
+ String threadFileName = currentFileName.substring( currentFileName.lastIndexOf("\\") +1 );
+ String folder = MemSpyFileOperations.getNextFreeDirectory();
+ if( folder == null){
+ return null;
+ }
+
+ folder = addSlashToEnd( folder );
+ folder = folder + threadFileName;
+
+ return folder;
+ }
+
+ /**
+ * Returns a path where Crash Analyser plugin can do various tasks (located under workspace).
+ * @return E.g. C:\My_Workspace\.metadata\.plugins\[plugin name]\
+ */
+ public static String getPluginWorkingLocation() {
+ IPath location = Platform.getStateLocation( MemSpyPlugin.getDefault().getBundle());
+ return location.toOSString();
+ }
+
+ /**
+ * Deletes directory and everything inside.
+ * @param dir directory name
+ * @return true if file operations were successful
+ */
+ public static boolean deleteDir(File dir) {
+ boolean isAllDeleted = deleteFiles(dir);
+ // after everything inside directory is deleted, remove directory itself.
+ return dir.delete() && isAllDeleted;
+ }
+
+
+
+
+ /**
+ * Delete files from dir, but leave the dir as it is.
+ * @param dir
+ * @return <code>true</code> if all files and subdirectories was deleted successfully, <code>false</code> otherwise.
+ */
+ public static boolean deleteFiles(File dir) {
+ boolean isAllDeleted = true;
+ if ( dir.isDirectory() ) {
+
+ // get list of everything inside file.
+ String[] children = dir.list();
+
+ // go thru file list and call this function recursively.
+ for ( int i=0; i < children.length; i++) {
+ boolean success = deleteDir(new File(dir, children[i]));
+ if (!success) {
+ isAllDeleted = false;
+ }
+ }
+ }
+ return isAllDeleted;
+ }
+
+ /**
+ * Returns all list of all log files(*.txt and *.log) from directory
+ * @param directory where from list is received
+ * @return files found in directory
+ */
+ public static File[] getFilesFromDirectory(File directory){
+ FilenameFilter filter = new MemSpyFileNameFilter();
+ return directory.listFiles( filter );
+ }
+
+ /**
+ * Get temporary SWMT file name with path
+ * @param cycleNumber cycle number or received heap
+ * @param date current date
+ * @return temp file name, null if operation was failed.
+ */
+ public static String getTempFileNameForSWMTLog( int cycleNumber, Date date ) {
+
+
+ // Format the current time.
+ SimpleDateFormat formatter = new SimpleDateFormat ( DATEFORMAT );
+ String dateString = formatter.format(date);
+
+ String fileName = SWMT_LOG_TEXT + " " + dateString + " " + CYCLE + " " + Integer.toString(cycleNumber) + ".txt";
+
+ // replace :'s with -'s as :'s cannot be on file names.
+ fileName = fileName.replace(':', '-');
+
+ String folder = MemSpyFileOperations.getPluginWorkingLocation() + TEMP;
+
+ // create directory if needed
+ File file1 = new File(folder);
+ if( !file1.exists() ){
+ if( !file1.mkdirs() ){
+ return null;
+ }
+ }
+ String filePath = file1.toString() + "\\"+ fileName;
+ return filePath;
+ }
+
+ /**
+ * Deletes MemSpy's temp directory and everything inside it
+ * @return <code>true</code> if operation was successful <code>false</code> otherwise.
+ */
+ public static boolean deleteTempMemSpyFiles(){
+ File folder = new File( MemSpyFileOperations.getPluginWorkingLocation() + TEMP );
+ return deleteDir(folder);
+
+ }
+
+
+ /**
+ * Creates next free directory for MemSpy data files
+ * @return next free directory where files can be copied.
+ */
+ public static String getNextFreeDirectory(){
+
+ // Get fileList from importedHeaps-directory
+ String directory = MemSpyFileOperations.getImportedDirectory();
+ File file = new File( directory );
+ String[] fileList = file.list();
+ directory = MemSpyFileOperations.addSlashToEnd( directory );
+
+
+ int i = 0;
+
+ File newFile = null;
+
+
+ // if ImportedHeaps-directory is found
+ if( fileList != null ){
+ // Go thru directory in a loop and find search for first free integer value for directory name.
+ while( i <= fileList.length ){
+
+ newFile = new File( directory + Integer.toString(i) );
+ if ( !newFile.isDirectory() )
+ {
+ break;
+ }
+ i++;
+ }
+ }
+ else{
+ newFile = new File( directory + "0" );
+ }
+
+ // if directories are created successfully, return path, if not return null
+ if( newFile.mkdirs() ){
+ String newFileString = MemSpyFileOperations.addSlashToEnd( newFile.toString() );
+ return newFileString;
+ }
+ else{
+ return null;
+ }
+
+ }
+
+ /**
+ * If the last character of the given path is not backslash, it is added
+ * and path with backslash is returned.
+ * @param path Path to which backslash is added
+ * @return Path which last character is backslash
+ */
+ public static String addSlashToEnd(String path) {
+ if (path.endsWith(File.separator)){
+ return path;
+ }
+ else{
+ return path + File.separator;
+ }
+ }
+
+ /**
+ * Get imported files directory
+ * @return path of the imported-directory
+ */
+ public static String getImportedDirectory(){
+ // get imported-directory
+ String directory = MemSpyFileOperations.getPluginWorkingLocation();
+ directory = MemSpyFileOperations.addSlashToEnd( directory );
+ return directory + IMPORTED_DIRECTORY_NAME;
+ }
+
+ /**
+ * Get configuration file path
+ * @return path of the configuration file, if file does not exist yet, method creates it.
+ */
+ public static String getCompareConfigurationFilePath(){
+ // get imported-directory
+ String directory = MemSpyFileOperations.getPluginWorkingLocation();
+ directory = MemSpyFileOperations.addSlashToEnd( directory );
+ directory = directory + CONFIGURATION_DIRECTORY_NAME;
+
+ File file = new File(directory);
+ if( !file.exists() ){
+ if( !file.mkdirs() ){
+ return null;
+ }
+ }
+ directory = MemSpyFileOperations.addSlashToEnd(directory);
+ directory = directory + "input.xml";
+ return directory;
+
+ }
+
+ /**
+ * Copies file to another directory with same filename
+ * @param filePath file that is copied
+ * @param directory output directory
+ * @return <code>true</code> if operation was successful <code>false</code> otherwise.
+ */
+ public static boolean copyFileToDirectory( String filePath, String directory){
+
+ String fileName = filePath.substring( filePath.lastIndexOf("\\") +1 );
+ String directoryTo = directory + fileName;
+
+ return copyFile( new File( filePath ), new File( directoryTo ) );
+
+ }
+
+
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/model/MemSpyLogParserEngine.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,213 @@
+/*
+ * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+ * All rights reserved.
+ * This component and the accompanying materials are made available
+ * under the terms of "Eclipse Public License v1.0"
+ * which accompanies this distribution, and is available
+ * at the URL "http://www.eclipse.org/legal/epl-v10.html".
+ *
+ * Initial Contributors:
+ * Nokia Corporation - initial contribution.
+ *
+ * Contributors:
+ *
+ * Description:
+ *
+ */
+
+package com.nokia.s60tools.memspy.model;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.Date;
+
+import com.nokia.s60tools.memspy.containers.ThreadInfo;
+import com.nokia.s60tools.memspy.containers.ThreadInfo.HeapDumpType;
+
+/**
+ * Heap Dump parser that is used when parsing heap dump file.
+ */
+public class MemSpyLogParserEngine {
+
+ // Writer that writes into file
+ private PrintWriter plainOutput;
+
+ private boolean fileOpen;
+
+ /**
+ *
+ * Checks that at least one heap info with binary data information is found from file given as parameter.
+ * Function also saves thread names from heap dump file into ArrayList what
+ * was given as parameter threadNames.
+ *
+ * @param file
+ * @param threadNames
+ * Arraylist where thread names are saved.
+ * @return true if threads containing binary data information were found from this file.
+ */
+ public boolean isFileHeapDumpFile(File file,
+ ArrayList<ThreadInfo> threadNames) {
+
+ boolean heapFound = false;
+ boolean heapDataFound = false;
+ boolean heapDataErrorFound = false;
+
+ try {
+ String heapInfo = "HEAP INFO FOR THREAD";
+ String heapData = "Heap Data";
+ String heapDataError = "Heap error";
+
+ BufferedReader reader = new BufferedReader(new FileReader(file));
+ String line = "";
+
+ // Go thru file in loop and search for lines that contain HEAP
+ // INFO-text. If text is found, save thread names into array list
+ // threadNames. If the thread doesn't contain any binary heap data information,
+ // the thread is removed from this array list.
+
+ while (reader.ready()) {
+ line = reader.readLine();
+ if (line.contains(heapInfo)) {
+
+ if ((heapDataFound && heapDataErrorFound) || !heapDataFound) {
+ if (threadNames.size() > 0) {
+ threadNames.remove(threadNames.size() - 1);
+ }
+ }
+
+ heapDataFound = false;
+ heapDataErrorFound = false;
+
+ if (line.contains("'")) {
+ String name = line.substring(line.indexOf("'") + 1);
+ if (name.contains("'")) {
+ String thread = name
+ .substring(0, name.indexOf("'"));
+ ThreadInfo threadInfo = new ThreadInfo();
+ threadInfo.setThreadName(thread);
+ Date date = new Date();
+ threadInfo.setDate(date);
+ threadInfo.setType(HeapDumpType.FILE);
+ String fName = MemSpyFileOperations
+ .getFileNameForTempHeapDump(thread, date);
+ threadInfo.setThreadFilePath(fName);
+ threadNames.add(threadInfo);
+
+ if (fileOpen) {
+ plainOutput.flush();
+ plainOutput.close();
+ }
+ if (!this.openFile(fName)) {
+ return false;
+ }
+ }
+ }
+ }
+
+ // Checking if the line contains binary heap data header
+ if (line.contains(heapData)) {
+ heapDataFound = true;
+ }
+
+ // Checking if the line contains binary heap data error
+ if (line.contains(heapDataError)) {
+ heapDataErrorFound = true;
+ }
+
+ if (fileOpen) {
+ plainOutput.write(line + "\n");
+ }
+ }
+
+ // Check for the last thread in file, because if the last thread is found and if it
+ // contains heap data with error or no heap data at all, it wouldn't be removed
+ // so it needs to be done here
+ if ((heapDataFound && heapDataErrorFound) || !heapDataFound) {
+ if (threadNames.size() > 0) {
+ threadNames.remove(threadNames.size() - 1);
+ }
+ }
+
+ if (threadNames.size() > 0) {
+ heapFound = true;
+ } else {
+ heapFound = false;
+ }
+
+ if (fileOpen) {
+ plainOutput.close();
+ fileOpen = false;
+ }
+ } catch (Exception e) {
+ return false;
+ }
+ return heapFound;
+ }
+
+ /**
+ * openFile creates new print writer into given path and saves it into
+ * member variable plainOutput
+ *
+ * @param fName
+ * file name
+ * @return true if file operation was successful
+ */
+ private boolean openFile(String fName) {
+ // If file needs to be opened, open it.
+
+ try {
+ plainOutput = new PrintWriter(new FileWriter(fName));
+ } catch (IOException e) {
+ return false;
+ }
+ this.fileOpen = true;
+ return true;
+ }
+
+ /**
+ * Check if this file is a SWMT log file
+ *
+ * @param file
+ * @return <code>true</code> if file contains a SWMT tag:
+ * {@link TraceCoreDataHandler#LAUNCHER_SWMT_LOG_START}
+ * <code>false</code> otherwise.
+ */
+ static public boolean isFileSWMTLog(File file) {
+ try {
+ String SWMTTag = TraceCoreDataHandler.LAUNCHER_SWMT_LOG_START;
+ BufferedReader reader = new BufferedReader(new FileReader(file));
+ String line = "";
+ int count = 0;
+
+ // Go thru file in loop and check if first line of file contains
+ // swmt-tag.
+
+ while (reader.ready() && count < 200) {
+ line = reader.readLine();
+ count++;
+
+ // if line contains tag, conclude that file is swmt-log
+ if (line.contains(SWMTTag)) {
+ return true;
+ }
+
+ // if line is other than empty, conclude that file is not
+ // swmt-log
+ if (line.length() > 0) {
+ return false;
+ }
+ }
+
+ } catch (Exception e) {
+ return false;
+ }
+
+ // if first 200 lines were empty, conclude that file is not SWMT-log
+ return false;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/model/SWMTCategoryConstants.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,145 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+package com.nokia.s60tools.memspy.model;
+
+import com.nokia.s60tools.util.debug.DbgUtility;
+
+/**
+ * Lists all the category constants that can be used with SWMT
+ */
+public class SWMTCategoryConstants {
+ public static final int CATEGORY_NONE = 0x0; // This is not used currently anywhere, but however available for use
+ public static final int CATEGORY_FILESERVERCACHE = 0x0001;
+ public static final int CATEGORY_BITMAPHANDLES = 0x0002;
+ public static final int CATEGORY_USERHEAP = 0x0004;
+ public static final int CATEGORY_KERNELHEAP = 0x0008;
+ public static final int CATEGORY_LOCALCHUNKS = 0x0010;
+ public static final int CATEGORY_GLOBALCHUNKS = 0x0020;
+ public static final int CATEGORY_RAMDRIVE = 0x0040;
+ public static final int CATEGORY_USERSTACKS = 0x0080;
+ public static final int CATEGORY_GLOBALDATA = 0x0100;
+ public static final int CATEGORY_RAMLOADEDCODE = 0x0200;
+ public static final int CATEGORY_KERNELHANDLES = 0x0400;
+ public static final int CATEGORY_OPENFILES = 0x0800;
+ public static final int CATEGORY_DISKUSAGE = 0x1000;
+ public static final int CATEGORY_SYSTEMMEMORY = 0x2000;
+ public static final int CATEGORY_WINDOWGROUPS = 0x4000;
+ public static final int CATEGORY_ALL = 0xFFFF; // This is default value in case user has not skipped any categories
+
+ /**
+ * Category profile constant for Basic Profile
+ */
+ public static final int PROFILE_BASIC = CATEGORY_USERHEAP | CATEGORY_USERSTACKS | CATEGORY_GLOBALDATA | CATEGORY_SYSTEMMEMORY;
+
+ /**
+ * Category profile constant for Ram & Disk Profile
+ */
+ public static final int PROFILE_RAM_DISK = CATEGORY_DISKUSAGE | CATEGORY_OPENFILES | CATEGORY_RAMLOADEDCODE | CATEGORY_RAMDRIVE;
+
+ /**
+ * Category profile constant for Ram, Disk & Heap Profile
+ */
+ public static final int PROFILE_RAM_DISK_HEAP = PROFILE_RAM_DISK | CATEGORY_USERHEAP | CATEGORY_KERNELHEAP;
+
+ /**
+ * Category profile constant for Ram, Disk, Heap & Handles Profile
+ */
+ public static final int PROFILE_RAM_DISK_HEAP_HANDLES = PROFILE_RAM_DISK_HEAP | CATEGORY_BITMAPHANDLES | CATEGORY_FILESERVERCACHE | CATEGORY_SYSTEMMEMORY;
+
+ /**
+ * Window Groups
+ */
+ public static final String WINDOW_GROUPS_TXT = "Window Groups";
+ /**
+ * Bitmap Handles
+ */
+ public static final String BITMAP_HANDLES_TXT = "Bitmap Handles";
+ /**
+ * FileServer Cache
+ */
+ public static final String FILE_SERVER_CACHE_TXT = "FileServer Cache";
+ /**
+ * RAM Drive
+ */
+ public static final String RAM_DRIVE_TXT = "RAM Drive";
+ /**
+ * Global Chunks
+ */
+ public static final String GLOBAL_CHUNKS_TXT = "Global Chunks";
+ /**
+ * Local Chunks
+ */
+ public static final String LOCAL_CHUNKS_TXT = "Local Chunks";
+ /**
+ * System Memory
+ */
+ public static final String SYSTEM_MEMORY_TXT = "System Memory";
+ /**
+ * RAM-loaded code
+ */
+ public static final String RAM_LOADED_CODE_TXT = "RAM-loaded code";
+ /**
+ * Open Files
+ */
+ public static final String OPEN_FILES_TXT = "Open Files";
+ /**
+ * Disk usage
+ */
+ public static final String DISK_USAGE_TXT = "Disk usage";
+ /**
+ * Global Data
+ */
+ public static final String GLOBAL_DATA_TXT = "Global Data";
+ /**
+ * User Stacks
+ */
+ public static final String USER_STACKS_TXT = "User Stacks";
+ /**
+ * Kernel Heap
+ */
+ public static final String KERNEL_HEAP_TXT = "Kernel Heap";
+ /**
+ * User Heap
+ */
+ public static final String USER_HEAP_TXT = "User Heap";
+
+
+ /**
+ * Debug prints those bits that are set in the category setting
+ * @param categories category settings to be debugged.
+ */
+ public static void debugPrintSWMTCategorySetting(int categories){
+ if((categories & CATEGORY_FILESERVERCACHE) != 0) DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "- CATEGORY_FILESERVERCACHE"); //$NON-NLS-1$
+ if((categories & CATEGORY_BITMAPHANDLES) != 0) DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "- CATEGORY_BITMAPHANDLES"); //$NON-NLS-1$
+ if((categories & CATEGORY_USERHEAP) != 0) DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "- CATEGORY_USERHEAP"); //$NON-NLS-1$
+ if((categories & CATEGORY_KERNELHEAP) != 0) DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "- CATEGORY_KERNELHEAP"); //$NON-NLS-1$
+ if((categories & CATEGORY_LOCALCHUNKS) != 0) DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "- CATEGORY_LOCALCHUNKS"); //$NON-NLS-1$
+ if((categories & CATEGORY_GLOBALCHUNKS) != 0) DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "- CATEGORY_GLOBALCHUNKS"); //$NON-NLS-1$
+ if((categories & CATEGORY_RAMDRIVE) != 0) DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "- CATEGORY_RAMDRIVE"); //$NON-NLS-1$
+ if((categories & CATEGORY_USERSTACKS) != 0) DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "- CATEGORY_USERSTACKS"); //$NON-NLS-1$
+ if((categories & CATEGORY_GLOBALDATA) != 0) DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "- CATEGORY_GLOBALDATA"); //$NON-NLS-1$
+ if((categories & CATEGORY_RAMLOADEDCODE) != 0) DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "- CATEGORY_RAMLOADEDCODE"); //$NON-NLS-1$
+ if((categories & CATEGORY_KERNELHANDLES) != 0) DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "- CATEGORY_KERNELHANDLES"); //$NON-NLS-1$
+ if((categories & CATEGORY_OPENFILES) != 0) DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "- CATEGORY_OPENFILES"); //$NON-NLS-1$
+ if((categories & CATEGORY_DISKUSAGE) != 0) DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "- CATEGORY_DISKUSAGE"); //$NON-NLS-1$
+ if((categories & CATEGORY_SYSTEMMEMORY) != 0) DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "- CATEGORY_SYSTEMMEMORY"); //$NON-NLS-1$
+ if((categories & CATEGORY_WINDOWGROUPS) != 0) DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "- CATEGORY_WINDOWGROUPS"); //$NON-NLS-1$
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/model/SWMTCategorys.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,180 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+package com.nokia.s60tools.memspy.model;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import com.nokia.s60tools.memspy.ui.dialogs.SWMTCategoryEntry;
+
+/**
+ * Singleton Class for holding SWMT Category profiles
+ */
+public class SWMTCategorys {
+
+
+ private static SWMTCategorys instance=null;
+
+
+ /**
+ * Private constructor
+ */
+ private SWMTCategorys(){
+ initializeCategoryEntries();
+ initializeCategoryProfiles();
+ }
+
+
+
+ /**
+ * Stores the category entries.
+ */
+ private List<SWMTCategoryEntry> categoryEntries;
+
+ private List<CategoryProfile> categoryProfiles;
+
+ /**
+ * Get only instance of this object
+ * @return instance
+ */
+ public static SWMTCategorys getInstance(){
+ if(instance==null){
+ instance = new SWMTCategorys();
+ }
+ return instance;
+ }
+
+ private void initializeCategoryProfiles() {
+ categoryProfiles = new ArrayList<CategoryProfile>();
+
+ CategoryProfile profile0 = new CategoryProfile("Basic", SWMTCategoryConstants.PROFILE_BASIC);
+ getCategoryProfiles().add(profile0);
+
+ CategoryProfile profile1 = new CategoryProfile("RAM & Disk Profile", SWMTCategoryConstants.PROFILE_RAM_DISK);
+ getCategoryProfiles().add(profile1);
+
+ CategoryProfile profile2 = new CategoryProfile("RAM, Disk & Heap Profile", SWMTCategoryConstants.PROFILE_RAM_DISK_HEAP);
+ getCategoryProfiles().add(profile2);
+
+ CategoryProfile profile3 = new CategoryProfile("RAM, Disk, Heap & Handles Profile", SWMTCategoryConstants.PROFILE_RAM_DISK_HEAP_HANDLES);
+ getCategoryProfiles().add(profile3);
+
+ CategoryProfile profile4 = new CategoryProfile("All", SWMTCategoryConstants.CATEGORY_ALL);
+ getCategoryProfiles().add(profile4);
+
+ }
+
+
+
+ /**
+ * Initializes category entry list.
+ */
+ private void initializeCategoryEntries() {
+ // Creating entry array
+ categoryEntries = new ArrayList< SWMTCategoryEntry>();
+ // Initializing value for the array
+ categoryEntries.add( new SWMTCategoryEntry(SWMTCategoryConstants.CATEGORY_USERHEAP, SWMTCategoryConstants.USER_HEAP_TXT));
+ categoryEntries.add( new SWMTCategoryEntry(SWMTCategoryConstants.CATEGORY_KERNELHEAP, SWMTCategoryConstants.KERNEL_HEAP_TXT));
+ categoryEntries.add( new SWMTCategoryEntry(SWMTCategoryConstants.CATEGORY_USERSTACKS, SWMTCategoryConstants.USER_STACKS_TXT));
+ categoryEntries.add( new SWMTCategoryEntry(SWMTCategoryConstants.CATEGORY_GLOBALDATA, SWMTCategoryConstants.GLOBAL_DATA_TXT));
+ categoryEntries.add( new SWMTCategoryEntry(SWMTCategoryConstants.CATEGORY_DISKUSAGE, SWMTCategoryConstants.DISK_USAGE_TXT));
+ categoryEntries.add( new SWMTCategoryEntry(SWMTCategoryConstants.CATEGORY_OPENFILES, SWMTCategoryConstants.OPEN_FILES_TXT));
+ categoryEntries.add( new SWMTCategoryEntry(SWMTCategoryConstants.CATEGORY_RAMLOADEDCODE, SWMTCategoryConstants.RAM_LOADED_CODE_TXT));
+ categoryEntries.add( new SWMTCategoryEntry(SWMTCategoryConstants.CATEGORY_SYSTEMMEMORY, SWMTCategoryConstants.SYSTEM_MEMORY_TXT));
+ categoryEntries.add( new SWMTCategoryEntry(SWMTCategoryConstants.CATEGORY_LOCALCHUNKS, SWMTCategoryConstants.LOCAL_CHUNKS_TXT));
+ categoryEntries.add( new SWMTCategoryEntry(SWMTCategoryConstants.CATEGORY_GLOBALCHUNKS, SWMTCategoryConstants.GLOBAL_CHUNKS_TXT));
+ categoryEntries.add( new SWMTCategoryEntry(SWMTCategoryConstants.CATEGORY_RAMDRIVE, SWMTCategoryConstants.RAM_DRIVE_TXT));
+ categoryEntries.add( new SWMTCategoryEntry(SWMTCategoryConstants.CATEGORY_FILESERVERCACHE, SWMTCategoryConstants.FILE_SERVER_CACHE_TXT));
+ categoryEntries.add( new SWMTCategoryEntry(SWMTCategoryConstants.CATEGORY_BITMAPHANDLES, SWMTCategoryConstants.BITMAP_HANDLES_TXT));
+ categoryEntries.add( new SWMTCategoryEntry(SWMTCategoryConstants.CATEGORY_WINDOWGROUPS, SWMTCategoryConstants.WINDOW_GROUPS_TXT));
+
+ }
+
+
+ /**
+ * Get all category entries exist
+ * @return the categoryEntries
+ */
+ public List<SWMTCategoryEntry> getCategoryEntries() {
+ return categoryEntries;
+ }
+
+ /**
+ * Get a category entry by ID
+ * @return the categoryEntry or <code>null</code> if not found
+ */
+ public SWMTCategoryEntry getCategoryEntry(int entryID) {
+
+
+ for (Iterator<SWMTCategoryEntry> iterator = categoryEntries.iterator(); iterator.hasNext();) {
+ SWMTCategoryEntry entry = (SWMTCategoryEntry) iterator.next();
+ if(entry.getCategoryId() == entryID){
+ return entry;
+ }
+ }
+
+ return null;
+ }
+
+
+ /**
+ * Get all category profiles created
+ * @return the categoryProfiles
+ */
+ public List<CategoryProfile> getCategoryProfiles() {
+ return categoryProfiles;
+ }
+
+ /**
+ * Get wanted SWMT Categorys by IDs
+ * @param categories
+ * @return {@link List} of {@link SWMTCategoryEntry}'s
+ */
+ public List<SWMTCategoryEntry> getCategoryEntries(int categories) {
+
+ List<SWMTCategoryEntry> wantedCategories = new ArrayList<SWMTCategoryEntry>();
+ for (Iterator<SWMTCategoryEntry> iterator = categoryEntries.iterator(); iterator.hasNext();) {
+ SWMTCategoryEntry entry = (SWMTCategoryEntry) iterator.next();
+ if((entry.getCategoryId() & categories) != 0){
+ wantedCategories.add(entry);
+ }
+ }
+ return wantedCategories;
+ }
+
+ /**
+ * Get profile by it's name
+ * @param profileName
+ * @return profile int or <code>null</code> if not found
+ */
+ public CategoryProfile getProfile(String profileName){
+
+ for (Iterator<CategoryProfile> iterator = categoryProfiles.iterator(); iterator
+ .hasNext();) {
+ CategoryProfile profile = (CategoryProfile) iterator.next();
+ if(profileName.equals(profile.getName())){
+ return profile;
+ }
+
+ }
+ return null;
+ }
+
+
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/model/TraceCoreDataHandler.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,595 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+
+package com.nokia.s60tools.memspy.model;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.regex.Pattern;
+
+import com.nokia.s60tools.memspy.containers.ThreadInfo;
+import com.nokia.s60tools.memspy.export.ITraceDataProcessor;
+import com.nokia.s60tools.memspy.interfaces.IMemSpyTraceListener.LauncherErrorType;
+import com.nokia.s60tools.memspy.util.MemSpyConsole;
+import com.nokia.s60tools.util.debug.DbgUtility;
+
+
+/**
+ * Monitors data received from TraceCore and acts based on it.
+ */
+public final class TraceCoreDataHandler implements ITraceDataProcessor {
+
+ // Count of lines
+ private int lineCount;
+
+ // boolean value that is used when parsing thread list
+ private boolean lastWasName;
+
+ // Array, where found thread names and id's are written
+ private ArrayList<ThreadInfo> threadArray = null;
+
+ // ThreadInfo-object where info is collected
+ private ThreadInfo threadInfo;
+
+ // boolean value that is set to true, when trace-lines are lost
+ private boolean dumpedTraces;
+
+ // boolean value that is set to false, when heap type is not symbian OS Rheap
+ private boolean heapTypeCorrect;
+
+ // boolean value that is true when some information is written to file
+ private boolean writeFile;
+
+ // boolean value that true when file is open
+ private boolean fileOpen;
+
+
+ // Writer that writes to file
+ private PrintWriter plainOutput;
+
+ // Writer that writes to file
+ private PrintWriter swmtHeadDumpOutput = null;
+
+
+ // boolean value that is true when some memspy operations are on-going.
+ private boolean logging;
+
+ // Trace engine.
+ private TraceCoreEngine engine;
+
+
+ //Strings
+ private final static String LAUNCHER_READY = "<MEMSPY_LAUNCHER_READY>";
+ private final static String MEMSPY_LAUNCHER_VERSION_PREFIX = "<MEMSPY_LAUNCHER_DATAVERSION=";//e.g. <MEMSPY_LAUNCHER_VERSION=1>
+ private final static String END_TAG = ">";
+ private final static String LAUNCHER_COLON = "::";
+ private final static String LAUNCHER_THREAD_ID = "Thread Id";
+ private final static String LAUNCHER_TYPE = "Type:";
+ private final static String LAUNCHER_SYMBIAN_OS_RHEAP = "Symbian OS RHeap";
+ private final static String LAUNCHER_HEAP_DUMP_START = "<MEMSPY_HEAP_DATA";
+ private final static String LAUNCHER_HEAP_DUMP_END = "</MEMSPY_HEAP_DATA";
+ //Heap info's will act as start point for new Head dump, when Head Dumps are received during SWMT logging
+ //E.g. following Heap info is received:
+ //HeapData - mc_isiserver::Main - HEAP INFO FOR THREAD 'mc_isiserver::Main'
+ private final static String LAUNCHER_HEAP_INFO_FOR_THREAD = "HEAP INFO FOR THREAD";
+ private final static String LAUNCHER_HEAPDATA = "HeapData -";
+ private final static String LAUNCHER_ERROR = "<MEMSPY_LAUNCHER_ERROR>";
+ private final static String DUMPED_TC_TRACES = "* Dumped Traces";
+ private final static String MEMSPY_PROGRESS = "<MEMSPY_PROGRESS>";
+
+ /**
+ * <code>SYSTEM WIDE MEMORY TRACKER<code> tag
+ */
+ public final static String LAUNCHER_SWMT_LOG_START = "<SYSTEM WIDE MEMORY TRACKER>";
+
+ private final static String LAUNCHER_SWMT_LOG_END = "</SYSTEM WIDE MEMORY TRACKER>";
+ private final static String LAUNCHER_SWMTDATA = "[SMT ";
+ private final static String LAUNCHER_CATEGORY_NOT_SUPPORTED = "<MEMSPY_LAUNCHER_CATEGORY_NOT_SUPPORTED>";
+
+ private ThreadInfo swmtHeadDumpThreadInfo;
+
+ /**
+ * Constructor.
+ * @param engine engine that uses handler
+ */
+ public TraceCoreDataHandler(TraceCoreEngine engine){
+ this.engine = engine;
+ lastWasName = false;
+ heapTypeCorrect = false;
+ writeFile = false;
+ lineCount = 0;
+ }
+
+ /**
+ * Method that is called when trace logging is started.
+ * @param fName Name of the file, where needed information is printed.
+ * @param fileOpen boolean value that is true when file needs to be opened.
+ */
+ public boolean startLogging(String fName, boolean fileOpen) {
+ logging = true;
+ lineCount = 0;
+
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "TraceCoreDataHandler.startLogging/fName=" + fName + ", fileOpen=" + fileOpen); //$NON-NLS-1$ //$NON-NLS-2$
+
+ // If file needs to be opened, open it.
+ this.fileOpen = fileOpen;
+ if( fileOpen ){
+ try {
+ plainOutput = new PrintWriter(new FileWriter( fName ));
+ }
+ catch (IOException e) {
+
+ engine.launcherError(LauncherErrorType.FILE);
+ return false;
+ }
+
+ }
+ return true;
+ }
+
+ /**
+ * Stops logging and closes file if needed.
+ */
+ public void stopLogging() {
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "TraceCoreDataHandler.stopLogging"); //$NON-NLS-1$
+ this.logging = false;
+ if( this.fileOpen ){
+ plainOutput.flush();
+ plainOutput.close();
+ }
+ stopSWMTHeadDumpLogging();
+ }
+
+ /**
+ * Flush and Close swmtHeadDumpOutput
+ */
+ private void stopSWMTHeadDumpLogging() {
+ if(swmtHeadDumpOutput != null){
+ swmtHeadDumpOutput.flush();
+ swmtHeadDumpOutput.close();
+ }
+ }
+
+ /**
+ * Open FileWriter for swmtHeadDumpOutput
+ */
+ private void startSWMTHeadDumpLogging(){
+ try {
+ File file = new File(swmtHeadDumpThreadInfo.getThreadFilePath());
+ File path = file.getParentFile();
+ if(!path.exists()){
+ path.mkdirs();
+ }
+ file.createNewFile();
+ if(swmtHeadDumpThreadInfo != null){
+ swmtHeadDumpOutput = new PrintWriter(new FileWriter( swmtHeadDumpThreadInfo.getThreadFilePath() ));
+ }
+ }
+ catch (IOException e) {
+ engine.launcherError(LauncherErrorType.FILE);
+ }
+ }
+
+ /**
+ * Processes trace data that is received. This method is called every time trace
+ * data is received when logging is on.
+ * @param traceLineStr trace data line
+ */
+ public void processDataLine(String traceLineStr) {
+
+ if (logging) {
+
+ if (traceLineStr != null) {
+
+ if(isMemSpyRelatedLine(traceLineStr)){
+ lineCount++;
+ }
+ // Reset timer every 10 MemSpy related lines.
+ if( lineCount > 10 ){
+ engine.restartErrorTimer();
+ lineCount = 0;
+ }
+
+ // If Line contains launcher error message
+ if( traceLineStr.contains( LAUNCHER_ERROR ) ){
+ handleLauncherErrorLine(traceLineStr);
+ }
+
+ // If line contains message of dumped traces
+ else if( traceLineStr.contains( DUMPED_TC_TRACES )){
+ handleDumpTCTracesLine();
+ }
+
+ // If line contains confirmation that Launcher is ready to receive new command
+ else if ( traceLineStr.contains(LAUNCHER_READY) ) {
+ handleLauncherReadyLine();
+ }
+ else if(traceLineStr.contains(MEMSPY_LAUNCHER_VERSION_PREFIX)){
+ handleLauncherVersionLine(traceLineStr);
+ }
+ //If launcher sends an progress message, restarting error timer so the timer wont reset progress
+ //this is done because of long taking progress was causing time outs.
+ else if(traceLineStr.contains(MEMSPY_PROGRESS)){
+ engine.restartErrorTimer();
+ }
+
+ // If receiving heap dump
+ else if( engine.getFirstTask() == TraceCoreEngine.MEMSPY_GET_HEAP_DUMP ){
+ handleHeadDumpLine(traceLineStr);
+ }
+
+ // If receiving SWMT log
+ else if( engine.getFirstTask() == TraceCoreEngine.MEMSPY_SWMT_UPDATE
+ || engine.getFirstTask() == TraceCoreEngine.MEMSPY_SWMT_RESET ){
+ handleSWMTLine(traceLineStr);
+ }
+
+ // If receiving thread info
+ else if( engine.getFirstTask() == TraceCoreEngine.MEMSPY_THREAD_INFO ){
+ handleThreadInfoLine(traceLineStr);
+ }
+
+ // Setting SWMT category low bits
+ else if( engine.getFirstTask() == TraceCoreEngine.MEMSPY_SET_CATEGORIES_LOW ){
+ handleCategoriesLowLine(traceLineStr);
+ }
+
+ // Setting SWMT category high bits
+ else if( engine.getFirstTask() == TraceCoreEngine.MEMSPY_SET_CATEGORIES_HIGH ){
+ handleCategoriesHighLine(traceLineStr);
+ }
+
+ // If Receiving thread list
+ else if( engine.getFirstTask() == TraceCoreEngine.MEMSPY_THREAD_LIST ){
+ handleThreadListLine(traceLineStr);
+ }
+
+ }
+ }
+
+ }
+
+ /**
+ * Checks that line has something to do with MemSpy related data.
+ * @param str line sting
+ * @return <code>true</code> if MemSpy related data, otherwise <code>false</code>.
+ */
+ private boolean isMemSpyRelatedLine(String str) {
+ return str.contains("HeapData") || str.contains("MemSpy");
+ }
+
+ private void handleLauncherVersionLine(String str) {
+ DbgUtility.println(DbgUtility.PRIORITY_LOOP, "TraceCoreDataHandler.processData/MEMSPY_LAUNCHER_VERSION_PREFIX"); //$NON-NLS-1$
+ String version = cutString(MEMSPY_LAUNCHER_VERSION_PREFIX, END_TAG, str);
+ engine.setMemSpyLauncherVersion(version);
+ }
+
+ private void handleLauncherReadyLine() {
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "TraceCoreDataHandler.processData/LAUNCHER_READY"); //$NON-NLS-1$
+ engine.memSpyReady();
+ }
+
+ private void handleDumpTCTracesLine() {
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "TraceCoreDataHandler.processData/DUMPED_TC_TRACES"); //$NON-NLS-1$
+ this.dumpedTraces = true;
+ }
+
+ private void handleLauncherErrorLine(String str) {
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "TraceCoreDataHandler.processData/LAUNCHER_ERROR"); //$NON-NLS-1$
+ if( str.contains("'") ){
+ str = str.substring( str.indexOf("'")+1 );
+ if( str.contains("'") ){
+ String error = str.substring( 0, str.indexOf("'") );
+ LauncherErrorType type = getErrorById(error);
+ engine.launcherError(type);
+ }
+ }
+ else{
+ // If no error code present, then parsing custom error message and sending information to console
+ String additionalErrorInfo = "";
+ // Getting error message string portion
+ String[] splitArr = str.split(Pattern.quote(":"));
+ if(splitArr.length == 2){
+ additionalErrorInfo = additionalErrorInfo + splitArr[1].trim();
+ }
+ // Passing launcher error forwards generic launcher error
+ engine.launcherError(LauncherErrorType.GENERAL_LAUNCHER_ERROR, additionalErrorInfo);
+ }
+ }
+
+ private void handleThreadListLine(String str) {
+ // If line contains "::" create new ThreadInfo-object
+ if ( str.contains( LAUNCHER_COLON ) ) {
+
+ threadInfo = new ThreadInfo();
+ threadInfo.setThreadName(str);
+ lastWasName = true;
+
+ }
+
+ // Save threadID into latest ThreadInfo-object and add info into thread list
+ if ( str.contains( LAUNCHER_THREAD_ID ) ){
+ if ( lastWasName ){
+ String threadID = str.substring( str.indexOf( LAUNCHER_THREAD_ID ) + LAUNCHER_THREAD_ID.length() );
+ threadID = threadID.trim();
+ threadInfo.setThreadID( threadID );
+ threadArray.add( threadInfo );
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "TraceCoreDataHandler.processData/LAUNCHER_THREAD_ID/id=" + threadInfo.getThreadID() + ", name=" + threadInfo.getThreadName()); //$NON-NLS-1$ //$NON-NLS-2$
+ lastWasName = false;
+ }
+ }
+ }
+
+ private void handleCategoriesHighLine(String str) {
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "TraceCoreDataHandler.processData/MEMSPY_SET_CATEGORIES_HIGH: " + str); //$NON-NLS-1$
+ }
+
+ private void handleCategoriesLowLine(String str) {
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "TraceCoreDataHandler.processData/MEMSPY_SET_CATEGORIES_LOW: " + str); //$NON-NLS-1$
+ if(str.contains(LAUNCHER_CATEGORY_NOT_SUPPORTED)){
+ //LAUNCHER_CATEGORY_NOT_SUPPORTED error
+ engine.launcherError(LauncherErrorType.CATEGORIES_NOT_SUPPORTED);
+ }
+ }
+
+ private void handleThreadInfoLine(String str) {
+ // Check for threads heap type
+ if ( str.contains( LAUNCHER_TYPE ) ){
+ if ( str.contains(LAUNCHER_SYMBIAN_OS_RHEAP) ){
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "TraceCoreDataHandler.processData/MEMSPY_THREAD_INFO"); //$NON-NLS-1$
+ heapTypeCorrect = true;
+ }
+ }
+ }
+
+ private void handleSWMTLine(String str) {
+ // Check for start tag
+ if ( str.contains( LAUNCHER_SWMT_LOG_START ) ) {
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "TraceCoreDataHandler.processData/LAUNCHER_SWMT_LOG_START"); //$NON-NLS-1$
+ this.writeFile = true;
+ engine.restartErrorTimer(); // Resetting error time instantly when getting start event of the logging
+ }
+
+ // If writing to file
+ if ( this.writeFile && str.contains(LAUNCHER_SWMTDATA) ){
+ this.writeLine( str );
+ }
+
+
+ // If we receive a Heap Dump line during SWMT logging
+ if ( this.writeFile &&
+ (str.contains(LAUNCHER_HEAPDATA)
+ || str.contains(LAUNCHER_HEAP_DUMP_START) || str.contains(LAUNCHER_HEAP_DUMP_END))){
+ handleHeapDumpDuringSWMTLogging(str);
+ }
+
+ // Check for end tag
+ if ( str.contains( LAUNCHER_SWMT_LOG_END ) ) {
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "TraceCoreDataHandler.processData/LAUNCHER_SWMT_LOG_END"); //$NON-NLS-1$
+ this.writeFile = false;
+ engine.restartErrorTimer(); // Resetting error time instantly when getting end event of the logging
+ }
+ }
+
+ /**
+ * Handling a Heap Dump line during SWMT logging
+ * @param str
+ */
+ private void handleHeapDumpDuringSWMTLogging(String str) {
+
+ //If we receiving a start point of Dump..
+ if(str.contains(LAUNCHER_HEAP_DUMP_START)){
+ DbgUtility.println(DbgUtility.PRIORITY_LOOP, "TraceCoreDataHandler.processData/Start SWMT Head Dump"); //$NON-NLS-1$
+ swmtHeadDumpThreadInfo = new ThreadInfo();
+ if(threadArray == null){
+ setThreadArray(new ArrayList<ThreadInfo>());
+ }
+ }
+ //If we receiving a Thread name of Dump, we create a new file for dump, and start dumping it
+ else if(str.contains(LAUNCHER_HEAP_INFO_FOR_THREAD)){
+
+ String threadName = getThreadNameFromInfo(str);
+ swmtHeadDumpThreadInfo.setThreadName(threadName);
+ DbgUtility.println(DbgUtility.PRIORITY_LOOP, "TraceCoreDataHandler.processData/SWMT Head Dump Thread name received: " +threadName); //$NON-NLS-1$
+
+ //String threadName, String threadID, String threadFilePath, Date date, HeapDumpType type
+ // Get file name for heap dump from engine
+ String filePath = MemSpyFileOperations.getFileNameForTempHeapDump(
+ swmtHeadDumpThreadInfo.getThreadName(), swmtHeadDumpThreadInfo.getDate());
+ swmtHeadDumpThreadInfo.setThreadFilePath(filePath);
+ startSWMTHeadDumpLogging();
+ writeSWMTHeadDumpLine(str);
+
+ DbgUtility.println(DbgUtility.PRIORITY_LOOP, "TraceCoreDataHandler.processData/SWMT Head Dump Thread file created: " +filePath); //$NON-NLS-1$
+
+ //Heap info's will act as start point for new Head dump, when Head Dumps are received during SWMT logging
+ //E.g. following Heap info is received:
+ //HeapData - mc_isiserver::Main - HEAP INFO FOR THREAD 'mc_isiserver::Main'
+ }
+
+ //If we receiving a end point of Dump...
+ else if(str.contains(LAUNCHER_HEAP_DUMP_END)){
+ DbgUtility.println(DbgUtility.PRIORITY_LOOP, "TraceCoreDataHandler.processData/End SWMT Head Dump"); //$NON-NLS-1$
+ threadArray.add( swmtHeadDumpThreadInfo );
+ stopSWMTHeadDumpLogging();
+ }
+
+ //Else we receiving a dump line, and writing it to the Dump file, not to SWMT file
+ else if(swmtHeadDumpThreadInfo != null && swmtHeadDumpOutput != null){
+ writeSWMTHeadDumpLine(str);
+ }
+ else{
+ DbgUtility.println(DbgUtility.PRIORITY_LOOP, "TraceCoreDataHandler.processData/LAUNCHER_HEAPDATA & MEMSPY_SWMT_UPDATE unknown line occured: " +str);
+ }
+ }
+
+ /**
+ * Get Thread name from Heap Info line
+ * @param str
+ * @return Thread name
+ */
+ private String getThreadNameFromInfo(String str) {
+ String name = str.substring(
+ (str.indexOf(LAUNCHER_HEAP_INFO_FOR_THREAD) + LAUNCHER_HEAP_INFO_FOR_THREAD.length()));
+ String separator = "'";
+ name = name.substring((name.indexOf(separator) + separator.length()), name.lastIndexOf(separator)).trim();
+ return name;
+ }
+
+ private void handleHeadDumpLine(String str) {
+ // Check for heap end tag
+ if ( str.contains( LAUNCHER_HEAP_DUMP_END ) ) {
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "TraceCoreDataHandler.processData/MEMSPY_GET_HEAP_DUMP/LAUNCHER_HEAP_DUMP_END"); //$NON-NLS-1$
+ this.writeFile = false;
+ }
+
+ // If writing to file
+ if ( this.writeFile && str.contains(LAUNCHER_HEAPDATA) ){
+ this.writeLine( str );
+ }
+
+ // Check for heap start tag
+ if ( str.contains( LAUNCHER_HEAP_DUMP_START ) ) {
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "TraceCoreDataHandler.processData/MEMSPY_GET_HEAP_DUMP/LAUNCHER_HEAP_DUMP_START"); //$NON-NLS-1$
+ this.writeFile = true;
+ }
+ }
+
+ /**
+ * Cut string from startTag to endTag
+ * @param startTag
+ * @param endTag
+ * @param str
+ * @return cutted string or str given if start and end tags does not found from given str
+ */
+ private static String cutString(String startTag, String endTag,
+ String str) {
+ if(!str.contains(startTag) && !str.contains(endTag)){
+ return str;
+ }
+ String ret = str.substring(str.indexOf(startTag) + startTag.length());
+ ret = ret.substring(0,ret.indexOf(endTag));
+ return ret;
+ }
+
+ /**
+ * Writes one line into opened file.
+ * @param line, Line that is written to file
+ */
+ private void writeLine(String line){
+ plainOutput.write(line + "\n");
+ }
+
+ /**
+ * Writes one line into opened file.
+ * @param line, Line that is written to file
+ */
+ private void writeSWMTHeadDumpLine(String line){
+ swmtHeadDumpOutput.write(line + "\n");
+ }
+
+
+ //
+ // Getters and setters for member variables
+ //
+
+ /**
+ * Set thread array
+ * @param threadArray
+ */
+ public void setThreadArray(ArrayList<ThreadInfo> threadArray) {
+ this.threadArray = threadArray;
+ }
+
+ /**
+ * Check if {@link TraceCoreDataHandler#LAUNCHER_COLON} was found in line
+ * @param lastWasName
+ */
+ public void setLastWasName(boolean lastWasName) {
+ this.lastWasName = lastWasName;
+ }
+
+ /**
+ * Check if heap type was correct
+ * @return <code>true</code> if heap type was correct, <code>false</code> otherwise.
+ */
+ public boolean isHeapTypeCorrect() {
+ return heapTypeCorrect;
+ }
+
+ /**
+ * Set heap type as correct
+ * @param heapTypeCorrect
+ */
+ public void setHeapTypeCorrect(boolean heapTypeCorrect) {
+ this.heapTypeCorrect = heapTypeCorrect;
+ }
+
+ /**
+ * Set dump traces
+ * @param dumpedTraces
+ */
+ public void setDumpedTraces(boolean dumpedTraces) {
+ this.dumpedTraces = dumpedTraces;
+ }
+
+ /**
+ * Check if trace was containing {@link TraceCoreDataHandler#DUMPED_TC_TRACES} lines
+ * @return <code>true</code> if dumped lines was found, <code>false</code> otherwise.
+ */
+ public boolean isDumpedTraces() {
+ return dumpedTraces;
+ }
+
+ /**
+ * Returns {@link LauncherErrorType} by its ordinal
+ * @param errorCodeAsString Error number as string
+ * @return {@link LauncherErrorType} or {@link LauncherErrorType#ACTIVATION} if no matching item found.
+ */
+ private LauncherErrorType getErrorById(String errorCodeAsString){
+
+ try {
+ int errorCode = Integer.parseInt(errorCodeAsString);
+ LauncherErrorType [] values = LauncherErrorType.values();
+ for (int i = 0; i < values.length; i++) {
+ if(errorCode == values[i].ordinal()){
+ return values[i];
+ }
+ }
+ } catch (NumberFormatException e) {
+ //If occurs, it's an internal error, MemSpy S60 side is giving id in wrong format.
+ e.printStackTrace();
+ MemSpyConsole.getInstance().printStackTrace(e);
+ }
+
+ return LauncherErrorType.ACTIVATION;
+ }
+
+ /**
+ * Get imported SWMT Heap Dumps
+ * @return imported SWMT Heap Dumps
+ */
+ public ArrayList<ThreadInfo> getImportedSWMTHeaps() {
+ return threadArray;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/model/TraceCoreEngine.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,1093 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+
+package com.nokia.s60tools.memspy.model;
+
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.ArrayList;
+import java.util.Date;
+
+import javax.swing.Timer;
+
+import com.nokia.s60tools.memspy.common.ProductInfoRegistry;
+import com.nokia.s60tools.memspy.containers.SWMTLogInfo;
+import com.nokia.s60tools.memspy.containers.ThreadInfo;
+import com.nokia.s60tools.memspy.containers.SWMTLogInfo.SWMTLogType;
+import com.nokia.s60tools.memspy.export.ITraceClientNotificationsIf;
+import com.nokia.s60tools.memspy.interfaces.IMemSpyTraceListener;
+import com.nokia.s60tools.memspy.interfaces.IMemSpyTraceListener.LauncherAction;
+import com.nokia.s60tools.memspy.interfaces.IMemSpyTraceListener.LauncherErrorType;
+import com.nokia.s60tools.memspy.plugin.MemSpyPlugin;
+import com.nokia.s60tools.memspy.preferences.MemSpyPreferences;
+import com.nokia.s60tools.memspy.ui.wizards.DeviceOrFileSelectionPage;
+import com.nokia.s60tools.memspy.util.MemSpyConsole;
+import com.nokia.s60tools.util.console.IConsolePrintUtility;
+import com.nokia.s60tools.util.debug.DbgUtility;
+
+
+/**
+ * <code>TraceCoreEngine</code> class offers public services for starting operations for
+ * getting heap dump and SWMT log data. It creates and manages list of sub tasks
+ * are requested sequentially until main operation chain is over (either successfully
+ * or with error).
+ *
+ * This class is tightly coupled with <code>TraceCoreDataHandler</code> class
+ * that parses trace data and passes flow control back to <code>TraceCoreEngine</code>
+ * between individual sub tasks.
+ *
+ * @see com.nokia.s60tools.memspy.model.TraceCoreDataHandler.java
+ */
+public class TraceCoreEngine implements ActionListener, ITraceClientNotificationsIf {
+
+ /**
+ * Enumerator for upper level operation progress status. Ordinal order of the operations should not be changed.
+ * Once operation status is advanced to <code>EProgressMemSpyOperationDone</code>
+ * the progress status is not initialized until wizard re-start, connection setting are changed, or an error occurs.
+ *
+ * The enumerator is used in order being able to give user best possible guidance on time-out error when we know
+ * the context in which the error has occurred.
+ */
+ public enum ProgressStatus{
+ EPROGRESS_INITIAL, // Initial status with no progress so far during current session
+ EPROGRESS_MEMSPY_LAUNCHED, // MemSpy has been launched successfully
+ EPROGRESS_FIRST_TASK_LAUNCHED, // First actual task for MemSpy is triggered (i.e. non-MemSpy launch task)
+ EPROGRESS_FIRST_TASK_DONE // First actual task for MemSpy completed successfully (i.e. non-MemSpy launch task)
+ }
+
+ // GroupIDs that are used
+ public final static String MEMSPY_LAUNCH = "10";
+ public final static String MEMSPY_THREAD_LIST = "11";
+ public final static String MEMSPY_THREAD_INFO = "12";
+ public final static String MEMSPY_GET_HEAP_DUMP = "13";
+ public final static String MEMSPY_SWMT_UPDATE = "14";
+ public final static String MEMSPY_SWMT_RESET = "16";
+ public final static String MEMSPY_STOP = "17";
+ public final static String MEMSPY_SET_CATEGORIES_LOW = "19";
+ public final static String MEMSPY_SET_CATEGORIES_HIGH = "20";
+ public final static String MEMSPY_SET_SWMT_HEAP_DUMP = "21";
+ public final static String MEMSPY_SET_HEAP_NAME_FILTER = "SUBSCRIBE_COMM_EVENT_SET_HEAP_NAME_FILTER";
+
+ // Time that device waits for line.
+ private final int SECOND = 1000;
+ private final int DEFAULT_WAIT_TIME = 20 * SECOND; // seconds
+ private final int MAX_WAIT_TIME = 60 * SECOND; // seconds
+ private int currentWaitTime;
+
+ /**
+ * Indicate that MemSpy Launcher data version is not received.
+ */
+ private static final int MEMSPY_LAUNCHER_VERSION_NOT_DEFINED = -1;
+
+ /* timer that is used in error correction */
+ private Timer errorTimer;
+
+ /* boolean value that is true when MemSpy is running */
+ private boolean MemSpyRunning;
+
+ /* Cycle number of swmt logs that is received next time */
+ private int cycleNumber;
+
+ /* interval between swmt logs */
+ private int interval;
+
+ /* timer that is used when receiving SWMT-logs via timer */
+ private Timer intervalTimer;
+
+ /* info of swmt-log that is currently received */
+ private SWMTLogInfo swmtLogInfo;
+
+ // Trace data handler
+ private TraceCoreDataHandler handler;
+
+ // Id of threads that is currently received
+ int threadID;
+
+ // Task list
+ private ArrayList<String> taskList;
+
+ // WizardPage, that is notified when operations are done.
+ private IMemSpyTraceListener wizardPage;
+
+ // Name of the file where heap dumps and SWMT-logs are written.
+ private String currentFile;
+
+ /**
+ * If S60 MemSpy is to be closed between cycles
+ */
+ private boolean resetBetweenCycles = false;
+
+ /**
+ * Stores MemSpy launcher communication version.
+ */
+ private int receivedMemSpyLauncherDataVersion = MEMSPY_LAUNCHER_VERSION_NOT_DEFINED;
+
+ /**
+ * Upper level operation progress status. Ordinal order of the operations should not be changed.
+ * Once operation status is advanced to <code>EProgressMemSpyOperationDone</code>
+ * the progress status is not initialized until wizard re-start, connection setting are changed, or an error occurs.
+ */
+ private ProgressStatus progressStatus = ProgressStatus.EPROGRESS_INITIAL;
+
+ /**
+ * Provides possibly additional error information about the occurred error.
+ */
+ private String additionalErrorInformation;
+
+ /**
+ * Constructor.
+ */
+ public TraceCoreEngine(){
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "TraceCoreEngine() Construct START"); //$NON-NLS-1$
+ this.MemSpyRunning = false;
+ this.handler = new TraceCoreDataHandler(this);
+ this.taskList = new ArrayList<String>();
+ this.errorTimer = null;
+ this.cycleNumber = 1;
+ this.interval = 0;
+ this.swmtLogInfo = null;
+ this.currentWaitTime = DEFAULT_WAIT_TIME;
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "TraceCoreEngine() Construct END"); //$NON-NLS-1$
+ }
+
+ /**
+ * Request thread list from MemSpyLauncher.
+ * @param threadArray array where thread names and id's are written
+ * @param wizard page which is notified when request is finished
+ * @return true, if connection to TraceCore established successfully, else false
+ */
+
+ public boolean requestThreadList( ArrayList<ThreadInfo> threadArray, DeviceOrFileSelectionPage wizard ){
+ this.wizardPage = wizard;
+
+ // Set handler values correct
+ handler.setLastWasName( false );
+ handler.setThreadArray( threadArray );
+
+ // if connection established successfully, return true
+ if( this.connect() ){
+
+ // Set handler values correct
+ handler.setLastWasName( false );
+ handler.setThreadArray( threadArray );
+
+ if( !this.MemSpyRunning ){
+ taskList.add( MEMSPY_LAUNCH );
+ }
+ taskList.add( MEMSPY_THREAD_LIST );
+ return this.runNextTask();
+ }
+ else{
+ return false;
+ }
+
+
+ }
+
+ /**
+ * Request Heap Dump from device and write it into text file
+ * @param threadID ID of thread which is requested from device
+ * @param wizardPage page which is notified when request is finished
+ * @param currentFile path of the file where Heap Dump is written
+ * @return true, if connection to TraceCore established successfully, else false
+ */
+ public boolean requestHeapDump( int threadID, IMemSpyTraceListener wizardPage, String currentFile ){
+
+ this.currentFile = currentFile;
+ this.wizardPage = wizardPage;
+ this.threadID = threadID;
+
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "TraceCoreEngine.requestHeapDump/threadID=" + threadID); //$NON-NLS-1$
+
+ if( this.connect() ){
+
+ // Reset heap type value
+ handler.setHeapTypeCorrect( false );
+
+ // Send id to trace,
+ if( !this.sendIntegerDataToLauncher(threadID) ){
+ launcherError(LauncherErrorType.ACTIVATION);
+ return false;
+ }
+ else{
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "TraceCoreEngine.requestHeapDump/activateId => OK"); //$NON-NLS-1$
+ }
+
+ if( !this.MemSpyRunning ){
+ taskList.add( MEMSPY_LAUNCH );
+ }
+
+ // Add tasks into task list
+ taskList.add( MEMSPY_THREAD_INFO );
+ taskList.add( MEMSPY_GET_HEAP_DUMP );
+
+ // start running tasks
+ return this.runNextTask();
+ }
+ else{
+ return false;
+ }
+ }
+
+ /**
+ * Request Heap Dump from device and write it into text file
+ * @param threadID ID of thread which is requested from device
+ * @param wizardPage page which is notified when request is finished
+ * @param currentFile path of the file where Heap Dump is written
+ * @return true, if connection to TraceCore established successfully, else false
+ */
+ public boolean requestHeapDump( String threadID, IMemSpyTraceListener wizardPage, String currentFile ){
+
+ return requestHeapDump( Integer.parseInt(threadID), wizardPage, currentFile );
+
+ }
+
+ /**
+ * Request SWMT-log from device and write it into file
+ * @param wizardPage page which is notified when request is finished
+ * @param currentFile path of the file where Heap Dump is written
+ * @param resetCycles should cycles be reseted
+ * @return true, if connection to TraceCore established successfully, else false
+ */
+ public boolean requestSWMTLog( IMemSpyTraceListener wizardPage, String currentFile, boolean resetCycles){
+ this.currentFile = currentFile;
+ this.wizardPage = wizardPage;
+
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "TraceCoreEngine.requestSWMTLog(resetCycles=" + resetCycles + ")/currentFile: " + currentFile); //$NON-NLS-1$ //$NON-NLS-2$
+
+ // if connection established successfully, return true
+ if( this.connect() ){
+
+ // stop and start MemSpy so that logging is reseted.
+ if( resetCycles == true ){
+ taskList.add( MEMSPY_STOP );
+ taskList.add( MEMSPY_LAUNCH );
+ }
+
+ // If MemSpy is not running launch it
+ if( !this.MemSpyRunning ){
+ taskList.add( MEMSPY_LAUNCH );
+ }
+
+ //Adding category settings requests, if the feature is supported
+ if(MemSpyPlugin.getDefault().isSWMTCategorySettingFeatureEnabled()){
+ taskList.add( MEMSPY_SET_CATEGORIES_LOW ); //LOW bytes has to be written always before high bytes
+ taskList.add( MEMSPY_SET_CATEGORIES_HIGH ); //HIGH bytes has to be written always after low bytes
+ }
+
+
+ // Set the name filter for User Heap SWMT category
+ if(MemSpyPreferences.isSWMTHeapDumpSelected() && !MemSpyPreferences.isProfileTrackedCategoriesSelected()) {
+ taskList.add( MEMSPY_SET_SWMT_HEAP_DUMP );
+ taskList.add( MEMSPY_SET_HEAP_NAME_FILTER );
+ }
+
+ taskList.add( MEMSPY_SWMT_UPDATE );
+
+ // start running tasks
+ return this.runNextTask();
+ }
+ else{
+ return false;
+ }
+ }
+
+ /**
+ * Starts timer based SWMT logging.
+ * @param wizardPage page which is notified when request is finished
+ * @param currentFile path of the file where Heap Dump is written
+ * @param resetInStart should cycles be reseted
+ * @param resetBetweenCycles if MemSpy S60 application is to be reseted between every cycle
+ * @param interval poll interval
+ * @return true, if connection to TraceCore established successfully, else false
+ */
+ public boolean startSWMTTimer( IMemSpyTraceListener wizardPage, int cycleNumber,
+ boolean resetInStart, boolean resetBetweenCycles, int interval ){
+ this.wizardPage = wizardPage;
+ this.resetBetweenCycles = resetBetweenCycles;
+
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "TraceCoreEngine.startSWMTTimer"); //$NON-NLS-1$
+
+ // if connection established successfully, return true
+ if( this.connect() ){
+ this.cycleNumber = cycleNumber - 1;
+ this.interval = interval;
+
+
+ if( resetInStart == true ){
+ taskList.add( MEMSPY_STOP );
+ taskList.add( MEMSPY_LAUNCH );
+
+ }
+
+ this.runNextTimedTask();
+
+ return true;
+ }
+ else{
+ return false;
+ }
+
+
+ }
+
+
+ /**
+ * Stops SWMT timer
+ * @return true if timer was stopped immediately, false if MemSpy operation was on-going and timer is stopped after after operations are done.
+ */
+ public boolean stopSWMTTimer(){
+
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "TraceCoreEngine.stopSWMTTimer"); //$NON-NLS-1$
+
+ // other variables to zero.
+ this.interval = 0;
+ this.cycleNumber = 1;
+
+ // if timer is, running stop it
+ if( intervalTimer != null && intervalTimer.isRunning() ){
+ intervalTimer.stop();
+ this.swmtLogInfo = null;
+ return true;
+ }
+ else{
+ return false;
+ }
+ }
+
+ /**
+ * addNextTimedTask.
+ * Adds next timed tasks into taskList if needed
+ */
+ private void runNextTimedTask(){
+
+ cycleNumber++;
+
+ // get new SWMT-object and set filename correct
+ swmtLogInfo = this.getNewSWMTInfo();
+ this.currentFile = swmtLogInfo.getPath();
+
+ // If MemSpy is not running launch it
+ if( !this.MemSpyRunning ){
+ taskList.add( MEMSPY_LAUNCH );
+ }
+ //If memSpy is running and we want to reset it between cycles
+ else if(this.MemSpyRunning && resetBetweenCycles == true ){
+ taskList.add( MEMSPY_STOP );
+ taskList.add( MEMSPY_LAUNCH );
+
+ }
+
+ //Adding category settings requests, if the feature is supported
+ if(MemSpyPlugin.getDefault().isSWMTCategorySettingFeatureEnabled()){
+ taskList.add( MEMSPY_SET_CATEGORIES_LOW ); //LOW bytes has to be written always before high bytes
+ taskList.add( MEMSPY_SET_CATEGORIES_HIGH ); //HIGH bytes has to be written always after low bytes
+ }
+
+ // Set the name filter for User Heap SWMT category
+ if(MemSpyPreferences.isSWMTHeapDumpSelected() && !MemSpyPreferences.isProfileTrackedCategoriesSelected()) {
+ taskList.add( MEMSPY_SET_SWMT_HEAP_DUMP );
+ taskList.add( MEMSPY_SET_HEAP_NAME_FILTER );
+ }
+
+
+ // Requesting SWMT update
+ taskList.add( MEMSPY_SWMT_UPDATE );
+
+ // start runnings tasks
+ this.runNextTask();
+ }
+
+ /**
+ * Function that handles calls when MemSpys operation is finished successfully
+ * This method is called from DataHandler every time tag <MEMSPY_LAUNCHER_READY>-tag received.
+ */
+ public void memSpyReady(){
+
+
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "TraceCoreEngine.memSpyReady"); //$NON-NLS-1$
+
+ //Check Launcher data version
+ checkMemSpyLauncherDataVersion();
+ //MemSpy launcher data version is received always before <MEMSPY_LAUNCHER_READY> -tag is received
+ //When version number is checked, returning -1 to received value
+ receivedMemSpyLauncherDataVersion = MEMSPY_LAUNCHER_VERSION_NOT_DEFINED;
+
+ // Stop logging trace data
+ handler.stopLogging();
+ // Stop listening trace data
+ MemSpyPlugin.getTraceProvider().stopListenTraceData();
+ // Stop timer
+ errorTimer.stop();
+
+ // Checking an updating progress status based on the completed task type
+ checkTaskForCurrentProgressStatus(this.taskList.get(0));
+
+ if( this.taskList.get(0) == MEMSPY_LAUNCH ){
+ //Setting timer value to MAX here when known that MemSpy Launcher in S60 target is OK
+ //(last successfully run command is MemSpy launch).
+ this.currentWaitTime = MAX_WAIT_TIME;
+
+ // MemSpy started successfully, update status
+ this.MemSpyRunning = true;
+
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "TraceCoreEngine.memSpyReady/MEMSPY_LAUNCH/MemSpyRunning=true"); //$NON-NLS-1$
+ if( this.taskList.size() >= 2 && this.taskList.get(1) == MEMSPY_THREAD_INFO ){
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "TraceCoreEngine.memSpyReady/MEMSPY_LAUNCH/activateId( threadID: "+ threadID); //$NON-NLS-1$
+ if( !this.sendIntegerDataToLauncher(threadID) ){
+ launcherError(LauncherErrorType.ACTIVATION);
+ }
+ else{
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "T raceCoreEngine.memSpyReady/MEMSPY_LAUNCH/activateId => OK"); //$NON-NLS-1$
+ }
+ }
+ }
+ else if( this.taskList.get(0) == MEMSPY_THREAD_LIST ){
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "TraceCoreEngine.memSpyReady/MEMSPY_THREAD_LIST"); //$NON-NLS-1$
+ this.wizardPage.operationFinished( LauncherAction.GET_THREAD_LIST );
+ }
+ else if( this.taskList.get(0) == MEMSPY_THREAD_INFO ){
+ // Heap info received
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "TraceCoreEngine.memSpyReady/MEMSPY_THREAD_INFO"); //$NON-NLS-1$
+
+ // If heap type is not correct, reset tasklist and return error
+ if( !handler.isHeapTypeCorrect() ){
+ this.taskList.clear();
+ this.wizardPage.deviceError( LauncherErrorType.HEAP_TYPE_WRONG );
+ }
+
+ // ignore dumped traces-messages.
+ if( handler.isDumpedTraces() ){
+ handler.setDumpedTraces( false );
+ }
+ }
+ else if( this.taskList.get(0) == MEMSPY_GET_HEAP_DUMP ){
+ // Heap Dump received
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "TraceCoreEngine.memSpyReady/MEMSPY_GET_HEAP_DUMP"); //$NON-NLS-1$
+
+ if( handler.isDumpedTraces() == false ){
+ // Tell wizard that request is finished
+ this.wizardPage.operationFinished( LauncherAction.GET_HEAP_DUMP );
+ }
+ else{
+ handler.setDumpedTraces( false );
+ this.launcherError(LauncherErrorType.HEAP_NOT_FOUND);
+ }
+ }
+ else if( this.taskList.get(0) == MEMSPY_SWMT_UPDATE || this.taskList.get(0) == MEMSPY_SWMT_RESET ){
+ // if SWMT log received
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "TraceCoreEngine.memSpyReady/MEMSPY_SWMT_UPDATE || MEMSPY_SWMT_RESET"); //$NON-NLS-1$
+
+ if( handler.isDumpedTraces() == false ){
+ // Tell wizard that request is finished
+
+ // if timed swmt-logging is on request notification after interval
+ if( swmtLogInfo != null ){
+
+ boolean timerRunning = false;
+
+ // if interval is more that zero, start counter and set timerRunning variable correct.
+ if( interval > 0 ){
+ intervalTimer = new Timer( interval * SECOND, this );
+ intervalTimer.start();
+ timerRunning = true;
+ }
+
+ // tell wizard that one log file has been received.
+ this.wizardPage.operationFinished( LauncherAction.TIMED_SWMT_UPDATE, swmtLogInfo, timerRunning);
+ swmtLogInfo = null;
+
+ }
+ else{
+ this.wizardPage.operationFinished( LauncherAction.SWMT_UPDATE );
+ }
+ }
+ else{
+ //Reset SWMT timer values.
+ this.stopSWMTTimer();
+
+ handler.setDumpedTraces( false );
+ this.launcherError(LauncherErrorType.HEAP_NOT_FOUND);
+ }
+ }
+ else if( this.taskList.get(0) == MEMSPY_STOP ){
+ MemSpyRunning = false;
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "TraceCoreEngine.memSpyReady/MEMSPY_STOP"); //$NON-NLS-1$
+ }
+
+ // Remove first task from list.
+ if(taskList.size() > 0){
+ this.taskList.remove(0);
+ // Updating progress status to next task launched status
+ // (only updated in case this is progress to previous situation).
+ setProgressStatus(ProgressStatus.EPROGRESS_FIRST_TASK_LAUNCHED);
+ }
+ // run next task
+ this.runNextTask();
+
+
+ }
+
+ /**
+ * Updates progress status based on given task id.
+ * Used setter method takes care that update is done only
+ * if there has been progress compared to previous situation.
+ * @param taskId task event for the task that was just completed
+ */
+ private void checkTaskForCurrentProgressStatus(String taskId) {
+ if( taskId == MEMSPY_LAUNCH ){
+ setProgressStatus(ProgressStatus.EPROGRESS_MEMSPY_LAUNCHED);
+ }
+ else{
+ // In case of other than launch task first task has been executed properly
+ setProgressStatus(ProgressStatus.EPROGRESS_FIRST_TASK_DONE);
+ }
+ }
+
+ /**
+ * Handles calls when launcher prints error message into trace.
+ * @param error error code
+ * @param clientContextErrorString provides optionally additional information about the error occurred
+ */
+ public void launcherError( LauncherErrorType error, String clientContextErrorString ){
+
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "TraceCoreEngine.launcherError/error: " + error); //$NON-NLS-1$
+
+ additionalErrorInformation = clientContextErrorString;;
+
+ handler.stopLogging();
+ // Stop listening trace data
+ MemSpyPlugin.getTraceProvider().stopListenTraceData();
+
+ // Stop timer
+ if( errorTimer != null ){
+ errorTimer.stop();
+ //Setting timer value to default when error occurred
+ this.currentWaitTime = DEFAULT_WAIT_TIME;
+ }
+
+ // if wizard has been shut down, don't send error message.
+ if( taskList.size() == 1 && taskList.get(0) == MEMSPY_STOP ){
+ return;
+ }
+ this.taskList.clear();
+ // Stop logging trace data
+
+ //
+ //When there are special handling about error, founding error codes and then call the wizard.
+ //But in default case, we just pass the error code to wizard to show the error.
+ //
+
+ // MemSpy not running.
+ if( error == LauncherErrorType.MEMSPY_NOT_RUNNING ){
+ wizardPage.deviceError( LauncherErrorType.MEMSPY_NOT_RUNNING );
+ this.MemSpyRunning = false;
+ }
+ else if( error == LauncherErrorType.NO_ANSWER_FROM_DEVICE ){
+ // No answer from device can happen because
+ if( handler.isDumpedTraces() ){
+ // Input data is corrupted and traces are dumped...
+ handler.setDumpedTraces( false );
+ wizardPage.deviceError( LauncherErrorType.DUMPED_TRACES );
+ }
+ else{
+ //..or connection is broken and we really has'nt got any response from device
+ wizardPage.deviceError( LauncherErrorType.NO_ANSWER_FROM_DEVICE );
+ }
+ }
+ else {
+ wizardPage.deviceError( error);
+ }
+
+ }
+
+
+ /**
+ * Function that is called when response from launcher is not received within reasonable time.
+ * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
+ */
+ public void actionPerformed(ActionEvent e) {
+
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "TraceCoreEngine.actionPerformed/e.getSource(): " + e.getSource().toString()); //$NON-NLS-1$
+
+ if( e.getSource() == errorTimer ){
+ // This function is called if MemSpy operation does not respond in time stored in currentWaitTime member variable.
+ // I.e. no answer has been received from the device in expected maximum time.
+ this.launcherError(LauncherErrorType.NO_ANSWER_FROM_DEVICE);
+ }
+ else if( e.getSource() == intervalTimer ){
+ this.runNextTimedTask();
+ // Notify wizard that SWMT receiving is started
+ wizardPage.startedReceivingSWMTLog();
+ intervalTimer.stop();
+ }
+
+ }
+
+
+ /**
+ * Shuts down MemSpy application. If some MemSpy operation is on-going schedule shutdown after that.
+ */
+ public void shutDownMemSpy(){
+
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "TraceCoreEngine.shutDownMemSpy"); //$NON-NLS-1$
+
+ // if MemSpy is running, send stop request
+ if( this.MemSpyRunning ) {
+ this.taskList.add( MEMSPY_STOP );
+ }
+
+ // If timer is not running( MemSpy is not currently operating ), run next task
+ if( errorTimer != null && !errorTimer.isRunning() ){
+ this.runNextTask();
+ }
+ disconnectTrace();
+ }
+
+ /**
+ * Check if MemSpy is running
+ * @return <code>true</code> if MemSpy is Running <code>false</code> otherwise.
+ */
+ public boolean isMemSpyRunning() {
+ return MemSpyRunning;
+ }
+
+ /**
+ * Establishes connection between plugin and device.
+ * @return true, is connection established successfully
+ */
+ private boolean connect(){
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "TraceCoreEngine.connect"); //$NON-NLS-1$
+ return MemSpyPlugin.getTraceProvider().connectTraceSource(this);
+ }
+
+ /**
+ * Disconnects connection between plugin and device if connection was started
+ * for this MemSpy run. Leaving connection up, if TraceViewer was already connected.
+ */
+ public void disconnectTrace() {
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "TraceCoreEngine.disconnectTrace"); //$NON-NLS-1$
+ MemSpyPlugin.getTraceProvider().disconnectTraceSource();
+ }
+
+ /**
+ * Sends current usage context-specific integer data to launcher.
+ * Integer data can contain values that can be expressed with 10 bytes
+ * i.e. only 10 lower bytes are taken into account when setting data.
+ * @param integerData integer data to be sent
+ * @return <code>false</code> if failed to send integer data, otherwise <code>true</code>
+ */
+ private boolean sendIntegerDataToLauncher(int integerData)
+ {
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "sendIntegerDataToLauncher: id=" + integerData); //$NON-NLS-1$
+ return MemSpyPlugin.getTraceProvider().sendIntData(integerData);
+ }
+
+ /**
+ * Sends current usage context-specific string message to launcher.
+ * @param stringData string data to send
+ * @param writesFile set to <code>true</code> if set trace handler needs to write some data into file
+ * @return <code>true</code> on success, otherwise <code>false</code>
+ */
+ private boolean sendStringDataToLauncher(String stringData, boolean writesFile){
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "TraceCoreEngine.sendMessage/message=" + stringData); //$NON-NLS-1$
+
+ if(! addDataProcessorAndSetupLogging(writesFile)){
+ return false;
+ }
+
+ if(! MemSpyPlugin.getTraceProvider().sendStringData(stringData)){
+ return false;
+ }
+
+ startErrorTimer();
+ return true;
+ }
+
+ /**
+ * activateTrace
+ * Sends activation/deactivation message via TraceCore
+ * @param group GroupID
+ * @param writesFile true, if set trace handler needs to write some data into file.
+ * return false if trace activation was not successful.
+ */
+ private boolean activateTrace( String group, boolean writesFile ){
+
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "TraceCoreEngine.activateTrace/group=" + group + ", writesFile=" + writesFile); //$NON-NLS-1$ //$NON-NLS-2$
+
+ if(! addDataProcessorAndSetupLogging(writesFile)){
+ return false;
+ }
+
+ if(! MemSpyPlugin.getTraceProvider().activateTrace(group)){
+ return false;
+ }
+
+ startErrorTimer();
+ return true;
+
+ }
+
+ /**
+ * Starts error time after request.
+ */
+ private void startErrorTimer() {
+ // Start Timer
+ errorTimer = new Timer( currentWaitTime, this );
+ errorTimer.start();
+ }
+
+ /**
+ * Adds dataprocessor and sets-up logging.
+ * @param writesFile true, if set trace handler needs to write some data into file.
+ * @return <code>true</code> in case of success, and <code>false</code> in case of some failure.
+ */
+ private boolean addDataProcessorAndSetupLogging(boolean writesFile) {
+
+ //Add DataProcessor to TraceViewer
+ if(! MemSpyPlugin.getTraceProvider().startListenTraceData(handler)){
+ return false;
+ }
+
+ // Start logging
+ if( !handler.startLogging(currentFile, writesFile ) ){
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * runNextTask
+ * Gets next task from list and sends it to TraceCore.
+ * @return false if operation fails.
+ */
+ private boolean runNextTask(){
+
+ try {
+ if( taskList.size() > 0 ){
+ String nextTask = taskList.get(0);
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "TraceCoreEngine.runNextTask/taskList.get(0)=" + nextTask); //$NON-NLS-1$
+
+ // Confirming that all necessary preparations for running the next task has been done.
+ prepareRunNextTask();
+
+ // Set writeFile value as false when task needs to write some data into file
+ if( nextTask == MEMSPY_GET_HEAP_DUMP || nextTask == MEMSPY_SWMT_UPDATE || nextTask == MEMSPY_SWMT_RESET ){
+ if( !activateTrace( nextTask, true ) ){
+ this.launcherError(LauncherErrorType.ACTIVATION);
+ return false;
+ }
+ }
+ else if(nextTask == MEMSPY_SET_HEAP_NAME_FILTER){
+ // This task used subscribe communication, instead of group IDs
+ // Send SWMT heap filter before activating command group
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "TraceCoreEngine.memSpyReady/MEMSPY_SET_HEAP_NAME_FILTER/sendMessage"); //$NON-NLS-1$
+ if( !this.sendStringDataToLauncher(getHeapNameFilterForSWMT(), false)){
+ launcherError(LauncherErrorType.ACTIVATION);
+ }
+ else{
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "TraceCoreEngine.memSpyReady/MEMSPY_SET_HEAP_NAME_FILTER/sendMessage => OK"); //$NON-NLS-1$
+ }
+ }
+ else{
+ if( !activateTrace( nextTask, false) ){
+ this.launcherError(LauncherErrorType.ACTIVATION);
+ return false;
+ };
+
+ }
+ }
+ else{
+ DbgUtility.println(DbgUtility.PRIORITY_LOOP, "TraceCoreEngine.runNextTask/empty taskList"); //$NON-NLS-1$
+ //Setting timer value to default when there are no tasks to run
+ this.currentWaitTime = DEFAULT_WAIT_TIME;
+ }
+ return true;
+
+ } catch (Exception e) {
+ String errMsg = "Unexpected exception in encountered in TraceCoreEngine.runNextTask: " + e;
+ MemSpyConsole.getInstance().println(errMsg , IConsolePrintUtility.MSG_ERROR);
+ return false;
+ }
+
+ }
+
+
+ /**
+ * Confirms that all necessary preparations for running the next task has been done.
+ */
+ private void prepareRunNextTask() {
+ if(this.taskList.get(0) == MEMSPY_SET_CATEGORIES_LOW ){
+ // Setting SWMT low bits data before activating command group
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "TraceCoreEngine.prepareRunNextTask/activateId( getCategoriesForSWMTLowBits(): "+ getCategoriesForSWMTLowBits()); //$NON-NLS-1$
+ if( !this.sendIntegerDataToLauncher( getCategoriesForSWMTLowBits()) ){
+ launcherError(LauncherErrorType.ACTIVATION );
+ }
+ else{
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "TraceCoreEngine.prepareRunNextTask/MEMSPY_SET_CATEGORIES_HIGH/activateId => OK"); //$NON-NLS-1$
+ }
+ }
+ else if( this.taskList.get(0) == MEMSPY_SET_CATEGORIES_HIGH ){
+ // Setting SWMT high bits data before activating command group
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "TraceCoreEngine.prepareRunNextTask/MEMSPY_SET_CATEGORIES_HIGH/activateId( getCategoriesForSWMTHighBits(): "+ getCategoriesForSWMTHighBits()); //$NON-NLS-1$
+ if( !this.sendIntegerDataToLauncher( getCategoriesForSWMTHighBits()) ){
+ launcherError(LauncherErrorType.ACTIVATION );
+ }
+ else{
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "TraceCoreEngine.prepareRunNextTask/MEMSPY_SET_CATEGORIES_HIGH/activateId => OK"); //$NON-NLS-1$
+ }
+ }
+ }
+
+ /**
+ * getNewSWMTInfo.
+ * Creates a new SWMTLogInfo object and sets correct filename and time into it.
+ * @return SWMTLogInfo-object
+ */
+ private SWMTLogInfo getNewSWMTInfo(){
+
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "TraceCoreEngine.getNewSWMTInfo"); //$NON-NLS-1$
+
+ // Create new SWMTLogInfo item.
+ SWMTLogInfo newItem = new SWMTLogInfo();
+
+ // set date correct
+ Date date = new Date();
+ newItem.setDate(date);
+
+
+ // set filename correct
+ newItem.setPath( MemSpyFileOperations.getTempFileNameForSWMTLog(cycleNumber, date) );
+
+ // set type
+ newItem.setType( SWMTLogType.DEVICE );
+
+ return newItem;
+ }
+
+ /**
+ * Get first task.
+ * @return first task from taskList.
+ */
+ public String getFirstTask(){
+ if( taskList.size() > 0 ){
+ return taskList.get(0);
+ }
+ else{
+ return null;
+ }
+ }
+
+ /**
+ * Gets lower 10 bits for SWMT categories that user wants to include into SWMT log.
+ * @return lower 10 bits for SWMT categories that user wants to include into SWMT log.
+ */
+ public int getCategoriesForSWMTLowBits() {
+ int lowBits = getCategoriesForSWMTWithKernelHandles() & 0x3ff; // ANDs away all the other that lower 10 bits
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "getCategoriesForSWMTLowBits(): " + String.format("0x%x", lowBits)); //$NON-NLS-1$
+ return lowBits;
+ }
+
+ /**
+ * Gets higher bits for SWMT categories that user wants to include into SWMT log.
+ * @return higher bits for SWMT categories that user wants to include into SWMT log.
+ */
+ public int getCategoriesForSWMTHighBits() {
+ int highBits = getCategoriesForSWMTWithKernelHandles()>>10;
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "getCategoriesForSWMTHighBits(): " + String.format("0x%x", highBits)); //$NON-NLS-1$
+ return highBits;
+ }
+
+ /**
+ * Gets SWMT categories that user wants to include into SWMT log.
+ * Includes always {@link SWMTCategoryConstants#CATEGORY_KERNELHANDLES} with it because SWMT Analyser
+ * needs it to be functional
+ * @return SWMT categories that user wants to include into SWMT log.
+ */
+ private int getCategoriesForSWMTWithKernelHandles() {
+ // CATEGORY_KERNELHANDLES is always included into fetched categories because data is required by SWMT analyser plug-in
+ //If SWMT Analyzer is modified so that Kernel Handles is not always needed then SWMTCategoryConstants.CATEGORY_KERNELHANDLES can be removed.
+ return getCategoriesForSWMT() | SWMTCategoryConstants.CATEGORY_KERNELHANDLES;
+ }
+
+
+ /**
+ * Gets SWMT categories that user wants to include into SWMT log.
+ * @return SWMT categories that user wants to include into SWMT log.
+ */
+ public int getCategoriesForSWMT() {
+ int sessionSpecificSWMTCategorySetting = MemSpyPreferences.getSWMTCategorySetting();
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "getCategoriesForSWMT(): " + String.format("0x%x", sessionSpecificSWMTCategorySetting)); //$NON-NLS-1$
+ SWMTCategoryConstants.debugPrintSWMTCategorySetting(sessionSpecificSWMTCategorySetting);
+ return sessionSpecificSWMTCategorySetting;
+ }
+
+ /**
+ * Sets SWMT categories that user wants to include into SWMT log.
+ * @param categoriesForSWMT SWMT categories that user wants to include into SWMT log.
+ * @param isProfileSettings <code>true</code> if these settings are profile settings
+ * <code>false</code> if these are custom settings
+ */
+ public void setCategoriesForSWMT(int categoriesForSWMT, boolean isProfileSettings) {
+ MemSpyPreferences.setSWMTCategorySetting(categoriesForSWMT, isProfileSettings);
+ }
+
+ /**
+ * Sets if User has select a Profile or not
+ * @param isProfileCategoriesSelected
+ */
+ public void setProfileTrackedCategoriesSelected(boolean isProfileCategoriesSelected) {
+ MemSpyPreferences.setProfileTrackedCategoriesSelected(isProfileCategoriesSelected);
+ }
+
+ /**
+ * Gets if User has select a Profile or not
+ * @return <code>true</code> if one of the profiles has been selected
+ */
+ public boolean isProfileTrackedCategoriesSelected() {
+ return MemSpyPreferences.isProfileTrackedCategoriesSelected();
+ }
+
+ /**
+ * Gets SWMT HeapNameFilter to filter User Heaps in SWMT log.
+ * @return SWMT HeapNameFilter that user wants to include into SWMT log.
+ */
+ public String getHeapNameFilterForSWMT() {
+ String filter = MemSpyPreferences.getSWMTHeapNameFilter();
+
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "getHeapNameFilterForSWMT(): " + filter); //$NON-NLS-1$
+ return filter;
+ }
+
+ /**
+ * Sets SWMT HeapNameFilter to filter User Heaps in SWMT log.
+ * @param HeapNameFilter SWMT HeapNameFilter that user wants to include into SWMT log.
+ */
+ public void setHeapNameFilterForSWMT(String heapNameFilterForSWMT) {
+ MemSpyPreferences.setSWMTHeapNameFilter(heapNameFilterForSWMT);
+ }
+
+ /**
+ * Restarts error timer
+ */
+ public void restartErrorTimer() {
+ if( errorTimer != null && errorTimer.isRunning() ){
+ errorTimer.restart();
+ }
+ }
+
+ /**
+ * Notify about MemSpy Launcher S60 application version
+ * @param version in format "x", e.g "1".
+ */
+ public void setMemSpyLauncherVersion(String version) {
+ String msg = "MemSpy Launcher data version: '" +version +"' detected in S60 target.";
+ DbgUtility.println(DbgUtility.PRIORITY_LOOP, msg);
+ MemSpyConsole.getInstance().println(msg);
+
+ receivedMemSpyLauncherDataVersion = Integer.parseInt(version);
+ }
+
+ /**
+ * Check if received MemSpy Launcher data version is at least required version
+ */
+ private void checkMemSpyLauncherDataVersion() {
+ int requiredVersion = ProductInfoRegistry.getRequiredMemSpyLauncherDataVersion();
+ DbgUtility.println(DbgUtility.PRIORITY_LOOP, "Required MemSpy Launcher data version: " +requiredVersion);
+ if(requiredVersion > receivedMemSpyLauncherDataVersion){
+ this.launcherError(LauncherErrorType.TOO_OLD_MEMSPY_LAUNCHER_DATAVERSION);
+ }
+ }
+
+ /**
+ * Get Heap Dump files that has been imported during SWMT logging.
+ * @return list about imported Heap Dumps.
+ */
+ public ArrayList<ThreadInfo> getImportedSWMTHeaps() {
+ return handler.getImportedSWMTHeaps();
+ }
+
+ /**
+ * Gets progress status for current wizard session with current connection settings.
+ * @return Progress status for current wizard session with current connection settings.
+ */
+ public ProgressStatus getProgressStatus() {
+ return progressStatus;
+ }
+
+ /**
+ * Sets progress status if there has been further progress after recent progress status update.
+ * @param progressStatus the progressStatus to set
+ */
+ private void setProgressStatus(ProgressStatus progressStatus) {
+ if(progressStatus.ordinal() > this.progressStatus.ordinal()){
+ this.progressStatus = progressStatus;
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "setProgressStatus: " + this.progressStatus.name()); //$NON-NLS-1$
+ }
+ }
+
+ /**
+ * Resets progress status back into initial value.
+ */
+ public void resetProgressStatus() {
+ this.progressStatus = ProgressStatus.EPROGRESS_INITIAL;
+ }
+
+ /**
+ * Delegates launcher error info further without any additional information
+ * @param generalLauncherError launcher error occurred
+ */
+ public void launcherError(LauncherErrorType launcherError) {
+ launcherError(launcherError, "");
+ }
+
+ /**
+ * Gets possible additional information related to occurred error.
+ * @return string containing additional information related to occurred error
+ */
+ public String getAdditionalErrorInformation() {
+ return additionalErrorInformation;
+ }
+
+ /* (non-Javadoc)
+ * @see com.nokia.s60tools.memspy.export.ITraceClientNotificationsIf#notifyError(java.lang.String)
+ */
+ public void notifyError(String message) {
+ // Currently only showing trace errors on console
+ MemSpyConsole.getInstance().println(message, MemSpyConsole.MSG_ERROR);
+ }
+
+ /* (non-Javadoc)
+ * @see com.nokia.s60tools.memspy.export.ITraceClientNotificationsIf#notifyInformation(java.lang.String)
+ */
+ public void notifyInformation(String message) {
+ // Currently only showing trace informative messages on console
+ MemSpyConsole.getInstance().println(message, MemSpyConsole.MSG_NORMAL);
+ }
+
+ /* (non-Javadoc)
+ * @see com.nokia.s60tools.memspy.export.ITraceClientNotificationsIf#notifyWarning(java.lang.String)
+ */
+ public void notifyWarning(String message) {
+ // Currently only showing trace warnings on console
+ MemSpyConsole.getInstance().println(message, MemSpyConsole.MSG_WARNING);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/model/UserEnteredData.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,373 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+
+package com.nokia.s60tools.memspy.model;
+
+import org.eclipse.jface.dialogs.IDialogSettings;
+
+import com.nokia.s60tools.memspy.plugin.MemSpyPlugin;
+
+/**
+ * This class is used to save and restore data which is entered by user in
+ * wizard pages.
+ *
+ */
+public class UserEnteredData {
+
+ // sections names for each wizard page
+ private static final String SECTION_SELECT_ACTION = "SelectActionPage";
+ private static final String SECTION_IMPORT_HEAP = "SelectDeviceOrFile";
+ private static final String SECTION_COMPARE_HEAPS_FIRST = "CompareHeapsFirst";
+ private static final String SECTION_COMPARE_HEAPS_SECOND = "CompareHeapsSecond";
+ private static final String SECTION_DEFINE_OUTPUT = "OutputFile";
+ private static final String SECTION_IMPORT_SWMT = "SWMT";
+ private static final String SECTION_PARAMETER_FILES = "ParameterFiles";
+
+
+ // Item key names.
+ private static final String PREVIOUS_RADIO_BUTTON_SELECTION = "PreviousRadioButtonSelection";
+ private static final String PREVIOUS_IMPORTED_FILES = "PreviousFiles";
+ private static final String PREVIOUS_INTERVAL = "Interval";
+
+ /**
+ * How many previously entered values are saved
+ */
+ public static final int MAX_SAVED_VALUES = 5;
+
+
+ /**
+ * Enumeration for actions available
+ */
+ public static enum ValueTypes { SELECT_ACTION,
+ IMPORT_HEAP,
+ COMPARE_HEAP_FIRST_HEAP,
+ COMPARE_HEAP_SECOND_HEAP,
+ SWMT,
+ OUTPUT_FILE}
+
+ /**
+ * Returns previous radio button selection from given valuetype
+ * @param valueType what radio button selection is requested
+ * @return previous radio button selection
+ */
+ public int getPreviousRadioButtonSelection( ValueTypes valueType) {
+ try {
+ int retval = 0;
+
+ // Get int from that section where value is saved.
+
+ switch(valueType){
+ case SELECT_ACTION:{
+ IDialogSettings section = getSection(SECTION_SELECT_ACTION);
+ if (section != null) {
+ retval = section.getInt(PREVIOUS_RADIO_BUTTON_SELECTION);
+
+ }
+ break;
+ }
+ case IMPORT_HEAP:{
+ IDialogSettings section = getSection(SECTION_IMPORT_HEAP);
+ if (section != null) {
+ retval = section.getInt(PREVIOUS_RADIO_BUTTON_SELECTION);
+ }
+ break;
+ }
+ case COMPARE_HEAP_FIRST_HEAP:{
+ IDialogSettings section = getSection(SECTION_COMPARE_HEAPS_FIRST);
+ if (section != null) {
+ retval = section.getInt(PREVIOUS_RADIO_BUTTON_SELECTION);
+
+ }
+ break;
+ }
+ case COMPARE_HEAP_SECOND_HEAP:{
+ IDialogSettings section = getSection(SECTION_COMPARE_HEAPS_SECOND);
+ if (section != null) {
+ retval = section.getInt(PREVIOUS_RADIO_BUTTON_SELECTION);
+
+ }
+ break;
+ }
+ case SWMT:{
+ IDialogSettings section = getSection(SECTION_IMPORT_SWMT);
+ if (section != null) {
+ retval = section.getInt(PREVIOUS_RADIO_BUTTON_SELECTION);
+
+ }
+ break;
+ }
+ default:{
+ break;
+ }
+ }
+ return retval;
+ } catch (Exception e) {
+ return 0;
+ }
+ }
+
+ /**
+ * Saves radio button selection into correct section
+ * @param valueType type of radio button
+ * @param value radio button value
+ */
+ public void saveRadioButtonSelection(ValueTypes valueType, int value) {
+ try {
+
+ // Save integer into correct section.
+
+ switch(valueType){
+ case SELECT_ACTION:{
+ IDialogSettings section = getSection(SECTION_SELECT_ACTION);
+ if (section != null) {
+ section.put(PREVIOUS_RADIO_BUTTON_SELECTION, value);
+ }
+ break;
+ }
+ case IMPORT_HEAP:{
+ IDialogSettings section = getSection(SECTION_IMPORT_HEAP);
+ if (section != null) {
+ section.put(PREVIOUS_RADIO_BUTTON_SELECTION, value);
+ }
+ break;
+ }
+ case COMPARE_HEAP_FIRST_HEAP:{
+ IDialogSettings section = getSection(SECTION_COMPARE_HEAPS_FIRST);
+ if (section != null) {
+ section.put(PREVIOUS_RADIO_BUTTON_SELECTION, value);
+ }
+ break;
+ }
+ case COMPARE_HEAP_SECOND_HEAP:{
+ IDialogSettings section = getSection(SECTION_COMPARE_HEAPS_SECOND);
+ if (section != null) {
+ section.put(PREVIOUS_RADIO_BUTTON_SELECTION, value);
+ }
+
+ break;
+ }
+ case SWMT:{
+ IDialogSettings section = getSection(SECTION_IMPORT_SWMT);
+ if (section != null) {
+ section.put(PREVIOUS_RADIO_BUTTON_SELECTION, value);
+ }
+ break;
+ }
+ default:{
+ break;
+ }
+ }
+
+
+ } catch (Exception E) {
+ // No actions needed
+ }
+ }
+
+ /**
+ * Returns wanted section
+ * @param section name of the wanted section
+ * @return wanted section
+ */
+ protected IDialogSettings getSection(String section) {
+ IDialogSettings retVal = null;
+ if (MemSpyPlugin.getDefault().getDialogSettings() != null) {
+ retVal = MemSpyPlugin.getDefault().getDialogSettings().getSection(section);
+ if (retVal == null) {
+ retVal = MemSpyPlugin.getDefault().getDialogSettings().addNewSection(section);
+ }
+ }
+ return retVal;
+ }
+
+
+ /**
+ * Returns values user has previously entered to wizard pages.
+ * @param valueType type of the values
+ * @return user's previous values
+ */
+ public String[] getPreviousValues(ValueTypes valueType) {
+ try {
+ String[] retVal = null;
+
+ // get value from correct section
+ switch (valueType) {
+ case IMPORT_HEAP: {
+ retVal = getPreviousPaths(SECTION_IMPORT_HEAP, PREVIOUS_IMPORTED_FILES);
+ break;
+ }
+ case COMPARE_HEAP_FIRST_HEAP: {
+ retVal = getPreviousPaths(SECTION_COMPARE_HEAPS_FIRST, PREVIOUS_IMPORTED_FILES);
+ break;
+ }
+ case COMPARE_HEAP_SECOND_HEAP: {
+ retVal = getPreviousPaths(SECTION_COMPARE_HEAPS_SECOND, PREVIOUS_IMPORTED_FILES);
+ break;
+ }
+ case OUTPUT_FILE:{
+ retVal = getPreviousPaths(SECTION_DEFINE_OUTPUT, PREVIOUS_IMPORTED_FILES);
+ break;
+ }
+ case SWMT:{
+ retVal = getPreviousPaths(SECTION_IMPORT_SWMT, PREVIOUS_INTERVAL);
+ break;
+ }
+ default:{
+ break;
+ }
+ }
+
+ return retVal;
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ /**
+ * Saves user's latest value.
+ * @param pathType value type
+ * @param value value to be saved
+ */
+ public void saveValue(ValueTypes pathType, String value) {
+ if (value.trim().length() < 1)
+ return;
+
+ try {
+ switch (pathType) {
+ case IMPORT_HEAP: {
+ savePath(value, PREVIOUS_IMPORTED_FILES, getSection(SECTION_IMPORT_HEAP));
+ break;
+ }
+
+ case COMPARE_HEAP_FIRST_HEAP: {
+ savePath(value, PREVIOUS_IMPORTED_FILES, getSection(SECTION_COMPARE_HEAPS_FIRST));
+
+ break;
+ }
+ case COMPARE_HEAP_SECOND_HEAP:{
+ savePath(value, PREVIOUS_IMPORTED_FILES, getSection(SECTION_COMPARE_HEAPS_SECOND));
+
+ break;
+ }
+ case OUTPUT_FILE:{
+ savePath(value, PREVIOUS_IMPORTED_FILES, getSection(SECTION_DEFINE_OUTPUT));
+ break;
+ }
+ case SWMT:{
+ savePath(value, PREVIOUS_INTERVAL, getSection(SECTION_IMPORT_SWMT));
+ break;
+ }
+ default:{
+ break;
+ }
+ }
+ } catch (Exception E) {
+ // No actions needed
+ }
+ }
+
+
+ /**
+ * Returns previously entered values of wanted context (i.e. wizard page).
+ * @param section section which contains array
+ * @param array name of the array whose values are needed
+ * @return previously entered paths of given section
+ */
+ protected String[] getPreviousPaths(String section, String array) {
+ String[] retVal = null;
+ IDialogSettings sect = getSection(section);
+ if (sect != null) {
+ retVal = sect.getArray(array);
+ }
+
+ return retVal;
+ }
+
+ /**
+ * Saves given path to correct section in dialog_settings.xml
+ * @param path path to save
+ * @param array name of the array which contains correct values
+ * @param section section which has array
+ */
+ protected void savePath(String path, String array, IDialogSettings section) {
+ if (section != null) {
+ String[] previousValues = section.getArray(array);
+
+ // No previous values exist
+ if (previousValues == null) {
+ previousValues = new String[1];
+ previousValues[0] = path;
+ // Previous values exists
+ } else {
+ int valuesCount = previousValues.length;
+
+ boolean valueExisted = false;
+ // see if passed value already exist.
+ for (int i = 0; i < valuesCount; i++) {
+ if (previousValues[i].compareToIgnoreCase(path) == 0) {
+ valueExisted = true;
+
+ // passed value exists, move it to first position
+ for (int j = i; j > 0; j--) {
+ previousValues[j] = previousValues[j-1];
+ }
+ previousValues[0] = path;
+
+ break;
+ }
+ }
+
+ // passed value did not exist, add it to first position (and move older values "down")
+ if (!valueExisted) {
+ if (valuesCount >= MAX_SAVED_VALUES) {
+ for (int i = valuesCount-1; i > 0; i--) {
+ previousValues[i] = previousValues[i-1];
+ }
+ previousValues[0] = path;
+ } else {
+ String[] values = new String[valuesCount + 1];
+ values[0] = path;
+ for (int i = 0; i < valuesCount; i++) {
+ values[i+1] = previousValues[i];
+ }
+ previousValues = values;
+ }
+ }
+ }
+ section.put(array, previousValues);
+ }
+ }
+
+
+ /**
+ * Get selections for dialog
+ * @return parameter files section
+ */
+ public static IDialogSettings getParameterFilesSection() {
+ IDialogSettings retVal = null;
+ if (MemSpyPlugin.getDefault().getDialogSettings() != null) {
+ retVal = MemSpyPlugin.getDefault().getDialogSettings().getSection(SECTION_PARAMETER_FILES);
+ if (retVal == null) {
+ retVal = MemSpyPlugin.getDefault().getDialogSettings().addNewSection(SECTION_PARAMETER_FILES);
+ }
+ }
+ return retVal;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/plugin/MemSpyPlugin.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,363 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+
+package com.nokia.s60tools.memspy.plugin;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+
+import org.eclipse.core.runtime.FileLocator;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtension;
+import org.eclipse.core.runtime.IExtensionPoint;
+import org.eclipse.core.runtime.IExtensionRegistry;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+
+import com.nokia.s60tools.memspy.export.ITraceClientNotificationsIf;
+import com.nokia.s60tools.memspy.export.ITraceDataProcessor;
+import com.nokia.s60tools.memspy.export.ITraceProvider;
+import com.nokia.s60tools.memspy.resources.ImageResourceManager;
+import com.nokia.s60tools.memspy.util.MemSpyConsole;
+import com.nokia.s60tools.util.debug.DbgUtility;
+
+
+/**
+ * The activator class controls the plug-in life cycle.
+ */
+public class MemSpyPlugin extends AbstractUIPlugin {
+
+ /**
+ * Plug-in ID for Launcher plug-in.
+ */
+ public static final String MEMSPY_TRACE_PLUGIN_ID = "com.nokia.s60tools.memspy.trace";//$NON-NLS-1$
+ /**
+ * Launcher plug-in binaries directory name.
+ */
+ public static final String LAUNCHER_BINARIES_DIR_NAME = "Launcher.binaries";//$NON-NLS-1$
+
+ /**
+ * Trace provider extension name.
+ */
+ final String EXTENSION_TRACE_PROVIDER = "traceprovider"; //$NON-NLS-1$
+
+ /**
+ * Plug-in ID constant.
+ */
+ public static final String PLUGIN_ID = "com.nokia.s60tools.memspy";
+
+ /**
+ * Member for storing plug-in install path.
+ */
+ private String pluginInstallPath = "";
+
+ /**
+ * Shared plug-in instance
+ */
+ private static MemSpyPlugin plugin;
+
+ /**
+ * Storing reference to possibly installed trace provider plug-in.
+ */
+ private static ITraceProvider traceProvider;
+
+ /**
+ * Preferences store instance reference.
+ */
+ private static IPreferenceStore prefsStore;
+
+ /**
+ * SWMT category setting feature is enabled by default, but may be disabled in case device does not support it.
+ */
+ boolean isSWMTCategorySettingFeatureEnabled = true;
+
+ /**
+ * The constructor
+ */
+ public MemSpyPlugin() {
+ plugin = this;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
+ */
+ public void start(BundleContext context) throws Exception {
+ super.start(context);
+ plugin = this;
+
+ String pluginInstallLocation = getPluginInstallPath();
+ String imagesPath = getImagesPath(pluginInstallLocation);
+
+ // Loading images required by this plug-in
+ ImageResourceManager.loadImages(imagesPath);
+
+ // Getting installed trace provider plug-in if available
+ traceProvider = findTraceProviderExtension();
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
+ */
+ public void stop(BundleContext context) throws Exception {
+ plugin = null;
+ super.stop(context);
+ }
+
+ /**
+ * Returns the shared instance
+ *
+ * @return the shared instance
+ */
+ public static MemSpyPlugin getDefault() {
+ return plugin;
+ }
+
+ /**
+ * Get plugin installation path
+ * @return the path where this plugin is installed
+ */
+ public static String getPluginInstallPath() {
+ try {
+ if ( plugin.pluginInstallPath.equals("") ) { //$NON-NLS-1$
+ // URL to the plugin's root ("/")
+ URL relativeURL = plugin.getBundle().getEntry("/"); //$NON-NLS-1$
+ // Converting into local path
+ URL localURL = FileLocator.toFileURL(relativeURL);
+ // Getting install location in correct form
+ File f = new File(localURL.getPath());
+ plugin.pluginInstallPath = f.getAbsolutePath();
+ }
+ return plugin.pluginInstallPath;
+ } catch (Exception e) {
+ return ""; //$NON-NLS-1$
+ }
+ }
+
+ /**
+ * Gets images path relative to given plugin install path.
+ * @param pluginInstallPath Plugin installation path.
+ * @return Path were image resources are located.
+ * @throws IOException
+ */
+ private String getImagesPath(String pluginInstallPath) throws IOException{
+ return pluginInstallPath
+ + File.separatorChar + "icons"; //$NON-NLS-1$
+ }
+
+ /**
+ * This must be called from UI thread. If called
+ * from non-ui thread this returns <code>null</code>.
+ * @return Currently active workbench page.
+ */
+ public static IWorkbenchPage getCurrentlyActivePage(){
+ return getDefault().getWorkbench().getActiveWorkbenchWindow().getActivePage();
+ }
+
+ /**
+ * This must be called from UI thread. If called
+ * from non-UI thread this returns <code>null</code>.
+ * @return The shell of the currently active workbench window..
+ */
+ public static Shell getCurrentlyActiveWbWindowShell(){
+ IWorkbenchPage page = getCurrentlyActivePage();
+ if(page != null){
+ return page.getWorkbenchWindow().getShell();
+ }
+ return null;
+ }
+
+ /**
+ * Checks if SWMT category setting feature is enabled.
+ * @return <code>true</code> if enabled, otherwise <code>false</code>.
+ */
+ public boolean isSWMTCategorySettingFeatureEnabled() {
+ return isSWMTCategorySettingFeatureEnabled;
+ }
+
+ /**
+ * Sets if SWMT category setting feature is enabled.
+ * @param isSWMTCategorySettingFeatureEnabled <code>true</code> if enabled, otherwise <code>false</code>.
+ */
+ public void setSWMTCategorySettingFeatureEnabled(
+ boolean isSWMTCategorySettingFeatureEnabled) {
+ this.isSWMTCategorySettingFeatureEnabled = isSWMTCategorySettingFeatureEnabled;
+ }
+
+ /**
+ * Gets MemSpy Launcher plugin's binaries directory path
+ * @return path were Launcher binaries are located.
+ */
+ public String getMemspyLauncherBinDir(){
+
+ Bundle bundle = Platform
+ .getBundle(MEMSPY_TRACE_PLUGIN_ID); //$NON-NLS-1$
+
+ String launcherBinDir = null;
+ try {
+ // URL to the Launcher binaries
+ URL relativeURL = bundle.getEntry(LAUNCHER_BINARIES_DIR_NAME); //$NON-NLS-1$
+ // Converting into local path
+ URL localURL = FileLocator.toFileURL(relativeURL);
+ // Getting install location in correct form
+ File file = new File(localURL.getPath());
+ launcherBinDir = file.getAbsolutePath();
+ MemSpyConsole.getInstance().println("MemSpyLauncher binaries dir detected: " +launcherBinDir);
+
+ } catch (IOException e) {
+ MemSpyConsole.getInstance().println("MemSpyLauncher binaries dir detection failed, reason: " +e);
+ e.printStackTrace();
+ }
+ return launcherBinDir;
+
+ }
+
+ /**
+ * Returns PreferenceStore where plugin preferences are stored.
+ * @return PreferenceStore where plugin preferences are stored
+ */
+ public static IPreferenceStore getPrefsStore() {
+ if (prefsStore == null){
+ prefsStore = getDefault().getPreferenceStore();
+ }
+
+ return prefsStore;
+ }
+
+ /**
+ * Gets trace provider interface instance if available.
+ * @return trace provider interface instance or <code>null</code> if not available
+ */
+ public static ITraceProvider getTraceProvider(){
+ if(isTraceProviderAvailable()){
+ return traceProvider;
+ }
+ // Otherwise returning a dummy provider instance
+ return createDummyTraceProviderInstance();
+ }
+
+ /**
+ * Creates a dummy trace provider instance.
+ * Client can safely reference to this dummy instance without any <code>NullPointerException</code>
+ * problems etc. However the corresponding functionalities from UI should be disables.
+ * @return dummy trace provider instance.
+ */
+ private static ITraceProvider createDummyTraceProviderInstance() {
+ // Creating just a dummy provider instance that does not do anything
+ return new ITraceProvider() {
+
+ public void stopListenTraceData() {
+ // dummy provider does not take any actions
+ }
+
+ public boolean startListenTraceData(ITraceDataProcessor dataProcessor) {
+ // dummy provider does not take any actions
+ return false;
+ }
+
+ public boolean sendStringData(String stringData) {
+ // dummy provider does not take any actions
+ return false;
+ }
+
+ public boolean sendIntData(int integerData) {
+ // dummy provider does not take any actions
+ return false;
+ }
+
+ public String getTraceSourcePreferencePageId() {
+ // dummy provider does not take any actions
+ return null;
+ }
+
+ public String getDisplayNameForCurrentConnection() {
+ return "<no trace plug-in installed>";
+ }
+
+ public void disconnectTraceSource() {
+ // dummy provider does not take any actions
+ }
+
+ public boolean connectTraceSource(
+ ITraceClientNotificationsIf traceClient) {
+ // dummy provider does not take any actions
+ return false;
+ }
+
+ public boolean activateTrace(String traceGroupID) {
+ // dummy provider does not take any actions
+ return false;
+ }
+
+ };
+ }
+
+ /**
+ * Checks if trace provider plug-in is available.
+ * @return <code>true</code> if trace provider interface available, otherwise <code>false</code>
+ */
+ public static boolean isTraceProviderAvailable(){
+ return (traceProvider != null);
+ }
+
+ /**
+ * Tries to find trace provider plug-ins. Selecting the first found one.
+ * @return reference to trace provider instance if found, otherwise <code>null</code>
+ */
+ ITraceProvider findTraceProviderExtension() {
+ try {
+ IExtensionRegistry er = Platform.getExtensionRegistry();
+ IExtensionPoint ep = er.getExtensionPoint(PLUGIN_ID, EXTENSION_TRACE_PROVIDER);
+ String uniqueIdentifier = ep.getUniqueIdentifier();
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "Found extension point: " + uniqueIdentifier); //$NON-NLS-1$
+ IExtension[] extensions = ep.getExtensions();
+
+ // if plug-ins were found.
+ if (extensions != null && extensions.length > 0) {
+
+ // read all found trace providers
+ for (int i = 0; i < extensions.length; i++) {
+ IConfigurationElement[] ce = extensions[i].getConfigurationElements();
+ if (ce != null && ce.length > 0) {
+ try {
+ ITraceProvider provider = (ITraceProvider)ce[0].createExecutableExtension("class"); //$NON-NLS-1$
+ // We support only one trace provider
+ if (provider != null) {
+ return provider;
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ return null;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/preferences/MemSpyPreferenceConstants.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,58 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+package com.nokia.s60tools.memspy.preferences;
+
+
+/**
+ * Class for storing keys to preferences.
+ */
+public class MemSpyPreferenceConstants {
+
+ /**
+ * preference DB key for SWMT Category Setting
+ */
+ public static final String SWMT_CATEGORY_SETTING = "SWMTCategorySetting"; //$NON-NLS-1$
+
+ /**
+ * preference DB key for SWMT Category Setting
+ */
+ public static final String SWMT_CATEGORY_SETTINGS_CUSTOM = "SWMTCategorySettingsCustom"; //$NON-NLS-1$
+
+ /**
+ * preference DB key for SWMT Category Setting
+ */
+ public static final String SWMT_CATEGORY_SETTING_PROFILE_SELECTED = "SWMTCategorySettingProfileSelected"; //$NON-NLS-1$
+
+ /**
+ * preference DB key for SWMT Heap Dump selection
+ */
+ public static final String SWMT_HEAP_DUMP_SELECTED = "SWMTHeapDumpSelected"; //$NON-NLS-1$
+
+ /**
+ * preference DB key for SWMT Heap filter Setting
+ */
+ public static final String SWMT_HEAPFILTER_SETTING = "SWMTHeapFilter"; //$NON-NLS-1$
+
+ /**
+ * preference DB key for closing S60 device between cycles
+ */
+ public static final String CLOSE_BETWEEN_CYCLES = "CloseS60DeviceBetweenCycles";//$NON-NLS-1$
+
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/preferences/MemSpyPreferenceInitializer.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,48 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+package com.nokia.s60tools.memspy.preferences;
+
+
+import org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer;
+
+import com.nokia.s60tools.memspy.model.SWMTCategoryConstants;
+import com.nokia.s60tools.memspy.plugin.MemSpyPlugin;
+
+/**
+ * Class used to initialize default preference values.
+ */
+public class MemSpyPreferenceInitializer extends AbstractPreferenceInitializer {
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer#initializeDefaultPreferences()
+ */
+ public void initializeDefaultPreferences() {
+
+ MemSpyPlugin.getPrefsStore().setDefault(MemSpyPreferenceConstants.SWMT_CATEGORY_SETTINGS_CUSTOM, SWMTCategoryConstants.PROFILE_BASIC);
+ MemSpyPlugin.getPrefsStore().setDefault(MemSpyPreferenceConstants.SWMT_CATEGORY_SETTING, SWMTCategoryConstants.PROFILE_BASIC);
+ MemSpyPlugin.getPrefsStore().setDefault(MemSpyPreferenceConstants.SWMT_CATEGORY_SETTING_PROFILE_SELECTED, true);
+ MemSpyPlugin.getPrefsStore().setDefault(MemSpyPreferenceConstants.SWMT_HEAPFILTER_SETTING, "");
+ MemSpyPlugin.getPrefsStore().setDefault(MemSpyPreferenceConstants.SWMT_HEAP_DUMP_SELECTED, false);
+ MemSpyPlugin.getPrefsStore().setDefault(MemSpyPreferenceConstants.CLOSE_BETWEEN_CYCLES, true);
+
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/preferences/MemSpyPreferences.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,149 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+package com.nokia.s60tools.memspy.preferences;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+
+import com.nokia.s60tools.memspy.plugin.MemSpyPlugin;
+
+/**
+ * Helper class to use Dependency Explorer preferences. Use this class for accessing DE preferences
+ * instead of accessing directly through {@link org.eclipse.jface.util.IPropertyChangeListener.IPreferenceStore}.
+ */
+public class MemSpyPreferences {
+
+
+ /**
+ * Gets SWMT category settings for this session.
+ * @return SWMT category settings for this session
+ */
+ public static int getSWMTCategorySetting() {
+
+ IPreferenceStore store = MemSpyPlugin.getPrefsStore();
+
+ boolean isProfileSelected = store.getBoolean(MemSpyPreferenceConstants.SWMT_CATEGORY_SETTING_PROFILE_SELECTED);
+ int value;
+ if(isProfileSelected){
+ value = getSWMTCategorySettingForProfile();
+ }else{
+ value = store.getInt(MemSpyPreferenceConstants.SWMT_CATEGORY_SETTINGS_CUSTOM);
+ }
+ return value ;
+ }
+
+ /**
+ * Gets SWMT category settings for Profile selection.
+ * @return SWMT category settings for profile
+ */
+ public static int getSWMTCategorySettingForProfile() {
+ IPreferenceStore store = MemSpyPlugin.getPrefsStore();
+ return store.getInt(MemSpyPreferenceConstants.SWMT_CATEGORY_SETTING);
+ }
+
+ /**
+ * Sets SWMT category settings for this session.
+ * @param sessionSpecificSWMTCategorySetting SWMT category settings to set for this session
+ */
+ public static void setSWMTCategorySetting(int sessionSpecificSWMTCategorySetting, boolean isProfileSettings) {
+ IPreferenceStore store = MemSpyPlugin.getPrefsStore();
+ setProfileTrackedCategoriesSelected(isProfileSettings);
+ if(isProfileSettings){
+ store.setValue(MemSpyPreferenceConstants.SWMT_CATEGORY_SETTING, sessionSpecificSWMTCategorySetting);
+ }else{
+ store.setValue(MemSpyPreferenceConstants.SWMT_CATEGORY_SETTINGS_CUSTOM, sessionSpecificSWMTCategorySetting);
+ }
+ }
+
+
+ /**
+ * Sets SWMT category settings for this session.
+ * @param sessionSpecificSWMTCategorySetting SWMT category settings to set for this session
+ */
+ public static void setProfileTrackedCategoriesSelected(boolean isAllCategoriesSelected) {
+ IPreferenceStore store = MemSpyPlugin.getPrefsStore();
+ store.setValue(MemSpyPreferenceConstants.SWMT_CATEGORY_SETTING_PROFILE_SELECTED, isAllCategoriesSelected);
+ }
+
+ /**
+ * Get if All Tracke Categories is selected.
+ * @param <code>true</code> if All is selected <code>false</code> otherwise.
+ */
+ public static boolean isProfileTrackedCategoriesSelected() {
+
+ IPreferenceStore store = MemSpyPlugin.getPrefsStore();
+ boolean isAllSelected = store.getBoolean(MemSpyPreferenceConstants.SWMT_CATEGORY_SETTING_PROFILE_SELECTED);
+ return isAllSelected;
+
+ }
+
+ /**
+ * Sets the SWMT Heap Dump selection on/off
+ * @param selection
+ */
+ public static void setSWMTHeapDumpSelected(boolean selection) {
+ IPreferenceStore store = MemSpyPlugin.getPrefsStore();
+ store.setValue(MemSpyPreferenceConstants.SWMT_HEAP_DUMP_SELECTED, selection);
+ }
+
+ /**
+ * Gets the SWMT Heap Dump selection
+ * @param <code>true</code> if Heap Dumps should receive with SWMT logging, <code>false</code> otherwise.
+ */
+ public static boolean isSWMTHeapDumpSelected( ) {
+ IPreferenceStore store = MemSpyPlugin.getPrefsStore();
+ return store.getBoolean(MemSpyPreferenceConstants.SWMT_HEAP_DUMP_SELECTED);
+ }
+
+ /**
+ * Gets SWMT category settings for this session.
+ * @return SWMT HeapNameFilter setting for this session.
+ */
+ public static String getSWMTHeapNameFilter() {
+ IPreferenceStore store = MemSpyPlugin.getPrefsStore();
+ String filter = store.getString(MemSpyPreferenceConstants.SWMT_HEAPFILTER_SETTING);
+ return filter;
+ }
+
+ /**
+ * Sets SWMT HeapNameFilter setting for this session.
+ * @param heapNameFilter SWMT HeapNameFilter settings to set for this session.
+ */
+ public static void setSWMTHeapNameFilter(String heapNameFilter) {
+ IPreferenceStore store = MemSpyPlugin.getPrefsStore();
+ store.setValue(MemSpyPreferenceConstants.SWMT_HEAPFILTER_SETTING, heapNameFilter);
+ }
+
+ /**
+ * Sets the user selection if S60 device is closed between cycles
+ * @param selection
+ */
+ public static void setCloseSymbianAgentBetweenCycles(boolean selection) {
+ IPreferenceStore store = MemSpyPlugin.getPrefsStore();
+ store.setValue(MemSpyPreferenceConstants.CLOSE_BETWEEN_CYCLES, selection);
+ }
+
+ /**
+ * Gets the user selection if S60 device is closed between cycles
+ * @param <code>true</code> if S60 Device is about to close between cycles, <code>false</code> otherwise.
+ */
+ public static boolean isCloseSymbianAgentBetweenCyclesSelected( ) {
+ IPreferenceStore store = MemSpyPlugin.getPrefsStore();
+ return store.getBoolean(MemSpyPreferenceConstants.CLOSE_BETWEEN_CYCLES);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/resources/HelpContextIDs.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,85 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+
+package com.nokia.s60tools.memspy.resources;
+
+/**
+ * IDs for context sensitive help.
+ * @see contexts.xml -file IDs links to <code> <context id="<ID>"> </code>
+ */
+public class HelpContextIDs {
+
+ /**
+ * The plug-in ID.
+ */
+ private static final String MEMSPY_HELP_PROJECT_PLUGIN_ID = "com.nokia.s60tools.memspy.help";
+
+ //
+ // ID's to MemSpy Help TOC
+ //
+
+ /**
+ * Id to Importing and analyzing heap dump files
+ */
+ public static final String MEMSPY_IMPORT_HEAP =
+ MEMSPY_HELP_PROJECT_PLUGIN_ID +".MEMSPY_HELP_IMPORT_HEAP";
+
+ /**
+ * Id to MemSpy Main View
+ */
+ public static final String MEMSPY_MAIN_VIEW =
+ MEMSPY_HELP_PROJECT_PLUGIN_ID +".MEMSPY_HELP_MAIN_VIEW";
+
+ /**
+ * Id to MemSpy Tasks
+ */
+ public static final String MEMSPY_SELECT_ACTION =
+ MEMSPY_HELP_PROJECT_PLUGIN_ID +".MEMSPY_HELP_IMPORT_SELECT_ACTION";
+
+ /**
+ * Id to Symbol and Map files
+ */
+ public static final String MEMSPY_IMPORT_SYMBOLS =
+ MEMSPY_HELP_PROJECT_PLUGIN_ID +".MEMSPY_HELP_IMPORT_SYMBOLS";
+
+ /**
+ * Id to Importing and comparing two heap dump files
+ */
+ public static final String MEMSPY_IMPORT_COMPARE =
+ MEMSPY_HELP_PROJECT_PLUGIN_ID +".MEMSPY_HELP_IMPORT_COMPARE";
+
+ /**
+ * Id to Importing and analyzing System Wide Memory Tracking log files
+ */
+ public static final String MEMSPY_IMPORT_SWMT =
+ MEMSPY_HELP_PROJECT_PLUGIN_ID +".MEMSPY_HELP_IMPORT_SWMT";
+
+ /**
+ * Id to Setting System Wide Memory Tracking tracked categories
+ */
+ public static final String MEMSPY_IMPORT_SWMT_CATEGORIES_DIALOG =
+ MEMSPY_HELP_PROJECT_PLUGIN_ID +".MEMSPY_HELP_IMPORT_SWMT_CATEGORIES_DIALOG";
+
+ /**
+ * Id to Configuring connection settings
+ */
+ public static final String MEMSPY_IMPORT_CONNECTION_SETTINGS =
+ MEMSPY_HELP_PROJECT_PLUGIN_ID +".MEMSPY_HELP_IMPORT_CONNECTION_SETTINGS";
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/resources/ImageKeys.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,61 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+
+package com.nokia.s60tools.memspy.resources;
+
+/**
+ * Keys to images with in application
+ */
+public class ImageKeys {
+ /**
+ * ID to MemSpy application icon
+ */
+ public static final String IMG_APP_ICON = "MEMSPY_IMG_APP_ICON";
+ /**
+ * ID to launch Heap Analyser icon
+ */
+ public static final String IMG_ANALYZE_HEAP = "MEMSPY_IMG_ANALYZE_HEAP";
+ /**
+ * ID to compare two heaps icon
+ */
+ public static final String IMG_COMPARE_2_HEAP = "MEMSPY_IMG_COMPARE_2_HEAP";
+ /**
+ * ID to export to HTML icon
+ */
+ public static final String IMG_EXPORT_TO_HTML = "MEMSPY_IMG_EXPORT_TO_HTML";
+ /**
+ * ID to Launch SWMT icon
+ */
+ public static final String IMG_LAUNCH_SWMT = "MEMSPY_IMG_LAUNCH_SWMT";
+ /**
+ * ID to Heap Dump icon
+ */
+ public static final String IMG_HEAP_DUMP = "MEMSPY_IMG_HEAP_DUMP";
+ /**
+ * ID to SWMT icon
+ */
+ public static final String IMG_SWMT_LOG = "MEMSPY_IMG_SWMT_LOG";
+ /**
+ * ID to Wizard icon
+ */
+ public static final String IMG_WIZARD = "MEMSPY_IMG_WIZARD";
+
+
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/resources/ImageResourceManager.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,82 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+package com.nokia.s60tools.memspy.resources;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.resource.ImageRegistry;
+import org.eclipse.jface.resource.JFaceResources;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Display;
+
+
+/**
+ * Class for handling MemSpy icons.
+ *
+ */
+public class ImageResourceManager {
+
+ /**
+ * Load images
+ * @param imagesPath
+ */
+ public static void loadImages(String imagesPath){
+
+ Display disp = Display.getCurrent();
+
+ ImageRegistry imgReg = JFaceResources.getImageRegistry();
+
+ //
+ // Storing images to image registry
+ //
+ Image img = new Image( disp, imagesPath + "\\memspy_16.png" );
+ imgReg.put( ImageKeys.IMG_APP_ICON, img );
+
+ img = new Image( disp, imagesPath + "\\Launch_SWMT.png" );
+ imgReg.put( ImageKeys.IMG_LAUNCH_SWMT, img );
+
+ img = new Image( disp, imagesPath + "\\Export_To_html.png" );
+ imgReg.put( ImageKeys.IMG_EXPORT_TO_HTML, img );
+
+ img = new Image( disp, imagesPath + "\\Compare_2_Heaps.png" );
+ imgReg.put( ImageKeys.IMG_COMPARE_2_HEAP, img );
+
+ img = new Image( disp, imagesPath + "\\Analyse_Heap.png" );
+ imgReg.put( ImageKeys.IMG_ANALYZE_HEAP, img );
+
+ img = new Image( disp, imagesPath + "\\Launch_SWMT.png" );
+ imgReg.put( ImageKeys.IMG_SWMT_LOG, img );
+
+ img = new Image( disp, imagesPath + "\\Analyse_Heap.png" );
+ imgReg.put( ImageKeys.IMG_HEAP_DUMP, img );
+
+ img = new Image( disp, imagesPath + "\\Memspy_45.png" );
+ imgReg.put( ImageKeys.IMG_WIZARD, img );
+
+ }
+
+ public static ImageDescriptor getImageDescriptor( String key ){
+ ImageRegistry imgReg = JFaceResources.getImageRegistry();
+ return imgReg.getDescriptor( key );
+ }
+
+ public static Image getImage( String key ){
+ ImageRegistry imgReg = JFaceResources.getImageRegistry();
+ return imgReg.get(key);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/ui/UiUtils.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,255 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+package com.nokia.s60tools.memspy.ui;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.dialogs.ErrorDialog;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.swt.program.Program;
+import org.eclipse.swt.widgets.Display;
+
+import com.nokia.s60tools.memspy.interfaces.IMemSpyTraceListener;
+import com.nokia.s60tools.memspy.interfaces.IMemSpyTraceListener.LauncherErrorType;
+import com.nokia.s60tools.memspy.model.TraceCoreEngine.ProgressStatus;
+import com.nokia.s60tools.memspy.plugin.MemSpyPlugin;
+import com.nokia.s60tools.memspy.util.MemSpyConsole;
+import com.nokia.s60tools.util.debug.DbgUtility;
+
+/**
+ * Static UI utility methods that are needed more than one place
+ * are located here in order to prevent code duplication.
+ */
+public class UiUtils {
+
+
+ /**
+ * Launcher SIS file name
+ */
+ private static final String MEM_SPY_LAUNCHER_S60_50_RN_D_SIGNED_SIS_FILE_NAME = "MemSpyLauncher_S60-50_RnD-signed.sis";
+
+ /**
+ * Shows error dialog that gives error context related information and guidance.
+ * E.g. Advises user to install launcher component to the device if it is needed.
+ * @param error Launcher error encountered
+ * @param errorMessage Error message to be shown to user
+ * @param progressStatus
+ */
+ public static void showErrorDialogToUser(final LauncherErrorType error, final String errorMessage, final ProgressStatus progressStatus) {
+
+ Runnable updateUiRunnable = new Runnable(){
+ public void run(){
+
+ // If no answer from device received, display dialog that allows user to install MemSpy Launcher.
+ if( error == LauncherErrorType.NO_ANSWER_FROM_DEVICE || error == LauncherErrorType.TOO_OLD_MEMSPY_LAUNCHER_DATAVERSION ){
+
+ switch (progressStatus) {
+ // Flow through on purpose 1
+ case EPROGRESS_MEMSPY_LAUNCHED: // MemSpy is launched but not yet actual task
+ case EPROGRESS_FIRST_TASK_LAUNCHED: // MemSpy is launched and also 1st real task is done
+ case EPROGRESS_FIRST_TASK_DONE: // Trace data has been received successfully at least once
+ showStandardErrorMessageDialog(errorMessage);
+ break;
+ // Flow through on purpose 2
+ case EPROGRESS_INITIAL: // MemSpy has not been launched successfully, so no progress at all
+ default:
+ adviceUserToInstallLauncherComponent(errorMessage);
+ break;
+ }
+ }
+ else{
+ showStandardErrorMessageDialog(errorMessage);
+ }
+
+ }
+
+ };
+
+ Display.getDefault().asyncExec(updateUiRunnable);
+ }
+
+ /**
+ * Shows standard eclipse error dialog with given error message
+ * @param errorMessage error message
+ */
+ private static void showStandardErrorMessageDialog(String errorMessage) {
+ Status status = new Status(IStatus.ERROR, MemSpyPlugin.PLUGIN_ID, 0, errorMessage, null);
+ // Display the dialog
+ ErrorDialog.openError(Display.getCurrent().getActiveShell(),IMemSpyTraceListener.ERROR_MEMSPY, null, status);
+ }
+
+ /**
+ * Advises used to install MemSpy launcher component and provides necessary action alternatives.
+ * @param errorMessage error message
+ */
+ private static void adviceUserToInstallLauncherComponent(final String errorMessage) {
+
+ MessageDialog dialog = new MessageDialog( Display.getCurrent().getActiveShell(),
+ IMemSpyTraceListener.ERROR_MEMSPY, null, errorMessage, MessageDialog.ERROR,
+ new String[]{ "Install RnD-signed MemSpy Launcher", "Open sis-file's directory in Explorer", "Don't install" }, 1);
+ dialog.open();
+
+ String launcherFolder = MemSpyPlugin.getDefault().getMemspyLauncherBinDir();
+ String launcherLocation = launcherFolder + File.separatorChar + MEM_SPY_LAUNCHER_S60_50_RN_D_SIGNED_SIS_FILE_NAME;
+
+ // if user wants to install launcher:
+ if( dialog.getReturnCode() == 0 ){
+ // find program for xls-filetype
+ Program p=Program.findProgram(".sis");
+ // if found, launch it.
+ if(p!=null){
+ // Check that found program was Nokia PC Suite.
+ p.execute( launcherLocation );
+ }
+ else{
+ Status status = new Status(IStatus.ERROR, MemSpyPlugin.PLUGIN_ID, 0,
+ "Unable to locate PC suite or other suitable software for installing .sis -file from computer. You can try installing MemSpy launcher manually from:\n"
+ + launcherLocation, null);
+ ErrorDialog.openError(Display.getCurrent().getActiveShell(),"MemSpy Error", null, status);
+ }
+
+ }
+
+ // Open directory in explorer
+ else if( dialog.getReturnCode() == 1 ){
+ try {
+ String directory = Platform.getConfigurationLocation().getURL().getFile();
+ directory = directory.substring(1);
+ Runtime.getRuntime().exec("explorer " + launcherFolder);
+ } catch (IOException e) {
+ Status status = new Status(IStatus.ERROR, MemSpyPlugin.PLUGIN_ID, 0, "Unable to open Explorer", null);
+ ErrorDialog.openError(Display.getCurrent().getActiveShell(),IMemSpyTraceListener.ERROR_MEMSPY, null, status);
+ e.printStackTrace();
+ }
+ }
+
+ }
+
+ /**
+ * Maps given launcher error to corresponding error message.
+ * @param error error enumerator
+ * @param clientContextString client context string for giving usage context info. Used only for possible console logging.
+ * @param progressStatus current progress status for giving extra information on the possible error condition.
+ * @return error message string
+ */
+ public static String getErrorMessageForLauncherError(LauncherErrorType error, String clientContextString, ProgressStatus progressStatus) {
+
+ String errorMessage;
+
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "getErrorMessageForLauncherError/progressStatus: " + progressStatus); //$NON-NLS-1$
+
+ switch (error){
+ case NO_ANSWER_FROM_DEVICE:{
+ errorMessage = getErrorDescriptionForNoAnswerFromDeviceError(progressStatus, clientContextString);
+ break;
+ }
+ case MEMSPY_NOT_RUNNING:{
+ errorMessage = IMemSpyTraceListener.ERROR_MEMSPY_NOT_RUNNING;
+ break;
+ }
+ case MEMSPY_NOT_FOUND:{
+ errorMessage = IMemSpyTraceListener.ERROR_MEMSPY_NOT_FOUND;
+ break;
+ }
+ case ACTIVATION:{
+ errorMessage = IMemSpyTraceListener.ERROR_ACTIVATION_NOT_SUCCESFUL;
+ break;
+ }
+ case FILE:{
+ errorMessage = IMemSpyTraceListener.ERROR_FILE_OPERATIONS_NOT_SUCCESSFUL;
+ break;
+ }
+ case TOO_OLD_MEMSPY_LAUNCHER_DATAVERSION:{
+ errorMessage = IMemSpyTraceListener.ERROR_TOO_OLD_MEMSPY_LAUNCHER_VERSION;
+ break;
+ }
+ case DUMPED_TRACES:{
+ errorMessage = IMemSpyTraceListener.ERROR_DUMPED_TRACES;
+ break;
+ }
+ case CATEGORIES_NOT_SUPPORTED:{
+ errorMessage = IMemSpyTraceListener.ERROR_CATEGORIES_NOT_SUPPORTED;
+ break;
+ }
+ case GENERAL_LAUNCHER_ERROR:{
+ errorMessage = IMemSpyTraceListener.ERROR_GENERAL_LAUNCHER_ERROR;
+ break;
+ }
+ // default handling in case new launcher error has been added but not handled appropriately
+ default:{
+ MemSpyConsole.getInstance().println(clientContextString + " error: '" //$NON-NLS-1$
+ + error.name() + "' occurrence." //$NON-NLS-1$
+ , MemSpyConsole.MSG_ERROR); //$NON-NLS-1$
+ errorMessage = IMemSpyTraceListener.ERROR_ACTIVATION_NOT_SUCCESFUL;
+ break;
+ }
+ }
+
+ return errorMessage;
+ }
+
+ /**
+ * Forms error description in no answer from device error situation.
+ * @param progressStatus progress status at the moment when error occurred.
+ * @param clientContextString Possibly more context-specific information
+ * @return
+ */
+ private static String getErrorDescriptionForNoAnswerFromDeviceError(ProgressStatus progressStatus, String clientContextString) {
+
+ // Default message start portion
+ String errorMessage = IMemSpyTraceListener.ERROR_NO_RESPONSE + " " + IMemSpyTraceListener.ERROR_POSSIBLE_REASONS;
+
+ switch (progressStatus) {
+
+ // Flow through on purpose 1
+ case EPROGRESS_MEMSPY_LAUNCHED: // MemSpy is launched but not yet actual task
+ case EPROGRESS_FIRST_TASK_DONE: // Trace data has been received successfully at least once
+ case EPROGRESS_FIRST_TASK_LAUNCHED: // MemSpy is launched and also 1st real task is done
+ // add USB error note.
+ errorMessage = errorMessage + IMemSpyTraceListener.ERROR_USB_TRACE_ENABLED;
+ // add check for connection information message
+ errorMessage = errorMessage + IMemSpyTraceListener.ERROR_CONNECTION_BROKEN;
+ break;
+
+ // Flow through on purpose 2
+ case EPROGRESS_INITIAL: // MemSpy has not been launched successfully, so no progress at all
+ default:
+ errorMessage = IMemSpyTraceListener.ERROR_NO_RESPONSE + " " + IMemSpyTraceListener.ERROR_POSSIBLE_REASONS;
+ // add USB error note.
+ errorMessage = errorMessage + IMemSpyTraceListener.ERROR_USB_TRACE_ENABLED;
+ // add install note for MemSpy Launcher
+ errorMessage = errorMessage + IMemSpyTraceListener.ERROR_INSTALL_MEMSPY_LAUNCHER;
+ break;
+ }
+
+ if(clientContextString.length() > 0){
+ MemSpyConsole.getInstance().println(IMemSpyTraceListener.ERROR_NO_RESPONSE
+ + IMemSpyTraceListener.ERROR_LAUNCHER_ERROR_DETAILS + clientContextString //$NON-NLS-1$
+ , MemSpyConsole.MSG_ERROR);
+ errorMessage = errorMessage + IMemSpyTraceListener.ERROR_SEE_CONSOLE_LOG;
+ }
+
+ return errorMessage;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/ui/actions/ToolbarShortcutAction.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,84 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+
+package com.nokia.s60tools.memspy.ui.actions;
+
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.IWorkbenchWindowActionDelegate;
+
+import com.nokia.s60tools.memspy.ui.views.MemSpyMainView;
+import com.nokia.s60tools.memspy.ui.wizards.MemSpyWizard.MemSpyWizardType;
+import com.nokia.s60tools.util.debug.DbgUtility;
+
+
+
+
+
+/**
+ * Action for toolbar and import shortcuts that launch MemSpy
+ * @see IWorkbenchWindowActionDelegate
+ */
+public class ToolbarShortcutAction implements IWorkbenchWindowActionDelegate {
+
+ /**
+ * The action has been activated. The argument of the
+ * method represents the 'real' action sitting
+ * in the workbench UI.
+ * @see IWorkbenchWindowActionDelegate#run
+ */
+ public void run(IAction action) {
+ // Open MemSpy's Main View
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "Show main view");
+ MemSpyMainView mainView = MemSpyMainView.showAndReturnYourself();
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "Run wizard");
+ mainView.runWizard( MemSpyWizardType.FULL, null );
+
+ }
+
+ /**
+ * Selection in the workbench has been changed. We
+ * can change the state of the 'real' action here
+ * if we want, but this can only happen after
+ * the delegate has been created.
+ * @see IWorkbenchWindowActionDelegate#selectionChanged
+ */
+ public void selectionChanged(IAction action, ISelection selection) {
+ // Not needed
+ }
+
+ /**
+ * We can use this method to dispose of any system
+ * resources we previously allocated.
+ * @see IWorkbenchWindowActionDelegate#dispose
+ */
+ public void dispose() {
+ // Not needed
+ }
+
+ /**
+ * We will cache window object in order to
+ * be able to provide parent shell for the message dialog.
+ * @see IWorkbenchWindowActionDelegate#init
+ */
+ public void init(IWorkbenchWindow window) {
+ // Not needed
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/ui/dialogs/SWMTCategoriesDialog.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,679 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+package com.nokia.s60tools.memspy.ui.dialogs;
+
+import java.util.ArrayList;
+
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.IMessageProvider;
+import org.eclipse.jface.dialogs.TitleAreaDialog;
+import org.eclipse.jface.viewers.CheckboxTableViewer;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.ITableLabelProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.MessageBox;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.PlatformUI;
+
+import com.nokia.s60tools.memspy.model.SWMTCategoryConstants;
+import com.nokia.s60tools.memspy.model.SWMTCategorys;
+import com.nokia.s60tools.memspy.preferences.MemSpyPreferences;
+import com.nokia.s60tools.memspy.resources.HelpContextIDs;
+import com.nokia.s60tools.memspy.resources.ImageKeys;
+import com.nokia.s60tools.memspy.resources.ImageResourceManager;
+import com.nokia.s60tools.memspy.util.MemSpyConsole;
+import com.nokia.s60tools.ui.S60ToolsTable;
+import com.nokia.s60tools.ui.S60ToolsTableColumnData;
+import com.nokia.s60tools.ui.S60ToolsTableFactory;
+import com.nokia.s60tools.ui.S60ToolsUIConstants;
+
+
+
+/**
+ * Dialog for selecting SWMT categories to be tracked.
+ */
+public class SWMTCategoriesDialog extends TitleAreaDialog{
+
+
+
+ //
+ // Private classes
+ //
+
+ private static final String HEAP_DATA_THREAD_FILTER_TXT = "Heap Data Thread Filter";
+
+ /**
+ * Label provider for table viewer component.
+ */
+ class SWMTCategoryViewerLabelProvider extends LabelProvider implements ITableLabelProvider{
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.ITableLabelProvider#getColumnImage(java.lang.Object, int)
+ */
+ public Image getColumnImage(Object element, int columnIndex) {
+ return null; // No images used
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.ITableLabelProvider#getColumnText(java.lang.Object, int)
+ */
+ public String getColumnText(Object element, int columnIndex) {
+ String label = element.toString();
+
+ SWMTCategoryEntry entryData = (SWMTCategoryEntry) element;
+
+ switch (columnIndex) {
+
+ case SWMTCategoryEntry.NAME_COLUMN_INDEX:
+ label = entryData.getCategoryName();
+ break;
+
+ default:
+ MemSpyConsole.getInstance().println("Unexpected column index: " + columnIndex, MemSpyConsole.MSG_ERROR); //$NON-NLS-1$ //$NON-NLS-2$
+ break;
+ }
+
+ return label;
+ }
+
+ }
+
+ //
+ // Private constants
+ //
+
+ /**
+ * Columns in the container area.
+ */
+ private static final int COLUMN_COUNT = 1;
+
+ /**
+ * Dialog width.
+ */
+ private static final int DIALOG_WIDTH = 425;
+
+ /**
+ * Dialog height.
+ */
+ private static final int DIALOG_HEIGHT = 550;
+
+ /**
+ * Percentage as decimal number how much table viewer is taking space horizontally.
+ */
+ private static final double TABLE_VIEWER_WIDTH_PERCENTAGE = 0.8;
+
+ /**
+ * Default guiding message shown to the user in add new mode.
+ */
+ private static final String DEFAULT_MESSAGE = "Set advanced options and tracked SWMT categories.";
+
+ /**
+ * Complete message shown to the user in add new mode.
+ */
+ private static final String COMPLETE_MESSAGE = "Press OK to save advanced options and set categories to be tracked";
+
+ /**
+ * Error message shown to the user in case no categories are selected.
+ */
+ private static final String ERROR_MESSAGE = "At least single category must be selected";
+
+ /**
+ * UI text for closing Symbian agent
+ */
+ private static final String CLOSE_MEM_SPY_BETWEEN_CYCLES_TEXT = "Close MemSpy Symbian Agent Between Cycles";
+
+ /**
+ * Tip text for closing Symbian agent
+ */
+ private static final String CLOSE_MEM_SPY_BETWEEN_CYCLES_TIP_TEXT = "Choose if the MemSpy Symbian agent in S60 target is closed between cycles. That is more realistic use case for memory usage point of view.";
+
+
+ //
+ // Member data
+ //
+
+ /**
+ * Flag used to make sure that create() and open() are called in correct order.
+ */
+ private boolean isCreateCalled = false;
+
+
+ //
+ // UI Controls
+ //
+
+ /**
+ * Container area for individual fields for the user for entering information.
+ */
+ private Composite container;
+
+ /**
+ * Reference to OK button that can be disabled/enabled
+ * due to current category selection-
+ */
+ private Button okActionBtn;
+
+ /**
+ * Viewer showing currently selected category file entries.
+ */
+ private CheckboxTableViewer categoryViewer;
+
+ /**
+ * Selected categories as a result of bitwise OR.
+ */
+ private int categorySelection = SWMTCategoryConstants.CATEGORY_ALL;
+
+ //User Heap filter text field
+ private Text heapText;
+
+ private Button closeBetweenCyclesButton;
+
+ private Button heapDumpBtn;
+
+ /**
+ * Constructor. Used to open dialog in order to add new entry.
+ * @param parentShell Parent shell for the dialog.
+ * @param categorySelection integer containing initially selected categories as a result of bitwise OR.
+ */
+ public SWMTCategoriesDialog(Shell parentShell, int categorySelection) {
+ super(parentShell);
+ this.categorySelection = categorySelection;
+ // Setting banner image
+ String bannerImage = ImageKeys.IMG_WIZARD;
+ setTitleImage(ImageResourceManager.getImage(bannerImage));
+ }
+
+
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.dialogs.Dialog#createButtonsForButtonBar(org.eclipse.swt.widgets.Composite)
+ */
+ protected void createButtonsForButtonBar(Composite parent) {
+ createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL,
+ true);
+ createButton(parent, IDialogConstants.CANCEL_ID, IDialogConstants.CANCEL_LABEL,
+ true);
+ okActionBtn = getButton(IDialogConstants.OK_ID);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.window.Window#configureShell(org.eclipse.swt.widgets.Shell)
+ */
+ protected void configureShell(Shell shell) {
+ super.configureShell(shell);
+ shell.setText("SWMT Categories and Advanced Options");
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.dialogs.Dialog#createDialogArea(org.eclipse.swt.widgets.Composite)
+ */
+ protected Control createDialogArea(Composite parent) {
+
+ Composite dialogAreaComposite = (Composite) super.createDialogArea(parent);
+
+ //
+ // Creating container and layout for it
+ //
+ container = new Composite(dialogAreaComposite, SWT.NONE);
+ GridLayout gdl = new GridLayout(COLUMN_COUNT, false);
+ // Settings margins according Carbide branding guideline
+ gdl.marginLeft = S60ToolsUIConstants.MARGIN_BTW_FRAME_AND_CONTENTS;
+ gdl.marginRight = S60ToolsUIConstants.MARGIN_BTW_FRAME_AND_CONTENTS;
+ gdl.marginTop = S60ToolsUIConstants.MARGIN_BTW_FRAME_AND_CONTENTS;
+ gdl.marginBottom = S60ToolsUIConstants.MARGIN_BTW_FRAME_AND_CONTENTS;
+ container.setLayout(gdl);
+ container.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+ //
+ // Symbian agent options group
+ //
+
+ createSymbianAgentOptionsGroup();
+
+ //
+ // Head dump group
+ //
+ createHeapDumpGroup();
+
+
+ //
+ // Creating table viewer for showing category file entries
+ //
+
+ categoryViewer = createCategoryCheckBoxTableViewer(container);
+ GridData categoryViewerGd = new GridData(GridData.FILL_BOTH);
+ // Spanning as many rows as there are actions buttons on the right
+ categoryViewerGd.verticalSpan = 3;
+ categoryViewerGd.widthHint = (int) (TABLE_VIEWER_WIDTH_PERCENTAGE * DIALOG_WIDTH);
+ categoryViewer.getControl().setLayoutData(categoryViewerGd);
+ categoryViewer.setSorter(new SWMTCategoryEntryTableViewerSorter());
+ // Adding selection change listener
+ categoryViewer.addSelectionChangedListener(new ISelectionChangedListener(){
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.ISelectionChangedListener#selectionChanged(org.eclipse.jface.viewers.SelectionChangedEvent)
+ */
+ public void selectionChanged(SelectionChangedEvent event) {
+ notifySelectionChanged();
+ }
+
+ });
+
+ //
+ // Setting providers for table viewer
+ //
+
+ // Creating content provider
+ GategoryProvider categoryViewerContentProvider = new GategoryProvider();
+ // Setting content provider
+ categoryViewer.setContentProvider(categoryViewerContentProvider);
+ categoryViewer.setInput(categoryViewerContentProvider);
+
+ // Label provider
+ categoryViewer.setLabelProvider(new SWMTCategoryViewerLabelProvider());
+
+ // Setting initial category selection state
+ InitializeSelectionState();
+
+ // Setting context-sensitive help ID
+ PlatformUI.getWorkbench().getHelpSystem().setHelp( dialogAreaComposite, HelpContextIDs.MEMSPY_IMPORT_SWMT_CATEGORIES_DIALOG);
+
+ // Dialog are composite ready
+ return dialogAreaComposite;
+ }
+
+
+ /**
+ * Private class to provide content for category viewer
+ */
+ class GategoryProvider implements IStructuredContentProvider {
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object)
+ */
+ public Object[] getElements(Object inputElement) {
+ return SWMTCategorys.getInstance().getCategoryEntries().toArray();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.IContentProvider#dispose()
+ */
+ public void dispose() {
+ // Not needed but needs to be implemented
+ }
+
+ public void inputChanged(Viewer viewer, Object oldInput,
+ Object newInput) {
+ // Not used but needs to be implemented
+ }
+
+ };
+
+ /**
+ * Creates group for Symbian agent options
+ */
+ private void createSymbianAgentOptionsGroup() {
+ Group closeSymbianGroup = new Group(container, SWT.SHADOW_NONE);
+ closeSymbianGroup.setText("Symbian Agent Options");
+ GridLayout closegl = new GridLayout(2, false);
+ GridData closegd = new GridData(GridData.FILL_BOTH);
+ closeSymbianGroup.setLayout(closegl);
+ closeSymbianGroup.setLayoutData(closegd);
+
+ closeBetweenCyclesButton = new Button(closeSymbianGroup, SWT.CHECK);
+ GridData closeLayoutData = new GridData(GridData.VERTICAL_ALIGN_END);
+ closeBetweenCyclesButton.setLayoutData( closeLayoutData);
+ closeBetweenCyclesButton.setToolTipText(CLOSE_MEM_SPY_BETWEEN_CYCLES_TIP_TEXT);
+ boolean isToBeClosedBetweenCycles = MemSpyPreferences.isCloseSymbianAgentBetweenCyclesSelected();
+ closeBetweenCyclesButton.setSelection(isToBeClosedBetweenCycles);
+
+ //Label for button, separate label is used because setting text to button wont align text to same vertical
+ //position than next label.
+ Label closeBetweenIntervalsLabel = new Label(closeSymbianGroup, SWT.LEFT );
+ GridData closeBetweenLabelData = new GridData(GridData.VERTICAL_ALIGN_CENTER);
+ closeBetweenIntervalsLabel.setText( CLOSE_MEM_SPY_BETWEEN_CYCLES_TEXT );
+ closeBetweenIntervalsLabel.setLayoutData(closeBetweenLabelData);
+
+ }
+
+
+ /**
+ * Creates group for Head Dumps
+ */
+ private void createHeapDumpGroup() {
+ //
+ // Head dump group
+ //
+ Group headDumpGroup = new Group(container, SWT.SHADOW_NONE);
+ headDumpGroup.setText("Heap Dumps During SWMT Logging");
+ GridLayout hdgl = new GridLayout(2, false);
+ GridData hdgd = new GridData(GridData.FILL_BOTH);
+ headDumpGroup.setLayout(hdgl);
+ headDumpGroup.setLayoutData(hdgd);
+
+ heapDumpBtn = new Button(headDumpGroup, SWT.CHECK);
+ heapDumpBtn.setText("Get Heap Dumps for Threads to Analyse with Heap Analyser");
+ heapDumpBtn.setToolTipText("Set if Heap Dumps is to be received for Threads during SWMT logging");
+ heapDumpBtn.addSelectionListener(new HeadDumpSelectionListener());
+ heapDumpBtn.setSelection(MemSpyPreferences.isSWMTHeapDumpSelected());
+ GridData hdBtnGd = new GridData();
+ hdBtnGd.horizontalSpan = 2;
+ heapDumpBtn.setLayoutData(hdBtnGd);
+
+ //Label for Heap gategory limit
+ Label heapTextLabel = new Label(headDumpGroup, SWT.LEFT );
+ heapTextLabel.setText(HEAP_DATA_THREAD_FILTER_TXT + ":");
+ String heapFilterToolTipText = "When filter string is specified, only Threads that contain text specified will be tracked.";
+ heapTextLabel.setToolTipText(heapFilterToolTipText);
+ GridData heapTextLimitLayoutData = new GridData(GridData.VERTICAL_ALIGN_CENTER);
+ heapTextLabel.setLayoutData( heapTextLimitLayoutData );
+
+ //heap limit text
+ heapText = new Text(headDumpGroup, SWT.LEFT | SWT.BORDER | SWT.BORDER);
+ heapText.setTextLimit(120);//Text limit 128 specified in S60 side
+ GridData heapTextLayoutData = new GridData(GridData.VERTICAL_ALIGN_CENTER);
+ heapTextLayoutData.widthHint = 140;
+ heapText.setLayoutData( heapTextLayoutData );
+ heapText.setToolTipText(heapFilterToolTipText);
+ if(heapDumpBtn.getSelection()){
+ heapText.setText(MemSpyPreferences.getSWMTHeapNameFilter());
+ }else{
+ heapText.setEnabled(false);
+ }
+ }
+
+ /**
+ * Listener for Heap Dumps button, updates preferences and text in Heap Dumps group.
+ */
+ private class HeadDumpSelectionListener implements SelectionListener{
+
+ /* (non-Javadoc)
+ * @see org.eclipse.swt.events.SelectionListener#widgetDefaultSelected(org.eclipse.swt.events.SelectionEvent)
+ */
+ public void widgetDefaultSelected(SelectionEvent e) {
+ // not needed
+
+ }
+
+ /*
+ * Change heapText and save preferences
+ * (non-Javadoc)
+ * @see org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt.events.SelectionEvent)
+ */
+ public void widgetSelected(SelectionEvent e) {
+ boolean selection = heapDumpBtn.getSelection();
+ if(selection){
+ heapText.setEnabled(true);
+ heapText.setText(MemSpyPreferences.getSWMTHeapNameFilter());
+ }else{
+ heapText.setText("");
+ heapText.setEnabled(false);
+ }
+ }
+
+
+ }
+
+ /**
+ * Save the heap filter text if enabled
+ */
+ private void saveHeapFilterText() {
+ //Check if heaptext is enabled, if it is, saving text to preferences
+ if(heapText.isEnabled()){
+ String heapFilterText = heapText.getText().trim();
+ MemSpyPreferences.setSWMTHeapNameFilter(heapFilterText);
+ }
+ }
+ /**
+ * Save the Close between cycles selection
+ */
+ private void saveCloseS60AgentBetweenCycles() {
+ boolean selection = closeBetweenCyclesButton.getSelection();
+ // User selects to close MemSpy S60 application between cycles
+ MemSpyPreferences.setCloseSymbianAgentBetweenCycles(selection);
+ }
+ /**
+ * Save the heap dump selection
+ */
+ private void saveHeapDumpSelection() {
+ boolean selection = heapDumpBtn.getSelection();
+ MemSpyPreferences.setSWMTHeapDumpSelected(selection);
+ }
+
+
+
+ /**
+ * Sets initial selection state for entries
+ */
+ private void InitializeSelectionState() {
+ int size = SWMTCategorys.getInstance().getCategoryEntries().size();
+ for (int i = 0; i < size; i++) {
+ SWMTCategoryEntry entry = (SWMTCategoryEntry) categoryViewer.getElementAt(i);
+ int isCategoryBitUp = categorySelection & entry.getCategoryId();
+ if(isCategoryBitUp != 0){
+ categoryViewer.setChecked(entry, true);
+ }
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.dialogs.TitleAreaDialog#getInitialSize()
+ */
+ protected Point getInitialSize() {
+ return new Point(DIALOG_WIDTH, DIALOG_HEIGHT);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.dialogs.Dialog#create()
+ */
+ public void create() {
+ super.create();
+ // Currently just does creation by super call and stores status
+ isCreateCalled = true;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.dialogs.Dialog#okPressed()
+ */
+ protected void okPressed() {
+
+ if(heapDumpBtn.getSelection()){
+ if(heapText.getText().trim().equals("")){
+ System.out.println("DEBUG: WARNING! Empty heap filter text!");
+ MessageBox box = new MessageBox(getShell(),SWT.ICON_WARNING | SWT.YES | SWT.NO);
+ String warningMsg = "Empty \"" +HEAP_DATA_THREAD_FILTER_TXT
+ + "\" field causes huge amount of data to be traced and tracing may take a very long time. "
+ +"It is highly recommended to use \"" +HEAP_DATA_THREAD_FILTER_TXT
+ + "\"."
+ +"\n\nDo you want to continue anyway?";
+ box.setMessage(warningMsg);
+ box.setText("Using \"" +HEAP_DATA_THREAD_FILTER_TXT
+ + "\" is recommended");
+ int yes_no = box.open();
+ //If user does not want to continue but cancel, returning, otherwise just continue to save all data and exit
+ if(yes_no == SWT.NO){
+ return;
+ }
+
+ }
+ }
+
+ saveHeapFilterText();
+ saveCloseS60AgentBetweenCycles();
+ saveHeapDumpSelection();
+ super.close();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.window.Window#open()
+ */
+ public int open(){
+ try {
+ // Making sure that create is called
+ if(!isCreateCalled){
+ create();
+ }
+ showDefaultMessage();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return super.open();
+ }
+
+ /**
+ * Resets possible error messages and show the default message.
+ */
+ private void showDefaultMessage() {
+ setErrorMessage(null);
+ setMessage(DEFAULT_MESSAGE, IMessageProvider.INFORMATION);
+ }
+
+ /**
+ * Informs user that parameters are valid and dialog can be
+ * dismissed with OK button..
+ */
+ private void setCompleteOkMessage() {
+ setErrorMessage(null);
+ setMessage(COMPLETE_MESSAGE, IMessageProvider.INFORMATION);
+ }
+
+ /**
+ * Shows error message in case no categories are selected.
+ */
+ private void showErrorMessage() {
+ setErrorMessage(ERROR_MESSAGE);
+ setMessage(null);
+ }
+
+ /**
+ * Disables OK button.
+ * This method is guarded against call during construction
+ * when button row has not been created yet and widget is <code>null</code>.
+ */
+ private void disableOk() {
+ if(okActionBtn != null){
+ okActionBtn.setEnabled(false);
+ }
+ }
+
+ /**
+ * Enables OK button.
+ * This method is guarded against call during construction
+ * when button row has not been created yet and widget is <code>null</code>.
+ */
+ private void enableOk() {
+ if(okActionBtn != null){
+ okActionBtn.setEnabled(true);
+ }
+ }
+
+ /**
+ * Updates buttons statuses according the current selection
+ * status of table entry viewer contents and refreshes contents.
+ */
+ private void notifySelectionChanged() {
+ Object[] selectedCategoryEntries = getSelectedCategoryEntries();
+ if(selectedCategoryEntries.length > 0){
+ updateSelectedCategories(selectedCategoryEntries);
+ enableOk();
+ setCompleteOkMessage();
+ }
+ else{
+ disableOk();
+ showErrorMessage();
+ }
+ categoryViewer.refresh();
+ }
+
+ /**
+ * Creates checkbox viewer component for showing available SWMT categories.
+ * @param parent Parent composite for the created composite.
+ * @return New <code>CheckboxTableViewer</code> object instance.
+ */
+ protected CheckboxTableViewer createCategoryCheckBoxTableViewer(Composite parent) {
+
+ ArrayList<S60ToolsTableColumnData> columnDataArr = new ArrayList<S60ToolsTableColumnData>();
+
+ //
+ // NOTE: Column indices must start from zero (0) and
+ // the columns must be added in ascending numeric
+ // order.
+ //
+ columnDataArr.add(new S60ToolsTableColumnData("Category", //$NON-NLS-1$
+ 350,
+ SWMTCategoryEntry.NAME_COLUMN_INDEX,
+ SWMTCategoryEntryTableViewerSorter.CRITERIA_NAME));
+
+ S60ToolsTableColumnData[] arr
+ = columnDataArr.toArray(
+ new S60ToolsTableColumnData[0]);
+
+ S60ToolsTable tbl = S60ToolsTableFactory.createCheckboxTable(parent, arr);
+
+ CheckboxTableViewer tblViewer = new CheckboxTableViewer(tbl.getTableInstance());
+ tbl.setHostingViewer(tblViewer);
+
+ return tblViewer;
+ }
+
+ /**
+ * Returns currently selected categories.
+ * @return currently selected categories
+ */
+ private Object[] getSelectedCategoryEntries() {
+ return categoryViewer.getCheckedElements();
+ }
+
+ /**
+ * Stores currently selected categories combined with bitwise as a single integer.
+ * @param selectedCategoryEntries array of selected category entries
+ */
+ private void updateSelectedCategories(Object[] selectedCategoryEntries) {
+ // Re-initializing category selection
+ categorySelection = SWMTCategoryConstants.CATEGORY_NONE;
+ for (int i = 0; i < selectedCategoryEntries.length; i++) {
+ SWMTCategoryEntry categoryEntry = (SWMTCategoryEntry) selectedCategoryEntries[i];
+ categorySelection = categorySelection | categoryEntry.getCategoryId();
+ }
+ }
+
+ /**
+ * Returns currently selected categories combined with bitwise as a single integer.
+ * @return currently selected categories combined with bitwise as a single integer.
+ */
+ public int getSelectedCategories() {
+ return categorySelection;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/ui/dialogs/SWMTCategoryEntry.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,70 @@
+/*
+* Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+package com.nokia.s60tools.memspy.ui.dialogs;
+
+import com.nokia.s60tools.memspy.model.SWMTCategoryConstants;
+
+
+/**
+ * Stores information on a single SIS file entry.
+ */
+public class SWMTCategoryEntry {
+
+ //
+ // Column sorting indices for table column sorter
+ //
+ public static final int NAME_COLUMN_INDEX = 0;
+
+ /**
+ * Category id listed in SWMT category constants
+ * @see SWMTCategoryConstants
+ */
+ private final int categoryId;
+
+ /**
+ * Name of the SWMT category.
+ */
+ private final String categoryName;
+
+ /**
+ * Constructor.
+ * @param categoryId path name of the directory SIS file is locating.
+ * @param categoryName name of the SIS file without path.
+ */
+ public SWMTCategoryEntry(int categoryId, String categoryName){
+ this.categoryId = categoryId;
+ this.categoryName = categoryName;
+ }
+
+ /**
+ * Gets path name of the directory SIS file is locating.
+ * @return path name of the directory SIS file is locating.
+ */
+ public int getCategoryId() {
+ return categoryId;
+ }
+
+ /**
+ * Gets name SWMT category.
+ * @return name SWMT category entry
+ */
+ public String getCategoryName() {
+ return categoryName;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/ui/dialogs/SWMTCategoryEntryTableViewerSorter.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,76 @@
+/*
+* Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+package com.nokia.s60tools.memspy.ui.dialogs;
+
+import org.eclipse.jface.viewers.Viewer;
+
+import com.nokia.s60tools.memspy.util.MemSpyConsole;
+import com.nokia.s60tools.ui.S60ToolsViewerSorter;
+
+/**
+ * Sorter implementation for SWMT category entry data.
+ */
+public class SWMTCategoryEntryTableViewerSorter extends S60ToolsViewerSorter {
+
+ //
+ // Sorting criteria constants
+ //
+ public static final int CRITERIA_NAME = 1;
+
+ /**
+ * Constructor
+ */
+ public SWMTCategoryEntryTableViewerSorter() {
+ super();
+ // By default we are not sorting the information
+ setSortCriteria(CRITERIA_NO_SORT);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.ViewerSorter#compare(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object)
+ */
+ public int compare(Viewer viewer, Object e1, Object e2) {
+
+ // By default comparison does not do any ordering
+ int compRes = 0;
+
+ SWMTCategoryEntry entry1 = (SWMTCategoryEntry) e1;
+ SWMTCategoryEntry entry2 = (SWMTCategoryEntry) e2;
+
+ switch (sortCriteria) {
+
+ case CRITERIA_NAME:
+ compRes = alphabeticSort(entry1.getCategoryName(), entry2.getCategoryName());
+ break;
+
+ case CRITERIA_NO_SORT:
+ // No sorting criteria defined.
+ break;
+
+ default:
+ MemSpyConsole.getInstance()
+ .println(
+ "Unexpected sort criteria for a catecory entriey encountered: " + sortCriteria, //$NON-NLS-1$
+ MemSpyConsole.MSG_ERROR);
+ break;
+ }
+
+ return compRes;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/ui/views/MemSpyDataSorter.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,101 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+package com.nokia.s60tools.memspy.ui.views;
+
+import org.eclipse.jface.viewers.Viewer;
+
+import com.nokia.s60tools.memspy.model.MemSpyFileBundle;
+import com.nokia.s60tools.ui.S60ToolsViewerSorter;
+
+/**
+ * class MemSpyDataSorter
+ * Data sorter for MemSpy's main view.
+ */
+
+public class MemSpyDataSorter extends S60ToolsViewerSorter {
+
+ /**
+ * Import function data is sorted by file type
+ */
+ public static final int FILE_TYPE = 1;
+ /**
+ * Import function data is sorted by file name
+ */
+ public static final int FILENAME = 2;
+
+ /**
+ * Import function data is sorted by time
+ */
+ public static final int TIME = 3;
+
+ /**
+ * Constructor
+ */
+ public MemSpyDataSorter() {
+ super();
+ // By default set sorting to time
+ setSortCriteria(TIME);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.ViewerSorter#compare(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object)
+ */
+ public int compare(Viewer viewer, Object e1, Object e2) {
+
+
+ // By default comparison does not do any ordering
+ int comparisonResult = 0;
+
+ MemSpyFileBundle f1 = (MemSpyFileBundle) e1;
+ MemSpyFileBundle f2 = (MemSpyFileBundle) e2;
+
+ switch (sortCriteria) {
+
+ case FILE_TYPE:
+ comparisonResult = f1.getFileType().compareToIgnoreCase( f2.getFileType() );
+ // when type is same, sort alphabetically
+ if( comparisonResult == 0 ){
+ comparisonResult = numericSort( f2.getTimeAsLong(), f1.getTimeAsLong() );
+ }
+ break;
+ case FILENAME:
+ comparisonResult = f1.getFileName().compareToIgnoreCase( f2.getFileName() );
+ break;
+ case TIME:
+ comparisonResult = numericSort( f2.getTimeAsLong(), f1.getTimeAsLong() );
+ if( comparisonResult == 0 ){
+ comparisonResult = numericSort( f2.getCycleNumberFromFileName(), f1.getCycleNumberFromFileName() );
+ }
+
+ break;
+ case CRITERIA_NO_SORT:
+ comparisonResult = f2.getFileType().compareToIgnoreCase( f1.getFileType() );
+ // when type is same, sort by file time
+ if( comparisonResult == 0 ){
+ comparisonResult = numericSort( f2.getTimeAsLong(), f1.getTimeAsLong() );
+ }
+ break;
+ default:
+ break;
+ }
+
+ return comparisonResult;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/ui/views/MemSpyMainView.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,1329 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+
+package com.nokia.s60tools.memspy.ui.views;
+
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.eclipse.core.filesystem.EFS;
+import org.eclipse.core.filesystem.IFileStore;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.IMenuListener;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.IToolBarManager;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.action.Separator;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.viewers.DoubleClickEvent;
+import org.eclipse.jface.viewers.IDoubleClickListener;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.window.Window;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.events.KeyListener;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.program.Program;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.FileDialog;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swt.widgets.MessageBox;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.ISharedImages;
+import org.eclipse.ui.IViewPart;
+import org.eclipse.ui.IViewReference;
+import org.eclipse.ui.IWorkbenchActionConstants;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.ide.IDE;
+import org.eclipse.ui.part.ViewPart;
+
+import com.nokia.s60tools.heapanalyser.interfaces.HeapAnalyserLauncher;
+import com.nokia.s60tools.memspy.interfaces.IAnalyseHeapJobListener;
+import com.nokia.s60tools.memspy.interfaces.INewMemSpyFilesObserver;
+import com.nokia.s60tools.memspy.model.AnalyseHeapJob;
+import com.nokia.s60tools.memspy.model.AnalyserXMLGenerator;
+import com.nokia.s60tools.memspy.model.AnalyserXMLParser;
+import com.nokia.s60tools.memspy.model.ImportEngine;
+import com.nokia.s60tools.memspy.model.MemSpyFileBundle;
+import com.nokia.s60tools.memspy.model.MemSpyFileOperations;
+import com.nokia.s60tools.memspy.model.UserEnteredData;
+import com.nokia.s60tools.memspy.model.UserEnteredData.ValueTypes;
+import com.nokia.s60tools.memspy.plugin.MemSpyPlugin;
+import com.nokia.s60tools.memspy.resources.HelpContextIDs;
+import com.nokia.s60tools.memspy.resources.ImageKeys;
+import com.nokia.s60tools.memspy.resources.ImageResourceManager;
+import com.nokia.s60tools.memspy.ui.wizards.MemSpyWizard;
+import com.nokia.s60tools.memspy.ui.wizards.MemSpyWizardDialog;
+import com.nokia.s60tools.memspy.ui.wizards.MemSpyWizard.MemSpyWizardType;
+import com.nokia.s60tools.memspy.util.MemSpyConsole;
+import com.nokia.s60tools.swmtanalyser.ui.actions.SwmtAnalyser;
+import com.nokia.s60tools.ui.S60ToolsTable;
+import com.nokia.s60tools.ui.S60ToolsTableColumnData;
+import com.nokia.s60tools.ui.S60ToolsTableFactory;
+import com.nokia.s60tools.ui.S60ToolsViewerSorter;
+import com.nokia.s60tools.util.debug.DbgUtility;
+
+
+
+/**
+ * <p>
+ * MemSpyMainView.
+ * The main view of MemSpy Carbide extension. Shows imported MemSpy data files in a table and allows user to:
+ * - Launch Heap Analyser to analyse one Heap Dump file.
+ * - Launch Heap Analyser to compare two Heap Dump files.
+ * - Launch SWMT-analyser and analyse one System Wide Memory Tracking log.
+ * <p>
+ */
+
+public class MemSpyMainView extends ViewPart implements INewMemSpyFilesObserver, SelectionListener, IAnalyseHeapJobListener, KeyListener {
+
+
+ /**
+ * Enumeration for actions for a MemSpy file
+ */
+ private enum FileActionType{NONE, ANALYSE_SWMT_ONE, ANALYSE_SWMT_MULTIPLE, ANALYSE_HEAP, COMPARE_HEAPS, DELETE};
+
+ /**
+ * TraceViewers ID com.nokia.traceviewer.view.TraceViewerView
+ */
+ private static final String TRACE_VIEWER_VIEW_ID = "com.nokia.traceviewer.view.TraceViewerView";
+
+ /**
+ * Main view's ID com.nokia.s60tools.memspy.ui.views.MemSpyMainView
+ */
+ private static final String ID = "com.nokia.s60tools.memspy.ui.views.MemSpyMainView";
+
+ /* viewer for table */
+ private TableViewer viewer;
+
+ /* contentProvider for table */
+ private MemSpyMainViewContentProvider contentProvider;
+
+ /* Launch Heap Analyser - action */
+ private Action launchHeapAnalyserAction;
+
+ /* Launch Wizard - action */
+ private Action launchWizardAction;
+
+ /* compare two heaps - action */
+ private Action compareTwoHeapsAction;
+
+ /* import and compare two heaps - action */
+ private Action importAndCompareHeapsAction;
+
+ /* import and compare two heaps - toolbar action
+ that changes based on selection*/
+ private Action compareHeapsToolbarAction;
+
+ /* Launch SWMT-analyser - action */
+ private Action launchSWMTAction;
+
+ /* delete selected files - action */
+ private Action deleteAction;
+
+ /* import engine */
+ private ImportEngine importEngine;
+
+ /* doubleClick - action */
+ private Action doubleClickAction;
+
+ /* open file in text editor */
+ private Action openFile;
+
+ /* edit symbol information */
+ private Action editSymbols;
+
+
+ //
+ //Strings for error and info messages
+ //
+
+ /**
+ * Error message for analysis startup
+ */
+ public final static String ERROR_LAUNCH_SWMT_ANALYSER = "MemSpy was unable to start analysing imported files.";
+ /**
+ * Error message for Heap Dump import
+ */
+ public final static String ERROR_HEAP_IMPORT_FAILED = "Some of the Heap Dumps were not imported successfully.( file operations were not successfull )";
+ /**
+ * Error message for SWMT import
+ */
+ public final static String ERROR_SWMT_IMPORT_FAILED = "SWMT-files were not imported successfully. ( file operations were not successfull )";
+ /**
+ * Error message for import
+ */
+ public final static String ERROR_IMPORT_HEADER = "Import error";
+ /**
+ * Warning message for compare
+ */
+ public final static String WARNING_COMPARE = "Compare Warning";
+ /**
+ * Warning message for filea allready exist
+ */
+ public final static String WARNING_FILE_EXISTS = "The file already exists. Do you want to replace the existing file?";
+
+ private final static String ERROR_COMPARE = "Compare error";
+ private final static String ERROR_HEAP_THREADS_NOT_SAME = "Selected Heaps cannot be compared. Only two Heap Dumps that are from same thread can be compared.";
+ private final static String ERROR_TOPIC = "MemSpy Error";
+ private final static String ERROR_CONFIGURATION_FILES_NOT_FOUND = "Configuration files for selected heaps cannot be found.";
+ private final static String ERROR_UNABLE_TO_GENERATE_CONFIGURATIONS = "Error was encountered when generating files that are needed when running Heap Analyser.";
+ private final static String ERROR_HEAP_ANALYSER = "Heap Analyser error.";
+ private final static String WARNING_SYMBOLS_NOT_SAME = "Selected files symbol definitions differ, do you wish to compare heaps anyway?";
+ private final static String FILE_DIALOG_DEFINE_OUTPUT = "Define output file name";
+ private final static String CONFIRMATION = "Confirmation";
+ private final static String CONFIRMATION_OPEN_FILE = "Open generated xls-file with application that is assosiated for that file type?";
+
+ private final static String TOOLTIP_COMPARE_2_IMPORTED_FILE = "Compare selected heaps with Heap Analyser";
+ private final static String TOOLTIP_TEXT_IMPORT_AND_COMPARE = "Import heap dump and compare it to selected heap";
+
+
+ /**
+ * The constructor.
+ */
+ public MemSpyMainView() {
+ importEngine = new ImportEngine( this );
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.part.WorkbenchPart#createPartControl(org.eclipse.swt.widgets.Composite)
+ */
+ public void createPartControl(Composite parent) {
+
+
+ ArrayList<S60ToolsTableColumnData> columnDataArr = new ArrayList<S60ToolsTableColumnData>();
+
+ columnDataArr.add(new S60ToolsTableColumnData("File Type", 150, 0, MemSpyDataSorter.FILE_TYPE));
+ columnDataArr.add(new S60ToolsTableColumnData("File Name", 300, 1, MemSpyDataSorter.FILENAME));
+ columnDataArr.add(new S60ToolsTableColumnData("Time", 150, 2, MemSpyDataSorter.TIME));
+
+
+ S60ToolsTableColumnData[] arr = columnDataArr.toArray(new S60ToolsTableColumnData[0]);
+
+ S60ToolsTable tbl = S60ToolsTableFactory.create(parent, arr);
+
+ viewer = new TableViewer( tbl.getTableInstance() );
+ contentProvider = new MemSpyMainViewContentProvider( this );
+ viewer.setContentProvider( contentProvider );
+ viewer.setLabelProvider(new MemSpyMainViewLabelProvider());
+ viewer.setComparator(new MemSpyDataSorter());
+ viewer.setSorter(new MemSpyDataSorter());
+ viewer.setInput(getViewSite());
+
+ tbl.addSelectionListener(this);
+ tbl.addKeyListener(this);
+ tbl.setHostingViewer(viewer);
+
+ try {
+ PlatformUI.getWorkbench().getHelpSystem().setHelp(viewer.getControl(),HelpContextIDs.MEMSPY_MAIN_VIEW);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ // Make actions
+ makeActions();
+
+ // hook context menus
+ hookContextMenu();
+
+ // hook double click action
+ hookDoubleClickAction();
+
+ // contribute to action bars
+ contributeToActionBars();
+
+ // refresh view
+ this.refreshView();
+
+ // update toolbar items state
+ this.enableAndDisableToolbarItems();
+
+
+
+ }
+
+ /**
+ * hookContextMenu.
+ * Creates context menu.
+ */
+ private void hookContextMenu() {
+ MenuManager menuMgr = new MenuManager("#PopupMenu");
+
+ // Adding all actions to menu.
+ menuMgr.add(launchHeapAnalyserAction);
+ menuMgr.add(compareTwoHeapsAction);
+ menuMgr.add(importAndCompareHeapsAction);
+ menuMgr.add(launchSWMTAction);
+ menuMgr.add(editSymbols);
+ menuMgr.add(openFile);
+ menuMgr.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
+ menuMgr.add(deleteAction);
+
+ menuMgr.addMenuListener(new IMenuListener() {
+ public void menuAboutToShow(IMenuManager manager) {
+ MemSpyMainView.this.fillContextMenu(manager);
+ }
+ });
+ Menu menu = menuMgr.createContextMenu(viewer.getControl());
+ viewer.getControl().setMenu(menu);
+ getSite().registerContextMenu(menuMgr, viewer);
+ }
+
+ /**
+ * contributeToActionBars.
+ * fills pull down menu and local toolbar
+ */
+ private void contributeToActionBars() {
+ IActionBars bars = getViewSite().getActionBars();
+ fillLocalToolBar(bars.getToolBarManager());
+ }
+
+
+ /**
+ * fillContextMenu.
+ * fills context menu depending what type of file or files are selected.
+ * @param manager menuManager
+ */
+ private void fillContextMenu(IMenuManager manager) {
+
+ FileActionType availableAction = this.getAvailableAction();
+
+ if( availableAction == FileActionType.ANALYSE_HEAP ){
+ launchHeapAnalyserAction.setEnabled(true);
+ compareTwoHeapsAction.setEnabled(false);
+ importAndCompareHeapsAction.setEnabled(true);
+ launchSWMTAction.setEnabled(false);
+ editSymbols.setEnabled(true);
+ openFile.setEnabled(true);
+ deleteAction.setEnabled(true);
+ }
+ else if( availableAction == FileActionType.ANALYSE_SWMT_ONE ){
+ launchHeapAnalyserAction.setEnabled(false);
+ compareTwoHeapsAction.setEnabled(false);
+ importAndCompareHeapsAction.setEnabled(false);
+ launchSWMTAction.setEnabled(true);
+ editSymbols.setEnabled(false);
+ openFile.setEnabled(true);
+ deleteAction.setEnabled(true);
+ }
+ else if( availableAction == FileActionType.ANALYSE_SWMT_MULTIPLE ){
+ launchHeapAnalyserAction.setEnabled(false);
+ compareTwoHeapsAction.setEnabled(false);
+ importAndCompareHeapsAction.setEnabled(false);
+ launchSWMTAction.setEnabled(true);
+ editSymbols.setEnabled(false);
+ openFile.setEnabled(false);
+ deleteAction.setEnabled(true);
+ }
+ else if( availableAction == FileActionType.COMPARE_HEAPS ){
+ launchHeapAnalyserAction.setEnabled(false);
+ compareTwoHeapsAction.setEnabled(true);
+ importAndCompareHeapsAction.setEnabled(false);
+ launchSWMTAction.setEnabled(false);
+ editSymbols.setEnabled(false);
+ openFile.setEnabled(false);
+ deleteAction.setEnabled(true);
+ }
+ else if( availableAction == FileActionType.DELETE ){
+ launchHeapAnalyserAction.setEnabled(false);
+ compareTwoHeapsAction.setEnabled(false);
+ importAndCompareHeapsAction.setEnabled(false);
+ launchSWMTAction.setEnabled(false);
+ editSymbols.setEnabled(false);
+ openFile.setEnabled(false);
+ deleteAction.setEnabled(true);
+ }
+ else if( availableAction == FileActionType.NONE ){
+ launchHeapAnalyserAction.setEnabled(false);
+ compareTwoHeapsAction.setEnabled(false);
+ importAndCompareHeapsAction.setEnabled(false);
+ launchSWMTAction.setEnabled(false);
+ editSymbols.setEnabled(false);
+ openFile.setEnabled(false);
+ deleteAction.setEnabled(false);
+ }
+ }
+
+
+ /**
+ * getAvailableAction.
+ * @return action type that is available for item or items that are currently selected.
+ */
+ private FileActionType getAvailableAction(){
+
+ // get selected items
+ IStructuredSelection selection = (IStructuredSelection) viewer.getSelection();
+
+ @SuppressWarnings("unchecked")
+ List selectionList = selection.toList();
+
+ boolean swmtFileFound = false;
+ boolean heapFileFound = false;
+
+ // go thru selected files-list
+ for(Object obj : selectionList){
+ MemSpyFileBundle bundle = (MemSpyFileBundle) obj;
+ if( bundle.getFileType().equals("SWMT-Log") ){
+ swmtFileFound = true;
+ }
+ else{
+ heapFileFound = true;
+ }
+ }
+
+ // if two files and no swmt files are found, compare heaps - action is available
+ if( selectionList.size() == 2 && heapFileFound && !swmtFileFound ){
+ return FileActionType.COMPARE_HEAPS;
+ }
+
+ // if swmt-files are found and no heap dumps are found, analyse swmt-action is available
+ else if( swmtFileFound && selectionList.size() == 1 ){
+ return FileActionType.ANALYSE_SWMT_ONE;
+ }
+ else if( swmtFileFound && !heapFileFound){
+ return FileActionType.ANALYSE_SWMT_MULTIPLE;
+ }
+
+ // if heap one heap file is found, analyse heap - action is available
+ else if( heapFileFound && selectionList.size() == 1 ){
+ return FileActionType.ANALYSE_HEAP;
+ }
+
+ // There are files selected, but only available action is delete.
+ else if( selectionList.size() > 0 ){
+ return FileActionType.DELETE;
+ }
+
+ // No files selected - no actions are available
+ return FileActionType.NONE;
+ }
+
+
+ /**
+ * enableAndDisableToolbarItems.
+ * Enables and disable toolbar items according to type of the selected file.
+ */
+ private void enableAndDisableToolbarItems(){
+ FileActionType availableAction = this.getAvailableAction();
+
+ if( availableAction == FileActionType.ANALYSE_HEAP ){
+ launchSWMTAction.setEnabled(false);
+ launchHeapAnalyserAction.setEnabled(true);
+ compareHeapsToolbarAction.setEnabled(true);
+ compareHeapsToolbarAction.setToolTipText(TOOLTIP_TEXT_IMPORT_AND_COMPARE);
+ deleteAction.setEnabled(true);
+
+
+ }
+ else if( availableAction == FileActionType.ANALYSE_SWMT_MULTIPLE || availableAction == FileActionType.ANALYSE_SWMT_ONE ){
+ launchSWMTAction.setEnabled(true);
+ launchHeapAnalyserAction.setEnabled(false);
+ compareHeapsToolbarAction.setEnabled(false);
+ deleteAction.setEnabled(true);
+ }
+ else if( availableAction == FileActionType.COMPARE_HEAPS ){
+ launchSWMTAction.setEnabled(false);
+ launchHeapAnalyserAction.setEnabled(false);
+ compareHeapsToolbarAction.setEnabled(true);
+ compareHeapsToolbarAction.setToolTipText(TOOLTIP_COMPARE_2_IMPORTED_FILE);
+ deleteAction.setEnabled(true);
+
+ }
+ else if( availableAction == FileActionType.DELETE ){
+ launchSWMTAction.setEnabled(false);
+ launchHeapAnalyserAction.setEnabled(false);
+ compareHeapsToolbarAction.setEnabled(false);
+ deleteAction.setEnabled(true);
+ }
+ else if( availableAction == FileActionType.NONE ){
+ launchSWMTAction.setEnabled(false);
+ launchHeapAnalyserAction.setEnabled(false);
+ compareHeapsToolbarAction.setEnabled(false);
+ deleteAction.setEnabled(false);
+ }
+ }
+
+
+ /**
+ * fillLocalToolBar.
+ * fills toolbar
+ * @param manager Toolbar manager
+ */
+ private void fillLocalToolBar(IToolBarManager manager) {
+ manager.add(launchSWMTAction);
+ manager.add(compareHeapsToolbarAction);
+ manager.add(launchHeapAnalyserAction);
+ manager.add(launchWizardAction);
+ manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
+ manager.add(deleteAction);
+
+ }
+
+
+ /**
+ * makeActions.
+ * Creates actions
+ */
+ private void makeActions() {
+
+ launchSWMTAction = new Action() {
+ @SuppressWarnings("unchecked")
+ public void run() {
+
+ // get selection list.
+ IStructuredSelection selection = (IStructuredSelection) viewer.getSelection();
+
+ // ensure that selected items are swmt-logs
+ if( !selection.isEmpty() ){
+
+ List<MemSpyFileBundle> list = selection.toList();
+ ArrayList<String> swmtLogs = new ArrayList<String>();
+
+ boolean allFilesAreSwmtLogs = true;
+
+ // Go thru bundle list and add all file paths into arraylist
+ for( MemSpyFileBundle item : list ){
+ swmtLogs.add( item.getFilePath() );
+ if( item.getFileType().equals("SWMT-log") ){
+ allFilesAreSwmtLogs = false;
+ }
+ }
+
+ // ensure that all selected files were swmt logs
+ if( allFilesAreSwmtLogs ){
+ // launch swmt analyser for selected logs.
+ SwmtAnalyser analyser = new SwmtAnalyser(MemSpyConsole.getInstance());
+ analyser.analyse( swmtLogs );
+ }
+ }
+ }
+ };
+ launchSWMTAction.setText("Launch SWMT-Analyser");
+ launchSWMTAction.setToolTipText("Launch SWMT-Analyser");
+ launchSWMTAction.setImageDescriptor(ImageResourceManager.getImageDescriptor(ImageKeys.IMG_LAUNCH_SWMT));
+
+
+ compareTwoHeapsAction = new Action() {
+ @SuppressWarnings("unchecked")
+ public void run() {
+
+ // get selected items:
+ ISelection selection = viewer.getSelection();
+ Object obj = ((IStructuredSelection)selection).toList();
+
+ List<MemSpyFileBundle> selectionList = (List<MemSpyFileBundle>)obj;
+
+ //verify that to heap files are selected.
+ if( getAvailableAction() == FileActionType.COMPARE_HEAPS ){
+ compareHeaps(selectionList);
+ }
+ }
+ };
+
+ compareTwoHeapsAction.setText(TOOLTIP_COMPARE_2_IMPORTED_FILE);
+ compareTwoHeapsAction.setToolTipText(TOOLTIP_COMPARE_2_IMPORTED_FILE);
+ compareTwoHeapsAction.setImageDescriptor(ImageResourceManager.getImageDescriptor(ImageKeys.IMG_COMPARE_2_HEAP));
+
+ importAndCompareHeapsAction = new Action() {
+ @SuppressWarnings("unchecked")
+ public void run() {
+
+ // get selected items:
+ ISelection selection = viewer.getSelection();
+ Object obj = ((IStructuredSelection)selection).toList();
+
+ List<MemSpyFileBundle> selectionList = (List<MemSpyFileBundle>)obj;
+
+ //verify that only one file is selected.
+ if( getAvailableAction() == FileActionType.ANALYSE_HEAP ){
+ importAndCompareHeaps(selectionList);
+ }
+ }
+ };
+
+ importAndCompareHeapsAction.setText(TOOLTIP_TEXT_IMPORT_AND_COMPARE);
+ importAndCompareHeapsAction.setToolTipText(TOOLTIP_TEXT_IMPORT_AND_COMPARE);
+ importAndCompareHeapsAction.setImageDescriptor(ImageResourceManager.getImageDescriptor(ImageKeys.IMG_COMPARE_2_HEAP));
+
+ compareHeapsToolbarAction = new Action() {
+ @SuppressWarnings("unchecked")
+ public void run() {
+
+ // get selected items:
+ ISelection selection = viewer.getSelection();
+ Object obj = ((IStructuredSelection)selection).toList();
+
+ List<MemSpyFileBundle> selectionList = (List<MemSpyFileBundle>)obj;
+
+ // check if only one file is selected.
+ if( getAvailableAction() == FileActionType.ANALYSE_HEAP ){
+ importAndCompareHeaps(selectionList);
+ }
+ // or if two heaps are selected, then compare them.
+ else if( getAvailableAction() == FileActionType.COMPARE_HEAPS ){
+ compareHeaps(selectionList);
+ }
+ }
+ };
+
+ compareHeapsToolbarAction.setText(TOOLTIP_COMPARE_2_IMPORTED_FILE);
+ compareHeapsToolbarAction.setToolTipText(TOOLTIP_COMPARE_2_IMPORTED_FILE);
+ compareHeapsToolbarAction.setImageDescriptor(ImageResourceManager.getImageDescriptor(ImageKeys.IMG_COMPARE_2_HEAP));
+
+ launchHeapAnalyserAction = new Action() {
+ @SuppressWarnings("unchecked")
+ public void run() {
+
+ ISelection selection = viewer.getSelection();
+ Object obj = ((IStructuredSelection)selection).toList();
+
+ List<MemSpyFileBundle> selectionList = (List<MemSpyFileBundle>)obj;
+
+ // Get thread name from xml-file
+ String xmlFile = selectionList.get(0).getXMLFilePath();
+ AnalyserXMLGenerator xml = readXMLFile(xmlFile);
+
+ //If Symbol files has not been set to data, before analyze, user have to set a Symbol file
+ if(!xml.hasXMLDebugMetaDataFile()){
+ //verify that only one file is selected.
+ if( selectionList.size() == 1 ){
+ //Make user to edit symbol files, and after that, continue to launch
+ int retCode = runWizard( MemSpyWizardType.SYMBOLS, xml );
+ //Don't giving an error message if user presses Cancel, instead just return
+ if(retCode == Window.CANCEL){
+ return;
+ }
+ }
+ }
+
+
+ String threadName = xml.getXMLThreadName();
+
+ //verify that only one file is selected.
+ if( selectionList.size() == 1 ){
+
+ //verify that heap dump file is selected.
+ if( selectionList.get(0).hasHeapDumpFile() ){
+
+ // get xml files path
+ String xmlPath = xmlFile;
+
+ // launch heap analyser
+ launchHeapAnalyser( xmlPath, null, threadName, true );
+
+ }
+
+
+ }
+ }
+ };
+ launchHeapAnalyserAction.setText("Analyse selected heap with Heap Analyser");
+ launchHeapAnalyserAction.setToolTipText("Analyse selected heap with Heap Analyser");
+ launchHeapAnalyserAction.setImageDescriptor(ImageResourceManager.getImageDescriptor(ImageKeys.IMG_ANALYZE_HEAP));
+
+
+ launchWizardAction = new Action() {
+ public void run() {
+ runWizard( MemSpyWizardType.FULL, null );
+ }
+ };
+
+ launchWizardAction.setText("Launch MemSpy's import Wizard");
+ launchWizardAction.setToolTipText("Launch MemSpy's import Wizard");
+ launchWizardAction.setImageDescriptor(ImageResourceManager.getImageDescriptor(ImageKeys.IMG_APP_ICON));
+
+
+ doubleClickAction = new Action() {
+ public void run() {
+ FileActionType action = getAvailableAction();
+ switch (action){
+ case ANALYSE_HEAP:{
+ launchHeapAnalyserAction.run();
+ break;
+ }
+ case ANALYSE_SWMT_ONE:
+ case ANALYSE_SWMT_MULTIPLE:{
+ launchSWMTAction.run();
+ break;
+ }
+ case COMPARE_HEAPS:{
+ compareTwoHeapsAction.run();
+ break;
+ }
+ default:{
+ // No need to do anything with other action.
+ break;
+ }
+
+ }
+ }
+ };
+
+
+
+ deleteAction = new Action() {
+ @SuppressWarnings("unchecked")
+ public void run() {
+ // get selected items:
+ ISelection selection = viewer.getSelection();
+ Object obj = ((IStructuredSelection)selection).toList();
+
+
+ List<MemSpyFileBundle> selectionList = (List<MemSpyFileBundle>)obj;
+
+ // ensure that some item(s) is selected.
+ if( selectionList.size() >= 1 ){
+
+ // Display a Confirmation dialog
+ MessageBox messageBox = new MessageBox(viewer.getControl().getShell(), SWT.ICON_QUESTION | SWT.YES | SWT.NO);
+ messageBox.setText("MemSpy - Delete Files");
+ messageBox.setMessage("Are you sure you want to delete selected files?");
+ int buttonID = messageBox.open();
+ if (buttonID == SWT.YES) {
+ for( MemSpyFileBundle item : selectionList ){
+
+ // delete it
+ item.delete();
+
+ }
+ refreshContentAndView();
+ }
+
+ }
+
+ }
+ };
+
+ deleteAction.setText("Delete");
+ deleteAction.setToolTipText("Delete selected item");
+ deleteAction.setImageDescriptor( PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(ISharedImages.IMG_TOOL_DELETE));
+
+
+ openFile = new Action() {
+ @SuppressWarnings("unchecked")
+ public void run() {
+ ISelection selection = viewer.getSelection();
+ Object obj = ((IStructuredSelection)selection).toList();
+
+ List<MemSpyFileBundle> selectionList = (List<MemSpyFileBundle>)obj;
+
+ //verify that only one file is selected.
+ if( selectionList.size() == 1 ){
+
+ // open selected log file in editor.
+ File fileToOpen = new File(selectionList.get(0).getFilePath());
+ if (fileToOpen.exists() && fileToOpen.isFile()) {
+ IFileStore fileStore = EFS.getLocalFileSystem().getStore(fileToOpen.toURI());
+ IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
+
+ try {
+ IDE.openEditorOnFileStore( page, fileStore );
+ } catch ( PartInitException e ) {
+ showErrorMessage(ERROR_TOPIC, "MemSpy was unable to open file.");
+ }
+ } else {
+ showErrorMessage(ERROR_TOPIC, "File does not exists.");
+
+ }
+
+ }
+ }
+ };
+ openFile.setText("Open selected file in text editor");
+ openFile.setToolTipText("Open selected file in text editor");
+
+ editSymbols = new Action() {
+ @SuppressWarnings("unchecked")
+ public void run() {
+ ISelection selection = viewer.getSelection();
+ Object obj = ((IStructuredSelection)selection).toList();
+
+ List<MemSpyFileBundle> selectionList = (List<MemSpyFileBundle>)obj;
+
+ //verify that only one file is selected.
+ if( selectionList.size() == 1 ){
+ AnalyserXMLGenerator info = readXMLFile(selectionList.get(0).getXMLFilePath());
+ runWizard( MemSpyWizardType.SYMBOLS, info );
+ }
+ }
+ };
+ editSymbols.setText("Edit symbol definitions of selected Heap Dump");
+ editSymbols.setToolTipText("Edit symbol definitions of selected Heap Dump");
+ }
+
+
+ /**
+ * Starts wizard to compare currently selected heap file.
+ * @param selectionList List from which selected file is found.
+ */
+ private void importAndCompareHeaps(List<MemSpyFileBundle> selectionList) {
+ // get info from xml-file
+ AnalyserXMLGenerator info = readXMLFile(selectionList.get(0).getXMLFilePath());
+
+ // set source files path into info
+ info.setXMLSourceFile(new String[]{ selectionList.get(0).getFilePath() });
+
+ // start wizard
+ runWizard( MemSpyWizardType.COMPARE, info);
+ }
+
+ /**
+ * Starts Heap analyzer to compare two currently selected heaps.
+ * @param selectionList List from which selected heap files are found.
+ */
+ private void compareHeaps(List<MemSpyFileBundle> selectionList) {
+ // get selected file bundles.
+ MemSpyFileBundle bundle1 = selectionList.get(0);
+ MemSpyFileBundle bundle2 = selectionList.get(1);
+
+ // read both Heap Dumps configuration files
+ AnalyserXMLGenerator generator1 = readXMLFile(bundle1.getXMLFilePath());
+ AnalyserXMLGenerator generator2 = readXMLFile(bundle2.getXMLFilePath());
+
+ // ensure that both generators were created successfully.
+ if( generator1 == null || generator2 == null ){
+ MessageDialog.openError( getSite().getShell(), ERROR_COMPARE, ERROR_CONFIGURATION_FILES_NOT_FOUND );
+ return;
+ }
+
+ // if Heaps are not from same thread show error message
+ if( !generator1.getXMLThreadName().equals( generator2.getXMLThreadName() ) ){
+ MessageDialog.openError( getSite().getShell(), ERROR_COMPARE, ERROR_HEAP_THREADS_NOT_SAME );
+ return;
+ }
+
+ boolean compare = true;
+
+ // if symbol definitions are not same, confirm that user really wants continue comparing
+ if( !Arrays.equals(generator1.getXMLDebugMetaDataFile(), generator2.getXMLDebugMetaDataFile() ) ){
+ // Display a Confirmation dialog
+ MessageBox messageBox = new MessageBox(viewer.getControl().getShell(), SWT.ICON_QUESTION | SWT.YES | SWT.NO);
+ messageBox.setText( WARNING_COMPARE );
+ messageBox.setMessage( WARNING_SYMBOLS_NOT_SAME );
+ int buttonID = messageBox.open();
+ if (buttonID == SWT.NO) {
+ compare = false;
+ }
+ }
+ if( compare ){
+
+ UserEnteredData data = new UserEnteredData();
+
+ // open file dialog for selecting a MemSpy file
+ FileDialog dialog = new FileDialog( getSite().getShell(), SWT.SAVE );
+ dialog.setText(FILE_DIALOG_DEFINE_OUTPUT);
+ String[] filterExt = { "*.xls" };
+ dialog.setFilterExtensions(filterExt);
+
+ // Restore previous output filename
+ String[] lastUsedFiles = data.getPreviousValues(ValueTypes.OUTPUT_FILE);
+ if( lastUsedFiles != null && lastUsedFiles.length > 0 ){
+ dialog.setFileName(lastUsedFiles[0]);
+ }
+
+ String result = dialog.open();
+
+
+ if( result != null ){
+
+ File file = new File( result );
+ // If file already exists, confirm that user wants to rewrite it.
+ if( file.exists() ){
+
+ // Display a Confirmation dialog
+ MessageBox messageBox = new MessageBox(viewer.getControl().getShell(), SWT.ICON_QUESTION | SWT.YES | SWT.NO);
+ messageBox.setText( WARNING_COMPARE );
+ messageBox.setMessage( WARNING_FILE_EXISTS );
+ int buttonID = messageBox.open();
+ if (buttonID == SWT.NO) {
+ compare = false;
+ }
+ }
+
+ if( compare ){
+
+ // Save output filename so that it can be restored later
+ data.saveValue(ValueTypes.OUTPUT_FILE, result);
+
+ generator1.setXMLAnalyseFileOutput(result);
+ String[] sources = new String[]{ bundle1.getFilePath(), bundle2.getFilePath() };
+
+ // generate configuration file for comparison
+ if( importEngine.generateCompareConfigurationFile(sources, generator1.getXMLThreadName(), generator1)){
+ launchHeapAnalyser( MemSpyFileOperations.getCompareConfigurationFilePath(), result, generator1.getXMLThreadName(), false );
+ }
+ else{
+ MessageDialog.openError( getSite().getShell(), ERROR_COMPARE, ERROR_UNABLE_TO_GENERATE_CONFIGURATIONS );
+ return;
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * hookDoubleClickAction
+ * adds double click listener
+ */
+ private void hookDoubleClickAction() {
+ viewer.addDoubleClickListener(new IDoubleClickListener() {
+ public void doubleClick(DoubleClickEvent event) {
+ doubleClickAction.run();
+ }
+ });
+ }
+
+ /**
+ * setFocus.
+ * Passing the focus request to the viewer's control.
+ */
+ public void setFocus() {
+ viewer.getControl().setFocus();
+ }
+
+
+ /**
+ * Makes main view visible and returns an instance of itself. Can be called from
+ * an UI thread only.
+ * @return instance of main view
+ */
+ public static MemSpyMainView showAndReturnYourself() {
+ return showAndReturnYourself(false);
+ }
+
+ /**
+ * Makes main view visible and returns an instance of itself. Can be called from
+ * an UI thread only.
+ * @return instance of main view
+ */
+ public static MemSpyMainView showAndReturnYourself(boolean openOnly) {
+ try {
+
+ IWorkbenchWindow ww = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
+ if (ww == null)
+ return null;
+
+ IWorkbenchPage page = ww.getActivePage();
+ IWorkbenchPart currentPart = page.getActivePart();
+
+ // Checking if view is already open
+ IViewReference[] viewRefs = page.getViewReferences();
+ for (int i = 0; i < viewRefs.length; i++) {
+ IViewReference reference = viewRefs[i];
+ String id = reference.getId();
+ if(id.equalsIgnoreCase(MemSpyMainView.ID)){
+ // Found, restoring the view
+ IViewPart viewPart = reference.getView(true);
+ if (!openOnly)
+ page.activate(viewPart);
+ return (MemSpyMainView)viewPart;
+ }
+ }
+
+ // View was not found, opening it up as a new view.
+ MemSpyMainView mView = (MemSpyMainView)page.showView(MemSpyMainView.ID);
+ if (openOnly)
+ page.bringToTop(currentPart);
+ return mView;
+
+ } catch (Exception e) {
+ e.printStackTrace();
+
+ return null;
+ }
+ }
+
+ /**
+ * runWizard().
+ * Starts MemSpy import wizard.
+ * @return {@link Window#OK} if Finish pressed, {@link Window#CANCEL} if Cancel was pressed.
+ */
+ public int runWizard( MemSpyWizardType wizardType, AnalyserXMLGenerator info ){
+
+
+ MemSpyWizard wizard = null;
+ if( wizardType == MemSpyWizardType.FULL ){
+ wizard = new MemSpyWizard( wizardType, null );
+
+ }
+ else if( wizardType == MemSpyWizardType.COMPARE || wizardType == MemSpyWizardType.SYMBOLS ){
+ wizard = new MemSpyWizard( wizardType, info );
+ }
+
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "Open wizard dialog");
+ // Open wizard dialog
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "Create Dialog");
+ MemSpyWizardDialog wizDialog = new MemSpyWizardDialog(getViewSite().getShell(), wizard);
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "Set dialog data");
+ wizard.setData(wizDialog);
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "Set dialog size");
+ wizDialog.setPageSize(600, 600);
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "Add pagecnhangelistener");
+ wizDialog.addPageChangedListener(wizard);
+ wizard.setWindowTitle("MemSpy Import Wizard");
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "Creating wizaDialog");
+ wizDialog.create();
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "open wizaDialog");
+
+ return wizDialog.open();
+ }
+
+ /**
+ * readXMLFile.
+ * Reads xml file from given path.
+ * @param XMLFilePath path of xml-file
+ * @return analyserXMLFile with read values.
+ */
+ private AnalyserXMLGenerator readXMLFile(String XMLFilePath){
+
+ FileReader reader = null;
+ try {
+ File file = new File( XMLFilePath );
+ reader = new FileReader(file );
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ return null;
+ }
+ catch (Exception e) {
+ e.printStackTrace();
+ return null;
+ }
+ BufferedReader bReader = new BufferedReader(reader);
+ AnalyserXMLGenerator xml = AnalyserXMLParser.parseXML( bReader );
+ return xml;
+
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see com.nokia.s60tools.memspy.interfaces.INewMemSpyFilesObserver#memSpyFilesUpdated()
+ */
+ public void memSpyFilesUpdated() {
+ Runnable refreshRunnable = new Runnable(){
+ public void run(){
+ refreshView();
+ // Sort files so that newly imported files are in top
+ ((S60ToolsViewerSorter) viewer.getSorter()).setSortCriteria(MemSpyDataSorter.TIME);
+ }
+ };
+ Display.getDefault().asyncExec(refreshRunnable);
+
+
+ }
+
+ /**
+ * refreshView.
+ * Refreshes view asynchronously.
+ */
+ private void refreshView() {
+ Runnable refreshRunnable = new Runnable(){
+ public void run(){
+ viewer.refresh();
+ enableAndDisableToolbarItems();
+
+ }
+ };
+
+ // Has to be done in its own thread
+ // in order not to cause invalid thread access
+ Display.getDefault().asyncExec(refreshRunnable);
+ }
+
+ /**
+ * refreshContentAndView.
+ * Refreshes content and view synchronously.
+ */
+ private void refreshContentAndView(){
+ contentProvider.refresh();
+ viewer.refresh();
+ this.enableAndDisableToolbarItems();
+ }
+
+ /**
+ * Refreshes content and view asynchronously.
+ */
+ public void refreshContentAndViewAsync() {
+ Runnable refreshRunnable = new Runnable(){
+ public void run(){
+ refreshContentAndView();
+ }
+ };
+
+ Display.getDefault().asyncExec(refreshRunnable);
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.swt.events.SelectionListener#widgetDefaultSelected(org.eclipse.swt.events.SelectionEvent)
+ */
+ public void widgetDefaultSelected(SelectionEvent arg0) {
+ // can be left empty.
+
+ }
+ public void widgetSelected(SelectionEvent arg0) {
+ this.enableAndDisableToolbarItems();
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see com.nokia.s60tools.memspy.interfaces.IAnalyseHeapJobListener#heapAnalyserReturnValue(int)
+ */
+ public void heapAnalyserFinished(final int returnValue) {
+
+ if( returnValue != 0 ){
+ String errorMessage = HeapAnalyserLauncher.getErrorMessage(returnValue);
+ // Reporting error to console
+ String consoleErrMsg = "Heap Analyser launch failure with process exit value=" + returnValue + "."
+ + " " + errorMessage;
+ reportConsoleMessage(consoleErrMsg, MemSpyConsole.MSG_ERROR);
+ // Reporting error to user
+ showErrorMessage(ERROR_HEAP_ANALYSER, errorMessage );
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see com.nokia.s60tools.memspy.interfaces.IAnalyseHeapJobListener#heapAnalyserReturnValue(int, java.lang.String)
+ */
+ public void heapAnalyserFinished(int returnValue, final String outputFilePath) {
+
+ // if error occured
+ if( returnValue != 0 ){
+ this.heapAnalyserFinished(returnValue);
+ }
+
+ else{
+ Runnable refreshRunnable = new Runnable(){
+ public void run(){
+ /*// Ask user if generated file should be opened on excel
+ boolean compare = MessageDialog.openConfirm(getSite().getShell(), CONFIRMATION, CONFIRMATION_OPEN_FILE );
+ */
+ boolean compare = true;
+ // Display a Confirmation dialog
+ MessageBox messageBox = new MessageBox(viewer.getControl().getShell(), SWT.ICON_QUESTION | SWT.YES | SWT.NO);
+ messageBox.setText( CONFIRMATION );
+ messageBox.setMessage( CONFIRMATION_OPEN_FILE );
+ int buttonID = messageBox.open();
+ if (buttonID == SWT.NO) {
+ compare = false;
+ }
+ if( compare ){
+
+ // find program for xls-filetype
+ Program p=Program.findProgram(".xls");
+
+ // if found, launch it.
+ if(p!=null){
+ p.execute(outputFilePath);
+ }
+ }
+
+ }
+ };
+
+ // Has to be done in its own thread
+ // in order not to cause invalid thread access
+ Display.getDefault().asyncExec(refreshRunnable);
+
+
+ }
+ }
+
+
+ /**
+ * Get import engine.
+ * @return importEngine
+ */
+ public ImportEngine getImportEngine() {
+ return importEngine;
+ }
+
+ /**
+ * Shows error message asynchronously.
+ * @param header header of message
+ * @param text error text
+ */
+ public void showErrorMessage(final String header, final String text){
+ Runnable showErrorMessageRunnable = new Runnable(){
+ public void run(){
+ MessageDialog.openError( getSite().getShell(), header, text);
+ }
+ };
+
+ // Has to be done in its own thread
+ // in order not to cause invalid thread access
+ Display.getDefault().asyncExec(showErrorMessageRunnable);
+ }
+
+ /**
+ * Reports message to console asynchronously.
+ * @param consoleMsg console message.
+ * @param messageType console message type
+ */
+ public void reportConsoleMessage(final String consoleMsg, final int messageType){
+ Runnable reportConsoleMessageRunnable = new Runnable(){
+ public void run(){
+ MemSpyConsole.getInstance().println(consoleMsg, messageType);
+ }
+ };
+
+ // Has to be done in its own thread
+ // in order not to cause invalid thread access
+ Display.getDefault().asyncExec(reportConsoleMessageRunnable);
+ }
+
+ /**
+ * Shows trace viewer plugin
+ */
+ public static void showTraceViewer() {
+ try {
+
+ IWorkbenchWindow ww = MemSpyPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow();
+ if (ww == null)
+ return;
+ IWorkbenchPage page = ww.getActivePage();
+
+ // Checking if view is already open
+ IViewReference[] viewRefs = page.getViewReferences();
+ for (int i = 0; i < viewRefs.length; i++) {
+ IViewReference reference = viewRefs[i];
+ String id = reference.getId();
+ if(id.equalsIgnoreCase(TRACE_VIEWER_VIEW_ID)){
+ // Found, restoring the view
+ IViewPart viewPart = reference.getView(true);
+ page.activate(viewPart);
+ return;
+ }
+ }
+
+ // View was not found, opening it up as a new view.
+ page.showView(TRACE_VIEWER_VIEW_ID);
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * launchHeapAnalyser.
+ * Launches Heap Analyser.
+ * @param configurationFilePath path of the configuration file
+ * @param analyseOutputFilePath path of the output file
+ * @param threadName thread's name
+ * @param viewingHeap true, if action is view heap
+ */
+ public void launchHeapAnalyser( String configurationFilePath, String analyseOutputFilePath, String threadName, boolean viewingHeap ){
+
+ AnalyseHeapJob analyseHeapJob;
+
+ // set heap job's name correct
+ if( viewingHeap ){
+ analyseHeapJob = new AnalyseHeapJob( "Heap Analyser Running, Viewing heap from thread: " + threadName, this );
+ }
+ else{
+ analyseHeapJob = new AnalyseHeapJob( "Heap Analyser Running, Comparing Heaps from thread: " + threadName , this );
+ }
+
+ // set output file path
+ analyseHeapJob.setAnalyseOutputFile( analyseOutputFilePath );
+
+ // launch Heap Analyser
+ analyseHeapJob.setConfigurationFile( configurationFilePath );
+ analyseHeapJob.refresh();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.swt.events.KeyListener#keyPressed(org.eclipse.swt.events.KeyEvent)
+ */
+ public void keyPressed(KeyEvent keyEvent) {
+
+ // if delete key is pressed run delete -action.
+ if( keyEvent.keyCode == java.awt.event.KeyEvent.VK_DELETE){
+ deleteAction.run();
+ }
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.swt.events.KeyListener#keyReleased(org.eclipse.swt.events.KeyEvent)
+ */
+ public void keyReleased(KeyEvent arg0) {
+ // can be left empty.
+ }
+ /* (non-Javadoc)
+ * @see com.nokia.s60tools.memspy.interfaces.INewMemSpyFilesObserver#setOutputFilePath(java.lang.String)
+ */
+ public void setOutputFilePath(String outputFilePath) {
+ // can be left empty.
+ }
+
+ /**
+ * Launch the SWMT analyser with given files
+ * @param files
+ */
+ public void launchSWMTAnalyser( final ArrayList<String> files ){
+ Runnable showErrorMessageRunnable = new Runnable(){
+ public void run(){
+ // launch swmt analyser for selected logs.
+ SwmtAnalyser analyser = new SwmtAnalyser(MemSpyConsole.getInstance());
+ analyser.analyse( files );
+ }
+ };
+
+ // Has to be done in its own thread
+ // in order not to cause invalid thread access
+ Display.getDefault().asyncExec(showErrorMessageRunnable);
+
+ }
+
+ /**
+ * Callback called when symbol filea are updated by user
+ * @param symbols
+ */
+ public void symbolsUpdated( final AnalyserXMLGenerator symbols ){
+ Runnable editSymbolDefinitions = new Runnable(){
+ @SuppressWarnings("unchecked")
+ public void run(){
+ // get selected file bundle
+ ISelection selection = viewer.getSelection();
+ Object obj = ((IStructuredSelection)selection).toList();
+ List<MemSpyFileBundle> selectionList = (List<MemSpyFileBundle>)obj;
+ //verify that only one file is selected.
+ if( selectionList.size() == 1 ){
+ if( !importEngine.generateViewConfigurationFile(selectionList.get(0).getFilePath(), symbols.getXMLThreadName(), symbols) ){
+ showErrorMessage(ERROR_TOPIC, "File operations were failed when trying to save new symbol definitions. Definitions may not be saved.");
+ }
+ }
+ }
+ };
+ Display.getDefault().asyncExec(editSymbolDefinitions);
+
+ }
+
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/ui/views/MemSpyMainViewContentProvider.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,66 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+
+package com.nokia.s60tools.memspy.ui.views;
+
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.Viewer;
+
+import com.nokia.s60tools.memspy.interfaces.INewMemSpyFilesObserver;
+import com.nokia.s60tools.memspy.model.MemSpyFileManager;
+
+/**
+ * This class provides content for main view
+ */
+class MemSpyMainViewContentProvider implements IStructuredContentProvider {
+
+ private final MemSpyFileManager memSpyFileManager;
+
+ /**
+ * Create new content provider
+ * @param observer
+ */
+ public MemSpyMainViewContentProvider( INewMemSpyFilesObserver observer ){
+ memSpyFileManager = new MemSpyFileManager( observer );
+ }
+ /**
+ * Refresh file manager
+ * @see MemSpyFileManager#refresh()
+ */
+ public void refresh() {
+ memSpyFileManager.refresh();
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object)
+ */
+ public void inputChanged(Viewer v, Object oldInput, Object newInput) {
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.IContentProvider#dispose()
+ */
+ public void dispose() {
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object)
+ */
+ public Object[] getElements(Object parent) {
+ return memSpyFileManager.getmemSpyFiles();
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/ui/views/MemSpyMainViewLabelProvider.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,55 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+
+package com.nokia.s60tools.memspy.ui.views;
+
+import org.eclipse.jface.viewers.ITableLabelProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.swt.graphics.Image;
+
+import com.nokia.s60tools.memspy.model.MemSpyFileBundle;
+import com.nokia.s60tools.memspy.resources.ImageKeys;
+import com.nokia.s60tools.memspy.resources.ImageResourceManager;
+
+class MemSpyMainViewLabelProvider extends LabelProvider implements ITableLabelProvider {
+ /**
+ * Returns text for a column defined by index
+ */
+ public String getColumnText(Object obj, int index) {
+ MemSpyFileBundle cFileBundle = (MemSpyFileBundle)obj;
+ return cFileBundle.getText(index);
+ }
+ public Image getColumnImage(Object obj, int index) {
+ if (index == MemSpyFileBundle.INDEX_FILE_TYPE){
+ return getImage(obj);
+ }
+ else{
+ return null;
+ }
+ }
+ public Image getImage(Object obj) {
+ MemSpyFileBundle bundle = (MemSpyFileBundle)obj;
+ if( bundle.hasHeapDumpFile() ){
+ return ImageResourceManager.getImage(ImageKeys.IMG_HEAP_DUMP);
+ }
+ else{
+ return ImageResourceManager.getImage(ImageKeys.IMG_SWMT_LOG);
+ }
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/ui/wizards/DeviceOrFileSelectionPage.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,1436 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+
+package com.nokia.s60tools.memspy.ui.wizards;
+
+import java.io.File;
+import java.lang.reflect.InvocationTargetException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.FileDialog;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+import org.eclipse.swt.widgets.TableItem;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.PlatformUI;
+
+import com.nokia.s60tools.memspy.containers.SWMTLogInfo;
+import com.nokia.s60tools.memspy.containers.ThreadInfo;
+import com.nokia.s60tools.memspy.containers.ThreadInfo.HeapDumpType;
+import com.nokia.s60tools.memspy.interfaces.IMemSpyTraceListener;
+import com.nokia.s60tools.memspy.model.MemSpyFileOperations;
+import com.nokia.s60tools.memspy.model.MemSpyLogParserEngine;
+import com.nokia.s60tools.memspy.model.TraceCoreEngine;
+import com.nokia.s60tools.memspy.model.UserEnteredData;
+import com.nokia.s60tools.memspy.model.UserEnteredData.ValueTypes;
+import com.nokia.s60tools.memspy.plugin.MemSpyPlugin;
+import com.nokia.s60tools.memspy.resources.HelpContextIDs;
+import com.nokia.s60tools.memspy.ui.UiUtils;
+import com.nokia.s60tools.ui.preferences.PreferenceUtils;
+import com.nokia.s60tools.ui.wizards.S60ToolsWizardPage;
+import com.nokia.s60tools.util.debug.DbgUtility;
+
+
+public class DeviceOrFileSelectionPage extends S60ToolsWizardPage implements
+ SelectionListener, ModifyListener, IMemSpyTraceListener {
+
+ /**
+ * Selection index for import from device via TraceViewer radio button
+ */
+ private static final int DEVICE_RADIO_BUTTON_SELECTION_INDEX = 2;
+
+ public enum PageType{ IMPORT_PAGE, COMPARE_FIRST_HEAP, COMPARE_SECOND_HEAP };
+
+ // UI elements
+ private Combo fileCombo;
+ private Button buttonBrowseFile;
+
+ private Button fileRadioButton;
+ private Button deviceRadioButton;
+ private Button loadThreadListButton;
+ private Button connectionSettingsButton;
+ private Button getHeapButton;
+
+ private Label heapsReceivedLabel;
+ private Label connectionTextLabel;
+ private Label connectionNameInUseLabel;
+
+ private GridData threadSelectionGridData;
+ private GridData fileSelectionGridData;
+ private GridData deviceThreadTableGridData;
+ private GridData importedHeapTableGridData;
+ private GridData loadThreadListGridData;
+ private GridData connectionGridData;
+ private GridData connectionButtonGridData;
+ private GridData connectionNameInUseGridData;
+ private GridData threadFilterTypesGridData;
+ private GridData threadFilterGridData;
+
+ private Group compareGroup;
+
+
+ private Group fileSelectionGroup;
+ private Composite fileLocationGroup;
+ private Composite fileThreadListGroup;
+
+ private Group radioButtonGroup;
+ private Group threadSelectionGroup;
+ private Composite threadListGroup;
+ private Composite threadButtonGroup;
+
+ /**
+ * Table that is shown when getting heap From File System.
+ */
+ private Table fileThreadTable;
+ /**
+ * Table which contents can be loaded/refreshed from the device.
+ */
+ private Table deviceThreadTable;
+ /**
+ * Table that contains two heaps that are to be compared when Import and compare is selected.
+ */
+ private Table comparedHeapsTable;
+ /**
+ * Table in second page, where only imported heap can be selected.
+ */
+ private Table importedHeapTable;
+
+ /**
+ * Text field for setting filter text.
+ */
+ private String filterText;
+ /**
+ * Filter text.
+ */
+ private Text threadFilterText;
+ /**
+ * Combo for filtering types.
+ */
+ private Combo threadFilterTypesCombo;
+
+ // Thread list from one file
+ private ArrayList<ThreadInfo> fileThreadList;
+
+ // selected thread from thread list
+ private ThreadInfo comparedThread;
+
+ // Decoder Engine
+ private MemSpyLogParserEngine engine;
+
+ // Thread list received from usb/musti
+ ArrayList<ThreadInfo> deviceThreadList;
+
+ // TraceCore engine
+ TraceCoreEngine traceEngine;
+
+ // List of received heaps:
+ ArrayList<ThreadInfo> receivedHeaps;
+
+ // Heap that is currently received
+ ThreadInfo receivedHeap;
+
+ // this pages UserEnterData section
+ ValueTypes section;
+
+ // viewed error message
+ String errorMessage;
+
+ // Type of this page
+ PageType pageType;
+
+ // boolean variable, which is set to true if some MemSpy operation is running.
+ boolean memSpyOperationRunning;
+
+ // MemSpy operation processes:
+ // receive thread list
+ IRunnableWithProgress receiveThreadListProcess;
+ // receive heap
+ IRunnableWithProgress receiveHeapProcess;
+
+
+ //Strings
+
+ private final static String FILE_SELECTION_DIALOG_TEXT = "Select Heap Dump File";
+ private final static String GET_HEAP_RADIO_BUTTON = "Get Heap:";
+ private final static String GET_HEAP_FROM_FILE_RADIO_BUTTON = "From File System";
+ private final static String GET_HEAP_FROM_DEVICE_RADIO_BUTTON = "From Device via TraceViewer";
+ private final static String HEAP_DUMP_LOCATION_TEXT = "Define Location of Heap Dump File:";
+ private final static String BROWSE_TEXT = "Browse...";
+ private final static String HEAP_CONTAINS_TEXT_IMPORT = "Selected file contains heaps from following threads.";
+ private final static String HEAP_CONTAINS_TEXT_COMPARE = "Selected file contains heaps from following threads, select thread which heap needs to be compared.";
+ private final static String THREAD_NAME_TEXT = "Thread Name";
+ private final static String SELECT_THREAD_TEXT = GET_HEAP_FROM_DEVICE_RADIO_BUTTON;
+ private final static String SELECT_FILE_TEXT = GET_HEAP_FROM_FILE_RADIO_BUTTON;
+ private final static String LOAD_REFRESH_THREAD_LIST_BUTTON = "Load/Refresh Thread List";
+ private final static String CONNECTION_SETTINGS_BUTTON = "Connection Settings...";
+ private final static String CURRENTLY_USING_TEXT = "Currently using:";
+ private final static String GET_HEAP_NOW_BUTTON = "Get Selected Heap Now";
+ private final static String HEAP_DUMP_RECEIVED = "Heap Dump Received";
+ private final static String RECEIVING_THREAD_LIST = "Receiving Thread List: ";
+ private final static String RECEIVING_HEAP_DUMP = "Receiving Heap Dump: ";
+ private final static String HEAP_DUMPS_RECEIVED = " Heap Dumps Received";
+ private final static String COMPARE_HEAPS = "Compared heaps";
+
+
+ // Error/warning messages
+ private final static String ERROR_INVALID_FILE = "Invalid heap dump file. The file doesn't contain any threads with binary data information.";
+ private final static String ERROR_FILE_NOT_FOUND = "File not found";
+ private final static String SELECT_COMPARED_THREAD = "Select thread which heap needs to be compared";
+ private final static String WARNING_HEAPS_NOT_FROM_SAME_THREAD = "Compared heaps are not from same thread";
+
+ private final static String ERROR_DRM_THREAD = "Heaps from threads which name contains word \"drm\" cannot be received due to security policies.";
+ private final static String ERROR_DBGTRS_THREAD = "Heaps from threads which name contains word \"dbgtrcserver::!DbgTrcServer\" cannot be received due to Trace restrictions.";
+
+
+ /**
+ * DeviceOrFileSelectionPage(String pageName)
+ * Constructor
+ * @param pagename name of this wizard page
+ */
+ protected DeviceOrFileSelectionPage( String pageName, String title, String description, ValueTypes section,
+ PageType pageType, TraceCoreEngine traceEngine ) {
+ super(pageName);
+ setTitle( title );
+ setDescription( description );
+ this.engine = new MemSpyLogParserEngine();
+ this.fileThreadList = new ArrayList<ThreadInfo>();
+ this.deviceThreadList = new ArrayList<ThreadInfo>();
+ this.traceEngine = traceEngine;
+ this.receivedHeaps = new ArrayList<ThreadInfo>();
+ this.receivedHeap = new ThreadInfo();
+ this.section = section;
+ this.errorMessage = "";
+ this.pageType = pageType;
+ this.comparedThread = null;
+ memSpyOperationRunning = false;
+ this.createMemSpyProcesses();
+ this.filterText = "";
+ }
+
+ /**
+ * (non-Javadoc)
+ * @see com.nokia.s60tools.ui.wizards.S60ToolsWizardPage#setInitialFocus()
+ */
+
+ public void setInitialFocus() {
+ fileCombo.setFocus();
+ }
+
+ /**
+ * (non-Javadoc)
+ * @see org.eclipse.swt.events.SelectionListener#widgetDefaultSelected(org.eclipse.swt.events.SelectionEvent)
+ */
+ public void widgetDefaultSelected(SelectionEvent e) {
+ this.getHeapButtonPressed();
+ }
+
+ /**
+ * (non-Javadoc)
+ * @see org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt.events.SelectionEvent)
+ */
+ public void widgetSelected(SelectionEvent e) {
+ if (e.widget == buttonBrowseFile) {
+ // open file dialog for selecting a Heap Dump file
+ FileDialog dialog = new FileDialog(this.getShell());
+ dialog.setText(FILE_SELECTION_DIALOG_TEXT);
+ String[] filterExt = { "*.txt", "*.log", "*.*" };
+ dialog.setFilterExtensions(filterExt);
+ dialog.setFilterPath(fileCombo .getText());
+ String result = dialog.open();
+ if (result != null ){
+ fileCombo.setText(result);
+ }
+
+ }
+
+ // Update controls after radio buttons state changes to false
+ else if ( ( e.widget == deviceRadioButton && deviceRadioButton.getSelection() == false ) ||
+ ( e.widget == fileRadioButton && fileRadioButton.getSelection() == false ) ){
+ this.hideAndRevealItems();
+ getWizard().getContainer().updateButtons();
+
+ MemSpyWizard wizard = (MemSpyWizard) getWizard();
+ if( this.pageType != PageType.IMPORT_PAGE ){
+ wizard.setComparedHeaps();
+ }
+
+ }
+
+ // Open connection settings.
+ else if ( e.widget == connectionSettingsButton ){
+ // Open connection Trace viewers connection settings.
+ Shell shell = MemSpyPlugin.getCurrentlyActiveWbWindowShell();
+ PreferenceUtils.openPreferencePage(MemSpyPlugin.getTraceProvider().getTraceSourcePreferencePageId(), shell);
+
+ // Disconnect trace source so that new settings are used when sending next request
+ MemSpyPlugin.getTraceProvider().disconnectTraceSource();
+
+ MemSpyWizard wizard = (MemSpyWizard) this.getWizard();
+ // update new settings to each wizard page.
+ wizard.updateConnectionSettings();
+ }
+
+ // Load thread list from device
+ else if ( e.widget == loadThreadListButton ){
+ this.loadThreadListButtonPressed();
+ }
+ else if ( e.widget == getHeapButton ){
+ this.getHeapButtonPressed();
+ }
+ else if( e.widget == deviceThreadTable ){
+ this.enableAndDisableGetHeapButton();
+ }
+ else if( e.widget == importedHeapTable ){
+ this.enableAndDisableGetHeapButton();
+ }
+ else if( e.widget == fileThreadTable ){
+
+ // get selection index from thread table
+ int selectionIndex = fileThreadTable.getSelectionIndex();
+
+ // set selected heap as compared heap
+ comparedThread = fileThreadList.get( selectionIndex );
+
+ // get wizard and update compared thread names
+ MemSpyWizard wizard = (MemSpyWizard)this.getWizard();
+ wizard.setComparedHeaps();
+
+ wizard.showImportedHeapsInComparePage( false );
+
+ // update buttons
+ getWizard().getContainer().updateButtons();
+
+ // Set selection back to table after updatebuttons has cleared it.
+ fileThreadTable.setSelection( selectionIndex );
+
+ }
+ else if( e.widget == threadFilterTypesCombo) {
+ updateThreadList();
+ }
+
+
+ }
+
+ /**
+ * (non-Javadoc)
+ * @see org.eclipse.swt.events.ModifyListener#modifyText(org.eclipse.swt.events.ModifyEvent)
+ */
+ public void modifyText(ModifyEvent event) {
+ if (event.widget.equals(fileCombo)) {
+ try {
+ getWizard().getContainer().updateButtons();
+ } catch (Exception e) {
+ }
+ }
+ else if (event.widget.equals(threadFilterText)) {
+ filterText = threadFilterText.getText();
+ updateThreadList();
+ }
+ }
+
+ /**
+ * (non-Javadoc)
+ * @see com.nokia.s60tools.ui.wizards.S60ToolsWizardPage#recalculateButtonStates()
+ */
+ public void recalculateButtonStates() {
+
+ }
+
+
+ /**
+ * hideAndRevealItems()
+ * Hides and reveals controls according to radiobutton states.
+ */
+ private void hideAndRevealItems() {
+
+ // get radiobutton selection
+ boolean fileSelected = true;
+ if( deviceRadioButton.getSelection() == false ){
+ fileSelected = false;
+ }
+
+ // exlude/include needed controls
+ fileSelectionGridData.exclude = fileSelected;
+ threadSelectionGridData.exclude = !fileSelected;
+
+ if( fileSelected ){
+ // Since excluded groups size and location are not updated, do it now
+ threadSelectionGroup.setSize( fileSelectionGroup.getSize() );
+ threadSelectionGroup.setLocation(fileSelectionGroup.getLocation());
+
+ }
+ else{
+ // Since excluded groups size and location are not updated, do it now
+ fileSelectionGroup.setSize( threadSelectionGroup.getSize() );
+ fileSelectionGroup.setLocation(threadSelectionGroup.getLocation());
+
+ }
+ // Hide/show needed controls
+ fileSelectionGroup.setVisible(!fileSelected);
+ threadSelectionGroup.setVisible(fileSelected);
+
+
+
+ }
+
+
+ /**
+ * canFinish()
+ * Returns false, because symbol files must be defined always.
+ */
+ public boolean canFinish()
+ {
+ return false;
+ }
+
+
+
+ public boolean refreshFileThreadList(){
+
+ File file = new File(fileCombo.getText());
+
+ // If file exists
+ if (file.isFile() && file.exists()) {
+
+ // Empty thread list table
+ fileThreadTable.removeAll();
+
+ fileThreadList.clear();
+
+ // Check that file is Heap Dump file and display thread names in table.
+ if ( engine.isFileHeapDumpFile(file, fileThreadList) ) {
+ this.setErrorMessage(null);
+
+
+ for( int i = 0; i < fileThreadList.size(); i++ ){
+ TableItem newItem = new TableItem(fileThreadTable, SWT.NONE,i);
+ newItem.setText(fileThreadList.get(i).getThreadName());
+ }
+ if( fileThreadList.size() == 1 ){
+ comparedThread = fileThreadList.get(0);
+ ((MemSpyWizard)this.getWizard()).setComparedHeaps();
+ }
+
+ // If comparing heaps and no heap is selected as compared heap
+ if( comparedThread == null && this.pageType != PageType.IMPORT_PAGE){
+ this.setErrorMessage(SELECT_COMPARED_THREAD);
+ return false;
+ }
+ else{
+ // if importing heaps, set first heap as compared heap.
+ if( this.pageType == PageType.IMPORT_PAGE ){
+ comparedThread = fileThreadList.get(0);
+ }
+ return true;
+ }
+ }
+ else {
+ this.setErrorMessage(ERROR_INVALID_FILE);
+ return false;
+ }
+ }
+ else {
+ this.setErrorMessage(ERROR_FILE_NOT_FOUND );
+ return false;
+ }
+
+ }
+
+ /**
+ * (non-Javadoc)
+ * @see org.eclipse.jface.wizard.WizardPage#canFlipToNextPage()
+ */
+
+ public boolean canFlipToNextPage() {
+
+ if( fileRadioButton.getSelection() ){
+ try {
+ if( !this.refreshFileThreadList() ){
+ return false;
+ }
+ }
+ catch (Exception e) {
+ e.printStackTrace();
+ return false;
+ }
+
+ }
+ else{ // deviceRadioButton.getSelection()
+ if( receivedHeaps.size() > 0 ){
+ this.setErrorMessage(null);
+ }
+ else{
+ this.setErrorMessage(null);
+ return false;
+ }
+ }
+
+ if( this.pageType == PageType.COMPARE_FIRST_HEAP || this.pageType == PageType.COMPARE_SECOND_HEAP ){
+ MemSpyWizard wizard = (MemSpyWizard)this.getWizard();
+ if( !wizard.areComparedHeapsFromSameThread() ){
+ this.setMessage(WARNING_HEAPS_NOT_FROM_SAME_THREAD, ERROR);
+ if( this.pageType == PageType.COMPARE_SECOND_HEAP ){
+ return false;
+ }
+ }
+ else{
+ this.setMessage(null);
+ }
+ }
+ return true;
+
+
+
+
+ }
+
+
+ /**
+ * loadUserEnteredData
+ * Loads previously used values and selections into UI components
+ */
+
+ private void loadUserEnteredData(){
+
+ // restore previous state of radio buttons.
+ // if last value is not found, set selection file.
+
+ UserEnteredData data = new UserEnteredData();
+ int lastUsedSource = data.getPreviousRadioButtonSelection(section);
+
+ // Restoring previous state of radio buttons only if device import is also possible and was previously selected
+ if(MemSpyPlugin.isTraceProviderAvailable() && lastUsedSource == DEVICE_RADIO_BUTTON_SELECTION_INDEX){
+ deviceRadioButton.setSelection( true );
+ fileRadioButton.setSelection( false );
+ }
+ else{
+ deviceRadioButton.setSelection( false );
+ fileRadioButton.setSelection( true );
+ }
+
+ // Restore previous values to file combobox
+ String[] lastUsedFiles = data.getPreviousValues( section );
+ if ( lastUsedFiles != null ) {
+ fileCombo.setItems( lastUsedFiles );
+ fileCombo.select(0);
+ }
+
+ }
+
+ /**
+ * saveUserEnteredData.
+ * Saves user entered values and selections.
+ */
+ public void saveUserEnteredData(){
+ UserEnteredData data = new UserEnteredData();
+
+ // Save Action radio-buttons state
+ if( deviceRadioButton.getSelection() ){
+ data.saveRadioButtonSelection(section, 2);
+ }
+ else {
+ data.saveRadioButtonSelection(section, 1);
+ }
+
+ // Save file combo box
+ String item = fileCombo.getText();
+ data.saveValue(section, item);
+
+
+
+ }
+
+ /**
+ * enableAndDisableGetHeapButton.
+ * Enables/Disables "Get Heap Now" -button regarding wizard's state
+ */
+ private void enableAndDisableGetHeapButton(){
+ final PageType type = this.pageType;
+ Runnable updateUiRunnable = new Runnable(){
+ public void run(){
+ if( type == PageType.COMPARE_SECOND_HEAP && !importedHeapTableGridData.exclude ) {
+ getHeapButton.setEnabled( true );
+ }
+ else if( deviceThreadTable.getSelectionCount() == 1 ){
+ getHeapButton.setEnabled( true );
+ }
+ else{
+ getHeapButton.setEnabled( false );
+ }
+ }
+ };
+ Display.getDefault().asyncExec(updateUiRunnable);
+
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see com.nokia.s60tools.memspy.ui.wizards.MemSpyTraceListener#operationFinished(com.nokia.s60tools.memspy.ui.wizards.MemSpyTraceListener.LauncherAction)
+ */
+ public void operationFinished( LauncherAction action ){
+
+
+ this.memSpyOperationRunning = false;
+
+ if( action == LauncherAction.GET_HEAP_DUMP ){
+ this.updateReceivedHeap();
+ }
+ else if( action == LauncherAction.GET_THREAD_LIST ){
+
+ // command wizard to update all thread tables from all wizard pages
+ ((MemSpyWizard)this.getWizard()).updateThreadLists( this.deviceThreadList );
+ }
+
+
+ }
+
+ /**
+ * updateReceivedHeap.
+ * Does all actions that are done when Heap Dump file has been received.
+ */
+ private void updateReceivedHeap(){
+ receivedHeaps.add( receivedHeap );
+
+
+ if( this.pageType == PageType.COMPARE_FIRST_HEAP || this.pageType == PageType.COMPARE_SECOND_HEAP ){
+ comparedThread = receivedHeap;
+ }
+
+ final MemSpyWizard wizard = (MemSpyWizard)this.getWizard();
+
+ Runnable updateUiRunnable = new Runnable(){
+ public void run(){
+
+ // if this is import page, update UI's receivedHeaps-text
+ if( pageType == PageType.IMPORT_PAGE ){
+ heapsReceivedLabel.setText( Integer.toString( receivedHeaps.size() ) + HEAP_DUMPS_RECEIVED );
+ threadButtonGroup.layout();
+ }
+
+ // If this is compare heaps page, command wizard to update all compare-tables.
+ else{
+ wizard.setComparedHeaps();
+ }
+
+ // hide thread list selection in second compare page.
+ if( pageType == PageType.COMPARE_FIRST_HEAP ){
+ wizard.showImportedHeapsInComparePage( true );
+ }
+
+ // Getting selected item from currently active table
+ TableItem item;
+ if( pageType == PageType.COMPARE_SECOND_HEAP && importedHeapTable.isVisible() ) {
+ item = importedHeapTable.getItem( importedHeapTable.getSelectionIndex() );
+ } else {
+ item = deviceThreadTable.getItem( deviceThreadTable.getSelectionIndex() );
+ }
+ ThreadInfo thread = (ThreadInfo)item.getData();
+
+ // Imported threads needs to be updated from first compare page.
+ if( pageType == PageType.COMPARE_FIRST_HEAP ) {
+ // sets thread list selection in 2. comparePage
+ wizard.setThreadListSelectionToComparePages( thread );
+ }
+
+ // get date formatter
+ SimpleDateFormat formatter = new SimpleDateFormat ( MemSpyFileOperations.DATEFORMAT );
+ String date = formatter.format( receivedHeap.getDate() );
+ item.setText( 1, date );
+ // Date is saved to thread information so that it will be available if table is sorted.
+ thread.setStatus(date);
+ }
+
+ };
+
+ // needs to be called from UI thread.
+ Display.getDefault().asyncExec(updateUiRunnable);
+ }
+
+ /**
+ * Updates list and uses current filtering.
+ */
+ public void updateThreadList(){
+ Runnable updateUiRunnable = new Runnable(){
+ public void run(){
+ String filter = filterText;
+ deviceThreadTable.removeAll();
+ for( ThreadInfo thread : deviceThreadList ) {
+ if(threadFilterTypesCombo.getSelectionIndex() == 0) {
+ // Starts with filter.
+ if(thread.getThreadName().toLowerCase().startsWith(filter.toLowerCase())) {
+ TableItem newItem = new TableItem(deviceThreadTable, SWT.NONE);
+ newItem.setText( new String[]{ thread.getThreadName(), thread.getStatus() } );
+ newItem.setData(thread);
+ }
+ } else {
+ // Contains filter.
+ if(thread.getThreadName().toLowerCase().contains(filter.toLowerCase())) {
+ TableItem newItem = new TableItem(deviceThreadTable, SWT.NONE);
+ newItem.setText( new String[]{ thread.getThreadName(), thread.getStatus() } );
+ newItem.setData(thread);
+ }
+ }
+ }
+
+ // update wizard buttons
+ getWizard().getContainer().updateButtons();
+ // Update get heap button.
+ enableAndDisableGetHeapButton();
+ }
+ };
+ Display.getDefault().asyncExec(updateUiRunnable);
+
+ }
+
+ /**
+ * updateConnectionText
+ * updates connection text to match used settings
+ */
+
+ public void updateConnectionText(){
+ // Updating connection name.
+ String displayName = MemSpyPlugin.getTraceProvider().getDisplayNameForCurrentConnection();
+ connectionNameInUseLabel.setText(displayName);
+ // Update layout.
+ threadSelectionGroup.layout();
+ threadButtonGroup.layout();
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see com.nokia.s60tools.memspy.ui.wizards.MemSpyTraceListener#deviceError(com.nokia.s60tools.memspy.ui.wizards.MemSpyTraceListener.LauncherErrorType)
+ */
+ public void deviceError( final LauncherErrorType error ){
+
+ Date date = new Date (System.currentTimeMillis());
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "DeviceOrFileSelectionPage.deviceError: '" + error.name() +"' time:'" +date.toString() + "'."); //$NON-NLS-1$ $NON-NLS-2$ $NON-NLS-3$
+ memSpyOperationRunning = false;
+
+ // Getting user visible error message
+ errorMessage = UiUtils.getErrorMessageForLauncherError(error, traceEngine.getAdditionalErrorInformation(), traceEngine.getProgressStatus()); //$NON-NLS-1$
+
+ // Handling HeapDump query-specific logic related to the error
+ switch (error){
+ case HEAP_NOT_FOUND:{
+ errorMessage = ERROR_HEAP_NOT_FOUND;
+ this.receivedHeap = null;
+ break;
+ }
+ }
+
+ // Advising user to install launcher component to the device
+ UiUtils.showErrorDialogToUser(error, errorMessage, traceEngine.getProgressStatus());
+
+ }
+
+ /**
+ * Gets trace engine object instance.
+ * @return used TraceEngine-object
+ */
+ public TraceCoreEngine getTraceEngine() {
+ return traceEngine;
+ }
+
+
+ /**
+ * Sets thread info into comparedHeaps-table.
+ * @param firstHeap first compared heap
+ * @param secondHeap second compared heap
+ */
+ public void setComparedHeap( final ThreadInfo firstHeap, final ThreadInfo secondHeap ){
+ Runnable updateUiRunnable = new Runnable(){
+ public void run(){
+ comparedHeapsTable.removeAll();
+ TableItem firstItem = new TableItem(comparedHeapsTable, SWT.NONE, 0 );
+ TableItem secondItem = new TableItem(comparedHeapsTable, SWT.NONE, 1 );
+
+ // get date formatter
+ SimpleDateFormat formatter = new SimpleDateFormat ( MemSpyFileOperations.DATEFORMAT );
+ if( firstHeap != null){
+ firstItem.setText( new String[]{ firstHeap.getThreadName(), formatter.format( firstHeap.getDate() ) } );
+ }
+ if( secondHeap != null ){
+ secondItem.setText( new String[]{ secondHeap.getThreadName(), formatter.format( secondHeap.getDate() ) } );
+ }
+
+ }
+
+ };
+ Display.getDefault().asyncExec(updateUiRunnable);
+ }
+
+ /**
+ * setThreadListSelection.
+ * Sets thread list selection into given index and updates thread list selection into importedHeapTable if needed
+ * @param thread Thread information.
+ */
+ public void setThreadListSelection( final ThreadInfo thread ){
+ Runnable updateUiRunnable = new Runnable(){
+ public void run(){
+ if( pageType == PageType.COMPARE_SECOND_HEAP ){
+ ThreadInfo importedThread = thread.clone();
+
+ importedHeapTable.removeAll();
+ // Get selected item from deviceThread
+ TableItem importedItem = new TableItem( importedHeapTable, SWT.NONE, 0 );
+
+ // copy selected item data into importedThread
+ importedItem.setText(new String[]{ importedThread.getThreadName(), importedThread.getStatus() });
+ importedItem.setData(importedThread);
+
+ // select thread in importedHeapTable
+ importedHeapTable.setSelection( 0 );
+
+ enableAndDisableGetHeapButton();
+ }
+ }
+
+ };
+ Display.getDefault().asyncExec(updateUiRunnable);
+ }
+
+ /**
+ * setDeviceThreadList.
+ * @param deviceThreadList new deviceThreadList
+ */
+ public void setDeviceThreadList(ArrayList<ThreadInfo> deviceThreadList) {
+ this.deviceThreadList = deviceThreadList;
+ }
+
+ /**
+ * getRecentHeap
+ * @return last received Heap's thread info.
+ */
+ public ThreadInfo getRecentHeap(){
+ if( this.deviceRadioButton.getSelection() ){
+ if( receivedHeaps.size() > 0 ){
+ ThreadInfo returnValue = receivedHeaps.get( receivedHeaps.size()-1 );
+ return returnValue;
+ }
+ else{
+ return null;
+ }
+ }
+ else{
+ if(comparedThread != null ){
+ return comparedThread;
+ }
+ else{
+ return null;
+ }
+ }
+ }
+
+ /**
+ * getImportedHeaps.
+ * @return imported heaps
+ */
+ public ArrayList<ThreadInfo> getImportedHeaps() {
+ if( this.deviceRadioButton.getSelection() ){
+ return receivedHeaps;
+ }
+ else{
+ return fileThreadList;
+ }
+ }
+
+ /**
+ * updateConnectionSettings.
+ * Updates new connection settings to UI
+ */
+ public void updateConnectionSettings() {
+ this.updateConnectionText();
+ }
+
+ /**
+ * setImportedThreadTableVisible.
+ * Shows/Hides importedHeapTable
+ * @param value true if importedHeapsTable should be shown.
+ */
+ public void setImportedThreadTableVisible( boolean value ){
+ if( this.pageType == PageType.COMPARE_SECOND_HEAP ){
+
+ deviceThreadTableGridData.exclude = value;
+ deviceThreadTable.setVisible( !value );
+
+ importedHeapTableGridData.exclude = !value;
+ importedHeapTable.setVisible( value );
+
+ loadThreadListGridData.exclude = value;
+ loadThreadListButton.setVisible( !value );
+
+ connectionButtonGridData.exclude = value;
+ connectionSettingsButton.setVisible( !value );
+
+ connectionGridData.exclude = value;
+ connectionTextLabel.setVisible( !value );
+
+ connectionNameInUseGridData.exclude = value;
+ connectionNameInUseLabel.setVisible( !value );
+
+ threadFilterGridData.exclude = value;
+ threadFilterText.setVisible( !value );
+
+ threadFilterTypesGridData.exclude = value;
+ threadFilterTypesCombo.setVisible( !value );
+
+ if( value == true ){
+
+ threadButtonGroup.setLayoutData( new GridData( GridData.FILL_BOTH));
+ }
+ else{
+ threadButtonGroup.setLayoutData( new GridData( GridData.VERTICAL_ALIGN_CENTER));
+
+ }
+ threadButtonGroup.layout();
+
+
+ }
+
+ threadSelectionGroup.layout();
+ threadListGroup.layout();
+
+ enableAndDisableGetHeapButton();
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.jface.dialogs.IDialogPage#createControl(org.eclipse.swt.widgets.Composite)
+ */
+ public void createControl(Composite parent) {
+
+ Composite composite = new Composite(parent, SWT.NULL);
+
+ // create the desired layout for this wizard page
+ GridLayout gl = new GridLayout();
+ gl.numColumns = 1;
+ composite.setLayout(gl);
+
+ if( this.pageType == PageType.COMPARE_FIRST_HEAP || this.pageType == PageType.COMPARE_SECOND_HEAP ){
+ GridLayout compareGroupGridLayout = new GridLayout();
+ compareGroupGridLayout.numColumns = 2;
+ compareGroup = new Group(composite, SWT.NONE);
+ compareGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ compareGroup.setText(COMPARE_HEAPS);
+ compareGroup.setLayout(compareGroupGridLayout);
+
+
+ // Table that contains all thread names and id's
+ comparedHeapsTable = new Table(compareGroup, SWT.BORDER);
+ TableColumn heapNameColumn = new TableColumn(comparedHeapsTable, SWT.LEFT);
+ heapNameColumn.setText(THREAD_NAME_TEXT);
+ heapNameColumn.setWidth(200);
+ TableColumn receivedColumn = new TableColumn(comparedHeapsTable, SWT.LEFT);
+ receivedColumn.setText(HEAP_DUMP_RECEIVED);
+ receivedColumn.setWidth(150);
+ comparedHeapsTable.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ comparedHeapsTable.setHeaderVisible(true);
+
+
+ TableItem newItem = new TableItem(comparedHeapsTable, SWT.NONE,0);
+ newItem.setText( new String[]{ "", "" } );
+ TableItem newItem1 = new TableItem(comparedHeapsTable, SWT.NONE,1);
+ newItem1.setText( new String[]{ "", "" } );
+
+
+ }
+
+
+ // Radio button group
+ GridLayout radioButtonGroupGridLayout = new GridLayout();
+ radioButtonGroup = new Group(composite, SWT.NONE);
+ radioButtonGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ radioButtonGroup.setText(GET_HEAP_RADIO_BUTTON);
+ radioButtonGroup.setLayout(radioButtonGroupGridLayout);
+ GridData radioButtonGridData = new GridData(GridData.FILL_HORIZONTAL);
+ radioButtonGridData.horizontalSpan = 2;
+
+ // Heap Dump File radio button
+ fileRadioButton = new Button(radioButtonGroup, SWT.RADIO);
+ fileRadioButton.setText(GET_HEAP_FROM_FILE_RADIO_BUTTON);
+ fileRadioButton.setLayoutData(radioButtonGridData);
+ fileRadioButton.addSelectionListener(this);
+ fileRadioButton.setSelection(true);
+
+ // From Device via TraceViewer radio button
+ deviceRadioButton = new Button(radioButtonGroup, SWT.RADIO);
+ deviceRadioButton.setText(GET_HEAP_FROM_DEVICE_RADIO_BUTTON);
+ deviceRadioButton.setLayoutData(radioButtonGridData);
+ deviceRadioButton.addSelectionListener(this);
+ deviceRadioButton.setSelection(false);
+
+ // In case trace plugin is not available, disabling import from device selection
+ if(!MemSpyPlugin.isTraceProviderAvailable()){
+ deviceRadioButton.setEnabled(false);
+ }
+
+ // File selection group
+
+ fileSelectionGroup = new Group(composite, SWT.NONE);
+ GridLayout fileSelectionGridLayout = new GridLayout();
+ fileSelectionGridLayout.numColumns = 1;
+
+ fileSelectionGridData = new GridData(GridData.FILL_BOTH);
+ fileSelectionGroup.setLayoutData(fileSelectionGridData);
+ fileSelectionGroup.setLayout(fileSelectionGridLayout);
+ fileSelectionGroup.setText(SELECT_FILE_TEXT);
+
+ // File location composite
+ fileLocationGroup = new Composite(fileSelectionGroup, SWT.NONE);
+ GridLayout fileLocationGridLayout = new GridLayout();
+ fileLocationGridLayout.numColumns = 2;
+ GridData fileLocationGridData = new GridData(GridData.FILL_HORIZONTAL);
+ fileLocationGroup.setLayoutData(fileLocationGridData);
+ fileLocationGroup.setLayout(fileLocationGridLayout);
+
+ // Define location label
+ Label defineFileLocation = new Label(fileLocationGroup, SWT.NONE);
+ defineFileLocation.setText( HEAP_DUMP_LOCATION_TEXT );
+ GridData defineFileLocationGridData = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
+ defineFileLocationGridData.horizontalSpan = 2;
+ defineFileLocation.setLayoutData(defineFileLocationGridData);
+
+ // File location combo
+ fileCombo = new Combo(fileLocationGroup, SWT.BORDER);
+ GridData fileDataGrid = new GridData(GridData.FILL_HORIZONTAL);
+
+ fileCombo.setLayoutData(fileDataGrid);
+ fileCombo.addModifyListener(this);
+
+ // Browse-button
+ buttonBrowseFile = new Button(fileLocationGroup, SWT.PUSH);
+ buttonBrowseFile.setText(BROWSE_TEXT);
+ buttonBrowseFile.addSelectionListener(this);
+
+ // File location group
+ fileThreadListGroup = new Composite(fileSelectionGroup, SWT.NONE);
+ GridLayout fileThreadListGridLayout = new GridLayout();
+ fileThreadListGridLayout.numColumns = 1;
+
+ GridData fileThreadListGridData = new GridData(GridData.FILL_BOTH);
+ fileThreadListGroup.setLayoutData(fileThreadListGridData);
+ fileThreadListGroup.setLayout(fileThreadListGridLayout);
+
+
+ // Define location label
+ Label threadsFromFileLabel = new Label(fileThreadListGroup, SWT.NONE);
+ if( this.pageType == PageType.IMPORT_PAGE ){
+ threadsFromFileLabel.setText( HEAP_CONTAINS_TEXT_IMPORT );
+ }
+ else{
+ threadsFromFileLabel.setText( HEAP_CONTAINS_TEXT_COMPARE );
+ }
+ threadsFromFileLabel.setLayoutData( new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING) );
+
+ // Threads from file table
+ fileThreadTable = new Table(fileThreadListGroup, SWT.BORDER);
+ TableColumn nameColumn = new TableColumn(fileThreadTable, SWT.LEFT);
+ nameColumn.setText(THREAD_NAME_TEXT);
+ nameColumn.setWidth(250);
+ fileThreadTable.setLayoutData(new GridData(GridData.FILL_BOTH));
+ fileThreadTable.setHeaderVisible(true);
+ fileThreadTable.setItemCount(5);
+
+ if( this.pageType == PageType.COMPARE_FIRST_HEAP || this.pageType == PageType.COMPARE_SECOND_HEAP ){
+ fileThreadTable.addSelectionListener(this);
+ }
+
+
+ // Thread Selection group
+
+ threadSelectionGroup = new Group(composite, SWT.NONE);
+ GridLayout threadSelectionGridLayout = new GridLayout();
+ threadSelectionGridLayout.numColumns = 2;
+
+
+ threadSelectionGridData = new GridData(GridData.FILL_BOTH);
+ threadSelectionGroup.setLayoutData(threadSelectionGridData);
+ threadSelectionGroup.setLayout(threadSelectionGridLayout);
+ threadSelectionGroup.setText(SELECT_THREAD_TEXT);
+
+ // Thread list Group
+ threadListGroup = new Composite(threadSelectionGroup, SWT.NONE);
+ GridLayout threadListLayout = new GridLayout();
+ threadListLayout.numColumns = 2;
+ threadListGroup.setLayoutData(new GridData(GridData.FILL_BOTH));
+ threadListGroup.setLayout(threadListLayout);
+
+ // Filter text field.
+ threadFilterText = new Text(threadListGroup, SWT.BORDER);
+ threadFilterText.setText("type filter text");
+ threadFilterGridData = new GridData(GridData.FILL_HORIZONTAL);
+ threadFilterGridData.grabExcessHorizontalSpace = true;
+ threadFilterGridData.grabExcessVerticalSpace = false;
+ threadFilterGridData.verticalAlignment = SWT.TOP;
+ threadFilterText.setLayoutData(threadFilterGridData);
+
+ threadFilterText.addModifyListener(this);
+
+ // Filter selection combo.
+ threadFilterTypesCombo = new Combo(threadListGroup, SWT.BORDER|SWT.READ_ONLY);
+ threadFilterTypesCombo.setItems(new String[]{"Starts with", "Contains"});
+ threadFilterTypesGridData = new GridData();
+ threadFilterTypesGridData.widthHint = 100;
+ threadFilterTypesCombo.select(0);
+ threadFilterTypesCombo.setLayoutData(threadFilterTypesGridData);
+
+ threadFilterTypesCombo.addSelectionListener(this);
+
+ // Table that contains all thread names and id's
+ deviceThreadTable = new Table(threadListGroup, SWT.BORDER);
+
+ TableColumn deviceThreadColumn = new TableColumn(deviceThreadTable, SWT.LEFT);
+ deviceThreadColumn.setText(THREAD_NAME_TEXT);
+ deviceThreadColumn.setWidth(200);
+ TableColumn receivedColumn = new TableColumn(deviceThreadTable, SWT.LEFT);
+ receivedColumn.setText(HEAP_DUMP_RECEIVED);
+ receivedColumn.setWidth(150);
+ deviceThreadTableGridData = new GridData(GridData.FILL_BOTH);
+ deviceThreadTableGridData.horizontalSpan = 2;
+ deviceThreadTable.setLayoutData( deviceThreadTableGridData );
+ deviceThreadTable.setHeaderVisible(true);
+ deviceThreadTable.addSelectionListener( this );
+
+ if( this.pageType == PageType.COMPARE_SECOND_HEAP ){
+ // Table where first imported heaps name is presented
+ importedHeapTable = new Table( threadListGroup, SWT.BORDER );
+ TableColumn importedThreadNameColumn = new TableColumn( importedHeapTable, SWT.LEFT );
+ importedThreadNameColumn.setText( THREAD_NAME_TEXT );
+ importedThreadNameColumn.setWidth( 200 );
+ TableColumn importedWhenColumn = new TableColumn( importedHeapTable, SWT.LEFT );
+ importedWhenColumn.setText( HEAP_DUMP_RECEIVED );
+ importedWhenColumn.setWidth( 150 );
+ //importedHeapTableGridData = new GridData(GridData.GRAB_VERTICAL);
+ importedHeapTableGridData = new GridData(GridData.FILL_HORIZONTAL);
+ importedHeapTable.setLayoutData( importedHeapTableGridData );
+ importedHeapTable.setHeaderVisible( true );
+ importedHeapTable.addSelectionListener( this );
+ }
+
+ // Thread button group
+ threadButtonGroup = new Composite(threadSelectionGroup, SWT.NONE);
+ GridLayout threadButtonLayout = new GridLayout();
+ threadButtonLayout.numColumns = 1;
+
+ GridData threadButtonGridData = new GridData(GridData.HORIZONTAL_ALIGN_CENTER);
+ threadButtonGroup.setLayoutData(threadButtonGridData);
+ threadButtonGroup.setLayout(threadButtonLayout);
+
+ loadThreadListButton = new Button(threadButtonGroup, SWT.PUSH);
+ loadThreadListGridData = new GridData(GridData.FILL_HORIZONTAL);
+ loadThreadListButton.setLayoutData( loadThreadListGridData );
+ loadThreadListButton.setText(LOAD_REFRESH_THREAD_LIST_BUTTON);
+ loadThreadListButton.addSelectionListener( this );
+
+ // Connection settings button
+
+ connectionSettingsButton = new Button(threadButtonGroup, SWT.PUSH);
+ connectionButtonGridData = new GridData(GridData.FILL_HORIZONTAL);
+ connectionSettingsButton.setLayoutData( connectionButtonGridData );
+ connectionSettingsButton.setText(CONNECTION_SETTINGS_BUTTON);
+ connectionSettingsButton.addSelectionListener(this);
+
+ // Connection settings labels
+ connectionTextLabel = new Label(threadButtonGroup, SWT.LEFT);
+ connectionTextLabel.setText(CURRENTLY_USING_TEXT);
+ connectionGridData = new GridData(GridData.HORIZONTAL_ALIGN_CENTER);
+ connectionTextLabel.setLayoutData( connectionGridData );
+
+ connectionNameInUseLabel = new Label(threadButtonGroup, SWT.LEFT);
+ connectionNameInUseGridData = new GridData(GridData.HORIZONTAL_ALIGN_CENTER);
+ connectionNameInUseLabel.setLayoutData( connectionNameInUseGridData );
+
+ // Get Heap button
+
+ getHeapButton = new Button(threadButtonGroup, SWT.PUSH);
+ getHeapButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ getHeapButton.setText(GET_HEAP_NOW_BUTTON);
+ getHeapButton.addSelectionListener( this );
+ this.enableAndDisableGetHeapButton();
+
+ if( this.pageType == PageType.IMPORT_PAGE ){
+ heapsReceivedLabel = new Label(threadButtonGroup, SWT.LEFT);
+ heapsReceivedLabel.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_CENTER));
+ heapsReceivedLabel.setText( "0" + HEAP_DUMPS_RECEIVED );
+ }
+ // load saved user entered data.
+ this.loadUserEnteredData();
+
+ // update buttons and texts on screen.
+ this.updateConnectionText();
+ this.hideAndRevealItems();
+ this.setImportedThreadTableVisible( false );
+
+ setHelps();
+ setInitialFocus();
+ setControl(composite);
+ }
+
+
+ /*
+ * (non-Javadoc)
+ * @see com.nokia.s60tools.memspy.ui.wizards.MemSpyTraceListener#operationFinished(com.nokia.s60tools.memspy.ui.wizards.MemSpyTraceListener.LauncherAction, com.nokia.s60tools.memspy.containers.SWMTLogInfo)
+ */
+ public void operationFinished(LauncherAction action, SWMTLogInfo swmtLogInfo, boolean timerRunning) {
+ // Can be left empty.
+
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see com.nokia.s60tools.memspy.ui.wizards.MemSpyTraceListener#startedReceivingSWMTLog()
+ */
+ public void startedReceivingSWMTLog() {
+ // Can be left empty.
+
+ }
+
+ private void loadThreadListButtonPressed(){
+ deviceThreadList.clear();
+ if( traceEngine.requestThreadList( deviceThreadList, (DeviceOrFileSelectionPage)getWizard().getContainer().getCurrentPage() ) ){
+ try {
+ getContainer().run(true, false, receiveThreadListProcess);
+ } catch (InvocationTargetException e1) {
+ e1.printStackTrace();
+ } catch (InterruptedException e1) {
+ e1.printStackTrace();
+ }
+ }
+ else{
+ MessageDialog.openError( this.getShell(), ERROR_MEMSPY, ERROR_CONNECTION);
+ }
+ }
+
+ /**
+ * getHeapButtonPressed.
+ * Method that is called when "Get Heap Now"-button is pressed.
+ */
+ private void getHeapButtonPressed(){
+ // Imported thread is loaded, if it is importedHeapTable is visible.
+ ThreadInfo thread;
+ if(this.pageType == PageType.COMPARE_SECOND_HEAP && importedHeapTable.isVisible()) {
+ if(importedHeapTable.getSelectionIndex() == -1) {
+ // No selection, nothing to do.
+ return;
+ }
+ thread = (ThreadInfo)importedHeapTable.getSelection()[0].getData();
+ } else {
+ if(deviceThreadTable.getSelectionIndex() == -1) {
+ // No selection, nothing to do.
+ return;
+ }
+ thread = (ThreadInfo)deviceThreadTable.getSelection()[0].getData();
+ }
+
+ // if thread name contains text "drm" it cannot be requested because of security reasons
+ if( thread.getThreadName().toLowerCase().contains("drm") ){
+ MessageDialog.openError( this.getShell(), ERROR_MEMSPY, ERROR_DRM_THREAD);
+ return;
+ }
+ // if thread name contains text "dbgtrcserver::!DbgTrcServer" it cannot be requested because of TraceCore
+ else if(thread.getThreadName().toLowerCase().contains("dbgtrcserver::!dbgtrcserver") ){
+ MessageDialog.openError( this.getShell(), ERROR_MEMSPY, ERROR_DBGTRS_THREAD);
+ return;
+ }
+
+ String threadID = thread.getThreadID();
+ Date date = new Date();
+ String threadName = thread.getThreadName();
+
+ // Get file name for heap dump from engine
+ String filePath = MemSpyFileOperations.getFileNameForTempHeapDump( threadName, date);
+
+ // Add new file into receivedHeaps-ArrayList
+ receivedHeap = new ThreadInfo();
+ receivedHeap.setThreadFilePath(filePath);
+ receivedHeap.setThreadID(threadID);
+ receivedHeap.setThreadName(threadName);
+ receivedHeap.setDate(date);
+ receivedHeap.setType(HeapDumpType.DEVICE);
+
+
+ if( traceEngine.requestHeapDump( threadID, this, filePath ) ){
+
+ try {
+ getContainer().run(true, false, receiveHeapProcess);
+ } catch (InvocationTargetException e1) {
+ // do nothing
+ e1.printStackTrace();
+ } catch (InterruptedException e1) {
+ // do nothing
+ e1.printStackTrace();
+ }
+ }
+ else{
+ MessageDialog.openError( this.getShell(), ERROR_MEMSPY, ERROR_CONNECTION);
+ receivedHeap = null;
+ }
+
+ getWizard().getContainer().updateButtons();
+
+ }
+
+ /**
+ * createMemSpyProcesses.
+ * Creates MemSpy operation processes.
+ */
+ private void createMemSpyProcesses(){
+
+ // receive thread list process
+ receiveThreadListProcess = new IRunnableWithProgress() {
+ public void run(IProgressMonitor monitor) {
+ memSpyOperationRunning = true;
+ monitor.beginTask(RECEIVING_THREAD_LIST, IProgressMonitor.UNKNOWN);
+ while(true){
+ // some delay, so that launcher has time to set it's state correct.
+ try {
+ Thread.sleep(500);
+ } catch (InterruptedException e) {
+ // do nothing
+ }
+ if( !memSpyOperationRunning ){
+ break;
+ }
+ }
+ monitor.done();
+ }
+ };
+
+ // receive heap process.
+ receiveHeapProcess = new IRunnableWithProgress() {
+ public void run(IProgressMonitor monitor) {
+ memSpyOperationRunning = true;
+ monitor.beginTask(RECEIVING_HEAP_DUMP, IProgressMonitor.UNKNOWN);
+ while(true){
+ // some delay
+ try {
+ Thread.sleep(500);
+ } catch (InterruptedException e) {
+ // do nothing
+ }
+ if( !memSpyOperationRunning ){
+ break;
+ }
+
+ }
+ monitor.done();
+
+ }
+ };
+ }
+
+ /**
+ * setHeapDumpFile.
+ * Sets parameter test to file combo box, selects file radio button and disables UI-components
+ * @param newFilePath new file path.
+ */
+ public void setHeapDumpFile( final String newFilePath ){
+ Runnable updateUiRunnable = new Runnable(){
+ public void run(){
+
+ if( deviceRadioButton.getSelection() ){
+ // select file system-radio button
+ fileRadioButton.setSelection(true);
+ deviceRadioButton.setSelection(false);
+ hideAndRevealItems();
+ }
+ // set text to file location combo box
+ fileCombo.setText( newFilePath );
+
+ // set selection buttons disabled.
+ fileCombo.setEnabled( false );
+ buttonBrowseFile.setEnabled( false );
+ deviceRadioButton.setEnabled(false);
+
+
+ }
+ };
+ Display.getDefault().asyncExec(updateUiRunnable);
+
+ }
+
+ /**
+ * getSelectedFilePath.
+ * @return text value from file combo box.
+ */
+ public String getSelectedFilePath(){
+ return fileCombo.getText();
+ }
+
+ /**
+ * resetFileCombo.
+ * sets text field in file combo box empty.
+ */
+ public void resetFileCombo(){
+ Runnable updateUiRunnable = new Runnable(){
+ public void run(){
+ fileCombo.setText( "" );
+ }
+ };
+ Display.getDefault().asyncExec(updateUiRunnable);
+ }
+
+
+ /**
+ * Sets this page's context sensitive helps
+ *
+ */
+ protected void setHelps() {
+
+ String helpContextId = null;
+ if( this.pageType == PageType.IMPORT_PAGE ){
+ helpContextId = HelpContextIDs.MEMSPY_IMPORT_HEAP;
+ }
+ else{
+ helpContextId = HelpContextIDs.MEMSPY_IMPORT_COMPARE;
+ }
+ PlatformUI.getWorkbench().getHelpSystem().setHelp( deviceRadioButton, helpContextId );
+ PlatformUI.getWorkbench().getHelpSystem().setHelp( fileRadioButton, helpContextId);
+ PlatformUI.getWorkbench().getHelpSystem().setHelp( fileCombo, helpContextId);
+ PlatformUI.getWorkbench().getHelpSystem().setHelp( fileThreadTable, helpContextId);
+
+ PlatformUI.getWorkbench().getHelpSystem().setHelp( loadThreadListButton, helpContextId );
+ PlatformUI.getWorkbench().getHelpSystem().setHelp( connectionSettingsButton, helpContextId);
+ PlatformUI.getWorkbench().getHelpSystem().setHelp( getHeapButton, helpContextId);
+ PlatformUI.getWorkbench().getHelpSystem().setHelp( deviceThreadTable, helpContextId);
+
+ }
+
+
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/ui/wizards/ExportFileNamePage.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,233 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+
+package com.nokia.s60tools.memspy.ui.wizards;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.FileDialog;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.ui.PlatformUI;
+
+import com.nokia.s60tools.memspy.model.UserEnteredData;
+import com.nokia.s60tools.memspy.model.UserEnteredData.ValueTypes;
+import com.nokia.s60tools.memspy.resources.HelpContextIDs;
+import com.nokia.s60tools.ui.wizards.S60ToolsWizardPage;
+
+public class ExportFileNamePage extends S60ToolsWizardPage implements ModifyListener, SelectionListener{
+
+ // UI-components
+ private Combo fileCombo;
+ private Button buttonBrowseFile;
+
+ // Strings
+ private final static String REPORT_LOCATION_TEXT = "File Location";
+ private final static String BROWSE_TEXT = "Browse...";
+ private final static String FILE_SELECTION_DIALOG_TEXT = "Define location for exported file.";
+ private final static String OUTPUT_FILE_TEXT = "Output file";
+ private final static String DESCRIPTION_TEXT = "Define file name for exported comparison report file(xls-file).";
+
+ /*
+ * (non-Javadoc)
+ * @see com.nokia.s60tools.ui.wizards.S60ToolsWizardPage#setInitialFocus()
+ */
+ public void setInitialFocus() {
+ fileCombo.setFocus();
+ }
+
+
+
+ /*
+ * (non-Javadoc)
+ * @see com.nokia.s60tools.ui.wizards.S60ToolsWizardPage#recalculateButtonStates()
+ */
+ public void recalculateButtonStates() {
+ }
+
+ /**
+ * ExportFileNamePage
+ * constructor
+ * @param pageName name of the page
+ */
+ protected ExportFileNamePage(String pageName) {
+ super(pageName);
+ setTitle(OUTPUT_FILE_TEXT);
+ setDescription(DESCRIPTION_TEXT);
+ }
+
+ public void createControl(Composite parent) {
+ // Radio button group
+ Composite composite = new Composite(parent, SWT.NULL);
+
+ // create the desired layout for this wizard page
+ GridLayout gl = new GridLayout();
+ gl.numColumns = 1;
+ composite.setLayout(gl);
+
+ // file location group
+ Group fileLocationGroup = new Group(composite, SWT.NONE);
+ fileLocationGroup.setLayoutData(new GridData(GridData.FILL_BOTH));
+ GridLayout fileLocationLayout = new GridLayout();
+ fileLocationLayout.numColumns = 2;
+ fileLocationGroup.setLayout( fileLocationLayout );
+ fileLocationGroup.setText( REPORT_LOCATION_TEXT );
+
+ // file combo
+ fileCombo = new Combo(fileLocationGroup, SWT.BORDER);
+ GridData fileDataGrid = new GridData(GridData.FILL_HORIZONTAL);
+ fileCombo.setLayoutData(fileDataGrid);
+ fileCombo.addModifyListener(this);
+
+ // browse button
+ buttonBrowseFile = new Button(fileLocationGroup, SWT.PUSH);
+ buttonBrowseFile.setText(BROWSE_TEXT);
+ buttonBrowseFile.addSelectionListener(this);
+
+ // load previous value
+ this.loadUserEnteredData();
+
+ setHelps();
+ setInitialFocus();
+ setControl(composite);
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.swt.events.ModifyListener#modifyText(org.eclipse.swt.events.ModifyEvent)
+ */
+ public void modifyText(ModifyEvent event) {
+
+ if (event.widget.equals(fileCombo)) {
+ try {
+ getWizard().getContainer().updateButtons();
+ } catch (Exception e) {
+ }
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.swt.events.SelectionListener#widgetDefaultSelected(org.eclipse.swt.events.SelectionEvent)
+ */
+ public void widgetDefaultSelected(SelectionEvent arg0) {
+
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt.events.SelectionEvent)
+ */
+ public void widgetSelected(SelectionEvent e) {
+ if (e.widget == buttonBrowseFile) {
+ // open file dialog for selecting a crash file
+ FileDialog dialog = new FileDialog(this.getShell(), SWT.SAVE );
+ dialog.setText(FILE_SELECTION_DIALOG_TEXT);
+ String[] filterExt = { "*.xls" };
+ dialog.setFilterExtensions(filterExt);
+
+ dialog.setFilterPath(fileCombo.getText());
+ String result = dialog.open();
+
+ // add xls-end if needed
+ if( !result.endsWith( ".xls" ) ){
+ result += ".xls";
+ }
+
+
+
+ fileCombo.setText(result);
+
+ }
+
+ }
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.jface.wizard.WizardPage#canFlipToNextPage()
+ */
+ public boolean canFlipToNextPage() {
+ if( fileCombo.getText() != "" ){
+ return true;
+ }
+ else {
+ return false;
+
+ }
+
+ }
+
+ /**
+ * loadUserEnteredData
+ * loads previous values into UI components
+ */
+ private void loadUserEnteredData(){
+ UserEnteredData data = new UserEnteredData();
+
+ // Restore previous values to file combobox
+ String[] lastUsedFiles = data.getPreviousValues(ValueTypes.OUTPUT_FILE);
+ if (lastUsedFiles != null) {
+ fileCombo.setItems(lastUsedFiles);
+ fileCombo.select(0);
+ }
+
+
+
+ }
+
+ /**
+ * saveUserEnteredData
+ * Saves current user entered data from UI components
+ */
+ public void saveUserEnteredData(){
+ UserEnteredData data = new UserEnteredData();
+
+ // Save file combo box
+ String item = fileCombo.getText();
+ data.saveValue(ValueTypes.OUTPUT_FILE, item);
+ }
+
+ /**
+ * getOutputFileName
+ * @return output file name
+ */
+ public String getOutputFileName(){
+ return fileCombo.getText();
+ }
+
+ /**
+ * Sets this page's context sensitive helps
+ *
+ */
+ protected void setHelps() {
+ PlatformUI.getWorkbench().getHelpSystem().setHelp( fileCombo, HelpContextIDs.MEMSPY_IMPORT_COMPARE);
+ PlatformUI.getWorkbench().getHelpSystem().setHelp( buttonBrowseFile, HelpContextIDs.MEMSPY_IMPORT_COMPARE);
+ PlatformUI.getWorkbench().getHelpSystem().setHelp( buttonBrowseFile, HelpContextIDs.MEMSPY_IMPORT_COMPARE);
+
+ }
+
+
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/ui/wizards/MemSpyWizard.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,641 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+
+package com.nokia.s60tools.memspy.ui.wizards;
+
+
+import java.io.File;
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.Arrays;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.wizard.IWizardPage;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.MessageBox;
+import org.eclipse.ui.IWorkbench;
+
+import com.nokia.s60tools.memspy.containers.SWMTLogInfo;
+import com.nokia.s60tools.memspy.containers.ThreadInfo;
+import com.nokia.s60tools.memspy.model.AnalyserXMLGenerator;
+import com.nokia.s60tools.memspy.model.ImportEngine;
+import com.nokia.s60tools.memspy.model.MemSpyFileOperations;
+import com.nokia.s60tools.memspy.model.TraceCoreEngine;
+import com.nokia.s60tools.memspy.model.UserEnteredData.ValueTypes;
+import com.nokia.s60tools.memspy.resources.ImageKeys;
+import com.nokia.s60tools.memspy.resources.ImageResourceManager;
+import com.nokia.s60tools.memspy.ui.views.MemSpyMainView;
+import com.nokia.s60tools.memspy.ui.wizards.DeviceOrFileSelectionPage.PageType;
+import com.nokia.s60tools.memspy.ui.wizards.SelectActionPage.MemSpyAction;
+import com.nokia.s60tools.ui.wizards.S60ToolsWizard;
+import com.nokia.s60tools.util.debug.DbgUtility;
+
+public class MemSpyWizard extends S60ToolsWizard {
+
+ public enum MemSpyWizardType{ FULL, COMPARE, SYMBOLS };
+
+ static private final ImageDescriptor bannerImgDescriptor = ImageResourceManager.getImageDescriptor(ImageKeys.IMG_WIZARD);
+
+
+ SelectActionPage selectActionPage;
+ DeviceOrFileSelectionPage importHeapPage;
+ DeviceOrFileSelectionPage compareHeapsFirstPage;
+ DeviceOrFileSelectionPage compareHeapsSecondPage;
+ ParameterFilesPage parameterFilesPage;
+ ExportFileNamePage exportFileNamePage;
+ SWMTLogPage swmtLogPage;
+ MemSpyMainView mainView;
+ ImportEngine importEngine;
+ MemSpyWizardDialog wizDialog;
+
+ MemSpyWizardType wizardType;
+ TraceCoreEngine traceEngine;
+ AnalyserXMLGenerator fillValues;
+
+ private final static String IMPORTING_FILES = "Importing Files";
+
+ public MemSpyWizard(){
+ super(bannerImgDescriptor);
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "MemSpyWizard constructor - start");
+
+ this.mainView = MemSpyMainView.showAndReturnYourself();
+ this.importEngine = mainView.getImportEngine();
+ this.setNeedsProgressMonitor(true);
+ this.traceEngine = new TraceCoreEngine();
+ this.wizardType = MemSpyWizardType.FULL;
+ this.fillValues = null;
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "MemSpyWizard constructor - end");
+
+ }
+
+ public MemSpyWizard( MemSpyWizardType wizardType, AnalyserXMLGenerator fillValues ) {
+ this();
+ this.wizardType = wizardType;
+ this.fillValues = fillValues;
+ if( wizardType != MemSpyWizardType.SYMBOLS ){
+ MemSpyMainView.showTraceViewer();
+ }
+ }
+
+
+ /**
+ * (non-Javadoc)
+ *
+ * @see com.nokia.s60tools.ui.wizards.S60ToolsWizard#addPages()
+ */
+ public void addPages() {
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "MemSpyWizard addpages - start");
+
+ // if wizard's type is full, add all pages.
+ if( wizardType == MemSpyWizardType.FULL ){
+
+ selectActionPage = new SelectActionPage("Select Action");
+ addPage(selectActionPage);
+
+ importHeapPage = new DeviceOrFileSelectionPage( "Get Heap From",
+ "Import Heap Wizard, step 1", "Define source for Heap Dump files. Logs can be imported from already existing files or from device via TraceViewer.", ValueTypes.IMPORT_HEAP,
+ PageType.IMPORT_PAGE, traceEngine );
+ addPage(importHeapPage);
+
+ compareHeapsFirstPage = new DeviceOrFileSelectionPage("Select First Heap",
+ "Compare Two Heaps Wizard, step 1", "Define source for first compared Heap Dump. Heap Dumps can be imported from already existing files\nor from device via TraceViewer.", ValueTypes.COMPARE_HEAP_FIRST_HEAP,
+ PageType.COMPARE_FIRST_HEAP, traceEngine);
+ addPage(compareHeapsFirstPage);
+
+ compareHeapsSecondPage = new DeviceOrFileSelectionPage("Select Second Heap",
+ "Compare Two Heaps Wizard, step 2", "Define source for second compared Heap Dump. Compared heap dumps must be from same thread.", ValueTypes.COMPARE_HEAP_SECOND_HEAP,
+ PageType.COMPARE_SECOND_HEAP, traceEngine);
+ addPage(compareHeapsSecondPage);
+
+ exportFileNamePage = new ExportFileNamePage("Define export file name");
+ addPage(exportFileNamePage);
+
+ parameterFilesPage = new ParameterFilesPage(null, null, "Import Heap Wizard, step 2");
+ addPage(parameterFilesPage);
+
+ swmtLogPage = new SWMTLogPage("Get SWMT-logs", traceEngine);
+ addPage(swmtLogPage);
+ }
+ // if wizard type is compare add only compare output and symbol pages.
+ else if( wizardType == MemSpyWizardType.COMPARE){
+
+ compareHeapsFirstPage = new DeviceOrFileSelectionPage("Select First Heap",
+ "Compare Two Heaps Wizard, step 1", "Define source for first compared Heap Dump. Heap Dumps can be imported from already existing files\nor from device via TraceViewer.", ValueTypes.COMPARE_HEAP_FIRST_HEAP,
+ PageType.COMPARE_FIRST_HEAP, traceEngine);
+ addPage(compareHeapsFirstPage);
+
+ // prefill path of compared Heap Dump to wizard page.
+ compareHeapsFirstPage.setHeapDumpFile( fillValues.getXMLSourceFile()[0] );
+
+ compareHeapsSecondPage = new DeviceOrFileSelectionPage("Select Second Heap",
+ "Compare Two Heaps Wizard, step 2", "Define source for second compared Heap Dump. Compared heap dumps must be from same thread.", ValueTypes.COMPARE_HEAP_SECOND_HEAP,
+ PageType.COMPARE_SECOND_HEAP, traceEngine);
+ addPage(compareHeapsSecondPage);
+
+ // reset file combo box text from second page.
+ compareHeapsSecondPage.resetFileCombo();
+
+ exportFileNamePage = new ExportFileNamePage("Define export file name");
+ addPage(exportFileNamePage);
+
+ parameterFilesPage = new ParameterFilesPage(fillValues.getXMLDebugMetaDataFile(), null, "Import Heap Wizard, step 2");
+ addPage(parameterFilesPage);
+
+
+
+
+ }
+ else if( wizardType == MemSpyWizardType.SYMBOLS ){
+ parameterFilesPage = new ParameterFilesPage( fillValues.getXMLDebugMetaDataFile(), fillValues.getXMLDebugMetaDataDirectory(), "Edit Symbol Definitions" );
+ addPage(parameterFilesPage);
+ }
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "MemSpyWizard addpages - end");
+
+ }
+
+ /**
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.wizard.Wizard#getNextPage(org.eclipse.jface.wizard.IWizardPage)
+ */
+ public IWizardPage getNextPage(IWizardPage page) {
+
+
+ if (page.equals( selectActionPage )) {
+
+ SelectActionPage SelectWizardPage = (SelectActionPage) page;
+ if ( SelectWizardPage.importHeapRadioButton.getSelection() ) {
+ return importHeapPage;
+ }
+ else if ( SelectWizardPage.compareTwoHeapsRadioButton.getSelection() ) {
+ return compareHeapsFirstPage;
+ }
+ else if ( SelectWizardPage.swmtRadioButton.getSelection() ) {
+ return swmtLogPage;
+ }
+ } else if ( page.equals(importHeapPage) ) {
+ return parameterFilesPage;
+ }
+
+ else if ( page.equals(compareHeapsFirstPage) ) {
+ return compareHeapsSecondPage;
+ }
+ else if ( page.equals(compareHeapsSecondPage ) ) {
+ return exportFileNamePage;
+ }
+ else if ( page.equals( exportFileNamePage ) ){
+ boolean setText = true;
+ File file = new File( exportFileNamePage.getOutputFileName());
+ if( file.exists() ){
+ // if file already exists confirm that user wants to overwrite it.
+ MessageBox messageBox = new MessageBox(this.getShell(), SWT.ICON_QUESTION | SWT.YES | SWT.NO);
+ messageBox.setText( MemSpyMainView.WARNING_COMPARE );
+ messageBox.setMessage( MemSpyMainView.WARNING_FILE_EXISTS );
+ int buttonID = messageBox.open();
+ if (buttonID == SWT.NO) {
+ setText = false;
+ }
+ }
+ if( setText == false ){
+ return exportFileNamePage;
+ }
+ return parameterFilesPage;
+ }
+
+
+ return page;
+ }
+
+ /**
+ * (non-Javadoc)
+ * @see org.eclipse.jface.wizard.Wizard#canFinish()
+ */
+ public boolean canFinish() {
+ if (this.getContainer().getCurrentPage() == parameterFilesPage) {
+ return parameterFilesPage.canFinish();
+ }
+ else if (this.getContainer().getCurrentPage() == swmtLogPage ){
+ return swmtLogPage.canFinish();
+ }
+ else {
+ return false;
+ }
+
+ }
+
+
+
+
+ /**
+ * (non-Javadoc)
+ * @see org.eclipse.jface.wizard.Wizard#performFinish()
+ */
+
+
+ public boolean performFinish() {
+
+ if( this.wizardType == MemSpyWizardType.FULL ){
+ // save form values
+ saveUserEnteredData();
+
+ IRunnableWithProgress importFiles = null;
+
+ // get selected action from first page.
+ final MemSpyAction action = selectActionPage.getAction();
+
+ importHeapPage.getTraceEngine().shutDownMemSpy();
+ // Initialize XML generator
+ AnalyserXMLGenerator generator = new AnalyserXMLGenerator();
+
+
+ if( action != MemSpyAction.SWMT ){
+
+ // read symbol definitions
+ this.getSymbolInformation(generator);
+
+ final AnalyserXMLGenerator finalGenerator = generator;
+
+ // if importing Heap Dump(s)
+ if( selectActionPage.getAction() == MemSpyAction.IMPORT_HEAP ){
+ final ArrayList<ThreadInfo> importedHeaps = importHeapPage.getImportedHeaps();
+ importFiles = new IRunnableWithProgress() {
+ public void run(IProgressMonitor monitor) {
+ monitor.beginTask(IMPORTING_FILES, IProgressMonitor.UNKNOWN);
+
+ // import heaps
+ importEngine.importAndAnalyseHeap( importedHeaps, finalGenerator, true );
+ }
+ };
+ }//if Comparing heaps
+ else if( selectActionPage.getAction() == MemSpyAction.COMPARE_HEAPS ){
+
+ final ArrayList<ThreadInfo> heaps = new ArrayList<ThreadInfo>();
+
+ heaps.add( compareHeapsFirstPage.getRecentHeap() );
+ heaps.add( compareHeapsSecondPage.getRecentHeap() );
+ final String output = exportFileNamePage.getOutputFileName();
+
+ importFiles = new IRunnableWithProgress() {
+ public void run(IProgressMonitor monitor) {
+ monitor.beginTask(IMPORTING_FILES, IProgressMonitor.UNKNOWN);
+ // import heaps
+ importEngine.importAndAnalyseHeap( heaps, finalGenerator, false );
+ // compare heaps
+ importEngine.compareHeaps( heaps.get(0), heaps.get(1), finalGenerator, output );
+ }
+ };
+
+ }
+ }
+ else{ // if importing SWMT-logs
+ final ArrayList<SWMTLogInfo> logList = swmtLogPage.getLogList();
+ final AnalyserXMLGenerator finalGenerator = generator;
+ importFiles = new IRunnableWithProgress() {
+ public void run(IProgressMonitor monitor) {
+ monitor.beginTask(IMPORTING_FILES, IProgressMonitor.UNKNOWN);
+
+ // import heaps if SWMT logging was also dumping heap data for thread(s)
+ final ArrayList<ThreadInfo> importedHeaps = traceEngine.getImportedSWMTHeaps();
+ if(importedHeaps != null){
+ //Don't delete temp folder and files yet, SWMT import will do that
+ importEngine.importAndAnalyseHeap( importedHeaps, finalGenerator, false, false );
+ }
+
+ // import swmt-logs and delete temp files & folder
+ importEngine.importSWMTLogs( logList, true );
+
+ }
+ };
+ }
+ try {
+ getContainer().run(true, false, importFiles);
+ }
+ catch (InvocationTargetException e1) {
+ // do nothing
+ e1.printStackTrace();
+ }
+ catch (InterruptedException e1) {
+ // do nothing
+ e1.printStackTrace();
+ }
+ MemSpyMainView.showAndReturnYourself();
+ }
+ else if( this.wizardType == MemSpyWizardType.COMPARE ){
+
+ IRunnableWithProgress importFiles = null;
+
+ compareHeapsFirstPage.getTraceEngine().shutDownMemSpy();
+
+ // Initialize XML generator
+ AnalyserXMLGenerator generator = new AnalyserXMLGenerator();
+
+ // read symbol definitions
+ this.getSymbolInformation(generator);
+
+ final AnalyserXMLGenerator finalGenerator = generator;
+ final ThreadInfo secondHeap = compareHeapsSecondPage.getRecentHeap();
+
+ // create new ThreadInfo object and format combobox value from first compare page to it's
+ // threadFilePath variable.(We don't want to import that heap again as it has already
+ // been updated.)
+ ThreadInfo firstModifiedHeap = new ThreadInfo();
+ firstModifiedHeap.setThreadFilePath( compareHeapsFirstPage.getSelectedFilePath() );
+ firstModifiedHeap.setThreadName( secondHeap.getThreadName() );
+ final ThreadInfo firstHeap = firstModifiedHeap;
+
+ final String output = exportFileNamePage.getOutputFileName();
+
+ importFiles = new IRunnableWithProgress() {
+ public void run(IProgressMonitor monitor) {
+ monitor.beginTask(IMPORTING_FILES, IProgressMonitor.UNKNOWN);
+ ArrayList<ThreadInfo> heaps = new ArrayList<ThreadInfo>();
+ heaps.add( secondHeap );
+ importEngine.importAndAnalyseHeap(heaps, finalGenerator, false);
+ importEngine.compareHeaps( firstHeap, secondHeap, finalGenerator, output );
+ }
+ };
+
+
+ try {
+ getContainer().run(true, false, importFiles);
+ }
+ catch (InvocationTargetException e1) {
+ // do nothing
+ e1.printStackTrace();
+ }
+ catch (InterruptedException e1) {
+ // do nothing
+ e1.printStackTrace();
+ }
+ MemSpyMainView.showAndReturnYourself();
+
+ }
+ else if(this.wizardType == MemSpyWizardType.SYMBOLS ){
+
+ // read symbol definitions
+ this.getSymbolInformation(fillValues);
+
+ // send new symbols to Main View
+ IRunnableWithProgress importFiles = new IRunnableWithProgress() {
+ public void run(IProgressMonitor monitor) {
+ monitor.beginTask("Saving new symbol definitions", IProgressMonitor.UNKNOWN);
+ mainView.symbolsUpdated(fillValues);
+ monitor.done();
+ }
+ };
+
+
+ try {
+ getContainer().run(true, false, importFiles);
+ }
+ catch (InvocationTargetException e1) {
+ // do nothing
+ e1.printStackTrace();
+ }
+ catch (InterruptedException e1) {
+ // do nothing
+ e1.printStackTrace();
+ }
+ }
+ return true;
+ }
+
+ /**
+ * (non-Javadoc)
+ * @see org.eclipse.jface.wizard.Wizard#performCancel()
+ */
+ public boolean performCancel() {
+ try {
+ if( this.wizardType == MemSpyWizardType.FULL){
+ this.saveUserEnteredData();
+ }
+
+ MemSpyMainView.showAndReturnYourself();
+
+ // delete temp files
+ MemSpyFileOperations.deleteTempMemSpyFiles();
+ traceEngine.shutDownMemSpy();
+ } catch (Exception e) {
+ // Some failure in above should not prevent user Canceling dialog
+ e.printStackTrace();
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "performCancel/exception: " + e);
+ }
+
+ return true;
+ }
+
+ /**
+ * (non-Javadoc)
+ * @see org.eclipse.jface.wizard.Wizard#getPreviousPage(org.eclipse.jface.wizard.IWizardPage)
+ */
+ public IWizardPage getPreviousPage(IWizardPage page) {
+ if (page.equals(importHeapPage)) {
+ return selectActionPage;
+ } else if (page.equals(compareHeapsFirstPage)) {
+ return selectActionPage;
+ } else if (page.equals(compareHeapsSecondPage)) {
+ return compareHeapsFirstPage;
+ }
+ return page;
+ }
+
+ /**
+ * setComparedHeaps
+ * sets compared thread names into each compare page
+ */
+ public void setComparedHeaps(){
+
+ // get recent thread infos from compare heap pages
+ ThreadInfo firstHeap = null;
+ ThreadInfo secondHeap = null;
+
+ firstHeap = compareHeapsFirstPage.getRecentHeap();
+ secondHeap = compareHeapsSecondPage.getRecentHeap();
+
+ // save thread infos into compare pages
+ compareHeapsSecondPage.setComparedHeap(firstHeap, secondHeap);
+ compareHeapsFirstPage.setComparedHeap(firstHeap, secondHeap);
+ }
+
+ /**
+ * updateThreadLists
+ * updates tread lists into each file or device selection page
+ * @param threadList
+ */
+ public void updateThreadLists(ArrayList<ThreadInfo> threadList){
+ // Each page gets new thread list so that status of threads won't change when another page is modified.
+ if(importHeapPage != null){
+ this.importHeapPage.setDeviceThreadList( copyThreadList( threadList ) );
+ this.importHeapPage.updateThreadList();
+ }
+ if(compareHeapsFirstPage != null){
+ this.compareHeapsFirstPage.setDeviceThreadList( copyThreadList( threadList ) );
+ this.compareHeapsFirstPage.updateThreadList();
+ }
+ if(compareHeapsFirstPage != null){
+ this.compareHeapsSecondPage.setDeviceThreadList( copyThreadList( threadList ) );
+ this.compareHeapsSecondPage.updateThreadList();
+ }
+ }
+
+ /**
+ * Copies threads to new list.
+ * @param threadList List to be copied.
+ * @return New list containing thread information in new list.
+ */
+ private ArrayList<ThreadInfo> copyThreadList(ArrayList<ThreadInfo> threadList) {
+ ArrayList<ThreadInfo> returnList = new ArrayList<ThreadInfo>();
+ for(ThreadInfo thread : threadList) {
+ returnList.add(thread.clone());
+ }
+ return returnList;
+ }
+
+ /**
+ * sets thread list selection and hides threadListTable from 2. comparePage
+ * @param thread Thread information.
+ */
+ public void setThreadListSelectionToComparePages( ThreadInfo thread ){
+ this.compareHeapsSecondPage.setThreadListSelection( thread );
+ }
+
+ /**
+ * shows or hides threadListTable in 2. comparePage
+ */
+ public void showImportedHeapsInComparePage( boolean value ){
+ this.compareHeapsSecondPage.setImportedThreadTableVisible( value );
+
+ }
+
+
+
+ /**
+ * Check if compared heaps are from same thread
+ * @return true if heaps are from same thread or other or both heaps are still undefined
+ */
+ public boolean areComparedHeapsFromSameThread(){
+ if( compareHeapsFirstPage.getRecentHeap() != null &&
+ compareHeapsSecondPage.getRecentHeap() != null ){
+ if( compareHeapsFirstPage.getRecentHeap().getThreadName().equals(compareHeapsSecondPage.getRecentHeap().getThreadName() ) ){
+ return true;
+ }
+ else{
+ return false;
+ }
+ }
+ else{
+ return true;
+ }
+
+ }
+
+
+ /**
+ * saveUserEnteredData
+ * calls saveUserEnteredData method of all wizard pages.
+ */
+ private void saveUserEnteredData(){
+
+ // Save form values so that they can be restored later
+ if( selectActionPage != null){
+ selectActionPage.saveUserEnteredData();
+ }
+ if( importHeapPage != null){
+ importHeapPage.saveUserEnteredData();
+ }
+ if( parameterFilesPage != null){
+ parameterFilesPage.saveUserEnteredData();
+ }
+ if( compareHeapsFirstPage != null){
+ compareHeapsFirstPage.saveUserEnteredData();
+ }
+ if( compareHeapsSecondPage != null){
+ compareHeapsSecondPage.saveUserEnteredData();
+ }
+ if( exportFileNamePage != null){
+ exportFileNamePage.saveUserEnteredData();
+ }
+ if( swmtLogPage != null){
+ swmtLogPage.saveUserEnteredData();
+ }
+ }
+
+ public void updateConnectionSettings(){
+ if( importHeapPage != null ){
+ this.importHeapPage.updateConnectionSettings();
+ }
+ if( compareHeapsFirstPage != null ){
+ this.compareHeapsFirstPage.updateConnectionSettings();
+ }
+ if( compareHeapsSecondPage != null ){
+ this.compareHeapsSecondPage.updateConnectionSettings();
+ }
+ if( swmtLogPage != null ){
+ this.swmtLogPage.updateConnectionSettings();
+ }
+
+ if(traceEngine != null){
+ // Resetting progress status in case connection settings have been changed
+ traceEngine.resetProgressStatus();
+ }
+
+ }
+
+ public void init(IWorkbench arg0, IStructuredSelection arg1) {
+
+ }
+
+ public void setData(MemSpyWizardDialog wizDialog){
+ this.wizDialog = wizDialog;
+ }
+
+ public void setCancelText( String newText ){
+ wizDialog.setCancelText( newText );
+ }
+
+ private void getSymbolInformation( AnalyserXMLGenerator symbolInfo ){
+
+ // combine map and symbol files into one String[] and set them into xmlGenerator
+ ArrayList<String> debugMetaData;
+ String[] symbolFiles = parameterFilesPage.getSymbolFiles();
+ if( symbolFiles == null ){
+ debugMetaData = new ArrayList<String>();
+ }
+ else{
+ debugMetaData = new ArrayList<String>(Arrays.asList( symbolFiles ));
+ }
+ if( parameterFilesPage.getMapFilesZip().equals("") == false ){
+ debugMetaData.add( parameterFilesPage.getMapFilesZip() );
+ }
+
+ // Set meta data folder
+ symbolInfo.setXMLDebugMetaDataFile(debugMetaData.toArray(new String [debugMetaData.size()]));
+ if( parameterFilesPage.getMapFilesFolder().equals("") == false ){
+ symbolInfo.setXMLDebugMetaDataDirectory( parameterFilesPage.getMapFilesFolder() );
+ }
+ else{
+ symbolInfo.setXMLDebugMetaDataDirectory(null);
+ }
+
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/ui/wizards/MemSpyWizardDialog.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,49 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+
+package com.nokia.s60tools.memspy.ui.wizards;
+
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.wizard.IWizard;
+import org.eclipse.jface.wizard.WizardDialog;
+import org.eclipse.swt.widgets.Shell;
+
+public class MemSpyWizardDialog extends WizardDialog {
+ @Override
+ public void create() {
+ super.create();
+ }
+
+ public MemSpyWizardDialog(Shell parentShell, IWizard newWizard) {
+ super(parentShell, newWizard);
+ }
+
+ public void enableBackCancelButtons(boolean enable) {
+ getButton(IDialogConstants.BACK_ID).setEnabled(enable);
+ getButton(IDialogConstants.CANCEL_ID).setEnabled(enable);
+
+
+ }
+
+ public void setCancelText(String newText){
+ getButton(IDialogConstants.CANCEL_ID).setText(newText);
+
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/ui/wizards/ParameterFilesPage.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,165 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+
+package com.nokia.s60tools.memspy.ui.wizards;
+
+import java.util.HashMap;
+
+import org.eclipse.swt.widgets.Composite;
+
+import com.nokia.s60tools.memspy.model.UserEnteredData;
+import com.nokia.s60tools.memspy.resources.HelpContextIDs;
+import com.nokia.s60tools.sdk.SdkUtils;
+import com.nokia.s60tools.ui.wizards.DebugMetadataWizardPage;
+
+
+/**
+ * class ParameterFilesPage
+ * This wizard page will query the user for locations symbol and map files.
+ */
+public class ParameterFilesPage extends DebugMetadataWizardPage {
+
+ private String[] symbolOrMapFiles;
+ private String mapFileDirectory;
+
+ private enum FileType{ SYMBOL, MAPFILE };
+
+
+ public ParameterFilesPage( String[] symbolOrMapFiles, String mapFileDirectory, String descriptionText ){
+ super("MemSpy", descriptionText, false, UserEnteredData.getParameterFilesSection(),
+ UserEnteredData.MAX_SAVED_VALUES);
+ this.symbolOrMapFiles = symbolOrMapFiles;
+ this.mapFileDirectory = mapFileDirectory;
+
+ }
+
+ public void createControl(Composite parent) {
+ super.createControl(parent);
+
+ // read symbolOrMapFiles-variables values and set them to UI items.
+
+ if( this.symbolOrMapFiles != null ){
+
+ //Reset Symbol file list-component
+ this.listSymbols.removeAll();
+
+
+ // Reset ui-components values
+
+ // set "No Map Files"-radio button selected.(and unselect other buttons)
+ this.buttonMapFilesFolderRadio.setSelection(false);
+ this.buttonMapFilesZipRadio.setSelection(false);
+ this.buttonSdkFolderRadio.setSelection(false);
+ this.buttonNoMapFilesRadio.setSelection(true);
+
+ // disable combo boxes and browse buttons buttons
+ this.comboMapFilesFolder.setEnabled(false);
+ this.buttonMapFolderBrowse.setEnabled(false);
+ this.comboMapFilesZip.setEnabled(false);
+ this.buttonZipBrowse.setEnabled(false);
+ this.comboSdkFolder.setEnabled(false);
+
+
+ for( String item : symbolOrMapFiles ){
+ if( getFileType(item) == FileType.SYMBOL ){
+ listSymbols.add(item);
+
+ }
+ else if(getFileType(item) == FileType.MAPFILE ){
+ comboMapFilesZip.setText(item);
+
+ // set zip-radio button selected.(and unselect other buttons)
+ this.buttonMapFilesFolderRadio.setSelection(false);
+ this.buttonMapFilesZipRadio.setSelection(true);
+ this.buttonSdkFolderRadio.setSelection(false);
+ this.buttonNoMapFilesRadio.setSelection(false);
+
+ // enable zip buttons
+ this.comboMapFilesFolder.setEnabled(false);
+ this.buttonMapFolderBrowse.setEnabled(false);
+ this.comboMapFilesZip.setEnabled(true);
+ this.buttonZipBrowse.setEnabled(true);
+ this.comboSdkFolder.setEnabled(false);
+ }
+ }
+
+ }
+ if( this.mapFileDirectory != null ){
+ comboMapFilesFolder.setText( mapFileDirectory );
+
+ // set folder-radio button selected.(and unselect other buttons)
+ this.buttonMapFilesFolderRadio.setSelection(true);
+ this.buttonMapFilesZipRadio.setSelection(false);
+ this.buttonSdkFolderRadio.setSelection(false);
+ this.buttonNoMapFilesRadio.setSelection(false);
+
+ // enable folder buttons
+ this.comboMapFilesFolder.setEnabled(true);
+ this.buttonMapFolderBrowse.setEnabled(true);
+ this.comboMapFilesZip.setEnabled(false);
+ this.buttonZipBrowse.setEnabled(false);
+ this.comboSdkFolder.setEnabled(false);
+
+ }
+ }
+
+ public boolean zipContainsMapFiles(String path) {
+ return SdkUtils.zipContainsMapFiles(path);
+ }
+
+ public String getHelpContext() {
+ return HelpContextIDs.MEMSPY_IMPORT_SYMBOLS;
+ }
+
+ public boolean canFlipToNextPage(){
+ return false;
+ }
+
+ public boolean canFinish() {
+ return canProceed();
+ }
+
+ public HashMap<String, String> getSdkMapFolders() {
+ return SdkUtils.getSdkMapFileFolders(true);
+ }
+
+ private static FileType getFileType( String fileName ){
+ int index = fileName.lastIndexOf('.');
+ if ( index <= 0 ){
+ return FileType.SYMBOL;
+ }
+ else{
+ String end = fileName.substring(index);
+ if(end.equals(".zip")){
+ return FileType.MAPFILE;
+ }
+ else{
+ return FileType.SYMBOL;
+ }
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see com.nokia.s60tools.ui.wizards.DebugMetadataWizardPage#folderContainsMapFiles(java.lang.String)
+ */
+ public boolean folderContainsMapFiles(String folder) {
+ return SdkUtils.folderContainsMapFiles(folder);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/ui/wizards/SWMTCategoryGroupComposite.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,388 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+package com.nokia.s60tools.memspy.ui.wizards;
+
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.jface.window.Window;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Layout;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Widget;
+
+import com.nokia.s60tools.memspy.model.CategoryProfile;
+import com.nokia.s60tools.memspy.model.SWMTCategorys;
+import com.nokia.s60tools.memspy.plugin.MemSpyPlugin;
+import com.nokia.s60tools.memspy.preferences.MemSpyPreferences;
+import com.nokia.s60tools.memspy.ui.dialogs.SWMTCategoriesDialog;
+import com.nokia.s60tools.ui.AbstractUIComposite;
+import com.nokia.s60tools.util.debug.DbgUtility;
+
+
+/**
+ * This interface is used to notify category selection changes
+ */
+interface SWMTCategorySelectionMediator{
+
+ /**
+ * Gets category selection as bitwise OR:ed integer.
+ * @return category selection
+ */
+ public int getCategorySelection();
+
+ /**
+ * Sets new category selection
+ * @param newCategorySelection new category selection as bitwise OR:ed integer
+ * @param isProfileSettings <code>true</code> if these settings are profile settings
+ * <code>false</code> if these are custom settings
+ */
+ public void setCategorySelection(int newCategorySelection, boolean isProfileSettings);
+
+ /**
+ * Set Categories button selection to "All" or "Custom".
+ * @param isProfileCategoriesSelected <code>true</code> if one profile is selected
+ * <code>false</code> otherwise.
+ */
+ public void setProfileTrackedCategoriesSelected(boolean isProfileTrackedCategoriesSelected);
+
+ /**
+ * Get if user has been selected to use one of the profiles Categories
+ * @return <code>true</code> if one profile is selected
+ * <code>false</code> if custom categories is selected.
+ */
+ public boolean isProfileTrackedCategoriesSelected();
+};
+
+
+/**
+ * Composite for SWMT category selection group in SWMTLogPage wizard page.
+ */
+public class SWMTCategoryGroupComposite extends AbstractUIComposite implements SelectionListener {
+
+ //
+ // Private constants
+ //
+ private static final int COMPOSITE_COLUMN_COUNT = 1;
+ private static final int TRACKED_CATEGORIES_GROUP_COLUMN_COUNT = 2;
+ //
+ // Private member data
+ //
+ private Button profileCategoriesRadioBtn;
+ private Button customCategoriesRadioBtn;
+ private Button editCategoriesPushButton;
+ private boolean isCustomCategorySelected = false;
+ private final SWMTCategorySelectionMediator mediator;
+ private boolean isCustomCategorySelectionEnabled = true;
+ private Combo profileCombo;
+
+ /**
+ * Constructor.
+ * @param parentComposite parent composite
+ * @param isCustomCategorySelected <code>true</code> if custom category is initially selected, otherwise <code>false</code>
+ * @param mediator mediator for handling category selection changes
+ * @param isCustomCategorySelectionEnabled <code>true</code> if custom category selection is enabled, otherwise <code>false</code>.
+ */
+ public SWMTCategoryGroupComposite(Composite parentComposite, boolean isCustomCategorySelected, SWMTCategorySelectionMediator mediator, boolean isCustomCategorySelectionEnabled) {
+ super(parentComposite);
+ this.isCustomCategorySelected = isCustomCategorySelected;
+ this.mediator = mediator;
+ this.isCustomCategorySelectionEnabled = isCustomCategorySelectionEnabled;
+ setCustomCategorySelection();
+ // Updating widget UI state based on the provided constructor parameters
+ setWidgetStates();
+ }
+
+ /**
+ * Sets custom category selection based on the feature availability
+ * and the current selection data.
+ */
+ private void setCustomCategorySelection() {
+ boolean isAllTrackedCategoriesSelected = mediator.isProfileTrackedCategoriesSelected();
+ if(isCustomCategorySelectionEnabled && !isAllTrackedCategoriesSelected){
+ // If feature is enabled and there is pre-selected values => custom category is selected
+ isCustomCategorySelected = true;
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see com.nokia.s60tools.ui.AbstractUIComposite#createControls()
+ */
+ @Override
+ protected void createControls() {
+
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION, this.getClass().getSimpleName() + ": createControls()"); //$NON-NLS-1$
+
+ // Tracked Categories -group
+ Group categoryGroup = new Group(this, SWT.SHADOW_NONE);
+ categoryGroup.setText("Tracked Categories and Advanced Options");
+ GridLayout gdl = new GridLayout(TRACKED_CATEGORIES_GROUP_COLUMN_COUNT, false);
+ GridData gd = new GridData(GridData.FILL_BOTH);
+ categoryGroup.setLayout(gdl);
+ categoryGroup.setLayoutData(gd);
+
+ Composite profileCom = new Composite(categoryGroup,SWT.NONE);
+ GridLayout pgl = new GridLayout(2, false);
+ pgl.marginHeight = 0;
+ pgl.marginWidth = 0;
+ GridData pgd = new GridData(GridData.FILL_BOTH);
+ pgd.horizontalSpan = 2;
+ pgd.grabExcessHorizontalSpace = true;
+ pgd.grabExcessVerticalSpace = true;
+ profileCom.setLayout(pgl);
+ profileCom.setLayoutData(pgd);
+
+ //
+ // Tracked Categories -group contents
+ //
+
+ boolean isProfileSelected = MemSpyPreferences.isProfileTrackedCategoriesSelected();
+
+ //Profiles button
+ profileCategoriesRadioBtn = new Button(profileCom, SWT.RADIO);
+ profileCategoriesRadioBtn.addSelectionListener(this);
+ profileCategoriesRadioBtn.setSelection(isProfileSelected);
+
+ profileCombo = new Combo( profileCom, SWT.BORDER | SWT.DROP_DOWN | SWT.READ_ONLY);
+ profileCombo.addSelectionListener(this);
+
+ List<CategoryProfile> categoryProfiles = SWMTCategorys.getInstance().getCategoryProfiles();
+ for (Iterator<CategoryProfile> iterator = categoryProfiles.iterator(); iterator
+ .hasNext();) {
+ CategoryProfile profile = (CategoryProfile) iterator.next();
+ profileCombo.add(profile.getName());
+ }
+
+
+ // Custom -radio button
+ customCategoriesRadioBtn = new Button(categoryGroup, SWT.RADIO);
+ customCategoriesRadioBtn.setText("Custom Categories and Advanced Options");
+ customCategoriesRadioBtn.addSelectionListener(this);
+ customCategoriesRadioBtn.setSelection(!isProfileSelected);
+
+ // Edit -push button
+ editCategoriesPushButton = new Button(categoryGroup, SWT.PUSH);
+ editCategoriesPushButton.setText("Edit...");
+ editCategoriesPushButton.addSelectionListener(this);
+ }
+
+ /**
+ * Sets selection and enabled disable states for the widgets
+ */
+ private void setWidgetStates() {
+
+ customCategoriesRadioBtn.setEnabled(true);
+ profileCategoriesRadioBtn.setEnabled(true);
+ profileCombo.setEnabled(true);
+
+ if(isCustomCategorySelected){
+ profileCombo.setEnabled(false);
+ profileCategoriesRadioBtn.setSelection(false);
+ customCategoriesRadioBtn.setSelection(true);
+ editCategoriesPushButton.setEnabled(true);
+ }
+ else{
+ profileCombo.setEnabled(true);
+ profileCategoriesRadioBtn.setSelection(true);
+ customCategoriesRadioBtn.setSelection(false);
+ editCategoriesPushButton.setEnabled(false);
+ }
+ setProfileComboSelectionAndTooltipText();
+
+ if(!isCustomCategorySelectionEnabled){
+ disableControls();
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see com.nokia.s60tools.ui.AbstractUIComposite#createLayout()
+ */
+ @Override
+ protected Layout createLayout() {
+ return new GridLayout(COMPOSITE_COLUMN_COUNT, false);
+ }
+
+ /* (non-Javadoc)
+ * @see com.nokia.s60tools.ui.AbstractUIComposite#createLayoutData()
+ */
+ @Override
+ protected Object createLayoutData() {
+ GridData gridData = new GridData(GridData.FILL_BOTH);
+ gridData.verticalSpan = 2;
+ return gridData;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.swt.events.SelectionListener#widgetDefaultSelected(org.eclipse.swt.events.SelectionEvent)
+ */
+ public void widgetDefaultSelected(SelectionEvent e) {
+ // Must be implemented but not needed in this case
+ }
+
+ /**
+ * Sets selection for profile Combo and sets tooltip text
+ */
+ private void setProfileComboSelectionAndTooltipText() {
+ int selectedProfile = MemSpyPreferences.getSWMTCategorySettingForProfile();
+
+ List<CategoryProfile> categoryProfiles = SWMTCategorys.getInstance()
+ .getCategoryProfiles();
+ int j = 0;
+ for (Iterator<CategoryProfile> iterator = categoryProfiles.iterator(); iterator
+ .hasNext();) {
+ CategoryProfile profile = (CategoryProfile) iterator.next();
+ if (selectedProfile == profile.getCategories()) {
+ //Selection of combo
+ profileCombo.select(j);
+ //Tootip text for combo selection
+ String categoryNames = "";
+ String[] profileCategoryNames = profile.getCategoryEntryNames();
+ //Collection names of all categories belongs to profile as comma separated list (but last with "and")
+ for (int i = 0; i < profileCategoryNames.length; i++) {
+ categoryNames += profileCategoryNames[i];
+ if (i == profileCategoryNames.length - 2) {
+ categoryNames += " and ";
+ } else if (i != profileCategoryNames.length - 1) {
+ categoryNames += ", ";
+ }
+ // else its last item and we dont need to add anything
+ }
+ String name = profile.getName();
+ //To show "&" char in tooltip, it must be replaced with "&&"
+ name = name.replace("&", "&&");
+ String toolTipText = "Profile: (" + name
+ + ") contains following categories: " + categoryNames;
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION, toolTipText);
+ profileCombo.setToolTipText(toolTipText);
+ break;
+ }
+
+ j++;
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt.events.SelectionEvent)
+ */
+ public void widgetSelected(SelectionEvent e) {
+ Widget widget = e.widget;
+
+ if(widget.equals(profileCategoriesRadioBtn)){
+ isCustomCategorySelected = false;
+ mediator.setProfileTrackedCategoriesSelected(true);
+ setWidgetStates();
+ }
+ else if(widget.equals(customCategoriesRadioBtn)){
+ isCustomCategorySelected = true;
+ mediator.setProfileTrackedCategoriesSelected(false);
+ setWidgetStates();
+ }
+ else if(widget.equals(editCategoriesPushButton)){
+ categoriesEditButtonPressed();
+ }
+ else if(widget.equals(profileCombo)){
+ String selectedProfile = profileCombo.getText();
+ CategoryProfile profile = SWMTCategorys.getInstance().getProfile(selectedProfile);
+ mediator.setCategorySelection(profile.getCategories(), true);
+ setProfileComboSelectionAndTooltipText();
+ }
+ }
+
+
+
+ /**
+ * Checks if custom category set has been selected by a user.
+ * @return <code>true</code> if custom category has been selected, otherwise <code>false</code>.
+ */
+ public boolean isCustomCategorySelected() {
+ return isCustomCategorySelected;
+ }
+
+ /**
+ * Handles Edit...-button press event.
+ */
+ private void categoriesEditButtonPressed() {
+ Shell sh = MemSpyPlugin.getCurrentlyActiveWbWindowShell();
+ SWMTCategoriesDialog entryDialog = new SWMTCategoriesDialog(sh, mediator.getCategorySelection());
+ entryDialog.create();
+ int userSelection = entryDialog.open();
+ if(userSelection == Window.OK){
+ int newCategorySelection = entryDialog.getSelectedCategories();
+ mediator.setCategorySelection(newCategorySelection, false);
+ }
+ }
+
+ /**
+ * Disables custom category selection programmatically and updates UI accordingly
+ */
+ public void disableCustomCategorySelection(){
+ isCustomCategorySelectionEnabled = false;
+ isCustomCategorySelected = false;
+ setWidgetStates();
+ }
+
+ /**
+ * Sets enable state false to the controls.
+ */
+ private void disableControls() {
+ // Disabling custom category selection
+ setEnabled(false);
+ profileCategoriesRadioBtn.setEnabled(false);
+ customCategoriesRadioBtn.setEnabled(false);
+ editCategoriesPushButton.setEnabled(false);
+ profileCombo.setEnabled(false);
+ }
+
+ /**
+ * Refreshes widget state
+ */
+ public void refresh(){
+ setWidgetStates();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.swt.widgets.Widget#dispose()
+ */
+ public void dispose(){
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION, this.getClass().getSimpleName() + ": dispose()"); //$NON-NLS-1$
+ super.dispose();
+ }
+
+ /**
+ * Sets buttons enabled/disabled
+ * @param isButtonsEnabled set <code>true</code> if buttons are enabled, and <code>false</code>
+ * if buttons are disabled
+ */
+ public void setButtonsEnabled(boolean isButtonsEnabled){
+ if(isButtonsEnabled){
+ setWidgetStates();
+ }else{
+ disableControls();
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/ui/wizards/SWMTLogPage.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,1362 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+
+package com.nokia.s60tools.memspy.ui.wizards;
+import java.io.File;
+import java.lang.reflect.InvocationTargetException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.dialogs.ErrorDialog;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.DirectoryDialog;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.FileDialog;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+import org.eclipse.swt.widgets.TableItem;
+import org.eclipse.ui.PlatformUI;
+
+import com.nokia.s60tools.memspy.containers.SWMTLogInfo;
+import com.nokia.s60tools.memspy.containers.SWMTLogInfo.SWMTLogType;
+import com.nokia.s60tools.memspy.interfaces.IMemSpyTraceListener;
+import com.nokia.s60tools.memspy.model.MemSpyFileOperations;
+import com.nokia.s60tools.memspy.model.MemSpyLogParserEngine;
+import com.nokia.s60tools.memspy.model.TraceCoreEngine;
+import com.nokia.s60tools.memspy.model.UserEnteredData;
+import com.nokia.s60tools.memspy.model.UserEnteredData.ValueTypes;
+import com.nokia.s60tools.memspy.plugin.MemSpyPlugin;
+import com.nokia.s60tools.memspy.preferences.MemSpyPreferences;
+import com.nokia.s60tools.memspy.resources.HelpContextIDs;
+import com.nokia.s60tools.memspy.ui.UiUtils;
+import com.nokia.s60tools.ui.preferences.PreferenceUtils;
+import com.nokia.s60tools.ui.wizards.S60ToolsWizardPage;
+import com.nokia.s60tools.util.debug.DbgUtility;
+
+/**
+ * SWMT-log import page is used for importing SWMT-logs from file system or from device.
+ */
+
+public class SWMTLogPage extends S60ToolsWizardPage implements SelectionListener, IMemSpyTraceListener, SWMTCategorySelectionMediator{
+
+ /**
+ * Selection index for import from device via TraceViewer radio button
+ */
+ private static final int DEVICE_RADIO_BUTTON_SELECTION_INDEX = 2;
+
+ // Array list of logs that are imported
+ // from files:
+ private ArrayList<SWMTLogInfo> fileLogList;
+ // from device:
+ private ArrayList<SWMTLogInfo> deviceLogList;
+
+ // SWMT-log that is currently received
+ SWMTLogInfo receivedLog;
+
+ // TraceCore engine
+ private TraceCoreEngine traceEngine;
+
+ // Cycle Number for SMWT-log file name
+ private int cycleNumber;
+
+ // Error message
+ String errorMessage;
+
+ // boolean value stating that error has been occurred and logs cannot be requested before removing
+ // all items and restarting from cycle 1.
+ boolean missedLogs;
+
+ //UI-components:
+ private Group radioButtonGroup;
+ private Button fileRadioButton;
+ private Button deviceRadioButton;
+
+ // Components for importing file from device
+ private Table fileLogsTable;
+ private Composite fileSelectionButtonComposite;
+ private Button addFileButton;
+ private Button addDirectoryButton;
+ private Button removeOneButton;
+ private Button removeAllButton;
+
+ private Group fileSelectionGroup;
+ private Group deviceGroup;
+
+ private GridData fileSelectionGridData;
+ private GridData deviceGridData;
+
+
+ // components for importing log from device
+ private Table deviceLogsTable;
+ private Composite loggingComposite;
+ private Button connectionSettingsButton;
+ private Button getLogNowButton;
+ private Button removeReceivedLogsButton;
+ private Label connectionNameInUseLabel;
+
+ // Timer related components
+ private Label intervalLabel;
+ private Label secondLabel;
+ private Button startTimerButton;
+ private Combo timerCombo;
+
+ /**
+ * UI composite for SWMT Category group
+ */
+ private SWMTCategoryGroupComposite categoryGroupComposite;
+
+ // boolean variable, which is set to true if some MemSpy operation is running.
+ boolean memSpyOperationRunning;
+ boolean memSpyStopping;
+ boolean memSpyTimerRunning;
+
+ // MemSpy operation processes:
+ // receive SWMT-log manually
+ IRunnableWithProgress receiveSWMTLogProcess;
+
+ private final static String GET_LOG_FROM_RADIO_BUTTON = "Get SWMT Log";
+ private final static String GET_FROM_FROM_FILE_RADIO_BUTTON = "From File System";
+ private final static String GET_LOG_FROM_DEVICE_RADIO_BUTTON = "From Device via TraceViewer";
+ private final static String LOG_FILES = "Log files:";
+ private final static String LOG_TYPE = "Type";
+ private final static String ADD_FILE = "Add File";
+ private final static String ADD_DIRECTORY = "Add Directory";
+ private final static String REMOVE_ONE = "Remove";
+ private final static String REMOVE_ALL = "Remove All";
+ private final static String ADD_FILE_TEXT = "Define Location of SWMT Log file:";
+ private final static String ADD_DIRECTORY_TEXT = "Define Location of directory that contains SWMT Logs:";
+ private final static String LOG_TYPE_FILE = "File";
+ private final static String LOG_TYPE_DIRECTORY = "Directory";
+
+ private final static String CONNECTION_SETTINGS_BUTTON = "Connection Settings...";
+ private final static String CURRENTLY_USING_TEXT = "Currently using:";
+ private final static String GET_LOG_NOW_BUTTON = "Get SWMT Log Now";
+ private final static String LOGS = "Logs";
+ private final static String RECEIVED = "Received";
+
+ private final static String RECEIVING_SWMT_LOG = "Receiving SWMT Log: ";
+ private final static String WAITING_FOR_TIMER = "Waiting for timer to expire: ";
+ private final static String STOPPING_TIMER = "Stopping timer: ";
+
+ private final static String TEXT_GET_LOG_WITH_TIMER = "Get Log with Timer";
+ private final static String TEXT_INTERVAL = "Interval:";
+ private final static String START_TIMER = "Start Timer";
+ private final static String TEXT_SECOND = "Seconds";
+
+ private final static String ERROR_INTERVAL = "Time interval needs to be integer and more than zero.";
+
+ /**
+ * Constructor.
+ * @param pageName name of the page
+ * @param traceEngine TraceCore engine that is used when requesting data from TC
+ */
+ protected SWMTLogPage(String pageName, TraceCoreEngine traceEngine) {
+ super(pageName);
+ setTitle("System Wide Memory Tracking Wizard");
+ setDescription("Define Source For SWMT logs that are imported. Logs can be imported from already existing files or from device via TraceViewer.");
+ this.fileLogList = new ArrayList<SWMTLogInfo>();
+ this.deviceLogList = new ArrayList<SWMTLogInfo>();
+ this.traceEngine = traceEngine;
+ this.createMemSpyProcesses();
+
+ this.memSpyTimerRunning = false;
+ this.memSpyOperationRunning = false;
+ this.memSpyStopping = false;
+ this.cycleNumber = 0;
+
+ this.missedLogs = false;
+ }
+
+ @Override
+ public void recalculateButtonStates() {
+ // no implementation needed
+ }
+
+ @Override
+ public void setInitialFocus() {
+ timerCombo.setFocus();
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.swt.events.SelectionListener#widgetDefaultSelected(org.eclipse.swt.events.SelectionEvent)
+ */
+ public void widgetDefaultSelected(SelectionEvent e) {
+ // Not needed in this case
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt.events.SelectionEvent)
+ */
+ public void widgetSelected(SelectionEvent e) {
+ // Update controls after radio buttons state changes to false
+ if ( ( e.widget == deviceRadioButton && deviceRadioButton.getSelection() == false ) ||
+ ( e.widget == fileRadioButton && fileRadioButton.getSelection() == false ) ){
+ //When selection is changed, we clear the previous results.
+ removeReceivedLogs();
+ this.hideAndRevealItems();
+ }
+
+ // open file dialog
+ else if (e.widget == addFileButton) {
+ // open file dialog for selecting a crash file
+ FileDialog dialog = new FileDialog(this.getShell(), SWT.MULTI);
+ dialog.setText(ADD_FILE_TEXT);
+ String[] filterExt = { "*.txt", "*.log", "*.*" };
+ dialog.setFilterExtensions(filterExt);
+
+ if (dialog.open() != null ){
+ String[] files = dialog.getFileNames();
+ String directory = dialog.getFilterPath();
+ directory = MemSpyFileOperations.addSlashToEnd( directory );
+
+ boolean noLogFound = false;
+
+ for( String item : files ){
+
+ // confirm that file is smwt log
+ if( MemSpyLogParserEngine.isFileSWMTLog( new File(directory + item)) ){
+ this.addFileLog( directory + item );
+ }
+
+ else{
+ noLogFound = true;
+ }
+ }
+
+ // if some of the selected files is not swmt-file show error message.
+ if( noLogFound ){
+ Status status = new Status(IStatus.ERROR, MemSpyPlugin.PLUGIN_ID, 0, "Some of the selected files is not SWMT-log file.", null);
+ // Display the dialog
+ ErrorDialog.openError(Display.getCurrent().getActiveShell(),ERROR_MEMSPY, null, status);
+ }
+ }
+
+
+ }
+
+ // open directory dialog
+ else if (e.widget == addDirectoryButton) {
+ // open file dialog for selecting a crash file
+ DirectoryDialog dialog = new DirectoryDialog(this.getShell());
+ dialog.setText(ADD_DIRECTORY_TEXT);
+ String result = dialog.open();
+ if (result != null ){
+
+ File[] allFiles = MemSpyFileOperations.getFilesFromDirectory( new File( result ) );
+
+ int swmtFileCount = 0;
+
+ for ( File item : allFiles ){
+ if( MemSpyLogParserEngine.isFileSWMTLog( item ) ){
+ swmtFileCount++;
+ this.addFileLog( item.toString() );
+ }
+ }
+ // if no SWMT-log files were found from selected directory, show error message.
+ if(swmtFileCount == 0){
+ Status status = new Status(IStatus.ERROR, MemSpyPlugin.PLUGIN_ID, 0, "No SWMT-logs were found from selected directory.", null);
+ // Display the dialog
+ ErrorDialog.openError(Display.getCurrent().getActiveShell(),ERROR_MEMSPY, null, status);
+
+
+ }
+ }
+ }
+
+ // remove selected log file
+ else if (e.widget == removeOneButton ){
+ if( fileLogsTable.getSelectionCount() == 1 ){
+ fileLogList.remove( fileLogsTable.getSelectionIndex() );
+ this.refreshFileLogTable();
+ }
+ }
+
+ // remove all log files
+ else if (e.widget == removeAllButton ){
+ fileLogList.clear();
+ this.refreshFileLogTable();
+ }
+
+ // open connection settings
+ else if ( e.widget == connectionSettingsButton ){
+ // Open connection Trace viewers connection settings.
+ Shell shell = MemSpyPlugin.getCurrentlyActiveWbWindowShell();
+ PreferenceUtils.openPreferencePage(MemSpyPlugin.getTraceProvider().getTraceSourcePreferencePageId(), shell);
+
+ // Disconnect trace source so that new settings are used when sending next request
+ MemSpyPlugin.getTraceProvider().disconnectTraceSource();
+
+ // get wizard pointer and cast it to MemSpyWizard
+ MemSpyWizard wizard = (MemSpyWizard) this.getWizard();
+ // update new settings to each wizard page.
+ wizard.updateConnectionSettings();
+ }
+
+ // get log now from TC
+ else if (e.widget == getLogNowButton ){
+ this.getLogNowPressed();
+ }
+
+ // Remove all log received from device-button
+ else if( e.widget == removeReceivedLogsButton ){
+ this.removeReceivedLogs();
+ }
+
+ // SWMT timer started
+ else if( e.widget == startTimerButton ){
+ this.getLogWithTimerPressed();
+ }
+
+
+ // if file logs table selection changes or button is pressed, enable and disable buttons
+ if( e.widget == this.fileLogsTable ||
+ e.widget == this.removeAllButton ||
+ e.widget == this.removeOneButton ||
+ e.widget == this.addFileButton ||
+ e.widget == this.addDirectoryButton ){
+ this.enableAndDisableFileButtons();
+ }
+ getWizard().getContainer().updateButtons();
+
+ }
+
+ /**
+ * Checks if wizard can be finished or not.
+ * @return boolean value if wizard can finish
+ */
+ public boolean canFinish(){
+
+ // if traceEngines taskList is not empty, return false
+ if( traceEngine.getFirstTask() != null ){
+ return false;
+ }
+
+ // if file or device log lists are not empty(depending on radiobutton selection) return true
+ if( fileRadioButton.getSelection() ){
+ if( fileLogList.size() > 0 ){
+ return true;
+ }
+ }
+ else{
+ if( deviceLogList.size() > 0 ){
+ return true;
+ }
+ }
+ return false;
+ }
+
+
+ /**
+ * Hides and reveals controls according to radio button states.
+ */
+ private void hideAndRevealItems() {
+
+ boolean fileSelected = true;
+
+ if( fileRadioButton.getSelection() == false ){
+ fileSelected = false;
+ }
+
+ // exclude/include needed controls
+ fileSelectionGridData.exclude = !fileSelected;
+ deviceGridData.exclude = fileSelected;
+
+ if( !fileSelected ){
+ // Since excluded groups size and location are not updated, do it now
+ deviceGroup.setSize( fileSelectionGroup.getSize() );
+ deviceGroup.setLocation(fileSelectionGroup.getLocation());
+ }
+ else{
+ // Since excluded groups size and location are not updated, do it now
+ fileSelectionGroup.setSize( deviceGroup.getSize() );
+ fileSelectionGroup.setLocation(deviceGroup.getLocation());
+
+ }
+ // Hide/show needed controls
+ fileSelectionGroup.setVisible(fileSelected);
+ deviceGroup.setVisible(!fileSelected);
+
+ }
+
+ /**
+ * Adds a log file.
+ * @param location of log file
+ */
+ private void addFileLog( String location ){
+
+ // create SWMTLogInfo object for log file.
+ SWMTLogInfo info = new SWMTLogInfo();
+ info.setType( SWMTLogType.FILE );
+ info.setPath( location );
+ fileLogList.add(info);
+
+ // get files name
+ String fileName = location.substring( location.lastIndexOf("\\") + 1 );
+
+ // add name into table
+ TableItem item = new TableItem( fileLogsTable, SWT.NONE, fileLogsTable.getItemCount() );
+ item.setText( new String[]{ fileName, LOG_TYPE_FILE });
+
+ }
+
+ /**
+ * Updates file log table so that it contains same data that file log list.
+ */
+ private void refreshFileLogTable(){
+ //Remove all items
+ fileLogsTable.removeAll();
+
+ for( int i = 0; i < fileLogList.size(); i++ ){
+ TableItem newItem = new TableItem(fileLogsTable, SWT.NONE,i);
+
+ // get item
+ SWMTLogInfo log = fileLogList.get(i);
+ String fileName = log.getPath();
+ String fileType = LOG_TYPE_DIRECTORY;
+
+ // Remove path if type is file
+ if( log.getType() == SWMTLogType.FILE ){
+ fileName = fileName.substring( fileName.lastIndexOf("\\") + 1 );
+ fileType = LOG_TYPE_FILE;
+ }
+
+ newItem.setText( new String[]{ fileName, fileType } );
+ }
+
+ }
+
+ /**
+ * Removed received logs.
+ */
+ private void removeReceivedLogs(){
+ // Delete all items in deviceLogList and deviceLogsTable
+ deviceLogList.clear();
+ deviceLogsTable.removeAll();
+
+ // Delete all temp files
+ MemSpyFileOperations.deleteTempMemSpyFiles();
+
+ // set cycle number to zero
+ cycleNumber = 0;
+
+ // reset missed logs value
+ missedLogs = false;
+
+ // enable and disable buttons
+ this.enableAndDisableDeviceButtonsAndSWMTCategoryGroup();
+ }
+
+ /**
+ * Gets list of log files that are in currently selected table.
+ * @return list of log files that are in currently selected table
+ */
+ public ArrayList<SWMTLogInfo> getLogList(){
+ if( fileRadioButton.getSelection() ){
+ return fileLogList;
+ }
+ else{
+ return deviceLogList;
+ }
+ }
+
+ /**
+ * Updates connection text to match used settings.
+ */
+ public void updateConnectionText(){
+ // Updating connection name.
+ String displayName = MemSpyPlugin.getTraceProvider().getDisplayNameForCurrentConnection();
+ connectionNameInUseLabel.setText(displayName);
+ loggingComposite.layout();
+ }
+
+ /**
+ * Loads previous values into UI components.
+ */
+ private void loadUserEnteredData(){
+
+ // if last value is not found, set selection file.
+ UserEnteredData data = new UserEnteredData();
+ int lastUsedSource = data.getPreviousRadioButtonSelection( ValueTypes.SWMT );
+
+ // Restoring previous state of radio buttons only if device import is also possible and was previously selected
+ if(MemSpyPlugin.isTraceProviderAvailable() && lastUsedSource == DEVICE_RADIO_BUTTON_SELECTION_INDEX){
+ deviceRadioButton.setSelection( true );
+ fileRadioButton.setSelection( false );
+ }
+ else{
+ deviceRadioButton.setSelection( false );
+ fileRadioButton.setSelection( true );
+ }
+
+ // Restore previous values to file combobox
+ String[] lastUsedFiles = data.getPreviousValues( ValueTypes.SWMT );
+ if (lastUsedFiles != null) {
+ timerCombo.setItems(lastUsedFiles);
+ timerCombo.select(0);
+ }
+
+ }
+
+ /**
+ * Saves user entered values and selections from UI components so that they can be restored later if needed.
+ */
+ public void saveUserEnteredData(){
+ UserEnteredData data = new UserEnteredData();
+
+ // Save Action radio-buttons state
+ if( deviceRadioButton.getSelection() ){
+ data.saveRadioButtonSelection(ValueTypes.SWMT, 2);
+ }
+ else {
+ data.saveRadioButtonSelection(ValueTypes.SWMT, 1);
+ }
+ data.saveValue(ValueTypes.SWMT, timerCombo.getText());
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see com.nokia.s60tools.memspy.ui.wizards.MemSpyTraceListener#deviceError(com.nokia.s60tools.memspy.ui.wizards.MemSpyTraceListener.LauncherErrorType)
+ */
+ public void deviceError( final LauncherErrorType error ){
+
+ Date date = new Date (System.currentTimeMillis());
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "SWMTLogPage.deviceError: '" + error.name() +"' time:'" +date.toString() + "'."); //$NON-NLS-1$ $NON-NLS-2$ $NON-NLS-3$
+
+ // Set MemSpy's state correct
+ memSpyOperationRunning = false;
+ memSpyTimerRunning = false;
+
+ // change Cancel text from wizard back to "Cancel"
+ this.setCancelText( "Cancel" );
+
+ // Getting user visible error message
+ errorMessage = UiUtils.getErrorMessageForLauncherError(error, traceEngine.getAdditionalErrorInformation(), traceEngine.getProgressStatus()); //$NON-NLS-1$
+
+ // Handling SWMT-specific logic related to the error
+ switch (error){
+ case DUMPED_TRACES:{
+ this.receivedLog = null;
+ break;
+ }
+ case CATEGORIES_NOT_SUPPORTED:{
+ disableSWMTCategoryFeature();
+ break;
+ }
+ }
+
+ // Add reset info into error message.
+ if(error != LauncherErrorType.CATEGORIES_NOT_SUPPORTED){
+ errorMessage = errorMessage + ERROR_SWMT_NEEDS_RESET;
+ }
+
+ // Set missedLogs value to true so that logs cannot be requested anymore because of missed logs.
+ missedLogs = true;
+
+ // Advising user to install launcher component to the device
+ UiUtils.showErrorDialogToUser(error, errorMessage, traceEngine.getProgressStatus());
+ }
+
+ /**
+ * Disables SWMT category feature for the rest of the session in case is was not supported by the device.
+ */
+ private void disableSWMTCategoryFeature() {
+ Runnable disableRunnable = new Runnable(){
+
+ public void run() {
+ try {
+ MemSpyPlugin.getDefault().setSWMTCategorySettingFeatureEnabled(false);
+ MemSpyPreferences.setProfileTrackedCategoriesSelected(true);
+ categoryGroupComposite.disableCustomCategorySelection();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ };
+
+ Display.getDefault().asyncExec(disableRunnable);
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see com.nokia.s60tools.memspy.ui.wizards.MemSpyTraceListener#operationFinished(com.nokia.s60tools.memspy.ui.wizards.MemSpyTraceListener.LauncherAction)
+ */
+ public void operationFinished(LauncherAction action) {
+
+ // reset missed logs.
+ missedLogs = false;
+
+ if( action == LauncherAction.SWMT_UPDATE ){
+ cycleNumber++;
+ this.updateReceivedSWMTLog( false );
+ }
+
+ }
+
+ /**
+ * Does actions that are made when SWMT log is received.
+ */
+ private void updateReceivedSWMTLog( final boolean timerRunning ){
+
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "SWMTLogPage.updateReceivedSWMTLog/timerRunning=" + timerRunning ); //$NON-NLS-1$
+
+ Runnable updateUiRunnable = new Runnable(){
+ public void run(){
+
+ // get date formatter
+ SimpleDateFormat formatter = new SimpleDateFormat ( MemSpyFileOperations.DATEFORMAT );
+ String date = formatter.format(receivedLog.getDate() );
+ // get files name
+ String path = receivedLog.getPath().substring( receivedLog.getPath().lastIndexOf("\\") + 1 );
+
+ // add log into table
+ TableItem item = new TableItem( deviceLogsTable, SWT.NONE, deviceLogsTable.getItemCount() );
+ item.setText( new String[]{ path, date });
+
+ // add receivedlog-object into deviceLogsList-Arraylist
+ deviceLogList.add( receivedLog );
+
+ if( timerRunning ){
+ // show progress bar
+ memSpyTimerRunning = true;
+ memSpyOperationRunning = false;
+
+ }
+ else{
+
+ // change Cancel text from wizard back to "Cancel"
+ setCancelText("Cancel");
+
+ // Set state correct
+ memSpyOperationRunning = false;
+
+ }
+ }
+
+ };
+ Display.getDefault().asyncExec(updateUiRunnable);
+ }
+
+ /**
+ * Enables and disables device buttons and SWMT category group UI according to current situation
+ */
+ private void enableAndDisableDeviceButtonsAndSWMTCategoryGroup(){
+
+ // Refreshes enable/disable status for SWMT category group UI
+ categoryGroupComposite.refresh();
+
+ // if log table is not empty, enable remove all button.
+ if( this.deviceLogsTable.getItemCount() > 0 ){
+ this.connectionSettingsButton.setEnabled(false);
+ this.removeReceivedLogsButton.setEnabled(true);
+ this.categoryGroupComposite.setButtonsEnabled(false);
+ this.categoryGroupComposite.setEnabled(false);
+ if( this.missedLogs ){
+ this.getLogNowButton.setEnabled(false);
+ this.startTimerButton.setEnabled(false);
+ }
+ }
+ else{
+ this.connectionSettingsButton.setEnabled(true);
+ this.removeReceivedLogsButton.setEnabled(false);
+ this.categoryGroupComposite.setButtonsEnabled(true);
+ this.categoryGroupComposite.setEnabled(true);
+ if( !this.missedLogs ){
+ this.getLogNowButton.setEnabled(true);
+ this.startTimerButton.setEnabled(true);
+ }
+ }
+ }
+
+ /**
+ * Enables and disables file buttons according to current situation.
+ */
+ private void enableAndDisableFileButtons(){
+
+ // If one log is selected, enable Remove button, otherwise disable it
+ if( this.fileLogsTable.getSelectionCount() == 1 ){
+ this.removeOneButton.setEnabled(true);
+ }
+ else{
+ this.removeOneButton.setEnabled(false);
+ }
+
+ // if log table is not empty, enable remove all button.
+ if( this.fileLogsTable.getItemCount() > 0 ){
+ this.removeAllButton.setEnabled(true);
+ }
+ else{
+ this.removeAllButton.setEnabled(false);
+ }
+
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.jface.wizard.WizardPage#canFlipToNextPage()
+ */
+ public boolean canFlipToNextPage() {
+ return false;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.jface.dialogs.IDialogPage#createControl(org.eclipse.swt.widgets.Composite)
+ */
+ public void createControl(Composite parent) {
+
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION, this.getClass().getSimpleName() + ": createControl()"); //$NON-NLS-1$
+
+ // Radio button group
+ Composite composite = new Composite(parent, SWT.NULL);
+
+ // create the desired layout for this wizard page
+ GridLayout gl = new GridLayout();
+ gl.numColumns = 1;
+ composite.setLayout(gl);
+
+ //Create group where to select if import from File System / From Device
+ createRadioButtonGroup(composite);
+
+ //Create group where import logs from File
+ createImportFromFileGroup(composite);
+
+ //Create group where import logs from Device
+ createImportFromDeviceGroup(composite);
+
+
+ // load saved user entered data.
+ this.loadUserEnteredData();
+
+ // update buttons and texts on screen.
+ this.updateConnectionText();
+
+ // Enable/disable buttons
+ this.enableAndDisableDeviceButtonsAndSWMTCategoryGroup(); //will call also #enableOrDisableHeapFilterText();
+ this.enableAndDisableFileButtons();
+
+ this.hideAndRevealItems();
+
+ // Setting context-sensitive help ID
+ PlatformUI.getWorkbench().getHelpSystem().setHelp( composite, HelpContextIDs.MEMSPY_IMPORT_SWMT);
+
+ setInitialFocus();
+ setControl(composite);
+ }
+
+ private void createImportFromDeviceGroup(Composite parent) {
+ // Device group
+
+ deviceGroup = new Group(parent, SWT.NONE);
+ GridLayout deviceGridLayout = new GridLayout();
+ deviceGridLayout.numColumns = 2;
+
+ deviceGridData = new GridData(GridData.FILL_BOTH);
+ deviceGroup.setLayoutData(deviceGridData);
+ deviceGroup.setLayout(deviceGridLayout);
+ deviceGroup.setText(GET_LOG_FROM_DEVICE_RADIO_BUTTON);
+
+
+
+ // Logs from device table
+
+ deviceLogsTable = new Table(deviceGroup, SWT.BORDER);
+ GridData tableGridData = new GridData(GridData.FILL_BOTH);
+ deviceLogsTable.setLayoutData(tableGridData);
+
+ TableColumn logsColumn = new TableColumn(deviceLogsTable, SWT.LEFT);
+ logsColumn.setText(LOGS);
+ logsColumn.setWidth(300);
+
+ TableColumn receivedColumn = new TableColumn(deviceLogsTable, SWT.LEFT);
+ receivedColumn.setText(RECEIVED);
+ receivedColumn.setWidth(110);
+
+ GridData deviceLogsTableGridData = new GridData(GridData.FILL_BOTH);
+ deviceLogsTable.setLayoutData(deviceLogsTableGridData);
+ deviceLogsTable.setHeaderVisible(true);
+ deviceLogsTable.addSelectionListener(this);
+
+
+ //
+ //Create logging composite, contains Get log now, Get log with timer and remove logs functions
+ //
+ createLoggingComposite(deviceGroup);
+
+ //
+ //Bottom composite where settings and categories are located
+ //
+ Composite bottomComposite = new Composite(deviceGroup,SWT.NONE);
+ GridLayout pgl = new GridLayout(2, false);
+ pgl.marginHeight = 0;
+ pgl.marginWidth = 0;
+ GridData pgd = new GridData(GridData.VERTICAL_ALIGN_END | GridData.FILL_HORIZONTAL);
+ bottomComposite.setLayout(pgl);
+ bottomComposite.setLayoutData(pgd);
+
+ //
+ //Create Connection settings group
+ //
+ createConnectionSettingsGroup(bottomComposite);
+
+ //
+ // Create and add SWMT category setting group
+ //
+ categoryGroupComposite = new SWMTCategoryGroupComposite(bottomComposite, false, this, MemSpyPlugin.getDefault().isSWMTCategorySettingFeatureEnabled());
+
+ }
+
+ private void createLoggingComposite(Composite parent) {
+
+ loggingComposite = new Composite(parent, SWT.NONE);
+ GridLayout deviceButtonLayout = new GridLayout();
+ GridData deviceButtonGridData = new GridData(SWT.FILL, SWT.FILL, true, true);//GridData.FILL_BOTH | GridData.VERTICAL_ALIGN_CENTER
+ deviceButtonLayout.numColumns = 1;
+ loggingComposite.setLayoutData(deviceButtonGridData);
+ loggingComposite.setLayout(deviceButtonLayout);
+
+ //
+ // Get Log now button
+ //
+ Composite getLogComposite = new Composite(loggingComposite, SWT.NONE);
+ GridLayout getLogLayout = new GridLayout();
+ GridData getLogGD = new GridData(SWT.FILL, SWT.BEGINNING, true, false);
+ getLogComposite.setLayoutData(getLogGD);
+ getLogComposite.setLayout(getLogLayout);
+
+ //Null label is added with no text to align get log now
+ @SuppressWarnings("unused")
+ Label nullLabel = new Label(getLogComposite,SWT.NULL);
+
+ getLogNowButton = new Button(getLogComposite, SWT.PUSH);
+ getLogNowButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL ));//| GridData.VERTICAL_ALIGN_BEGINNING
+ getLogNowButton.setText(GET_LOG_NOW_BUTTON);
+ getLogNowButton.addSelectionListener(this);
+
+ //
+ // Timer composite
+ //
+ Composite timerComposite = new Composite(loggingComposite, SWT.NONE);
+ GridLayout timerLayout = new GridLayout();
+ timerLayout.marginWidth = 0;
+ GridData timerGD = new GridData(SWT.FILL, SWT.CENTER, true, true);
+ timerComposite.setLayoutData(timerGD);
+ timerComposite.setLayout(timerLayout);
+
+ createTimerComposite(timerComposite);
+
+ //
+ // Remove all files button
+ //
+ Composite removeComposite = new Composite(loggingComposite, SWT.NONE);
+ GridLayout removeLayout = new GridLayout();
+ GridData removeGD = new GridData(SWT.FILL, SWT.BOTTOM, true, false);
+ removeComposite.setLayoutData(removeGD);
+ removeComposite.setLayout(removeLayout);
+
+ removeReceivedLogsButton = new Button(removeComposite, SWT.PUSH);
+ removeReceivedLogsButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));//| GridData.VERTICAL_ALIGN_END
+ removeReceivedLogsButton.setText(REMOVE_ALL);
+ removeReceivedLogsButton.addSelectionListener(this);
+ }
+
+ private void createConnectionSettingsGroup(Composite parent) {
+ Group connectionSettingsGroup = new Group(parent, SWT.NONE);
+ connectionSettingsGroup.setText("Connection");
+ GridLayout connectionGroupLayout = new GridLayout();
+ connectionGroupLayout.numColumns = 1;
+ connectionSettingsGroup.setLayout(connectionGroupLayout);
+ GridData connectionGridData = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
+ connectionSettingsGroup.setLayoutData(connectionGridData);
+
+
+ connectionSettingsButton = new Button(connectionSettingsGroup, SWT.PUSH);
+ connectionSettingsButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ connectionSettingsButton.setText(CONNECTION_SETTINGS_BUTTON);
+ connectionSettingsButton.addSelectionListener(this);
+
+ // Connection settings labels
+ Label connectionTextLabel = new Label(connectionSettingsGroup, SWT.LEFT);
+ connectionTextLabel.setText(CURRENTLY_USING_TEXT);
+ connectionTextLabel.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_CENTER));
+
+ connectionNameInUseLabel = new Label(connectionSettingsGroup, SWT.LEFT);
+ connectionNameInUseLabel.setLayoutData( new GridData(GridData.HORIZONTAL_ALIGN_CENTER) );
+ }
+
+ private void createImportFromFileGroup(Composite parent) {
+ // File selection group
+
+ fileSelectionGroup = new Group(parent, SWT.NONE);
+ GridLayout fileSelectionGridLayout = new GridLayout();
+ fileSelectionGridLayout.numColumns = 2;
+
+ fileSelectionGridData = new GridData(GridData.FILL_BOTH);
+ fileSelectionGroup.setLayoutData(fileSelectionGridData);
+ fileSelectionGroup.setLayout(fileSelectionGridLayout);
+ fileSelectionGroup.setText(GET_FROM_FROM_FILE_RADIO_BUTTON);
+
+ // Logs from file table
+
+ fileLogsTable = new Table(fileSelectionGroup, SWT.BORDER);
+ TableColumn fileColumn = new TableColumn(fileLogsTable, SWT.LEFT);
+ fileColumn.setText(LOG_FILES);
+ fileColumn.setWidth(300);
+
+ TableColumn nameColumn = new TableColumn(fileLogsTable, SWT.LEFT);
+ nameColumn.setText(LOG_TYPE);
+ nameColumn.setWidth(100);
+
+ GridData fileLogsTableGridData = new GridData(GridData.FILL_BOTH);
+ fileLogsTable.setLayoutData(fileLogsTableGridData);
+ fileLogsTable.setHeaderVisible(true);
+ fileLogsTable.addSelectionListener(this);
+
+ // File Selection button composite. Contains file operation buttons
+
+ fileSelectionButtonComposite = new Composite(fileSelectionGroup, SWT.NONE);
+ GridLayout threadButtonLayout = new GridLayout();
+ GridData fileSelectionButtonGridData = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
+ fileSelectionButtonComposite.setLayoutData(fileSelectionButtonGridData);
+ fileSelectionButtonComposite.setLayout(threadButtonLayout);
+ threadButtonLayout.numColumns = 1;
+
+ // Add file button
+ addFileButton = new Button(fileSelectionButtonComposite, SWT.PUSH);
+ addFileButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ addFileButton.setText(ADD_FILE);
+ addFileButton.addSelectionListener(this);
+
+ // Add folder button
+ addDirectoryButton = new Button(fileSelectionButtonComposite, SWT.PUSH);
+ addDirectoryButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ addDirectoryButton.setText(ADD_DIRECTORY);
+ addDirectoryButton.addSelectionListener(this);
+
+ // Remove one file button
+ removeOneButton = new Button(fileSelectionButtonComposite, SWT.PUSH);
+ removeOneButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ removeOneButton.setText(REMOVE_ONE);
+ removeOneButton.addSelectionListener(this);
+
+ // Remove all files and folders button
+ removeAllButton = new Button(fileSelectionButtonComposite, SWT.PUSH);
+ removeAllButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ removeAllButton.setText(REMOVE_ALL);
+ removeAllButton.addSelectionListener(this);
+ }
+
+ private void createRadioButtonGroup(Composite parent) {
+ // Radio button group
+ GridLayout radioButtonGroupGridLayout = new GridLayout();
+ radioButtonGroup = new Group(parent, SWT.NONE);
+ radioButtonGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ radioButtonGroup.setText(GET_LOG_FROM_RADIO_BUTTON);
+ radioButtonGroup.setLayout(radioButtonGroupGridLayout);
+ GridData radioButtonGridData = new GridData(GridData.FILL_HORIZONTAL);
+ radioButtonGridData.horizontalSpan = 2;
+
+ // File radio button
+ fileRadioButton = new Button(radioButtonGroup, SWT.RADIO);
+ fileRadioButton.setText(GET_FROM_FROM_FILE_RADIO_BUTTON);
+ fileRadioButton.setLayoutData(radioButtonGridData);
+ fileRadioButton.addSelectionListener(this);
+ fileRadioButton.setSelection(true);
+
+ // From Device via TraceViewer radio button
+ deviceRadioButton = new Button(radioButtonGroup, SWT.RADIO);
+ deviceRadioButton.setText(GET_LOG_FROM_DEVICE_RADIO_BUTTON);
+ deviceRadioButton.setLayoutData(radioButtonGridData);
+ deviceRadioButton.addSelectionListener(this);
+ deviceRadioButton.setSelection(false);
+
+ // In case trace plugin is not available, disabling import from device selection
+ if(!MemSpyPlugin.isTraceProviderAvailable()){
+ deviceRadioButton.setEnabled(false);
+ }
+ }
+
+ private void createTimerComposite(Composite parent) {
+ // Timer UI-components
+
+ Group timerComposite = new Group(parent, SWT.NONE);
+ timerComposite.setText(TEXT_GET_LOG_WITH_TIMER);
+
+ GridLayout timerLayout = new GridLayout();
+ timerLayout.numColumns = 2;
+ GridData timerGd = new GridData(SWT.FILL, SWT.CENTER, true, true);;
+ timerComposite.setLayoutData( timerGd );
+ timerComposite.setLayout( timerLayout );
+
+
+ // Interval- label
+ intervalLabel = new Label( timerComposite, SWT.LEFT );
+ intervalLabel.setText( TEXT_INTERVAL );
+ GridData intervalGd = new GridData();
+ intervalGd.horizontalSpan = 2;
+ intervalLabel.setLayoutData( intervalGd );
+
+ // Timer combo box
+ timerCombo = new Combo( timerComposite, SWT.BORDER);
+ GridData timerComboGridData = new GridData(GridData.HORIZONTAL_ALIGN_CENTER);
+ timerComboGridData.widthHint = 25;
+ timerCombo.setLayoutData( timerComboGridData );
+ timerCombo.setTextLimit(3);
+
+ // Interval- label
+ secondLabel = new Label( timerComposite, SWT.LEFT );
+ secondLabel.setText( TEXT_SECOND );
+ GridData secondLabelLayoutData = new GridData(GridData.HORIZONTAL_ALIGN_CENTER);
+ secondLabel.setLayoutData( secondLabelLayoutData );
+
+ // Start timer - button
+ startTimerButton = new Button(timerComposite, SWT.PUSH);
+ GridData startTimerGridData = new GridData( GridData.FILL_HORIZONTAL );
+ startTimerGridData.horizontalSpan = 2;
+ startTimerButton.setLayoutData( startTimerGridData );
+ startTimerButton.setText( START_TIMER );
+ startTimerButton.addSelectionListener(this);
+
+
+ }
+
+
+ /**
+ * Checks if device radio buttons is selected.
+ * @return <code>true</code> if device radio button is selected, otherwise <code>false</code>.
+ */
+ public boolean isDeviceRadioButtonSelected(){
+ return deviceRadioButton.getSelection();
+ }
+
+ /**
+ * Updates connection settings.
+ */
+ public void updateConnectionSettings() {
+ this.updateConnectionText();
+ }
+
+
+ /**
+ * Gets timer interval from interval UI-component.
+ * If interval set to text box is not valid, method prints error message and returns value 0.
+ * @return current timer interval
+ */
+ private int getTimerInteval() {
+ boolean showError = false;
+
+ int integer = 0;
+ try{
+ integer = Integer.parseInt( timerCombo.getText() );
+ }
+ catch( NumberFormatException e ){
+ // show error message of interval is not integer.
+ showError = true;
+ }
+
+ if( integer <= 0 && showError == false ){
+ // show error message if integer is negative or zero.
+ showError = true;
+ }
+
+ if( showError ){
+ // open error dialog and print error message
+ Status status = new Status(IStatus.ERROR, MemSpyPlugin.PLUGIN_ID, 0, ERROR_INTERVAL, null);
+ ErrorDialog.openError(Display.getCurrent().getActiveShell(),"MemSpy Error", null, status);
+ return 0;
+ }
+
+ return integer;
+
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see com.nokia.s60tools.memspy.ui.wizards.MemSpyTraceListener#operationFinished(com.nokia.s60tools.memspy.ui.wizards.MemSpyTraceListener.LauncherAction, com.nokia.s60tools.memspy.containers.SWMTLogInfo)
+ */
+ public void operationFinished(LauncherAction action, SWMTLogInfo swmtLogInfo, boolean timerRunning) {
+ if( action == LauncherAction.TIMED_SWMT_UPDATE ){
+
+ // update received log to table
+ this.receivedLog = swmtLogInfo;
+ this.updateReceivedSWMTLog( timerRunning );
+
+ // increase cycle number
+ cycleNumber++;
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see com.nokia.s60tools.memspy.ui.wizards.MemSpyTraceListener#startedReceivingSWMTLog()
+ */
+ public void startedReceivingSWMTLog() {
+
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "SWMTLogPage.startedReceivingSWMTLog"); //$NON-NLS-1$
+
+ // Set MemSpy's state correct
+ this.memSpyOperationRunning = true;
+ this.memSpyTimerRunning = false;
+ }
+
+ /**
+ * Method that is called when "Get Log Now" - button is pressed.
+ */
+ private void getLogNowPressed(){
+
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "SWMTLogPage.getLogNowPressed"); //$NON-NLS-1$
+
+ // if cycle number is zero(this is first log file in list), MemSpy's SWMT-logging needs to be reseted.
+ boolean reset = false;
+ if( deviceLogsTable.getItemCount() == 0 ){
+ reset = true;
+ cycleNumber = 1;
+ }
+
+ //Check if S60 application is ment to reset between cycles
+ boolean isToBeClosedBetweenCycles = MemSpyPreferences.isCloseSymbianAgentBetweenCyclesSelected() && !MemSpyPreferences.isProfileTrackedCategoriesSelected();
+ if(isToBeClosedBetweenCycles){
+ reset = true;
+ }
+
+ // Create new SWMTLogInfo object
+ receivedLog = new SWMTLogInfo();
+
+ // get temp file name for swmt-log
+ Date date = new Date();
+ receivedLog.setPath( MemSpyFileOperations.getTempFileNameForSWMTLog( cycleNumber, date ) );
+ receivedLog.setType( SWMTLogType.FILE );
+ receivedLog.setDate(date);
+ receivedLog.setType(SWMTLogType.DEVICE);
+
+ if( traceEngine.requestSWMTLog( this, receivedLog.getPath(), reset) ){
+
+ try {
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "SWMTLogPage.getLogNowPressed/getContainer().run/receiveSWMTLogProcess"); //$NON-NLS-1$
+ getContainer().run(true, false, receiveSWMTLogProcess);
+ } catch (InvocationTargetException e1) {
+ // do nothing
+ e1.printStackTrace();
+ } catch (InterruptedException e1) {
+ // do nothing
+ e1.printStackTrace();
+ }
+ enableAndDisableDeviceButtonsAndSWMTCategoryGroup();
+ }
+ else{
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "SWMTLogPage.getLogNowPressed/openError"); //$NON-NLS-1$
+ MessageDialog.openError( this.getShell(), ERROR_MEMSPY, ERROR_CONNECTION);
+ receivedLog = null;
+ }
+ }
+
+
+ /**
+ * Method that is called when "Start Timer" - button is pressed.
+ */
+ private void getLogWithTimerPressed(){
+
+ int interval = this.getTimerInteval();
+
+ // if interval is not zero continue
+ if( interval != 0 ){
+
+ // if cycle number is zero(this is first log file in list), MemSpy's SWMT-logging needs to be reseted.
+ boolean reset = false;
+ if( deviceLogsTable.getItemCount() == 0 ){
+ reset = true;
+ cycleNumber = 1;
+ }
+
+ boolean isToBeClosedBetweenCycles = MemSpyPreferences.isCloseSymbianAgentBetweenCyclesSelected() && !MemSpyPreferences.isProfileTrackedCategoriesSelected();
+
+ // if connect to trace source was established
+ if( traceEngine.startSWMTTimer(this, cycleNumber, reset, isToBeClosedBetweenCycles, interval) ){
+
+ // change Cancel text from wizard to "Stop Timer"
+ setCancelText("Stop Timer");
+
+ // launch receiveSWMTLog process.
+ try {
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "SWMTLogPage.getLogWithTimerPressed/getContainer().run/receiveSWMTLogProcess"); //$NON-NLS-1$
+ getContainer().run(true, true, receiveSWMTLogProcess);
+ } catch (InvocationTargetException e1) {
+ // do nothing
+ e1.printStackTrace();
+ } catch (InterruptedException e1) {
+ // do nothing
+ e1.printStackTrace();
+ }
+
+ // Enable/Disable device buttons.
+ enableAndDisableDeviceButtonsAndSWMTCategoryGroup();
+
+ }
+ else{
+ // increase cycle number
+ cycleNumber++;
+
+ // show error message
+ MessageDialog.openError( this.getShell(), ERROR_MEMSPY, ERROR_CONNECTION);
+
+ }
+ }
+ }
+
+ /**
+ * Method that is called when stop timer-button is pressed.
+ */
+ private void stopTimerPressed(){
+
+ this.memSpyTimerRunning = false;
+ if( traceEngine.stopSWMTTimer() ){
+ // if timer is stopped immediately, hide progress bar
+ memSpyStopping = false;
+
+ this.setCancelText("Cancel");
+ }
+ }
+
+ /**
+ * Created needed MemSpy processes.
+ */
+ private void createMemSpyProcesses(){
+
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "SWMTLogPage.createMemSpyProcesses/receiveSWMTLogProcess"); //$NON-NLS-1$
+
+ // receive SWMT-Log process
+ receiveSWMTLogProcess = new IRunnableWithProgress() {
+ /**
+ * In receive SWMT-Log process process views progress bar and checks every 0,5 seconds
+ * if current MemSpy process has been finished. After MemSpy process has finished. Progress
+ * bar is hidden.
+ */
+ public void run(IProgressMonitor monitor) {
+ memSpyOperationRunning = true;
+
+ monitor.beginTask(RECEIVING_SWMT_LOG, IProgressMonitor.UNKNOWN);
+ while(true){
+ // some delay, so that launcher has time to set it's state correct.
+ try {
+ Thread.sleep(500);
+ } catch (InterruptedException e) {
+ // do nothing
+ }
+
+ // If no operations are on-going, break
+ if( !memSpyOperationRunning && !memSpyTimerRunning && !memSpyStopping ){
+ break;
+ }
+
+ // If Cancel-message received, send stop request.
+ if( monitor.isCanceled() ){
+ monitor.beginTask(STOPPING_TIMER, IProgressMonitor.UNKNOWN);
+ stopTimerPressed();
+ }
+
+ // If timer and operation are running, show "Waiting for timer to expire"-text
+ else if ( memSpyTimerRunning ){
+ monitor.beginTask(WAITING_FOR_TIMER, IProgressMonitor.UNKNOWN);
+ }
+
+ // If MemSpy operation is running, show "Requesting Heap Dump" -text
+ else if( memSpyOperationRunning ){
+ monitor.beginTask(RECEIVING_SWMT_LOG, IProgressMonitor.UNKNOWN);
+ }
+ }
+ monitor.done();
+ }
+ };
+ }
+
+ /**
+ * Changes wizard's cancel button's text.
+ * @param newText new text for button
+ */
+ private void setCancelText( final String newText ){
+ Runnable updateUiRunnable = new Runnable(){
+ public void run(){
+ // change Cancel text from wizard back to "Cancel"
+ ( (MemSpyWizard)getWizard() ).setCancelText( newText );
+ }
+ };
+ // needs to be done on UI thread.
+ Display.getDefault().asyncExec(updateUiRunnable);
+ }
+
+ /* (non-Javadoc)
+ * @see com.nokia.s60tools.memspy.ui.wizards.SWMTCategoryGroupComposite.SWMTCategorySelectionChangeListener#categorySelectionChanged(int)
+ */
+ public void setCategorySelection(int newCategorySelection, boolean isProfileSettings) {
+ traceEngine.setCategoriesForSWMT(newCategorySelection, isProfileSettings);
+ }
+
+ /* (non-Javadoc)
+ * @see com.nokia.s60tools.memspy.ui.wizards.SWMTCategorySelectionMediator#getCategorySelection()
+ */
+ public int getCategorySelection() {
+ return traceEngine.getCategoriesForSWMT();
+ }
+
+ /* (non-Javadoc)
+ * @see com.nokia.s60tools.memspy.ui.wizards.SWMTCategorySelectionMediator#setAllTrackedCategoriesSelected(boolean)
+ */
+ public void setProfileTrackedCategoriesSelected(
+ boolean isAllCategoriesSelected) {
+ traceEngine.setProfileTrackedCategoriesSelected(isAllCategoriesSelected);
+ }
+
+ /* (non-Javadoc)
+ * @see com.nokia.s60tools.memspy.ui.wizards.SWMTCategorySelectionMediator#getAllTrackedCategoriesSelected()
+ */
+ public boolean isProfileTrackedCategoriesSelected() {
+ return traceEngine.isProfileTrackedCategoriesSelected();
+ }
+
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.dialogs.DialogPage#dispose()
+ */
+ public void dispose(){
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION, this.getClass().getSimpleName() + ": dispose()"); //$NON-NLS-1$
+ categoryGroupComposite.dispose();
+ super.dispose();
+ }
+
+
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/ui/wizards/SelectActionPage.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,172 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+
+package com.nokia.s60tools.memspy.ui.wizards;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.ui.PlatformUI;
+
+import com.nokia.s60tools.memspy.model.UserEnteredData;
+import com.nokia.s60tools.memspy.model.UserEnteredData.ValueTypes;
+import com.nokia.s60tools.memspy.resources.HelpContextIDs;
+import com.nokia.s60tools.ui.wizards.S60ToolsWizardPage;
+
+public class SelectActionPage extends S60ToolsWizardPage{
+
+ // Available actions
+ public enum MemSpyAction{IMPORT_HEAP, COMPARE_HEAPS, SWMT}
+
+ // UI components
+ public Button importHeapRadioButton;
+ public Button compareTwoHeapsRadioButton;
+ public Button swmtRadioButton;
+
+ /*
+ * (non-Javadoc)
+ * @see com.nokia.s60tools.ui.wizards.S60ToolsWizardPage#setInitialFocus()
+ */
+ public void setInitialFocus() {
+ }
+
+ public void recalculateButtonStates() {
+ }
+
+
+ protected SelectActionPage(String pageName) {
+ super(pageName);
+ setTitle("MemSpy Import Wizard, First step");
+ setDescription("Select action you wish to perform with MemSpy.");
+ }
+ public void createControl(Composite parent) {
+ // Radio button group
+
+ Composite composite = new Composite(parent, SWT.NULL);
+
+ // create the desired layout for this wizard page
+ GridLayout gl = new GridLayout();
+ gl.numColumns = 1;
+ composite.setLayout(gl);
+
+ // Radio Button Group
+ GridLayout radioButtonGroupGridLayout = new GridLayout();
+ Group radioButtonGroup = new Group (composite, SWT.NONE);
+ radioButtonGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ radioButtonGroup.setText("Select Action:");
+ radioButtonGroup.setLayout(radioButtonGroupGridLayout);
+ GridData radioButtonGridData = new GridData(GridData.FILL_HORIZONTAL);
+ radioButtonGridData.horizontalSpan = 2;
+
+ // Import Heap wizard radio button
+ importHeapRadioButton = new Button(radioButtonGroup, SWT.RADIO);
+ importHeapRadioButton.setText("Import heap and analyse log with Heap Analyser");
+ importHeapRadioButton.setLayoutData(radioButtonGridData);
+
+ // Compare Two Heaps radio button
+ compareTwoHeapsRadioButton = new Button(radioButtonGroup, SWT.RADIO);
+ compareTwoHeapsRadioButton.setText("Import heaps and compare logs with Heap Analyser");
+ compareTwoHeapsRadioButton.setLayoutData(radioButtonGridData);
+
+ // SWMT wizard radio button
+ swmtRadioButton = new Button(radioButtonGroup, SWT.RADIO);
+ swmtRadioButton.setText("Import System Wide Memory Tracking logs and analyse them with SWMT Analyser");
+ swmtRadioButton.setLayoutData(radioButtonGridData);
+
+ // restore previous value of radio button.
+ // if last value is not found, set selection to import heap
+
+ UserEnteredData data = new UserEnteredData();
+ int lastUsed = data.getPreviousRadioButtonSelection(ValueTypes.SELECT_ACTION);
+
+ if( lastUsed == 2 ){
+ compareTwoHeapsRadioButton.setSelection(true);
+ }
+ else if( lastUsed == 3 ){
+ swmtRadioButton.setSelection(true);
+ }
+ else {
+ importHeapRadioButton.setSelection(true);
+ }
+
+ setHelps();
+ setInitialFocus();
+ setControl(composite);
+ }
+
+ /**
+ * getAction
+ * @return currently selected action
+ */
+ public MemSpyAction getAction(){
+ if( importHeapRadioButton.getSelection() ){
+ return MemSpyAction.IMPORT_HEAP;
+ }
+ else if( compareTwoHeapsRadioButton.getSelection() ){
+ return MemSpyAction.COMPARE_HEAPS;
+ }
+ else{
+ return MemSpyAction.SWMT;
+ }
+
+ }
+
+
+ /**
+ * saves user entered data from UI components so that it can be restored later.
+ */
+ public void saveUserEnteredData(){
+ UserEnteredData data = new UserEnteredData();
+
+ // Save Action radio-buttons state
+ if( compareTwoHeapsRadioButton.getSelection() ){
+ data.saveRadioButtonSelection(ValueTypes.SELECT_ACTION, 2);
+ }
+ else if( swmtRadioButton.getSelection() ){
+ data.saveRadioButtonSelection(ValueTypes.SELECT_ACTION, 3);
+ }
+ else {
+ data.saveRadioButtonSelection(ValueTypes.SELECT_ACTION, 1);
+ }
+ }
+
+ /**
+ * canFlipPreviousPage
+ * returns always false because this is first page of wizard.
+ */
+ public boolean canFlipPreviousPage(){
+ return false;
+ }
+
+ /**
+ * Sets this page's context sensitive helps
+ *
+ */
+ protected void setHelps() {
+ PlatformUI.getWorkbench().getHelpSystem().setHelp( importHeapRadioButton, HelpContextIDs.MEMSPY_SELECT_ACTION);
+ PlatformUI.getWorkbench().getHelpSystem().setHelp( compareTwoHeapsRadioButton, HelpContextIDs.MEMSPY_SELECT_ACTION);
+ PlatformUI.getWorkbench().getHelpSystem().setHelp( swmtRadioButton, HelpContextIDs.MEMSPY_SELECT_ACTION);
+ PlatformUI.getWorkbench().getHelpSystem().setHelp( this.getShell(), HelpContextIDs.MEMSPY_SELECT_ACTION);
+
+ }
+
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/util/MemSpyConsole.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,68 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+package com.nokia.s60tools.memspy.util;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+
+import com.nokia.s60tools.memspy.resources.ImageKeys;
+import com.nokia.s60tools.memspy.resources.ImageResourceManager;
+import com.nokia.s60tools.util.console.AbstractProductSpecificConsole;
+
+/**
+ * Singleton class that offers console printing
+ * services for the MemSpy plug-in.
+ */
+public class MemSpyConsole extends AbstractProductSpecificConsole {
+
+ /**
+ * Singleton instance of the class.
+ */
+ static private MemSpyConsole instance = null;
+
+ /**
+ * Public accessor method.
+ * @return Singleton instance of the class.
+ */
+ static public MemSpyConsole getInstance(){
+ if(instance == null ){
+ instance = new MemSpyConsole();
+ }
+ return instance;
+ }
+
+ /**
+ * Private constructor forcing Singleton usage of the class.
+ */
+ private MemSpyConsole(){
+ }
+
+ /* (non-Javadoc)
+ * @see com.nokia.s60tools.util.console.AbstractProductSpecificConsole#getProductConsoleName()
+ */
+ protected String getProductConsoleName() {
+ return "MemSpy Console";
+ }
+
+ /* (non-Javadoc)
+ * @see com.nokia.s60tools.util.console.AbstractProductSpecificConsole#getProductConsoleImageDescriptor()
+ */
+ protected ImageDescriptor getProductConsoleImageDescriptor() {
+ return ImageResourceManager.getImageDescriptor(ImageKeys.IMG_APP_ICON);
+ }
+
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser.thirdpartysources/.classpath Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser.thirdpartysources/.settings/org.eclipse.jdt.core.prefs Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,8 @@
+#Tue Sep 22 14:04:29 EEST 2009
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser.thirdpartysources/META-INF/MANIFEST.MF Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,11 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Carbide.c++ Extensions - SWMT Analyser Thirdpartysources
+Bundle-SymbolicName: com.nokia.s60tools.swmtanalyser.thirdpartysources
+Bundle-Version: 1.6.0
+Bundle-Activator: com.nokia.s60tools.swmtanalyser.thirdpartysources.Activator
+Bundle-Vendor: Nokia
+Require-Bundle: org.eclipse.ui,
+ org.eclipse.core.runtime
+Bundle-ActivationPolicy: lazy
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser.thirdpartysources/about.html Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,22 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
+<html>
+<head>
+<title>About</title>
+<meta http-equiv=Content-Type content="text/html; charset=ISO-8859-1">
+</head>
+<body lang="EN-US">
+<h2>About This Content</h2>
+
+<p>Dec 11, 2009</p>
+
+<h3>Copyright</h3>
+
+<p>
+
+<p>Copyright © 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.<br>
+License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.</p>
+
+<p>
+
+</body>
+</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser.thirdpartysources/build.properties Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,22 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+#
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ iText-src-2.1.7.zip,\
+ about.html
Binary file sysperfana/memspyext/com.nokia.s60tools.swmtanalyser.thirdpartysources/iText-src-2.1.7.zip has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser.thirdpartysources/src/com/nokia/s60tools/swmtanalyser/thirdpartysources/Activator.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,68 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+package com.nokia.s60tools.swmtanalyser.thirdpartysources;
+
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.BundleContext;
+
+/**
+ * The activator class controls the plug-in life cycle
+ */
+public class Activator extends AbstractUIPlugin {
+
+ /**
+ * The plug-in ID for third party sources plugin
+ */
+ public static final String PLUGIN_ID = "com.nokia.s60tools.swmtanalyser.thirdpartysources";
+
+ // The shared instance
+ private static Activator plugin;
+
+ /**
+ * The constructor
+ */
+ public Activator() {
+ plugin = this;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
+ */
+ public void start(BundleContext context) throws Exception {
+ super.start(context);
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
+ */
+ public void stop(BundleContext context) throws Exception {
+ plugin = null;
+ super.stop(context);
+ }
+
+ /**
+ * Returns the shared instance
+ *
+ * @return the shared instance
+ */
+ public static Activator getDefault() {
+ return plugin;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/.classpath Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry exported="true" kind="lib" path="poi-3.2-FINAL-20081019.jar"/>
+ <classpathentry exported="true" kind="lib" path="poi-contrib-3.2-FINAL-20081019.jar"/>
+ <classpathentry exported="true" kind="lib" path="poi-scratchpad-3.2-FINAL-20081019.jar"/>
+ <classpathentry exported="true" kind="lib" path="iText-2.1.7.jar"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/.settings/org.eclipse.jdt.core.prefs Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,8 @@
+#Tue Sep 22 14:04:40 EEST 2009
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/META-INF/MANIFEST.MF Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,28 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Carbide.c++ Extensions - Swmt Analyser
+Bundle-SymbolicName: com.nokia.s60tools.swmtanalyser;singleton:=true
+Bundle-Version: 1.6.0
+Bundle-Activator: com.nokia.s60tools.swmtanalyser.SwmtAnalyserPlugin
+Bundle-Vendor: Nokia
+Require-Bundle: org.eclipse.ui,
+ org.eclipse.core.runtime,
+ org.eclipse.ui.forms,
+ com.nokia.s60tools.ui;bundle-version="1.5.0",
+ org.eclipse.core.filesystem,
+ org.eclipse.core.resources,
+ org.eclipse.ui.ide,
+ org.eclipse.ui.editors,
+ org.eclipse.draw2d,
+ com.nokia.s60tools.util;bundle-version="1.5.0"
+Bundle-ActivationPolicy: lazy
+Bundle-ClassPath: poi-3.2-FINAL-20081019.jar,
+ poi-contrib-3.2-FINAL-20081019.jar,
+ poi-scratchpad-3.2-FINAL-20081019.jar,
+ iText-2.1.7.jar,
+ .
+Export-Package: com.nokia.s60tools.swmtanalyser.data;x-friends:="com.nokia.s60tools.swmtanalyser.tests",
+ com.nokia.s60tools.swmtanalyser.exception;x-friends:="com.nokia.s60tools.swmtanalyser.tests",
+ com.nokia.s60tools.swmtanalyser.model;x-friends:="com.nokia.s60tools.swmtanalyser.tests",
+ com.nokia.s60tools.swmtanalyser.ui.actions
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/about.html Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,22 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
+<html>
+<head>
+<title>About</title>
+<meta http-equiv=Content-Type content="text/html; charset=ISO-8859-1">
+</head>
+<body lang="EN-US">
+<h2>About This Content</h2>
+
+<p>Dec 11, 2009</p>
+
+<h3>Copyright</h3>
+
+<p>
+
+<p>Copyright © 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.<br>
+License: <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.</p>
+
+<p>
+
+</body>
+</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/build.properties Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,13 @@
+javacSource=1.5
+javacTarget=1.5
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ plugin.xml,\
+ poi-3.2-FINAL-20081019.jar,\
+ poi-contrib-3.2-FINAL-20081019.jar,\
+ poi-scratchpad-3.2-FINAL-20081019.jar,\
+ icons/,\
+ iText-2.1.7.jar,\
+ about.html
Binary file sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/iText-2.1.7.jar has changed
Binary file sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/icons/Launch_SWMT.png has changed
Binary file sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/icons/green.png has changed
Binary file sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/icons/red.png has changed
Binary file sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/icons/yellow.png has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/plugin.xml Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.2"?>
+<plugin>
+ <extension
+ point="org.eclipse.ui.editors">
+ <editor
+ class="com.nokia.s60tools.swmtanalyser.editors.SWMTEditor"
+ default="false"
+ icon="icons/Launch_SWMT.png"
+ id="com.nokia.s60tools.swmtanalyser.editors.SWMTEditor"
+ name="SWMT Analyser"/>
+ </extension>
+</plugin>
Binary file sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/poi-3.2-FINAL-20081019.jar has changed
Binary file sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/poi-contrib-3.2-FINAL-20081019.jar has changed
Binary file sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/poi-scratchpad-3.2-FINAL-20081019.jar has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/SwmtAnalyserPlugin.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,155 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+package com.nokia.s60tools.swmtanalyser;
+
+import java.io.File;
+import java.net.URL;
+import java.util.ArrayList;
+
+import org.eclipse.core.runtime.FileLocator;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.BundleContext;
+
+import com.nokia.s60tools.swmtanalyser.analysers.IAnalyser;
+import com.nokia.s60tools.swmtanalyser.analysers.LinearAnalyser;
+import com.nokia.s60tools.swmtanalyser.analysers.ThreadDataAnalyser;
+import com.nokia.s60tools.util.console.IConsolePrintUtility;
+
+/**
+ * The activator class controls the plug-in life cycle
+ */
+public class SwmtAnalyserPlugin extends AbstractUIPlugin {
+
+ ArrayList<IAnalyser> Analysers = new ArrayList<IAnalyser>();
+
+ // The plug-in ID
+ public static final String PLUGIN_ID = "com.nokia.s60tools.swmtanalyser";
+
+ // The shared instance
+ private static SwmtAnalyserPlugin plugin;
+
+ private String pluginInstallPath = "";
+
+ /**
+ * Console for plug-in
+ */
+ private IConsolePrintUtility console;
+
+ /**
+ * The constructor
+ */
+ public SwmtAnalyserPlugin() {
+ plugin = this;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
+ */
+ public void start(BundleContext context) throws Exception {
+ super.start(context);
+ registerAnalyser(new LinearAnalyser());
+ registerAnalyser(new ThreadDataAnalyser());
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
+ */
+ public void stop(BundleContext context) throws Exception {
+ plugin = null;
+ super.stop(context);
+ }
+
+ /**
+ * Returns the shared instance
+ *
+ * @return the shared instance
+ */
+ public static SwmtAnalyserPlugin getDefault() {
+ return plugin;
+ }
+
+ /**
+ * Returns an image descriptor for the image file at the given
+ * plug-in relative path
+ *
+ * @param path the path
+ * @return the image descriptor
+ */
+ public static ImageDescriptor getImageDescriptor(String path) {
+ return imageDescriptorFromPlugin(PLUGIN_ID, path);
+ }
+
+ /**
+ * @param analyser will be registered for analysis. The tool invokes analysis
+ * on all registered analysers.
+ */
+ public void registerAnalyser(IAnalyser analyser)
+ {
+ if(!Analysers.contains(analyser))
+ Analysers.add(analyser);
+ }
+
+ public IAnalyser [] getRegisteredAnalysers()
+ {
+ return Analysers.toArray(new IAnalyser[0]);
+ }
+
+ public static String getPluginInstallPath() {
+ try {
+ if ("".equals(plugin.pluginInstallPath)) {
+ // URL to the plugin's root ("/")
+ URL relativeURL = plugin.getBundle().getEntry("/");
+ // Converting into local path
+ URL localURL = FileLocator.toFileURL(relativeURL);
+ // Getting install location in correct form
+ File f = new File(localURL.getPath());
+ plugin.pluginInstallPath = f.getAbsolutePath();
+ }
+ return plugin.pluginInstallPath;
+ } catch (Exception e) {
+ return "";
+ }
+ }
+
+ /**
+ * Set the IConsolePrintUtility for plug-in
+ * @param console
+ */
+ public void setConsole(IConsolePrintUtility console) {
+ this.console = console;
+ }
+
+ /**
+ * Get the console print utility
+ * @return console
+ */
+ public static IConsolePrintUtility getConsole(){
+ return getDefault().getConsolePrintUtility();
+ }
+
+ /**
+ * Get the console print utility
+ * @return console
+ */
+ private IConsolePrintUtility getConsolePrintUtility(){
+ return console;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/analysers/AnalyserConstants.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,48 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+package com.nokia.s60tools.swmtanalyser.analysers;
+
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.widgets.Display;
+
+/**
+ * Constants for general Analyser purposes
+ */
+public class AnalyserConstants {
+
+ /**
+ * Priority types
+ */
+ public static enum Priority {NEGLIGIBLE,NORMAL,HIGH,CRITICAL}
+ /**
+ * Delta types
+ */
+ public static enum DeltaType {SIZE, COUNT}
+ /**
+ * Color for Severity Normal
+ */
+ public static final Color COLOR_SEVERITY_NORMAL = new Color(Display.getCurrent(),121,255,121);//Green
+ /**
+ * Color for Severity High
+ */
+ public static final Color COLOR_SEVERITY_HIGH = new Color(Display.getCurrent(),255,255,138);//Yellow
+ /**
+ * Color for Severity Critical
+ */
+ public static final Color COLOR_SEVERITY_CRITICAL = new Color(Display.getCurrent(),254,106,99);//Red
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/analysers/IAnalyser.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,49 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+package com.nokia.s60tools.swmtanalyser.analysers;
+
+import com.nokia.s60tools.swmtanalyser.data.ParsedData;
+
+/**
+ *
+ * This Interface must be implemented by all swmt analysers
+ */
+public interface IAnalyser {
+
+
+ /**
+ * Analysis is started from this method. And all analysis results
+ * are added to a list.
+ *
+ * @param logData data objects of log file
+ */
+ public void analyse(ParsedData logData);
+
+
+ /**
+ * The method returns the array of issues.
+ * @return results
+ */
+ public Object [] getResults();
+
+ /**
+ * The method returns the array of children for a given issue.
+ * @param parent must be {@link ResultsParentNodes}
+ * @return childrens
+ */
+ public Object [] getChildren (Object parent);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/analysers/LinearAnalyser.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,537 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+package com.nokia.s60tools.swmtanalyser.analysers;
+
+import java.text.DecimalFormat;
+import java.util.ArrayList;
+
+import com.nokia.s60tools.swmtanalyser.data.DiskOverview;
+import com.nokia.s60tools.swmtanalyser.data.KernelElements;
+import com.nokia.s60tools.swmtanalyser.data.ParsedData;
+import com.nokia.s60tools.swmtanalyser.data.SystemData;
+import com.nokia.s60tools.swmtanalyser.model.SWMTLogReaderUtils;
+
+/**
+ *
+ * Defines Enum constants for all Kernel events to be analysed.
+ */
+enum KERNEL_EVENTS{
+ NO_OF_THREADS("Number of Threads"), NO_OF_PROCESSES("Number of Processes"),
+ NO_OF_TIMERS("Number of Timers"), NO_OF_SEMAPHORES("Number of Semaphores"),
+ NO_OF_SERVERS("Number of Servers"), NO_OF_MSGQUEUES("Number of Msg. Queues"),
+ NO_OF_SESSIONS("Number of Sessions"), NO_OF_CHUNKS("Number of Chunks");
+
+ private String event_name;
+ private String event_cateogory = "System Data";
+
+ private KERNEL_EVENTS(String eventName) {
+ this.event_name = eventName;
+ }
+
+ /**
+ * Returns event string
+ * @return name of the event
+ */
+ public String getEventName()
+ {
+ return event_name;
+ }
+
+ /**
+ * Returns event category
+ * @return category of the event
+ */
+ public String getEventCategory()
+ {
+ return event_cateogory;
+ }
+}
+
+/**
+ * Analyses RAM and DISK events and Kernal events. It implements interface IAnalyser.
+ *
+ */
+public class LinearAnalyser implements IAnalyser {
+
+ /**
+ * {@link #RAM_AND_DISK_TITLE} and {@link #KERNEL_ELEMS_TITLE} issues
+ */
+ ArrayList<ResultsParentNodes> allIssues = new ArrayList<ResultsParentNodes>();
+
+ protected static DecimalFormat Bytes_Format = new DecimalFormat("#####.##");
+ protected int [] time_intervals = null;
+
+ private static final String RAM_AND_DISK_TITLE = "RAM and Disk Memory";
+ private static final String KERNEL_ELEMS_TITLE = "Kernel Elements";
+
+ private ParsedData logData = null;
+
+
+ /* (non-Javadoc)
+ * @see com.nokia.s60tools.swmtanalyser.analysers.IAnalyser#analyse(com.nokia.s60tools.swmtanalyser.data.ParsedData)
+ */
+ public void analyse(ParsedData logData) {
+
+ this.logData = logData;
+ allIssues.clear();
+
+ //List to store RAM DISK issues
+ ArrayList<ResultElements> ram_disk_issues = new ArrayList<ResultElements>();
+
+ //Analyse RAM events using the logData and store the results in given list
+ analyseUsedRam(logData, ram_disk_issues);
+ //Analyse DISK events using the logData and store the results in given list
+ analyseDiskSizes(logData, ram_disk_issues);
+
+ //Create parent for all RAM and Disks issues.
+ ResultsParentNodes ram_and_disk_node = new ResultsParentNodes(RAM_AND_DISK_TITLE);
+ ram_and_disk_node.setChildren(ram_disk_issues);
+ allIssues.add(ram_and_disk_node);
+
+ //List to store Kernel issues
+ ArrayList<ResultElements> kernel_issues = new ArrayList<ResultElements>();
+ //Analyse Kernel events using the logData and store the results in given list
+ analyseKernelHandles(logData, kernel_issues);
+
+ //Create parent for all kernel issues found
+ ResultsParentNodes kernel_analysis_node = new ResultsParentNodes(KERNEL_ELEMS_TITLE);
+ kernel_analysis_node.setChildren(kernel_issues);
+ allIssues.add(kernel_analysis_node);
+ }
+
+
+ /* (non-Javadoc)
+ * @see com.nokia.s60tools.swmtanalyser.analysers.IAnalyser#getResults()
+ */
+ public Object[] getResults() {
+ return allIssues.toArray();
+ }
+
+
+ /* (non-Javadoc)
+ * @see com.nokia.s60tools.swmtanalyser.analysers.IAnalyser#getChildren(java.lang.Object)
+ */
+ public Object[] getChildren(Object parent)
+ {
+ if(parent instanceof ResultsParentNodes && allIssues.contains(parent))
+ {
+ return ((ResultsParentNodes)(parent)).getChildren();
+ }
+ else
+ return null;
+ }
+
+ /**
+ * This method linearly analyses the variation of used Ram size.
+ * @param logData signifies data of all seleced cycles.
+ * @param results signifies the list to which all issues will be added to.
+ */
+ private void analyseUsedRam(ParsedData logData, ArrayList<ResultElements> results)
+ {
+ SWMTLogReaderUtils utils = new SWMTLogReaderUtils();
+
+ ArrayList<SystemData> systemData = utils.getSystemDataFromAllCycles(logData);
+
+ //Store used memory values
+ long [] usedRamValues = new long[logData.getNumberOfCycles()];
+
+ //Calculate used memory using the total and free memroy
+ for(int i=0; i<logData.getNumberOfCycles(); i++)
+ {
+ long totalMem = systemData.get(i).getTotalMemory();
+ long freeMem = systemData.get(i).getFreeMemory();
+
+ if(totalMem == -1 || freeMem == -1){
+ usedRamValues[i] = 0;
+ }
+ else{
+ long usedMemory = totalMem - freeMem;
+ usedRamValues[i] = usedMemory;
+ }
+ }
+
+ //Get the delta value.
+ long usedMemChange = utils.calculateDeltaForGivenSet(usedRamValues);
+
+ ResultElements res_elem = new ResultElements("RAM", "RAM used", getFormattedBytes(usedMemChange), usedMemChange, AnalyserConstants.DeltaType.SIZE);
+ res_elem.setEventValues(usedRamValues);
+
+ calculateGrowinessAndPriority(usedRamValues, res_elem);
+
+ //Add if the element priority is CRITICAL or HIGH or NORMAL
+ if(res_elem.getPriority() != AnalyserConstants.Priority.NEGLIGIBLE)
+ results.add(res_elem);
+
+ }
+
+ /**
+ * This method linearly analyses the variation of used size for all disks.
+ * @param logData signifies data of all seleced cycles.
+ * @param results signifies the list to which all issues will be added to.
+ */
+ private void analyseDiskSizes(ParsedData logData, ArrayList<ResultElements> results)
+ {
+ SWMTLogReaderUtils utils = new SWMTLogReaderUtils();
+ ArrayList<String> diskNames = utils.getAllDiskNames(logData);
+ for(String disk:diskNames) {
+ ArrayList<DiskOverview> diskData = utils.getUsedMemoryAndSizesForDisk(disk, logData);
+
+ //Store used memory values
+ long [] diskUsedValues = new long[logData.getNumberOfCycles()];
+ for(int i=0; i<logData.getNumberOfCycles(); i++){
+ diskUsedValues[i] = diskData.get(i).getUsedSize();
+ }
+ long delta = utils.calculateDeltaForGivenSet(diskUsedValues);
+
+ ResultElements res_elem = new ResultElements(disk, "Disk used", getFormattedBytes(delta), delta, AnalyserConstants.DeltaType.SIZE);
+ res_elem.setEventValues(diskUsedValues);
+
+ calculateGrowinessAndPriority(diskUsedValues, res_elem);
+ //Add if the element priority is CRITICAL or HIGH or NORMAL
+ if(res_elem.getPriority() != AnalyserConstants.Priority.NEGLIGIBLE)
+ results.add(res_elem);
+ }
+ }
+
+ /**
+ * This method analyses variation of various kernel handles.
+ * @param logData signifies data of all seleced cycles.
+ * @param results signifies the list to which all issues will be added to.
+ */
+ private void analyseKernelHandles(ParsedData logData, ArrayList<ResultElements> results)
+ {
+ SWMTLogReaderUtils utils = new SWMTLogReaderUtils();
+ ArrayList<KernelElements> kernelElems = utils.getKerenelElemsFromAllCycles(logData);
+
+ for(KERNEL_EVENTS event: KERNEL_EVENTS.values()){
+ long [] event_values = new long[kernelElems.size()];
+ for(int i=0; i<kernelElems.size(); i++)
+ event_values[i] = getKernelEventValue(kernelElems.get(i),event);
+ long delta = utils.calculateDeltaForGivenSet(event_values);
+
+ ResultElements result_elem = new ResultElements(event.getEventName(), event.getEventCategory(), Long.toString(delta), delta, AnalyserConstants.DeltaType.COUNT);
+ result_elem.setEventValues(event_values);
+
+ calculateGrowinessAndPriority(event_values,result_elem);
+ //Add if the element priority is CRITICAL or HIGH or NORMAL
+ if(result_elem.getPriority() != AnalyserConstants.Priority.NEGLIGIBLE)
+ results.add(result_elem);
+ }
+ }
+
+ /**
+ *
+ * @param kernelData -- structure which holds info about all kernel handles in one cycle.
+ * @param event -- name of the kernel event whose value must be read from the structure.
+ * @return value of the event.
+ */
+ private long getKernelEventValue(KernelElements kernelData, KERNEL_EVENTS event)
+ {
+ long event_value = 0;
+
+ switch(event)
+ {
+ case NO_OF_PROCESSES:
+ event_value = kernelData.getNumberOfProcesses();
+ break;
+ case NO_OF_THREADS:
+ event_value = kernelData.getNumberOfThreads();
+ break;
+ case NO_OF_CHUNKS:
+ event_value = kernelData.getNumberOfChunks();
+ break;
+ case NO_OF_SEMAPHORES:
+ event_value = kernelData.getNumberOfSemaphores();
+ break;
+ case NO_OF_SERVERS:
+ event_value = kernelData.getNumberOfServers();
+ break;
+ case NO_OF_SESSIONS:
+ event_value = kernelData.getNumberOfSessions();
+ break;
+ case NO_OF_TIMERS:
+ event_value = kernelData.getNumberOfTimers();
+ break;
+ case NO_OF_MSGQUEUES:
+ event_value = kernelData.getNumberOfMsgQueues();
+ break;
+ }
+
+ return event_value;
+ }
+
+ /**
+ * The method calculates growiness factor based on given event
+ * values and given time intervals.
+ * @param values values of the event to be analysed
+ * @param time time intervals
+ * @return growiness factor.
+ */
+ private double calculateGrowiness(long [] values, int [] time)
+ {
+ if(values.length != time.length)
+ return 0;
+
+ long [] time_differences = new long[time.length];
+
+ for(int i=0; i<time.length; i++)
+ {
+ if(i == 0)
+ time_differences[i] = 0;
+ else
+ time_differences[i] = time[i] - time[i-1];
+ }
+ long [] normalizedRoCs = calculateNormalizedRoC(values);
+
+ double [] normalizedRocWithTime = new double [normalizedRoCs.length];
+
+ for(int i=0; i<normalizedRocWithTime.length; i++)
+ {
+ if(i == 0)
+ normalizedRocWithTime[i] = 0;
+ else
+ {
+ //Assuming time difference is greater than zero.
+
+ normalizedRocWithTime[i] = (double)(normalizedRoCs[i])/Math.log(time_differences[i]);
+ }
+ }
+
+ double [] overallNormalizedRoc = new double [normalizedRocWithTime.length];
+
+ overallNormalizedRoc[0] = 0;
+ double totalNormalizedRoc = 0.0;
+
+ for(int i=1; i < normalizedRocWithTime.length; i++)
+ {
+ if(normalizedRocWithTime[i] > 0)
+ overallNormalizedRoc[i] = overallNormalizedRoc[i-1] + normalizedRocWithTime[i];
+ else if(normalizedRocWithTime[i] < 0)
+ overallNormalizedRoc[i] = -Math.log(-normalizedRocWithTime[i])+ overallNormalizedRoc[i-1];
+ else
+ overallNormalizedRoc[i] = overallNormalizedRoc[i-1];
+ }
+
+ totalNormalizedRoc = overallNormalizedRoc[overallNormalizedRoc.length - 1];
+ int growth_index = calculateStableGrowth(values);
+ double growiness_factor = Math.exp(growth_index);
+
+ double log_of_first = 0;
+ double log_of_last = 0;
+
+ if(values[values.length -1] != 0)
+ log_of_last = Math.log(values[values.length -1]);
+
+ if(values[0] != 0)
+ log_of_first = Math.log(values[0]);
+
+ double log_diff = log_of_last - log_of_first;
+
+ double tmp = Math.round(Math.exp(totalNormalizedRoc));
+ double final_growth_factor = tmp * log_diff + growiness_factor;
+
+ return final_growth_factor;
+ }
+
+ protected long [] calculateNormalizedRoC(long [] values)
+ {
+ long [] deltas = new long[values.length];
+ long [] valueVsBaseline = new long[values.length];
+
+ deltas[0] = 0;
+ valueVsBaseline[0] = 0;
+
+ for(int i=1; i<values.length; i++)
+ {
+ deltas[i] = values[i] - values[i-1];
+ valueVsBaseline[i] = values[i] - values[0];
+ }
+
+ long [] normalizedRoC = new long[values.length];
+ normalizedRoC[0] = 0;
+
+ for(int i=1; i < values.length; i++)
+ {
+ if(deltas[i] > 0)
+ {
+ if(valueVsBaseline[i] > 0)
+ normalizedRoC[i] = (long)Math.log(deltas[i]);
+
+ else if(valueVsBaseline[i] < 0)
+ normalizedRoC[i] = (long)(Math.log(deltas[i] + valueVsBaseline[i]));
+ else
+ normalizedRoC[i] = 0;
+ }
+ else if(deltas[i] < 0)
+ normalizedRoC[i] = -(long)Math.log(-deltas[i]);
+ else
+ normalizedRoC[i] = 0;
+ }
+
+ return normalizedRoC;
+ }
+
+ private int calculateStableGrowth(long [] values)
+ {
+ int [] stableGrowiness = new int[values.length];
+
+ for(int i=0; i<stableGrowiness.length; i++)
+ {
+ if(i >0)
+ {
+ long diff = values[i] - values[i-1];
+
+ if(diff > 0)
+ {
+ stableGrowiness[i] = stableGrowiness[i-1] + 1;
+ }
+ else if(diff == 0)
+ stableGrowiness[i] = stableGrowiness[i-1];
+ else
+ {
+ if(values[i] > values[0])
+ stableGrowiness[i] = stableGrowiness[i-1] - 1;
+ else
+ stableGrowiness[i] = 0;
+ }
+ }
+ }
+
+ return stableGrowiness[stableGrowiness.length-1];
+ }
+
+ /**
+ * The method calculates priority of an issue, based on the values of
+ * growiness factor, delta factor and number of Cycles.
+ * @param growing_factor
+ * @param delta_factor
+ * @param noOfCycles
+ * @return priority of the issue.
+ */
+ protected AnalyserConstants.Priority calculatePriorityFactor(double growing_factor, double delta_factor, int noOfCycles)
+ {
+ double high_threshold = Math.exp(noOfCycles - 1);
+ int temp = noOfCycles/2;
+ double normal_threshold = Math.exp(temp);
+
+ int temp1 = noOfCycles/4;
+ double low_threshold = Math.exp(temp1);
+
+ if(growing_factor > high_threshold)
+ {
+ if(delta_factor > 0)
+ return AnalyserConstants.Priority.CRITICAL;
+ }
+ if(growing_factor > normal_threshold)
+ {
+ if(delta_factor > 0.5)
+ return AnalyserConstants.Priority.CRITICAL;
+ else if(delta_factor > 0)
+ return AnalyserConstants.Priority.HIGH;
+ }
+ if(growing_factor > low_threshold)
+ {
+ if(delta_factor > 3)
+ return AnalyserConstants.Priority.CRITICAL;
+ else if(delta_factor > 0.5)
+ return AnalyserConstants.Priority.HIGH;
+ }
+ if(growing_factor > Math.exp(1))
+ {
+ if(delta_factor > 5)
+ return AnalyserConstants.Priority.CRITICAL;
+ else if(delta_factor > 3)
+ return AnalyserConstants.Priority.HIGH;
+ }
+ if(growing_factor >0 && delta_factor > 0)
+ return AnalyserConstants.Priority.NORMAL;
+
+ return AnalyserConstants.Priority.NEGLIGIBLE;
+ }
+
+ /**
+ * The method formats the given value to Bytes, Kilo Bytes and Mega Bytes.
+ * @param bytes -- value to be formatted.
+ * @return formatted string in KB or MB
+ */
+ protected String getFormattedBytes(long bytes)
+ {
+ String formatted_value = "";
+
+ if (bytes < 1024)
+ {
+ formatted_value += Bytes_Format.format(bytes) + " B"; //$NON-NLS-1$
+ }
+ else if (bytes <= 500 * 1024)
+ {
+ formatted_value += Bytes_Format.format(bytes / 1024) + " KB"; //$NON-NLS-1$
+ }
+ else
+ {
+ formatted_value += Bytes_Format.format(((float) bytes / (1024 * 1024))) + " MB"; //$NON-NLS-1$
+ }
+
+ return formatted_value;
+ }
+
+ /**
+ * The method calculates Growiness and priority based on given set of values.
+ * As no time intervals are provided, the method treats that the event is alive in all cycles (from first to last).
+ * @param event_values -- values of the event being analysed.
+ * @param result_elem -- structure to which calculated growiness and priority would be set to.
+ */
+ protected void calculateGrowinessAndPriority(long [] event_values, ResultElements result_elem)
+ {
+ SWMTLogReaderUtils utils = new SWMTLogReaderUtils();
+
+ if(time_intervals == null)
+ time_intervals = utils.getTimeIntervalsFromLogData(logData);
+
+ calculateGrowinessAndPriority(event_values, time_intervals, result_elem);
+
+ }
+
+ /**
+ * The method calculates Growiness and priority based on given set of values and given time intervals
+ * @param event_values
+ * @param log_intervals
+ * @param result_elem
+ */
+ protected void calculateGrowinessAndPriority(long [] event_values, int [] log_intervals, ResultElements result_elem)
+ {
+ double growiness = calculateGrowiness(event_values, log_intervals);
+
+ long firstValue = event_values[0];
+ long lastValue = event_values[event_values.length -1];
+
+ double log_of_first = 0;
+ double log_of_last = 0;
+
+ if(firstValue != 0)
+ log_of_first = Math.log(firstValue);
+ if(lastValue != 0)
+ log_of_last = Math.log(lastValue);
+
+ double prioritization_factor = log_of_last - log_of_first;
+
+ AnalyserConstants.Priority priority = calculatePriorityFactor(growiness, prioritization_factor, log_intervals.length);
+
+ result_elem.setGrowingFactor(growiness);
+ result_elem.setPriority(priority);
+
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/analysers/ResultElements.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,301 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+package com.nokia.s60tools.swmtanalyser.analysers;
+
+import org.eclipse.swt.graphics.Color;
+/**
+ * Input object for tree viewer in analysis tab.
+ *
+ */
+public class ResultElements implements Comparable<ResultElements>{
+
+ /**
+ * Item name
+ */
+ public static final String ITEM_NAME_COLUMN = "Item name";
+ /**
+ * Event
+ */
+ public static final String EVENT_COLUMN = "Event";
+ /**
+ * Delta
+ */
+ public static final String DELTA_COLUMN = "Delta";
+ /**
+ * Severity
+ */
+ public static final String SEVERITY_COLUMN = "Severity";
+
+ private static final String TAB = "\t";
+
+ private String itemName;
+ private String event;
+ private String delta;
+ private long delta_value;
+ private double growing_factor;
+ private Color color;
+ private long [] event_values;
+
+ private AnalyserConstants.Priority priority = AnalyserConstants.Priority.NEGLIGIBLE;
+ private AnalyserConstants.DeltaType deltaType = AnalyserConstants.DeltaType.COUNT;
+
+ /**
+ * Construction
+ * @param itemName
+ * @param event
+ * @param delta
+ * @param deltaValue
+ * @param type
+ */
+ ResultElements(String itemName, String event, String delta, long deltaValue, AnalyserConstants.DeltaType type)
+ {
+ this.itemName = itemName;
+ this.event = event;
+ this.delta = delta;
+ this.delta_value = deltaValue;
+ this.deltaType = type;
+ }
+
+ /**
+ * @return item name
+ */
+ public String toString()
+ {
+ return this.itemName;
+ }
+
+
+ /**
+ * Get tab separated headers for this result.
+ * @return headers with tab as separator
+ */
+ public String getTabSeparatedHeaders()
+ {
+ //NOTE: If reorganized, also #getTabSeparatedValues() must reorganize
+ StringBuffer b = new StringBuffer();
+ b.append(ITEM_NAME_COLUMN);
+ b.append(TAB);
+ b.append(EVENT_COLUMN);
+ b.append(TAB);
+ b.append(DELTA_COLUMN);
+ b.append(TAB);
+ b.append(SEVERITY_COLUMN);
+
+ return b.toString();
+
+ }
+
+ /**
+ * Get tab separated values for this result.
+ * @return values
+ */
+ public String getTabSeparatedValues()
+ {
+ //NOTE: If reorganized, also #getTabSeparatedHeaders() must reorganize
+ StringBuffer b = new StringBuffer();
+ b.append(itemName);
+ b.append(TAB);
+ b.append(event);
+ b.append(TAB);
+ b.append(delta);
+ b.append(TAB);
+ b.append(getPriority());
+
+ return b.toString();
+
+ }
+
+
+
+ /**
+ * Get delta
+ * @return delta
+ */
+ public String getDelta() {
+ return delta;
+ }
+
+ /**
+ * Set delta
+ * @param delta
+ */
+ public void setDelta(String delta) {
+ this.delta = delta;
+ }
+
+ /**
+ * Get item name
+ * @return item name
+ */
+ public String getItemName() {
+ return itemName;
+ }
+
+ /**
+ * Get event
+ * @return event
+ */
+ public String getEvent() {
+ return event;
+ }
+
+ /**
+ * Set event
+ * @param event
+ */
+ public void setEvent(String event) {
+ this.event = event;
+ }
+
+ /**
+ * Get growing factor
+ * @return growing factor
+ */
+ public double getGrowingFactor() {
+ return growing_factor;
+ }
+
+ /**
+ * Set growing factor
+ * @param growing_factor
+ */
+ public void setGrowingFactor(double growing_factor) {
+ this.growing_factor = growing_factor;
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Comparable#compareTo(java.lang.Object)
+ */
+ public int compareTo(ResultElements input) {
+
+ int priority_comparision = this.getPriority().compareTo(input.getPriority());
+
+ if(priority_comparision == 0)
+ {
+ if(this.growing_factor > input.growing_factor)
+ return 1;
+ else if(this.growing_factor < input.growing_factor)
+ return -1;
+ else
+ return 0;
+ }
+ else
+ return priority_comparision;
+ }
+
+ /**
+ * Compare this objects {@link #getDelta()} to given object {@link #getDelta()}
+ * Returns a negative integer, zero, or a positive integer
+ * as this object is less than, equal to, or greater than the specified object.
+ * @param input
+ * @return 0 if this object is equal to given object,
+ * 1 if this object is greater to given object,
+ * -1 if this object is less to given object
+ */
+ public int compareByDelta(ResultElements input)
+ {
+ long input_delta = input.getDeltaValue();
+
+ if(delta_value > input_delta)
+ return 1;
+ else if(delta_value < input_delta)
+ return -1;
+ else
+ return 0;
+
+ }
+ /**
+ * Get priority
+ * @return priority
+ */
+ public AnalyserConstants.Priority getPriority() {
+ return priority;
+ }
+
+ /**
+ * Set priority
+ * @param priority
+ */
+ public void setPriority(AnalyserConstants.Priority priority) {
+ this.priority = priority;
+ }
+
+ /**
+ * Get delta
+ * @return delta
+ */
+ public long getDeltaValue() {
+ return delta_value;
+ }
+
+ /**
+ * Set delta
+ * @param delta_value
+ */
+ public void setDeltaValue(long delta_value) {
+ this.delta_value = delta_value;
+ }
+
+ /**
+ * Get Delta type
+ * @return delta type
+ */
+ public AnalyserConstants.DeltaType getType() {
+ return deltaType;
+ }
+
+ /**
+ * Set delta type
+ * @param type
+ */
+ public void setType(AnalyserConstants.DeltaType type) {
+ this.deltaType = type;
+ }
+
+ /**
+ * Get color
+ * @return color
+ */
+ public Color getColor() {
+ return color;
+ }
+
+ /**
+ * Set Color
+ * @param color
+ */
+ public void setColor(Color color) {
+ this.color = color;
+ }
+
+ /**
+ * Get event values
+ * @return values
+ */
+ public long[] getEventValues() {
+ return event_values;
+ }
+
+ /**
+ * Set event values
+ * @param event_values
+ */
+ public void setEventValues(long[] event_values) {
+ this.event_values = event_values;
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/analysers/ResultsParentNodes.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,93 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+package com.nokia.s60tools.swmtanalyser.analysers;
+
+import java.util.ArrayList;
+/**
+ * Input object(parent) for tree viewer in analysis tab.
+ *
+ */
+public class ResultsParentNodes{
+
+ private String description;
+ private ArrayList<ResultElements> children;
+ private ArrayList<ResultElements> filteredChildren = new ArrayList<ResultElements>();
+
+ /**
+ * Construction
+ * @param description
+ */
+ ResultsParentNodes(String description)
+ {
+ this.description = description;
+ }
+
+ /**
+ * Set the childrens of this element
+ * @param childArrayList
+ */
+ public void setChildren(ArrayList<ResultElements> childArrayList)
+ {
+ this.children = childArrayList;
+ }
+
+ /**
+ * Get childrens
+ * @return childrens as {@link ResultElements}
+ */
+ public Object[] getChildren()
+ {
+ if(children != null)
+ return children.toArray(new ResultElements[0]);
+ else
+ return null;
+ }
+
+ /**
+ * Get description
+ */
+ public String toString()
+ {
+ return this.description;
+ }
+
+ /**
+ * Add a filtered children
+ * @param child
+ */
+ public void addFilteredChild(ResultElements child)
+ {
+ filteredChildren.add(child);
+ }
+
+ /**
+ * Get all filtered childrens
+ * @return
+ */
+ public ArrayList<ResultElements> getFilteredChildrenList()
+ {
+ return filteredChildren;
+ }
+ /**
+ * Get count for filtered childrens
+ * @return count
+ */
+ public int getFilteredCount()
+ {
+ return filteredChildren.size();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/analysers/ThreadDataAnalyser.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,264 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+package com.nokia.s60tools.swmtanalyser.analysers;
+
+import java.util.ArrayList;
+
+import com.nokia.s60tools.swmtanalyser.data.CycleData;
+import com.nokia.s60tools.swmtanalyser.data.ParsedData;
+import com.nokia.s60tools.swmtanalyser.data.ThreadData;
+import com.nokia.s60tools.swmtanalyser.data.ThreadSegments;
+import com.nokia.s60tools.swmtanalyser.model.SWMTLogReaderUtils;
+
+/**
+ *
+ * Defines Enum constants for all Thread events to be analysed.
+ */
+enum THREAD_EVENTS {
+
+ HEAP_SIZE("Heap size"), NO_OF_FILES("No of Files"), HEAP_ALLOC_SPACE("Heap allocated space"), HEAP_ALLOC_CELLS("Heap allocated cell count"), NO_OF_PSHANDLES("No of PS Handles");
+
+ private String description;
+
+ THREAD_EVENTS(String desc)
+ {
+ description = desc;
+ }
+ public String getDescription()
+ {
+ return description;
+ }
+}
+/**
+ * Analyser class implementation for Thread data
+ */
+public class ThreadDataAnalyser extends LinearAnalyser{
+
+ private static final String THREADS_TITLE = "Threads";
+
+ ArrayList<ResultsParentNodes> treeElements = new ArrayList<ResultsParentNodes>();
+
+
+ /* (non-Javadoc)
+ * @see com.nokia.s60tools.swmtanalyser.analysers.LinearAnalyser#analyse(com.nokia.s60tools.swmtanalyser.data.ParsedData)
+ */
+ public void analyse(ParsedData logData) {
+
+ treeElements.clear();
+ ResultsParentNodes thread_issues = new ResultsParentNodes(THREADS_TITLE);
+
+ SWMTLogReaderUtils utils = new SWMTLogReaderUtils();
+
+ ArrayList<String> heapThreads = utils.getAllThreadNames(logData);
+
+ int in = 0;
+
+ ArrayList<ResultElements> sub_issues = new ArrayList<ResultElements> ();
+
+ for(String thName: heapThreads)
+ {
+ ArrayList<ThreadData> thData = utils.getHeapDataFromAllCycles(thName, logData);
+ ThreadSegments [] segments = utils.getHeapSegments(thData);
+
+ if(segments != null){
+
+ THREAD_EVENTS [] events = THREAD_EVENTS.values();
+
+ for(THREAD_EVENTS event:events)
+ analyseThreadEvent(event, thName, thData, logData, segments, sub_issues);
+
+ }
+
+ in++;
+ }
+
+ thread_issues.setChildren(sub_issues);
+
+ treeElements.add(thread_issues);
+
+ }
+
+ /* (non-Javadoc)
+ * @see com.nokia.s60tools.swmtanalyser.analysers.LinearAnalyser#getResults()
+ */
+ public Object[] getResults() {
+
+ return treeElements.toArray();
+ }
+
+ /* (non-Javadoc)
+ * @see com.nokia.s60tools.swmtanalyser.analysers.LinearAnalyser#getChildren(java.lang.Object)
+ */
+ public Object[] getChildren(Object parent)
+ {
+ if(parent instanceof ResultsParentNodes && treeElements.contains(parent))
+ {
+ return ((ResultsParentNodes)(parent)).getChildren();
+ }
+ else
+ return null;
+ }
+
+ /**
+ * This method analyses data of given thread event
+ * @param event thread event to be analysed
+ * @param thName name of the thread
+ * @param heapData represents data of given thread from all log files
+ * @param logData represents data of all log files
+ * @param thSegments array of segments in which the thread is alive
+ * @param results structure to which all thread issues will be added to.
+ */
+ private void analyseThreadEvent(THREAD_EVENTS event, String thName, ArrayList<ThreadData> heapData, ParsedData logData, ThreadSegments [] thSegments, ArrayList<ResultElements> results)
+ {
+ SWMTLogReaderUtils utils = new SWMTLogReaderUtils();
+ CycleData[] cyclesData = logData.getLogData();
+
+ for(int i=0; i<thSegments.length; i++)
+ {
+ ThreadSegments segment = thSegments[i];
+ long [] heap_size_values;
+ int [] time_intervals;
+
+ int startIndex = segment.getStartCycle() - 1;
+ int endIndex = segment.getEndCycle() - 1;
+ long delta;
+
+ long [] event_values = new long[logData.getNumberOfCycles()];
+
+ if(heapData.get(endIndex).getStatus() == CycleData.Deleted)
+ {
+ int tmp = 0;
+ heap_size_values = new long[segment.getEndCycle() - segment.getStartCycle()];
+
+ time_intervals = new int[heap_size_values.length];
+
+ for(int j = startIndex; j < endIndex; j++, tmp++)
+ {
+ heap_size_values[tmp] = getEventValue(heapData.get(j), event);
+
+ if(tmp == 0)
+ time_intervals[tmp] = 0;
+ else
+ time_intervals[tmp] = (int)(time_intervals[tmp -1] + utils.getDurationInSeconds(cyclesData[j-1].getTime(), cyclesData[j].getTime()));
+ }
+
+ }
+ else
+ {
+ int tmp = 0;
+ heap_size_values = new long[segment.getEndCycle() - segment.getStartCycle() + 1];
+ time_intervals = new int[heap_size_values.length];
+
+ for(int j = startIndex; j <= endIndex; j++, tmp++)
+ {
+ heap_size_values[tmp] = getEventValue(heapData.get(j), event);
+
+ if(tmp == 0)
+ time_intervals[tmp] = 0;
+ else
+ time_intervals[tmp] = (int)(time_intervals[tmp -1] + utils.getDurationInSeconds(cyclesData[j-1].getTime(), cyclesData[j].getTime()));
+ }
+
+ }
+
+ delta = utils.calculateDeltaForGivenSet(heap_size_values);
+
+ String thread_instance = thName;
+
+ if(thSegments.length > 1){
+ int id = i+1;
+ thread_instance += "(0" + id + ")";
+
+ int index;
+
+ for(index=0; index < startIndex; index++){
+ event_values[index] = 0;
+ }
+
+ for(int tmp =0; tmp < heap_size_values.length; tmp++)
+ {
+ event_values[index] = heap_size_values[tmp];
+ index++;
+ }
+
+ for(;index < cyclesData.length ;index++)
+ event_values[index] = 0;
+ }
+ else
+ {
+ for(int index=0; index < heapData.size(); index++)
+ event_values[index] = getEventValue(heapData.get(index), event);
+ }
+ String formatted_delta = Long.toString(delta);
+ AnalyserConstants.DeltaType delta_type = AnalyserConstants.DeltaType.COUNT;
+ switch(event)
+ {
+ case HEAP_SIZE:
+ case HEAP_ALLOC_SPACE:
+ formatted_delta = getFormattedBytes(delta);
+ delta_type = AnalyserConstants.DeltaType.SIZE;
+ }
+
+ ResultElements res_elem = new ResultElements(thread_instance, event.getDescription(), formatted_delta, delta, delta_type);
+ res_elem.setEventValues(event_values);
+
+ calculateGrowinessAndPriority(heap_size_values, time_intervals, res_elem);
+ if(res_elem.getPriority() != AnalyserConstants.Priority.NEGLIGIBLE)
+ {
+ results.add(res_elem);
+ }
+ }
+
+ }
+
+ /**
+ *
+ * @param thData structure represents entire data of a thread in one log(cycle).
+ * @param event a specific thread event
+ * @return value of the given event.
+ */
+ private long getEventValue(ThreadData thData, THREAD_EVENTS event)
+ {
+ long event_value = 0;
+
+ if(thData.getStatus() == CycleData.Deleted)
+ return 0;
+
+ switch(event)
+ {
+ case HEAP_SIZE:
+ event_value = thData.getHeapChunkSize();
+ break;
+ case NO_OF_FILES:
+ event_value = thData.getOpenFiles();
+ break;
+ case HEAP_ALLOC_SPACE:
+ event_value = thData.getHeapAllocatedSpace();
+ break;
+ case HEAP_ALLOC_CELLS:
+ event_value = thData.getAllocatedCells();
+ break;
+ case NO_OF_PSHANDLES:
+ event_value = thData.getPsHandles();
+ break;
+ }
+
+ return event_value;
+
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/data/ChunksData.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,87 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+package com.nokia.s60tools.swmtanalyser.data;
+
+/**
+ * Stores chunk related data.
+ *
+ */
+public class ChunksData {
+ private String processName;
+ private String chunkName;
+ private String handle;
+ private String baseAddr;
+ private long size = -1;
+ private int attrib;
+ private boolean isKernelHandleDeleted;
+
+ public ChunksData() {}
+
+ public ChunksData(ChunksData target)
+ {
+ this.chunkName = target.chunkName;
+ this.processName = target.processName;
+ this.baseAddr = target.baseAddr;
+ this.size = target.size;
+ this.attrib = target.attrib;
+ }
+
+ public int getAttrib() {
+ return attrib;
+ }
+ public void setAttrib(int attrib) {
+ this.attrib = attrib;
+ }
+ public String getBaseAddr() {
+ return baseAddr;
+ }
+ public void setBaseAddr(String baseAddr) {
+ this.baseAddr = baseAddr;
+ }
+ public String getChunkName() {
+ return chunkName;
+ }
+ public void setChunkName(String chunkName) {
+ this.chunkName = chunkName;
+ }
+ public String getHandle() {
+ return handle;
+ }
+ public void setHandle(String handle) {
+ this.handle = handle;
+ }
+ public String getProcessName() {
+ return processName;
+ }
+ public void setProcessName(String processName) {
+ this.processName = processName;
+ }
+ public long getSize() {
+ return size;
+ }
+ public void setSize(long size) {
+ this.size = size;
+ }
+
+ public boolean isKernelHandleDeleted() {
+ return isKernelHandleDeleted;
+ }
+
+ public void setKernelHandleDeleted(boolean isKernelHandleDeleted) {
+ this.isKernelHandleDeleted = isKernelHandleDeleted;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/data/CycleData.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,953 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+package com.nokia.s60tools.swmtanalyser.data;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+
+public class CycleData implements Comparable<CycleData>{
+
+ private String fileName;
+ private int cycleNumber;
+ private String time;
+ private String romCheckSum;
+ private String romVersion;
+ private long changeCount;
+ private long freeMemory = -1;
+ private long totalMemory = -1;
+ private long prevFreeMem;
+ private long memspyRam;
+
+ public static final int Deleted = 0;
+ public static final int New = 1;
+ public static final int Alive =2;
+
+ private ArrayList<PSHandlesData> psHandlesList;
+ private ArrayList<KernelHandles> kernelHandlesList;
+ private ArrayList<DiskData> disksList;
+ private ArrayList<FilesData> filesList;
+ private ArrayList<GlobalDataChunks> globalDataChunksList;
+ private ArrayList<StackData> stacksList;
+ private ArrayList<ChunksData> nonRHeapList;
+ private ArrayList<HeapData> heapsList;
+ private ArrayList<ChunksData> chunksList;
+ private ArrayList<WindowGroups> wndgList;
+
+ private ArrayList<String> newlyCreatedDisks;
+ private ArrayList<String> updatedDisks;
+ private ArrayList<String> deletedDisks;
+
+ private ArrayList<String> newlyCreatedThreads;
+ private ArrayList<String> updatedThreads;
+ private ArrayList<String> deletedThreads;
+
+ private ArrayList<String> newlyCreatedHeaps;
+ private ArrayList<String> updatedHeaps;
+ private ArrayList<String> deletedHeaps;
+
+
+ /**
+ * @param diskData will be added to the list of disks, maintained internally
+ */
+ public void addDiskData(DiskData diskData)
+ {
+ if(disksList == null)
+ disksList = new ArrayList<DiskData>();
+
+ disksList.add(diskData);
+ }
+
+ /**
+ * @param kernelData will be added to the list of kernelhandles, maintained internally
+ */
+ public void addKernelData(KernelHandles kernelData)
+ {
+ if(kernelHandlesList == null)
+ kernelHandlesList = new ArrayList<KernelHandles>();
+
+ kernelHandlesList.add(kernelData);
+ }
+
+ /**
+ * @param fileData will be added to the list of files, maintained internally
+ */
+ public void addFileData(FilesData fileData)
+ {
+ if(filesList == null)
+ filesList = new ArrayList<FilesData>();
+
+ filesList.add(fileData);
+ }
+
+ /**
+ * @param HPAS Handles Data will be added to the list of ps handles data, maintained internally
+ */
+ public void addHPASHandlesData(PSHandlesData psHandlesData)
+ {
+ if(psHandlesList == null)
+ psHandlesList = new ArrayList<PSHandlesData>();
+
+ psHandlesList.add(psHandlesData);
+ }
+
+ /**
+ * @param heapData will be added to the list of heaps, maintained internally
+ */
+ public void addHeapData(HeapData heapData)
+ {
+ if(heapsList == null)
+ heapsList = new ArrayList<HeapData>();
+
+ heapsList.add(heapData);
+ }
+
+ /**
+ * @param stackData will be added to the list of stacks, maintained internally
+ */
+ public void addStackData(StackData stackData)
+ {
+ if(stacksList == null)
+ stacksList = new ArrayList<StackData>();
+
+ stacksList.add(stackData);
+ }
+
+ /**
+ * @param Chunks Data will be added to the list of chunks data, maintained internally
+ */
+ public void addChunksData(ChunksData chunksData)
+ {
+ if( chunksList == null)
+ chunksList = new ArrayList<ChunksData>();
+
+ chunksList.add(chunksData);
+ }
+
+ /**
+ * @param Chunks Data will be added to the list of chunks data, maintained internally.
+ */
+ public void addGlobalChunksData(GlobalDataChunks globalChunksData)
+ {
+ if( globalDataChunksList == null)
+ globalDataChunksList = new ArrayList<GlobalDataChunks>();
+
+ globalDataChunksList.add(globalChunksData);
+ }
+
+ /**
+ *
+ * @param Window Groups Data will be added to the list of window groups, maintained internally.
+ */
+ public void addWindowGroupsData(WindowGroups wndgData)
+ {
+ if(wndgList == null)
+ wndgList = new ArrayList<WindowGroups>();
+
+ wndgList.add(wndgData);
+ }
+
+ /**
+ * @returns an arraylist of disknames present in this cycle.
+ */
+ public ArrayList<String> getDiskNames()
+ {
+ ArrayList<String> diskNames = new ArrayList<String>();
+
+ if(disksList != null)
+ for(DiskData d:disksList)
+ diskNames.add(d.getName());
+
+ return diskNames;
+ }
+
+ /**
+ * This method parses the cycle data and stores the disk names to
+ * corresponding lists based on their status.
+ *
+ */
+ public void parseDisksList()
+ {
+ newlyCreatedDisks = new ArrayList<String>();
+ updatedDisks = new ArrayList<String>();
+ deletedDisks = new ArrayList<String>();
+
+ if(disksList != null){
+ for(DiskData d:disksList){
+ if(d.getStatus() == CycleData.New)
+ newlyCreatedDisks.add(d.getName());
+ else if(d.getStatus() == CycleData.Alive)
+ updatedDisks.add(d.getName());
+ else if(d.getStatus() == CycleData.Deleted)
+ deletedDisks.add(d.getName());
+ }
+ }
+
+ }
+
+ /**
+ * This method parses the handles list of a cycle data and if the handle type
+ * if thread, it stores thread names of those handles to corresponding lists
+ * based on their status
+ *
+ */
+ public void parseAllThreads()
+ {
+ newlyCreatedThreads = new ArrayList<String>();
+ updatedThreads = new ArrayList<String>();
+ deletedThreads = new ArrayList<String>();
+
+ if(kernelHandlesList != null){
+ for(KernelHandles handle:kernelHandlesList){
+ if(handle.getHandleType().equals("Thread"))
+ {
+ if(handle.getStatus() == CycleData.New)
+ newlyCreatedThreads.add(handle.getHandleName());
+ else if(handle.getStatus() == CycleData.Alive)
+ updatedThreads.add(handle.getHandleName());
+ else if(handle.getStatus() == CycleData.Deleted)
+ deletedThreads.add(handle.getHandleName());
+ }
+ }
+ }
+
+ }
+
+ /**
+ *
+ * @param threadName name of the thread whose stack data is needed
+ * @return class which stores stack information
+ */
+ public StackData getStackData(String threadName)
+ {
+ if(stacksList != null)
+ {
+ for(StackData st:stacksList)
+ {
+ if(st.getThreadName().equalsIgnoreCase(threadName))
+ return st;
+ }
+ }
+
+ return null;
+ }
+
+ public int getNewOpenFiles(String threadName)
+ {
+ int openFilesCnt = 0;
+
+ if(filesList != null)
+ {
+ for(FilesData file:filesList)
+ {
+ if(file.getThreadName().equalsIgnoreCase(threadName)
+ && file.getStatus() == CycleData.New)
+ openFilesCnt++;
+ }
+
+ }
+
+ return openFilesCnt;
+ }
+
+ public int getDeletedFiles(String threadName)
+ {
+ int closedFilesCnt = 0;
+
+ if(filesList != null)
+ {
+ for(FilesData file:filesList)
+ {
+ if(file.getThreadName().equalsIgnoreCase(threadName)
+ && file.getStatus() == CycleData.Deleted)
+ closedFilesCnt++;
+ }
+ }
+
+ return closedFilesCnt;
+ }
+
+ public int getUpdatedFiles(String threadName)
+ {
+ int openFilesCnt = 0;
+
+ if(filesList != null)
+ {
+ for(FilesData file:filesList)
+ {
+ if(file.getThreadName().equalsIgnoreCase(threadName)
+ && file.getStatus() == CycleData.Alive)
+ openFilesCnt++;
+ }
+ //DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "Openfiles for " + threadName + " are " + openFilesCnt);
+ }
+
+ return openFilesCnt;
+ }
+
+ public int getNewPSHandles(String threadName)
+ {
+ int psHandlesCnt = 0;
+
+ if(psHandlesList != null)
+ {
+ for(PSHandlesData psHandle:psHandlesList)
+ {
+ if(psHandle.getThreadName().equalsIgnoreCase(threadName)
+ && (psHandle.getStatus() == CycleData.New))
+ psHandlesCnt++;
+ }
+ }
+
+ return psHandlesCnt;
+ }
+
+ public int getDeletedPSHandles(String threadName)
+ {
+ int deletedHandlesCnt = 0;
+
+ if(psHandlesList != null)
+ {
+ for(PSHandlesData psHandle:psHandlesList)
+ {
+ if(psHandle.getThreadName().equalsIgnoreCase(threadName)
+ && psHandle.getStatus() == CycleData.Deleted)
+ deletedHandlesCnt++;
+ }
+ }
+
+ return deletedHandlesCnt;
+ }
+
+ public int getUpdatedPSHandles(String threadName)
+ {
+ int alivePSHandles = 0;
+
+ if(psHandlesList != null)
+ {
+ for(PSHandlesData psHandle:psHandlesList)
+ {
+ if(psHandle.getThreadName().equalsIgnoreCase(threadName)
+ && psHandle.getStatus() == CycleData.Alive)
+ alivePSHandles++;
+ }
+ //DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "Openfiles for " + threadName + " are " + openFilesCnt);
+
+ }
+
+ return alivePSHandles;
+ }
+
+ public ArrayList<String> getNewlyCreatedDisks()
+ {
+ return newlyCreatedDisks;
+ }
+
+ public ArrayList<String> getUpdatedDisks()
+ {
+ return updatedDisks;
+ }
+
+ public ArrayList<String> getDeletedDisks()
+ {
+ return deletedDisks;
+ }
+
+ public ArrayList<String> getNewlyCreatedThreads()
+ {
+ return newlyCreatedThreads;
+ }
+
+ public ArrayList<String> getUpdatedThreads()
+ {
+ return updatedThreads;
+ }
+
+ public ArrayList<String> getDeletedThreads()
+ {
+ return deletedThreads;
+ }
+
+ /**
+ * Reads the values for given disk in this cycledata.
+ * @param diskName name of the disk whose info must be fetched.
+ * @return a structure which can store used memory and size values.
+ */
+ public DiskOverview getDiskUsedAndFreeSize(String diskName)
+ {
+ if(disksList != null)
+ {
+ DiskOverview overview = new DiskOverview();
+
+ int index = -1;
+ for(DiskData disk:disksList)
+ {
+ index++;
+ if(disk.getName().equalsIgnoreCase(diskName))
+ {
+ DiskData diskData = disksList.get(index);
+ overview.setSize(diskData.getSize());
+ overview.setFreeSize(diskData.getFreeSize());
+ overview.setStatus(diskData.getStatus());
+
+ return overview;
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ *
+ * @param threadName name of the thread whose heap data is needed.
+ * @return class which stores heap information of given thread in this cycle.
+ */
+ public ThreadData getHeapData(String threadName)
+ {
+
+ if(heapsList != null)
+ {
+ ThreadData data = new ThreadData(threadName);
+ for(HeapData heap:heapsList)
+ {
+ if(heap.getThreadName().equalsIgnoreCase(threadName))
+ {
+ data.setHeapChunkSize(heap.getSize());
+ data.setMaxHeapSize(heap.getMaxSize());
+ data.setAllocatedCells(heap.getAllocatedCells());
+ data.setFreeCells(heap.getFreeCells());
+ data.setHeapAllocatedSpace(heap.getAllocSpace());
+ data.setHeapFreeSpace(heap.getFreeSpace());
+ data.setLargestAllocCellSize(heap.getLargestAllocCell());
+ data.setLargestFreeCellSize(heap.getLargestFreeCell());
+ data.setFreeSlackSize(heap.getFreeSlack());
+ data.setStatus(heap.getStatus());
+
+ return data;
+ }
+ }
+ }
+
+ return null;
+ }
+
+ public int getKernelHandles()
+ {
+ if(kernelHandlesList != null)
+ return kernelHandlesList.size();
+ else
+ return 0;
+ }
+
+ /**
+ * This method parses all heap structures for this cycle and
+ * stores the thread names of those heaps to corresponding lists
+ * based on their status
+ *
+ */
+ public void parseAllHeaps()
+ {
+ newlyCreatedHeaps = new ArrayList<String>();
+ updatedHeaps = new ArrayList<String>();
+ deletedHeaps = new ArrayList<String>();
+
+ if(heapsList != null){
+ for(HeapData heap:heapsList){
+ if(heap.getStatus() == CycleData.New)
+ newlyCreatedHeaps.add(heap.getThreadName());
+ else if(heap.getStatus() == CycleData.Alive)
+ updatedHeaps.add(heap.getThreadName());
+ else if(heap.getStatus() == CycleData.Deleted)
+ deletedHeaps.add(heap.getThreadName());
+ }
+ }
+
+ }
+
+ /**
+ * @return list of thread names whose heap is created in this cycle.
+ */
+ public ArrayList<String> getNewHeapThreads()
+ {
+ return newlyCreatedHeaps;
+ }
+
+ /**
+ * @return list of thread names whose heap information is
+ * updated in this cycle.
+ */
+ public ArrayList<String> getAliveHeapThreads()
+ {
+ return updatedHeaps;
+ }
+
+ /**
+ * @return list of thread names whose heap is deleted in this cycle.
+ *
+ */
+ public ArrayList<String> getDeletedHeapThreads()
+ {
+ return deletedHeaps;
+ }
+
+ /**
+ * This method parses all stack structures for this cycle and
+ * returns the list of thread names for all newly created stacks.
+ *
+ */
+ public ArrayList<String> getNewStackThreads()
+ {
+ ArrayList<String> threadNames = new ArrayList<String>();
+
+ if(stacksList != null)
+ for(StackData stack:stacksList)
+ {
+ if(stack.getStatus() == CycleData.New)
+ threadNames.add(stack.getThreadName());
+ }
+ return threadNames;
+ }
+
+ /**
+ * This method parses all stack structures for this cycle and
+ * returns the list of thread names for updated stacks.
+ *
+ */
+ public ArrayList<String> getAliveStackThreads()
+ {
+ ArrayList<String> threadNames = new ArrayList<String>();
+
+ if(stacksList != null)
+ for(StackData stack:stacksList)
+ {
+ if(stack.getStatus() == CycleData.Alive)
+ threadNames.add(stack.getThreadName());
+ }
+ return threadNames;
+ }
+
+ /**
+ * This method parses all stack structures for this cycle and
+ * returns the list of thread names for all deleted stacks.
+ *
+ */
+ public ArrayList<String> getDeletedStackThreads()
+ {
+ ArrayList<String> threadNames = new ArrayList<String>();
+
+ if(stacksList != null)
+ for(StackData stack:stacksList)
+ {
+ if(stack.getStatus() == CycleData.Deleted){
+ threadNames.add(stack.getThreadName());
+ }
+ }
+ return threadNames;
+ }
+
+ /**
+ *
+ * @return list of thread names which contain PSHandles
+ */
+ public ArrayList<String> getHPASThreads()
+ {
+ ArrayList<String> threadNames = new ArrayList<String>();
+
+ if(psHandlesList != null)
+ for(PSHandlesData hpas:psHandlesList)
+ threadNames.add(hpas.getThreadName());
+
+ return threadNames;
+ }
+
+ /**
+ *
+ * @return list of thread names which contain file handles.
+ */
+ public ArrayList<String> getFileThreads()
+ {
+ ArrayList<String> threadNames = new ArrayList<String>();
+
+ if(filesList != null)
+ for(FilesData file:filesList)
+ threadNames.add(file.getThreadName());
+
+ return threadNames;
+ }
+
+ public ArrayList<String> getDeletedChunkNames ()
+ {
+ ArrayList<String> deletedChunks = new ArrayList<String>();
+
+ if(kernelHandlesList != null){
+ for(KernelHandles handle:kernelHandlesList){
+
+ if(handle.getHandleType().equals("Chunk") &&
+ (handle.getStatus() == CycleData.Deleted))
+ {
+ deletedChunks.add(handle.getHandleName());
+ }
+ }
+ }
+
+ return deletedChunks;
+ }
+
+
+
+ public long getChangeCount() {
+ return changeCount;
+ }
+ public void setChangeCount(long changeCount) {
+ this.changeCount = changeCount;
+ }
+ public int getCycleNumber() {
+ return cycleNumber;
+ }
+ public void setCycleNumber(int cycleNumber) {
+ this.cycleNumber = cycleNumber;
+ }
+ public String getFileName() {
+ return fileName;
+ }
+ public void setFileName(String fileName) {
+ this.fileName = fileName;
+ }
+
+ public long getMemspyRam() {
+ return memspyRam;
+ }
+ public void setMemspyRam(long memspyRam) {
+ this.memspyRam = memspyRam;
+ }
+ public long getPrevFreeMem() {
+ return prevFreeMem;
+ }
+ public void setPrevFreeMem(long prevFreeMem) {
+ this.prevFreeMem = prevFreeMem;
+ }
+ public String getTime() {
+ return time;
+ }
+ public void setTime(String time) {
+ this.time = time;
+ }
+
+ /**
+ * Clears all the previous data
+ *
+ */
+ public void clear()
+ {
+ if(disksList != null)
+ disksList.clear();
+ if(heapsList != null)
+ heapsList.clear();
+ if(stacksList != null)
+ stacksList.clear();
+ if(globalDataChunksList != null)
+ globalDataChunksList.clear();
+ if(nonRHeapList != null)
+ nonRHeapList.clear();
+ if(chunksList != null)
+ chunksList.clear();
+ if(kernelHandlesList != null)
+ kernelHandlesList.clear();
+ if(filesList != null)
+ filesList.clear();
+ if(psHandlesList != null)
+ psHandlesList.clear();
+ }
+
+ public ArrayList<GlobalDataChunks> getGlobalDataChunksList() {
+ ArrayList<GlobalDataChunks> s = new ArrayList<GlobalDataChunks>();
+ if(globalDataChunksList!=null)
+ for (GlobalDataChunks data: globalDataChunksList)
+ s.add(data);
+ return s;
+ }
+
+ public GlobalDataChunks getGlobalChunkDataFor(String chunkName)
+ {
+ if(globalDataChunksList != null)
+ {
+ for(GlobalDataChunks data : globalDataChunksList)
+ {
+ if(data.getChunkName().equalsIgnoreCase(chunkName))
+ {
+ return data;
+ }
+ }
+ }
+ return null;
+ }
+
+ public ChunksData getChunkDataFor(String chunkName)
+ {
+ if(chunksList != null)
+ {
+ for(ChunksData data : chunksList)
+ {
+ if(data.getChunkName().equalsIgnoreCase(chunkName))
+ {
+ return data;
+ }
+ }
+ }
+ return null;
+ }
+
+ public ArrayList<String> getGlobalChunkNames()
+ {
+ ArrayList<String> chunkNames = new ArrayList<String>();
+
+ if(globalDataChunksList != null)
+ for(GlobalDataChunks glod:globalDataChunksList)
+ chunkNames.add(glod.getChunkName());
+
+ return chunkNames;
+ }
+
+
+
+ public ArrayList<String> getNonHeapChunkNames()
+ {
+ ArrayList<String> chunkNames = new ArrayList<String>();
+
+ if(chunksList != null)
+ for(ChunksData chnk:chunksList)
+ chunkNames.add(chnk.getChunkName());
+
+ return chunkNames;
+ }
+
+ public ArrayList<PSHandlesData> getPsHandlesList() {
+ ArrayList<PSHandlesData> s = new ArrayList<PSHandlesData>();
+ for (PSHandlesData data: psHandlesList)
+ s.add(data);
+
+ return s;
+ }
+
+ public ArrayList<KernelHandles> getGenHandlesList() {
+ ArrayList<KernelHandles> s = new ArrayList<KernelHandles>();
+ for (KernelHandles data: kernelHandlesList)
+ s.add(data);
+
+ return s;
+
+ }
+
+ public ArrayList<DiskData> getDisksList() {
+ ArrayList<DiskData> s = new ArrayList<DiskData>();
+ for (DiskData data: disksList)
+ s.add(data);
+ return s;
+ }
+
+ public ArrayList<HeapData> getHeapsList() {
+ ArrayList<HeapData> s = new ArrayList<HeapData>();
+ for (HeapData data: heapsList)
+ s.add(data);
+ return s;
+ }
+
+ public ArrayList<ChunksData> getChunksList() {
+ ArrayList<ChunksData> s = new ArrayList<ChunksData>();
+ if(chunksList!=null)
+ for (ChunksData data: chunksList)
+ s.add(data);
+ return s;
+ }
+
+ /**
+ *
+ * @returns list of window groups from this cycle.
+ */
+ public ArrayList<WindowGroups> getWindowGroupsData()
+ {
+ ArrayList<WindowGroups> list = new ArrayList<WindowGroups>();
+
+ if(wndgList != null)
+ {
+ for(WindowGroups wndg:wndgList)
+ {
+ list.add(wndg);
+ }
+ }
+
+ return list;
+ }
+ public long getFreeMemory() {
+ return freeMemory;
+ }
+
+ public void setFreeMemory(long freeMemory) {
+ this.freeMemory = freeMemory;
+ }
+
+ public long getTotalMemory() {
+ return totalMemory;
+ }
+
+ public void setTotalMemory(long totalMemory) {
+ this.totalMemory = totalMemory;
+ }
+
+ public String getRomCheckSum() {
+ return romCheckSum;
+ }
+
+ public void setRomCheckSum(String romCheckSum) {
+ this.romCheckSum = romCheckSum;
+ }
+
+ public String getRomVersion() {
+ return romVersion;
+ }
+
+ public void setRomVersion(String romVersion) {
+ this.romVersion = romVersion;
+ }
+
+ /**
+ *
+ * This method returns the data related to various kernel elements.
+ */
+ public KernelElements getAllOpenKernelElements()
+ {
+ KernelElements elements = new KernelElements();
+
+ if(kernelHandlesList != null){
+ for(KernelHandles handle:kernelHandlesList)
+ {
+ if(handle.getHandleType().equals("Timer"))
+ {
+ int count = elements.getNumberOfTimers();
+
+ if(handle.getStatus() == CycleData.New)
+ count++;
+ else if(handle.getStatus() == CycleData.Deleted)
+ count--;
+
+ elements.setNumberOfTimers(count);
+ }
+ else if(handle.getHandleType().equals("Semaphore"))
+ {
+ int count = elements.getNumberOfSemaphores();
+
+ if(handle.getStatus() == CycleData.New)
+ count++;
+ else if(handle.getStatus() == CycleData.Deleted)
+ count--;
+
+ elements.setNumberOfSemaphores(count);
+ }
+ else if(handle.getHandleType().equals("Process"))
+ {
+ int count = elements.getNumberOfProcesses();
+
+ if(handle.getStatus() == CycleData.New)
+ count++;
+ else if(handle.getStatus() == CycleData.Deleted)
+ count--;
+
+ elements.setNumberOfProcesses(count);
+ }
+ else if(handle.getHandleType().equals("Thread"))
+ {
+ int count = elements.getNumberOfThreads();
+
+ if(handle.getStatus() == CycleData.New)
+ count++;
+ else if(handle.getStatus() == CycleData.Deleted)
+ count--;
+
+ elements.setNumberOfThreads(count);
+ }
+ else if(handle.getHandleType().equals("Chunk"))
+ {
+ int count = elements.getNumberOfChunks();
+
+ if(handle.getStatus() == CycleData.New)
+ count++;
+ else if(handle.getStatus() == CycleData.Deleted)
+ count--;
+
+ elements.setNumberOfChunks(count);
+ }
+ else if(handle.getHandleType().equals("Session"))
+ {
+ int count = elements.getNumberOfSessions();
+
+ if(handle.getStatus() == CycleData.New)
+ count++;
+ else if(handle.getStatus() == CycleData.Deleted)
+ count--;
+
+ elements.setNumberOfSessions(count);
+ }
+ else if(handle.getHandleType().equals("Server"))
+ {
+ int count = elements.getNumberOfServers();
+
+ if(handle.getStatus() == CycleData.New)
+ count++;
+ else if(handle.getStatus() == CycleData.Deleted)
+ count--;
+
+ elements.setNumberOfServers(count);
+ }
+ else if(handle.getHandleType().equals("Msg. Queue"))
+ {
+ int count = elements.getNumberOfMsgQueues();
+
+ if(handle.getStatus() == CycleData.New)
+ count++;
+ else if(handle.getStatus() == CycleData.Deleted)
+ count--;
+
+ elements.setNumberOfMsgQueues(count);
+ }
+ }
+ }
+ return elements;
+ }
+
+ public int compareTo(CycleData tmp) {
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd HH:mm:ss");
+ Date aDate=null;
+ Date bDate=null;
+ try {
+ aDate = sdf.parse(this.getTime());
+ bDate = sdf.parse(tmp.getTime());
+ } catch (ParseException e) {
+ e.printStackTrace();
+ }
+
+ if(aDate.before(bDate))
+ {
+ return -1;
+ }
+ else if(aDate.after(bDate))
+ {
+ return 1;
+ }
+ return 0;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/data/DiskData.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,72 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+package com.nokia.s60tools.swmtanalyser.data;
+
+public class DiskData {
+ private String driveName;
+ private long size;
+ private long freeSize;
+ private int status;
+
+ public void setName(String name)
+ {
+ this.driveName = name;
+ }
+ public void setSize(String size)
+ {
+ this.size = Long.parseLong(size);
+ }
+
+ public void setFreeSize(String freeSize)
+ {
+ this.freeSize = Long.parseLong(freeSize);
+ }
+
+ public String getName()
+ {
+ return driveName;
+ }
+
+ /**
+ * @param status
+ * This method sets the status of this handle to New, Alive or Deleted
+ */
+ public void setStatus(String status)
+ {
+ if(status.equals("[N]+[A]"))
+ this.status = CycleData.New;
+ else if (status.equals("[A]"))
+ this.status = CycleData.Alive;
+ else
+ this.status = CycleData.Deleted;
+ }
+ public int getStatus()
+ {
+ return status;
+ }
+
+ public long getFreeSize()
+ {
+ return this.freeSize;
+ }
+
+ public long getSize()
+ {
+ return this.size;
+
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/data/DiskOverview.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,75 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+package com.nokia.s60tools.swmtanalyser.data;
+
+public class DiskOverview {
+
+ private long freeSize;
+ private long size;
+ private int status;
+
+ public DiskOverview(DiskOverview target)
+ {
+ this.freeSize = target.freeSize;
+ this.size = target.size;
+ this.status = target.status;
+ }
+
+ public DiskOverview()
+ {
+ this.freeSize = -1;
+ this.size = -1;
+ }
+
+ public long getFreeSize()
+ {
+ return freeSize;
+ }
+
+ public long getSize()
+ {
+ return size;
+ }
+
+ public long getUsedSize()
+ {
+ if(freeSize == -1 || size == -1)
+ return -1;
+ else
+ return size - freeSize;
+ }
+
+ public void setFreeSize(long freeSize)
+ {
+ this.freeSize = freeSize;
+ }
+
+ public void setSize(long size)
+ {
+ this.size = size;
+ }
+
+ public int getStatus() {
+ return status;
+ }
+
+ public void setStatus(int status) {
+ this.status = status;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/data/FilesData.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,68 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+package com.nokia.s60tools.swmtanalyser.data;
+
+public class FilesData {
+ private String fileName;
+ private String threadName;
+ private long fileSize;
+ private int status;
+
+ public void setFileName(String fileName){
+ this.fileName = fileName;
+ }
+
+ public void setFileSize(String fileSize){
+ this.fileSize = Long.parseLong(fileSize);
+ }
+
+ public void setThreadName(String threadName){
+ this.threadName = threadName;
+ }
+
+ /**
+ * @param status
+ * This method sets the status of this file to New, Alive or Deleted
+ */
+ public void setStatus(String status)
+ {
+ if(status.equals("[N]+[A]"))
+ this.status = CycleData.New;
+ else if (status.equals("[A]"))
+ this.status = CycleData.Alive;
+ else
+ this.status = CycleData.Deleted;
+ }
+
+ public int getStatus()
+ {
+ return status;
+ }
+
+ public String getThreadName(){
+ return threadName;
+ }
+
+ public String getFileName() {
+ return fileName;
+ }
+
+ public long getFileSize() {
+ return fileSize;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/data/GlobalDataChunks.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,77 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+package com.nokia.s60tools.swmtanalyser.data;
+/**
+ * Stores GLOD data from the log files.
+ */
+public class GlobalDataChunks {
+ private String processName;
+ private String chunkName;
+ private String baseAddr;
+ private long size = -1;
+ private int attrib;
+ private boolean isKernelHandleDeleted;
+
+ public GlobalDataChunks(){}
+
+ public GlobalDataChunks(GlobalDataChunks target)
+ {
+ this.chunkName = target.chunkName;
+ this.processName = target.processName;
+ this.baseAddr = target.baseAddr;
+ this.size = target.size;
+ this.attrib = target.attrib;
+ }
+ public int getAttrib() {
+ return attrib;
+ }
+ public void setAttrib(int attrib) {
+ this.attrib = attrib;
+ }
+ public String getBaseAddr() {
+ return baseAddr;
+ }
+ public void setBaseAddr(String baseAddr) {
+ this.baseAddr = baseAddr;
+ }
+ public String getChunkName() {
+ return chunkName;
+ }
+ public void setChunkName(String chunkName) {
+ this.chunkName = chunkName;
+ }
+ public String getProcessName() {
+ return processName;
+ }
+ public void setProcessName(String processName) {
+ this.processName = processName;
+ }
+ public long getSize() {
+ return size;
+ }
+ public void setSize(long size) {
+ this.size = size;
+ }
+
+ public boolean isKernelHandleDeleted() {
+ return isKernelHandleDeleted;
+ }
+
+ public void setKernelHandleDeleted(boolean isKernelHandleDeleted) {
+ this.isKernelHandleDeleted = isKernelHandleDeleted;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/data/HeapData.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,187 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+package com.nokia.s60tools.swmtanalyser.data;
+/**
+ * Stores the HEAP data from the log files.
+ *
+ */
+public class HeapData {
+ private String threadName;
+ private String processName;
+ private String baseAddr;
+ private long size;
+ private long maxSize;
+ private long allocatedCells;
+ private long freeCells;
+ private long allocSpace;
+ private long freeSpace;
+ private long freeSlack;
+ private long largestFreeCell;
+ private long largestAllocCell;
+ private int attrib;
+
+ public void setThreadAndProcessName(String threadName)
+ {
+ int index = threadName.indexOf("::");
+ this.processName = threadName.substring(0, index-1);
+ this.threadName = threadName;
+ }
+
+ public long getAllocatedCells() {
+ return allocatedCells;
+ }
+
+ public void setAllocatedCells(String allocatedCells) {
+ this.allocatedCells = Long.parseLong(allocatedCells);
+ }
+
+ public long getAllocSpace() {
+ return allocSpace;
+ }
+
+ public void setAllocSpace(String allocSpace) {
+ this.allocSpace = Long.parseLong(allocSpace);
+ }
+
+ public String getBaseAddr() {
+ return baseAddr;
+ }
+
+ public void setBaseAddr(String baseAddr) {
+ this.baseAddr = baseAddr;
+ }
+
+ public long getFreeCells() {
+ return freeCells;
+ }
+
+ public void setFreeCells(String freeCells) {
+ this.freeCells = Long.parseLong(freeCells);
+ }
+
+ public long getFreeSlack() {
+ return freeSlack;
+ }
+
+ public void setFreeSlack(String freeSlack) {
+ this.freeSlack = Long.parseLong(freeSlack);
+ }
+
+ public long getFreeSpace() {
+ return freeSpace;
+ }
+
+ public void setFreeSpace(String freeSpace) {
+ this.freeSpace = Long.parseLong(freeSpace);
+ }
+
+ public long getLargestAllocCell() {
+ return largestAllocCell;
+ }
+
+ public void setLargestAllocCell(String largestAllocCell) {
+ this.largestAllocCell = Long.parseLong(largestAllocCell);
+ }
+
+ public long getLargestFreeCell() {
+ return largestFreeCell;
+ }
+
+ public void setLargestFreeCell(String largestFreeCell) {
+ this.largestFreeCell = Long.parseLong(largestFreeCell);
+ }
+
+ public String getProcessName() {
+ return processName;
+ }
+
+ /*public void setProcessName(String processName) {
+ this.processName = processName;
+ }*/
+
+ public long getSize() {
+ return size;
+ }
+
+ public void setSize(String size) {
+ this.size = Long.parseLong(size);
+ }
+
+ public long getMaxSize() {
+ return maxSize;
+ }
+
+ public void setMaxSize(String maxSize) {
+ this.maxSize = Long.parseLong(maxSize);
+ }
+ public String getThreadName() {
+ return threadName;
+ }
+ /**
+ * @param status
+ * This method sets the status of this heap to New, Alive or Deleted
+ */
+ public void setStatus(String status)
+ {
+ if(status.equals("[N]+[A]"))
+ attrib = CycleData.New;
+ else if (status.equals("[A]"))
+ attrib = CycleData.Alive;
+ else
+ attrib = CycleData.Deleted;
+ }
+ public int getStatus()
+ {
+ return attrib;
+ }
+
+ public void setAllocatedCells(long allocatedCells) {
+ this.allocatedCells = allocatedCells;
+ }
+
+ public void setAllocSpace(long allocSpace) {
+ this.allocSpace = allocSpace;
+ }
+ public int getAttrib() {
+ return attrib;
+ }
+ public void setAttrib(int attrib) {
+ this.attrib = attrib;
+ }
+
+ public void setFreeCells(long freeCells) {
+ this.freeCells = freeCells;
+ }
+
+ public void setFreeSlack(long freeSlack) {
+ this.freeSlack = freeSlack;
+ }
+ public void setFreeSpace(long freeSpace) {
+ this.freeSpace = freeSpace;
+ }
+ public void setLargestAllocCell(long largestAllocCell) {
+ this.largestAllocCell = largestAllocCell;
+ }
+ public void setLargestFreeCell(long largestFreeCell) {
+ this.largestFreeCell = largestFreeCell;
+ }
+
+ public void setSize(long size) {
+ this.size = size;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/data/KernelElements.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,85 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+/**
+ * This class contains the information about various kernel elements.
+ */
+package com.nokia.s60tools.swmtanalyser.data;
+/**
+ * Stores kernel handles information
+ *
+ */
+public class KernelElements {
+
+ private int numberOfThreads = 0;
+ private int numberOfProcesses = 0;
+ private int numberOfTimers = 0;
+ private int numberOfSessions = 0;
+ private int numberOfSemaphores = 0;
+ private int numberOfServers = 0;
+ private int numberOfChunks = 0;
+ private int numberOfMsgQueues = 0;
+
+ public int getNumberOfProcesses() {
+ return numberOfProcesses;
+ }
+ public void setNumberOfProcesses(int numberOfProcesses) {
+ this.numberOfProcesses = numberOfProcesses;
+ }
+ public int getNumberOfSemaphores() {
+ return numberOfSemaphores;
+ }
+ public void setNumberOfSemaphores(int numberOfSemaphores) {
+ this.numberOfSemaphores = numberOfSemaphores;
+ }
+ public int getNumberOfServers() {
+ return numberOfServers;
+ }
+ public void setNumberOfServers(int numberOfServers) {
+ this.numberOfServers = numberOfServers;
+ }
+ public int getNumberOfSessions() {
+ return numberOfSessions;
+ }
+ public void setNumberOfSessions(int numberOfSessions) {
+ this.numberOfSessions = numberOfSessions;
+ }
+ public int getNumberOfThreads() {
+ return numberOfThreads;
+ }
+ public void setNumberOfThreads(int numberOfThreads) {
+ this.numberOfThreads = numberOfThreads;
+ }
+ public int getNumberOfTimers() {
+ return numberOfTimers;
+ }
+ public void setNumberOfTimers(int numberOfTimers) {
+ this.numberOfTimers = numberOfTimers;
+ }
+ public int getNumberOfChunks() {
+ return numberOfChunks;
+ }
+ public void setNumberOfChunks(int numberOfChunks) {
+ this.numberOfChunks = numberOfChunks;
+ }
+ public int getNumberOfMsgQueues() {
+ return numberOfMsgQueues;
+ }
+ public void setNumberOfMsgQueues(int numberOfMsgQueues) {
+ this.numberOfMsgQueues = numberOfMsgQueues;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/data/KernelHandles.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,68 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+package com.nokia.s60tools.swmtanalyser.data;
+
+/**
+ * Stores HGEN information
+ *
+ */
+public class KernelHandles {
+
+ private String handleName;
+ private String handle;
+ private String handleType;
+ private int attrib;
+
+ public void setHandleName(String name) {
+ this.handleName = name;
+ }
+ public void setHandle(String handle){
+ this.handle = handle;
+ }
+ public void setHandleType(String handleType){
+ this.handleType = handleType;
+ }
+
+ /**
+ * @param status
+ * This method sets the status of this handle to New, Alive or Deleted
+ */
+ public void setStatus(String status)
+ {
+ if(status.equals("[N]+[A]"))
+ attrib = CycleData.New;
+ else if (status.equals("[A]"))
+ attrib = CycleData.Alive;
+ else
+ attrib = CycleData.Deleted;
+ }
+
+ public int getStatus(){
+ return attrib;
+ }
+
+ public String getHandleType(){
+ return handleType;
+ }
+
+ public String getHandleName(){
+ return handleName;
+ }
+ public String getHandle() {
+ return handle;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/data/OverviewData.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,30 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+package com.nokia.s60tools.swmtanalyser.data;
+
+/**
+ * Stores overview information from all the log files.
+ *
+ */
+public class OverviewData {
+
+ public int noOfcycles;
+ public String fromTime;
+ public String toTime;
+ public long duration;
+ public String durationString;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/data/PSHandlesData.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,89 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+package com.nokia.s60tools.swmtanalyser.data;
+
+/**
+ * Stores HPAS data from the log file.
+ *
+ */
+public class PSHandlesData {
+
+ public static String [] keyTypes = new String [] {"EInt", "EByteArray", "EText", "ELargeByteArray","ELargeText", "ETypeLimit", "ETypeMask"};
+
+ private String handleName;
+ private String handle;
+ private long key;
+ private int keyType;
+ private long threadId;
+ private String threadName;
+ private int attrib;
+
+ public int getStatus()
+ {
+ return attrib;
+ }
+ public String getHandle() {
+ return handle;
+ }
+ public void setHandle(String handle) {
+ this.handle = handle;
+ }
+ public String getHandleName() {
+ return handleName;
+ }
+ public void setHandleName(String handleName) {
+ this.handleName = handleName;
+ }
+ public long getKey() {
+ return key;
+ }
+ public void setKey(long key) {
+ this.key = key;
+ }
+ public int getKeyType() {
+ return keyType;
+ }
+ public void setKeyType(int keyType) {
+ this.keyType = keyType;
+ }
+ public long getThreadId() {
+ return threadId;
+ }
+ public void setThreadId(long threadId) {
+ this.threadId = threadId;
+ }
+ public String getThreadName() {
+ return threadName;
+ }
+ public void setThreadName(String threadName) {
+ this.threadName = threadName;
+ }
+
+ /**
+ * @param status
+ * This method sets the status of this handle to New, Alive or Deleted
+ */
+ public void setStatus(String status)
+ {
+ if(status.equals("[N]+[A]"))
+ attrib = CycleData.New;
+ else if (status.equals("[A]"))
+ attrib = CycleData.Alive;
+ else
+ attrib = CycleData.Deleted;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/data/ParsedData.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,45 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+package com.nokia.s60tools.swmtanalyser.data;
+
+import java.util.ArrayList;
+/**
+ * Stores the cycle data objects of all log files.
+ *
+ */
+public class ParsedData {
+
+ private ArrayList<CycleData> logData;
+
+ public void setParsedData(ArrayList<CycleData> logData){
+ this.logData = logData;
+ }
+
+ public CycleData[] getLogData(){
+ if(this.logData != null)
+ return logData.toArray(new CycleData[0]);
+ else
+ return null;
+ }
+
+ public int getNumberOfCycles(){
+ if(logData == null)
+ return 0;
+ else
+ return logData.size();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/data/StackData.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,64 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+package com.nokia.s60tools.swmtanalyser.data;
+/**
+ * Stores STAK data.
+ *
+ */
+public class StackData {
+ private String threadName;
+ private String chunkName;
+ private long size;
+ private int status;
+
+
+ public String getChunkName() {
+ return chunkName;
+ }
+ public void setChunkName(String chunkName) {
+ this.chunkName = chunkName;
+ }
+ public long getSize() {
+ return size;
+ }
+ public void setSize(String size) {
+ this.size = Long.parseLong(size);
+ }
+ public String getThreadName() {
+ return threadName;
+ }
+ public void setThreadName(String threadName) {
+ this.threadName = threadName;
+ }
+ public int getStatus() {
+ return status;
+ }
+
+ /**
+ * @param status
+ * This method sets the status of this stack to New, Alive or Deleted
+ */
+ public void setStatus(String status)
+ {
+ if(status.equals("[N]+[A]"))
+ this.status = CycleData.New;
+ else if (status.equals("[A]"))
+ this.status = CycleData.Alive;
+ else
+ this.status = CycleData.Deleted;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/data/SystemData.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,52 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+package com.nokia.s60tools.swmtanalyser.data;
+
+/**
+ * This class is used to store RAM information of a cycle
+ */
+public class SystemData {
+ //Free memory
+ private long freeMemory;
+ //Total memory
+ private long totalMemory;
+
+ public long getFreeMemory() {
+ return freeMemory;
+ }
+ public void setFreeMemory(long freeMemory) {
+ this.freeMemory = freeMemory;
+ }
+ public long getTotalMemory() {
+ return totalMemory;
+ }
+ public void setTotalMemory(long usedMemory) {
+ this.totalMemory = usedMemory;
+ }
+
+ public SystemData()
+ {
+ this.freeMemory = -1;
+ this.totalMemory = -1;
+ }
+
+ public SystemData(SystemData target)
+ {
+ this.freeMemory = target.freeMemory;
+ this.totalMemory = target.totalMemory;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/data/ThreadData.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,183 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+package com.nokia.s60tools.swmtanalyser.data;
+
+/**
+ * This class is used to store thread information at one cycle
+ */
+public class ThreadData {
+ private String name; //name of the thread
+ private int cycleNo; //number of the swmt cycle
+ private long heapChunkSize = -1; //size of the heap chunk
+ private long maxHeapSize = -1; //maximum size of the heap
+ private long heapAllocatedSpace = -1; //allocated heap space
+ private long heapFreeSpace = -1; //free heap space
+ private long freeSlackSize = -1; //free slack space
+ private long allocatedCells = -1; //number of allocated cells in the heap
+ private long freeCells = -1; //number of free cells in the heap.
+ private long largestAllocCellSize = -1; //size of the largest allocated cell
+ private long largestFreeCellSize = -1; //size of the largest free cell
+ private long openFiles = 0; //number of open files
+ private long stackSize = -1; //size of stack
+ private long psHandles = 0; //number of p&s handles
+ private boolean isKernelHandleDeleted;
+ private int heapStatus;
+ private int stackStatus;
+
+ /**
+ * Default constructor
+ * @param name name of the thread.
+ */
+ public ThreadData(String name){
+ this.name = name;
+ }
+
+ /**
+ * Copy constructor
+ * @param target thread data to copy initial values from
+ */
+ public ThreadData(ThreadData target)
+ {
+ this.name = target.name;
+ this.heapChunkSize = target.heapChunkSize;
+ this.maxHeapSize = target.maxHeapSize;
+ this.heapAllocatedSpace = target.heapAllocatedSpace;
+ this.heapFreeSpace = target.heapFreeSpace;
+ this.freeSlackSize = target.freeSlackSize;
+ this.allocatedCells = target.allocatedCells;
+ this.freeCells = target.freeCells;
+ this.largestAllocCellSize = target.largestAllocCellSize;
+ this.largestFreeCellSize = target.largestFreeCellSize;
+ this.openFiles = target.openFiles;
+ this.stackSize = target.stackSize;
+ this.psHandles = target.psHandles;
+ this.stackStatus = target.stackStatus;
+ this.heapStatus = target.heapStatus;
+ }
+
+ public long getAllocatedCells() {
+ return allocatedCells;
+ }
+ public void setAllocatedCells(long allocatedCells) {
+ this.allocatedCells = allocatedCells;
+ }
+ public long getFreeCells() {
+ return freeCells;
+ }
+ public void setFreeCells(long freeCells) {
+ this.freeCells = freeCells;
+ }
+ public long getFreeSlackSize() {
+ return freeSlackSize;
+ }
+ public void setFreeSlackSize(long freeSlackSize) {
+ this.freeSlackSize = freeSlackSize;
+ }
+ public long getHeapAllocatedSpace() {
+ return heapAllocatedSpace;
+ }
+ public void setHeapAllocatedSpace(long heapAllocatedSpace) {
+ this.heapAllocatedSpace = heapAllocatedSpace;
+ }
+ public long getHeapChunkSize() {
+ return heapChunkSize;
+ }
+ public void setHeapChunkSize(long heapChunkSize) {
+ this.heapChunkSize = heapChunkSize;
+ }
+ public long getHeapFreeSpace() {
+ return heapFreeSpace;
+ }
+ public void setHeapFreeSpace(long heapFreeSpace) {
+ this.heapFreeSpace = heapFreeSpace;
+ }
+ public long getMaxHeapSize() {
+ return maxHeapSize;
+ }
+ public void setMaxHeapSize(long maxHeapSize) {
+ this.maxHeapSize = maxHeapSize;
+ }
+ public String getName() {
+ return name;
+ }
+
+ public long getOpenFiles() {
+ return openFiles;
+ }
+ public void setOpenFiles(long openFiles) {
+ this.openFiles = openFiles;
+ }
+
+ public long getPsHandles() {
+ return psHandles;
+ }
+ public void setPsHandles(long psHandles) {
+ this.psHandles = psHandles;
+ }
+ public long getStackSize() {
+ return stackSize;
+ }
+ public void setStackSize(long stackSize) {
+ this.stackSize = stackSize;
+ }
+ public long getLargestAllocCellSize() {
+ return largestAllocCellSize;
+ }
+ public void setLargestAllocCellSize(long largestAllocCellSize) {
+ this.largestAllocCellSize = largestAllocCellSize;
+ }
+ public long getLargestFreeCellSize() {
+ return largestFreeCellSize;
+ }
+ public void setLargestFreeCellSize(long largestFreeCellSize) {
+ this.largestFreeCellSize = largestFreeCellSize;
+ }
+ public int getStatus()
+ {
+ return heapStatus;
+ }
+ public void setStatus(int status)
+ {
+ this.heapStatus = status;
+ }
+ public int getStackStatus() {
+ return stackStatus;
+ }
+ public void setStackStatus(int stackStatus) {
+ this.stackStatus = stackStatus;
+ }
+
+ public int getCycleNumber() {
+ return cycleNo;
+ }
+
+ public void setCycleNumber(int cycleNo) {
+ this.cycleNo = cycleNo;
+ }
+
+ public boolean isKernelHandleDeleted() {
+ return isKernelHandleDeleted;
+ }
+
+ public void setKernelHandleDeleted(boolean isKernelHandleDeleted) {
+ this.isKernelHandleDeleted = isKernelHandleDeleted;
+ }
+
+}
+
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/data/ThreadSegments.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,40 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+package com.nokia.s60tools.swmtanalyser.data;
+
+/**
+ * Stores start and end cycle numbers of an instance if the thread has multiple instances.
+ *
+ */
+public class ThreadSegments {
+
+ private int startCycle = -1;
+ private int endCycle = -1;
+
+ public int getStartCycle() {
+ return startCycle;
+ }
+ public void setStartCycle(int startCycle) {
+ this.startCycle = startCycle;
+ }
+ public int getEndCycle() {
+ return endCycle;
+ }
+ public void setEndCycle(int endCycle) {
+ this.endCycle = endCycle;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/data/WindowGroupEventData.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,94 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+package com.nokia.s60tools.swmtanalyser.data;
+
+/**
+ * Data structure to maintain the number of event occurences
+ * for each window group, in each cycle.
+ */
+public class WindowGroupEventData {
+
+ private int event_0_count;
+ private int event_1_count;
+ private int event_2_count;
+ private int event_3_count;
+
+ public WindowGroupEventData(WindowGroupEventData target)
+ {
+ this.event_0_count = target.event_0_count;
+ this.event_1_count = target.event_1_count;
+ this.event_2_count = target.event_2_count;
+ this.event_3_count = target.event_3_count;
+ }
+ public WindowGroupEventData(){}
+
+ public void incrementEventCount(int eventNum)
+ {
+ switch(eventNum)
+ {
+ case 0:
+ event_0_count++;
+ break;
+ case 1:
+ event_1_count++;
+ break;
+ case 2:
+ event_2_count++;
+ break;
+ case 3:
+ event_3_count++;
+ break;
+ }
+ }
+
+ public void decrementEventCount(int eventNum)
+ {
+ switch(eventNum)
+ {
+ case 0:
+ event_0_count--;
+ break;
+ case 1:
+ event_1_count--;
+ break;
+ case 2:
+ event_2_count--;
+ break;
+ case 3:
+ event_3_count--;
+ break;
+ }
+ }
+
+ public int getEvent_0_count() {
+ return event_0_count;
+ }
+
+ public int getEvent_1_count() {
+ return event_1_count;
+ }
+
+ public int getEvent_2_count() {
+ return event_2_count;
+ }
+
+ public int getEvent_3_count() {
+ return event_3_count;
+ }
+
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/data/WindowGroups.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,56 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+package com.nokia.s60tools.swmtanalyser.data;
+
+/**
+ *
+ * Data structure to hold the window group events.
+ *
+ */
+public class WindowGroups {
+
+ private String name;
+ private int id;
+ private int event;
+ private int status;
+ public int getEvent() {
+ return event;
+ }
+ public void setEvent(int event) {
+ this.event = event;
+ }
+ public int getId() {
+ return id;
+ }
+ public void setId(int id) {
+ this.id = id;
+ }
+ public String getName() {
+ return name;
+ }
+ public void setName(String name) {
+ this.name = name;
+ }
+ public int getStatus() {
+ return status;
+ }
+ public void setStatus(int status) {
+ this.status = status;
+ }
+
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/dialogs/AdvancedFilterDialog.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,653 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+package com.nokia.s60tools.swmtanalyser.dialogs;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.events.VerifyEvent;
+import org.eclipse.swt.events.VerifyListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+
+import com.nokia.s60tools.swmtanalyser.analysers.AnalyserConstants;
+import com.nokia.s60tools.swmtanalyser.dialogs.SaveFilterOptions.ValueTypes;
+
+/**
+ * UI Dialog class for Advanced Filter Options.
+ *
+ */
+public class AdvancedFilterDialog extends Dialog implements SelectionListener{
+
+ private Button[] severity_buttons;
+ private Combo delta_dropdown;
+ private Combo delta_dropdown2;
+ private Button filter_button;
+ private Button cancel_button;
+ private Text start_text;
+ private Text end_text;
+ private Text start_text2;
+ private Text end_text2;
+ private String[] delta_filter_type = {"Doesn't matter", "Between", "Equals", "Greater than", "Less than"};
+ private Combo startwith_dropdown;
+ private Text item_name_text;
+ private Button[] ram_and_disk_buttons;
+ private Button[] thread_event_buttons;
+ private Button[] system_events_buttons;
+ private TextVerifyListener verify_listener = new TextVerifyListener();
+ private FilterInput input;
+ private Button reset_button;
+
+ /**
+ * Construction
+ * @param parent shell
+ */
+ public AdvancedFilterDialog(Shell parent) {
+ super(parent);
+ setShellStyle(getShellStyle()|SWT.RESIZE);
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.dialogs.Dialog#createContents(org.eclipse.swt.widgets.Composite)
+ */
+ @Override
+ protected Control createContents(Composite parent) {
+ Composite composite = new Composite(parent, SWT.RESIZE);
+ composite.setLayout(new GridLayout(1, false));
+ composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ composite.setSize(400, 500);
+ composite.getShell().setText("Custom filter");
+
+ Group item_name_grp = new Group(composite, SWT.NONE);
+ item_name_grp.setText("Item name");
+ item_name_grp.setLayout(new GridLayout(3,false));
+ item_name_grp.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+ Label item_label = new Label(item_name_grp, SWT.WRAP);
+ item_label.setText("Item name:");
+
+ startwith_dropdown = new Combo(item_name_grp, SWT.BORDER|SWT.READ_ONLY);
+ startwith_dropdown.setItems(new String[]{"Start with", "Contains"});
+ startwith_dropdown.select(0);
+
+ item_name_text = new Text(item_name_grp, SWT.BORDER);
+ item_name_text.setLayoutData(new GridData(GridData.FILL_HORIZONTAL|GridData.GRAB_HORIZONTAL));
+
+ Group event_name_grp = new Group(composite, SWT.NONE);
+ event_name_grp.setText("Event name");
+ event_name_grp.setLayout(new GridLayout(3,true));
+ event_name_grp.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+ Label eventLabel = new Label(event_name_grp, SWT.WRAP|SWT.BOLD);
+ eventLabel.setText("RAM and Disk memory events:");
+ GridData eventLabelGD = new GridData(GridData.FILL_HORIZONTAL);
+ eventLabelGD.horizontalSpan = 4;
+ eventLabel.setLayoutData(eventLabelGD);
+
+ String[] ram_and_disk_event_names = {"RAM used", "Disk used"};
+ ram_and_disk_buttons = new Button[2];
+ for(int i=0; i<ram_and_disk_buttons.length; i++)
+ {
+ ram_and_disk_buttons[i] = new Button(event_name_grp, SWT.CHECK);
+ ram_and_disk_buttons[i].setText(ram_and_disk_event_names[i]);
+ }
+
+ Label thread_events_label = new Label(event_name_grp, SWT.WRAP|SWT.BOLD);
+ thread_events_label.setText("Thread events:");
+ thread_events_label.setLayoutData(eventLabelGD);
+
+ String[] thread_event_names = {"Heap size", "Heap allocated space", "Heap allocated cell count", "No of Files", "No of PS Handles"};
+ thread_event_buttons = new Button[thread_event_names.length];
+ for (int i = 0; i < thread_event_buttons.length; i++) {
+ thread_event_buttons[i] = new Button(event_name_grp, SWT.CHECK);
+ thread_event_buttons[i].setText(thread_event_names[i]);
+ }
+
+ Label system_events_label = new Label(event_name_grp, SWT.WRAP|SWT.BOLD);
+ system_events_label.setText("System data events:");
+ system_events_label.setLayoutData(eventLabelGD);
+
+ String[] system_event_names = {"System Data"};
+ system_events_buttons = new Button[system_event_names.length];
+ for (int i = 0; i < system_events_buttons.length; i++) {
+ system_events_buttons[i] = new Button(event_name_grp, SWT.CHECK);
+ system_events_buttons[i].setText(system_event_names[i]);
+ }
+
+ Group severity_grp = new Group(composite, SWT.NONE);
+ severity_grp.setText("Severity");
+ severity_grp.setLayout(new GridLayout(4, true));
+ severity_grp.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+ String[] severity_names = {"All", "Critical", "High", "Normal"};
+ severity_buttons = new Button[4];
+ for (int i = 0; i < severity_buttons.length; i++) {
+ severity_buttons[i] = new Button(severity_grp, SWT.CHECK);
+ severity_buttons[i].setText(severity_names[i]);
+ severity_buttons[i].setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ severity_buttons[i].addSelectionListener(this);
+ severity_buttons[i].setEnabled(false);
+ }
+ severity_buttons[0].setEnabled(true);
+ severity_buttons[0].setSelection(true);
+
+ Group delta_grp = new Group(composite, SWT.NONE);
+ delta_grp.setText("Delta");
+ delta_grp.setLayout(new GridLayout(5, false));
+ delta_grp.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+ Label delta_label = new Label(delta_grp, SWT.WRAP);
+ delta_label.setText("Delta (bytes):");
+
+ delta_dropdown = new Combo(delta_grp, SWT.BORDER|SWT.READ_ONLY);
+ delta_dropdown.setItems(delta_filter_type);
+ delta_dropdown.select(0);
+ delta_dropdown.addSelectionListener(this);
+
+ GridData textGD = new GridData(GridData.FILL);
+ textGD.widthHint = 100;
+ start_text = new Text(delta_grp, SWT.BORDER);
+ start_text.setText("0");
+ start_text.setLayoutData(textGD);
+ start_text.setEnabled(false);
+ start_text.addVerifyListener(verify_listener);
+
+ Label and_label = new Label(delta_grp, SWT.WRAP);
+ and_label.setText("and");
+
+ end_text = new Text(delta_grp, SWT.BORDER);
+ end_text.setText("0");
+ end_text.setLayoutData(textGD);
+ end_text.setEnabled(false);
+ end_text.addVerifyListener(verify_listener);
+
+ Label delta_label2 = new Label(delta_grp, SWT.WRAP);
+ delta_label2.setText("Delta (count):");
+
+ delta_dropdown2 = new Combo(delta_grp, SWT.BORDER|SWT.READ_ONLY);
+ delta_dropdown2.setItems(delta_filter_type);
+ delta_dropdown2.select(0);
+ delta_dropdown2.addSelectionListener(this);
+
+ start_text2 = new Text(delta_grp, SWT.BORDER);
+ start_text2.setText("0");
+ start_text2.setLayoutData(textGD);
+ start_text2.setEnabled(false);
+ start_text2.addVerifyListener(verify_listener);
+
+ Label and_label2 = new Label(delta_grp, SWT.WRAP);
+ and_label2.setText("and");
+
+ end_text2 = new Text(delta_grp, SWT.BORDER);
+ end_text2.setText("0");
+ end_text2.setLayoutData(textGD);
+ end_text2.setEnabled(false);
+ end_text2.addVerifyListener(verify_listener);
+
+ restorePreviousValues();
+ return super.createContents(composite);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.dialogs.Dialog#createButtonsForButtonBar(org.eclipse.swt.widgets.Composite)
+ */
+ @Override
+ protected void createButtonsForButtonBar(Composite parent) {
+ filter_button = this.createButton(parent, IDialogConstants.OK_ID, "Filter", true);
+ filter_button.addSelectionListener(this);
+ reset_button = this.createButton(parent, IDialogConstants.DESELECT_ALL_ID, "Reset", false);
+ reset_button.addSelectionListener(this);
+ cancel_button = this.createButton(parent, IDialogConstants.CANCEL_ID, "Cancel", false);
+ cancel_button.addSelectionListener(this);
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.swt.events.SelectionListener#widgetDefaultSelected(org.eclipse.swt.events.SelectionEvent)
+ */
+ public void widgetDefaultSelected(SelectionEvent e) {
+ if(e.widget == severity_buttons[0])
+ {
+ for (int i = 1; i < severity_buttons.length; i++) {
+ severity_buttons[i].setEnabled(false);
+ }
+ }
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt.events.SelectionEvent)
+ */
+ public void widgetSelected(SelectionEvent e) {
+ if(e.widget == severity_buttons[0])
+ {
+ for (int i = 1; i < severity_buttons.length; i++) {
+ severity_buttons[i].setEnabled(!severity_buttons[0].getSelection());
+ }
+ }
+ else if(e.widget == delta_dropdown)
+ {
+ changeTextBoxStatus(delta_dropdown, start_text, end_text);
+ }
+ else if(e.widget == delta_dropdown2)
+ {
+ changeTextBoxStatus(delta_dropdown2, start_text2, end_text2);
+ }
+ }
+
+ /**
+ * Get filter options
+ * @return options
+ */
+ public FilterInput getFilterOptions()
+ {
+ return input;
+ }
+
+ /**
+ * Enable/Disable the To and From text boxes based on the selection
+ * @param drop_down Combo
+ * @param start To Text box
+ * @param end From Text box
+ */
+ private void changeTextBoxStatus(Combo drop_down, Text start, Text end)
+ {
+ int i = drop_down.getSelectionIndex();
+ switch (i) {
+ case 0:
+ start.setEnabled(false);
+ end.setEnabled(false);
+ break;
+ case 1:
+ start.setEnabled(true);
+ end.setEnabled(true);
+ break;
+ case 2:
+ start.setEnabled(true);
+ end.setEnabled(false);
+ break;
+ case 3:
+ start.setEnabled(true);
+ end.setEnabled(false);
+ break;
+ case 4:
+ start.setEnabled(true);
+ end.setEnabled(false);
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ /**
+ * Helper class to store all settings in the Advanced Dialog
+ *
+ */
+ public class FilterInput
+ {
+ int filter_option;
+ String filter_text;
+ String[] events;
+ AnalyserConstants.Priority[] severities;
+ int delta_bytes_option;
+ long start_size;
+ long end_size;
+ int delta_count_option;
+ long start_count;
+ long end_count;
+ public int getDelta_count_option() {
+ return delta_count_option;
+ }
+ public void setDelta_count_option(int delta_count_option) {
+ this.delta_count_option = delta_count_option;
+ }
+ public int getDelta_bytes_option() {
+ return delta_bytes_option;
+ }
+ public void setDelta_kb_option(int delta_kb_option) {
+ this.delta_bytes_option = delta_kb_option;
+ }
+ public long getEnd_count() {
+ return end_count;
+ }
+ public void setEnd_count(long end_count) {
+ this.end_count = end_count;
+ }
+ public long getEnd_size() {
+ return end_size;
+ }
+ public void setEnd_size(long end_size) {
+ this.end_size = end_size;
+ }
+ public String[] getEvents() {
+ return events;
+ }
+ public void setEvents(String[] events) {
+ this.events = events;
+ }
+ public int getName_Filter_option() {
+ return filter_option;
+ }
+ private void setFilter_option(int filter_option) {
+ this.filter_option = filter_option;
+ }
+ public String getFilter_text() {
+ return filter_text;
+ }
+ public void setFilter_text(String filter_text) {
+ this.filter_text = filter_text;
+ }
+ public AnalyserConstants.Priority[] getSeverities() {
+ return severities;
+ }
+ public void setSeverities(AnalyserConstants.Priority[] severities) {
+ this.severities = severities;
+ }
+ public long getStart_count() {
+ return start_count;
+ }
+ public void setStart_count(long start_count) {
+ this.start_count = start_count;
+ }
+ public long getStart_size() {
+ return start_size;
+ }
+ public void setStart_size(long start_size) {
+ this.start_size = start_size;
+ }
+
+ }
+
+ /**
+ * Verify Listener to stop typing alphabetics in the To and From text boxes.
+ *
+ */
+ private class TextVerifyListener implements VerifyListener
+ {
+ public void verifyText(VerifyEvent event) {
+ switch (event.keyCode) {
+ case SWT.BS: // Backspace
+ case SWT.DEL: // Delete
+ case SWT.HOME: // Home
+ case SWT.END: // End
+ case SWT.ARROW_LEFT: // Left arrow
+ case SWT.ARROW_RIGHT: // Right arrow
+ return;
+ }
+ if (!Character.isDigit(event.character)) {
+ event.doit = false; // disallow the action
+ }
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.dialogs.Dialog#okPressed()
+ */
+ @Override
+ protected void okPressed() {
+ saveValues();
+ input = new FilterInput();
+ input.setFilter_option(startwith_dropdown.getSelectionIndex());
+ input.setFilter_text(item_name_text.getText());
+
+ input.setEvents(getSelectedEvents());
+
+ ArrayList<AnalyserConstants.Priority> severities = new ArrayList<AnalyserConstants.Priority>();
+ for (int i = 0; i < severity_buttons.length; i++) {
+ if(i==0 && severity_buttons[i].getSelection())
+ break;
+ else if(severity_buttons[i].getSelection())
+ severities.add(AnalyserConstants.Priority.valueOf(severity_buttons[i].getText().toUpperCase()));
+ }
+ input.setSeverities(severities.toArray(new AnalyserConstants.Priority[0]));
+
+ input.setDelta_kb_option(delta_dropdown.getSelectionIndex());
+ input.setStart_size(Long.parseLong(start_text.getText()));
+ input.setEnd_size(Long.parseLong(end_text.getText()));
+
+ input.setDelta_count_option(delta_dropdown2.getSelectionIndex());
+ input.setStart_count(Long.parseLong(start_text2.getText()));
+ input.setEnd_count(Long.parseLong(end_text2.getText()));
+
+ if(getShell()!=null)
+ getShell().dispose();
+ setReturnCode(Dialog.OK);
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.dialogs.Dialog#buttonPressed(int)
+ */
+ @Override
+ protected void buttonPressed(int buttonId) {
+
+ if(buttonId == IDialogConstants.DESELECT_ALL_ID)
+ {
+ startwith_dropdown.select(0);
+ item_name_text.setText("");
+ for (int i = 0; i < ram_and_disk_buttons.length; i++) {
+ ram_and_disk_buttons[i].setSelection(false);
+ }
+ for (int i = 0; i < thread_event_buttons.length; i++) {
+ thread_event_buttons[i].setSelection(false);
+ }
+ for (int i = 0; i < system_events_buttons.length; i++) {
+ system_events_buttons[i].setSelection(false);
+ }
+ severity_buttons[0].setSelection(true);
+ severity_buttons[0].notifyListeners(SWT.Selection, new Event());
+ delta_dropdown.select(0);
+ delta_dropdown.notifyListeners(SWT.Selection, new Event());
+ delta_dropdown2.select(0);
+ delta_dropdown2.notifyListeners(SWT.Selection, new Event());
+ }
+ super.buttonPressed(buttonId);
+ }
+
+ /**
+ * Returns string array of all selected events
+ * @return events
+ */
+ public String[] getSelectedEvents()
+ {
+ ArrayList<String> events = new ArrayList<String>();
+ for (int i = 0; i < ram_and_disk_buttons.length; i++) {
+ if(ram_and_disk_buttons[i].getSelection())
+ events.add(ram_and_disk_buttons[i].getText());
+ }
+ for (int i = 0; i < thread_event_buttons.length; i++) {
+ if(thread_event_buttons[i].getSelection())
+ events.add(thread_event_buttons[i].getText());
+ }
+ for (int i = 0; i < system_events_buttons.length; i++) {
+ if(system_events_buttons[i].getSelection())
+ events.add(system_events_buttons[i].getText());
+ }
+ return events.toArray(new String[events.size()]);
+ }
+
+ /**
+ * Returns array of selected severities. If the array size is 0, then assume that all severities selected.
+ * @return severities array
+ */
+ public String[] getSelectedSeverities()
+ {
+ ArrayList<String> severities = new ArrayList<String>();
+ for (int i = 1; i < severity_buttons.length; i++) {
+ if(severity_buttons[i].getSelection())
+ severities.add(severity_buttons[i].getText());
+ }
+ return severities.toArray(new String[0]);
+ }
+
+ /**
+ * Returns start and end values for the delta to search.
+ * @param drop_down
+ * @param start
+ * @param end
+ * @return
+ */
+ private String[] getToFromValues(Combo drop_down, Text start, Text end)
+ {
+ int i = drop_down.getSelectionIndex();
+ String[] values = null;
+ switch (i) {
+ case 0:
+ break;
+ case 1:
+ values = new String[2];
+ values[0] = start.getText();
+ values[1] = end.getText();
+ break;
+ case 2:
+ values = new String[1];
+ values[0] = start.getText();
+ break;
+ case 3:
+ values = new String[1];
+ values[0] = start.getText();
+ break;
+ case 4:
+ values = new String[1];
+ values[0] = start.getText();
+ break;
+ default:
+ break;
+ }
+ return values;
+ }
+
+ /**
+ * Saves values to dialog settings.
+ *
+ */
+ private void saveValues() {
+ SaveFilterOptions save = new SaveFilterOptions();
+ save.saveDropdownOption(ValueTypes.FILTER_TYPE, startwith_dropdown.getText());
+ save.saveDropdownOption(ValueTypes.ITEM_TEXT, item_name_text.getText());
+ String[] events = getSelectedEvents();
+ save.saveValues(ValueTypes.EVENTS, events);
+ String[] severities = getSelectedSeverities();
+ save.saveValues(ValueTypes.SEVERITIES, severities);
+ save.saveDropdownOption(ValueTypes.SIZE_TYPE, delta_dropdown.getText());
+ save.saveValues(ValueTypes.SIZES, getToFromValues(delta_dropdown,start_text, end_text));
+ save.saveDropdownOption(ValueTypes.COUNT_TYPE, delta_dropdown2.getText());
+ save.saveValues(ValueTypes.COUNTS, getToFromValues(delta_dropdown2,start_text2, end_text2));
+ }
+
+ /**
+ * Restore privious values and shows in advanced dialog.
+ *
+ */
+ private void restorePreviousValues() {
+ SaveFilterOptions restore = new SaveFilterOptions();
+
+ String filter_option = restore.getPreviousDropdownOption(ValueTypes.FILTER_TYPE);
+ if(filter_option!=null)
+ startwith_dropdown.select(startwith_dropdown.indexOf(filter_option));
+ String filter_text = restore.getPreviousDropdownOption(ValueTypes.ITEM_TEXT);
+ if(filter_text!=null)
+ item_name_text.setText(filter_text);
+ String[] events = restore.getValues(ValueTypes.EVENTS);
+ String[] severities = restore.getValues(ValueTypes.SEVERITIES);
+ String delta_size_option = restore.getPreviousDropdownOption(ValueTypes.SIZE_TYPE);
+ String[] sizes = restore.getValues(ValueTypes.SIZES);
+ String delta_count_option = restore.getPreviousDropdownOption(ValueTypes.COUNT_TYPE);
+ String[] counts = restore.getValues(ValueTypes.COUNTS);
+
+ List<String> events_list = new ArrayList<String>();
+ if(events!=null)
+ events_list = Arrays.asList(events);
+ List<String> severity_list = new ArrayList<String>();
+ if(severities!=null)
+ severity_list = Arrays.asList(severities);
+
+ for (int i = 0; i < ram_and_disk_buttons.length; i++) {
+ if(events_list.contains(ram_and_disk_buttons[i].getText()))
+ ram_and_disk_buttons[i].setSelection(true);
+ }
+ for (int i = 0; i < thread_event_buttons.length; i++) {
+ if(events_list.contains(thread_event_buttons[i].getText()))
+ thread_event_buttons[i].setSelection(true);
+ }
+ for (int i = 0; i < system_events_buttons.length; i++) {
+ if(events_list.contains(system_events_buttons[i].getText()))
+ system_events_buttons[i].setSelection(true);
+ }
+ for (int i = 1; i < severity_buttons.length; i++) {
+ if(severity_list.contains(severity_buttons[i].getText()))
+ {
+ severity_buttons[0].setSelection(false);
+ severity_buttons[0].notifyListeners(SWT.Selection, new Event());
+ severity_buttons[i].setSelection(true);
+ }
+ }
+ if(delta_size_option!=null)
+ {
+ delta_dropdown.select(delta_dropdown.indexOf(delta_size_option));
+ delta_dropdown.notifyListeners(SWT.Selection, new Event());
+
+ //setText will not work if the verify listener is there.
+ //So, remove it for temporary
+ start_text.removeVerifyListener(verify_listener);
+ end_text.removeVerifyListener(verify_listener);
+ if(sizes!=null && sizes.length == 2)
+ {
+ start_text.setText(sizes[0]);
+ end_text.setText(sizes[1]);
+ }
+ else if(sizes!=null && sizes.length == 1)
+ {
+ start_text.setText(sizes[0]);
+ }
+ //Add listeners again
+ start_text.addVerifyListener(verify_listener);
+ end_text.addVerifyListener(verify_listener);
+ }
+
+ if(delta_count_option!=null)
+ {
+ delta_dropdown2.select(delta_dropdown2.indexOf(delta_count_option));
+ delta_dropdown2.notifyListeners(SWT.Selection, new Event());
+
+ //setText will not work if the verify listener is there.
+ //So, remove it for temporary
+ start_text2.removeVerifyListener(verify_listener);
+ end_text2.removeVerifyListener(verify_listener);
+ if(counts!=null && counts.length == 2)
+ {
+ start_text2.setText(counts[0]);
+ end_text2.setText(counts[1]);
+ }
+ else if(counts!=null && counts.length == 1)
+ start_text2.setText(counts[0]);
+
+ //Add listeners again
+ start_text2.addVerifyListener(verify_listener);
+ end_text2.addVerifyListener(verify_listener);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/dialogs/SaveFilterOptions.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,217 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+package com.nokia.s60tools.swmtanalyser.dialogs;
+
+import org.eclipse.jface.dialogs.IDialogSettings;
+
+import com.nokia.s60tools.swmtanalyser.SwmtAnalyserPlugin;
+
+/**
+ * Helper class to store the selections in Advanced Filter Dialog.
+ *
+ */
+public class SaveFilterOptions {
+
+ public static final String FILTER_OPTION_SECTION = "Filter Selection Section";
+ public static final String FILTER_OPTION = "Filter Selection";
+
+ public static final String FILTER_TEXT_SECTION = "Filter Text Section";
+ public static final String FILTER_TEXT = "Filter text";
+
+ public static final String EVENTS_SECTION = "Events Section";
+ public static final String EVENTS_LIST = "List of events";
+
+ public static final String SEVERITY_SECTION = "Severity Section";
+ public static final String SEVERITY_LIST = "List of severities";
+
+ public static final String SIZE_OPTION_SECTION = "Size Selection Section";
+ public static final String SIZE_OPTION = "Size Selection";
+
+ public static final String COUNT_OPTION_SECTION = "Count Selection Section";
+ public static final String COUNT_OPTION = "Count Selection";
+
+ public static final String SIZES_SECTION = "Sizes Section";
+ public static final String TO_FROM_SIZES = "Sizes";
+
+ public static final String COUNTS_SECTION = "Counts Section";
+ public static final String TO_FROM_COUNT = "Counts";
+
+ public static enum ValueTypes {FILTER_TYPE, ITEM_TEXT, EVENTS, SEVERITIES, SIZE_TYPE, COUNT_TYPE, SIZES, COUNTS}
+
+
+ /**
+ * Save selected values
+ * @see #getValues(ValueTypes)
+ * @param key
+ * @param values
+ */
+ public void saveValues(ValueTypes key, String[] values) {
+ IDialogSettings section = null;
+ switch (key) {
+ case EVENTS:
+ section = getSection(EVENTS_SECTION);
+ if(section!=null)
+ section.put(EVENTS_LIST, values);
+ break;
+ case SEVERITIES:
+ section = getSection(SEVERITY_SECTION);
+ if(section!=null)
+ section.put(SEVERITY_LIST, values);
+ break;
+ case SIZES:
+ section = getSection(SIZES_SECTION);
+ if(section!=null)
+ section.put(TO_FROM_SIZES, values);
+ break;
+ case COUNTS:
+ section = getSection(COUNTS_SECTION);
+ if(section!=null)
+ section.put(TO_FROM_COUNT, values);
+
+ break;
+ default:
+ break;
+ }
+ }
+
+ /**
+ * Get values for type
+ * @see #saveValues(ValueTypes, String[])
+ * @param key
+ * @return values
+ */
+ public String[] getValues(ValueTypes key)
+ {
+ IDialogSettings section = null;
+ String[] values = null;
+ switch (key) {
+ case EVENTS:
+ section = getSection(EVENTS_SECTION);
+ if(section != null)
+ values = section.getArray(EVENTS_LIST);
+ break;
+ case SEVERITIES:
+ section = getSection(SEVERITY_SECTION);
+ if(section != null)
+ values = section.getArray(SEVERITY_LIST);
+ break;
+ case SIZES:
+ section = getSection(SIZES_SECTION);
+ if(section != null)
+ values = section.getArray(TO_FROM_SIZES);
+ break;
+ case COUNTS:
+ section = getSection(COUNTS_SECTION);
+ if(section != null)
+ values = section.getArray(TO_FROM_COUNT);
+ break;
+ default:
+ break;
+ }
+ return values;
+ }
+
+ /**
+ * Save selected value using that in next time when dialog is opened
+ * @see #getPreviousDropdownOption(ValueTypes)
+ * @see #getValues(ValueTypes) for indexes
+ * @param key
+ * @param index
+ */
+ public void saveDropdownOption(ValueTypes key, String index)
+ {
+ IDialogSettings section = null;
+ switch (key) {
+ case SIZE_TYPE:
+ section = getSection(SIZE_OPTION_SECTION);
+ if(section!=null)
+ section.put(SIZE_OPTION, index);
+ break;
+
+ case COUNT_TYPE:
+ section = getSection(COUNT_OPTION_SECTION);
+ if(section!=null)
+ section.put(COUNT_OPTION, index);
+ break;
+ case FILTER_TYPE:
+ section = getSection(FILTER_OPTION_SECTION);
+ if(section!=null)
+ section.put(FILTER_OPTION, index);
+ break;
+ case ITEM_TEXT:
+ section = getSection(FILTER_TEXT_SECTION);
+ if(section!=null)
+ section.put(FILTER_TEXT, index);
+ break;
+ default:
+ break;
+ }
+ }
+
+ /**
+ * Get previously selected value for type
+ * @see #saveDropdownOption(ValueTypes, String)
+ * @param key
+ * @return previously selected value for type (one of the public constants described in this class).
+ */
+ public String getPreviousDropdownOption(ValueTypes key)
+ {
+ IDialogSettings section = null;
+ String index = null;
+ switch (key) {
+ case SIZE_TYPE:
+ section = getSection(SIZE_OPTION_SECTION);
+ if(section != null)
+ index = section.get(SIZE_OPTION);
+ break;
+ case COUNT_TYPE:
+ section = getSection(COUNT_OPTION_SECTION);
+ if(section != null)
+ index = section.get(COUNT_OPTION);
+ break;
+ case FILTER_TYPE:
+ section = getSection(FILTER_OPTION_SECTION);
+ if(section != null)
+ index = section.get(FILTER_OPTION);
+ break;
+ case ITEM_TEXT:
+ section = getSection(FILTER_TEXT_SECTION);
+ if(section != null)
+ index = section.get(FILTER_TEXT);
+ break;
+ default:
+ break;
+ }
+ return index;
+ }
+
+ /**
+ * @param sectionName name of the section to be retrieved
+ * @return section which maps to given name, in dialog_setting.xml file.
+ */
+ protected IDialogSettings getSection(String sectionName) {
+ IDialogSettings retVal = null;
+ if (SwmtAnalyserPlugin.getDefault().getDialogSettings() != null) {
+ retVal = SwmtAnalyserPlugin.getDefault().getDialogSettings().getSection(sectionName);
+ if (retVal == null) {
+ retVal = SwmtAnalyserPlugin.getDefault().getDialogSettings().addNewSection(sectionName);
+ }
+ }
+ return retVal;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/editors/FilterTextTable.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,438 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+package com.nokia.s60tools.swmtanalyser.editors;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Random;
+import java.util.Map.Entry;
+
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.action.IMenuListener;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.viewers.CheckStateChangedEvent;
+import org.eclipse.jface.viewers.CheckboxTableViewer;
+import org.eclipse.jface.viewers.ICheckStateListener;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerSorter;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swt.widgets.TableColumn;
+import org.eclipse.swt.widgets.Text;
+
+import com.nokia.s60tools.swmtanalyser.ui.actions.CopyToClipboardAction;
+import com.nokia.s60tools.swmtanalyser.ui.actions.ISelectionProvider;
+import com.nokia.s60tools.swmtanalyser.ui.graphs.IGraphTypeSelectionListener;
+import com.nokia.s60tools.util.debug.DbgUtility;
+
+/**
+ * Customized TableViewer UI class for showing items in Graphs Tab.
+ *
+ */
+public class FilterTextTable extends Composite implements ISelectionProvider{
+
+
+ /**
+ * Copy a to clipboard action
+ */
+ private IAction actionContextMenuCopyTo;
+
+ //Check box Table Viewer
+ private CheckboxTableViewer tableViewer;
+ //Text box to filter items in table
+ private Text filterText;
+ //Drop down to select filter type -> 'Start with' or -> 'Contains'
+ private Combo filterTypes;
+ //Label for showing the numbr of checked elements
+ private Label statusLabel;
+ //Viewer filter for tableviewer
+ private TableTextFilter textFilter;
+ private IGraphTypeSelectionListener graphListener;
+ //Checkbox state change listener
+ private CheckBoxStateChangeListener listener;
+ //Temporary elements
+ private String tableName;
+ /**
+ * Item names for creating {@link TableViewerInputObject}
+ */
+ ArrayList<String> input = new ArrayList<String>();
+
+ /**
+ * Save all checked elements in this
+ */
+ Map<String, Color> checked = new HashMap<String, Color>();
+ /**
+ * Threads
+ */
+ static final String THREADS_TITLE = "Threads";
+ /**
+ * Chunks
+ */
+ static final String CHUNKS_TITLE = "Chunks";
+ /**
+ * Disks
+ */
+ static final String DISKS_TITLE = "Disks";
+ /**
+ * System Data
+ */
+ static final String SYSTEM_DATA_TITLE = "System Data";
+
+ /**
+ * Construction
+ * @param graphListener
+ * @param composite
+ * @param columnName
+ */
+ public FilterTextTable(IGraphTypeSelectionListener graphListener, Composite composite, String columnName) {
+
+ super(composite, SWT.NONE);
+
+ this.tableName = columnName;
+ this.graphListener = graphListener;
+
+ setLayout(new GridLayout(2, false));
+ GridData g = new GridData(GridData.FILL_BOTH);
+ setLayoutData(g);
+
+ filterText = new Text(this, SWT.BORDER);
+ filterText.setText("type filter text");
+ GridData gd = new GridData(GridData.FILL_HORIZONTAL);
+ gd.grabExcessHorizontalSpace = true;
+ gd.grabExcessVerticalSpace = false;
+ gd.verticalAlignment = SWT.TOP;
+ filterText.setLayoutData(gd);
+ filterText.selectAll();
+ textFilter = new TableTextFilter(1);
+
+ filterText.addModifyListener(new ModifyListener(){
+ public void modifyText(ModifyEvent e) {
+ String t = ((Text)e.widget).getText();
+ textFilter.setFilterText(t);
+ textFilter.setFilterTypeIndex(filterTypes.getSelectionIndex());
+ refreshTableContents();
+ }
+
+ });
+
+ filterTypes = new Combo(this, SWT.BORDER|SWT.READ_ONLY);
+ filterTypes.setItems(new String[]{"Starts with", "Contains"});
+ GridData data = new GridData();
+ data.widthHint = 100;
+ data.heightHint = 15;
+ filterTypes.select(0);
+ filterTypes.setLayoutData(data);
+ filterTypes.addSelectionListener(new SelectionListener() {
+ /* (non-Javadoc)
+ * @see org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt.events.SelectionEvent)
+ */
+ public void widgetSelected(SelectionEvent e) {
+ textFilter.setFilterTypeIndex(filterTypes.getSelectionIndex());
+ refreshTableContents();
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.swt.events.SelectionListener#widgetDefaultSelected(org.eclipse.swt.events.SelectionEvent)
+ */
+ public void widgetDefaultSelected(SelectionEvent e) {
+ // Not needed/used
+ }
+ });
+
+ tableViewer = CheckboxTableViewer.newCheckList(this, SWT.BORDER|SWT.FULL_SELECTION | SWT.MULTI);
+ GridData tableData = new GridData(GridData.FILL_BOTH);
+ tableData.horizontalSpan = 2;
+
+ tableViewer.getTable().setLayoutData(tableData);
+
+ TableColumn tc = new TableColumn(tableViewer.getTable(), SWT.CENTER);
+ tc.setWidth(50);
+ tc.setResizable(true);
+
+ TableColumn tc1 = new TableColumn(tableViewer.getTable(), SWT.LEFT);
+ tc1.setText(columnName);
+ tc1.setWidth(400);
+ tc1.setResizable(true);
+ tc1.addListener(SWT.Selection, new Listener(){
+ public void handleEvent(Event event) {
+ TableColumn sortedColumn = tableViewer.getTable().getSortColumn();
+ TableColumn currentSelected = (TableColumn)event.widget;
+
+ int dir = tableViewer.getTable().getSortDirection();
+
+ if(sortedColumn == currentSelected){
+ dir = dir == SWT.UP ? SWT.DOWN : SWT.UP;
+ }else
+ {
+ tableViewer.getTable().setSortColumn(currentSelected);
+ dir = SWT.UP;
+ }
+ if(currentSelected == tableViewer.getTable().getColumn(1))
+ {
+ tableViewer.setSorter(new Sorter(dir));
+ }
+ tableViewer.getTable().setSortDirection(dir);
+ }
+ });
+
+ tableViewer.getTable().setHeaderVisible(true);
+ tableViewer.getTable().setLinesVisible(true);
+ tableViewer.setContentProvider(new TableStructuredContentProvider(this));
+ tableViewer.setLabelProvider(new TableLabelColorProvider());
+
+ listener = new CheckBoxStateChangeListener();
+ tableViewer.addCheckStateListener(listener);
+
+ tableViewer.addFilter(textFilter);
+
+ GridData lGd = new GridData(GridData.FILL_HORIZONTAL);
+ lGd.verticalAlignment = GridData.END;
+ statusLabel = new Label(this, SWT.NONE);
+ statusLabel.setText("Selected : 0");
+ statusLabel.setLayoutData(lGd);
+
+
+ actionContextMenuCopyTo = new CopyToClipboardAction(this);
+
+ //
+ // Context menu
+ //
+ MenuManager menuMgr = new MenuManager("#ContextMenu1");
+ menuMgr.setRemoveAllWhenShown(true);
+ menuMgr.addMenuListener(new IMenuListener() {
+ public void menuAboutToShow(IMenuManager manager) {
+ FilterTextTable.this.populateContextMenu(manager);
+ }
+ });
+ Menu menu = menuMgr.createContextMenu(tableViewer.getTable());
+ tableViewer.getTable().setMenu(menu);
+ }
+
+ /**
+ * Refreshes data table contents.
+ */
+ private void refreshTableContents() {
+ //Refresh in separate thread to avoid invalid thread access.
+ Runnable runnable = new Runnable(){
+ public void run() {
+ tableViewer.refresh();
+ }
+ };
+ Display.getDefault().syncExec(runnable);
+
+ //After refresh, check the elements again if any selected before.
+ Iterator<Entry<String, Color>> itr = checked.entrySet().iterator();
+ while(itr.hasNext())
+ {
+ Entry<String, Color> entry = itr.next();
+ for(int i=0; i < tableViewer.getTable().getItemCount(); i++)
+ {
+ TableViewerInputObject objNow = (TableViewerInputObject)tableViewer.getElementAt(i);
+ //If name is same, then update the color and object
+ if(entry.getKey().equals(objNow.getName()))
+ {
+ tableViewer.setChecked(objNow, true);
+ tableViewer.getTable().getItem(i).setBackground(0, entry.getValue());
+ objNow.setColor(entry.getValue());
+ CheckStateChangedEvent ev = new CheckStateChangedEvent(tableViewer, objNow, true);
+ listener.checkStateChanged(ev);
+ }
+ }
+ }
+
+ //If in the filtered list no selection is there, then clear the graph
+ if(tableViewer.getCheckedElements().length==0)
+ {
+ CheckStateChangedEvent ev = new CheckStateChangedEvent(tableViewer, null, false);
+ listener.checkStateChanged(ev);
+ }
+ //Update the status label
+ statusLabel.setText("Selected : "+tableViewer.getCheckedElements().length);
+ }
+
+ /**
+ * Set the input and update label
+ * @param input
+ */
+ public void setInput(ArrayList<String> input) {
+ this.input = input;
+ statusLabel.setText("Selected : 0");
+ tableViewer.setInput(this.input);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.swt.widgets.Control#setEnabled(boolean)
+ */
+ public void setEnabled(boolean arg0) {
+ filterText.setEnabled(arg0);
+ filterTypes.setEnabled(arg0);
+ tableViewer.getTable().setEnabled(arg0);
+ //tableViewer.setAllGrayed(arg0);
+ super.setEnabled(arg0);
+ }
+
+ /**
+ * Clears the selections in table.
+ *
+ */
+ public void cancelSelectionList(){
+ statusLabel.setText("Selected : 0");
+ tableViewer.refresh();
+ checked.clear();
+ }
+
+ /**
+ * Set the text to filter and notify listeners
+ * @param text
+ */
+ public void setFilterText(String text)
+ {
+ filterText.setText(text);
+ filterText.notifyListeners(SWT.Modify, new Event());
+ }
+
+ /**
+ *
+ * Customized CheckState Listener class.
+ *
+ */
+ class CheckBoxStateChangeListener implements ICheckStateListener
+ {
+ /**
+ * When CheckBox selection is changed, the tool generates
+ * random colors and assigns them to selected threads.
+ * These colors are used to distinguish graphs related to different threads.
+ * Also, this method informs the listeners about selected threads/chunks/disks/system-elements.
+ */
+ public void checkStateChanged(CheckStateChangedEvent e) {
+
+ TableViewerInputObject obj =((TableViewerInputObject)e.getElement());
+
+ if(obj!=null)
+ {
+ if(e.getChecked())
+ {
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "::::::::"+obj);
+ Random rand = new Random();
+ int r = rand.nextInt(255);
+ int g = rand.nextInt(255);
+ int b = rand.nextInt(255);
+
+ if(obj.getColor() == null)
+ obj.setColor(new Color(Display.getDefault(), r, g, b));
+
+ if(!checked.containsKey(obj.getName()))
+ checked.put(obj.getName(), obj.getColor());
+ }
+ else
+ {
+ obj.setColor(null);
+ checked.remove(obj.getName());
+ }
+ tableViewer.update(obj, null);
+ }
+ if(tableName.equals(THREADS_TITLE))
+ graphListener.notifyThreadsSelection();
+ else if(tableName.equals(CHUNKS_TITLE))
+ graphListener.notifyChunksSelection();
+ else if(tableName.equals(DISKS_TITLE))
+ graphListener.notifyDisksSelection();
+ else if(tableName.equals(SYSTEM_DATA_TITLE))
+ graphListener.notifySysElementsSelection();
+
+ tableViewer.getTable().deselectAll();
+ statusLabel.setText("Selected : "+tableViewer.getCheckedElements().length);
+ }
+
+ }
+
+ /**
+ * Returns the table viewer associated with this.
+ * @return tableViewer
+ */
+ public CheckboxTableViewer getTableViewer()
+ {
+ return this.tableViewer;
+ }
+
+ /**
+ * @return check state listener associated with this table.
+ */
+ public CheckBoxStateChangeListener getCheckStateListener()
+ {
+ return this.listener;
+ }
+
+ /**
+ * This sorter class is associated with element name
+ *
+ */
+ class Sorter extends ViewerSorter
+ {
+ int sortDirection;
+
+ Sorter(int sortDirection)
+ {
+ this.sortDirection = sortDirection;
+ }
+ public int compare(Viewer viewer, Object e1, Object e2)
+ {
+ int returnValue = 0;
+
+ TableViewerInputObject o1 = (TableViewerInputObject)e1;
+ TableViewerInputObject o2 = (TableViewerInputObject)e2;
+
+ returnValue = o1.getName().toLowerCase().compareTo(o2.getName().toLowerCase());
+
+ if(sortDirection == SWT.UP)
+ return returnValue;
+ else
+ return returnValue * -1;
+ }
+ }
+
+ /**
+ * Populates context menu at run time.
+ * @param manager Menu manager instance.
+ */
+ private void populateContextMenu(IMenuManager manager) {
+ manager.add(actionContextMenuCopyTo);
+ }
+
+ /* (non-Javadoc)
+ * @see com.nokia.s60tools.swmtanalyser.ui.actions.ISelectionProvider#getSelection()
+ */
+ public ISelection getUserSelection() {
+ return tableViewer.getSelection();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/editors/GraphedItemsContentProvider.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,57 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+package com.nokia.s60tools.swmtanalyser.editors;
+
+import java.util.ArrayList;
+
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.Viewer;
+
+/**
+ * Content provider for Graphed Items TableViewer
+ *
+ */
+public class GraphedItemsContentProvider implements IStructuredContentProvider {
+
+ @SuppressWarnings("unchecked")
+ private ArrayList inputs;
+
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object)
+ */
+ @SuppressWarnings("unchecked")
+ public Object[] getElements(Object arg0) {
+ inputs = (ArrayList)arg0;
+ return inputs.toArray();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.IContentProvider#dispose()
+ */
+ public void dispose() {
+
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object)
+ */
+ public void inputChanged(Viewer arg0, Object arg1, Object arg2) {
+
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/editors/GraphedItemsHelper.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,355 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+package com.nokia.s60tools.swmtanalyser.editors;
+
+import java.util.ArrayList;
+import java.util.Random;
+
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.action.IMenuListener;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.viewers.CheckStateChangedEvent;
+import org.eclipse.jface.viewers.CheckboxTableViewer;
+import org.eclipse.jface.viewers.ICheckStateListener;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerSorter;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swt.widgets.TabItem;
+import org.eclipse.swt.widgets.TableColumn;
+
+import com.nokia.s60tools.swmtanalyser.ui.actions.CopyToClipboardAction;
+import com.nokia.s60tools.swmtanalyser.ui.actions.ISelectionProvider;
+import com.nokia.s60tools.swmtanalyser.ui.graphs.GraphForAllEvents;
+
+/**
+ * Helper class for graphed items tab.
+ *
+ */
+public class GraphedItemsHelper implements Listener, ISelectionProvider{
+
+ /**
+ * Copy a to clipboard action
+ */
+ private IAction actionContextMenuCopyTo;
+
+
+ CheckboxTableViewer graphedItemsViewer = null;
+
+ private GraphForAllEvents graphedItemsGraph;
+ private GraphedItemsSelectionListener graphedItemChangedListener;
+
+ /**
+ * Construts UI controls over the area of given TabItem.
+ * @param graphedItemsTab represents Graphed items Tab.
+ * @param allEventsGraph represents the graph which gets updated based upon
+ * the actions on UI controls of the Graphed items tab.
+ */
+ public CheckboxTableViewer constructGraphedItemsViewer(TabItem graphedItemsTab, GraphForAllEvents allEventsGraph)
+ {
+ this.graphedItemsGraph = allEventsGraph;
+
+ Composite compAllItems = new Composite(graphedItemsTab.getParent(), SWT.NONE);
+ compAllItems.setLayout(new GridLayout(1, true));
+
+
+ graphedItemsViewer = CheckboxTableViewer.newCheckList(compAllItems, SWT.BORDER | SWT.FULL_SELECTION | SWT.MULTI );
+ graphedItemsViewer.getTable().setLayoutData(new GridData(GridData.FILL_VERTICAL|GridData.FILL_HORIZONTAL));
+
+ TableColumn tc = new TableColumn(graphedItemsViewer.getTable(), SWT.CENTER);
+ tc.setWidth(50);
+ tc.setResizable(true);
+
+ TableColumn elems_col = new TableColumn(graphedItemsViewer.getTable(), SWT.LEFT);
+ elems_col.setText(GraphedItemsInput.COL1_ELEMENTS);
+ elems_col.setWidth(600);
+ elems_col.setResizable(true);
+ elems_col.addListener(SWT.Selection, this);
+
+ TableColumn event_col = new TableColumn(graphedItemsViewer.getTable(), SWT.LEFT);
+ event_col.setText(GraphedItemsInput.COL2_EVENT);
+ event_col.setWidth(150);
+ event_col.setResizable(true);
+ event_col.addListener(SWT.Selection, this);
+
+ TableColumn type_col = new TableColumn(graphedItemsViewer.getTable(), SWT.LEFT);
+ type_col.setText(GraphedItemsInput.COL3_TYPE);
+ type_col.setWidth(150);
+ type_col.setResizable(true);
+ type_col.addListener(SWT.Selection, this);
+
+ graphedItemsViewer.getTable().setHeaderVisible(true);
+ graphedItemsViewer.getTable().setLinesVisible(true);
+
+ graphedItemsViewer.setContentProvider(new GraphedItemsContentProvider());
+ graphedItemsViewer.setLabelProvider(new TableLabelColorProvider());
+
+ graphedItemChangedListener = new GraphedItemsSelectionListener(allEventsGraph);
+ graphedItemsViewer.addCheckStateListener(graphedItemChangedListener);
+
+ hookContextMenu();
+
+ graphedItemsTab.setControl(compAllItems);
+
+ return graphedItemsViewer;
+ }
+
+ /**
+ * This method creates the context menu on the Graphed Items Tab
+ */
+
+ private void hookContextMenu()
+ {
+ MenuManager menuMgr = new MenuManager("#PopupMenu"); //$NON-NLS-1$
+ menuMgr.setRemoveAllWhenShown(true);
+ menuMgr.addMenuListener(new IMenuListener() {
+ public void menuAboutToShow(IMenuManager manager) {
+ fillContextMenu(manager);
+ }
+ });
+ Menu menu = menuMgr.createContextMenu(graphedItemsViewer.getTable());
+ graphedItemsViewer.getTable().setMenu(menu);
+ }
+
+ private Color getRandomColor()
+ {
+ Random rand = new Random();
+ int r = rand.nextInt(255);
+ int g = rand.nextInt(255);
+ int b = rand.nextInt(255);
+ return new Color(Display.getCurrent(), r, g,b);
+ }
+
+ /**
+ * The method checks all items in the given viewer and assigns random colors for all checked items.
+ * @param tableViewer
+ */
+ private void selectAllItems(CheckboxTableViewer tableViewer)
+ {
+ tableViewer.setAllChecked(true);
+
+ for(Object obj:tableViewer.getCheckedElements())
+ {
+ if(obj instanceof GraphedItemsInput){
+ GraphedItemsInput graphedItem = (GraphedItemsInput)obj;
+
+ if(graphedItem.getColor() == null)
+ graphedItem.setColor(getRandomColor());
+
+ tableViewer.update(obj, null);
+ }
+ }
+
+ }
+
+ /**
+ * @param manager -- MenuManager on which actions will be created.
+ */
+ private void fillContextMenu(IMenuManager manager) {
+ //Popup Action to check all items in the graphed items viewer.
+ Action checkAllItems = new Action()
+ {
+ {
+ this.setText("Check all");
+ this.setToolTipText("");
+ }
+ public void run()
+ {
+ selectAllItems(graphedItemsViewer);
+ notifyGraphedItemsSelection(graphedItemsViewer, graphedItemsGraph);
+ }
+
+ };
+ manager.add(checkAllItems);
+
+ //Popup action to uncheck all items in the graphed items viewer
+ Action unCheckAllItems = new Action()
+ {
+ {
+ this.setText("Uncheck all");
+ }
+ public void run()
+ {
+ for(Object obj:graphedItemsViewer.getCheckedElements())
+ {
+ ((GraphedItemsInput)obj).setColor(null);
+ graphedItemsViewer.setChecked(obj, false);
+ graphedItemsViewer.update(obj, null);
+ CheckStateChangedEvent e = new CheckStateChangedEvent(graphedItemsViewer, obj, false);
+ graphedItemChangedListener.checkStateChanged(e);
+ }
+ this.setToolTipText("");
+ }
+
+ };
+ manager.add(unCheckAllItems);
+
+ //Popup action to remove all items in the graphed items viewer
+ Action removeAllItems = new Action()
+ {
+ public void run()
+ {
+ graphedItemsViewer.setInput(null);
+ graphedItemsViewer.refresh();
+ CheckStateChangedEvent e = new CheckStateChangedEvent(graphedItemsViewer, null, false);
+ graphedItemChangedListener.checkStateChanged(e);
+ graphedItemsGraph.removeAllData();
+ }
+ {
+ this.setText("Remove all");
+ this.setToolTipText("");
+ }
+ };
+ manager.add(removeAllItems);
+
+ actionContextMenuCopyTo = new CopyToClipboardAction(this);
+ manager.add(actionContextMenuCopyTo);
+ }
+
+ /**
+ * This method updates the graph based on the selections made in the given graphed items viewer.
+ * @param tableViewer
+ * @param graphToBeUpdated
+ */
+ private void notifyGraphedItemsSelection(CheckboxTableViewer tableViewer, GraphForAllEvents graphToBeUpdated)
+ {
+ Object [] checkedElems = tableViewer.getCheckedElements();
+
+ ArrayList<GraphedItemsInput> selectedItems = new ArrayList<GraphedItemsInput>();
+
+ for(Object obj:checkedElems)
+ {
+ GraphedItemsInput graphInput = (GraphedItemsInput)obj;
+ selectedItems.add(graphInput);
+ }
+
+ graphToBeUpdated.setGraphedItemsInput(selectedItems);
+ graphToBeUpdated.constructGraphArea();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.swt.widgets.Listener#handleEvent(org.eclipse.swt.widgets.Event)
+ */
+ public void handleEvent(Event event) {
+
+ TableColumn sortedColumn = graphedItemsViewer.getTable().getSortColumn();
+ TableColumn currentSelected = (TableColumn)event.widget;
+
+ int dir = graphedItemsViewer.getTable().getSortDirection();
+
+ if(sortedColumn == currentSelected){
+ dir = dir == SWT.UP ? SWT.DOWN : SWT.UP;
+ }else
+ {
+ graphedItemsViewer.getTable().setSortColumn(currentSelected);
+ dir = SWT.UP;
+ }
+ graphedItemsViewer.setSorter(new Sorter(dir,currentSelected));
+ graphedItemsViewer.getTable().setSortDirection(dir);
+ }
+
+
+ /**
+ *
+ * Customized CheckStateListener for Graphed Items viewer.
+ * This listener is associated with the Graphed Items viewer.
+ * The 'checkStateChanged' method gets invoked, when items are
+ * checked/unchecked in Graphed Items viewer.
+ *
+ */
+ class GraphedItemsSelectionListener implements ICheckStateListener
+ {
+ private GraphForAllEvents graphToBeUpdated;
+
+ public GraphedItemsSelectionListener(GraphForAllEvents graphToBeUpdated){
+ this.graphToBeUpdated = graphToBeUpdated;
+ }
+ public void checkStateChanged(CheckStateChangedEvent e) {
+
+ GraphedItemsInput obj =((GraphedItemsInput)e.getElement());
+ if(obj!=null)
+ {
+ if(e.getChecked())
+ {
+ if(obj.getColor() == null)
+ obj.setColor(getRandomColor());
+ }
+ else
+ {
+ obj.setColor(null);
+ }
+ graphedItemsViewer.update(obj, null);
+ }
+
+ notifyGraphedItemsSelection(graphedItemsViewer,graphToBeUpdated);
+ }
+
+
+ }
+
+ /**
+ * This sorter class is associated with table in Graphed Items Tab
+ * It contains logic to sort the table based on various columns.
+ *
+ */
+ class Sorter extends ViewerSorter
+ {
+ int sortDirection;
+ TableColumn column;
+ Sorter(int sortDirection, TableColumn column)
+ {
+ this.sortDirection = sortDirection;
+ this.column = column;
+ }
+ public int compare(Viewer viewer, Object e1, Object e2)
+ {
+ int returnValue = 0;
+
+ GraphedItemsInput o1 = (GraphedItemsInput)e1;
+ GraphedItemsInput o2 = (GraphedItemsInput)e2;
+
+ if(column.getText().equalsIgnoreCase(GraphedItemsInput.COL1_ELEMENTS))
+ returnValue = o1.getName().toLowerCase().compareTo(o2.getName().toLowerCase());
+ else if(column.getText().equalsIgnoreCase(GraphedItemsInput.COL2_EVENT))
+ returnValue = o1.getEvent().toLowerCase().compareTo(o2.getEvent().toLowerCase());
+ else if(column.getText().equalsIgnoreCase(GraphedItemsInput.COL3_TYPE))
+ returnValue = o1.getType().toLowerCase().compareTo(o2.getType().toLowerCase());
+
+ if(sortDirection == SWT.UP)
+ return returnValue;
+ else
+ return returnValue * -1;
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see com.nokia.s60tools.swmtanalyser.ui.actions.ISelectionProvider#getSelection()
+ */
+ public ISelection getUserSelection() {
+ return graphedItemsViewer.getSelection();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/editors/GraphedItemsInput.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,125 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+package com.nokia.s60tools.swmtanalyser.editors;
+
+import org.eclipse.swt.graphics.Color;
+
+/**
+ * Input class for the tableviewer in GraphedItems tab.
+ *
+ */
+public class GraphedItemsInput {
+
+ public static final String COL1_ELEMENTS = "Elements";
+ public static final String COL2_EVENT = "Event";
+ public static final String COL3_TYPE = "Type";
+
+ private static final String TAB = "\t";
+
+ private String name;
+ private String event;
+ private String type;
+ private Color color;
+
+ /**
+ * Get event parameter
+ * @return event
+ */
+ public String getEvent() {
+ return event;
+ }
+ /**
+ * Set event parameter
+ * @param event
+ */
+ public void setEvent(String event) {
+ this.event = event;
+ }
+ /**
+ * Get name parameter
+ * @return name
+ */
+ public String getName() {
+ return name;
+ }
+ /**
+ * Set name parameter
+ * @param name
+ */
+ public void setName(String name) {
+ this.name = name;
+ }
+ /**
+ * Get type parameter
+ * @return type
+ */
+ public String getType() {
+ return type;
+ }
+ /**
+ * Set type parameter
+ * @param type
+ */
+ public void setType(String type) {
+ this.type = type;
+ }
+ /**
+ * Get color parameter
+ * @return color
+ */
+ public Color getColor() {
+ return color;
+ }
+ /**
+ * Set color parameter
+ * @param color
+ */
+ public void setColor(Color color) {
+ this.color = color;
+ }
+
+ /**
+ * Get tab separated values for this result.
+ * @return values
+ */
+ public String getTabSeparatedValues() {
+ StringBuffer b = new StringBuffer();
+ b.append(getName());
+ b.append(TAB);
+ b.append(getEvent());
+ b.append(TAB);
+ b.append(getType());
+
+ return b.toString();
+ }
+
+ /**
+ * Get tab separated headers for this result.
+ * @return headers with tab as separator
+ */
+ public String getTabSeparatedHeaders() {
+ StringBuffer b = new StringBuffer();
+ b.append(COL1_ELEMENTS);
+ b.append(TAB);
+ b.append(COL2_EVENT);
+ b.append(TAB);
+ b.append(COL3_TYPE);
+
+ return b.toString();
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/editors/IssuesFilter.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,178 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+package com.nokia.s60tools.swmtanalyser.editors;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerFilter;
+
+import com.nokia.s60tools.swmtanalyser.analysers.AnalyserConstants;
+import com.nokia.s60tools.swmtanalyser.analysers.ResultElements;
+import com.nokia.s60tools.swmtanalyser.dialogs.AdvancedFilterDialog.FilterInput;
+
+/**
+ * Customized ViewerFilter for TableViewer in Analysis tab.
+ *
+ */
+public class IssuesFilter extends ViewerFilter {
+
+ //Filter text
+ private String search_key = null;
+ //Settings selected in the advanced filter options dialog
+ private FilterInput adv_options = null;
+
+ /**
+ * Set filter text
+ * @param value
+ */
+ public void setFilterText(String value)
+ {
+ search_key = value;
+ }
+
+ /**
+ * Set advanced filter to issues
+ * @param adv_option
+ */
+ public void setAdvancedSearchOptions(FilterInput adv_option)
+ {
+ this.adv_options = adv_option;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.ViewerFilter#select(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object)
+ */
+ public boolean select(Viewer viewer, Object parentElement, Object element) {
+
+ //If the search is done using the advanced filter options dialog
+ if(adv_options!=null)
+ {
+ int filter_option = adv_options.getName_Filter_option();
+ String filter_text = adv_options.getFilter_text();
+ List<String> events = new ArrayList<String>();
+ if(adv_options.getEvents()!=null)
+ events = Arrays.asList(adv_options.getEvents());
+
+ List<AnalyserConstants.Priority> severities = new ArrayList<AnalyserConstants.Priority>();
+ if(adv_options.getSeverities()!=null)
+ severities = Arrays.asList(adv_options.getSeverities());
+
+ int delta_bytes_option = adv_options.getDelta_bytes_option();
+ long s1 = adv_options.getStart_size();
+ long e1 = adv_options.getEnd_size();
+
+ int delta_count_option = adv_options.getDelta_count_option();
+ long s2 = adv_options.getStart_count();
+ long e2 = adv_options.getEnd_count();
+
+ if(element instanceof ResultElements)
+ {
+ ResultElements item = (ResultElements)element;
+ String item_name = item.getItemName();
+ String event = item.getEvent();
+ long delta = item.getDeltaValue();
+ AnalyserConstants.Priority p = item.getPriority();
+
+ boolean flag = true;
+
+ if(filter_option == 0 && filter_text!=null && !item_name.toLowerCase().startsWith(filter_text.toLowerCase()))
+ return false;
+ if(filter_option == 1 && filter_text!=null && item_name.toLowerCase().indexOf(filter_text.toLowerCase()) == -1)
+ return false;
+ if(events.size()>0 && !events.contains(event))
+ return false;
+ if(severities.size()>0 && !severities.contains(p))
+ return false;
+ if(item.getType().compareTo(AnalyserConstants.DeltaType.SIZE)==0)
+ {
+ switch (delta_bytes_option) {
+ case 0:
+ //flag = flag && true;
+ break;
+ case 1:
+ if(delta < s1 || delta > e1)
+ return false;
+ break;
+ case 2:
+ if(delta != s1)
+ return false;
+ break;
+ case 3:
+ if(delta < s1)
+ return false;
+ break;
+ case 4:
+ if(delta > s1)
+ return false;
+ break;
+
+ default:
+ break;
+ }
+ }
+ else if(item.getType().compareTo(AnalyserConstants.DeltaType.COUNT)==0)
+ {
+ switch (delta_count_option) {
+ case 0:
+ //flag = flag && true;
+ break;
+ case 1:
+ if(delta < s2 || delta > e2)
+ return false;
+ break;
+ case 2:
+ if(delta != s2)
+ return false;
+ break;
+ case 3:
+ if(delta < s2)
+ return false;
+ break;
+ case 4:
+ if(delta > s2)
+ return false;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ return flag;
+ }
+ }
+
+ //If searching is cancelled.
+ if(search_key == null)
+ return true;
+
+ //If search is done using the severity dropdown in the Analysis tab.
+ if(element instanceof ResultElements)
+ {
+ ResultElements item = (ResultElements)element;
+ AnalyserConstants.Priority p = item.getPriority();
+ if(p.name().toLowerCase().matches(search_key.toLowerCase()))
+ return true;
+ else
+ return false;
+ }
+ return true;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/editors/IssuesTreeContentProvider.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,85 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+package com.nokia.s60tools.swmtanalyser.editors;
+
+import java.util.ArrayList;
+
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.Viewer;
+
+import com.nokia.s60tools.swmtanalyser.analysers.ResultsParentNodes;
+
+/**
+ * ContentProvider for table viewer in the Analysis tab.
+ *
+ */
+public class IssuesTreeContentProvider implements ITreeContentProvider {
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.ITreeContentProvider#getChildren(java.lang.Object)
+ */
+ public Object[] getChildren(Object parent) {
+ ArrayList<Object> total_children = new ArrayList<Object>();
+
+ if(parent instanceof ResultsParentNodes) {
+ return ((ResultsParentNodes)parent).getChildren();
+ }
+
+ return total_children.toArray();
+
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.ITreeContentProvider#getParent(java.lang.Object)
+ */
+ public Object getParent(Object arg0) {
+ if(arg0 instanceof ResultsParentNodes)
+ return arg0;
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.ITreeContentProvider#hasChildren(java.lang.Object)
+ */
+ public boolean hasChildren(Object arg0) {
+ return getChildren(arg0)!=null && getChildren(arg0).length > 0;
+ }
+
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object)
+ */
+ @SuppressWarnings("unchecked")
+ public Object[] getElements(Object arg0) {
+ return ((ArrayList)arg0).toArray();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.IContentProvider#dispose()
+ */
+ public void dispose() {
+
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object)
+ */
+ public void inputChanged(Viewer arg0, Object arg1, Object arg2) {
+
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/editors/IssuesTreeLabelProvider.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,168 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+package com.nokia.s60tools.swmtanalyser.editors;
+
+import org.eclipse.jface.viewers.ILabelProviderListener;
+import org.eclipse.jface.viewers.ITableColorProvider;
+import org.eclipse.jface.viewers.ITableFontProvider;
+import org.eclipse.jface.viewers.ITableLabelProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Display;
+
+import com.nokia.s60tools.swmtanalyser.analysers.AnalyserConstants;
+import com.nokia.s60tools.swmtanalyser.analysers.ResultElements;
+import com.nokia.s60tools.swmtanalyser.analysers.ResultsParentNodes;
+
+/**
+ * LableProvider for the tree viewer in the Analysis tab
+ *
+ */
+public class IssuesTreeLabelProvider extends LabelProvider implements ITableLabelProvider, ITableColorProvider, ITableFontProvider {
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.ITableLabelProvider#getColumnImage(java.lang.Object, int)
+ */
+ public Image getColumnImage(Object arg0, int arg1) {
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.ITableLabelProvider#getColumnText(java.lang.Object, int)
+ */
+ public String getColumnText(Object element, int column_index) {
+
+ if(column_index == 1)
+ {
+ if(element instanceof ResultsParentNodes)
+ {
+ return ((ResultsParentNodes)element).toString();
+ }
+ else if(element instanceof ResultElements)
+ {
+ return ((ResultElements)element).getItemName();
+ }
+ }
+ else if(column_index == 2)
+ {
+ if(element instanceof ResultElements)
+ return ((ResultElements)element).getEvent();
+ }
+ else if(column_index == 3)
+ {
+ if(element instanceof ResultElements)
+ return ((ResultElements)element).getDelta();
+ }
+ else if(column_index == 4)
+ {
+ if(element instanceof ResultElements)
+ return ((ResultElements)element).getPriority().name();
+ }
+ //For internal testing.
+ /*else if(arg1 == 4)
+ {
+ if(arg0 instanceof ResultElements)
+ return ((ResultElements)arg0).getGrowing_factor()+"";
+ }*/
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.BaseLabelProvider#addListener(org.eclipse.jface.viewers.ILabelProviderListener)
+ */
+ public void addListener(ILabelProviderListener arg0) {
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.BaseLabelProvider#dispose()
+ */
+ public void dispose() {
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.BaseLabelProvider#isLabelProperty(java.lang.Object, java.lang.String)
+ */
+ public boolean isLabelProperty(Object arg0, String arg1) {
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.BaseLabelProvider#removeListener(org.eclipse.jface.viewers.ILabelProviderListener)
+ */
+ public void removeListener(ILabelProviderListener arg0) {
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.ITableColorProvider#getBackground(java.lang.Object, int)
+ */
+ public Color getBackground(Object element, int columnIndex) {
+
+ if(element instanceof ResultElements )
+ {
+ ResultElements item = (ResultElements)element;
+
+ if(columnIndex == 4)
+ {
+ Color background_color = null;
+
+ switch (item.getPriority()) {
+ case CRITICAL:
+ background_color = AnalyserConstants.COLOR_SEVERITY_CRITICAL;
+ break;
+ case HIGH:
+ background_color = AnalyserConstants.COLOR_SEVERITY_HIGH;
+ break;
+ case NORMAL:
+ background_color = AnalyserConstants.COLOR_SEVERITY_NORMAL;
+ break;
+
+ default:
+ break;
+ }
+ return background_color;
+ }
+ else if(columnIndex == 0)
+ {
+ return item.getColor();
+ }
+ }
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.ITableColorProvider#getForeground(java.lang.Object, int)
+ */
+ public Color getForeground(Object element, int columnIndex) {
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.ITableFontProvider#getFont(java.lang.Object, int)
+ */
+ public Font getFont(Object arg0, int arg1) {
+ if(arg0 instanceof ResultsParentNodes)
+ {
+ Font f = Display.getCurrent().getSystemFont();
+ return new Font(Display.getCurrent(), f.getFontData()[0].getName(), 8, SWT.BOLD);
+ }
+ return null;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/editors/IssuesViewer.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,467 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+package com.nokia.s60tools.swmtanalyser.editors;
+
+import java.util.ArrayList;
+
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.action.IMenuListener;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.viewers.CheckStateChangedEvent;
+import org.eclipse.jface.viewers.CheckboxTreeViewer;
+import org.eclipse.jface.viewers.ICheckStateListener;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerFilter;
+import org.eclipse.jface.viewers.ViewerSorter;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Tree;
+import org.eclipse.swt.widgets.TreeColumn;
+import org.eclipse.swt.widgets.TreeItem;
+
+import com.nokia.s60tools.swmtanalyser.analysers.ResultElements;
+import com.nokia.s60tools.swmtanalyser.analysers.ResultsParentNodes;
+import com.nokia.s60tools.swmtanalyser.resources.Tooltips;
+import com.nokia.s60tools.swmtanalyser.ui.actions.CopyToClipboardAction;
+import com.nokia.s60tools.swmtanalyser.ui.actions.ISelectionProvider;
+import com.nokia.s60tools.swmtanalyser.ui.graphs.GraphsUtils;
+import com.nokia.s60tools.swmtanalyser.ui.graphs.LinearIssuesGraph;
+
+/**
+ * Customized tree viewer in the Analysis tab.
+ *
+ */
+public class IssuesViewer implements Listener, ICheckStateListener, ISelectionProvider {
+
+ /**
+ * Copy a to clipboard action
+ */
+ private IAction actionContextMenuCopyTo;
+
+ private Tree issues_tree;
+ private CheckboxTreeViewer issues_viewer;
+ private LinearIssuesGraph issue_graph;
+
+
+ /**
+ * Construction
+ * @param tree
+ * @param graphToBeUpdated
+ */
+ public IssuesViewer(Tree tree, LinearIssuesGraph graphToBeUpdated)
+ {
+ this.issues_tree = tree;
+ issues_viewer = new CheckboxTreeViewer(tree);
+
+ GridData tableData = new GridData(GridData.FILL_BOTH);
+ tableData.horizontalSpan = 7;
+ tableData.grabExcessVerticalSpace = true;
+
+ issues_viewer.getTree().setLayoutData(tableData);
+ this.issue_graph = graphToBeUpdated;
+
+ issues_viewer.addCheckStateListener(this);
+
+ }
+ /**
+ * Create linear analysis results tree and graph
+ */
+ public void createIssuesViewerAndGraph()
+ {
+ TreeColumn tc = new TreeColumn(issues_viewer.getTree(), SWT.LEFT);
+ tc.setWidth(60);
+ tc.setResizable(true);
+
+ TreeColumn itemName = new TreeColumn(issues_viewer.getTree(), SWT.NONE);
+ itemName.setText(ResultElements.ITEM_NAME_COLUMN);
+ itemName.setWidth(300);
+ itemName.setToolTipText("Name of the thread/chunk/disk etc.");
+
+ TreeColumn event = new TreeColumn(issues_viewer.getTree(), SWT.NONE);
+ event.setText(ResultElements.EVENT_COLUMN);
+ event.setWidth(200);
+ event.setToolTipText("Name of the event.");
+
+ TreeColumn delta = new TreeColumn(issues_viewer.getTree(), SWT.NONE);
+ delta.setText(ResultElements.DELTA_COLUMN);
+ delta.setWidth(150);
+ delta.setToolTipText("Difference between the last and first cycle values.");
+
+ TreeColumn severity = new TreeColumn(issues_viewer.getTree(), SWT.CENTER);
+ severity.setText(ResultElements.SEVERITY_COLUMN);
+ severity.setWidth(100);
+ severity.setResizable(false);
+ severity.setToolTipText("Severity of the issue.");
+
+ itemName.addListener(SWT.Selection, this);
+ event.addListener(SWT.Selection, this);
+ delta.addListener(SWT.Selection,this);
+ severity.addListener(SWT.Selection, this);
+
+ issues_viewer.getTree().setHeaderVisible(true);
+ issues_viewer.getTree().setLinesVisible(true);
+
+ issues_tree.setSortColumn(severity);
+ issues_tree.setSortDirection(SWT.DOWN);
+ issues_viewer.setSorter(new IssuesSorter(SWT.DOWN, severity));
+
+ //Showing tooltip for the each issue in the tree view
+ Listener treeListener = new Listener () {
+ Shell tip = null;
+ Label label = null;
+ public void handleEvent (Event event) {
+ switch (event.type) {
+ case SWT.Dispose:
+ case SWT.KeyDown:
+ case SWT.MouseExit:
+ case SWT.MouseMove: {
+ if (tip == null) break;
+ tip.dispose ();
+ tip = null;
+ label = null;
+ break;
+ }
+ case SWT.MouseHover: {
+ TreeItem item = issues_tree.getItem (new Point (event.x, event.y));
+ if (item != null && getTooltipForItem(item)!="") {
+ if (tip != null && !tip.isDisposed ()) tip.dispose ();
+ tip = new Shell (Display.getCurrent().getActiveShell(), SWT.ON_TOP | SWT.NO_FOCUS | SWT.TOOL);
+ tip.setBackground (Display.getCurrent().getSystemColor (SWT.COLOR_INFO_BACKGROUND));
+ FillLayout layout = new FillLayout ();
+ layout.marginWidth = 2;
+ tip.setLayout (layout);
+ label = new Label (tip, SWT.NONE);
+ label.setForeground (Display.getCurrent().getSystemColor (SWT.COLOR_INFO_FOREGROUND));
+ label.setBackground (Display.getCurrent().getSystemColor (SWT.COLOR_INFO_BACKGROUND));
+ label.setData ("TreeItem", item);
+ label.setText (getTooltipForItem(item));
+ Point size = tip.computeSize (SWT.DEFAULT, SWT.DEFAULT);
+ Point p = new Point(event.x, event.y);
+ Point pp = Display.getCurrent().map(issues_tree, null, p);
+ tip.setBounds (pp.x, pp.y+20, size.x, size.y);
+ tip.setVisible (true);
+ }
+ }
+ }
+ }
+ };
+ issues_tree.addListener (SWT.Dispose, treeListener); //When widget disposed
+ issues_tree.addListener (SWT.KeyDown, treeListener); //When mouse key pressed
+ issues_tree.addListener (SWT.MouseMove, treeListener); //When mouse moved
+ issues_tree.addListener (SWT.MouseHover, treeListener); //When mouse hovers over the control
+ issues_tree.addListener (SWT.MouseExit, treeListener);
+
+ issue_graph.constructGraphArea();
+
+ hookContextMenu();
+ }
+
+ /**
+ * Sets the content provider for viewer
+ * @see {@link CheckboxTreeViewer#setContentProvider(org.eclipse.jface.viewers.IContentProvider)}
+ * @param contentProvider
+ */
+ public void setContentProvider(ITreeContentProvider contentProvider)
+ {
+ issues_viewer.setContentProvider(contentProvider);
+ }
+
+ /**
+ * Sets the label provider for viewer
+ * @see {@link CheckboxTreeViewer#setLabelProvider(org.eclipse.jface.viewers.IBaseLabelProvider)}
+ * @param labelProvider
+ */
+ public void setLabelProvider(IssuesTreeLabelProvider labelProvider)
+ {
+ issues_viewer.setLabelProvider(labelProvider);
+ }
+
+ /**
+ * Adds a filter to viewer
+ * @see {@link CheckboxTreeViewer#addFilter(ViewerFilter)}
+ * @param filter
+ */
+ public void addFilter(ViewerFilter filter)
+ {
+ issues_viewer.addFilter(filter);
+ }
+
+ /**
+ * Refresh the viewer @see
+ * {@link CheckboxTreeViewer#refresh()}
+ */
+ public void refresh()
+ {
+ issues_viewer.refresh();
+ }
+
+ /**
+ * Set the input to viewer and expand
+ * @see {@link CheckboxTreeViewer#setInput(Object)}
+ * @see {@link CheckboxTreeViewer#expandAll()}
+ * @param input
+ */
+ public void setInput(Object input)
+ {
+ issues_viewer.setInput(input);
+ issues_viewer.expandAll();
+ }
+
+ /**
+ * Get the input from viewer
+ * @see {@link CheckboxTreeViewer#getInput()}
+ * @param input
+ */
+ public Object getInput()
+ {
+ return issues_viewer.getInput();
+ }
+
+ /**
+ * Returns the description for the given event.
+ * @param item TreeItem of event
+ * @return tooltip description
+ */
+ public String getTooltipForItem(TreeItem item)
+ {
+ String tooltip = item.getText(2);
+ if(tooltip == "Heap size")
+ {
+ tooltip = Tooltips.getTooltip("Tooltips.HeapSize")
+ +"\n"+Tooltips.getTooltip("Tooltips.Delta")
+ +"\n"+Tooltips.getTooltip("Tooltips.Severity");
+ }
+ else if(tooltip == "No of Files")
+ {
+ tooltip = Tooltips.getTooltip("Tooltips.NoOfFiles1")+item.getText(1)+Tooltips.getTooltip("Tooltips.NoOfFiles2")
+ +"\n"+Tooltips.getTooltip("Tooltips.Delta")
+ +"\n"+Tooltips.getTooltip("Tooltips.Severity");
+ }
+ else if(tooltip == "Heap allocated space")
+ {
+ tooltip = Tooltips.getTooltip("Tooltips.HeapAllocatedSpace")
+ +"\n"+Tooltips.getTooltip("Tooltips.Delta")
+ +"\n"+Tooltips.getTooltip("Tooltips.Severity");
+ }
+ else if(tooltip == "Heap allocated cell count")
+ {
+ tooltip = Tooltips.getTooltip("Tooltips.HeapAllocatedCellCount")
+ +"\n"+Tooltips.getTooltip("Tooltips.Delta")
+ +"\n"+Tooltips.getTooltip("Tooltips.Severity");
+ }
+ else if(tooltip == "No of PS Handles")
+ {
+ tooltip = Tooltips.getTooltip("Tooltips.NoOfPSHandles")+item.getText(1)
+ +"\n"+Tooltips.getTooltip("Tooltips.Delta")
+ +"\n"+Tooltips.getTooltip("Tooltips.Severity");
+ }
+ else if(tooltip == "System Data")
+ {
+ tooltip = Tooltips.getTooltip("Tooltips.SystemData")
+ +"\n"+Tooltips.getTooltip("Tooltips.Delta")
+ +"\n"+Tooltips.getTooltip("Tooltips.Severity");
+ }
+ else if(tooltip == "RAM used")
+ {
+ tooltip = Tooltips.getTooltip("Tooltips.RAMUsed")
+ +"\n"+Tooltips.getTooltip("Tooltips.Delta")
+ +"\n"+Tooltips.getTooltip("Tooltips.Severity");
+ }
+ else if(tooltip == "Disk used")
+ {
+ tooltip = Tooltips.getTooltip("Tooltips.DiskUsed")+item.getText(1)
+ +"\n"+Tooltips.getTooltip("Tooltips.Delta")
+ +"\n"+Tooltips.getTooltip("Tooltips.Severity");
+ }
+
+ return tooltip;
+ }
+
+ private class IssuesSorter extends ViewerSorter
+ {
+
+ private int direction;
+ private TreeColumn givenColumn;
+
+ public IssuesSorter(int direction, TreeColumn sortColumn)
+ {
+ this.direction = direction;
+ this.givenColumn = sortColumn;
+ }
+ public int compare(Viewer viewer, Object obj1, Object obj2)
+ {
+ int result = 0;
+
+ if(obj1 instanceof ResultElements && obj2 instanceof ResultElements)
+ {
+ ResultElements elem1 = (ResultElements)obj1;
+ ResultElements elem2 = (ResultElements)obj2;
+
+ if(givenColumn.getText().equalsIgnoreCase(ResultElements.DELTA_COLUMN))
+ {
+ result = elem1.compareByDelta(elem2);
+ }
+ else if(givenColumn.getText().equalsIgnoreCase(ResultElements.SEVERITY_COLUMN))
+ {
+ result = elem1.compareTo(elem2);
+ }
+ else if(givenColumn.getText().equalsIgnoreCase(ResultElements.ITEM_NAME_COLUMN))
+ {
+ result = elem1.getItemName().compareTo(elem2.getItemName());
+ }
+ else if(givenColumn.getText().equalsIgnoreCase(ResultElements.EVENT_COLUMN))
+ {
+ result = elem1.getEvent().compareTo(elem2.getEvent());
+ }
+ if(direction == SWT.UP)
+ return result * 1;
+ else
+ return result * -1;
+ }
+ return result;
+ }
+
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.swt.widgets.Listener#handleEvent(org.eclipse.swt.widgets.Event)
+ */
+ public void handleEvent(Event event)
+ {
+ TreeColumn sortedColumn = issues_tree.getSortColumn();
+ TreeColumn currentSelected = (TreeColumn)event.widget;
+
+ int dir = issues_tree.getSortDirection();
+
+ if(sortedColumn == currentSelected){
+ dir = dir == SWT.UP ? SWT.DOWN : SWT.UP;
+ }else
+ {
+ issues_tree.setSortColumn(currentSelected);
+ dir = SWT.UP;
+ }
+
+ issues_viewer.setSorter(new IssuesSorter(dir, currentSelected));
+ issues_viewer.getTree().setSortDirection(dir);
+
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.ICheckStateListener#checkStateChanged(org.eclipse.jface.viewers.CheckStateChangedEvent)
+ */
+ public void checkStateChanged(CheckStateChangedEvent event) {
+
+ Object selectedElement = event.getElement();
+
+ if(selectedElement == null)
+ return;
+
+ if(selectedElement instanceof ResultsParentNodes)
+ {
+ ((CheckboxTreeViewer)(issues_viewer)).setSubtreeChecked(selectedElement, event.getChecked());
+ Object [] children = ((ResultsParentNodes)(selectedElement)).getChildren();
+
+ for(Object obj:children)
+ {
+ if(obj instanceof ResultElements)
+ {
+ ResultElements res = (ResultElements)obj;
+ CheckStateChangedEvent stateChangeEvent = new CheckStateChangedEvent(((CheckboxTreeViewer)(issues_viewer)), res, event.getChecked());
+ checkStateChanged(stateChangeEvent);
+ }
+ }
+ }
+ else if(selectedElement instanceof ResultElements) {
+ {
+ ResultElements elem = ((ResultElements)selectedElement);
+
+ if(event.getChecked())
+ {
+ if(elem.getColor() == null)
+ elem.setColor(GraphsUtils.getRandomColor());
+ }
+ else
+ {
+ elem.setColor(null);
+ }
+ issues_viewer.update(elem, null);
+ }
+ notifyIssuesSelection();
+ }
+
+ }
+
+ private void notifyIssuesSelection()
+ {
+ Object [] checkedElems = ((CheckboxTreeViewer)(issues_viewer)).getCheckedElements();
+
+ ArrayList<ResultElements> selectedItems = new ArrayList<ResultElements>();
+
+ for(Object obj:checkedElems)
+ {
+ if(obj instanceof ResultElements)
+ {
+ ResultElements elem = (ResultElements)obj;
+ selectedItems.add(elem);
+ }
+ }
+
+ issue_graph.setSelectedIssues(selectedItems);
+ issue_graph.constructGraphArea();
+ }
+ /**
+ * This method creates the context menu on the Graphed Items Tab
+ */
+
+ private void hookContextMenu()
+ {
+ MenuManager menuMgr = new MenuManager("#PopupMenu"); //$NON-NLS-1$
+ menuMgr.setRemoveAllWhenShown(true);
+ menuMgr.addMenuListener(new IMenuListener() {
+ public void menuAboutToShow(IMenuManager manager) {
+ fillContextMenu(manager);
+ }
+ });
+ Menu menu = menuMgr.createContextMenu(issues_viewer.getControl());
+ issues_viewer.getControl().setMenu(menu);
+ }
+
+ /**
+ * @param manager -- MenuManager on which actions will be created.
+ */
+ private void fillContextMenu(IMenuManager manager) {
+ actionContextMenuCopyTo = new CopyToClipboardAction(this);
+ manager.add(actionContextMenuCopyTo);
+ }
+
+ /* (non-Javadoc)
+ * @see com.nokia.s60tools.swmtanalyser.ui.actions.ISelectionProvider#getSelection()
+ */
+ public ISelection getUserSelection() {
+ return issues_viewer.getSelection();
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/editors/SWMTEditor.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,1661 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+package com.nokia.s60tools.swmtanalyser.editors;
+
+import java.io.File;
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.Random;
+import java.util.Map.Entry;
+
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.dialogs.IMessageProvider;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.dialogs.ProgressMonitorDialog;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.jface.viewers.CheckStateChangedEvent;
+import org.eclipse.jface.viewers.CheckboxTableViewer;
+import org.eclipse.jface.wizard.WizardDialog;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.SashForm;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.MouseListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.ImageData;
+import org.eclipse.swt.graphics.ImageLoader;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.layout.FormAttachment;
+import org.eclipse.swt.layout.FormData;
+import org.eclipse.swt.layout.FormLayout;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.program.Program;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.FileDialog;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.List;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swt.widgets.MenuItem;
+import org.eclipse.swt.widgets.Sash;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.TabFolder;
+import org.eclipse.swt.widgets.TabItem;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+import org.eclipse.swt.widgets.TableItem;
+import org.eclipse.swt.widgets.Tree;
+import org.eclipse.swt.widgets.TreeItem;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IEditorSite;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.forms.events.ExpansionAdapter;
+import org.eclipse.ui.forms.events.ExpansionEvent;
+import org.eclipse.ui.forms.widgets.FormToolkit;
+import org.eclipse.ui.forms.widgets.ScrolledForm;
+import org.eclipse.ui.forms.widgets.Section;
+import org.eclipse.ui.forms.widgets.TableWrapData;
+import org.eclipse.ui.forms.widgets.TableWrapLayout;
+import org.eclipse.ui.ide.IDE;
+import org.eclipse.ui.part.MultiPageEditorPart;
+
+import com.nokia.s60tools.swmtanalyser.SwmtAnalyserPlugin;
+import com.nokia.s60tools.swmtanalyser.analysers.AnalyserConstants;
+import com.nokia.s60tools.swmtanalyser.analysers.IAnalyser;
+import com.nokia.s60tools.swmtanalyser.analysers.ResultElements;
+import com.nokia.s60tools.swmtanalyser.analysers.ResultsParentNodes;
+import com.nokia.s60tools.swmtanalyser.data.CycleData;
+import com.nokia.s60tools.swmtanalyser.data.OverviewData;
+import com.nokia.s60tools.swmtanalyser.data.ParsedData;
+import com.nokia.s60tools.swmtanalyser.dialogs.AdvancedFilterDialog;
+import com.nokia.s60tools.swmtanalyser.dialogs.AdvancedFilterDialog.FilterInput;
+import com.nokia.s60tools.swmtanalyser.model.ExcelCreator;
+import com.nokia.s60tools.swmtanalyser.model.SWMTLogReaderUtils;
+import com.nokia.s60tools.swmtanalyser.ui.graphs.ChunksGraph;
+import com.nokia.s60tools.swmtanalyser.ui.graphs.DisksGraph;
+import com.nokia.s60tools.swmtanalyser.ui.graphs.GenericGraph;
+import com.nokia.s60tools.swmtanalyser.ui.graphs.GraphForAllEvents;
+import com.nokia.s60tools.swmtanalyser.ui.graphs.GraphsUtils;
+import com.nokia.s60tools.swmtanalyser.ui.graphs.IGraphTypeSelectionListener;
+import com.nokia.s60tools.swmtanalyser.ui.graphs.LinearIssuesGraph;
+import com.nokia.s60tools.swmtanalyser.ui.graphs.SwmtGraph;
+import com.nokia.s60tools.swmtanalyser.ui.graphs.SystemDataGraph;
+import com.nokia.s60tools.swmtanalyser.ui.graphs.ThreadsGraph;
+import com.nokia.s60tools.swmtanalyser.wizards.ReportGenerationWizard;
+
+/**
+ * SWMT Analyser editor view
+ *
+ */
+public class SWMTEditor extends MultiPageEditorPart implements SelectionListener, IGraphTypeSelectionListener{
+
+ // Overview Page Controls
+ private ScrolledForm form;
+ private Combo toCombo;
+ private Button allBtn;
+ private Button notAllBtn;
+ private Button export;
+
+ //Trace Page Controls
+ private TabItem eventsTab;
+ private Combo eventsCombo;
+ private List eventList;
+ private TabFolder innerTabFolder;
+ private TabItem threadTab;
+ private TabItem chunksTab;
+ private TabItem diskTab;
+ private TabItem sysInfoTab;
+ private FilterTextTable threadTble;
+ private FilterTextTable chunkTble;
+ private FilterTextTable diskTble;
+ private FilterTextTable sysinfoTble;
+
+ private static enum CATEGORIES { All_events, Chunks, Disk, Files, Heap, HPAS, RAM, System_info };
+ private String[] CHUNKS_GRP = { "Global data size", "Non heap chunk size" };
+ private String[] DISK_GRP = { "Disk used", "Disk total" };
+ private String[] FILES_GRP = { "No of Files" };
+ private String[] HEAP_GRP = { "Max size", "Heap size", "Heap allocated space", "Heap free space", "Heap allocated cell count", "Heap free cell count", "Free slack" }; //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$
+ private String[] HPAS_GRP = { "No of PS Handles" };
+ private String[] RAM_GRP = { "RAM used", "RAM total" };
+ private String[] SYSINFO_GRP = { "System Data" };
+ private String[] ALL_GRP = { "RAM used", "RAM total", "Global data size", "Non heap chunk size", "Disk used", "Disk total", "No of Files", "Max size", "Heap size", "Heap allocated space", "Heap free space", "Heap allocated cell count", "Heap free cell count", "Free slack", "No of PS Handles", "System Data" }; //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$ //$NON-NLS-9$ //$NON-NLS-10$ //$NON-NLS-11$ //$NON-NLS-12$ //$NON-NLS-13$ //$NON-NLS-14$ //$NON-NLS-15$ //$NON-NLS-16$
+
+ //Stores overiew information to be displayed in the first page
+ private OverviewData ov;
+
+ // All cycles data
+ private ParsedData parsedData = new ParsedData();
+ private ArrayList<String> threads = new ArrayList<String>();
+ private ArrayList<String> chunks = new ArrayList<String>();
+ private ArrayList<String> nonHeapChunks = new ArrayList<String>();
+ private ArrayList<String> disks = new ArrayList<String>();
+
+ //Four table viewer for 4 tabs in the Graphs tab
+ private CheckboxTableViewer threadViewer;
+ private CheckboxTableViewer chunksViewer;
+ private CheckboxTableViewer disksViewer;
+ private CheckboxTableViewer sysElemsViewer;
+
+ private String lastSelectedEvent = RAM_GRP[0];
+
+ private SwmtGraph graph;
+ private GraphForAllEvents allEventsGraph;
+
+ private String selectedEvent;
+ private CheckboxTableViewer graphedItemsViewer;
+ private ArrayList<GraphedItemsInput> graphed = new ArrayList<GraphedItemsInput>();
+ private TabFolder mainTabFolder;
+ private Label title;
+
+ private Table issues_table;
+ private Button viewAll_btn;;
+
+ private int ANALYSIS_PAGE = -1;
+ private int OVERVIEW_PAGE = -1;
+ private int GRAPHS_PAGE = -1;
+ private Tree issues_tree;
+ private MenuItem analyse_menuItem;
+ private Combo severity_combo;
+ private Label severity_label;
+ private IssuesFilter filter;
+ private IssuesViewer viewer;
+ private ArrayList<Object> analysis_results_obj = new ArrayList<Object>();
+
+ private static final String NO_ISSUES_MSG = "No Critical issues found.";
+ private static final String GRAPHED_ITEMS_LABEL = "Graphed items";
+ private Button advanced_filter_button;
+ private Button generate_report_btn;
+ private SashForm graphSash;
+
+ /**
+ * Creates a multi-page editor.
+ */
+ public SWMTEditor() {
+ super();
+ }
+
+ /**
+ * Creates overview page of the SWMT Editor.
+ */
+ private void createOverviewPage() {
+ Composite composite = new Composite(getContainer(), SWT.NONE);
+ FillLayout layoutF = new FillLayout();
+ composite.setLayout(layoutF);
+ FormToolkit toolkit = new FormToolkit(composite.getDisplay());
+ form = toolkit.createScrolledForm(composite);
+ form.setText("Overview:");
+
+ TableWrapLayout layout = new TableWrapLayout();
+ layout.leftMargin = 10;
+ layout.rightMargin = 10;
+ layout.numColumns = 2;
+ form.getBody().setLayout(layout);
+ form.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+ if(parsedData.getNumberOfCycles() == 1 && parsedData.getLogData()[0].getCycleNumber() != 1)
+ form.setMessage("This is a delta log file. It may not contain complete information. \nTo get complete information, selected logs must be in consecutive order starting from cycle 1.", IMessageProvider.WARNING);
+
+ Section section = toolkit.createSection(form.getBody(), Section.DESCRIPTION|Section.TITLE_BAR|Section.TWISTIE|Section.EXPANDED);
+ TableWrapData td = new TableWrapData(TableWrapData.FILL);
+ td.align = TableWrapData.FILL;
+ td.grabHorizontal = true;
+
+ section.setLayoutData(td);
+ section.addExpansionListener(new ExpansionAdapter() {
+ public void expansionStateChanged(ExpansionEvent e) {
+ form.reflow(true);
+ }
+ });
+ section.setText("Properties");
+ section.setDescription("This section describes general information about log files");
+ Composite sectionClient = toolkit.createComposite(section);
+ sectionClient.setLayout(new GridLayout());
+ toolkit.createLabel(sectionClient, "Number of Cycles : "+ov.noOfcycles);
+
+ if(ov.noOfcycles > 1)
+ toolkit.createLabel(sectionClient, "Time Period : "+ov.fromTime + " to " + ov.toTime);
+ else if(ov.noOfcycles == 1){
+ toolkit.createLabel(sectionClient, "Time Period : "+ov.fromTime);
+ }
+ if(ov.duration >= 60)
+ toolkit.createLabel(sectionClient, "Time Duration : "+ov.duration + " sec (" + ov.durationString +")"); //$NON-NLS-3$
+ else
+ toolkit.createLabel(sectionClient, "Time Duration : "+ov.duration + " sec");
+ section.setClient(sectionClient);
+
+ Section analysisSection = toolkit.createSection(form.getBody(), Section.TITLE_BAR|Section.TWISTIE|Section.EXPANDED);
+ TableWrapData td3 = new TableWrapData(TableWrapData.FILL_GRAB);
+ td3.rowspan = 3;
+ td3.grabHorizontal = true;
+ td3.grabVertical = true;
+ analysisSection.setLayoutData(td3);
+ analysisSection.setText("Analysis");
+ Composite analysisComp = toolkit.createComposite(analysisSection);
+ analysisComp.setLayout(new GridLayout(1, false));
+ analysisComp.setLayoutData(new GridData(GridData.FILL));
+
+ toolkit.createLabel(analysisComp, "Top 5 issues:");
+
+ issues_table = toolkit.createTable(analysisComp, SWT.FULL_SELECTION|SWT.BORDER|SWT.SINGLE);
+ GridData table_GD = new GridData(GridData.FILL_HORIZONTAL);
+ //table_GD.heightHint = 200;
+ issues_table.setLayoutData(table_GD);
+ TableColumn col1 = new TableColumn(issues_table, SWT.NONE);
+ col1.setWidth(250);
+ col1.setText("Item");
+ TableColumn col2 = new TableColumn(issues_table, SWT.NONE);
+ col2.setWidth(200);
+ col2.setText("Event");
+ issues_table.pack();
+ issues_table.setHeaderVisible(true);
+ issues_table.setToolTipText("Double click to analyse...");
+
+ issues_table.addSelectionListener(this);
+
+ final Menu menuPopup = new Menu(issues_table);
+ analyse_menuItem = new MenuItem(menuPopup, SWT.CASCADE);
+ analyse_menuItem.setText("Analyse...");
+ analyse_menuItem.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+
+ //Open Analysis tab
+ setActivePage(ANALYSIS_PAGE);
+ //If the issues viewer is in filtered state, then make it to show all the issues.
+ filter.setFilterText(null);
+ viewer.refresh();
+
+ //Find the TreeItem which matches the selection.
+ TreeItem child_toBeSelected = null;
+ TreeItem parent_toBeExpanded = null;
+ for(TreeItem parent:issues_tree.getItems())
+ {
+ parent.setExpanded(true);
+ parent.notifyListeners(SWT.Expand, new Event());
+ for(TreeItem child:parent.getItems())
+ {
+ if(child.getText(1).equals(issues_table.getSelection()[0].getText(0)) && child.getText(2).equals(issues_table.getSelection()[0].getText(1)))
+ {
+ parent_toBeExpanded = parent;
+ child_toBeSelected = child;
+ break;
+ }
+ }
+ }
+
+ //Select the matched Treeitem in viewer.
+ if(child_toBeSelected!=null && parent_toBeExpanded !=null)
+ {
+ issues_tree.showItem(child_toBeSelected);
+ issues_tree.select(child_toBeSelected);
+ issues_tree.setFocus();
+ }
+ }
+ });
+
+
+ issues_table.setMenu(menuPopup);
+
+ issues_table.addMouseListener(new MouseListener(){
+ public void mouseDoubleClick(MouseEvent e) {
+ if(analyse_menuItem.isEnabled())
+ analyse_menuItem.notifyListeners(SWT.Selection, new Event());
+ }
+ public void mouseDown(MouseEvent e) {
+ }
+ public void mouseUp(MouseEvent e) {
+ }
+ });
+ issues_table.pack();
+
+ viewAll_btn = toolkit.createButton(analysisComp, "View all issues...", SWT.PUSH);
+ GridData viewAll_GD = new GridData(GridData.FILL);
+ viewAll_GD.horizontalAlignment = GridData.END;
+ viewAll_btn.setLayoutData(viewAll_GD);
+ viewAll_btn.addSelectionListener(this);
+ analysisSection.setClient(analysisComp);
+
+ Section romDetails = toolkit.createSection(form.getBody(), Section.DESCRIPTION|Section.TITLE_BAR|Section.TWISTIE|Section.EXPANDED);
+ TableWrapData tableData = new TableWrapData(TableWrapData.FILL);
+ tableData.align = TableWrapData.FILL;
+ tableData.grabHorizontal = true;
+
+ romDetails.setLayoutData(tableData);
+ romDetails.addExpansionListener(new ExpansionAdapter() {
+ public void expansionStateChanged(ExpansionEvent e) {
+ form.reflow(true);
+ }
+ });
+ romDetails.setText("ROM Details");
+ romDetails.setDescription("This section displays the ROM information from log files");
+ Composite romSection = toolkit.createComposite(romDetails);
+ romSection.setLayout(new GridLayout());
+
+ CycleData firstCycle = parsedData.getLogData()[0];
+
+ toolkit.createLabel(romSection, "ROM Checksum : " + firstCycle.getRomCheckSum());
+ toolkit.createLabel(romSection, "ROM Version : " + firstCycle.getRomVersion());
+ romDetails.setClient(romSection);
+
+ Section section2 = toolkit.createSection(form.getBody(), Section.DESCRIPTION|Section.TITLE_BAR|Section.TWISTIE|Section.EXPANDED);
+ TableWrapData td2 = new TableWrapData(TableWrapData.FILL);
+ section2.setLayoutData(td2);
+ section2.addExpansionListener(new ExpansionAdapter() {
+ public void expansionStateChanged(ExpansionEvent e) {
+ form.reflow(true);
+ }
+ });
+ section2.setText("Export Options");
+ section2.setDescription("Specify the export options");
+ Composite sectionClient2 = toolkit.createComposite(section2);
+ sectionClient2.setLayout(new GridLayout(4, false));
+
+ GridData gd1 = new GridData();
+ gd1.horizontalSpan = 4;
+ allBtn = toolkit.createButton(sectionClient2, "All",SWT.RADIO);
+ notAllBtn = toolkit.createButton(sectionClient2, "Selected log files",SWT.RADIO);
+ allBtn.setLayoutData(gd1);
+ allBtn.setSelection(true);
+ allBtn.addSelectionListener(this);
+
+ notAllBtn.setLayoutData(gd1);
+ notAllBtn.addSelectionListener(this);
+
+ toolkit.createLabel(sectionClient2, "From");
+ Label fromLabel = new Label(sectionClient2, SWT.NONE);
+
+ toolkit.createLabel(sectionClient2, " To");
+ toCombo = new Combo(sectionClient2, SWT.DROP_DOWN|SWT.READ_ONLY);
+ toCombo.setEnabled(false);
+ toCombo.addSelectionListener(this);
+
+ Composite exportComp = new Composite(sectionClient2,SWT.NONE);
+ exportComp.setLayout(new GridLayout());
+ GridData exGD = new GridData();
+ exGD.horizontalSpan = 4;
+ exportComp.setLayoutData(exGD);
+ export = toolkit.createButton(exportComp, "Export as XLS...", SWT.PUSH);
+ export.addSelectionListener(this);
+
+ section2.setClient(sectionClient2);
+
+ OVERVIEW_PAGE = addPage(composite);
+ setPageText(OVERVIEW_PAGE, "Overview");
+
+
+ CycleData [] parsed_cycles = parsedData.getLogData();
+
+ if(parsedData.getNumberOfCycles() == 1)
+ {
+ int cycleNo = parsed_cycles[0].getCycleNumber();
+ fromLabel.setText(Integer.toString(cycleNo));
+ toCombo.add(Integer.toString(cycleNo));
+ }
+ else
+ {
+ fromLabel.setText("1");
+ for (int i = 1 ; i <= parsed_cycles.length ; i++)
+ {
+ toCombo.add(Integer.toString(i));
+ }
+ }
+
+ toCombo.select(parsed_cycles.length -1);
+
+ }
+
+ /**
+ * Creates Graphs page of the SWMT Editor.
+ *
+ */
+ private void createGraphsPage()
+ {
+ Composite parent = new Composite(getContainer(), SWT.NONE);
+ parent.setLayout(new FormLayout());
+
+ Composite titleBar = new Composite(parent, SWT.NONE);
+ Composite holder = new Composite(parent, SWT.NONE);
+
+ title = new Label(titleBar, SWT.CENTER|SWT.BORDER);
+ title.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_DARK_BLUE));
+ title.setForeground(parent.getDisplay().getSystemColor(SWT.COLOR_WHITE));
+
+ Font roman_8 = new Font(parent.getDisplay(), "Arial", 10, SWT.BOLD);
+ title.setFont(roman_8);
+ title.setText("");
+
+ FormData data = new FormData();
+ data.left = new FormAttachment(0);
+ data.right = new FormAttachment(100);
+ title.setLayoutData(data);
+
+ FormData formData = new FormData();
+ formData.top = new FormAttachment(0);
+ formData.left = new FormAttachment(0);
+ formData.right = new FormAttachment(100);
+ titleBar.setLayoutData(formData);
+ titleBar.setLayout(new FormLayout());
+
+ // FormData for the overall holder composite
+ formData = new FormData();
+ formData.top = new FormAttachment(titleBar);
+ formData.bottom = new FormAttachment(100);
+ formData.left = new FormAttachment(0);
+ formData.right = new FormAttachment(100);
+ holder.setLayoutData(formData);
+ holder.setLayout(new FormLayout());
+
+ SashForm graphSash = new SashForm(holder, SWT.VERTICAL|SWT.SMOOTH|SWT.BORDER);
+ graphSash.SASH_WIDTH = 5;
+ graphSash.setLayout(new FillLayout());
+
+ Composite bottomComposite = new SashForm(holder, SWT.VERTICAL);
+ final Sash acrossSash = new Sash(holder, SWT.HORIZONTAL);
+
+ formData = new FormData();
+ formData.top = new FormAttachment(0);
+ formData.bottom = new FormAttachment(acrossSash);
+ formData.left = new FormAttachment(0);
+ formData.right = new FormAttachment(100);
+ graphSash.setLayoutData(formData);
+ graphSash.setLayout(new FormLayout());
+
+ // FormData for bottom composite
+ formData = new FormData();
+ formData.top = new FormAttachment(acrossSash);
+ formData.bottom = new FormAttachment(100);
+ formData.left = new FormAttachment(0);
+ formData.right = new FormAttachment(100);
+ bottomComposite.setLayoutData(formData);
+ bottomComposite.setLayout(new FormLayout());
+
+ // FormData for acrossSash
+ // Put it initially in the middle
+ formData = new FormData();
+ formData.top = new FormAttachment(50);
+ formData.left = new FormAttachment(0);
+ formData.right = new FormAttachment(100);
+ acrossSash.setLayoutData(formData);
+
+ final FormData acrossSashData = formData;
+ final Composite parentFinal = acrossSash.getParent();
+ acrossSash.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent event) {
+ if (event.detail != SWT.DRAG) {
+ acrossSashData.top = new FormAttachment(0, event.y);
+ parentFinal.layout();
+ }
+ }
+ });
+ graph = new SwmtGraph(graphSash);
+ allEventsGraph = new GraphForAllEvents(graphSash);
+
+ graph.setInputCyclesData(parsedData);
+ allEventsGraph.setInputCyclesData(parsedData);
+
+ graph.constructGraphArea();
+
+ mainTabFolder = new TabFolder(bottomComposite, SWT.NONE);
+ mainTabFolder.setLayout(new FillLayout(2));
+ GridData tabGD=new GridData(GridData.FILL_HORIZONTAL);
+ mainTabFolder.setLayoutData(tabGD);
+ mainTabFolder.addSelectionListener(this);
+
+ //Construct Events Tab
+ constructEventTabsArea(mainTabFolder);
+ //Construct Graphed Items Tab
+ TabItem graphedItemsTab = new TabItem(mainTabFolder,SWT.NONE);
+ graphedItemsTab.setText(GRAPHED_ITEMS_LABEL);
+
+ GraphedItemsHelper graphedTabHelper = new GraphedItemsHelper();
+ graphedItemsViewer = graphedTabHelper.constructGraphedItemsViewer(graphedItemsTab, allEventsGraph);
+
+ GRAPHS_PAGE = addPage(parent);
+ setPageText(GRAPHS_PAGE, " Graphs ");
+
+ if(threads != null)
+ threadTble.setInput(threads);
+ if(chunks != null)
+ chunkTble.setInput(chunks);
+ if(disks != null)
+ diskTble.setInput(disks);
+
+ sysinfoTble.setInput(GenericGraph.getGraphableKernels());
+
+
+
+ }
+
+ /**
+ * Creates Anlysis page in the SWMT Editor
+ *
+ */
+ private void createAnalysisPage()
+ {
+ Composite parentComposite = new Composite(getContainer(), SWT.NONE);
+ parentComposite.setLayout(new FormLayout());
+
+ Composite titleBar = new Composite(parentComposite, SWT.NONE);
+ Composite holder = new Composite(parentComposite, SWT.NONE);
+
+ Label graph_title = new Label(titleBar, SWT.CENTER|SWT.BORDER);
+ graph_title.setBackground(parentComposite.getDisplay().getSystemColor(SWT.COLOR_DARK_BLUE));
+ graph_title.setForeground(parentComposite.getDisplay().getSystemColor(SWT.COLOR_WHITE));
+
+ Font roman_8 = new Font(parentComposite.getDisplay(), "Arial", 10, SWT.BOLD);
+ graph_title.setFont(roman_8);
+ graph_title.setText("");
+
+ FormData formData = new FormData();
+ formData.top = new FormAttachment(0);
+ formData.left = new FormAttachment(0);
+ formData.right = new FormAttachment(100);
+ titleBar.setLayoutData(formData);
+ titleBar.setLayout(new FormLayout());
+
+ FormData data = new FormData();
+ data.left = new FormAttachment(0);
+ data.right = new FormAttachment(100);
+ graph_title.setLayoutData(data);
+
+ // FormData for the overall holder composite
+ formData = new FormData();
+ formData.top = new FormAttachment(titleBar);
+ formData.bottom = new FormAttachment(100);
+ formData.left = new FormAttachment(0);
+ formData.right = new FormAttachment(100);
+ holder.setLayoutData(formData);
+ holder.setLayout(new FormLayout());
+
+ graphSash = new SashForm(holder, SWT.VERTICAL|SWT.SMOOTH|SWT.BORDER);
+ graphSash.SASH_WIDTH = 5;
+ graphSash.setLayout(new FillLayout());
+
+ Composite bottomComposite = new SashForm(holder, SWT.VERTICAL);
+ final Sash acrossSash = new Sash(holder, SWT.HORIZONTAL);
+
+ formData = new FormData();
+ formData.top = new FormAttachment(0);
+ formData.bottom = new FormAttachment(acrossSash);
+ formData.left = new FormAttachment(0);
+ formData.right = new FormAttachment(100);
+ graphSash.setLayoutData(formData);
+ graphSash.setLayout(new FormLayout());
+
+ // FormData for bottom
+ formData = new FormData();
+ formData.top = new FormAttachment(acrossSash);
+ formData.bottom = new FormAttachment(100);
+ formData.left = new FormAttachment(0);
+ formData.right = new FormAttachment(100);
+ bottomComposite.setLayoutData(formData);
+ bottomComposite.setLayout(new FormLayout());
+
+ // FormData for acrossSash
+ // Put it initially in the middle
+ formData = new FormData();
+ formData.top = new FormAttachment(50);
+ formData.width = 20;
+ formData.left = new FormAttachment(0);
+ formData.right = new FormAttachment(100);
+ acrossSash.setLayoutData(formData);
+
+ final FormData acrossSashData = formData;
+ final Composite parentFinal = acrossSash.getParent();
+ acrossSash.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent event) {
+ if (event.detail != SWT.DRAG) {
+ acrossSashData.top = new FormAttachment(0, event.y);
+ parentFinal.layout();
+ }
+ }
+ });
+
+ Composite parent = new Composite(bottomComposite, SWT.NONE);
+ parent.setLayout(new GridLayout(7, false));
+ parent.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+ Label title = new Label(parent, SWT.WRAP);
+ title.setText("Linear Analysis Results");
+ title.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+ //Action button used for creation of report file.
+ generate_report_btn = new Button(parent, SWT.PUSH);
+ generate_report_btn.setText("Generate report...");
+ generate_report_btn.setToolTipText("Click here to generate pdf report for the selected issues.");
+ generate_report_btn.addSelectionListener(this);
+
+ Label separator = new Label(parent, SWT.SEPARATOR);
+ GridData sepGD = new GridData();
+ sepGD.heightHint = 25;
+ separator.setLayoutData(sepGD);
+
+ Label severity = new Label(parent, SWT.NONE);
+ severity.setText("Severity:");
+
+ severity_label = new Label(parent, SWT.WRAP);
+ severity_label.setText(" ");
+ GridData d = new GridData(GridData.FILL);
+ d.heightHint = 20;
+ severity_label.setLayoutData(d);
+
+ severity_combo = new Combo(parent, SWT.BORDER|SWT.READ_ONLY);
+ d = new GridData();
+ d.widthHint = 100;
+ severity_combo.setLayoutData(d);
+ severity_combo.setItems(new String[]{"All", AnalyserConstants.Priority.CRITICAL.name(), AnalyserConstants.Priority.HIGH.name(),AnalyserConstants.Priority.NORMAL.name(), "Custom filter"});
+ severity_combo.addSelectionListener(this);
+ severity_combo.select(0);
+ severity_combo.setToolTipText("Severity of an issue.");
+
+ //Action button used to launch Custom filter dialog.
+ advanced_filter_button = new Button(parent, SWT.PUSH);
+ advanced_filter_button.setText("Set Custom filter...");
+ advanced_filter_button.addSelectionListener(this);
+ advanced_filter_button.setToolTipText("Advanced settings to filter issues below.");
+ advanced_filter_button.setEnabled(false);
+
+ issues_tree = new Tree(parent, SWT.FULL_SELECTION | SWT.MULTI | SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL | SWT.CHECK);
+ GridData gd = new GridData(GridData.FILL_BOTH);
+ gd.horizontalSpan = 7;
+ gd.grabExcessVerticalSpace = true;
+ issues_tree.addSelectionListener(this);
+
+ LinearIssuesGraph issue_graph = new LinearIssuesGraph(graphSash);
+ issue_graph.setLogData(parsedData);
+
+ //Creates issues viewer.
+ viewer = new IssuesViewer(issues_tree, issue_graph);
+ viewer.createIssuesViewerAndGraph();
+ viewer.setContentProvider(new IssuesTreeContentProvider());
+ viewer.setLabelProvider(new IssuesTreeLabelProvider());
+ filter = new IssuesFilter();
+ viewer.addFilter(filter);
+
+ ANALYSIS_PAGE = addPage(parentComposite);
+ setPageText(ANALYSIS_PAGE, " Analysis ");
+
+ SWMTAnalysisRunnable start_analysis = new SWMTAnalysisRunnable();
+ IWorkbench wb = PlatformUI.getWorkbench();
+ IWorkbenchWindow win = wb.getActiveWorkbenchWindow();
+ Shell shell = win != null ? win.getShell() : null;
+ try {
+ new ProgressMonitorDialog(shell).run(true, true, start_analysis);
+ } catch (InvocationTargetException err) {
+ err.printStackTrace();
+ } catch (InterruptedException err) {
+ err.printStackTrace();
+ }
+ viewer.setInput(analysis_results_obj);
+
+ //Set top 5 issues in the overview tab
+ setTopIssues(analysis_results_obj);
+
+ issues_tree.setFocus();
+ }
+
+ /**
+ * Construts UI controls under Events Tab area.
+ * @param mainTabFolder represents parent folder
+ */
+ private void constructEventTabsArea(TabFolder mainTabFolder)
+ {
+ eventsTab = new TabItem(mainTabFolder,SWT.NONE);
+ eventsTab.setText(" Events ");
+
+ //Events Tab => events list and 4 inner tabs
+ SashForm form=new SashForm(mainTabFolder, SWT.BORDER|SWT.HORIZONTAL|SWT.SMOOTH);
+ form.setLayout(new GridLayout());
+
+ Composite eventC = new Composite(form, SWT.NONE);
+ eventC.setLayout(new GridLayout(1,false));
+ eventC.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+ eventsCombo = new Combo(eventC, SWT.BORDER|SWT.V_SCROLL | SWT.READ_ONLY);
+
+ GridData comboGD = new GridData(GridData.FILL_HORIZONTAL);
+ eventsCombo.setLayoutData(comboGD);
+ for(CATEGORIES value : CATEGORIES.values())
+ eventsCombo.add(value.toString());
+ eventsCombo.addSelectionListener(this);
+
+
+ eventList = new List(eventC, SWT.BORDER|SWT.SINGLE|SWT.V_SCROLL|SWT.H_SCROLL);
+ GridData listGD = new GridData(GridData.FILL_BOTH);
+ listGD.grabExcessVerticalSpace = true;
+ eventList.setLayoutData(listGD);
+ eventList.addSelectionListener(this);
+
+ innerTabFolder = new TabFolder(form, SWT.NONE);
+ innerTabFolder.setLayout(new GridLayout());
+ GridData innertabGD = new GridData(GridData.FILL_HORIZONTAL|GridData.FILL_VERTICAL);
+ innertabGD.verticalSpan = 2;
+ innerTabFolder.setLayoutData(innertabGD);
+ innerTabFolder.addSelectionListener(this);
+
+ threadTab = new TabItem(innerTabFolder,SWT.NONE);
+ threadTab.setText(" Threads ");
+
+ Composite compositeThrd = new Composite(innerTabFolder, SWT.NONE);
+ compositeThrd.setLayout(new GridLayout(1, true));
+ threadTble = new FilterTextTable(this, compositeThrd, FilterTextTable.THREADS_TITLE);
+ this.threadViewer = threadTble.getTableViewer();
+
+ GridData table_layout_data = new GridData(GridData.FILL_BOTH);
+ table_layout_data.grabExcessVerticalSpace = true;
+
+ compositeThrd.setLayoutData(table_layout_data);
+ threadTab.setControl(compositeThrd);
+
+ chunksTab = new TabItem(innerTabFolder,SWT.NONE);
+ chunksTab.setText(" Chunks ");
+
+ Composite compositeChnk = new Composite(innerTabFolder, SWT.NONE);
+ compositeChnk.setLayout(new GridLayout(1, true));
+ chunkTble = new FilterTextTable(this, compositeChnk, FilterTextTable.CHUNKS_TITLE);
+ compositeChnk.setLayoutData(table_layout_data);
+ chunksTab.setControl(compositeChnk);
+ this.chunksViewer = chunkTble.getTableViewer();
+
+ diskTab = new TabItem(innerTabFolder,SWT.NONE);
+ diskTab.setText(" Disks ");
+
+ Composite compositeDisk = new Composite(innerTabFolder, SWT.NONE);
+ compositeDisk.setLayout(new GridLayout(1, false));
+ compositeDisk.setLayoutData(table_layout_data);
+ diskTble = new FilterTextTable(this, compositeDisk, FilterTextTable.DISKS_TITLE);
+ diskTab.setControl(compositeDisk);
+ this.disksViewer = diskTble.getTableViewer();
+
+ sysInfoTab = new TabItem(innerTabFolder,SWT.NONE);
+ sysInfoTab.setText(" System Data ");
+
+ Composite compositeSysinfo = new Composite(innerTabFolder, SWT.NONE);
+ compositeSysinfo.setLayout(new GridLayout(1, false));
+ compositeSysinfo.setLayoutData(table_layout_data);
+ sysinfoTble = new FilterTextTable(this, compositeSysinfo, FilterTextTable.SYSTEM_DATA_TITLE);
+ sysInfoTab.setControl(compositeSysinfo);
+ this.sysElemsViewer = sysinfoTble.getTableViewer();
+
+ eventsCombo.select(0);
+ eventsCombo.notifyListeners(SWT.Selection, new Event());
+
+ form.setWeights(new int[] {30,70});
+ form.SASH_WIDTH = 1;
+ eventsTab.setControl(form);
+ }
+
+ /**
+ * Creates the pages of the multi-page editor.
+ */
+ protected void createPages() {
+
+ if(parsedData == null || parsedData.getNumberOfCycles() == 0)
+ return;
+
+ createOverviewPage();
+
+ if(parsedData.getNumberOfCycles() > 1)
+ {
+ createGraphsPage();
+ createAnalysisPage();
+ }
+ else
+ {
+ TableItem no_issues_item = new TableItem(issues_table,SWT.NONE);
+ no_issues_item.setText(NO_ISSUES_MSG);
+ viewAll_btn.setEnabled(false);
+ }
+ }
+
+ /**
+ * The method picks up the top 5 critical issues from the given list of issues
+ * and displays them in the overview page.
+ * @param issues_results
+ */
+ public void setTopIssues(ArrayList<Object> issues_results)
+ {
+ if(issues_results.size() == 0)
+ {
+ TableItem item = new TableItem(issues_table,SWT.NONE);
+ item.setText(NO_ISSUES_MSG);
+ return;
+ }
+
+ ArrayList<ResultElements> critical_issues = new ArrayList<ResultElements>();
+
+ for(Object obj:issues_results)
+ {
+ if(obj instanceof ResultsParentNodes)
+ {
+ ResultsParentNodes parent = (ResultsParentNodes)obj;
+ Object[] children = parent.getChildren();
+
+ for(Object issue:children)
+ {
+ if(issue instanceof ResultElements)
+ {
+ ResultElements issue_elem = (ResultElements)(issue);
+ if(issue_elem.getPriority() == AnalyserConstants.Priority.CRITICAL)
+ critical_issues.add(issue_elem);
+ }
+ }
+ }
+ }
+
+ if(critical_issues.size() == 0)
+ {
+ TableItem item = new TableItem(issues_table,SWT.NONE);
+ item.setText(NO_ISSUES_MSG);
+ return;
+ }
+ else
+ {
+ Collections.sort(critical_issues);
+
+ for(int index = critical_issues.size()-1, i=1; i <=5;i++,index--)
+ {
+ if(index < 0)
+ break;
+
+ ResultElements temp = critical_issues.get(index);
+ TableItem item = new TableItem(issues_table,SWT.NONE);
+ item.setText(new String[]{temp.getItemName(),temp.getEvent()});
+ }
+ }
+
+ }
+
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.part.MultiPageEditorPart#dispose()
+ */
+ public void dispose() {
+ super.dispose();
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.part.EditorPart#doSave(org.eclipse.core.runtime.IProgressMonitor)
+ */
+ public void doSave(IProgressMonitor monitor) {
+ getEditor(0).doSave(monitor);
+ }
+ /**
+ * Saves the multi-page editor's document as another file.
+ * Also updates the text for page 0's tab, and updates this multi-page editor's input
+ * to correspond to the nested editor's.
+ * @see org.eclipse.ui.part.EditorPart#doSaveAs()
+ */
+ public void doSaveAs() {
+ IEditorPart editor = getEditor(0);
+ editor.doSaveAs();
+ setPageText(0, editor.getTitle());
+ setInput(editor.getEditorInput());
+ }
+
+ /**
+ * Go to marker
+ * @see IDE#gotoMarker(IEditorPart, IMarker)
+ * @param marker
+ */
+ public void gotoMarker(IMarker marker) {
+ setActivePage(0);
+ IDE.gotoMarker(getEditor(0), marker);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.part.MultiPageEditorPart#init(org.eclipse.ui.IEditorSite, org.eclipse.ui.IEditorInput)
+ */
+ public void init(IEditorSite site, IEditorInput editorInput)
+ throws PartInitException {
+ if (!(editorInput instanceof SWMTEditorInput))
+ throw new PartInitException("Invalid Input: Must be SWMTEditorInput");
+ parsedData = ((SWMTEditorInput)editorInput).getParsedData();
+ ov = ((SWMTEditorInput)editorInput).getOverview();
+
+ SWMTLogReaderUtils util = new SWMTLogReaderUtils();
+
+ threads = util.getAllThreadNames(parsedData);
+ if(threads != null)
+ Collections.sort(threads);
+
+ chunks = util.getAllGlobalChunkNames(parsedData);
+ if(chunks != null)
+ Collections.sort(chunks);
+
+ nonHeapChunks = util.getAllNonHeapChunkNames(parsedData);
+ if(nonHeapChunks != null)
+ Collections.sort(nonHeapChunks);
+
+ disks = util.getAllDiskNames(parsedData);
+ if(disks != null)
+ Collections.sort(disks);
+
+ super.init(site, editorInput);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.part.EditorPart#isSaveAsAllowed()
+ */
+ public boolean isSaveAsAllowed() {
+ return true;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.swt.events.SelectionListener#widgetDefaultSelected(org.eclipse.swt.events.SelectionEvent)
+ */
+ public void widgetDefaultSelected(SelectionEvent e) {
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt.events.SelectionEvent)
+ */
+ public void widgetSelected(SelectionEvent e) {
+
+ //When Export button is selected, data from given log files
+ //will be exported to an excel file.
+ if(e.widget == export)
+ {
+ FileDialog dlg = new FileDialog(Display.getCurrent().getActiveShell(), SWT.SAVE);
+ dlg.setFilterExtensions(new String[]{"*.xls"});
+ String fileName = dlg.open();
+ if(fileName==null)
+ return;
+
+ SWMTExcelCreationRunnableWithProcess process = new SWMTExcelCreationRunnableWithProcess(fileName, parsedData, toCombo.getSelectionIndex()+1);
+ IWorkbench wb = PlatformUI.getWorkbench();
+ IWorkbenchWindow win = wb.getActiveWorkbenchWindow();
+ Shell shell = win != null ? win.getShell() : null;
+ try {
+ new ProgressMonitorDialog(shell).run(true, true, process);
+ } catch (InvocationTargetException err) {
+ err.printStackTrace();
+ } catch (InterruptedException err) {
+ err.printStackTrace();
+ }
+ }
+ else if(e.widget == allBtn)
+ {
+ toCombo.setEnabled(false);
+ }
+ else if(e.widget == notAllBtn)
+ {
+ toCombo.setEnabled(true);
+ }
+ else if(e.widget == viewAll_btn)
+ {
+ this.setActivePage(ANALYSIS_PAGE);
+ }
+ /*
+ * When Events list selection is changed, all previous selections should be cleared
+ * and they should be moved to Graphed items tab.
+ * Also, listeners of enabled tables should be notified.
+ */
+ else if(e.widget == eventList)
+ {
+ selectedEvent = eventList.getSelection()[0];
+ title.setText(selectedEvent);
+ updateGraphedItemsList(lastSelectedEvent);
+
+ if(!selectedEvent.equals(lastSelectedEvent))
+ {
+ chunkTble.cancelSelectionList();
+ threadTble.cancelSelectionList();
+ diskTble.cancelSelectionList();
+ sysinfoTble.cancelSelectionList();
+ }
+
+ if(!selectedEvent.equals(lastSelectedEvent) && graph != null)
+ graph.clearGraph();
+
+ if(Arrays.asList(RAM_GRP).contains(selectedEvent))
+ {
+ threadTble.setEnabled(false);
+ chunkTble.setEnabled(false);
+ diskTble.setEnabled(false);
+ sysinfoTble.setEnabled(false);
+
+ DisksGraph diskGraph = new DisksGraph();
+ GenericGraph.EventTypes eventType = GraphsUtils.getMappedEvent(selectedEvent);
+ diskGraph.setEvent(eventType);
+ diskGraph.setCyclesData(parsedData);
+
+ if(graph != null)
+ graph.redraw(diskGraph);
+ }
+ else
+ {
+ if(Arrays.asList(CHUNKS_GRP).contains(selectedEvent))
+ {
+ if(Arrays.asList(CHUNKS_GRP).indexOf(selectedEvent)==0 && !selectedEvent.equals(lastSelectedEvent))
+ chunkTble.setInput(chunks);
+ else if(Arrays.asList(CHUNKS_GRP).indexOf(selectedEvent)==1 && !selectedEvent.equals(lastSelectedEvent))
+ chunkTble.setInput(nonHeapChunks);
+ innerTabFolder.setSelection(chunksTab);
+
+ CheckStateChangedEvent event = new CheckStateChangedEvent(chunksViewer, null, false);
+
+ if(chunkTble.getCheckStateListener() != null)
+ chunkTble.getCheckStateListener().checkStateChanged(event);
+ }
+ else if(Arrays.asList(HEAP_GRP).contains(selectedEvent) || Arrays.asList(FILES_GRP).contains(selectedEvent) || Arrays.asList(HPAS_GRP).contains(selectedEvent))
+ {
+ innerTabFolder.setSelection(threadTab);
+
+ CheckStateChangedEvent event = new CheckStateChangedEvent(threadViewer, null, false);
+ if(threadTble.getCheckStateListener() != null)
+ threadTble.getCheckStateListener().checkStateChanged(event);
+ }
+ else if(Arrays.asList(DISK_GRP).contains(selectedEvent))
+ {
+ innerTabFolder.setSelection(diskTab);
+
+ CheckStateChangedEvent event = new CheckStateChangedEvent(disksViewer, null, false);
+ if(diskTble.getCheckStateListener() != null)
+ diskTble.getCheckStateListener().checkStateChanged(event);
+ }
+ else if(Arrays.asList(SYSINFO_GRP).contains(selectedEvent))
+ {
+ innerTabFolder.setSelection(sysInfoTab);
+
+ CheckStateChangedEvent event = new CheckStateChangedEvent(sysElemsViewer, null, false);
+
+ if(sysinfoTble.getCheckStateListener() != null)
+ sysinfoTble.getCheckStateListener().checkStateChanged(event);
+ }
+
+ threadTble.setEnabled(innerTabFolder.getItem(innerTabFolder.getSelectionIndex())==threadTab);
+ chunkTble.setEnabled(innerTabFolder.getItem(innerTabFolder.getSelectionIndex())==chunksTab);
+ diskTble.setEnabled(innerTabFolder.getItem(innerTabFolder.getSelectionIndex())==diskTab);
+ sysinfoTble.setEnabled(innerTabFolder.getItem(innerTabFolder.getSelectionIndex())==sysInfoTab);
+
+ }
+
+ lastSelectedEvent = selectedEvent;
+ }
+ //Events list will be modified based on the selection of
+ //event category from the drop down box.
+ else if(e.widget == eventsCombo)
+ {
+ eventList.removeAll();
+ CATEGORIES index = CATEGORIES.valueOf(eventsCombo.getText());
+ switch(index)
+ {
+ case All_events:
+ eventList.setItems(ALL_GRP);
+ break;
+ case Chunks:
+ eventList.setItems(CHUNKS_GRP);
+ break;
+ case Disk:
+ eventList.setItems(DISK_GRP);
+ break;
+ case Files:
+ eventList.setItems(FILES_GRP);
+ break;
+ case Heap:
+ eventList.setItems(HEAP_GRP);
+ break;
+ case HPAS:
+ eventList.setItems(HPAS_GRP);
+ break;
+ case RAM:
+ eventList.setItems(RAM_GRP);
+ break;
+ case System_info:
+ eventList.setItems(SYSINFO_GRP);
+ break;
+ }
+ eventList.select(0);
+
+ if(eventList.getItemCount() > 0)
+ {
+ eventList.notifyListeners(SWT.Selection, new Event());
+ }
+ }
+ else if(e.widget == mainTabFolder && mainTabFolder.getSelectionIndex() != -1 &&
+ mainTabFolder.getSelection()[0].getText().trim().equalsIgnoreCase(GRAPHED_ITEMS_LABEL))
+ {
+ selectedEvent = eventList.getSelection()[0];
+ updateGraphedItemsList(selectedEvent);
+
+ title.setText("Graphed Items");
+
+ Object [] checkedElems = graphedItemsViewer.getCheckedElements();
+ ArrayList<GraphedItemsInput> selectedItems = new ArrayList<GraphedItemsInput>();
+
+ for(Object obj:checkedElems)
+ {
+ GraphedItemsInput graphInput = (GraphedItemsInput)obj;
+ selectedItems.add(graphInput);
+ }
+
+ allEventsGraph.setGraphedItemsInput(selectedItems);
+ allEventsGraph.constructGraphArea();
+
+ }
+ else if(e.widget == mainTabFolder && mainTabFolder.getSelectionIndex() != -1 && mainTabFolder.getSelection()[0] == eventsTab)
+ {
+ if(graphedItemsViewer.getInput() == null)
+ {
+ graphed.clear();
+ }
+ graph.constructGraphArea();
+
+ if(eventList.getSelectionIndex() != -1){
+ title.setText(eventList.getItem(eventList.getSelectionIndex()));
+ eventList.notifyListeners(SWT.Selection, new Event());
+ }
+ else
+ title.setText("");
+
+ }
+
+ //Issues list gets modified based on the selection of Severity
+ //from the drop down box.
+ else if(e.widget == severity_combo)
+ {
+ advanced_filter_button.setEnabled(false);
+ filter.setAdvancedSearchOptions(null);
+ Image img = null;
+ String icon_name = "";
+ switch(severity_combo.getSelectionIndex())
+ {
+ case 1:
+ icon_name = "\\red.png";
+ filter.setFilterText(AnalyserConstants.Priority.CRITICAL.name());
+ break;
+ case 2:
+ icon_name = "\\yellow.png";
+ filter.setFilterText(AnalyserConstants.Priority.HIGH.name());
+ break;
+ case 3:
+ icon_name = "\\green.png";
+ filter.setFilterText(AnalyserConstants.Priority.NORMAL.name());
+ break;
+ case 4:
+ advanced_filter_button.setEnabled(true);
+ default:
+ icon_name = null;
+ filter.setFilterText(null);
+ break;
+ }
+ if(icon_name!=null)
+ {
+ try {
+ img = new Image( Display.getCurrent(), SwmtAnalyserPlugin.getPluginInstallPath() + "\\icons" + icon_name);
+ } catch (RuntimeException e1) {
+ e1.printStackTrace();
+ }
+ }
+ severity_label.setImage(img);
+ issues_tree.setFocus();
+ viewer.refresh();
+ }
+ else if(e.widget == issues_table)
+ {
+ analyse_menuItem.setEnabled(!issues_table.getSelection()[0].getText(0).startsWith(NO_ISSUES_MSG));
+ }
+ else if(e.widget == advanced_filter_button)
+ {
+ AdvancedFilterDialog dlg = new AdvancedFilterDialog(Display.getCurrent().getActiveShell());
+ int status = dlg.open();
+ if(status == Dialog.OK)
+ {
+ FilterInput input = dlg.getFilterOptions();
+ filter.setAdvancedSearchOptions(input);
+ issues_tree.setFocus();
+ viewer.refresh();
+ }
+ }
+ else if(e.widget == generate_report_btn)
+ {
+ //Save graph in temporary location
+ GC gc = new GC(graphSash);
+ Image image = new Image(Display.getCurrent(), graphSash.getClientArea().width, graphSash.getClientArea().height);
+ graphSash.setFocus();
+ gc.copyArea(image, 0, 0);
+ gc.dispose();
+ ImageData data = image.getImageData();
+ ImageLoader loader = new ImageLoader();
+ loader.data = new ImageData[] {data};
+ loader.save(SwmtAnalyserPlugin.getPluginInstallPath()+"\\swmt_graph.bmp", SWT.IMAGE_BMP);
+ image.dispose();
+
+ // Now open the wizard
+ Runnable showWizardRunnable = new Runnable(){
+ public void run(){
+ WizardDialog wizDialog;
+ ReportGenerationWizard wiz = new ReportGenerationWizard(ov, parsedData.getLogData()[0].getRomCheckSum(), parsedData.getLogData()[0].getRomVersion(), issues_tree);
+ wizDialog = new WizardDialog(Display.getCurrent().getActiveShell(), wiz);
+ wizDialog.create();
+ wizDialog.getShell().setSize(400, 500);
+ wizDialog.addPageChangedListener(wiz);
+ wizDialog.open();
+ }
+ };
+ Display.getDefault().asyncExec(showWizardRunnable);
+ }
+ }
+
+ /**
+ * SWMT specific runnable process for creating excel.
+ *
+ */
+ private class SWMTExcelCreationRunnableWithProcess implements IRunnableWithProgress
+ {
+ private String fileName;
+ private CycleData [] data = new CycleData [0];
+ private int exportFilesNo;
+ private OverviewData ovData;
+ public SWMTExcelCreationRunnableWithProcess(String fileName, ParsedData parsedData,int exportFiles) {
+ this.data = parsedData.getLogData();
+ this.fileName = fileName;
+ this.exportFilesNo = exportFiles;
+ }
+
+ public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
+ createExcel(monitor);
+ }
+
+ private void createExcel(IProgressMonitor monitor)
+ {
+ monitor.beginTask("Parsing log files...", 10);
+ ExcelCreator creator = new ExcelCreator(fileName);
+ ovData = (new SWMTLogReaderUtils()).getOverviewInformationFromCyclesData(data, this.exportFilesNo);
+ creator.setOverviewPageInput(ovData);
+
+ ArrayList<CycleData> exportedCycles = new ArrayList<CycleData>();
+
+ if(this.exportFilesNo >= 255)
+ {
+ int extras = this.exportFilesNo - 254;
+ ArrayList<Integer> series = new ArrayList<Integer>(extras);
+
+ if(extras ==1)
+ {
+ series.add(this.exportFilesNo/2);
+ creator.setSkipFileConstant(series);
+ }
+ else
+ {
+ int temp = this.exportFilesNo;
+ while(series.size()!=extras)
+ {
+ temp = temp/2;
+ for(int i=2; i<this.exportFilesNo; i++)
+ {
+ if(i%temp == 0)
+ {
+ if(!series.contains(i))
+ series.add(i);
+ if(series.size() == extras)
+ break;
+ }
+ }
+ }
+ creator.setSkipFileConstant(series);
+ }
+ }
+
+ for(int i=0; i<exportFilesNo; i++)
+ {
+ CycleData cycle = data[i];
+ exportedCycles.add(cycle);
+ }
+ monitor.worked(3);
+
+ ParsedData exportedData = new ParsedData();
+ exportedData.setParsedData(exportedCycles);
+
+ creator.setInputCyclesData(exportedData);
+
+ if(creator.createExcel(monitor))
+ {
+ monitor.done();
+ Runnable p = new Runnable(){
+
+ public void run() {
+ if(MessageDialog.openQuestion(Display.getCurrent().getActiveShell(),"Confirmation","Would you like to open the saved file?"))
+ {
+ Program p=Program.findProgram(".xls");
+ if(p!=null)
+ p.execute(fileName);
+ }
+ }
+
+ };
+ Display.getDefault().asyncExec(p);
+ }
+ else
+ {
+ File file = new File(fileName);
+ file.delete();
+ }
+ }
+ }
+
+ /**
+ * Runnable class to run analysis in new thread.
+ *
+ */
+ public class SWMTAnalysisRunnable implements IRunnableWithProgress
+ {
+
+ public SWMTAnalysisRunnable() {
+ }
+
+ public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
+ monitor.beginTask("Analysing data...", 10);
+ int worked = 0;
+ for(IAnalyser analyser:SwmtAnalyserPlugin.getDefault().getRegisteredAnalysers())
+ {
+ analyser.analyse(parsedData);
+ analysis_results_obj.addAll(Arrays.asList(analyser.getResults()));
+ worked = worked + 10/(SwmtAnalyserPlugin.getDefault().getRegisteredAnalysers().length) ;
+ monitor.worked(worked);
+ }
+ monitor.done();
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see com.nokia.s60tools.swmtanalyser.ui.graphs.IGraphTypeSelectionListener#notifyThreadsSelection()
+ */
+ public void notifyThreadsSelection()
+ {
+ Object [] checkedElements = this.threadViewer.getCheckedElements();
+
+ ArrayList<String> threadNames = new ArrayList<String>();
+ ArrayList<Color> threadColors = new ArrayList<Color>();
+
+ for(Object obj: checkedElements)
+ {
+ if(obj instanceof TableViewerInputObject)
+ {
+ TableViewerInputObject checkedItem = (TableViewerInputObject)obj;
+
+ threadNames.add(checkedItem.getName());
+ threadColors.add(checkedItem.getColor());
+ }
+ }
+
+ //Graph class will be informed about the selected event and selected threads.
+ ThreadsGraph thGraph = new ThreadsGraph();
+ GenericGraph.EventTypes eventType = GraphsUtils.getMappedEvent(selectedEvent);
+ thGraph.setEvent(eventType);
+ thGraph.setUserSelectedItems(threadNames);
+ thGraph.setCyclesData(parsedData);
+ thGraph.setColors(threadColors);
+
+ graph.redraw(thGraph);
+ }
+
+ /* (non-Javadoc)
+ * @see com.nokia.s60tools.swmtanalyser.ui.graphs.IGraphTypeSelectionListener#notifyChunksSelection()
+ */
+ public void notifyChunksSelection()
+ {
+ Object [] checkedElements = this.chunksViewer.getCheckedElements();
+
+ ArrayList<String> chunkNames = new ArrayList<String>();
+ ArrayList<Color> chunkColors = new ArrayList<Color>();
+
+ for(Object obj: checkedElements)
+ {
+ if(obj instanceof TableViewerInputObject)
+ {
+ TableViewerInputObject checkedItem = (TableViewerInputObject)obj;
+
+ chunkNames.add(checkedItem.getName());
+ chunkColors.add(checkedItem.getColor());
+ }
+ }
+
+ //Graph class will be informed about the selected event and selected chunks.
+ ChunksGraph chnkGraph = new ChunksGraph();
+ GenericGraph.EventTypes eventType = GraphsUtils.getMappedEvent(selectedEvent);
+ chnkGraph.setEvent(eventType);
+ chnkGraph.setUserSelectedItems(chunkNames);
+ chnkGraph.setCyclesData(parsedData);
+ chnkGraph.setColors(chunkColors);
+
+ graph.redraw(chnkGraph);
+ }
+
+ /* (non-Javadoc)
+ * @see com.nokia.s60tools.swmtanalyser.ui.graphs.IGraphTypeSelectionListener#notifyDisksSelection()
+ */
+ public void notifyDisksSelection()
+ {
+ Object [] checkedElements = this.disksViewer.getCheckedElements();
+
+ ArrayList<String> diskNames = new ArrayList<String>();
+ ArrayList<Color> diskColors = new ArrayList<Color>();
+
+ for(Object obj: checkedElements)
+ {
+ if(obj instanceof TableViewerInputObject)
+ {
+ TableViewerInputObject checkedItem = (TableViewerInputObject)obj;
+
+ diskNames.add(checkedItem.getName());
+ diskColors.add(checkedItem.getColor());
+ }
+ }
+ //Graph class will be informed about the selected event and selected disks.
+ DisksGraph diskGraph = new DisksGraph();
+ GenericGraph.EventTypes eventType = GraphsUtils.getMappedEvent(selectedEvent);
+ diskGraph.setEvent(eventType);
+ diskGraph.setUserSelectedItems(diskNames);
+ diskGraph.setCyclesData(parsedData);
+ diskGraph.setColors(diskColors);
+
+ this.setGraphTitle(selectedEvent);
+ graph.redraw(diskGraph);
+ }
+
+ /* (non-Javadoc)
+ * @see com.nokia.s60tools.swmtanalyser.ui.graphs.IGraphTypeSelectionListener#notifySysElementsSelection()
+ */
+ public void notifySysElementsSelection()
+ {
+ Object [] checkedElements = this.sysElemsViewer.getCheckedElements();
+
+ ArrayList<String> sysElemNames = new ArrayList<String>();
+ ArrayList<Color> sysElemColors = new ArrayList<Color>();
+
+ for(Object obj: checkedElements)
+ {
+ if(obj instanceof TableViewerInputObject)
+ {
+ TableViewerInputObject checkedItem = (TableViewerInputObject)obj;
+
+ sysElemNames.add(checkedItem.getName());
+ sysElemColors.add(checkedItem.getColor());
+ }
+ }
+
+ //Graph class will be informed about the selected event and selected system elements.
+ SystemDataGraph sysDataGraph = new SystemDataGraph();
+ GenericGraph.EventTypes eventType = GraphsUtils.getMappedEvent(selectedEvent);
+ sysDataGraph.setEvent(eventType);
+ sysDataGraph.setUserSelectedItems(sysElemNames);
+ sysDataGraph.setCyclesData(parsedData);
+ sysDataGraph.setColors(sysElemColors);
+
+ graph.redraw(sysDataGraph);
+ }
+
+ /**
+ * Changes the graph title with the given name
+ * @param name graph name to be set
+ */
+ private void setGraphTitle(String name)
+ {
+ if(this.title != null)
+ title.setText(name);
+ }
+
+ /**
+ * WHen Graphed items tab is selected, the items selected in the events tab will be moved
+ * to Graphed items tab.
+ * @param event
+ */
+ public void updateGraphedItemsList(String event)
+ {
+ if(threadTble.getEnabled())
+ {
+ Iterator<Entry<String, Color>> itr = threadTble.checked.entrySet().iterator();
+ while(itr.hasNext())
+ {
+ Entry<String, Color> entry = itr.next();
+ GraphedItemsInput item = new GraphedItemsInput();
+ graph.storeClearedEventValues(entry.getKey(), allEventsGraph);
+
+ item.setName(entry.getKey());
+ item.setEvent(event);
+ item.setColor(entry.getValue());
+ item.setType("Thread");
+ if(!checkItemInTheList(item,graphed))
+ graphed.add(item);
+ }
+ }
+ else if(chunkTble.getEnabled())
+ {
+ Iterator<Entry<String, Color>> itr = chunkTble.checked.entrySet().iterator();
+ while(itr.hasNext())
+ {
+ Entry<String, Color> entry = itr.next();
+ GraphedItemsInput item = new GraphedItemsInput();
+ graph.storeClearedEventValues(entry.getKey(), allEventsGraph);
+
+ item.setName(entry.getKey());
+ item.setColor(entry.getValue());
+ item.setEvent(event);
+ item.setType("Chunk");
+ if(!checkItemInTheList(item,graphed))
+ graphed.add(item);
+ }
+ }
+ else if(diskTble.getEnabled())
+ {
+ Iterator<Entry<String, Color>> itr = diskTble.checked.entrySet().iterator();
+ while(itr.hasNext())
+ {
+ Entry<String, Color> entry = itr.next();
+ GraphedItemsInput item = new GraphedItemsInput();
+ graph.storeClearedEventValues(entry.getKey(), allEventsGraph);
+
+ item.setName(entry.getKey());
+ item.setColor(entry.getValue());
+ item.setEvent(event);
+ item.setType("Disk");
+ if(!checkItemInTheList(item,graphed))
+ graphed.add(item);
+ }
+ }
+ else if(sysinfoTble.getEnabled())
+ {
+ Iterator<Entry<String, Color>> itr = sysinfoTble.checked.entrySet().iterator();
+ while(itr.hasNext())
+ {
+ Entry<String, Color> entry = itr.next();
+ GraphedItemsInput item = new GraphedItemsInput();
+ graph.storeClearedEventValues(entry.getKey(), allEventsGraph);
+
+ item.setName(entry.getKey());
+ item.setColor(entry.getValue());
+ item.setEvent(event);
+ item.setType("System Data");
+ if(!checkItemInTheList(item,graphed))
+ graphed.add(item);
+ }
+ }
+ else if(Arrays.asList(RAM_GRP).contains(event))
+ {
+ GraphedItemsInput item = new GraphedItemsInput();
+ graph.storeClearedEventValues(event, allEventsGraph);
+
+ item.setName(event);
+ item.setEvent(event);
+ item.setType("Memory");
+ if(!checkItemInTheList(item,graphed))
+ graphed.add(item);
+ }
+
+ if(graphed.size()>0)
+ {
+ graphedItemsViewer.setInput(graphed);
+ graphedItemsViewer.setAllChecked(true);
+ for(Object obj : graphedItemsViewer.getCheckedElements())
+ {
+ GraphedItemsInput item = (GraphedItemsInput)obj;
+ if(item.getColor() == null)
+ item.setColor(getRandomColor());
+ graphedItemsViewer.update(item, null);
+ }
+ }
+ }
+
+ /**
+ * The given item from the given list is checked.
+ * @param item
+ * @param list
+ * @return
+ */
+ public boolean checkItemInTheList(GraphedItemsInput item, ArrayList<GraphedItemsInput> list)
+ {
+ for(GraphedItemsInput obj: list)
+ {
+ if(item.getEvent().equals(obj.getEvent()) && item.getName().equals(obj.getName()) && item.getType().equals(obj.getType()))
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Generates random color.
+ * @return a random color
+ */
+ public Color getRandomColor()
+ {
+ Random rand = new Random();
+ int r = rand.nextInt(255);
+ int g = rand.nextInt(255);
+ int b = rand.nextInt(255);
+ return new Color(Display.getCurrent(), r, g,b);
+ }
+
+
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/editors/SWMTEditorInput.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,143 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+package com.nokia.s60tools.swmtanalyser.editors;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IPersistableElement;
+
+import com.nokia.s60tools.swmtanalyser.data.CycleData;
+import com.nokia.s60tools.swmtanalyser.data.OverviewData;
+import com.nokia.s60tools.swmtanalyser.data.ParsedData;
+
+/**
+ * SWMT Analyser specific input to the SWMT Editor.
+ *
+ */
+public class SWMTEditorInput implements IEditorInput {
+
+ private ParsedData parsedData = new ParsedData();
+ private OverviewData overview = new OverviewData();
+
+ /**
+ * Get parsed data
+ * @return parsed data
+ */
+ public ParsedData getParsedData() {
+ return parsedData;
+ }
+ /**
+ * Set parsed data
+ * @param parsedData
+ */
+ public void setParsedData(ParsedData parsedData) {
+ this.parsedData = parsedData;
+ }
+ /**
+ * Get overview
+ * @return overview
+ */
+ public OverviewData getOverview() {
+ return overview;
+ }
+ /**
+ * Set overview
+ * @param overview
+ */
+ public void setOverview(OverviewData overview) {
+ this.overview = overview;
+ }
+ /**
+ * Constructor
+ * @param parsedData
+ * @param ov
+ */
+ public SWMTEditorInput(ParsedData parsedData, OverviewData ov) {
+ this.parsedData = parsedData;
+ this.overview = ov;
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.IEditorInput#exists()
+ */
+ public boolean exists() {
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.IEditorInput#getImageDescriptor()
+ */
+ public ImageDescriptor getImageDescriptor() {
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.IEditorInput#getName()
+ */
+ public String getName() {
+ return "Result of " + parsedData.getNumberOfCycles() + " SWMT logs";
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.IEditorInput#getPersistable()
+ */
+ public IPersistableElement getPersistable() {
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.IEditorInput#getToolTipText()
+ */
+ public String getToolTipText() {
+ return "Result of " + parsedData.getNumberOfCycles()+" SWMT Log files";
+ }
+
+
+ /* (non-Javadoc)
+ * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class)
+ */
+ @SuppressWarnings("unchecked")
+ public Object getAdapter(Class adapter) {
+ return null;
+ }
+
+ /*
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ public boolean equals(Object o) {
+ if(!(o instanceof SWMTEditorInput))
+ return false;
+
+ SWMTEditorInput input = (SWMTEditorInput)o;
+
+ CycleData[] currentLogData = this.parsedData.getLogData();
+ CycleData[] givenLogData = input.parsedData.getLogData();
+
+ if (this.parsedData.getNumberOfCycles() != input.parsedData.getNumberOfCycles())
+ return false;
+ else if(currentLogData == null || givenLogData== null)
+ return false;
+ else
+ {
+ for (int i=0; i<currentLogData.length; i++) {
+ if(!currentLogData[i].getFileName().equals(givenLogData[i].getFileName()))
+ return false;
+ }
+ }
+ return true;
+
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/editors/TableLabelColorProvider.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,128 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+package com.nokia.s60tools.swmtanalyser.editors;
+
+import org.eclipse.jface.viewers.ILabelProviderListener;
+import org.eclipse.jface.viewers.ITableColorProvider;
+import org.eclipse.jface.viewers.ITableLabelProvider;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Image;
+
+/**
+ * Label provider for chunks/threads/disks/sys ebent tables
+ *
+ */
+public class TableLabelColorProvider implements ITableColorProvider, ITableLabelProvider {
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.ITableColorProvider#getBackground(java.lang.Object, int)
+ */
+ public Color getBackground(Object arg0, int columnIndex) {
+
+ if(arg0 instanceof TableViewerInputObject)
+ {
+ if(columnIndex == 0)
+ {
+ TableViewerInputObject obj =((TableViewerInputObject)arg0);
+ return obj.getColor();
+ }
+ }
+ else if(arg0 instanceof GraphedItemsInput)
+ {
+ GraphedItemsInput item = (GraphedItemsInput)arg0;
+ Color color = item.getColor();
+ if(columnIndex == 0)
+ return color;
+ }
+
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.ITableColorProvider#getForeground(java.lang.Object, int)
+ */
+ public Color getForeground(Object arg0, int arg1) {
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.ITableLabelProvider#getColumnImage(java.lang.Object, int)
+ */
+ public Image getColumnImage(Object arg0, int arg1) {
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.ITableLabelProvider#getColumnText(java.lang.Object, int)
+ */
+ public String getColumnText(Object arg0, int columnIndex) {
+ if(arg0 instanceof TableViewerInputObject)
+ {
+ if(columnIndex == 1)
+ return ((TableViewerInputObject)arg0).getName();
+ }
+ else if(arg0 instanceof GraphedItemsInput)
+ {
+ GraphedItemsInput item = (GraphedItemsInput)arg0;
+ String value=null;
+ switch(columnIndex)
+ {
+ case 0:
+ value = null;
+ break;
+ case 1:
+ value = item.getName();
+ break;
+ case 2:
+ value = item.getEvent();
+ break;
+ case 3:
+ value = item.getType();
+ break;
+ }
+ return value;
+ }
+
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.IBaseLabelProvider#addListener(org.eclipse.jface.viewers.ILabelProviderListener)
+ */
+ public void addListener(ILabelProviderListener arg0) {
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.IBaseLabelProvider#dispose()
+ */
+ public void dispose() {
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.IBaseLabelProvider#isLabelProperty(java.lang.Object, java.lang.String)
+ */
+ public boolean isLabelProperty(Object arg0, String arg1) {
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.IBaseLabelProvider#removeListener(org.eclipse.jface.viewers.ILabelProviderListener)
+ */
+ public void removeListener(ILabelProviderListener arg0) {
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/editors/TableStructuredContentProvider.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,64 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+package com.nokia.s60tools.swmtanalyser.editors;
+
+import java.util.ArrayList;
+
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.Viewer;
+
+/**
+ * Content provider for chunk/thread/disk etc.. tables
+ *
+ */
+public class TableStructuredContentProvider implements IStructuredContentProvider {
+
+ FilterTextTable table;
+ /**
+ * Constructor
+ * @param table
+ */
+ public TableStructuredContentProvider(FilterTextTable table) {
+ this.table = table;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object)
+ */
+ public Object[] getElements(Object arg0) {
+ ArrayList<TableViewerInputObject> items = new ArrayList<TableViewerInputObject>();
+ for(String name: table.input)
+ {
+ TableViewerInputObject obj = new TableViewerInputObject(name, null);
+ items.add(obj);
+ }
+ return items.toArray();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.IContentProvider#dispose()
+ */
+ public void dispose() {
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object)
+ */
+ public void inputChanged(Viewer arg0, Object arg1, Object arg2) {
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/editors/TableTextFilter.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,100 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+package com.nokia.s60tools.swmtanalyser.editors;
+
+import org.eclipse.jface.viewers.ITableLabelProvider;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerFilter;
+
+/**
+ * Filter class for the all tables
+ *
+ */
+public class TableTextFilter extends ViewerFilter {
+
+ private String filterText = "";
+ private int columnIndex = 0;
+ private int filterTypeIndex = 0;
+
+ /**
+ * Constructor
+ * @param columnIndex
+ */
+ public TableTextFilter(int columnIndex) {
+ super();
+ this.columnIndex = columnIndex;
+ }
+
+ /**
+ * Get filter text
+ * @return filter text
+ */
+ public String getFilterText() {
+ return filterText;
+ }
+
+ /**
+ * Get column index
+ * @return column index
+ */
+ public int getColumnIndex() {
+ return columnIndex;
+ }
+
+ /**
+ * Set column index
+ * @param columnIndex
+ */
+ public void setColumnIndex(int columnIndex) {
+ this.columnIndex = columnIndex;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.ViewerFilter#select(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object)
+ */
+ @Override
+ public boolean select(Viewer viewer, Object parentElement, Object element) {
+ if (filterText.length() > 0) {
+ String name = ((ITableLabelProvider)((TableViewer) viewer).getLabelProvider()).getColumnText(element, columnIndex);
+ if(filterTypeIndex == 0){
+ return (name.toLowerCase().startsWith(this.filterText.toLowerCase()));
+ }
+ else{
+ return (name.toLowerCase().indexOf(this.filterText.toLowerCase()) > -1);
+ }
+ } else
+ return true;
+ }
+
+ /**
+ * Set filter text
+ * @param filterText
+ */
+ public void setFilterText(String filterText) {
+ this.filterText = filterText;
+ }
+
+ /**
+ * Set filter type index
+ * @param index
+ */
+ public void setFilterTypeIndex(int index) {
+ this.filterTypeIndex = index;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/editors/TableViewerInputObject.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,66 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+package com.nokia.s60tools.swmtanalyser.editors;
+
+import org.eclipse.swt.graphics.Color;
+
+/**
+ * Input object for 4 tables in events tab
+ *
+ */
+public class TableViewerInputObject {
+ private Color color;
+ private String name;
+
+ /**
+ * Constructor
+ * @param name
+ * @param color
+ */
+ public TableViewerInputObject(String name, Color color) {
+ this.color = color;
+ this.name = name;
+ }
+ /**
+ * Get color
+ * @return color
+ */
+ public Color getColor() {
+ return color;
+ }
+ /**
+ * Set color
+ * @param color
+ */
+ public void setColor(Color color) {
+ this.color = color;
+ }
+ /**
+ * Get name
+ * @return name
+ */
+ public String getName() {
+ return name;
+ }
+ /**
+ * Set name
+ * @param name
+ */
+ public void setName(String name) {
+ this.name = name;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/exception/SwmtFormatException.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,37 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+package com.nokia.s60tools.swmtanalyser.exception;
+
+/**
+ * SWMT Analyser specific exception.
+ */
+public class SwmtFormatException extends Exception {
+
+ /**
+ * Default serial ID
+ */
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * Constructor
+ * @param msg
+ */
+ public SwmtFormatException(String msg)
+ {
+ super(msg);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/model/ExcelCreator.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,2148 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+package com.nokia.s60tools.swmtanalyser.model;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.poi.hssf.usermodel.HSSFCell;
+import org.apache.poi.hssf.usermodel.HSSFCellStyle;
+import org.apache.poi.hssf.usermodel.HSSFFont;
+import org.apache.poi.hssf.usermodel.HSSFRichTextString;
+import org.apache.poi.hssf.usermodel.HSSFRow;
+import org.apache.poi.hssf.usermodel.HSSFSheet;
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
+import org.apache.poi.hssf.util.HSSFColor;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.swt.widgets.Display;
+
+import com.nokia.s60tools.swmtanalyser.data.ChunksData;
+import com.nokia.s60tools.swmtanalyser.data.CycleData;
+import com.nokia.s60tools.swmtanalyser.data.DiskOverview;
+import com.nokia.s60tools.swmtanalyser.data.GlobalDataChunks;
+import com.nokia.s60tools.swmtanalyser.data.OverviewData;
+import com.nokia.s60tools.swmtanalyser.data.ParsedData;
+import com.nokia.s60tools.swmtanalyser.data.SystemData;
+import com.nokia.s60tools.swmtanalyser.data.ThreadData;
+import com.nokia.s60tools.swmtanalyser.data.WindowGroupEventData;
+import com.nokia.s60tools.util.debug.DbgUtility;
+
+/**
+ * Creates Excel when log files exported.
+ *
+ */
+public class ExcelCreator {
+
+ private String fileName;
+ private FileOutputStream out;
+
+ private HSSFWorkbook wb;
+ private OverviewData ovData;
+ private ArrayList<Integer> constants = new ArrayList<Integer>();
+
+ private Map<String, HSSFCellStyle> styles;
+ private ParsedData logData;
+ private Map<String, ArrayList<ThreadData>> heapData = new HashMap<String, ArrayList<ThreadData>> ();
+ private Map<String, ArrayList<GlobalDataChunks>> glodData = new HashMap<String, ArrayList<GlobalDataChunks>> ();
+ private Map<String, ArrayList<ChunksData>> chunkData = new HashMap<String, ArrayList<ChunksData>> ();
+ private Map<String, ThreadData> deltaData = new HashMap<String, ThreadData> ();
+ private Map<String, String> glodDeltaData = new HashMap<String, String> ();
+ private Map<String, String> chunkDeltaData = new HashMap<String, String> ();
+ private ArrayList<String> heapThreads;
+ private ArrayList<String> glodChunks;
+ private ArrayList<String> nonHeapChunks;
+
+ private long totalHeapSizeChange =0;
+ private long totalFreeCellChange =0;
+ private long totalAllocCellChange =0;
+ private long totalFreeSpaceChange =0;
+ private long totalAllocSpaceChange =0;
+ private long totalSlackSpaceChange =0;
+ private long totalFilesChange =0;
+ private long totalHandlesChange =0;
+ private int j = 0;
+
+ private static final String NOT_AVAILABLE = "N/A";
+
+ /**
+ * Construction
+ * @param fileName
+ */
+ public ExcelCreator(String fileName) {
+ //create a new workbook
+ wb = new HSSFWorkbook();
+ this.fileName = fileName;
+ }
+
+ /**
+ * Set overview data
+ * @param ovdata
+ */
+ public void setOverviewPageInput(OverviewData ovdata)
+ {
+ this.ovData = ovdata;
+ }
+
+ /**
+ * Set all the parsed data of log files.
+ * @param cyclesData
+ */
+ public void setInputCyclesData(ParsedData cyclesData)
+ {
+ this.logData = cyclesData;
+ }
+
+ /**
+ * The cycle numbers to be skipped when there are more than 254 cycles.
+ * @param constants
+ */
+ public void setSkipFileConstant(ArrayList<Integer> constants)
+ {
+ this.constants = constants;
+ }
+
+ private boolean updateMonitor(IProgressMonitor monitor, String message)
+ {
+ if(monitor!=null)
+ monitor.subTask(message);
+ if(monitor.isCanceled())
+ {
+ monitor.done();
+ try {
+ out.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Create a excel document
+ * @param monitor
+ * @return <code>true</code> if document was created successfully <code>false</code> otherwise.
+ */
+ public boolean createExcel(IProgressMonitor monitor)
+ {
+
+ File file = new File(fileName);
+
+ if(file.exists() && !file.delete()){
+ Runnable p = new Runnable(){
+ public void run() {
+ MessageDialog.openError(Display.getCurrent().getActiveShell(), "SWMT Analyser", fileName + "file already exists and could not be deleted.\nPlease close it if open and try again.");
+ }
+ };
+ Display.getDefault().asyncExec(p);
+ return false;
+ }
+
+ try {
+ out = new FileOutputStream(fileName);
+ } catch (FileNotFoundException e) {
+ Runnable p = new Runnable(){
+ public void run() {
+ MessageDialog.openError(Display.getCurrent().getActiveShell(), "SWMT Analyser", "Error in creating file " + fileName);
+ }
+ };
+ Display.getDefault().asyncExec(p);
+ return false;
+
+ }
+
+ styles = createStyles(wb);
+
+ SWMTLogReaderUtils utilsObj = new SWMTLogReaderUtils();
+
+ readGlobalDataFromAllCycles(glodData, logData);
+ getFieldDifferencesForAllGlodChunks(glodDeltaData, logData);
+
+ readChunkDataFromAllCycles(chunkData, logData);
+ getFieldDifferencesForAllChunks(chunkDeltaData, logData);
+
+ readHeapDataFromAllCycles(heapData, logData);
+ getFieldDifferencesForAllThreads(deltaData, logData);
+
+ heapThreads = utilsObj.getAllHeapThreads(logData);
+ Collections.sort(heapThreads);
+
+ if(!updateMonitor(monitor, "Creating overview sheet..."))
+ return false;
+ createOverViewTab();
+
+ if(!updateMonitor(monitor, "Creating disk memory sheet..."))
+ return false;
+ createDiskVariationSheet();
+
+ if(!updateMonitor(monitor, "Creating global chunks sheet..."))
+ return false;
+ createGlobalChunksSheet();
+
+ if(!updateMonitor(monitor, "Creating non heap chunks sheet..."))
+ return false;
+ createNonHeapChunkSheet();
+
+ if(!updateMonitor(monitor, "Creating heap size sheet..."))
+ return false;
+ createHeapSizeTab();
+
+ if(!updateMonitor(monitor, "Creating heap allocated space sheet..."))
+ return false;
+ createHeapAllocSpaceTab();
+
+ if(!updateMonitor(monitor, "Creating heap free space sheet..."))
+ return false;
+ createHeapFreeSpaceTab();
+
+ if(!updateMonitor(monitor, "Creating allocated cells sheet..."))
+ return false;
+ createAllocatedCellsTab();
+
+ if(!updateMonitor(monitor, "Creating free cells sheet..."))
+ return false;
+ createFreeCellsTab();
+
+ if(!updateMonitor(monitor, "Creating free slack sheet..."))
+ return false;
+ createFreeSlackTab();
+
+ if(!updateMonitor(monitor, "Creating largest allocated cells sheet..."))
+ return false;
+ createLargestAllocSizeTab();
+
+ if(!updateMonitor(monitor, "Creating largest free size sheet..."))
+ return false;
+ createLargestFreeSizeTab();
+
+ if(!updateMonitor(monitor, "Creating window groups sheet..."))
+ return false;
+ createWindowGroupSheet();
+
+ // write the workbook to the output stream
+ // close our file (don't blow out our file handles
+ try {
+ wb.write(out);
+ out.close();
+ } catch (IOException err) {
+ err.printStackTrace();
+ try {
+ out.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return false;
+ }
+
+ return true;
+ }
+
+ private boolean createOverViewTab()
+ {
+ //create a new sheet
+ HSSFSheet sheet = wb.createSheet();
+ // declare a row object reference
+ HSSFRow row = null;
+ // declare a cell object reference
+ HSSFCell cell = null;
+
+ //set the sheet name in Unicode
+ wb.setSheetName(0, "Overview");
+
+ row=sheet.createRow(0);
+ //r.setHeight((short)500);
+
+ cell= row.createCell(0);
+ cell.setCellStyle(styles.get("header"));
+ cell.setCellValue(new HSSFRichTextString("Overview"));
+
+ row=sheet.createRow(1);
+ cell=row.createCell(0);
+ cell.setCellValue(new HSSFRichTextString("Number of Cycles"));
+ cell=row.createCell(1);
+ cell.setCellStyle(styles.get("cell_number"));
+
+ CycleData firstCycle = logData.getLogData()[0];
+
+ if(ovData.noOfcycles == 1)
+ cell.setCellValue(new HSSFRichTextString(ovData.noOfcycles + " (" + firstCycle.getCycleNumber() + ")"));
+ else
+ cell.setCellValue(ovData.noOfcycles);
+
+ row=sheet.createRow(2);
+ cell=row.createCell(0);
+ cell.setCellValue(new HSSFRichTextString("Number of Cycles Truncated"));
+ cell=row.createCell(1);
+ cell.setCellValue(constants.size());
+
+ row=sheet.createRow(3);
+ cell = row.createCell(0);
+ cell.setCellValue(new HSSFRichTextString("Time Period"));
+ HSSFCell timePeriod = row.createCell(1);
+
+ row=sheet.createRow(4);
+ cell=row.createCell(0);
+ cell.setCellValue(new HSSFRichTextString("Time Duration"));
+ cell=row.createCell(1);
+ cell.setCellValue(new HSSFRichTextString(ovData.duration + " sec(" + ovData.durationString + ")"));
+
+ row=sheet.createRow(5);
+ cell=row.createCell(0);
+ cell.setCellValue(new HSSFRichTextString("ROM Checksum"));
+ cell=row.createCell(1);
+ cell.setCellValue(new HSSFRichTextString(firstCycle.getRomCheckSum()));
+
+ row=sheet.createRow(6);
+ cell=row.createCell(0);
+ cell.setCellValue(new HSSFRichTextString("ROM Version"));
+ cell=row.createCell(1);
+ cell.setCellValue(new HSSFRichTextString(firstCycle.getRomVersion()));
+
+ sheet.createRow(7);
+ sheet.createRow(8);
+ sheet.createRow(9);
+
+ row = sheet.createRow(10);
+ cell = row.createCell(0);
+ cell.setCellStyle(styles.get("header2"));
+ cell.setCellValue(new HSSFRichTextString(""));
+
+ cell = row.createCell(1);
+ cell.setCellStyle(styles.get("header2"));
+ cell.setCellValue(new HSSFRichTextString("Delta"));
+
+ HSSFRow totalHeapSizeRow = sheet.createRow(11);
+ cell = totalHeapSizeRow.createCell(0);
+ cell.setCellStyle(styles.get("cell_bold"));
+ cell.setCellValue(new HSSFRichTextString("Heap Size"));
+
+ HSSFRow freeCellRow = sheet.createRow(12);
+ cell = freeCellRow.createCell(0);
+ cell.setCellStyle(styles.get("cell_bold"));
+ cell.setCellValue(new HSSFRichTextString("Free Cell count"));
+
+ HSSFRow alloCellRow = sheet.createRow(13);
+ cell = alloCellRow.createCell(0);
+ cell.setCellStyle(styles.get("cell_bold"));
+ cell.setCellValue(new HSSFRichTextString("Allocated Cell count"));
+
+ HSSFRow freeSpaceRow = sheet.createRow(14);
+ cell = freeSpaceRow.createCell(0);
+ cell.setCellStyle(styles.get("cell_bold"));
+ cell.setCellValue(new HSSFRichTextString("Free space"));
+
+ HSSFRow allocSpaceRow = sheet.createRow(15);
+ cell = allocSpaceRow.createCell(0);
+ cell.setCellStyle(styles.get("cell_bold"));
+ cell.setCellValue(new HSSFRichTextString("Allocated space"));
+
+ HSSFRow slackSpaceRow = sheet.createRow(16);
+ cell = slackSpaceRow.createCell(0);
+ cell.setCellStyle(styles.get("cell_bold"));
+ cell.setCellValue(new HSSFRichTextString("Slack space"));
+
+ HSSFRow filesRow = sheet.createRow(17);
+ cell = filesRow.createCell(0);
+ cell.setCellStyle(styles.get("cell_bold"));
+ cell.setCellValue(new HSSFRichTextString("Total files"));
+
+ HSSFRow psHandlesRow = sheet.createRow(18);
+ cell = psHandlesRow.createCell(0);
+ cell.setCellStyle(styles.get("cell_bold"));
+ cell.setCellValue(new HSSFRichTextString("Total P&S Handles"));
+
+ sheet.createRow(19);
+ sheet.createRow(20);
+ sheet.createRow(21);
+ sheet.createRow(22);
+
+ row = sheet.createRow(23);
+ createOverviewFields(row);
+
+ createDataInOverView(sheet, 24);
+
+ cell = totalHeapSizeRow.createCell(1);
+ cell.setCellStyle(styles.get("blue_font"));
+ cell.setCellValue(totalHeapSizeChange);
+
+ cell = freeCellRow.createCell(1);
+ cell.setCellStyle(styles.get("blue_font"));
+ cell.setCellValue(totalFreeCellChange);
+
+ cell = alloCellRow.createCell(1);
+ cell.setCellStyle(styles.get("blue_font"));
+ cell.setCellValue(totalAllocCellChange);
+
+ cell = freeSpaceRow.createCell(1);
+ cell.setCellStyle(styles.get("blue_font"));
+ cell.setCellValue(totalFreeSpaceChange);
+
+ cell = allocSpaceRow.createCell(1);
+ cell.setCellStyle(styles.get("blue_font"));
+ cell.setCellValue(totalAllocSpaceChange);
+
+ cell = slackSpaceRow.createCell(1);
+ cell.setCellStyle(styles.get("blue_font"));
+ cell.setCellValue(totalSlackSpaceChange);
+
+ cell = filesRow.createCell(1);
+ cell.setCellStyle(styles.get("blue_font"));
+ cell.setCellValue(totalFilesChange);
+
+ cell = psHandlesRow.createCell(1);
+ cell.setCellStyle(styles.get("blue_font"));
+ cell.setCellValue(totalHandlesChange);
+
+ sheet.autoSizeColumn((short)0);
+ sheet.autoSizeColumn((short)1);
+ sheet.autoSizeColumn((short)2);
+ sheet.autoSizeColumn((short)3);
+ sheet.autoSizeColumn((short)4);
+ sheet.autoSizeColumn((short)5);
+ sheet.autoSizeColumn((short)6);
+ sheet.autoSizeColumn((short)7);
+ sheet.autoSizeColumn((short)8);
+ sheet.autoSizeColumn((short)9);
+ sheet.autoSizeColumn((short)10);
+ sheet.autoSizeColumn((short)11);
+
+
+ if(ovData.noOfcycles > 1)
+ timePeriod.setCellValue(new HSSFRichTextString(ovData.fromTime + " to " + ovData.toTime));
+ else
+ timePeriod.setCellValue(new HSSFRichTextString(ovData.fromTime));
+
+ return true;
+ }
+
+ /**
+ * This method creates the sheet for RAM and DISK Memory data.
+ * It shows the variation of RAM and Disk Memory in each cycle.
+ *
+ */
+ private void createDiskVariationSheet() {
+ //create a new sheet
+ HSSFSheet sheet = wb.createSheet();
+ // declare a row object reference
+ HSSFRow row = null;
+ HSSFRow description = null;
+ // declare a cell object reference
+ HSSFCell cell = null;
+
+ //set the sheet name in Unicode
+ wb.setSheetName(1, "RAM and Disk Memory");
+
+ row = sheet.createRow(0);
+ //r.setHeight((short)500);
+
+ cell = row.createCell(0);
+ cell.setCellStyle(styles.get("header"));
+ cell.setCellValue(new HSSFRichTextString("RAM and Disk Memory"));
+
+ description = sheet.createRow(1);
+
+ //creates an empty row
+ row = sheet.createRow(2);
+
+ row = sheet.createRow(3);
+
+ cell = row.createCell(0);
+ cell.setCellStyle(styles.get("header2"));
+ cell.setCellValue(new HSSFRichTextString(""));
+
+ addCycleIntervals(row);
+
+ cell = row.createCell((int)(row.getLastCellNum()));
+ cell.setCellStyle(styles.get("header2"));
+ cell.setCellValue(new HSSFRichTextString("Delta"));
+
+ SWMTLogReaderUtils utils = new SWMTLogReaderUtils();
+ ArrayList<String> diskNames = utils.getAllDiskNames(logData);
+
+ int rowNo = 4;
+
+ row = sheet.createRow(rowNo);
+ cell = row.createCell(0);
+ cell.setCellStyle(styles.get("cell_normal"));
+ cell.setCellValue(new HSSFRichTextString("RAM (Used)"));
+
+ ArrayList<SystemData> systemData = utils.getSystemDataFromAllCycles(logData);
+
+ long [] usedMemValues = new long[logData.getNumberOfCycles()];
+
+ j=1;
+ for(int i=0; i<logData.getNumberOfCycles(); i++)
+ {
+ long totalMem = systemData.get(i).getTotalMemory();
+ long freeMem = systemData.get(i).getFreeMemory();
+
+ if(totalMem == -1 || freeMem == -1){
+ //cell.getCellStyle().setAlignment(HSSFCellStyle.ALIGN_CENTER);
+ usedMemValues[i] = -1;
+ }
+ else{
+ long usedMemory = totalMem - freeMem;
+ usedMemValues[i] = usedMemory;
+ }
+
+ if(constants.contains(i+1))
+ continue;
+
+ cell = row.createCell(j++);
+ cell.setCellStyle(styles.get("cell_number"));
+ cell.setCellType(HSSFCell.CELL_TYPE_NUMERIC);
+
+ if(usedMemValues[i] == -1)
+ cell.setCellValue(new HSSFRichTextString(NOT_AVAILABLE));
+ else
+ cell.setCellValue(usedMemValues[i]);
+
+ //cell.setCellValue(logData.get(i).getFreeMemory());
+ }
+
+ cell = row.createCell(logData.getNumberOfCycles()+1-constants.size());
+ cell.setCellStyle(styles.get("cell_number"));
+ long usedMemChange = utils.calculateDeltaForGivenSet(usedMemValues);
+
+ cell.setCellValue(usedMemChange);
+
+ /*cell = row.createCell(logData.size()+1);
+ cell.setCellStyle(styles.get("cell_number"));
+
+ long firstCycleValue = logData.get(0).getFreeMemory();
+ long lastCycleValue = logData.get(logData.size()-1).getFreeMemory();
+
+ if(firstCycleValue!= -1 && lastCycleValue!= -1)
+ cell.setCellValue(lastCycleValue - firstCycleValue);
+ else{
+ //cell.getCellStyle().setAlignment(HSSFCellStyle.ALIGN_CENTER);
+ cell.setCellValue(new HSSFRichTextString(NOT_AVAILABLE));
+ }*/
+
+ rowNo++;
+
+ row = sheet.createRow(rowNo);
+ cell = row.createCell(0);
+ cell.setCellStyle(styles.get("cell_normal"));
+ cell.setCellValue(new HSSFRichTextString("RAM (Size)"));
+
+ long [] totalMemValues = new long[logData.getNumberOfCycles()];
+
+ j=1;
+ for(int i=0; i<logData.getNumberOfCycles(); i++)
+ {
+ long totalMem = systemData.get(i).getTotalMemory();
+
+ if(totalMem == -1){
+ totalMemValues[i] = -1;
+ }
+ else{
+ totalMemValues[i] = totalMem;
+ }
+ //cell.setCellValue(logData.get(i).getFreeMemory());
+
+ if(constants.contains(i+1))
+ continue;
+
+ cell = row.createCell(j++);
+ cell.setCellStyle(styles.get("cell_number"));
+ cell.setCellType(HSSFCell.CELL_TYPE_NUMERIC);
+
+ if(totalMemValues[i] == -1)
+ cell.setCellValue(new HSSFRichTextString(NOT_AVAILABLE));
+ else
+ cell.setCellValue(totalMemValues[i]);
+ }
+
+ cell = row.createCell(logData.getNumberOfCycles() + 1 -constants.size());
+ cell.setCellStyle(styles.get("cell_number"));
+ long totalMemChange = utils.calculateDeltaForGivenSet(totalMemValues);
+
+ cell.setCellValue(totalMemChange);
+
+ Collections.sort(diskNames);
+
+ for(String name:diskNames)
+ {
+ rowNo++;
+
+ row = sheet.createRow(rowNo);
+ cell = row.createCell(0);
+ cell.setCellStyle(styles.get("cell_normal"));
+ cell.setCellValue(new HSSFRichTextString(name + " (Used)"));
+
+ ArrayList<DiskOverview> values = utils.getUsedMemoryAndSizesForDisk(name, logData);
+ long [] usedSizes = new long[values.size()];
+
+ j=1;
+ for(int i=0; i<values.size(); i++)
+ {
+ if(constants.contains(i+1))
+ continue;
+
+ cell = row.createCell(j++);
+ cell.setCellStyle(styles.get("cell_number"));
+ cell.setCellType(HSSFCell.CELL_TYPE_NUMERIC);
+
+ long usedSize = values.get(i).getUsedSize();
+
+ if(usedSize == -1){
+ //cell.getCellStyle().setAlignment(HSSFCellStyle.ALIGN_CENTER);
+ cell.setCellValue(new HSSFRichTextString(NOT_AVAILABLE));
+ }
+ else
+ cell.setCellValue(usedSize);
+
+ usedSizes[i] = usedSize;
+
+ }
+ cell = row.createCell(logData.getNumberOfCycles()+1-constants.size());
+ cell.setCellStyle(styles.get("cell_number"));
+ long deltaValue = utils.calculateDeltaForGivenSet(usedSizes);
+
+ cell.setCellValue(deltaValue);
+ rowNo++;
+
+ row = sheet.createRow(rowNo);
+ cell = row.createCell(0);
+ cell.setCellStyle(styles.get("cell_normal"));
+ cell.setCellValue(new HSSFRichTextString(name + " (Size)"));
+
+ long [] sizeValues = new long[values.size()];
+
+ j=1;
+ for(int i=0; i<values.size(); i++)
+ {
+ if(constants.contains(i+1))
+ continue;
+
+ cell = row.createCell(j++);
+ cell.setCellStyle(styles.get("cell_number"));
+ cell.setCellType(HSSFCell.CELL_TYPE_NUMERIC);
+
+ long size = values.get(i).getSize();
+
+ if(size == -1){
+ //cell.getCellStyle().setAlignment(HSSFCellStyle.ALIGN_CENTER);
+ cell.setCellValue(new HSSFRichTextString(NOT_AVAILABLE));
+ }
+ else
+ cell.setCellValue(size);
+
+ sizeValues[i] = size;
+ }
+
+ cell = row.createCell(logData.getNumberOfCycles()+1-constants.size());
+ cell.setCellStyle(styles.get("cell_number"));
+ long sizeDelta = utils.calculateDeltaForGivenSet(sizeValues);
+
+ cell.setCellValue(sizeDelta);
+
+ }
+
+ for(int i=0; i <= logData.getNumberOfCycles(); i++)
+ {
+ sheet.autoSizeColumn((short)i);
+ }
+ cell = description.createCell(0);
+ cell.setCellValue(new HSSFRichTextString("Specifies the amount of used RAM and disk memories of all drives in bytes, for each cycle in seconds"));
+ }
+
+ private void createHeapSizeTab()
+ {
+ HSSFSheet sheet = wb.createSheet();
+ // declare a row object reference
+ HSSFRow row = null;
+ HSSFRow description = null;
+ // declare a cell object reference
+ HSSFCell cell = null;
+
+ //set the sheet name in Unicode
+ wb.setSheetName(4, "Total Heap Size");
+
+ row = sheet.createRow(0);
+ //r.setHeight((short)500);
+
+ cell = row.createCell(0);
+ cell.setCellStyle(styles.get("header"));
+ cell.setCellValue(new HSSFRichTextString("Total Heap Size"));
+
+ description = sheet.createRow(1);
+
+ //creates an empty row.
+ row = sheet.createRow(2);
+
+ row = sheet.createRow(3);
+ cell = row.createCell(0);
+ cell.setCellStyle(styles.get("header1"));
+ cell.setCellValue(new HSSFRichTextString("Threads"));
+ addCycleIntervals(row);
+
+ cell = row.createCell((int)row.getLastCellNum());
+ cell.setCellStyle(styles.get("header2"));
+ cell.setCellValue(new HSSFRichTextString("Delta"));
+
+ int rowNo = 4;
+
+ for(String heap:heapThreads)
+ {
+ row = sheet.createRow(rowNo);
+ cell = row.createCell(0);
+ cell.setCellStyle(styles.get("cell_normal"));
+ cell.setCellValue(new HSSFRichTextString(heap));
+
+ ArrayList<ThreadData> heapValues = heapData.get(heap.toLowerCase());
+
+ if(heapValues != null)
+ {
+ int j=1;
+ for(int i=0; i<heapValues.size(); i++)
+ {
+ if(constants.contains(i+1))
+ {
+ if(heap.equalsIgnoreCase("!SensorServer[1020507e]0001::OrientationThread"))
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "Skipping data from Cycle.." + i);
+ continue;
+ }
+
+ cell = row.createCell(j++);
+ cell.setCellStyle(styles.get("cell_number"));
+ ThreadData thData = heapValues.get(i);
+
+ if(thData.getStatus() == 0){
+ //cell.getCellStyle().setAlignment(HSSFCellStyle.ALIGN_CENTER);
+ cell.setCellValue(new HSSFRichTextString(NOT_AVAILABLE));
+ }
+ else
+ cell.setCellValue(thData.getHeapChunkSize());
+ }
+ }
+
+ cell = row.createCell(logData.getNumberOfCycles()+1-constants.size());
+ cell.setCellStyle(styles.get("cell_number"));
+
+ ThreadData delta = deltaData.get(heap.toLowerCase());
+
+ //DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "Delta for the thread " + heap + " is " + delta);
+
+ if(delta != null){
+ long heapSizeDelta = delta.getHeapChunkSize();
+ cell.setCellValue(heapSizeDelta);
+ }
+ else
+ cell.setCellValue(0);
+
+ rowNo++;
+ }
+ for(int i=0; i <= logData.getNumberOfCycles(); i++)
+ {
+ sheet.autoSizeColumn((short)i);
+ }
+ cell = description.createCell(0);
+ cell.setCellValue(new HSSFRichTextString("Specifies the total heap size for each thread in bytes, for each cycle in seconds"));
+ }
+
+ private void createHeapAllocSpaceTab()
+ {
+ HSSFSheet sheet = wb.createSheet();
+ // declare a row object reference
+ HSSFRow row = null;
+ HSSFRow description = null;
+ // declare a cell object reference
+ HSSFCell cell = null;
+
+ //set the sheet name in Unicode
+ wb.setSheetName(5, "Total heap alloc space");
+
+ row = sheet.createRow(0);
+ //r.setHeight((short)500);
+
+ cell = row.createCell(0);
+ cell.setCellStyle(styles.get("header"));
+ cell.setCellValue(new HSSFRichTextString("Total Heap Allocated Space"));
+
+ description = sheet.createRow(1);
+
+ //creates an empty row.
+ row = sheet.createRow(2);
+
+ row = sheet.createRow(3);
+ cell = row.createCell(0);
+ cell.setCellStyle(styles.get("header1"));
+ cell.setCellValue(new HSSFRichTextString("Threads"));
+ addCycleIntervals(row);
+
+ cell = row.createCell((int)row.getLastCellNum());
+ cell.setCellStyle(styles.get("header2"));
+ cell.setCellValue(new HSSFRichTextString("Delta"));
+
+ int rowNo = 4;
+
+ for(String heap:heapThreads)
+ {
+ row = sheet.createRow(rowNo);
+ cell = row.createCell(0);
+ cell.setCellStyle(styles.get("cell_normal"));
+ cell.setCellValue(new HSSFRichTextString(heap));
+
+ ArrayList<ThreadData> heapValues = heapData.get(heap.toLowerCase());
+
+ if(heapValues != null)
+ {
+ int j=1;
+ for(int i=0; i<heapValues.size(); i++)
+ {
+ if(constants.contains(i+1))
+ continue;
+
+ cell = row.createCell(j++);
+ cell.setCellStyle(styles.get("cell_number"));
+ ThreadData thData = heapValues.get(i);
+
+ if(thData.getStatus() == 0){
+ //cell.getCellStyle().setAlignment(HSSFCellStyle.ALIGN_CENTER);
+ cell.setCellValue(new HSSFRichTextString(NOT_AVAILABLE));
+ }
+ else
+ cell.setCellValue(thData.getHeapAllocatedSpace());
+
+ }
+ }
+ cell = row.createCell(logData.getNumberOfCycles()+1-constants.size());
+ cell.setCellStyle(styles.get("cell_number"));
+
+ if(deltaData.get(heap.toLowerCase()) != null){
+ long heapAllocSpaceDelta = deltaData.get(heap.toLowerCase()).getHeapAllocatedSpace();
+ cell.setCellValue(heapAllocSpaceDelta);
+ }
+ else
+ cell.setCellValue(0);
+
+ rowNo++;
+ }
+
+ for(int i=0; i <= logData.getNumberOfCycles(); i++)
+ {
+ sheet.autoSizeColumn((short)i);
+ }
+
+ cell = description.createCell(0);
+ cell.setCellValue(new HSSFRichTextString("Specifies the total heap allocated space for each thread in bytes, for each cycle in seconds"));
+ }
+
+ private void createHeapFreeSpaceTab()
+ {
+ HSSFSheet sheet = wb.createSheet();
+ // declare a row object reference
+ HSSFRow row = null;
+ HSSFRow description = null;
+ // declare a cell object reference
+ HSSFCell cell = null;
+
+ //set the sheet name in Unicode
+ wb.setSheetName(6, "Total heap free space");
+
+ row = sheet.createRow(0);
+ //r.setHeight((short)500);
+
+ cell = row.createCell(0);
+ cell.setCellStyle(styles.get("header"));
+ cell.setCellValue(new HSSFRichTextString("Total Heap Free Space"));
+
+ description = sheet.createRow(1);
+
+ //creates an empty row.
+ row = sheet.createRow(2);
+
+ row = sheet.createRow(3);
+ cell = row.createCell(0);
+ cell.setCellStyle(styles.get("header1"));
+ cell.setCellValue(new HSSFRichTextString("Threads"));
+ addCycleIntervals(row);
+
+ cell = row.createCell((int)row.getLastCellNum());
+ cell.setCellStyle(styles.get("header2"));
+ cell.setCellValue(new HSSFRichTextString("Delta"));
+
+ int rowNo = 4;
+
+ for(String heap:heapThreads)
+ {
+ row = sheet.createRow(rowNo);
+ cell = row.createCell(0);
+ cell.setCellStyle(styles.get("cell_normal"));
+ cell.setCellValue(new HSSFRichTextString(heap));
+
+ ArrayList<ThreadData> heapValues = heapData.get(heap.toLowerCase());
+
+ if(heapValues != null)
+ {
+ int j=1;
+ for(int i=0; i<heapValues.size(); i++)
+ {
+ if(constants.contains(i+1))
+ continue;
+
+ cell = row.createCell(j++);
+ cell.setCellStyle(styles.get("cell_number"));
+ ThreadData thData = heapValues.get(i);
+
+ if(thData.getStatus() == 0){
+ //cell.getCellStyle().setAlignment(HSSFCellStyle.ALIGN_CENTER);
+ cell.setCellValue(new HSSFRichTextString(NOT_AVAILABLE));
+ }
+ else
+ cell.setCellValue(thData.getHeapFreeSpace());
+ }
+ }
+
+ cell = row.createCell(logData.getNumberOfCycles() + 1 -constants.size());
+ cell.setCellStyle(styles.get("cell_number"));
+
+ if(deltaData.get(heap.toLowerCase()) != null){
+ long heapFreeeDelta = deltaData.get(heap.toLowerCase()).getHeapFreeSpace();
+ cell.setCellValue(heapFreeeDelta);
+ }
+ else
+ cell.setCellValue(0);
+
+ rowNo++;
+ }
+ for(int i=0; i <= logData.getNumberOfCycles(); i++)
+ {
+ sheet.autoSizeColumn((short)i);
+ }
+
+ cell = description.createCell(0);
+ cell.setCellValue(new HSSFRichTextString("Specifies the total heap free space for each thread in bytes, for each cycle in seconds"));
+ }
+
+ private void createAllocatedCellsTab()
+ {
+ HSSFSheet sheet = wb.createSheet();
+ // declare a row object reference
+ HSSFRow row = null;
+ HSSFRow description = null;
+ // declare a cell object reference
+ HSSFCell cell = null;
+
+ //set the sheet name in Unicode
+ wb.setSheetName(7, "Allocated heap cell count");
+
+ row = sheet.createRow(0);
+ //r.setHeight((short)500);
+
+ cell = row.createCell(0);
+ cell.setCellStyle(styles.get("header"));
+ cell.setCellValue(new HSSFRichTextString("Allocated heap cell count"));
+
+ description = sheet.createRow(1);
+
+ //creates an empty row.
+ row = sheet.createRow(2);
+
+ row = sheet.createRow(3);
+ cell = row.createCell(0);
+ cell.setCellStyle(styles.get("header1"));
+ cell.setCellValue(new HSSFRichTextString("Threads"));
+ addCycleIntervals(row);
+
+ cell = row.createCell((int)row.getLastCellNum());
+ cell.setCellStyle(styles.get("header2"));
+ cell.setCellValue(new HSSFRichTextString("Delta"));
+
+ int rowNo = 4;
+
+ for(String heap:heapThreads)
+ {
+ row = sheet.createRow(rowNo);
+ cell = row.createCell(0);
+ cell.setCellStyle(styles.get("cell_normal"));
+ cell.setCellValue(new HSSFRichTextString(heap));
+
+ ArrayList<ThreadData> heapValues = heapData.get(heap.toLowerCase());
+
+ if(heapValues != null)
+ {
+ int j=1;
+ for(int i=0; i<heapValues.size(); i++)
+ {
+ if(constants.contains(i+1))
+ continue;
+
+ cell = row.createCell(j++);
+ cell.setCellStyle(styles.get("cell_number"));
+ ThreadData thData = heapValues.get(i);
+
+ if(thData.getStatus() == 0){
+ //cell.getCellStyle().setAlignment(HSSFCellStyle.ALIGN_CENTER);
+ cell.setCellValue(new HSSFRichTextString(NOT_AVAILABLE));
+ }
+ else
+ cell.setCellValue(thData.getAllocatedCells());
+ }
+ }
+ cell = row.createCell(logData.getNumberOfCycles()+1-constants.size());
+ cell.setCellStyle(styles.get("cell_number"));
+
+ if(deltaData.get(heap.toLowerCase()) != null){
+ long allocCellsDelta = deltaData.get(heap.toLowerCase()).getAllocatedCells();
+ cell.setCellValue(allocCellsDelta);
+ }
+ else
+ cell.setCellValue(0);
+
+ rowNo++;
+ }
+ for(int i=0; i <= logData.getNumberOfCycles(); i++)
+ {
+ sheet.autoSizeColumn((short)i);
+ }
+
+ cell = description.createCell(0);
+ cell.setCellValue(new HSSFRichTextString("Specifies the allocated heap cell count for each thread in bytes, for each cycle in seconds"));
+ }
+
+ private void createFreeCellsTab()
+ {
+ HSSFSheet sheet = wb.createSheet();
+ // declare a row object reference
+ HSSFRow row = null;
+ HSSFRow description = null;
+ // declare a cell object reference
+ HSSFCell cell = null;
+
+ //set the sheet name in Unicode
+ wb.setSheetName(8, "Free heap cell count");
+
+ row = sheet.createRow(0);
+
+ cell = row.createCell(0);
+ cell.setCellStyle(styles.get("header"));
+ cell.setCellValue(new HSSFRichTextString("Free heap cell count"));
+
+ description = sheet.createRow(1);
+
+ //creates an empty row.
+ row = sheet.createRow(2);
+
+ row = sheet.createRow(3);
+ cell = row.createCell(0);
+ cell.setCellStyle(styles.get("header1"));
+ cell.setCellValue(new HSSFRichTextString("Threads"));
+ addCycleIntervals(row);
+
+ cell = row.createCell((int)row.getLastCellNum());
+ cell.setCellStyle(styles.get("header2"));
+ cell.setCellValue(new HSSFRichTextString("Delta"));
+
+ int rowNo = 4;
+
+ for(String heap:heapThreads)
+ {
+ row = sheet.createRow(rowNo);
+ cell = row.createCell(0);
+ cell.setCellStyle(styles.get("cell_normal"));
+ cell.setCellValue(new HSSFRichTextString(heap));
+
+ ArrayList<ThreadData> heapValues = heapData.get(heap.toLowerCase());
+
+ if(heapValues != null)
+ {
+ int j=1;
+ for(int i=0; i<heapValues.size(); i++)
+ {
+ if(constants.contains(i+1))
+ continue;
+
+ cell = row.createCell(j++);
+ cell.setCellStyle(styles.get("cell_number"));
+ ThreadData thData = heapValues.get(i);
+
+ if(thData.getStatus() == 0){
+ //cell.getCellStyle().setAlignment(HSSFCellStyle.ALIGN_CENTER);
+ cell.setCellValue(new HSSFRichTextString(NOT_AVAILABLE));
+ }
+ else
+ cell.setCellValue(thData.getFreeCells());
+ }
+ }
+
+ cell = row.createCell(logData.getNumberOfCycles()+1-constants.size());
+ cell.setCellStyle(styles.get("cell_number"));
+
+ if(deltaData.get(heap.toLowerCase()) != null){
+ long heapFreeCellsDelta = deltaData.get(heap.toLowerCase()).getFreeCells();
+ cell.setCellValue(heapFreeCellsDelta);
+ }
+ else
+ cell.setCellValue(0);
+
+ rowNo++;
+ }
+ for(int i=0; i <= logData.getNumberOfCycles(); i++)
+ {
+ sheet.autoSizeColumn((short)i);
+ }
+
+ cell = description.createCell(0);
+ cell.setCellValue(new HSSFRichTextString("Specifies the free heap cell count for each thread in bytes, for each cycle in seconds"));
+ }
+
+ private void createFreeSlackTab()
+ {
+ HSSFSheet sheet = wb.createSheet();
+ // declare a row object reference
+ HSSFRow row = null;
+ HSSFRow description = null;
+ // declare a cell object reference
+ HSSFCell cell = null;
+
+ //set the sheet name in Unicode
+ wb.setSheetName(9, "Free Slack");
+
+ row = sheet.createRow(0);
+ //r.setHeight((short)500);
+
+ cell = row.createCell(0);
+ cell.setCellStyle(styles.get("header"));
+ cell.setCellValue(new HSSFRichTextString("Free slack"));
+
+ description = sheet.createRow(1);
+
+ //creates an empty row.
+ row = sheet.createRow(2);
+
+ row = sheet.createRow(3);
+ cell = row.createCell(0);
+ cell.setCellStyle(styles.get("header1"));
+ cell.setCellValue(new HSSFRichTextString("Threads"));
+ addCycleIntervals(row);
+
+ cell = row.createCell((int)row.getLastCellNum());
+ cell.setCellStyle(styles.get("header2"));
+ cell.setCellValue(new HSSFRichTextString("Delta"));
+
+ int rowNo = 4;
+
+ for(String heap:heapThreads)
+ {
+ row = sheet.createRow(rowNo);
+ cell = row.createCell(0);
+ cell.setCellStyle(styles.get("cell_normal"));
+ cell.setCellValue(new HSSFRichTextString(heap));
+
+ ArrayList<ThreadData> heapValues = heapData.get(heap.toLowerCase());
+
+ if(heapValues != null)
+ {
+ int j=1;
+ for(int i=0; i<heapValues.size(); i++)
+ {
+ if(constants.contains(i+1))
+ continue;
+
+ cell = row.createCell(j++);
+ cell.setCellStyle(styles.get("cell_number"));
+ ThreadData thData = heapValues.get(i);
+
+ if(thData.getStatus() == 0){
+ //cell.getCellStyle().setAlignment(HSSFCellStyle.ALIGN_CENTER);
+ cell.setCellValue(new HSSFRichTextString(NOT_AVAILABLE));
+ }
+ else
+ cell.setCellValue(thData.getFreeSlackSize());
+ }
+ }
+ cell = row.createCell(logData.getNumberOfCycles()+1-constants.size());
+ cell.setCellStyle(styles.get("cell_number"));
+
+ if(deltaData.get(heap.toLowerCase()) != null){
+ long heapSlackDelta = deltaData.get(heap.toLowerCase()).getFreeSlackSize();
+ cell.setCellValue(heapSlackDelta);
+ }
+ else
+ cell.setCellValue(0);
+
+ rowNo++;
+ }
+ for(int i=0; i <= logData.getNumberOfCycles(); i++)
+ {
+ sheet.autoSizeColumn((short)i);
+ }
+
+ cell = description.createCell(0);
+ cell.setCellValue(new HSSFRichTextString("Specifies the free slack size for each thread in bytes, for each cycle in seconds"));
+ }
+
+ private void createLargestAllocSizeTab()
+ {
+ HSSFSheet sheet = wb.createSheet();
+ // declare a row object reference
+ HSSFRow row = null;
+ HSSFRow description = null;
+ // declare a cell object reference
+ HSSFCell cell = null;
+
+ //set the sheet name in Unicode
+ wb.setSheetName(10, "Largest allocated cell size in heap");
+
+ row = sheet.createRow(0);
+ //r.setHeight((short)500);
+
+ cell = row.createCell(0);
+ cell.setCellStyle(styles.get("header"));
+ cell.setCellValue(new HSSFRichTextString("Largest allocated cell size in heap"));
+
+ sheet.autoSizeColumn((short)0);
+
+ description = sheet.createRow(1);
+
+ //creates an empty row.
+ row = sheet.createRow(2);
+
+ row = sheet.createRow(3);
+ cell = row.createCell(0);
+ cell.setCellStyle(styles.get("header1"));
+ cell.setCellValue(new HSSFRichTextString("Threads"));
+ addCycleIntervals(row);
+
+ cell = row.createCell((int)row.getLastCellNum());
+ cell.setCellStyle(styles.get("header2"));
+ cell.setCellValue(new HSSFRichTextString("Delta"));
+
+ int rowNo = 4;
+
+ for(String heap:heapThreads)
+ {
+ row = sheet.createRow(rowNo);
+ cell = row.createCell(0);
+ cell.setCellStyle(styles.get("cell_normal"));
+ cell.setCellValue(new HSSFRichTextString(heap));
+
+ ArrayList<ThreadData> heapValues = heapData.get(heap.toLowerCase());
+
+ if(heapValues != null)
+ {
+ int j=1;
+ for(int i=0; i<heapValues.size(); i++)
+ {
+ if(constants.contains(i+1))
+ continue;
+
+ cell = row.createCell(j++);
+ cell.setCellStyle(styles.get("cell_number"));
+ ThreadData thData = heapValues.get(i);
+
+ if(thData.getStatus() == 0){
+ //cell.getCellStyle().setAlignment(HSSFCellStyle.ALIGN_CENTER);
+ cell.setCellValue(new HSSFRichTextString(NOT_AVAILABLE));
+ }
+ else
+ cell.setCellValue(thData.getLargestAllocCellSize());
+ }
+ }
+ cell = row.createCell(logData.getNumberOfCycles() + 1 -constants.size());
+ cell.setCellStyle(styles.get("cell_number"));
+
+ if(deltaData.get(heap.toLowerCase()) != null){
+ long largetAllocCellDelta = deltaData.get(heap.toLowerCase()).getLargestAllocCellSize();
+ cell.setCellValue(largetAllocCellDelta);
+ }
+ else
+ cell.setCellValue(0);
+
+ rowNo++;
+ }
+ for(int i=0; i <= logData.getNumberOfCycles(); i++)
+ {
+ sheet.autoSizeColumn((short)i);
+ }
+
+ cell = description.createCell(0);
+ cell.setCellValue(new HSSFRichTextString("Specifies the largest allocated cell size in heap for each thread in bytes, for each cycle in seconds"));
+ }
+
+ private void createLargestFreeSizeTab()
+ {
+ HSSFSheet sheet = wb.createSheet();
+ // declare a row object reference
+ HSSFRow row = null;
+ HSSFRow description = null;
+ // declare a cell object reference
+ HSSFCell cell = null;
+
+ //set the sheet name in Unicode
+ wb.setSheetName(11, "Largest free cell size in heap");
+
+ row = sheet.createRow(0);
+ //r.setHeight((short)500);
+
+ cell = row.createCell(0);
+ cell.setCellStyle(styles.get("header"));
+ cell.setCellValue(new HSSFRichTextString("Largest free cell size in heap"));
+
+ description = sheet.createRow(1);
+
+ //creates an empty row.
+ row = sheet.createRow(2);
+
+ row = sheet.createRow(3);
+ cell = row.createCell(0);
+ cell.setCellStyle(styles.get("header1"));
+ cell.setCellValue(new HSSFRichTextString("Threads"));
+ addCycleIntervals(row);
+
+ cell = row.createCell((int)row.getLastCellNum());
+ cell.setCellStyle(styles.get("header2"));
+ cell.setCellValue(new HSSFRichTextString("Delta"));
+
+ int rowNo = 4;
+
+ for(String heap:heapThreads)
+ {
+ row = sheet.createRow(rowNo);
+ cell = row.createCell(0);
+ cell.setCellStyle(styles.get("cell_normal"));
+ cell.setCellValue(new HSSFRichTextString(heap));
+
+ ArrayList<ThreadData> heapValues = heapData.get(heap.toLowerCase());
+
+ if(heapValues != null)
+ {
+ int j=1;
+ for(int i=0; i<heapValues.size(); i++)
+ {
+ if(constants.contains(i+1))
+ continue;
+
+ cell = row.createCell(j++);
+ cell.setCellStyle(styles.get("cell_number"));
+ ThreadData thData = heapValues.get(i);
+
+ if(thData.getStatus() == 0){
+ //cell.getCellStyle().setAlignment(HSSFCellStyle.ALIGN_CENTER);
+ cell.setCellValue(new HSSFRichTextString(NOT_AVAILABLE));
+ }
+ else
+ cell.setCellValue(thData.getLargestFreeCellSize());
+ }
+ }
+
+ cell = row.createCell(logData.getNumberOfCycles()+1-constants.size());
+ cell.setCellStyle(styles.get("cell_number"));
+
+ if(deltaData.get(heap.toLowerCase()) != null){
+ long largestFreeCellDelta = deltaData.get(heap.toLowerCase()).getLargestFreeCellSize();
+ cell.setCellValue(largestFreeCellDelta);
+ }
+ else
+ cell.setCellValue(0);
+
+ rowNo++;
+ }
+ for(int i=0; i <= logData.getNumberOfCycles(); i++)
+ {
+ sheet.autoSizeColumn((short)i);
+ }
+
+ cell = description.createCell(0);
+ cell.setCellValue(new HSSFRichTextString("Specifies the largest free cell size in heap for each thread in bytes, for each cycle in seconds"));
+ }
+
+ /**
+ * This method creates the sheet for Global Data.
+ *
+ *
+ */
+ private void createGlobalChunksSheet()
+ {
+ HSSFSheet sheet = wb.createSheet();
+ // declare a row object reference
+ HSSFRow row = null;
+ HSSFRow description = null;
+ // declare a cell object reference
+ HSSFCell cell = null;
+
+ //set the sheet name in Unicode
+ wb.setSheetName(2, "Global Data");
+
+ row = sheet.createRow(0);
+ //r.setHeight((short)500);
+
+ cell = row.createCell(0);
+ cell.setCellStyle(styles.get("header"));
+ cell.setCellValue(new HSSFRichTextString("Global Data"));
+
+ description = sheet.createRow(1);
+
+ //creates an empty row.
+ row = sheet.createRow(2);
+
+ row = sheet.createRow(3);
+ cell = row.createCell(0);
+ cell.setCellStyle(styles.get("header1"));
+ cell.setCellValue(new HSSFRichTextString("Chunk Names"));
+ addCycleIntervals(row);
+
+ cell = row.createCell((int)row.getLastCellNum());
+ cell.setCellStyle(styles.get("header2"));
+ cell.setCellValue(new HSSFRichTextString("Delta"));
+
+ int rowNo = 4;
+
+ for(String heap:glodChunks)
+ {
+ row = sheet.createRow(rowNo);
+ cell = row.createCell(0);
+ cell.setCellStyle(styles.get("cell_normal"));
+ cell.setCellValue(new HSSFRichTextString(heap));
+
+ ArrayList<GlobalDataChunks> heapValues = glodData.get(heap);
+
+ int j=1;
+ for(int i=0; i<heapValues.size(); i++)
+ {
+ if(constants.contains(i+1))
+ continue;
+
+ cell = row.createCell(j++);
+ cell.setCellStyle(styles.get("cell_number"));
+ GlobalDataChunks thData = heapValues.get(i);
+
+ if(thData.getAttrib() == 0){
+ //cell.getCellStyle().setAlignment(HSSFCellStyle.ALIGN_CENTER);
+ cell.setCellValue(new HSSFRichTextString(NOT_AVAILABLE));
+ }
+ else
+ cell.setCellValue(thData.getSize());
+ }
+
+ cell = row.createCell(logData.getNumberOfCycles()+1-constants.size());
+ cell.setCellStyle(styles.get("cell_number"));
+
+ if(glodDeltaData.get(heap) != null){
+ long largestFreeCellDelta = Long.parseLong(glodDeltaData.get(heap));
+ cell.setCellValue(largestFreeCellDelta);
+ }
+ rowNo++;
+ }
+ for(int i=0; i <= logData.getNumberOfCycles(); i++)
+ {
+ sheet.autoSizeColumn((short)i);
+ }
+
+ cell = description.createCell(0);
+ cell.setCellValue(new HSSFRichTextString("Specifies the chunk sizes in bytes that caontains global data, for each cycle in seconds"));
+
+ }
+
+ private void createNonHeapChunkSheet()
+ {
+ //create a new sheet
+ HSSFSheet sheet = wb.createSheet();
+ // declare a row object reference
+ HSSFRow row = null;
+ HSSFRow description = null;
+ // declare a cell object reference
+ HSSFCell cell = null;
+
+ //set the sheet name in Unicode
+ wb.setSheetName(3, "Non-heap chunks");
+
+ row = sheet.createRow(0);
+ //r.setHeight((short)500);
+
+ cell = row.createCell(0);
+ cell.setCellStyle(styles.get("header"));
+ cell.setCellValue(new HSSFRichTextString("Non-Heap Chunk Size"));
+
+ description = sheet.createRow(1);
+
+ //creates an empty row
+ row = sheet.createRow(2);
+
+ row = sheet.createRow(3);
+ cell = row.createCell(0);
+ cell.setCellStyle(styles.get("header2"));
+ cell.setCellValue(new HSSFRichTextString("Chunk Names"));
+ addCycleIntervals(row);
+
+ cell = row.createCell((int)row.getLastCellNum());
+ cell.setCellStyle(styles.get("header2"));
+ cell.setCellValue(new HSSFRichTextString("Delta"));
+
+ int rowNo = 4;
+
+ for(String heap:nonHeapChunks)
+ {
+ row = sheet.createRow(rowNo);
+ cell = row.createCell(0);
+ cell.setCellStyle(styles.get("cell_normal"));
+ cell.setCellValue(new HSSFRichTextString(heap));
+
+ ArrayList<ChunksData> chunkValues = chunkData.get(heap);
+
+ int j=1;
+ for(int i=0; i<chunkValues.size(); i++)
+ {
+ if(constants.contains(i+1))
+ continue;
+
+ cell = row.createCell(j++);
+ cell.setCellStyle(styles.get("cell_number"));
+ ChunksData chData = chunkValues.get(i);
+
+ if(chData.getAttrib() == 0){
+ //cell.getCellStyle().setAlignment(HSSFCellStyle.ALIGN_CENTER);
+ cell.setCellValue(new HSSFRichTextString(NOT_AVAILABLE));
+ }
+ else
+ cell.setCellValue(chData.getSize());
+ }
+
+ cell = row.createCell(logData.getNumberOfCycles()+1-constants.size());
+ cell.setCellStyle(styles.get("cell_number"));
+
+ if(chunkDeltaData.get(heap) != null){
+ long largestFreeCellDelta = Long.parseLong(chunkDeltaData.get(heap));
+ cell.setCellValue(largestFreeCellDelta);
+ }
+ rowNo++;
+ }
+
+ for(int i=0; i <= logData.getNumberOfCycles(); i++)
+ {
+ sheet.autoSizeColumn((short)i);
+ }
+
+ cell = description.createCell(0);
+ cell.setCellValue(new HSSFRichTextString("Specifies the non heap chunk sizes in bytes, for each cycle in seconds"));
+ }
+
+ /**
+ * This method creates sheet with Window Group events.
+ *
+ */
+ private void createWindowGroupSheet()
+ {
+ //create a new sheet
+ HSSFSheet sheet = wb.createSheet();
+ // declare a row object reference
+ HSSFRow row = null;
+ HSSFRow description = null;
+ // declare a cell object reference
+ HSSFCell cell = null;
+
+ //set the sheet name in Unicode
+ wb.setSheetName(12, "Window Groups");
+
+ row = sheet.createRow(0);
+ //r.setHeight((short)500);
+
+ cell = row.createCell(0);
+ cell.setCellStyle(styles.get("header"));
+ cell.setCellValue(new HSSFRichTextString("Window Group Events"));
+
+ description = sheet.createRow(1);
+
+ //creates an empty row
+ row = sheet.createRow(2);
+
+ row = sheet.createRow(3);
+ cell = row.createCell(0);
+ cell.setCellStyle(styles.get("header2"));
+ cell.setCellValue(new HSSFRichTextString("Window Group Names"));
+ addCycleIntervals(row);
+
+ SWMTLogReaderUtils utils = new SWMTLogReaderUtils();
+ ArrayList<String> wndg_names = utils.getWindowGroupNames(logData);
+
+ int rowNo = 4;
+
+ if(wndg_names == null)
+ return;
+ else
+ {
+ for(String name:wndg_names)
+ {
+ row = sheet.createRow(rowNo++);
+ cell = row.createCell(0);
+ cell.setCellStyle(styles.get("cell_normal"));
+ cell.setCellValue(new HSSFRichTextString(name));
+
+ ArrayList<WindowGroupEventData> events_list = utils.getAllWindowGroupEvents(name, logData);
+
+ int j = 1;
+
+ for(int i=0; i<events_list.size(); i++)
+ {
+ if(constants.contains(i+1))
+ continue;
+
+ cell = row.createCell(j++);
+ cell.setCellStyle(styles.get("cell_normal"));
+
+ WindowGroupEventData eventSet = events_list.get(i);
+
+ if(eventSet == null){
+ cell.setCellValue(new HSSFRichTextString(NOT_AVAILABLE));
+ }
+ else
+ {
+ StringBuffer tmp = new StringBuffer();
+
+ if(eventSet.getEvent_0_count() > 0)
+ tmp.append(" NoEvent(" + eventSet.getEvent_0_count() + ")");
+ if(eventSet.getEvent_1_count() > 0)
+ tmp.append(" NameChanged(" + eventSet.getEvent_1_count() + ")");
+ if(eventSet.getEvent_2_count() > 0)
+ tmp.append(" FocusGained(" + eventSet.getEvent_2_count() + ")");
+ if(eventSet.getEvent_3_count() > 0)
+ tmp.append(" FocusLost(" + eventSet.getEvent_3_count() + ")");
+
+ cell.setCellValue(new HSSFRichTextString(tmp.toString()));
+ }
+
+ }
+ }
+
+ for(int i=0; i <= logData.getNumberOfCycles(); i++)
+ sheet.autoSizeColumn((short)i);
+
+ cell = description.createCell(0);
+ cell.setCellValue(new HSSFRichTextString("Specifies the type and number of events for each window group, in each cycle."));
+ }
+ }
+ /**
+ * create set of cell styles
+ */
+ private Map<String, HSSFCellStyle> createStyles(HSSFWorkbook wb){
+ Map<String, HSSFCellStyle> styles = new HashMap<String, HSSFCellStyle>();
+
+ HSSFCellStyle style;
+ HSSFFont headerFont = wb.createFont();
+ headerFont.setColor(HSSFColor.WHITE.index);
+ headerFont.setBoldweight(HSSFFont.BOLDWEIGHT_NORMAL);
+ headerFont.setFontHeightInPoints((short)18);
+ style = createBorderedStyle(wb);
+ style.setAlignment(HSSFCellStyle.ALIGN_LEFT);
+ style.setFillForegroundColor(HSSFColor.BLUE.index);
+ style.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
+ style.setFont(headerFont);
+ styles.put("header", style);
+
+ HSSFFont font1 = wb.createFont();
+ font1.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
+ font1.setFontHeightInPoints((short)12);
+ font1.setFontName(HSSFFont.FONT_ARIAL);
+ font1.setColor(HSSFColor.WHITE.index);
+ style = createBorderedStyle(wb);
+ style.setAlignment(HSSFCellStyle.ALIGN_CENTER);
+ style.setFillForegroundColor(HSSFColor.BLUE.index);
+ style.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
+ style.setFont(font1);
+ style.setWrapText(true);
+ styles.put("header2", style);
+
+ style = createBorderedStyle(wb);
+ style.setAlignment(HSSFCellStyle.ALIGN_LEFT);
+ style.setFillForegroundColor(HSSFColor.BLUE.index);
+ style.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
+ style.setFont(font1);
+ style.setWrapText(true);
+ styles.put("header1", style);
+
+ HSSFFont font3 = wb.createFont();
+ font3.setColor(HSSFColor.BLACK.index);
+ font3.setFontHeightInPoints((short)10);
+ font3.setFontName(HSSFFont.FONT_ARIAL);
+ font3.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
+ style = createBorderedStyle(wb);
+ style.setAlignment(HSSFCellStyle.ALIGN_LEFT);
+ style.setFont(font3);
+ styles.put("cell_bold", style);
+
+ HSSFFont font5 = wb.createFont();
+ font5.setColor(HSSFColor.BLACK.index);
+ font5.setBoldweight(HSSFFont.BOLDWEIGHT_NORMAL);
+ style = createBorderedStyle(wb);
+ style.setAlignment(HSSFCellStyle.ALIGN_LEFT);
+ style.setFont(font5);
+ styles.put("cell_normal", style);
+
+ HSSFFont font4 = wb.createFont();
+ font4.setFontHeightInPoints((short)10);
+ font4.setColor(HSSFColor.WHITE.index);
+ style = createBorderedStyle(wb);
+ style.setFillForegroundColor(HSSFColor.BLUE.index);
+ style.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
+ style.setFont(font4);
+ styles.put("cell_blue_font_white", style);
+
+ style = createBorderedStyle(wb);
+ style.setAlignment(HSSFCellStyle.ALIGN_RIGHT);
+ styles.put("cell_number", style);
+
+ HSSFFont blue_font = wb.createFont();
+ blue_font.setFontHeightInPoints((short)10);
+ blue_font.setColor(HSSFColor.BLUE.index);
+ style = createBorderedStyle(wb);
+ style.setAlignment(HSSFCellStyle.ALIGN_RIGHT);
+ style.setFont(blue_font);
+ styles.put("blue_font", style);
+
+ return styles;
+ }
+
+ private HSSFCellStyle createBorderedStyle(HSSFWorkbook wb){
+ HSSFCellStyle style = wb.createCellStyle();
+ style.setBorderRight(HSSFCellStyle.BORDER_THIN);
+ style.setRightBorderColor(HSSFColor.BLACK.index);
+ style.setBorderBottom(HSSFCellStyle.BORDER_THIN);
+ style.setBottomBorderColor(HSSFColor.BLACK.index);
+ style.setBorderLeft(HSSFCellStyle.BORDER_THIN);
+ style.setLeftBorderColor(HSSFColor.BLACK.index);
+ style.setBorderTop(HSSFCellStyle.BORDER_THIN);
+ style.setTopBorderColor(HSSFColor.BLACK.index);
+ return style;
+ }
+
+ /**
+ * This method adds cells with values of time intervals between
+ * consecutive cycles to given row.
+ * @param row
+ */
+ private void addCycleIntervals(HSSFRow row)
+ {
+ HSSFCell cell = null;
+
+ SWMTLogReaderUtils utils = new SWMTLogReaderUtils();
+
+ cell = row.createCell(1);
+ cell.setCellStyle(styles.get("header2"));
+ cell.setCellValue(0);
+
+ if(logData == null)
+ return;
+
+ long prevDuration = 0;
+
+ int i;
+ String currentTime = "";
+ String prevTime = "";
+ int j=1;
+ int filesSkipped = 1;
+
+ CycleData [] cycles = logData.getLogData();
+
+ for(i=1; i<logData.getNumberOfCycles();i++)
+ {
+ if(constants.contains(i+1))
+ {
+ filesSkipped++ ;
+ continue;
+ }
+ j++;
+ currentTime = cycles[i].getTime();
+ //if(constants.contains(i-1))
+ // prevTime = logData.get(i-2).getTime();
+ //else
+ // prevTime = logData.get(i-1).getTime();
+ prevTime = cycles[i-filesSkipped].getTime();
+
+ long timeDiff = utils.getDurationInSeconds(prevTime, currentTime);
+ cell = row.createCell(j);
+ cell.setCellStyle(styles.get("header2"));
+ cell.setCellType(HSSFCell.CELL_TYPE_NUMERIC);
+
+ if(timeDiff < 0)
+ {
+ cell.setCellValue(new HSSFRichTextString("Cycle " + (i+1)));
+ return;
+ }
+ else
+ {
+ timeDiff += prevDuration;
+ prevDuration = timeDiff;
+
+ cell.setCellValue(timeDiff);
+ }
+ filesSkipped = 1;
+ }
+
+ }
+
+ private void createOverviewFields(HSSFRow row)
+ {
+ HSSFCell cell = row.createCell(0);
+ cell.setCellStyle(styles.get("header1"));
+ cell.getCellStyle().setAlignment(HSSFCellStyle.ALIGN_LEFT);
+ cell.setCellValue(new HSSFRichTextString("Threads"));
+
+ cell = row.createCell(1);
+ cell.setCellStyle(styles.get("header1"));
+ cell.getCellStyle().setAlignment(HSSFCellStyle.ALIGN_LEFT);
+ cell.setCellValue(new HSSFRichTextString("Status"));
+
+ cell = row.createCell(2);
+ cell.setCellStyle(styles.get("header1"));
+ cell.getCellStyle().setAlignment(HSSFCellStyle.ALIGN_LEFT);
+ cell.setCellValue(new HSSFRichTextString("Max Heap Size"));
+
+ cell = row.createCell(3);
+ cell.setCellStyle(styles.get("header1"));
+ cell.getCellStyle().setAlignment(HSSFCellStyle.ALIGN_LEFT);
+ cell.setCellValue(new HSSFRichTextString("Change in Heap \n size (in Bytes)"));
+
+ cell = row.createCell(4);
+ cell.setCellStyle(styles.get("header1"));
+ cell.setCellValue(new HSSFRichTextString("Change in Heap Allocated \n space (in Bytes) "));
+
+ cell = row.createCell(5);
+ cell.setCellStyle(styles.get("header1"));
+ cell.getCellStyle().setAlignment(HSSFCellStyle.ALIGN_LEFT);
+ cell.setCellValue(new HSSFRichTextString("Change in Heap \n Free space (in Bytes)"));
+
+ cell = row.createCell(6);
+ cell.setCellStyle(styles.get("header1"));
+ cell.getCellStyle().setAlignment(HSSFCellStyle.ALIGN_LEFT);
+ cell.setCellValue(new HSSFRichTextString("Change in Allocated \n Cell Count"));
+
+ cell = row.createCell(7);
+ cell.setCellStyle(styles.get("header1"));
+ cell.getCellStyle().setAlignment(HSSFCellStyle.ALIGN_LEFT);
+ cell.setCellValue(new HSSFRichTextString("Change in Free \n Cell Count"));
+
+ cell = row.createCell(8);
+ cell.setCellStyle(styles.get("header1"));
+ cell.getCellStyle().setAlignment(HSSFCellStyle.ALIGN_LEFT);
+ cell.setCellValue(new HSSFRichTextString("Change in Slack \n space size (in Bytes) "));
+
+ cell = row.createCell(9);
+ cell.setCellStyle(styles.get("header1"));
+ cell.getCellStyle().setAlignment(HSSFCellStyle.ALIGN_LEFT);
+ cell.setCellValue(new HSSFRichTextString("Stack size"));
+
+ cell = row.createCell(10);
+ cell.setCellStyle(styles.get("header1"));
+ cell.getCellStyle().setAlignment(HSSFCellStyle.ALIGN_LEFT);
+ cell.setCellValue(new HSSFRichTextString("No. of Files \n opened"));
+
+ cell = row.createCell(11);
+ cell.setCellStyle(styles.get("header1"));
+ cell.getCellStyle().setAlignment(HSSFCellStyle.ALIGN_LEFT);
+ cell.setCellValue(new HSSFRichTextString("No. of \n P&S Handles"));
+
+ }
+
+ private void createDataInOverView(HSSFSheet sheet, int rowNo)
+ {
+ SWMTLogReaderUtils utils = new SWMTLogReaderUtils();
+
+ ArrayList<String> allThreads = utils.getAllThreadNames(logData);
+ Collections.sort(allThreads);
+
+ long [] maxHeapSizes = new long[allThreads.size()];
+ long [] heapSizes = new long[allThreads.size()];
+ long [] freeCells = new long[allThreads.size()];
+ long [] allocCells = new long[allThreads.size()];
+ long [] freeSpace = new long[allThreads.size()];
+ long [] allocSpace = new long[allThreads.size()];
+ long [] slackSpace = new long[allThreads.size()];
+ long [] totalFiles = new long[allThreads.size()];
+ long [] totalHandles = new long[allThreads.size()];
+ long [] totalStacks = new long[allThreads.size()];
+
+ int i =0;
+
+ for(String thName:allThreads)
+ {
+ if(thName.startsWith("MemSpy") && thName.endsWith("::MemSpy"))
+ continue;
+
+ HSSFRow row = sheet.createRow(rowNo);
+ HSSFCell cell = row.createCell(0);
+
+ cell.setCellStyle(styles.get("cell_normal"));
+ cell.setCellValue(new HSSFRichTextString(thName));
+
+ cell = row.createCell(1);
+ cell.setCellStyle(styles.get("cell_normal"));
+
+ if(logData.getNumberOfCycles() == 1)
+ {
+ cell.setCellValue(new HSSFRichTextString("Alive"));
+ }
+ else
+ {
+ int status = utils.getThreadStatusFromAllCycles(thName, logData);
+
+ if(status == 0)
+ cell.setCellValue(new HSSFRichTextString("Dead"));
+ else if(status == 1 || status == 2)
+ cell.setCellValue(new HSSFRichTextString("Alive"));
+ else
+ cell.setCellValue(new HSSFRichTextString(NOT_AVAILABLE));
+ }
+
+ ThreadData threadDelta = deltaData.get(thName.toLowerCase());
+
+ cell = row.createCell(2);
+ cell.setCellStyle(styles.get("cell_number"));
+ cell.setCellValue(threadDelta.getMaxHeapSize());
+
+ maxHeapSizes[i] = threadDelta.getMaxHeapSize();
+ /*ArrayList<String> heapThreads = utils.getAllHeapThreads(logData);
+ long delta = 0;
+ long lastValue = 0;
+
+ ArrayList<ThreadData> heapData = utils.getHeapDataFromAllCycles(thName, logData);
+
+ if(utils.getHeapStatusFromAllCycles(thName, logData) == 0)
+ {
+ //Display zeros for all heap fields
+ maxHeapSize = 0;
+ delta = 0;
+ }
+ else{
+ lastValue = heapData.get(logData.size()-1).getHeapChunkSize();
+ maxHeapSize = heapData.get(logData.size()-1).getMaxHeapSize();
+
+ long firstValue = 0;
+
+ for(int i=heapData.size()-2; i>=0; i--)
+ {
+ ThreadData data = heapData.get(i);
+ if(data.getStatus() != CycleData.Deleted){
+ firstValue = data.getHeapChunkSize();
+ }
+ else
+ break;
+ }
+
+ if(firstValue != -1)
+ delta = lastValue - firstValue;
+ } */
+
+ //cell.setCellValue(maxHeapSize);
+
+ cell = row.createCell(3);
+ cell.setCellStyle(styles.get("cell_number"));
+ cell.setCellValue(threadDelta.getHeapChunkSize());
+ heapSizes[i] = threadDelta.getHeapChunkSize();
+
+ cell = row.createCell(4);
+ cell.setCellStyle(styles.get("cell_number"));
+ cell.setCellValue(threadDelta.getHeapAllocatedSpace());
+ allocSpace[i] = threadDelta.getHeapAllocatedSpace();
+
+ cell = row.createCell(5);
+ cell.setCellStyle(styles.get("cell_number"));
+ cell.setCellValue(threadDelta.getHeapFreeSpace());
+ freeSpace[i] = threadDelta.getHeapFreeSpace();
+
+ cell = row.createCell(6);
+ cell.setCellStyle(styles.get("cell_number"));
+ cell.setCellValue(threadDelta.getAllocatedCells());
+ allocCells[i] = threadDelta.getAllocatedCells();
+
+ cell = row.createCell(7);
+ cell.setCellStyle(styles.get("cell_number"));
+ cell.setCellValue(threadDelta.getFreeCells());
+ freeCells[i] = threadDelta.getFreeCells();
+
+ cell = row.createCell(8);
+ cell.setCellStyle(styles.get("cell_number"));
+ cell.setCellValue(threadDelta.getFreeSlackSize());
+ slackSpace[i] = threadDelta.getFreeSlackSize();
+
+ cell = row.createCell(9);
+ cell.setCellStyle(styles.get("cell_number"));
+ cell.setCellValue(threadDelta.getStackSize());
+ totalStacks[i] = threadDelta.getStackSize();
+
+ cell = row.createCell(10);
+ cell.setCellStyle(styles.get("cell_number"));
+ cell.setCellValue(threadDelta.getOpenFiles());
+ totalFiles[i] = threadDelta.getOpenFiles();
+
+ cell = row.createCell(11);
+ cell.setCellStyle(styles.get("cell_number"));
+ cell.setCellValue(threadDelta.getPsHandles());
+ totalHandles[i] = threadDelta.getPsHandles();
+
+ i++;
+
+ rowNo++;
+ }
+
+ if(allThreads.size() > 0)
+ {
+
+ HSSFRow totalRow = sheet.createRow(rowNo);
+
+ long totalMaxHeapSize = utils.calculateAndGetTotal(maxHeapSizes);
+ long totalStackSize = utils.calculateAndGetTotal(totalStacks);
+ totalHeapSizeChange = utils.calculateAndGetTotal(heapSizes);
+ totalFreeCellChange = utils.calculateAndGetTotal(freeCells);
+ totalAllocCellChange = utils.calculateAndGetTotal(allocCells);
+ totalFreeSpaceChange = utils.calculateAndGetTotal(freeSpace);
+ totalAllocSpaceChange = utils.calculateAndGetTotal(allocSpace);
+ totalSlackSpaceChange = utils.calculateAndGetTotal(slackSpace);
+ totalFilesChange = utils.calculateAndGetTotal(totalFiles);
+ totalHandlesChange = utils.calculateAndGetTotal(totalHandles);
+
+ HSSFCell cell = totalRow.createCell(2);
+ cell.setCellStyle(styles.get("cell_blue_font_white"));
+ cell.setCellValue(totalMaxHeapSize);
+
+ cell = totalRow.createCell(3);
+ cell.setCellStyle(styles.get("cell_blue_font_white"));
+ cell.setCellValue(totalHeapSizeChange);
+
+ cell = totalRow.createCell(4);
+ cell.setCellStyle(styles.get("cell_blue_font_white"));
+ cell.setCellValue(totalAllocSpaceChange);
+
+ cell = totalRow.createCell(5);
+ cell.setCellStyle(styles.get("cell_blue_font_white"));
+ cell.setCellValue(totalFreeSpaceChange);
+
+ cell = totalRow.createCell(6);
+ cell.setCellStyle(styles.get("cell_blue_font_white"));
+ cell.setCellValue(totalAllocCellChange);
+
+ cell = totalRow.createCell(7);
+ cell.setCellStyle(styles.get("cell_blue_font_white"));
+ cell.setCellValue(totalFreeCellChange);
+
+ cell = totalRow.createCell(8);
+ cell.setCellStyle(styles.get("cell_blue_font_white"));
+ cell.setCellValue(totalSlackSpaceChange);
+
+ cell = totalRow.createCell(9);
+ cell.setCellStyle(styles.get("cell_blue_font_white"));
+ cell.setCellValue(totalStackSize);
+
+ cell = totalRow.createCell(10);
+ cell.setCellStyle(styles.get("cell_blue_font_white"));
+ cell.setCellValue(totalFilesChange);
+
+ cell = totalRow.createCell(11);
+ cell.setCellStyle(styles.get("cell_blue_font_white"));
+ cell.setCellValue(totalHandlesChange);
+ }
+
+ }
+ private void readHeapDataFromAllCycles(Map<String, ArrayList<ThreadData>> map, ParsedData logData)
+ {
+ SWMTLogReaderUtils utils = new SWMTLogReaderUtils();
+ //heapThreads = utils.getAllHeapThreads(logData);
+
+ ArrayList<String> allThreads = utils.getAllThreadNames(logData);
+ for(String heap:allThreads)
+ {
+ //ignoring the data related to MemSpy threads
+ if(heap.startsWith("MemSpy") && heap.endsWith("::MemSpy"))
+ continue;
+
+ ArrayList<ThreadData> heapData = utils.getHeapDataFromAllCycles(heap, logData);
+
+ map.put(heap.toLowerCase(), heapData);
+ }
+ }
+
+ private void readGlobalDataFromAllCycles(Map<String, ArrayList<GlobalDataChunks>> map, ParsedData logData)
+ {
+ SWMTLogReaderUtils utils = new SWMTLogReaderUtils();
+ glodChunks = utils.getAllGlobalChunkNames(logData);
+
+ Collections.sort(glodChunks);
+ for(String glod:glodChunks)
+ {
+ ArrayList<GlobalDataChunks> globData = utils.getGLOBDataFromAllCycles(glod, logData);
+ map.put(glod, globData);
+ }
+ }
+
+ private void readChunkDataFromAllCycles(Map<String, ArrayList<ChunksData>> map, ParsedData logData)
+ {
+ SWMTLogReaderUtils utils = new SWMTLogReaderUtils();
+ nonHeapChunks = utils.getAllNonHeapChunkNames(logData);
+
+ Collections.sort(nonHeapChunks);
+ for(String chunk:nonHeapChunks)
+ {
+ ArrayList<ChunksData> globData = utils.getChunkDataFromAllCycles(chunk, logData);
+ map.put(chunk, globData);
+ }
+ }
+
+ private void getFieldDifferencesForAllThreads(Map<String, ThreadData> map, ParsedData logData)
+ {
+ SWMTLogReaderUtils utils = new SWMTLogReaderUtils();
+
+ ArrayList<String> allThreads = utils.getAllThreadNames(logData);
+
+ for(String s:allThreads)
+ {
+ //ignoring the data related to MemSpy threads
+ if(s.startsWith("MemSpy") && s.endsWith("::MemSpy"))
+ continue;
+
+ ThreadData delta = utils.getChangeinHeapData(s, heapData.get(s.toLowerCase()), logData);
+
+ map.put(s.toLowerCase(), delta);
+ }
+ }
+
+ private void getFieldDifferencesForAllGlodChunks(Map<String, String> map, ParsedData logData)
+ {
+ SWMTLogReaderUtils utils = new SWMTLogReaderUtils();
+
+ ArrayList<String> allGlodChunks = utils.getAllGlobalChunkNames(logData);
+
+ for(String s:allGlodChunks)
+ {
+ long delta = utils.getChangeinGlodChunksData(s, logData);
+
+ map.put(s, delta+"");
+ }
+ }
+
+ private void getFieldDifferencesForAllChunks(Map<String, String> map, ParsedData logData)
+ {
+ SWMTLogReaderUtils utils = new SWMTLogReaderUtils();
+
+ ArrayList<String> allChunks = utils.getAllNonHeapChunkNames(logData);
+
+ for(String s:allChunks)
+ {
+ long delta = utils.getChangeinChunksData(s, logData);
+
+ map.put(s, delta+"");
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/model/SWMTLogReaderUtils.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,1361 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+package com.nokia.s60tools.swmtanalyser.model;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Date;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+
+import com.nokia.s60tools.swmtanalyser.data.ChunksData;
+import com.nokia.s60tools.swmtanalyser.data.CycleData;
+import com.nokia.s60tools.swmtanalyser.data.DiskOverview;
+import com.nokia.s60tools.swmtanalyser.data.GlobalDataChunks;
+import com.nokia.s60tools.swmtanalyser.data.KernelElements;
+import com.nokia.s60tools.swmtanalyser.data.OverviewData;
+import com.nokia.s60tools.swmtanalyser.data.ParsedData;
+import com.nokia.s60tools.swmtanalyser.data.StackData;
+import com.nokia.s60tools.swmtanalyser.data.SystemData;
+import com.nokia.s60tools.swmtanalyser.data.ThreadData;
+import com.nokia.s60tools.swmtanalyser.data.ThreadSegments;
+import com.nokia.s60tools.swmtanalyser.data.WindowGroupEventData;
+import com.nokia.s60tools.swmtanalyser.data.WindowGroups;
+import com.nokia.s60tools.util.debug.DbgUtility;
+
+/**
+ * Helper class which has some util methods.
+ *
+ */
+public class SWMTLogReaderUtils {
+
+ private static final String CHECK_SUM = "Checksum";
+ private static final String VERSION = "Version";
+
+ /**
+ * Construction
+ */
+ public SWMTLogReaderUtils() {
+ }
+
+ /**
+ * Parse all the given text log files and create store the basic data in CycleData object for each file.
+ * @param inputFiles
+ * @param cycles
+ * @param monitor
+ * @return <code>null</code> if everything was OK, error message if otherwise.
+ */
+ public String getCycleDataArrayFromLogFiles(ArrayList<String> inputFiles, ArrayList<CycleData> cycles, IProgressMonitor monitor)
+ {
+ int i = 0;
+ for(String path: inputFiles)
+ {
+ i++;
+ if(monitor != null)
+ {
+ if(monitor.isCanceled())
+ return null;
+ if(i == inputFiles.size()/2)
+ monitor.worked(5);
+ }
+ File aFile = new File(path);
+ ArrayList<String> lines = new ArrayList<String>();
+ int lineNum;
+ try {
+ BufferedReader input = new BufferedReader(new FileReader(aFile));
+ try {
+ String line = null;
+ lineNum = 0;
+ while (( line = input.readLine()) != null){
+
+ //Increment line number
+ lineNum++;
+
+ line = line.trim();
+ //Ignoring newlines and lines which are having only spaces
+ if(line.length() == 0)
+ continue;
+
+ //Line must start with test [MemSpy], if not it is invalid input.
+ if(!line.startsWith("[MemSpy]"))
+ {
+ return "Error in the log ("+path+"): at line " + lineNum + "\nLine does not start with [MemSpy].";
+ }
+
+ if(line.contains("Type"))
+ break;
+
+ //Add valid line to array
+ lines.add(line);
+
+ }
+ }
+ finally {
+ input.close();
+ }
+ }
+ catch (IOException ex){
+ ex.printStackTrace();
+ return ex.getMessage();
+ }
+
+ String cycleNumLine = null;
+ String timeLine = null;
+
+ String romCheckSum = null;
+ String romVersion = null;
+
+ for(String str:lines)
+ {
+ if(str.contains("Cycle number"))
+ cycleNumLine = str;
+ if(str.contains("Time"))
+ timeLine = str;
+
+ if(str.contains("ROM") && str.contains(CHECK_SUM))
+ romCheckSum = str;
+ else if(str.contains("ROM") && str.contains(VERSION))
+ romVersion = str;
+ }
+
+ if(cycleNumLine == null || timeLine == null)
+ return "Error in the Log " + path + "\n The log might not contain Cycle number or Time information. Please check";
+
+ if(romCheckSum == null || romVersion == null)
+ return "Error in the Log " + path + "\n The log might not contain ROM information. Please check";
+
+ //Read cycle number
+ String num = cycleNumLine.substring(cycleNumLine.indexOf("Cycle number") + 12).trim();
+ int cycleNo = Integer.parseInt(num);
+
+ //Read Time
+ String time = timeLine.substring(timeLine.indexOf("Time") + 4).trim();
+
+ String checkSum = romCheckSum.substring(romCheckSum.indexOf(CHECK_SUM) + (CHECK_SUM).length()).trim();
+ String romVer = romVersion.substring(romVersion.indexOf(VERSION) + (VERSION).length()).trim();
+
+ CycleData cycleData = new CycleData();
+ cycleData.setTime(time);
+ cycleData.setCycleNumber(cycleNo);
+ cycleData.setFileName(path);
+ cycleData.setRomCheckSum(checkSum);
+ cycleData.setRomVersion(romVer);
+
+ cycles.add(cycleData);
+ }
+
+ return null;
+ }
+
+ /**
+ * Gets the overview information till the selected log file.
+ * @param allCyclesData CycleData list
+ * @param toCycle Cycle number till where you want to export
+ * @return OverviewData
+ */
+ public OverviewData getOverviewInformationFromCyclesData(CycleData[] allCyclesData, int toCycle)
+ {
+ OverviewData overview = new OverviewData();
+ overview.noOfcycles = toCycle;
+
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd HH:mm:ss");
+ Date aDate=null;
+ Date bDate=null;
+ try {
+ aDate = sdf.parse(allCyclesData[0].getTime());
+ bDate = sdf.parse(allCyclesData[toCycle-1].getTime());
+ } catch (ParseException e) {
+ e.printStackTrace();
+ }
+
+ long t1= aDate.getTime();
+ long t2= bDate.getTime();
+ //time difference in seconds
+ overview.duration = (t2-t1)/1000;
+ //Get date and time in the format like : Jan 7, 2008 1:56:44 PM
+ overview.fromTime = DateFormat.getDateTimeInstance().format(aDate);
+ overview.toTime = DateFormat.getDateTimeInstance().format(bDate);
+ overview.durationString = millisecondToDHMS(overview.duration*1000);
+
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "Cycle Numbers :" + overview.noOfcycles );
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "Time Period :" + overview.fromTime + " to " + overview.toTime );
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "Time Duration :" + overview.duration + " sec (" + overview.durationString + ")");
+
+ return overview;
+ }
+
+ /**
+ * Returns the difference between two time strings
+ * @param startTime
+ * @param endTime
+ * @return difference between startTime and endTime in seconds.
+ */
+ public long getDurationInSeconds(String startTime, String endTime)
+ {
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd HH:mm:ss");
+
+ Date aDate=null;
+ Date bDate=null;
+
+ try {
+ aDate = sdf.parse(startTime);
+ bDate = sdf.parse(endTime);
+ } catch (ParseException e) {
+ return -1;
+ }
+
+ long t1= aDate.getTime();
+ long t2= bDate.getTime();
+ //time difference in seconds
+ return (t2-t1)/1000;
+
+ }
+ /**
+ * converts time (in milliseconds) to
+ * "d, h, min, sec"
+ * @return time in readable format.
+ */
+ public String millisecondToDHMS(long duration) {
+ long ONE_SECOND = 1000;
+ long ONE_MINUTE = ONE_SECOND * 60;
+ long ONE_HOUR = ONE_MINUTE * 60;
+ long ONE_DAY = ONE_HOUR * 24;
+
+ String res = "";
+ long temp = 0;
+ if (duration >= ONE_SECOND) {
+ temp = duration / ONE_DAY;
+ if (temp > 0) {
+ res = temp + " d";
+ duration -= temp * ONE_DAY;
+
+ if (duration >= ONE_MINUTE) {
+ res += ", ";
+ }
+ }
+
+ temp = duration / ONE_HOUR;
+ if (temp > 0) {
+ res += temp + " h";
+ duration -= temp * ONE_HOUR;
+ if (duration >= ONE_MINUTE) {
+ res += ", ";
+ }
+ }
+
+ temp = duration / ONE_MINUTE;
+ if (temp > 0) {
+ res += temp + " min";
+ duration -= temp * ONE_MINUTE;
+
+ if(duration >= ONE_SECOND) {
+ res += ", ";
+ }
+ }
+
+ temp = duration / ONE_SECOND;
+ if (temp > 0) {
+ res += temp + " sec";
+ }
+ return res;
+ }
+ else {
+ return "0 sec";
+ }
+ }
+
+ /**
+ * This will check whether the CycleData objects are in concecutive order and
+ * if not, this will return the reordered list.
+ * @param allCyclesData
+ * @return Reordered list, if any cycle data is missing null will be returned
+ */
+ public ArrayList<CycleData> checkCycleOrder(ArrayList<CycleData> allCyclesData)
+ {
+ ArrayList<CycleData> orderedCycles = new ArrayList<CycleData>();
+
+ /*for(int i=0; i<allCyclesData.size(); i++) {
+ for (CycleData cycledata : allCyclesData) {
+ if(cycledata.getCycleNumber() == i+1)
+ {
+ orderedCycles.add(cycledata);
+ break;
+ }
+ }
+ if(orderedCycles.size() != i+1)
+ return null;
+ }*/
+ CycleData[] before = allCyclesData.toArray(new CycleData[0]);
+ Arrays.sort(before);
+ if(before!=null && before.length>0 && before[0].getCycleNumber() == 1)
+ {
+ int i= 1;
+ for (CycleData data: before) {
+ data.setCycleNumber(i);
+ orderedCycles.add(data);
+ i++;
+ }
+ return orderedCycles;
+ }
+ else
+ return null;
+ }
+
+ /**
+ * This method fetches list of all newly created disk names from all the
+ * cycles. If only one cycle is selected it fetches list of new and updated disk names.
+ * @param data specifies list of CycleData to be parsed
+ * @return list of disknames from all the cycles
+ */
+ public ArrayList<String> getAllDiskNames(ParsedData data)
+ {
+ if(data == null || data.getNumberOfCycles() ==0)
+ return null;
+
+ CycleData [] parsed_cycles = data.getLogData();
+
+ CycleData firstCycle = parsed_cycles[0];
+ firstCycle.parseDisksList();
+ ArrayList<String> totalDisks = new ArrayList<String>(firstCycle.getNewlyCreatedDisks());
+
+ if(parsed_cycles.length == 1)
+ {
+ ArrayList<String> updatedDisks = firstCycle.getUpdatedDisks();
+
+ for(String disk:updatedDisks)
+ {
+ if(!totalDisks.contains(disk))
+ totalDisks.add(disk);
+ }
+
+ return totalDisks;
+ }
+ for(int i=1; i<parsed_cycles.length;i++)
+ {
+ CycleData cycle = parsed_cycles[i];
+ cycle.parseDisksList();
+ ArrayList<String> newDisks = cycle.getNewlyCreatedDisks();
+
+ for(String disk:newDisks)
+ {
+ if(!totalDisks.contains(disk))
+ totalDisks.add(disk);
+ }
+ }
+
+ return totalDisks;
+ }
+
+ /**
+ * This method fetches Used Memory and Size data for a given disk from given list of cycledata.
+ * @param diskName name of the disk, whose used memory and size must be fetched.
+ * @param data list of cycledata which needs to be parsed.
+ * @return list of used memory and size values for all cycles.
+ */
+ public ArrayList<DiskOverview> getUsedMemoryAndSizesForDisk(String diskName, ParsedData parsedData)
+ {
+
+ ArrayList<DiskOverview> diskTotalData = new ArrayList<DiskOverview>();
+ DiskOverview prevData = new DiskOverview();
+
+ CycleData [] cycles = parsedData.getLogData();
+
+ for(CycleData cycle:cycles)
+ {
+ DiskOverview ov = null;
+
+ if(!cycle.getDeletedDisks().contains(diskName)){
+ DiskOverview tmp = cycle.getDiskUsedAndFreeSize(diskName);
+
+ if(tmp != null)
+ ov = new DiskOverview(tmp);
+ else
+ {
+ ov = new DiskOverview(prevData);
+
+ if(prevData.getStatus() == CycleData.New)
+ ov.setStatus(CycleData.Alive);
+ }
+
+ }
+ else
+ ov = new DiskOverview();
+
+ diskTotalData.add(ov);
+ prevData = ov;
+ }
+
+ /*for(int i=0;i<diskTotalData.size();i++)
+ {
+ System.out.print("Variation for DISK " + diskName + " in Cycle " + i);
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "USED: " + diskTotalData.get(i).getUsedSize() + " FREE: " + diskTotalData.get(i).getFreeSize());
+ }*/
+
+ return diskTotalData;
+ }
+
+ /**
+ * This method fetches System Used Memory and Size for each cycle from given list of cycledata.
+ * @param data list of cycledata which needs to be parsed.
+ * @return list of system used memory and size values for all cycles.
+ */
+ public ArrayList<SystemData> getSystemDataFromAllCycles(ParsedData parsedData)
+ {
+
+ ArrayList<SystemData> systemData = new ArrayList<SystemData>();
+ SystemData prevData = new SystemData();
+
+ CycleData [] cycles = parsedData.getLogData();
+
+ for(CycleData cycle:cycles)
+ {
+ SystemData ov = new SystemData(prevData);
+
+ long freeMem = cycle.getFreeMemory();
+ long totalMem = cycle.getTotalMemory();
+
+ if(freeMem != -1)
+ {
+ ov.setFreeMemory(freeMem);
+ }
+ if(totalMem != -1)
+ ov.setTotalMemory(totalMem);
+
+ systemData.add(ov);
+ prevData = ov;
+ }
+
+ /*for(int i=0;i<diskTotalData.size();i++)
+ {
+ System.out.print("Variation for DISK " + diskName + " in Cycle " + i);
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "USED: " + diskTotalData.get(i).getUsedSize() + " FREE: " + diskTotalData.get(i).getFreeSize());
+ }*/
+
+ return systemData;
+ }
+ /**
+ * The method creates a union list of newly created threads in each cycle.
+ * @param data list of Cycle data structures to be parsed
+ * @return union list of thread names from all the cycles.
+ */
+ public ArrayList<String> getAllThreadNames(ParsedData data)
+ {
+ if(data == null || data.getNumberOfCycles() == 0)
+ return null;
+
+ CycleData[] parsed_cycles = data.getLogData();
+ CycleData firstCycle = parsed_cycles[0];
+ firstCycle.parseAllThreads();
+ ArrayList<String> totalThreads = new ArrayList<String>(firstCycle.getNewlyCreatedThreads());
+
+ if(parsed_cycles.length == 1)
+ {
+ ArrayList<String> updatedThreads = firstCycle.getUpdatedThreads();
+
+ for(String thread:updatedThreads)
+ {
+ if(!totalThreads.contains(thread))
+ totalThreads.add(thread);
+ }
+
+ ArrayList<String> threadsFromAllViews = getThreadsFromAllViews(firstCycle);
+
+ for(String thread:threadsFromAllViews)
+ {
+ if(!totalThreads.contains(thread))
+ totalThreads.add(thread);
+ }
+
+ return totalThreads;
+ }
+ for(int i=1; i<parsed_cycles.length;i++)
+ {
+ CycleData cycle = parsed_cycles[i];
+ cycle.parseAllThreads();
+ ArrayList<String> newThreads = cycle.getNewlyCreatedThreads();
+
+ for(String thread:newThreads)
+ {
+ if(!totalThreads.contains(thread))
+ totalThreads.add(thread);
+ }
+ }
+
+ return totalThreads;
+ }
+
+ /**
+ * This method fetches list of all heap thread names from all the cycles.
+ * If only one cycle is selected it fetches list of new and updated heap thread names.
+ * @param data specifies list of CycleData to be parsed
+ * @return list of those thread names which contain heap information, in one or many cycles.
+ */
+ public ArrayList<String> getAllHeapThreads(ParsedData parsedData)
+ {
+
+ CycleData [] logData = parsedData.getLogData();
+ CycleData firstCycle = logData[0];
+
+ firstCycle.parseAllHeaps();
+ ArrayList<String> totalHeaps = new ArrayList<String>(firstCycle.getNewHeapThreads());
+
+ if(logData.length == 1)
+ {
+ ArrayList<String> updatedHeaps = firstCycle.getAliveHeapThreads();
+
+ for(String thread:updatedHeaps)
+ {
+ if(!totalHeaps.contains(thread))
+ totalHeaps.add(thread);
+ }
+
+ return totalHeaps;
+ }
+ for(int i=1; i<logData.length;i++)
+ {
+ CycleData cycle = logData[i];
+
+ cycle.parseAllHeaps();
+ ArrayList<String> newHeaps = cycle.getNewHeapThreads();
+
+ for(String thread:newHeaps)
+ {
+ if(!totalHeaps.contains(thread))
+ totalHeaps.add(thread);
+ }
+ }
+
+ return totalHeaps;
+ }
+
+ /**
+ * This method fetches all the data for a given thread from given list of cycledata.
+ * @param threadName name of the thread whose data is needed.
+ * @param cycles list of cycledata structures to be parsed for the thread data.
+ * @return list of ThreadData structures. Each structure holds values of given thread fields in each cycle.
+ */
+ public ArrayList<ThreadData> getHeapDataFromAllCycles(String threadName, ParsedData parsedData)
+ {
+ ArrayList<ThreadData> allData = new ArrayList<ThreadData>();
+
+ ThreadData prevData = new ThreadData(threadName);
+ CycleData[] cycles = parsedData.getLogData();
+
+ for(CycleData cycle:cycles)
+ {
+ ThreadData currentData = null;
+
+ cycle.parseAllThreads();
+
+ //Fetch the data for this thread in this cycle.
+ //If no data in this cycle, copy the data from the previous cycle.
+
+ ThreadData tmp = cycle.getHeapData(threadName);
+
+ if(tmp != null)
+ currentData = tmp;
+ else{
+ currentData = new ThreadData(prevData);
+ if(prevData.getStatus() == CycleData.New)
+ currentData.setStatus(CycleData.Alive);
+ }
+
+ StackData stakData = cycle.getStackData(threadName);
+
+ if(stakData != null)
+ {
+ currentData.setStackStatus(stakData.getStatus());
+ currentData.setStackSize(stakData.getSize());
+ }
+ else
+ {
+ if(prevData.getStackStatus() == CycleData.New)
+ currentData.setStackStatus(CycleData.Alive);
+ else
+ currentData.setStackStatus(prevData.getStackStatus());
+
+ currentData.setStackSize(prevData.getStackSize());
+ }
+
+ int openFilesCnt = cycle.getNewOpenFiles(threadName);
+ int closedFilesCnt = cycle.getDeletedFiles(threadName);
+
+ int newPSHandlesCnt = cycle.getNewPSHandles(threadName);
+ int deletedPSHandlesCnt = cycle.getDeletedPSHandles(threadName);
+
+ if(cycles.length == 1)
+ {
+ int updatedFiles = cycle.getUpdatedFiles(threadName);
+ int updatedPSHandles = cycle.getUpdatedPSHandles(threadName);
+
+ currentData.setOpenFiles(openFilesCnt + updatedFiles);
+ currentData.setPsHandles(newPSHandlesCnt + updatedPSHandles);
+ }
+
+ else
+ {
+ openFilesCnt += prevData.getOpenFiles();
+
+ openFilesCnt -= closedFilesCnt;
+ currentData.setOpenFiles(openFilesCnt);
+
+ newPSHandlesCnt += prevData.getPsHandles();
+ newPSHandlesCnt -= deletedPSHandlesCnt;
+
+ currentData.setPsHandles(newPSHandlesCnt);
+ }
+
+ if(cycle.getDeletedThreads().contains(threadName))
+ currentData.setKernelHandleDeleted(true);
+
+ currentData.setCycleNumber(cycle.getCycleNumber());
+ allData.add(currentData);
+ prevData = currentData;
+ }
+
+ return allData;
+ }
+
+ /**
+ * Returns the array of global data chunks list of given chunk
+ * from all the log files data.
+ * @param chunkName
+ * @param cycles
+ * @return List of {@link GlobalDataChunks} with given chunk name
+ */
+ public ArrayList<GlobalDataChunks> getGLOBDataFromAllCycles(String chunkName, ParsedData logData)
+ {
+
+ ArrayList<GlobalDataChunks> allData = new ArrayList<GlobalDataChunks>();
+
+ GlobalDataChunks prevData = new GlobalDataChunks();
+
+ CycleData [] logCycles = logData.getLogData();
+
+ for(CycleData cycle:logCycles)
+ {
+ GlobalDataChunks currentData = null;
+ GlobalDataChunks tmp = cycle.getGlobalChunkDataFor(chunkName);
+ if(tmp != null)
+ currentData = tmp;
+ else{
+ currentData = new GlobalDataChunks(prevData);
+
+ if(prevData.getAttrib() == CycleData.New)
+ currentData.setAttrib(CycleData.Alive);
+ }
+
+ if(cycle.getDeletedChunkNames().contains(chunkName))
+ currentData.setKernelHandleDeleted(true);
+
+ allData.add(currentData);
+ prevData = currentData;
+ }
+
+ return allData;
+ }
+
+ /**
+ * Returns the array of chunks data list of given chunk
+ * from all the log files data.
+ * @param chunkName
+ * @param cycles
+ * @return list of {@link ChunksData} with given name
+ */
+ public ArrayList<ChunksData> getChunkDataFromAllCycles(String chunkName, ParsedData logData)
+ {
+ ArrayList<ChunksData> allData = new ArrayList<ChunksData>();
+
+ ChunksData prevData = new ChunksData();
+
+ CycleData[] cycles = logData.getLogData();
+ for(CycleData cycle:cycles)
+ {
+ ChunksData currentData = null;
+ ChunksData tmp = cycle.getChunkDataFor(chunkName);
+ if(tmp != null)
+ currentData = tmp;
+ else{
+ currentData = new ChunksData(prevData);
+ if(prevData.getAttrib() == CycleData.New)
+ currentData.setAttrib(CycleData.Alive);
+ }
+
+ if(cycle.getDeletedChunkNames().contains(chunkName))
+ currentData.setKernelHandleDeleted(true);
+
+ allData.add(currentData);
+ prevData = currentData;
+ }
+
+ return allData;
+ }
+
+ /**
+ * This method returns the array of kernel elements data from all the given log files data.
+ * @param parsedData
+ * @return array of kernel elements
+ */
+ public ArrayList<KernelElements> getKerenelElemsFromAllCycles(ParsedData parsedData)
+ {
+ ArrayList<KernelElements> allData = new ArrayList<KernelElements>();
+ KernelElements prevData = new KernelElements();
+
+ CycleData [] cycles = parsedData.getLogData();
+ for(CycleData cycle:cycles)
+ {
+ KernelElements currentData = cycle.getAllOpenKernelElements();
+
+ int timers = currentData.getNumberOfTimers();
+ int semaphores = currentData.getNumberOfSemaphores();
+ int servers = currentData.getNumberOfServers();
+ int sessions = currentData.getNumberOfSessions();
+ int processes = currentData.getNumberOfProcesses();
+ int threads = currentData.getNumberOfThreads();
+ int chunks = currentData.getNumberOfChunks();
+ int msgQueues = currentData.getNumberOfMsgQueues();
+
+
+ if(parsedData.getNumberOfCycles() != 1)
+ {
+
+ timers += prevData.getNumberOfTimers();
+ semaphores += prevData.getNumberOfSemaphores();
+ sessions += prevData.getNumberOfSessions();
+ servers += prevData.getNumberOfServers();
+ processes += prevData.getNumberOfProcesses();
+ threads += prevData.getNumberOfThreads();
+ chunks += prevData.getNumberOfChunks();
+ msgQueues += prevData.getNumberOfMsgQueues();
+
+ //newTimers -= closedTimers;
+ currentData.setNumberOfTimers(timers);
+ currentData.setNumberOfSemaphores(semaphores);
+ currentData.setNumberOfProcesses(processes);
+ currentData.setNumberOfSessions(sessions);
+ currentData.setNumberOfServers(servers);
+ currentData.setNumberOfThreads(threads);
+ currentData.setNumberOfChunks(chunks);
+ currentData.setNumberOfMsgQueues(msgQueues);
+
+ }
+ allData.add(currentData);
+ prevData = currentData;
+
+ }
+ return allData;
+ }
+ /**
+ *
+ * @param threadName name of thread whose status is needed.
+ * @param data list of cycledata to be parsed
+ * @return the recent status of the thread from given cycles.
+ */
+ public int getThreadStatusFromAllCycles(String threadName, ParsedData parsedData)
+ {
+ int status = -1;
+
+ CycleData [] cycles = parsedData.getLogData();
+
+ for(CycleData cycle:cycles)
+ {
+ cycle.parseAllThreads();
+ if(cycle.getNewlyCreatedThreads().contains(threadName))
+ status = CycleData.New;
+ else if(cycle.getUpdatedThreads().contains(threadName))
+ status = CycleData.Alive;
+ else if(cycle.getDeletedThreads().contains(threadName))
+ status = CycleData.Deleted;
+
+ }
+ return status;
+ }
+
+ /**
+ *
+ * @param threadName name of thread whose heap status is needed.
+ * @param data list of cycledata to be parsed
+ * @return the recent status of the given thread's heap.
+ */
+ public int getHeapStatusFromAllCycles(String threadName, ParsedData parsedData)
+ {
+ int status = 0;
+ CycleData [] cycles = parsedData.getLogData();
+
+ for(CycleData cycle:cycles)
+ {
+ cycle.parseAllHeaps();
+
+ ArrayList<String> newHeapThreads = convertAllStringsToLowerCase(cycle.getNewHeapThreads());
+ ArrayList<String> aliveHeaps = convertAllStringsToLowerCase(cycle.getAliveHeapThreads());
+ ArrayList<String> deletedHeaps = convertAllStringsToLowerCase(cycle.getDeletedHeapThreads());
+
+ if(newHeapThreads.contains(threadName.toLowerCase()) ||
+ aliveHeaps.contains(threadName.toLowerCase()))
+ status = 1;
+ else if(deletedHeaps.contains(threadName.toLowerCase()))
+ status = 0;
+ }
+
+ return status;
+ }
+
+ /**
+ * Get the stack status of a given thread name
+ * @param threadName name of thread whose heap status is needed.
+ * @param data list of cycledata to be parsed
+ * @return the recent status of the given thread's stack.
+ */
+ public int getStackStatusFromAllCycles(String threadName, ParsedData parsedData)
+ {
+ int status = 0;
+ CycleData[] cycles = parsedData.getLogData();
+
+ for(CycleData cycle:cycles)
+ {
+ ArrayList<String> newStacks = convertAllStringsToLowerCase(cycle.getNewStackThreads());
+ ArrayList<String> aliveStacks = convertAllStringsToLowerCase(cycle.getAliveStackThreads());
+ ArrayList<String> deletedStacks = convertAllStringsToLowerCase(cycle.getDeletedStackThreads());
+
+ if(newStacks.contains(threadName.toLowerCase()) ||
+ aliveStacks.contains(threadName.toLowerCase()))
+ status = 1;
+ else if(deletedStacks.contains(threadName.toLowerCase()))
+ status = 0;
+ }
+
+ return status;
+ }
+
+ /**
+ * Get the delta data for the given threadname from all the cycles.
+ * @param threadName name of the thread
+ * @param logData list of cycledata to be parsed.
+ * @return the ThreadData structure which holds the differences for various
+ * fields in the lastCycle and the cycle in which the thread has actually started.
+ */
+ public ThreadData getChangeinHeapData(String threadName, ArrayList<ThreadData> allCyclesData, ParsedData logData)
+ {
+ ThreadData heapDataChange = new ThreadData(threadName);
+
+ //If the heap for this thread is already deleted all the
+ //heap related fields will be set to 0.
+ if(getHeapStatusFromAllCycles(threadName, logData) == 0)
+ {
+ //Display zeros for all heap fields
+ heapDataChange.setMaxHeapSize(0);
+ heapDataChange.setHeapChunkSize(0);
+ heapDataChange.setHeapAllocatedSpace(0);
+ heapDataChange.setHeapFreeSpace(0);
+ heapDataChange.setAllocatedCells(0);
+ heapDataChange.setFreeCells(0);
+ heapDataChange.setFreeSlackSize(0);
+ heapDataChange.setLargestAllocCellSize(0);
+ heapDataChange.setLargestFreeCellSize(0);
+
+ }
+ else{
+
+ ThreadData lastHeapData = allCyclesData.get(logData.getNumberOfCycles()-1);
+
+ //Get the heap values from the cycle in which the
+ //thread is started.
+ ThreadData firstHeapData = null;
+
+ for(int i=allCyclesData.size()-2; i>=0; i--)
+ {
+ ThreadData data = allCyclesData.get(i);
+ if(data.getStatus() != CycleData.Deleted){
+ firstHeapData = data;
+ }
+ else
+ break;
+ }
+
+ if(firstHeapData != null)
+ {
+ heapDataChange.setMaxHeapSize(firstHeapData.getMaxHeapSize());
+ long changeInHeapSize = lastHeapData.getHeapChunkSize() - firstHeapData.getHeapChunkSize();
+ long changeInAllocSpace = lastHeapData.getHeapAllocatedSpace() - firstHeapData.getHeapAllocatedSpace();
+ long changeInFreeSpace = lastHeapData.getHeapFreeSpace() - firstHeapData.getHeapFreeSpace();
+ long changeInAllocCells = lastHeapData.getAllocatedCells() - firstHeapData.getAllocatedCells();
+ long changeInFreeCells = lastHeapData.getFreeCells() - firstHeapData.getFreeCells();
+ long changeInSlackSize = lastHeapData.getFreeSlackSize() - firstHeapData.getFreeSlackSize();
+ long changeInLargestAllocCell = lastHeapData.getLargestAllocCellSize() - firstHeapData.getLargestAllocCellSize();
+ long changeInLargestFreeCell = lastHeapData.getLargestFreeCellSize() - firstHeapData.getLargestFreeCellSize();
+
+ heapDataChange.setHeapChunkSize(changeInHeapSize);
+ heapDataChange.setHeapAllocatedSpace(changeInAllocSpace);
+ heapDataChange.setHeapFreeSpace(changeInFreeSpace);
+ heapDataChange.setAllocatedCells(changeInAllocCells);
+ heapDataChange.setFreeCells(changeInFreeCells);
+ heapDataChange.setFreeSlackSize(changeInSlackSize);
+ heapDataChange.setLargestAllocCellSize(changeInLargestAllocCell);
+ heapDataChange.setLargestFreeCellSize(changeInLargestFreeCell);
+
+ }
+ else
+ {
+ heapDataChange.setMaxHeapSize(lastHeapData.getMaxHeapSize());
+ heapDataChange.setHeapChunkSize(lastHeapData.getHeapChunkSize());
+ heapDataChange.setHeapAllocatedSpace(lastHeapData.getHeapAllocatedSpace());
+ heapDataChange.setHeapFreeSpace(lastHeapData.getHeapFreeSpace());
+ heapDataChange.setAllocatedCells(lastHeapData.getAllocatedCells());
+ heapDataChange.setFreeCells(lastHeapData.getFreeCells());
+ heapDataChange.setFreeSlackSize(lastHeapData.getFreeSlackSize());
+ heapDataChange.setLargestAllocCellSize(lastHeapData.getLargestAllocCellSize());
+ heapDataChange.setLargestFreeCellSize(lastHeapData.getLargestFreeCellSize());
+ }
+ }
+
+ ThreadData lastHeapData = allCyclesData.get(logData.getNumberOfCycles()-1);
+
+ if(getStackStatusFromAllCycles(threadName, logData) == 0)
+ {
+ heapDataChange.setStackSize(0);
+ }
+ else
+ {
+ heapDataChange.setStackSize(lastHeapData.getStackSize());
+ }
+
+ heapDataChange.setOpenFiles(lastHeapData.getOpenFiles());
+
+ if(lastHeapData.getPsHandles() == -1)
+ heapDataChange.setPsHandles(0);
+ else
+ heapDataChange.setPsHandles(lastHeapData.getPsHandles());
+
+ return heapDataChange;
+ }
+
+ /**
+ * Returns the start and end cycle numbers for the threads having multiple instances
+ * @param threadData list
+ * @return start and end cycle numbers
+ */
+ public ThreadSegments [] getHeapSegments(ArrayList<ThreadData> threadData)
+ {
+ ArrayList<ThreadSegments> thSegments = new ArrayList<ThreadSegments>();
+ boolean is_thread_started = false;
+ ThreadSegments segment = null;
+
+ for(ThreadData data: threadData)
+ {
+ if(data.getStatus() == CycleData.New && !is_thread_started)
+ {
+ segment = new ThreadSegments();
+ is_thread_started = true;
+ segment.setStartCycle(data.getCycleNumber());
+ }
+ if((data.getStatus() == CycleData.Deleted || data.getCycleNumber() == threadData.size()) && is_thread_started)
+ {
+ is_thread_started = false;
+ if(segment != null){
+ segment.setEndCycle(data.getCycleNumber());
+ thSegments.add(segment);
+ }
+ }
+ }
+ return thSegments.toArray(new ThreadSegments[0]);
+ }
+ /**
+ * Returns the delta value for the given global chunk.
+ * @param chunkName
+ * @param logData
+ * @return delta value for the given global chunk
+ */
+ public long getChangeinGlodChunksData(String chunkName, ParsedData logData)
+ {
+
+ ArrayList<GlobalDataChunks> heapData = getGLOBDataFromAllCycles(chunkName, logData);
+
+
+ if(heapData.get(heapData.size()-1).getAttrib() == CycleData.Deleted)
+ return 0;
+ else
+ {
+ long lastValue = heapData.get(heapData.size()-1).getSize();
+ long firstValue = 0;
+ for(GlobalDataChunks data: heapData)
+ {
+ if(data.getSize() != -1)
+ {
+ firstValue = data.getSize();
+ break;
+ }
+ }
+ return lastValue - firstValue;
+ }
+ }
+
+ /**
+ * Returns the delta value for the given chunk.
+ * @param chunkName
+ * @param logData
+ * @return delta value for the given chunk
+ */
+ public long getChangeinChunksData(String chunkName, ParsedData logData)
+ {
+ ArrayList<ChunksData> heapData = getChunkDataFromAllCycles(chunkName, logData);
+
+ if(heapData.get(heapData.size()-1).getAttrib() == CycleData.Deleted)
+ return 0;
+ else
+ {
+ long lastValue = heapData.get(heapData.size()-1).getSize();
+ long firstValue = 0;
+ for(ChunksData data: heapData)
+ {
+ if(data.getSize() != -1)
+ {
+ firstValue = data.getSize();
+ break;
+ }
+ }
+ return lastValue - firstValue;
+ }
+ }
+
+ /**
+ * Return sum of the given delta values.
+ * @param deltaValues
+ * @return the sum of all given values
+ */
+ public long calculateAndGetTotal(long[] deltaValues)
+ {
+ long total = 0;
+
+ for(long value:deltaValues)
+ {
+ total = total + value;
+ }
+ return total;
+ }
+
+ /**
+ * Returns time intervals for all the given cycles.
+ * @param parsedData
+ * @return intervals
+ */
+ public int [] getTimeIntervalsFromLogData(ParsedData parsedData)
+ {
+ CycleData [] cyclesData = parsedData.getLogData();
+
+ if(cyclesData == null)
+ return null;
+
+ int [] timeIntervals = new int[cyclesData.length];
+
+ timeIntervals[0] = 0;
+
+ for(int i=1; i<timeIntervals.length; i++)
+ timeIntervals[i] = (int)getDurationInSeconds(cyclesData[i-1].getTime(), cyclesData[i].getTime()) + timeIntervals[i-1];
+
+ return timeIntervals;
+ }
+ /**
+ *
+ * @param valuesArr
+ * @return the difference between the last value and the first value, if the given set does not contain -1.
+ * If the set contains -1, the value after that would be treated as the first value.
+ */
+ public long calculateDeltaForGivenSet(long [] valuesArr)
+ {
+ int length = valuesArr.length;
+
+ long lastValue = valuesArr[length-1];
+ long firstValue = -1;
+
+ for(int i = length-2; i>=0;i--)
+ {
+ if(valuesArr[i] != -1)
+ firstValue = valuesArr[i];
+ else
+ break;
+ }
+
+ if(lastValue != -1)
+ {
+ if(firstValue != -1)
+ return lastValue - firstValue;
+ else
+ return lastValue;
+ }
+ else
+ return 0;
+ }
+
+ /**
+ * Returns unique list of global chunk names from all the log files.
+ * @see GlobalDataChunks#getChunkName()
+ * @param data
+ * @return list about global chunk names
+ */
+ public ArrayList<String> getAllGlobalChunkNames(ParsedData data)
+ {
+ if(data == null || data.getNumberOfCycles() == 0)
+ return null;
+
+ CycleData [] parsed_cycles = data.getLogData();
+ ArrayList<String> globalChunkNames = new ArrayList<String>();
+
+ for(CycleData cycle: parsed_cycles)
+ {
+ if(cycle.getGlobalDataChunksList()!=null)
+ for(GlobalDataChunks chunkName:cycle.getGlobalDataChunksList())
+ {
+ if(!globalChunkNames.contains(chunkName.getChunkName()))
+ globalChunkNames.add(chunkName.getChunkName());
+ }
+ }
+
+ return globalChunkNames;
+ }
+
+ /**
+ * Returns unique list of non heap chunk names from all the log files.
+ * @see ChunksData#getChunkName()
+ * @param data
+ * @return List of non heap chunk names
+ */
+ public ArrayList<String> getAllNonHeapChunkNames(ParsedData data)
+ {
+ if(data == null || data.getNumberOfCycles() == 0)
+ return null;
+
+ ArrayList<String> chunkNames = new ArrayList<String>();
+ CycleData [] parsed_cycles = data.getLogData();
+
+ for(CycleData cycle: parsed_cycles)
+ {
+ if(cycle.getChunksList()!=null)
+ for(ChunksData chunkName:cycle.getChunksList())
+ {
+ if(!chunkNames.contains(chunkName.getChunkName()))
+ chunkNames.add(chunkName.getChunkName());
+ }
+ }
+
+ return chunkNames;
+ }
+
+ /**
+ * This method returns unique list of window group names from all the log files.
+ * @param data
+ * @return window group names
+ */
+ public ArrayList<String> getWindowGroupNames(ParsedData data)
+ {
+ if(data == null || data.getNumberOfCycles() == 0)
+ return null;
+
+ ArrayList<String> wndgNames = new ArrayList<String>();
+ CycleData [] parsed_cycles = data.getLogData();
+
+ for(CycleData cycle: parsed_cycles)
+ {
+ for(WindowGroups name:cycle.getWindowGroupsData())
+ {
+ if(!wndgNames.contains(name.getName()))
+ wndgNames.add(name.getName());
+ }
+ }
+
+ return wndgNames;
+ }
+
+ /**
+ * Get {@link WindowGroupEventData} for given window group name
+ * @param windowGroupName
+ * @param logData
+ * @return list of window group data
+ */
+ public ArrayList<WindowGroupEventData> getAllWindowGroupEvents(String windowGroupName, ParsedData logData)
+ {
+ if(logData == null || logData.getNumberOfCycles() == 0)
+ return null;
+
+ CycleData [] parsed_cycles = logData.getLogData();
+
+ ArrayList<WindowGroupEventData> eventsData = new ArrayList<WindowGroupEventData>();
+
+ WindowGroupEventData prevData = null;
+
+ for(CycleData cycle:parsed_cycles)
+ {
+ WindowGroupEventData currentData;
+
+ if(prevData == null)
+ currentData = new WindowGroupEventData();
+ else
+ currentData = new WindowGroupEventData(prevData);
+
+ for(WindowGroups grp: cycle.getWindowGroupsData())
+ {
+ if(grp.getName().equalsIgnoreCase(windowGroupName))
+ {
+ if(grp.getStatus() == CycleData.New || grp.getStatus() == CycleData.Alive)
+ currentData.incrementEventCount(grp.getEvent());
+ else if(grp.getStatus() == CycleData.Deleted)
+ currentData.decrementEventCount(grp.getEvent());
+ }
+ }
+
+ prevData = currentData;
+ eventsData.add(currentData);
+ }
+
+ return eventsData;
+ }
+ /**
+ * Get all threads names from data
+ * @param data
+ * @return List of thread names.
+ */
+ public ArrayList<String> getThreadsFromAllViews(CycleData data)
+ {
+ ArrayList<String> threads = new ArrayList<String>();
+
+ data.parseAllHeaps();
+
+ for(String threadName:data.getNewHeapThreads())
+ {
+ if(!threads.contains(threadName))
+ threads.add(threadName);
+ }
+
+ for(String threadName:data.getAliveHeapThreads())
+ {
+ if(!threads.contains(threadName))
+ threads.add(threadName);
+ }
+
+ for(String threadName:data.getNewStackThreads())
+ {
+ if(!threads.contains(threadName))
+ threads.add(threadName);
+ }
+
+ for(String threadName:data.getAliveStackThreads())
+ {
+ if(!threads.contains(threadName))
+ threads.add(threadName);
+ }
+
+ for(String threadName:data.getFileThreads())
+ {
+ if(!threads.contains(threadName))
+ threads.add(threadName);
+ }
+
+ for(String threadName:data.getHPASThreads())
+ {
+ if(threadName.length() !=0 && !threads.contains(threadName))
+ threads.add(threadName);
+ }
+ return threads;
+ }
+
+ /**
+ * Gets the total for given delta values.
+ * @param deltaValues
+ * @return total delta values counted together
+ */
+ public long getTotal(ArrayList<String> deltaValues)
+ {
+ long total = 0;
+ for(String value:deltaValues)
+ {
+ if(value != "N/A")
+ total = total + Long.parseLong(value);
+ }
+ return total;
+ }
+
+ /**
+ * Converts all given strings to lower case.
+ * @param inputList
+ * @return
+ */
+ private ArrayList<String> convertAllStringsToLowerCase(ArrayList<String> inputList)
+ {
+ ArrayList<String> outputList = new ArrayList<String>();
+ if(inputList != null)
+ {
+ for(int i=0;i<inputList.size();i++)
+ outputList.add(inputList.get(i).toLowerCase());
+
+ }
+ return outputList;
+ }
+
+ /**
+ * Checks whether the ROM version and ROM Checksum of all log files are same or not.
+ * @param cycleData
+ * @return <code>true</code> if ROM Checksum is OK <code>false</code> otherwise.
+ */
+ public boolean checkRomInfo(ArrayList<CycleData> cycleData)
+ {
+ boolean result = true;
+
+ for(int i = 0; i<=cycleData.size()-2; i++)
+ {
+ String currentCheckSum = cycleData.get(i).getRomCheckSum();
+ String nextCheckSum = cycleData.get(i+1).getRomCheckSum();
+
+ String currentVersion = cycleData.get(i).getRomVersion();
+ String nextVersion = cycleData.get(i+1).getRomVersion();
+
+ if((!currentCheckSum.equals(nextCheckSum)) || (!currentVersion.equals(nextVersion)))
+ {
+ result = false;
+ break;
+ }
+ }
+
+ return result;
+ }
+
+ /**
+ * Check timestamps from consecutive cycles
+ * if log n+1 time stamp is lesser than log n then return log n+1 cycle number. else return 0
+ * @param allcycleData
+ * @return Returns cycle number or 0
+ */
+ public int checkTimeStamp(ArrayList<CycleData> allcycleData){
+
+ for(int i=1;i<allcycleData.size();i++){
+ String currentTime = allcycleData.get(i).getTime();
+ String prevTime = allcycleData.get(i-1).getTime();
+ long timeDiff = getDurationInSeconds(prevTime, currentTime);
+ if(timeDiff < 0){
+ // if time stamp of log n+1 is lesser than log n
+ return allcycleData.get(i).getCycleNumber();
+ }
+
+ }
+ return 0;// if time stamp of log n+1 is greater than log n
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/model/SwmtParser.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,523 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+package com.nokia.s60tools.swmtanalyser.model;
+
+import java.io.BufferedReader;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
+
+import com.nokia.s60tools.swmtanalyser.data.ChunksData;
+import com.nokia.s60tools.swmtanalyser.data.CycleData;
+import com.nokia.s60tools.swmtanalyser.data.DiskData;
+import com.nokia.s60tools.swmtanalyser.data.FilesData;
+import com.nokia.s60tools.swmtanalyser.data.GlobalDataChunks;
+import com.nokia.s60tools.swmtanalyser.data.HeapData;
+import com.nokia.s60tools.swmtanalyser.data.KernelHandles;
+import com.nokia.s60tools.swmtanalyser.data.PSHandlesData;
+import com.nokia.s60tools.swmtanalyser.data.StackData;
+import com.nokia.s60tools.swmtanalyser.data.SystemData;
+import com.nokia.s60tools.swmtanalyser.data.WindowGroups;
+import com.nokia.s60tools.swmtanalyser.exception.SwmtFormatException;
+
+/**
+ * Reads the text log files and stores all the data in CycleData objects.
+ *
+ */
+public class SwmtParser {
+
+ private static BufferedReader reader = null;
+
+ /**
+ * @param path specifes the filesystem path of swmt log to be parsed
+ * @param cycleData is the data structure, wherein the parsed data gets stored.
+ * @return error messages during parsing. In case of successful parsing, null will be returned
+ */
+ public static String parseSwmtLog(String path, CycleData cycleData) throws SwmtFormatException
+ {
+ FileReader inputStr;
+ int lineNo = 0;
+
+ try
+ {
+ inputStr = new FileReader(path);
+
+ reader = new BufferedReader(inputStr);
+ String s = null;
+
+ while((s = reader.readLine()) != null)
+ {
+ lineNo++;
+
+ if(s.contains("{SYSM}"))
+ {
+ SystemData sysData = readSystemMemory(s);
+
+ if(sysData != null)
+ {
+ if(s.contains("Free"))
+ cycleData.setFreeMemory(sysData.getFreeMemory());
+ else if(s.contains("Total"))
+ cycleData.setTotalMemory(sysData.getTotalMemory());
+ }
+ else
+ {
+ SwmtFormatException ex = new SwmtFormatException("Error in SYSM view. ");
+ throw ex;
+ }
+ //String freeRam = s.substring(s.indexOf(FREE_MEM) + (FREE_MEM).length()).trim();
+
+ }
+ if(s.contains("{DISK}")){
+ DiskData diskData = readDiskData(s);
+
+ if(diskData != null){
+ cycleData.addDiskData(diskData);
+ }
+ else{
+ SwmtFormatException ex = new SwmtFormatException("Error in DISK view. ");
+ throw ex;
+ }
+ }
+ else if(s.contains("{HGEN}"))
+ {
+ KernelHandles kernelData = readKernelHandlesData(s);
+
+ if(kernelData != null){
+ cycleData.addKernelData(kernelData);
+ }
+ else{
+ SwmtFormatException ex = new SwmtFormatException("Error in HGEN view. ");
+ throw ex;
+ }
+ }
+ else if(s.contains("{FILE}"))
+ {
+ //DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "Processing File info..");
+ FilesData fileData = readFileData(s);
+
+ if(fileData != null)
+ cycleData.addFileData(fileData);
+
+ else{
+ SwmtFormatException ex = new SwmtFormatException("Error in FILE view. ");
+ throw ex;
+ }
+ }
+ else if(s.contains("{HEAP}"))
+ {
+ //DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "Processing Heap info..");
+ HeapData heapData = readHeapData(s);
+
+ if(heapData != null)
+ cycleData.addHeapData(heapData);
+ else{
+ SwmtFormatException ex = new SwmtFormatException("Error in HEAP view. ");
+ throw ex;
+ }
+ }
+ else if(s.contains("{STAK}"))
+ {
+ //DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "Processing Stack info..");
+ StackData stackData = readStackData(s);
+
+ if(stackData != null)
+ cycleData.addStackData(stackData);
+ else{
+ SwmtFormatException ex = new SwmtFormatException("Error in STAK view. ");
+ throw ex;
+ }
+ }
+ else if(s.contains("{HPAS}"))
+ {
+ PSHandlesData psHandlesData= readHPASHandlesData(s);
+
+ if(psHandlesData != null){
+ cycleData.addHPASHandlesData(psHandlesData);
+ }
+ else{
+ SwmtFormatException ex = new SwmtFormatException("Error in HPAS view. ");
+ throw ex;
+ }
+ }
+ else if(s.contains("{CHNK}"))
+ {
+ ChunksData chunksData= readChunksData(s);
+
+ if(chunksData != null){
+ cycleData.addChunksData(chunksData);
+ }
+ else{
+ SwmtFormatException ex = new SwmtFormatException("Error in CHNK view. ");
+ throw ex;
+ }
+ }
+ else if(s.contains("{GLOD}"))
+ {
+ GlobalDataChunks globalChunksData= readGlobalChunksData(s);
+
+ if(globalChunksData != null){
+ cycleData.addGlobalChunksData(globalChunksData);
+ }
+ else{
+ SwmtFormatException ex = new SwmtFormatException("Error in GLOD view. ");
+ throw ex;
+ }
+ }
+ else if(s.contains("{WNDG}"))
+ {
+ WindowGroups wndgData = readWindowGroupsData(s);
+
+ if(wndgData != null){
+ cycleData.addWindowGroupsData(wndgData);
+ }
+ else
+ {
+ SwmtFormatException ex = new SwmtFormatException("Error in WNDG view. ");
+ throw ex;
+ }
+ }
+ }
+
+ }
+ catch (FileNotFoundException e) {
+ return e.getMessage();
+ } catch (IOException e) {
+ return e.getMessage();
+ }catch(SwmtFormatException e)
+ {
+ throw new SwmtFormatException(e.getMessage() + " Line No: " + lineNo);
+ }
+
+ finally {
+ try{
+ reader.close();
+ }catch(IOException e){
+
+ }
+ }
+ return null;
+ }
+
+ /**
+ * This method reads the DISK data from the given string
+ * and returns a DiskData object. If the string does not contain
+ * "MemSpy" and "{DISK}" tags, it returns null.
+ */
+ private static DiskData readDiskData(String str) throws SwmtFormatException
+ {
+ //DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "Reading Disk Data..");
+
+ if(str.contains("MemSpy") && str.contains("{DISK}"))
+ {
+ DiskData data = new DiskData();
+ String [] subStrings = str.split(",");
+
+ if(subStrings.length !=8)
+ throw new SwmtFormatException("Invalid number of fields in DISK view.");
+
+ data.setName(subStrings[1].trim());
+ data.setSize(subStrings[3].trim());
+ data.setFreeSize(subStrings[4].trim());
+ data.setStatus(subStrings[7].trim());
+
+ return data;
+ }
+ return null;
+ }
+
+ /**
+ * This method reads the information under SYSM bucket to get the
+ * total memory and free memory of the system.
+ */
+ private static SystemData readSystemMemory(String str) throws SwmtFormatException
+ {
+ if(str.contains("MemSpy") && str.contains("{SYSM}"))
+ {
+ SystemData sysData = new SystemData();
+ String [] subStrings = str.split(",");
+
+ if(subStrings.length !=4)
+ throw new SwmtFormatException("Invalid number of fields in SYSM view.");
+
+ if(str.contains("Free"))
+ sysData.setFreeMemory(Long.parseLong(subStrings[2]));
+ if(str.contains("Total"))
+ sysData.setTotalMemory(Long.parseLong(subStrings[2]));
+
+ return sysData;
+ }
+
+ return null;
+ }
+ /**
+ * This method reads the Kerenel Handles data from the given string
+ * and returns a KernelHandles object. If the string does not contain
+ * "MemSpy" and "{HGEN}" tags, it returns null.
+ */
+ private static KernelHandles readKernelHandlesData(String str) throws SwmtFormatException
+ {
+ if(str.contains("MemSpy") && str.contains("{HGEN}"))
+ {
+ KernelHandles kernelData = new KernelHandles();
+ //DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "Parsing Kernel Data " + str);
+
+ String [] subStrings = str.split(",");
+
+ if(subStrings.length != 5)
+ throw new SwmtFormatException("Invalid number of fields in HGEN view.");
+
+ kernelData.setHandleName(subStrings[1].trim());
+ kernelData.setHandle(subStrings[2].trim());
+ kernelData.setHandleType(subStrings[3].trim());
+ kernelData.setStatus(subStrings[4].trim());
+
+ return kernelData;
+ }
+ return null;
+ }
+
+ /**
+ * This method reads the FILE data from the given string
+ * and returns a FilesData object. If the string does not contain
+ * "MemSpy" and "{FILE}" tags, it returns null.
+ * @throws SwmtFormatException if the string is having invalid number formats
+ */
+ private static FilesData readFileData(String str) throws SwmtFormatException
+ {
+ if(str.contains("MemSpy") && str.contains("{FILE}"))
+ {
+ //DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "Parsing File Data " + str);
+ FilesData fileData = new FilesData();
+
+ String [] subStrings = str.split(",");
+
+ if(subStrings.length != 6)
+ throw new SwmtFormatException("Invalid number of fields in FILE view");
+
+ fileData.setFileName(subStrings[1].trim());
+ fileData.setThreadName(subStrings[2].trim());
+ fileData.setFileSize(subStrings[3].trim());
+ fileData.setStatus(subStrings[5].trim());
+
+ return fileData;
+ }
+ return null;
+ }
+
+ /**
+ * This method reads the Heap data from the given string
+ * and returns a HeapData object. If the string does not contain
+ * "MemSpy" and "{HEAP}" tags, it returns null.
+ * @throws SwmtFormatException
+ */
+ private static HeapData readHeapData(String str) throws SwmtFormatException
+ {
+ if(str.contains("MemSpy") && str.contains("{HEAP}"))
+ {
+ //DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "Parsing Heap Data " + str);
+ HeapData heapData = new HeapData();
+
+ String [] subStrings = str.split(",");
+
+ if(subStrings.length != 18)
+ throw new SwmtFormatException("Invalid number of fields in HEAP view");
+
+ if(!subStrings[1].contains("::"))
+ throw new SwmtFormatException("Invalid thread name");
+
+ heapData.setThreadAndProcessName(subStrings[1].trim());
+ heapData.setBaseAddr(subStrings[4].trim());
+ heapData.setSize(subStrings[5].trim());
+ heapData.setMaxSize(subStrings[7].trim());
+ heapData.setAllocatedCells(subStrings[10].trim());
+ heapData.setAllocSpace(subStrings[11].trim());
+ heapData.setFreeCells(subStrings[12].trim());
+ heapData.setFreeSpace(subStrings[13].trim());
+ heapData.setFreeSlack(subStrings[14].trim());
+ heapData.setLargestFreeCell(subStrings[15].trim());
+ heapData.setLargestAllocCell(subStrings[16].trim());
+ heapData.setStatus(subStrings[17].trim());
+
+ return heapData;
+ }
+ return null;
+ }
+
+ /**
+ * This method reads the STACK data from the given string
+ * and returns a StackData object. If the string does not contain
+ * "MemSpy" and "{STAK}" tags, it returns null.
+ * @throws SwmtFormatException
+ */
+ private static StackData readStackData(String str) throws SwmtFormatException
+ {
+ if(str.contains("MemSpy") && str.contains("{STAK}"))
+ {
+ //DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "Parsing Stack Data " + str);
+ StackData stackData = new StackData();
+
+ String [] subStrings = str.split(",");
+
+ if(subStrings.length != 6)
+ throw new SwmtFormatException("Invalid number of fields in STAK view");
+
+ if(!subStrings[1].contains("::"))
+ throw new SwmtFormatException("Invalid thread name");
+
+ stackData.setThreadName(subStrings[1].trim());
+ stackData.setChunkName(subStrings[2].trim());
+ stackData.setSize(subStrings[4].trim());
+ stackData.setStatus(subStrings[5].trim());
+
+ return stackData;
+ }
+ return null;
+ }
+
+ /**
+ * This method reads the HPAS Handles data from the given string
+ * and returns a HPAS Handles object. If the string does not contain
+ * "MemSpy" and "{HPAS}" tags, it returns null.
+ */
+ private static PSHandlesData readHPASHandlesData(String str) throws SwmtFormatException
+ {
+ if(str.contains("MemSpy") && str.contains("{HPAS}"))
+ {
+ PSHandlesData psHandlesData = new PSHandlesData();
+
+ String [] subStrings = str.split(",");
+
+ if(subStrings.length != 11)
+ throw new SwmtFormatException("Invalid number of fields in HPAS view");
+
+ psHandlesData.setHandleName(subStrings[1].trim());
+ psHandlesData.setHandle(subStrings[2].trim());
+ psHandlesData.setKeyType(Integer.parseInt(subStrings[3].trim()));
+ psHandlesData.setThreadId(Long.parseLong(subStrings[8].trim()));
+ psHandlesData.setThreadName(subStrings[9].trim());
+ psHandlesData.setStatus(subStrings[10].trim());
+
+ return psHandlesData;
+ }
+ return null;
+ }
+
+ /**
+ * This method reads the Chunks data from the given string
+ * and returns a Chunk data object. If the string does not contain
+ * "MemSpy" and "{CHNK}" tags, it returns null.
+ */
+ private static ChunksData readChunksData(String str) throws SwmtFormatException
+ {
+ if(str.contains("MemSpy") && str.contains("{CHNK}"))
+ {
+ ChunksData chunkData = new ChunksData();
+
+ String [] subStrings = str.split(",");
+ if(subStrings.length != 8)
+ throw new SwmtFormatException("Invalid number of fields in CHUNK view");
+
+ chunkData.setProcessName(subStrings[1].trim());
+ chunkData.setChunkName(subStrings[2].trim());
+ chunkData.setHandle(subStrings[3].trim());
+ chunkData.setBaseAddr(subStrings[4].trim());
+ chunkData.setSize(Long.parseLong(subStrings[5].trim()));
+ if(subStrings[7].equals("[N]+[A]"))
+ chunkData.setAttrib(CycleData.New);
+ else if(subStrings[7].equals("[D]"))
+ chunkData.setAttrib(CycleData.Deleted);
+ else if(subStrings[7].equals("[A]"))
+ chunkData.setAttrib(CycleData.Alive);
+
+ return chunkData;
+ }
+ return null;
+ }
+
+ /**
+ * This method reads the Global Chunks data from the given string
+ * and returns a GlobalChunk data object. If the string does not contain
+ * "MemSpy" and "{GLOD}" tags, it returns null.
+ */
+ private static GlobalDataChunks readGlobalChunksData(String str) throws SwmtFormatException
+ {
+ if(str.contains("MemSpy") && str.contains("{GLOD}"))
+ {
+ GlobalDataChunks chunkData = new GlobalDataChunks();
+
+ String [] subStrings = str.split(",");
+ if(subStrings.length != 8)
+ throw new SwmtFormatException("Invalid number of fields in HPAS view");
+
+ chunkData.setProcessName(subStrings[1].trim());
+ chunkData.setChunkName(subStrings[2].trim());
+ chunkData.setBaseAddr(subStrings[4].trim());
+
+ if(subStrings[5].trim().length()!=0)
+ chunkData.setSize(Long.parseLong(subStrings[5].trim()));
+ else
+ chunkData.setSize(-1);
+
+ if(subStrings[7].trim().equals("[N]+[A]"))
+ chunkData.setAttrib(CycleData.New);
+ else if(subStrings[7].trim().equals("[D]"))
+ chunkData.setAttrib(CycleData.Deleted);
+ else if(subStrings[7].trim().equals("[A]"))
+ chunkData.setAttrib(CycleData.Alive);
+
+ return chunkData;
+ }
+ return null;
+ }
+
+ /**
+ *
+ * This method parses the data related to WNDG events.
+ */
+ private static WindowGroups readWindowGroupsData(String start_line) throws SwmtFormatException
+ {
+ if(start_line.contains("MemSpy") && start_line.contains("{WNDG}"))
+ {
+ String [] subStrings = start_line.split(",");
+
+ if(subStrings.length != 6)
+ throw new SwmtFormatException("Invalid number of fields in WNDG view");
+
+ WindowGroups wndgData = new WindowGroups();
+
+ String id_str = subStrings[1].trim();
+ int id = Integer.parseInt(id_str);
+
+ int event = Integer.parseInt(subStrings[4].trim());
+
+ wndgData.setId(id);
+ wndgData.setName(subStrings[2].trim());
+ wndgData.setEvent(event);
+
+ if(subStrings[5].trim().equals("[N]+[A]"))
+ wndgData.setStatus(CycleData.New);
+ else if(subStrings[5].trim().equals("[D]"))
+ wndgData.setStatus(CycleData.Deleted);
+ else if(subStrings[5].trim().equals("[A]"))
+ wndgData.setStatus(CycleData.Alive);
+
+ return wndgData;
+ }
+ return null;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/resources/HelpContextIds.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,34 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+package com.nokia.s60tools.swmtanalyser.resources;
+
+/**
+ * Class holding Context sensitive help ID:s
+ */
+public class HelpContextIds {
+
+ /**
+ * Plug-in ID for help plug-in
+ */
+ private static final String MEMSPY_HELP_PROJECT_ID = "com.nokia.s60tools.memspy.help"; //$NON-NLS-1$
+
+ /**
+ * Context sensitive help id for generating PDF reports
+ */
+ public static final String SWMT_REPORT_WIZARD_HELP =
+ MEMSPY_HELP_PROJECT_ID + ".MEMSPY_SWMT_REPORT_GENERATION_WIZARD"; //$NON-NLS-1$
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/resources/Tooltips.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,47 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+package com.nokia.s60tools.swmtanalyser.resources;
+
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+/**
+ * Helper class to get the tooltips from the resource file.
+ *
+ */
+public class Tooltips {
+ private static final String BUNDLE_NAME = "com.nokia.s60tools.swmtanalyser.resources.tooltip"; //$NON-NLS-1$
+
+ private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle
+ .getBundle(BUNDLE_NAME);
+
+ private Tooltips() {
+ }
+
+ /**
+ * Get a tooltip by key
+ * @param key
+ * @return tooltip
+ */
+ public static String getTooltip(String key) {
+ try {
+ return RESOURCE_BUNDLE.getString(key);
+ } catch (MissingResourceException e) {
+ return '!' + key + '!';
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/resources/tooltip.properties Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,27 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+#
+Tooltips.HeapSize=Heap size: The amount of memory that is currently reserved for the heap itself.
+Tooltips.NoOfFiles1=No of Files: Number of files that the selected thread '
+Tooltips.NoOfFiles2=' currently has open.
+Tooltips.HeapAllocatedSpace=Heap allocated space: The amount of currently allocated memory in heap.
+Tooltips.HeapAllocatedCellCount=Heap allocated cell count: The alloc. count is the number of allocated cells that exist within this heap.
+Tooltips.NoOfPSHandles=No of Publish && Subscribe handles owned by the selected thread
+Tooltips.SystemData=List of all of the kernel-side DObjectCon containers that are in use, called kernal handles
+Tooltips.RAMUsed=The amount of currently used RAM memory.
+Tooltips.DiskUsed=The amount of currently used memory in disk
+Tooltips.Delta=The delta is the difference between the last and first cycle value.
+Tooltips.Severity=Severity is also called as Growing Factor and is determined using the internal algorithm.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/ui/actions/CopyToClipboardAction.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,140 @@
+/*
+* Copyright (c) 2007 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+package com.nokia.s60tools.swmtanalyser.ui.actions;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+
+import com.nokia.s60tools.swmtanalyser.SwmtAnalyserPlugin;
+import com.nokia.s60tools.swmtanalyser.analysers.ResultElements;
+import com.nokia.s60tools.swmtanalyser.analysers.ResultsParentNodes;
+import com.nokia.s60tools.swmtanalyser.editors.GraphedItemsInput;
+import com.nokia.s60tools.swmtanalyser.editors.TableViewerInputObject;
+import com.nokia.s60tools.ui.StringArrayClipboardCopyHandler;
+import com.nokia.s60tools.ui.actions.S60ToolsBaseAction;
+import com.nokia.s60tools.util.console.IConsolePrintUtility;
+import com.nokia.s60tools.util.debug.DbgUtility;
+
+/**
+ * Action class for Copy text data from tables to clipboard
+ */
+public class CopyToClipboardAction extends S60ToolsBaseAction {
+
+ /**
+ * Table viewer instance where items are located is given by observer,
+ * also call back is send back through observer
+ */
+ private final ISelectionProvider observer;
+
+ /**
+ * Constructor
+ * @param observer to provide selection
+ */
+ public CopyToClipboardAction(ISelectionProvider observer) {
+ super("Copy",
+ "Copy to clipboard",
+ IAction.AS_PUSH_BUTTON, null);
+ this.observer = observer;
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.action.Action#run()
+ */
+ public void run() {
+ try {
+
+ //Get selection made in UI through observer
+ ISelection selection = observer.getUserSelection();
+ if (selection == null || selection.isEmpty()){
+ return;//If no selections made, just return
+ }
+ // go through all selected files and add file path to clipboard
+ // ISelection comes from {@link TableViewer} so, there's nothing we
+ // can do about type safety.
+ @SuppressWarnings("unchecked")
+ Iterator<TableViewerInputObject> iter = ((IStructuredSelection) selection)
+ .iterator();
+ List<Object> items = new ArrayList<Object>();
+
+ String tab = "\t";
+ boolean isHeaderFound = false;
+ String headers = null;
+ //Get all selected items
+ while (iter.hasNext()) {
+ Object o = iter.next();
+ String str = null;
+ //Copy from Graphs
+ if(o instanceof TableViewerInputObject){
+ TableViewerInputObject to = (TableViewerInputObject)o;
+ str = to.getName();
+ }
+ //Copy from Graphed items
+ else if(o instanceof GraphedItemsInput){
+ GraphedItemsInput gi = (GraphedItemsInput)o;
+ str = gi.getTabSeparatedValues();
+ //Adding headers when found out at least one data item
+ if(!isHeaderFound){
+ headers = gi.getTabSeparatedHeaders();
+ isHeaderFound = true;
+ }
+ }
+ //Copy from Analysis (data)
+ else if(o instanceof ResultElements){
+ ResultElements re = (ResultElements)o;
+ str = tab + re.getTabSeparatedValues();
+ //Adding headers when found out at least one data item
+ if(!isHeaderFound){
+ headers = tab + re.getTabSeparatedHeaders();
+ isHeaderFound = true;
+ }
+ }
+ //Copy from Analysis (parent node)
+ else if(o instanceof ResultsParentNodes){
+ ResultsParentNodes rpn = (ResultsParentNodes)o;
+ str = rpn.toString();
+ }
+ //Else it's internal error if we can't found proper handle to class given to Copy.
+ else{
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "Unable to found Copy functionality to Object: (" +o + "), Class: " +o.getClass());
+ }
+
+ if(str != null){
+ items.add(str);
+ }
+
+ }
+
+ //If at least one data item was found, also data headers will be added, but only once.
+ if(headers != null){
+ items.add(0, headers);
+ }
+
+ StringArrayClipboardCopyHandler copyHandler = new StringArrayClipboardCopyHandler();
+ copyHandler.acceptAndCopy(items);
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ SwmtAnalyserPlugin.getConsole().println(e.getMessage(),
+ IConsolePrintUtility.MSG_ERROR);
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/ui/actions/ISelectionProvider.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,35 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+package com.nokia.s60tools.swmtanalyser.ui.actions;
+
+import org.eclipse.jface.viewers.ISelection;
+
+/**
+ * Interface for provide selection that User has been made in UI
+ */
+public interface ISelectionProvider {
+
+
+ /**
+ * Get selection that user has made in UI
+ * @return selection made in UI
+ */
+ public ISelection getUserSelection();
+
+
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/ui/actions/SwmtAnalyser.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,193 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+package com.nokia.s60tools.swmtanalyser.ui.actions;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.dialogs.ProgressMonitorDialog;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IEditorDescriptor;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.PlatformUI;
+
+import com.nokia.s60tools.swmtanalyser.SwmtAnalyserPlugin;
+import com.nokia.s60tools.swmtanalyser.data.CycleData;
+import com.nokia.s60tools.swmtanalyser.data.OverviewData;
+import com.nokia.s60tools.swmtanalyser.data.ParsedData;
+import com.nokia.s60tools.swmtanalyser.editors.SWMTEditorInput;
+import com.nokia.s60tools.swmtanalyser.exception.SwmtFormatException;
+import com.nokia.s60tools.swmtanalyser.model.SWMTLogReaderUtils;
+import com.nokia.s60tools.swmtanalyser.model.SwmtParser;
+import com.nokia.s60tools.util.console.IConsolePrintUtility;
+
+/**
+ * Interface to start analysis.
+ *
+ */
+public class SwmtAnalyser {
+
+ private static final String SWMT_EDITOR_ID = "com.nokia.s60tools.swmtanalyser.editors.SWMTEditor";
+ private ArrayList<String> inputs;
+ private ArrayList<CycleData> cycleData;
+ private String status = null;
+ private boolean isCancelled;
+ private SWMTLogReaderUtils logReader = new SWMTLogReaderUtils();
+ private String parserError;
+
+ /**
+ * Construction for creating SWMT Analyser to editor area.
+ * @param console
+ */
+ public SwmtAnalyser(IConsolePrintUtility console) {
+ SwmtAnalyserPlugin.getDefault().setConsole(console);
+ }
+
+ /**
+ * Analyse given logs files.
+ * @param swmtFiles list of swmt log files to be analysed
+ */
+ public void analyse(ArrayList<String> swmtFilePaths)
+ {
+ if(swmtFilePaths != null)
+ {
+ inputs = swmtFilePaths;
+ cycleData = new ArrayList<CycleData>();
+
+ isCancelled = false;
+ IRunnableWithProgress op = new IRunnableWithProgress() {
+ public void run(IProgressMonitor monitor) {
+ monitor.beginTask("Reading log files..", 10);
+ status = logReader.getCycleDataArrayFromLogFiles(inputs, cycleData, monitor);
+ if(monitor.isCanceled())
+ isCancelled = true;
+
+ monitor.done();
+ }
+ };
+
+ IWorkbench wb = PlatformUI.getWorkbench();
+ IWorkbenchWindow win = wb.getActiveWorkbenchWindow();
+
+ Shell shell = win != null ? win.getShell() : null;
+ try {
+ new ProgressMonitorDialog(shell).run(true, true, op);
+ } catch (InvocationTargetException e) {
+ e.printStackTrace();
+ return;
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ return;
+ }
+
+ if(isCancelled)
+ return;
+
+ if(status != null)
+ {
+ MessageDialog.openError(Display.getCurrent().getActiveShell(), "SWMT Analyser", status);
+ return;
+ }
+ else if(cycleData.size()>1)
+ {
+ cycleData = logReader.checkCycleOrder(cycleData);
+ if(cycleData==null)
+ {
+ MessageDialog.openError(Display.getCurrent().getActiveShell(), "SWMT Analyser", "Invalid order of the log files. The selected files must be in consecutive order and must start from the first cycle.");
+ return;
+ }
+
+ if(!logReader.checkRomInfo(cycleData))
+ {
+ MessageDialog.openError(Display.getCurrent().getActiveShell(), "SWMT Analyser", "Selected logs do not have common ROM Checksum and Version. Hence, they cannot be compared.");
+ return;
+ }
+ int ret = logReader.checkTimeStamp(cycleData);
+ if(ret!= 0)
+ {
+ MessageDialog.openError(Display.getCurrent().getActiveShell(), "SWMT Analyser", "In selected logs, the time stamp of log cycle "+ ret +" is lesser than log cycle "+ (ret -1)+". Hence, they cannot be analysed together.");
+ return;
+ }
+ }
+ else if(cycleData.size() == 1 && cycleData.get(0).getCycleNumber() != 1)
+ {
+ boolean ok = MessageDialog.openQuestion(Display.getCurrent().getActiveShell(), "SWMT Analyser", "This is a delta file. It does not contain the complete information. Do you still want to continue ?");
+ if(!ok)
+ return;
+ }
+
+ //Files are valid and the cycle numbers are in order.
+ //So, get overview information to be displayed in the editor view
+ OverviewData ov = logReader.getOverviewInformationFromCyclesData(cycleData.toArray(new CycleData[0]),cycleData.size());
+
+ Runnable runnable = new Runnable(){
+ public void run() {
+ for(int i=0; i<cycleData.size(); i++)
+ {
+ CycleData cycle = cycleData.get(i);
+ cycle.clear();
+
+ try {
+ SwmtParser.parseSwmtLog(cycle.getFileName(), cycle);
+ } catch (SwmtFormatException e) {
+ parserError = e.getMessage();
+ Runnable runnable = new Runnable(){
+ public void run() {
+ MessageDialog.openError(Display.getCurrent().getActiveShell(), "SWMT Analyser", "Error while parsing the log file " + parserError );
+ }
+ };
+ Display.getDefault().asyncExec(runnable);
+ return;
+ }
+ }
+ }
+ };
+ Display.getDefault().syncExec(runnable);
+
+ IWorkbenchPage page=PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
+ try
+ {
+ IEditorDescriptor descriptor = PlatformUI.getWorkbench().getEditorRegistry().findEditor(SWMT_EDITOR_ID);
+ if(descriptor == null)
+ {
+ MessageDialog.openError(Display.getDefault().getActiveShell(),"SWMT Analyser", "SWMT Editor is not found");
+ return;
+ }
+
+ ParsedData logData = new ParsedData();
+ logData.setParsedData(cycleData);
+ page.openEditor(new SWMTEditorInput(logData,ov), descriptor.getId(), true,IWorkbenchPage.MATCH_INPUT);
+
+ } catch (PartInitException e) {
+ e.printStackTrace();
+ }
+ }
+ else
+ {
+ MessageDialog.openError(Display.getCurrent().getActiveShell(), "SWMT Analyser", "Invalid input. Unable to open SWMT Editor");
+ return;
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/ui/graphs/ChunksGraph.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,440 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+package com.nokia.s60tools.swmtanalyser.ui.graphs;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+import org.eclipse.draw2d.Graphics;
+import org.eclipse.draw2d.Polyline;
+import org.eclipse.draw2d.geometry.PointList;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Transform;
+import org.eclipse.swt.widgets.Display;
+
+import com.nokia.s60tools.swmtanalyser.data.ChunksData;
+import com.nokia.s60tools.swmtanalyser.data.CycleData;
+import com.nokia.s60tools.swmtanalyser.data.GlobalDataChunks;
+import com.nokia.s60tools.swmtanalyser.model.SWMTLogReaderUtils;
+import com.nokia.s60tools.util.debug.DbgUtility;
+
+/**
+ * This class contains all needed logic to paint data related to Global and Non-Heap chunks.
+ *
+ */
+public class ChunksGraph extends GenericGraph {
+
+ private HashMap<String, ArrayList<GlobalDataChunks>> chunksData = new HashMap<String, ArrayList<GlobalDataChunks>>();
+ private HashMap<String, ArrayList<ChunksData>> nonHeapChunksData = new HashMap<String, ArrayList<ChunksData>>();
+
+ private HashMap<String, Polyline> pointsData = new HashMap<String, Polyline>();
+
+ private double visY;
+ private double multiplier;
+
+ /* (non-Javadoc)
+ * @see com.nokia.s60tools.swmtanalyser.ui.graphs.GenericGraph#paint(org.eclipse.draw2d.Graphics)
+ */
+ public void paint(Graphics graphics) {
+
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION, this.getClass().getSimpleName() + "/paint START");
+
+ ArrayList<String> chunksList = this.getUserSelectedItems();
+
+ if(chunksList == null)
+ return;
+
+ // Storing original settings before graphs are painted with case-specific settings
+ int origLineWidth = graphics.getLineWidth();
+ Color origColor = graphics.getForegroundColor();
+ int origLineStyle = graphics.getLineStyle();
+
+ // Setting graph drawing specific settings
+ graphics.setLineWidth(CommonGraphConstants.DEFAULT_GRAPH_LINE_WIDTH);
+ graphics.setLineStyle(SWT.LINE_SOLID);
+
+ int [] listX = this.calculateTimeIntervals();
+ this.lastSampleTime = listX[listX.length-1];
+
+ int k=0;
+
+ for(String chnk: chunksList)
+ {
+ if(this.getEvent().equals(GenericGraph.EventTypes.GLOBAL_DATA_SIZE))
+ valuesToBePlotted = getGlobalChnkSizeData(chnk);
+ else if(this.getEvent().equals(GenericGraph.EventTypes.NON_HEAP_CHUNK_SIZE))
+ valuesToBePlotted = getNonHeapChnkSizeData(chnk);
+
+ int [] points = new int[valuesToBePlotted.length *2];
+
+ double visY = visualSizeY - CommonGraphConstants.XLEGENDSPACE;
+ boolean handleDeleted = false;
+
+ List<List<Integer>> ListOfSolidLinePoints = new ArrayList<List<Integer>>();
+ ArrayList<Integer> solidLinePoints = new ArrayList<Integer>();
+
+ for (int i = 0, j = 0; i < valuesToBePlotted.length; i++, j++)
+ {
+ if (valuesToBePlotted[i] <= 0){
+ // Not showing zero values to a user, not meaningful data
+ DbgUtility.println(DbgUtility.PRIORITY_LOOP, "continued because value <= 0");
+ continue;
+ }
+
+ int x_point = (int)(listX[i]/getScale());
+ int y_point =(int) (visY - valuesToBePlotted[i] /multiplier);
+
+ points[j] = x_point;
+ points[++j] = y_point;
+
+ if(!handleDeleted){
+ if(y_point > 0){
+ solidLinePoints.add(x_point);
+ solidLinePoints.add(y_point);
+ DbgUtility.println(DbgUtility.PRIORITY_LOOP, "add 1: x_point: " + x_point + ", y_point: " + y_point);
+ }
+ else{
+ DbgUtility.println(DbgUtility.PRIORITY_LOOP, "skipped because zero value");
+ }
+ }
+
+ boolean handleStatus = getHandleStatus(i+1, chnk);
+
+ if(handleStatus && !handleDeleted){
+ handleDeleted = true;
+
+ if(solidLinePoints.size() > 0)
+ ListOfSolidLinePoints.add(solidLinePoints);
+
+ solidLinePoints = new ArrayList<Integer>();
+ }
+
+ if(handleDeleted && getChunkStatus(i+1, chnk)== CycleData.New )
+ {
+ handleDeleted = false;
+ if(y_point > 0){
+ // Graphing only positive values
+ solidLinePoints.add(x_point);
+ solidLinePoints.add(y_point);
+ DbgUtility.println(DbgUtility.PRIORITY_LOOP, "add 2:x_point: " + x_point + ", y_point: " + y_point);
+ }
+ else{
+ DbgUtility.println(DbgUtility.PRIORITY_LOOP, "skipped because zero value");
+ }
+ }
+
+ points[i] = x_point;
+ points[i+1] = y_point;
+ }
+
+ if(solidLinePoints.size() > 0)
+ ListOfSolidLinePoints.add(solidLinePoints);
+
+ graphics.setForegroundColor(this.getColors().get(k));
+ graphics.setLineWidth(2);
+
+ for(int i=0; i < ListOfSolidLinePoints.size(); i++)
+ {
+ int [] solidPts = GraphsUtils.CreateIntArrayFromIntegerList(ListOfSolidLinePoints.get(i));
+
+ if(solidPts != null)
+ {
+ if(ListOfSolidLinePoints.size() > 1)
+ {
+ int instance_id = i+1;
+ graphics.drawString("(0" + instance_id + ")", solidPts[0]+2, solidPts[1] - 15);
+ }
+ graphics.setLineStyle(SWT.LINE_SOLID);
+ graphics.drawPolyline(solidPts);
+
+ // Drawing markers to the data points
+ GraphsUtils.drawMarkers(graphics, solidPts);
+ }
+ }
+
+ Polyline line = new Polyline();
+ line.setPoints(new PointList(points));
+
+ pointsData.put(chnk, line);
+
+ k++;
+ }
+
+ // Restoring original settings before paint call
+ graphics.setLineStyle(origLineStyle);
+ graphics.setForegroundColor(origColor);
+ graphics.setLineWidth(origLineWidth);
+
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION, this.getClass().getSimpleName() + "/paint END");
+ }
+
+ /* (non-Javadoc)
+ * @see com.nokia.s60tools.swmtanalyser.ui.graphs.GenericGraph#paintYAxis(org.eclipse.swt.graphics.GC)
+ */
+ public void paintYAxis(GC gc) {
+
+ visY = visualSizeY - CommonGraphConstants.XLEGENDSPACE;
+ multiplier = GraphsUtils.prettyMaxBytes(maxBytes) / visY;
+
+ double yIncrement = visY / 10;
+ int previousBottom = 0;
+
+ for (int k = 10; k >= 0; k--)
+ {
+ // location for the value indicator is k * 1/10 the height of the display
+ int y = (int) (visY - (yIncrement * k));
+
+ int bytes = (int)(yIncrement * multiplier) * k;
+
+ String legend = "";
+
+ if (maxBytes < 10000)
+ {
+ legend += bytes + " B"; //$NON-NLS-1$
+ }
+ else if (maxBytes <= 500 * 1024)
+ {
+ legend += (bytes / 1024) + " KB"; //$NON-NLS-1$
+ }
+ else
+ {
+ legend += MBformat.format(((float) bytes / (1024 * 1024))) + " MB"; //$NON-NLS-1$
+ }
+ Point extent = gc.stringExtent(legend);
+
+ gc.drawLine(CommonGraphConstants.YLEGENDSPACE - 3, (int)y + 1, CommonGraphConstants.YLEGENDSPACE, (int)y + 1);
+
+ if (y >= previousBottom)
+ {
+ gc.drawString(legend, CommonGraphConstants.YLEGENDSPACE - extent.x -2, (int)y);
+ previousBottom = (int)y + extent.y;
+ }
+ }
+
+ final Image image = this.getVerticalLabel("Bytes");
+ gc.setAdvanced(true);
+ final org.eclipse.swt.graphics.Rectangle rect2 = image.getBounds();
+ Transform transform = new Transform(Display.getDefault());
+
+ transform.translate(rect2.height / 2f, rect2.width / 2f);
+ transform.rotate(-90);
+ transform.translate(-rect2.width / 2f, -rect2.height / 2f);
+
+ gc.setTransform(transform);
+ gc.drawImage(image, -(int)visY/3, 1);
+
+ transform.dispose();
+ gc.dispose();
+
+ }
+
+ private void fetchEntireDataForSelectedChunks()
+ {
+ ArrayList<String> selectedChunks = this.getUserSelectedItems();
+
+ SWMTLogReaderUtils utils = new SWMTLogReaderUtils();
+
+ if(this.getEvent().equals(GenericGraph.EventTypes.GLOBAL_DATA_SIZE))
+ {
+ for(String chunk:selectedChunks)
+ {
+ ArrayList<GlobalDataChunks> chnkData = utils.getGLOBDataFromAllCycles(chunk, this.getCyclesData());
+ chunksData.put(chunk, chnkData);
+ }
+ }
+ else if(this.getEvent().equals(GenericGraph.EventTypes.NON_HEAP_CHUNK_SIZE))
+ {
+ for(String chunk:selectedChunks)
+ {
+ ArrayList<ChunksData> chnkData = utils.getChunkDataFromAllCycles(chunk, this.getCyclesData());
+ nonHeapChunksData.put(chunk, chnkData);
+ }
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see com.nokia.s60tools.swmtanalyser.ui.graphs.GenericGraph#prepareData()
+ */
+ public void prepareData() {
+ fetchEntireDataForSelectedChunks();
+
+ for(String chnk:getUserSelectedItems())
+ {
+ int [] valuesToBePlotted = null;
+
+ switch(this.getEvent())
+ {
+ case GLOBAL_DATA_SIZE:
+ valuesToBePlotted = getGlobalChnkSizeData(chnk);
+ break;
+ case NON_HEAP_CHUNK_SIZE:
+ valuesToBePlotted = getNonHeapChnkSizeData(chnk);
+ break;
+ }
+
+ if(valuesToBePlotted == null)
+ continue;
+
+ int maxValue = calculateMaxValue(valuesToBePlotted);
+
+ if(maxValue > maxBytes)
+ maxBytes = maxValue;
+ }
+
+ }
+
+ private boolean getHandleStatus(int cycleNo, String chunkName)
+ {
+ boolean status = false;
+
+ if(this.getEvent().equals(GenericGraph.EventTypes.GLOBAL_DATA_SIZE))
+ {
+ ArrayList<GlobalDataChunks> glod_data = chunksData.get(chunkName);
+
+ status = glod_data.get(cycleNo -1).isKernelHandleDeleted();
+ }
+ else if(this.getEvent().equals(GenericGraph.EventTypes.NON_HEAP_CHUNK_SIZE))
+ {
+ ArrayList<ChunksData> chunks_data = nonHeapChunksData.get(chunkName);
+
+ status = chunks_data.get(cycleNo -1).isKernelHandleDeleted();
+ }
+
+ return status;
+ }
+
+ private int getChunkStatus(int cycleNo, String chunkName)
+ {
+ int status = 0;
+
+ if(this.getEvent().equals(GenericGraph.EventTypes.GLOBAL_DATA_SIZE))
+ {
+ ArrayList<GlobalDataChunks> glod_data = chunksData.get(chunkName);
+
+ status = glod_data.get(cycleNo -1).getAttrib();
+ }
+ else if(this.getEvent().equals(GenericGraph.EventTypes.NON_HEAP_CHUNK_SIZE))
+ {
+ ArrayList<ChunksData> chunks_data = nonHeapChunksData.get(chunkName);
+
+ status = chunks_data.get(cycleNo -1).getAttrib();
+ }
+
+ return status;
+ }
+ private int [] getGlobalChnkSizeData(String chnkName)
+ {
+ ArrayList<GlobalDataChunks> data = chunksData.get(chnkName);
+
+ int [] values = new int[data.size()];
+
+ for(int i=0; i<data.size(); i++)
+ {
+ if(data.get(i).getAttrib() == CycleData.Deleted)
+ values[i] = 0;
+ else
+ values [i] = (int)data.get(i).getSize();
+ }
+
+ return values;
+ }
+ private int [] getNonHeapChnkSizeData(String chnkName)
+ {
+ ArrayList<ChunksData> data = nonHeapChunksData.get(chnkName);
+
+ int [] values = new int[data.size()];
+
+ for(int i=0; i<data.size(); i++)
+ {
+ if(data.get(i).getAttrib() == CycleData.Deleted)
+ values[i] = 0;
+ else
+ values [i] = (int)data.get(i).getSize();
+ }
+
+ return values;
+ }
+
+ /* (non-Javadoc)
+ * @see com.nokia.s60tools.swmtanalyser.ui.graphs.GenericGraph#getToolTipText(int, int)
+ */
+ public String getToolTipText(int x, int y)
+ {
+ if(y > (int)visY)
+ return null;
+
+ String text = "";
+
+ double xValue = x + timeOffset;
+ int scaledX = (int)(xValue * getScale());
+
+ double valY = visY - y;
+ double bytes = valY * multiplier;
+
+ String scaledY = "";
+
+ if (bytes < 10000)
+ {
+ scaledY += Bytes_Format.format(bytes) + " B"; //$NON-NLS-1$
+ }
+ else if (bytes <= 500 * 1024)
+ {
+ scaledY += Bytes_Format.format(bytes / 1024) + " KB"; //$NON-NLS-1$
+ }
+ else
+ {
+ scaledY += MBformat.format(((float) bytes / (1024 * 1024))) + " MB"; //$NON-NLS-1$
+ }
+
+ text += scaledX + " s, " + scaledY;
+ for(String chnk: getUserSelectedItems())
+ {
+ Polyline line = pointsData.get(chnk);
+
+ if(line != null && line.containsPoint(x, y))
+ text += "\n" + chnk;
+ }
+
+ return text;
+ }
+
+ /**
+ * Get {@link GlobalDataChunks} for given chunk name
+ * @param chnkName
+ * @return List of chunks with given name
+ */
+ public ArrayList<GlobalDataChunks> getGlobalChunkData(String chnkName)
+ {
+ return chunksData.get(chnkName);
+ }
+
+ /**
+ * Get {@link ChunksData} for given chunk name
+ * @param chnkName
+ * @return List of data with given name
+ */
+ public ArrayList<ChunksData> getNonHeapChunkData(String chnkName)
+ {
+ return nonHeapChunksData.get(chnkName);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/ui/graphs/CommonGraphConstants.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,48 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+package com.nokia.s60tools.swmtanalyser.ui.graphs;
+
+/**
+ * Contains constants that are shared by multiple graph
+ * drawing related classes.
+ */
+public class CommonGraphConstants {
+
+ /**
+ * Context menu title for action: Show Entire Graph
+ */
+ public static final String SHOW_ENTIRE_GRAPH_CONTEXT_MENU_ITEM_TITLE = "Show Entire Graph";
+ /**
+ * Context menu title for action: Save graph...
+ */
+ public static final String SAVE_GRAPH_CONTEXT_MENU_ITEM_TITLE = "Save graph...";
+ /**
+ * Room reserved for Y-axis legend in X-axis direction.
+ */
+ public static final int YLEGENDSPACE = 60;
+ /**
+ * Room reserved for X-axis legend in Y-axis direction.
+ */
+ public static final int XLEGENDSPACE = 50;
+ /**
+ * Default line width for the graphs.
+ */
+ protected static final int DEFAULT_GRAPH_LINE_WIDTH = 2;
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/ui/graphs/DisksGraph.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,431 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+package com.nokia.s60tools.swmtanalyser.ui.graphs;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+
+import org.eclipse.draw2d.Graphics;
+import org.eclipse.draw2d.Polyline;
+import org.eclipse.draw2d.geometry.PointList;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Transform;
+import org.eclipse.swt.widgets.Display;
+
+import com.nokia.s60tools.swmtanalyser.data.DiskOverview;
+import com.nokia.s60tools.swmtanalyser.data.SystemData;
+import com.nokia.s60tools.swmtanalyser.model.SWMTLogReaderUtils;
+import com.nokia.s60tools.util.debug.DbgUtility;
+
+/**
+ * This class contains all needed logic to paint data related to Disks.
+ */
+public class DisksGraph extends GenericGraph {
+
+ private HashMap<String, ArrayList<DiskOverview>> totalDiskData = new HashMap<String, ArrayList<DiskOverview>>();
+ private HashMap<String, Polyline> pointsData = new HashMap<String, Polyline>();
+
+ private double visY;
+ private double multiplier;
+
+ private int [] Ram_Used_Values;
+ private int [] Ram_Total_Values;
+ private ArrayList<SystemData> sysData;
+
+ /* (non-Javadoc)
+ * @see com.nokia.s60tools.swmtanalyser.ui.graphs.GenericGraph#paint(org.eclipse.draw2d.Graphics)
+ */
+ public void paint(Graphics graphics) {
+
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION, this.getClass().getSimpleName() + "/paint START");
+
+ // Storing original graphics settings
+ Color origColor = graphics.getForegroundColor();
+ int origLineWidth = graphics.getLineWidth();
+
+ int [] listX = this.calculateTimeIntervals();
+
+ this.lastSampleTime = listX[listX.length-1];
+
+ if(this.getEvent().equals(EventTypes.RAM_USED) || this.getEvent().equals(EventTypes.RAM_TOTAL))
+ {
+ if(this.getEvent().equals(EventTypes.RAM_USED))
+ {
+ valuesToBePlotted = Ram_Used_Values;
+ }
+ else if(this.getEvent().equals(EventTypes.RAM_TOTAL))
+ {
+ valuesToBePlotted = Ram_Total_Values;
+ }
+
+ if(valuesToBePlotted == null)
+ return;
+
+ int [] points = new int[valuesToBePlotted.length *2];
+
+ double visY = visualSizeY - CommonGraphConstants.XLEGENDSPACE;
+
+ for (int i = 0, j = 0; i < valuesToBePlotted.length; i++)
+ {
+ points[j++] = (int)(listX[i]/getScale());
+
+ points[j] =(int) (visY - valuesToBePlotted[i] /multiplier);
+
+ if (points[j] < 0)
+ points[j] = 0;
+
+ j++;
+ }
+
+ graphics.setForegroundColor(Display.getCurrent().getSystemColor(SWT.COLOR_BLUE));
+ graphics.drawPolyline(points);
+ // Drawing markers to the data points
+ GraphsUtils.drawMarkers(graphics, points);
+
+ Polyline line = new Polyline();
+ line.setPoints(new PointList(points));
+
+ if(this.getEvent().equals(EventTypes.RAM_USED))
+ {
+ pointsData.put("RAM Used", line);
+ }
+ else if(this.getEvent().equals(EventTypes.RAM_TOTAL))
+ {
+ pointsData.put("RAM Total", line);
+ }
+
+ }
+ else{
+ ArrayList<String> disksList = this.getUserSelectedItems();
+
+ if(disksList == null)
+ return;
+
+ int k=0;
+
+ for(String disk: disksList){
+
+ ArrayList<DiskOverview> data = totalDiskData.get(disk);
+
+ valuesToBePlotted = new int[data.size()];
+
+ for(int i =0; i<data.size(); i++)
+ {
+ EventTypes event = this.getEvent();
+
+ valuesToBePlotted[i] = getEventValueFromDisksData(data.get(i), event);
+
+ }
+ int [] points = new int[valuesToBePlotted.length *2];
+
+ double visY = visualSizeY - CommonGraphConstants.XLEGENDSPACE;
+
+ for (int i = 0, j = 0; i < valuesToBePlotted.length; i++)
+ {
+ points[j++] = (int)(listX[i]/getScale());
+
+ points[j] =(int) (visY - valuesToBePlotted[i] /multiplier);
+
+ if (points[j] < 0)
+ points[j] = 0;
+
+ j++;
+ }
+
+ // Setting graph-specific settings
+ graphics.setLineWidth(CommonGraphConstants.DEFAULT_GRAPH_LINE_WIDTH);
+ graphics.setForegroundColor(this.getColors().get(k));
+ graphics.drawPolyline(points);
+ // Drawing markers to the data points
+ GraphsUtils.drawMarkers(graphics, points);
+
+ Polyline line = new Polyline();
+ line.setPoints(new PointList(points));
+ pointsData.put(disk, line);
+
+ k++;
+
+ } // for
+ } // else
+
+ // Restoring original graphics settings
+ graphics.setForegroundColor(origColor);
+ graphics.setLineWidth(origLineWidth);
+
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION, this.getClass().getSimpleName() + "/paint END");
+ }
+
+ /* (non-Javadoc)
+ * @see com.nokia.s60tools.swmtanalyser.ui.graphs.GenericGraph#paintYAxispaintYAxis(org.eclipse.swt.graphics.GC)
+ */
+ @Override
+ public void paintYAxis( GC gc) {
+
+ visY = visualSizeY - CommonGraphConstants.XLEGENDSPACE;
+ multiplier = GraphsUtils.prettyMaxBytes(maxBytes) / visY;
+
+ double yIncrement = visY / 10;
+ int previousBottom = 0;
+
+ for (int k = 10; k >= 0; k--)
+ {
+ // location for the value indicator is k * 1/10 the height of the display
+ int y = (int) (visY - (yIncrement * k));
+
+ int bytes = (int)(yIncrement * multiplier) * k;
+
+ String legend = "";
+
+ if (maxBytes < 10000)
+ {
+ legend += bytes + " B"; //$NON-NLS-1$
+ }
+ else if (maxBytes <= 500 * 1024)
+ {
+ legend += (bytes / 1024) + " KB"; //$NON-NLS-1$
+ }
+ else
+ {
+ legend += MBformat.format(((float) bytes / (1024 * 1024))) + " MB"; //$NON-NLS-1$
+ }
+ Point extent = gc.stringExtent(legend);
+
+ gc.drawLine(CommonGraphConstants.YLEGENDSPACE - 3, (int)y + 1, CommonGraphConstants.YLEGENDSPACE, (int)y + 1);
+
+ if (y >= previousBottom)
+ {
+ gc.drawString(legend, CommonGraphConstants.YLEGENDSPACE - extent.x -2, (int)y);
+ previousBottom = (int)y + extent.y;
+ }
+ }
+
+ final Image image = this.getVerticalLabel("Bytes");
+ gc.setAdvanced(true);
+ final org.eclipse.swt.graphics.Rectangle rect2 = image.getBounds();
+ Transform transform = new Transform(Display.getDefault());
+
+ transform.translate(rect2.height / 2f, rect2.width / 2f);
+ transform.rotate(-90);
+ transform.translate(-rect2.width / 2f, -rect2.height / 2f);
+
+ gc.setTransform(transform);
+ gc.drawImage(image, -(int)visY/3, 1);
+
+ transform.dispose();
+ gc.dispose();
+
+ }
+
+ /* (non-Javadoc)
+ * @see com.nokia.s60tools.swmtanalyser.ui.graphs.GenericGraph#prepareData()
+ */
+ public void prepareData() {
+
+ EventTypes event = this.getEvent();
+ if(this.getEvent().equals(EventTypes.RAM_USED) || this.getEvent().equals(EventTypes.RAM_TOTAL))
+ {
+ SWMTLogReaderUtils utils = new SWMTLogReaderUtils();
+
+ sysData = utils.getSystemDataFromAllCycles(this.getCyclesData());
+ int [] eventVals;
+
+ switch(event)
+ {
+ case RAM_USED:
+ eventVals = getRamUsedMemFromSysData(sysData);
+ break;
+ case RAM_TOTAL:
+ eventVals = getRamTotalMemFromSysData(sysData);
+ break;
+ default:
+ eventVals = new int[1];
+ break;
+ }
+
+ int maxValue = calculateMaxValue(eventVals);
+
+ if(maxValue > maxBytes){
+ maxBytes = maxValue;
+ }
+
+ return;
+ }
+ fetchEntireDataForSelectedDisks();
+
+ for(String disk:getUserSelectedItems())
+ {
+ ArrayList<DiskOverview> data = totalDiskData.get(disk);
+
+ int[] eventValues = new int[data.size()];
+ for(int i =0; i<data.size(); i++)
+ {
+ eventValues[i] = getEventValueFromDisksData(data.get(i), event);
+
+ int maxValue = calculateMaxValue(eventValues);
+
+ if(maxValue > maxBytes){
+ maxBytes = maxValue;
+ }
+ }
+
+ }
+
+ }
+
+ private void fetchEntireDataForSelectedDisks()
+ {
+ ArrayList<String> selectedDisks = this.getUserSelectedItems();
+
+ SWMTLogReaderUtils utils = new SWMTLogReaderUtils();
+
+ for(String disk:selectedDisks)
+ {
+ ArrayList<DiskOverview> diskData = utils.getUsedMemoryAndSizesForDisk(disk, this.getCyclesData());
+ totalDiskData.put(disk, diskData);
+ }
+ }
+
+ private int getEventValueFromDisksData(DiskOverview diskData, EventTypes event)
+ {
+ int value = 0;
+
+ switch(event)
+ {
+ case DISK_USED_SIZE:
+ value = (int) diskData.getUsedSize();
+ break;
+ case DISK_TOTAL_SIZE:
+ value = (int) diskData.getSize();
+ break;
+ default:
+ value = 0;
+ break;
+ }
+
+ return value;
+ }
+
+ /* (non-Javadoc)
+ * @see com.nokia.s60tools.swmtanalyser.ui.graphs.GenericGraph#getToolTipText(int, int)
+ */
+ public String getToolTipText(int x, int y)
+ {
+ if(y > (int)visY)
+ return null;
+
+ String text = "";
+ double xValue = x + timeOffset;
+ int scaledX = (int)(xValue * getScale());
+
+ double valY = visY - y;
+ double bytes = valY * multiplier;
+
+ String scaledY = "";
+
+ if (bytes < 10000)
+ {
+ scaledY += Bytes_Format.format(bytes) + " B"; //$NON-NLS-1$
+ }
+ else if (bytes <= 500 * 1024)
+ {
+ scaledY += Bytes_Format.format(bytes / 1024) + " KB"; //$NON-NLS-1$
+ }
+ else
+ {
+ scaledY += MBformat.format(((float) bytes / (1024 * 1024))) + " MB"; //$NON-NLS-1$
+ }
+ text += scaledX + " s, " + scaledY;
+
+ if(this.getEvent().equals(EventTypes.RAM_USED))
+ {
+ Polyline line = pointsData.get("RAM Used");
+
+ if(line != null && line.containsPoint(x, y))
+ text += "\n RAM Used";
+ }
+ else if (this.getEvent().equals(EventTypes.RAM_TOTAL))
+ {
+ Polyline line = pointsData.get("RAM Total");
+
+ if(line != null && line.containsPoint(x, y))
+ text += "\n RAM Total";
+ }
+ else
+ {
+ for(String disk: getUserSelectedItems())
+ {
+ Polyline line = pointsData.get(disk);
+
+ if(line != null && line.containsPoint(x, y))
+ text += "\n" + disk;
+ }
+ }
+
+ return text;
+ }
+
+
+ private int [] getRamUsedMemFromSysData(ArrayList<SystemData> sysData)
+ {
+ Ram_Used_Values = new int[sysData.size()];
+
+ for(int i=0; i<sysData.size(); i++)
+ {
+ SystemData currentData = sysData.get(i);
+ Ram_Used_Values[i] = (int) (currentData.getTotalMemory() - currentData.getFreeMemory());
+ }
+
+ return Ram_Used_Values;
+ }
+
+ private int [] getRamTotalMemFromSysData(ArrayList<SystemData> sysData)
+ {
+ Ram_Total_Values = new int[sysData.size()];
+
+ for(int i=0; i<sysData.size(); i++)
+ {
+ SystemData currentData = sysData.get(i);
+ Ram_Total_Values[i] = (int) (currentData.getTotalMemory());
+ }
+
+ return Ram_Total_Values;
+ }
+
+ /**
+ * Get {@link DiskOverview} data for given disk name
+ * @param diskName
+ * @return data for given disk name
+ */
+ public ArrayList<DiskOverview> getDiskData(String diskName)
+ {
+ return totalDiskData.get(diskName);
+ }
+
+ /**
+ * Get {@link SystemData}
+ * @return system data
+ */
+ public ArrayList<SystemData> getSystemData()
+ {
+ return sysData;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/ui/graphs/GenericGraph.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,385 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+package com.nokia.s60tools.swmtanalyser.ui.graphs;
+
+import java.text.DecimalFormat;
+import java.util.ArrayList;
+
+import org.eclipse.draw2d.FigureCanvas;
+import org.eclipse.draw2d.Graphics;
+import org.eclipse.draw2d.geometry.Rectangle;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.widgets.Display;
+
+import com.nokia.s60tools.swmtanalyser.data.CycleData;
+import com.nokia.s60tools.swmtanalyser.data.KernelElements;
+import com.nokia.s60tools.swmtanalyser.data.ParsedData;
+import com.nokia.s60tools.swmtanalyser.model.SWMTLogReaderUtils;
+
+public abstract class GenericGraph {
+
+ //
+ // Constants
+ //
+
+ /**
+ * Mega Byte format
+ */
+ protected static final DecimalFormat MBformat = new DecimalFormat("#####.0");
+ /**
+ * Byte format
+ */
+ protected static final DecimalFormat Bytes_Format = new DecimalFormat("#####.##");
+ /**
+ * Label for time in X axis
+ */
+ protected static final String TIME_X_AXIS_LABEL = "Time (h:min:s)";
+
+ //
+ // Members
+ //
+ private EventTypes event;
+ private ArrayList<String> userSelectedItems;
+ private ArrayList<Color> colors;
+ private ParsedData parsedData;
+ private double scale = 1.0;
+
+
+ protected int maxBytes = 10;
+ protected int[] valuesToBePlotted = null;
+ protected int lastSampleTime = 0;
+ protected int visualSizeY = 0;
+ protected int timeOffset = 0;
+
+ /**
+ * Event types to map the event names into corresponding event enumerators.
+ * @see com.nokia.s60tools.swmtanalyser.ui.graphs.GraphsUtils#EVENT_NAMES_ARR
+ */
+ public enum EventTypes {GLOBAL_DATA_SIZE, NON_HEAP_CHUNK_SIZE, DISK_USED_SIZE, DISK_TOTAL_SIZE, NO_OF_FILES, MAX_HEAP_SIZE, HEAP_SIZE, HEAP_ALLOC_SPACE, HEAP_FREE_SPACE, HEAP_ALLOC_CELL_COUNT, HEAP_FREE_CELL_COUNT, HEAP_FREE_SLACK, NO_OF_PSHANDLES, RAM_USED, RAM_TOTAL, SYSTEM_DATA};
+
+ private static ArrayList<String> graphableKernels = new ArrayList<String>();
+
+ /**
+ * Get graphable kernels
+ * @return the graphable kernels
+ */
+ public static ArrayList<String> getGraphableKernels() {
+ return graphableKernels;
+ }
+
+ static{
+ graphableKernels.add("Number of Processes");
+ graphableKernels.add("Number of Threads");
+ graphableKernels.add("Number of Timers");
+ graphableKernels.add("Number of Semaphores");
+ graphableKernels.add("Number of Servers");
+ graphableKernels.add("Number of Sessions");
+ graphableKernels.add("Number of Chunks");
+ graphableKernels.add("Number of Msg. Queues");
+ }
+
+ /**
+ * Get cycles data
+ * @return cycle data
+ */
+ public ParsedData getCyclesData() {
+ return parsedData;
+ }
+
+ /**
+ * Set cycles data
+ * @param parsedData
+ */
+ public void setCyclesData(ParsedData parsedData) {
+ this.parsedData = parsedData;
+ }
+
+ /**
+ * Get event
+ * @return event
+ */
+ public EventTypes getEvent() {
+ return event;
+ }
+
+ /**
+ * Set event
+ * @param event
+ */
+ public void setEvent(EventTypes event) {
+ this.event = event;
+ }
+
+ /**
+ * Get items that user has been selected
+ * @return selected items
+ */
+ public ArrayList<String> getUserSelectedItems() {
+ return userSelectedItems;
+ }
+
+ /**
+ * Set items that user has been selected
+ * @param userSelectedItems
+ */
+ public void setUserSelectedItems(ArrayList<String> userSelectedItems) {
+ this.userSelectedItems = userSelectedItems;
+ }
+
+ /**
+ * Draw contents to drawn area
+ * @param graphics
+ */
+ public abstract void paint(Graphics graphics);
+ /**
+ * Prepare data for drawing
+ */
+ public abstract void prepareData();
+ /**
+ * Draw headers to Y axis
+ * @param gc
+ */
+ public abstract void paintYAxis(GC gc);
+ /**
+ * Get tool tip text for coordinates
+ * @param x
+ * @param y
+ * @return tooltip text
+ */
+ public abstract String getToolTipText(int x, int y);
+
+ /**
+ * Draw lines to background
+ * @param canvas
+ * @param graphics
+ */
+ public void drawBackGroundLines(FigureCanvas canvas, Graphics graphics)
+ {
+ Rectangle canvasRect = graphics.getClip(new org.eclipse.draw2d.geometry.Rectangle());
+ graphics.setForegroundColor(new Color(Display.getDefault(), new RGB(200, 200, 200)));
+ graphics.setBackgroundColor(new Color(Display.getDefault(), new RGB(170,170,170)));
+
+ int height = canvas.getClientArea().height;
+ int width = canvas.getClientArea().width;
+
+ graphics.fillRectangle(new Rectangle(canvasRect.x,0,width, height-50));
+
+ double visY = height - CommonGraphConstants.XLEGENDSPACE;
+
+ int k = 0;
+
+ for (float y = 0; k <= 10; y += visY * 10000 / 100001, k++)
+ {
+ for (int x = canvasRect.x; x <= canvasRect.x + canvasRect.width; x += 5)
+ {
+ if ((x / 5) % 2 == 0) graphics.drawLine(x, ((int)y) + 1, x + 5, ((int)y) + 1);
+ }
+ }
+
+ graphics.setForegroundColor(new Color(Display.getDefault(), new RGB(100, 100, 100)));
+ graphics.setBackgroundColor(new Color(Display.getDefault(),new RGB(255, 255, 255)));
+
+ // horizontal lines
+ if (width > 0)
+ {
+ for (int x = 0; x <= canvasRect.x + canvasRect.width; x += 50)
+ {
+ if (x % 100 == 0)
+ graphics.setForegroundColor(new Color(Display.getDefault(), new RGB(100, 100, 100)));
+ else
+ graphics.setForegroundColor(new Color(Display.getDefault(),new RGB(200, 200, 200)));
+
+ for (int y = 0; y < height; y += 5)
+ {
+ if ((y / 5) % 2 == 0)
+ graphics.drawLine(x, y, x, y + 5);
+ }
+ }
+ }
+
+ graphics.setForegroundColor(new Color(Display.getDefault(), new RGB(100, 100, 100)));
+ graphics.setBackgroundColor(new Color(Display.getDefault(),new RGB(255, 255, 255)));
+
+ for (int x = 0; x <= canvasRect.x + canvasRect.width; x += 50)
+ {
+ double time = (double) x;
+ TimeObject timeObj = new TimeObject(time, scale);
+ graphics.drawString(timeObj.getHourMinutesAndSeconds(), x + 5, height - 13);
+ if(timeObj.hasDays()){
+ graphics.drawString(timeObj.getDays(), x + 5, height - 26);
+ }
+ }
+ Image img = getVerticalLabel(TIME_X_AXIS_LABEL);
+ graphics.drawImage(img, width/2, height-30);
+ }
+
+ /**
+ * Called when horizontal bar is moved in graphs, to set X location of current selection.
+ * @param x X-location of {@link org.eclipse.draw2d.geometry.Point}
+ */
+ public void setScrolledXOrigin(int x)
+ {
+ this.timeOffset = x;
+ }
+
+ /**
+ * Get cycle times from parsed data
+ * @return list of times
+ */
+ protected int [] calculateTimeIntervals()
+ {
+ int [] time = new int[parsedData.getNumberOfCycles()];
+ int prevDuration = 0;
+ time[0] = 0;
+
+ SWMTLogReaderUtils utils = new SWMTLogReaderUtils();
+
+ CycleData [] cycles = parsedData.getLogData();
+ for(int i=1; i<parsedData.getNumberOfCycles();i++)
+ {
+ String currentTime = cycles[i].getTime();
+ String prevTime = cycles[i-1].getTime();
+ int timeDiff = (int)utils.getDurationInSeconds(prevTime, currentTime);
+
+ if(timeDiff < 0)
+ {
+ //error condition
+ }
+ else
+ {
+ timeDiff += prevDuration;
+ prevDuration = timeDiff;
+
+ time[i] = timeDiff;
+ }
+
+ }
+
+ return time;
+ }
+
+ /**
+ * Get largest value from given items
+ * @param values
+ * @return largest value found
+ */
+ protected int calculateMaxValue(int [] values)
+ {
+ int maxValue = 0;
+
+ for(int i=0; i<values.length; i++)
+ {
+ if(values[i] > maxValue)
+ maxValue = values[i];
+ }
+
+ return maxValue;
+ }
+
+ /**
+ * Get colors
+ * @return colors
+ */
+ public ArrayList<Color> getColors() {
+ return colors;
+ }
+
+ /**
+ * Set colors
+ * @param colors
+ */
+ public void setColors(ArrayList<Color> colors) {
+ this.colors = colors;
+ }
+
+ /**
+ * Get label for vertical axis
+ * @param name
+ * @return label
+ */
+ protected Image getVerticalLabel(String name)
+ {
+ return GraphsUtils.getVerticalLabel(name, 110, 15, 9);
+ }
+
+ /**
+ * Get scale
+ * @return scale
+ */
+ public double getScale() {
+ return scale;
+ }
+
+ /**
+ * Set scale
+ * @param scale
+ */
+ public void setScale(double scale) {
+ this.scale = scale;
+ }
+
+ /**
+ * Set visual size
+ * @param height
+ */
+ public void setVisualSize(int height)
+ {
+ this.visualSizeY = height;
+ }
+
+ /**
+ * Get count for wanted item
+ * @param item
+ * @param kernelsList
+ * @return count of items wanted
+ */
+ protected int [] getValuesForGivenKerenelElement(String item, ArrayList<KernelElements> kernelsList)
+ {
+ int [] values = new int[kernelsList.size()];
+
+ int index = graphableKernels.indexOf(item);
+
+ for(int i=0; i<kernelsList.size(); i++)
+ {
+ KernelElements kernels = kernelsList.get(i);
+
+ if(index == 0)
+ values [i] = kernels.getNumberOfProcesses();
+ else if(index == 1)
+ values[i] = kernels.getNumberOfThreads();
+ else if(index == 2)
+ values [i] = kernels.getNumberOfTimers();
+ else if(index == 3)
+ values [i] = kernels.getNumberOfSemaphores();
+ else if(index == 4)
+ values [i] = kernels.getNumberOfServers();
+ else if(index == 5)
+ values [i] = kernels.getNumberOfSessions();
+ else if(index == 6)
+ values [i] = kernels.getNumberOfChunks();
+ else if(index == 7)
+ values [i] = kernels.getNumberOfMsgQueues();
+
+ }
+
+ return values;
+
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/ui/graphs/GraphForAllEvents.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,1514 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+package com.nokia.s60tools.swmtanalyser.ui.graphs;
+
+import java.text.DecimalFormat;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+import org.eclipse.draw2d.ColorConstants;
+import org.eclipse.draw2d.FigureCanvas;
+import org.eclipse.draw2d.FlowLayout;
+import org.eclipse.draw2d.Graphics;
+import org.eclipse.draw2d.Panel;
+import org.eclipse.draw2d.Polyline;
+import org.eclipse.draw2d.geometry.PointList;
+import org.eclipse.draw2d.geometry.Rectangle;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.action.IMenuListener;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.action.Separator;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ControlAdapter;
+import org.eclipse.swt.events.ControlEvent;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.MouseMoveListener;
+import org.eclipse.swt.events.PaintEvent;
+import org.eclipse.swt.events.PaintListener;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Drawable;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.graphics.Transform;
+import org.eclipse.swt.layout.FormAttachment;
+import org.eclipse.swt.layout.FormData;
+import org.eclipse.swt.layout.FormLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swt.widgets.ScrollBar;
+
+import com.nokia.s60tools.swmtanalyser.data.ChunksData;
+import com.nokia.s60tools.swmtanalyser.data.CycleData;
+import com.nokia.s60tools.swmtanalyser.data.DiskOverview;
+import com.nokia.s60tools.swmtanalyser.data.GlobalDataChunks;
+import com.nokia.s60tools.swmtanalyser.data.KernelElements;
+import com.nokia.s60tools.swmtanalyser.data.ParsedData;
+import com.nokia.s60tools.swmtanalyser.data.SystemData;
+import com.nokia.s60tools.swmtanalyser.data.ThreadData;
+import com.nokia.s60tools.swmtanalyser.editors.GraphedItemsInput;
+import com.nokia.s60tools.swmtanalyser.model.SWMTLogReaderUtils;
+import com.nokia.s60tools.swmtanalyser.ui.graphs.GenericGraph.EventTypes;
+import com.nokia.s60tools.ui.IImageProvider;
+import com.nokia.s60tools.ui.actions.CopyImageToClipboardAction;
+import com.nokia.s60tools.util.debug.DbgUtility;
+
+/**
+ * Graphs to be shown in Graphed items -tab when Graphs-tab is active.
+ */
+public class GraphForAllEvents extends ZoomableGraph implements MouseMoveListener, IImageProvider {
+
+ //
+ // Constants
+ //
+
+ /**
+ * Marking data points that are not really drawn with zero values.
+ */
+ private static final int NOT_DRAWN_DATA_POINT = -1;
+
+ //
+ // Members
+ //
+ private Composite parentComposite;
+
+ private HashMap<String, ArrayList<ThreadData>> heapData = new HashMap<String, ArrayList<ThreadData>>();
+ private HashMap<String, ArrayList<GlobalDataChunks>> globalDataChunks = new HashMap<String, ArrayList<GlobalDataChunks>>();
+ private HashMap<String, ArrayList<ChunksData>> nonHeapChnksData = new HashMap<String, ArrayList<ChunksData>>();
+ private HashMap<String, ArrayList<DiskOverview>> disksData = new HashMap<String, ArrayList<DiskOverview>>();
+ private HashMap<GraphedItemsInput, int []> valuesForSelectedItems = new HashMap<GraphedItemsInput, int[]>();
+ private HashMap<GraphedItemsInput, Polyline> pointsData = new HashMap<GraphedItemsInput, Polyline>();
+
+ private ArrayList<SystemData> systemData = new ArrayList<SystemData>();
+ private ArrayList<KernelElements> kernelData = new ArrayList<KernelElements>();
+
+ private ArrayList<GraphedItemsInput> graphedItemsInput = new ArrayList<GraphedItemsInput>();
+ private ParsedData parsedData = new ParsedData();
+
+ private FigureCanvas yAxis;
+ private int maxBytes = 10;
+ private int maxCount = 10;
+ private double scale = 1.0;
+ private int timeOffset = 0;
+
+ private double visY;
+ private FigureCanvas figureCanvas;
+
+ private static DecimalFormat MBformat = new DecimalFormat("#####.0");
+ private static DecimalFormat Bytes_Format = new DecimalFormat("#####.##");
+
+ private int [] timeSamples;
+ private int lastTimeSample;
+ private FigureCanvas numberAxis;
+
+ private boolean scalingNeeded;
+
+ private IAction showEntireGraph;
+ private IAction saveGraph;
+
+ /**
+ * Constructor
+ * @param composite
+ */
+ public GraphForAllEvents(Composite composite)
+ {
+ this.parentComposite = composite;
+ }
+
+ /**
+ * Set graphed items
+ * @param input
+ */
+ public void setGraphedItemsInput(ArrayList<GraphedItemsInput> input)
+ {
+ this.graphedItemsInput = input;
+ }
+ /**
+ * Set heap data
+ * @param thName
+ * @param values
+ */
+ public void setHeapSizeForThread(String thName, ArrayList<ThreadData> values)
+ {
+ heapData.put(thName, values);
+ }
+
+ /**
+ * Set global data chunks
+ * @param chnkName
+ * @param values
+ */
+ public void setGlobalChunkSizeForChunk(String chnkName, ArrayList<GlobalDataChunks> values)
+ {
+ globalDataChunks.put(chnkName, values);
+ }
+
+ /**
+ * Set non heap chunk data
+ * @param chnkName
+ * @param values
+ */
+ public void setNonHeapChunkSizeForChunk(String chnkName, ArrayList<ChunksData> values)
+ {
+ nonHeapChnksData.put(chnkName, values);
+ }
+
+ /**
+ * Set disk data
+ * @param diskName
+ * @param values
+ */
+ public void setDiskData(String diskName, ArrayList<DiskOverview> values)
+ {
+ disksData.put(diskName, values);
+ }
+
+ /**
+ * Set cycles data
+ * @param cyclesData
+ */
+ public void setInputCyclesData(ParsedData cyclesData)
+ {
+ this.parsedData = cyclesData;
+ timeSamples = this.calculateTimeIntervals();
+ lastTimeSample = timeSamples[timeSamples.length-1];
+ }
+
+ /**
+ * Set kernel data
+ * @param kernelData
+ */
+ public void setKernelData(ArrayList<KernelElements> kernelData)
+ {
+ this.kernelData = kernelData;
+ }
+
+ /**
+ * Set System data
+ * @param sysData
+ */
+ public void setSystemData(ArrayList<SystemData> sysData)
+ {
+ this.systemData = sysData;
+ }
+
+ /**
+ * Create Graphed items area
+ */
+ public void constructGraphArea()
+ {
+ //Prepare data
+ prepareData();
+
+ if(parsedData == null || parentComposite == null)
+ return;
+
+ Control [] children = parentComposite.getChildren();
+
+ if(children != null)
+ {
+ for(Control child:children)
+ child.dispose();
+ }
+
+ scalingNeeded = true;
+ timeOffset = 0;
+
+ Composite parent = new Composite(parentComposite, SWT.NONE);
+ parent.setLayout(new FormLayout());
+
+ yAxis = new FigureCanvas(parent);
+
+ numberAxis = new FigureCanvas(parent);
+ figureCanvas = new FigureCanvas(parent);
+ FormData formData = new FormData();
+ formData.top = new FormAttachment(0);
+ formData.bottom = new FormAttachment(100);
+ formData.left = new FormAttachment(0);
+ formData.width = 50;
+ numberAxis.setLayoutData(formData);
+
+ formData = new FormData();
+ formData.top = new FormAttachment(0);
+ formData.bottom = new FormAttachment(100);
+ formData.left = new FormAttachment(numberAxis);
+ formData.width = 60;
+ yAxis.setLayoutData(formData);
+
+ formData = new FormData();
+ formData.top = new FormAttachment(0);
+ formData.bottom = new FormAttachment(100);
+ formData.left = new FormAttachment(yAxis, 0, SWT.RIGHT);
+ formData.right = new FormAttachment(100);
+
+ figureCanvas.setLayoutData(formData);
+
+ yAxis.setBackground(ColorConstants.white);
+ numberAxis.setBackground(ColorConstants.white);
+
+ yAxis.addPaintListener(new PaintListener()
+ {
+ public void paintControl(PaintEvent event) {
+ GC localGC = event.gc;
+
+ org.eclipse.swt.graphics.Rectangle rect = figureCanvas.getClientArea();
+
+ visY = rect.height - CommonGraphConstants.XLEGENDSPACE;
+
+ int countOfYAxisLabels = 10;
+ double yIncrement = visY / countOfYAxisLabels;
+ int previousBottom = 0;
+
+ double multiplier = GraphsUtils.prettyMaxBytes(maxBytes)/visY;
+
+ for (int k = countOfYAxisLabels; k >= 0; k--)
+ {
+ // location for the value indicator is k * 1/10 the height of the display
+ int y = (int) (visY - (yIncrement * k));
+
+ int bytes = (int)(yIncrement * multiplier) * k;
+ String legend = "";
+
+ if (maxBytes < 10000)
+ {
+ legend += bytes + " B"; //$NON-NLS-1$
+ }
+ else if (maxBytes <= 500 * 1024)
+ {
+ legend += (bytes / 1024) + " KB"; //$NON-NLS-1$
+ }
+ else
+ {
+ legend += MBformat.format(((float) bytes / (1024 * 1024))) + " MB"; //$NON-NLS-1$
+ }
+
+ Point extent = localGC.stringExtent(legend);
+
+ localGC.drawLine(CommonGraphConstants.YLEGENDSPACE - 3, (int)y + 1, 60, (int)y + 1);
+
+ if (y >= previousBottom)
+ {
+ localGC.drawString(legend, 60 - extent.x -2, (int)y);
+ previousBottom = (int)y + extent.y;
+ }
+ }
+ localGC.setLineWidth(2);
+ localGC.drawLine(CommonGraphConstants.YLEGENDSPACE, 0, 60, rect.height);
+
+ final Image image = GraphsUtils.getDoubleYAxisVerticalLabel("Bytes");
+
+ localGC.setAdvanced(true);
+ final org.eclipse.swt.graphics.Rectangle rect2 = image.getBounds();
+ Transform transform = new Transform(Display.getDefault());
+
+ transform.translate(rect2.height / 2f, rect2.width / 2f);
+ transform.rotate(-90);
+ transform.translate(-rect2.width / 2f, -rect2.height / 2f);
+
+ localGC.setTransform(transform);
+ localGC.drawImage(image, -(int)visY/3, 1);
+
+ transform.dispose();
+ localGC.dispose();
+ }
+ });
+
+ numberAxis.addPaintListener(new PaintListener()
+ {
+ public void paintControl(PaintEvent event) {
+
+ GC localGC = event.gc;
+ org.eclipse.swt.graphics.Rectangle rect = figureCanvas.getClientArea();
+ visY = rect.height - CommonGraphConstants.XLEGENDSPACE;
+ double yIncrement = visY / 10;
+ int previousBottom = 0;
+ double multiplier = GraphsUtils.roundToNearestNumber(maxCount)/visY;
+
+ for (int k = 10; k >= 0; k--)
+ {
+ // location for the value indicator is k * 1/10 the height of the display
+ int y = (int) (visY - (yIncrement * k));
+ int yValue = (int)(yIncrement * multiplier) * k;
+ String legend = yValue + "";
+ Point extent = localGC.stringExtent(legend);
+ localGC.drawLine(50 - 3, (int)y + 1, 50, (int)y + 1);
+ if (y >= previousBottom)
+ {
+ localGC.drawString(legend, 50 - extent.x -2, (int)y);
+ previousBottom = (int)y + extent.y;
+ }
+ }
+ localGC.setLineWidth(2);
+ localGC.drawLine(50, 0, 50, rect.height);
+
+ final Image image = GraphsUtils.getDoubleYAxisVerticalLabel("Count");
+ localGC.setAdvanced(true);
+ final org.eclipse.swt.graphics.Rectangle rect2 = image.getBounds();
+ Transform transform = new Transform(Display.getDefault());
+
+ transform.translate(rect2.height / 2f, rect2.width / 2f);
+ transform.rotate(-90);
+ transform.translate(-rect2.width / 2f, -rect2.height / 2f);
+
+ localGC.setTransform(transform);
+ localGC.drawImage(image, -(int)visY/3, 10);
+
+ transform.dispose();
+ localGC.dispose();
+
+ }
+ });
+
+
+ figureCanvas.setBackground(ColorConstants.white);
+ Panel panel = new Panel()
+ {
+ public void paint(Graphics graphics)
+ {
+ DbgUtility.println(DbgUtility.PRIORITY_LOOP, "GraphForAllEvents/Panel/paint START");
+
+ drawBackGroundLines(figureCanvas,graphics);
+ paintData(graphics);
+
+ DbgUtility.println(DbgUtility.PRIORITY_LOOP, "GraphForAllEvents/Panel/paint END");
+
+ }
+ };
+
+ panel.setLayoutManager(new FlowLayout());
+ figureCanvas.setContents(panel);
+ figureCanvas.addMouseMoveListener(this);
+
+ final ScrollBar horizontalBar = figureCanvas.getHorizontalBar();
+ horizontalBar.addSelectionListener(new SelectionListener()
+ {
+
+ public void widgetDefaultSelected(SelectionEvent arg0) {
+
+ }
+
+ public void widgetSelected(SelectionEvent event) {
+ timeOffset = figureCanvas.getViewport().getViewLocation().x;
+ figureCanvas.redraw();
+
+ }
+
+ });
+
+ figureCanvas.addControlListener(new ControlAdapter()
+ {
+ public void controlResized(ControlEvent e) {
+ horizontalBar.setPageIncrement(figureCanvas.getBounds().width);
+
+ if(scalingNeeded)
+ {
+ zoomGraph();
+ scalingNeeded = false;
+ }
+ yAxis.redraw();
+ numberAxis.redraw();
+ figureCanvas.redraw();
+
+ }
+ });
+
+ zoomGraph();
+ hookContextMenu();
+ parentComposite.layout(true);
+ }
+
+ /**
+ * Adds Pop-Up menu items on th graph area.
+ *
+ */
+ private void hookContextMenu() {
+ MenuManager menuMgr = new MenuManager("#PopupMenu"); //$NON-NLS-1$
+ menuMgr.setRemoveAllWhenShown(true);
+ menuMgr.addMenuListener(new IMenuListener() {
+ public void menuAboutToShow(IMenuManager manager) {
+ fillContextMenu(manager);
+ }
+ });
+ Menu menu = menuMgr.createContextMenu(figureCanvas);
+ figureCanvas.setMenu(menu);
+ }
+
+ protected void fillContextMenu(IMenuManager manager) {
+ zoomIn = new Action()
+ {
+ public void run()
+ {
+ zoomIn();
+ }
+ {
+ this.setText(ZOOM_IN_CONTEXT_MENU_TITLE);
+ }
+ };
+
+ zoomOut = new Action()
+ {
+ public void run()
+ {
+ zoomOut();
+ }
+ {
+ this.setText(ZOOM_OUT_CONTEXT_MENU_TITLE);
+ }
+ };
+ showEntireGraph = new Action()
+ {
+ public void run()
+ {
+ zoomGraph();
+ }
+ {
+ this.setText(CommonGraphConstants.SHOW_ENTIRE_GRAPH_CONTEXT_MENU_ITEM_TITLE);
+ }
+ };
+
+ saveGraph = new Action()
+ {
+ public void run()
+ {
+ GraphsUtils.saveGraph(parentComposite);
+ }
+ {
+ this.setText(CommonGraphConstants.SAVE_GRAPH_CONTEXT_MENU_ITEM_TITLE);
+ }
+ };
+
+
+ copy = new CopyImageToClipboardAction(this);
+
+ manager.add(zoomIn);
+ manager.add(new Separator());
+ manager.add(zoomOut);
+ manager.add(new Separator());
+ manager.add(showEntireGraph);
+ manager.add(saveGraph);
+ manager.add(copy);
+
+ // Finally updating action states
+ updateViewActionEnabledStates();
+
+ }
+
+ /**
+ * Sets enabled/disabled states for actions commands
+ * on this view, based on the current application state.
+ * This method should be called whenever an operation is
+ * started or stopped that might have effect on action
+ * button states.
+ */
+ private void updateViewActionEnabledStates() {
+ setEnableState(zoomIn, !(this.scale == GraphsUtils.nextScale(scale, false)));
+ boolean zoomOutEnableCondition1 = !(this.scale == GraphsUtils.nextScale(scale, true));
+ boolean zoomOutEnableCondition2 = !(this.lastTimeSample / this.scale <= figureCanvas.getClientArea().width);
+ setEnableState(zoomOut, zoomOutEnableCondition1 && zoomOutEnableCondition2);
+ }
+
+ /* (non-Javadoc)
+ * @see com.nokia.s60tools.swmtanalyser.ui.graphs.ZoomableGraph#zoomIn()
+ */
+ protected void zoomIn()
+ {
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "GraphForAllEvents - Zoom In");
+ //Preconditions checked already in updateViewActionEnabledStates
+ this.scale = GraphsUtils.nextScale(scale, false);
+ figureCanvas.redraw();
+ setNewSize();
+ }
+
+ /* (non-Javadoc)
+ * @see com.nokia.s60tools.swmtanalyser.ui.graphs.ZoomableGraph#zoomOut()
+ */
+ protected void zoomOut()
+ {
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "GraphForAllEvents - Zoom Out");
+ //Preconditions checked already in updateViewActionEnabledStates
+ this.scale = GraphsUtils.nextScale(this.scale, true);
+ setNewSize();
+ }
+
+ /**
+ * This method zoom in the graph area to the maximum possible scale
+ * and then zooms out, so that it fits in the canvas area
+ */
+ private void zoomGraph()
+ {
+ int width = figureCanvas.getClientArea().width;
+
+ if(width <=0 )
+ return;
+
+ double new_scale = this.scale;
+
+ double prevNew = new_scale;
+
+ //first zoom in until it is too big to fit
+ while (this.lastTimeSample / new_scale <= width)
+ {
+ new_scale = GraphsUtils.nextScale(new_scale, false);
+
+ if(prevNew == new_scale)
+ break;
+
+ prevNew = new_scale;
+ }
+ // now zoom out until it just fits
+ while (this.lastTimeSample / new_scale > width)
+ {
+ new_scale = GraphsUtils.nextScale(new_scale, true);
+
+ if(prevNew == new_scale)
+ break;
+
+ prevNew = new_scale;
+ }
+
+ if (new_scale == this.scale)
+ return;
+
+ this.scale = new_scale;
+ setNewSize();
+ }
+
+ /**
+ * This method sets the size of the panel, when scale is changed.
+ * When graph extends beyond visible area, horizontal scroll bar appears automatically.
+ */
+ private void setNewSize()
+ {
+ int lastSample = this.lastTimeSample;
+
+ int prefSize = (int)(lastSample/scale);
+
+ timeOffset = 0;
+ Panel panel = (Panel)(figureCanvas.getContents());
+ panel.setPreferredSize(prefSize + 100, 0);
+
+ if (prefSize >= figureCanvas.getClientArea().width) {
+ timeOffset = figureCanvas.getViewport().getViewLocation().x;
+ panel.setSize(prefSize + 100, 0);
+ }
+
+ }
+
+ /**
+ * @param canvas
+ * @param graphics
+ */
+ private void drawBackGroundLines(FigureCanvas canvas, Graphics graphics)
+ {
+ Rectangle canvasRect = graphics.getClip(new org.eclipse.draw2d.geometry.Rectangle());
+ graphics.setForegroundColor(new Color(Display.getDefault(), new RGB(200, 200, 200)));
+ graphics.setBackgroundColor(new Color(Display.getDefault(), new RGB(170,170,170)));
+
+ int height = canvas.getClientArea().height;
+ int width = canvas.getClientArea().width;
+
+ graphics.fillRectangle(new Rectangle(canvasRect.x,0,width, height-50));
+
+ double visY = height - CommonGraphConstants.XLEGENDSPACE;
+
+ int k = 0;
+
+ for (float y = 0; k <= 10; y += visY * 10000 / 100001, k++)
+ {
+ for(int x = canvasRect.x; x <= canvasRect.x + canvasRect.width; x += 5)
+ {
+ if ((x / 5) % 2 == 0) graphics.drawLine(x, ((int)y) + 1, x + 5, ((int)y) + 1);
+ }
+ }
+
+ graphics.setForegroundColor(new Color(Display.getDefault(), new RGB(100, 100, 100)));
+ graphics.setBackgroundColor(new Color(Display.getDefault(),new RGB(255, 255, 255)));
+
+ // horizontal lines
+ if (width > 0)
+ {
+ for (int x = 0; x <= canvasRect.x + canvasRect.width; x += 50)
+ {
+ if (x % 100 == 0)
+ graphics.setForegroundColor(new Color(Display.getDefault(), new RGB(100, 100, 100)));
+ else
+ graphics.setForegroundColor(new Color(Display.getDefault(),new RGB(200, 200, 200)));
+
+ for (int y = 0; y < height; y += 5)
+ {
+ if ((y / 5) % 2 == 0)
+ graphics.drawLine(x, y, x, y + 5);
+ }
+
+ }
+ }
+
+ graphics.setForegroundColor(new Color(Display.getDefault(), new RGB(100, 100, 100)));
+ graphics.setBackgroundColor(new Color(Display.getDefault(),new RGB(255, 255, 255)));
+
+ for (int x = 0; x <= canvasRect.x + canvasRect.width; x += 50)
+ {
+ double time = (double) x;
+ TimeObject timeObj = new TimeObject(time, scale);
+ graphics.drawString(timeObj.getHourMinutesAndSeconds(), x + 5, height - 13);
+ if(timeObj.hasDays()){
+ graphics.drawString(timeObj.getDays(), x + 5, height - 26);
+ }
+ }
+ Image img = GraphsUtils.getDoubleYAxisVerticalLabel(GenericGraph.TIME_X_AXIS_LABEL);
+ graphics.drawImage(img, width/2, height-30);
+
+ }
+ private void paintData(Graphics graphics)
+ {
+ DbgUtility.println(DbgUtility.PRIORITY_LOOP, this.getClass().getSimpleName() + "/paintData START");
+
+ Rectangle canvasRect = graphics.getClip(new org.eclipse.draw2d.geometry.Rectangle());
+
+ if(this.graphedItemsInput == null)
+ return;
+
+ int [] listX = timeSamples;
+
+ for(GraphedItemsInput item:graphedItemsInput)
+ {
+ int [] valuesToBePlotted = valuesForSelectedItems.get(item);
+
+ if(valuesToBePlotted == null)
+ continue;
+
+ int [] points = new int[valuesToBePlotted.length *2];
+
+ double visY = canvasRect.height - CommonGraphConstants.XLEGENDSPACE;
+
+ EventTypes eventType = GraphsUtils.getMappedEvent(item.getEvent());
+
+ double multiplier = 1;
+ boolean isThreadEvent = false;
+ boolean isChunkEvent = false;
+
+ switch (eventType)
+ {
+ case NO_OF_FILES:
+ case NO_OF_PSHANDLES:
+ case HEAP_ALLOC_CELL_COUNT:
+ case HEAP_FREE_CELL_COUNT:
+ case SYSTEM_DATA:
+ multiplier = GraphsUtils.roundToNearestNumber(maxCount)/visY;
+ break;
+ default:
+ multiplier = GraphsUtils.prettyMaxBytes(maxBytes)/visY;
+ break;
+ }
+
+ switch(eventType)
+ {
+ case NO_OF_FILES:
+ case NO_OF_PSHANDLES:
+ case MAX_HEAP_SIZE:
+ case HEAP_SIZE:
+ case HEAP_ALLOC_CELL_COUNT:
+ case HEAP_FREE_CELL_COUNT:
+ case HEAP_ALLOC_SPACE:
+ case HEAP_FREE_SLACK:
+ case HEAP_FREE_SPACE:
+ isThreadEvent = true;
+ break;
+ case GLOBAL_DATA_SIZE:
+ case NON_HEAP_CHUNK_SIZE:
+ isChunkEvent = true;
+ break;
+ }
+
+ // Scaling values before actual drawing
+ for (int i = 0, j = 0; i < valuesToBePlotted.length; i++, j++)
+ {
+ // Scaling X-coordinate value
+ int x_point = (int)(listX[i]/scale);
+
+ // Scaling positive Y-coordinate value and ...
+ int y_point = NOT_DRAWN_DATA_POINT; // ... zero and negative ones are not drawn
+ if (valuesToBePlotted[i] > 0){
+ y_point = (int) (visY - valuesToBePlotted[i] /multiplier);
+ }
+
+ // Storing value
+ points[j] = x_point;
+ points[++j] = y_point;
+ }
+
+ // Storing original values
+ Color origColor = graphics.getForegroundColor();
+ int origLineWidth = graphics.getLineWidth();
+ int origLineStyle = graphics.getLineStyle();
+
+ graphics.setForegroundColor(item.getColor());
+ graphics.setLineWidth(CommonGraphConstants.DEFAULT_GRAPH_LINE_WIDTH);
+
+ if(isThreadEvent){
+ paintThreadEvents(graphics, points, item.getName());
+ }
+ else if(isChunkEvent)
+ {
+ paintChunkEvents(graphics, points, item.getName(), item.getEvent());
+ }
+ else{
+ graphics.drawPolyline(points);
+ }
+
+ // Drawing markers to the data points
+ GraphsUtils.drawMarkers(graphics, points);
+
+ Polyline line = new Polyline();
+ line.setPoints(new PointList(points));
+ pointsData.put(item, line);
+
+ // Restoring original values
+ graphics.setForegroundColor(origColor);
+ graphics.setLineWidth(origLineWidth);
+ graphics.setLineStyle(origLineStyle);
+ }
+
+ DbgUtility.println(DbgUtility.PRIORITY_LOOP, this.getClass().getSimpleName() + "/paintData END");
+ }
+
+ /**
+ * prepare data for drawing
+ */
+ private void prepareData()
+ {
+ maxBytes = 10;
+ maxCount = 10;
+
+ for(GraphedItemsInput obj:graphedItemsInput)
+ {
+ String itemName = obj.getName();
+ String event = obj.getEvent();
+
+ int [] values = getValuesForGivenItemAndEvent(itemName, event);
+
+ if(values == null)
+ {
+ continue;
+ }
+ valuesForSelectedItems.put(obj, values);
+
+ int maxValue = calculateMaxValue(values);
+
+ EventTypes eventType = GraphsUtils.getMappedEvent(event);
+
+ switch(eventType)
+ {
+ case NO_OF_FILES:
+ case NO_OF_PSHANDLES:
+ case HEAP_ALLOC_CELL_COUNT:
+ case HEAP_FREE_CELL_COUNT:
+ case SYSTEM_DATA:
+ if(maxValue > maxCount){
+ maxCount = maxValue;
+ }
+ break;
+ default:
+ if(maxValue > maxBytes){
+ maxBytes = maxValue;
+ }
+ break;
+ }
+ }
+ }
+
+ private int [] getValuesForGivenItemAndEvent(String itemName, String event)
+ {
+ EventTypes eventType = GraphsUtils.getMappedEvent(event);
+ int [] valuesForSelectedItem = null;
+
+ switch(eventType)
+ {
+ case GLOBAL_DATA_SIZE:
+ valuesForSelectedItem = getGlobalChunkSize(itemName, globalDataChunks);
+ break;
+ case NON_HEAP_CHUNK_SIZE:
+ valuesForSelectedItem = getNonHeapChunkSize(itemName, nonHeapChnksData);
+ break;
+ case DISK_USED_SIZE:
+ valuesForSelectedItem = getUsedDiskSize(itemName, disksData);
+ break;
+ case DISK_TOTAL_SIZE:
+ valuesForSelectedItem = getTotalDiskSize(itemName, disksData);
+ break;
+ case NO_OF_FILES:
+ valuesForSelectedItem = getAllFiles(itemName, heapData);
+ break;
+ case MAX_HEAP_SIZE:
+ valuesForSelectedItem = getMaxHeapSize(itemName, heapData);
+ break;
+ case HEAP_SIZE:
+ valuesForSelectedItem = getHeapSize(itemName, heapData);
+ break;
+ case HEAP_ALLOC_SPACE:
+ valuesForSelectedItem = getHeapAllocSpace(itemName, heapData);
+ break;
+ case HEAP_FREE_SPACE:
+ valuesForSelectedItem = getHeapFreeSpace(itemName, heapData);
+ break;
+ case HEAP_ALLOC_CELL_COUNT:
+ valuesForSelectedItem = getHeapAllocCellsCount(itemName, heapData);
+ break;
+ case HEAP_FREE_CELL_COUNT:
+ valuesForSelectedItem = getHeapFreeCellsCount(itemName, heapData);
+ break;
+ case HEAP_FREE_SLACK:
+ valuesForSelectedItem = getHeapFreeSlack(itemName, heapData);
+ break;
+ case NO_OF_PSHANDLES:
+ valuesForSelectedItem = getPSHandles(itemName, heapData);
+ break;
+ case RAM_USED:
+ valuesForSelectedItem = getUsedRam(systemData);
+ break;
+ case RAM_TOTAL:
+ valuesForSelectedItem = getTotalRam(systemData);
+ break;
+ case SYSTEM_DATA:
+ valuesForSelectedItem = getDataForSystemElement(itemName, kernelData);
+ break;
+ }
+ return valuesForSelectedItem;
+ }
+
+ private int[] getDataForSystemElement(String itemName, ArrayList<KernelElements> kernelData)
+ {
+ SystemDataGraph sysGraph = new SystemDataGraph();
+ return sysGraph.getValuesForGivenKerenelElement(itemName, kernelData);
+ }
+ private int[] getTotalRam(ArrayList<SystemData> systemData) {
+
+ int [] totalRam = new int[systemData.size()];
+
+ for(int i=0; i < systemData.size(); i++)
+ {
+ totalRam[i] = (int)systemData.get(i).getTotalMemory();
+ }
+ return totalRam;
+ }
+
+ private int[] getUsedRam(ArrayList<SystemData> systemData) {
+ int [] usedRam = new int[systemData.size()];
+
+ for(int i=0; i < systemData.size(); i++)
+ {
+ usedRam[i] = (int)(systemData.get(i).getTotalMemory() - systemData.get(i).getFreeMemory());
+ }
+ return usedRam;
+ }
+
+ private int[] getPSHandles(String itemName, HashMap<String, ArrayList<ThreadData>> heapData) {
+
+ ArrayList<ThreadData> totalData = heapData.get(itemName);
+
+ if(totalData != null)
+ {
+ int [] psValues = new int [totalData.size()];
+
+ for(int i=0; i<totalData.size(); i++)
+ {
+ ThreadData data = totalData.get(i);
+ psValues[i] = (int)data.getPsHandles();
+ }
+
+ return psValues;
+ }
+
+ return null;
+ }
+ private int[] getHeapFreeSlack(String itemName, HashMap<String, ArrayList<ThreadData>> heapData) {
+
+ ArrayList<ThreadData> totalData = heapData.get(itemName);
+
+ if(totalData != null)
+ {
+ int [] freeSlack = new int [totalData.size()];
+
+ for(int i=0; i<totalData.size(); i++)
+ {
+ ThreadData data = totalData.get(i);
+
+ if(data.getStatus() == CycleData.Deleted)
+ freeSlack[i] = 0;
+ else
+ freeSlack[i] = (int)data.getFreeSlackSize();
+ }
+
+ return freeSlack;
+ }
+
+ return null;
+ }
+ private int[] getHeapFreeCellsCount(String itemName, HashMap<String, ArrayList<ThreadData>> heapData) {
+
+ ArrayList<ThreadData> totalData = heapData.get(itemName);
+
+ if(totalData != null)
+ {
+ int [] freeCellsCount = new int [totalData.size()];
+
+ for(int i=0; i<totalData.size(); i++)
+ {
+ ThreadData data = totalData.get(i);
+
+ if(data.getStatus() == CycleData.Deleted)
+ freeCellsCount[i] = 0;
+ else
+ freeCellsCount[i] = (int)data.getFreeCells();
+ }
+
+ return freeCellsCount;
+ }
+
+ return null;
+ }
+
+ private int[] getHeapAllocCellsCount(String itemName, HashMap<String, ArrayList<ThreadData>> heapData) {
+
+ ArrayList<ThreadData> totalData = heapData.get(itemName);
+
+ if(totalData != null)
+ {
+ int [] allocCellsCount = new int [totalData.size()];
+
+ for(int i=0; i<totalData.size(); i++)
+ {
+ ThreadData data = totalData.get(i);
+
+ if(data.getStatus() == CycleData.Deleted)
+ allocCellsCount[i] = 0;
+ else
+ allocCellsCount[i] = (int)data.getAllocatedCells();
+ }
+
+ return allocCellsCount;
+ }
+ return null;
+ }
+ private int[] getHeapFreeSpace(String itemName, HashMap<String, ArrayList<ThreadData>> heapData) {
+
+ ArrayList<ThreadData> totalData = heapData.get(itemName);
+
+ if(totalData != null)
+ {
+ int [] heapFreeSpace = new int [totalData.size()];
+
+ for(int i=0; i<totalData.size(); i++)
+ {
+ ThreadData data = totalData.get(i);
+
+ if(data.getStatus() == CycleData.Deleted)
+ heapFreeSpace[i] = 0;
+ else
+ heapFreeSpace[i] = (int)data.getHeapFreeSpace();
+ }
+
+ return heapFreeSpace;
+ }
+ return null;
+ }
+ private int[] getHeapAllocSpace(String itemName, HashMap<String, ArrayList<ThreadData>> heapData) {
+ ArrayList<ThreadData> totalData = heapData.get(itemName);
+
+ if(totalData != null)
+ {
+ int [] heapAllocSpace = new int [totalData.size()];
+
+ for(int i=0; i<totalData.size(); i++)
+ {
+ ThreadData data = totalData.get(i);
+
+ if(data.getStatus() == CycleData.Deleted)
+ heapAllocSpace[i] = 0;
+ else
+ heapAllocSpace[i] = (int)data.getHeapAllocatedSpace();
+ }
+
+ return heapAllocSpace;
+ }
+ return null;
+ }
+
+ private int[] getHeapSize(String itemName, HashMap<String, ArrayList<ThreadData>> heapData) {
+
+ ArrayList<ThreadData> totalData = heapData.get(itemName);
+
+ if(totalData != null)
+ {
+ int [] heapSize = new int [totalData.size()];
+
+ for(int i=0; i<totalData.size(); i++)
+ {
+ ThreadData data = totalData.get(i);
+
+ if(data.getStatus() == CycleData.Deleted)
+ heapSize[i] = 0;
+ else
+ heapSize[i] = (int)data.getHeapChunkSize();
+ }
+
+ return heapSize;
+ }
+ return null;
+ }
+ private int[] getMaxHeapSize(String itemName, HashMap<String, ArrayList<ThreadData>> heapData) {
+
+ ArrayList<ThreadData> totalData = heapData.get(itemName);
+
+ if(totalData != null)
+ {
+ int [] maxHeapSize = new int [totalData.size()];
+
+ for(int i=0; i<totalData.size(); i++)
+ {
+ ThreadData data = totalData.get(i);
+
+ if(data.getStatus() == CycleData.Deleted)
+ maxHeapSize[i] = 0;
+ else
+ maxHeapSize[i] = (int)data.getMaxHeapSize();
+ }
+
+ return maxHeapSize;
+ }
+ return null;
+ }
+ private int[] getAllFiles(String itemName, HashMap<String, ArrayList<ThreadData>> heapData) {
+
+ ArrayList<ThreadData> totalData = heapData.get(itemName);
+
+ if(totalData != null)
+ {
+ int [] allFiles = new int [totalData.size()];
+
+ for(int i=0; i<totalData.size(); i++)
+ {
+ ThreadData data = totalData.get(i);
+ allFiles[i] = (int)data.getOpenFiles();
+ }
+
+ return allFiles;
+ }
+ return null;
+ }
+ private int[] getTotalDiskSize(String itemName, HashMap<String, ArrayList<DiskOverview>> disksData) {
+
+ ArrayList<DiskOverview> totalData = disksData.get(itemName);
+
+ if(totalData != null)
+ {
+ int [] diskSize = new int [totalData.size()];
+
+ for(int i=0; i<totalData.size(); i++)
+ {
+ DiskOverview data = totalData.get(i);
+
+ if(data.getStatus() == CycleData.Deleted)
+ diskSize[i] = 0;
+ else
+ diskSize[i] = (int)data.getSize();
+ }
+
+ return diskSize;
+ }
+ return null;
+ }
+ private int[] getUsedDiskSize(String itemName, HashMap<String, ArrayList<DiskOverview>> disksData) {
+
+ ArrayList<DiskOverview> totalData = disksData.get(itemName);
+
+ if(totalData != null)
+ {
+ int [] diskSize = new int [totalData.size()];
+
+ for(int i=0; i<totalData.size(); i++)
+ {
+ DiskOverview data = totalData.get(i);
+
+ if(data.getStatus() == CycleData.Deleted)
+ diskSize[i] = 0;
+ else
+ diskSize[i] = (int)data.getUsedSize();
+ }
+
+ return diskSize;
+ }
+ return null;
+ }
+ private int[] getNonHeapChunkSize(String itemName, HashMap<String, ArrayList<ChunksData>> nonHeapChnksData) {
+
+ ArrayList<ChunksData> totalData = nonHeapChnksData.get(itemName);
+
+ if(totalData != null)
+ {
+ int [] chunkSizes = new int[totalData.size()];
+
+ for(int i=0; i<totalData.size(); i++)
+ {
+ ChunksData chnkData = totalData.get(i);
+
+ if(chnkData.getAttrib() == CycleData.Deleted)
+ chunkSizes[i] = 0;
+ else
+ chunkSizes[i] = (int)chnkData.getSize();
+ }
+
+ return chunkSizes;
+ }
+
+ return null;
+ }
+ private int[] getGlobalChunkSize(String itemName, HashMap<String, ArrayList<GlobalDataChunks>> glodData) {
+
+ ArrayList<GlobalDataChunks> totalData = glodData.get(itemName);
+
+ if(totalData != null)
+ {
+ int [] chnkSize = new int [totalData.size()];
+
+ for(int i=0; i<totalData.size(); i++)
+ {
+ GlobalDataChunks data = totalData.get(i);
+
+ if(data.getAttrib() == CycleData.Deleted)
+ chnkSize[i] = 0;
+ else
+ chnkSize[i] = (int)data.getSize();
+ }
+
+ return chnkSize;
+ }
+ return null;
+ }
+
+ private int calculateMaxValue(int [] values)
+ {
+ int maxValue = 0;
+
+ for(int i=0; i<values.length; i++)
+ {
+ if(values[i] > maxValue)
+ maxValue = values[i];
+ }
+ return maxValue + 1000;
+ }
+
+ private int [] calculateTimeIntervals()
+ {
+ CycleData [] cyclesData = parsedData.getLogData();
+ int [] time = new int[cyclesData.length];
+ int prevDuration = 0;
+ time[0] = 0;
+
+ SWMTLogReaderUtils utils = new SWMTLogReaderUtils();
+
+ for(int i=1; i<cyclesData.length;i++)
+ {
+ String currentTime = cyclesData[i].getTime();
+ String prevTime = cyclesData[i-1].getTime();
+ int timeDiff = (int)utils.getDurationInSeconds(prevTime, currentTime);
+
+ if(timeDiff < 0)
+ {
+ //error condition
+ }
+ else
+ {
+ timeDiff += prevDuration;
+ prevDuration = timeDiff;
+
+ time[i] = timeDiff;
+ }
+
+ }
+
+ return time;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.swt.events.MouseMoveListener#mouseMove(org.eclipse.swt.events.MouseEvent)
+ */
+ public void mouseMove(MouseEvent event) {
+
+ int x = event.x;
+ int y = event.y;
+
+ if(y > (int)visY)
+ figureCanvas.setToolTipText(null);
+
+ String text = "";
+ double xValue = x + timeOffset;
+ int scaledX = (int)(xValue * scale);
+ double valY = visY - y;
+
+ double count_multiplier = GraphsUtils.roundToNearestNumber(maxCount)/visY;
+ double bytes_multiplier = GraphsUtils.prettyMaxBytes(maxBytes)/visY;
+
+ String scaledY_1 = getFormattedValues(valY * bytes_multiplier);
+ int scaledY_2 = (int)(Math.round((valY * count_multiplier)));
+
+ text += scaledX + "s " + scaledY_1 + " , " + scaledY_2 ;
+
+ for(GraphedItemsInput item:graphedItemsInput)
+ {
+ Polyline line = pointsData.get(item);
+
+ if(line != null && line.containsPoint(x, y))
+ {
+ text += "\n" + item.getName();
+
+ if(!item.getName().equalsIgnoreCase(item.getEvent()))
+ text += " -- " + item.getEvent();
+ }
+ }
+
+ figureCanvas.setToolTipText(text);
+ figureCanvas.redraw();
+ }
+
+ private String getFormattedValues(double bytes)
+ {
+ String scaledY = "";
+
+ if (bytes < 10000)
+ {
+ scaledY += Bytes_Format.format(bytes) + " B"; //$NON-NLS-1$
+ }
+ else if (bytes <= 500 * 1024)
+ {
+ scaledY += Bytes_Format.format(bytes / 1024) + " KB"; //$NON-NLS-1$
+ }
+ else
+ {
+ scaledY += MBformat.format(((float) bytes / (1024 * 1024))) + " MB"; //$NON-NLS-1$
+ }
+
+ return scaledY;
+ }
+
+ /**
+ * Clear all data from items
+ */
+ public void removeAllData()
+ {
+ heapData.clear();
+ globalDataChunks.clear();
+ nonHeapChnksData.clear();
+ disksData.clear();
+ systemData.clear();
+ kernelData.clear();
+ valuesForSelectedItems.clear();
+ pointsData.clear();
+ }
+
+ /**
+ * Paints thread related events.
+ * @param graphics graphics context
+ * @param points points to draw in array [X0, Y0, X1, Y1, ... ] with zero Y-values pruned out
+ * @param threadName name of the thread
+ */
+ private void paintThreadEvents(Graphics graphics, int [] points, String threadName)
+ {
+ SWMTLogReaderUtils utils = new SWMTLogReaderUtils();
+ ArrayList<ThreadData> data = utils.getHeapDataFromAllCycles(threadName, parsedData);
+
+ boolean handleDeleted = false;
+
+ List<List<Integer>> ListOfSolidLinePoints = new ArrayList<List<Integer>>();
+ ArrayList<Integer> solidLinePoints = new ArrayList<Integer>();
+
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "thread: " + threadName);
+
+ for (int i = 0, j = 0; i < parsedData.getNumberOfCycles(); i++, j++){
+
+ int x_point = points[j];
+ int y_point = points[++j];
+
+ if(y_point == NOT_DRAWN_DATA_POINT){
+ continue; // There is no valid data for this cycle
+ }
+
+ DbgUtility.println(DbgUtility.PRIORITY_LOOP, "Plotting data of threads");
+ if(!handleDeleted){
+ solidLinePoints.add(x_point);
+ solidLinePoints.add(y_point);
+ DbgUtility.println(DbgUtility.PRIORITY_LOOP, "add 1: x_point: " + x_point + ", y_point: " + y_point);
+ }
+
+ ThreadData threadData = data.get(i);
+
+ if(threadData.isKernelHandleDeleted() && !handleDeleted){
+ handleDeleted = true;
+
+ if(solidLinePoints.size() > 0)
+ ListOfSolidLinePoints.add(solidLinePoints);
+ solidLinePoints = new ArrayList<Integer>();
+ }
+
+ if(handleDeleted && threadData.getStatus() == CycleData.New)
+ {
+ handleDeleted = false;
+ solidLinePoints.add(x_point);
+ solidLinePoints.add(y_point);
+ }
+
+ }
+
+ if(solidLinePoints.size() > 0)
+ ListOfSolidLinePoints.add(solidLinePoints);
+
+ for(int i=0; i < ListOfSolidLinePoints.size(); i++)
+ {
+ int [] solidPts = GraphsUtils.CreateIntArrayFromIntegerList(ListOfSolidLinePoints.get(i));
+
+ if(solidPts != null)
+ {
+ if(ListOfSolidLinePoints.size() > 1)
+ {
+ int instance_id = i+1;
+ graphics.drawString("(0" + instance_id + ")", solidPts[0]+2, solidPts[1] - 15);
+ }
+ graphics.setLineStyle(SWT.LINE_SOLID);
+ graphics.drawPolyline(solidPts);
+ }
+ }
+
+ }
+
+ private void paintChunkEvents(Graphics graphics, int [] points, String item_name, String event)
+ {
+ SWMTLogReaderUtils utils = new SWMTLogReaderUtils();
+ ArrayList<ThreadData> data = utils.getHeapDataFromAllCycles(item_name, parsedData);
+
+ boolean handleDeleted = false;
+
+ List<List<Integer>> ListOfSolidLinePoints = new ArrayList<List<Integer>>();
+ ArrayList<Integer> solidLinePoints = new ArrayList<Integer>();
+
+ for (int i = 0, j = 0; i < parsedData.getNumberOfCycles(); i++, j++)
+ {
+ int x_point = points[j];
+ int y_point = points[++j];
+
+ if (y_point <= 0){
+ // Not showing zero values to a user, not meaningful data
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "continued because value <= 0");
+ continue;
+ }
+
+ DbgUtility.println(DbgUtility.PRIORITY_LOOP, "Plotting data of threads");
+ if(!handleDeleted){
+ if(y_point > 0){
+ solidLinePoints.add(x_point);
+ solidLinePoints.add(y_point);
+ DbgUtility.println(DbgUtility.PRIORITY_LOOP, "add 1: x_point: " + x_point + ", y_point: " + y_point);
+ }
+ else{
+ DbgUtility.println(DbgUtility.PRIORITY_LOOP, "skipped because zero value");
+ }
+ }
+
+ getHandleStatus(i+1, item_name, event);
+ if(data.get(i).isKernelHandleDeleted() && !handleDeleted){
+ handleDeleted = true;
+
+ if(solidLinePoints.size() > 0)
+ ListOfSolidLinePoints.add(solidLinePoints);
+ solidLinePoints = new ArrayList<Integer>();
+ }
+
+ if(handleDeleted && data.get(i).getStatus() == CycleData.New)
+ {
+ handleDeleted = false;
+
+ solidLinePoints.add(x_point);
+ solidLinePoints.add(y_point);
+ }
+
+ }
+
+ if(solidLinePoints.size() > 0)
+ ListOfSolidLinePoints.add(solidLinePoints);
+
+ for(int i=0; i < ListOfSolidLinePoints.size(); i++)
+ {
+ int [] solidPts = GraphsUtils.CreateIntArrayFromIntegerList(ListOfSolidLinePoints.get(i));
+
+ if(solidPts != null)
+ {
+ if(ListOfSolidLinePoints.size() > 1)
+ {
+ int instance_id = i+1;
+ graphics.drawString("(0" + instance_id + ")", solidPts[0]+2, solidPts[1] - 15);
+ }
+ graphics.setLineStyle(SWT.LINE_SOLID);
+ graphics.drawPolyline(solidPts);
+ }
+ }
+
+ }
+
+ private boolean getHandleStatus(int cycleNo, String chunkName, String event)
+ {
+ boolean status = false;
+
+ SWMTLogReaderUtils utils = new SWMTLogReaderUtils();
+
+ if(event.equals(GenericGraph.EventTypes.GLOBAL_DATA_SIZE))
+ {
+ ArrayList<GlobalDataChunks> glod_data = utils.getGLOBDataFromAllCycles(chunkName, parsedData);
+
+ status = glod_data.get(cycleNo -1).isKernelHandleDeleted();
+ }
+ else if(event.equals(GenericGraph.EventTypes.NON_HEAP_CHUNK_SIZE))
+ {
+ ArrayList<ChunksData> chunks_data = utils.getChunkDataFromAllCycles(chunkName, parsedData);
+
+ status = chunks_data.get(cycleNo -1).isKernelHandleDeleted();
+ }
+
+ return status;
+ }
+
+ /* (non-Javadoc)
+ * @see com.nokia.s60tools.swmtanalyser.ui.actions.IImageProvider#getImage()
+ */
+ public Image getImage() {
+ return new Image(Display.getCurrent(), parentComposite.getClientArea().width, parentComposite.getClientArea().height);
+ }
+
+ /* (non-Javadoc)
+ * @see com.nokia.s60tools.swmtanalyser.ui.actions.IImageProvider#getDrawable()
+ */
+ public Drawable getDrawable() {
+ return parentComposite;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/ui/graphs/GraphsUtils.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,529 @@
+/*
+ * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+ * All rights reserved.
+ * This component and the accompanying materials are made available
+ * under the terms of "Eclipse Public License v1.0"
+ * which accompanies this distribution, and is available
+ * at the URL "http://www.eclipse.org/legal/epl-v10.html".
+ *
+ * Initial Contributors:
+ * Nokia Corporation - initial contribution.
+ *
+ * Contributors:
+ *
+ * Description:
+ *
+ */
+package com.nokia.s60tools.swmtanalyser.ui.graphs;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Random;
+
+import org.eclipse.draw2d.Graphics;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.ImageData;
+import org.eclipse.swt.graphics.ImageLoader;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.FileDialog;
+
+import com.nokia.s60tools.swmtanalyser.ui.graphs.GenericGraph.EventTypes;
+import com.nokia.s60tools.util.debug.DbgUtility;
+
+/**
+ * Graph utilities common to all graph types.
+ */
+public class GraphsUtils {
+
+ //
+ // Constants
+ //
+
+ /**
+ * Constant for no marker possibility.
+ */
+ private static final int NO_MARKER = -1;
+
+ /**
+ * Possible marker sizes from smallest to biggest value.
+ */
+ private static final int[] MARKER_SIZES = { 4, 6, 8 };
+
+ /**
+ * Default marker size.
+ */
+ private static final int DEFAULT_MARKER = MARKER_SIZES[2];
+
+ /**
+ * Array of event names used to map the event names into corresponding event
+ * enumerators.
+ *
+ * @see com.nokia.s60tools.swmtanalyser.ui.graphs.GenericGraph.EventTypes
+ */
+ private static final String[] EVENT_NAMES_ARR = { "Global data size",
+ "Non heap chunk size", "Disk used", "Disk total", "No of Files",
+ "Max size", "Heap size", "Heap allocated space", "Heap free space",
+ "Heap allocated cell count", "Heap free cell count", "Free slack",
+ "No of PS Handles", "RAM used", "RAM total", "System Data" };
+
+ /**
+ * Percentage of byte count to be graphed that is added extra reserve in
+ * order to show markers appropriately.
+ */
+ private static final int MARKER_MARGIN_PERCENTAGE = 5;
+
+ //
+ // Symbolic name constants for different byte units use in setting Y-axis
+ // value level according given maximum byte value
+ //
+ private static final int KILOBYTE = 1024;
+ private static final int MEGABYTE = 1024 * 1024;
+
+ //
+ // Members
+ //
+ private static String imageFilename;
+ private static Composite parentComposite;
+
+ /**
+ * Maps event names into corresponding enumerator type
+ *
+ * @param event
+ * event name
+ * @return enumerator constant corresponding to the given event
+ */
+ public static EventTypes getMappedEvent(String eventName) {
+ int index = Arrays.asList(EVENT_NAMES_ARR).indexOf(eventName);
+ GenericGraph.EventTypes eventType = null;
+
+ switch (index) {
+ case 0:
+ eventType = GenericGraph.EventTypes.GLOBAL_DATA_SIZE;
+ break;
+ case 1:
+ eventType = GenericGraph.EventTypes.NON_HEAP_CHUNK_SIZE;
+ break;
+ case 2:
+ eventType = GenericGraph.EventTypes.DISK_USED_SIZE;
+ break;
+ case 3:
+ eventType = GenericGraph.EventTypes.DISK_TOTAL_SIZE;
+ break;
+ case 4:
+ eventType = GenericGraph.EventTypes.NO_OF_FILES;
+ break;
+ case 5:
+ eventType = GenericGraph.EventTypes.MAX_HEAP_SIZE;
+ break;
+ case 6:
+ eventType = GenericGraph.EventTypes.HEAP_SIZE;
+ break;
+ case 7:
+ eventType = GenericGraph.EventTypes.HEAP_ALLOC_SPACE;
+ break;
+ case 8:
+ eventType = GenericGraph.EventTypes.HEAP_FREE_SPACE;
+ break;
+ case 9:
+ eventType = GenericGraph.EventTypes.HEAP_ALLOC_CELL_COUNT;
+ break;
+ case 10:
+ eventType = GenericGraph.EventTypes.HEAP_FREE_CELL_COUNT;
+ break;
+ case 11:
+ eventType = GenericGraph.EventTypes.HEAP_FREE_SLACK;
+ break;
+ case 12:
+ eventType = GenericGraph.EventTypes.NO_OF_PSHANDLES;
+ break;
+ case 13:
+ eventType = GenericGraph.EventTypes.RAM_USED;
+ break;
+ case 14:
+ eventType = GenericGraph.EventTypes.RAM_TOTAL;
+ break;
+ case 15:
+ eventType = GenericGraph.EventTypes.SYSTEM_DATA;
+ break;
+ }
+
+ return eventType;
+ }
+
+ /**
+ * Get next scale when zooming in or out
+ * @param scale
+ * @param bigger give <code>true</code> when zooming out and <code>false</code> when zooming in.
+ * @return next scale
+ */
+ public static double nextScale(double scale, boolean bigger) {
+ double logScale = Math.log10(scale);
+ double floorLogScale = Math.floor(Math.log10(scale));
+ double mostSignificantDigit = Math.rint(Math.pow(10,
+ (logScale - floorLogScale)));
+ double powerOfTen = Math.pow(10, floorLogScale);
+
+ if (bigger) {
+ if (mostSignificantDigit < 2) {
+ mostSignificantDigit = 2;
+ } else if (mostSignificantDigit < 5) {
+ mostSignificantDigit = 5;
+ } else {
+ mostSignificantDigit = 10;
+ }
+ } else {
+ if (mostSignificantDigit > 5) {
+ mostSignificantDigit = 5;
+ } else if (mostSignificantDigit > 2) {
+ mostSignificantDigit = 2;
+ } else if (mostSignificantDigit > 1) {
+ mostSignificantDigit = 1;
+ } else {
+ mostSignificantDigit = 0.5;
+ }
+ }
+
+ double result = mostSignificantDigit * powerOfTen;
+
+ if (result < 0.1)
+ result = 0.1;
+
+ return result;
+ }
+
+ /**
+ * Save the given composite as an image to local file system.
+ *
+ * @param parent
+ */
+ public static void saveGraph(Composite parent) {
+ parentComposite = parent;
+ FileDialog dlg = new FileDialog(Display.getCurrent().getActiveShell(),
+ SWT.SAVE);
+ dlg.setFilterExtensions(new String[] { "*.bmp", "*.png", "*.jpeg" });
+ imageFilename = dlg.open();
+ if (imageFilename == null)
+ return;
+
+ Runnable p = new Runnable() {
+ public void run() {
+ GC gc = new GC(parentComposite);
+ Image image = new Image(Display.getCurrent(), parentComposite
+ .getClientArea().width,
+ parentComposite.getClientArea().height);
+ parentComposite.setFocus();
+ gc.copyArea(image, 0, 0);
+ gc.dispose();
+ ImageData data = image.getImageData();
+ ImageLoader loader = new ImageLoader();
+ loader.data = new ImageData[] { data };
+ if (imageFilename != null)
+ loader.save(imageFilename, SWT.IMAGE_BMP);
+ image.dispose();
+ }
+ };
+ Display.getDefault().timerExec(500, p);
+ }
+
+ /**
+ * Generate random color.
+ *
+ * @return a random color
+ */
+ public static Color getRandomColor() {
+ Random rand = new Random();
+ int r = rand.nextInt(255);
+ int g = rand.nextInt(255);
+ int b = rand.nextInt(255);
+ return new Color(Display.getCurrent(), r, g, b);
+ }
+
+ /**
+ * Creates an image and writes the given text vertically on the image. This
+ * is used to represent the Y-axis names in the Analysis tab and Graphed
+ * events -graphs. Those graphs show double Y-axis and therefore layout
+ * differs from single Y-axis situation.
+ *
+ * @param axisLabelName
+ * name of the label
+ * @return vertical axis label image
+ */
+ public static Image getDoubleYAxisVerticalLabel(String axisLabelName) {
+ return getVerticalLabel(axisLabelName, 90, 18, 10);
+ }
+
+ /**
+ * Creates an image and writes the given text vertically on the image with
+ * given coordinates and font size.
+ *
+ * @param axisLabelName
+ * name of the label
+ * @param x
+ * x-coordinate
+ * @param y
+ * y-coordinate
+ * @param fontSize
+ * font size
+ * @return vertical axis label image
+ */
+ public static Image getVerticalLabel(String axisLabelName, int x, int y,
+ int fontSize) {
+ final Image image = new Image(Display.getDefault(), x, y);
+ GC gc = new GC(image);
+ Font font = new Font(Display.getDefault(), Display.getDefault()
+ .getSystemFont().getFontData()[0].getName(), fontSize, SWT.BOLD);
+ gc.setFont(font);
+ gc.setBackground(Display.getDefault().getSystemColor(SWT.COLOR_WHITE));
+ gc.fillRectangle(0, 0, 90, 15);
+ gc.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_BLACK));
+ gc.drawText(axisLabelName + " ->", 0, 0, true);
+ font.dispose();
+ gc.dispose();
+ return image;
+ }
+
+ /**
+ * Draws markers to data points with current foreground color and marker
+ * size.
+ *
+ * @param graphics
+ * Graphics context
+ * @param points
+ * Data point array in format [ X0, Y0, X1, Y1, ... ]
+ */
+ private static void drawMarkers(Graphics graphics, int[] points,
+ int markerSize) {
+ Color backgroundColor = graphics.getBackgroundColor();
+ graphics.setBackgroundColor(graphics.getForegroundColor());
+ for (int j = 0; j < points.length; j += 2) {
+ int width = markerSize;
+ int height = width;
+ int x = points[j] - (width / 2);
+ int y = points[j + 1] - (width / 2);
+ graphics.fillRectangle(x, y, width, height);
+ }
+ graphics.setBackgroundColor(backgroundColor);
+ }
+
+ /**
+ * Resolving minimum space between subsequent X-coordinate data points. This
+ * method expects that there are at least 2 x,y pairs in the array
+ *
+ * @param points
+ * Data point array in format [ X0, Y0, X1, Y1, ... ]
+ * @return minimum space between subsequent X-coordinate data points
+ */
+ private static int resolveMinumumXDelta(int[] points) {
+ int minDelta = points[2] - points[0];
+ for (int i = 4; i < points.length; i += 2) {
+ int delta = points[i] - points[i - 2];
+ if (delta < minDelta) {
+ minDelta = delta;
+ }
+ }
+ return minDelta;
+ }
+
+ /**
+ * Draws markers to data points with current foreground color. Markers drawn
+ * only if there is enough room in X-axis to draw them between all
+ * individual data points.
+ *
+ * @param graphics
+ * Graphics context
+ * @param points
+ * Data point array in format [ X0, Y0, X1, Y1, ... ]
+ */
+ public static void drawMarkers(Graphics graphics, int[] points) {
+ int markerSize = NO_MARKER; // By default not drawing markers if there
+ // is no room for them
+ // Checking deltas only if there is more than single point to draw
+ if (points.length > 2) {
+ // Resolving minimum space between subsequent X-coordinate data
+ // points
+ int minDelta = resolveMinumumXDelta(points);
+ // Resolving if there is at all need to draw markers
+ for (int i = MARKER_SIZES.length - 1; i >= 0; i--) {
+ int size = MARKER_SIZES[i];
+ if (size < minDelta) {
+ markerSize = size; // Using this size in drawing
+ break;
+ }
+ }
+ // DbgUtility.println(DbgUtility.PRIORITY_LOOP, "minDelta: " + minDelta); //$NON-NLS-1$
+ } else {
+ // Using default marker in case there
+ markerSize = DEFAULT_MARKER;
+ }
+ // DbgUtility.println(DbgUtility.PRIORITY_LOOP, "markerSize: " + markerSize); //$NON-NLS-1$
+ // Drawing markers
+ if (markerSize != NO_MARKER) {
+ drawMarkers(graphics, points, markerSize);
+ }
+ }
+
+ /**
+ * Gets nearest Y-legend bytes label from the given bytes
+ *
+ * @param bytes
+ * bytes number
+ * @return nearest Y-legend bytes label from the given bytes
+ */
+ static public int prettyMaxBytes(int bytes) {
+
+ // Adding some margin that makes possible to show also markers
+ int byteMarginForMarkers = (int) Math
+ .ceil((MARKER_MARGIN_PERCENTAGE / 100.0) * bytes);
+ bytes = bytes + byteMarginForMarkers;
+
+ // DbgUtility.println(DbgUtility.PRIORITY_LOOP, "prettyMaxBytes/bytes: " + bytes); //$NON-NLS-1$
+ // DbgUtility.println(DbgUtility.PRIORITY_LOOP, "byteMarginForMarkers: " + byteMarginForMarkers); //$NON-NLS-1$
+
+ // Before 10 KB limit using byte units are used Y-axis legend and
+ // therefore thousand is used as checkpoint limit instead if KILOBYTE
+ final int thousand = 1000;
+
+ if (bytes < thousand)
+ bytes = thousand;
+ else if (bytes < 10 * thousand)
+ bytes = 10 * thousand;
+ else if (bytes < 20 * KILOBYTE)
+ bytes = 20 * KILOBYTE;
+ else if (bytes < 30 * KILOBYTE)
+ bytes = 30 * KILOBYTE;
+ else if (bytes < 50 * KILOBYTE)
+ bytes = 50 * KILOBYTE;
+ else if (bytes < 100 * KILOBYTE)
+ bytes = 100 * KILOBYTE;
+ else if (bytes < 150 * KILOBYTE)
+ bytes = 150 * KILOBYTE;
+ else if (bytes < 200 * KILOBYTE)
+ bytes = 200 * KILOBYTE;
+ else if (bytes < 300 * KILOBYTE)
+ bytes = 300 * KILOBYTE;
+ else if (bytes < 400 * KILOBYTE)
+ bytes = 400 * KILOBYTE;
+ else if (bytes < 500 * KILOBYTE)
+ bytes = 500 * KILOBYTE;
+ else if (bytes < 600 * KILOBYTE)
+ bytes = 600 * KILOBYTE;
+ else if (bytes < 700 * KILOBYTE)
+ bytes = 700 * KILOBYTE;
+ else if (bytes < 800 * KILOBYTE)
+ bytes = 800 * KILOBYTE;
+ else if (bytes < 900 * KILOBYTE)
+ bytes = 900 * KILOBYTE;
+ else if (bytes < 1000 * KILOBYTE)
+ bytes = 1000 * KILOBYTE;
+ else if (bytes < 1 * MEGABYTE)
+ bytes = 1 * MEGABYTE;
+ else if (bytes < 2 * MEGABYTE)
+ bytes = 2 * MEGABYTE;
+ else if (bytes < 3 * MEGABYTE)
+ bytes = 3 * MEGABYTE;
+ else if (bytes < 5 * MEGABYTE)
+ bytes = 5 * MEGABYTE;
+ else if (bytes < 10 * MEGABYTE)
+ bytes = 10 * MEGABYTE;
+ else if (bytes < 20 * MEGABYTE)
+ bytes = 20 * MEGABYTE;
+ else if (bytes < 30 * MEGABYTE)
+ bytes = 30 * MEGABYTE;
+ else if (bytes < 50 * MEGABYTE)
+ bytes = 50 * MEGABYTE;
+ else if (bytes < 100 * MEGABYTE)
+ bytes = 100 * MEGABYTE;
+ else if (bytes < 200 * MEGABYTE)
+ bytes = 200 * MEGABYTE;
+ else if (bytes < 300 * MEGABYTE)
+ bytes = 300 * MEGABYTE;
+ else if (bytes < 500 * MEGABYTE)
+ bytes = 500 * MEGABYTE;
+ else
+ bytes = ((bytes + 1024 * MEGABYTE - 1) / (1024 * MEGABYTE))
+ * (1024 * MEGABYTE);
+
+ return bytes;
+ }
+
+ /**
+ * Converts list of <code>Point</code> objects into integer array.
+ *
+ * @param pointsList
+ * list of point objects
+ * @return points converted in 1-dimensional integer array.
+ */
+ public static int[] convertPointListToIntArray(List<Point> pointsList) {
+ int[] integerArray = new int[pointsList.size() * 2];
+ for (int i = 0, j = 0; i < pointsList.size(); i++, j += 2) {
+ Point pnt = pointsList.get(i);
+ integerArray[j] = pnt.x;
+ integerArray[(j + 1)] = pnt.y;
+ }
+ return integerArray;
+ }
+
+ /**
+ * Gets nearest Y-legend count value label from the given input count value.
+ * Maximum count value handled is 999*100 i.e. 99900 counts.
+ *
+ * @param inputCountValue
+ * bytes input count value
+ * @return nearest Y-legend count value label from the given input count
+ * value.
+ * @return
+ */
+ static public int roundToNearestNumber(int inputCountValue) {
+ int tempCount = inputCountValue;
+
+ // Adding some safe margin for making sure that all data points with
+ // markers are drawn appropriately
+ int countMarginForMarkers = (int) Math
+ .ceil((MARKER_MARGIN_PERCENTAGE / 100.0) * tempCount);
+ tempCount = tempCount + countMarginForMarkers;
+
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION,
+ "roundToNearestNumber/count: " + tempCount); //$NON-NLS-1$
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION,
+ "countMarginForMarkers: " + countMarginForMarkers); //$NON-NLS-1$
+
+ if (tempCount < 10)
+ tempCount = 10;
+ else if (tempCount < 50)
+ tempCount = 50;
+ else if (tempCount < 100)
+ tempCount = 100;
+ else {
+ for (int i = 2; i < 1000; i++) {
+ if (tempCount < (i * 100)) {
+ tempCount = i * 100;
+ break;
+ }
+ }
+ }
+
+ return tempCount;
+ }
+
+ /**
+ * Builds int array from Integer List object
+ *
+ * @param solidsList
+ * Integer list
+ * @return int array
+ */
+ public static int[] CreateIntArrayFromIntegerList(List<Integer> solidsList) {
+ int[] solidPts = new int[solidsList.size()];
+ for (int j = 0; j < solidsList.size(); j++) {
+ solidPts[j] = solidsList.get(j);
+ }
+ return solidPts;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/ui/graphs/IGraphTypeSelectionListener.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,42 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+package com.nokia.s60tools.swmtanalyser.ui.graphs;
+
+/**
+ * Implementors of this interface can be notified when selected graph type changes
+ * and implementor can do necessary actions based on the changed selection.
+ */
+public interface IGraphTypeSelectionListener {
+
+ /**
+ * Listeners are notified when user changes the selection of threads,
+ */
+ public void notifyThreadsSelection();
+ /**
+ * Listeners are notified when user changes the selection of chunks.
+ */
+ public void notifyChunksSelection();
+ /**
+ * Listeners are notified when user changes the selection of disks.
+ */
+ public void notifyDisksSelection();
+ /**
+ * Listeners are notified when user changes the selection of elements to be shown.
+ */
+ public void notifySysElementsSelection();
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/ui/graphs/LinearIssuesGraph.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,812 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+package com.nokia.s60tools.swmtanalyser.ui.graphs;
+
+import java.text.DecimalFormat;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+import org.eclipse.draw2d.ColorConstants;
+import org.eclipse.draw2d.FigureCanvas;
+import org.eclipse.draw2d.FlowLayout;
+import org.eclipse.draw2d.Graphics;
+import org.eclipse.draw2d.Panel;
+import org.eclipse.draw2d.Polyline;
+import org.eclipse.draw2d.geometry.PointList;
+import org.eclipse.draw2d.geometry.Rectangle;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.action.IMenuListener;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.action.Separator;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ControlAdapter;
+import org.eclipse.swt.events.ControlEvent;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.MouseMoveListener;
+import org.eclipse.swt.events.PaintEvent;
+import org.eclipse.swt.events.PaintListener;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Drawable;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.graphics.Transform;
+import org.eclipse.swt.layout.FormAttachment;
+import org.eclipse.swt.layout.FormData;
+import org.eclipse.swt.layout.FormLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swt.widgets.ScrollBar;
+
+import com.nokia.s60tools.swmtanalyser.analysers.ResultElements;
+import com.nokia.s60tools.swmtanalyser.data.ParsedData;
+import com.nokia.s60tools.swmtanalyser.model.SWMTLogReaderUtils;
+import com.nokia.s60tools.swmtanalyser.ui.graphs.GenericGraph.EventTypes;
+import com.nokia.s60tools.ui.IImageProvider;
+import com.nokia.s60tools.ui.actions.CopyImageToClipboardAction;
+import com.nokia.s60tools.util.debug.DbgUtility;
+
+/**
+ * Graph to be shown in Analysis tab.
+ */
+public class LinearIssuesGraph extends ZoomableGraph implements MouseMoveListener, IImageProvider {
+
+ private static DecimalFormat MBformat = new DecimalFormat("#####.0");
+ private static DecimalFormat Bytes_Format = new DecimalFormat("#####.##");
+
+ private HashMap<ResultElements, Polyline> pointsData = new HashMap<ResultElements, Polyline>();
+
+ private Composite parentComposite;
+ private FigureCanvas yAxis;
+ private FigureCanvas numberAxis;
+ private FigureCanvas figureCanvas;
+ private int[] timeSamples;
+ private ArrayList<ResultElements> selectedIssues;
+ private boolean scalingNeeded;
+
+ private double visY;
+ private int maxBytes = 10;
+ private int maxCount = 10;
+ private double scale = 1.0;
+ private int timeOffset = 0;
+
+ /**
+ * Construction
+ * @param composite
+ */
+ public LinearIssuesGraph(Composite composite)
+ {
+ this.parentComposite = composite;
+ }
+
+ /**
+ * Draw the area
+ */
+ public void constructGraphArea()
+ {
+ if(parentComposite == null)
+ return;
+
+ Control [] children = parentComposite.getChildren();
+
+ if(children != null)
+ {
+ for(Control child:children)
+ child.dispose();
+ }
+
+ calculateMultiplier();
+ scalingNeeded = true;
+
+ Composite parent = new Composite(parentComposite, SWT.NONE);
+ parent.setLayout(new FormLayout());
+
+ yAxis = new FigureCanvas(parent);
+
+ numberAxis = new FigureCanvas(parent);
+ figureCanvas = new FigureCanvas(parent);
+ FormData formData = new FormData();
+ formData.top = new FormAttachment(0);
+ formData.bottom = new FormAttachment(100);
+ formData.left = new FormAttachment(0);
+ formData.width = 50;
+ numberAxis.setLayoutData(formData);
+
+ formData = new FormData();
+ formData.top = new FormAttachment(0);
+ formData.bottom = new FormAttachment(100);
+ formData.left = new FormAttachment(numberAxis);
+ formData.width = 60;
+ yAxis.setLayoutData(formData);
+
+ formData = new FormData();
+ formData.top = new FormAttachment(0);
+ formData.bottom = new FormAttachment(100);
+ formData.left = new FormAttachment(yAxis, 0, SWT.RIGHT);
+ formData.right = new FormAttachment(100);
+
+ figureCanvas.setLayoutData(formData);
+
+ yAxis.setBackground(ColorConstants.white);
+ numberAxis.setBackground(ColorConstants.white);
+
+ yAxis.addPaintListener(new PaintListener()
+ {
+ public void paintControl(PaintEvent event) {
+ GC localGC = event.gc;
+
+ org.eclipse.swt.graphics.Rectangle rect = figureCanvas.getClientArea();
+
+ visY = rect.height - CommonGraphConstants.XLEGENDSPACE;
+
+ double yIncrement = visY / 10;
+ int previousBottom = 0;
+
+ double multiplier = GraphsUtils.prettyMaxBytes(maxBytes)/visY;
+
+ for (int k = 10; k >= 0; k--)
+ {
+ // location for the value indicator is k * 1/10 the height of the display
+ int y = (int) (visY - (yIncrement * k));
+
+ int bytes = (int)(yIncrement * multiplier) * k;
+ String legend = "";
+
+ if (maxBytes < 10000)
+ {
+ legend += bytes + " B"; //$NON-NLS-1$
+ }
+ else if (maxBytes <= 500 * 1024)
+ {
+ legend += (bytes / 1024) + " KB"; //$NON-NLS-1$
+ }
+ else
+ {
+ legend += MBformat.format(((float) bytes / (1024 * 1024))) + " MB"; //$NON-NLS-1$
+ }
+
+ Point extent = localGC.stringExtent(legend);
+
+ localGC.drawLine(CommonGraphConstants.YLEGENDSPACE - 3, (int)y + 1, 60, (int)y + 1);
+
+ if (y >= previousBottom)
+ {
+ localGC.drawString(legend, 60 - extent.x -2, (int)y);
+ previousBottom = (int)y + extent.y;
+ }
+ }
+ localGC.setLineWidth(2);
+ localGC.drawLine(CommonGraphConstants.YLEGENDSPACE, 0, 60, rect.height);
+
+ final Image image = GraphsUtils.getDoubleYAxisVerticalLabel("Bytes");
+
+ localGC.setAdvanced(true);
+ final org.eclipse.swt.graphics.Rectangle rect2 = image.getBounds();
+ Transform transform = new Transform(Display.getDefault());
+
+ transform.translate(rect2.height / 2f, rect2.width / 2f);
+ transform.rotate(-90);
+ transform.translate(-rect2.width / 2f, -rect2.height / 2f);
+
+ localGC.setTransform(transform);
+ localGC.drawImage(image, -(int)visY/3, 1);
+
+ transform.dispose();
+ localGC.dispose();
+ }
+ });
+
+ numberAxis.addPaintListener(new PaintListener()
+ {
+ public void paintControl(PaintEvent event) {
+
+ GC localGC = event.gc;
+ org.eclipse.swt.graphics.Rectangle rect = figureCanvas.getClientArea();
+ visY = rect.height - CommonGraphConstants.XLEGENDSPACE;
+ double yIncrement = visY / 10;
+ int previousBottom = 0;
+ double multiplier = GraphsUtils.roundToNearestNumber(maxCount)/visY;
+ for (int k = 10; k >= 0; k--)
+ {
+ // location for the value indicator is k * 1/10 the height of the display
+ int y = (int) (visY - (yIncrement * k));
+ int yValue = (int)(yIncrement * multiplier) * k;
+ String legend = yValue + "";
+ Point extent = localGC.stringExtent(legend);
+ localGC.drawLine(50 - 3, (int)y + 1, 50, (int)y + 1);
+ if (y >= previousBottom)
+ {
+ localGC.drawString(legend, 50 - extent.x -2, (int)y);
+ previousBottom = (int)y + extent.y;
+ }
+ }
+ localGC.setLineWidth(2);
+ localGC.drawLine(50, 0, 50, rect.height);
+
+ final Image image = GraphsUtils.getDoubleYAxisVerticalLabel("Count");
+ localGC.setAdvanced(true);
+ final org.eclipse.swt.graphics.Rectangle rect2 = image.getBounds();
+ Transform transform = new Transform(Display.getDefault());
+
+ transform.translate(rect2.height / 2f, rect2.width / 2f);
+ transform.rotate(-90);
+ transform.translate(-rect2.width / 2f, -rect2.height / 2f);
+
+ localGC.setTransform(transform);
+ localGC.drawImage(image, -(int)visY/3, 10);
+
+ transform.dispose();
+ localGC.dispose();
+
+ }
+ });
+
+
+ figureCanvas.setBackground(ColorConstants.white);
+ Panel panel = new Panel()
+ {
+ public void paint(Graphics graphics)
+ {
+// DbgUtility.println(DbgUtility.PRIORITY_LOOP, "LinearIssuesGraph/Panel/paint START");
+
+ drawBackGroundLines(figureCanvas,graphics);
+ paintData(graphics);
+
+// DbgUtility.println(DbgUtility.PRIORITY_LOOP, "LinearIssuesGraph/Panel/paint END");
+ }
+ };
+
+ panel.setLayoutManager(new FlowLayout());
+ figureCanvas.setContents(panel);
+ figureCanvas.addMouseMoveListener(this);
+
+ final ScrollBar horizontalBar = figureCanvas.getHorizontalBar();
+ horizontalBar.addSelectionListener(new SelectionListener()
+ {
+
+ public void widgetDefaultSelected(SelectionEvent arg0) {
+
+ }
+
+ public void widgetSelected(SelectionEvent event) {
+ timeOffset = figureCanvas.getViewport().getViewLocation().x;
+ figureCanvas.redraw();
+ }
+
+ });
+
+ figureCanvas.addControlListener(new ControlAdapter()
+ {
+ public void controlResized(ControlEvent e) {
+ horizontalBar.setPageIncrement(figureCanvas.getBounds().width);
+
+ if(scalingNeeded)
+ {
+ zoomGraph();
+ scalingNeeded = false;
+ }
+ //setNewSize();
+ yAxis.redraw();
+ numberAxis.redraw();
+ figureCanvas.redraw();
+
+ }
+ });
+
+ zoomGraph();
+ figureCanvas.redraw();
+ hookContextMenu();
+ parentComposite.layout(true);
+ }
+
+ /**
+ * Draw background lines on the canvas
+ * @param canvas
+ * @param graphics
+ */
+ public void drawBackGroundLines(FigureCanvas canvas, Graphics graphics)
+ {
+ Rectangle canvasRect = graphics.getClip(new org.eclipse.draw2d.geometry.Rectangle());
+ graphics.setForegroundColor(new Color(Display.getDefault(), new RGB(200, 200, 200)));
+ graphics.setBackgroundColor(new Color(Display.getDefault(), new RGB(170,170,170)));
+
+ int height = canvas.getClientArea().height;
+ int width = canvas.getClientArea().width;
+
+ graphics.fillRectangle(new Rectangle(canvasRect.x,0,width, height-50));
+
+ double visY = height - CommonGraphConstants.XLEGENDSPACE;
+
+ int k = 0;
+
+ for (float y = 0; k <= 10; y += visY * 10000 / 100001, k++)
+ {
+ for(int x = canvasRect.x; x <= canvasRect.x + canvasRect.width; x += 5)
+ {
+ if ((x / 5) % 2 == 0) graphics.drawLine(x, ((int)y) + 1, x + 5, ((int)y) + 1);
+ }
+ }
+
+ graphics.setForegroundColor(new Color(Display.getDefault(), new RGB(100, 100, 100)));
+ graphics.setBackgroundColor(new Color(Display.getDefault(),new RGB(255, 255, 255)));
+
+ // horizontal lines
+ if (width > 0)
+ {
+ for (int x = 0; x <= canvasRect.x + canvasRect.width; x += 50)
+ {
+ if (x % 100 == 0)
+ graphics.setForegroundColor(new Color(Display.getDefault(), new RGB(100, 100, 100)));
+ else
+ graphics.setForegroundColor(new Color(Display.getDefault(),new RGB(200, 200, 200)));
+
+ for (int y = 0; y < height; y += 5)
+ {
+ if ((y / 5) % 2 == 0)
+ graphics.drawLine(x, y, x, y + 5);
+ }
+
+ }
+ }
+
+ graphics.setForegroundColor(new Color(Display.getDefault(), new RGB(100, 100, 100)));
+ graphics.setBackgroundColor(new Color(Display.getDefault(),new RGB(255, 255, 255)));
+
+ for (int x = 0; x <= canvasRect.x + canvasRect.width; x += 50)
+ {
+ double time = (double) x;
+ TimeObject timeObj = new TimeObject(time, scale);
+ graphics.drawString(timeObj.getHourMinutesAndSeconds(), x + 5, height - 13);
+ if(timeObj.hasDays()){
+ graphics.drawString(timeObj.getDays(), x + 5, height - 26);
+ }
+ }
+ Image img = GraphsUtils.getDoubleYAxisVerticalLabel(GenericGraph.TIME_X_AXIS_LABEL);
+ graphics.drawImage(img, width/2, height-30);
+
+ }
+
+ private void paintData(Graphics graphics)
+ {
+ DbgUtility.println(DbgUtility.PRIORITY_LOOP, this.getClass().getSimpleName() + "/paintData START");
+
+ try
+ {
+ Rectangle canvasRect = graphics.getClip(new org.eclipse.draw2d.geometry.Rectangle());
+
+ if(this.selectedIssues == null || selectedIssues.size() == 0)
+ return;
+
+ int [] listX = timeSamples;
+ int k = 0;
+
+ calculateMultiplier();
+
+ // Storing original graphics settings
+ Color origColor = graphics.getForegroundColor();
+ int origLineWidth = graphics.getLineWidth();
+ // Setting line width for drawing the graph
+ graphics.setLineWidth(CommonGraphConstants.DEFAULT_GRAPH_LINE_WIDTH);
+
+ for(ResultElements item:selectedIssues)
+ {
+ long [] valuesToBePlotted = item.getEventValues();
+
+ if(valuesToBePlotted == null)
+ continue;
+
+ double visY = canvasRect.height - CommonGraphConstants.XLEGENDSPACE;
+ double multiplier = 1;
+
+ EventTypes eventType = GraphsUtils.getMappedEvent(item.getEvent());
+
+ switch (eventType)
+ {
+ case NO_OF_FILES:
+ case NO_OF_PSHANDLES:
+ case HEAP_ALLOC_CELL_COUNT:
+ case HEAP_FREE_CELL_COUNT:
+ case SYSTEM_DATA:
+ multiplier = GraphsUtils.roundToNearestNumber(maxCount)/visY;
+ break;
+ default:
+ multiplier = GraphsUtils.prettyMaxBytes(maxBytes)/visY;
+ break;
+ }
+
+ List<Point> pointsList = new ArrayList<Point>();
+
+ for (int i = 0; i < valuesToBePlotted.length; i++)
+ {
+ // Showing only positive values
+ if(valuesToBePlotted[i] > 0){
+ int scaledXPoint = (int)(listX[i]/scale);
+ int scaledYPoint = (int) (visY - valuesToBePlotted[i] /multiplier);;
+ Point p = new Point(scaledXPoint, scaledYPoint);
+ pointsList.add(p);
+ }
+ }
+
+ // Converting point list into integer array for drawing
+ int[] points = GraphsUtils.convertPointListToIntArray(pointsList);
+
+ graphics.setForegroundColor(item.getColor());
+
+ // Drawing graph
+ graphics.drawPolyline(points);
+ // Drawing markers to the data points
+ GraphsUtils.drawMarkers(graphics, points);
+
+ Polyline line = new Polyline();
+ line.setPoints(new PointList(points));
+ pointsData.put(item, line);
+
+ k++;
+ }
+
+ // Restoring original settings
+ graphics.setForegroundColor(origColor);
+ graphics.setLineWidth(origLineWidth);
+
+ }catch(Exception e){
+ e.printStackTrace();
+ }
+ }
+
+ private void calculateMultiplier()
+ {
+ maxCount = 10;
+ maxBytes = 10;
+
+ if(selectedIssues == null)
+ return;
+
+ for(ResultElements item:selectedIssues)
+ {
+ long [] valuesToBePlotted = item.getEventValues();
+
+ if(valuesToBePlotted == null)
+ return;
+
+ int maxValue = (int)calculateMaxValue(valuesToBePlotted);
+
+ EventTypes eventType = GraphsUtils.getMappedEvent(item.getEvent());
+
+ switch (eventType)
+ {
+ case NO_OF_FILES:
+ case NO_OF_PSHANDLES:
+ case HEAP_ALLOC_CELL_COUNT:
+ case HEAP_FREE_CELL_COUNT:
+ case SYSTEM_DATA:
+ if(maxValue > maxCount)
+ maxCount = maxValue;
+ break;
+ default:
+ if(maxValue > maxBytes)
+ maxBytes = maxValue;
+ break;
+ }
+ }
+
+ }
+ /**
+ * Adds Pop-Up menu items on th graph area.
+ *
+ */
+ private void hookContextMenu() {
+ MenuManager menuMgr = new MenuManager("#PopupMenu"); //$NON-NLS-1$
+ menuMgr.setRemoveAllWhenShown(true);
+ menuMgr.addMenuListener(new IMenuListener() {
+ public void menuAboutToShow(IMenuManager manager) {
+ fillContextMenu(manager);
+ }
+ });
+ Menu menu = menuMgr.createContextMenu(figureCanvas);
+ figureCanvas.setMenu(menu);
+ }
+
+ protected void fillContextMenu(IMenuManager manager) {
+ zoomIn = new Action()
+ {
+ public void run()
+ {
+ zoomIn();
+ }
+ {
+ this.setText(ZOOM_IN_CONTEXT_MENU_TITLE);
+ }
+ };
+
+ zoomOut = new Action()
+ {
+ public void run()
+ {
+ zoomOut();
+ }
+ {
+ this.setText(ZOOM_OUT_CONTEXT_MENU_TITLE);
+ }
+ };
+ IAction showEntireGraph = new Action()
+ {
+ public void run()
+ {
+ zoomGraph();
+ }
+ {
+ this.setText(CommonGraphConstants.SHOW_ENTIRE_GRAPH_CONTEXT_MENU_ITEM_TITLE);
+ }
+ };
+
+ IAction saveGraph = new Action()
+ {
+ public void run()
+ {
+ GraphsUtils.saveGraph(parentComposite);
+ }
+ {
+ this.setText(CommonGraphConstants.SAVE_GRAPH_CONTEXT_MENU_ITEM_TITLE);
+ }
+ };
+
+ copy = new CopyImageToClipboardAction(this);
+
+ manager.add(zoomIn);
+ manager.add(new Separator());
+ manager.add(zoomOut);
+ manager.add(new Separator());
+ manager.add(showEntireGraph);
+ manager.add(saveGraph);
+ manager.add(copy);
+
+ // Finally updating action states
+ updateViewActionEnabledStates();
+
+ }
+
+ /**
+ * Sets enabled/disabled states for actions commands
+ * on this view, based on the current application state.
+ * This method should be called whenever an operation is
+ * started or stopped that might have effect on action
+ * button states.
+ */
+ private void updateViewActionEnabledStates() {
+ // Zoom In
+ setEnableState(zoomIn, !(this.scale == GraphsUtils.nextScale(scale, false)));
+
+ // Zoom Out
+ boolean zoomOutEnableCondition1 = !(this.scale == GraphsUtils.nextScale(scale, true));
+ int width = figureCanvas.getClientArea().width;
+ int lastTimeSample = timeSamples[timeSamples.length - 1];
+ boolean zoomOutEnableCondition2 = !(lastTimeSample / this.scale <= width);
+ setEnableState(zoomOut, zoomOutEnableCondition1 && zoomOutEnableCondition2);
+ }
+
+
+ /* (non-Javadoc)
+ * @see com.nokia.s60tools.swmtanalyser.ui.graphs.ZoomableGraph#zoomIn()
+ */
+ protected void zoomIn()
+ {
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "LinearIssuesGraph - Zoom In");
+ //Preconditions checked already in updateViewActionEnabledStates
+ this.scale = GraphsUtils.nextScale(scale, false);
+ figureCanvas.redraw();
+ setNewSize();
+ }
+
+ /* (non-Javadoc)
+ * @see com.nokia.s60tools.swmtanalyser.ui.graphs.ZoomableGraph#zoomOut()
+ */
+ protected void zoomOut()
+ {
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "LinearIssuesGraph - Zoom Out");
+ //Preconditions checked already in updateViewActionEnabledStates
+ this.scale = GraphsUtils.nextScale(this.scale, true);
+ setNewSize();
+
+ }
+ /**
+ * This method zoom in the graph area to the maximum possible scale
+ * and then zooms out, so that it fits in the canvas area
+ */
+ public void zoomGraph()
+ {
+ int width = figureCanvas.getClientArea().width;
+
+ if(width <=0)
+ return;
+
+ double new_scale = this.scale;
+
+ double prevNew = new_scale;
+
+ int lastSampleTime = timeSamples[timeSamples.length - 1];
+ //first zoom in until it is too big to fit
+ while (lastSampleTime / new_scale <= width){
+ new_scale = GraphsUtils.nextScale(new_scale, false);
+
+ if(prevNew == new_scale)
+ break;
+
+ prevNew = new_scale;
+
+ }
+ // now zoom out until it just fits
+ while (lastSampleTime / new_scale > width){
+ new_scale = GraphsUtils.nextScale(new_scale, true);
+
+ if(prevNew == new_scale)
+ break;
+
+ prevNew = new_scale;
+ }
+
+ if (new_scale == this.scale)
+ return;
+
+ this.scale = new_scale;
+
+ setNewSize();
+ }
+
+
+ /**
+ * This method sets the size of the panel, when scale is changed.
+ * When graph extends beyond visible area, horizontal scroll bar appears automatically.
+ *
+ */
+ private void setNewSize()
+ {
+ int lastSample = timeSamples[timeSamples.length - 1];
+
+ int prefSize = (int)(lastSample/scale);
+
+ timeOffset = 0;
+ Panel panel = (Panel)(figureCanvas.getContents());
+ panel.setPreferredSize(prefSize + 100, 0);
+
+ if (prefSize >= figureCanvas.getClientArea().width) {
+ timeOffset = figureCanvas.getViewport().getViewLocation().x;
+ panel.setSize(prefSize + 100, 0);
+ }
+
+ }
+
+ /**
+ * Set issues that user has been selected
+ * @param selectedIssues
+ */
+ public void setSelectedIssues(ArrayList<ResultElements> selectedIssues) {
+ this.selectedIssues = selectedIssues;
+ }
+
+ /**
+ * Set parsed data
+ * @param logsData
+ */
+ public void setLogData(ParsedData logsData)
+ {
+ SWMTLogReaderUtils utils = new SWMTLogReaderUtils();
+ timeSamples = utils.getTimeIntervalsFromLogData(logsData);
+ }
+
+ private long calculateMaxValue(long [] values)
+ {
+ long maxValue = 0;
+
+ for(int i=0; i<values.length; i++)
+ {
+ if(values[i] > maxValue)
+ maxValue = values[i];
+ }
+
+ return maxValue;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.swt.events.MouseMoveListener#mouseMove(org.eclipse.swt.events.MouseEvent)
+ */
+ public void mouseMove(MouseEvent event) {
+ int x = event.x;
+ int y = event.y;
+
+ if(y > (int)visY)
+ figureCanvas.setToolTipText(null);
+
+ String text = "";
+ double xValue = x + timeOffset;
+ int scaledX = (int)(xValue * scale);
+ double valY = visY - y;
+
+ double count_multiplier = GraphsUtils.roundToNearestNumber(maxCount)/visY;
+ double bytes_multiplier = GraphsUtils.prettyMaxBytes(maxBytes)/visY;
+
+ String scaledY_1 = getFormattedValues(valY * bytes_multiplier);
+ int scaledY_2 = (int)(Math.round((valY * count_multiplier)));
+
+ text += scaledX + "s " + scaledY_1 + " , " + scaledY_2 ;
+
+ if(selectedIssues != null)
+ {
+ for(ResultElements item:selectedIssues)
+ {
+ Polyline line = pointsData.get(item);
+
+ if(line != null && line.containsPoint(x, y))
+ {
+ text += "\n" + item.getItemName();
+ text += " -- " + item.getEvent();
+ }
+ }
+ }
+
+ figureCanvas.setToolTipText(text);
+ figureCanvas.redraw();
+ }
+
+ /**
+ *
+ * @param bytes represents value to be formatted.
+ * @return formatted value
+ */
+ private String getFormattedValues(double bytes)
+ {
+ String scaledY = "";
+
+ if (bytes < 10000)
+ {
+ scaledY += Bytes_Format.format(bytes) + " B"; //$NON-NLS-1$
+ }
+ else if (bytes <= 500 * 1024)
+ {
+ scaledY += Bytes_Format.format(bytes / 1024) + " KB"; //$NON-NLS-1$
+ }
+ else
+ {
+ scaledY += MBformat.format(((float) bytes / (1024 * 1024))) + " MB"; //$NON-NLS-1$
+ }
+
+ return scaledY;
+ }
+
+ /* (non-Javadoc)
+ * @see com.nokia.s60tools.swmtanalyser.ui.actions.IImageProvider#getImage()
+ */
+ public Image getImage() {
+ return new Image(Display.getCurrent(), parentComposite.getClientArea().width, parentComposite.getClientArea().height);
+ }
+
+ /* (non-Javadoc)
+ * @see com.nokia.s60tools.swmtanalyser.ui.actions.IImageProvider#getDrawable()
+ */
+ public Drawable getDrawable() {
+ return parentComposite;
+ }
+
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/ui/graphs/SwmtGraph.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,537 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+package com.nokia.s60tools.swmtanalyser.ui.graphs;
+
+import java.util.ArrayList;
+
+import org.eclipse.draw2d.ColorConstants;
+import org.eclipse.draw2d.FigureCanvas;
+import org.eclipse.draw2d.FlowLayout;
+import org.eclipse.draw2d.Graphics;
+import org.eclipse.draw2d.Panel;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.action.IMenuListener;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.action.Separator;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ControlAdapter;
+import org.eclipse.swt.events.ControlEvent;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.MouseMoveListener;
+import org.eclipse.swt.events.PaintEvent;
+import org.eclipse.swt.events.PaintListener;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Drawable;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.layout.FormAttachment;
+import org.eclipse.swt.layout.FormData;
+import org.eclipse.swt.layout.FormLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swt.widgets.ScrollBar;
+
+import com.nokia.s60tools.swmtanalyser.data.ChunksData;
+import com.nokia.s60tools.swmtanalyser.data.DiskOverview;
+import com.nokia.s60tools.swmtanalyser.data.GlobalDataChunks;
+import com.nokia.s60tools.swmtanalyser.data.KernelElements;
+import com.nokia.s60tools.swmtanalyser.data.ParsedData;
+import com.nokia.s60tools.swmtanalyser.data.SystemData;
+import com.nokia.s60tools.swmtanalyser.data.ThreadData;
+import com.nokia.s60tools.ui.IImageProvider;
+import com.nokia.s60tools.ui.actions.CopyImageToClipboardAction;
+import com.nokia.s60tools.util.debug.DbgUtility;
+/**
+ * Graph to be shown in Graphs tab.
+ *
+ */
+public class SwmtGraph extends ZoomableGraph implements MouseMoveListener, IImageProvider {
+
+ private FigureCanvas figureCanvas;
+ private FigureCanvas yAxis;
+ private ParsedData logData;
+ private Composite parentComposite;
+
+ private boolean scaleNeedsUpdation = true;
+ private GenericGraph graph;
+ /**
+ * Constructor
+ * @param parent
+ */
+ public SwmtGraph(Composite parent)
+ {
+ this.parentComposite = parent;
+ }
+
+ /**
+ * Set parsed data
+ * @param parsedData
+ */
+ public void setInputCyclesData(ParsedData parsedData)
+ {
+ this.logData = parsedData;
+ }
+
+ /**
+ * Draw graph area
+ */
+ public void constructGraphArea()
+ {
+ if(this.logData == null || this.logData.getLogData() == null || parentComposite == null)
+ return;
+
+ Control [] children = parentComposite.getChildren();
+
+ if(children != null)
+ {
+ for(Control child:children)
+ child.dispose();
+ }
+
+ Composite parent = new Composite(parentComposite, SWT.NONE);
+ parent.setLayout(new FormLayout());
+
+ yAxis = new FigureCanvas(parent);
+ figureCanvas = new FigureCanvas(parent);
+ //figureCanvas.setSize(500, 450);
+
+ FormData formData = new FormData();
+ formData.top = new FormAttachment(0);
+ formData.bottom = new FormAttachment(100);
+ formData.left = new FormAttachment(0);
+ formData.width = 60;
+ yAxis.setLayoutData(formData);
+
+ formData = new FormData();
+ formData.top = new FormAttachment(0);
+ formData.bottom = new FormAttachment(100);
+ formData.left = new FormAttachment(yAxis, 0, SWT.RIGHT);
+ formData.right = new FormAttachment(100);
+ figureCanvas.setLayoutData(formData);
+
+ yAxis.setBackground(ColorConstants.white);
+ yAxis.addPaintListener(new PaintListener()
+ {
+
+ public void paintControl(PaintEvent event) {
+
+ if(graph != null)
+ graph.paintYAxis(event.gc);
+ else
+ event.gc.dispose();
+
+ }
+ });
+
+ yAxis.addControlListener(new ControlAdapter(){
+ public void controlResized(ControlEvent e) {
+ }
+ });
+
+ figureCanvas.setBackground(new Color(Display.getDefault(), new RGB(255,255,255)));
+
+ Panel panel = new Panel()
+ {
+ public void paint(Graphics graphics)
+ {
+ DbgUtility.println(DbgUtility.PRIORITY_LOOP, "SwmtGraph/Panel/paint START");
+
+ if(graph != null){
+ graph.drawBackGroundLines(figureCanvas, graphics);
+ graph.paint(graphics);
+ }
+ else{
+ erase();
+ }
+ DbgUtility.println(DbgUtility.PRIORITY_LOOP, "SwmtGraph/Panel/paint END");
+ }
+
+
+ };
+
+ panel.setLayoutManager(new FlowLayout());
+
+ figureCanvas.setContents(panel);
+
+ figureCanvas.addMouseMoveListener(this);
+ hookContextMenu();
+
+ final ScrollBar horizontalBar = figureCanvas.getHorizontalBar();
+
+ horizontalBar.addSelectionListener(new SelectionListener()
+ {
+
+ public void widgetDefaultSelected(SelectionEvent arg0) {
+
+ }
+
+ public void widgetSelected(SelectionEvent event) {
+
+ if(graph != null){
+ graph.setScrolledXOrigin((figureCanvas.getViewport().getViewLocation().x));
+ }
+
+ figureCanvas.redraw();
+ }
+
+ });
+
+ figureCanvas.addControlListener(new ControlAdapter()
+ {
+ public void controlResized(ControlEvent e) {
+ horizontalBar.setPageIncrement(figureCanvas.getBounds().width);
+
+ if(graph != null)
+ graph.setVisualSize(figureCanvas.getClientArea().height);
+ if(scaleNeedsUpdation)
+ {
+ zoomGraph();
+ scaleNeedsUpdation = false;
+ }
+
+ yAxis.redraw();
+ figureCanvas.redraw();
+
+ }
+ });
+ parentComposite.layout();
+
+ }
+
+ /**
+ * Add Pop-Up Menus on Graph area.
+ *
+ */
+ private void hookContextMenu() {
+ MenuManager menuMgr = new MenuManager("#PopupMenu"); //$NON-NLS-1$
+ menuMgr.setRemoveAllWhenShown(true);
+ menuMgr.addMenuListener(new IMenuListener() {
+ public void menuAboutToShow(IMenuManager manager) {
+ fillContextMenu(manager);
+ }
+ });
+ Menu menu = menuMgr.createContextMenu(figureCanvas);
+ figureCanvas.setMenu(menu);
+ }
+
+ protected void fillContextMenu(IMenuManager manager) {
+
+ zoomIn = new Action()
+ {
+ public void run()
+ {
+ zoomIn();
+ }
+ {
+ this.setText(ZOOM_IN_CONTEXT_MENU_TITLE);
+ }
+ };
+
+ zoomOut = new Action()
+ {
+ public void run()
+ {
+ zoomOut();
+ }
+ {
+ this.setText(ZOOM_OUT_CONTEXT_MENU_TITLE);
+ }
+ };
+ IAction showEntireGraph = new Action()
+ {
+ public void run()
+ {
+ zoomGraph();
+ }
+ {
+ this.setText(CommonGraphConstants.SHOW_ENTIRE_GRAPH_CONTEXT_MENU_ITEM_TITLE);
+ }
+ };
+
+ IAction saveGraph = new Action()
+ {
+ public void run()
+ {
+ GraphsUtils.saveGraph(parentComposite);
+ }
+ {
+ this.setText(CommonGraphConstants.SAVE_GRAPH_CONTEXT_MENU_ITEM_TITLE);
+ }
+ };
+
+ copy = new CopyImageToClipboardAction(this);
+
+ manager.add(zoomIn);
+ manager.add(new Separator());
+ manager.add(zoomOut);
+ manager.add(new Separator());
+ manager.add(showEntireGraph);
+ manager.add(saveGraph);
+ manager.add(copy);
+
+ // Finally updating action states
+ updateViewActionEnabledStates();
+ }
+
+ /**
+ * This method acts as an interface for redrawig graphs
+ * @param graph
+ */
+ public void redraw(GenericGraph graph)
+ {
+ this.graph = graph;
+
+ try{
+
+ graph.setVisualSize(figureCanvas.getClientArea().height);
+ graph.prepareData();
+ int [] timeSamples = graph.calculateTimeIntervals();
+ graph.lastSampleTime = timeSamples[timeSamples.length -1];
+
+ //Zooms Graph to fit last sample value
+ zoomGraph();
+ yAxis.redraw();
+ figureCanvas.redraw();
+ }catch(Exception e){
+ e.printStackTrace();
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.swt.events.MouseMoveListener#mouseMove(org.eclipse.swt.events.MouseEvent)
+ */
+ public void mouseMove(MouseEvent event) {
+
+ if(this.graph != null)
+ {
+ this.figureCanvas.setToolTipText(this.graph.getToolTipText(event.x, event.y));
+ this.figureCanvas.redraw();
+ }
+ }
+
+ /**
+ * Clear graph
+ */
+ public void clearGraph()
+ {
+ this.graph = null;
+ try{
+ yAxis.redraw();
+ figureCanvas.redraw();
+
+ }catch(NullPointerException e){
+
+ }
+ }
+
+ /**
+ * This method stores data corresponding to given item, so that it can be
+ * used in Graphed items view.
+ * @param itemName
+ * @param allEventsGraph
+ */
+ public void storeClearedEventValues(String itemName, GraphForAllEvents allEventsGraph)
+ {
+ if(this.graph != null)
+ {
+ if(graph instanceof ThreadsGraph){
+ ArrayList<ThreadData> values = ((ThreadsGraph)(graph)).getDataForThread(itemName);
+
+ allEventsGraph.setHeapSizeForThread(itemName, values);
+
+ }
+ else if(graph instanceof ChunksGraph)
+ {
+ if(graph.getEvent().equals(GenericGraph.EventTypes.GLOBAL_DATA_SIZE))
+ {
+ ArrayList<GlobalDataChunks> values = ((ChunksGraph)(graph)).getGlobalChunkData(itemName);
+
+ allEventsGraph.setGlobalChunkSizeForChunk(itemName, values);
+ }
+ else if(graph.getEvent().equals(GenericGraph.EventTypes.NON_HEAP_CHUNK_SIZE))
+ {
+ ArrayList<ChunksData> values = ((ChunksGraph)(graph)).getNonHeapChunkData(itemName);
+
+ allEventsGraph.setNonHeapChunkSizeForChunk(itemName, values);
+ }
+
+ }
+ else if(graph instanceof DisksGraph)
+ {
+ if(graph.getEvent().equals(GenericGraph.EventTypes.DISK_USED_SIZE) ||
+ graph.getEvent().equals(GenericGraph.EventTypes.DISK_TOTAL_SIZE))
+ {
+ ArrayList<DiskOverview> values = ((DisksGraph)(graph)).getDiskData(itemName);
+
+ allEventsGraph.setDiskData(itemName, values);
+ }
+
+ else if(graph.getEvent().equals(GenericGraph.EventTypes.RAM_USED)||
+ graph.getEvent().equals(GenericGraph.EventTypes.RAM_TOTAL))
+ {
+ ArrayList<SystemData> sysData = ((DisksGraph)(graph)).getSystemData();
+
+ allEventsGraph.setSystemData(sysData);
+ }
+ }
+ else if(graph instanceof SystemDataGraph)
+ {
+ ArrayList<KernelElements> kernelData = ((SystemDataGraph)(graph)).getKernelData();
+
+ allEventsGraph.setKernelData(kernelData);
+ }
+ }
+ }
+
+ /**
+ * Sets enabled/disabled states for actions commands
+ * on this view, based on the current application state.
+ * This method should be called whenever an operation is
+ * started or stopped that might have effect on action
+ * button states.
+ */
+ private void updateViewActionEnabledStates() {
+ //Zoom In
+ setEnableState(zoomIn, !(this.graph != null && graph.getScale() == GraphsUtils.nextScale(graph.getScale(), false)));
+
+ //Zoom Out
+ if(this.graph != null)
+ {
+ boolean zoomOutEnableCondition1 = !(graph.getScale() == GraphsUtils.nextScale(graph.getScale(), true));
+ int width = figureCanvas.getClientArea().width;
+ boolean zoomOutEnableCondition2 = !(graph.lastSampleTime / graph.getScale() <= width);
+ setEnableState(zoomOut, zoomOutEnableCondition1 && zoomOutEnableCondition2);
+ }
+ else{
+ setEnableState(zoomOut, false);
+ }
+
+ }
+
+ /* (non-Javadoc)
+ * @see com.nokia.s60tools.swmtanalyser.ui.graphs.ZoomableGraph#zoomIn()
+ */
+ protected void zoomIn()
+ {
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "SwmtGraph - Zoom In");
+ //Preconditions checked already in updateViewActionEnabledStates
+ graph.setScale(GraphsUtils.nextScale(graph.getScale(), false));
+ setNewSize();
+ }
+
+ /* (non-Javadoc)
+ * @see com.nokia.s60tools.swmtanalyser.ui.graphs.ZoomableGraph#zoomOut()
+ */
+ protected void zoomOut()
+ {
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "SwmtGraph - Zoom Out");
+ //Preconditions checked already in updateViewActionEnabledStates
+ graph.setScale(GraphsUtils.nextScale(graph.getScale(), true));
+ setNewSize();
+ }
+
+ /**
+ * This method first zooms in graph to the maximum possible scale
+ * and zooms out so that it fits in the canvas area.
+ *
+ */
+ public void zoomGraph()
+ {
+ int width = figureCanvas.getClientArea().width;
+
+ if(width <=0 || this.graph == null)
+ return;
+
+ double new_scale = graph.getScale();
+
+ double prevNew = new_scale;
+
+ //first zoom in until it is too big to fit
+ while (graph.lastSampleTime / new_scale <= width){
+ new_scale = GraphsUtils.nextScale(new_scale, false);
+
+ if(prevNew == new_scale)
+ break;
+
+ prevNew = new_scale;
+
+ }
+ // now zoom out until it just fits
+ while (graph.lastSampleTime / new_scale > width){
+ new_scale = GraphsUtils.nextScale(new_scale, true);
+
+ if(prevNew == new_scale)
+ break;
+
+ prevNew = new_scale;
+ }
+
+ if (new_scale == graph.getScale())
+ return;
+
+ graph.setScale(new_scale);
+ setNewSize();
+ }
+
+ /**
+ * This method sets the size of the panel, when scale is changed.
+ * When graph extends beyond visible area, horizontal scroll bar appears automatically.
+ *
+ */
+ private void setNewSize()
+ {
+ if(graph == null)
+ return;
+
+ graph.setScrolledXOrigin(0);
+ double scale = graph.getScale();
+ int lastSample = graph.lastSampleTime;
+
+ int prefSize = (int)(lastSample/scale);
+
+ Panel panel = (Panel)(figureCanvas.getContents());
+ panel.setPreferredSize(prefSize + 100, 0);
+
+ if (prefSize >= figureCanvas.getClientArea().width) {
+ graph.setScrolledXOrigin(figureCanvas.getViewport().getViewLocation().x);
+ panel.setSize(prefSize + 100, 0);
+ }
+
+ }
+
+ /* (non-Javadoc)
+ * @see com.nokia.s60tools.swmtanalyser.ui.actions.IImageProvider#getImage()
+ */
+ public Image getImage() {
+ return new Image(Display.getCurrent(), parentComposite.getClientArea().width, parentComposite.getClientArea().height);
+ }
+
+ /* (non-Javadoc)
+ * @see com.nokia.s60tools.swmtanalyser.ui.actions.IImageProvider#getDrawable()
+ */
+ public Drawable getDrawable() {
+ return parentComposite;
+ }
+
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/ui/graphs/SystemDataGraph.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,220 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+package com.nokia.s60tools.swmtanalyser.ui.graphs;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+
+import org.eclipse.draw2d.Graphics;
+import org.eclipse.draw2d.Polyline;
+import org.eclipse.draw2d.geometry.PointList;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Transform;
+import org.eclipse.swt.widgets.Display;
+
+import com.nokia.s60tools.swmtanalyser.data.KernelElements;
+import com.nokia.s60tools.swmtanalyser.model.SWMTLogReaderUtils;
+import com.nokia.s60tools.util.debug.DbgUtility;
+
+/**
+ * This class contains all needed logic to paint data related to System data.
+ */
+public class SystemDataGraph extends GenericGraph
+{
+ private ArrayList<KernelElements> kernelElements;
+ private HashMap <String, Polyline> pointsData = new HashMap<String, Polyline>();
+
+ private double visY;
+ private double multiplier;
+
+ /* (non-Javadoc)
+ * @see com.nokia.s60tools.swmtanalyser.ui.graphs.GenericGraph#paint(org.eclipse.draw2d.Graphics)
+ */
+ public void paint(Graphics graphics) {
+
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION, this.getClass().getSimpleName() + "/paint START");
+
+ ArrayList<String> selectedItems = this.getUserSelectedItems();
+
+ if(selectedItems == null)
+ return;
+
+ int [] listX = this.calculateTimeIntervals();
+ this.lastSampleTime = listX[listX.length-1];
+
+ int k=0;
+
+ // Storing drawing settings
+ Color origColor = graphics.getForegroundColor();
+ int origLineWidth = graphics.getLineWidth();
+ // Setting drawing settings
+ graphics.setLineWidth(CommonGraphConstants.DEFAULT_GRAPH_LINE_WIDTH);
+
+ for(String item: selectedItems)
+ {
+ int [] valuesToBePlotted = getValuesForGivenKerenelElement(item, kernelElements);
+
+ if(valuesToBePlotted == null)
+ return;
+
+ int [] points = new int[valuesToBePlotted.length *2];
+
+ double visY = visualSizeY - CommonGraphConstants.XLEGENDSPACE;
+
+ for (int i = 0, j = 0; i < valuesToBePlotted.length; i++)
+ {
+ points[j++] = (int)(listX[i]/getScale());
+
+ points[j] =(int) (visY - valuesToBePlotted[i] /multiplier);
+
+ if (points[j] < 0)
+ points[j] = 0;
+
+ j++;
+ }
+
+ graphics.setForegroundColor(this.getColors().get(k));
+ // Drawing graph
+ graphics.drawPolyline(points);
+ // Drawing markers to the data points
+ GraphsUtils.drawMarkers(graphics, points);
+
+ Polyline line = new Polyline();
+ line.setPoints(new PointList(points));
+ pointsData.put(item, line);
+
+ k++;
+ }
+
+ // Restoring drawing settings
+ graphics.setForegroundColor(origColor);
+ graphics.setLineWidth(origLineWidth);
+
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION, this.getClass().getSimpleName() + "/paint END");
+ }
+
+ /* (non-Javadoc)
+ * @see com.nokia.s60tools.swmtanalyser.ui.graphs.GenericGraph#paintYAxis(org.eclipse.swt.graphics.GC)
+ */
+ public void paintYAxis( GC gc) {
+
+ visY = visualSizeY - CommonGraphConstants.XLEGENDSPACE;
+ multiplier = GraphsUtils.roundToNearestNumber(maxBytes) / visY;
+
+ double yIncrement = visY / 10;
+ int previousBottom = 0;
+
+ for (int k = 10; k >= 0; k--)
+ {
+ // location for the value indicator is k * 1/10 the height of the display
+ int y = (int) (visY - (yIncrement * k));
+
+ int bytes = (int)(yIncrement * multiplier)* k;
+
+ String legend = "";
+ legend += bytes ;
+
+ Point extent = gc.stringExtent(legend);
+
+ gc.drawLine(CommonGraphConstants.YLEGENDSPACE - 3, (int)y + 1, CommonGraphConstants.YLEGENDSPACE, (int)y + 1);
+
+ if (y >= previousBottom)
+ {
+ gc.drawString(legend, CommonGraphConstants.YLEGENDSPACE - extent.x -2, (int)y);
+ previousBottom = (int)y + extent.y;
+ }
+ }
+
+ final Image image = this.getVerticalLabel("Count");
+ gc.setAdvanced(true);
+ final org.eclipse.swt.graphics.Rectangle rect2 = image.getBounds();
+ Transform transform = new Transform(Display.getDefault());
+
+ transform.translate(rect2.height / 2f, rect2.width / 2f);
+ transform.rotate(-90);
+ transform.translate(-rect2.width / 2f, -rect2.height / 2f);
+
+ gc.setTransform(transform);
+ gc.drawImage(image, -(int)visY/3, 0);
+
+ transform.dispose();
+ gc.dispose();
+
+ }
+
+ /* (non-Javadoc)
+ * @see com.nokia.s60tools.swmtanalyser.ui.graphs.GenericGraph#prepareData()
+ */
+ public void prepareData() {
+
+ SWMTLogReaderUtils utils = new SWMTLogReaderUtils();
+
+ kernelElements = utils.getKerenelElemsFromAllCycles(this.getCyclesData());
+
+ for(String item:getUserSelectedItems())
+ {
+ int [] values = getValuesForGivenKerenelElement(item, kernelElements);
+
+ int maxValue = calculateMaxValue(values);
+
+ if(maxValue > maxBytes){
+ maxBytes = maxValue;
+ }
+ }
+ }
+
+
+ /* (non-Javadoc)
+ * @see com.nokia.s60tools.swmtanalyser.ui.graphs.GenericGraph#getToolTipText(int, int)
+ */
+ public String getToolTipText(int x, int y)
+ {
+ if(y > (int)visY)
+ return null;
+
+ String text = "";
+
+ double xValue = x + timeOffset;
+ int scaledX = (int)(xValue * getScale());
+ int valY = (int)visY - y;
+ int scaledY = (int)(valY * multiplier);
+
+ text += scaledX + " s, " + scaledY;
+
+ for(String elem: getUserSelectedItems())
+ {
+ Polyline line = pointsData.get(elem);
+
+ if(line != null && line.containsPoint(x, y))
+ text += "\n" + elem;
+ }
+
+ return text;
+ }
+
+ /**
+ * Get kernel data
+ * @return kernel data
+ */
+ public ArrayList<KernelElements> getKernelData()
+ {
+ return this.kernelElements;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/ui/graphs/ThreadsGraph.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,477 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+package com.nokia.s60tools.swmtanalyser.ui.graphs;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+import org.eclipse.draw2d.Graphics;
+import org.eclipse.draw2d.Polyline;
+import org.eclipse.draw2d.geometry.PointList;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Transform;
+import org.eclipse.swt.widgets.Display;
+
+import com.nokia.s60tools.swmtanalyser.data.CycleData;
+import com.nokia.s60tools.swmtanalyser.data.ThreadData;
+import com.nokia.s60tools.swmtanalyser.model.SWMTLogReaderUtils;
+import com.nokia.s60tools.util.debug.DbgUtility;
+
+/**
+ * This class contains all needed logic to paint data related to Threads.
+ */
+public class ThreadsGraph extends GenericGraph {
+
+ //
+ // Members
+ //
+ private HashMap<String, ArrayList<ThreadData>> threadData = new HashMap<String, ArrayList<ThreadData>>();
+ private HashMap<String, Polyline> samplesData = new HashMap<String, Polyline>();
+ private double visY;
+ private double multiplier;
+ private boolean yAxisNeedsToBeChanged = false;
+
+ /* (non-Javadoc)
+ * @see com.nokia.s60tools.swmtanalyser.ui.graphs.GenericGraph#paint(org.eclipse.draw2d.Graphics)
+ */
+ public void paint(Graphics graphics) {
+
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION, this.getClass().getSimpleName() + "/paint START");
+
+ // Getting threads that user has been selected
+ ArrayList<String> threadsList = this.getUserSelectedItems();
+
+ if(threadsList == null){
+ // No thread data selected for drawing
+ return;
+ }
+
+ // Storing original settings before graphs are painted with case-specific settings
+ int origLineWidth = graphics.getLineWidth();
+ Color origColor = graphics.getForegroundColor();
+ int origLineStyle = graphics.getLineStyle();
+
+ // Setting graph drawing specific settings
+ graphics.setLineWidth(CommonGraphConstants.DEFAULT_GRAPH_LINE_WIDTH);
+ graphics.setLineStyle(SWT.LINE_SOLID);
+
+ // Getting cycle time stamps
+ int [] listX = this.calculateTimeIntervals();
+ this.lastSampleTime = listX[listX.length-1];
+
+ // Each thread is drawn by different color stored in external array
+ int colorIndex=0;
+ visY = visualSizeY - CommonGraphConstants.XLEGENDSPACE;
+
+ // Looping through all the threads
+ for(String th: threadsList)
+ {
+ ArrayList<ThreadData> data = threadData.get(th);
+
+ boolean handleDeleted = false;
+
+ int[] valuesToBePlotted = new int[data.size()];
+ int [] points = new int[valuesToBePlotted.length *2];
+
+ List<List<Integer>> ListOfSolidLinePoints = new ArrayList<List<Integer>>();
+ ArrayList<Integer> solidLinePoints = new ArrayList<Integer>();
+
+ for(int i =0, j=0; i<data.size(); i++, j++)
+ {
+ EventTypes event = this.getEvent();
+
+ valuesToBePlotted[i] = getEventValueFromThreadData(data.get(i), event);
+ DbgUtility.println(DbgUtility.PRIORITY_LOOP, "valuesToBePlotted[i] before scaling: " + valuesToBePlotted[i]);
+
+ if (valuesToBePlotted[i] <= 0){
+ // Not showing zero values to a user, not meaningful data
+ DbgUtility.println(DbgUtility.PRIORITY_LOOP, "continued to next Y-value because value was <= 0");
+ continue;
+ }
+
+ // Scaling both X and Y coordinate according currently used scaling
+ int x_point = (int)(listX[i]/getScale());
+ int y_point =(int) (visY - valuesToBePlotted[i] /multiplier);
+
+ // Drawing data only if handle has been
+ if(!handleDeleted){
+ if(y_point > 0){
+ solidLinePoints.add(x_point);
+ solidLinePoints.add(y_point);
+ DbgUtility.println(DbgUtility.PRIORITY_LOOP, "add 1: x_point: " + x_point + ", y_point: " + y_point);
+ }
+ else{
+ DbgUtility.println(DbgUtility.PRIORITY_LOOP, "skipped because non-positive Y-axis value");
+ }
+ }
+
+ if(data.get(i).isKernelHandleDeleted() && !handleDeleted){
+ handleDeleted = true;
+ }
+
+ if(handleDeleted && data.get(i).getStatus() == CycleData.New)
+ {
+ handleDeleted = false;
+
+ if(y_point > 0){
+ // Graphing only positive values
+ solidLinePoints.add(x_point);
+ solidLinePoints.add(y_point);
+ DbgUtility.println(DbgUtility.PRIORITY_LOOP, "add 2:x_point: " + x_point + ", y_point: " + y_point);
+ }
+ else{
+ DbgUtility.println(DbgUtility.PRIORITY_LOOP, "skipped because zero value");
+ }
+ }
+
+ points[j] = x_point;
+ points[++j] = y_point;
+ }
+
+ if(solidLinePoints.size() > 0){
+ // Adding point for this thread graph, possible to have more instances for same thread name
+ ListOfSolidLinePoints.add(solidLinePoints);
+ }
+
+ visY = visualSizeY - CommonGraphConstants.XLEGENDSPACE;
+
+ // Each thread have a separate color
+ graphics.setForegroundColor(this.getColors().get(colorIndex));
+
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "No of solid lists are " + ListOfSolidLinePoints.size());
+
+ for(int i=0; i < ListOfSolidLinePoints.size(); i++)
+ {
+ int [] solidPts = GraphsUtils.CreateIntArrayFromIntegerList(ListOfSolidLinePoints.get(i));
+
+ if(solidPts != null)
+ {
+ if(ListOfSolidLinePoints.size() > 1)
+ {
+ int instance_id = i+1;
+ graphics.drawString("(0" + instance_id + ")", solidPts[0]+2, solidPts[1] - 15);
+ }
+
+ // Drawing graph based on the stored data points
+ graphics.drawPolyline(solidPts);
+
+ // Drawing markers to the data points
+ GraphsUtils.drawMarkers(graphics, solidPts);
+ }
+ }
+
+ Polyline line = new Polyline();
+ line.setPoints(new PointList(points));
+
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "Putting the points list in a map for '" + th + "'.");
+ samplesData.put(th, line);
+
+ colorIndex++;
+ }
+
+ // Restoring original settings before paint call
+ graphics.setLineStyle(origLineStyle);
+ graphics.setForegroundColor(origColor);
+ graphics.setLineWidth(origLineWidth);
+
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION, this.getClass().getSimpleName() + "/paint END");
+ }
+
+ /* (non-Javadoc)
+ * @see com.nokia.s60tools.swmtanalyser.ui.graphs.GenericGraph#paintYAxis(org.eclipse.swt.graphics.GC)
+ */
+ public void paintYAxis(GC gc)
+ {
+ double visY = visualSizeY - CommonGraphConstants.XLEGENDSPACE;
+
+ switch(this.getEvent())
+ {
+ case NO_OF_FILES:
+ case HEAP_ALLOC_CELL_COUNT:
+ case HEAP_FREE_CELL_COUNT:
+ case NO_OF_PSHANDLES:
+ multiplier = GraphsUtils.roundToNearestNumber(maxBytes) / visY;
+ yAxisNeedsToBeChanged = true;
+ break;
+ default:
+ multiplier = GraphsUtils.prettyMaxBytes(maxBytes) / visY;
+ break;
+ }
+ int countOfYAxisLabels = 10;
+ double yIncrement = visY / countOfYAxisLabels;
+ int previousBottom = 0;
+
+ for (int k = countOfYAxisLabels; k >= 0; k--)
+ {
+ // location for the value indicator is k * 1/10 the height of the display
+ int y = (int) (visY - (yIncrement * k));
+
+ int bytes = (int)(yIncrement * multiplier) * k;
+
+ String legend = "";
+
+ switch(this.getEvent())
+ {
+ case NO_OF_FILES:
+ case HEAP_ALLOC_CELL_COUNT:
+ case HEAP_FREE_CELL_COUNT:
+ case NO_OF_PSHANDLES:
+ legend += bytes;
+ break;
+ default:
+ //legend += bytes + "B";
+ if (maxBytes < 10000)
+ {
+ legend += bytes + " B"; //$NON-NLS-1$
+ }
+ else if (maxBytes <= 500 * 1024)
+ {
+ legend += (bytes / 1024) + " KB"; //$NON-NLS-1$
+ }
+ else
+ {
+ legend += MBformat.format(((float) bytes / (1024 * 1024))) + " MB"; //$NON-NLS-1$
+ }
+ break;
+ }
+
+ Point extent = gc.stringExtent(legend);
+
+ gc.drawLine(CommonGraphConstants.YLEGENDSPACE - 3, (int)y + 1, CommonGraphConstants.YLEGENDSPACE, (int)y + 1);
+
+ if (y >= previousBottom)
+ {
+ gc.drawString(legend, CommonGraphConstants.YLEGENDSPACE - extent.x -2, (int)y);
+ previousBottom = (int)y + extent.y;
+ }
+ }
+
+ if(yAxisNeedsToBeChanged)
+ drawCountLabel(gc, (int)(visY/3));
+ else
+ drawBytesLabel(gc, (int)(visY/3));
+ }
+
+ private void fetchEntireDataForSelectedThreads()
+ {
+ ArrayList<String> selectedThreads = this.getUserSelectedItems();
+ SWMTLogReaderUtils utils = new SWMTLogReaderUtils();
+
+ for(String th:selectedThreads)
+ {
+ ArrayList<ThreadData> thData = utils.getHeapDataFromAllCycles(th, this.getCyclesData());
+ threadData.put(th, thData);
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see com.nokia.s60tools.swmtanalyser.ui.graphs.GenericGraph#prepareData()
+ */
+ public void prepareData()
+ {
+ fetchEntireDataForSelectedThreads();
+
+ for(String th:getUserSelectedItems())
+ {
+ ArrayList<ThreadData> data = threadData.get(th);
+
+ valuesToBePlotted = new int[data.size()];
+ for(int i =0; i<data.size(); i++)
+ {
+ EventTypes event = this.getEvent();
+ valuesToBePlotted[i] = getEventValueFromThreadData(data.get(i), event);
+ int maxValue = calculateMaxValue(valuesToBePlotted);
+ if(maxValue > maxBytes)
+ maxBytes = maxValue;
+ }
+
+ }
+
+ }
+
+ private int getEventValueFromThreadData(ThreadData thData, EventTypes event)
+ {
+ int value = 0;
+
+ if(thData.getStatus() == CycleData.Deleted)
+ return 0;
+
+ switch(event)
+ {
+ case NO_OF_FILES:
+ value = (int)thData.getOpenFiles();
+ break;
+ case MAX_HEAP_SIZE:
+ value = (int)thData.getMaxHeapSize();
+ break;
+ case HEAP_SIZE:
+ value = (int)thData.getHeapChunkSize();
+ break;
+ case HEAP_ALLOC_SPACE:
+ value = (int)thData.getHeapAllocatedSpace();
+ break;
+ case HEAP_FREE_SPACE:
+ value = (int)thData.getHeapFreeSpace();
+ break;
+ case HEAP_ALLOC_CELL_COUNT:
+ value = (int)thData.getAllocatedCells();
+ break;
+ case HEAP_FREE_CELL_COUNT:
+ value = (int)thData.getFreeCells();
+ break;
+ case HEAP_FREE_SLACK:
+ value = (int)thData.getFreeSlackSize();
+ break;
+ case NO_OF_PSHANDLES:
+ value = (int)thData.getPsHandles();
+ break;
+ default:
+ value = 0;
+ break;
+ }
+
+ return value;
+ }
+
+ /* (non-Javadoc)
+ * @see com.nokia.s60tools.swmtanalyser.ui.graphs.GenericGraph#getToolTipText(int, int)
+ */
+ public String getToolTipText(int x, int y)
+ {
+ if(y > (int)visY)
+ return null;
+
+ String text = "";
+
+ double xValue = x + timeOffset;
+ int scaledX = (int)(xValue * getScale());
+
+ double valY = visY - y;
+ double scaledY = valY * multiplier;
+
+ String yValue = "";
+
+ yValue+= (int)(scaledY);
+
+ switch(this.getEvent())
+ {
+ case NO_OF_FILES:
+ case NO_OF_PSHANDLES:
+ case HEAP_ALLOC_CELL_COUNT:
+ case HEAP_FREE_CELL_COUNT:
+ text += scaledX + " s, " + yValue;
+ break;
+ default:
+ yValue = getFormattedValues(scaledY);
+ text += scaledX + " s, " + yValue;
+ break;
+ }
+
+ for(String th: getUserSelectedItems())
+ {
+ Polyline line = samplesData.get(th);
+ if(line != null && line.containsPoint(x, y))
+ text += "\n" + th;
+
+ }
+
+ return text;
+ }
+
+ /**
+ * Get thread data for thread
+ * @param thread
+ * @return thread data
+ */
+ public ArrayList<ThreadData> getDataForThread(String thread)
+ {
+ return this.threadData.get(thread);
+ }
+
+ /**
+ * Draws Bytes label on given gc at given position
+ * @param gc
+ * @param position
+ */
+ private void drawBytesLabel(GC gc, int position)
+ {
+ final Image image = this.getVerticalLabel("Bytes");
+ gc.setAdvanced(true);
+ final org.eclipse.swt.graphics.Rectangle rect2 = image.getBounds();
+ Transform transform = new Transform(Display.getDefault());
+
+ transform.translate(rect2.height / 2f, rect2.width / 2f);
+ transform.rotate(-90);
+ transform.translate(-rect2.width / 2f, -rect2.height / 2f);
+
+ gc.setTransform(transform);
+ gc.drawImage(image, -position, 0);
+
+ transform.dispose();
+ gc.dispose();
+
+ }
+
+ /**
+ * Draws Count label on given gc at given position
+ * @param gc
+ * @param position
+ */
+ private void drawCountLabel(GC gc, int position)
+ {
+ final Image image = this.getVerticalLabel("Count");
+ gc.setAdvanced(true);
+ final org.eclipse.swt.graphics.Rectangle rect2 = image.getBounds();
+ Transform transform = new Transform(Display.getDefault());
+
+ transform.translate(rect2.height / 2f, rect2.width / 2f);
+ transform.rotate(-90);
+ transform.translate(-rect2.width / 2f, -rect2.height / 2f);
+
+ gc.setTransform(transform);
+ gc.drawImage(image, -position, 0);
+
+ transform.dispose();
+ gc.dispose();
+
+ }
+
+ private String getFormattedValues(double bytes)
+ {
+ String scaledY = "";
+
+ if (bytes < 10000)
+ {
+ scaledY += Bytes_Format.format(bytes) + " B"; //$NON-NLS-1$
+ }
+ else if (bytes <= 500 * 1024)
+ {
+ scaledY += Bytes_Format.format(bytes / 1024) + " KB"; //$NON-NLS-1$
+ }
+ else
+ {
+ scaledY += MBformat.format(((float) bytes / (1024 * 1024))) + " MB"; //$NON-NLS-1$
+ }
+
+ return scaledY;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/ui/graphs/TimeObject.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,128 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+package com.nokia.s60tools.swmtanalyser.ui.graphs;
+
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.TimeZone;
+
+/**
+ * Object for storing time to show in X-axis in UI. Handles time formatting.
+ */
+public class TimeObject {
+
+ private String days = null;
+
+ private String hourMinutesAndSeconds = null;
+
+
+ /**
+ * Create a time object
+ * @param time
+ * @param scale
+ */
+ public TimeObject(double time, double scale){
+ init(time, scale);
+ }
+
+ /**
+ * Get the days with units, e.g. "1d" or "12d"
+ * @return the days <code>null</code> if not defined or less than 1
+ */
+ public String getDays() {
+ return days;
+ }
+
+ /**
+ * Set day String with units, e.g. "1d"
+ * @param days the days to set
+ */
+ public void setDays(String days) {
+ this.days = days;
+ }
+
+ /**
+ * Get Hours, minutes and seconds as "h:m:s" -format
+ * @return the hourMinutesAndSeconds
+ */
+ public String getHourMinutesAndSeconds() {
+ return hourMinutesAndSeconds;
+ }
+
+ /**
+ * Set Hours, minutes and seconds as "h:m:s" -format
+ * @param hourMinutesAndSeconds the hourMinutesAndSeconds to set
+ */
+ public void setHourMinutesAndSeconds(String hourMinutesAndSeconds) {
+ this.hourMinutesAndSeconds = hourMinutesAndSeconds;
+ }
+
+ /**
+ * Check if days has been set for this time object
+ * @return <code>true</code> if there are days set, <code>false</code> otherwise.
+ */
+ public boolean hasDays() {
+ return getDays() != null;
+ }
+
+ /**
+ * Scaling the time and decides how to show the time in UI.
+ * E.g.
+ * <br>"30s"
+ * <br>"1m 30s"
+ * <br>"40m"
+ * <br>"1h 30m"
+ * @param time
+ * @param scale
+ * @return time with units to add in graph
+ */
+ private void init(double time, double scale) {
+
+ time = time * scale;
+ long timeAsLong = (long)time * 1000;//Ms to s
+ String hoursMinsAndSecs ;
+
+ //To avoid TimeZone adding e.g. 2hours to time, using GMT
+ Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));//$NON-NLS-1$
+ SimpleDateFormat hmsDf;//Date format for hours, minutes and seconds
+ hmsDf = new SimpleDateFormat("H:m:s");//$NON-NLS-1$
+ hmsDf.setCalendar(cal);
+
+ //If it has been taken more than one day, also days must be calculated
+ if(time > (60*60*24)){
+ //Decrease one day for time, because SimpeDateFormat will show "0" days as day "1"
+ timeAsLong = timeAsLong - (60*60*24*1000);
+ SimpleDateFormat dDf = new SimpleDateFormat("D'd'");//$NON-NLS-1$
+ dDf.setCalendar(cal);
+ Date date = new Date (timeAsLong);
+ hoursMinsAndSecs = hmsDf.format(date );
+ String days = dDf.format(date);
+ setDays(days);
+ setHourMinutesAndSeconds(hoursMinsAndSecs);
+ }
+ //If it has been taken less than day, we need only hours minutes and seconds
+ else{
+ Date date = new Date (timeAsLong);
+ hoursMinsAndSecs = hmsDf.format(date );
+ setHourMinutesAndSeconds(hoursMinsAndSecs);
+ }
+
+
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/ui/graphs/ZoomableGraph.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,75 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+package com.nokia.s60tools.swmtanalyser.ui.graphs;
+
+import org.eclipse.jface.action.IAction;
+
+/**
+ * Common abstract base class for graphs that support zoom operations.
+ */
+public abstract class ZoomableGraph {
+
+
+ /**
+ * Context menu title for action: Zoom In
+ */
+ protected static final String ZOOM_IN_CONTEXT_MENU_TITLE = "Zoom In";
+
+ /**
+ * Context menu title for action: Zoom Out
+ */
+ protected static final String ZOOM_OUT_CONTEXT_MENU_TITLE = "Zoom Out";
+
+ /**
+ * Copy -action
+ */
+ protected IAction copy;
+
+
+ /**
+ * Zoom In -action
+ */
+ protected IAction zoomIn;
+
+ /**
+ * Zoom Out -action
+ */
+ protected IAction zoomOut;
+
+ /**
+ * This method zooms in the graph area.
+ */
+ protected abstract void zoomIn();
+
+ /**
+ * This method zooms out the graph area.
+ */
+ protected abstract void zoomOut();
+
+ /**
+ * Sets given enable state for an action if it is non <code>null</code>.
+ * @param action Action to set enable status for.
+ * @param enableStatus <code>true</code> if enabled, otherwise <code>false</code>.
+ */
+ protected void setEnableState(IAction action, boolean enableStatus) {
+ if(action != null){
+ action.setEnabled(enableStatus);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/wizards/CommentsPage.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,289 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+package com.nokia.s60tools.swmtanalyser.wizards;
+
+import java.io.File;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.FileDialog;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.swt.widgets.Tree;
+import org.eclipse.swt.widgets.TreeItem;
+import org.eclipse.ui.PlatformUI;
+
+import com.nokia.s60tools.swmtanalyser.resources.HelpContextIds;
+import com.nokia.s60tools.ui.wizards.S60ToolsWizardPage;
+/**
+ * First page in the Report Generation wizard. i.e. Comments page.
+ *
+ */
+public class CommentsPage extends S60ToolsWizardPage implements SelectionListener, ModifyListener {
+
+ //Radio button for creating type1 report
+ private Button type1_radio;
+ //Radio button for creating overview type report
+ private Button type2_radio;
+ //Save as button to select the pdf file path/name
+ private Button browse_btn;
+ //Text box to show the selected path
+ private Text path_txt;
+ //Text box to enetr comments
+ private Text commentsText;
+ //Label to explain about the selected radio option
+ private Label info;
+
+ //Temporary variables used
+ private Tree all_tree_items;
+ private boolean checked = false;
+
+ /**
+ * Create a comments page
+ * @param pageName
+ * @param all_tree_items
+ */
+ protected CommentsPage(String pageName, Tree all_tree_items) {
+ super(pageName);
+ setTitle("Report Options");
+ setDescription("Select your options");
+ this.all_tree_items = all_tree_items;
+ }
+
+ /* (non-Javadoc)
+ * @see com.nokia.s60tools.ui.wizards.S60ToolsWizardPage#recalculateButtonStates()
+ */
+ public void recalculateButtonStates() {
+
+ }
+
+ /* (non-Javadoc)
+ * @see com.nokia.s60tools.ui.wizards.S60ToolsWizardPage#setInitialFocus()
+ */
+ public void setInitialFocus() {
+
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.swt.events.SelectionListener#widgetDefaultSelected(org.eclipse.swt.events.SelectionEvent)
+ */
+ public void widgetDefaultSelected(SelectionEvent e) {
+
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt.events.SelectionEvent)
+ */
+ public void widgetSelected(SelectionEvent e) {
+ if(e.widget == browse_btn)
+ {
+ FileDialog dlg = new FileDialog(this.getShell(), SWT.SAVE);
+ dlg.setFilterExtensions(new String[]{"*.pdf"});
+ String path = dlg.open();
+ if(path != null)
+ path_txt.setText(path);
+ }
+ else if(e.widget == type1_radio)
+ {
+ //If option 1 is selected, explain about that option.
+ info.setText("This case the report contains only the information about the selected issues.\nAnd graph will be shown for the selected issues.");
+ }
+ else if(e.widget == type2_radio)
+ {
+ //If option 2 is selected, explain about that option.
+ info.setText("This case the report contains the overview information of all the type of issues.");
+ }
+
+ checkForCompletion();
+ this.getContainer().updateButtons();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.swt.events.ModifyListener#modifyText(org.eclipse.swt.events.ModifyEvent)
+ */
+ public void modifyText(ModifyEvent arg0) {
+ checkForCompletion();
+ this.getContainer().updateButtons();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.dialogs.IDialogPage#createControl(org.eclipse.swt.widgets.Composite)
+ */
+ public void createControl(Composite parent) {
+ Composite parentComposite = new Composite(parent, SWT.NONE);
+ parentComposite.setLayout(new GridLayout(2, false));
+
+ GridData gd = new GridData(GridData.FILL_HORIZONTAL);
+ gd.horizontalSpan = 2;
+
+ Label title = new Label(parentComposite, SWT.WRAP);
+ title.setText("Select type of report to be created:");
+ title.setLayoutData(gd);
+
+ type1_radio = new Button(parentComposite, SWT.RADIO);
+ type1_radio.setText("Create report for the selected issues");
+ type1_radio.setLayoutData(gd);
+ type1_radio.setToolTipText("This case the report contains only the information about the selected issues.\nAnd graph will be shown for the selected issues.");
+ type1_radio.addSelectionListener(this);
+
+ type2_radio = new Button(parentComposite, SWT.RADIO);
+ type2_radio.setText("Create overview report");
+ type2_radio.setLayoutData(gd);
+ type2_radio.setToolTipText("This case the report contains the overview information of all the type of issues");
+ type2_radio.addSelectionListener(this);
+
+ info=new Label(parentComposite,SWT.WRAP);
+ info.setText("This case the report contains only the information about the selected issues.\nAnd graph will be shown for the selected issues.");
+ GridData lblGD=new GridData(SWT.FILL, SWT.TOP, true, false, 1, 1);
+ lblGD.horizontalSpan = 2;
+ lblGD.verticalIndent=8;
+ info.setLayoutData(lblGD);
+
+ Label comments_label = new Label(parentComposite, SWT.WRAP);
+ comments_label.setText("Enter your comments here:");
+ GridData lbl_gd = new GridData(GridData.FILL_HORIZONTAL);
+ lbl_gd.horizontalSpan = 2;
+ comments_label.setLayoutData(lbl_gd);
+
+ commentsText = new Text(parentComposite, SWT.BORDER|SWT.MULTI|SWT.V_SCROLL|SWT.H_SCROLL);
+ GridData txt_gd = new GridData(GridData.FILL_HORIZONTAL);
+ txt_gd.heightHint = 100;
+ txt_gd.horizontalSpan = 2;
+ commentsText.setLayoutData(txt_gd);
+ commentsText.addModifyListener(this);
+
+ Label browse_label = new Label(parentComposite, SWT.WRAP);
+ browse_label.setText("Provide report file path here:");
+ browse_label.setLayoutData(lbl_gd);
+
+ path_txt = new Text(parentComposite, SWT.BORDER);
+ path_txt.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ path_txt.addModifyListener(this);
+
+ browse_btn = new Button(parentComposite, SWT.PUSH);
+ browse_btn.setText("Save as...");
+ browse_btn.addSelectionListener(this);
+
+ setHelp(parentComposite);
+ setControl(parentComposite);
+ }
+
+ /**
+ * Check if overview report was selected or not.
+ * @return <code>true</code> if overview report was selected, <code>false</code> otherwise.
+ */
+ public boolean isOverviewReportSelected()
+ {
+ return type2_radio.getSelection();
+ }
+
+ /**
+ * Returns filename with path provided in the text box
+ * @return file name
+ */
+ public String getFileName()
+ {
+ return path_txt.getText();
+ }
+
+ /**
+ * Returns comments provided.
+ * @return comment text
+ */
+ public String getComments()
+ {
+ return commentsText.getText();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.wizard.WizardPage#canFlipToNextPage()
+ */
+ public boolean canFlipToNextPage() {
+ checkForCompletion();
+ return super.canFlipToNextPage();
+ }
+
+ /**
+ * Checks wizard completion.
+ * @return true if completed.
+ */
+ public boolean checkForCompletion(){
+ setErrorMessage(null);
+ if(type1_radio.getSelection() && !areItemsChecked())
+ {
+ setErrorMessage("No issues are selected. Please select some issues in the analysis view.");
+ return false;
+ }
+ else if(commentsText.getText()==null || commentsText.getText() == "")
+ {
+ setErrorMessage("Enter your comments");
+ return false;
+ }
+ else if(!(new File(path_txt.getText()).isAbsolute())|| !(new File(path_txt.getText())).getParentFile().exists())
+ {
+ setErrorMessage("Invalid file name");
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Checks whether any issues are selected or not.
+ * @return true if any issue(child) is selected.
+ */
+ private boolean areItemsChecked() {
+ checked = false;
+ //To avoid invalid thread access, running in new thread.
+ Display.getDefault().syncExec(new Runnable() {
+ public void run() {
+ for(TreeItem i:all_tree_items.getItems())
+ {
+ if(i.getItemCount() > 0)
+ {
+ for(TreeItem child : i.getItems())
+ {
+ if(child.getChecked())
+ {
+ checked = true;
+ return;
+ }
+ }
+ }
+ }
+ }});
+ return checked;
+ }
+
+ /**
+ * Set context sensitive helps
+ * @param parentComposite
+ */
+ private void setHelp(Composite parentComposite)
+ {
+ PlatformUI.getWorkbench().getHelpSystem().setHelp(parentComposite,
+ HelpContextIds.SWMT_REPORT_WIZARD_HELP);
+
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/wizards/ReportCreationJob.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,615 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+package com.nokia.s60tools.swmtanalyser.wizards;
+
+import java.awt.Color;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.util.ArrayList;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Tree;
+import org.eclipse.swt.widgets.TreeItem;
+
+import com.lowagie.text.BadElementException;
+import com.lowagie.text.Chapter;
+import com.lowagie.text.Chunk;
+import com.lowagie.text.Document;
+import com.lowagie.text.DocumentException;
+import com.lowagie.text.Element;
+import com.lowagie.text.Font;
+import com.lowagie.text.FontFactory;
+import com.lowagie.text.PageSize;
+import com.lowagie.text.Paragraph;
+import com.lowagie.text.Rectangle;
+import com.lowagie.text.pdf.GrayColor;
+import com.lowagie.text.pdf.PdfPCell;
+import com.lowagie.text.pdf.PdfPTable;
+import com.lowagie.text.pdf.PdfWriter;
+import com.nokia.s60tools.swmtanalyser.SwmtAnalyserPlugin;
+import com.nokia.s60tools.swmtanalyser.analysers.AnalyserConstants;
+import com.nokia.s60tools.swmtanalyser.data.OverviewData;
+import com.nokia.s60tools.util.console.AbstractProductSpecificConsole;
+import com.nokia.s60tools.util.console.IConsolePrintUtility;
+
+/**
+ * Job to create PDF report.
+ *
+ */
+public class ReportCreationJob extends Job {
+
+
+ /**
+ * Spacing after a header text, to avoid texts to be too close each other
+ */
+ private static final int SPACING_AFTER_HEADER_TEXT = 5;
+ //Paddings in cells
+ private float cellPaddingSmall;
+ private float cellPaddingTableHeader;
+
+ //Colors used in document
+ private Color colorHeading;
+ private Color colorTableHeaderBackGrd;
+ private Color colorTable2ndHeaderBackGrd;
+ private Color colorSeverityNormal;
+ private Color colorSeverityHigh;
+ private Color colorSeverityCritical;
+
+ //Fonts used in document
+ private Font fontTable2ndHeaderText;
+ private Font fontHeader;
+ private Font fontNormalSmallTables;
+ private Font fontNormal;
+ private Font fontHeading2;
+ private Font fontHeading1;
+
+ //PDF filename
+ private String fileName = null;
+ //Use given comments
+ private String comment = null;
+ //Oveview info to write in pdf
+ private OverviewData ov;
+ //ROM Checksum to write in pdf
+ private String rom_checkSum_string;
+ //ROM Version to write in pdf
+ private String rom_version_string;
+ //Tree object to get the issues info
+ private Tree all_tree_items;
+ //To save the report type option
+ boolean isOverviewReport;
+ //temporary variable
+ private PdfPTable table;
+
+ /**
+ * Job constructor.
+ * @param name Job name
+ * @param fileName PDF filename
+ * @param comment User given comments
+ * @param ov Overview object
+ * @param checksum ROM Checksum
+ * @param version ROM Version
+ * @param issues_tree Tree object from Analysis view.
+ * @param isOverviewReport report type
+ */
+ public ReportCreationJob(String name, String fileName, String comment, OverviewData ov, String checksum, String version, Tree issues_tree, boolean isOverviewReport) {
+ super(name);
+ this.fileName = fileName;
+ this.comment = comment;
+ this.ov = ov;
+ this.rom_checkSum_string = checksum;
+ this.rom_version_string = version;
+ this.all_tree_items = issues_tree;
+ this.isOverviewReport = isOverviewReport;
+
+ //Initialize Colors and Fonts
+ initStyles();
+ }
+
+ /**
+ * Initializing Colors and fonts to be used in PDF Document.
+ * Color scheme is taken from Carbide logo.
+ */
+ private void initStyles() {
+
+ //
+ // Colors used are picked up from Carbide.c++ -logo, from dark blue to white
+ // #003399 = 0, 51, 153 -Dark blue
+ // #0088ff = 0, 136, 255 -mid blue
+ // #33aaff = 51, 170, 255 -mid blue 2
+ // #88ccff = 136, 204, 255 -thin blue
+ // #ffffff = -white
+ //
+
+ //
+ //Using Carbide.c++ logo colors to decorate report
+ //
+ colorHeading = new Color(0, 51, 153);
+ colorTableHeaderBackGrd = new Color (136, 204, 255);
+ colorTable2ndHeaderBackGrd = new Color (0, 136, 255);
+
+
+ //
+ // Setting Severity Colors for PDF report from Analyser view colors.
+ //
+ org.eclipse.swt.graphics.Color color = AnalyserConstants.COLOR_SEVERITY_CRITICAL;
+ colorSeverityCritical = new Color (color.getRed(),color.getGreen(),color.getBlue());
+
+ color = AnalyserConstants.COLOR_SEVERITY_HIGH;
+ colorSeverityHigh = new Color (color.getRed(),color.getGreen(),color.getBlue());
+
+ color = AnalyserConstants.COLOR_SEVERITY_NORMAL;
+ colorSeverityNormal = new Color (color.getRed(),color.getGreen(),color.getBlue());
+
+ //
+ // Font used in report
+ //
+ String font = FontFactory.HELVETICA;
+
+ //
+ // Creating fonts
+ //
+ fontTable2ndHeaderText = FontFactory.getFont(font,10f,Font.NORMAL, Color.WHITE);
+ fontHeader = FontFactory.getFont(font, 16, Font.BOLD, Color.BLACK);
+ fontNormalSmallTables = FontFactory.getFont(font,9f,Font.NORMAL);
+ fontNormal = FontFactory.getFont(font,10f,Font.NORMAL);
+ fontHeading2 = FontFactory.getFont(font,10f,Font.BOLD);
+ fontHeading1 = FontFactory.getFont(font,12f,Font.BOLD, colorHeading);
+
+ cellPaddingSmall = 1.0f;
+ cellPaddingTableHeader = 3.0f;
+
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime.IProgressMonitor)
+ */
+ protected IStatus run(IProgressMonitor monitor) {
+
+ monitor.beginTask("Creating report...", 10);
+
+ try {
+ //Instantiation of document object
+ Document document = new Document(PageSize.A4, 50, 50, 50, 50);
+ PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(this.fileName));
+ document.open();
+
+ addGeneralDetails(document);
+
+ if(!this.isOverviewReport) //If the report type is 1. i.e., report for selected issues only.
+ {
+ addSelectedIssuesReport(document);
+ }
+ else // If the report type is 2. i.e., Overview report
+ {
+ addOverviewReport(document);
+ }
+
+ addComments(document);
+
+ //Close document
+ document.close();
+ //Close the writer
+ writer.close();
+
+
+ } catch (DocumentException e) {
+ e.printStackTrace();
+ SwmtAnalyserPlugin.getConsole().println("Unable to write document, error was: '" +e +"'", IConsolePrintUtility.MSG_ERROR);
+ }
+ catch (FileNotFoundException e) {
+ e.printStackTrace();
+ SwmtAnalyserPlugin.getConsole().println("Unable to write document, error was: '" +e +"'", IConsolePrintUtility.MSG_ERROR);
+ }
+ catch (Exception e) {
+ e.printStackTrace();
+ AbstractProductSpecificConsole absConsole = (AbstractProductSpecificConsole)SwmtAnalyserPlugin.getConsole();
+ absConsole.printStackTrace(e);
+ SwmtAnalyserPlugin.getConsole().println("Unable to write document, error was: '" +e +"'", IConsolePrintUtility.MSG_ERROR);
+ }
+ return Status.OK_STATUS;
+ }
+
+ private void addComments(Document document) throws DocumentException {
+ //Create new line
+ document.add(Chunk.NEWLINE);
+ //Comments heading
+ Paragraph comments_title = new Paragraph("User given comments", fontHeading1);
+ document.add(comments_title);
+
+ Paragraph comments = new Paragraph(this.comment, fontNormal);
+ document.add(comments);
+ }
+
+ private void addGeneralDetails(Document document) throws DocumentException {
+ //Report Title
+ Paragraph title = new Paragraph("MemSpy - System Wide Memory Tracking - Analysis Report", fontHeader);
+ title.setAlignment(Element.ALIGN_CENTER);
+ document.add(title);
+ document.add(Chunk.NEWLINE);
+
+ //Introduction title
+ Paragraph hdng = new Paragraph("Introduction of Memspy (S60) and SWMT Analyser", fontHeading1);
+ document.add(hdng);
+
+ //About the MemSpy S60 Application
+ Paragraph intro_memspy = new Paragraph("The MemSpy S60 application tracks various subsystems that directly or indirectly contribute to overall system memory usage and provides information about the changes in these subsystems at specified time intervals.", fontNormal);
+ document.add(intro_memspy);
+ document.add(Chunk.NEWLINE);
+ //About the SWMT Analyser
+ Paragraph intro_swmt = new Paragraph("A System Wide Memory Tracker log file contains information about system wide memory status changes over time. SWMT Analyser is a Carbide.c++ Extension for analyzing System Wide Memory Tracking logs produced by the MemSpy S60 application and imported to PC with the MemSpy Carbide.c++ Extension.", fontNormal);
+ document.add(intro_swmt);
+ document.add(Chunk.NEWLINE);
+
+ //Properties heading
+ Paragraph props_title = new Paragraph("Properties", fontHeading1);
+ document.add(props_title);
+ Chunk no_of_cycles = new Chunk("No of cycles : ", fontHeading2);
+ document.add(no_of_cycles);
+ Chunk cycles = new Chunk(ov.noOfcycles+"", fontNormal);
+ document.add(cycles);
+ document.add(Chunk.NEWLINE);
+
+ Chunk time_period = new Chunk("Time period : ", fontHeading2);
+ document.add(time_period);
+ Chunk period = new Chunk(ov.fromTime+" to "+ov.toTime, fontNormal);
+ document.add(period);
+ document.add(Chunk.NEWLINE);
+
+ Chunk duration = new Chunk("Time duration : ", fontHeading2);
+ document.add(duration);
+ Chunk dur = new Chunk(ov.durationString, fontNormal);
+ document.add(dur);
+ document.add(Chunk.NEWLINE);
+
+
+ document.add(Chunk.NEWLINE);
+ Paragraph rom_title = new Paragraph("ROM Details", fontHeading1);
+ document.add(rom_title);
+ Chunk rom_checksum = new Chunk("ROM Checksum : ", fontHeading2);
+ document.add(rom_checksum);
+ Chunk checksum = new Chunk(this.rom_checkSum_string, fontNormal);
+ document.add(checksum);
+ document.add(Chunk.NEWLINE);
+
+ Chunk rom_version = new Chunk("ROM Version : ", fontHeading2);
+ document.add(rom_version);
+ Chunk version = new Chunk(this.rom_version_string, fontNormal);
+ document.add(version);
+ document.add(Chunk.NEWLINE);
+ document.add(Chunk.NEWLINE);
+ }
+
+ private void addSelectedIssuesReport(Document document) throws DocumentException,
+ BadElementException {
+ Paragraph selected_title = new Paragraph("Selected issues", fontHeading1);
+ selected_title.setSpacingAfter(SPACING_AFTER_HEADER_TEXT);
+ document.add(selected_title);
+
+ Display.getDefault().syncExec(new Runnable() {
+ public void run() {
+ table = getTableForTheSelectedIssues(all_tree_items);
+ }
+ });
+ document.add(table);
+
+ document.add(Chunk.NEWLINE);
+
+
+ Paragraph graph_title = new Paragraph("Graph for the selected issues", fontHeading1);
+ //Using chapter, so title stays together with image
+ Chapter chapter = new Chapter(graph_title,0);
+ //Chapter with out number, when depth is 0
+ chapter.setNumberDepth(0);
+
+
+ com.lowagie.text.Image img = null;
+ try {
+ img = com.lowagie.text.Image.getInstance(SwmtAnalyserPlugin.getPluginInstallPath()+"\\swmt_graph.bmp");
+ } catch (MalformedURLException e) {
+ e.printStackTrace();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ img.scalePercent(50f);
+ img.setBorder(Rectangle.BOX);
+ img.setBorderWidth(1f);
+ img.setBorderColor(new GrayColor(0.5f));
+ //Adding image to chapter
+ chapter.add(img);
+ //Adding chapter to document
+ document.add(chapter);
+
+ }
+
+ private void addOverviewReport(Document document) throws DocumentException {
+ Paragraph res_title = new Paragraph("Overview Of Analysis Results", fontHeading1);
+ res_title.setSpacingAfter(SPACING_AFTER_HEADER_TEXT);
+ document.add(res_title);
+
+ Display.getDefault().syncExec(new Runnable() {
+ public void run() {
+ table = getTableForOverallIssues(all_tree_items);
+ }
+ });
+ document.add(table);
+ document.add(Chunk.NEWLINE);
+
+ res_title = new Paragraph("Details", fontHeading1);
+ document.add(res_title);
+
+ res_title = new Paragraph("Critical Severity Issues", fontHeading2);
+ res_title.setSpacingAfter(SPACING_AFTER_HEADER_TEXT);
+
+ Display.getDefault().syncExec(new Runnable() {
+ public void run() {
+ table = getTableForIssues(all_tree_items, AnalyserConstants.Priority.CRITICAL);;
+ }
+ });
+ if(table!=null)
+ {
+ document.add(res_title);
+ document.add(table);
+ document.add(Chunk.NEWLINE);
+ }
+
+ res_title = new Paragraph("High Severity Issues", fontHeading2);
+ res_title.setSpacingAfter(SPACING_AFTER_HEADER_TEXT);
+
+ Display.getDefault().syncExec(new Runnable() {
+ public void run() {
+ table = getTableForIssues(all_tree_items, AnalyserConstants.Priority.HIGH);
+ }
+ });
+ if(table!=null)
+ {
+ document.add(res_title);
+ document.add(table);
+ document.add(Chunk.NEWLINE);
+ }
+
+ res_title = new Paragraph("Normal Severity Issues", fontHeading2);
+ res_title.setSpacingAfter(SPACING_AFTER_HEADER_TEXT);
+
+ Display.getDefault().syncExec(new Runnable() {
+ public void run() {
+ table = getTableForIssues(all_tree_items, AnalyserConstants.Priority.NORMAL);
+ }
+ });
+ if(table!=null)
+ {
+ document.add(res_title);
+ document.add(table);
+ }
+ }
+
+ /**
+ * Returns a table for issues of given priority type from the selected issues.
+ * @param allTreeItems tree
+ * @param p priority
+ * @return
+ */
+ private PdfPTable getTableForIssues(Tree allTreeItems, AnalyserConstants.Priority p) {
+
+ float[] relativeWidth = {60, 25, 15};//100% total
+ PdfPTable table = new PdfPTable(relativeWidth);
+ table.setWidthPercentage(100);
+
+ PdfPCell cell = new PdfPCell (new Paragraph ("Item name"));
+ cell.setHorizontalAlignment (Element.ALIGN_CENTER);
+ cell.setVerticalAlignment (Element.ALIGN_MIDDLE);
+ cell.setBackgroundColor (colorTableHeaderBackGrd);
+ cell.setPadding (cellPaddingTableHeader);
+ table.addCell (cell);
+
+ cell = new PdfPCell (new Paragraph ("Event"));
+ cell.setHorizontalAlignment (Element.ALIGN_CENTER);
+ cell.setVerticalAlignment (Element.ALIGN_MIDDLE);
+ cell.setBackgroundColor (colorTableHeaderBackGrd);
+ cell.setPadding (cellPaddingTableHeader);
+ table.addCell (cell);
+
+ cell = new PdfPCell (new Paragraph ("Delta"));
+ cell.setHorizontalAlignment (Element.ALIGN_CENTER);
+ cell.setVerticalAlignment (Element.ALIGN_MIDDLE);
+ cell.setBackgroundColor (colorTableHeaderBackGrd);
+ cell.setPadding (cellPaddingTableHeader);
+ table.addCell (cell);
+
+
+ for(TreeItem parent : allTreeItems.getItems())
+ {
+ for(TreeItem child : parent.getItems())
+ {
+ if(child.getText(4).toLowerCase().equals(p.toString().toLowerCase()))
+ {
+
+ cell = new PdfPCell (new Paragraph (child.getText(1),fontNormalSmallTables));
+ cell.setHorizontalAlignment (Element.ALIGN_LEFT);
+ cell.setVerticalAlignment (Element.ALIGN_MIDDLE);
+ cell.setPadding (cellPaddingSmall);
+ table.addCell (cell);
+
+ cell = new PdfPCell (new Paragraph (child.getText(2),fontNormalSmallTables));
+ cell.setHorizontalAlignment (Element.ALIGN_LEFT);
+ cell.setVerticalAlignment (Element.ALIGN_MIDDLE);
+ cell.setPadding (cellPaddingSmall);
+ table.addCell (cell);
+
+ cell = new PdfPCell (new Paragraph (child.getText(3),fontNormalSmallTables));
+ cell.setHorizontalAlignment (Element.ALIGN_LEFT);
+ cell.setVerticalAlignment (Element.ALIGN_MIDDLE);
+ cell.setPadding (cellPaddingSmall);
+ table.addCell (cell);
+ }
+ }
+ }
+ if(table.getRows().size() > 1)
+ return table;
+
+ return table;
+ }
+
+ /**
+ * Returns a table for the overview issues of all types.
+ * @param all
+ * @return
+ */
+ private PdfPTable getTableForOverallIssues(Tree all) {
+ PdfPTable table = new PdfPTable(2);
+ table.setWidthPercentage(100);
+
+ PdfPCell cell = new PdfPCell (new Paragraph ("Severity"));
+ cell.setHorizontalAlignment (Element.ALIGN_CENTER);
+ cell.setVerticalAlignment (Element.ALIGN_MIDDLE);
+ cell.setBackgroundColor (colorTableHeaderBackGrd);
+ cell.setPadding (cellPaddingTableHeader);
+ table.addCell (cell);
+
+ cell = new PdfPCell (new Paragraph ("Count"));
+ cell.setHorizontalAlignment (Element.ALIGN_CENTER);
+ cell.setVerticalAlignment (Element.ALIGN_MIDDLE);
+ cell.setBackgroundColor (colorTableHeaderBackGrd);
+ cell.setPadding (cellPaddingTableHeader);
+ table.addCell (cell);
+
+ int critical = 0;
+ int high = 0;
+ int normal = 0;
+
+ for(TreeItem parent : all.getItems())
+ {
+ for(TreeItem child : parent.getItems())
+ {
+ if(child.getText(4).toLowerCase().equals(AnalyserConstants.Priority.CRITICAL.toString().toLowerCase()))
+ critical++;
+ else if(child.getText(4).toLowerCase().equals(AnalyserConstants.Priority.HIGH.toString().toLowerCase()))
+ high++;
+ else if(child.getText(4).toLowerCase().equals(AnalyserConstants.Priority.NORMAL.toString().toLowerCase()))
+ normal++;
+ }
+ }
+
+ table.addCell(new PdfPCell (new Paragraph ("CRITICAL",fontNormalSmallTables)));
+ table.addCell(new PdfPCell (new Paragraph (critical+"",fontNormalSmallTables)));
+ table.addCell(new PdfPCell (new Paragraph ("HIGH",fontNormalSmallTables)));
+ table.addCell(new PdfPCell (new Paragraph (high+"",fontNormalSmallTables)));
+ table.addCell(new PdfPCell (new Paragraph ("NORMAL",fontNormalSmallTables)));
+ table.addCell(new PdfPCell (new Paragraph (normal+"",fontNormalSmallTables)));
+
+ return table;
+ }
+
+ /**
+ * Returns a table for the selected issues.
+ * @param issuesTree
+ * @return
+ */
+ private PdfPTable getTableForTheSelectedIssues(Tree issuesTree) {
+
+ float[] relativeWidth = {50, 22, 14, 14};//100% total
+ PdfPTable table = new PdfPTable(relativeWidth);
+ table.setWidthPercentage(100);
+
+ PdfPCell cell = new PdfPCell (new Paragraph ("Item name"));
+ cell.setHorizontalAlignment (Element.ALIGN_CENTER);
+ cell.setVerticalAlignment (Element.ALIGN_MIDDLE);
+ cell.setBackgroundColor (colorTableHeaderBackGrd);
+ cell.setPadding (cellPaddingTableHeader);
+ table.addCell (cell);
+
+ cell = new PdfPCell (new Paragraph ("Event"));
+ cell.setHorizontalAlignment (Element.ALIGN_CENTER);
+ cell.setVerticalAlignment (Element.ALIGN_MIDDLE);
+ cell.setBackgroundColor (colorTableHeaderBackGrd);
+ cell.setPadding (cellPaddingTableHeader);
+ table.addCell (cell);
+
+ cell = new PdfPCell (new Paragraph ("Delta"));
+ cell.setHorizontalAlignment (Element.ALIGN_CENTER);
+ cell.setVerticalAlignment (Element.ALIGN_MIDDLE);
+ cell.setBackgroundColor (colorTableHeaderBackGrd);
+ cell.setPadding (cellPaddingTableHeader);
+ table.addCell (cell);
+
+ cell = new PdfPCell (new Paragraph ("Severity"));
+ cell.setHorizontalAlignment (Element.ALIGN_CENTER);
+ cell.setVerticalAlignment (Element.ALIGN_MIDDLE);
+ cell.setBackgroundColor (colorTableHeaderBackGrd);
+ cell.setPadding (cellPaddingTableHeader);
+ table.addCell (cell);
+
+ for(TreeItem item : issuesTree.getItems())
+ {
+ ArrayList<TreeItem> selected = new ArrayList<TreeItem>();
+ for(TreeItem child: item.getItems())
+ if(child.getChecked())
+ selected.add(child);
+
+ if(selected.size() > 0)
+ {
+ cell = new PdfPCell (new Paragraph (item.getText(1),fontTable2ndHeaderText));
+ cell.setHorizontalAlignment (Element.ALIGN_LEFT);
+ cell.setBackgroundColor (colorTable2ndHeaderBackGrd);
+ cell.setPadding (cellPaddingTableHeader);
+ cell.setColspan(4);
+ table.addCell (cell);
+
+ for(TreeItem child: selected)
+ {
+ cell = new PdfPCell (new Paragraph (child.getText(1),fontNormalSmallTables));
+ cell.setHorizontalAlignment (Element.ALIGN_LEFT);
+ cell.setPadding (cellPaddingSmall);
+ table.addCell (cell);
+
+ cell = new PdfPCell (new Paragraph (child.getText(2),fontNormalSmallTables));
+ cell.setHorizontalAlignment (Element.ALIGN_LEFT);
+ cell.setPadding (cellPaddingSmall);
+ table.addCell (cell);
+
+ cell = new PdfPCell (new Paragraph (child.getText(3),fontNormalSmallTables));
+ cell.setHorizontalAlignment (Element.ALIGN_LEFT);
+ cell.setPadding (cellPaddingSmall);
+ table.addCell (cell);
+
+ cell = new PdfPCell (new Paragraph (child.getText(4),fontNormalSmallTables));
+ cell.setHorizontalAlignment (Element.ALIGN_CENTER);
+
+ if(child.getText(4).toLowerCase().equals(AnalyserConstants.Priority.CRITICAL.toString().toLowerCase())){
+ cell.setBackgroundColor (colorSeverityCritical);
+ }
+ else if(child.getText(4).toLowerCase().equals(AnalyserConstants.Priority.HIGH.toString().toLowerCase())){
+ cell.setBackgroundColor (colorSeverityHigh);
+ }
+ else if(child.getText(4).toLowerCase().equals(AnalyserConstants.Priority.NORMAL.toString().toLowerCase())){
+ cell.setBackgroundColor (colorSeverityNormal);
+ }
+ cell.setPadding(cellPaddingSmall);
+ table.addCell (cell);
+ }
+ }
+ }
+ return table;
+ }
+
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/wizards/ReportGenerationWizard.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,103 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+package com.nokia.s60tools.swmtanalyser.wizards;
+
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.swt.program.Program;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Tree;
+
+import com.nokia.s60tools.swmtanalyser.data.OverviewData;
+import com.nokia.s60tools.ui.wizards.S60ToolsWizard;
+
+/**
+ * Report Generation Wizard
+ *
+ */
+public class ReportGenerationWizard extends S60ToolsWizard {
+
+ //Comments page
+ private CommentsPage comments_page;
+ //Overview object to write overview info to pdf
+ private OverviewData ov;
+ //ROM Checksum
+ private String rom_checkSum;
+ //ROM Version
+ private String rom_version;
+ //Tree object from Analysis view
+ private Tree issues_tree;
+ //PDF file name
+ private String fileName;
+
+ /**
+ * Constructor
+ * @param ov Overview Data Object
+ * @param checksum ROM Checksum string
+ * @param version ROM Version string
+ * @param issues_tree Tree object from the Analysis view.
+ */
+ public ReportGenerationWizard(OverviewData ov, String checksum, String version, Tree issues_tree) {
+ setWindowTitle("Create Report");
+ this.ov = ov;
+ this.rom_checkSum = checksum;
+ this.rom_version = version;
+ this.issues_tree = issues_tree;
+ }
+
+ /* (non-Javadoc)
+ * @see com.nokia.s60tools.ui.wizards.S60ToolsWizard#addPages()
+ */
+ public void addPages() {
+ comments_page = new CommentsPage("Comments", issues_tree);
+ addPage(comments_page);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.wizard.Wizard#performFinish()
+ */
+ public boolean performFinish() {
+
+ fileName = comments_page.getFileName();
+ String comment = comments_page.getComments();
+ boolean isOverviewReport = comments_page.isOverviewReportSelected();
+ ReportCreationJob engine = new ReportCreationJob("Creating report", fileName, comment, ov, this.rom_checkSum, this.rom_version, issues_tree, isOverviewReport);
+ engine.setUser(true);
+ engine.schedule();
+
+ //Ask user whether to open the created pdf file or not
+ Runnable p = new Runnable(){
+ public void run() {
+ if(MessageDialog.openQuestion(Display.getCurrent().getActiveShell(),"Confirmation","Would you like to open the saved report?")) //$NON-NLS-2$
+ {
+ Program p=Program.findProgram(".pdf");
+ if(p!=null)
+ p.execute(fileName);
+ }
+ }
+ };
+ Display.getDefault().asyncExec(p);
+ return true;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.wizard.Wizard#canFinish()
+ */
+ public boolean canFinish() {
+ return comments_page.checkForCompletion();
+ }
+
+}