지난회에서 우리는 소프트웨어 공학에 대하여 알아보았고, 그것을 토대로 WEBDOC_C에 대하여 대략적으로 알아보았다. 지난 호에 이어서 이번호에서는 WEBDOC_C의 생성기가 어떻게 이루어졌으면 어떤 역할을 하는지 알아보자.
--------------------------------------------------
연재순서
1회 2002. 3 : WEBDOC_C 분석기 설계와 구현(1)
2회 2002. 4: WEBDOC_C 생성기 설계와 구현(2)
연재 가이드 라인
운영체제 : 레드햇 리눅스 6.0 이상
개발도구 : jdk 1.2.1, gcc 2.96 이상권장
기초지식 : C와 자바에 대한 기본개념
응용분야 : 다른 프로그램 언어 분석능력 향상
박종민 bicman3@chollian.net
울산대학교 정보통신원 정보기획팀에 근무하고 있다. 2001년 대한민국 소프트웨어 공모대전 리눅스 부문 동상을 수상했으며, ‘2001 인터내셔널 IBM 리눅스 스콜라 챌린지’에서 한국인으로는 유일하게 수상했다. 리눅스 커널 및 POSIX 기반의 시스템 프로그래밍에 관심이 많다.
-----------------------------------------------
WEBDOC_C 생성기
WEBDOC_C는 지난호에서 소개한 분석기를 통하여 소스코드를 분석한 결과가 저장되어 있는 데이터베이스로부터 정보를 가져와서 사용자의 요청에 의해 함수호출관계 구조도나 전역변수 호출관계 구조도 및 소스코드를 보여주는 역할을 한다. 아래의 <그림 1>은 WEBDOC_C의 화면이다.
<그림 1> WEBDOC_C 전체적인 화면
왼쪽 상단의 리스트는 함수리스트인데 원시코드의 함수들에 대한 정보를 보여준다. 이 부분을 클릭하면 그 함수로부터 파생된 함수, 즉 그 함수가 호출한 함수의 구조를 보여준다. 그 밑의 전역변수 리스트도 마찬가지로 사용자가 전역변수를 클릭하면 그 전역변수를 사용한 함수들에 대한 정보를 오른쪽 캔버스에 보여주게 된다. 전역변수 리스트 밑에는 구조도와 소스라는 라디오버튼이 있는데 구조도를 선택하면 오른쪽 캔버스에 구조도로 나타나서 함수호출관계를 구조도로 보여주게 되고, 소스를 선택하면 오른쪽 구조도에 소스코드가 나타나서 선택한 함수나 전역변수의 위치에 빨간색으로 표시된다.
WEBDOC_C 생성기의 구조
WEBDOC_C 생성기는 4개의 자바 서블릿 (Java Servlet)파일과 1개의 자바 애플릿 (Java Applet) 파일로 구성되어 있다. 자바 서블릿 파일들은 지난번에 소개한 8개의 테이블로 구성되어 있는 테이블에서 필요한 정보를 추출한다.
<그림 2> WEBDOC_C 생성기의 구조
<그림 2>에서와 같이 WEBDOC_C의 4개의 서블릿 파일들은 각각 다른 역할을 한다. WEBDOC_C에서는 서블릿과 애플릿간 HTTP 통신을 이용하여 정보를 주고받는데, 이것은 지난호에서 소개했듯이 자바 애플릿의 보안모델이 ‘샌드박스(SandBox)’ 모델이기 때문인데, 이것은 애플릿은 잘 실행되지만, 클라이언트로의 자원접근은 강력하게 차단되어 있다. 자바 애플릿에서 직접 데이터베이스로 접근하는 것은 어렵기 때문에 자바 서블릿을 사용해 데이터베이스로 접근하고, 원하는 정보를 추출한다. 아래의 <표 1>은 각각의 서블릿 파일 및 애플릿 파일의 기능을 설명하고 있다.
파 일 명
기 능
dbCflow.class
함수의 구조를 보여주는 cflow테이블에서 값을 참조하여 함수호출구조도 값을 넘겨준다.
dbConnect.class
함수이름 및 함수의 정보들을 넘겨준다.
dbValue.class
전역변수 이름 및 전역변수의 정보를 넘겨준다.
dbDrawValue.class
전역변수 호출 구조를 넘겨준다.
project.class
메인 애플릿 클래스로서 서블릿 파일들과 HTTP기반 통신으로 자료를 받아서 캔버스에
호출관계 구조를 보여준다.
<그림 3> WEBDOC_C 순서도
<그림 3>은 WEBDOC_C의 순서도이다. 사용자는 초기 인증과정을 통과하면 기존의 프로젝트를 볼 수 있으며, 만약 프로젝트가 없거나 새로운 프로젝트를 만들고 싶을 때는 프로젝트 업로드를 눌러서 새로운 프로젝트를 생성하면 된다. 일단 생성된 프로젝트나 기존의 프로젝트에는 만약 소스코드가 있을 경우 표시가 되며, 소스코드가 없을 때에는 사용자에게 소스코드를 업로드 해달라는 버튼이 표시된다. 소스코드가 있을 경우에 제목을 클릭 했을 때 분석화면으로 넘어가서 분석되어 있는 기존의 소스코드를 보여주게 된다. 소스코드 업로드시 만약 소스코드가 잘 못 되었으면 다시 소스코드 리스트를 보여주는 화면으로 넘어가고, 업로드가 성공하고 분석도 성공했으면, 바로 프로젝트 화면으로 넘어가게 된다.
try {
Class.forName("gwe.sql.gweMysqlDriver");
String url="jdbc:mysql://localhost:3306/project";
con=DriverManager.getConnection(url,"root","passwd"); //DB 접근요청
stmt = con.createStatement();
rs = stmt.executeQuery("Select a.fun_name from func a, file b where a.file_no = b.file_no and b.file_name = '" + fn + "' order by fun_name"); //함수이름을 참조하여 넘겨준다.
while(rs.next())
{
outer.println(rs.getString(1)); //그냥 함수 이름만 찍어준다.
//즉 함수이름만 애플릿으로 넘긴다.
}
}
..................
이하생략
---------------------------------------------------------------------------------------------
앞의 두 소스는 생성기의 핵심인 dbCflow와 dbConnect의 소스이다. 두 소스는 매우 유사하며, 데이터베이스로 질의하는 부분만 다르고 똑같다. 일반적으로 서블릿에서 데이터베이스에 접근하는 방식으로 택하고 있으며, 애플릿으로 값을 넘겨주기 위한 작업은 특별히 하지 않는다. 즉 데이터베이스에서 가져온 값들을 그냥 웹 브라우져로 뿌려주는 outer.println(rs.getString(..))이러한 함수를 써서 HTTP를 통해 정보를 보내게 되면 애플릿에서 이것을 받아 해시테이블에 저장하여 정보를 가공하여 보여준다. 아래의 코드들은 서블릿에서 보내온 정보를 받아서 가공하는 proejct.java 소스의 일부이다. 소스의 양이 많아서 한꺼번에 소개하기 힘들어서 나눠서 살펴보자.
---------------------------------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////////
/// 작성기관 : 울산대학교 컴정학부 OOSE-LAB ////
/// 파일명 : Project.java ////
/// 경로명 : /var/www/html/common/outputwork /////
/// /Project.class /////
/// 작성일 : 2001년 4월 30일 /////
/// 작성자 : 박종민 /////
/// 지도교수 : 이명재 ////
/// 사용목적 : 생성기 메인 애플릿 소스 ////
//////////////////////////////////////////////////////////////////////////////
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
import java.io.*;
import java.net.URL; //HTTP기반 통신을 위해
import com.oreilly.servlet.HttpMessage; //서블릿과 애플릿 통신을 위해
import java.util.StringTokenizer;
import java.util.Properties;
import java.util.Hashtable;
import java.lang.*;
import java.net.*;
...... 생략
//서블릿에서 함수의 값을 전달받는 메소드, dbConnect.class와 연동하는 부분이다.
private void getFuncUsingHttpText() {
try {
//아래의 서블릿 경로에서 함수값들을 http header에 넣어서 전달받는다.
URL url = new URL(getCodeBase(),"/examples/servlet/dbConnect" + "?filename=" + parameter);
HttpMessage msg = new HttpMessage(url); //자료를 넘겨받기 위한 msg 객체 생성
InputStream in = msg.sendGetMessage(); // 스트림 형태로 전달받는다.
DataInputStream result = new DataInputStream(new BufferedInputStream(in));
String func;
while((func= result.readLine()) != null) {
funlist.add(func); //함수부분에 뿌려준다.
}
in.close(); //객체를 닫아준다.
}
catch (Exception e) {
e.printStackTrace();
}
}
//구조도를 그리기 위해 서블릿에서 값을 전달받는 메소드
private void getCflowUsingHttpText() {
try {
URL url = new URL(getCodeBase(),"/examples/servlet/dbCflow" + "?filename="
+ parameter); //이부분에서 filename 부분을 파라미터 값으로 받는다.
HttpMessage msg = new HttpMessage(url);
InputStream in = msg.sendGetMessage();
DataInputStream result = new DataInputStream(new BufferedInputStream(in));
String str2;
Records = new Hashtable[3];
//token을 써서 각각 넘어오는 값들을 짤라준다. (공백이 구분자)
while((str2= result.readLine()) != null) {
StringTokenizer tokens = new StringTokenizer(str2);
//토큰으로 짜른다.
String strtmp = null;
while(tokens.hasMoreTokens()) {
index++;
for (int i=0; i< 3; i++) {
if (index ==1) {
Records[i] = new Hashtable();
//해쉬테이블에 넣어준다.
}
}
for (int k=0; k <3; k++) {
strtmp = tokens.nextToken();
Records[k].put(new Integer(index),strtmp);
}
}
max = index;
}
in.close();
}
catch (Exception k) {
k.printStackTrace();
max = -1;
}
}
--------------------------------------------------------------------------------------------
위의 소스는 서블릿 파일로부터 정보를 전달받아서 해쉬테이블에 저장하거나 함수이름 같은 것을 리스트박스에 등록시켜주는 메소드이다.
이렇게 전달받은 정보를 바탕으로 project 애플릿은 사용자의 요구에 따라 함수호출관계 구조도나 전역변수 호출관계 구조도를 그리기 위한 작업을 시작하게 된다. 위의 소스를 살펴보면 함수부분만 나타나는데, 전역변수 부분도 유사하다. 아래의 소스는 실제로 구조도가 작성되는 부분이다.
--------------------------------------------------------------------------------------------
......전략
public void tree_process() {
int count = 0;
int level2_count = 0;
int level3_count = 0;
int cnt = 0;
// 다시 간추려서 겹치는 것을 찾아내는 루틴
int tmp_cnt = 0;
int no_db = 0;
boolean flag_input = false;
for (int k = 0; k < level3_count; k++) {
String level3_tmp = (String)my.Level3_Draw.get(new Integer(k));
for (int r = 0; r < level3_count; r++) {
String xtmp = (String)my.Level3_Draw.get(new Integer(r));
if (level3_tmp.compareTo(xtmp) == 0) {
tmp_cnt += 1;
}
}
if (tmp_cnt >= 2) { //여기서 겹치는 level3의 함수를 축출해 낸다.
if (no_db == 0) {
test2.put(new Integer(no_db),level3_tmp);
no_db += 1;
}
else if (no_db > 0) {
for (int f = 0; f < no_db; f ++) {
eqstr = (String)my.Level3_Result.get(new Integer(f));
if (level3_tmp.compareTo(eqstr) == 0) {
flag_input = false;
break;
}
else if (level3_tmp.compareTo(eqstr) != 0){
flag_input = true;
} //else if
} //for
if (my.func_flag == true && my.stview_flag==false && my.value_flag ==false && my.srcview_flag == true) {
String func_line;
for (int j = 1; j <= file_max; j++) {
func_line = new Integer(j) + " : " + (String)fileRecords.get(new Integer(j)); //일단 넣어준다.
my.Src_Record.put(new Integer(j-1), func_line);
}
my.file_max = file_max;
}
my.draw();
}
.......
---------------------------------------------------------------------------------------------
소스가 다소 복잡하지만 자세히 살펴보면 해시테이블을 이용하여 호출한 함수와 호출된 함수의 관계를 나타낸다는 것을 알아볼 수 있다. 서블릿 파일로부터 정보를 전달받아서 해시테이블에 데이터베이스 구조와 유사하게 저장한다. 즉, 깊이, 호출한 함수, 호출된 함수 순으로 저장을 한 후, 그것을 토대로 가공을 하게 된다. 그 다음에는 레벨(Level) 1일 때 처리, 레벨 2일 때 처리 등 레벨별로 처리를 한 후 캔버스에 그림을 그리게 된다.
전역변수도 좀 더 쉬운 방법으로 처리할 수 있는데, 그 전역변수를 호출한 함수이름만 찾으면 되기 때문이다.
2개의 라디오 버튼중에 소스코드를 선택한 후 함수리스트나, 전역변수리스트 중 하나를 선택하면 오른쪽 캔버스에는 소스코드가 나오며, 선택한 함수나 전역변수가 빨간색으로 표시된다.
=======================================박스=============================
대표적인 소프트웨어 공학제품들
1) Soft4Soft (http://www.soft4soft.com/)
(주)소프트4소프트는 ETRI(한국전자통신연구원) 벤처 창업 기업으로서, 국내 최초로 개발한 역공학/재공학 기술의 연구 결과를 이용하여 소프트웨어 및 데이타베이스의 역공학/재공학/테스팅/품질관리/컴포넌트 추출 도구 등 S/W 관리 기술의 신제품을 연구개발하는 기술집약형 벤처기업이다.
(주)소프트4소프트는 기존의 소프트웨어 관리 또는 소프트웨어 개발 시, Software Metric 기반에서 소프트웨어의 분석 및 유지 보수 등에 필요한 역공학 기술, 소프트웨어의 재사용과 현대화 등에 필요한 재공학 기술, 그리고 소프트웨어의 시험 평가와 검증에 필요한 테스팅과 품질 관리 기술 등의 통합적인 소프트웨어 관리 도구인 재공학 소프트웨어 기술(RESORT, Re-Engineering Software Technology)를 개발하고 있다.
Soft4Soft가 개발하고 있는 제품의 용도는 아래와 같다.
맞춤형 S/W 관리 도구의 기술을 이용하여 자체 시험/품질 시스템 구축
소프트웨어 품질 향상 및 비용 절감(개발 비용/ 유지 보수 비용)
S/W 개발 기간 단축 및 표준화
프로젝트 관리의 효율성 증대
높은 재사용성 및 문서화 용이성 제공
2) Software Blacksmiths (http://www.swbs.com)
CDOC를 개발한 회사이다. 본 프로젝트인 WEBDOC_C를 개발하는데 제일 많이 참조하였다.
SWBS의 제품은 C/C++ 코드를 전문적으로 분석하여 여러 가지 형태로 그 결과치를 내 놓는데 그것을 살펴보면
HTML, TXT, RTF 등 텍스트 기반이다. 최근의 제품은 자바로 만들어져, 플랫폼 독립적으로 쓰일 수 있다.
따라서 구동환경을 보면 Windows 95/98/NT 기반, Linux, Sun Solaris 및 DOS기반에서도 잘 돌아간다.
SWBS의 제품은 아래와 같다
CLIST action-diagram 리스트나 혹은 소스코드를 다시 포맷해서 보여준다.
CCALL 트리구조로 함수 호출관계를 보여준다.
CCMT 각각의 함수에 대한 주석을 달아준다. 즉 호출한 함수와 호출된 함수를 표시해 준다.
CREF 함수간의 교차참조에 대한 것을 알려준다. C++이나 JAVA의 클래스 구조도나 트리 구조를 보여준다.
CMETRIC 코드 복잡도 및 코드 카운터에 대한 정보를 보여준다..
JavTREE 자바 기반의 CCALL이다. 최근작품이다.
3) Tall Tree Software Company (http://www.tall-tree.com/)
Tall Tree Software는 DocJet라는 작품이 대표적이다. 이 프로그램은 C 및 C++, JAVA, Visual Basic, DELPHI 에 대한 문서화를 시키는데 사용되는 도구이다. 같은회사 제품인 AltHelp와 같이 사용하면 비쥬얼 스튜디오에 플러그인 하여 여러 가지 포맷으로 분석결과를 나타낼 수 있다.
=========================================================================================
마치면서
지금까지 역공학과 UML 및 웹 프로그래밍기법을 사용한 웹 기반의 C 원시 코드 문서화 도구(WEBDOC_C) 의 설계 및 구현에 대해 살펴보았다.
이 도구의 개발을 위해 현재 전 세계적인 표준인 UML을 사용하여 시스템의 외부 행위와 전체적인 사용 흐름을 설계하였으며, 구현 방법으로는 다양한 웹 프로그래밍 기술을 사용하여 기존의 소프트웨어 공학 응용프로그램들과의 결합을 시도하였다. 앞으로 웹 기반의 기술이 지속적으로 발전할 것으로 예상되어, 웹 Metrics와 웹 유지보수(Web Maintenance) 기술을 포함한 웹 분석 (Web Analysis)을 연구할 계획이다.
참고자료
[1] Randy Jay Yarger, George Reese & Tim King, My SQL & mSQL, O'Reilly and
Associates, 2000
[2] Chikofsky E.,Cross J., Reverse Engineering and Design Recovery: A Taxonomy,
IEEE software, Vol 7. No.1, Jan. 1990
[3] Ian Sommerville, Software Engineering, Fifth Edition, Addsion-Wesley 1998.
[4] SoftWare BlackSmiths Home Pages, CDOC Documentation Tool for C, C++ and Java,
http://www.swbs.com
[5] Tall Tree Software Company Home Pages, DocJet Soruce Code Documentation
System, http://www.tall-tree.com/
[6] Imagix Corporation Home Pages, Imagix 4D-reverse engineering and software
documentation tool, http://www.imagix.com/
[7] Tzerpos V.,Farmaner H.G, Web-Based Presentation of Hierarchic Software
Architecture, Proc. Workshop on Software Engineering (on) the World Wide Web,
Boston, May,19,1997