'nature'에 해당되는 글 1건

  1. 2010.10.15 네이쳐와 빌더

네이쳐와 빌더

PDE 2010. 10. 15. 11:42

네이쳐

네이쳐(Nature)는 한 프로젝트가 갖는 일부 성질들에 대한 추상성을 제공한다. 예를 들어 한 개의 플러그인 프로젝트는, 자바 프로젝트의 특성과, PDE의 특성을 갖는다. 이런 프로젝트의 특성을 네이쳐라고 하며, 한 프로젝트는 여러개의 네이쳐를 가질 수 있다.

네이쳐의 주임무는 다음과 같다.

  • 프로젝트가 해당 특성을 갖기 위해 필요한 자원의 준비와 해제
  • 필요한 경우, 프로젝트의 빌드 방법을 플랫폼에 알려줌

네이쳐의 선언

   
      
         
      
      
      
   

최근 RCP등과 더불어 추가된 확장점들은 확장 노드(<extension />)가 아닌 그 하위 IConfigurationElement에서 상세 기술 및, ID지정을 많이 하지만, 네이쳐는 확장노드 그자체에 이름과 ID가 기술된다. 오래전 부터 존재하던 확장점들은 대체로 이런 성격이다. 익스텐젼 노드 자체가 네이쳐 노드란 사실을 빨리 눈치채지 못하면 네이쳐 노드를 만들려고 헤맬수도 있다.

3라인에서 지정된 네이쳐 클래스는 IProjectNature 인터페이스를 구현해야 하며, 네이쳐가 설치되거나 해제될 때 처리해야 할 일을 맡는다. 5라인에서 연관된 빌더 ID를 지정해 줄 수 있지만, 네이쳐 확장점 자체가 빌더를 관리해 주지는 않으며, 빌더절에서 다시 설명한다. required-nature 노드를 이용하여 디펜던시를 지정할 수 있다. 네이쳐 추가/삭제시 조건이 만족되지 않으면 Exception을 발생시켜준다.

프로그래밍으로 네이쳐 추가

IProject p = ...

IProjectDescription description = p.getDescription();
List<String> natureIds = new ArrayList<String>();

// 기존 네이쳐 아이디들 추가
natureIds.addAll(Arrays.asList(description.getNatureIds()));
natureIds.add("추가할 네이쳐 아이디");

// 프로젝트 디스크립션 갱신
description.setNatureIds(natureIds.toArray(new String[natureIds.size()]));

// 프로젝트에 새로운 디스크립션 반영
p.setDescription(description, new NullProgressMonitor());

프로젝트를 변경 할 때는 IProjectDescription을 얻어 수정 한 다음, 프로젝트에 다시 그 디스크립션을 넘김으로서 반영한다. 새로운 네이쳐가담긴 디스크립션이 프로젝트에 주어질 때 다음과 같은 일이 일어난다.

Project -> NatureManager: 네이쳐 구성 요청
NatureManager -> 네이쳐: (de)configure
네이쳐 -> Project: 구성

네이쳐 Configuration

네이쳐가 프로젝트에 추가되면, 네이쳐 객체는 configure 메소드를 콜백 받는다. 이때 필요한 런타임 라이브러리를 클래스패스에 추가한다던가, 빌더를 구성한다던가와 같은 작업을 수행 할 수 있다. 이 작업은 대칭성을 이루어 deconfigure()를 통해 해제된다. 하지만, 네이쳐의 추가와 삭제는 FacetedProject와 달리 사용자가 자유자재로 추가/삭제할 수 있는 UI가 없기 때문에, 규칙의 강제성은 적은 편이다. 네이쳐는 위저드 내지, 프로그래머가 작성한 코드에 의해서만 추가 삭제된다.

빌더

빌더란 워크스페이스에 리소스 변경이 있을 때마다 (자동 빌드의 경우) 또는 사용자가 명시적으로 빌드 요청을 내릴 때, 모든 프로젝트들에 대해 주어진 빌드 스펙에 따라 결과물을 만들어내는 개체들이다. 이 과정중에 문제가 생기면 리소스 마커를 이용하여 에러나 경고등을 문제 뷰에 나타나게 하기도 한다.

