How to assign a shortcut key to run a particular EASE script - eclipse

I am curious whether it is possible to assign a shortcut key to run a particular EASE script. I know that I can add scripts to UI, but for me applying of shortcut keys is more familiar and convenient way to do my work.
Maybe, first I should create a popup-menu item and then assign a key to the item. So I've added the context menu item but I can not find any reference to the item in Preferences>>General>>Keys.

I find out the way to run a particular EASE script typing a sequence of keys:
create an eclipse plugin project;
add extension points to define a key binding, a command handler and an ease module;
write a module class and a command handler class.
The command handler's method called "execute" is invoked when I type the sequence of keys. As I can use the module to access the command handler synchronously, so I can assign code to be run from within the "execute" method.
This is plugin.xml:
<?xml version="1.0" encoding="UTF-8"?>
<?eclipse version="3.4"?>
<plugin>
<extension point="org.eclipse.ui.bindings">
<key sequence="Ctrl+Shift+D"
commandId="m5.command_0"
schemeId="org.eclipse.ui.defaultAcceleratorConfiguration"
contextId="org.eclipse.jdt.ui.javaEditorScope"/>
</extension>
<extension point="org.eclipse.ui.commands">
<command name="Execute custom command"
defaultHandler="m5.handlers.CustomHandler_0"
description="Execute custom command"
categoryId="org.eclipse.jdt.ui.category.source"
id="m5.command_0">
</command>
</extension>
<extension
point="org.eclipse.ease.modules">
<module
category="org.eclipse.ease.category.system"
class="m5.handlers.Module1"
id="M5.module1"
name="M5.module1"
visible="true">
</module>
</extension>
</plugin>
This is the command handler:
package m5.handlers;
import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
public class CustomHandler_0 extends AbstractHandler {
private static Runnable runnable;
protected synchronized static void setRunnableToExecute(Runnable codeToRun){
runnable = codeToRun;
}
#Override
public Object execute(ExecutionEvent arg0) throws ExecutionException {
System.out.println("command_0");
if(runnable != null){
runnable.run();
}
return null;
}
}
This is the module:
package m5.handlers;
import org.eclipse.ease.modules.AbstractScriptModule;
import org.eclipse.ease.modules.WrapToScript;
import m5.handlers.CustomHandler_0;
public class Module1 extends AbstractScriptModule{
#WrapToScript
public void setCommand_0(String code){
CustomHandler_0.setRunnableToExecute(new Runnable(){
#Override
public void run() {
getScriptEngine().executeAsync(code);
}
});
}
}

Related

Unable to open multiple selected files and folders using Eclipse ShowInSystemExplorerHandler API

Hi I am using Eclipse ShowInSystemExplorerHandler API, it is working fine if I select a single file or folder. But it does not work for multiple selection of files or folders. I provide below the code snippet. Please help me how to resolve so that I should be able to open multiple folders/files in OS specific explorer. By the way I am using structuredSelection.forEach so that I can open all the files and folders.
Find below the code.
#SuppressWarnings("restriction")
public class OpenExplorerHandler extends AbstractHandler {
#Override
public Object execute(ExecutionEvent event) throws ExecutionException {
IWorkbenchWindow window = HandlerUtil.getActiveWorkbenchWindowChecked(event);
ISelectionService service = window.getSelectionService();
IStructuredSelection structuredSelection = (IStructuredSelection) service.getSelection();
structuredSelection.forEach( selctionElement -> {
if (selctionElement instanceof IAdaptable) {
IResource resource = (IResource) ((IAdaptable) selctionElement).getAdapter(IResource.class);
File selectedFileFolder = resource.getLocation().toFile();
String filePath = selectedFileFolder.getAbsolutePath();
ECommandService commandService = PlatformUI.getWorkbench().getService(ECommandService.class);
EHandlerService handlerService = PlatformUI.getWorkbench().getService(EHandlerService.class);
Command command = commandService.getCommand(ShowInSystemExplorerHandler.ID);
if (command.isDefined()) {
ParameterizedCommand parameterizedCommand = commandService
.createCommand(ShowInSystemExplorerHandler.ID, Collections.singletonMap(
ShowInSystemExplorerHandler.RESOURCE_PATH_PARAMETER, filePath));
if (handlerService.canExecute(parameterizedCommand)) {
handlerService.executeHandler(parameterizedCommand);
}
}
}
});
return null;
}
}
The implementation of the ShowInSystemExplorerHandler command handler turns out to be rather odd. Although you can pass the resource to open as a parameter (which you are doing) it still looks at the number of items currently selected to determine if the handler is enabled and will only be enabled when exactly one item is selected.
If you debug the code you will see that handlerService.canExecute(parameterizedCommand) is returning false because more that one item is selected.
So it doesn't look like you can use this directly with multiple items selected.
What you can do is define your own command and handler that calls the same code. Something like:
<extension
point="org.eclipse.ui.commands">
<command
categoryId="org.eclipse.ui.category.navigate"
name="show in explorer"
id="my.showInSystemExplorer"
description="Show in Explorer">
<commandParameter
id="org.eclipse.ui.ide.showInSystemExplorer.path"
name="Resource path"
optional="false">
</commandParameter>
</command>
</extension>
<extension
point="org.eclipse.ui.handlers">
<handler
class="org.eclipse.ui.internal.ide.handlers.ShowInSystemExplorerHandler"
commandId="my.showInSystemExplorer">
</handler>
</extension>
Then replace ShowInSystemExplorerHandler.ID in the code with the id of your command (my.showInSystemExplorer in the example).

