diff options
author | Daniel Rolka | 2013-08-14 13:24:48 +0000 |
---|---|---|
committer | Gerrit Code Review @ Eclipse.org | 2013-08-14 15:05:59 +0000 |
commit | 0b5f24fa4c7134bf901e387289303c75678784ca (patch) | |
tree | c2b217fc35cdd919df8a7c4e2f898faf81341788 | |
parent | dcf95dc4cde7496c927bb5842d9e76065c573fe5 (diff) | |
download | org.eclipse.e4.tools-0b5f24fa4c7134bf901e387289303c75678784ca.tar.gz org.eclipse.e4.tools-0b5f24fa4c7134bf901e387289303c75678784ca.tar.xz org.eclipse.e4.tools-0b5f24fa4c7134bf901e387289303c75678784ca.zip |
Bug 414853 - [tools] Create tool for monitoring e4 events
Signed-off-by: Daniel Rolka <daniel.rolka@pl.ibm.com>
38 files changed, 2213 insertions, 1 deletions
diff --git a/build/org.eclipse.e4.core.tools.update/category.xml b/build/org.eclipse.e4.core.tools.update/category.xml index 59f94280..e98a904c 100644 --- a/build/org.eclipse.e4.core.tools.update/category.xml +++ b/build/org.eclipse.e4.core.tools.update/category.xml @@ -21,12 +21,19 @@ <feature url="features/org.eclipse.e4.tools.e3x.bridge.feature_0.14.0.qualifier.jar" id="org.eclipse.e4.tools.e3x.bridge.feature" version="0.14.0.qualifier"> <category name="org.eclipse.e4.tools.e3x.bridge"/> </feature> - <feature url="features/org.eclipse.e4.tools.e3x.bridge.feature.source_0.14.0.qualifier.jar" id="org.eclipse.e4.tools.e3x.bridge.feature.source" version="0.14.0.qualifier"> + <feature url="features/org.eclipse.e4.tools.e3x.bridge.feature.source_0.14.0.qualifier.jar" id="org.eclipse.e4.tools.e3x.bridge.feature.source" version="0.14.0.qualifier"> <category name="org.eclipse.e4.tools.e3x.bridge"/> </feature> + <feature url="features/org.eclipse.e4.tools.event.spy.feature_0.15.0.qualifier.jar" id="org.eclipse.e4.tools.event.spy.feature" version="0.15.0.qualifier"> + <category name="org.eclipse.e4.tools.event.spy"/> + </feature> + <feature url="features/org.eclipse.e4.tools.event.spy.feature.source_0.15.0.qualifier.jar" id="org.eclipse.e4.tools.event.spy.feature.source" version="0.15.0.qualifier"> + <category name="org.eclipse.e4.tools.event.spy"/> + </feature> <category-def name="org.eclipse.e4.tools.core" label="Eclipse 4 core tools"/> <category-def name="org.eclipse.e4.tools.css.spy" label="CSS spy for Eclipse 4"/> <category-def name="org.eclipse.e4.tools.e3x.bridge" label="Eclipse 3.x bridge"/> <category-def name="org.eclipse.e4.tools.css.editor" label="CSS file editor"/> + <category-def name="org.eclipse.e4.tools.event.spy" label="Eclipse 4 event spy"/> </site> diff --git a/bundles/org.eclipse.e4.tools.event.spy/.classpath b/bundles/org.eclipse.e4.tools.event.spy/.classpath new file mode 100644 index 00000000..64c5e31b --- /dev/null +++ b/bundles/org.eclipse.e4.tools.event.spy/.classpath @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="UTF-8"?> +<classpath> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/> + <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/> + <classpathentry kind="src" path="src"/> + <classpathentry kind="output" path="bin"/> +</classpath> diff --git a/bundles/org.eclipse.e4.tools.event.spy/.project b/bundles/org.eclipse.e4.tools.event.spy/.project new file mode 100644 index 00000000..d26d07f7 --- /dev/null +++ b/bundles/org.eclipse.e4.tools.event.spy/.project @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.e4.tools.event.spy</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/bundles/org.eclipse.e4.tools.event.spy/.settings/org.eclipse.jdt.core.prefs b/bundles/org.eclipse.e4.tools.event.spy/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 00000000..af0f20f9 --- /dev/null +++ b/bundles/org.eclipse.e4.tools.event.spy/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,7 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 +org.eclipse.jdt.core.compiler.compliance=1.5 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.5 diff --git a/bundles/org.eclipse.e4.tools.event.spy/META-INF/MANIFEST.MF b/bundles/org.eclipse.e4.tools.event.spy/META-INF/MANIFEST.MF new file mode 100644 index 00000000..8b49e598 --- /dev/null +++ b/bundles/org.eclipse.e4.tools.event.spy/META-INF/MANIFEST.MF @@ -0,0 +1,26 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: %Bundle-Name +Bundle-SymbolicName: org.eclipse.e4.tools.event.spy;singleton:=true +Bundle-Version: 0.15.0.qualifier +Bundle-Vendor: %Bundle-Vendor +Require-Bundle: org.eclipse.ui, + org.eclipse.core.runtime, + org.eclipse.e4.core.di;bundle-version="1.3.0", + org.eclipse.e4.ui.workbench, + org.eclipse.e4.core.contexts;bundle-version="1.3.0", + org.eclipse.e4.ui.model.workbench;bundle-version="1.0.0", + org.eclipse.e4.core.services;bundle-version="1.1.0", + javax.inject;bundle-version="1.0.0", + org.eclipse.e4.ui.bindings;bundle-version="0.10.100", + org.eclipse.core.resources;bundle-version="3.8.100", + org.eclipse.jdt.core;bundle-version="3.9.0", + org.eclipse.jdt.ui;bundle-version="3.9.0", + org.eclipse.pde.core;bundle-version="3.9.0", + org.eclipse.pde.ui;bundle-version="3.8.0", + org.eclipse.pde.runtime;bundle-version="3.4.400", + org.eclipse.osgi.services;bundle-version="3.3.100", + org.eclipse.e4.ui.services;bundle-version="1.0.0" +Bundle-RequiredExecutionEnvironment: J2SE-1.5 +Bundle-ActivationPolicy: lazy +Import-Package: javax.annotation;version="1.1.0" diff --git a/bundles/org.eclipse.e4.tools.event.spy/build.properties b/bundles/org.eclipse.e4.tools.event.spy/build.properties new file mode 100644 index 00000000..e9863e28 --- /dev/null +++ b/bundles/org.eclipse.e4.tools.event.spy/build.properties @@ -0,0 +1,5 @@ +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + .,\ + plugin.xml diff --git a/bundles/org.eclipse.e4.tools.event.spy/plugin.xml b/bundles/org.eclipse.e4.tools.event.spy/plugin.xml new file mode 100644 index 00000000..e9395f19 --- /dev/null +++ b/bundles/org.eclipse.e4.tools.event.spy/plugin.xml @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="UTF-8"?> +<?eclipse version="3.4"?> +<plugin> + <extension + id="org.eclipse.e4.tools.event.spy" + name="E4 Event spy" + point="org.eclipse.e4.workbench.model"> + <processor + beforefragment="false" + class="org.eclipse.e4.tools.event.spy.Installer"> + </processor> + </extension> + +</plugin> diff --git a/bundles/org.eclipse.e4.tools.event.spy/pom.xml b/bundles/org.eclipse.e4.tools.event.spy/pom.xml new file mode 100644 index 00000000..84fb6caf --- /dev/null +++ b/bundles/org.eclipse.e4.tools.event.spy/pom.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.eclipse.e4.tools</groupId> + <artifactId>e4-tools-aggregator</artifactId> + <version>0.15.0-SNAPSHOT</version> + <relativePath>../../</relativePath> + </parent> + + <groupId>org.eclipse.e4</groupId> + <artifactId>org.eclipse.e4.tools.event.spy</artifactId> + <version>0.15.0.qualifier</version> + <packaging>eclipse-plugin</packaging> + +</project> diff --git a/bundles/org.eclipse.e4.tools.event.spy/src/org/eclipse/e4/tools/event/spy/BindingDescriptor.java b/bundles/org.eclipse.e4.tools.event.spy/src/org/eclipse/e4/tools/event/spy/BindingDescriptor.java new file mode 100644 index 00000000..a24513c1 --- /dev/null +++ b/bundles/org.eclipse.e4.tools.event.spy/src/org/eclipse/e4/tools/event/spy/BindingDescriptor.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright (c) 2013 IBM Corporation and others. + * 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.e4.tools.event.spy; + +public enum BindingDescriptor { + OpenSpyDialogInDialogAndWindow("M2+M3+F8", "org.eclipse.ui.contexts.dialogAndWindow"); + + private String bindingContextId; + + private String keySequence; + + private BindingDescriptor(String keySequence, String bindingContextId) { + this.keySequence = keySequence; + this.bindingContextId = bindingContextId; + } + + public String getBindingContextId() { + return bindingContextId; + } + + public String getKeySequence() { + return keySequence; + } +} diff --git a/bundles/org.eclipse.e4.tools.event.spy/src/org/eclipse/e4/tools/event/spy/CommandDescriptor.java b/bundles/org.eclipse.e4.tools.event.spy/src/org/eclipse/e4/tools/event/spy/CommandDescriptor.java new file mode 100644 index 00000000..866ddf47 --- /dev/null +++ b/bundles/org.eclipse.e4.tools.event.spy/src/org/eclipse/e4/tools/event/spy/CommandDescriptor.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright (c) 2013 IBM Corporation and others. + * 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.e4.tools.event.spy; + +public enum CommandDescriptor { + OpenSpyDialog("org.eclipse.e4.tools.event.spy.openSpyDialog.cmd", "Open event spy dialog"); + + private String id; + + private String name; + + private CommandDescriptor(String id, String name) { + this.id = id; + this.name = name; + } + + public String getId() { + return id; + } + + public String getName() { + return name; + } +} diff --git a/bundles/org.eclipse.e4.tools.event.spy/src/org/eclipse/e4/tools/event/spy/Constants.java b/bundles/org.eclipse.e4.tools.event.spy/src/org/eclipse/e4/tools/event/spy/Constants.java new file mode 100644 index 00000000..61c8a3e2 --- /dev/null +++ b/bundles/org.eclipse.e4.tools.event.spy/src/org/eclipse/e4/tools/event/spy/Constants.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright (c) 2013 IBM Corporation and others. + * 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.e4.tools.event.spy; + +import org.eclipse.e4.tools.event.spy.util.PluginUtils; +import org.eclipse.e4.ui.bindings.EBindingService; + +public class Constants { + public static final String PLUGIN_ID = PluginUtils.getBundleId(Constants.class); + + public static final String BINDING_MODIFIED_BY_USER_TAG = EBindingService.TYPE_ATTR_TAG + ":user"; + + public static final String BINDING_DELETED_BY_USER_TAG = EBindingService.DELETED_BINDING_TAG; +} diff --git a/bundles/org.eclipse.e4.tools.event.spy/src/org/eclipse/e4/tools/event/spy/Installer.java b/bundles/org.eclipse.e4.tools.event.spy/src/org/eclipse/e4/tools/event/spy/Installer.java new file mode 100644 index 00000000..d175ba4b --- /dev/null +++ b/bundles/org.eclipse.e4.tools.event.spy/src/org/eclipse/e4/tools/event/spy/Installer.java @@ -0,0 +1,137 @@ +/******************************************************************************* + * Copyright (c) 2013 IBM Corporation and others. + * 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.e4.tools.event.spy; + + +import javax.inject.Inject; + +import org.eclipse.e4.core.di.annotations.Execute; +import org.eclipse.e4.tools.event.spy.handlers.OpenSpyDialogHandler; +import org.eclipse.e4.tools.event.spy.util.LoggerWrapper; +import org.eclipse.e4.tools.event.spy.util.PluginUtils; +import org.eclipse.e4.ui.model.application.MApplication; +import org.eclipse.e4.ui.model.application.commands.MBindingTable; +import org.eclipse.e4.ui.model.application.commands.MCommand; +import org.eclipse.e4.ui.model.application.commands.MCommandsFactory; +import org.eclipse.e4.ui.model.application.commands.MHandler; +import org.eclipse.e4.ui.model.application.commands.MKeyBinding; + +@SuppressWarnings("restriction") +public class Installer { + @Inject + private MApplication application; + + @Inject + private LoggerWrapper logger; + + @Execute + public void execute() { + logger.info("installing ..."); + + registerCommand(CommandDescriptor.OpenSpyDialog, BindingDescriptor.OpenSpyDialogInDialogAndWindow, OpenSpyDialogHandler.class); + + logger.info("installed"); + } + + private void registerCommand(CommandDescriptor commandDesc, BindingDescriptor bindingDesc, Class<?> handlerCls) { + MCommand command = getCommand(application, commandDesc); + if (command == null) { + command = createCommand(commandDesc); + application.getCommands().add(command); + } + + Object binding = getBindingOrBindingTable(application, command, bindingDesc); + if (binding == null) { + logger.warn("binding context ''{0}'' for command ''{1}'' not found", + bindingDesc.getBindingContextId(), commandDesc.getName()); + return; + } + + if (binding instanceof MKeyBinding) { + MKeyBinding keyBinding = (MKeyBinding) binding; + if (keyBinding.getTags().contains(Constants.BINDING_MODIFIED_BY_USER_TAG)) { + logger.info("key binding for command ''{0}'' changed to {1}", commandDesc.getName(), keyBinding.getKeySequence()); + + } else if (keyBinding.getTags().contains(Constants.BINDING_DELETED_BY_USER_TAG)) { + logger.info("key binding for command ''{0}'' has been deleted. The command is disabled", commandDesc.getName()); + } + return; //command already processed + } + + ((MBindingTable) binding).getBindings().add(createKeyBinding(command, bindingDesc)); + logger.info("key binding for command ''{0}'' is {1}", commandDesc.getName(), bindingDesc.getKeySequence()); + + MHandler handler = getHandler(application, commandDesc); + if (handler == null) { + handler = createHandler(command, handlerCls); + application.getHandlers().add(handler); + } + } + + private MCommand getCommand(MApplication application, CommandDescriptor descriptor) { + for (MCommand command: application.getCommands()) { + if (descriptor.getId().equals(command.getElementId())) { + return command; + } + } + return null; + } + + private MCommand createCommand(CommandDescriptor descriptor) { + MCommand command = MCommandsFactory.INSTANCE.createCommand(); + command.setElementId(descriptor.getId()); + command.setCommandName(descriptor.getName()); + command.setContributorURI(PluginUtils.getContributorURI()); + return command; + } + + private MHandler getHandler(MApplication application, CommandDescriptor descriptor) { + for (MHandler handler: application.getHandlers()) { + if (descriptor.getId().equals(handler.getElementId())) { + return handler; + } + } + return null; + } + + private MHandler createHandler(MCommand command, Class<?> handlerCls) { + MHandler handler = MCommandsFactory.INSTANCE.createHandler(); + handler.setElementId(command.getElementId()); + handler.setCommand(command); + handler.setContributionURI(PluginUtils.getContributionURI(handlerCls)); + handler.setContributorURI(PluginUtils.getContributorURI()); + return handler; + } + + private Object getBindingOrBindingTable(MApplication application, MCommand command, BindingDescriptor descriptor) { + MBindingTable result = null; + for (MBindingTable bindingTable: application.getBindingTables()) { + for (MKeyBinding keyBinding : bindingTable.getBindings()) { + if (keyBinding.getCommand() == command) { + return bindingTable; + } + } + if (descriptor.getBindingContextId().equals(bindingTable.getBindingContext().getElementId())) { + result = bindingTable; + } + } + return result; + } + + private MKeyBinding createKeyBinding(MCommand command, BindingDescriptor descriptor) { + MKeyBinding keyBinding = MCommandsFactory.INSTANCE.createKeyBinding(); + keyBinding.setElementId(command.getElementId()); + keyBinding.setCommand(command); + keyBinding.setKeySequence(descriptor.getKeySequence()); + keyBinding.setContributorURI(PluginUtils.getContributorURI()); + return keyBinding; + } +} diff --git a/bundles/org.eclipse.e4.tools.event.spy/src/org/eclipse/e4/tools/event/spy/core/CapturedEventFilterMatcher.java b/bundles/org.eclipse.e4.tools.event.spy/src/org/eclipse/e4/tools/event/spy/core/CapturedEventFilterMatcher.java new file mode 100644 index 00000000..a360cd33 --- /dev/null +++ b/bundles/org.eclipse.e4.tools.event.spy/src/org/eclipse/e4/tools/event/spy/core/CapturedEventFilterMatcher.java @@ -0,0 +1,124 @@ +/******************************************************************************* + * Copyright (c) 2013 IBM Corporation and others. + * 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.e4.tools.event.spy.core; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.e4.tools.event.spy.model.CapturedEvent; +import org.eclipse.e4.tools.event.spy.model.CapturedEventFilter; +import org.eclipse.e4.tools.event.spy.model.ItemToFilter; +import org.eclipse.e4.tools.event.spy.model.Operator; +import org.eclipse.e4.tools.event.spy.model.Parameter; +import org.eclipse.e4.tools.event.spy.model.SpecialValue; + +public class CapturedEventFilterMatcher { + public boolean matches(CapturedEvent event, CapturedEventFilter filter) { + Object value = getItemToFilterValue(event, filter.getItemToFilter()); + + if (value instanceof List) { + List<?> list = (List<?>) value; + for (Object item: list) { + if (matches(filter.getValue(), item, filter.getOperator())) { + return true; + } + } + return false; + } + return matches(filter.getValue(), value, filter.getOperator()); + } + + private Object getItemToFilterValue(CapturedEvent event, ItemToFilter itemToFilter) { + if (itemToFilter.equals(ItemToFilter.Topic)) { + return event.getTopic(); + } + if (itemToFilter.equals(ItemToFilter.Publisher)) { + return event.getPublisherClassName(); + } + if (itemToFilter.equals(ItemToFilter.ChangedElement)) { + return event.getChangedElementClassName(); + } + if (itemToFilter.equals(ItemToFilter.ParameterName)) { + List<String> names = new ArrayList<String>(); + for (Parameter parameter: event.getParameters()) { + names.add(parameter.getName()); + } + return names; + } + if (itemToFilter.equals(ItemToFilter.ParameterValue)) { + List<Object> values = new ArrayList<Object>(); + for (Parameter parameter: event.getParameters()) { + values.add(parameter.getValue()); + } + return values; + } + if (itemToFilter.equals(ItemToFilter.ParameterNameAndValue)) { + List<String> nameAndValues = new ArrayList<String>(); + for (Parameter parameter: event.getParameters()) { + String nameAndValue = String.format(SpecialValue.NameAndValue.toString(), parameter.getName().trim(), + (parameter.getValue() == null? SpecialValue.Null: parameter.getValue().toString().trim())); + nameAndValues.add(nameAndValue); + } + return nameAndValues; + } + + throw new IllegalArgumentException("Not supported item to filter found: " + itemToFilter.toString()); + } + + private boolean matches(String expected, Object current, Operator operator) { + if (SpecialValue.Null.toString().equalsIgnoreCase(expected)) { + return operator.isPositive()? matchesToNull(current): !matchesToNull(current); + } + if ( SpecialValue.EmptyString.toString().equalsIgnoreCase(expected)) { + return operator.isPositive()? matchesToEmptyString(current): !matchesToEmptyString(current); + } + if (Operator.Equals.equals(operator)) { + return equalsTo(expected, current); + } + if (Operator.NotEquals.equals(operator)) { + return !equalsTo(expected, current); + } + if (Operator.Contains.equals(operator)) { + return contains(expected, current); + } + if (Operator.NotContains.equals(operator)) { + return !contains(expected, current); + } + if (Operator.StartsWith.equals(operator)) { + return startsWith(expected, current); + } + if (Operator.NotStartsWith.equals(operator)) { + return !startsWith(expected, current); + } + + throw new IllegalArgumentException("Not supported operator found: " + operator); + } + + private boolean matchesToEmptyString(Object current) { + return current != null && current instanceof String && current.toString().isEmpty(); + } + + private boolean matchesToNull(Object current) { + return current == null || current.toString().equalsIgnoreCase(SpecialValue.Null.toString()); + } + + private boolean equalsTo(String expected, Object current) { + return current != null && expected.equalsIgnoreCase(current.toString()); + } + + private boolean contains(String expected, Object current) { + return current != null && current.toString().toLowerCase().contains(expected.toLowerCase()); + } + + private boolean startsWith(String expected, Object current) { + return current != null && current.toString().toLowerCase().startsWith(expected.toLowerCase()); + } +} diff --git a/bundles/org.eclipse.e4.tools.event.spy/src/org/eclipse/e4/tools/event/spy/core/EventMonitor.java b/bundles/org.eclipse.e4.tools.event.spy/src/org/eclipse/e4/tools/event/spy/core/EventMonitor.java new file mode 100644 index 00000000..6d0f900a --- /dev/null +++ b/bundles/org.eclipse.e4.tools.event.spy/src/org/eclipse/e4/tools/event/spy/core/EventMonitor.java @@ -0,0 +1,125 @@ +/******************************************************************************* + * Copyright (c) 2013 IBM Corporation and others. + * 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.e4.tools.event.spy.core; + +import java.util.Collection; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + +import org.eclipse.e4.core.services.events.IEventBroker; +import org.eclipse.e4.tools.event.spy.model.CapturedEvent; +import org.eclipse.e4.tools.event.spy.model.CapturedEventFilter; +import org.eclipse.e4.ui.internal.workbench.UIEventPublisher; +import org.eclipse.e4.ui.services.internal.events.EventBroker; +import org.eclipse.e4.ui.workbench.UIEvents; +import org.osgi.service.event.Event; +import org.osgi.service.event.EventHandler; + +public class EventMonitor { + + public interface NewEventListener { + void newEvent(CapturedEvent event); + } + + private final static String TOPIC = UIEvents.UITopicBase + UIEvents.TOPIC_SEP + UIEvents.ALL_SUB_TOPICS; + + @SuppressWarnings({"serial", "restriction"}) + private static Set<Integer> EVENT_HELPER_CLASSES = new HashSet<Integer>() {{ + add(UIEvents.class.getName().hashCode()); + add(UIEventPublisher.class.getName().hashCode()); + }}; + + private Collection<CapturedEventFilter> filters; + + private IEventBroker eventBroker; + + private NewEventListener listener; + + private CapturedEventFilterMatcher eventFilterMatcher; + + private EventHandler eventHandler = new EventHandler() { + public void handleEvent(Event event) { + if (listener == null) { + return; + } + + CapturedEvent capturedEvent = new CapturedEvent(); + capturedEvent.setTopic(event.getTopic()); + capturedEvent.setPublisherClassName(getPublisherClassName()); + + for (String propertyName: event.getPropertyNames()) { + Object value = event.getProperty(propertyName); + capturedEvent.addParameter(propertyName, value); + if (value != null && UIEvents.EventTags.ELEMENT.equals(propertyName)) { + capturedEvent.setChangedElementClassName(value.getClass().getName()); + } + } + + if (shouldBeCaptured(capturedEvent)) { + listener.newEvent(capturedEvent); + } + } + }; + + public EventMonitor(IEventBroker eventBroker) { + this.eventBroker = eventBroker; + } + + public void start(Collection<CapturedEventFilter> filters) { + this.filters = filters; + eventBroker.subscribe(TOPIC, eventHandler); + } + + public void stop() { + eventBroker.unsubscribe(eventHandler); + } + + public void setNewEventListener(NewEventListener listener) { + this.listener = listener; + } + + private boolean shouldBeCaptured(CapturedEvent event) { + if (filters != null) { + Iterator<CapturedEventFilter> iter = filters.iterator(); + while (iter.hasNext()) { + if (!getEventFilterMatcher().matches(event, iter.next())) { + return false; + } + } + } + return true; + } + + private String getPublisherClassName() { + StackTraceElement items[] = Thread.currentThread().getStackTrace(); + boolean foundEventBroker = false; + + for (int i=0; i<items.length; i++) { + String clsName = items[i].getClassName(); + if (!foundEventBroker && clsName.equals(EventBroker.class.getName())) { + foundEventBroker = true; + } else if (foundEventBroker) { + if (!EVENT_HELPER_CLASSES.contains(clsName.hashCode())) { + return String.format("%s (%s:%d)", clsName, items[i].getMethodName(), items[i].getLineNumber()); + } + } + } + return ""; + } + + private CapturedEventFilterMatcher getEventFilterMatcher() { + if (eventFilterMatcher == null) { + eventFilterMatcher = new CapturedEventFilterMatcher(); + } + return eventFilterMatcher; + } +} diff --git a/bundles/org.eclipse.e4.tools.event.spy/src/org/eclipse/e4/tools/event/spy/handlers/OpenSpyDialogHandler.java b/bundles/org.eclipse.e4.tools.event.spy/src/org/eclipse/e4/tools/event/spy/handlers/OpenSpyDialogHandler.java new file mode 100644 index 00000000..2d059763 --- /dev/null +++ b/bundles/org.eclipse.e4.tools.event.spy/src/org/eclipse/e4/tools/event/spy/handlers/OpenSpyDialogHandler.java @@ -0,0 +1,23 @@ +/******************************************************************************* + * Copyright (c) 2013 IBM Corporation and others. + * 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.e4.tools.event.spy.handlers; + +import org.eclipse.e4.core.contexts.ContextInjectionFactory; +import org.eclipse.e4.core.contexts.IEclipseContext; +import org.eclipse.e4.core.di.annotations.Execute; +import org.eclipse.e4.tools.event.spy.ui.SpyDialog; + +public class OpenSpyDialogHandler { + @Execute + public void execute(IEclipseContext context) { + ContextInjectionFactory.make(SpyDialog.class, context).open(); + } +} diff --git a/bundles/org.eclipse.e4.tools.event.spy/src/org/eclipse/e4/tools/event/spy/model/CapturedEvent.java b/bundles/org.eclipse.e4.tools.event.spy/src/org/eclipse/e4/tools/event/spy/model/CapturedEvent.java new file mode 100644 index 00000000..060b8f57 --- /dev/null +++ b/bundles/org.eclipse.e4.tools.event.spy/src/org/eclipse/e4/tools/event/spy/model/CapturedEvent.java @@ -0,0 +1,70 @@ +/******************************************************************************* + * Copyright (c) 2013 IBM Corporation and others. + * 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.e4.tools.event.spy.model; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class CapturedEvent { + private String topic; + + private String publisherClassName = ""; + + private String changedElementClassName = ""; + + private List<Parameter> parameters; + + public void setTopic(String topic) { + this.topic = topic; + } + + public String getTopic() { + return topic; + } + + public void setPublisherClassName(String publisherClassName) { + this.publisherClassName = publisherClassName; + } + + public String getPublisherClassName() { + return publisherClassName; + } + + public void setChangedElementClassName(String changedElementClassName) { + this.changedElementClassName = changedElementClassName; + } + + public String getChangedElementClassName() { + return changedElementClassName; + } + + public void addParameter(String name, Object value) { + if (parameters == null) { + parameters = new ArrayList<Parameter>(); + } + parameters.add(new Parameter(name, value)); + } + + @SuppressWarnings("unchecked") + public List<Parameter> getParameters() { + return parameters != null? parameters: Collections.EMPTY_LIST; + } + + public boolean hasParameters() { + return parameters != null; + } + + @Override + public String toString() { + return topic; + } +} diff --git a/bundles/org.eclipse.e4.tools.event.spy/src/org/eclipse/e4/tools/event/spy/model/CapturedEventFilter.java b/bundles/org.eclipse.e4.tools.event.spy/src/org/eclipse/e4/tools/event/spy/model/CapturedEventFilter.java new file mode 100644 index 00000000..e7706fd5 --- /dev/null +++ b/bundles/org.eclipse.e4.tools.event.spy/src/org/eclipse/e4/tools/event/spy/model/CapturedEventFilter.java @@ -0,0 +1,56 @@ +/******************************************************************************* + * Copyright (c) 2013 IBM Corporation and others. + * 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.e4.tools.event.spy.model; + +public class CapturedEventFilter { + private final static String FILTER_AS_STRING_PATTERN = "Capture event when '%s' %s '%s'"; + + private final ItemToFilter itemToFilter; + + private final Operator operator; + + private final String value; + + public CapturedEventFilter(ItemToFilter itemToFilter, Operator operator, String value) { + this.itemToFilter = itemToFilter; + this.operator = operator; + this.value = normalize(itemToFilter, value); + } + + public ItemToFilter getItemToFilter() { + return itemToFilter; + } + + public Operator getOperator() { + return operator; + } + + public String getValue() { + return value; + } + + private String normalize(ItemToFilter itemToFilter, String value) { + if (ItemToFilter.ParameterNameAndValue.equals(itemToFilter)) { + String[] splitted = value.split("="); + if (splitted.length != 2) { + throw new IllegalArgumentException("Invalid value format, it should be: " + + String.format(SpecialValue.NameAndValue.toString(), "Name", "Value")); + } + return String.format(SpecialValue.NameAndValue.toString(), splitted[0].trim(), splitted[1].trim()); + } + return value; + } + + @Override + public String toString() { + return String.format(FILTER_AS_STRING_PATTERN, itemToFilter, operator, value); + } +} diff --git a/bundles/org.eclipse.e4.tools.event.spy/src/org/eclipse/e4/tools/event/spy/model/CapturedEventTreeSelection.java b/bundles/org.eclipse.e4.tools.event.spy/src/org/eclipse/e4/tools/event/spy/model/CapturedEventTreeSelection.java new file mode 100644 index 00000000..6dddc176 --- /dev/null +++ b/bundles/org.eclipse.e4.tools.event.spy/src/org/eclipse/e4/tools/event/spy/model/CapturedEventTreeSelection.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright (c) 2013 IBM Corporation and others. + * 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.e4.tools.event.spy.model; + +public class CapturedEventTreeSelection { + private String selection; + + private boolean parameter; + + public CapturedEventTreeSelection(String selection, boolean parameter) { + this.selection = selection; + this.parameter = parameter; + } + + public String getSelection() { + return selection; + } + + public boolean isParameter() { + return parameter; + } +} diff --git a/bundles/org.eclipse.e4.tools.event.spy/src/org/eclipse/e4/tools/event/spy/model/ItemToFilter.java b/bundles/org.eclipse.e4.tools.event.spy/src/org/eclipse/e4/tools/event/spy/model/ItemToFilter.java new file mode 100644 index 00000000..1565bebd --- /dev/null +++ b/bundles/org.eclipse.e4.tools.event.spy/src/org/eclipse/e4/tools/event/spy/model/ItemToFilter.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright (c) 2013 IBM Corporation and others. + * 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.e4.tools.event.spy.model; + + +public enum ItemToFilter { + NotSelected("-- item to filter --"), + Topic("Topic"), + ParameterName("Parameter name"), + ParameterNameAndValue("Parameter name and value"), + ParameterValue("Some parameter value"), + Publisher("Event publisher"), + ChangedElement("Changed element"); + + private String text; + + private ItemToFilter(String text) { + this.text = text; + } + + @Override + public String toString() { + return text; + } + + public static ItemToFilter toItem(String text) { + for (ItemToFilter item: values()) { + if (item.text.equals(text)) { + return item; + } + } + throw new IllegalArgumentException(String.format("%s not found for: %s", + ItemToFilter.class.getSimpleName(), text)); + } +}
\ No newline at end of file diff --git a/bundles/org.eclipse.e4.tools.event.spy/src/org/eclipse/e4/tools/event/spy/model/Operator.java b/bundles/org.eclipse.e4.tools.event.spy/src/org/eclipse/e4/tools/event/spy/model/Operator.java new file mode 100644 index 00000000..135a1898 --- /dev/null +++ b/bundles/org.eclipse.e4.tools.event.spy/src/org/eclipse/e4/tools/event/spy/model/Operator.java @@ -0,0 +1,49 @@ +/******************************************************************************* + * Copyright (c) 2013 IBM Corporation and others. + * 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.e4.tools.event.spy.model; + +public enum Operator { + NotSelected("-- operator --", false), + Equals("equals to", true), + NotEquals("not equals to", false), + Contains("contains", true), + NotContains("not contains", false), + StartsWith("starts with", true), + NotStartsWith("not starts with", false); + + private String text; + + private boolean positive; + + private Operator(String text, boolean positive) { + this.text = text; + this.positive = positive; + } + + @Override + public String toString() { + return text; + } + + public boolean isPositive() { + return positive; + } + + public static Operator toOperator(String text) { + for (Operator operator: values()) { + if (operator.text.equals(text)) { + return operator; + } + } + throw new IllegalArgumentException(String.format("%s not found for: %s", + Operator.class.getSimpleName(), text)); + } +} diff --git a/bundles/org.eclipse.e4.tools.event.spy/src/org/eclipse/e4/tools/event/spy/model/Parameter.java b/bundles/org.eclipse.e4.tools.event.spy/src/org/eclipse/e4/tools/event/spy/model/Parameter.java new file mode 100644 index 00000000..2de4d103 --- /dev/null +++ b/bundles/org.eclipse.e4.tools.event.spy/src/org/eclipse/e4/tools/event/spy/model/Parameter.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright (c) 2013 IBM Corporation and others. + * 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.e4.tools.event.spy.model; + +public class Parameter { + private String name; + private Object value; + + public Parameter(String name, Object value) { + this.name = name; + this.value = value; + } + + public String getName() { + return name; + } + + public Object getValue() { + return value; + } +} diff --git a/bundles/org.eclipse.e4.tools.event.spy/src/org/eclipse/e4/tools/event/spy/model/SpecialValue.java b/bundles/org.eclipse.e4.tools.event.spy/src/org/eclipse/e4/tools/event/spy/model/SpecialValue.java new file mode 100644 index 00000000..30145559 --- /dev/null +++ b/bundles/org.eclipse.e4.tools.event.spy/src/org/eclipse/e4/tools/event/spy/model/SpecialValue.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright (c) 2013 IBM Corporation and others. + * 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.e4.tools.event.spy.model; + +public enum SpecialValue { + Null("null"), + EmptyString("empty"), + NameAndValue("%s=%s"); + + private String text; + + private SpecialValue(String text) { + this.text = text; + } + + @Override + public String toString() { + return text; + } +} diff --git a/bundles/org.eclipse.e4.tools.event.spy/src/org/eclipse/e4/tools/event/spy/ui/CapturedEventFilters.java b/bundles/org.eclipse.e4.tools.event.spy/src/org/eclipse/e4/tools/event/spy/ui/CapturedEventFilters.java new file mode 100644 index 00000000..5ddd7187 --- /dev/null +++ b/bundles/org.eclipse.e4.tools.event.spy/src/org/eclipse/e4/tools/event/spy/ui/CapturedEventFilters.java @@ -0,0 +1,265 @@ +/******************************************************************************* + * Copyright (c) 2013 IBM Corporation and others. + * 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.e4.tools.event.spy.ui; + +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.e4.tools.event.spy.model.CapturedEventFilter; +import org.eclipse.e4.tools.event.spy.model.ItemToFilter; +import org.eclipse.e4.tools.event.spy.model.Operator; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.FocusEvent; +import org.eclipse.swt.events.FocusListener; +import org.eclipse.swt.layout.RowData; +import org.eclipse.swt.layout.RowLayout; +import org.eclipse.swt.widgets.Combo; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Group; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Link; +import org.eclipse.swt.widgets.List; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Text; +import org.eclipse.swt.widgets.ToolTip; + +public class CapturedEventFilters { + private final static String NOT_SELECTED_VALUE = "-- expected value --"; + + private Composite control; + + private Text valueText; + + private Combo itemToFilterCombo; + + private Combo operatorCombo; + + private ToolTip validationErrorToolTip; + + private List filters; + + private Map<Integer, CapturedEventFilter> rawFilters; + + + /* Layout scheme: + * + * +-- control --------------------------------------------+ + * | +-- New filter group -------------------------------+ | + * | | | | + * | | Capture event when|combo|combo|text|add filter | | + * | | | | + * | +---------------------------------------------------+ | + * | +-- Defined filter group ---------------------------+ | + * | | | | + * | | List | +-- composite -----------------+ | | + * | | | | remove selected | remove all | | | + * | | | +------------------------------+ | | + * | | | | + * | +---------------------------------------------------+ | + * +-------------------------------------------------------+ + * + * */ + + //TODO: Fix layout data for groups + public CapturedEventFilters(Composite outer) { + control = new Composite(outer, SWT.NONE); + RowLayout layout = new RowLayout(SWT.VERTICAL); + layout.marginLeft = 0; + layout.fill = true; + control.setLayout(layout); + + createNewFilterGroup(control); + + createDefinedFiltersGroup(control); + } + + private void createNewFilterGroup(Composite parent) { + Group newFilterGroup = new Group(parent, SWT.NONE); + newFilterGroup.setText("New filter:"); + newFilterGroup.setLayout(new RowLayout(SWT.HORIZONTAL)); + + Label label = new Label(newFilterGroup, SWT.CENTER); + label.setText("Capture event when:"); + + itemToFilterCombo = new Combo(newFilterGroup, SWT.READ_ONLY); + for (ItemToFilter item: ItemToFilter.values()) { + itemToFilterCombo.add(item.toString()); + } + itemToFilterCombo.select(0); + + operatorCombo = new Combo(newFilterGroup, SWT.READ_ONLY); + for (Operator operator: Operator.values()) { + operatorCombo.add(operator.toString()); + } + operatorCombo.select(0); + + valueText = new Text(newFilterGroup, SWT.BORDER); + valueText.setLayoutData(new RowData(130, SWT.DEFAULT)); + valueText.setText(NOT_SELECTED_VALUE); + valueText.addFocusListener(new FocusListener() { + public void focusLost(FocusEvent e) { + if (valueText.getText().trim().isEmpty()) { + valueText.setText(NOT_SELECTED_VALUE); + } + } + public void focusGained(FocusEvent e) { + if (NOT_SELECTED_VALUE.equals(valueText.getText())) { + valueText.setText(""); + } + } + }); + + Link link = new Link(newFilterGroup, SWT.NONE); + link.setText("<a>Add filter</a>"); + link.addListener (SWT.Selection, new Listener() { + public void handleEvent(Event event) { + addNewFilter(); + } + }); + } + + private void createDefinedFiltersGroup(Composite parent) { + Group definedFiltersGroup = new Group(parent, SWT.NONE); + definedFiltersGroup.setText("Defined filters (relation between filters is AND):"); + definedFiltersGroup.setLayout(new RowLayout(SWT.HORIZONTAL)); + + filters = new List(definedFiltersGroup, SWT.BORDER); + filters.setLayoutData(new RowData(403, 84)); + + + Composite composite = new Composite(definedFiltersGroup, SWT.NONE); + composite.setLayout(new RowLayout(SWT.VERTICAL)); + + Link link = new Link(composite, SWT.NONE); + link.setText("<a>Remove selected</a>"); + link.addListener (SWT.Selection, new Listener() { + public void handleEvent(Event event) { + removeFilterAt(filters.getSelectionIndex()); + } + }); + + link = new Link(composite, SWT.NONE); + link.setText("<a>Remove all</a>"); + link.addListener (SWT.Selection, new Listener() { + public void handleEvent(Event event) { + removeAllFilters(); + } + }); + } + + public Control getControl() { + return control; + } + + @SuppressWarnings("unchecked") + public Collection<CapturedEventFilter> getFilters() { + return rawFilters == null || rawFilters.isEmpty()? Collections.EMPTY_LIST: rawFilters.values(); + } + + public boolean hasFilters() { + return rawFilters != null && !rawFilters.isEmpty(); + } + + public int getFiltersCount() { + return rawFilters == null? 0: rawFilters.size(); + } + + private void addNewFilter() { + ItemToFilter selectedItemToFilter = + ItemToFilter.toItem(itemToFilterCombo.getItem(itemToFilterCombo.getSelectionIndex())); + if (ItemToFilter.NotSelected.equals(selectedItemToFilter)) { + getTooltip().setText(String.format("%s is not selected", getFieldName(ItemToFilter.NotSelected))); + getTooltip().setVisible(true); + return; + } + + Operator selectedOperator = Operator.toOperator(operatorCombo.getItem(operatorCombo.getSelectionIndex())); + if (Operator.NotSelected.equals(selectedOperator)) { + getTooltip().setText(String.format("%s is not selected", getFieldName(Operator.NotSelected))); + getTooltip().setVisible(true); + return; + } + + String value = valueText.getText(); + if (value.isEmpty() || value.equals(NOT_SELECTED_VALUE)) { + getTooltip().setText(String.format("%s is empty", getFieldName(NOT_SELECTED_VALUE))); + getTooltip().setVisible(true); + return; + } + + CapturedEventFilter eventFilter = null; + try { + eventFilter = new CapturedEventFilter(selectedItemToFilter, selectedOperator, value); + } catch(IllegalArgumentException exc) { + getTooltip().setText(exc.getMessage()); + getTooltip().setVisible(true); + return; + } + + if (rawFilters == null) { + rawFilters = new HashMap<Integer, CapturedEventFilter>(); + } + + String filterAsString = eventFilter.toString(); + if (rawFilters.containsKey(filterAsString.hashCode())) { + getTooltip().setText(String.format("Filter has been already added: %s", filterAsString)); + getTooltip().setVisible(true); + return; + } + + filters.add(filterAsString); + rawFilters.put(filterAsString.hashCode(), eventFilter); + + itemToFilterCombo.select(0); + operatorCombo.select(0); + valueText.setText(NOT_SELECTED_VALUE); + } + + private ToolTip getTooltip() { + if (validationErrorToolTip == null) { + validationErrorToolTip = new ToolTip(Display.getCurrent().getActiveShell(), SWT.BALLOON | SWT.ICON_WARNING); + } + return validationErrorToolTip; + } + + private void removeFilterAt(int index) { + if (index < 0) { + getTooltip().setText("Filter to remove is not selected"); + getTooltip().setVisible(true); + return; + } + + String filterAsString = filters.getItem(index); + filters.remove(index); + rawFilters.remove(filterAsString.hashCode()); + } + + private void removeAllFilters() { + if (rawFilters == null || rawFilters.isEmpty()) { + getTooltip().setText("Filter list is empty"); + getTooltip().setVisible(true); + return; + } + + filters.removeAll(); + rawFilters.clear(); + } + + private String getFieldName(Object notSelectedName) { + String fieldName = notSelectedName.toString().replaceAll("-", "").trim(); + return Character.toUpperCase(fieldName.charAt(0)) + fieldName.substring(1); + } +} diff --git a/bundles/org.eclipse.e4.tools.event.spy/src/org/eclipse/e4/tools/event/spy/ui/CapturedEventTree.java b/bundles/org.eclipse.e4.tools.event.spy/src/org/eclipse/e4/tools/event/spy/ui/CapturedEventTree.java new file mode 100644 index 00000000..7e0b23e7 --- /dev/null +++ b/bundles/org.eclipse.e4.tools.event.spy/src/org/eclipse/e4/tools/event/spy/ui/CapturedEventTree.java @@ -0,0 +1,155 @@ +/******************************************************************************* + * Copyright (c) 2013 IBM Corporation and others. + * 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.e4.tools.event.spy.ui; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.e4.tools.event.spy.model.CapturedEvent; +import org.eclipse.e4.tools.event.spy.model.CapturedEventTreeSelection; +import org.eclipse.e4.tools.event.spy.model.ItemToFilter; +import org.eclipse.e4.tools.event.spy.model.Parameter; +import org.eclipse.e4.tools.event.spy.util.ParameterFormatter; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.events.MouseListener; +import org.eclipse.swt.events.TreeEvent; +import org.eclipse.swt.events.TreeListener; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Tree; +import org.eclipse.swt.widgets.TreeColumn; +import org.eclipse.swt.widgets.TreeItem; + + + +public class CapturedEventTree { + + public interface SelectionListener { + void selectionChanged(CapturedEventTreeSelection selection); + } + + private Tree tree; + + private SelectionListener selectionListener; + + private List<ItemToFilter> columns = new ArrayList<ItemToFilter>(); + + + /* Layout scheme: + * + * +-- parent---------------+ + * | | + * | Tree | + * | | + * +------------------------+ + * + * */ + + public CapturedEventTree(Composite parent) { + tree = new Tree(parent, SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION); + tree.setHeaderVisible(true); + tree.setLinesVisible(true); + + TreeColumn column = new TreeColumn(tree, SWT.LEFT); + column.setText(ItemToFilter.Topic.toString()); + column.setWidth(350); + columns.add(ItemToFilter.Topic); + + column = new TreeColumn(tree, SWT.LEFT); + column.setText(ItemToFilter.Publisher.toString()); + column.setWidth(150); + columns.add(ItemToFilter.Publisher); + + column = new TreeColumn(tree, SWT.LEFT); + column.setText(ItemToFilter.ChangedElement.toString()); + column.setWidth(150); + columns.add(ItemToFilter.ChangedElement); + + addTreeEventListeners(); + } + + @SuppressWarnings("unchecked") + private void addTreeEventListeners() { + tree.addTreeListener(new TreeListener() { + public void treeExpanded(TreeEvent e) { + TreeItem item = (TreeItem) e.item; + TreeItem paramItem = item.getItem(0); + if (paramItem.getText().isEmpty()) { + for (Parameter param: (List<Parameter>) paramItem.getData()) { + if (paramItem == null) { + paramItem = new TreeItem(item, SWT.NONE); + } + paramItem.setText(ParameterFormatter.toString(param)); + paramItem = null; + } + } + + } + public void treeCollapsed(TreeEvent e) { + } + }); + + tree.addMouseListener(new MouseListener() { + public void mouseUp(MouseEvent e) { + } + public void mouseDoubleClick(MouseEvent e) { + + } + public void mouseDown(MouseEvent e) { + TreeItem[] items = tree.getSelection(); + if (items == null || items.length == 0) { + return; + } + int selectedItemIndex = -1; + for (int i=0; i<columns.size(); i++) { + Rectangle rec = items[0].getBounds(i); + if (e.x >= rec.x && e.x <= rec.x + rec.width) { + selectedItemIndex = i; + break; + } + } + if (selectedItemIndex >= 0 && selectionListener != null) { + String selection = items[0].getText(selectedItemIndex); + if (!selection.isEmpty()) { + selectionListener.selectionChanged(new CapturedEventTreeSelection(selection,items[0].getItemCount() == 0)); + } + } + } + }); + } + + public void addEvent(CapturedEvent event) { + TreeItem item = new TreeItem(tree, SWT.NONE); + + item.setText(columns.indexOf(ItemToFilter.Topic), event.getTopic()); + item.setText(columns.indexOf(ItemToFilter.Publisher), event.getPublisherClassName()); + item.setText(columns.indexOf(ItemToFilter.ChangedElement), event.getChangedElementClassName()); + + if (event.hasParameters()) { + item = new TreeItem(item, SWT.NONE); + item.setData(event.getParameters()); + } + } + + public void setSelectionListener(SelectionListener selectionListener) { + this.selectionListener = selectionListener; + } + + public Control getControl() { + return tree; + } + + public void removeAll() { + tree.removeAll(); + } +} diff --git a/bundles/org.eclipse.e4.tools.event.spy/src/org/eclipse/e4/tools/event/spy/ui/SpyDialog.java b/bundles/org.eclipse.e4.tools.event.spy/src/org/eclipse/e4/tools/event/spy/ui/SpyDialog.java new file mode 100644 index 00000000..e7a29f18 --- /dev/null +++ b/bundles/org.eclipse.e4.tools.event.spy/src/org/eclipse/e4/tools/event/spy/ui/SpyDialog.java @@ -0,0 +1,238 @@ +/******************************************************************************* + * Copyright (c) 2013 IBM Corporation and others. + * 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.e4.tools.event.spy.ui; + +import javax.inject.Inject; + +import org.eclipse.e4.core.services.events.IEventBroker; +import org.eclipse.e4.tools.event.spy.core.EventMonitor; +import org.eclipse.e4.tools.event.spy.model.CapturedEvent; +import org.eclipse.e4.tools.event.spy.model.CapturedEventTreeSelection; +import org.eclipse.e4.tools.event.spy.util.LoggerWrapper; +import org.eclipse.e4.tools.event.spy.util.PDEUtils; +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.RowData; +import org.eclipse.swt.layout.RowLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Shell; + +public class SpyDialog extends Dialog implements EventMonitor.NewEventListener { + private final static String DIALOG_TITLE = "Event spy dialog"; + + private final static String[] SHOW_FILTER_LINK_TEXT = new String[]{"Show filters", "Hide filters"}; + + private CapturedEventTree capturedEventTree; + + private CapturedEventFilters capturedEventFilters; + + private Composite outer; + + private EventMonitor eventMonitor; + + private ToggleLink showFiltersLink; + + @Inject + private LoggerWrapper logger; + + @Inject + private IEventBroker eventBroker; + + @Inject + public SpyDialog(Shell shell) { + super(shell); + setShellStyle(SWT.DIALOG_TRIM | SWT.RESIZE); + } + + /* Layout scheme: + * + * +-- Outer ----------------------------------------+ + * | +-- actionBar --------------------------------+ | + * | | | | + * | | Start capturing events | ShowFiltersLink | | + * | | | | + * | +---------------------------------------------+ | + * +-------------------------------------------------+ + * | | + * | CapturedEventFilters | + * | | + * +-------------------------------------------------+ + * | | + * | CapturedEventTree | + * | | + * +-------------------------------------------------+ + * | | + * | Close | + * | | + * +-------------------------------------------------+ + * + * */ + + @Override + protected Point getInitialSize() { + return new Point(600, 400); + } + + @Override + protected Control createDialogArea(Composite parent) { + outer = (Composite) super.createDialogArea(parent); + + createActionBar(outer); + createFilters(outer); + createCapturedEventTree(outer); + + return outer; + } + + private void createActionBar(Composite parent) { + Composite actionBar = new Composite(parent, SWT.NONE); + GridData gridData = createDefaultGridData(); + gridData.grabExcessVerticalSpace = false; + actionBar.setLayoutData(gridData); + + RowLayout rowLayout = new RowLayout(SWT.HORIZONTAL); + rowLayout.spacing = 20; + actionBar.setLayout(rowLayout); + + ToggleLink link = new ToggleLink(actionBar); + link.setText(new String[]{"Start capturing events", "Stop capturing events"}); + link.setClickListener(new ToggleLink.ClickListener() { + public void clicked(boolean toggled) { + if (toggled) { + captureEvents(); + } else { + stopCaptureEvents(); + } + } + }); + + showFiltersLink = new ToggleLink(actionBar); + showFiltersLink.setText(new String[]{SHOW_FILTER_LINK_TEXT[0], SHOW_FILTER_LINK_TEXT[1]}); + showFiltersLink.getControl().setLayoutData(new RowData(130, SWT.DEFAULT)); + showFiltersLink.setClickListener(new ToggleLink.ClickListener() { + public void clicked(boolean toggled) { + showFilters(toggled); + } + }); + } + + private void createFilters(Composite parent) { + capturedEventFilters = new CapturedEventFilters(outer); + capturedEventFilters.getControl().setVisible(false); + GridData gridData = createDefaultGridData(); + gridData.grabExcessVerticalSpace = false; + gridData.exclude = true; + capturedEventFilters.getControl().setLayoutData(gridData); + } + + private void createCapturedEventTree(Composite parent) { + capturedEventTree = new CapturedEventTree(outer); + capturedEventTree.getControl().setLayoutData(createDefaultGridData()); + capturedEventTree.setSelectionListener(new CapturedEventTree.SelectionListener() { + public void selectionChanged(CapturedEventTreeSelection selection) { + openResource(selection); + } + }); + } + + @Override + protected void configureShell(Shell newShell) { + super.configureShell(newShell); + newShell.setText(DIALOG_TITLE); + } + + @Override + protected void createButtonsForButtonBar(Composite parent) { + createButton(parent, IDialogConstants.OK_ID, "Close", false); + } + + public void captureEvents() { + capturedEventTree.removeAll(); + if (eventMonitor == null) { + eventMonitor = new EventMonitor(eventBroker); + eventMonitor.setNewEventListener(this); + } + eventMonitor.start(capturedEventFilters.getFilters()); + getShell().setText(DIALOG_TITLE + " - capturing..."); + } + + public void stopCaptureEvents() { + if (eventMonitor != null) { + eventMonitor.stop(); + } + getShell().setText(DIALOG_TITLE); + } + + public void newEvent(CapturedEvent event) { + capturedEventTree.addEvent(event); + } + + private void openResource(CapturedEventTreeSelection selection) { + String name = selection.getSelection(); + if (selection.isParameter()) { + String[] splitted = selection.getSelection().split("="); + if (splitted.length == 2) { + name = splitted[1]; + } + } + + try { + PDEUtils.openClass(name); + } catch(ClassNotFoundException exc) { + logger.warn(exc.getMessage()); + } + } + + private void showFilters(boolean filtersVisible) { + capturedEventFilters.getControl().setVisible(filtersVisible); + ((GridData) capturedEventFilters.getControl().getLayoutData()).exclude = !filtersVisible; + + //Filters have been set and filters UI is not visible so we have to mark it to user + if (!filtersVisible && capturedEventFilters.hasFilters()) { + showFiltersLink.setText(new String[] { String.format("%s (%d)", SHOW_FILTER_LINK_TEXT[0], + capturedEventFilters.getFiltersCount()), SHOW_FILTER_LINK_TEXT[1]}); + } else { + showFiltersLink.setText(new String[] {SHOW_FILTER_LINK_TEXT[0], SHOW_FILTER_LINK_TEXT[1]}); + } + + outer.layout(false); + } + + private GridData createDefaultGridData() { + GridData gridData = new GridData(); + gridData.verticalAlignment = GridData.FILL; + gridData.verticalSpan = 2; + gridData.grabExcessVerticalSpace = true; + gridData.horizontalAlignment = GridData.FILL; + gridData.grabExcessHorizontalSpace = true; + return gridData; + } + + /** for testing/modifying dialog UI + public static void main(String... args) { + Display display = new Display (); + Shell shell = new Shell (display); + shell.open (); + + SpyDialog dialog = new SpyDialog(shell); + + dialog.open(); + while (!shell.isDisposed()) { + if (!display.readAndDispatch ()) display.sleep (); + } + display.dispose (); + } + */ +} diff --git a/bundles/org.eclipse.e4.tools.event.spy/src/org/eclipse/e4/tools/event/spy/ui/ToggleLink.java b/bundles/org.eclipse.e4.tools.event.spy/src/org/eclipse/e4/tools/event/spy/ui/ToggleLink.java new file mode 100644 index 00000000..58e71944 --- /dev/null +++ b/bundles/org.eclipse.e4.tools.event.spy/src/org/eclipse/e4/tools/event/spy/ui/ToggleLink.java @@ -0,0 +1,69 @@ +/******************************************************************************* + * Copyright (c) 2013 IBM Corporation and others. + * 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.e4.tools.event.spy.ui; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Link; +import org.eclipse.swt.widgets.Listener; + +public class ToggleLink { + private Link link; + + private ClickListener listener; + + private String[] text = {"", ""}; + + public interface ClickListener { + void clicked(boolean toggled); + } + + public ToggleLink(Composite parent) { + link = new Link(parent, SWT.NONE); + link.setSize(SWT.DEFAULT, SWT.DEFAULT); + link.addListener (SWT.Selection, new Listener() { + public void handleEvent(Event event) { + updateText(); + if (listener != null) { + listener.clicked(isToggled()); + } + } + }); + } + + private void updateText() { + String textToUpdate = link.getText().contains(text[0])? text[1]: text[0]; + setText(textToUpdate); + } + + private void setText(String text) { + link.setText(String.format("<a>%s</a>", text)); + } + + public void setClickListener(ClickListener listener) { + this.listener = listener; + } + + public void setText(String[] text /*normal text, toggle text*/) { + this.text = text; + setText(isToggled()? text[1]: text[0]); + } + + public Control getControl() { + return link; + } + + private boolean isToggled() { + return link.getText().contains(text[1]); + } +} diff --git a/bundles/org.eclipse.e4.tools.event.spy/src/org/eclipse/e4/tools/event/spy/util/LoggerWrapper.java b/bundles/org.eclipse.e4.tools.event.spy/src/org/eclipse/e4/tools/event/spy/util/LoggerWrapper.java new file mode 100644 index 00000000..cb3a95d5 --- /dev/null +++ b/bundles/org.eclipse.e4.tools.event.spy/src/org/eclipse/e4/tools/event/spy/util/LoggerWrapper.java @@ -0,0 +1,111 @@ +/******************************************************************************* + * Copyright (c) 2013 IBM Corporation and others. + * 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.e4.tools.event.spy.util; + +import javax.inject.Inject; + +import org.eclipse.e4.core.di.annotations.Creatable; +import org.eclipse.e4.core.di.annotations.Optional; +import org.eclipse.e4.core.services.log.Logger; +import org.eclipse.e4.tools.event.spy.Constants; + +@Creatable +public class LoggerWrapper extends Logger { + @Optional + @Inject + private Logger logger; + + @Override + public boolean isErrorEnabled() { + if (logger != null) { + return logger.isErrorEnabled(); + } + return false; + } + + @Override + public boolean isTraceEnabled() { + if (logger != null) { + return logger.isTraceEnabled(); + } + return false; + } + + @Override + public boolean isWarnEnabled() { + if (logger != null) { + return logger.isWarnEnabled(); + } + return false; + } + + @Override + public boolean isInfoEnabled() { + if (logger != null) { + return logger.isInfoEnabled(); + } + return false; + } + + @Override + public boolean isDebugEnabled() { + if (logger != null) { + return logger.isDebugEnabled(); + } + return false; + } + + @Override + public void error(Throwable t, String message) { + if (logger != null && isErrorEnabled()) { + logger.error(t, withPluginInfo(message)); + } + } + + @Override + public void warn(Throwable t, String message) { + if (logger != null && isWarnEnabled()) { + logger.warn(t, withPluginInfo(message)); + } + } + + @Override + public void info(Throwable t, String message) { + if (logger != null && isInfoEnabled()) { + logger.info(t, withPluginInfo(message)); + } + } + + @Override + public void trace(Throwable t, String message) { + if (logger != null && isTraceEnabled()) { + logger.trace(t, withPluginInfo(message)); + } + } + + @Override + public void debug(Throwable t) { + if (logger != null && isDebugEnabled()) { + logger.debug(t); + } + } + + @Override + public void debug(Throwable t, String message) { + if (logger != null && isDebugEnabled()) { + logger.debug(t, withPluginInfo(message)); + } + } + + private String withPluginInfo(String message) { + return String.format("Plugin '%s': %s", Constants.PLUGIN_ID, message); + } +} diff --git a/bundles/org.eclipse.e4.tools.event.spy/src/org/eclipse/e4/tools/event/spy/util/PDEUtils.java b/bundles/org.eclipse.e4.tools.event.spy/src/org/eclipse/e4/tools/event/spy/util/PDEUtils.java new file mode 100644 index 00000000..274aadf5 --- /dev/null +++ b/bundles/org.eclipse.e4.tools.event.spy/src/org/eclipse/e4/tools/event/spy/util/PDEUtils.java @@ -0,0 +1,87 @@ +/******************************************************************************* + * Copyright (c) 2013 IBM Corporation and others. + * 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.e4.tools.event.spy.util; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.jdt.core.IJavaProject; +import org.eclipse.jdt.core.IType; +import org.eclipse.jdt.core.JavaCore; +import org.eclipse.jdt.core.JavaModelException; +import org.eclipse.jdt.ui.JavaUI; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.osgi.util.NLS; +import org.eclipse.pde.core.plugin.IPluginModelBase; +import org.eclipse.pde.core.plugin.PluginRegistry; +import org.eclipse.pde.internal.core.PDECore; +import org.eclipse.pde.internal.core.SearchablePluginsManager; +import org.eclipse.pde.internal.runtime.PDERuntimeMessages; +import org.eclipse.pde.internal.runtime.PDERuntimePlugin; +import org.eclipse.swt.widgets.Display; +import org.eclipse.ui.PartInitException; + +public class PDEUtils { + private final static Pattern CLASS_NAME_PATTERN = Pattern.compile("(([a-zA-Z_]+[0-9]*\\.)+[a-zA-Z_]+[a-z0-9]*)"); + + public static void openClass(String clsName) throws ClassNotFoundException { + Matcher matcher = CLASS_NAME_PATTERN.matcher(clsName); + if (matcher.find()) { + try { + clsName = matcher.group(1).trim(); + openClass(Class.forName(clsName)); + } catch(ClassNotFoundException exc) { + throw new ClassNotFoundException("Class not found in the bundle classpath: " + clsName); + } + } + } + + public static void openClass(Class<?> cls) { + IPluginModelBase model = PluginRegistry.findModel(PluginUtils.getBundleId(cls)); + IResource resource = model != null ? model.getUnderlyingResource() : null; + IJavaProject project = null; + + // if we don't find a model + if (model == null) { + MessageDialog.openError(Display.getCurrent().getActiveShell(), PDERuntimeMessages.SpyIDEUtil_noSourceFound_title, + NLS.bind(PDERuntimeMessages.SpyIDEUtil_noSourceFound_message, new Object[] {cls.getName()})); + return; + } + + if (resource != null) { // project is open in workspace + project = JavaCore.create(resource.getProject()); + } else { + SearchablePluginsManager manager = PDECore.getDefault().getSearchablePluginsManager(); + try { + manager.createProxyProject(new NullProgressMonitor()); + manager.addToJavaSearch(new IPluginModelBase[] {model}); + project = manager.getProxyProject(); + } catch (CoreException e) { + } + } + if (project != null) + openInEditor(project, cls.getName()); + } + + private static void openInEditor(IJavaProject project, String clazz) { + try { + IType type = project.findType(clazz); + JavaUI.openInEditor(type, false, true); + } catch (JavaModelException e) { + PDERuntimePlugin.log(e); + } catch (PartInitException e) { + PDERuntimePlugin.log(e); + } + } +} diff --git a/bundles/org.eclipse.e4.tools.event.spy/src/org/eclipse/e4/tools/event/spy/util/ParameterFormatter.java b/bundles/org.eclipse.e4.tools.event.spy/src/org/eclipse/e4/tools/event/spy/util/ParameterFormatter.java new file mode 100644 index 00000000..9ebc147c --- /dev/null +++ b/bundles/org.eclipse.e4.tools.event.spy/src/org/eclipse/e4/tools/event/spy/util/ParameterFormatter.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright (c) 2013 IBM Corporation and others. + * 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.e4.tools.event.spy.util; + +import org.eclipse.e4.tools.event.spy.model.Parameter; + +public class ParameterFormatter { + //TODO: Add some parameter formatting and break to long strings into multiple lines + public static String toString(Parameter parameter) { + return String.format("%s = %s", parameter.getName(), parameter.getValue()); + } +} diff --git a/bundles/org.eclipse.e4.tools.event.spy/src/org/eclipse/e4/tools/event/spy/util/PluginUtils.java b/bundles/org.eclipse.e4.tools.event.spy/src/org/eclipse/e4/tools/event/spy/util/PluginUtils.java new file mode 100644 index 00000000..cf3524f2 --- /dev/null +++ b/bundles/org.eclipse.e4.tools.event.spy/src/org/eclipse/e4/tools/event/spy/util/PluginUtils.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright (c) 2013 IBM Corporation and others. + * 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.e4.tools.event.spy.util; + +import org.eclipse.e4.tools.event.spy.Constants; +import org.osgi.framework.Bundle; +import org.osgi.framework.FrameworkUtil; + +public class PluginUtils { + public static String getContributorURI() { + return String.format("platform:/plugin/%s", Constants.PLUGIN_ID); + } + + public static String getContributionURI(Class<?> contributionCls) { + return String.format("bundleclass://%s/%s", Constants.PLUGIN_ID, contributionCls.getName()); + } + + public static String getBundleId(Class<?> cls) { + Bundle bundle = FrameworkUtil.getBundle(cls); + if (bundle == null) { + throw new IllegalArgumentException("Cannot find bundle for class: " + cls.getName()); + } + return bundle.getSymbolicName(); + } +} diff --git a/features/org.eclipse.e4.tools.event.spy.feature/.project b/features/org.eclipse.e4.tools.event.spy.feature/.project new file mode 100644 index 00000000..fc6d26cd --- /dev/null +++ b/features/org.eclipse.e4.tools.event.spy.feature/.project @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.e4.tools.event.spy.feature</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.pde.FeatureBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.FeatureNature</nature>
+ </natures>
+</projectDescription>
diff --git a/features/org.eclipse.e4.tools.event.spy.feature/build.properties b/features/org.eclipse.e4.tools.event.spy.feature/build.properties new file mode 100644 index 00000000..b3a611b5 --- /dev/null +++ b/features/org.eclipse.e4.tools.event.spy.feature/build.properties @@ -0,0 +1,2 @@ +bin.includes = feature.xml,\ + feature.properties diff --git a/features/org.eclipse.e4.tools.event.spy.feature/feature.properties b/features/org.eclipse.e4.tools.event.spy.feature/feature.properties new file mode 100644 index 00000000..ebea9fc0 --- /dev/null +++ b/features/org.eclipse.e4.tools.event.spy.feature/feature.properties @@ -0,0 +1,147 @@ +############################################################################### +# Copyright (c) 2013 IBM Corporation and others. +# 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: +# IBM Corporation - initial API and implementation +############################################################################### +# feature.properties +# contains externalized strings for feature.xml +# "%foo" in feature.xml corresponds to the key "foo" in this file +# java.io.Properties file (ISO 8859-1 with "\" escapes) +# This file should be translated. + +# "featureName" property - name of the feature +featureName=E4 Event Spy (Incubation) + +# "providerName" property - name of the company that provides the feature +providerName=Eclipse.org + +# "updateSiteName" property - label for the update site +updateSiteName=The Eclipse Project Updates + +# "secondarySiteName" property - label for the update site +secondaryUpdateSiteName= + +# "description" property - description of the feature +description=E4 Event Spy + +# "copyright" property - text of the "Feature Update Copyright" +copyright=\ +Copyright (c) 2013 IBM Corporation and others.\n\ +All rights reserved. This program and the accompanying materials\n\ +are made available under the terms of the Eclipse Public License v1.0\n\ +which accompanies this distribution, and is available at\n\ +http://www.eclipse.org/legal/epl-v10.html\n\ +\n\ +Contributors:\n\ + IBM Corporation - initial API and implementation\n +################ end of copyright property #################################### + +# "licenseURL" property - URL of the "Feature License" +# do not translate value - just change to point to a locale-specific HTML page +licenseURL=license.html + +# "license" property - text of the "Feature Update License" +# should be plain text version of license agreement pointed to be "licenseURL" +license=\ +ECLIPSE FOUNDATION SOFTWARE USER AGREEMENT\n\ +March 17, 2005\n\ +\n\ +Usage Of Content\n\ +\n\ +THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION AND/OR\n\ +OTHER MATERIALS FOR OPEN SOURCE PROJECTS (COLLECTIVELY "CONTENT").\n\ +USE OF THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS\n\ +AGREEMENT AND/OR THE TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR\n\ +NOTICES INDICATED OR REFERENCED BELOW. BY USING THE CONTENT, YOU\n\ +AGREE THAT YOUR USE OF THE CONTENT IS GOVERNED BY THIS AGREEMENT\n\ +AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS\n\ +OR NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE\n\ +TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND CONDITIONS\n\ +OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED\n\ +BELOW, THEN YOU MAY NOT USE THE CONTENT.\n\ +\n\ +Applicable Licenses\n\ +\n\ +Unless otherwise indicated, all Content made available by the Eclipse Foundation\n\ +is provided to you under the terms and conditions of the Eclipse Public\n\ +License Version 1.0 ("EPL"). A copy of the EPL is provided with this\n\ +Content and is also available at http://www.eclipse.org/legal/epl-v10.html.\n\ +For purposes of the EPL, "Program" will mean the Content.\n\ +\n\ +Content includes, but is not limited to, source code, object code,\n\ +documentation and other files maintained in the Eclipse.org CVS\n\ +repository ("Repository") in CVS modules ("Modules") and made available\n\ +as downloadable archives ("Downloads").\n\ +\n\ + - Content may be structured and packaged into modules to facilitate delivering,\n\ + extending, and upgrading the Content. Typical modules may include plug-ins ("Plug-ins"),\n\ + plug-in fragments ("Fragments"), and features ("Features").\n\ + - Each Plug-in or Fragment may be packaged as a sub-directory or JAR (Java? ARchive)\n\ + in a directory named "plugins".\n\ + - A Feature is a bundle of one or more Plug-ins and/or Fragments and associated material.\n\ + Each Feature may be packaged as a sub-directory in a directory named "features".\n\ + Within a Feature, files named "feature.xml" may contain a list of the names and version\n\ + numbers of the Plug-ins and/or Fragments associated with that Feature.\n\ + - Features may also include other Features ("Included Features"). Within a Feature, files\n\ + named "feature.xml" may contain a list of the names and version numbers of Included Features.\n\ +\n\ +Features may also include other Features ("Included Features"). Files named\n\ +"feature.xml" may contain a list of the names and version numbers of\n\ +Included Features.\n\ +\n\ +The terms and conditions governing Plug-ins and Fragments should be\n\ +contained in files named "about.html" ("Abouts"). The terms and\n\ +conditions governing Features and Included Features should be contained\n\ +in files named "license.html" ("Feature Licenses"). Abouts and Feature\n\ +Licenses may be located in any directory of a Download or Module\n\ +including, but not limited to the following locations:\n\ +\n\ + - The top-level (root) directory\n\ + - Plug-in and Fragment directories\n\ + - Inside Plug-ins and Fragments packaged as JARs\n\ + - Sub-directories of the directory named "src" of certain Plug-ins\n\ + - Feature directories\n\ +\n\ +Note: if a Feature made available by the Eclipse Foundation is installed using the\n\ +Eclipse Update Manager, you must agree to a license ("Feature Update\n\ +License") during the installation process. If the Feature contains\n\ +Included Features, the Feature Update License should either provide you\n\ +with the terms and conditions governing the Included Features or inform\n\ +you where you can locate them. Feature Update Licenses may be found in\n\ +the "license" property of files named "feature.properties". Such Abouts,\n\ +Feature Licenses and Feature Update Licenses contain the terms and\n\ +conditions (or references to such terms and conditions) that govern your\n\ +use of the associated Content in that directory.\n\ +\n\ +THE ABOUTS, FEATURE LICENSES AND FEATURE UPDATE LICENSES MAY REFER\n\ +TO THE EPL OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS.\n\ +SOME OF THESE OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):\n\ +\n\ + - Common Public License Version 1.0 (available at http://www.eclipse.org/legal/cpl-v10.html)\n\ + - Apache Software License 1.1 (available at http://www.apache.org/licenses/LICENSE)\n\ + - Apache Software License 2.0 (available at http://www.apache.org/licenses/LICENSE-2.0)\n\ + - IBM Public License 1.0 (available at http://oss.software.ibm.com/developerworks/opensource/license10.html)\n\ + - Metro Link Public License 1.00 (available at http://www.opengroup.org/openmotif/supporters/metrolink/license.html)\n\ + - Mozilla Public License Version 1.1 (available at http://www.mozilla.org/MPL/MPL-1.1.html)\n\ +\n\ +IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR\n\ +TO USE OF THE CONTENT. If no About, Feature License or Feature Update License\n\ +is provided, please contact the Eclipse Foundation to determine what terms and conditions\n\ +govern that particular Content.\n\ +\n\ +Cryptography\n\ +\n\ +Content may contain encryption software. The country in which you are\n\ +currently may have restrictions on the import, possession, and use,\n\ +and/or re-export to another country, of encryption software. BEFORE\n\ +using any encryption software, please check the country's laws,\n\ +regulations and policies concerning the import, possession, or use,\n\ +and re-export of encryption software, to see if this is permitted.\n\ +\n\ +Java and all Java-based trademarks are trademarks of Sun Microsystems, Inc. in the United States, other countries, or both.\n +########### end of license property ########################################## diff --git a/features/org.eclipse.e4.tools.event.spy.feature/feature.xml b/features/org.eclipse.e4.tools.event.spy.feature/feature.xml new file mode 100644 index 00000000..9b314be9 --- /dev/null +++ b/features/org.eclipse.e4.tools.event.spy.feature/feature.xml @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="UTF-8"?> +<feature + id="org.eclipse.e4.tools.event.spy.feature" + label="%featureName" + version="0.15.0.qualifier" + provider-name="%providerName"> + + <description> + %description + </description> + + <copyright> + %copyright + </copyright> + + <license url="%licenseURL"> + %license + </license> + + <plugin + id="org.eclipse.e4.tools.event.spy" + download-size="0" + install-size="0" + version="0.0.0" + unpack="false"/> + +</feature> diff --git a/features/org.eclipse.e4.tools.event.spy.feature/forceQualifierUpdate.txt b/features/org.eclipse.e4.tools.event.spy.feature/forceQualifierUpdate.txt new file mode 100644 index 00000000..2e3e3376 --- /dev/null +++ b/features/org.eclipse.e4.tools.event.spy.feature/forceQualifierUpdate.txt @@ -0,0 +1,2 @@ +# To force a version qualifier update add the bug here + diff --git a/features/org.eclipse.e4.tools.event.spy.feature/license.html b/features/org.eclipse.e4.tools.event.spy.feature/license.html new file mode 100644 index 00000000..c6af966b --- /dev/null +++ b/features/org.eclipse.e4.tools.event.spy.feature/license.html @@ -0,0 +1,79 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN"> +<html> +<head> +<meta http-equiv=Content-Type content="text/html; charset=iso-8859-1"> +<title>Eclipse.org Software User Agreement</title> +</head> + +<body lang="EN-US" link=blue vlink=purple> +<h2>Eclipse Foundation Software User Agreement</h2> +<p>March 17, 2005</p> + +<h3>Usage Of Content</h3> + +<p>THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION AND/OR OTHER MATERIALS FOR OPEN SOURCE PROJECTS + (COLLECTIVELY "CONTENT"). USE OF THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS AGREEMENT AND/OR THE TERMS AND + CONDITIONS OF LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW. BY USING THE CONTENT, YOU AGREE THAT YOUR USE + OF THE CONTENT IS GOVERNED BY THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS OR + NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND + CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU MAY NOT USE THE CONTENT.</p> + +<h3>Applicable Licenses</h3> + +<p>Unless otherwise indicated, all Content made available by the Eclipse Foundation is provided to you under the terms and conditions of the Eclipse Public License Version 1.0 + ("EPL"). A copy of the EPL is provided with this Content and is also available at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>. + For purposes of the EPL, "Program" will mean the Content.</p> + +<p>Content includes, but is not limited to, source code, object code, documentation and other files maintained in the Eclipse.org CVS repository ("Repository") in CVS + modules ("Modules") and made available as downloadable archives ("Downloads").</p> + +<ul> + <li>Content may be structured and packaged into modules to facilitate delivering, extending, and upgrading the Content. Typical modules may include plug-ins ("Plug-ins"), plug-in fragments ("Fragments"), and features ("Features").</li> + <li>Each Plug-in or Fragment may be packaged as a sub-directory or JAR (Java™ ARchive) in a directory named "plugins".</li> + <li>A Feature is a bundle of one or more Plug-ins and/or Fragments and associated material. Each Feature may be packaged as a sub-directory in a directory named "features". Within a Feature, files named "feature.xml" may contain a list of the names and version numbers of the Plug-ins + and/or Fragments associated with that Feature.</li> + <li>Features may also include other Features ("Included Features"). Within a Feature, files named "feature.xml" may contain a list of the names and version numbers of Included Features.</li> +</ul> + +<p>The terms and conditions governing Plug-ins and Fragments should be contained in files named "about.html" ("Abouts"). The terms and conditions governing Features and +Included Features should be contained in files named "license.html" ("Feature Licenses"). Abouts and Feature Licenses may be located in any directory of a Download or Module +including, but not limited to the following locations:</p> + +<ul> + <li>The top-level (root) directory</li> + <li>Plug-in and Fragment directories</li> + <li>Inside Plug-ins and Fragments packaged as JARs</li> + <li>Sub-directories of the directory named "src" of certain Plug-ins</li> + <li>Feature directories</li> +</ul> + +<p>Note: if a Feature made available by the Eclipse Foundation is installed using the Eclipse Update Manager, you must agree to a license ("Feature Update License") during the +installation process. If the Feature contains Included Features, the Feature Update License should either provide you with the terms and conditions governing the Included Features or +inform you where you can locate them. Feature Update Licenses may be found in the "license" property of files named "feature.properties" found within a Feature. +Such Abouts, Feature Licenses, and Feature Update Licenses contain the terms and conditions (or references to such terms and conditions) that govern your use of the associated Content in +that directory.</p> + +<p>THE ABOUTS, FEATURE LICENSES, AND FEATURE UPDATE LICENSES MAY REFER TO THE EPL OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS. SOME OF THESE +OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):</p> + +<ul> + <li>Common Public License Version 1.0 (available at <a href="http://www.eclipse.org/legal/cpl-v10.html">http://www.eclipse.org/legal/cpl-v10.html</a>)</li> + <li>Apache Software License 1.1 (available at <a href="http://www.apache.org/licenses/LICENSE">http://www.apache.org/licenses/LICENSE</a>)</li> + <li>Apache Software License 2.0 (available at <a href="http://www.apache.org/licenses/LICENSE-2.0">http://www.apache.org/licenses/LICENSE-2.0</a>)</li> + <li>IBM Public License 1.0 (available at <a href="http://oss.software.ibm.com/developerworks/opensource/license10.html">http://oss.software.ibm.com/developerworks/opensource/license10.html</a>)</li> + <li>Metro Link Public License 1.00 (available at <a href="http://www.opengroup.org/openmotif/supporters/metrolink/license.html">http://www.opengroup.org/openmotif/supporters/metrolink/license.html</a>)</li> + <li>Mozilla Public License Version 1.1 (available at <a href="http://www.mozilla.org/MPL/MPL-1.1.html">http://www.mozilla.org/MPL/MPL-1.1.html</a>)</li> +</ul> + +<p>IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR TO USE OF THE CONTENT. If no About, Feature License, or Feature Update License is provided, please +contact the Eclipse Foundation to determine what terms and conditions govern that particular Content.</p> + +<h3>Cryptography</h3> + +<p>Content may contain encryption software. The country in which you are currently may have restrictions on the import, possession, and use, and/or re-export to + another country, of encryption software. BEFORE using any encryption software, please check the country's laws, regulations and policies concerning the import, + possession, or use, and re-export of encryption software, to see if this is permitted.</p> + +<small>Java and all Java-based trademarks are trademarks of Sun Microsystems, Inc. in the United States, other countries, or both.</small> +</body> +</html> diff --git a/features/org.eclipse.e4.tools.event.spy.feature/pom.xml b/features/org.eclipse.e4.tools.event.spy.feature/pom.xml new file mode 100644 index 00000000..6135106e --- /dev/null +++ b/features/org.eclipse.e4.tools.event.spy.feature/pom.xml @@ -0,0 +1,48 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.eclipse.e4.tools</groupId> + <artifactId>e4-tools-aggregator</artifactId> + <version>0.15.0-SNAPSHOT</version> + <relativePath>../../</relativePath> + </parent> + + <groupId>org.eclipse.e4</groupId> + <artifactId>org.eclipse.e4.tools.event.spy.feature</artifactId> + <version>0.15.0.qualifier</version> + <packaging>eclipse-feature</packaging> + + <build> + <plugins> + <plugin> + <groupId>org.eclipse.tycho.extras</groupId> + <artifactId>tycho-source-feature-plugin</artifactId> + <executions> + <execution> + <phase>package</phase> + <id>source-feature</id> + <goals> + <goal>source-feature</goal> + </goals> + </execution> + </executions> + </plugin> + <plugin> + <groupId>org.eclipse.tycho</groupId> + <artifactId>tycho-p2-plugin</artifactId> + <version>${tycho.version}</version> + <executions> + <execution> + <id>attached-p2-metadata</id> + <phase>package</phase> + <goals> + <goal>p2-metadata</goal> + </goals> + </execution> + </executions> + </plugin> + </plugins> + </build> + +</project>
\ No newline at end of file @@ -50,10 +50,12 @@ <module>./bundles/org.eclipse.e4.tools.css.editor.ui</module> <module>./bundles/org.eclipse.e4.tools.css.editor</module> <module>./bundles/org.eclipse.e4.tools.css.spy</module> + <module>./bundles/org.eclipse.e4.tools.event.spy</module> <module>./features/org.eclipse.e4.core.tools.feature</module> <module>./features/org.eclipse.e4.tools.css.editor.feature</module> <module>./features/org.eclipse.e4.tools.css.spy.feature</module> <module>./features/org.eclipse.e4.tools.e3x.bridge.feature</module> + <module>./features/org.eclipse.e4.tools.event.spy.feature</module> <module>./build/org.eclipse.e4.core.tools.update/</module> </modules> </project> |