Posts Tagged ‘Papercut’

Eclipse Papercut #6 – Modifying Mylyn Context

Monday, October 5th, 2009

In this episode of Eclipse Papercuts I will demonstrate how to modify the Mylyn tasks context. Many thanks to David Green for providing sample code to access the Mylyn context.

Mylyn makes certain assumptions how the developer works. If you start a new task the Mylyn context is empty and fills up based on the selected files.

Which is not always the way I work. Frequently I know that for my task a whole package (or project) is relevant. I would like to include all classes in this package / project in my Mylyn task.

Ok, lets see how we can solve this papercut. I describe how to add Java classes from a package to an active task.

Create an command which extends the package explorer with a new popup commands as described here Extend the package explorer.

Create the command handler with the following coding:


package de.vogella.mylyn.tasksmodify.handlers;

import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.mylyn.context.core.ContextCore;
import org.eclipse.mylyn.context.core.IInteractionContext;
import org.eclipse.mylyn.internal.context.core.ContextCorePlugin;
import org.eclipse.mylyn.monitor.core.InteractionEvent;
import org.eclipse.mylyn.monitor.core.InteractionEvent.Kind;
import org.eclipse.ui.handlers.HandlerUtil;

public class SampleHandler extends AbstractHandler {
	public Object execute(ExecutionEvent event) throws ExecutionException {

		IStructuredSelection selection = (IStructuredSelection) HandlerUtil
				.getActiveMenuSelection(event);
		if (selection ==null){
			return null;
		}

		Object firstElement = selection.getFirstElement();

		if (firstElement instanceof IPackageFragment) {
			IPackageFragment mypackage = (IPackageFragment) firstElement;
			try {
				if (mypackage.getKind() == IPackageFragmentRoot.K_SOURCE){
					 ICompilationUnit[] compilationUnits = mypackage.getCompilationUnits();
					 for (ICompilationUnit iCompilationUnit : compilationUnits) {
						 IInteractionContext activeContext = ContextCore.getContextManager()
							.getActiveContext();
						 ContextCorePlugin.getContextManager().processInteractionEvent(iCompilationUnit,
									Kind.PROPAGATION, InteractionEvent.ID_UNKNOWN, activeContext);
					}
				}
			} catch (JavaModelException e) {
				e.printStackTrace();
			}
		}

		return null;
	}
}

Launch your plugin. Create a Mylyn task and select a package in the package explorer. Select your commands and all files of this package will be added to the task.

Further reading: If you want to access other Java Elements, e.g. Project and add them to the Mylyn task this tutorial might help you: Eclipse JDT.

Please note that ContextCorePlugin is supposed to be internal API but I did not find another way of accessing the Mylyn tasks.

 

Eclipse Papercut #5 – Getting external libraries as bundles

Monday, September 21st, 2009

In this episode of Eclipse Papercuts I explain how you get bundles for popolar Java libraries for your Eclipse plugin development.

I believe it has advantages to work with plugin projects instead of pure Java projects even if the plan is not to create Eclipse plugins / RCP applications.

The core strength of OSGi for this scenario is in my opinion the encapsalation and protection of your inner classes. With OSGi bundles you decide which packages of your project are exported and therefore visible to other projects (via the tab Runtime in the editor for the file plugin.xml).

This leaves only one problem: If you are using externally libraries you have to convert them into bundles / plugins.

I would be nicer to consume pre-packages bundles. As I created a bug iText should be OSGi and tweeted about it Chris Aniszczyk pointed me to Eclipse Orbit.

Eclipse Orbit provides lots of standard libraries already pre-packaged as bundles / plugins.

Lets see how you could get the iText version from Orbit. Check the Orbit FAQ to find out more.

You need to connect via cvs to the Eclipse cvs repository. CVS URL is :pserver:anonymous@dev.eclipse.org/cvsroot/tools

Navigate to “org.eclipse.orbit”. Select “com.lowagie.text” and check it out.

orbit10

