Наши партнеры

UnixForum





Библиотека сайта rus-linux.net

Среда разработки Eclipse

Глава 6 из книги "Архитектура приложений с открытым исходным кодом", том 1.

Оригинал: Eclipse, глава из книги "The Architecture of Open Source Applications" том 1.
Автор: Kim Moir
Перевод: Н.Ромоданов

6.1. Ранний вариант Eclipse

В начале 21-го века разработчикам программного обеспечения было предложено много инструментальных средств, но немногими из них можно было пользоваться одновременно. В проекте Eclipse старались создать платформу с открытым кодом, предназначенную для построения совместно работающих инструментальных средств для разработчиков приложений. Это должно было позволить разработчикам сосредоточиться на написании новых инструментов, а не писать код, который будет связан с вопросами инфраструктуры, например, с взаимодействием с файловой системой, работой с обновлениями и с подключением к хранилищам исходного кода. В проекте Eclipse, пожалуй, самым известным инструментальным средством,предназначенным для разработки на языке java, является Java Development Tools (JDT). Предполагалось, что это инструментальное средств для Java будет служить примером для тех, кто заинтересован в разработке инструментария для других языков.

Прежде, чем мы углубимся в архитектуру Eclipse, давайте посмотрим на то, как Eclipse SDK выглядит для разработчика. После запуска Eclipse и выбора рабочего пространства (workbench), вам будет представлен набор панелей для работы с Java (Java perspective). Такой набор состоит из специальных инструментальных панелей и панелей редакторов, которые необходимы в конкретном случае.

Рис.1: Набор панелей для работы с языком Java

В ранних вариантах архитектуры Eclipse SDK было три основных элемента, которые соответствовали трем основным подпроектам: платформе, инструментальным средствам JDT (Java Development Tools) и среде разработки плагинов PDE (Plug-In Development Environment).

6.1.1. Платформа

Платформа Eclipse написана с использованием Java и для того, чтобы ее запустить, требуется виртуальная машина Java VM. Платформа построена из небольших функциональных блоков, называемых плагинами. Плагины являются основой компонентной модели Eclipse. Плагин является, по существу, JAR-файлами с манифестом, в котором описывается плагин, его зависимости, и то, как его можно использовать или расширять. Эта информация манифеста изначально хранилась в файле plug-in.xml, который находился в корневой папке плагина. Инструментальные средства Java представляют собой плагины, предназначенные для ведения разработки на языке Java. Среда разработки плагинов (PDE) предоставляет собой набор инструментов для разработки плагинов расширений Eclipse. Плагины Eclipse написаны на языке Java, но также могут содержать другие добавления, например, файлы HTML в качестве онлайновой документации. Каждый плагин может иметь свой собственный загрузчик классов. Плагины могут зависеть от других плагинов, что указывается в инструкциях requires в файле plugin.xml. Если взгляните на файл plugin.xml плагина org.eclipse.ui, вы увидите его название и номер версии, а также зависимости, которые необходимо импортировать из других плагинов.

<?xml version="1.0" encoding="UTF-8"?>
<plugin
   id="org.eclipse.ui"
   name="%Plugin.name"
   version="2.1.1"
   provider-name="%Plugin.providerName"
   class="org.eclipse.ui.internal.UIPlugin">

   <runtime>
      <library name="ui.jar">
         <export name="*"/>
         <packages prefixes="org.eclipse.ui"/>
      </library>
   </runtime>
   <requires>
      <import plugin="org.apache.xerces"/>
      <import plugin="org.eclipse.core.resources"/>
      <import plugin="org.eclipse.update.core"/>
      :       :        :
      <import plugin="org.eclipse.text" export="true"/>
      <import plugin="org.eclipse.ui.workbench.texteditor" export="true"/>
      <import plugin="org.eclipse.ui.editors" export="true"/>
   </requires>
</plugin>

Чтобы поощрять создание проектов на платформе Eclipse, требуется механизм, который может расширять платформу, и нужно, чтобы платформа могла использовать такое расширение. Это достигается за счет использования расширений и точек расширений, еще одного элемента компонентной модели Eclipse. С помощью экспорта определяются интерфейсы, которыми, как вы ожидаете, воспользуются другие разработчики, когда будут писать собственные расширения; в результате классы, доступные за пределами вашего плагина, ограничиваются только теми, которые экспортируются. Также устанавливаются дополнительные ограничения на ресурсы, доступные за пределами плагина, что представляет собой отличие от того, когда доступными делаются все публичные методы или классы (т. е. типа public — прим.пер.). Экспортируемые плагины рассматриваются как публичный интерфейс API. Все остальное считается частными особенностями реализации (т. е. типа private — прим.пер.). Чтобы написать плагин, который добавит пункт меню на панели инструментов Eclipse, вы можете использовать точку расширения actionSets в плагине org.eclipse.ui.

