쎄느강은 좌우를 나누고 한강은 남북을 가른다
홍세화 지음/한겨레출판

입사하고 바쁘고 정신없이 보내던 기간동안 틈틈히 조금씩 읽어나갔던 책이다. 워낙 홍세화씨의 글을 재밌게 읽고 있고, 그의 글을 좋아하지만 여건상 오랜시간이 지난 뒤에야 독후감을 남기려고 하니 기억을 더듬는 것이 힘에 부친다.

<나는 빠리의 택시 운전사>에서는 그가 보여주고 싶은 프랑스 사회를 택시운전의 경험과 시야 안에서 비교적 제약을 가지고 소개하고 있으나 이 책에서 그는 그러한 제약을 털어버리고 치밀하게 프랑스 사회를 들여다보고 있다. 특히 제2부 "프랑스 사람들 이야기"에서는 한국사회와의 비교를 목적으로 하지 않고 그들의 삶과 문화 그 자체를 예리한 시선으로 바라보고 우리에게 전달하고 있다. 물론 제3부에 "한국 사회와 프랑스 사회와의 만남"에서 프랑스 사회에서 배워야 할 점과 우리의 장점을 찾아내고자 하는 노력을 잊지 않고 있다.

홍세화씨가 소개하는 프랑스 사회의 단면을 바라보며 이상적인 사회는 어떤 사회인가에 대해서 생각해 볼 기회를 갖게 된다. 나는 김구선생이 말씀하셨던 것 처럼 부유한 사회가 이상적인 사회라고는 생각하지 않는다. 사회의 구성원들이 모두 행복을 누릴 수 있는 사회가 이상적인 사회라고 생각한다.

누구나 행복을 추구할 권리가 있고 개개인이 그 권리를 누리는 가운데 다른사람이 누리고자 하는 권리와 충돌이 발생할 수 있다. 나는 그 충돌을 해결하는 방법과 문화에서 그 사회가 이상적이고 성숙한 사회인지 아닌지가 구별된다고 본다. 따라서 엥똘레랑스에 대한 단호한 엥똘레랑스를 주장했던 홍세화씨의 주장처럼 대한민국 사회에서 극우와 극좌는 배제되어야 된다. 공화국에 이념에 따라 당리당략이 아닌 공익(!)을 위해서 좌, 우, 중도세력이 각자의 생각을 주장하고, 함께 토론하고, 서로의 생각을 존중하는 문화가 정착되어야 한다고 생각한다.
사용자 삽입 이미지

책상과 의자를 구입하여 사택에 마련한 독서환경. 쾌적하구나!

어제밤 소백산맥 등반을 끝으로 대우증권 파견근무를 마무리하고 오늘부터 분당의 R&D Center로 출근하게 되었다. 5주의 파견기간 중에 첫주는 교육을 받았고 4주는 실전 개발에 투입되어 일했다. 그 기간동안 함께 했던 분들과의 작별인사를 소백산맥으로 나누었는데, 소백산맥이라함은 소주+백세주+산사춘+맥주를 섞은 술을 의미한다. 폭탄주를 만들 듯 소주를 가득채운 소주잔을 맥주잔에 넣고 그 뒤로 이름순서대로 백세주, 산사춘, 맥주를 이어 붓는다.

이 술이 대단한 것은 목넘김이 끝내주며 잠깐의 잠복기간을 거쳐 불시에 올라오는 술의 기운이 상당하다는 것! 소백산맥은 주도(?)가 중요한데 5분 간격으로 세잔을 원샷해야 한다. 절도있게 소백산맥을 제대로 넘고 같이 일하신 분들의 칭찬(?)을 받았지만 멀쩡했던 것은 잠시, 이야기를 전개하던 중 갑자기 술기운이 오르기 시작했다. 칵테일바로 자리를 옮겨 깔로아 밀크를 시켜놓고 조금씩 마시던 중 도저히 이대로는 힘들어서 밖으로 나가서 술마시고 전화하는 추태를 부리고 말았다. 전화 받아준 S양과 P양에게 심심한 감사를 ...

고운정들었던 대우증권에서 일하시는 분들과 작별인사를 하고 미운정들었던 7007-1을 마지막(?)으로 타고 분당 사택으로 돌아왔다. 그리고 바로 누워버렸다. 아침에 R&D Center에 출근하기 위해 느지막히 8시에 일어났더니 아침대란이 벌어지고 있었다. 사람은 많은데 화장실은 부족하여 바로 샤워를 할 수 없는 상황! 다행히 정신없이 움직여 9시가 되기전에 식당에 도착하여 회사식당에서 아침식사를 하고 하루를 시작할 수 있었다.

연구소에 들어와보니 할일이 이미 할당되어 있었고 승호형에게 상당히 두꺼운 책을 4권 받아서 그 중에 한권을 읽고 있다. 오랜만에 영어로 쓰여진 책을 읽는게 좀 갑갑하긴 해도 새로운 것을 해볼 수 있다는 것에 감사한다. 우리나라의 회사의 대부분이 Database로 오라클을 사용하는 상황에서 기존의 Oracle을 대상으로 하는 코드를 우리회사의 Database 제품인 티베로(Tibero)에서 동작할 수 있게 하는 일의 일부(?)를 맡게 되었다. 중요하고 의미있는 일인 만큼 열심히 해봐야지. 게다가 재밌을 것 같다!

오랜만에 희진이랑 메신저로 대화하다가 재밌는 이야기를 들었다. 내가 회사에 들어가게 되면 책리뷰가 초토화될꺼라고 사람들이 예견 했다는 사실. 불행하게도 그 예견은 제대로 맞아 떨어지고 있다. 정말 입사 이후 책 리뷰를 한권도 올리지 못했다!

하지만 나는 아주 조금씩이라도 책을 읽어가고 있다. 거의 다 읽어가는 책도 있고 다 읽어서 리뷰를 쓸 책이 한권 있긴 한데 컴퓨터를 여유있게 할 수 있는 시간이 부족하다 보니 자꾸 미루게 된다.

사실 회사를 다니는 요즈음에도 하루에 책을 읽을 수 있는 시간은 2시간 이상이다. 점심시간 1시간과 저녁시간 30분을 활용할 수 있고 자기전에 30분에서 1시간 정도 책을 읽을 여유가 있다. 하지만 아직까지는 새로운 사람들과 친해지고 싶어서 책을 읽기 보다는 사람들과 어울리는데 시간을 많이 소비하고 있다. 게다가 제때 볼 수 없는 드라마를 점심시간에 보다 보니 책 읽을 시간이 부족하고, 사택에 들어가면 잠들기 전에 동료들과 맥주 한잔 하거나 위닝10을 같이 하다보니 더더욱 책 읽을 여유를 잃고 있다.

그러나! 이제 자의반 타의반으로 다시 책을 읽을 수 있는 여건이 조성되고 있다. 점심시간에 보던 드라마(주몽, 하얀거탑)가 오늘밤에 모두 끝난다. 사람들과도 꽤 친해져서 책을 읽는데 시간을 더 할애할 수 있고 오늘 사택에서 사용할 책상과 의자를 구입함으로써 최적의 환경을 갖출 수 있게 되었다. 다다음주에 연구소로 복귀 한다면 출퇴근으로 소비하는 대략 하루에 3시간 대신에 달리기와 독서를 위해 시간을 더 할애할 수 있을 것으로 보여진다.
 
따라서 조만간 일주일에 2권 이상 책을 읽어내는 페이스를 회복할 수 있을 것 같다. 다시 다독하며 느끼고 배우며 성장할 수 있도록 노력하자. 내가 생각하는 최고의 자기개발 방법인 독서를 게을리 할 순 없으니까.
대우증권에 파견나가서 하고 있는 일은 대우증권의 차세대 시스템을 구축하는 것인데, 이때 사용되는 우리회사의 솔루션은 티맥스와 프로프레임이다. 티맥스는 미들웨어로서 프로프레임은 프레임워크로서의 위상을 가지며 이 둘은 물론 서로 긴밀히 연동되어 동작한다.

기존의 신한은행 프로젝트와 SK Telecom 프로젝트에서는 프로프레임 3.0이 사용되었는데, 이번 대우증권 프로젝트는 프로프레임 4.0이 처음 사용되고 있다. 그만큼 새로운 도전이기에 다소 파일럿 프로젝트의 성격을 가지게 되고 개발과정에서 변동사항이 있어 어려움을 겪기도 한다.

"프로프레임 4.0 사상"이라고 부를 만큼 프로프레임 4.0의 개발방법론은 기존의 날코딩과 확연히 다르다. 회사 보안상, 대우증권 업무 프로세스 보안상 스크린 샷을 보여드릴 수는 없지만 대략적으로 소개하자면, 가장 눈에 띄는 것은 EMB Desiner라고 할 수 있다. 프로그램을 작성하는데 있어 코드부터 작성하는 것이 아니라 업무의 플로우를 순서도 그리듯이 사각형과 화살표를 사용하여 나타낸다. 이는 DB접근에 해당하는 DBIO 모듈이나 비지니스 모듈 등을 끌어와 붙이는 작업을 포함한다. 모듈을 끌어다 쓰는 경우에는 Pro Mapper를 통해 입, 출력 데이터를 매핑한다.

프로젝트를 진행할 때 일주일에 한번씩 회의를 갖는다. 이 시간에는 프로프레임 4.0을 사용하여 시스템을 개발하면서 생각해볼만한 개선사항, 표준안등을 토론한다. 그리고 토론결과의 일부는 연구소로 피드백되어 프로프레임 4.0의 개선을 도모하고 있다.

우리회사가 만든 미들웨어 위에, 우리회사가 만든 프레임워크와 개발툴을 사용하여 시스템을 구축하면서 회사에 대한 자부심이 커가는 요즘이다.
사용자 삽입 이미지

금강 휴게소에서 야크 소세지를 먹으며


사용자 삽입 이미지

창원역에 내려서


새집의 거실


새가족이 된 슬기


슬기의 집


사용자 삽입 이미지

새집에서 바라본 풍경


사용자 삽입 이미지

2층이 우리집!

어제 무사히 일을 마무리 하고 오늘은 창원으로 이사간 집을 찾았다. 4시간 30분을 버스에서 보내야 하므로 버스에서 숙면을 취할 요량으로 새벽 3시까지 사택 동료들과 PC방에서 스타를 한 후 맥주를 마시고 잤다. 그러나 알람을 월~금에 맞춰놓은 관계로 야탑에서 출발하는 버스를 놓치고 부랴부랴 고속터미널로 가서 10시 30분 출발하는 버스를 탔다.

