사실 에디터란, 편집되는 대상에 따라 평가 방식이 달라지기 때문에, 그 전체에 대해 품질 점검표를 만들 수는 없습니다. 본 기사에서는 이클립스로 만들어진 에디터로서 지켜야 할 기본 품질 속성에 대해 알아봅니다. 100점 부터 시작하여, 자신이 만든 에디터가 감점 요소에 해당되면 해당 점수만 큼 감점하시면 됩니다.

ps. 이클립스를 배우면 배울 수록 기존의 이클립스에 있는 에디터들이 얼마나 잘 만들어졌나에 심한 충격을 받게 됩니다. 그래도 힘 냅시다.

1. File 선택 동기화 : 5점

  1. 에디터를 두 세개 정도 엽니다.
  2. 리소스 네비게이터나, 패키지 익스플로러 뷰는 좌우화살표 모양의 Link with Editor 버튼이 있습니다. 이 버튼을 누릅니다.
  3. 활성 에디터와 뷰의 파일 선택이 동기화 되어야 합니다.

만약 에디터의 입력이 복수의 파일등으로 구성되는 경우라면, 아마도 여러분은 직접 IEditorInput을 만드셨을 겁니다. 이 경우에는 에디터와 IEditorInput이 IFile.class에 대한 어댑터 질의에 응답하여야지만 그러한 기능이 정상작동합니다.

2. 에디터 복원 : 5점

  1. 본인이 만든 에디터를 두 세개 정도 엽니다.
  2. 이클립스를 종료하고 다시 실행합니다.
  3. 열어 두었던 모든 에디터가 되살아나 있어야 합니다.

IFileEditorInput 등과 같은 경우만 입력으로 고려한 경우, 이러한 내용은 모두 저절로 처리 되어 잘 알기 어렵지만, 실제로 에디터의 입력은 뷰에 표시되는 한 모델 객체 일 수도 있습니다. 예를 들면 MyLyn의 태스크 엘리먼트들은 파일이 아닙니다. 이러한 경우엔, 입력을 보존하고, 복원하는 작업을 직접 수행해야 합니다.

보존과정

워크벤치 -> IEditorInput : getPersistable
IEditorInput --> 워크벤치: IPersistable
워크벤치 -> IPersistable: getFactoryId
워크벤치 -> 워크벤치: id를 이용하여 메멘토 노드 생성
워크벤치 -> IPersistable: saveState
IPersistable-> IPersistable: 입력 상태 저장

복원 과정

워크벤치 -> 워크벤치: id로 팩토리 탐색
워크벤치 -> 엘레멘트 팩토리: 메멘토 노드 전달
엘레멘트 팩토리 -> 엘레멘트 팩토리 : IEditorInput  복원
엘레멘트 팩토리 -> 워크벤치: IEditorInput
워크벤치 -> 워크벤치 : 에디터 복원

메멘토 노드는 일종의 XML 노드입니다. 워크벤치는 종료될때 XML로 종료직전의 상황을 기록합니다. 팩토리는 Element Factory 확장점을 이용하여 등록합니다.

3. 파일 동기화: 총 배점 20

  1. 에디터를 엽니다.
  2. 텍스트 에디터등 다른 에디터로도 그 파일을 엽니다.
  3. 다른 에디터에서 수정한 뒤 저장합니다.
  4. 원래 에디터를 활성화 합니다.
  5. 더티 마크가 없던 경우, 파일을 즉시 다시 읽어 들여 표시해야 하고, 더티마크가 있는 경우, 파일의 내용이 바뀌었으니 다시 읽겠냐고 질의해야 합니다. : 10점
  6. 에디터가 열린 채로 해당 파일을 삭제하거나, 부모 폴더를 삭제하거나, 프로젝트를 삭제하거나 Close합니다. 이 때 에디터는 사라져야 합니다. : 5점
  7. 에디터가 열린 상태로 파일을 리네임 하거나 다른 곳으로 이동시킵니다. 에디터에서 조금 작업을 한 뒤 저장하면, 바뀐 파일로 안전하게 저장되야 하며, Save as... 기능도 작동해야 합니다. : 5점

이 기능은 SVN, CVS등 업데이트, get contents등과 같은 기능이 제대로 동작하는데에도 매우 중요합니다. 입력이 IFileEditorInput이었던 경우, 다음과 같이 워크스페이스를 리스닝 해야 합니다. 왜 해당 파일이 아니라, 전체 워크스페이스를 감시해야 하는지는 이어서 설명합니다.

if (input instanceof IFileEditorInput) {
	ResourcesPlugin.getWorkspace().addResourceChangeListener(this);
}

해당 리소스에 영향을 미치는 방법은 아주 다양합니다. 프로젝트 닫기, 프로젝트 리네임, 부모 폴더 이동, 부모폴더 삭제, 부모폴더 리네임등등 경우의 수가 매우 다양합니다. 따라서, 워크스페이스 전체의 이벤트를 감시한다음, 그것을 해당 리소스를 기준으로 의미를 번역하여 사용합니다.

public void resourceChanged(IResourceChangeEvent e) {
	IFileEditorInput input = (IFileEditorInput) getEditorInput();
	IFile file = input.getFile();
	IPath fullPath = file.getFullPath();

	// 프로젝트가 닫긴경우. bug 8593
	if (e.getDelta() == null) {
		return;
	}

	IResourceDelta relatedDelta = e.getDelta().findMember(fullPath);
	if (relatedDelta == null) {
		return;
	}

	int kind = relatedDelta.getKind();

	if (kind == IResourceDelta.REMOVED) {
		handleResourceRemoved(relatedDelta);
	}

	if (kind == IResourceDelta.CHANGED && !this.isSaving) {
		handleResourceChanged(relatedDelta);
	}
}

