Monday, April 16, 2012

Expression Examples

The previous post about the Expression Framework might be a bit confusing. Therefore I will provide some expression examples for eclipse built in source providers and tester and for the custom property tester provided in the previous post.

Source code for this tutorial is available on github as a single zip archive, as a Team Project Set or you can browse the files online. 

Preparations

Create a new Plug-in Project called com.codeandme.coreexpressions.samples. Add dependencies to org.eclipse.ui, org.eclipse.core.runtime and com.codeandme.coreexpressions. Set the content of plugin.xml to
<?xml version="1.0" encoding="UTF-8"?>
<?eclipse version="3.4"?>
<plugin>
   <extension
         point="org.eclipse.ui.commands">
      <command
            defaultHandler="com.codeandme.coreexpressions.samples.Login"
            id="com.codeandme.coreexpressions.commands.login"
            name="login">
      </command>
      <command
            defaultHandler="com.codeandme.coreexpressions.samples.Logout"
            id="com.codeandme.coreexpressions.commands.logout"
            name="logout">
      </command>
   </extension>
</plugin>
Add a new class com.codeandme.coreexpressions.samples.Login
package com.codeandme.coreexpressions.samples;

import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.commands.IHandler;
import org.eclipse.ui.ISourceProvider;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.services.ISourceProviderService;

import com.codeandme.coreexpressions.ExampleSourceProvider;

public class Login extends AbstractHandler implements IHandler {

 @Override
 public Object execute(ExecutionEvent event) throws ExecutionException {

  ISourceProviderService service = (ISourceProviderService) PlatformUI.getWorkbench().getService(
    ISourceProviderService.class);
  ISourceProvider provider = service.getSourceProvider(ExampleSourceProvider.CURRENT_USER);
  if (provider instanceof ExampleSourceProvider)
   ((ExampleSourceProvider) provider).setCurrentUser("John Doe");

  return null;
 }
}
and another class com.codeandme.coreexpressions.samples.Logout
package com.codeandme.coreexpressions.samples;

import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.commands.IHandler;
import org.eclipse.ui.ISourceProvider;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.services.ISourceProviderService;

import com.codeandme.coreexpressions.ExampleSourceProvider;

public class Logout extends AbstractHandler implements IHandler {

 @Override
 public Object execute(ExecutionEvent event) throws ExecutionException {
  ISourceProviderService service = (ISourceProviderService) PlatformUI.getWorkbench().getService(
    ISourceProviderService.class);
  ISourceProvider provider = service.getSourceProvider(ExampleSourceProvider.CURRENT_USER);
  if (provider instanceof ExampleSourceProvider)
   ((ExampleSourceProvider) provider).setCurrentUser(null);

  return null;
 }
}
We will use these commands in a later step of our tutorial.

The first commands we use will simply bind to the commandId=org.eclipse.ui.file.exit.

Test 1: Enable for a specific view

Our first expression will reveal a toolbar item in the Project Explorer view when the view is active.
      <menuContribution
            allPopups="false"
            locationURI="toolbar:org.eclipse.ui.navigator.ProjectExplorer">
            <command
                  commandId="org.eclipse.ui.file.exit"
                  label="Test1"
                  style="push">
               <visibleWhen
                     checkEnabled="false">
                  <with
                        variable="activePartId">
                     <equals
                           value="org.eclipse.ui.navigator.ProjectExplorer">
                     </equals>
                  </with>
               </visibleWhen>
            </command>
      </menuContribution>
We need to set checkEnabled on the visibleWhen element to false, otherwise the expression will not be active. The with section uses activePartId as source. It is a string containing the ID of the active view/editor (see description).

The equals section compares the source value with org.eclipse.ui.navigator.ProjectExplorer, returning true when the Project Explorer View is active.

Run your Plug-in as a new Eclipse application and activate the Project Explorer to see the toolbar entry appear/disappear.

Test 2: Enable when Projects are selected


Next we want a button to be visible when at least one project is selected.
            <command
                  commandId="org.eclipse.ui.file.exit"
                  label="Test2"
                  style="push">
               <visibleWhen
                     checkEnabled="false">
                  <with
                        variable="selection">
                     <iterate
                           operator="or">
                        <adapt
                              type="org.eclipse.core.resources.IProject">
                        </adapt>
                     </iterate>
                  </with>
               </visibleWhen>
            </command>
Now we use the selection source provider, which provides the current selection. The iterate operator is nice as it tests all elements of a collection. By setting operator to or we define that at least one element of the collection has to pass the test.

There exists an instanceof operator which we could use to check against org.eclipse.core.resources.IProject. Unfortunately not all projects implement that interface. Instead they use the adapter framework. Therefore we use the adapt operator to see if the element can be adapted to an IProject. Of course this works for all classes implementing the interface directly too.


Test 3: Enable when exactly 2 txt Files are selected


Now for something more complex. A button shall be visible when exactly two resources are selected and both have an extension of .txt.
            <command
                  commandId="org.eclipse.ui.file.exit"
                  label="Test3"
                  style="push">
               <visibleWhen
                     checkEnabled="false">
                  <with
                        variable="selection">
                     <and>
                        <iterate
                              operator="and">
                           <test
                                 property="org.eclipse.core.resources.extension "
                                 value="txt">
                           </test>
                        </iterate>
                        <count
                              value="2">
                        </count>
                     </and>
                  </with>
               </visibleWhen>
            </command>
The property tester for file extensions is described in the documentation. The count operator counts the elements within a collection.


Test 4: Login/Logout

Let's add two more buttons for a very basic user login.
   <extension
         point="org.eclipse.ui.menus">
      <menuContribution
            allPopups="false"
            locationURI="menu:file?after=additions">
         <command
               commandId="com.codeandme.coreexpressions.commands.login"
               label="Login"
               style="push">
            <visibleWhen
                  checkEnabled="false">
               <with
                     variable="com.codeandme.coreexpressions.currentStatus">
                  <or>
                     <equals
                           value="startup">
                     </equals>
                     <equals
                           value="logged off">
                     </equals>
                  </or>
               </with>
            </visibleWhen>
         </command>
         <command
               commandId="com.codeandme.coreexpressions.commands.logout"
               label="Logoff"
               style="push">
            <visibleWhen
                  checkEnabled="false">
               <with
                     variable="com.codeandme.coreexpressions.currentUser">
                  <equals
                        value="John Doe">
                  </equals>
               </with>
            </visibleWhen>
         </command>
      </menuContribution>
We use dedicated commands that will set/reset the current user of our source provider from the previous post. The different source providers for both buttons do not necessarily make sense - we could achieve the same with just one source. Its just to give you an idea how it works.


We use our custom property tester to verify the current logon state and the current user.

No comments:

Post a Comment