처음 두시간은 무난히 숙면을 취해 휴게소까지는 편하게 갈 수 있었다. 오랜만에 찾은 금강휴게소에서 금강의 강바람을 맞으며 소세지를 사먹었는데 운치가 그만이였다. 휴게소에서부터 창원까지는 졸다 깨다를 반복했다. 드디어 창원에 도착! 새로 이사간 집의 주소가 "창원시 북면 무곡리 양촌마을"인 관계로 아버지께서 마중나오셔서 차를 타고 집을 향했다.

생각보다 더 시골스러운 동네였지만 우리사 이사한 집은 겉으로 보기에도 동네에서 제일 좋아 보였다! 이사가서 꼬맹이가 제일 신났다고 어머니께서 말씀하셨는데 아니나 다를까 집에 도착하니 꼬맹이가 제일 먼저 뛰어나왔다.

사용자 삽입 이미지

이사한 새집은 너무 좋아 보였다! 전원에 있다는 자체만으로도 평화롭고 아늑한 느낌을 주었고 집자체도 잘 만들어서 살기에 좋은 것 같다. 게다가 내가 집에 도착 한 후 한시간 후에 새식구(?)를 맞이했다. 태어난지 3개월된 진도개를 키우기로 한 것이다. 부모님은 "슬기"라고 이름을 짓고 개집을 마련해 주었으나 아직 겁이 나는지 좀처럼 들어가려 하지 않는다.

사택에서도 그다지 불편함을 느끼지 못하고 동료들과 즐겁게 살고 있으나, 집이 주는 편안함은 흉내낼 수 없는 것 같다. 계속 여기서 지내고 싶을 만큼 새 집이 마음에 든다. 부모님을 위해 사드린 냉장고가 아직 도착하지 않은 것이 진한 아쉬움으로 남는 것이 옥의 티! 멀리 있지만 자주 찾아뵐 수 있도록 노력해야겠다.

꿈 속에서 계속 입으로, 머리로 되네였던 CUS_A0T113M ...

꿈에서 깨어나 잠시 정신 못 차리고 있을때 '대체 CUS_A0T113M이 뭐지?' 라고 생각하고 있다가 정신을 차리고 다시 생각해보니 최근 자주 작업하던 테이블 이름이였다. 교수님이 말씀하신 꿈 속에서 디버깅을 할 정도의 구루의 경지까지는 아니였지만 얼마나 업무에 집중했으면 아침에 일어나서 나도 모르게 테이블 이름을 되네였을까!

사용자 삽입 이미지

부모님은 지난주에 창원으로 이사가셨고 첫월급을 탔지만 아직 못 찾아뵙고 있다. 첫월급으로 냉장고를 사드렸는데 이번주는 꼭 집에 내려가고 싶어서, 주중에 맡은 분량의 일을 끝내기 위해 정신없이 달려왔다. 내일 하루 열심히 해서 맡은 일을 깔끔히 처리하고, 뿌듯한 마음으로 창원에 내려갈 수 있도록 노력해야겠다.

지인들에게 내 소식을 알리는 두서없는 글이라 근황이라는 제목을 붙였다. 앞으로도 종종 근황이라는 제목으로 블로그를 통해 간접적으로나마 소통하고자 한다. 주중에 시간을 내어 사람을 만나는 일은 당분간 불가능하고 주말이라는 시간이 워낙 한정적이다 보니 직접적으로 소통하는 것이 쉽지 않은 것이 현실.

그럼에도 불구하고 나는 초보 개발자로서의 현재의 삶에 만족하고 있다. 매일 아침 6시 30분에 일어나 출근해서 밤 10시까지 점심 , 저녁식사를 제외한 시간에 쉼없이 개발에 몰두해야 하지만 내가 하고 있는 일 자체가 재미있을 뿐더러 실제로 필요한 일이라는 생각이 들어 하루하루 큰 보람을 느끼고 있다.

아무것도 모르는 상태에서 사수인 이대리님이 친절하게 설명해주셔서 업무를 이해하는데 큰 도움이 되었다. 차주부터는 더욱 열심히 해서 기대에 부응할 수 있도록 해야겠다. 파견 나오기 전에 입사동기들끼리 무슨 팀이에요? 라고 물으면 OS팀이요, JVM팀이요, DB팀이요 등등의 대답을 들을 수 있었지만, 요즘의 대답은 계좌팀, 매매팀, 상품팀 등등 일만큼 다들 파견근무에 적응한 것 같다. 난 상품팀에서 펀드에 관련된 온라인 서비스를 개발하고 있다.

이제는 김전임이라고 불리는 것이 자연스럽고 사원증을 목에 걸고 있어도 어색하지 않다. 항상 내가 하고 있는 일에서 의미를 찾고 보람을 느끼며 그렇게 하루하루를 열심히 살아가야겠다. 그리고 스스로 옳다고 믿는 가치를 삶속에서 지켜나갈 수 있도록 긴장의 끈을 놓치말자.

사택에서 회사 연구실을 오갈 때 서현역 삼성플라자를 지나가게 된다. 평소에는 밤늦게 다니느라 몰랐는데 일요일 밤 친구를 만나기 위해 사택을 떠나 서현역 앞에 갔을 때 깜짝 놀랐다. 이렇게 대단한 번화가가 집에서 걸어서 10분 거리에 있을 줄이야!

강남역 주변을 뺨칠 정도로 이쁜이(?)들도 많고, 물가도 비싸다. 사택이 있는 곳은 거주지역으로 조용하고 평화로워서 좋고 조금만 나오면 이것저것 없는것이 없는 번화가가 있어서 좋다. 개인적으로는 교보문고가 가장 마음에 든다.

가장 결정적인 것은 교통이 편리하다는 사실. 서현역 근처에서 버스를 타면 웬만한 곳에 다 갈 수 있다. 심지어 막히지 않으면 광화문도 20분이면 도달할 수 있고 강남역, 양재역 등에도 편하게 갈 수 있다.

사용자 삽입 이미지

회사 연구실은 서현역 삼성플라자에서 5분 거리에있다. 연구원들이 온전히 집중할 수 있도록 2인 1실의 환경을 제공한다. 아침, 점심은 식당에서 1000원, 2000원에 깔끔하게 해결 할 수 있고 저녁과 야식은 공짜로 먹을 수 있고 주말에 연구실에 나오면 역시 공짜로 밥을 먹을 수 있다. 감사한 마음이 절로 생기는 좋은 환경이지만, 파견근무가 끝나야 연구실 생활이 가능하다. 맡은 일을 충실히 해내고 연구실에 복귀할 수 있도록 내일부터 정신차리고 열심히 해야겠다.

이번주 월요일부터 분당에서 과천으로 출근하고 있다. 2월 입사한 신입연구원 전원이 모증권사 프로젝트로 한달동안 파견되었기 때문. 사택에서 매일 아침 6시 30분쯤 일어나 버스를 타고 과천을 향한다. 김밥집에서 간단히 아침을 해결하고 오전 9시부터 오후 9시까지 제품교육을 받고 있다. 우리가 할 일은 회사에서 개발한 미들웨어와 프레임워크를 적용하여 기존의 시스템을 새롭게 구축하는 작업이다.

수업(?)을 듣는 것은 정말로 지루한 작업이다. 내용을 놓치고 있진 않지만 요즘 수면이 부족해 꾸벅꾸벅 졸면서 듣고 있다. 차라리 빨리 작업에 들어갔으면 하는 마음이 굴뚝같다. 막상 다음주부터 작업을 시작하면 지금을 그리워하게 될지도 모르겠지만 ...

9시에 과천에서 퇴근하여 분당 연구실에 도착하는 시간은 대략 10시쯤. 연구실 사람들과 어울리고 이것저것 하다보면 금방 11시 30분이 되어 사택으로 돌아간다. 지루한 교육은 내일로 끝나고 다음주부터는 진짜 개발이다. 리얼 시스템을 개발한다는 사실이 나를 흥분시키기도 하지만 정해진 분량과 시간 그리고 나의 능력에 대한 의구심 때문에 조금은 불안하다.

여하튼! 구정연휴가 눈앞이구나. 내일 밤에는 집으로 ...

평온한 일상을 좋아하는 나로서는 그다지 반갑지 않은 다양한 이벤트로 가득한 한주가 지나고 집에 돌아와 평온한 휴식을 취하고 있다.

월요일에서 입사하여 수요일까지는 서울 코엑스 근처의 교육장에서 경력사원과 함께 교육을 받았다. 매일 아침 9시까지 코엑스로 가는 길은 험난했다. 한동안 늦잠을 즐기다 매일 아침 6시에 일어나는 것은 쉽지 않았고 하루 종일 피곤했다. 게다가 정장차림은 나를 더욱 지치게 했으니  빨리 사택에 입주하여 연구실에 걸어서 출퇴근하게 될 날이 간절히 기다려졌다.

드디어 목요일에 연구실 첫 출근! 블로그를 통해 알게된 승호형과 같은 팀이 된 관계로 다른 동기들과 달리 내 자리가 어디인지 알 수 있었다. 하지만 정착할 수 없었던 이유는 연구실 출근 첫 날 내가 속해 있는 Core실의 워크샵이 있었기 때문. 원래 9시쯤 출발할 예정이였으나 비가 와서 스키장을 포기하고 일정은 늦춰져 오후 3시에 출발하게 되었다. 컴퓨터가 없는 신입들은 회의실에 모여 오랫동안 회사의 미래와 비전과 개인의 경험에 대하여 이야기를 나누며 시간을 죽일 수 밖에 없었다. 방이 정해진 나는 새로온 컴퓨터를 세팅하고 짐을 풀며 시간을 보내기도 하였지만 결국 켜보지 못하고 워크샵을 떠나게 되었다.

