Recursos com ligações

As abordagens anteriores a recursos e sistema de ficheiros (Correlacionar recursos com localizações em disco) partiram do princípio de que todos os recursos num projecto se encontrem no mesmo lugar no sistema de ficheiros.  Tal é geralmente verdade.  Contudo, o conceito de recursos com ligações na área de trabalho é facultado para que os ficheiros e as pastas contidos num projecto possam ser armazenados num sistema de ficheiros fora da localização do projecto. 

Os recursos com ligações podem ser localizados em qualquer localização num sistema de ficheiros. Podem residir fora da localização do projecto ou até dentro de outro projecto. Há poucas restrições às localizações dos recursos ligados. Pode ser usado o método IWorkspace.validateLinkLocation para garantir que determinada localização é válida para criar um recurso ligado.

Os recursos ligados são criados com o método IFolder.createLink ou IFile.createLink. Para determinar programaticamente se dado recurso é recurso ligado, poderá utilizar o método IResource.isLinked. Repare que este método só devolve true em caso de recursos ligados e não de descendentes de recursos ligados.

À parte estes métodos especiais para criar recursos ligados e saber se dado recurso o é, poderá utilizar a API do espaço de trabalho normal ao manipular recursos ligados. Na maioria dos casos, os recursos ligados funcionam exactamente como quaisquer outros recursos no espaço de trabalho. No entanto, aplicam-se algumas restrições ao mover, copiar ou eliminar recursos ligados.   Consulte IResource e respectivas subclasses para informações sobre operações individuais e suas limitações.

Variáveis de caminho

As variáveis de caminho podem ser usadas ao especificar a localização de recursos ligados.  Uma variável de caminho é uma correlação (String -> IPath) ou (String -> URI) simples que define um atalho para uma localização num sistema de ficheiros. As variáveis podem facilitar a gestão de recursos ligados reduzindo o número de lugares onde se utilizam caminhos de sistema de ficheiros absolutos codificados imutáveis.

As variáveis de caminho dinamizam a gestão de recursos ligados para os utilizadores de vários modos:

O último artigo desta lista merece mais explicações. Quando um utilizador cria um recurso ligado num projecto, é adicionada uma descrição do recurso ligado ao ficheiro de descrição do projecto (".project") na localização do projecto. Ao utilizar uma variável de caminho, os utilizadores podem partilhar um projecto (copiando o conteúdo do projecto ou usando um repositório) e redefinir a variável para se adaptar a cada estação de trabalho individual.  Por exemplo, um utilizador poderá armazenar recursos externos em c:\temp num sistema, enquanto outro utilizador com Unix pode armazenar os mesmos recursos em /home/username/tmp.  Definir uma variável de caminho em cada espaço de trabalho (TEMP=c:\temp e TEMP=/home/userb/tmp) permite aos utilizadores contornar esta diferença e partilhar os projectos com recursos ligados tal como estão.

O IPathVariableManager define a API para criar, manipular e resolver variáveis de caminho. Proporciona também métodos para validar nomes e valores de variáveis antes de os criar e para instalar um ouvinte a ser notificado quando se alteram definições de variáveis de caminho. Poderá obter uma instância desta classe com IWorkspace.getPathVariableManager. Consulte os exemplos de código no final desta secção para mais detalhes.

O método IResource.getRawLocationURI pode ser utilizado para encontrar a localização não processada de um recurso com ligações. Ou seja, para obter o verdadeiro nome da variável de caminho em vez de resolver o respectivo valor.  Se a localização de um recurso não for definida com a variável de caminho, o método getRawLocationURI age da mesma forma que o método getLocationURI.

Ligações quebradas

Os clientes que manipulam recursos programaticamente devem ter em mente a possibilidade de ligações quebradas. As ligações quebradas ocorrem quando não existe uma localização de recurso ligado ou a mesma é especificada relativamente a uma variável de caminho indefinida. Aplicam-se os seguinte casos especiais na utilização do protocolo IResource:

Compatibilidade com plug-ins instalados

Alguns plug-ins poderão não tratar recursos ligados, de modo que há vários mecanismos disponíveis para os desactivar. Se escrever um plug-in que precise absolutamente que todo o conteúdo de um projecto se encontre na localização predefinida do projecto, poderá usar estes mecanismos para impedir os utilizadores de criarem recursos ligados onde não quiser que apareçam.

O primeiro mecanismo chama-se veto à natureza do projecto. Se definir a sua própria natureza de projecto, poderá especificar na definição da natureza que esta última não é compatível com recursos ligados. De seguida é apresentado um exemplo de uma definição de natureza que emprega o veto à natureza:

<extension
	id="myNature"
	name="My Nature"
	point="org.eclipse.core.resources.natures">
	<runtime>
		<run class="com.xyz.MyNature"/>
	</runtime>
	<options allowLinking="false"/>
</extension>

O segundo mecanismo para impedir a criação de recursos ligados é o gancho de equipa. Se definir a sua própria implementação de repositório, poderá utilizar o ponto de extensão org.eclipse.core.resources.teamHook para impedir a criação de recursos ligados em projectos que sejam partilhados com o tipo de repositório. Por predefinição, os fornecedores de repositórios não permitem recursos ligados em projectos ligados ao repositório.  

Se o suporte do repositório for facultado por um plug-in mais antigo que não considere recursos ligados, não poderá criar recursos ligados nesses projectos.  

Por fim, há uma definição de preferências que se pode utilizar para desactivar recursos ligados em todo o espaço de trabalho. Porquanto os anteriores dois mecanismos de veto funcionem projecto a projecto, esta preferência afecta todos os projectos no espaço de trabalho. Para definir esta preferência programaticamente, utilize a preferência ResourcesPlugin.PREF_DISABLE_LINKING. Repare que mesmo quando definida, os utilizadores ou os plug-ins podem sobrepô-la desactivando-a.

Recursos ligados em código

Vejamos alguns exemplos da utilização de recursos ligados em código. Começamos por definir uma variável de caminho:

   IWorkspace workspace = ResourcesPlugin.getWorkspace();
   IPathVariableManager pathMan = workspace.getPathVariableManager();
   String name = "TEMP";
   IPath value = new Path("c:\\temp");
   if (pathMan.validateName(name).isOK() && pathMan.validateValue(value).isOK()) {
      pathMan.setValue(name, value);
        } else {
      //invalid name or value, throw an exception or warn user
   }

Agora podemos criar um recurso ligado relativo à variável de caminho definida:

   IProject project = workspace.getProject("Project");//assume this exists
   IFolder link = project.getFolder("Link");
   IPath location = new Path("TEMP/folder");
   if (workspace.validateLinkLocation(location).isOK()) {
      link.createLink(location, IResource.NONE, null);
   } else {
      //invalid location, throw an exception or warn user
   }

E já está! Já temos uma pasta ligada no espaço de trabalho chamada "Ligação" que se encontra em "c:\temp\pasta".

Terminamos com algumas porções de código neste recurso ligado para ilustrar o comportamento de outros métodos relacionados com recursos ligados:

   link.getFullPath() ==> "/Project/Link"
   link.getLocation() ==> "c:\temp\folder"
   link.getRawLocation() ==> "TEMP/folder"
   link.isLinked() ==> "true"
   
   IFile child = link.getFile("abc.txt");
   child.create(...);
   child.getFullPath() ==> "/Project/Link/abc.txt"
   child.getLocation() ==> "c:\temp\folder\abc.txt"
   child.getRawLocation() ==> "c:\temp\folder\abc.txt"
   child.isLinked() ==> "false"