Если запущена платформа и активен модуль ресурсов, то рабочая область представлена экземпляром IWorkspace, обеспечивающим протокол для доступа к находящимся в ней ресурсам. Экземпляр IWorkspace - это связанный набор файлов и папок в локальной файловой системе. Обратиться к рабочей области можно из класса модуля (определенного в org.eclipse.core.resources).
IWorkspace workspace = ResourcesPlugin.getWorkspace();
Если модуль ресурсов не запущен, то рабочая среда существует исключительно в локальной файловой системе и управляется стандартными файловыми средствами. Так как мы пытаемся разобраться в API модуля ресурсов, то давайте посмотрим, как рабочая область выглядит на диске.
При установке SDK платформы файлы распаковываются в выбранный каталог. Назовем этот каталог корневым каталогом платформы. В числе прочих, в нем содержится каталог plugins. Внутри корневого каталога платформы есть каталог workspace, в котором хранятся ресурсы, создаваемые и управляемые платформой. Для каждого проекта рабочей области в каталоге workspace выделяется отдельный подкаталог. В нем хранятся папки и файлы проекта.
Например, если SDK установлен в c:\MySDK, то в каталоге c:\MySDK\workspace будут подкаталоги с именами проектов : MyWeb и MyServlet. Эти каталоги называются каталогами содержимого проекта. Каталоги содержимого создаются платформой при создании проекта.
В каждом каталоге хранятся файлы и папки проекта, расположены они при этом точно так же, как и в дереве ресурсов рабочей области. Имена и содержимое всех файлов идентичны, и нет разницы, откуда к ним обращаться - с диска или из рабочей области. Отличается только файл .project - отличие объяснено ниже.
C:\MySDK\workspace (корневой каталог рабочей области) .metadata\ (каталог метаданных платформы) MyWeb\ (каталог содержимого проекта для MyWeb) .project index.html images\ logo.png MyServlet\ (каталог содержимого проекта для MyServlet) .project src\ main.java bin\ main.class
В платформе есть особый каталог .metadata, в котором хранится внутренняя информация платформы. Каталог .metadata рабочей области служит "черным ящиком." В блоке метаданных хранятся важные сведения о структуре рабочей области, например, ссылки на проект или свойства ресурсов, поэтому обращаться к ним можно только с помощью средств API платформы. Через общий API файловой системы с этими файлами работать нельзя.
Кроме того, для каждого проекта создается файл .project, в котором хранятся метаданные проекта. Информация этого файла большей частью совпадает с информацией в IProjectDescription проекта.
Кроме каталога .metadata и файлов .project, папками и файлами каталога рабочей области можно управлять любыми средствами. Это не обязательно будут встроенные средства управления. Могут быть, например, утилиты файловой системы или текстовые редакторы. И все же пользователю следует быть очень внимательным при редактировании этих файлов одновременно как средствами рабочей области, так и внешними. (Это всегда так, если изменять файл сразу в двух редакторах.) В рабочей среде предусмотрены функции обновления, служащие для согласования представления ресурсов в рабочей области с их реальным состоянием в файловой системе. Поэтому рабочая область периодически обновляется.
С помощью API ресурса можно управлять деревом этого ресурса программно. Ниже приведены несколько фрагментов кода, дающих впечатление об API ресурса. API ресурса определяется в ряде интерфейсов в org.eclipse.core.resources. Здесь можно найти интерфейсы для всех типов ресурсов, например: IProject, IFolder и IFile. Общие протоколы определяются в IResource. Также нам пригодится интерфейс IPath из org.eclipse.core.runtime, в котором представлены разбитые на сегменты пути, например, пути ресурсов и файловой системы.
Управление ресурсами очень похоже на управление файлами с помощью java.io.File. API основан на описателях. Если вы работаете с API типа getProject или getFolder, то описатель возвращается ресурсу. Конечно, нет никаких гарантий (и требований), что этот ресурс существует. Проверить существование ресурса можно с помощью метода exists.
Для перехода из модуля в рабочую область необходимо в первую очередь получить IWorkspaceRoot, который представляет собой вершину иерархии ресурсов рабочей области.
IWorkspaceRoot myWorkspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
Теперь, имея корень рабочей области, мы можем получить доступ к ее проектам.
IProject myWebProject = myWorkspaceRoot.getProject("MyWeb"); // open if necessary if (myWebProject.exists() && !myWebProject.isOpen()) myWebProject.open(null);
Прежде, чем начать управление проектом, его следует открыть. При открытии проекта с диска читается его структура, и в памяти создается представление дерева ресурсов проекта. Открытие проекта - это явная операция, поскольку для каждого открытого проекта выделяется память для внутреннего представления ресурсов, и открытые проекты в какой-то мере участвуют в различных событиях жизненного цикла ресурса (например, компоновка), которые могут быть длительными. Как правило, обращение к закрытым проектам невозможно и будет неудачным, даже если их ресурсы по-прежнему находятся в файловой системе.
Обратите внимание, что многие примеры ресурсов при управлении ими передают параметр null. Многие операции с ресурсами занимают много времени, и лучше будет обеспечить возможность вывода отчета о состоянии и возможность отмены. Если в вашем коде есть пользовательский интерфейс, то вы, скорее всего, будете передавать параметр IProgressMonitor, выдающий отчет о состоянии этого ресурса и позволяющий пользователю при необходимости отменить операцию. А пока мы просто передаем null, обозначающий отсутствие отслеживания состояния выполнения.
После открытия проекта можно обращаться к его существующим файлам и папкам и создавать новые. В следующем примере мы создадим файловый ресурс на основе файла, находящегося за пределами рабочей области.
IFolder imagesFolder = myWebProject.getFolder("images"); if (imagesFolder.exists()) { // создание нового файла IFile newLogo = imagesFolder.getFile("newLogo.png"); FileInputStream fileStream = new FileInputStream( "c:/MyOtherData/newLogo.png"); newLogo.create(fileStream, false, null); // создание закрывает поток файла. }
В первой строке этого примера мы получаем описатель папки images. Перед тем, как начать с ним что-то делать, следует проверить существование папки методом exists. В противном случае при получении файла newLogo описатель не будет указывать на реальный файл до тех пор, пока он не будет создан (последняя строка). В этом примере мы создаем файл и заполняем его содержимым файла logo.png.
Следующий фрагмент похож на предыдущий, но он не создает новый файл на основе содержимого logo, а копирует logo в newLogo.
IFile logo = imagesFolder.getFile("logo.png"); if (logo.exists()) { IPath newLogoPath = new Path("newLogo.png"); logo.copy(newLogoPath, false, null); IFile newLogo = imagesFolder.getFile("newLogo.png"); ... }
И наконец, создаем другую папку изображений и перемещаем туда вновь созданный файл. При перемещении файл переименовывается.
... IFolder newImagesFolder = myWebProject.getFolder("newimages"); newImagesFolder.create(false, true, null); IPath renamedPath = newImagesFolder.getFullPath().append("renamedLogo.png"); newLogo.move(renamedPath, false, null); IFile renamedLogo = newImagesFolder.getFile("renamedLogo.png");
Во многих методах API ресурса используется булевская переменная force, указывающая, необходимо ли принудительно обновлять ресурс, не синхронизированный с соответствующим файлом в файловой системе. Дополнительные сведения приведены в разделе IResource . Определить, синхронизирован ли ресурс с файловой системой, можно также с помощью флага IResource.isSynchronized.
В примере дерева ресурсов мы считаем, что все каталоги содержимого проекта находятся в каталоге workspace, находящемся в корневом каталоге платформы (C:\MySDK\workspace). Такова стандартная конфигурация проектов. Однако каталог содержимого проекта можно связать с любым каталогом файловой системы, даже находящимся на другом логическом диске.
Благодаря возможности связывания каталога проекта с любым расположением, не зависящим от других проектов, пользователь может хранить свой проект там, где удобно ему или его группе. Каталог содержимого проекта должен считаться "всеобщим достоянием." Это означает, что пользователи могут создавать, изменять и удалять ресурсы средствами рабочей среды и модулей или напрямую системными средствами.
Путь к ресурсу - не то же самое, что полный системный путь. Путь к ресурсу всегда отражает место расположения проекта (обычно это каталог workspace). Для того, чтобы получить полный системный путь к ресурсу, необходимо запросить место его расположения с помощью IResource.getLocation. Однако, изменить это место с помощью метода IProjectDescription.setLocation нельзя, поскольку этот метод - всего лишь установка для структуры данных.
Если требуется узнать объект ресурса, находящийся по заданному системному пути, можно воспользоваться методом IWorkspaceRoot.getFileForLocation или IWorkspaceRoot.getContainerForLocation.
Когда мы изменяем дерево ресурсов рабочей области с помощью API, происходит не только обновление объектов ресурсов, но и изменение файлов в файловой системе. Что же происходит при изменении файлов ресурсов вне API платформы?
Внешние изменения ресурса не отражаются в рабочей области и объектах ресурса до тех пор, пока не будут обнаружены модулем ресурсов. С помощью механизма (своего для каждой операционной системы) модуль ресурсов обнаруживает изменения файловой системы, внесенные извне. Кроме того, с помощью API ресурса можно организовать согласование объектов ресурсов и рабочей области с локальной файловой системой без вмешательства пользователя. При необходимости пользователь может принудительно обновить представление рабочей среды в навигаторе ресурсов.
Во многих методах API ресурсов используется параметр force, указывающий, как будут обрабатываться не синхронизированные с файловой системой ресурсы. Более конкретные сведения об этом параметре можно найти в справочнике по API для каждого метода. Существуют также методы, позволяющие программно управлять обновлением файловой системы, например, метод IResource.refreshLocal(int depth, IProgressMonitor monitor). Сведения о работе с ним можно найти в разделе IResource.
Для модулей, в которых необходима поддержка собственных механизмов обновления рабочей области на основе состояния внешней файловой системы, можно воспользоваться точкой расширения org.eclipse.core.resources.refreshProviders. Дополнительная информация приведена в разделе Механизмы обновлений.