<extension-point id="actionSets" name="%ExtPoint.actionSets"
                 schema="schema/actionSets.exsd"/>
<extension-point id="commands" name="%ExtPoint.commands"
                 schema="schema/commands.exsd"/>
<extension-point id="contexts" name="%ExtPoint.contexts"
                 schema="schema/contexts.exsd"/>
<extension-point id="decorators" name="%ExtPoint.decorators"
                 schema="schema/decorators.exsd"/>
<extension-point id="dropActions" name="%ExtPoint.dropActions"
                 schema="schema/dropActions.exsd"/>

Расширение вашего плагина, которое добавляет пункт меню к точке расширения org.eclipse.ui.actionSet, будет выглядеть следующим образом:

<?xml version="1.0" encoding="UTF-8"?>
<plugin
   id="com.example.helloworld"
   name="com.example.helloworld"
   version="1.0.0">
   <runtime>
      <library name="helloworld.jar"/>
   </runtime>
   <requires>
      <import plugin="org.eclipse.ui"/>
   </requires>
   <extension
         point="org.eclipse.ui.actionSets">
      <actionSet
            label="Example Action Set"
            visible="true"
            id="org.eclipse.helloworld.actionSet">
         <menu
               label="Example &Menu"
               id="exampleMenu">
            <separator
                  name="exampleGroup">
            </separator>
         </menu>
         <action
               label="&Example Action"
               icon="icons/example.gif"
               tooltip="Hello, Eclipse world"
               class="com.example.helloworld.actions.ExampleAction"
               menubarPath="exampleMenu/exampleGroup"
               toolbarPath="exampleGroup"
               id="org.eclipse.helloworld.actions.ExampleAction">
         </action>
      </actionSet>
   </extension>
</plugin>

Когда запускается Eclipse, среда выполнения платформы сканирует манифесты плагинов вашей инсталляции и строит реестр плагинов, хранящихся в памяти. Отображения между точками расширений и соответствующими расширения осуществляются по именам. Получившийся в результате реестр плагинов можно использовать из интерфейса API, предоставляемого платформой Eclipse. Реестр кэшируется на диске с тем, чтобы эту информацию могла было загрузить снова в следующий раз, когда Eclipse будет перезапущен. Все плагины, которые будут обнаружены при запуске, будут занесены в реестр, но они не будут активированы (загруженные классы) до тех пор, пока код не будет в действительности использован. Этот подход называется ленивой или отложенной активацией. Влияние добавление дополнительных сборок на производительность вашей инсталляции уменьшается за счет того, что действительная загрузка классов, ассоциированных с плагинами, не будет происходить до тех пор, пока классы действительно не понадобятся. Например, плагин, который добавляется к точке расширения org.eclipse.ui.actionSet, не будет активироваться до тех пор, пока пользователь не выберет новый пункт меню на панели инструментов.

Рис.6.2: Пример меню

Код, с помощью которого создается этот пункт меню, выглядит следующим образом:

package com.example.helloworld.actions;

import org.eclipse.jface.action.IAction;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.IWorkbenchWindowActionDelegate;
import org.eclipse.jface.dialogs.MessageDialog;

public class ExampleAction implements IWorkbenchWindowActionDelegate {
    private IWorkbenchWindow window;

    public ExampleAction() {
    }

    public void run(IAction action) {
        MessageDialog.openInformation(
            window.getShell(),
            "org.eclipse.helloworld",
            "Hello, Eclipse architecture world");
    }

    public void selectionChanged(IAction action, ISelection selection) {
    }

    public void dispose() {
    }

    public void init(IWorkbenchWindow window) {
        this.window = window;
    }
}

Как только пользователь выбирает новый элемент на панели инструментов, плагин, реализующий точку расширения, делает запрос в регистр расширений. Плагин, реализующий расширение, создает экземпляр расширения и плагин загружается. Как только будет активирован плагин, в нашем примере будет запущен конструктор ExampleAction, а затем будет инициализировано делегируемое действие Workbench. Поскольку выбор в рабочем пространстве изменился и был создан делегат, действие может поменяться. Откроется диалоговое окно с сообщением «Hello, Eclipse architecture world».

Такая расширяемая архитектура была одним из ключей к успешному росту экосистемы Eclipse. Компании или частные лица могли разрабатывать новые плагины и либо реализовывать их в виде открытого исходного кода или продавать их как коммерческие изделия.