Xtext, get Iselection Input in the LaunchMydslShortcut

I'm trying to make a simple DSL with Xtext and execute it with an interpreter, the grammar is the initial Hello Word project.
I can can execute the .Text file successfully.
In the org.xtext.example.mydsl.ui project I write this in the plugin.xml file To run the Project from my class LaunchMydslShortcut.
<extension
point="org.eclipse.debug.ui.launchShortcuts">
<shortcut
class="org.xtext.example.mydsl.ui.MyDslExecutableExtensionFactory:org.xtext.example.mydsl.ui.launch.LaunchMydslShortcut"
icon="icon/sample.gif"
id="org.xtext.example.mydsl.u.launchMyDsl"
label="MyDsll"
modes="run">
<contextualLaunch>
<enablement>
<with variable="selection">
<count value="1"/>
<iterate
ifEmpty="false"
operator="and">
<adapt type="org.eclipse.core.resources.IFile"/>
<test property="org.eclipse.debug.ui.matchesPattern"
value="*.mydsl"/>
</iterate>
</with>
</enablement>
<contextLabel
mode="run"
label="Run Mydsl"/>
</contextualLaunch>
</shortcut>
</extension>
This is my LaunchMydslShortcut class :
class LaunchMydslShortcut implements ILaunchShortcut {
#Inject
private IResourceForEditorInputFactory resourceFactory;
override launch(ISelection selection, String mode) {
println("launch from selection")
}
override launch(IEditorPart editor, String mode) {
val input = editor.editorInput
if (editor instanceof XtextEditor && input instanceof FileEditorInput) {
val resource = resourceFactory.createResource(input)
resource.load(newHashMap())
println("launch Doooone")
}
}
}
However, I'm expecting to use launch(IEditorPart editor, String mode) function, but it executes the launch(ISelection selection, String mode).
so the question would be, what's the différence between the two? why my project is using the first? and how do I use the second?
The first one void launch(ISelection selection, String mode) is called when you launch your generator from the package explorer for example.
The second one void launch(IEditorPart editor, String mode) is called when launching from an editor context menu.
You can use a Utility to get the input file you need and then create an IResource.
Good example is in org.eclipse.xtext.xtext.launcher.WorkflowLaunchUtils.workflowFileFor(ISelection) and org.eclipse.xtext.xtext.launcher.WorkflowLaunchUtils.workflowFileFor(IEditorPart) it works with mwe2 files but it is easy to adopt it for your DSL.

Can I order my TestNG listeners?

I have a situation where I need to enable/disable tests(using AnnotationTransformer listener) based on the parameter coming from my suite files(using ISuiteListener listener). However, when I try to read the parameters in my suite file before calling AnnotationTransformer, I am not able to do so.
This does not help:
<listeners preserve-order="true">
<listener class name="automation.test.SentinelSuiteListener" />
<listener class-name="automation.test.AnnotationTransformer" />
</listeners>
Also, when I try to implement both these interfaces together, the method for AnnoataionTransformer i.e. transform goes before the onStart() method:
public class AnnotationTransformer implements IAnnotationTransformer, ISuiteListener {
String currentRunModeInSuite;
#Override
public void onStart(ISuite suite) {
currentRunModeInSuite = suite.getParameter("currentRunMode");
}
#Override
public void transform(ITestAnnotation annotation, Class testClass, Constructor testConstructor, Method testMethod) {
System.out.println("***Test case under review : " + testMethod.getName());
for(int i=0; i<annotation.getGroups().length;i++){
System.out.println(annotation.getGroups()[i]);
}
System.out.println(currentRunModeInSuite);
}
#Override
public void onFinish(ISuite suite) {
// TODO Auto-generated method stub
}
}
The behavior you seen is the expected one because TestNG works step by step.
First, it looks for tests and reads their datas. You can be triggered if you want to change them and it's the goal of IAnnotationTransformer.
Then, TestNG runs suite/tests/classes/methods and you can be triggered by that with ISuiteListener or else.
What you need is IMethodInstance which is called during the run: http://testng.org/doc/documentation-main.html#methodinterceptors
Fyi, the <listeners> node doesn't accept preserve-order attribute. See the documentation: http://testng.org/testng-1.0.dtd.php

How can I use a JUnit RunListener in Eclipse?