숙소에 도착하자 마자 활발한 승호형이 축구를 제안했고 많은 사람들이 바지, 신발 다 버려가며 진흙탕에서 축구를 즐겼다. 축구가 끝나고 숙소로 돌아와서는 사람들이 자연스럽게 삼삼오오모여 카드게임 및 보드게임을 즐기기 시작했다. 신입동기인 형들과 함께 어색하게 둘러 앉아 있다가 고스톱을 치자는 제의가 들어왔다. 고스톱을 칠 줄 몰랐기 때문에 이번 기회에 배우자는 심산으로 열심히 배웠는데 이렇게 재밌을수가! 7시까지 고스톱을 치고 식당으로 이동하여 통돼지 바베큐에 술을 마셨다. 실원이 모두 남자다 보니 남자들만 있을 때 가능한 분위기(?) 속에서 신입사원의 소개가 있었다.  그 과정에서 실장님이 익숙한 이름을 부르셨는데 숭실대 다닐때 많이 뵜던 전상훈 선배님이 계셔서 이 바닥이 좁다는 말을 실감할 수 있었다. 신입사원 소개 할때 소주 3잔을 연달아 마신 것을 포함하여 한병 반정도를 마신 상태로 다시 숙소로 돌아와 고스톱을 재개!  새벽 3시넘어서야 게임을 마무리 하고 4시 30분쯤 잠들 수 있었다. 다음날 아침식사를 하고 숙소를 떠나 찜찔방을 향했는데 도착해보니 대명비발디파크 안에 있는 사우나 및 찜질방이였다! 눈 앞에 펼쳐진 슬로프를 보며 승호형과 나는 "여기까지 왔는데 스키(보드)를 못타다니!"라고 이야기 하며 아쉬움을 감추지 못했다. 그런데 극적으로 찜질방 매표소 앞에서 스키(보드) 타고 싶은 사람은 회사에서 3만원을 지원해 줄테니 자비로 타도 된다고 해서 6명이 그렇게 스키장을 향하게 되었다. 처음에는 초급 슬로프를 3번 타고 바로 중급 슬로프인 재즈로 이동했다. 보드를 잘 타시는 형이 있어서 배우면서 재밌게 탈 수 있었다. 이제는 중급 슬로프도 겁 없이 즐길 수 있을 정도! 겨우 3시간 정도였지만 새롭게 만난 Core실 분들과 함께 즐거운 시간을 보낼 수 있었다. 연구실로 돌아와 컴퓨터 세팅을 마치고 사택에 가서 자리를 잡고 숙면을 취할 수 있었다.

토요일인 오늘에는 청계산 산행이 있었다. 생각보다 금방 매봉에 올랐는데 내가 속한 Core실 신입 5인방이 가장 먼저 매봉에 올라 강한 체력과 단결력을 과시(?)했다. 하산한 후 식당에서 토종닭 요리에 막걸리를 마시고 대낮에 빨간 얼굴로 집에 돌아왔다. 일주일 내내 하루에 6시간도 제대로 잠을 이루지 못한 관계로 집에서 완전히 뻗어버렸다.

원래의 스토리는 여기서 마무리 되고 다음주 월요일부터 연구실에 출근해야 하는 것이지만, 어제 비팍의 재즈에 올라 핸드폰을 꺼낸 순간 반갑지 않은 문자를 확인했다. 앞으로 한달동안 연구실을 떠나 외부 프로젝트를 수행하러 파견나가야 한다는 ...

진짜 기업에서 수행되는 프로젝트는 어떤 것인지, 우리회사의 제품이 어떻게 쓰이는지 확인 해 볼 수 있는 좋은 기회이기도 하지만 나는 하루라도 빨리 연구실의 평온한 일상에 적응하고 싶다. 일단 주어진 미션을 충실히 달성해야겠지!

어제 교육과정에서 조편성을 한 후 저녁식사를 하며 서로 친해졌고, 오늘은 본격적으로 "팀빌딩"이라는 교육과정을 체험했다. 여느 대기업에서 하는 것에 비하면야 아주 약소하지만, 오랜만에 팀명을 정하고 팀구호와 팀가를 만드는 쑥쓰러운 작업을 해냈다.

우리가 정한 팀의 이름은 바로 티빡이!

마빡이의 배경노래를 개사하여 팀가를 만들고 실제 노래를 부를때는 마빡이 율동(?)을 어설프게 따라했고, 마지막 팀 구호에서는 티빡이라 외치며 우리가 만든 티빡이 자세를 부끄럽게 취해보였다.

공연(?)이 끝나고 어떤 한 분이 이런 말씀을 하셨다.

"아... 회사 옮겨야겠다."

다들 나처럼 내성적(?)인 분들이 모인 집단이라 그런지 우리는 쑥쓰러움을 "수고하셨습니다"라는 말로 서로 무마하며 자리에 앉았다.

그 동안 키워주신 부모님께 감사드리는 마음으로 절을 올리고 첫 출근을 위해 아침 일찍 집을 나섰다. 좋은 기분으로 길을 나섰으나 오랜만에 겪는 혼잡한 서울에서의 출근은 역시 예상대로 피곤했다. 8시에 집을 나서 9시 35분이 되어서야 삼성역 근처의 교육센터에 도착할 수 있었다. 빨리 사택에 입주하여 연구실에 걸어서 출근할 수 있는 날이 오길!

아는 사람이 별로 없을 줄 알았는데 생각보다 대학원 동문들이 많아서 쉽게 적응할 수 있었다. 그 중에 절반은 서로 안면은 있지만 인사를 나눈적이 없었는데 이번 기회에 친해질 수 있었다. 조편성을 하면서 새롭게 만난 분들도 좋은 분들이였고, 나와 같은 Core실에 가게될 신입연구원들도 다들 좋은 분이라 연구실 생활이 기대가 된다.
 
6시까지 회사생활에 대한 교육을 마치고 저녁식사는 삼겹살에 소주를 함께했는데, 아주 오랜만에 마시는 소주인지라 1병정도에 한계치에 도달하여 집에 오는 길이 적잖이 고생스러웠다. 다시는 술을 많이 마시지 않겠다는, 언젠가는 또 잊어버릴 다짐을 하는 나 ...

대기업이 아닌 이 회사를 선택한 이유는 다른 곳에서 경험할 수 없는 도전적인 연구를 해볼 수 있다는 것과 실력있는 분들이 많이 계셔서 엔지니어로 성장하기에 유리하다고 판단했기 때문이다. 물론 부족한 능력에 비해 잠재력을 인정해 주고 좋은 대우를 해주었다는 측면도 크게 작용했다.

빨리 3일과정의 교육이 끝나고 연구소에서 내 책상, 내 컴퓨터를 가지고 생활할 날이 오길. 서울의 출퇴근을 경험하며 벌써 부터 한적한 대전생활이 그리워진다.

사용자 삽입 이미지

내 인생의 마지막(?) 졸업식에 참가하기 위해 아침 일찍 영등포역에서 새마을호를 타고 대전역을 향했다. 졸업식은 2시 부터였지만 교수님을 뵙기 위해 약소한 선물을 들고 일찍 출발했다. 아뿔사! 185번을 타고 동측 쪽문에서 내렸는데 학생증이 없어 정문까지 걸어야했다. 아침 일찍인데도 벌써 부터 정문앞에 꽃을 파는 상인들이 나와 졸업하는 나에게 꽃을 사라고 했다.

연구실에 들러 교수님께서 오시기를 기다렸다. 점심에는 연구실 사람들과 피자를 먹은 후 교수님 방에 들러 인사드렸다. 행진(?)을 하기 위해 학부체육관에 모여 줄을 섰다. 2시가 가까워 오자 학부체육관에서부터 졸업식이 열리는 노천극장까지의 무질서한(?) 행진이 시작되었다.

졸업식장으로 들어서는 순간 우린 모두 탄성을 질렀다. 공부하다가 스스로의 한계에 좌절하거나 혹은 청춘사업으로 인해 골머리가 아플때 가끔 찾아가서 별보고 음악들으며 기분전환하던 그 음산한(?) 노천극장이 화려한 옷을 입고 있었다. 졸업생들이 앉을 자리에는 담요와 핫팩이 있었다! 학부모석에는 우산모양의 난로까지!!!

명예박사학위 수여식에서부터 축사, 치사, 식사 등의 뭐가 뭔지 구분도 안되는 순서가 지나면서 내 발은 얼어서 동상에 걸릴 것 같은 지경에 이르렀으나 누구하나 불평하는 사람이 없는 것을 보면 다들 학교측의 철저한 준비에 만족 내지는 감동하고 있는 듯 했다. 한 사람씩 단상위에서 이름을 불러주고 졸업장을 준다는 이야기를 들었기 때문에 시간이 너무 오래 걸리지 않을까 걱정이 되었으나, 2개의 큐를 마련하여 각각 대략 2초에 한명씩 뽑아내니 생각보다 빨리 진행이 되었다. 추억에 남을 만한 졸업식을 만들어 주겠다던 학교측의 약속은 충실히 이행된 듯!  

졸업식이 끝나고 부모님을 만나 사진을 찍고, 전산과로 돌아와 연구실 사람들, 동기, 후배들과 사진을 찍었다. 어머니께 졸업가운을 입혀드리고 사진을 찍을 때가 가장 뿌듯했던 것 같다. 졸업가운을 반납하고 졸업증명서를 띠어 졸업이 되었음을 확인하고 안심한 후 학교를 떠나 유성에서 저녁을 먹었다.

돌아오는 길에 내가 일하게 될 회사 연구실과 내가 거주하게 될 사택에 들러 짐을 두고 돌아왔다. 정겨운 사람들이 함께 했던 연구실을 떠나 마음 열고 함께 할 수 있는 사람이 (아직은) 없는 낯선 장소를 만나서야 비로소 나의 대학원 생활이 온전히 끝이 났음을 실감할 수 있었고 그래서 조금은 침울한 기분으로 집으로 돌아왔다.

하지만 이제 겨우 내 인생의 1막이 끝이 났을 뿐 ...
사용자 삽입 이미지

개봉하면 꼭 보고 싶은 영화였는데, 우연히 어둠의 경로(?)를 통해 받아보게 되었다. 개인적으로 이런 진부한(?) 스토리를 좋아하는 편이다. 노력끝에 원하는 걸 성취하는 스토리! 영화의 초반에는 록키가 동기부여를 얻고, 중반에는 유명한 록키 배경음악과 함께 훈련을 하고, 후반에는 경기를 하는 기존의 흐름을 철저히 답습하고 있다.

록키의 사랑하는 아내 에드리안은 죽었고, 그의 아들은 록키의 그늘에 가려 자신의 삶을 찾지 못하고 괴로워 하는 상황에서 이야기는 전개된다. 경기는 비교적 박진감 넘치지 않지만 경기 후의 감동은 그 어떤 록키 시리즈보다도 대단했다. 경기의 승패와 상관없이 다가오는 감동은 록키가 아들에게 했던 이야기에서 비롯된다. 그는 경기에서 진정한 승리를 보여주었으니까.

