토요일, 10월 03, 2009

CubridManager를 Eclipse RAP로 바꾸기



오픈소스 프로젝트로 진행중인 Cubrid DB의 CubridManager(http://dev.naver.com/projects/cubrid-manager/forum)를 RAP로 수정해보려고 버르다 오늘 그러니까 음 오전 11시부터 시작했습니다.
지금 시간이 대략 오후 10시이고, 중간에 밥먹고 영화 한 두편쯤 보고 있는 시점에서 에러를 74개까지 줄여논 상태입니다.



지금은 더 해야할지(?) 약간의 의문이 들고, 이 정도면 수고는 했다고 나에게 위로 하고 싶습니다.
누군가 나처럼 고민을 할지도 모르니 작업의 진행을 설명 드리겠습니다.
아마도 RCP, RAP두개의 프로젝트 호환성을 위해서도 약간은 도움이 되실거구요.
Cubridmanager를 개발하시는 분들에게도 도움이 되실거니.

VMWare에 Windows 2003서버 위에 CubridServer를 인스톨했습니다.
작업은 Eclipse 3.5로 RCP로 된 CubridManager를 가져왔습니다. About만 빼고는 별 무리 없이 가져왔고, 동작 또한 잘 되었습니다. 그래서 Eclipse RAP도 3.5로 환경을 맞추 었습니다. 이것은 3.5로 RAP를 위해서 어쩔수 없는 선택이었는지도 모릅니다. 1.2.1 Service Release 버전으로 작업했습니다. 글을 쓰는 시점에서는 1.3 M2 Build 버전으로 왜 하지 않았을까 싶습니다. 1.3 M2 Build버전으로 시도해도 되겠다 싶습니다.

먼저 어떻게든 RAP환경에서 동작하도록 해보는것이 첫번째 미션이고, 두번째는 잘 동작하는것은 그 다음으로 하겠습니다.
com.cubrid.cubridmanager.app.rap 프로젝트를 생성하고 cuburidmanager를 시작할 메인을 준비했습니다.



대략 프로젝트 구성은 다음과 같더랬습니다
우선 Dependencies중에 org.eclipse.ui를 -> org.eclipse.rap.ui로 모두 수정했습니다.
com.cubrid.cubridmanager.core 프로젝트는 별무리 없이 가져와졌습니다.
com.cubrid.cubridmanager.help 프로젝트는 org.eclipse.rap.ui, core.runtime이외의 모든 의존관계를 삭제했습니다.
문제는 com.cubrid.cubridmanager.ui 프로젝트였습니다. 처음 띄우는 에러가 몇개만 표시되어 와~~ 행복 했습니다. 사실은 에러가 너무 많아서 다 표시하지 못해서 그렇더군요.

대부분은 에러는
1) import org.eclipse.ui.help.IWorkbenchHelpSystem;
2) org.eclipse.swt.widgets.DirectoryDialog.java
3) org.eclipse.swt.widgets.FileDialog.java
4) Font, FontData, Color, Image, GC
5) StyledText, TextViewer
에네들 때문에 나는 에러 였습니다.

그중 1번은 context help를 쓴 거의 모든 파일에 문제가 나타났습니다.
아참, 위의 사실은 손으로 삽질의 삽질을 하던중에 공통점을 뽑았구요.
1번은 cubridmanager소스 중에 공통된 에러가 나오면 주석으로 막는 프로그램을 만들어서 일괄로 삭제했습니다.(링크를 걸던지 소스를 첨부하지요)
그리고 2,3과 몇몇개는 더미 클래스를 만들었습니다. 물런 아무 동작하지 않겠지요.
휴~

이렇게까지 에러를 제거하니 에러 숫자가 무한히 줄었습니다.

가장 문제가 되는 것은 StyleText와 ,TextViewer를 사용하는 부분 이었습니다. 물런 dnd와 eventlistenr등도 되었지만...
그중 쿼리에디트 창인 QueryEditorPart 를 수정하는 문제가 남아있습니다.
다른 클래스와 복잡하게 연결되어서 손을 대고는 있으나 각종인터페이스와 없는 클래스를 짜집기하는것도 한계가 된 상태입니다. QueryEditorPart 이넘만 해결하면 돌아 갈(?) 듯 싶은데 말입니다.

