번역/수정 자료 입니다.
이클립스 플러그인 및 이클립스RCP에서 IResource인터페이스를 이용하여 Eclipse Workspace상의 자원을 취급하는 방법에 대해서 알아 보자.
Eclipse의 모든 자원은 Workspace로 불리는 영역에 저장 된다. Workspace는 Eclipse Workbench에 대해서 하나만 존재하여, 폴더나 파일 등의 자원은 이 Workspace상에 맵핑 되지 않으면 Eclipse에서 취급할 수 없다. 또, Workspace에는 항상 하나의 Workspace Root만 존재 한다. 또한, Workspace Root에는 몇 개의 Project가 존재해, 그 Project내에 폴더나 파일이 존재 하게 된다.
또, Project나 폴더, 파일 이라고 하는 Resource는 실제의 파일 시스템에 맵핑 된다. Eclipse의 프로젝트, 폴더, 파일 등의 Resource는 파일시스템의 디렉토리나 파일에 대응한다. 하지만 이러한 Eclipse의 자원을 직접 파일시스템을 이용하여 취급하는 것은 좋지 않다. 반드시 각 자원 마다 할당할 수 있는 Resource의 인터페이스(IResource, IFolder, IFile등..)를 이용하여 취급해야만 한다.
위에서 설명한 대로 Resource의 조작은 Resource핸들을 이용해서 수행한다. 통상적으로 Resource의 핸들은 갑자기 작성할 수 없고, 임의의 Resource 핸들을 작성하기 위해서는, 그 Resource의 컨테이너가 되는 Resource의 핸들이 필요하다. 예를 들면, 파일의 Resource를 작성하기 위해서는, 프로젝트나 폴더의 핸들이 필요하다. 또, 폴더를 작성하기 위해서는, 프로젝트나 부모 폴더의 핸들이 필요하다. 또한, 프로젝트를 작성하기 위해서는 Workspace Root의 핸들이 필요하다.
그러면 Workspace Root의 핸들 작성은 어떻가 하는가 하면, Workspace Root는 항상 존재하는 것으로 생성하거나 복사, 이동 할 수없다. 또 Workspace Root의 핸들은 IWorkspaceRoot인터페이스롤 나타내져 플러그인의 코드 어디에서도 아래와 같은 방법으로 취득 할 수 있다.
|
IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); |
이IWorkspaceRoot 오브젝트는, 프로젝트의 컨테이너가 되는 자원의 핸들이기 때문에, IWorkspaceRoot를 취득하면, 프로젝트의 작성이 가능하게 된다. 또, 프로젝트의 핸들은 IProject인터레이스로 나타내지며 폴더와 파일은 각각 IFolder, IFile인터레이스로 나타낸다. 이러한 Resource를 나타내는 인터페이스는 모두 IResource의 하위 인터페이스 들이다.
우선, 위에서 취득했던 IWorkspaceRoot를 사용해 프로젝트를 작성해 보자.
|
IProgressMonitor monitor = ……
IWorkspaceRoot root = ResourcePlugin.getWorkspace().getRoot();
//프로젝트 핸들의 작성
IProject project = root.getProject("My Project");
If(!project.exists()){
Project.create(monitor); //① 실제 프로젝트 작성
Project.open(monitor); //프로젝트 오픈
……
} |
①의 부분에 create()라는 이름의 말 그대로 무언가를 생성하는 메소드가 있다. 그 이전에 getProject()라고 하는 메소드가 있지만 이는 프로젝트의 핸들을 작성하는 메소드이다. 그 다음 create()메소드를 통하여 실제로 디렉토리를 작성하거나 Eclipse의 프로젝트를 작성한다. 즉 IWorkspaceRoot.getProject()메소드에서는 프로젝트의 핸들을 작성하는 것 만으로는 Workspace상에 도 파일시스템상에도 아무 영향이 없다. 또, IWorkspaceRoot.getProject()메소드에는 2종류가 있어서 다음과 같이 정의 되고 있다.
|
정 의 |
의 미 |
|
IProject getProject(String name) |
주로 프로젝트핸들의 작성에 사용된다. 인수 name에 프로젝트명을 지정한다. 이프로젝트명을 가지는 프로젝트가 워크스페이사항에 존재하고 있는 경우에는, 그 프롲게트의 핸들이 리턴되며 존재하지 않는 경우에는 그 프로젝트명을 가지는 프로젝트 핸들이 작성되어 리턴된다. 그러나 이 경우 리턴된 핸들은 이 단계에서는 Workspace상에 맵핑 되지는 않는다. |
|
IProject[] getProject() |
Workspace상에 존재하는 모든 프로젝트의 핸들의 배열을 리턴한다. |
여기서, getProject(String name)를 사용해서 프로젝트 핸들을 작성 한다고 해도, 실제 프로젝트는 워크스페이스나 파일시스템에 생성되지 않는다. 실제로 프로젝트를 작성 하기위해서는 IProject.create()메소드를 호출 해야 한다. 그리고 create()메소드를 호출하기 전에, getProject()메소드로 저정한 프롲게트명을 가지는 프로젝트가 Workspace상에 이미 존재하고 있을지를 체그할 필요도 있다.(이미 존재 하는 프로젝트 핸들로 create()메소드를 호출하면 예외가 발생한다.)
Create()메소드를 호출한 단계에서 getProject()로 작성한 프로젝트 핸들이 워크스페이스에 추가되어 프로젝트와 맵핑되는 디렉토리가 파일 시스템상에 생성 된다. 그러나 이 단계에도 작성한 프로젝트에 대해 어떠한 조작도 할 수없다. 작성한 프로젝트에 폴더나 파일을 추가하기 위해서는 프로젝트를 여는 작업을 해야 한다. 프로젝트를 열기 위해서는 IProject.open()메소드를 사용한다. 이후, 프로젝트에 Resource 추가 등의 조작이 가능하게 된다. 또, IProject의 create()/open()메소드는 모두 시간이 걸리는 처리 이므로 유저에게 조작의 진행 상황을 보고하는, IProgressMonitor형태의 오브젝트를 인수로 받는다. 이 인수에 null을 지정하면 진행상황은 보고되지 않는다.
이것으로 프롲게트의 작성은 완료 되었다. 프로젝트는 파일 및 폴더의 컨테이너이므로 IProject를 취득하면 폴더와 파일의 작성이 가능하게 된다.
|
IProject project = ...
// 파일 작성
IFile file = project.getFile("MyFile.file"); // 파일 핸들 작성
file.create(new ByteArrayInputStream(new byte[0]),false,null); // 실제 파일 작성
IFolder folder = project.getFolder("MyFolder"); // 폴더 핸들 작성
folder.create(false,true,null); // 실제 폴더 작성 |
이러한 파일이나 폴더 역시 프로젝트의 경우와 마찬가지로 getFile(), getFolder()와 같은 메소드로 핸들을 작성한 후 create()메소드로 실제의 Resource를 작성하게 된다. 또, 파일을 작성하기 위한 메소드 IFile.create()의 정의는 아래와 같다.
|
public void create(InputStream source,
boolean force,
IProgressMonitor monitor) throw CoreException |
여기서 인수 source는 작성하고자 하는 파일의 내용을 지정한다. 이 인수에 null을 지정하면 파일은 로컬파일이 아닌 것으로 취급 된다. 이 파일이 Workspace상에 존재해도 로컬 파일시스템상에는 존재하지않는 것을 나타낸다. 따라서 로컬 파일시스템에 파일을 작성하는 경우에는 source에 null을 입력하는 것이 아니라 위와 같은 ByteArrayInputStream 오브젝트를 입력한다.
인수 force에는 이 Resource가 파일 시스템과 동기화가 이루어지지 않아도 수정 가능하도록 할지를 지정한다. 이것에 false를 입력하면 같은 이름의 파일이 로컬 파일시스템 상에 없을 경우에만 수정 할 수 있도록 한다. true를 입력하면 같은 이름의 파일이 로컬 파일 시스템에 존재하는 경우라도 soruce에 지정한 내용을 그 파일에 덮어 쓰게 된다.
인수 monitor에는 IProject.create()등의 메소드와 같이 작업의 진행 상황을 사용자에게 알리기 위한 IProgressMonitor를 지정한다. 이 인수에 null을 지정하면 진행상황은 표시되지 않는다.
폴더를 작성하기 위한 IFolder.create()메소드의 정의는 아래와 같다.
|
public void create(InputStream source,
boolean local,
IProgressMonitor monitor) throw CoreException |
인수 force와 monitor는 IFile의 경우와 같다. 또 인수 local에는 그 폴더를 로컬로 작성하는지 여부를 지정한다. 이 인수에 false를 지정하면 Workspace상에는 이 폴더가 작성되지만 로컬 파일 시스템 상에는 디렉토리가 생성 되지 않는다.(코드상에서 해당 자원이 로컬인지 확인하려면 IResource.isLocal()메소드를 사용한다.)
이와 같이 Workspace상의 자원이 반드시 로컬 파일 시스템과 동기화가 이루어 지는 것은 아니다. 좀더 구체적인 예를 들면, 패키지 익스플로어에 MyProject라는 프로젝트가 표시되고 있다고하면 이 MyProject라고 하는 Resource는 통상적으로 파일 시스템의 디렉토리에 맵핑되어(생성되어)있을 것이다. 그러나 패키지 익스플로어를 이용하지 않고 탐색기 등을 이용해서 해당 디렉토리를 삭제 했을 경우에 Workspace상에는 프로젝트 핸들이 존재하지만 로컬 파일 시스템에는 존재하지 않는다.
따라서 Resource 핸들을 사용해서 Workspace상의 Resource를 조작하는 경우 에는 create()나 move, delete등의 메소드를 호출하기 전에(이러한 메소드는 핸들에 맵핑된 로컬 파일 시스템의 Resource를 조작한다.)Resource 핸들에 맵핑된 실제의 로컬 파일 시스템상의 자원이 존재하는지 IResource.exists()메소드를 사용하여 체크해야 할 필요가 있다. 이와 비슷하게 IProject의 경우 에 프로젝트가 열려있지 않은경우(IProject.isOpen()==false)에는 그 프로젝트에 몇 개의 Resource가 있다고 해도 IResource.exists()메소드는 false를 리턴한다. 따라서 프로젝트 내의 Resource의 존재의 체크하기 전에IProject.open()메소드를 호출해야 한다.