네가 알고 있는 것이겠지만 내가 얘기를 좀 해줄까? 이 세상은 결코 따스한 햇살과 무지개로만 채워져 있지 않아. 온갖 추악한 인간사와 더러운 세상만사가 공존하는 곳이지. 그렇다고 세상을 거칠게 살라는 건 아니다. 그런 태도는 자신의 영혼을 갉아먹을 뿐이니깐. 하지만, 너와 나, 그리고 그 누구도 아닌 사람들.. 세상을 힘껏 살아가야 돼. 네가 얼마나 성공적으로 사느냐가 아니라. 네가 얼마나 삶을 치열하게 살아가느냐가 중요한 거야. 조금씩 앞으로 전진하면서, 그러면서 하나씩 얻어나가는거야. 계속 전진하면서 말이야. 그게 바로 진정한 승리야.

오즈 엠티에 이어 2박 3일의 일정으로 휘닉스파크에 다녀왔다. 엠티에서 방은 작은데 사람이 많아서 도저히 잘 수 없는 지경이라 밤을 새우고, 다음날은 다시 하루를 뒤집어 새벽 6시에 이어나 8시에 삼성역에서 윤서누나를 만나 휘팍으로 가는 버스를 탔다. 물론 매우 피곤한 상태로 ...

숙소에 도착해 라면을 끓여먹은 후 장비를 빌려 11시쯤 스패로우를 오르는 리프트를 탈 수 있었다. 보드는 작년에 3시간 타본 것이 전부. 과연 그때만큼 탈 수 있을까 불안을 떨칠 수가 없었다. 그러나 다행히 약간 불안하긴 했지만 사이드 슬리핑과 펜쥴럼으로 내려오는데에는 큰 무리가 없었다. 스패로우를 한번 내려오며 예전의 감을 회복한 후, 연구실 사람들을 만나지 못한 관계로 홀로 동영상 강좌에서 본대로 베이직 턴을 시도해보았다. 의외로 몇 번만에 양방향의 베이직 턴을 어설프게 구사할 수 있게 되었다. 그렇게 첫 날은 스패로우에서만 베이직 턴을 연습하며 보냈다. 저녁시간은 보드게임과 맥주와 "주몽"과 함께 보내고 잠들었다.

둘째날 아침에 일어나보니 온몸이 만신창이! 라면으로 아침을 때우고 다시 스키장으로 고고싱! 보드를 잘타는 요셉이가 가세하여 얼떨결에 시작부터 몽블랑에 올랐다. 안그래도 눈이 내리고 안개낀 날씨에 몽블랑을 오르는 리프트(콘돌) 위에서 "이게 잘하는 짓인가?"하는 생각을 떨쳐낼 수가 없었다. 어제의 어설픈 턴조차 구사하기 힘든 상황에서 무작정 파노라마로 내려가기 시작했다. 산등성이의 완만한 경사에서 요셉이의 가르침을 받으며 감을 잡고 내 자세가 상당히 불안하다는 지적을 받았다. 거의 서서 타고 있었고 무게 중심이 뒤에 실려 있었다. 드디어 본격적인 경사를 만나 턴을 시도하고 넘어져 눈위를 질질 끌려가기를 몇 차례 반복하며 조금씩 나아갔다. 그렇게 오전에는 조금은(?) 버거운 파노라마에서 연습을 했다.

점심을 먹으려고 12시 30분에 모였는데, 지갑이 사라졌다는 사실을 깨달았다. 작년에는 순일이한테 빌린 보드장갑을 잊어버리더니 이번에는 내 지갑이란 말인가? 심하게 몇 번 구르면서 주머니의 자크가 조금씩 열렸고 언젠가 어디에선가 빠져나간 것 같다. 분실물 센터에 신고하긴 했으나 찾으리라는 기대는 안드로메다로 ...

스키장에 가기 직전에 마트에 들러 10만원을 뽑으려고 시도했으나 CMA 현금카드라서 그런건지 안뽑아진 것이 전화위복! 잃어버린 지갑에는 단 돈 천원이 들어 있었다. 돈은 그렇다 치고 애지중지 하던 지갑과 그 안에 들어 있던 주민등록증, 운전면허증, CMA 보안카드, CMA 현금카드, TTL 멤버쉽 카드, 학생증, LG카드, 신한맥스카드, 삼성카드 등을 다시 재발급 받을 생각을 하니 정신적 데미지가 느껴진다. (칠칠맞지 못한 영혼이여 빨리 꼼꼼하고 야무진 아가씨를 만나야 할텐데 ...)

지갑분실건만 아니면 다 좋을 것 같은 오후, 스패로우까지 걸어가는 것이 귀찮다는 것에 의견을 모으고 초급자 탑승금지라고 써있는 리프트(팔콘)를 타고 불새마루에 올랐다. 키위에서 보드를 착용하며 아래로 보이는 상당한 경사에 후회가 밀려왔다. 도저히 턴이라고는 시도조차 해볼 수 없어 보였다. 처음에는 사이드 슬리핑으로 낙엽쓸면서 겨우 내려오다가 몇 번 가다 보니 힘들게 턴을 하며 내려올 수 있었다. 키위 아래로 이어지는 팽귄은 작년의 추억을 떠올리게 했다. 워낙 겁이 많아서 무게 중심을 뒤로 빼는 습관이 완전히 고쳐지지 않았지만 대략 턴으로 끝까지 내려올 수 있게 되어 나름대로 흡족했다.

이번 경험으로 지금까지 총 3일동안 스노우보드를 배웠는데, 속도감도 좋고 엣지로 눈을 긁는(?) 느낌도 좋다. 다만 몇 번 심하게 넘어져서 현재의 몸상태가 엉망이라는 것과 지갑을 잊어버려 집에 오자마자 여기저기 재발급 받으러 다니고 있다는 사실이 에러! 어느정도의 기초를 닦았으니 다음주에 회사 워크샵에서 스키장을 찾게 되면 좀더 능숙하게 탈 수 있도록 연습해 보아야겠다.

인생의 마지막 방학을 보내고 있다. 오늘까지는 집에서 빈둥빈둥. 역시 놀고는 못사는 성격이라 그런지 빈둥빈둥 노는 것이 즐겁지만은 않다. 게다가 내 책상이 없다는 핑계로, TV 소리가 들린다는 핑계로 책도 읽지 않고 있으니 조금은 스스로 한심하다는 생각도 들지만 이것도 이번이 마지막이라고 생각하고 그냥 내버려 두고 있다.
 
내일부터 졸업식까지는 살인일정(?)이 기다리고 있다. 주말에는 오즈 엠티를 다녀올 예정이고, 다음주 월요일부터는 연구실 식구들과 함께 휘닉스파크에 2박 3일 일정으로 보드를 타게 될 것이다. (연구실을 떠난 처지에 조금 민망하기도 하지만. ^^;)

게다가 오늘 회사에서 전화가 왔는데, 연구소 입사 첫 날 회사 워크샵으로 스키장에 간다는 반가운 소식을 전달받았다. 일체의 렌탈비와 리프트권 비용을 모두 지원해준다는 파격적인 사실과 함께! 그리고 내가 어떤팀에 들어가게 될지도 알게 되었다.

작년 2월 난생 처음 스키장에 갔고, 엉덩이 보호대 없이 보드복이 아닌 100kg 나갈때 즐겨입던 파카잠바를 입고 힘들게 보드타는 법을 배웠다. 3시간의 넘어짐 끝에 펜쥴렴을 어느정도 자유롭게 구사하게 되었을 때, 주간권이 끝나는 시간이 다가와 무리하게 빨리 내려오다 그만 심하게 넘어졌는데, 잠깐 거동을 할 수 없을 정도로 고통스러웠다. 그리고 그 이후로 안탔다 ......

올해는 보호대와 함께 보드복도 제대로 갖춰입고, 겁은 상실하고, 턴까지 꼭 배워보고 싶다. 돈 생각하지 말고 마지막 방학을 만끽하자!

나에게는 결코 짧지 않았던 2년간의 대전생활을 정리하고 집으로 돌아왔다. 떠나기 이틀 전에는 볼링클럽인 SIGBOWL 식구들과 볼링 게임이 끝난 후 와인, 맥주 파티에 이어 새벽 2시까지 보드게임을 즐기며 마지막 시간을 함께 했고, 떠나기 하루 전인 어제 밤에는 동문들과 저녁을 먹고 영화를 보며 역시 즐거운 시간을 보냈다. (함께 해주신 분들께 감사 드려요!)

난생 처음 이사다운 이사를 해봤는데 하루만에 끝나긴 했지만 역시 만만치 않았다. 120~130권 가량 되는 책을 운반하는 것이 걱정스러웠는데 오히려 가장 힘들었던 것은 옷을 담은 거대한(?) 보따리를 옮기는 작업이였다. 아침에 순일이가 도와준 덕분에 무난히 기숙사를 비우고, 오후에는 윤경 누나, 재호형, 현석군이 도와준 덕분에 연구실의 책과 잡동사니를 담고 있는 다섯 박스의 짐을 쉽게 차에 옮길 수 있었다. (이사 도와주신 분들께 감사 드려요!)

대부분의 연구실 사람들은 다음주 스키장에서 다시 만날 수 있는 관계로 가볍게 인사를 드리려고 한분한분 찾아뵙고 잠깐의 이야기를 나누면서 나는 그분들의 정이 느껴져서 따뜻한(?) 울음을 목으로 삼켜야만했다. (항상 따뜻하게 대해주신 연구실 식구들께 감사 드려요!)

사실 떠나기 직전까지는 별로 실감이 나지 않았다. 이삿짐을 꾸리는 그 순간까지도 그저 무덤덤했는데. 고속도로로 나와 경부고속도로와 합류하는 지점에 들어서자 짧은 순간 그 동안의 추억들이 주마등처럼 머리속을 스쳐가며 나는 바보처럼 서럽게 울고 있었다. 대전에 처음 왔던 순간의 다짐만큼 열심히 하지 않아서 지난 2년이 후회스러웠을까? 결코 다시는 돌아오지 않을 순간들을 놓치고 싶지 않았던걸까? 항상 따뜻하게 대해주던 연구실 식구들이 벌써 그리웠던걸까? ......