Orbit keeps the different version of the library as cvs branches. Select your project and select Replace With -> Another Branch or Version…
orbit20

orbit30

After selecting the branch and pressing ok the system will download the library and you can start using the library.

In addition to Orbit you can also use the Springsource bundle repository. On this website you can search for bundles and download then directly. You can then import them as plugin projects into your workspace.

 

Eclipse Papercut #4 – Modifying Eclipse PDE default launch configuration

Monday, July 27th, 2009

In this episode of the Eclipse Papercut series I will change the default PDE launch configuration. During this process I show how to get and modify Eclipse PDE code.

Lets define the papercut:

One thing I always have to do during plugin and Eclipse RCP development is to make the following settings in the launch configuration:

  1. add -consoleLog in the arguments tab
  2. Select the flag “Validate plug-in automatically prio to launching” on the plug-ins tab

This papercut has two dimensions.

The first one is that for everybody who knows about these settings it is not a problem to set them up. It is just time-consuming and error prone. Sometimes I’m searching why something does not work and then I’m banging my head because I forgot to set -consoleLog.

The second dimension is that this default launch configuration makes it harder for new plugin and Eclipse RCP developers to get started. I frequently see questions in the Eclipse newsgroup and other places which can be answered by: “please set -consoleLog” or “press the Validate button”.

So I seek to change the current behavior.

Adding “-consoleLog” is easy. Go to preference, select the target platform, select “Edit” and add -consoleLog as a argument.

target10

target20

Of course this does not help the new developers but I come back to this later in this post.

To set the “Validate plug-in automatically prio to launching” flag we have to look into Eclipse PDE code.

A launch configuration is contributed by the extension point “org.eclipse.debug.core.launchConfigurationTypes”. To search through your existing plugins import your plugins into a new workspace. A plugin search reveals that “org.eclipse.pde.ui” contributes such an extension.

Eclipse PDE can be found in the Eclipse cvs via the repository path “/cvsroot/eclipse”. Search here for the folder “pde” which contains the pde plugins. Checkout the plugin “org.eclipse.pde.ui”.

Here we find quickly the right extension point.

pde10

After some pocking around the code and some debugging I found the class “AbstractPluginBlock” and the method “setDefaults”. The change is trivial:

public void setDefaults(ILaunchConfigurationWorkingCopy config) {
	config.setAttribute(IPDELauncherConstants.INCLUDE_OPTIONAL, true);
	config.setAttribute(IPDELauncherConstants.AUTOMATIC_ADD, true);
	config.setAttribute(IPDELauncherConstants.AUTOMATIC_VALIDATE, true); // This has changed from false to true
	config.setAttribute(IPDELauncherConstants.SHOW_SELECTED_ONLY, false);
}

If you now run Eclipse with this adjusted plugin the flag “Validate…” will be flagged for a new runtime configuration.

Now lets return to the addtion of “-consoleLog” to the target platform. I argued earlier that the absence of “-consoleLog” makes it harder for beginner to get started with plugin and RCP development. Changing the target platform is not trivial for starters, so the better solution was if was part of the standard code.

We find the relevant code easily with a text seach for an existing launch parameter, e.g. “-arch”. The responsible class is “LaunchArgumentsHelper” and the method getInitialProgramArguments(). We add “-consoleLog” to the following line:


StringBuffer buffer = new StringBuffer("-os ${target.os} -ws ${target.ws} -arch ${target.arch} -nl ${target.nl} -consoleLog"); //$NON-NLS-1$

Thats it. By deploying the plugin into our Eclipse IDE we have the changed behavior.

I have submitted bugs and attached the patches. Bug Report for “Validate plug-in automatically prio to launching” and Bug Report for -consoleLog.

I hope that these patches will get accepted. If they would be accepted I believe it would be a little easier for new developers to get started.

If someone finds a reason why these settings should not always be the default I would suggest a new PDE preference page which contains the settings for these launch parameters.

 

Eclipse Papercut #2 – Changing Eclipse subversive default behavior