빌더의 선언


  
    
    
  

나머지 속성은 직관적이므로 생략하고, isConfigurable이라는 것은 사용자가 직접 증분, 클린, 풀 빌드를 선택할 수 있는지 여부를 체크하게 하겠느냐라는 것이다. 프로젝트의 속성 다이얼로그의 빌더 항목에 표시된다.

빌더 클래스의 주요 인터페이스

protected IProject[] build(int kind, Map args, IProgressMonitor monitor);
public ISchedulingRule getRule(int kind, Map args);

1번라인이 주 진입점으로 실제로 빌드 작업을 수행해야 하는 곳이다. 리턴값은 빌드에 의하여, 다른 프로젝트가 영향을 받아, 다시 빌드해야 하는 경우를 위한 것으로 Frozen될 때 까지 반복되니 주의하자. kind는 빌드 타입을 나타내는 것으로 전체 빌드인지, 증분 빌드인지, 클린 빌드인지등의 정보가 넘어오며, 맵을 통해 옵션들이 전달된다. 두번째 라인의 스케쥴링 룰은 이 빌드 작업이 다른 작업과 배타적으로 동작하기 위한 스케쥴링 룰을 정의 한다. 기본 구현은 워크스페이스 록이다. 스케쥴링 룰에 대해서는 Job과 스케쥴링 룰문서를 참조할 수 있다.

빌드 스펙 구성

빌드관련 기능을 가진 네이쳐는 프로젝트를 configure()할 때, 프로젝트의 빌드 스펙을 변경하여 빌더를 사용할 수 있도록 해야 한다. 프로젝트들은 빌더 커맨드라는 것을 가지고 있는데, 프로젝트의 컨텐츠가 변경될 때마다(자동 빌드의 경우) 가지고 있는 커맨드들을 수행하게 된다. 이러한 커맨드의 집합을 프로젝트의 빌드 스펙이라고 한다.

빌더 커맨드

public interface ICommand {
	public Map getArguments();
	public String getBuilderName();
	public boolean isBuilding(int kind);
	public boolean isConfigurable();
	public void setArguments(Map args);
	public void setBuilderName(String builderName);
	public void setBuilding(int kind, boolean value);
}

결국 빌더 커맨드는 어떤 빌더에게 어떤 변수들을 가지고 빌드를 시킬 것이냐 하는 명세서 객체이다. 빌더 커맨드는 IProjectDescription의 newCommand()로 새로 만들 수 있다. 주의 할 점은 get/set builderName의 인자는 빌더 확장점에서 주었던 ID이다. 이름이 아니다. 확장점에서 준 이름은 UI에서만 표시되고, 코드상으로 빌더 이름은 ID를 의미한다.

description.setBuildSpec(newCommands);
getProject().setDescription(description, new NullProgressMonitor());

프로젝트가 원래가지고 있던 빌더 커맨드 리스트에 새 커맨드를 확장하여, 디스크립션에 추가한다음, 디스크립션을 프로젝트에 제출하면, 이제 이 프로젝트는 주어진 빌더 커맨드에 의해, 리소스가 변경될 때마다 빌더를 호출한다.

Faceted Proejct

프로젝트 네이쳐는 프로젝트에 대하여 상대적으로 정적이다. 예를 들어 자바 프로젝트가 C++ 프로젝트로 변모하는 일은 없다. 하지만 J2EE프로젝트에 스프링, 스트러츠, 태그 라이브러리등의 추가삭제는 훨씬 더 빈번하게 일어난다. 네이쳐의 정적 구조로는 이들에 대응하기 힘들기 때문에, 웹 파생 프로젝트 특성은 Nature가 아닌 Facet으로 처리한다. 따라서 관련 니즈가 있는 사람들은 Faceted Project에 관한 문서들을 찾아 보면 된다. 해당 소스는 BeA가 대부분 기여했는데, IBM과 달리 주석이 빈약하고, 소스 변동이 심해 고생을 좀 각오해야한다. IBM만세. 나 일좀 시켜줘.

Posted by 지이이이율
,