사용자 삽입 이미지

드디어 2월 입사 이후에 거주하게 될 사택을 배정 받았다. 분당 서현역을 중심으로 왼쪽 위에 빨간 네모가 회사 연구소, 오른쪽 아래 파란 네모가 사택이다. 지하철 몇 정거장 떨어진 곳에서 회사를 다니게 될 것으로 예상했는데 정말 가까운 곳이라서 마음에 든다.

왼쪽 아래 초록색으로 보이는 부분이 분당 중앙공원! 달리기를 좋아하는 나에게 최적의 장소가 될 것 같다. 걸어서 출퇴근하고, 회사에서 밥먹고, 놀 시간 없이(?) 열심히 일하면 그야말로 돈이 굴러 들어오겠구나!

이클립스의 기본적인 사용자 인터페이스는 크게 view와 editor로 구성됩니다. 이 글에서는 매우 간단한(!) VICODE의 Log View를 가지고 View의 구현방법을 소개하겠습니다.

사용자 삽입 이미지

먼저 plugin.xml에서 View를 확장하는 부분을 보겠습니다.

<extension
         point="org.eclipse.ui.views">
      <view
            category="kr.ac.kaist.vicode"
            class="kr.ac.kaist.vicode.view.log.LogView"
            icon="icons/esterel_image.gif"
            id="kr.ac.kaist.vicode.logview"
            name="Log"/>
      <category
            id="kr.ac.kaist.vicode"
            name="VICODE"/>
   </extension>

org.eclipse.ui.views 확장점을 사용합니다. 해당 View를 포함할 카테고리를 지정하고 View를 표현하는 아이콘을 정의합니다. 이제 LogView.java 코드를 보겠습니다. 그렇게 길지 않으니 전체 코드를 늘어놓고 글을 이어나가도록 하지요.

public class LogView extends ViewPart
{
 private Table table;
 private TableColumn[] columns;
 private final String[] TABLE_COLUMN_NAMES = { "Message", "Location", "Time" };
 private final int[] TABLE_COLUMN_WIDTH = { 400, 400, 150 };
 public LogView()
 {
  super();
 }
 public void createPartControl(Composite parent)
 {
  table = new Table(parent, SWT.BORDER | SWT.V_SCROLL);
  columns = new TableColumn[TABLE_COLUMN_NAMES.length];
  for(int i=0, n=TABLE_COLUMN_NAMES.length; i < n; i++)
  {
   columns[i] = new TableColumn(table, SWT.NONE);
   columns[i].setText(TABLE_COLUMN_NAMES[i]);
   columns[i].setWidth(TABLE_COLUMN_WIDTH[i]);
  }
  table.setHeaderVisible(true);
  table.setLinesVisible(true);
 }
 public void setLog(String message, String location)
 {
  Date date = new Date();
  SimpleDateFormat dateFormat = new SimpleDateFormat("hh:mm:ss");
  String dateString = dateFormat.format(date);
  TableItem ti = new TableItem(table, SWT.NONE);
  ti.setText(0, message);
  ti.setText(1, location);
  ti.setText(2, dateString);
  for (int i = 0; i < columns.length; i++)
  {
   columns[i].pack();
  }
 }
 public void clearLog()
 {
  table.clearAll();
 }
 public void setFocus()
 {
  table.setFocus();
 }
}

View를 구현한 클래스는 ViewPart 클래스를 상속합니다. 예제의 Log View 처럼 단순히 정보를 보여주는 View를 구현하는 경우에는 createPartControl() 메서드에서 보여주고 싶은 위짓을 정의하는 것으로 간단히 View를 구성할 수 있습니다. View에 Action을 추가한다던가 워크벤치의 다른 View 혹은 Editor와 상호작용하도록 하려면 조금 더 복잡해지겠지요.

여기서 한가지 명확히 해야할 것은 JFace viewer의 위상입니다. JFace viewer는 모델-뷰 구조를 기반으로 사용자가 쉽게 유려한 viewer를 만들 수 있도록 돕기 위해 제작된 일종의 UI 프레임워크입니다. 따라서 JFace viewer를 제작할 때 모델의 데이터를 뷰에 전달하는 Contents Provider, Label Provider 등을 구현해야 하는 것이죠. 중요한 것은(!) JFace viewer는 이클립스에서 UI를 표현할 수 있는 어떤 곳에도 붙일 수 있다는 것 입니다. 마법사의 한 페이지에 붙일 수도 있고 Editor에 붙일 수도 있죠. 이 글에서 말하는 Viewer가 아닌 View는 이클립스 워크벤치의 일부로서 화면에 정보를 나타내기 위한 부분이라고 생각할 수 있습니다. 구현하기에 따라서는 ViewPart를 상속하여 Editor의 역할을 수행하도록 만들 수도 있습니다.

본론으로 돌아와서 createPartControl() 메서드에서 SWT의 table 컨트롤을 추가하고 초기화 합니다. View에 정보를 제공하고자 하는 다른 클래스에서는 clearLog(), setLog() 메서드를 이용해서 View에 포함된 table 위짓에 값을 추가 및 삭제하게 됩니다. LogView의 인스턴스는 id를 이용해서 다음과 같이 얻을 수 있습니다.
 
 public void init(IWorkbenchWindow window)
 {
  this.window = window;
 }

 ...
 LogView logView =
    (LogView) window.getActivePage().findView(IResourceIDs.LOG_VIEW_ID);

Multi-page Editor는 여러페이지를 가진 에디터로, VICODE에서 spec.xml을 편집하는 Specifiaction Editor를 다음과 같이 총 4페이지로 구성된 형태의 에디터로 작성하였습니다. 이 글에서는 에디터 자체에 대한 내용보다는 여러페이지로 구성된 에디터를 작성하는 경우에 구현방법과 고려해야할 사항들에 대해서 소개하겠습니다.

0123

Specification Editor에서 편집할 spec.xml 파일은 총 3가지 section으로 구성되어 있습니다. 에디터의 처음 3페이지는 각 section의 편집과정을 돕기 위해 컨트롤로 구성된 폼 에디터를 제공하며 마지막 페이지는 spec.xml을 직접 편집할 수 있도록 XML 에디터를 포함하고 있습니다.

구현 디테일로 들어가기 이전에 Multi-page Editor를 구현할 때 고려해야 할 사항에 대해서 설명하겠습니다. Multi-page Editor는 하나의 EditorInput을 여러 페이지에서 편집하게 되므로 편집하는 내용이 겹치는 경우에는 서로 다른 페이지 간의 값을 동기화 처리를 해주어야 합니다. 이 글에서 설명하는 페이지간의 동기화 방법은 직접 고안한 것이므로 효율적이지 않을 수 있습니다. ^^;

VICODE의 Specification Editor의 경우에 EditorInput은 spec.xml 입니다. 처음 3페이지의 폼 에디터와 마지막 페이지의 spec.xml 페이지는 편집의 범위가 겹치게 됩니다. 게다가 spec.xml을 구성하는 3가지 section 사이에서도 서로 값이 의존적으로 사용되기 때문에 각 페이지에서 변경된 값은 항상 다른 페이지에도 적용되어야 합니다. VICODE의 경우 다음과 같이 3가지 객체의 값이 동기화된 상태로 유지되어야 합니다.

spec.xml - AST - 각 페이지의 컨트롤이 가지는 값

AST는 spec.xml을 파싱해서 얻게 되는 Abstract Syntax Tree를 의미합니다. 에디터가 실행되면 spec.xml을 파싱해서 AST에 저장하게 되고 각 페이지의 컨트롤의 값은 AST의 값을 바탕으로 채워지게 됩니다. 이 것은 제가 말한 동기화의 아주 일부분이죠. 상세내용은 뒤에서 다루기로 하고 일단 코드를 보도록 하겠습니다.

우선 Editor의 확장점은 org.eclipse.ui.editors 입니다. Multi-page editor의 확장은 다른 editor의 확장방법과 다르지 않습니다. 다음은 확장을 정의한 plugin.xml의 일부입니다.

<extension
         point="org.eclipse.ui.editors">
      <editor
            class="kr.ac.kaist.vicode.editor.spec.SpecEditor"
            contributorClass="kr.ac.kaist.vicode.editor.spec.SpecEditorContributor"
            default="true"
            filenames="spec.xml"
            icon="icons/sample.gif"
            id="kr.ac.kaist.vicode.editor.spec.SpecEditor"
            name="Specification Editor"/>
</extension>

filenames 속성을 통해 spec.xml 파일에만 적용되도록 정의하였습니다. 이제 에디터를 구현한 SpecEditor 클래스를 살펴보겠습니다.