I wrote a simple RunListener for JUnit which works quite well with Maven. I could register it for the maven-failsafe-plugin via
<properties>
<property>
<name>listener</name>
<value>com.asml.lcp.middleware.common.jboss.test.tps.TestDocumentationListener</value>
</property>
</properties>
and see the correct output from the listener.
Now I want to register the same RunListener in Eclipse to see the same output there, when I run the tests.
Is this possible? For testing purposes and to be consistent it would be nice to have the same output.
I have a set of tests that need a database to be executed. I want to create the database at the beginning of their execution and remove it at the end.
From maven I've also added a RunListener to the maven-surefire-plugin and it works fine. And I've also added a system property variable named ismaven. When I execute the test from maven this variable is initialized but when I execute the tests from the Eclipse, this variable is null (I access to the variable with System.getProperty).
<configuration>
<properties>
<property>
<name>listener</name>
<value>com.mycompany.MyRunListener</value>
</property>
</properties>
<systemPropertyVariables>
<ismaven>true</ismaven>
</systemPropertyVariables>
</configuration>
All my database tests inherit from a class that has a #BeforeClass and an #AfterClass methods. These methods check if the test is being executed by Maven or by the Eclipse checking the value of the ismaven property. If the test is being executed by maven, the ismaven property has a value and they do anything. But is the test is being executed by the Eclipse, the ismaven variable is null and they starts (#BeforeClass) or stops (#AfterClass) the database:
#BeforeClass
public static void checkIfStartDatabase() {
String ismaven = System.getProperty("ismaven");
// If it is not maven, start the database
if (ismaven == null) {
startDatabase();
}
}
#AfterClass
public static void checkIfStopDatabase() {
String ismaven = System.getProperty("ismaven");
// If it is not maven, stop the database
if (ismaven == null) {
stopDatabase();
}
}
This solution doesn't solve 100% your problem but if you implement it you can execute (and debug) all the tests of one JUnit class using the Eclipse and you can also execute all the tests of your project using Maven with the guarantee that you will execute once a piece of code before or after the execution of all your tests.
Yes, it is possible. Basically you have to implement your own Runner and inside the run method, you can add a custom run listener. I figured this out based on this post, point 2.
Here is my listener
public class TestLogger extends RunListener
{
public void testFinished(Description description)
{
System.out.println("Successful " + description.getMethodName());
}
}
and here is my Runner
public class TestRunner extends BlockJUnit4ClassRunner
{
public TestRunner(Class<?> klass) throws InitializationError
{
super(klass);
}
#Override
public void run(RunNotifier notifier)
{
notifier.addListener(new TestLogger()); // THIS IS THE IMPORTANT LINE
super.run(notifier);
}
}
and here is my actual junit test
#RunWith(TestRunner.class) // THIS LINE IS ALSO IMPORTANT
public class MyTest1
{
#Test
public void Test1() throws Exception
{
if (Math.random() < .5) throw new Exception("ouch");
assertFalse(Math.random() < .5);
}
}
You can run MyTest1 or the Test1 method using the context menu in Eclipse and it will invoke the testLogger as you would expect.
I did some more reseatrch on this. As far as I can see now, there is no way to add a run listener too the JUnit runs in Eclipse.

Confused about IAdaptable with IActionFilters

I'm confuse about IAdaptable and related classes. Which class is the adapter, the adaptee, the adaptable type?
[Context]
I have a context menu for entries of a table/tree viewer. Certain actions in the context menu must not be visible depending on the state of the respective object in the viewer (i.e. attribute value of a row in the table viewer).
I can achieve this with a config like this in plugin.xml:
<extension
point="org.eclipse.ui.popupMenus">
<objectContribution
adaptable="false"
id="<some_id>"
objectClass="<object_class_of_viewer_entry>">
<visibility>
<objectState name="buildable" value="true"/>
</visibility>
<action
class="<my_action_class>"
However, this only works if the object class implements org.eclipse.ui.IActionFilter.
[Problem]
My object class can't implement IActionFilter, I don't want to change its interface. Hence, I need to work around that using the IAdaptable mechanism.
Reading the Eclipse documentation left me all puzzled with terms (adapter, the adaptee, adaptable type) and I'm still confused about how to go about my problem.
The object class (referred to by in the above config) must remain untouched.
My approach was the following.
<extension
point="org.eclipse.core.runtime.adapters">
<factory
adaptableType="<object_class_of_viewer_entry>"
class="MyFactory">
<adapter
type="org.eclipse.ui.IActionFilter">
</adapter>
</factory>
</extension>
MyFactory is like this:
public class MyFactory implements IAdapterFactory {
private static final Class[] types = {
<object_class_of_viewer_entry>.class,
};
#Override
public Object getAdapter(Object adaptableObject, Class adapterType) {
return new <class_that_implements_IActionFilter>((<object_class_of_viewer_entry>) adaptableObject);
}
#Override
public Class[] getAdapterList() {
return types;
}
}
What's wrong about this? Where did I miss something?
Turns out everything, well, almost everything, was correct. I had simply mixed up interface and implementation of object_class_of_viewer_entry in the plugin.xml.
Two articles that helped: http://www.eclipsezone.com/articles/what-is-iadaptable/ and http://wiki.eclipse.org/FAQ_How_do_I_use_IAdaptable_and_IAdapterFactory%3F