diff options
Diffstat (limited to 'systemtap')
33 files changed, 920 insertions, 690 deletions
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.structures/src/org/eclipse/linuxtools/systemtap/structures/TreeDefinitionNode.java b/systemtap/org.eclipse.linuxtools.systemtap.structures/src/org/eclipse/linuxtools/systemtap/structures/TreeDefinitionNode.java index a3a421a031..4f42c52fa6 100644 --- a/systemtap/org.eclipse.linuxtools.systemtap.structures/src/org/eclipse/linuxtools/systemtap/structures/TreeDefinitionNode.java +++ b/systemtap/org.eclipse.linuxtools.systemtap.structures/src/org/eclipse/linuxtools/systemtap/structures/TreeDefinitionNode.java @@ -11,8 +11,9 @@ package org.eclipse.linuxtools.systemtap.structures; - public class TreeDefinitionNode extends TreeNode { + private String definition; + public TreeDefinitionNode(Object d, String disp, String def, boolean c) { super(d, disp, c); definition = def; @@ -31,6 +32,4 @@ public class TreeDefinitionNode extends TreeNode { super.dispose(); definition = null; } - - private String definition; } diff --git a/systemtap/org.eclipse.linuxtools.systemtap.structures/src/org/eclipse/linuxtools/systemtap/structures/TreeNode.java b/systemtap/org.eclipse.linuxtools.systemtap.structures/src/org/eclipse/linuxtools/systemtap/structures/TreeNode.java index 639be9f36e..d130f5841b 100644 --- a/systemtap/org.eclipse.linuxtools.systemtap.structures/src/org/eclipse/linuxtools/systemtap/structures/TreeNode.java +++ b/systemtap/org.eclipse.linuxtools.systemtap.structures/src/org/eclipse/linuxtools/systemtap/structures/TreeNode.java @@ -15,12 +15,17 @@ import java.util.ArrayList; import java.util.List; public class TreeNode { + private List<TreeNode> children; + private Object data; + private String display; + private boolean clickable; + public TreeNode(Object d, boolean c) { children = new ArrayList<>(); data = d; clickable = c; - if(null == data) { + if (data == null) { display = null; } else { display = d.toString(); @@ -46,8 +51,8 @@ public class TreeNode { return children.size(); } - public TreeNode getChildAt(int i){ - if(children.size() > i) { + public TreeNode getChildAt(int i) { + if (children.size() > i) { return children.get(i); } else { return null; @@ -63,15 +68,15 @@ public class TreeNode { } public boolean remove(int i) { - if(children.size() > i) { - return(null != children.remove(i)); + if (children.size() > i) { + return (null != children.remove(i)); } else { return false; } } public boolean removeAll() { - for(int i=children.size()-1; i>=0; i--) { + for (int i = children.size() - 1; i >= 0; i--) { remove(i); } return true; @@ -86,8 +91,8 @@ public class TreeNode { } /** - * Restructures the tree so that probes are grouped by type and - * functions are sorted alphabetically. + * Restructures the tree so that probes are grouped by type and functions + * are sorted alphabetically. */ public void sortTree() { sortLevel(); @@ -115,7 +120,7 @@ public class TreeNode { } public void dispose() { - if (null != children) { + if (children != null) { for (TreeNode child : children) { child.dispose(); } @@ -128,7 +133,7 @@ public class TreeNode { /** * @since 2.0 */ - public TreeNode getChildByName(String name){ + public TreeNode getChildByName(String name) { for (TreeNode child : children) { if (child.toString().equals(name)) { return child; @@ -137,9 +142,4 @@ public class TreeNode { return null; } - - private List<TreeNode> children; - private Object data; - private String display; - private boolean clickable; } diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide.tests/src/org/eclipse/linuxtools/systemtap/ui/ide/test/structures/TreeSettingsTest.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide.tests/src/org/eclipse/linuxtools/systemtap/ui/ide/test/structures/TreeSettingsTest.java index bf9fdec389..5dcf7d0311 100644 --- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide.tests/src/org/eclipse/linuxtools/systemtap/ui/ide/test/structures/TreeSettingsTest.java +++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide.tests/src/org/eclipse/linuxtools/systemtap/ui/ide/test/structures/TreeSettingsTest.java @@ -16,6 +16,11 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import org.eclipse.linuxtools.internal.systemtap.ui.ide.structures.TreeSettings; +import org.eclipse.linuxtools.internal.systemtap.ui.ide.structures.nodedata.FuncparamNodeData; +import org.eclipse.linuxtools.internal.systemtap.ui.ide.structures.nodedata.FunctionNodeData; +import org.eclipse.linuxtools.internal.systemtap.ui.ide.structures.nodedata.ProbeNodeData; +import org.eclipse.linuxtools.internal.systemtap.ui.ide.structures.nodedata.ProbevarNodeData; +import org.eclipse.linuxtools.systemtap.structures.TreeDefinitionNode; import org.eclipse.linuxtools.systemtap.structures.TreeNode; import org.junit.Before; import org.junit.Test; @@ -65,19 +70,22 @@ public class TreeSettingsTest { temp = TreeSettings.getFunctionTree(); assertEquals("Funcs no children", 0, temp.getChildCount()); assertEquals("Funcs object", t.getData().toString(), temp.getData().toString()); - assertEquals("Funcs display", t.toString(),temp.toString()); + assertEquals("Funcs display", t.toString(), temp.toString()); + assertEquals("Funcs clickable", t.isClickable(), temp.isClickable()); TreeSettings.setTrees(t1, t); temp = TreeSettings.getFunctionTree(); assertEquals("Funcs no children", 0, temp.getChildCount()); assertEquals("Funcs object", t1.getData(), temp.getData()); assertEquals("Funcs display", t1.toString(), temp.toString()); + assertEquals("Funcs clickable", t1.isClickable(), temp.isClickable()); TreeSettings.setTrees(t2, t); temp = TreeSettings.getFunctionTree(); assertEquals("Funcs no children", 0, temp.getChildCount()); - assertEquals("Funcs object", t2.getData().toString(),temp.getData()); + assertEquals("Funcs object", t2.getData().toString(), temp.getData()); assertEquals("Funcs display", t2.toString(), temp.toString()); + assertEquals("Funcs clickable", t2.isClickable(), temp.isClickable()); t.add(t2); t.add(t1); @@ -100,18 +108,21 @@ public class TreeSettingsTest { assertEquals("Probs no children", 0, temp.getChildCount()); assertEquals("Probs object", t.getData().toString(), temp.getData().toString()); assertEquals("Probs display", t.toString(), temp.toString()); + assertEquals("Probs clickable", t.isClickable(), temp.isClickable()); TreeSettings.setTrees(t, t1); temp = TreeSettings.getProbeTree(); assertEquals("Probs no children", 0, temp.getChildCount()); assertEquals("Probs object", t1.getData(), temp.getData()); assertEquals("Probs display", t1.toString(), temp.toString()); + assertEquals("Probs clickable", t1.isClickable(), temp.isClickable()); TreeSettings.setTrees(t, t2); temp = TreeSettings.getProbeTree(); assertEquals("Probs no children", 0, temp.getChildCount()); assertEquals("Probs object", t2.getData().toString(), temp.getData()); assertEquals("Probs display", t2.toString(), temp.toString()); + assertEquals("Probs clickable", t2.isClickable(), temp.isClickable()); t.add(t2); t.add(t1); @@ -120,6 +131,54 @@ public class TreeSettingsTest { assertEquals("Probs has children", 2, temp.getChildCount()); assertEquals("Probs child object", t2.getData().toString(), temp.getChildAt(0).getData()); assertEquals("Probs child display", t2.toString(), temp.getChildAt(0).toString()); + } + + @Test + public void testDefinitionTrees() { + TreeNode temp; + TreeDefinitionNode t1 = new TreeDefinitionNode("t1", "deftree1", "location", true); + TreeDefinitionNode t2 = new TreeDefinitionNode("t2", "deftree2", null, true); + + TreeSettings.setTrees(t1, t2); + temp = TreeSettings.getFunctionTree(); + assertTrue("Tree should have been saved as a definition node", temp instanceof TreeDefinitionNode); + assertEquals("Funcs definition", t1.getDefinition(), ((TreeDefinitionNode) temp).getDefinition()); + assertEquals("Funcs object", t1.getData(), temp.getData()); + assertEquals("Funcs display", t1.toString(), temp.toString()); + assertEquals("Funcs clickable", t1.isClickable(), temp.isClickable()); + temp = TreeSettings.getProbeTree(); + assertTrue("Even with a null definition, tree should have been saved as a definition node", temp instanceof TreeDefinitionNode); + assertEquals("Probs definition", t2.getDefinition(), ((TreeDefinitionNode) temp).getDefinition()); + assertEquals("Probs object", t2.getData(), temp.getData()); + assertEquals("Probs display", t2.toString(), temp.toString()); + assertEquals("Probs clickable", t2.isClickable(), temp.isClickable()); + } + + @Test + public void testStapNodeData() { + TreeNode temp; + TreeNode t1 = new TreeNode(new FunctionNodeData("function ftest(x:long)", null), true); + t1.add(new TreeNode(new FuncparamNodeData("long"), "x", false)); + + TreeNode t2 = new TreeNode(new ProbeNodeData("ptest"), true); + t2.add(new TreeNode(new ProbevarNodeData("x:long"), false)); + + TreeSettings.setTrees(t1, t2); + temp = TreeSettings.getFunctionTree(); + assertTrue("Improper data type", temp.getData() instanceof FunctionNodeData); + assertEquals("Function data not saved", t1.getData().toString(), temp.getData().toString()); + assertEquals("Funcs has children", t1.getChildCount(), temp.getChildCount()); + assertTrue("Improper data type", temp.getChildAt(0).getData() instanceof FuncparamNodeData); + assertEquals("Function parameter data not saved", + t1.getChildAt(0).getData().toString(), temp.getChildAt(0).getData().toString()); + + temp = TreeSettings.getProbeTree(); + assertTrue("Improper data type", temp.getData() instanceof ProbeNodeData); + assertEquals("Probe data not saved", t2.getData().toString(), temp.getData().toString()); + assertEquals("Probs has children", t2.getChildCount(), temp.getChildCount()); + assertTrue("Improper data type", temp.getChildAt(0).getData() instanceof ProbevarNodeData); + assertEquals("Probe variable data not saved", + t2.getChildAt(0).getData().toString(), temp.getChildAt(0).getData().toString()); } } diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide.tests/src/org/eclipse/linuxtools/systemtap/ui/ide/test/swtbot/TestCreateSystemtapScript.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide.tests/src/org/eclipse/linuxtools/systemtap/ui/ide/test/swtbot/TestCreateSystemtapScript.java index b884db5ad9..ac5f469508 100644 --- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide.tests/src/org/eclipse/linuxtools/systemtap/ui/ide/test/swtbot/TestCreateSystemtapScript.java +++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide.tests/src/org/eclipse/linuxtools/systemtap/ui/ide/test/swtbot/TestCreateSystemtapScript.java @@ -266,18 +266,6 @@ public class TestCreateSystemtapScript { bot = new SWTWorkbenchBot(); stapInstalled = true; - // Dismiss "Systemtap not installed" dialog(s) if present. - try { - SWTBotShell shell = bot.shell("Cannot Run SystemTap").activate(); - stapInstalled = false; - shell.close(); - - shell = bot.shell("Cannot Run SystemTap").activate(); - shell.close(); - } catch (WidgetNotFoundException e) { - //ignore - } - try { bot.viewByTitle("Welcome").close(); // hide Subclipse Usage stats popup if present/installed @@ -298,6 +286,18 @@ public class TestCreateSystemtapScript { } } + // Dismiss "Systemtap not installed" dialog(s) if present. + try { + SWTBotShell shell = bot.shell("Cannot Run SystemTap").activate(); + stapInstalled = false; + shell.close(); + + shell = bot.shell("Cannot Run SystemTap").activate(); + shell.close(); + } catch (WidgetNotFoundException e) { + //ignore + } + // Create a Systemtap project. SWTBotMenu fileMenu = bot.menu("File"); SWTBotMenu newMenu = fileMenu.menu("New"); diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/IDEPlugin.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/IDEPlugin.java index 52ace35be4..fad891dbbc 100644 --- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/IDEPlugin.java +++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/IDEPlugin.java @@ -55,7 +55,6 @@ public class IDEPlugin extends AbstractUIPlugin { workbenchListener = new IDECloseMonitor(); plugin.getWorkbench().addWorkbenchListener(workbenchListener); - TapsetLibrary.init(); } /** @@ -95,8 +94,7 @@ public class IDEPlugin extends AbstractUIPlugin { IPreferenceStore p = ConsoleLogPlugin.getDefault().getPreferenceStore(); String user = p.getString(ConsoleLogPreferenceConstants.SCP_USER); String host = p.getString(ConsoleLogPreferenceConstants.HOST_NAME); - if (path == null) - { + if (path == null) { path = ""; //$NON-NLS-1$ } try { diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/IDESessionSettings.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/IDESessionSettings.java index c89951ed48..ba0d067f66 100644 --- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/IDESessionSettings.java +++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/IDESessionSettings.java @@ -34,8 +34,6 @@ import org.eclipse.ui.dialogs.ListDialog; * @author Ryan Morse */ public class IDESessionSettings { - public static String tapsetLocation = ""; //$NON-NLS-1$ - /** * Use {@link IDESessionSettings#setActiveSTPEditor(STPEditor)} and * {@link IDESessionSettings#getActiveSTPEditor()} diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/ProbeAliasAction.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/ProbeAliasAction.java index 9b6d75f789..090952d726 100644 --- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/ProbeAliasAction.java +++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/ProbeAliasAction.java @@ -14,8 +14,8 @@ package org.eclipse.linuxtools.internal.systemtap.ui.ide.actions; import org.eclipse.linuxtools.internal.systemtap.ui.ide.IDESessionSettings; import org.eclipse.linuxtools.internal.systemtap.ui.ide.Localization; import org.eclipse.linuxtools.internal.systemtap.ui.ide.editors.stp.STPEditor; -import org.eclipse.linuxtools.internal.systemtap.ui.ide.structures.ProbeNodeData; -import org.eclipse.linuxtools.internal.systemtap.ui.ide.structures.ProbevarNodeData; +import org.eclipse.linuxtools.internal.systemtap.ui.ide.structures.nodedata.ProbeNodeData; +import org.eclipse.linuxtools.internal.systemtap.ui.ide.structures.nodedata.ProbevarNodeData; import org.eclipse.linuxtools.internal.systemtap.ui.ide.views.ProbeAliasBrowserView; import org.eclipse.linuxtools.systemtap.structures.TreeNode; import org.eclipse.ui.IWorkbenchWindow; diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPMetadataSingleton.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPMetadataSingleton.java index 347521bcb6..2b254ff7a6 100644 --- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPMetadataSingleton.java +++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPMetadataSingleton.java @@ -33,9 +33,7 @@ public final class STPMetadataSingleton { private static STPMetadataSingleton instance = null; - private STPMetadataSingleton() { - TapsetLibrary.init(); - } + private STPMetadataSingleton() {} public static STPMetadataSingleton getInstance() { if (instance == null) { @@ -57,7 +55,7 @@ public final class STPMetadataSingleton { List<String> matches = new LinkedList<>(); String groupName = extractProbeGroupName(prefix); - for (TreeNode node : getEachProbeCategoryNode()) { + for (TreeNode node : TapsetLibrary.getProbeCategoryNodes()) { if (node == null) { continue; } @@ -99,10 +97,6 @@ public final class STPMetadataSingleton { return getMatchingChildren(node, prefix); } - private TreeNode[] getEachProbeCategoryNode() { - return new TreeNode[]{TapsetLibrary.getStaticProbes(), TapsetLibrary.getProbeAliases()}; - } - private String[] getMatchingChildren(TreeNode node, String prefix) { ArrayList<String> matches = new ArrayList<>(); diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/handlers/DefinitionHandler.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/handlers/DefinitionHandler.java index 8adcf78d9b..5c5af4608b 100644 --- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/handlers/DefinitionHandler.java +++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/handlers/DefinitionHandler.java @@ -21,7 +21,7 @@ import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.linuxtools.internal.systemtap.ui.ide.CommentRemover; import org.eclipse.linuxtools.internal.systemtap.ui.ide.editors.stp.STPEditor; -import org.eclipse.linuxtools.internal.systemtap.ui.ide.structures.ISearchableNode; +import org.eclipse.linuxtools.internal.systemtap.ui.ide.structures.nodedata.ISearchableNode; import org.eclipse.linuxtools.systemtap.structures.TreeDefinitionNode; import org.eclipse.linuxtools.systemtap.ui.editor.handlers.file.OpenFileHandler; import org.eclipse.ui.IEditorPart; diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/preferences/EnvironmentVariablesPreferencePage.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/preferences/EnvironmentVariablesPreferencePage.java index 6cdc93774e..63644c0d96 100644 --- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/preferences/EnvironmentVariablesPreferencePage.java +++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/preferences/EnvironmentVariablesPreferencePage.java @@ -59,10 +59,11 @@ public class EnvironmentVariablesPreferencePage extends PreferencePage implement sc.setExpandVertical(true); sc.setContent(c); - envVariables = new StringFieldEditor[PreferenceConstants.P_ENV.length]; - for (int i = 0; i < envVariables.length; i++) { - envVariables[i] = createStringFieldEditor(PreferenceConstants.P_ENV[i][0], - PreferenceConstants.P_ENV[i][1], c); + envVariables = new StringFieldEditor[PreferenceConstants.P_ENV.values().length]; + int i = 0; + for (PreferenceConstants.P_ENV env : PreferenceConstants.P_ENV.values()) { + envVariables[i] = createStringFieldEditor(env.toPrefKey(), env.toEnvKey(), c); + i++; } return sc; } @@ -119,17 +120,16 @@ public class EnvironmentVariablesPreferencePage extends PreferencePage implement public static String[] getEnvironmentVariables() { ArrayList<String> vars = new ArrayList<>(); String[] envVars = null; - String var; int i; if (IDEPlugin.getDefault() == null || IDEPlugin.getDefault().getPreferenceStore() == null) { return null; } IPreferenceStore p = IDEPlugin.getDefault().getPreferenceStore(); - for (i = 0; i < PreferenceConstants.P_ENV.length; i++) { - var = p.getString(PreferenceConstants.P_ENV[i][0]).trim(); - if (!var.isEmpty()) { - vars.add(PreferenceConstants.P_ENV[i][1] + "=" + var); //$NON-NLS-1$ + for (PreferenceConstants.P_ENV env : PreferenceConstants.P_ENV.values()) { + String val = p.getString(env.toPrefKey()).trim(); + if (!val.isEmpty()) { + vars.add(env.createKeyValString(val)); } } diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/preferences/PreferenceConstants.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/preferences/PreferenceConstants.java index fc5a779515..266b4049f5 100644 --- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/preferences/PreferenceConstants.java +++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/preferences/PreferenceConstants.java @@ -17,11 +17,35 @@ package org.eclipse.linuxtools.internal.systemtap.ui.ide.preferences; public class PreferenceConstants { //environmentvariables - public static final String[][] P_ENV = new String[][] { - {"EnvLdLibraryPath", "LD_LIBRARY_PATH"}, //$NON-NLS-1$ //$NON-NLS-2$ - {"EnvPath", "PATH"}, //$NON-NLS-1$ //$NON-NLS-2$ - {"EnvSystemtapTapset", "SYSTEMTAP_TAPSET"}, //$NON-NLS-1$ //$NON-NLS-2$ - {"EnvSystemtapRuntime", "SYSTEMTAP_RUNTIME"}, //$NON-NLS-1$ //$NON-NLS-2$ - }; + public static enum P_ENV { + LD_LIBRARY_PATH { + @Override + public String toPrefKey() { + return "EnvLdLibraryPath"; //$NON-NLS-1$ + } + }, PATH { + @Override + public String toPrefKey() { + return "EnvPath"; //$NON-NLS-1$ + } + }, SYSTEMTAP_TAPSET { + @Override + public String toPrefKey() { + return "EnvSystemtapTapset"; //$NON-NLS-1$ + } + }, SYSTEMTAP_RUNTIME { + @Override + public String toPrefKey() { + return "EnvSystemtapRuntime"; //$NON-NLS-1$ + } + }; + public abstract String toPrefKey(); + public String toEnvKey() { + return toString(); + } + public String createKeyValString(String value) { + return toEnvKey() + '=' + value.trim(); + } + } } diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/preferences/messages.properties b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/preferences/messages.properties index a65e76793a..74e2b4fa48 100644 --- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/preferences/messages.properties +++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/preferences/messages.properties @@ -17,5 +17,5 @@ DirectoryValidator_CanNotContain=Can not contain '//' DirectoryValidator_FolderName=Must be a longer folder name DirectoryValidator_MustEnd=Must end with '/' DirectoryValidator_NotNull=Can't be null -EnvironmentVariablesPreferencePage_Title=Environment Variables. +EnvironmentVariablesPreferencePage_Title=Environment Variables\n(Default values will be used for those left blank) SystemTapPreferencePageDescription=Preferences for the entire GUI application diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/FunctionParser.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/FunctionParser.java index bb65ca01c8..27ca954f35 100644 --- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/FunctionParser.java +++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/FunctionParser.java @@ -21,6 +21,8 @@ import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.linuxtools.internal.systemtap.ui.ide.CommentRemover; import org.eclipse.linuxtools.internal.systemtap.ui.ide.IDEPlugin; +import org.eclipse.linuxtools.internal.systemtap.ui.ide.structures.nodedata.FuncparamNodeData; +import org.eclipse.linuxtools.internal.systemtap.ui.ide.structures.nodedata.FunctionNodeData; import org.eclipse.linuxtools.systemtap.structures.TreeDefinitionNode; import org.eclipse.linuxtools.systemtap.structures.TreeNode; @@ -32,7 +34,7 @@ import org.eclipse.linuxtools.systemtap.structures.TreeNode; * @author Ryan Morse * @since 2.0 */ -public class FunctionParser extends TapsetParser { +public final class FunctionParser extends TreeTapsetParser { private static FunctionParser parser = null; private TreeNode functions; @@ -48,7 +50,7 @@ public class FunctionParser extends TapsetParser { private static final Pattern P_ALL_CAP = Pattern.compile("[A-Z_1-9]*"); //$NON-NLS-1$ private static final Pattern P_RETURN = Pattern.compile("\\sreturn\\W"); //$NON-NLS-1$ - public static FunctionParser getInstance(){ + public static FunctionParser getInstance() { if (parser != null) { return parser; } @@ -60,18 +62,12 @@ public class FunctionParser extends TapsetParser { super("Function Parser"); //$NON-NLS-1$ } - /** - * Returns the root node of the tree of functions generated by - * parseFiles. Functions are grouped by source file. - * @return A tree of tapset functions grouped by file. - */ - public synchronized TreeNode getFunctions() { + @Override + public synchronized TreeNode getTree() { return functions; } - /** - * This method will clean up everything from the run. - */ + @Override public void dispose() { functions.dispose(); } @@ -80,7 +76,7 @@ public class FunctionParser extends TapsetParser { protected IStatus run(IProgressMonitor monitor) { boolean cancelled = runPass2Functions(); functions.sortTree(); - fireUpdateEvent(); //Inform listeners that everything is done + fireUpdateEvent(); //Inform listeners that everything is done return new Status(!cancelled ? IStatus.OK : IStatus.CANCEL, IDEPlugin.PLUGIN_ID, ""); //$NON-NLS-1$ } @@ -97,11 +93,8 @@ public class FunctionParser extends TapsetParser { */ private boolean runPass2Functions() { String tapsetContents = SharedParser.getInstance().getTapsetContents(); - if (cancelRequested) { - return false; - } // Create a new function tree each time, so as to not add duplicates - functions = new TreeNode("", false); //$NON-NLS-1$ + functions = new TreeNode(null, false); if (tapsetContents == null) { // Functions are only drawn from the tapset dump, so exit if it's empty. return true; @@ -112,7 +105,7 @@ public class FunctionParser extends TapsetParser { SharedParser sparser = SharedParser.getInstance(); while (st.hasNextLine()) { - if (cancelRequested) { + if (isCancelRequested()) { return false; } String tok = st.nextLine(); @@ -178,7 +171,7 @@ public class FunctionParser extends TapsetParser { Matcher mParams = P_PARAM.matcher(params); while (mParams.find()) { parentFunction.add(new TreeNode( - new FuncparamNodeData(mParams.group(), mParams.group(2)), + new FuncparamNodeData(mParams.group(2)), mParams.group(1), false)); } } diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/Messages.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/Messages.java index 64e8b9a515..8dd1c6f218 100644 --- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/Messages.java +++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/Messages.java @@ -23,6 +23,7 @@ public class Messages extends NLS { public static String TapsetParser_CannotRunStapMessage; public static String TapsetParser_CannotRunStapTitle; public static String TapsetParser_ErrorRunningSystemtap; + public static String SharedParser_NoOutput; static { // initialize resource bundle NLS.initializeMessages(BUNDLE_NAME, Messages.class); diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/ProbeParser.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/ProbeParser.java index 1c04a1017c..d02cd2e601 100644 --- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/ProbeParser.java +++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/ProbeParser.java @@ -21,6 +21,8 @@ import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.linuxtools.internal.systemtap.ui.ide.IDEPlugin; +import org.eclipse.linuxtools.internal.systemtap.ui.ide.structures.nodedata.ProbeNodeData; +import org.eclipse.linuxtools.internal.systemtap.ui.ide.structures.nodedata.ProbevarNodeData; import org.eclipse.linuxtools.systemtap.structures.TreeDefinitionNode; import org.eclipse.linuxtools.systemtap.structures.TreeNode; @@ -32,9 +34,9 @@ import org.eclipse.linuxtools.systemtap.structures.TreeNode; * @author Ryan Morse * @since 2.0 */ -public final class ProbeParser extends TapsetParser { +public final class ProbeParser extends TreeTapsetParser { - static final String PROBE_REGEX = "(?s)(?<!\\w)probe\\s+{0}\\s*\\+?="; //$NON-NLS-1$ + public static final String PROBE_REGEX = "(?s)(?<!\\w)probe\\s+{0}\\s*\\+?="; //$NON-NLS-1$ private static final String TAPSET_PROBE_REGEX = "probe {0} \\+?="; //$NON-NLS-1$ private TreeNode probes; @@ -54,18 +56,12 @@ public final class ProbeParser extends TapsetParser { super("Probe Parser"); //$NON-NLS-1$ } - /** - * Returns the root node of the tree of the probe alias generated by - * parseFiles. Probes are grouped by target location. - * @return A tree of tapset probe aliases grouped by probe location. - */ - public synchronized TreeNode getProbes() { + @Override + public synchronized TreeNode getTree() { return probes; } - /** - * This method will clean up everything from the run. - */ + @Override public void dispose() { probes.dispose(); statics.dispose(); @@ -78,17 +74,17 @@ public final class ProbeParser extends TapsetParser { reset(); addStaticProbes(); - if (cancelRequested){ + if (isCancelRequested()) { return new Status(IStatus.CANCEL, IDEPlugin.PLUGIN_ID, ""); //$NON-NLS-1$ } - boolean cancelled = addProbeAliases(collect(null)); + addProbeAliases(); constructRootTree(); fireUpdateEvent(); //Inform listeners that everything is done - return new Status(!cancelled ? IStatus.OK : IStatus.CANCEL, IDEPlugin.PLUGIN_ID, ""); //$NON-NLS-1$ + return new Status(!isCancelRequested() ? IStatus.OK : IStatus.CANCEL, IDEPlugin.PLUGIN_ID, ""); //$NON-NLS-1$ } private void reset() { - probes = new TreeNode("", false); //$NON-NLS-1$ + probes = new TreeNode(null, false); statics = new TreeNode(Messages.ProbeParser_staticProbes, false); aliases = new TreeNode(Messages.ProbeParser_aliasProbes, false); } @@ -100,45 +96,23 @@ public final class ProbeParser extends TapsetParser { probes.add(aliases); } - /** - * Returns a String containing all of the content from the probe - * point list, including variables and their type. - * - * stap -L - * Will list all available probe points - * @return the probe points consolidated into a single string - */ - private String collect(String script) { - String[] options; - if(null == script) { - script = "**"; //$NON-NLS-1$ - options = new String[] {"-L"}; //$NON-NLS-1$ - } else { - options = null; - } - - String s = runStap(options, script, false); - if (s == null) { - return ""; //$NON-NLS-1$ + private void addStaticProbes() { + String probeDump = runStap(new String[]{"--dump-probe-types"}, null, false); //$NON-NLS-1$ + if (probeDump == null) { + return; } - - return s; - } - - private boolean addStaticProbes() { - String s = runStap(new String[]{"--dump-probe-types"}, null, false); //$NON-NLS-1$ TreeNode group = null; - try (Scanner st = new Scanner(s)) { - while(st.hasNextLine()) { - if (cancelRequested) { - return false; + try (Scanner st = new Scanner(probeDump)) { + while (st.hasNextLine()) { + if (isCancelRequested()) { + return; } String tokenString = st.nextLine(); String probeName = (new StringTokenizer(tokenString)).nextToken(); group = addOrFindProbeGroup(extractProbeGroupName(probeName), group, statics); group.add(makeStaticProbeNode(probeName)); } - return true; + return; } } @@ -149,16 +123,19 @@ public final class ProbeParser extends TapsetParser { * ProbeTree organized as: * Root->Named Groups->ProbePoints->Variables * - * @param probeDump A list of probe points with the same formatting used by stap -L. * @return <code>false</code> if a cancellation prevented all probes from being added; * <code>true</code> otherwise. */ - private boolean addProbeAliases(String probeDump) { + private void addProbeAliases() { + String probeDump = runStap(new String[]{"-L"}, "**", false); //$NON-NLS-1$ //$NON-NLS-2$ + if (probeDump == null) { + return; + } TreeNode group = null; try (Scanner st = new Scanner(probeDump)) { - while(st.hasNextLine()) { - if (cancelRequested) { - return false; + while (st.hasNextLine()) { + if (isCancelRequested()) { + return; } String tokenString = st.nextLine(); // If the token starts with '_' or '__' it is a private probe so @@ -178,7 +155,7 @@ public final class ProbeParser extends TapsetParser { addAllVarNodesToProbeNode(probeTokenizer, probeNode); } } - return true; + return; } } @@ -196,12 +173,12 @@ public final class ProbeParser extends TapsetParser { // If the current probe belongs to a group other than // the most recent group. This should rarely be needed because the // probe list is sorted... mostly. - if(groupNode == null || !groupNode.toString().equals(groupName)) { + if (groupNode == null || !groupNode.toString().equals(groupName)) { groupNode = category.getChildByName(groupName); } // Create a new group and add it - if(groupNode == null) { + if (groupNode == null) { groupNode = new TreeNode(groupName, true); category.add(groupNode); } @@ -247,6 +224,9 @@ public final class ProbeParser extends TapsetParser { private String findDefinitionOf(String probeName) { SharedParser sparser = SharedParser.getInstance(); String tapsetContents = sparser.getTapsetContents(); + if (tapsetContents == null) { + return null; + } Matcher probeMatcher = Pattern.compile(MessageFormat.format(TAPSET_PROBE_REGEX, Pattern.quote(probeName))).matcher(tapsetContents); if (!probeMatcher.find()) { return null; @@ -267,14 +247,14 @@ public final class ProbeParser extends TapsetParser { private void addAllVarNodesToProbeNode(StringTokenizer varTokenizer, TreeNode probeNode) { StringBuilder prev = new StringBuilder(""); //$NON-NLS-1$ // the remaining tokens are variable names and variable types name:type. - while(varTokenizer.hasMoreTokens()){ + while (varTokenizer.hasMoreTokens()) { String token = varTokenizer.nextToken(); // Because some variable types contain spaces (var2:struct task_struct) // the only way to know if we have the entire string representing a // variable is if we reach the next token containing a ':' or we reach // the end of the stream. - if (token.contains(":") && prev.length() > 0){ //$NON-NLS-1$ + if (token.contains(":") && prev.length() > 0) { //$NON-NLS-1$ prev.setLength(prev.length() - 1); // Remove the trailing space. addVarNodeToProbeNode(prev.toString(), probeNode); prev.setLength(0); @@ -283,7 +263,7 @@ public final class ProbeParser extends TapsetParser { } // Add the last token if there is one - if (prev.length() > 0){ + if (prev.length() > 0) { prev.setLength(prev.length() - 1); // Remove the trailing space. addVarNodeToProbeNode(prev.toString(), probeNode); } diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/SharedParser.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/SharedParser.java index 66c0cc51c1..18e88f6f19 100644 --- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/SharedParser.java +++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/SharedParser.java @@ -18,9 +18,17 @@ import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.linuxtools.internal.systemtap.ui.ide.IDEPlugin; +/** + * A helper class for performing tapset-loading operations, + * and sharing the results with other {@link TapsetParser}s. + * Note that class this does not implement {@link ITreeParser}, + * as no front-end operations are performed. + */ public final class SharedParser extends TapsetParser { static final String TAG_FILE = "# file"; //$NON-NLS-1$ + private static final String[] STAP_OPTIONS = new String[] {"-v", "-p1", "-e"}; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + private static final String STAP_DUMMYPROBE = "probe begin{}"; //$NON-NLS-1$ /** * A pattern that can be used to locate file paths listed in stap tapset dumps. */ @@ -66,10 +74,19 @@ public final class SharedParser extends TapsetParser { @Override protected IStatus run(IProgressMonitor monitor) { - tapsetContents = runStap(new String[] {"-v", "-p1", "-e"}, "probe begin{}", false); //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$//$NON-NLS-4$ + String contents = runStap(STAP_OPTIONS, STAP_DUMMYPROBE, false); + if (contents == null) { + return new Status(IStatus.ERROR, IDEPlugin.PLUGIN_ID, Messages.SharedParser_NoOutput); + } // Exclude the dump of the test script by excluding everything before the second pathname // (which is the first actual tapset file, not the input script). - tapsetContents = tapsetContents.substring(tapsetContents.indexOf(TAG_FILE, tapsetContents.indexOf(TAG_FILE)+1)); + int firstTagIndex = contents.indexOf(TAG_FILE); + if (firstTagIndex != -1) { + int beginIndex = contents.indexOf(TAG_FILE, firstTagIndex + 1); + if (beginIndex != -1) { + tapsetContents = contents.substring(beginIndex); + } + } return new Status(IStatus.OK, IDEPlugin.PLUGIN_ID, ""); //$NON-NLS-1$ } diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/TapsetLibrary.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/TapsetLibrary.java index a7c2f48d8b..77e446c6bb 100644 --- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/TapsetLibrary.java +++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/TapsetLibrary.java @@ -23,31 +23,31 @@ import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.util.IPropertyChangeListener; import org.eclipse.jface.util.PropertyChangeEvent; import org.eclipse.linuxtools.internal.systemtap.ui.ide.IDEPlugin; -import org.eclipse.linuxtools.internal.systemtap.ui.ide.IDESessionSettings; import org.eclipse.linuxtools.internal.systemtap.ui.ide.Localization; import org.eclipse.linuxtools.internal.systemtap.ui.ide.preferences.IDEPreferenceConstants; import org.eclipse.linuxtools.internal.systemtap.ui.ide.preferences.PreferenceConstants; import org.eclipse.linuxtools.man.parser.ManPage; import org.eclipse.linuxtools.systemtap.structures.TreeNode; import org.eclipse.linuxtools.systemtap.structures.listeners.IUpdateListener; +import org.eclipse.swt.widgets.Display; import org.eclipse.ui.PlatformUI; - - /** * This class is used for obtaining all probes and functions from the tapsets. - * It will initially try to obtain the list from the TreeSettings.xml file, but - * if there is a problem doing that it will run the TapsetParser in order to - * obtain everything that way. + * If stored tapsets are in use, it will try to obtain the list from the TreeSettings memento. + * Otherwise, or if there is a problem with the memento, it will instead run the TapsetParsers + * in order to obtain tapset information. * @author Ryan Morse */ public final class TapsetLibrary { - private static TreeNode functionTree = null; private static TreeNode probeTree = null; - private static FunctionParser functionParser = null; - private static ProbeParser probeParser = null; + private static FunctionParser functionParser = FunctionParser.getInstance(); + private static ProbeParser probeParser = ProbeParser.getInstance(); + + private static final IUpdateListener functionCompletionListener = new ParseCompletionListener(functionParser); + private static final IUpdateListener probeCompletionListener = new ParseCompletionListener(probeParser); public static TreeNode getProbes() { return probeTree; @@ -61,6 +61,10 @@ public final class TapsetLibrary { return probeTree == null ? null : probeTree.getChildByName(Messages.ProbeParser_aliasProbes); } + public static TreeNode[] getProbeCategoryNodes() { + return new TreeNode[] {getStaticProbes(), getProbeAliases()}; + } + public static TreeNode getFunctions() { return functionTree; } @@ -68,6 +72,22 @@ public final class TapsetLibrary { private static HashMap<String, String> pages = new HashMap<>(); /** + * Returns the documentation for the given element and caches the result. Use this + * function if the given element is known to be a probe, function, or tapset. + * @param element + * @return + * @since 2.0 + */ + public static synchronized String getAndCacheDocumentation(String element) { + String doc = pages.get(element); + if (doc == null) { + doc = getDocumentation(element); + pages.put(element, doc); + } + return doc; + } + + /** * Returns the documentation for the given probe, function, or tapset. * @since 2.0 */ @@ -118,71 +138,132 @@ public final class TapsetLibrary { return documentation; } - /** - * Returns the documentation for the given element and caches the result. Use this - * function if the given element is known to be a probe, function, or tapset. - * @param element - * @return - * @since 2.0 - */ - public static synchronized String getAndCacheDocumentation(String element) { - String doc = pages.get(element); - if (doc == null) { - doc = getDocumentation(element); - pages.put(element, doc); + private static void init() { + IPreferenceStore preferenceStore = IDEPlugin.getDefault().getPreferenceStore(); + preferenceStore.addPropertyChangeListener(propertyChangeListener); + + functionParser.addListener(functionCompletionListener); + probeParser.addListener(probeCompletionListener); + + if (preferenceStore.getBoolean(IDEPreferenceConstants.P_STORED_TREE) + && isTreeFileCurrent()) { + readTreeFile(); + } else { + runStapParser(); } - return doc; } - private static IPropertyChangeListener propertyChangeListener = new IPropertyChangeListener() { + private static final IPropertyChangeListener propertyChangeListener = new IPropertyChangeListener() { @Override public void propertyChange(PropertyChangeEvent event) { - if (event.getProperty().equals(IDEPreferenceConstants.P_TAPSETS)) { + String property = event.getProperty(); + if (property.equals(IDEPreferenceConstants.P_TAPSETS) + || property.equals(PreferenceConstants.P_ENV.SYSTEMTAP_TAPSET.toPrefKey())) { runStapParser(); + } else if (property.equals(IDEPreferenceConstants.P_STORED_TREE)) { + if (event.getNewValue().equals(false)) { + // When turning off stored trees, reload the tapset contents directly. + TreeSettings.deleteTrees(); + runStapParser(); + } else { + // When turning on stored trees, store the current trees (if possible). + TreeSettings.setTrees(functionTree, probeTree); + } } } }; - /** - * This method will attempt to get the most up-to-date information. - * However, if the TapsetParser is running already it will quit, - * assuming that new information will be available soon. By registering - * a listener at that point the class can be notified when an update is - * available. - */ - public static void init() { - if (null != functionParser && null != probeParser) { - return; + private static class ParseCompletionListener implements IUpdateListener { + TreeTapsetParser parser; + public ParseCompletionListener(TreeTapsetParser parser) { + this.parser = parser; } - IPreferenceStore preferenceStore = IDEPlugin.getDefault().getPreferenceStore(); - preferenceStore.addPropertyChangeListener(propertyChangeListener); + @Override + public void handleUpdateEvent() { + if (!parser.isCancelRequested()) { + if (parser.equals(functionParser)) { + functionTree = parser.getTree(); + cacheFunctionManpages.schedule(); + } else { + probeTree = parser.getTree(); + cacheProbeManpages.schedule(); + } - if (preferenceStore.contains(IDEPreferenceConstants.P_STORED_TREE) - && preferenceStore.getBoolean(IDEPreferenceConstants.P_STORED_TREE) - && isTreeFileCurrent()) { - readTreeFile(); - } else { - runStapParser(); + if (IDEPlugin.getDefault().getPreferenceStore().getBoolean(IDEPreferenceConstants.P_STORED_TREE)) { + TreeSettings.setTrees(functionTree, probeTree); + } + } + synchronized (parser) { + parser.notifyAll(); + } } } /** - * This method will create a new instance of the TapsetParser in order + * This method will trigger the appropriate parsing jobs * to get the information directly from the files. + * If the jobs are already in progess, they will be restarted. */ private static void runStapParser() { + stop(); + clearTrees(); SharedParser.getInstance().clearTapsetContents(); - - functionParser = FunctionParser.getInstance(); - functionParser.addListener(functionCompletionListener); functionParser.schedule(); - - probeParser = ProbeParser.getInstance(); - probeParser.addListener(probeCompletionListener); probeParser.schedule(); } + private static void clearTrees() { + if (functionTree != null) { + functionTree.dispose(); + functionTree = null; + } + if (probeTree != null) { + probeTree.dispose(); + probeTree = null; + } + } + + private static Job cacheFunctionManpages = new Job(Localization.getString("TapsetLibrary.0")) { //$NON-NLS-1$ + private boolean cancelled; + + @Override + protected IStatus run(IProgressMonitor monitor) { + TreeNode nodes = getFunctions(); + for (int i = 0, n = nodes.getChildCount(); i < n && !this.cancelled; i++) { + getAndCacheDocumentation("function::" + (nodes.getChildAt(i).toString())); //$NON-NLS-1$ + } + + return new Status(IStatus.OK, IDEPlugin.PLUGIN_ID, ""); //$NON-NLS-1$; + } + + @Override + protected void canceling() { + this.cancelled = true; + } + + }; + + private static Job cacheProbeManpages = new Job(Localization.getString("TapsetLibrary.1")) { //$NON-NLS-1$ + private boolean cancelled; + + @Override + protected IStatus run(IProgressMonitor monitor) { + for (TreeNode nodes : getProbeCategoryNodes()) { + for (int i = 0, n = nodes.getChildCount(); i < n && !this.cancelled; i++) { + getAndCacheDocumentation("probe::" + (nodes.getChildAt(i).toString())); //$NON-NLS-1$ + } + } + + return new Status(IStatus.OK, IDEPlugin.PLUGIN_ID, ""); //$NON-NLS-1$; + } + + @Override + protected void canceling() { + this.cancelled = true; + } + }; + /** * This method will get all of the tree information from * the TreeSettings xml file. @@ -190,6 +271,8 @@ public final class TapsetLibrary { private static void readTreeFile() { functionTree = TreeSettings.getFunctionTree(); probeTree = TreeSettings.getProbeTree(); + cacheFunctionManpages.schedule(); + cacheProbeManpages.schedule(); } /** @@ -200,19 +283,20 @@ public final class TapsetLibrary { private static boolean isTreeFileCurrent() { long treesDate = TreeSettings.getTreeFileDate(); - IPreferenceStore p = IDEPlugin.getDefault().getPreferenceStore(); - String[] tapsets = p.getString(IDEPreferenceConstants.P_TAPSETS).split(File.pathSeparator); - - File f = getTapsetLocation(p); + File f = getTapsetLocation(); if (f == null || !checkIsCurrentFolder(treesDate, f)) { return false; } - for (int i = 0; i < tapsets.length; i++) { - f = new File(tapsets[i]); - if (!f.exists() || f.lastModified() > treesDate - || f.canRead() && !checkIsCurrentFolder(treesDate, f)) { - return false; + IPreferenceStore p = IDEPlugin.getDefault().getPreferenceStore(); + String[] tapsets = p.getString(IDEPreferenceConstants.P_TAPSETS).split(File.pathSeparator); + if (!tapsets[0].trim().isEmpty()) { + for (int i = 0; i < tapsets.length; i++) { + f = new File(tapsets[i]); + if (!f.exists() || f.lastModified() > treesDate + || f.canRead() && !checkIsCurrentFolder(treesDate, f)) { + return false; + } } } return true; @@ -220,35 +304,64 @@ public final class TapsetLibrary { /** * This method attempts to locate the default tapset directory. - * @param p Preference store where the tapset location might be stored - * @return File representing the default tapset location. + * @return File representing the default tapset location, or + * <code>null</code> if it cannot be found. */ - public static File getTapsetLocation(IPreferenceStore p) { - File f; - String path = p.getString(PreferenceConstants.P_ENV[2][0]); - if (path.trim().isEmpty()) { - f = new File("/usr/share/systemtap/tapset"); //$NON-NLS-1$ - if (!f.exists()) { - f = new File("/usr/local/share/systemtap/tapset"); //$NON-NLS-1$ - if (!f.exists()) { - InputDialog i = new InputDialog( - PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), - Localization.getString("TapsetBrowserView.TapsetLocation"), Localization.getString("TapsetBrowserView.WhereDefaultTapset"), "", null); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - i.open(); - p.setValue(PreferenceConstants.P_ENV[2][0], i.getValue()); - f = new File(i.getValue()); - } - } - } else { - f = new File(path); + public static File getTapsetLocation() { + final IPreferenceStore p = IDEPlugin.getDefault().getPreferenceStore(); + File f = attemptToGetFileFrom(p.getString(PreferenceConstants.P_ENV.SYSTEMTAP_TAPSET.toPrefKey())); + if (f != null) { + return f; + } + + f = attemptToGetFileFrom(System.getenv(PreferenceConstants.P_ENV.SYSTEMTAP_TAPSET.toEnvKey())); + if (f != null) { + return f; + } + + f = attemptToGetFileFrom("/usr/share/systemtap/tapset"); //$NON-NLS-1$ + if (f != null) { + return f; } - if (f.exists()) { - IDESessionSettings.tapsetLocation = f.getAbsolutePath(); + + f = attemptToGetFileFrom("/usr/local/share/systemtap/tapset"); //$NON-NLS-1$ + if (f != null) { return f; } + + Display.getDefault().asyncExec(new Runnable() { + + @Override + public void run() { + InputDialog i = new InputDialog( + PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), + Localization.getString("TapsetBrowserView.TapsetLocation"), //$NON-NLS-1$ + Localization.getString("TapsetBrowserView.WhereDefaultTapset"), null, null); //$NON-NLS-1$ + i.open(); + String path = i.getValue(); + if (path != null) { + // This preference update should trigger a property listener + // that will update the tapset trees. + p.setValue(PreferenceConstants.P_ENV.SYSTEMTAP_TAPSET.toPrefKey(), i.getValue()); + } + } + + }); return null; } + private static File attemptToGetFileFrom(String path) { + if (path == null) { + return null; + } + String trimmed = path.trim(); + if (trimmed.isEmpty()) { + return null; + } + File f = new File(trimmed); + return f.exists() ? f : null; + } + /** * This method checks the provided time stap against the folders * time stamp. This is to see if the folder may have new data in it @@ -273,95 +386,12 @@ public final class TapsetLibrary { } /** - * Adds a new listener to the TapsetParser - * @param listener the listener to be added - * @return boolean indicating whether or not the listener was added - * @since 2.0 - */ - public static boolean addFunctionListener(IUpdateListener listener) { - if(null == functionParser) { - return false; - } - functionParser.addListener(listener); - return true; - } - - /** - * @since 2.0 - */ - public static boolean addProbeListener(IUpdateListener listener) { - if(null == probeParser) { - return false; - } - probeParser.addListener(listener); - return true; - } - - private static Job cacheFunctionManpages = new Job(Localization.getString("TapsetLibrary.0")) { //$NON-NLS-1$ - private boolean cancelled; - - @Override - protected IStatus run(IProgressMonitor monitor) { - TreeNode node = functionParser.getFunctions(); - int n = node.getChildCount(); - for (int i = 0; i < n && !this.cancelled; i++) { - getAndCacheDocumentation("function::" + (node.getChildAt(i).toString())); //$NON-NLS-1$ - } - - return new Status(IStatus.OK, IDEPlugin.PLUGIN_ID, ""); //$NON-NLS-1$; - } - - @Override - protected void canceling() { - this.cancelled = true; - } - - }; - - private static Job cacheProbeManpages = new Job(Localization.getString("TapsetLibrary.1")) { //$NON-NLS-1$ - @Override - protected IStatus run(IProgressMonitor monitor) { - TreeNode node = probeParser.getProbes(); - int n = node.getChildCount(); - for (int i = 0; i < n; i++) { - getAndCacheDocumentation("tapset::" + (node.getChildAt(i).toString())); //$NON-NLS-1$ - // No need to pre-cache probes; they can be fetched pretty quickly. - } - - return new Status(IStatus.OK, IDEPlugin.PLUGIN_ID, ""); //$NON-NLS-1$; - } - }; - - private static final IUpdateListener functionCompletionListener = new IUpdateListener() { - @Override - public void handleUpdateEvent() { - functionTree = functionParser.getFunctions(); - cacheFunctionManpages.schedule(); - TreeSettings.setTrees(functionTree, probeTree); - synchronized (functionParser) { - functionParser.notifyAll(); - } - } - }; - - private static final IUpdateListener probeCompletionListener = new IUpdateListener() { - @Override - public void handleUpdateEvent() { - probeTree = probeParser.getProbes(); - cacheProbeManpages.schedule(); - synchronized (probeParser) { - probeParser.notifyAll(); - } - } - }; - - /** * Blocks the current thread until the parser has finished * parsing probes and functions. * @since 2.0 */ public static void waitForInitialization() { - while (functionParser.getResult() == null) { + while (functionParser.getState() != Job.NONE) { try { synchronized (functionParser) { functionParser.wait(5000); @@ -370,7 +400,7 @@ public final class TapsetLibrary { break; } } - while (probeParser.getResult() == null) { + while (probeParser.getState() != Job.NONE) { try { synchronized (probeParser) { probeParser.wait(5000); @@ -382,33 +412,34 @@ public final class TapsetLibrary { } /** - * This method will stop services started by - * {@link TapsetLibrary#init()} such as the {@link TapsetParser} + * This method will stop all running tapset parsers, and will block + * the calling thread until they have terminated. * @since 1.2 */ public static void stop() { - if(null != functionParser) { - functionParser.cancel(); - cacheFunctionManpages.cancel(); - try { - functionParser.join(); - } catch (InterruptedException e) { - // The current thread was interrupted while waiting - // for the parser thread to exit. Nothing to do - // continue stopping. - } - } - if(probeParser != null) { - probeParser.cancel(); - cacheProbeManpages.cancel(); - try { - probeParser.join(); - } catch (InterruptedException e) { - // The current thread was interrupted while waiting - // for the parser thread to exit. Nothing to do - // continue stopping. - } + functionParser.cancel(); + cacheFunctionManpages.cancel(); + probeParser.cancel(); + cacheProbeManpages.cancel(); + try { + functionParser.join(); + } catch (InterruptedException e) { + // The current thread was interrupted while waiting + // for the parser thread to exit. Nothing to do + // continue stopping. } + try { + cacheFunctionManpages.join(); + } catch (InterruptedException e) {} + try { + probeParser.join(); + } catch (InterruptedException e) {} + try { + cacheProbeManpages.join(); + } catch (InterruptedException e) {} + } + static { + init(); } } diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/TapsetParser.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/TapsetParser.java index 2675b32e12..62812afb8b 100644 --- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/TapsetParser.java +++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/TapsetParser.java @@ -14,14 +14,17 @@ package org.eclipse.linuxtools.internal.systemtap.ui.ide.structures; import java.io.File; import java.io.IOException; import java.util.ArrayList; +import java.util.concurrent.atomic.AtomicBoolean; +import org.eclipse.core.runtime.jobs.IJobChangeEvent; +import org.eclipse.core.runtime.jobs.IJobChangeListener; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.linuxtools.internal.systemtap.ui.ide.IDEPlugin; import org.eclipse.linuxtools.internal.systemtap.ui.ide.StringOutputStream; +import org.eclipse.linuxtools.internal.systemtap.ui.ide.preferences.EnvironmentVariablesPreferencePage; import org.eclipse.linuxtools.internal.systemtap.ui.ide.preferences.IDEPreferenceConstants; -import org.eclipse.linuxtools.systemtap.graphing.ui.widgets.ExceptionErrorDialog; import org.eclipse.linuxtools.systemtap.structures.listeners.IUpdateListener; import org.eclipse.linuxtools.systemtap.structures.process.SystemtapProcessFactory; import org.eclipse.linuxtools.systemtap.structures.runnable.StringStreamGobbler; @@ -48,38 +51,62 @@ import com.jcraft.jsch.JSchException; */ public abstract class TapsetParser extends Job { - private ArrayList<IUpdateListener> listeners; + private static AtomicBoolean displayingError = new AtomicBoolean(false); - protected boolean cancelRequested; + private ArrayList<IUpdateListener> listeners = new ArrayList<>(); + private boolean cancelRequested = false; + public boolean isCancelRequested() { + return cancelRequested; + } protected TapsetParser(String jobTitle) { super(jobTitle); - listeners = new ArrayList<>(); - cancelRequested = false; + addJobChangeListener(new IJobChangeListener() { + @Override + public void sleeping(IJobChangeEvent event) { + } + @Override + public void scheduled(IJobChangeEvent event) { + } + @Override + public void running(IJobChangeEvent event) { + } + @Override + public void done(IJobChangeEvent event) { + cancelRequested = false; + } + @Override + public void awake(IJobChangeEvent event) { + } + @Override + public void aboutToRun(IJobChangeEvent event) { + } + }); } @Override protected void canceling() { - super.canceling(); - this.cancelRequested = true; + cancelRequested = true; + getThread().interrupt(); } /** - * This method will register a new listener with the parser - * @param listener The listener that will receive updateEvents + * Register a new listener with this parser. + * @param listener The listener that will receive an update event when this + * parser has completed its operation. */ public void addListener(IUpdateListener listener) { - if (null != listener) { + if (listener != null) { listeners.add(listener); } } /** - * This method will unregister the listener with the parser - * @param listener The listener that no longer wants to recieve update events + * Unregister the listener with this parser. + * @param listener The listener that no longer wants to recieve update events. */ public void removeListener(IUpdateListener listener) { - if (null != listener) { + if (listener != null) { listeners.remove(listener); } } @@ -94,7 +121,8 @@ public abstract class TapsetParser extends Job { } /** - * Runs the stap with the given options and returns the output generated + * Runs stap with the given options and returns the output generated, + * or <code>null</code> if the case of an error. * @param options String[] of any optional parameters to pass to stap * @param probe String containing the script to run stap on, * or <code>null</code> for scriptless commands @@ -105,14 +133,14 @@ public abstract class TapsetParser extends Job { String[] args = null; String[] tapsets = IDEPlugin.getDefault().getPreferenceStore() .getString(IDEPreferenceConstants.P_TAPSETS).split(File.pathSeparator); - boolean noTapsets = tapsets[0].trim().length() == 0; - boolean noOptions = options[0].trim().length() == 0; + boolean noTapsets = tapsets[0].trim().isEmpty(); + boolean noOptions = options[0].trim().isEmpty(); int size = probe != null ? 2 : 1; - if (tapsets.length > 0 && !noTapsets) { + if (!noTapsets) { size += tapsets.length<<1; } - if (options.length > 0 && !noOptions) { + if (!noOptions) { size += options.length; } @@ -123,13 +151,13 @@ public abstract class TapsetParser extends Job { } //Add extra tapset directories - if (tapsets.length > 0 && !noTapsets) { + if (!noTapsets) { for (int i = 0; i < tapsets.length; i++) { args[1 + 2*i] = "-I"; //$NON-NLS-1$ args[2 + 2*i] = tapsets[i]; } } - if (options.length > 0 && !noOptions) { + if (!noOptions) { for (int i = 0, s = noTapsets ? 1 : 1 + tapsets.length*2; i<options.length; i++) { args[s + i] = options[i]; } @@ -145,15 +173,16 @@ public abstract class TapsetParser extends Job { String host = p.getString(ConsoleLogPreferenceConstants.HOST_NAME); String password = p.getString(ConsoleLogPreferenceConstants.SCP_PASSWORD); - Channel channel = SystemtapProcessFactory.execRemoteAndWait(args,str, strErr, user, host, password); + Channel channel = SystemtapProcessFactory.execRemoteAndWait(args, str, strErr, user, host, password); if (channel == null) { displayError(Messages.TapsetParser_CannotRunStapTitle, Messages.TapsetParser_CannotRunStapMessage); } return (!getErrors ? str : strErr).toString(); } else { - Process process = RuntimeProcessFactory.getFactory().exec(args, null, null); - if(process == null){ + Process process = RuntimeProcessFactory.getFactory().exec( + args, EnvironmentVariablesPreferencePage.getEnvironmentVariables(), null); + if (process == null) { displayError(Messages.TapsetParser_CannotRunStapTitle, Messages.TapsetParser_CannotRunStapMessage); return null; } @@ -176,23 +205,25 @@ public abstract class TapsetParser extends Job { } } catch (JSchException|IOException e) { - ExceptionErrorDialog.openError(Messages.TapsetParser_ErrorRunningSystemtap, e); + displayError(Messages.TapsetParser_ErrorRunningSystemtap, e.getMessage()); } catch (InterruptedException e) { - // TODO Auto-generated catch block - e.printStackTrace(); + // Interrupted; exit. } return null; } private void displayError(final String title, final String error) { - Display.getDefault().asyncExec(new Runnable() { - @Override - public void run() { - IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); - MessageDialog.openWarning(window.getShell(), title, error); - } - }); + if (displayingError.compareAndSet(false, true)) { + Display.getDefault().asyncExec(new Runnable() { + @Override + public void run() { + IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); + MessageDialog.openWarning(window.getShell(), title, error); + displayingError.set(false); + } + }); + } } } diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/TreeSettings.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/TreeSettings.java index 6053ae9051..55d5561521 100644 --- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/TreeSettings.java +++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/TreeSettings.java @@ -12,12 +12,14 @@ package org.eclipse.linuxtools.internal.systemtap.ui.ide.structures; import java.io.File; -import java.io.FileNotFoundException; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.util.Calendar; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Path; +import org.eclipse.linuxtools.internal.systemtap.ui.ide.structures.nodedata.StapTreeDataFactory; import org.eclipse.linuxtools.systemtap.structures.TreeDefinitionNode; import org.eclipse.linuxtools.systemtap.structures.TreeNode; import org.eclipse.ui.IMemento; @@ -33,226 +35,218 @@ import org.eclipse.ui.XMLMemento; * @author Ryan Morse */ public final class TreeSettings { - private TreeSettings() { - } - /** - * Returns the modification date for the Tree File. Used to make sure that the cache is not out of - * date. - * @return The datestamp for the Tree file. - */ - public static long getTreeFileDate() { - if (!readData()) { - return -1; - } - return treeFileDate; - } + private static final String FILE_NAME = "TreeSettings"; //$NON-NLS-1$ + private static final String FILE_DIRECTORY = ".systemtapgui"; //$NON-NLS-1$ + + private static final String M_DISP = "display"; //$NON-NLS-1$ + private static final String M_DATA = "data"; //$NON-NLS-1$ + private static final String M_DATATYPE = "datatype"; //$NON-NLS-1$ + private static final String M_DEFINITON = "definition"; //$NON-NLS-1$ + private static final String M_CLICKABLE = "clickable"; //$NON-NLS-1$ + private static final String M_NULL = "<null>"; //$NON-NLS-1$ + private static final String M_ITEM = "item"; //$NON-NLS-1$ + + private static final String T_FUNCTIONS = "functionTree"; //$NON-NLS-1$ + private static final String T_PROBES = "probeTree"; //$NON-NLS-1$ + private static final String T_DATE = "modifiedDate"; //$NON-NLS-1$ + private static final String T_VERSION = "version"; //$NON-NLS-1$ + private static final String VERSION_NUMBER = "3.0"; //$NON-NLS-1$ + + private static TreeNode cachedFunctions; + private static TreeNode cachedProbes; + private static File settingsFile = null; - /** - * Allows access to the Tapset Function tree, which contains information about all - * functions stored in the tapset library. - * @return The <code>TreeNode</code> root of the Function tree. - * @since 2.0 - */ - public static TreeNode getFunctionTree() { - if (!readData()) { - return null; - } - return functions; - } + private TreeSettings() {} /** - * Allows access to the Tapset Probe Alias tree, which contains a list of all probe aliases - * in the tapset library. - * @return The <code>TreeNode</code> root of the Probe Alias tree. - * @since 2.0 + * Deletes the Function and Probe Alias trees that have been saved to the filesystem + * as an {@link IMemento}. + * @return <code>true</code> if the delete attempt succeeded, <code>false</code> otherwise. */ - public static TreeNode getProbeTree() { - if (!readData()) { - return null; + static boolean deleteTrees() { + boolean deleted; + try { + deleted = settingsFile.delete(); + } catch (SecurityException e) { + deleted = false; } - return probes; - } - - /** - * Sets the Probe Alias and Function trees that are being cached to the trees given as arguments. - * @param func The Function tree to store in cache. - * @param probe The Probe Alias tree to store in cache. - * @return True if the caching is successful. - * @since 2.0 - */ - public static boolean setTrees(TreeNode func, TreeNode probe) { - if (null == func || null == probe) { - return false; + if (deleted) { + clearCachedTrees(); } - functions = func; - probes = probe; - return writeData(); + return deleted; } /** - * Reads the contents of the cache file into memory. - * @return True if the read is successful. + * Saves the provided Function and Probe Alias trees into an {@link IMemento} on + * the filesystem. <p> + * Note: Both trees must be saved at the same time to better ensure that they + * are both obtained from the same tapset state. + * @param functions The Function tree to store in cache. + * @param probes The Probe Alias tree to store in cache. + * @return <code>true</code> if the caching is successful. */ - private static boolean readData() { - if (null == settingsFile && !openFile()) { + public static synchronized boolean setTrees(TreeNode functions, TreeNode probes) { + if (functions == null || probes == null || !isTreeFileAvailable()) { return false; } - try (FileReader reader = new FileReader(settingsFile)) { - if(!reader.ready()) { - reader.close(); - return false; - } - - XMLMemento data = XMLMemento.createReadRoot(reader, "TreeSettings"); //$NON-NLS-1$ - - IMemento child = data.getChild("functionTree"); //$NON-NLS-1$ - String s = child.getString("string"); //$NON-NLS-1$ - if ("<null>".equals(s)) { //$NON-NLS-1$ - s = null; - } - String d = child.getString("data"); //$NON-NLS-1$ - if ("<null>".equals(d)) { //$NON-NLS-1$ - d = null; - } + XMLMemento data = XMLMemento.createWriteRoot(FILE_NAME); + writeTree(data, T_FUNCTIONS, functions); + writeTree(data, T_PROBES, probes); - functions = new TreeNode(d, s, false); - readTree(child, functions, 0); + data.createChild(T_DATE) + .putTextData((Long.valueOf(Calendar.getInstance().getTimeInMillis())).toString()); - child = data.getChild("probeTree"); //$NON-NLS-1$ - s = child.getString("string"); //$NON-NLS-1$ - if ("<null>".equals(s)) { //$NON-NLS-1$ - s = null; - } - d = child.getString("data"); //$NON-NLS-1$ - if ("<null>".equals(d)) { //$NON-NLS-1$ - d = null; - } - probes = new TreeNode(d, s, false); - readTree(child, probes, 0); + data.createChild(T_VERSION).putTextData(VERSION_NUMBER); - child = data.getChild("modifiedDate"); //$NON-NLS-1$ - treeFileDate = Long.parseLong(child.getString("date")); //$NON-NLS-1$ - } catch(IOException|WorkbenchException fnfe) { + try (FileWriter writer = new FileWriter(settingsFile)) { + data.save(writer); + } catch (IOException e) { return false; } + clearCachedTrees(); return true; } /** - * Writes the tree data currently stored by this class to disk for later access. - * @return True if the write is successful. + * Writes the tree passed in to the {@link IMemento} argument. + * @param data The {@link IMemento} to store the tree to. + * @param name The name to give to the <code>parent</code> node. + * @param tree The {@link TreeNode} to store. */ - private static boolean writeData() { - if (null == settingsFile && !openFile()) { - return false; + private static void writeTree(IMemento data, String name, TreeNode tree) { + IMemento child = data.createChild(name); + child.putString(M_DISP, tree.toString()); + Object treeData = tree.getData(); + if (treeData != null) { + child.putString(M_DATA, treeData.toString()); + child.putString(M_DATATYPE, StapTreeDataFactory.getDataObjectID(treeData)); } - - try { - XMLMemento data = XMLMemento.createWriteRoot("TreeSettings"); //$NON-NLS-1$ - - IMemento child = data.createChild("functionTree"); //$NON-NLS-1$ - writeTree(child, functions, 0); - - child = data.createChild("probeTree"); //$NON-NLS-1$ - writeTree(child, probes, 0); - - child = data.createChild("modifiedDate"); //$NON-NLS-1$ - child.putString("date", (Long.valueOf(Calendar.getInstance().getTimeInMillis())).toString()); //$NON-NLS-1$ - - FileWriter writer = new FileWriter(settingsFile); - data.save(writer); - } catch(FileNotFoundException fnfe) { - return false; - } catch(IOException e) { - return false; + if (tree instanceof TreeDefinitionNode) { + child.putString(M_DEFINITON, + getStringFromValue(((TreeDefinitionNode) tree).getDefinition())); + } + child.putBoolean(M_CLICKABLE, tree.isClickable()); + for (int i = 0, n = tree.getChildCount(); i < n; i++) { + writeTree(child, M_ITEM, tree.getChildAt(i)); } + } - return true; + private static void clearCachedTrees() { + if (cachedFunctions != null) { + cachedFunctions.dispose(); + cachedFunctions = null; + } + if (cachedProbes != null) { + cachedProbes.dispose(); + cachedProbes = null; + } } /** - * Writes the tree passed in to the <code>IMemento</code> argument, up to the specified depth. - * @param child The <code>IMemento</code> to store the tree to. - * @param tree The <code>TreeNode</code> to store. - * @param depth The maximum depth level to write out. + * Allows access to the Tapset Function tree, which contains information about all + * functions stored in the tapset library. + * @return The {@link TreeNode} root of the Function tree. + * @since 2.0 */ - private static void writeTree(IMemento child, TreeNode tree, int depth) { - if (null == tree.toString()) { - child.putString("string", "<null>"); //$NON-NLS-1$ //$NON-NLS-2$ - } else { - child.putString("string", tree.toString()); //$NON-NLS-1$ + public static synchronized TreeNode getFunctionTree() { + if (cachedFunctions == null) { + cachedFunctions = readData(T_FUNCTIONS); } + return cachedFunctions; + } - if (null == tree.getData()) { - child.putString("data", "<null>"); //$NON-NLS-1$ //$NON-NLS-2$ - } else { - child.putString("data", tree.getData().toString()); //$NON-NLS-1$ + /** + * Allows access to the Tapset Probe Alias tree, which contains a list of all probe aliases + * in the tapset library. + * @return The {@link TreeNode} root of the Probe Alias tree. + * @since 2.0 + */ + public synchronized static TreeNode getProbeTree() { + if (cachedProbes == null) { + cachedProbes = readData(T_PROBES); } + return cachedProbes; + } - if (tree instanceof TreeDefinitionNode) { - if (null == ((TreeDefinitionNode) tree).getDefinition()) { - child.putString("definition", "<null>"); //$NON-NLS-1$ //$NON-NLS-2$ - } else { - child.putString( - "definition", ((TreeDefinitionNode) tree).getDefinition()); //$NON-NLS-1$ - } + /** + * Reads the contents of the cached memento to recreate the stored trees. + * @return True if the read is successful. + */ + private static TreeNode readData(String section) { + IMemento data = getTreeFileMemento(); + if (data == null) { + return null; } + return readTree(data.getChild(section)); + } - child.putInteger("click", (tree.isClickable()?1:0)); //$NON-NLS-1$ - for(int i=0; i<tree.getChildCount(); i++) { - writeTree(child.createChild("level" + depth), tree.getChildAt(i), depth+1); //$NON-NLS-1$ + /** + * Opposite action as writeTree. Reconstruct a tree from a previously-saved {@link IMemento}. + * @param data The {@link IMemento} to read the tree out of. + * @return The reconstructed {@link TreeNode}. + */ + private static TreeNode readTree(IMemento data) { + String disp = data.getString(M_DISP); + String def = data.getString(M_DEFINITON); + boolean c = data.getBoolean(M_CLICKABLE); + Object d = StapTreeDataFactory.createObjectFromString(data.getString(M_DATA), data.getString(M_DATATYPE)); + + TreeNode parent; + if (def == null) { + parent = new TreeNode(d, disp, c); + } else { + parent = new TreeDefinitionNode(d, disp, getValueFromString(def), c); + } + for (IMemento child : data.getChildren()) { + parent.add(readTree(child)); } + return parent; } /** - * Opposite action as writeTree. Reads the <code>IMemento</code> passed in into the <code>TreeNode</code> - * up to the requested maximum depth. - * @param data The <code>IMemento</code> to read the tree out of. - * @param parent The <code>TreeNode</code> to store the tree in. - * @param depth The maximum depth to read. + * Returns the modification date for the tree file. + * Use this to make sure that the cache is not out of date. + * @return The datestamp for the Tree file. */ - private static void readTree(IMemento data, TreeNode parent, int depth) { - IMemento[] children = data.getChildren("level" + depth); //$NON-NLS-1$ + public synchronized static long getTreeFileDate() { + IMemento data = getTreeFileMemento(); + if (data != null) { + IMemento child = data.getChild(T_DATE); + try { + return Long.parseLong(child.getTextData()); + } catch (NumberFormatException e) {} + } + return -1; + } - try { - if(null != children) { - for(int i=0; i<children.length; i++) { - String s = children[i].getString("string"); //$NON-NLS-1$ - String d = children[i].getString("data"); //$NON-NLS-1$ - String def = children[i].getString("definition"); //$NON-NLS-1$ - - boolean c = ((0==children[i].getInteger("click").intValue())?false:true); //$NON-NLS-1$ - - if ("<null>".equals(s)) { //$NON-NLS-1$ - s = null; - } - if ("<null>".equals(d)) { //$NON-NLS-1$ - d = null; - } - - TreeNode t; - if(null == def) { - t = new TreeNode(d, s, c); - } else { - if ("<null>".equals(def)) { //$NON-NLS-1$ - def = null; - } - - t = new TreeDefinitionNode(d, s, def, c); - } - parent.add(t); - - readTree(children[i], t, depth+1); - } + private static IMemento getTreeFileMemento() { + if (!isTreeFileAvailable()) { + return null; + } + + try (FileReader reader = new FileReader(settingsFile)) { + IMemento data = XMLMemento.createReadRoot(reader, FILE_NAME); + IMemento versionChild = data.getChild(T_VERSION); + if (versionChild != null && versionChild.getTextData().equals(VERSION_NUMBER)) { + return data; } - } catch(NullPointerException e) { + return null; + } catch (IOException | WorkbenchException fnfe) { + return null; } } - private static boolean openFile() { - settingsFile = new File(System.getenv("HOME") + "/.systemtapgui/" + fileName); //$NON-NLS-1$ //$NON-NLS-2$ + private static boolean isTreeFileAvailable() { + if (settingsFile != null) { + return true; + } + + IPath path = new Path(System.getenv("HOME")). //$NON-NLS-1$ + append(FILE_DIRECTORY).append(FILE_NAME). + addFileExtension("xml"); //$NON-NLS-1$ + settingsFile = path.toFile(); try { if (!settingsFile.exists()){ @@ -261,16 +255,18 @@ public final class TreeSettings { settingsFile.getParentFile().mkdirs(); settingsFile.createNewFile(); } - } catch(IOException ioe) { + } catch (IOException ioe) { return false; } return true; } - private static long treeFileDate; - private static TreeNode functions; - private static TreeNode probes; - private static final String fileName = "/TreeSettings.xml"; //$NON-NLS-1$ - private static File settingsFile = null; + private static String getStringFromValue(String val) { + return val == null ? M_NULL : val; + } + + private static String getValueFromString(String string) { + return M_NULL.equals(string) ? null : string; + } } diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/TreeTapsetParser.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/TreeTapsetParser.java new file mode 100644 index 0000000000..e0b0ebd806 --- /dev/null +++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/TreeTapsetParser.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright (c) 2014 Red Hat, Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Red Hat - initial API and implementation + *******************************************************************************/ + +package org.eclipse.linuxtools.internal.systemtap.ui.ide.structures; + +import org.eclipse.linuxtools.systemtap.structures.TreeNode; + +/** + * A base abstract class to be used for extensions of {@link TapsetParser} + * that construct a displayable {@link TreeNode}. + */ +public abstract class TreeTapsetParser extends TapsetParser { + + protected TreeTapsetParser(String jobTitle) { + super(jobTitle); + } + + /** + * @return The tree that this parser constructs. + */ + abstract TreeNode getTree(); + + /** + * Clean up everything from the last parse run. + */ + abstract void dispose(); + +} diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/messages.properties b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/messages.properties index f7b7d419bd..1b53522a4b 100644 --- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/messages.properties +++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/messages.properties @@ -15,3 +15,4 @@ ProbeParser_aliasProbes=Probe Aliases TapsetParser_CannotRunStapMessage=Make sure SystemTap is installed. TapsetParser_CannotRunStapTitle=Cannot Run SystemTap TapsetParser_ErrorRunningSystemtap=Error Running SystemTap +SharedParser_NoOutput=No stap output was generated
\ No newline at end of file diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/FuncparamNodeData.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/nodedata/FuncparamNodeData.java index 7fbdc33638..bea31c0fdb 100644 --- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/FuncparamNodeData.java +++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/nodedata/FuncparamNodeData.java @@ -8,20 +8,23 @@ * Contributors: * Red Hat - initial API and implementation *******************************************************************************/ -package org.eclipse.linuxtools.internal.systemtap.ui.ide.structures; +package org.eclipse.linuxtools.internal.systemtap.ui.ide.structures.nodedata; + +import org.eclipse.linuxtools.internal.systemtap.ui.ide.structures.FunctionParser; +import org.eclipse.linuxtools.systemtap.structures.TreeNode; + /** * A structure for containing extra information of SystemTap function parameters. * @since 3.0 */ public class FuncparamNodeData implements ISingleTypedNode { - - private final String line; + static final String ID = "FuncparamNodeData"; //$NON-NLS-1$ private final String type; @Override public String toString() { - return line; + return getType(); } @Override @@ -31,12 +34,11 @@ public class FuncparamNodeData implements ISingleTypedNode { /** * Create a new instance of function parameter information. (Note that the name of a function - * or parameter is stored in a {@link org.eclipse.linuxtools.systemtap.structures.TreeNode}, not here.) - * @param line The <code>String</code> representation of the entire parameter. - * @param type The <code>String</code> representation of only the parameter's type. + * or parameter is stored in a {@link TreeNode}, not here.) + * @param type The <code>String</code> representation of the parameter's type. + * Pass <code>null</code> if the type is unknown. */ - public FuncparamNodeData(String line, String type) { - this.line = line; + public FuncparamNodeData(String type) { this.type = type == null ? FunctionParser.UNKNOWN_TYPE : type; // Parameters can't be void. } } diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/FunctionNodeData.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/nodedata/FunctionNodeData.java index 4ad3f85c9d..31e8e437ad 100644 --- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/FunctionNodeData.java +++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/nodedata/FunctionNodeData.java @@ -8,16 +8,20 @@ * Contributors: * Red Hat - Initial API and implementation *******************************************************************************/ -package org.eclipse.linuxtools.internal.systemtap.ui.ide.structures; +package org.eclipse.linuxtools.internal.systemtap.ui.ide.structures.nodedata; /** * A structure for containing extra information of SystemTap functions. * @since 3.0 */ public class FunctionNodeData implements ISearchableNode, ISingleTypedNode { + static final String ID = "FunctionNodeData"; //$NON-NLS-1$ + private final static String SPLIT = " - "; //$NON-NLS-1$ + private final static String VOID = "void"; //$NON-NLS-1$ private final String line; private final String type; + @Override public boolean isRegexSearch() { return false; @@ -33,7 +37,7 @@ public class FunctionNodeData implements ISearchableNode, ISingleTypedNode { @Override public String toString() { - return getSearchToken(); + return line + SPLIT + (type != null ? type : VOID); } /** @@ -47,12 +51,20 @@ public class FunctionNodeData implements ISearchableNode, ISingleTypedNode { /** * Create a new instance of function node information. (Note that the name of a function - * or parameter is stored in a {@link org.eclipse.linuxtools.systemtap.structures.TreeNode}, not here.) - * @param line Set this to the original script text that defines this function. - * @param type The <code>String</code> representation of the return type of the function. + * or parameter is stored in a {@link TreeNode}, not here.) + * @param line The original script text that defines this function. + * @param type The <code>String</code> representation of the return type of the function + * (<code>null</code> for void). */ public FunctionNodeData(String line, String type) { this.line = line; this.type = type; } + + public FunctionNodeData(String fromString) { + int splitPoint = fromString.lastIndexOf(SPLIT); + this.line = fromString.substring(0, splitPoint); + String type = fromString.substring(splitPoint + SPLIT.length()); + this.type = !type.equals(VOID) ? type : null; + } } diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/ISearchableNode.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/nodedata/IMultiTypedNode.java index e207e1e58a..94875344c8 100644 --- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/ISearchableNode.java +++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/nodedata/IMultiTypedNode.java @@ -9,9 +9,16 @@ * Red Hat - initial API and implementation *******************************************************************************/ -package org.eclipse.linuxtools.internal.systemtap.ui.ide.structures; +package org.eclipse.linuxtools.internal.systemtap.ui.ide.structures.nodedata; -public interface ISearchableNode { - String getSearchToken(); - boolean isRegexSearch(); +import java.util.List; + +/** + * An interface for a data object associated with a list of data types. + */ +public interface IMultiTypedNode { + /** + * @return A list of the names of all of this object's associated data types. + */ + List<String> getTypes(); } diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/nodedata/ISearchableNode.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/nodedata/ISearchableNode.java new file mode 100644 index 0000000000..9569423497 --- /dev/null +++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/nodedata/ISearchableNode.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright (c) 2014 Red Hat, Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Red Hat - initial API and implementation + *******************************************************************************/ + +package org.eclipse.linuxtools.internal.systemtap.ui.ide.structures.nodedata; + +/** + * An interface for a data object that stores a <code>String</code> token + * that should be searched for in a text file. + */ +public interface ISearchableNode { + /** + * @return The token to search a text file for. + */ + String getSearchToken(); + + /** + * @return <code>true</code> if {@link #getSearchToken()} is a regular expression, + * or <code>false</code> if it is a plain-text search token. + */ + boolean isRegexSearch(); +} diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/ISingleTypedNode.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/nodedata/ISingleTypedNode.java index 94d5f7b161..c14175e4ad 100644 --- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/ISingleTypedNode.java +++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/nodedata/ISingleTypedNode.java @@ -9,8 +9,14 @@ * Red Hat - initial API and implementation *******************************************************************************/ -package org.eclipse.linuxtools.internal.systemtap.ui.ide.structures; +package org.eclipse.linuxtools.internal.systemtap.ui.ide.structures.nodedata; +/** + * An interface for a data object that can associate itself with a data type. + */ public interface ISingleTypedNode { + /** + * @return The name of this object's associated data type. + */ String getType(); } diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/ProbeNodeData.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/nodedata/ProbeNodeData.java index d5b63e18b9..7f8a20a6b7 100644 --- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/ProbeNodeData.java +++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/nodedata/ProbeNodeData.java @@ -9,13 +9,16 @@ * Red Hat - initial API and implementation *******************************************************************************/ -package org.eclipse.linuxtools.internal.systemtap.ui.ide.structures; +package org.eclipse.linuxtools.internal.systemtap.ui.ide.structures.nodedata; import java.text.MessageFormat; -public class ProbeNodeData implements ISearchableNode { +import org.eclipse.linuxtools.internal.systemtap.ui.ide.structures.ProbeParser; +public class ProbeNodeData implements ISearchableNode { + static final String ID = "ProbeNodeData"; //$NON-NLS-1$ private final String name; + private final String line; @Override public boolean isRegexSearch() { @@ -32,7 +35,7 @@ public class ProbeNodeData implements ISearchableNode { @Override public String toString() { - return getSearchToken(); + return line; } /** @@ -43,7 +46,8 @@ public class ProbeNodeData implements ISearchableNode { */ public ProbeNodeData(String line) { int spaceIndex = line.indexOf(' '); - name = (spaceIndex != -1 ? line.substring(0, spaceIndex) : line).trim(); + this.line = line; + this.name = (spaceIndex != -1 ? line.substring(0, spaceIndex) : line).trim(); } } diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/ProbevarNodeData.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/nodedata/ProbevarNodeData.java index bcb0208ead..f54176c839 100644 --- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/ProbevarNodeData.java +++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/nodedata/ProbevarNodeData.java @@ -9,7 +9,7 @@ * Red Hat - initial API and implementation *******************************************************************************/ -package org.eclipse.linuxtools.internal.systemtap.ui.ide.structures; +package org.eclipse.linuxtools.internal.systemtap.ui.ide.structures.nodedata; import java.util.Arrays; import java.util.Collections; @@ -19,9 +19,9 @@ import java.util.List; * A structure for containing extra information of SystemTap probe variables. * @since 3.0 */ -public class ProbevarNodeData { +public class ProbevarNodeData implements IMultiTypedNode { + static final String ID = "ProbevarNodeData"; //$NON-NLS-1$ private String text; - private String name; private List<String> types; /** @@ -34,32 +34,24 @@ public class ProbevarNodeData { } /** - * @return The name of the variable. - */ - public String getName() { - return name; - } - - /** * @return A list of all tokens used to describe the variable's type. */ + @Override public List<String> getTypes() { return types; } /** * Create a new instance of probe variable node information. - * @param line A line of text generated by running "stap -L" which - * provides all information pertaining to a probe point. + * @param info A <code>String</code> formatted as "(name):(type)", which provides + * all information pertaining to the probe variable. */ - public ProbevarNodeData(String line) { - text = line.trim(); + public ProbevarNodeData(String info) { + text = info.trim(); int colonIndex = text.indexOf(':'); if (colonIndex == -1) { - name = text; types = Collections.emptyList(); } else { - name = line.substring(0, colonIndex); types = Arrays.asList(text.substring(colonIndex+1).split(" ")); //$NON-NLS-1$ } } diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/nodedata/StapTreeDataFactory.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/nodedata/StapTreeDataFactory.java new file mode 100644 index 0000000000..426b484af5 --- /dev/null +++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/nodedata/StapTreeDataFactory.java @@ -0,0 +1,56 @@ +/******************************************************************************* + * Copyright (c) 2014 Red Hat, Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Red Hat - initial API and implementation + *******************************************************************************/ + +package org.eclipse.linuxtools.internal.systemtap.ui.ide.structures.nodedata; + + +public class StapTreeDataFactory { + public final static String NON_NODE_ID = "Object"; //$NON-NLS-1$ + + public static String getDataObjectID(Object dataObject) { + if (dataObject == null) { + return null; + } + if (dataObject instanceof ProbeNodeData) { + return ProbeNodeData.ID; + } + if (dataObject instanceof ProbevarNodeData) { + return ProbevarNodeData.ID; + } + if (dataObject instanceof FunctionNodeData) { + return FunctionNodeData.ID; + } + if (dataObject instanceof FuncparamNodeData) { + return FuncparamNodeData.ID; + } + return NON_NODE_ID; + } + + public static Object createObjectFromString(String stringOf, String objectID) { + if (stringOf == null || objectID == null) { + return null; + } + if (objectID.equals(ProbeNodeData.ID)) { + return new ProbeNodeData(stringOf); + } + if (objectID.equals(ProbevarNodeData.ID)) { + return new ProbevarNodeData(stringOf); + } + if (objectID.equals(FunctionNodeData.ID)) { + return new FunctionNodeData(stringOf); + } + if (objectID.equals(FuncparamNodeData.ID)) { + return new FuncparamNodeData(stringOf); + } + return stringOf; + } + +} diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/views/BrowserView.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/views/BrowserView.java index dca0101c54..3890fc7248 100644 --- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/views/BrowserView.java +++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/views/BrowserView.java @@ -17,7 +17,7 @@ import org.eclipse.jface.viewers.ITreeContentProvider; import org.eclipse.jface.viewers.LabelProvider; import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.jface.viewers.Viewer; -import org.eclipse.linuxtools.internal.systemtap.ui.ide.IDEPlugin; +import org.eclipse.linuxtools.internal.systemtap.ui.ide.actions.BrowserViewAction; import org.eclipse.linuxtools.systemtap.structures.TreeNode; import org.eclipse.linuxtools.systemtap.structures.listeners.IUpdateListener; import org.eclipse.swt.SWT; @@ -25,10 +25,8 @@ import org.eclipse.swt.graphics.Image; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Menu; -import org.eclipse.ui.ISharedImages; import org.eclipse.ui.IWorkbenchActionConstants; import org.eclipse.ui.IWorkbenchPartSite; -import org.eclipse.ui.PlatformUI; import org.eclipse.ui.dialogs.FilteredTree; import org.eclipse.ui.dialogs.PatternFilter; import org.eclipse.ui.handlers.CollapseAllHandler; @@ -47,6 +45,8 @@ import org.eclipse.ui.part.ViewPart; */ public abstract class BrowserView extends ViewPart { protected TreeViewer viewer; + protected TreeNode tree; + protected BrowserViewAction doubleClickAction; private CollapseAllHandler collapseHandler; @@ -97,14 +97,6 @@ public abstract class BrowserView extends ViewPart { protected abstract Image getEntryImage(TreeNode treeObj); - protected Image getGenericImage(TreeNode treeObj) { - if (treeObj.getChildCount() == 0) { - return IDEPlugin.getImageDescriptor("icons/vars/var_unk.gif").createImage(); //$NON-NLS-1$ - } else { - return PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJ_FOLDER); - } - } - /** * Provides the icon and text for each entry in the tapset tree. * @author Ryan Morse @@ -158,23 +150,39 @@ public abstract class BrowserView extends ViewPart { @Override public void dispose() { super.dispose(); - viewer = null; - if(collapseHandler != null) { + if (collapseHandler != null) { collapseHandler.dispose(); + collapseHandler = null; + } + if (tree != null) { + tree.dispose(); + tree = null; + } + if (viewer != null) { + if (doubleClickAction != null) { + viewer.removeDoubleClickListener(doubleClickAction); + } + viewer = null; + } + if (doubleClickAction != null) { + doubleClickAction.dispose(); + doubleClickAction = null; } } abstract void refresh(); - protected class ViewUpdater implements IUpdateListener { + protected IUpdateListener viewUpdater = new IUpdateListener() { @Override public void handleUpdateEvent() { - viewer.getControl().getDisplay().asyncExec(new Runnable() { - @Override - public void run() { - refresh(); - } - }); + if (viewer != null) { + viewer.getControl().getDisplay().asyncExec(new Runnable() { + @Override + public void run() { + refresh(); + } + }); + } } - } -}
\ No newline at end of file + }; +} diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/views/FunctionBrowserView.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/views/FunctionBrowserView.java index fd7722247a..e6c646b38d 100644 --- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/views/FunctionBrowserView.java +++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/views/FunctionBrowserView.java @@ -13,8 +13,9 @@ package org.eclipse.linuxtools.internal.systemtap.ui.ide.views; import org.eclipse.linuxtools.internal.systemtap.ui.ide.IDEPlugin; import org.eclipse.linuxtools.internal.systemtap.ui.ide.actions.FunctionBrowserAction; -import org.eclipse.linuxtools.internal.systemtap.ui.ide.structures.ISingleTypedNode; +import org.eclipse.linuxtools.internal.systemtap.ui.ide.structures.FunctionParser; import org.eclipse.linuxtools.internal.systemtap.ui.ide.structures.TapsetLibrary; +import org.eclipse.linuxtools.internal.systemtap.ui.ide.structures.nodedata.ISingleTypedNode; import org.eclipse.linuxtools.systemtap.structures.TreeNode; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.widgets.Composite; @@ -29,9 +30,6 @@ import org.eclipse.swt.widgets.Composite; */ public class FunctionBrowserView extends BrowserView { public static final String ID = "org.eclipse.linuxtools.internal.systemtap.ui.ide.views.FunctionBrowserView"; //$NON-NLS-1$ - private FunctionBrowserAction doubleClickAction; - private TreeNode functions; - private TreeNode localFunctions; /** * Creates the UI on the given <code>Composite</code> @@ -39,8 +37,7 @@ public class FunctionBrowserView extends BrowserView { @Override public void createPartControl(Composite parent) { super.createPartControl(parent); - TapsetLibrary.init(); - TapsetLibrary.addFunctionListener(new ViewUpdater()); + FunctionParser.getInstance().addListener(viewUpdater); refresh(); makeActions(); } @@ -67,34 +64,13 @@ public class FunctionBrowserView extends BrowserView { */ @Override public void refresh() { - functions = TapsetLibrary.getFunctions(); - if (functions != null){ - addLocalFunctions(localFunctions); + tree = TapsetLibrary.getFunctions(); + if (tree != null) { + viewer.setInput(tree); } } /** - * Adds the local functions specified in the argument to the viewer. - * @param localFunctionTree A tree of the local functions. - */ - public void addLocalFunctions(TreeNode localFunctionTree) { - if(functions.getChildCount() > 0) { - TreeNode localFuncs = functions.getChildAt(0); - - if("<local>".equals(localFuncs.toString())) { //$NON-NLS-1$ - functions.remove(0); - } - - if(null != localFunctions) { - localFunctions = localFunctionTree; - localFunctions.setDisplay("<local>"); //$NON-NLS-1$ - functions.addAt(localFunctions, 0); - } - } - viewer.setInput(functions); - } - - /** * Wires up all of the actions for this browser, such as double and right click handlers. */ private void makeActions() { @@ -106,21 +82,7 @@ public class FunctionBrowserView extends BrowserView { @Override public void dispose() { super.dispose(); - if(null != viewer) { - viewer.removeDoubleClickListener(doubleClickAction); - } - if(null != doubleClickAction) { - doubleClickAction.dispose(); - } - doubleClickAction = null; - if(null != localFunctions) { - localFunctions.dispose(); - } - localFunctions = null; - if(null != functions) { - functions.dispose(); - } - functions = null; - TapsetLibrary.stop(); + FunctionParser.getInstance().removeListener(viewUpdater); } + } diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/views/KernelBrowserView.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/views/KernelBrowserView.java index 5e191fdf9a..12be1d8025 100644 --- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/views/KernelBrowserView.java +++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/views/KernelBrowserView.java @@ -36,6 +36,8 @@ import org.eclipse.linuxtools.systemtap.structures.KernelSourceTree; import org.eclipse.linuxtools.systemtap.structures.TreeNode; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.widgets.Composite; +import org.eclipse.ui.ISharedImages; +import org.eclipse.ui.PlatformUI; import org.eclipse.ui.progress.UIJob; /** @@ -46,6 +48,8 @@ import org.eclipse.ui.progress.UIJob; */ public class KernelBrowserView extends BrowserView { + public static final String ID = "org.eclipse.linuxtools.internal.systemtap.ui.ide.views.KernelBrowserView"; //$NON-NLS-1$ + private class KernelRefreshJob extends Job { private boolean remote; private URI kernelLocationURI; @@ -97,16 +101,14 @@ public class KernelBrowserView extends BrowserView { if (kst == null) { return Status.OK_STATUS; } - viewer.setInput(kst.getTree()); + tree = kst.getTree(); + viewer.setInput(tree); kst.dispose(); monitor.done(); return Status.OK_STATUS; } } - public static final String ID = "org.eclipse.linuxtools.internal.systemtap.ui.ide.views.KernelBrowserView"; //$NON-NLS-1$ - private KernelSourceAction doubleClickAction; - /** * Creates the UI on the given <code>Composite</code> */ @@ -128,14 +130,17 @@ public class KernelBrowserView extends BrowserView { @Override protected Image getEntryImage(TreeNode treeObj) { - String item = treeObj.getData().toString(); - if(item.endsWith(".c")) { //$NON-NLS-1$ - return IDEPlugin.getImageDescriptor("icons/files/file_c.gif").createImage(); //$NON-NLS-1$ - } - if(item.endsWith(".h")) { //$NON-NLS-1$ - return IDEPlugin.getImageDescriptor("icons/files/file_h.gif").createImage(); //$NON-NLS-1$ + if (treeObj.toString().lastIndexOf('.') != -1) { + String item = treeObj.getData().toString(); + if (item.endsWith(".c")) { //$NON-NLS-1$ + return IDEPlugin.getImageDescriptor("icons/files/file_c.gif").createImage(); //$NON-NLS-1$ + } + if (item.endsWith(".h")) { //$NON-NLS-1$ + return IDEPlugin.getImageDescriptor("icons/files/file_h.gif").createImage(); //$NON-NLS-1$ + } + return IDEPlugin.getImageDescriptor("icons/vars/var_unk.gif").createImage(); //$NON-NLS-1$ } - return getGenericImage(treeObj); + return PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJ_FOLDER); } /** @@ -147,7 +152,7 @@ public class KernelBrowserView extends BrowserView { public void refresh() { IPreferenceStore p = IDEPlugin.getDefault().getPreferenceStore(); String kernelSource = p.getString(IDEPreferenceConstants.P_KERNEL_SOURCE); - if(null == kernelSource || kernelSource.length() < 1) { + if (kernelSource == null || kernelSource.length() < 1) { showBrowserErrorMessage(Localization.getString("KernelBrowserView.NoKernelSourceFound")); //$NON-NLS-1$ return; } @@ -202,9 +207,9 @@ public class KernelBrowserView extends BrowserView { } private void showBrowserErrorMessage(String message) { - TreeNode t = new TreeNode("", "", false); //$NON-NLS-1$ //$NON-NLS-2$ - t.add(new TreeNode("", message, false)); //$NON-NLS-1$ - viewer.setInput(t); + tree = new TreeNode("", "", false); //$NON-NLS-1$ //$NON-NLS-2$ + tree.add(new TreeNode("", message, false)); //$NON-NLS-1$ + viewer.setInput(tree); } /** @@ -214,24 +219,17 @@ public class KernelBrowserView extends BrowserView { private final IPropertyChangeListener propertyChangeListener = new IPropertyChangeListener() { @Override public void propertyChange(PropertyChangeEvent event) { - if(event.getProperty().equals(IDEPreferenceConstants.P_KERNEL_SOURCE) || + if (event.getProperty().equals(IDEPreferenceConstants.P_KERNEL_SOURCE) || event.getProperty().equals(IDEPreferenceConstants.P_REMOTE_LOCAL_KERNEL_SOURCE) || event.getProperty().equals(IDEPreferenceConstants.P_EXCLUDED_KERNEL_SOURCE)) { - refresh(); + viewUpdater.handleUpdateEvent(); } } }; @Override public void dispose() { - super.dispose(); IDEPlugin.getDefault().getPreferenceStore().removePropertyChangeListener(propertyChangeListener); - if(null != viewer) { - viewer.removeDoubleClickListener(doubleClickAction); - } - if(null != doubleClickAction) { - doubleClickAction.dispose(); - } - doubleClickAction = null; + super.dispose(); } } diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/views/ProbeAliasBrowserView.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/views/ProbeAliasBrowserView.java index fe8e358255..47f06df11c 100644 --- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/views/ProbeAliasBrowserView.java +++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/views/ProbeAliasBrowserView.java @@ -15,12 +15,15 @@ import java.util.List; import org.eclipse.linuxtools.internal.systemtap.ui.ide.IDEPlugin; import org.eclipse.linuxtools.internal.systemtap.ui.ide.actions.ProbeAliasAction; -import org.eclipse.linuxtools.internal.systemtap.ui.ide.structures.ProbeNodeData; -import org.eclipse.linuxtools.internal.systemtap.ui.ide.structures.ProbevarNodeData; +import org.eclipse.linuxtools.internal.systemtap.ui.ide.structures.ProbeParser; import org.eclipse.linuxtools.internal.systemtap.ui.ide.structures.TapsetLibrary; +import org.eclipse.linuxtools.internal.systemtap.ui.ide.structures.nodedata.ProbeNodeData; +import org.eclipse.linuxtools.internal.systemtap.ui.ide.structures.nodedata.ProbevarNodeData; import org.eclipse.linuxtools.systemtap.structures.TreeNode; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.widgets.Composite; +import org.eclipse.ui.ISharedImages; +import org.eclipse.ui.PlatformUI; /** @@ -32,7 +35,6 @@ import org.eclipse.swt.widgets.Composite; */ public class ProbeAliasBrowserView extends BrowserView { public static final String ID = "org.eclipse.linuxtools.internal.systemtap.ui.ide.views.ProbeAliasBrowserView"; //$NON-NLS-1$ - private ProbeAliasAction doubleClickAction; /** * Creates the UI on the given <code>Composite</code> @@ -40,8 +42,7 @@ public class ProbeAliasBrowserView extends BrowserView { @Override public void createPartControl(Composite parent) { super.createPartControl(parent); - TapsetLibrary.init(); - TapsetLibrary.addProbeListener(new ViewUpdater()); + ProbeParser.getInstance().addListener(viewUpdater); refresh(); makeActions(); } @@ -71,7 +72,7 @@ public class ProbeAliasBrowserView extends BrowserView { if (treeObj.getData() instanceof ProbeNodeData) { return IDEPlugin.getImageDescriptor("icons/misc/probe_obj.gif").createImage(); //$NON-NLS-1$ } - return getGenericImage(treeObj); + return PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJ_FOLDER); } /** @@ -79,9 +80,9 @@ public class ProbeAliasBrowserView extends BrowserView { */ @Override public void refresh() { - TreeNode probes = TapsetLibrary.getProbes(); - if (probes != null){ - super.viewer.setInput(probes); + tree = TapsetLibrary.getProbes(); + if (tree != null) { + viewer.setInput(tree); } } @@ -97,12 +98,7 @@ public class ProbeAliasBrowserView extends BrowserView { @Override public void dispose() { super.dispose(); - if (null != viewer) { - viewer.removeDoubleClickListener(doubleClickAction); - } - if (null != doubleClickAction) { - doubleClickAction.dispose(); - } - doubleClickAction = null; + ProbeParser.getInstance().removeListener(viewUpdater); } + } |