Quando o núcleo da plataforma está sendo executado e o plug-in de recursos está ativo, a área de trabalho é representada por uma ocorrência de IWorkspace, que fornece protocolo de acesso aos recursos que contém. Uma ocorrência de IWorkspace representa uma coleção de arquivos e diretórios associados no sistema de arquivos local. Você pode acessar a área de trabalho na classe do plug-in de recursos, emorg.eclipse.core.resources.
ResourcesPlugin.getWorkspace();
Quando o plug-in de recursos não está sendo executado, a área de trabalho existe somente no sistema de arquivos local e é visualizada ou manipulada pelo usuário através de ferramentas padrão com base no arquivo. Vamos ver a aparência da área de trabalho no disco, conforme explicamos a API do plug-in de recursos.
Quando você instalou a plataforma SDK, descompactou os arquivos em um diretório de sua escolha. Chamaremos esse diretório de diretório raiz da plataforma. Ele é o diretório que contém o diretório plug-ins, entre outros. Dentro do diretório raiz da plataforma, existe um diretório workspace que é utilizado para conter os recursos criados e manipulados pela plataforma. Se você olhar no diretório workspace, verá subdiretórios separados para cada projeto existente no espaço de trabalho. Nesses subdiretórios estão as pastas e os arquivos de cada projeto.
Se a SDK do nosso exemplo estiver instalada em c:\MySDK, no diretório c:\MySDK\workspace encontraremos subdiretórios nomeados após os projetos da área de trabalho, MyWeb e MyServlet. Eles são chamados de diretórios de conteúdo dos projetos. Os diretórios de conteúdo são criados pela plataforma quando o usuário cria um projeto.
Dentro de cada diretório, encontramos arquivos e pastas do projeto, cujo layout é exatamente o mesmo daquele na árvore de recursos da área de trabalho. Todos os nomes de arquivo são os mesmos e os conteúdos são os mesmos, quer sejam acessados através do sistema de arquivos ou da área de trabalho. A única surpresa é o arquivo .project, explicado a seguir.
C:\MySDK\workspace (raiz da área de trabalho) .metadata\ (diretório de metadados da plataforma) MyWeb\ (diretório de conteúdo do projeto para MyWeb) .project index.html images\ logo.gif MyServlet\ (diretório de conteúdo do projeto para MyServlet) .project src\ main.java bin\ main.class
A plataforma tem um diretório especial .metadata para armazenamento de informações internas da plataforma. O diretório .metadata de uma área de trabalho é considerado uma "caixa preta".Informações importantes sobre a estrutura da área de trabalho, como referências de um projeto ou as propriedades de um recurso, são armazenadas na parte de meta-dados da área de trabalho e devem ser acessadas somente pelas ferramentas, através da API da plataforma. Esses arquivos nunca devem ser editados ou manipulados utilizando a API genérica do sistema de arquivos.
Além disso, cada projeto possui seu próprio arquivo .project, em que os metadados sobre o projeto são mantidos. Este arquivo é basicamente equivalente em disco às informações encontradas no IProjectDescription de um projeto.
Com exceção do diretório .metadata e dos arquivos .project, as pastas e arquivos no diretório do espaço de trabalho são acessíveis por outras ferramentas. Os arquivos e diretórios podem ser manipulados por ferramentas não integradas, como editores de texto e utilitários do sistema de arquivos. O único problema é que o usuário deve ter cuidado ao editar esses arquivos tanto no workbench como externamente. (Isso não é diferente de quando um usuário edita um arquivo utilizando duas ferramentas separadas independentes.) O workbench fornece operações de atualização para reconciliar a exibição dos recursos do espaço de trabalho com o estado real no sistema de arquivos.
A API do recurso permite-nos manipular essa árvore de recursos no código. A seguir veremos alguns fragmentos de código, para experimentar rapidamente a API do recurso. A API do recurso é definida em um série de interfaces no org.eclipse.core.resources. Há interfaces para todos os tipos de recursos, como IProject, IFolder e IFile. O protocolo comum extensível é definido em IResource. Utilizamos também a interface de org.eclipse.core.runtime IPath, a qual representa caminhos segmentados, como caminhos do recurso ou do sistema de arquivos.
A manipulação de recursos é muito semelhante à manipulação de arquivos utilizando o java.io.File. A API tem como base identificadores. Ao utilizar uma API como getProject ou getFolder, você recebe um identificador para o recurso. Não há garantia ou requisito de que o próprio recurso exista até que você tente fazer algo com o identificador. Se você espera que um recurso exista, é possível utilizar o método exists para assegurar que este seja o caso.
Para navegar pela área de trabalho a partir de um plug-in, devemos primeiro obter o IWorkspaceRoot, que representa o topo da hierarquia de recursos na área de trabalho.
IWorkspaceRoot myWorkspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
Depois de obtermos a raiz da área de trabalho, podemos acessar os projetos que estão nela.
IProject myWebProject = myWorkspaceRoot.getProject("MyWeb"); // abra se necessário if (myWebProject.exists() && !myWebProject.isOpen()) myWebProject.open(null);
Para poder manipular um projeto, precisamos primeiro abri-lo. A abertura do projeto lê a estrutura dele no disco e cria a representação da árvore de recursos do projeto do objeto na memória. A abertura de um projeto é uma operação explícita, pois cada projeto aberto consome memória para representar a árvore de recursos internamente e os projetos abertos participam de vários eventos do ciclo de vida do recurso (como construção), os quais podem ser demorados. Em geral, os projetos fechados não podem ser acessados e aparecerão vazios, embora os recursos ainda estejam presentes no sistema de arquivos.
Você notará que muitos desses exemplos de recurso passam um parâmetro nulo durante a manipulação de recursos. Muitas operações do recurso são pesadas o suficiente para garantir relatórios de progresso e cancelamento do usuário. Se o código possui uma interface com o usuário, geralmente você transmitirá um IProgressMonitor, que permite que o plug-in de recursos relate o progresso conforme o recurso é manipulado e permite ao usuário cancelar a operação, se desejado. Por enquanto, vamos simplesmente transmitir null, indicando nenhuma monitoração de progresso.
Depois do projeto ter sido aberto, podemos acessar suas pastas e arquivos e também criar adicionais. No exemplo a seguir, criamos um recurso de arquivo a partir do conteúdo de um arquivo localizado fora de nosso espaço de trabalho.
IFolder imagesFolder = myWebProject.getFolder("images"); if (imagesFolder.exists()) { // criar um novo arquivo IFile newLogo = imagesFolder.getFile("newLogo.gif"); FileInputStream fileStream = new FileInputStream( "c:/MyOtherData/newLogo.gif"); newLogo.create(fileStream, false, null); // a criação fecha o fluxo de arquivos, sem problemas. }
No exemplo acima, a primeira linha obtém um identificador para a pasta de imagens. Devemos antes verificar se a pasta existe para podermos fazer qualquer coisa interessante com ela. Da mesma forma, quando obtemos o arquivo newLogo, o identificador não representará um arquivo real enquanto não criarmos o arquivo na última linha. Neste exemplo, criamos o arquivo ocupando-o com o conteúdo de logo.gif.
O framento a seguir é similar ao anterior, a exceção é que ele copia o arquivo newLogo do logotipo original, em vez de criar um novo a partir de seu conteúdo.
IFile logo = imagesFolder.getFile("logo.gif"); if (logo.exists()) { IPath newLogoPath = new Path("newLogo.gif"); logo.copy(newLogoPath, false, null); IFile newLogo = imagesFolder.getFile("newLogo.gif"); ... }
Finalmente, criaremos outra pasta de imagens e moveremos o arquivo recentemente criado para ela. Renomeamos o arquivo como um efeito colateral dessa movimentação.
... IFolder newImagesFolder = myWebProject.getFolder("newimages"); newImagesFolder.create(false, true, null); IPath renamedPath = newImagesFolder.getFullPath().append("renamedLogo.gif"); newLogo.move(renamedPath, false, null); IFile renamedLogo = newImagesFolder.getFile("renamedLogo.gif");
Muitos dos métodos de API do recurso incluem um sinalizador booleano force que especifica se os recursos que estão fora de sincronização com os arquivos correspondentes no sistema de arquivos local serão atualizados assim mesmo. Consulte IResource para obter informações adicionais. Também é possível utilizar IResource.isSynchronized para determinar se um recurso específico está em sincronia com o sistema de arquivos.
No exemplo de árvore de recursos, assumimos que todos os diretórios de conteúdo do projeto estão no diretório workspace, abaixo do diretório raiz da plataforma (C:\MySDK\workspace). Essa é a configuração padrão para projetos. No entanto, o diretório de conteúdo de um projeto pode ser mapeado novamente para qualquer diretório arbitrário no sistema de arquivos, talvez uma unidade de disco diferente.
A capacidade de mapear a localização de um projeto independentemente dos outros permite ao usuário armazenar o conteúdo de um projeto no lugar apropriado para ele e sua equipe. O diretório de conteúdo de um projeto deve ser considerado "aberto a todos". Isso significa que os usuários podem criar, modificar e excluir recursos utilizando a área de trabalho e os plug-ins ou utilizando diretamente as ferramentas e os editores com base no sistema de arquivos.
Os nomes de caminho do recurso não são caminhos completos do sistema de arquivos. Os caminhos do recurso têm sempre como base a localização do projeto (normalmente o diretório workspace). Para obter o caminho completo do sistema de arquivos até um recurso, você deve consultar sua localização utilizando IResource.getLocation. No entanto, não será possível utilizar IProjectDescription.setLocation para alterar sua localização, pois esse método é apenas um simples definidor de uma estrutura de dados.
De modo contrário, para obter o objeto de recurso correspondente fornecido um caminho do sistema de arquivos, é possível utilizar IWorkspaceRoot.getFileForLocation ou IWorkspaceRoot.getContainerForLocation.
Quando utilizamos a API dos recursos para modificar a árvore de recursos da nossa área de trabalho, os arquivos são alterados no sistema de arquivos além da atualização dos objetos do nosso recurso. E as alterações dos arquivos do recurso que acontecem fora da API da plataforma?
As alterações externas não serão refletidas nos objetos da área de trabalho e do recurso enquanto não forem detectadas pelo plug-in de recursos. Os clientes podem utilizar a API do recurso para reconciliar objetos do espaço de trabalho e do recurso com o sistema de arquivos local, silenciosamente e sem a intervenção do usuário. O usuário sempre pode forçar explicitamente uma atualização na exibição do navegador de recurso do workbench.
Nota: muitos dos métodos nas APIs de recurso incluem um parâmetro force, o qual especifica como os recursos que estão fora de sincronização com o sistema de arquivos devem ser tratados. A Referência da API para cada método fornece informações específicas sobre esse parâmetro. Outros métodos na API permitem o controle programático da atualização do sistema de arquivos, como IResource.refreshLocal(int depth, IProgressMonitor monitor). ConsulteIResource para obter informações sobre a utilização correta e os custos.