11 번째 라인이 리소스 변경 이벤트를, 입력 파일을 기준으로 상대적 이벤트로 변환하는 코드입니다.

4. 문서 동기화 : 10점

  • 에디터를 엽니다.
  • 메뉴의 Window / New Window 를 선택하여, 워크벤치 윈도우를 하나 더 엽니다.
  • 새 윈도우에서도 같은 파일에 대한 같은 에디터를 엽니다.
  • 어느 한쪽을 수정하면 즉시 동일한 컨텐츠를 보여 주어야 합니다.
  • 어느 한쪽에서 저장하면, 나머지 한쪽에서도 더티마크가 사라져야 합니다.

이클립스 텍스트 기반 에디터는 DocuemntProvider를 통해서 문서를 공급받습니다. 따라서, JavaEditor와 Text Editor를 동시에 열어 둔 경우, 둘은 같은 도큐먼트를 공급받게 되어 수정 즉시, 저장하지 않도라도 동일한 내용을 표시하게 됩니다. 에디터가 파일로부터 모델을 직접만드는 방식으로 구현해서는 안됩니다.

여러개의 파일로부터 나온 모델(문서)들이 서로 참조를 갖는 경우, 한 파일로 부터 하나의 모델만 공급되는 중간 체계가 있어야 하는것은 매우 중요합니다. 그렇지 않다면, 모델단위로 쉽게 구현될 수 있었던 리팩토링이, 파일 변경이벤트로만 처리되어야 하므로 매우 어렵고 복잡한 문제로 바뀔 것입니다.

GEF 에디터의 기본구현에 포함된 EditDomain은 EditorPart를 하나만 갖으면서 CommandStack을 내장하고 있기 때문에, 이 사항을 충족하는데는 상당히 까다롭고 높은 비용이 듭니다. ㅠㅠ

5. 사용자 단축키 지정: 10점

  • 메뉴에서 Windows / Preference 를 엽니다.
  • 필터에서 key라고 입력하고, key 노드를 선탣합니다.
  • 우측 필터에 에디터의 이름을 입력합니다.
  • 에디터와 연관된 모든 단축키가 즉시 알아볼 수 있는 형태로 나타나야 하며 변경할 수 있어야 합니다. 예를 들어 '삭제', '추가'와 같은 형태로 나타난다면 사용자는 "뭘 삭제하고 추가한단 말이지?" 라고 생각할 것입니다.
  • 변경한 단축키는 노출된 모든 경로에 즉시 표시되고 적용되야 합니다. (팝업 메뉴 등등)
  • When 필드에서 "in My Editor" 와 같은 여러분이 만든 에디터를 사용중일때를 의미하는 컨텍스트가 공급되야 합니다.
  • 여러분의 에디터를 사용하는 도중 Ctrl+3을 누르고, "삭제", "~추가" 등과 같은 명령어를 직접 타이핑 하여 해당 명령을 실행 시킬 수 있어야 합니다.: 예를 들어 자바 에디터에서 필드를 선택한 뒤 Ctrl+3을 누르고 generate라고 입력해 보십시오.

이클립스 3.2의 주요한 변화는 액션이 가벼워 졌다는 점입니다. IAction객체는 UI생성과 비즈니스 로직-run()이 함께 있기 때문에 매우 무겁습니다. 단지 툴바에 버튼을 하나 그리기 위해서 클래스가 로드되고, 그로 인해 플러그인까지 시작되어 버리기 때문에, 이클립스의 시작시간 아주 느리게 만듭니다. 이클립스는 어마어마하게 많은 플러그인들이 전사적으로 뒤섞여 동작하기 때문에, 이 룰을 따르지 않으면 치명적인 결과가 나타납니다. 이러한 명령들은 모두 Command라고 부르는 확장점으로 선언적으로 설계되어야 합니다. 그러면 이클립스는 XML파일을 로드하는 것 만으로도 UI를 만들 수 있고, 플러그인은 시작되지 않아도 됩니다. 또한 이렇게 선언적으로 만들어진 명령들은, 자동적으로 단축키 설정등과 같은 플랫폼의 지원을 받을 수 있게 됩니다. 이클립스 위키에서 Command Framework, Core Expression, Menu Contribution, UIContext를 참조하십시오.

6. Team Support: 10점

  • 새파일을 만들고 에디터를 엽니다.
  • SVN등에 이 프로젝트를 셰어하고 커밋합니다.
  • 문서 변경, 저장 커밋을 몇 차례 반복합니다.
  • history 뷰를 열어, 과거버전을 더블 클릭하면 제대로 열려야 하며, *읽기 전용*으로 열려야 합니다.
  • 읽기 전용으로 열린 과거 버전의 파일을 Save as... 로 저장하면, 편집이 가능해져야 합니다.
  • 만약 이전 버전과의 비교 에디터를 공급했다면 당신은 이 평가표를 읽을 필요도 없는 구루이십니다. 부끄럽게 왜 그럽시니까. 원츄-3-b

7. 클립보드, 프린팅: 10점

  • 당신의 에디터에서 일부 모델을 Copy 합니다.
  • 메모장에 붙여 넣으면 텍스트로, 워드에 붙여 넣으면 스타일 텍스트로, 그림판에 붙여 넣으면 그림으로 붙여 넣어져야 합니다.
  • 인쇄가 되어야 합니다.

'PDE' 카테고리의 다른 글

빌드 자동화 하기 #1 - Hello Ant  (2) 2011.03.07
이클립스 플러그인에 DLL 포함시키기  (0) 2010.12.10
제품 빌드시 자주 발생하는 문제들  (0) 2010.11.26
Bundle과 Resource  (0) 2010.10.28
네이쳐와 빌더  (0) 2010.10.15
Posted by 지이이이율
,