Одна из наиболее важных концепций, касающаяся Eclipse, представляет собой утверждение, что все является плагинами. Независимо от того, входит ли плагин в платформу Eclipse, или вы написали его самостоятельно, все плагины являются главными компонентами собранного приложения. На рис.6.3 показаны кластеры функциональных возможностей, предоставляемых плагинами в ранних вариантах Eclipse.

Рис.6.3: Архитектура ранних вариантов Eclipse

Рабочее пространство (workbench) является наиболее известным элементом интерфейса для пользователей платформы Eclipse, т. к. в нем находятся данные, определяющие, как Eclipse будет представлен пользователю на рабочем столе. Рабочее пространство состоит из наборов окон, отдельных окон и окон редакторов. Редакторы ассоциированы с типами файлов и, поэтому, при открытии файла запускается необходимый редактор. Примером отдельного окна является окно «problems» (Проблемы), в котором указываются ошибки или предупреждения, касающиеся вашего кода на Java. Окна редакторов и отдельные окна совместно образуют набор окон или перспективу (perspective), в котором пользователям предоставляются инструментальные средства, организованные определенным образом.

Рабочее пространство Eclipse строится на базе инструментального набора виджетов Standard Widget Toolkit (SWT) и Jface, причем SWT заслуживает немного более детального рассмотрения. Инструментальные наборы виджетов могут быть как нативными, так и эмулирующими. Нативный инструментальный набор виджетов использует для создания компонентов пользовательского интерфейса, например, списков и кнопок, обращения к операционной системе. Взаимодействие с компонентами обрабатывается операционной системой. Эмулирующий инструментальный набор виджетов реализует компонент без обращения к операционной системе и самостоятельно обрабатывает нажатия мыши и клавиатуры, рисует, управляет фокусом и другими функциями и не перекладывает все это на операционную систему. Обе конструкции имеют свои сильные и слабые стороны.

Нативные инструментальные наборы виджетов являются «самим совершенством». Их виджеты выглядят на рабочем столе также, как и их аналоги из других приложений. Поставщики операционных систем постоянно изменяют внешний вид своих виджетов и добавляют новые возможности. Нативные инструментальные наборы виджетов получают эти обновления без всяких дополнительных затрат. К сожалению, нативные инструментальные наборы трудно реализовывать, поскольку виджеты операционной системы, на базе которых они создаются, значительно различаются и приводит ведет к противоречиям и программы теряют свойство переносимости.

Эмулирующий инструментальный набор виджетов либо имеет свой собственный внешний вид, либо пытается выполнять отрисовку и вести себя точно так, как это происходит в операционной системе. Их главное преимущество над нативными наборами состоит в их гибкости (хотя современные нативные инструментальные наборы виджетов, например, Windows Presentation Framework (WPF), столь же гибки). Поскольку код, реализующий виджет, является частью инструментария, а не встроен в операционную систему, виджет может выполнять отрисовку и вести себя любым образом. Программы, в которых используются эмулирующие инструменталные наборы виджетов, хорошо переносятсяс одной системы на другие. Ранние варианты эмулирующих инструменталных наборов виджетов имели плохую репутацию. Часто они были медлительными и плохо эмулировали работу операционной системы и из-за этого они выглядели неуместно на рабочем столе. В частности, в то время можно было легко отличить программы на языка Smalltalk-80 из-за того, что в них использовались эмулирующие виджеты. Пользователи знали, что они управляли «программой Smalltalk» и это плохо влияло на принятие приложений, написанных на Smalltalk.

В отличие от других языков программирования, например, C и C++, первые версии языка Java были доступны с нативным инструментальным набором виджетов, который имел название Abstract Window Toolkit (AWT). Считается, что AWT достаточно ограниченный, имеет ошибки, противоречивый и все его ругают. Фирма Sun и многие другие, отчасти из-за того, что имели опыт работы с AWT, считали нативный инструментальный набор виджетов, который был переносимым и обладал хорошей производительностью, непригодным для работы. Решением был Swing, полнофункциональный эмулирующий инструментальный набор виджетов.

Приблизительно в 1999 году подразделение OTI использовало язык Java для реализации продукта под названием VisualAge Micro Edition. В первой версии VisualAge Micro Edition использовался Swing, причем опыт OTI по использованию Swing не был положительным. Ранние версии Swing имели ошибки, работали долго и тратили много памяти, а аппаратура того времени была недостаточно мощной с тем, чтобы обеспечить приемлемую производительность. Подразделение OTI успешно создало нативный инструментальный набор виджетов для Smalltalk-80 и для других реализаций Smalltalk, в результате чего язык Smalltalk был встречен с одобрением. Этот опыт был использован для создания первой версии пакета SWT. VisualAge Micro Edition и SWT имели успех и когда началась работа над Eclipse, естественным выбором стал SWT. Использование в Eclipse пакета SWT поверх Swing раскололо сообщество Java. Некоторые видели заговор, но Eclipse добился успеха и использование SWT отличало его от других программ на языке Java. Eclipse обладал достаточной производительностью, имел хороший внешний вид и общее настроение было следующим: «Я не могу поверить, что это программа на языке Java».