public class SpecEditor extends MultiPageEditorPart
    implements IResourceChangeListener
{
 private final String endl = "\n";
 private TextEditor editor;
 private String specFilePath;
 private int currentPageIndex = 0;
 private int editorPageIndex;
 private CommunicationPage communicationPage;
 private ApiPage apiPage;
 private RulePage rulePage;

 private Spec spec;

MultiPageEditorPart를 상속하여 구현합니다. 멤버변수로 눈여겨 보아야 할 것은 각 페이지를 참조할 수 있는 인스턴스와 AST를 저장하는 spec 입니다. ApiPage 등은 Composite을 상속한 클래스로 페이지를 구성하는 컨트롤을 정의하고 있습니다. editor는 마지막 페이지를 구성하는 XML 에디터의 레퍼런스 입니다. 이제 각 페이지를 어떻게 에디터에 추가하는지 살펴보겠습니다.

 protected void createPages()
 {
  createCommunicationPage();
  createApiPage();
  createRulePage();
  createXmlEditorPage();
 }
 void createRulePage()
 {
  rulePage = new RulePage(getContainer(), SWT.NONE, this);
  int index = addPage(rulePage);
  setPageText(index, "Rule");
  rulePage.setSpec(spec);
 }
 void createXmlEditorPage()
 {
  try
  {
   editor = new XMLEditor();
   editorPageIndex = addPage(editor, getEditorInput());
   setPageText(editorPageIndex, editor.getTitle());
  }
  catch (PartInitException e)
  {
   ErrorDialog.openError(getSite().getShell(), "Error creating nested text editor", null, e.getStatus());
  }
 }

createPages() 메서드에 페이지를 추가하는 코드를 작성해 주어야 합니다. 여기서 불리는 createRulePage()를 살펴보면 addPage() 메서드를 이용해서 에디터에 페이지를 추가하는 것을 확인할 수 있습니다. XML 에디터를 추가하는 createXmlEditorPage() 메서드에서는 addPage() 메서드의 두번째 인자에 Multi-page Editor의 EditorInput(spec.xml)을 넘겨줍니다.

Multi-page Editor에서 save가 발생한 경우 호출되는 doSave() 메서드를 작성해야 합니다.

 public void doSave(IProgressMonitor monitor)
 {
  if (currentPageIndex == editorPageIndex)
  {
    getEditor(editorPageIndex).doSave(monitor); // save
   Xml2Spec parser = new Xml2Spec(specFilePath);
   spec = parser.parseSpec(); // parsing to get AST

   communicationPage.setSpec(spec); // set AST to each page
   apiPage.setSpec(spec);
   rulePage.setSpec(spec);

  }
 }

Specification Editor에서 첫 3페이지는 저장 명령이 유효하지 않고 Apply 버튼을 클릭함으로써 수정내용을 AST와 파일에 적용하도록 구성되어 있습니다. Reply 버튼을 클릭하면 AST의 내용으로 컨트롤의 값을 복구 합니다. 반면에 4번째 페이지인 XML 에디터 페이지를 선택한 경우에 저장하게 되면 XML 에디터의 doSave() 메서드를 호출하여 spec.xml에 저장하게 됩니다. 저장이 완료되면 spec.xml의 내용이 갱신되었기 때문에 이를 다시 파싱하여 새로운 AST를 얻고 각 페이지에 setSpec() 메서드를 이용해 AST를 갱신해줍니다. 각 페이지는 이 AST를 이용해 컨트롤에 값을 설정하겠죠.

다음으로는 페이지가 변경되었을 때 호출되는 pageChange() 메서드를 볼까요?

 protected void pageChange(int newPageIndex)
 {
  switch (newPageIndex)
  {
  case 0:
   communicationPage.updatePage(); // AST to control
   break;
  case 1:
   apiPage.updatePage();
   break;
  case 2:
   rulePage.updatePage();
   break;
  case 3:
   updateSpecFile(); // AST to spec.xml
   break;
  default:
  }
  currentPageIndex = newPageIndex; // save current page index
 }

처음 3페이지가 선택된 경우에는 AST의 내용을 바탕으로 컨트롤의 값을 채워주는 함수인 updatePage() 메서드를 호출합니다. 4페이지가 선택된 경우에는 AST의 내용을 spec.xml에 저장합니다. 따라서 XML 에디터는 최근 변경된 spec.xml의 코드를 출력하게 됩니다.

흐름을 다시 정리해보면, 에디터가 열리면서 spec.xml을 파싱하여 AST를 저장합니다. 처음 3페이지가 선택된 경우에는 AST의 내용을 가지고 페이지를 구성하는 컨트롤의 값을 채웁니다. 이 컨트롤의 값을 수정한 후 Apply 버튼을 누르게 되면 AST를 갱신함과 동시에 spec.xml 파일을 AST를 가지고 저장합니다. 반대로 XML 에디터에서 수정하고 저장한 경우에는 저장된 spec.xml 파일을 다시 파싱하여 AST를 구하고 이 것을 각 페이지에 넘겨줍니다.

이해를 돕기 위해 아래에 SpecEditor.java, RulePage.java 파일을 예제로 남깁니다.
 
헌법의 풍경
김두식 지음/교양인

기숙사 침대 위에 올려져 있는 이 책을 보고 순일군은 명저라며 꼭 읽어보라고 권한적이 있다. 읽을 책을 고르는 방법 중에 개인적으로 가장 선호하는 것은 네트워크 독서법. 웹에서 하이퍼링크를 따라가듯 <21세기에는 바꿔야할 거짓말>에서 김두식님의 이야기를 듣고 그의 책을 읽고 싶어서 이 책을 선택하게 되었다. 아쉽게도 양심적 병역거부에 대해서 다룬 <칼을 쳐서 보습을>은 구할 수 없는 상태였다.

제목이 주는 위압감처럼 우리는 헌법에 대해서 "어려운 것", "보통 사람은 알 수 없는 것", "높으신 분들이 결정하는 것" 이라고 생각하며 살아왔다. 그러나 헌법의 존재 의미가 국가를 통제하고 우리의 인권과 권익을 보장하기 위한 것이라는 데에 생각이 미치면 결코 어렵게 느끼고 멀리해야 할 것이 아니라 충분히 이해하고 적극 활용해야 함을 깨달을 수 있다. 이 책은 우리에게 헌법에 좀 더 쉽게 다가갈 수 있도록 도와준다는 것에 큰 의미가 있다고 생각한다.

나는 이 책을 쓴 저자의 용기에 박수를 보낸다. 1년여의 짧은 시간동안 검사직을 수행하던 저자는 법조계의 오랜관행과 특권의식에 때문에 자신의 신념을 지키기 어려움을 괴로워 하다 과감히 검사직을 그만두고 미국에서 유학중인 아내를 위해 2년동안 전업주부(?)의 역할을 충실히 이행한다. 지금은 코넬대 법과대학에 진학하여 석사학위 취득후 경북대 법대에서 학생들을 가르치고 있다.

자신의 법대를 선택했던 이유에서 부터 검사를 관두기까지의 여정을 소개하고, 법에서 정답은 없다는 것을 음란과 예술사이에서 가르쳐준다. 특히 여기서는 토론을 통해 사회적 합의를 이루어가는 과정을 잘 그려놓고 있어 올바른 민주주의가 어떠한 절차를 통해서 완성될 수 있는지를 잘 설명해주고 있다. 2장에서는 "국가라는 이름의 괴물"의 위험성에 대해서 설명하고 국가를 견제하기 위한 법과 법조인의 역할에 대해서 성찰해본다. 3장은 법조인들이 어떻게 특권의식을 가지게 되는지를 자신의 경험을 통해 소개하고 있다. "어렵고 가난한 사람을 위해 일하겠다던" 법조인들의 초심이 어떻게 특권의식으로 변질되어 가는지를 잘 설명하고 있다. 그 밖에도 대한민국 검찰과 헌법 정신, 정당한 권리인 묵비권의 힘, 차별받지 않을 권리 등에 대하여 저자의 생각을 확인할 수 있다.

난 우리 법조인들이 가지고 있는 특권의식에 적잖이 놀랐다. "어렵고 가난한 사람을 위해 일하겠다던" 그들의 초심이 변질되어 가는 과정을 보면서, 의식있는 사람도 긴장의 끈을 놓으면 얼마든지 현실속에서 변질될 수 있다는 것을 확인할 수 있었다. 지금 내가 정의라고 믿는 것들을 지켜나갈 수 있도록 끝없이 읽고 생각하고 배우며 자신의 삶에 미학을 부여할 수 있도록 노력해야겠다는 생각이 든다.
친구를 만나고 집으로 돌아오는 길에 당산역 앞에서 또 그들(?)을 만났다. 서울에 살때는 꽤 자주 만났는데 대전 생활을 하면서 만난 것은 오늘이 두번째(만남의 장소는 물론 모두 서울). 헤드폰에서 흘러나오는 이루마의 연주곡을 들으며 유유히 버스 정류장을 향하는데 어떤 사람이 말을 걸어왔다.

"당신에게서 좋은 운이 보입니다. 잠깐만 ..."

나는 손사레를 치며 지나쳤다. 그를 뿌리치고 난 후 10초후에 또 다른 사람이 나를 잡으며,

"좋은 기운을 타고나셨네요. 잠깐만 ..."
"관심 없습니다."

두번째 도인(?)도 매정히 뿌리쳤다. 평소 같으면 호기심에 몇 마디 들어봤겠지만, 오늘은 빨리 들어가서 <하얀 거탑>을 봐야 하기에 자제의 미덕을 발휘했다.

난 유난히 도인(?)들에게 잘 찍히는 편이다. 정말 내가 비범한(?) 인물이여서 그런건지, 잘 속을 것 같아 보여서 그런건지는 모르겠으나 전자였으면 좋겠다. 작년 말에 고속버스터미널역에서 만난 여자도인(?)은 나를 보고 대단한 능력을 가지고 있는데 뭔가(?)가 기운을 막고 있어서 능력발휘를 못하고 있다고 이야기했다. 형편없는 집중력에 머리가 잘 돌아가지 않을 때면 가끔 이 여자도인의 말이 신경쓰이는 것을 보면 나도 참 ...

지인의 지인의 경험담에 의하면 그들을 따르게 되면 어깨들이 지키고 있는 장소에 가서 절 하고 돈 내고 온다고 하는데 그들의 정체는 무엇일까?

비슷한 경험 다들 가지고 계신가요?
012345

KAIST에 들어오기 이전에 정은 누나에게 이런 이야기를 한 적이 있다.

"KAIST 졸업하면 ETRI에 취직해서 대전에서 연구원으로 조용히 살고 싶어요."

워낙 서울의 번잡함에 지친 나의 이런 반응에 누나는 "젊은이로서 바람직한 생각은 아닌 것 같다"라고 일침을 놓아주셨다. 대전 생활을 2년동안 해오면서 나는 충분히 정은 누나의 생각을 이해하게 되었다. 특히 바로 그 ETRI를 방문하고 나서 더욱 "서울의 활기"를 생각하게 되었다.

오늘은 프로젝트에 관련해서 발표를 하고 협력방안을 모색하기 위해 ETRI에 다녀왔다. 대략 8명 정도의 ETRI 연구원들 앞에서 발표 및 데모를 마치고 나오는 길에 홀가분한 마음으로 사진을 찍어보았다. '언제 다시 와보겠어'라고 생각하며 ...

서울의 번잡함보다 싫었던 것은 출퇴근의 피곤함이였던 것 같다. 매일 3시간 가량을 길거리에서 허비해야 한다는 것이 항상 불만이였기에 대학원은 기숙사에서 걸어(!) 다닐 수 있는 곳으로 가야겠다고 마음먹었다. 꿈은 이루어져 동측기숙사에서 연구실까지는 걸어서 10분거리도 안되지만, 가끔은 출퇴근 하며 여러 사람과 스쳐 지나가던 때가 그립기도 했다. KAIST에서 느끼는 정체를 알 수 없는, 주기적으로 찾아오는 "외로움"도 아마 사람이 그리웠기 때문이었을 것 같다.

KAIST보다 ETRI의 분위기는 더 늘어지는 것 같다. (물론 개인적인 느낌임을 밝힌다.) 유원지에 온 것 같은 쾌적한 환경에 주위를 둘러봐도 사람 10명 찾아보기 힘든 한적함. 덕분에 "활기"라는 것을 찾기는 쉽지 않았다. 강력한 "귀차니즘"에 전염될 것만 같은 느낌.

여전히 나는 차분함을 좋아하는 사람이라 학교의 분위기를 좋아하긴 하지만, 대전에 있는 2년동안 사람들을 많이 만나지 못한 것이 아쉬움으로 남는다. 다행히 내가 일할 곳은 서울과 가깝지만 서울만큼 번잡하지 않은(?) 분당이고 내가 살 곳도 회사에서 지하철 몇 정거장거리에 있는 곳이 될 것이므로 걸어서 혹은 자전거 타고 출퇴근이 가능 할 것 같다. 게다가 강남과 가까워 사람들을 만나기도 좋다. 떠나는 아쉬움과 새로운 환경에 대한 기대로 싱숭생숭한 요즘이다.

요즘 내가 하는 유일한 게임은 피파온라인. 한번 손대면 끝도 없이 계속 플레이 하게되는 RPG게임과 달리 한 경기로 깔끔하게 마무리 되는 스포츠게임은 시간 부담없이 즐길 수 있다는 장점이 있다. 탄력 받으면 여러게임을 연달아 하기도 하지만.
 
피파온라인에서 나의 등수는 대략 82000등이다. 그럭저럭 중상위권(?)에 속하는 등수라고 할 수 있고, 승률은 대략 51.5%, 골득실은 대략 +30골. 빨간 유니폼이 마음에 들고 4-4-2 포메이션을 고집하는 관계로 영국대표님 혹은 맨유를 선택해서 게임을 즐기고 있다.
 
재밌게 하다가 이 게임을 지우게 될 때가 있다. 바로 매너와 배려라는 것을 전혀 모르는 초딩(?)을 만났을 때! 오늘 점심을 먹고 식후땡(?)으로 피파온라인을 몇 게임 했다. 나보다 등수는 하위권이였으나 승률과 골득실은 훨씬 뛰어난 친구와 게임을 즐기게 되었는데, 이 친구가 게임 중에 하는 소리가 가관이다. 골이 들어 갈때마다 혼자 "골", "굿" 이러면서 슬슬 약올리기 시작하더니  나중에는 "그 실력으로 날 이기려고?", "ㅉㅉㅉ" 이라고 혼잣말을 즐기고 있었다. 기억하고 싶지 않은 건지, 기억이 안나는 건지 그 밖에도 반말을 포함하여 상대방의 기분을 상하게 하는 말들을 지치치도 않고 혼자서(!) 열심히 쏟아냈다.

이럴 때 나는 철저히 침묵으로 일관한다. 어차피 대응해봐야 나도 똑같이 초딩(?)이 되어버린다는 생각이 들어서. 하지만 초딩(?)의 철 없는 몇 마디에 기분이 상하는 걸 보면 나도 아직 한참 어린 것 같다. 그렇게 기분이 상하고 나면 부질없음을 깨닫고 차분히 책으로 돌아간다.

만행 1
현각 지음, 김홍희 사진/열림원
만행 2
현각 지음, 김홍희 사진/열림원

몇달 전 선애누나가 이 책을 읽으시면서 대략의 줄거리를 이야기 해주셨는데 그 것을 듣고 난 꼭 이 책을 읽고 싶었다. 꼭 사서 읽고 싶었는데 절판되어서 결국 못 구하다가 선애누나에게 빌려서 3일만에 읽어버렸다. 나 스스로 최근 종교에 대해서 많은 고민을 하고 있었기 때문에 현각스님이 천주교 집안에서 태어나 스님이 되기까지의 이야기가 너무나 궁금했다.

현각 스님이 되기 전의 폴은 호기심이 왕성한 아이였다. 그는 성경을 수도 없이 읽었고 신실한 믿음을 가지고 있었으며 예수님의 뜻을 따라 남을 돕는 삶을 살고자 노력했다. 폴은 카톨릭계 학교에 다녔는데 수녀님들은 그의 질문에 당황하고 힐책할 뿐 납득할만한 대답을 주지 못한다. 그 질문이 내가 기독교에 가지고 있는 것과 너무나 비슷했기 때문에 나 역시 책을 읽으면서 수녀님들의 대답이 실망스럽게 느껴졌다.

이를테면 "불신지옥"에 관한 것이나, 태어날 때 부터 불행을 가지고 태어나는 아이들에 대한 것이다. 하나님은 아이들을 사랑하신다고 하는데 태어날 때 부터 마약에 중독되어 태어나는 아이, 에이즈에 감염되어 태어나는 아이, 먹고 살기도 힘든 가난한 환경에서 태어나는 아이들을 어떻게 이해할 수 있을까? 폴의 의문을 접하며 나는 김혜자님의 <꽃으로도 때리지 마라>에서 그녀가 아프리카의 처참한 상황을 바라보며 외쳤던 외마디가 들려오는 듯 했다.

폴은 어려서 부터 진리를 찾고 싶어 했기에 예일 대학에 진학하여 본격적으로 철학과 신학을 파고 들었다. 그 과정에서 그는 키르케고르, 쇼펜하우어 등의 많은 철학자를 만났으나 명확힌 진리를 찾지 못하고 방황한다. 그후 하버드 대학원에 진학한 폴은 우연히 한국의 숭산스님의 이야기를 듣고 매료되어 한국을 찾고 종국에는 스님이 되어 폴이 아닌 현각이 되었다.

참선을 통해 자기 안에서 진리를 찾는 선불교의 스님이 된 현각은 오히려 자신이 수행자로서 참선을 하는 것이 예수님의 뜻을 이해하고 예수님의 뜻대로 사는 것에 도움이 된다고 이야기 한다. 어떤 종교집단에 소속되어, 어떤 형식을 따르는 것이 중요한 것이 아니라 예수나 부처와 같은 성인의 가르침을 따라 마음과 행동을 일치시켜 남을 돕는 삶을 사는 것이 중요한 것이 아닐까 하는 생각이 든다.

현각의 스승인 숭산스님은 세계에 현존하는 4대 생불로서 어린아이 같은 맑은 눈과 순수한 미소를 가진 분이라고 한다. 책을 읽으면서 나도 그분을 뵙고 싶고, 그 분의 설법을 들어보고 싶다는 생각이 들었다. 또한 불교라는 종교에 대한 강한 호기심이 생겨 현각스님과 숭산스님의 쓴 책을 읽어볼 계획이다. 진리란 무엇일까? 무엇이 올바른 삶일까?

이 글에서는 SWTJFace가 대략 무엇인지, 그리고 이클립스에서 차지하는 위상은 어떤 것인지에 대해서 개괄적으로 이야기하겠습니다. JFace는 일종의 프레임워크이다 보니 공부를 상당히해야 코딩이 가능하지만, SWT를 이용한 코딩은 AWT/Swing으로 UI를 작성해 보신 분이라면 쉽게 적응하실 수 있으리라 생각됩니다. 구조에 큰 차이가 없습니다.

SWT는 Standard Widget Toolkit의 약자로 이클립스에서 UI를 표현하는데 사용되는 API 입니다. SWT가 나오기전에는 AWT와 Swing을 사용했습니만, 써보신 분은 아시겠지만 UI가 어설프고 예쁘지가 않습니다. SWT의 특징은 현재 사용중인 OS에 어울리는 미려한 UI를 제공한다는 것입니다. JNI를 이용해 호스트 운영체제가 제공하는 사용자 인터페이스를 불러서 사용하기 때문이죠. 이클립스를 윈도우, 리눅스에서 각각 실행해보면 SWT와 Swing의 차이를 확인할 수 있습니다. Swing을 사용한 어플리케이션은 윈도우에서나 리눅스에서나 적당히 비슷하면서도 적당히 어설픈 UI를 보여줍니다.

이클립스 플러그인을 제작할 때, SWT는 빈번히 사용됩니다. 마법사의 각 페이지나 Preference 페이지를 작성할 때 등등 세부 사용자 인터페이스를 정의할 때 SWT 코딩을 해야 합니다. 이클립스에서 UI를 제공하는 클래스는 다음과 같이 createContents() 메서드를 오버라이딩 함으로써 유저 인터페이스를 정의합니다. 이때 사용되는 것이 SWT 입니다.

 protected Control createContents(Composite parent) {
  // TODO Auto-generated method stub
  initializeDialogUnits(parent);
  // Get composite and set layout manager
  Composite composite = new Composite(parent, SWT.NONE);
  GridLayout layout = new GridLayout();
  layout.marginHeight = convertVerticalDLUsToPixels
    (IDialogConstants.VERTICAL_MARGIN);
  layout.marginWidth = 0;
  layout.verticalSpacing = convertVerticalDLUsToPixels(10);
  layout.horizontalSpacing = convertHorizontalDLUsToPixels
    (IDialogConstants.HORIZONTAL_SPACING);
  composite.setLayout(layout);

AWT/Swing과 다른 몇가지 SWT의 특징을 언급하고 JFace로 넘어가겠습니다. 우선 Widget간의 부모/자식 관계를 맺는 방법에서 차이가 있습니다. AWT/Swing에서는 다음과 같은 방법으로 부모 인스턴스에 자식 인스턴스를 추가합니다. 패널에 버튼을 추가하는 것을 예로 들 수 있겠습니다.

부모_인스턴스.add(자식_인스턴스);

반면에 SWT에서는 자식 인스턴스를 생성할 때 부모의 인스턴스를 첫번째 인자로 넘겨줍니다. 예제코드에서 Composite을 추가하는 부분을 참조하세요. 그리고 두번째 인자로 스타일 비츠(style bits)라는 것을 정의합니다. SWT.NONE, SWT.PUSH, SWT.CHECK 등이 스타일 비츠에 해당합니다. 이 상수들을 |로 묶어 Widget의 속성을 결정합니다. 물론 각 Widget마다 유효한 스타일 비츠가 정해져 있습니다. 마지막으로 언급할 것은 SWT가 실제 운영체제의 리소스를 사용하기 때문에 더 이상 쓰지 않을 때 해제해야 한다는 점 입니다. 대부분의 SWT Widget은 앞서 살펴본 것 처럼 생성자에서 부모를 지정하기 때문에, 부모를 폐기하면 자식도 폐기된다는 규칙에 의해서 문제가 되지 않습니다. 하지만 부모의 Widget 없이 생성된 SWT 오브젝트인 Font, Image, Color 등등은 사용하지 않을 때 직접 폐기해야 합니다.

JFace는 SWT를 보완하기 위해, 모델 기반 접근 방법(model-based approach)을 기반으로 더 적은 시간에, 더 이해하기 쉬운, 재사용 가능한 코드를 작성할 수 있도록 설계되었습니다. JFace는 UI를 효과적으로 작성하기 위한 일종의 프레임워크라고 할 수 있습니다. JFace 뷰어를 예로 들자면, JFace 뷰어가 제공하는 클래스를 상속해 정해진 절차를 따라서(!) '뚝딱뚝딱' UI를 코딩하면 '짠!' 하고 그럴듯한 하이퀄리티(?)의 UI를 화면에서 확인할 수 있는 것 입니다. JFace는 모델-뷰 구조로 구성되어있기 때문에, 이미 어플리케이션에서 사용하던 모델을 자연스럽게 사용할 수 있습니다. 물론 모델과 뷰사이의 연결을 담당하는 코드를 작성해야 하겠지만요. (e.g. ContentProvider , LabelProvider) JFace는 UI의 얼개에 해당하므로 SWT 역시 함께 사용해야 합니다. 

아주 오랜만에 이클립스 플러그인에 관한 글을 다시 적게 되었습니다. 연구실에 남아있을 마지막 2주일 동안 그 동안 못다뤘던 부분들을 정리하려 합니다. 오늘은 마법사에 대해서 다루겠습니다. 마법사(Wizard)가 무엇인지는 각종 개발툴을 써보셨다면 이미 잘 알고계실 것 같습니다.  VICODE 사용자 메뉴얼을 존대말로 쓰다보니 탄력받아(?) 존대말로 쓰게 되었네요.

마법사는 여러 페이지로 구성되어 있습니다. 각 페이지는 프로젝트를 생성하는 등의 작업을 위한 일련의 단계를 표현합니다. 그리고 각 페이지는 자신에게 필요한 정보가 입력되었는지를 판단하여 마법사에게 알립니다. 마법사는 페이지의 상태에 따라 다음 페이지로의 이동가능 여부를 판단하여 UI에 반영하는 것이죠. 모든 페이지가 완료 상태에 도달하면 Finish 버튼이 활성화 되어 마법사를 종료할 수 있습니다. Finish 버튼이 클릭되면 마법사는 각 페이지에서 받은 정보를 바탕으로 원하는 작업을 수행하게 됩니다.

코드레벨에서 살펴보면 마법사는 마법사 클래스각 페이지에 해당하는 클래스의 집합으로 구성됩니다. 마법사 클래스는 페이지 클래스를 참조하고 있고  addpages() 함수에서 페이지 클래스를 마법사에 등록합니다.

지금부터는 코드를 가지고 상세구현 과정을 살펴보도록 하겠습니다. 이클립스 플러그인의 시작은 확장점입니다. 마법사를 추가할 수 있는 확장점은 총 3가지가 있는데, 이 글에서는 프로젝트 생성 마법사를 추가하는데 사용되는 org.eclipse.ui.newWizards를 사용하겠습니다. 다음코드는 확장을 정의한 plugin.xml 코드의 일부분입니다.

   <!-- new project wizard -->
   <extension
         point="org.eclipse.ui.newWizards">
      <category
            id="kr.ac.kaist.vicode"
            name="VICODE"/>

      <wizard
            canFinishEarly="false"
            category="kr.ac.kaist.vicode"
            class="kr.ac.kaist.vicode.wizard.NewProjectWizard"
            finalPerspective="kr.ac.kaist.vicode.perspective"
            hasPages="true"
            icon="icons/esterel_image.gif"
            id="kr.ac.kaist.vicode.newprojectwizard"
            name="VICODE Project"
            preferredPerspectives="kr.ac.kaist.vicode.perspective"
            project="true"/>
   </extension>

마법사 확장점에는 여러가지 속성이 있습니다. Perspective 관련 속성에는 VICODE perspective의 id를 정의하였습니다. canFinishEarly는 모든 페이지를 다 거치지 않아도 완료할 수 있는 마법사인지를 정의합니다. hasPages는 여러 페이지를 가진 마법사인지를 정의합니다. 예제로 보여드릴 VICODE 프로젝트 생성 마법사는 2페이지로 구성되어 있고 모든 페이지를 거쳐야 하므로 위의 코드와 같이 정의하였습니다.

먼저 마법사 클래스(NewProjectWizard)를 살펴보도록 하겠습니다.

public class NewProjectWizard extends Wizard implements INewWizard
{
 private WizardNewProjectCreationPage mainPage;
 private WizardInitialPage initialPage;

 private IProject newProject;

 public boolean performFinish()
 {
  createNewProject();
  initialPage.finish(newProject);
  return true;
 }

 public void addPages()
 {
  mainPage = new WizardNewProjectCreationPage("New VICODE Project (1/2)");
  mainPage.setDescription("Create a new VICODE project in the workspace");
  mainPage.setTitle("Create VICODE Project");
  initialPage = new WizardInitialPage("New VICODE Project (2/2)");
  initialPage.setDescription("You can specify top module name and communication event.");
  initialPage.setTitle("Module declaration for hardware and Communication Event");
  addPage(mainPage);
  addPage(initialPage);

 }

프로젝트 마법사 클래스는 Wizard 클래스와 INewWizard 인터페이스를 상속합니다. 예제 마법사의 목표는 두 페이지에 걸쳐 정보를 받아 들인 후 프로젝트를 생성하는 것 입니다. 총 2페이지로 구성되어 있는데, 첫번째 페이지는 구현하지 않고 이미 작성된 프로젝트 생성 페이지를 가져다가 사용하였습니다. 이 페이지는 단순히 프로젝트 이름과 저장위치를 지정할 수 있도록 구성되어 있습니다. 두 번째 페이지는 VICODE 프로젝트를 생성하는데 있어 필요한 정보를 입력받기 위해 직접 구현한 페이지입니다.

addPages() 메서드에서는 각 페이지의 인스턴스를 생성하고 초기화한 후에 addPage() 메서드를 호출하여 마법사에 각 페이지를 등록합니다. Finish 버튼이 클릭되면 호출되는 performFinish() 메서드에서 마법사 완료시에 필요한 일들을 기술합니다. 실제 프로젝트가 생성되는 코드는 첨부파일을 참조하시기 바랍니다.

01

지금부터는 두번째 페이지에 해당하는 코드를 살펴 보겠습니다.

public class WizardInitialPage extends WizardPage
{
 public void createControl(Composite parent)
 {
  Composite composite = new Composite(parent, SWT.NONE);
  GridLayout gridLayout = new GridLayout();
  gridLayout.numColumns = 1;
  composite.setLayout(gridLayout);
  createModuleNameGroup(composite);
  createCommunicationGroup(composite);
  setControl(composite);

  updatePageComplete();
  setMessage(null);
  setErrorMessage(null);

 }
 private void updatePageComplete()
 {
  setPageComplete(false);
  // 페이지의 완결성 체크
  if (moduleNameText.getText().equals(""))
   return;
  // 페이지의 완결성 체크를 건너 뛰었다면 페이지를 완료상태로 변경
  setPageComplete(true);
  setMessage(null);
  setErrorMessage(null);

 }

마법사의 모든 페이지 클래스는 WizardPage 클래스를 상속합니다. UI를 정의하는 다른 클래스와 마찬가지로 createControll() 메서드에서 SWT로 사용자 인터페이스를 작성합니다. 마지막에 호출되는 메서드인 updatePageComplete()는 페이지에 필요한 정보가 입력되어 있는지를 판단하기 위해 제가 작성한 메서드 입니다. 이 메서드는 각 컨트롤에서 값이 변경될때마다 호출되어 페이지가 완료상태인지를 setPageComplete() 메서드를 호출하여 마법사에 알립니다.

이상으로 이클립스 플랫폼에서 마법사를 구현하는 방법에 대해서 말씀드렸습니다. 아래 첨부한 소스코드를 참조하시면 이해하시는데 도움이 될 것 같습니다.


사용자 삽입 이미지

요즘 내가 하고 있는 일은 유종의 미를 거두고 원할한 인수인계를 위해 내가 개발한 VICODE의 사용자, 개발자 메뉴얼을 작성하는 것이다. 간단한 예제에 대하여 개발하는 과정을 직접 따라가며 메뉴얼을 작성하던 중 사진 아래에 보이는 임베디드 보드를 활용하여 실제로 시스템을 구현하는 단계에 이르렀다.

VICODE의 핵심기능 중 하나는 임베디드 리눅스에서 돌아가는 소프트웨어와 임베드드 보드에 붙어 있는 FPGA의 하드웨어간의 인터페이스를 자동으로 생성하는 것이다. 하드웨어와 소프트웨어 사이의 연결통로를 자동으로 생성해주어 소프트웨어는 라이브러리를 사용하듯 API를 호출하여 하드웨어와 통신할 수 있도록 하는 것이다.

원하는 시나리오는 다음과 같다. 소프트웨어가 A()라는 함수를 호출하고 B()라는 함수를 호출하면 LED 1번에 찬란하게 빛이 들어와야 한다. 그러나 결과는 깜깜 무소식! 순간 내 머리속을 스치는 단어는 "리콜". (석사학위논문은 지도교수가 6개월안에 취소할 수 있는데 우리는 이를 흔히 "리콜"이라고 부른다.) 순간 마음이 분주해졌다. 소프트웨어 버그였다면 비교적 금방 찾겠지만 소프트웨어와 하드웨어사이의 통신은 몇 단계를 거치기 때문에 무엇이 문제인지 찾기 힘들다. 결국 묵혀둔 연구노트를 펼쳐 원인을 발견하고 문제해결에 성공. 희망의 LED가 찬란하게 빛났다.

아직 연구실에서 해야할 일이 많지만 내가 원해서 하는 일이기에 즐겁게 하고 있다. VICODE를 이어서 개발하게 될 재호형이나 올해 연구실에 들어올 석사신입생들의 시행착오를 조금이라도 줄여줄 수 있다고 생각하니 뿌듯한 마음이 든다. 떠나는 뒷모습이 아름답도록(?) 남은 기간 내게 주어진 일들을 즐겁게 매듭짓자!

+ Recent posts