Pull to refresh

Мой первый Eclipse-плагин

Reading time4 min
Views26K
Приветствую, дорогие хаброчитатели!
Некоторое время назад мне выпала интересная задача – написать плагин для Eclipse. Причем плагин не простой, а с хитрой задумкой.
Опыта написания плагинов для Eclipse у меня никогда не было, но надо – так надо, а что из этого получилось – под хаброкатом.

Хитрая задумка формулировалась так(точная цитата):
«В Eclipse существует понятие launch-конфигураций – настроек запуска проектов из workspace'а. Эти launch-конфигурации имеют разные свойства в зависимости от типа запускаемых приложений (java-приложение, Eclipse plugins, JUnit-тесты).
Иногда возникает потребность запускать несколько приложений из одного workspace'а – например, мы пишем клиент-серверное приложение и хотим одновременно запускать и сервер, и клиента. Для таких целей было бы удобно иметь новый тип launch-конфигураций – composite, который бы позволял создавать новую конфигурацию, ссылающуюся на существующие. При этом при запуске этой композитной конфигурации должны запускаться все конфигурации, на которые она ссылается. Задание – реализовать eclipse-plugin('ы), добавляющие такую новую launch-конфигурацию.»
Итак, получив и поняв эту задачу, я начал с того, что делает любой нормальный человек при решении задачи – декомпозиция задачи.

Крупная декомпозиция


Ну по-большому счету мне надо: плагин-раз, как сделать launch-конфигурацию – два.

Плагин


Моей отправной точкой для разработки плагина были вот эти две статьи:

Прочитав статьи я скачал инструментарий, на котором буду ваять плагин.
Качал тут: https://www.eclipse.org/downloads.
Качать надо не что попало, а то, что содержит “Plug-in Development Environment”.
Скачали – запускаем.
Жмем File-> New-> Project-> Plugin project
В появившемся окошке(рисунок ниже) жмем Next



Появится окошко:



В нем вбиваем стандартные настройки и жмем Next.
Появится окошко:



Здесь тоже все весьма стандартно, НО необходимо обратить внимание на крыж “This plug-in will make contributions to the UI” – его убираем, если UI не нужен и наборот. Жмем Next.
Появится следующее окошко:



Тут можете выбрать шаблон плагина, а я просто отщелкнул крыж вверху и нажал Finish.
В результате проект плагина будет создан и появится на экране нечто подобное:



Здесь мы можем на вкладке Dependencies добавить различные зависимости плагина, а файл plugin.xml играет весьма важную роль в разработке плагина.
Итак, как сделать плагин мы разобрались.
Дальше нас интересуют launch-конфигурации и с чем их едят.

Launch-конфигурация


Итак, что за зверь launch-конфигурация? По-сути это просто конфигурация запуска программы.
То есть настройка параметров с которыми будет запущена программа.
Подробнее об этом можно почитать тут: http://wiki.eclipse.org/FAQ_What_is_a_launch_configuration%3F
Как сделать launch-конфигурацию описано тут: http://www.eclipse.org/articles/Article-Launch-Framework/launch.html

Вернемся к задаче


Итак, как лепить плагин и launch-конфигурацию стало понятно.
Начнем.
Мы сделаем два плагина:
  • andrey.compositelaunchconfig – здесь будет собственно все что надо, для того чтобы запустить несколько launch-конфигураций. Но без UI. В статье приведенной выше, пишут, что лучше так разделить собственно логику и UI, вдруг кому-то захочется запустить как-то хитро это добро, и UI ему не нужен.
  • andrey.compositelaunchconfig.ui – здесь будет собственно ui этого дела.

Прочитав то, что в ссылочках, приведенных выше, Кэп какбе намекает, что надо бы для реализации launch-конфигурации заимплементить интерфейс ILaunchConfigurationDelegate.
Не будем стесняться и заимплементим интерфейс:

public class CompositeLaunchConfigurationDelegate implements ILaunchConfigurationDelegate {

	private void launchInnerConfiguration(ILaunchConfiguration configuration, String mode, ILaunch launch, IProgressMonitor monitor) throws CoreException {
		
		ILaunch configurationLaunch = configuration.launch(mode,monitor);
		for (IDebugTarget debugTarget : configurationLaunch.getDebugTargets()) {
			launch.addDebugTarget(debugTarget);
		}
		for (IProcess process : configurationLaunch.getProcesses()) {
			launch.addProcess(process);
		}
	}
		
	@Override
	public void launch(ILaunchConfiguration configuration, String mode, ILaunch launch, IProgressMonitor monitor) throws CoreException {
		
		if(!Utils.isLaunchModeValid(mode))
			throw new CoreException(new Status(IStatus.ERROR,Activator.getPluginId(),"launch mode is not valid"));
		if(!Utils.isConfigurationValid(configuration))
			throw new CoreException(new Status(IStatus.ERROR,Activator.getPluginId(),"configuration is not valid"));
		try
		{
			List<ILaunchConfiguration> launchConfigurations = Utils.getInnerConfigurations(configuration);
			SubMonitor launchMonitor = SubMonitor.convert(monitor, configuration.getName(), launchConfigurations.size());
			for (ILaunchConfiguration launchConfiguration : launchConfigurations) {
				if (!monitor.isCanceled()) {
					launchInnerConfiguration(launchConfiguration,mode,launch,launchMonitor.newChild(1));
				}
			}
		}
		finally{
			monitor.done();
		}
	}	

}


Параллельно мы сделаем функциональность, которая будет позволять проверить, что композитная конфигурация не зациклилась(ато возьмет какой-нибудь злой дядя и сделать конфигурацию, которая будет ссылаться на саму себя, а так мы его – опа по руке:))

Делаем UI


C UI-ным плагином все достаточно просто.
1.Нам надо сделать закладку, которая будет содержать настройки.
Для этого нам можно унаследоваться от класса AbstractLaunchConfigurationTab.
2. Сделать группу закладок, для этого нам надо унаследоваться от класса AbstractLaunchConfigurationTabGroup.
Итого
В результате всех этих нехитрых манипуляция получилась вот такая штука:



Слева все доступные конфигурации, а справа те, которые будут запускаться.
Tags:
Hubs:
Total votes 19: ↑12 and ↓7+5
Comments4

Articles