Ранние варианты Eclipse SDK работали на Linux и Windows. В 2010 году появилась поддержка более десятка платформ. Разработчик может написать приложение для одной платформы, и развернуть его на нескольких платформах. В то время в рамках сообщества Java разработка нового инструментального набора виджетов для Java считалась спорным вопросом, но те, кто работал с Eclipse, чувствовали, что нужно потратить усилия и получить лучшее нативное решение, используемое на рабочем столе. Это справедливо и сегодня, и есть миллионы строк кода, зависящего от SWT.

JFace представляет собой слой поверх SWT, предоставляющий инструментальные средства для обычных задач программирования пользовательского интерфейса, например, фреймворки для работы с настройками и визардами. Точно также, как и SWT, он разрабатывался так, чтобы его можно было использовать со многими оконными системами. Тем не менее, это чистый код на языке Java, в котором нет нативного кода платформ.

В рамках платформы также предоставляется интегрированная система подсказок, базирующаяся на небольших блоках информации, которые называются темами. Тема состоит из метки и ссылки на место, где находится сама тема. Ссылка может указывать на HTML-файл с документацией или на XML-документ, описывающий дополнительные ссылки. Темы группируются вместе в виде оглавлений (в TOC). Темы можно рассматривать как листья, а TOC - как три подразделения организации. Для того, чтобы добавить содержимое подсказки к вашему приложению, вы можете к точке расширения org.eclipse.help.toc добавить org.eclipse.platform.doc.isv plugin.xml так, как это сделано ниже.

<?xml version="1.0" encoding="UTF-8"?>
<?eclipse version="3.0"?>
<plugin>

<!-- ===================================================================== -->
<!-- Определяем первичное содержимое TOC                                   -->
<!-- ===================================================================== -->
   &l;textension
         point="org.eclipse.help.toc">
      <toc
            file="toc.xml"
            primary="true">
      </toc>
      <index path="index"/>
   </extension>
<!-- ===================================================================== -->
<!-- Определяем содержимое TOC для подтем                                  -->
<!-- ===================================================================== -->
   <extension
         point="org.eclipse.help.toc">
      <;toc
            file="topics_Guide.xml">
      </toc>
      &l;ttoc
            file="topics_Reference.xml">
      </toc>
      <toc
            file="topics_Porting.xml">
      </toc>
      <toc
            file="topics_Questions.xml">
      &l;t/toc>
      <toc
            file="topics_Samples.xml">
      </toc>
   </extension>

Для индексирования и онлайнового поиска содержимого подсказок используется пакет Apache Lucene. В ранних вариантах Eclipse онлайновая подсказка представляла собой веб-приложение, работающая на сервере Tomcat. Кроме того, за счет предоставления подсказки в самом Eclipse, у вас также могли использовать некоторое подмножество плагинов, предназначенные для работы с подсказками, для того, чтобы создавать автономно работающие серверы подсказок [3].

Eclipse также предоставлял поддержку среды командной работы с репозитарием исходного кода, создания патчей и других обычно выполняемых задач. В рабочем пространстве предоставлялся набор файлов и метаданных, с помощью которых ваша работа будет сохранена в файловой системе. Имелся также отладчик, позволяющий отслеживать проблемы в коде Java, а также фреймворк для построения отладчиков для конкретных языков.

Одна из целей проекта Eclipse состояла в поддержке разработчиков программ с открытым исходным кодом и разработчиков коммерческих программ в использовании данной технологии для расширения платформы в соответствие с их собственными потребностями, причем один из способов поощрения применения данной технологии заключался в предоставлении стабильного интерфейса API. API можно рассматривать как технический контракт, определяющий поведение вашего приложения. Его также можно рассматривать как социальный контракт. В проекте Eclipse есть мантра - «API - навсегда». Так что следует быть исключительно аккуратным когда пишется интерфейс API и учитывать, что он предназначен для использования на неопределенно долгий срок. Стабильное API представляет собой контракт между клиентом или потребителем и поставщиком API. Этот контракт гарантирует, что клиент может положится на использование платформы Eclipse, API в которой предоставляет на длительный срок, и не надо будет беспокоиться о том, что потребуется рефакторинг части клиентского приложения. Хороший интерфейс API также достаточно гибок с тем, чтобы можно было развивать его реализации.


Продолжение статьи: Инструментарий Java Development Tools (JDT).