지금은 QueryEditorPart 아이와 그 부하들의 벽에 같혀 있는 듯합니다.
당장에는 아이디어가 없네요. StyleText는 Text로 수정하여 사용하였고 대략 문제는 없을듯 합니다만, 다른 문제가 역시나 존재합니다. 또한 클래스 전체를 막아 버리자나 이 클래스가 거의 중앙에 끼워 있어서 에러가 완전 이구요. 이것을 대체할만한 이쁜 아이를 만들어 놔야하는데, CubridManager를 이렇게 하루 보는 것으로는 소스를 파악하기에는, 저의 코드를 파악하는 능력이 한계입니다.(물런 제가 CubridManager의 개발팀 이라면 두개의 프로젝트가 포괄할수있는 좀더 유연한 구조를 제안할것입니다만..)

좀더 분석한다면 이것을 RAP도 범용적으로 포괄하는 아이로 바꿔 줄수도 있을듯합니다.
포인트는 다른 클래스를 되도록이면 수정하지 않고도 바쿼주는 것입니다.

음, RAP가 쓸만하다는걸 나름 증명하고 싶었는데, 막상 아무 상관없는 CubridManager를 옮겨 보려니 여간 괴로운게 아닙니다.

RAP개발팀이 Eclipse를 RAP를 옮길때도 같은 방법(?)으로 하나씩 옮겨온 것으로 생각되는데, 이 작업이 얼마나 힘들었을지 상상하기도 싫어 져 버렸(?) 습니다. 좋아(?)하는 술(?) 한잔이 생각날 뿐입니다. 그들의 희생(?)과 뛰어남에 그저 존경을 표하고 싶을 뿐입니다.

약간의 알콜이 필요한데, 어디 부를넘도 없고 누구 말대로 왕따인건 확실한듯합니다.

위에서 언급했던 소스 주석 만드는 유틸입니다. 약간 문제가 있구요.
정교하게 사용할만한 그런게 아니라 일단 돌리고 사용했습니다.
apache의 commons-io-1.4.jar를 사용하였습니다.

코드일괄 주석만들기
public class ReplcaeSource {
static String sourceDir = "C:\\dev\\eclipse-galileo\\workspace-rap-cubrid\\com.cubrid.cubridmanager.ui\\src";

static String[] sourceText = { "import org.eclipse.ui.help",
"IWorkbenchHelpSystem whs", "whs.setHelp", "getHelpSystem()",
"CubridManagerHelpContextIDs" };

static String replaceText = "//";

public static void main(String[] args) {
ReplcaeSource replace = new ReplcaeSource();
replace.goChange(sourceDir);
}

public void goChange(String sourceDir) {
File f = new File(sourceDir);
String[] dirList = f.list();
if (dirList == null)
return;

for (String file : dirList) {
String fullyPath = sourceDir + File.separator + file;
System.out.println("check source is " + fullyPath);
File tmpFile = new File(fullyPath);

if (tmpFile.isFile()) {
// 마지막이 .java로 끝나는 애만 수정한다.
if (fullyPath.lastIndexOf(".java") >= 0)
fileChange(fullyPath);
} else if (tmpFile.isDirectory()) {
goChange(fullyPath);
}
}
}

private void fileChange(String file) {
System.out.println("\t #### " + file);
List writeList = new ArrayList();
boolean isModify = false;

LineIterator it = null;
try {

it = FileUtils.lineIterator(new File(file));
while (it.hasNext()) {
String line = it.nextLine();

for (String chkTxt : sourceText) {
if (line.indexOf(chkTxt) >= 0) {
line = "//" + line;

isModify = true;
}
}

writeList.add(line);
}

} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
LineIterator.closeQuietly(it);
}

try {
// 모두 작업했으면 저장한다.
if (isModify) {
System.out.println("ChageText to " + file);
FileUtils.writeLines(new File(file), writeList);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}

댓글 2개:

  1. 그냥 궁금해서 그러는데,
    큐브리드에 계시나요?
    noaats 아니신가요?

    답글삭제
  2. 큐브리도, noaats도 아닙니다.
    noaats는 어디서 보신건가요?
    그만둔지 몇년이 넘었네요.

    관삼감사드립니다.

    답글삭제