Wednesday, July 8th, 2009

Update: Igor Burilo (Eclipse Subversive developer) was kind enough to accept a modified version of patch developed in this episode. While I’m very happy about this, this unfortunately renders this example irrelevant . You still might want to read this to see how to checkout code from the Eclipse version control system.

In this second part of my 7 Paper Cuts in Eclipse I want to change some standard Eclipse code.

This second papercut is a bit more complex as the first papercut; I’m planning to return to simpler examples in the next papercut.

So lets define the papercut:

I frequently create example projects which I share in a svn repository. For related projects I use the mulitproject layout. The standard in subversion is “Simple Mode – One project for one repository”. Therefore everytime I share a project I have to switch in the subversion dialog from “Simple Mode” to “Advanced Mode”.

papercut1_10

Nothing big? I agree, hence the perfect example for a papercut.

To change the coding of this dialog we need to find the class which is responsible to display this page. Plug-in Spy make this easy via Alt + Shift + F1.

papercut1_20

Now you need to download the source code of the plug-in ”
org.eclipse.team.svn.ui”. This plug-in is stored in svn and can get access via subversion itself. The URL for the subversion repository view is: “http://dev.eclipse.org/svnroot/technology/org.eclipse.subversive”. See here to learn how to use svn and cvs to access the Eclipse code

Add this repository in the “SVN Repository” view and check-out (download) the plug-ins ”
org.eclipse.team.svn.ui” and “org.eclipse.team.svn.core”. You find them in “trunk”.

papercut1_30

Looking at the coding of SelectProjectNamePage.java changing the selection only requires a few lines to be changed.

I use Eclipse Preferences to remember the last user selection.

protected SelectProjectNamePageSimpleModeComposite simpleModeComposite;
	protected ShareProjectNameAdvancedModeComposite advancedModeComposite;
	private static String SELECTION_MODE = "isSimpleMode";

	public SelectProjectNamePage() {
		super(
			SelectProjectNamePage.class.getName(),
			"",  //$NON-NLS-1$
			SVNTeamUIPlugin.instance().getImageDescriptor("icons/wizards/newconnect.gif")); //$NON-NLS-1$
		Preferences preferences = new ConfigurationScope()
		.getNode("org.eclipse.team.svn.ui.wizard.shareproject");
		Preferences preference = preferences.node("note1");
		this.isSimpleMode = preference.getBoolean(SELECTION_MODE, true);;
	}

and I have to change a few more lines to use isSimpleMode everywhere:

this.simpleModeRadionButton.setSelection(this.isSimpleMode);
....
this.advancedModeRadionButton.setSelection(!this.isSimpleMode); // Either or
this.advancedModeRadionButton.addSelectionListener(modeListener);

And I have to set the preference in the ModeListener


	protected class ModeListener extends SelectionAdapter {
		public void widgetSelected(SelectionEvent e) {
			//change controls area mode
			Button modeButton = (Button) e.widget;
			if (SelectProjectNamePage.this.simpleModeRadionButton == modeButton && SelectProjectNamePage.this.isSimpleMode == false) {
				SelectProjectNamePage.this.isSimpleMode = true;
				preference.putBoolean(SELECTION_MODE, true);
				enableControlsArea();
			} else if (SelectProjectNamePage.this.advancedModeRadionButton == modeButton && SelectProjectNamePage.this.isSimpleMode == true) {
				SelectProjectNamePage.this.isSimpleMode = false;
				preference.putBoolean(SELECTION_MODE, false);
				enableControlsArea();
			}
		}
	}

The full source code is attached.

SelectProjectNamePage

If you now export these two plug-ins into your runnig Eclipse, this dialog will remember the last selection (Simple vrs. Advanced).

As I hope this behavior is useful to others I created a bug report (with a patch). See Bug . I hope the subversion programmers will consider this patch (or an improved version of it).

Remember sharing is good. Open Source does not only allow you to solve your issues but it makes it easy to contribute back.

See Eclipse Papercuts to get all posts in this series.