Thursday, February 26, 2009

Quick Tip : Adding SWT controls to the Trim Area

Sometimes RCP applications needs to show a label or some swt control on the trim area (outer boundary of the workbench window ) for example in the status area, after the perspective switch bar area and so on.

org.eclipse.ui.menus extension point allows to places command or control on the toolbar , menubar or on the trim area. For this post, if you want to add a control or command to the status area or the perspective switch area, use the following locationURI.

For placing it on the status area - toolbar:org.eclipse.ui.trim.status this will place the control or command on the status area. ( You have to make sure the status area is made visible in the workbenchwindowadvisors preWindowOpen() method as


public void preWindowOpen() {
IWorkbenchWindowConfigurer configurer = getWindowConfigurer();
configurer.setInitialSize(new Point(600, 400));
configurer.setShowCoolBar(true);
configurer.setShowPerspectiveBar(true);
configurer.setShowStatusLine(true);
}


For placing it on the perspective switch area - toolbar:org.eclipse.ui.trim.command2, this will add the control next to the perspective switch area.

The extension point should create a menuContribution with the correct locationURI, and add the controls/commands to a toolbar.


<extension
point="org.eclipse.ui.menus">
<menuContribution
locationURI="toolbar:org.eclipse.ui.trim.command2">
<toolbar
id="com.blog.sample.toolbar1">
<control
class="com.blog.sample.WorkbenchWindowControlContribution1">
</control>
</toolbar>
</menuContribution>
</extension>


Have fun !

Tuesday, February 24, 2009

Eclipse : Minimizing the RCP App to the system tray.

ApplicationWorkbenchWindowAdvisor of the RCP application can handle preWindowShellClose() and postWindowClose(). If you want the application to be stored to the system tray when closed, the preWindowClose event can be handled as below to add a system tray icon with Open and Exit actions which will open/exit the workbench.


@Override
public boolean preWindowShellClose() {
final TrayItem item = new TrayItem(
Display.getCurrent().getSystemTray(), SWT.NONE);
final Image image = Activator.getImageDescriptor("icons/mail.ico")
.createImage();
item.setImage(image);
item.setToolTipText("RCPMail - Tray Icon");
getWindowConfigurer().getWindow().getShell().setVisible(false);
item.addSelectionListener(new SelectionAdapter() {
public void widgetDefaultSelected(SelectionEvent e) {
Shell workbenchWindowShell = getWindowConfigurer().getWindow()
.getShell();
workbenchWindowShell.setVisible(true);
workbenchWindowShell.setActive();
workbenchWindowShell.setFocus();
workbenchWindowShell.setMinimized(false);
image.dispose();
item.dispose();
}
});

Shell workbenchWindowShell = getWindowConfigurer().getWindow()
.getShell();
// Create a Menu
final Menu menu = new Menu(workbenchWindowShell, SWT.POP_UP);
// Create the exit menu item.
final MenuItem exit = new MenuItem(menu, SWT.PUSH);
exit.setText("Exit");

// Create the open menu item.
final MenuItem open = new MenuItem(menu, SWT.PUSH);
open.setText("Open");
// make the workbench visible in the event handler for exit menu item.
open.addListener(SWT.Selection, new Listener() {
public void handleEvent(Event event) {
// Do a workbench close in the event handler for exit menu item.
exit.addListener(SWT.Selection, new Listener() {
public void handleEvent(Event event) {
image.dispose();
item.dispose();
open.dispose();
exit.dispose();
menu.dispose();
getWindowConfigurer().getWorkbenchConfigurer().getWorkbench()
.close();
}
}); Shell workbenchWindowShell = getWindowConfigurer().getWindow()
.getShell();
workbenchWindowShell.setVisible(true);
workbenchWindowShell.setActive();
workbenchWindowShell.setFocus();
workbenchWindowShell.setMinimized(false);
image.dispose();
item.dispose();
open.dispose();
exit.dispose();
menu.dispose();
}
});
item.addListener(SWT.MenuDetect, new Listener() {
public void handleEvent(Event event) {
menu.setVisible(true);
}
});
// Do a workbench close in the event handler for exit menu item.
exit.addListener(SWT.Selection, new Listener() {
public void handleEvent(Event event) {
image.dispose();
item.dispose();
open.dispose();
exit.dispose();
menu.dispose();
getWindowConfigurer().getWorkbenchConfigurer().getWorkbench()
.close();
}
});
return false;
}

Equinox : Authenticate with Database Login using Equinox Security

Most of the desktop applications require a authentication step when the application is started. Eclipse does not yet provide a login mechanism to authenticate the user. But the equinox security has it on the proposal to support login dialog based authentication. Till then, what would be the best way to do the authentication with existing equinox security features. Lets have a look at RCP Mail Template with a login dialog during start up.

Equinox implements the standard Java Authentication and Authorization Service ( JAAS ) to authenticate and authorize. We will look at some realtime examples of how to do the authentication.

Equinox supports extension login modules which can be configured via the loginmodule extension. The extension can be configured with nt login module, LDAP login modules from the sun security modules or can be configured with custom written LoginModules like RDBMSLoginModule, SecureStorage Logins and so on.

The example from the org.eclipse.equinox.security.sample from the equinox cvs (org.eclipse.equinox/incubator/security/bundles/org.eclipse.equinox.security.sample ) /cvsroot/rt explains adding LDAP, WIN32 and other login modules to the application. Here in this example we will write a custom LoginModule which authenticates against a database connection.

RDBMSLoginModule - The login modules has to implement LoginModule interface from javax security. The LoginModule contains initialize, login, logout, commit and abort methods. The initialize method gives the CallbackHanlder and other options.

The Login Method which does the authentication has to be implemented against a database for this example.

public boolean login() throws LoginException
{

if (callbackHandler == null)
throw new LoginException("Error: no CallbackHandler available "
+ "to garner authentication information from the user");

try
{
// Setup default callback handlers.
Callback[] callbacks = new Callback[] { new NameCallback("Username: "),
new PasswordCallback("Password: ", false), new NameCallback("Database: ") };

callbackHandler.handle(callbacks);

String username = ((NameCallback) callbacks[0]).getName();
String password = new String(((PasswordCallback) callbacks[1]).getPassword());
String dbname = ((NameCallback) callbacks[2]).getName();

((PasswordCallback) callbacks[1]).clearPassword();

success = rdbmsValidate(username, password,dbname); // This method should try to connect
//to the database with the given username,password, url and return true on success.

callbacks[0] = null;
callbacks[1] = null;

if (!success)
throw new LoginException("Authentication failed: Password does not match");

return (true);
}
catch (LoginException ex)
{
throw ex;
}
catch (Exception ex)
{
success = false;
throw new LoginException(ex.getMessage());
}
}
The LoginModule is declared with org.eclipse.equinox.security.loginModule extension point.


<extension
id="com.sample.login.RdbmsLoginModule"
point="org.eclipse.equinox.security.loginModule">
<loginModule
class="com.sample.login.RdbmsLoginModule">
</loginModule>
</extension>

The login method calls the callback handler which is configured in the plugin.xml via the extension org.eclipse.equinox.security.callbackHandler

<extension
id="com.sample.login.LoginDialogCallbackHandler"
point="org.eclipse.equinox.security.callbackHandler">
<callbackHandler
class="com.sample.login.LoginDialogCallbackHandler">
</callbackhandler>
</extension>


The call back handler is mapped to a configName in this case say RDBMS to a Dialog which takes username, password and the db url.

The CallBackHandlerMapping is done as follows

<extension
point="org.eclipse.equinox.security.callbackHandlerMapping">
<callbackHandlerMapping
callbackHandlerId="com.sample.login.LoginDialogCallbackHandler"
configName="RDBMS">
</callbackHandlerMapping>
</extension>

Once the rdbmsValidate method successfully connects to the database with the given values , a javax.security.auth.Subject can be constructed with the Credentials and Principals as an authenticated user.

private boolean rdbmsValidate(String user, String pass) throws Exception
{

Connection con;
boolean passwordMatch = true;

try
{
Class.forName(driverClass);
}
catch (java.lang.ClassNotFoundException e)
{
System.err.print("ClassNotFoundException: ");
System.err.println(e.getMessage());
throw new LoginException("Database driver class not found: " + driverClass);
}

try
{
if (debug)
System.out.println("\t\t[RdbmsLoginModule] Trying to connect...");

con = DriverManager.getConnection(url, user, pass);
if(con == null )
passwordMatch = false;
else
//Construct a subject.
} catch(Exception ex) {
}
return (passwordMatch)'
}

Now that all the extension points are made for the authentication. We need to call the LoginModule at the appropriate place on the application. Usually the Eclipse Application start method is a good place to keep the Authentication process.

Create the LoginContext from the RDBMS callback handler defined in the plugin.xml.

public Object start(final IApplicationContext context) throws Exception
{
String configName = Activator.getConfigurationName();
URL configUrl = Activator.getBundleContext().getBundle().getEntry("jaas_config.txt");
ILoginContext secureContext = LoginContextFactory.createContext(configName, configUrl);
secureContext.registerListener(new ProgressMonitorListener());
Integer result = null;
final Display display = PlatformUI.createDisplay();
try
{
result = (Integer) Subject.doAs(secureContext.getSubject(), getRunAction(display));
}
finally
{
display.dispose();
secureContext.logout();
}
// TBD handle javax.security.auth.login.LoginException

if (result != null && PlatformUI.RETURN_RESTART == result.intValue())
return EXIT_RESTART;
return EXIT_OK;
}


Add the following methods to the Activator class of the plugin.


private static final String CONFIG_PREF = "loginConfiguration";//$NON-NLS-1$

private static final String CONFIG_DEFAULT = "other";

public static BundleContext getBundleContext()
{
return bundleContext;
}

public static String getConfigurationName()
{
return new DefaultScope().getNode(PLUGIN_ID).get(CONFIG_PREF, CONFIG_DEFAULT);
}

Finally the jaas_config.txt file which defines the RDBMS callback Handler name with the Login Module extension ( RDBMSLoginModule ) should be placed in the plugin's root folder.


RDBMS {
org.eclipse.equinox.security.auth.module.ExtensionLoginModule required
extensionId="com.sample.login.RdbmsLoginModule"
debug=true;
};

Wednesday, February 18, 2009

Quick Tips : Opening the Eclipse Preferences with a specfic Preference Page.

When we create PreferencePages in a Eclipse RCP applications, the window->Preferences menu item opens the preferences dialog and all the preferneces are shown in the Preferences window. How about showing a particular preference page from a toolbar button in a view / application.

Before the command framework we can do it using the PreferenceUtil class like belore


PreferencesUtil.createPreferenceDialogOn(shell, preferencePageId, displayedIds, data)


But with the help of the command framework,it is way easy to do this task.


point="org.eclipse.ui.menus">
locationURI="toolbar:com.blog.sample.ui.ButtonView">
commandId="org.eclipse.ui.window.preferences"
label="Preferences"
style="push">
name="preferencePageId"
value="com.blog.sample.ui.CorePreferencePage">






The commandID opens the org.eclipse.ui.window.preferences with all the preferences. The parameter passed to the command tells the Preferences to open the preference window with the page that we want.

Have fun !.

Eclipse : How to Implement ISelectionProvider

ISelectionProvider interface provides a way to send selection events to the the ISelectionService which is received by all the ISelectionListener implementing views. All the JFace Structured viewers implements the ISelectionProvider and provide a StructuredSelection.

There are scenarios where we have a custom view which might want to fire a Selectionto the listeners. Let us look at how to do that.

Say you have a view with a Button and on clicking the button you want to send a selection event.



import org.eclipse.core.runtime.ListenerList;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.part.ViewPart;

public class ButtonView extends ViewPart implements ISelectionProvider {

private String selection;

ListenerList listeners = new ListenerList();

Button button = null;

@Override
public void createPartControl(Composite parent) {
parent.setLayout(new GridLayout(2, false));
button = new Button(parent, SWT.BORDER);
button.setText("Press Me");
getSite().setSelectionProvider(this);
button.addMouseListener(new MouseAdapter() {
@Override
public void mouseDown(MouseEvent e) {
setSelection(new StructuredSelection(button.getText()));
}
});
}

@Override
public void setFocus() {
}

public void addSelectionChangedListener(ISelectionChangedListener listener) {
listeners.add(listener);
}

public ISelection getSelection() {
return new StructuredSelection(selection);
}

public void removeSelectionChangedListener(
ISelectionChangedListener listener) {
listeners.remove(listener);
}

public void setSelection(ISelection select) {

Object[] list = listeners.getListeners();
for (int i = 0; i < list.length; i++) {
((ISelectionChangedListener) list[i])
.selectionChanged(new SelectionChangedEvent(this, select));
}
}

}




Now the ButtonView is implementing the ISelectionProvider and registered itself as a SelectionProvider to the workbench site. Now lets add the view to the views extension point. We will also create a ButtonListenerView which behaves as a SelectionListener by implementing ISelectionListener.



import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.ISelectionListener;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.part.ViewPart;

public class ButtonListenerView extends ViewPart implements ISelectionListener {

Button button;

@Override
public void createPartControl(Composite parent) {
getSite().getPage().addSelectionListener(this);
button = new Button(parent, SWT.BORDER);
button.setText("Before Selection Happened");
}

@Override
public void setFocus() {


}

public void selectionChanged(IWorkbenchPart part, ISelection selection) {
if (part instanceof ButtonView) {
String text = ((StructuredSelection) selection).getFirstElement()
.toString();
button.setText(text);
}
}

}




Now ButtonView sends the selection event to the selection service and the ButtonListenerView listens for the Selection events from the workbench. There is one more step to add the views to the views extension.


<extension
point="org.eclipse.ui.views">
<view
class="com.blog.sample.ui.ButtonView"
id="com.blog.sample.ui.ButtonView"
name="Button View"
restorable="true">
</view>
<view
class="com.blog.sample.ui.ButtonListenerView"
id="com.blog.sample.ui.ButtonListenerView"
name="Button Listener"
restorable="true">
</view>
</extension>



Lets see the screenshot before and after the button is clicked on the ButtonView.

Before the ButtonView send the ISelection,


Now clicking the Press Me button sends a selection event to all the listeners. ButtonListenerView processes the selection in the selectionChanged method.

Saturday, February 14, 2009

Eclipse : Keeping Preferences and Preferences UI separate

Eclipse Preferences and PreferenceStore does not connect well with each other. When we have a Core plugin which handles the preferences and the initial values, keeping the UI in a separate plugin becomes difficult. The core plugin does not have access to the PreferenceStore since it is a not UI plugin. The UI Plugin with PreferencePage cannot populate using the Preferences from the core plugin.

So how do we couple these together. The UI Plugin can create a PreferenceStore using the bundle id of the Core Plugin.



public class CorePreferencePage extends FieldEditorPreferencePage implements
IWorkbenchPreferencePage {

public CorePreferencePage() {
IPreferenceStore store = new ScopedPreferenceStore(new InstanceScope(),
""com.blog.sample.core"");
setPreferenceStore(store);
}

@Override
protected void createFieldEditors() {
BooleanFieldEditor formatOnSave = new BooleanFieldEditor("ABC", "ABC",
getFieldEditorParent());
addField(formatOnSave);

}

public void init(IWorkbench workbench) {

}

}



Now we can see the preferences of the Core Plugin in the UI Plugin's preference Page. But what if the preferences are not overridden and they are initialized from the Core Plugin using the Preference Initializer.


public class CorePreferenceInitializer extends AbstractPreferenceInitializer {

public CorePreferenceInitializer() {

}

@Override
public void initializeDefaultPreferences() {
Preferences node = new DefaultScope().getNode("com.blog.sample.core");
node.put("ABC", "true");
}
}


and the core plugin declares an extension point to initialize the value when the preference node is accessed. But the initializer will be only invoked only if it is invoked from the bundle which is initialized.








Now the initializer is invoked when it is accessed from the Core Plugin getPreferences. Now the UI Plugin does not know about the default values from the initializer. Whats the workaround?

Add a duplicate extension point on the UI Plugin with the same initializer from the Core Plugin. Now when you open the prefernece page the initializer on the Core Plugin is invoked and the values are set to default.

Have fun !

Friday, February 13, 2009

Eclipse : Adding a Static text to the toolbar

There are situations you need to show a static text on the toolbar with a user name or some sort of text. This can be done using the ControlContribution.

JFace provides ControlContribution which can be added to the toolbar.




public class LabelControlContribution extends ControlContribution
{

protected LabelControlContribution(String id)
{
super(id);
}

@Override
protected Control createControl(Composite parent)
{
final Label b = new Label(parent, SWT.LEFT);
b.setText("Label: <Your User Name>");
return b;
}

}



Add the ControlContribution to the coolbar in the ApplicationActionBarAdvisors fillCoolbar method.


IToolBarManager toolbar1 = new ToolBarManager(SWT.FLAT
| SWT.RIGHT_TO_LEFT);
coolBar.add(new ToolBarContributionItem(toolbar1, "label"));
toolbar1.add(new LabelContribution("Label"));


Now the toolbar with the ControlContribution gets added to the Toolbar.

Quick Tip : Multiple Target Platform support from 3.5M5

Eclipse now supports adding multiple target platforms. The Target platform preference page in Plugin-Development allows adding multiple target platforms and assigning one of them as default.

This feature is still experimental. More details at http://download.eclipse.org/eclipse/downloads/drops/S-3.5M5-200902021535/eclipse-news-M5.html

Quick Tip : Eclipse-BundleShape header - Package plugins as directory

Eclipse MANIFEST.MF with a '.' for the Bundle-classpath packages the plugin as a jar file when the plugin is exported. But there are many cases where the plugin needs to be directory to read the files inside the plugin.

From 3.5 , eclipse supports a new header in the MANIFEST.MF called Eclipse-BundleShape. The header allows two types 'dir' and 'jar'.

Wednesday, February 11, 2009

Eclipse : How to create Wizards

Eclipse provides easy ways to create wizards and connect them to standard eclipse actions like New, Import,Export and so on. If you want to add a Wizard to file->New menu, you can use the newWizards extension point.


point="org.eclipse.ui.newWizards">
class="com.blog.sample.loginapp.SampleWizard"
id="com.blog.sample.loginApp.wizard3"
name="Sample Wizard">




This adds a Sample Wizard to the File New action. Now the SampleWizard has to include all the pages in the wizard. First of all, the SampleWizard has to implement the IWizard interface ( can extend the abstract implementation Wizard ).


import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.wizard.Wizard;
import org.eclipse.ui.INewWizard;
import org.eclipse.ui.IWorkbench;

public class SampleWizard extends Wizard implements INewWizard {

public SampleWizard() {

}

@Override
public boolean performFinish() {

return false;
}

public void init(IWorkbench workbench, IStructuredSelection selection) {


}

}


This creates a Wizard as shown below.



Now to add a Page to the SampleWizard , create a WizardPage and add it.


public class SamplePage extends WizardPage {

Text text = null;

public SamplePage() {
super("SamplePage1");
setTitle("Page1");
setDescription("Page1 Description");
}

public void createControl(Composite parent) {
Composite comp = new Composite(parent, SWT.NONE);
comp.setLayout(new GridLayout(2, false));
Label label = new Label(comp, SWT.NONE);
label.setText("Text ");
text = new Text(comp, SWT.BORDER);
text.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
setControl(parent);
}

@Override
public boolean isPageComplete() {
return super.isPageComplete();
}

}


Now the SamplePage has to be added to the SampleWizard via the addPages method as follows.


@Override
public void addPages() {
super.addPages();
addPage(samplePage);
}


This adds the page as below.



The isPageComplete() method from the SamplePage enables/disables the Next button if the page is complete. Once all the data is taken from the page. The isPageComplete returns true to the SampleWizard. At the end, the SampleWizard enables the finish the Button by looking at the canFinish return value. The canFinish can return true if the mandatory values are entered.

Have fun !.

Eclipse : How to save a dirty view

Eclipse has editors and views. When the contents of a editor is modified, the editor's state changes to dirty state and the user is asked to save it when he closes the application.

Editors implement IEditorPart interface which extends ISaveablePart. ISaveablePart has the following methods.



@Override
public void doSave(IProgressMonitor monitor)
{

}

@Override
public void doSaveAs()
{

}

@Override
public boolean isDirty()
{

return false;
}

@Override
public boolean isSaveAsAllowed()
{

return false;
}

@Override
public boolean isSaveOnCloseNeeded()
{

return false;
}



So if you need the ViewPart to behave like a editor when the content is modified, the ISaveablePart should be implemented by the ViewPart class.

More importantly when something is changed on the View, set the dirty flag to true and fire a property change event to the workbench, otherwise the Save menu item will not be enabled on the workbench.


public boolean isDirty()
{
return _dirty;
}

protected void setDirty(boolean value)
{
_dirty = value;
firePropertyChange(PROP_DIRTY);
}

Eclipse : Most useful Eclipse plugins for a developer

There are lot of open source and commercial eclipse plugin available out there. Here are some of the best plugins that i have used during my eclipse based application development.

Subclipse

Checking out code from the version control will be the first step for any developer. CVS, Subversion are two of the mostly used Version control systems. Eclipse IDE provides the CVS Repository access by default. Since we had a Subversion repository for our version control, we needed a Subversion client for eclipse. There are two major SVN Clients for eclispe, Subclipse and Subversive.

We have chosen Subclipse over subversice since we had some performance problem using Subversive.

You can get it from http://subclipse.tigris.org/

Checkstyle

Software development involves the teams writing code properly by following some coding standard. Following the coding standard helps in many ways like, maintainability and readability. Eclipse has plugins which enforces these coding standards during the development. Checkstyle plugin is a freely available plugin which checks coding standards and also some java best practices.

Checkstyle is configurable through the Eclipse preferences where the user can import a predefined checkstyle xml file.

You can get it from http://eclipse-cs.sourceforge.net/

Code Coverage

Softwares need to be tested at different levels like unit testing, system testing , integration testing and so on. The software programmer usually writes unit test code to test an unit of functionality in the software. The unit tests cover a particular portion of the code base developed. The code coverage tools highlights the unit test covered code and gives statistical information about the testing.

Eclipse has a plugin called EclEmma which integrates into the Run Configuration and gives all the coverage details.

you can get it from http://www.eclemma.org/


DBViewer

Most projects has a backend database which holds the application data. The developers writes SQL queries to retrieve the database results or maps the database columns to Object relational mapping tools like Hibernate. DBViewer plugin helps doing all this inside eclipse ide itself rather than using additional java sql tools.

You can configure any number of databases and query them and edit them using a simple table from inside eclipse.

You can get if from http://www.ne.jp/asahi/zigen/home/plugin/dbviewer/about_jp.html

Plugin Builder

Once the plugins are developed in eclipse. The plugins and features needs to be built on a build machine to achieve continuous integration. Pluginbuilder is a eclipse plugin which helps creating build xml files from inside eclipse.

You can get it from http://www.pluginbuilder.org/

Eclipse : Uncloseable ViewPart

There are some cases where view part must not be closed in a perpective. Eclipse RCP provides an easy way to make the viewpart uncloseable.

From the perspective class which defines the layout for the Perspective, the viewpart can be set uncloseable.



public void createInitialLayout(final IPageLayout layout)
{
final String editorArea = layout.getEditorArea();
layout.addView(View.ID, IPageLayout.LEFT, 0.5f, editorArea);
layout.getViewLayout(View.ID).setCloseable(false);
}

Monday, February 2, 2009

Eclipse RCP: Removing unwanted actionSets from menubar

Eclipse provides some default actionSets when you include the plugins like org.eclipse.ui. In many cases, the application does not need these actions.
So how do we remove these actions from the menubar and toolbar? Well, there is this ugly code which removes the unwanted action sets.


final ActionSetRegistry reg = WorkbenchPlugin.getDefault().getActionSetRegistry();
final IActionSetDescriptor[] actionSets = reg.getActionSets();
final String[] removeActionSets = new String[] {
"org.eclipse.search.searchActionSet","org.eclipse.ui.cheatsheets.actionSet",
"org.eclipse.ui.actionSet.keyBindings","org.eclipse.ui.edit.text.actionSet.navigation",
"org.eclipse.ui.edit.text.actionSet.annotationNavigation","org.eclipse.ui.edit.text.actionSet.convertLineDelimitersTo",
"org.eclipse.ui.edit.text.actionSet.openExternalFile","org.eclipse.ui.externaltools.ExternalToolsSet",
"org.eclipse.ui.WorkingSetActionSet","org.eclipse.update.ui.softwareUpdates",
"org.eclipse.ui.actionSet.openFiles","org.eclipse.mylyn.tasks.ui.navigation", };

for (int i = 0; i < actionSets.length; i++) {
boolean found = false;
for (int j = 0; j <; removeActionSets.length; j++) { if(removeActionSets[j].equals(actionSets[i].getId())) { found= true; } } if(!found) { continue; } final IExtension ext = actionSets[i].getConfigurationElement().getDeclaringExtension(); reg.removeExtension(ext, new Object[] { actionSets[i] }); }

But this code needs to access restricted API from eclipse internal packages. When the eclipse activities are introduced the above discouraged can be declaratively done inside the plugin.xml file. If you wanted to remove the search menu from the menubar, define an activity and use the pattern org.eclipse.search.* as the activity pattern as below.




<extension point="org.eclipse.ui.activities">
<activity id="com.sequenom.ivd.actitivities.unwantedActionSet1" name="Unwanted Search ActionSet">
<enabledwhen>
<with variable="activePartId">
<equals value="com.sequenom.ivd.actitivities.unwantedActionSet">
</equals>
</with></enabledwhen></activity></extension>

<activitypatternbinding activityid="com.sequenom.ivd.actitivities.unwantedActionSet1" pattern="org.eclipse.search.*">
</activitypatternbinding>

This will remove the search menu from your application. Have fun !