달력

5

« 2024/5 »

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

자바 프레임웍에서 Ajax 애플리케이션 구현을 위한 Google Web Toolkit





난이도 : 중급

Noel Rappin, Senior Software Engineer, Motorola, Inc.

2007 년 2 월 06 일

Google Web Toolkit (GWT)은 동적 Java™Script의 생성에 혁신을 가져왔습니다. GWT를 사용하면, 개발자들은 익숙한 자바 기술을 사용하여 사용자 인터페이스(UI)와 이벤트 모델을 디자인하고 대다수의 브라우저에 익숙한 코드를 만드는 일을 하게 됩니다. 이 글을 통해, GWT의 기초를 설명하고, GWT에서 Asynchronous JavaScript + XML (Ajax) 애플리케이션을 만드는 방법과, 자바 언어로 코드를 작성하는 방법을 설명합니다. 또한 온라인에서 피자를 판매하는 Slicr라고 하는 Web 2.0 비즈니스 샘플을 가지고, GWT 애플리케이션을 생성 및 실행하는 방법을 설명합니다.

GWT를 사용하여, 전통적인 자바 GUI 인터페이스를 구현하는 것 보다 훨씬 더 쉽게, 더욱 풍부한 Ajax 브라우저 클라이언트 인터페이스를 구현할 수 있다. GWT가 매우 놀랍기는 하지만, 전체 웹 애플리케이션을 이것 하나로 만들 수는 없다. 서버에 데이터 스토어가 있어야 하고, 데이터를 자바 객체로 변환하여, GWT가 서버에서 클라이언트로 전달할 수 있도록 하는 프레임웍이 있어야 한다. 본 기술자료 시리즈에서, 100% 순수 자바 데이터베이스인 Apache Derby를 사용하는 방법을 설명한다.

이 글에서는 GWT에 대한 중점적인 설명과 더불어, GWT를 설정하는 방법과 사용자 액션에 반응하는 간단한 클라이언트 인터페이스를 구현하는 방법을 설명한다. 후속 기술자료에서는 Derby 데이터베이스를 설치하고, GWT 프론트엔드를 Derby 기반 백엔드에 연결하는 방법을 설명한다. 마지막으로, 개발 환경 밖에서 시스템을 전개하는 방법도 배운다.

Ajax 리소스 센터에서는 Ajax 프로그래밍 모델과 관련한 기술자료, 튜토리얼, 포럼, 블로그, wiki, 이벤트, 뉴스 등이 제공된다.

Google Web Toolkit이란 무엇인가?

GWT를 사용하여, 자바 프로그래밍 언어로 Ajax 애플리케이션을 개발할 수 있다. Ajax 애플리케이션의 장점은 전통적인 UI 애플리케이션과 연결되는 풍부한 인터랙티브 환경일 것이다. 그림 1은 샘플 GWT 인터페이스로서 데스크탑 이메일 애플리케이션이다. 이 데모는 GWT 웹 사이트에서 볼 수 있다.


그림 1. GWT 이메일 데모
A GWT e-mail demonstration

GWT의 가장 고유한 기능은 Ajax 애플리케이션을 만들 수 있고, 자바 언어로 코드를 작성할 수 있다는 점이다. 선호하는 자바 통합 개발 환경(IDE)을 사용하여, 클라이언트를 디버깅 할 수도 있다. 자바 객체를 사용하여 클라이언트와 서버간 통신도 가능하고, 모든 것이 자바 애플릿 보다 가볍다.

GWT는 기본적으로 컴파일러이다. GWT는 자바 코드를 HTML 페이지에 삽입되어 실행될 수 있는 JavaScript 코드로 변환하여 클라이언트 측 애플리케이션을 실행하는데 사용된다. JavaScript 코드는 거의 모든 브라우저에서 지원되므로 여러분은 프로그램의 인터페이스와 인터랙션에 집중할 수 있다.

물론, GWT가 컴파일러일 뿐이라면, 거론하지 않았을 것이다. 다행히도, 그 이상의 기능을 한다. GWT는 컴파일러 메커니즘 뿐 만 아니라, 아래와 같은 부가적인 특징이 있다.

  • 표준 UI 위젯은 유연하고, 거의 모든 주요 브라우저에서 실행된다. (Safari와 Opera 포함)
  • 클라이언트 측의 이벤트를 포착하고 응답하는 이벤트 메커니즘.
  • 웹 애플리케이션과 서버 간 비동기식 호출을 관리하는 프레임웍.
  • Ajax 애플리케이션이 예상 Back 버튼 작동에 관여하지 않도록 하는, STATEFUL 브라우저 히스토리를 만드는 메커니즘.
  • JUnit을 사용하여 클라이언트 애플리케이션용 단위 테스트를 작성하는 테스트 프레임웍.

본 시리즈에서는 이러한 기능들을 설명할 것이다. 하지만 먼저, GWT를 다운로드 및 설치해야 한다.

GWT 설치하기

이 글을 쓰고 있는 현재, GWT 최신 버전은 1.2이다. (참고자료) GWT는 Microsoft® Windows® XP, Windows 2000, Linux® 그리고, Mac OS X에서 실행되는 GTK+ 2.2.1 또는 그 이후 버전에서 완벽히 지원된다.

다운로드 한 압축 파일을 원하는 디렉토리에 압축을 푼다. 버전들마다 약간 다르지만, 기본 엘리먼트는 다음과 같다.

  • 세 개의 .jar 파일: gwt-user.jar 에는 프로젝트 classpath에 필요한 사용자 클래스들이 포함되어 있다. gwt-dev-windows.jar 또는 gwt-dev-linux.jar에는 컴파일러 코드가 포함되어 있다. 세 번째 파일, gwt-servlet.jar는 전개(deploy)에 사용된다.
  • 세 개의 명령행 유틸리티: applicationCreator, junitCreator, projectCreator. (Windows에서는, .cmd가 붙는다.)
  • 샘플 코드 디렉토리

GWT를 사용할 때, 일부 파일들은 임시 파일들을 관리하기 위해 GWT 홈 디렉토리에 놓인다.

프로젝트 만들기

다운로드를 마치면, 가장 먼저 프로젝트를 만들어야 한다. 온라인에서 피자를 파는, Slicr라고 하는 새로운 Web 2.0 비즈니스의 온라인 사이트를 구축할 것이다. GWT 프로젝트를 설정하는 방법들은 IDE를 사용할 것인지의 여부에 따라 다르다. 여기에서는 GWT 명령행 유틸리티의 지원도 받는 무료 Eclipse를 사용하도록 하자.

명령행 유틸리티를 사용하여 Eclipse 프로젝트를 만든다.

  1. 하드 드라이브의 적당한 곳에 slicr라고 하는 새로운 디렉토리를 만든다.
  2. 새로운 slicr 디렉토리에 명령어 프롬프트를 연다.
  3. 다음 명령어를 입력한다. (슬래시와 그 외 것들을 각자 운영 체계에 맞게 변환한다.)

<GWT_HOME>/projectCreator -eclipse slicr

이 명령어로는 GWT 프로젝트에 필요한 최소한의 것만 만든다. 새로운 src 하위 디렉토리와 새로운 .project와 .classpath 파일이 생겼다.

지금 바로 프로젝트로 시작할 수 있지만, GWT는 그 이상의 구조를 기대한다. 다음 명령어를 사용하여 설정할 수 있다.


<GWT_HOME>/applicationCreator -eclipse slicr com.ibm.examples.client.Slicr

-eclipse slicr 인자는 Eclipse 프로젝트의 이름이고, projectCreator에서 사용했던 것과 같아야 한다. (그렇지 않으면, Eclipse 내에서 GWT 애플리케이션을 시작하는데 문제가 생긴다.) 마지막 인자는 애플리케이션의 메인 클래스가 될 클래스 풀네임(fullname)이다. 이때, 패키지명의 마지막은 의미상 client로 정하기로 하고, client 이전의 부모 패키지 이름은 여러분이 알아서 작성하도록 한다. (일단, 'com.ibm.examples'로 부모 패키지 이름을 정하였다.)

이 명령어는 몇 가지 파일을 생성한다. .java 파일은 메인 클래스이고, 해당 클래스에 동반된 패키지 명에 부합되게 부모 디렉토리 들이 생성된다. 여러분은 최하위 디렉토리에는 clientpublic이 생성되어 있는 것을 확인 할 수 있다. 앞에서 거론한 public 디렉토리에는 Slicr.html와 Slicr.gwt.xml을 확인 할 수 있다. 또한, GWT는 eclipse가 사용하게 될 Slicr.launch파일과 두 개의 셀 스크립트 파일을 생성 한다.




위로


Eclipse로 옮기기

이제 프로젝트를 Eclipse로 옮긴다.

  1. Eclipse를 열고, File > Import를 클릭한다.
  2. 새로운 창에서, General 트리를 확장하여 Existing Projects into Workspace를 선택한다.
  3. Next를 클릭한 다음 Browse를 클릭하여 slicr 루트 디렉토리를 선택한다.
  4. 프로젝트를 선택하고, Copy projects into workspace 옵션이 설정되지 않도록 한다. (프로젝트를 옮기지 않을 것이기 때문이다.)

이 프로세스를 통해, 코드를 Eclipse로 옮겨서 볼 수 있다. GWT는 세 개의 중요한 파일들을 만들었다. 첫 번째가 com.ibm.examples 패키지에 있는 slicr.gwt.xml 파일이다. Listing 1은 XML 설정 파일이다.


Listing 1. slicr.gwt.xml
				
<module>
    <inherits name='com.google.gwt.user.User'/>
    <entry-point class='com.ibm.examples.client.Slicr'/>
</module>

여기에서 GWT 애플리케이션에 대한 모듈을 정의할 수 있다. 모듈(module)은 GWT 코드의 기본 단위이고, 클라이언트가 사용하는 HTML 페이지가 참조한다.

두 번째 파일은 퍼블릭 디렉토리에서 만들어진 Slicr.html 파일이다. 이것은 웹 애플리케이션의 프론트 페이지로서 클라이언트로 보내지는 .html 파일이다. 실제로 필요하지 않는 많은 코멘트들이 들어있다. Listing 2는 파일의 핵심 부분이다.


Listing 2. Slicr.html
				
<html>
    <head>
        <title>Wrapper HTML for Slicr</title>
        <meta name='gwt:module' 
            content='com.ibm.examples.Slicr'>
    </head>
    <body>
        <script language="javascript" 
            src="gwt.js"></script>
        <iframe id="__gwt_historyFrame" 
            style="width:0;height:0;border:0"></iframe>
        <h1>Slicr</h1>
        <p>
            This is an example of a host page for 
            the Slicr application. 
        </p>
        <table align=center>
            <tr>
                <td id="slot1"></td>
                <td id="slot2"></td>
            </tr>
        </table>
    </body>
</html>

가장 중요한 것은 바로 위의 .html 파일이다. 원하는 어떤 HTML이라도 추가할 수 있다. 가장 중요한 것은 HTML 파일에 원하는 어떤 내용이라도 추가 및 변형 할 수 있다는 것이다. 단지, GWT는 아래 네 가지 엘리먼트에 의해서 실행된다.

  • meta 태그: name 애트리뷰트와 content 애트리뷰트는 모듈의 완전한 형식을 갖춘 논리적 이름이다. (XML 모듈 파일과, 확장자 없는 XML의 파일 이름을 포함하고 있는 패키지이다.) 이 태그는 HTML 페이지를 특정 모듈로 연결시킨다. 페이지를 호출하면 모듈이 시작된다. (특히, 모듈에 있는 모든 엔트리 포인트들이 초기화 된다.)
  • script 태그: 이 태그는, GWT 자바 코드를 JavaScript 코드로 변환할 때 생성된 파일 중 하나인 gwt.js라고 하는 파일을 로딩한다. 이 파일은 모든 클라이언트 코드의 로딩을 제어하기 때문에, 프로그램을 실행하는 것 보다 이를 포함시키는 것이 더 중요하다.
  • iframe 태그: 이 태그를 쓰여진 대로 정확히 사용하면 웹 애플리케이션은 히스토리와 상태를 기억할 수 있다. GWT 애플리케이션에서 Back 버튼을 실행 불가로 만들 필요가 없다.
  • td 태그: 특정 .html 파일에 있는 이 태그에는 JavaScript 식별자들이 포함된다. 특별한 것은 없지만, GWT는 이 식별자를 엘리먼트를 배치할 장소로서 사용한다.

자바 시작 클래스

GWT는 재사용이 가능한(boilerplate) 자바 시작 클래스도 Listing 3과 같이 만든다.


Listing 3. 자바 시작 클래스
				
public class Slicr implements EntryPoint {

  public void onModuleLoad() {
    final Button button = new Button("Click me");
    final Label label = new Label();
    button.addClickListener(new ClickListener() {
      public void onClick(Widget sender) {
        if (label.getText().equals(""))
          label.setText("Hello World!");
        else
          label.setText("");
      }
    });
    RootPanel.get("slot1").add(button);
    RootPanel.get("slot2").add(label);
  }
}

위의 자바 클래스는 client 패키지에 있고, 이로 인하여 GWT는 해당 코드를 JavaScript로 컴파일 할 것이다. 이것은 파일에 해당 특정 제한이 있는 것 같지만, 코드 내부를 보면 기본적인 Java 1.4 코드일 뿐이다.EntryPoint 인터페이스는 onModuleLoad()만을 정의하였으며, GWT는 이 모듈을 참조하는 HTML 페이지가 로딩되면 이 메소드를 자동으로 호출하게 되는 것이다.

위의 코드는 단순하다고 할 수 있다. 처음 두 라인에 버튼과 레이블을 정의한다. 그 다음 두 라인에서는, RootPanel.get() 메소드를 사용하여, 이 위젯들을 HTML 페이지의 특정 엘리먼트로 연결시킨다. 이 메소드에 대한 인자는 HTML 페이지에 정의된 엘리먼트의 JavaScript ID이다.

위의 코드 라인들 사이에 Swing에서와 같이 이벤트를 묶는데 사용하는 것과 비슷한 방식을 사용하여 이벤트 리스너(eventListner)를 정의한다. 위의 경우, 버튼을 클릭하면 ClickListener가 호출된다.




위로


GWT 프로그램 실행하기

GWT가 만든 샘플 프로그램을 실행해 보자. GWT 프로그램을 실행하는 두 가지 방법이 있다. 바로 웹 모드(Web mode)와 호스트 모드(hosted mode)이다. 웹 모드는 완전한 전개 모드로서, GWT 프로그램을 JavaScript 코드로 컴파일 한 후에 실행한다.

호스트 모드는 개발하는 동안 사용된다. 호스트 모드란, 클라이언트와 서버 코드를 한번에 시뮬레이트 하면서, 개발하는 동안 전개를 단순화 시키는 일종의 에뮬레이터이다. (호스트 모드는 Mac OS X에서는 불가능하다.) 디버거와 함께 IDE를 사용한다면, 호스트 모드에서 GWT 프로그램을 실행할 수 있으며, JavaScript로 컴파일 될 코드 부분에서 중단점(breakpoint)을 지정하고 그의 변수(variable)의 변경사항을 알아낼 수 있다. 이러한 부분은 개발 시 매우 유용하며, GWT로 작업하게 되면, 대부분 호스트 모드를 사용하게 된다.

또한, 여러 가지 방법들로 호스트 모드를 실행할 수 있다. 이전에 실행했던 applicationCreator 스크립트는 명령행에서 호출할 수 있는 Slicr-shell 스크립트를 만들어서 호스트 모드를 실행할 수 있도록 하였다. 또한, 이 글 초반에, GWT 프로젝트를 Eclipse로 반입하는 방법을 설명했다. Eclipse 프로젝트에서, Run 메뉴 또는 툴바에서 Debug 또는 Run을 선택할 수 있다. 생성된 창을 통해서는 Java Application을 클릭하여 Slicr 옵션을 볼 수 있다. 이 옵션은 GWT가 만들었고, 나머지 프로젝트와 함께 Eclipse로 반입했던 Slicr.launch 파일에서 사용할 수 있다.


그림 2. 호스트 모드 호출하기
Invoking hosted mode

호스트 모드에서 실행할 때, 두 개의 창이 나타난다. (처음 실행할 경우, 호스트 모드 설정이 초기화되는 동안 1분여의 시간이 걸린다.) 그림 3에서 보이는 첫 번째 창의 이름은 Google Web Toolkit Development Shell / Port 8888.이다. 여기에는 GWT의 에러와 로그 메시지들이 들어있다. 툴바를 사용하여, 새로운 호스트 브라우저를 열 수 있고, 스크린상의 로그를 확장, 축소, 삭제할 수 있다.


그림 3. 호스트 모드 쉘 윈도우
Hosted mode shell window

그림 4에 보이는 두 번째 창은 브라우저 모습이다. 보다시피, slicr.html 페이지에서 생성된 정적 HTML과 Slicr.java EntryPoint 클래스에서 생성된 버튼 위젯이 있다. 버튼을 클릭하면 레이블이 선택된다. 설정 단계에서 오류가 있었다면, 이 창을 볼 수 없고 대신 쉘에 에러 메시지가 나타난다. 모든 이름들이 정확한지를 확인하라. (특히, .launch 파일에서, 정확한 프로젝트 디렉토리가 지정되었는지를 확인한다.)


그림 4. 호스트 모드 브라우저
Hosted mode simulated browser

클라이언트 설정하기

이 글에서는 스크린상에서 위젯을 실행시키는 것에 초점을 맞추겠다. 그림 5에 보이는 스크린은 매우 단순해 보이지만, 꽤나 기능적이다.


그림 5. Slicr
Slicr

페이지가 로딩될 때 이러한 위젯들을 생성시키려면, EntryPoint 클래스의 onModuleLoad() 메소드에 코드를 넣어야 한다. Listing 4는 두개의 데이터를 정의하고, 각 패널을 구현하기 위해 헬퍼를 호출하는 메소드를 정의하고 있다. 이 코드가 실행되려면, slicr ID로 HTML 페이지에 엘리먼트를 삽입해야 한다. 이렇게 하면 리스팅의 RootPanel.get() 명령어가 그 페이지의 엘리먼트를 찾을 수 있다. 가장 쉬운 방법은 이전 HTML 리스팅의 테이블을 >div id="slicr" /<로 대체하는 것이다.


Listing 4. 모듈 로드 이벤트 핸들러
				
private DockPanel panel;
private List clearables;

public void onModuleLoad() {
    clearables = new ArrayList();
    initDockPanel();
    panel.add(buildActionPanel(), DockPanel.SOUTH);
    panel.add(buildPizzaTypePanel(), DockPanel.WEST);
    panel.add(buildToppingPanel(), DockPanel.EAST);
    RootPanel.get("slicr").add(panel);
}

위젯 설정하기

DockPanel에 모든 위젯을 설정하도록 한다. GWT에서의 DockPanel이란, Swing에서 BorderLayout을 사용하는 Panel에 해당한다. Swing에서는 한 개의 panel 클래스와 여러 개의 레이아웃 매니저가 있는 반면, GWT에는 여러 Panel 서브클래스가 있고, 각각 자식 위젯을 전개하는 고유의 알고리즘이 있다. 다른 패널 클래스로는 SimplePanel, HTMLTable, FlowPanel, StackPanel 등이 있다. DockPanel을 만드는 것은 어렵지 않다. 아래 Listing 5에서와 같이 세터(setter)가 이 일을 대신한다.


Listing 5. 메인 패널 초기화 하기
				
private void initDockPanel() {
    panel = new DockPanel();
    panel.setBorderWidth(1);
    panel.setSpacing(5);
}

SOUTH 패널(button) 생성하기

DockPanel의 선착순 원리를 따르기 때문에, 먼저 하단부 패널을 정의한다. 이런 방식으로, SOUTH 위젯은 전체 패널에서 실행한다. 아래 Listing 6과 같이 HorizontalPanel을 액션 패널로서 정의한다. (GWT의 HorizontalPanel이란, Swing에서의 box와 비슷하다고 보면 된다.)


Listing 6. SOUTH (buttons) 패널
				
public HorizontalPanel buildActionPanel() {
    HorizontalPanel actions = new HorizontalPanel();
    actions.setSpacing(10);
    Button clear = new Button("Clear");
    clear.addClickListener(new ClearClickListener());
    Button newPizza = new Button("Another Pizza");
    Button submitOrder = new Button("Submit");
    actions.add(clear);
    actions.add(newPizza);
    actions.add(submitOrder);
    return actions;
}

GWT Button 위젯을 사용하여 세 개의 버튼을 만든 다음, 패널에 추가한다. 또한, 나중에 정의하게 될 Clear 버튼에 ClickListener를 만든다. GWT는 이벤트 리스너들을 Swing과는 다르게 나눈다. ClickListener는 마우스 클릭만 리스닝한다. (종종, 인라인 클래스로서 정의된 리스너를 보곤 하는데, 이 스타일은 읽고 테스트 하기 까다롭기 때문에 네임드 클래스를 만들었다.)

WEST 패널(pizza type) 생성하기

pizza type 의 패널은 Listing 7과 같이 복잡하지 않다. GWT RadioButton 위젯을 사용하면 된다.


Listing 7. WEST (pizza types) 패널
				
public static final String[] PIZZA_TYPES = new String[] {
    "Thin Crust Medium", "Thin Crust Large", 
    "Thin Crust X-Large", "Thick Crust Medium", 
    "Thick Crust Large"
};

private VerticalPanel buildPizzaTypePanel() {
    VerticalPanel pizzaTypes = new VerticalPanel();
    HTML label = new HTML("<h2>Pizza</h2>");
    pizzaTypes.add(label);
    for (int i = 0; i < PIZZA_TYPES.length; i++) {
        RadioButton radio = new RadioButton("pizzaGroup", 
            PIZZA_TYPES[i]);
        clearables.add(radio);
        pizzaTypes.add(radio);
    }
    return pizzaTypes;
}

HTML을 실행하는 레이블인 HTML 위젯을 사용할 것이다. HTML 위젯은 결국 HTML상의 <span> 태그 주위의 래퍼(Wrapper)로서 역할을 한다. RadioButton 컨스트럭터(constructor)는 두 개의 인자들을 취한다. 첫 번째는 라디오 버튼용 스트링 레이블이고, 두 번째는 텍스트 레이블이다. 각 버튼을 패널과 인스턴스 리스트에 추가하면 이 리스너들 중 한 곳에서 사용하게 될 것이다.


EAST 패널 (toppings) 만들기

topping 패널은 Listing 8처럼 좀더 복잡하다. 사용자가 다양한 토핑을 가진 피자를 만들 수 있도록 해야 한다. 토핑 버튼을 클릭하면 두 쪽 모두 체크되지만, 한 쪽만 체크되거나, 개별적으로 삭제될 수 있다. 모든 것의 줄을 맞춰야 하기 때문에 Grid를 사용한다.


Listing 8. 토핑 그리드
				
public static final String[] TOPPINGS = new String[] {
    "Anchovy", "Gardineria", "Garlic", 
    "Green Pepper", "Mushrooms", "Olives", 
    "Onions", "Pepperoni", "Pineapple", 
    "Sausage", "Spinach"
};

private VerticalPanel buildToppingPanel() {
    VerticalPanel toppings = new VerticalPanel();
    toppings.add(new HTML("<h2>Toppings</h2>"));
    Grid topGrid = new Grid(TOPPINGS.length + 1, 3);
    topGrid.setText(0, 0, "Topping");
    topGrid.setText(0, 1, "Left");
    topGrid.setText(0, 2, "Right");
    for (int i = 0; i < TOPPINGS.length; i++) {
        Button button = new Button(TOPPINGS[i]);
        CheckBox leftCheckBox = new CheckBox();
        CheckBox rightCheckBox = new CheckBox();
        clearables.add(leftCheckBox);
        clearables.add(rightCheckBox);
        button.addClickListener(new ToppingButtonListener(
                leftCheckBox, rightCheckBox));
        topGrid.setWidget(i + 1, 0, button);	
        topGrid.setWidget(i + 1, 1, leftCheckBox);
        topGrid.setWidget(i + 1, 2, rightCheckBox);
    }
    toppings.add(topGrid);
    return toppings;
}

VerticalPanelHTML 위젯을 사용한다. GWT Grid에 모든 것을 놓기 때문에, 그리드의 크기를 설정해야 한다. 그리드의 각 셀에는 플레인 텍스트나, 또 다른 GWT 위젯을 포함시킬 수 있다. 각 행(row)에, 버튼과 두 개의 체크 박스를 만들고, 이들을 셀에 맞춰 정렬한다. 버튼용 리스너를 추가하고, 체크 박스를 clearable 리스트에 놓는다.

리스너 정의

위젯을 설정했다면, 두 개의 정의된 리스너를 보자. 두 개 중 더 단순한 것이 Clear 버튼에 대한 것이다. Listing 9와 같이 이 버튼은 clearable 리스트에서 실행되고, 모든 것을 지운다.


Listing 9. Clear 버튼에 정의된 리스너
				
private class ClearClickListener implements ClickListener {
    public void onClick(Widget sender) {
    for (Iterator iter = clearables.iterator(); iter.hasNext();) {
            CheckBox cb = (CheckBox) iter.next();
            cb.setChecked(false);
        }
    }
}

주: GWT에서, RadioButton은 실제로 CheckBox의 서브클래스이다. 따라서 위 코드는 class cast exception을 트리거(trigger)하지 않는다.

토핑 버튼용 리스너는 더 복잡하다. 제휴 체크 박스들 중 어떤 것도 선택되지 않으면, 이 리스너는 두 개의 체크 박스 모두를 선택한다. 다른 상황에서는, 두 가지 모두를 지운다. Listing 10은 그 예이다.


Listing 10. 버튼에 정의된 리스너
				
private class ToppingButtonListener implements ClickListener {

    private CheckBox cb1;
    private CheckBox cb2;

    public ToppingButtonListener(CheckBox cb1, CheckBox cb2) {
        this.cb1 = cb1;
        this.cb2 = cb2;
    }

    public void onClick(Widget sender) {
        boolean unchecked = !cb1.isChecked() && !cb2.isChecked();
        cb1.setChecked(unchecked);
        cb2.setChecked(unchecked);
    }
}

공유 사이트...

digg Digg
del.icio.us del.icio.us
Slashdot Slashdot

예고

이번 글에서는 slicr 클라이언트를 구현해 보았다. 다음 글에서는 Derby 데이터베이스를 사용하여 서버 측에서 데이터 레이어를 구현하고, 데이터베이스에서 온 데이터를 GWT 클라이언트로 보내질 수 있는 자바 객체들로 변환하는 방법을 설명하겠다. 서버와 클라이언트를 연결하는 원격 프로시저 아키텍처도 설명한다.

서버 측이 개별적으로 실행되어야 한다면, 개발 및 실행 환경에 이를 전개하는 방법을 고려해야 한다. 또한, 인터페이스를 보기 좋은 모양으로 만드는 방법도 배울 것이다. 그 전에 GWT 다운로드 사이트에 가서 직접 실행해 보기 바란다.

기사의 원문보기



참고자료

교육

제품 및 기술 얻기

토론


필자소개

Noel Rappin 박사는 Georgia Institute of Technology의 Graphics, Visualization, and Usability Center 소속이며, Motorola의 소프트웨어 엔지니어이다. wxPython in Action and Jython Essentials를 공동 집필했다.

출처 : IBM developerworks
:
Posted by 뽀기

애플리케이션에 맞게 데이터를 인코딩(encode) 하는 가장 올바른 방법


JavaScript가 필요한 문서 옵션은 디스플레이되지 않습니다.



난이도 : 중급

Dethe Elza, Senior Software Developer, Uniserve Communications Corporation
David Mertz, Ph.D, Author, Gnosis Software, Inc.

2007 년 2 월 06 일

Ajax(Asynchronous JavaScript and XML)는 신뢰성을 기반으로, 서버에 채널을 개방하여, 웹 애플리케이션에서 사용되는 데이터를 교환하는 신개념 웹 브라우저입니다. 이것은 표준 웹 기술과는 반대되는 개념이고, Ajax를 기반으로 개발 할 때, 전통적인 웹 페이지들과는 다른 디자인 정책이 필요합니다. 백(back) 버튼을 관리하는 방법, 업데이트 된 데이터를 디스플레이 하는 방법, 업데이트를 보내는 빈도수 등도 그 예가 될 수 있습니다. 이 글에서는 데이터 교환에 어떤 포맷을 사용해야 할 것인지를 중점적으로 설명합니다.

Ajax라는 단어에서 X는 XML을 뜻하지만, XML은 언어가 아니라 언어를 구현하는 툴킷이다. 따라서, 가장 먼저, 기존 언어를 사용할 것인가, 아니면 자신의 언어로 재 구축할 것인지를 결정해야 한다. 결정하고 나서는 부가적인 문제들이 생기기 시작한다. 기존의 언어들은 자신의 필요에 맞는가, 자신에 필요에 맞게 설계할 수 있는가? 그 언어를 처리할 툴은 있는가, 툴을 구현해야 하는가? 다른 사람들과 커뮤니케이션을 해야 한다면, 그 언어는 잘 알려진 언어인가? 다른 애플리케이션들도 쉽게 여러분의 데이터에 액세스 하여, 사용할 수 있는가?

그래픽 데이터일 경우에는 (X)HTML, SVG 또는 X3D, 데이터 조각에는 Atom, 단순한 아웃라인에는 OPML, 그래프에는 RDF 등 용도가 확실한 것도 있다. 완벽한 기능을 갖추고 있고, 장황한 DocBook, DITA, OpenOffice 포맷으로 된 데이터를 보낼 수도 있다. (참고자료)

한편, Ajax라는 단어에서 X가 무엇을 뜻하는지에 상관없이, 여러분이 원하는 다양한 종류의 데이터를 보낼 수 있다. 바이너리 데이터, 이미지, 무비, PDF 파일도 가능하지만, JavaScript로 되어있는 브라우저에서는 다루기 어렵다. XML 보다 단순한 텍스트 포맷으로 보낼 수도 있다. Tab 또는 콤마 분리 리스트(tab-, comma-delimited list), Markdown, YAML, JSON 등을 XML 대안으로 사용할 수 있다. 이외에도, XML을 사용하지 않는 수 십 개의 옵션들이 있다. (참고자료 - XML Alternatives 웹 사이트 참조) 물론, 장황함(verbose)과 풍부함(rich)의 차이는 있다. 심지어, 이 리스트에 있는 한 개의 아이템에서도 여러 가지의 데이터 인코딩 방식이 있을 수 있다.

  • OpenOffice Spreadsheet
  • DITA (Darwin Information Typing Architecture)
  • DocBook
  • RDF-XML
  • XHTML
  • Microformat
  • Atom
  • OPML (Outline Processor Markup Language)
  • Custom XML
  • Markdown / Textile / reStructured Text
  • YAML (YAML Ain't Markup Language)
  • JSON (JavaScript Object Notation)
  • Comma- (or Tab-) delimited text

무엇을 선택하여야 하는가?

이러한 많은 옵션들 중에서, 어떻게 하면 현명한 결정을 내릴 수 있을까? 위에 제시한 리스트는 엄밀히 말해서 복잡한 순서대로 나열한 것은 아니다.

  • 우선, 가장 단순한 방식 또는 가장 복잡한 방식으로 포맷을 사용할 수 있다.
  • 생성, 읽기, 파싱, 프로세스 중에서 어떤 것이 가장 복잡한 것인지를 파악해야 한다. 예를 들어, XML은 그 자체로 복잡한 편이지만, 파서가 브라우저에 이미 있기 때문에 파싱은 오히려 단순하다.
  • 복잡성은 데이터의 유형에 상당히 많이 의존한다. 스프레드시트나 데이터베이스처럼, 고정된 구조를 갖고 있는가? 워드 프로세싱 문서나 블로그 포스트처럼 유연한(loosely) 구조를 갖고 있는가? 항공기 매뉴얼 같은 대형 문서인가, 응답 코드 같은 작은 데이터 조각인가? 데이터 세트가 크다면, 이것을 한 번에 보낼 것인가, 아니면 필요할 때마다 작은 조각 단위로 보낼 것인가? 큰 데이터를 작은 조각 단위로 나누는 것은 얼마나 어려우며, 받는 쪽에서, 작은 조각들을 올바르게 조합하려면 얼마나 많은 정보가 필요한가?

즉, 무엇이 가장 중요한 요소인가?

  • 장황함/대역폭(특별한 경우를 제외하고는, 이러한 요소는 여러분이 생각하는 것만큼 중요하지 않다.)
  • 가독성(작성 가능성, 관리성)
  • 파싱 난이도(클라이언트 측과 서버 측)
  • 파싱 속도(네이티브 대 스크립팅)
  • 정보 손실(ordered pairs -> dictionary -> sets)
  • 유연성(가끔은, 덜 유연한 것이 더 나을 때도 있다.)
  • 언어 이식성(얼마나 많은 언어들을 사용할 수 있는가?)
  • 정확성(포맷에 어느 정도 순응하는가?)
  • 라운드 트리핑 (Round-Tripping) (Markdown -> XHTML -> Markdown, 얼마나 많은 데이터 손실이 있는가?)

속도, 대역폭 활용, 효율성을 위해서가 아니라, 사용자를 만족시키기 위해 최적화 하는 경우가 대부분이다. 지연되는 부분은 숨기고, 즉각적인 업데이트가 가능하다면, 미미한 네트워크 지연은 문제가 되지 않는다. 바로 이것이 Ajax의 가장 큰 장점일 것이다.




위로


제 1 원칙

이 글에서, 몇 가지 선택 원칙을 제시하고, 이를 뒷받침 할 몇 가지 예제도 소개하겠다. 이모든 것들이 여러 가지 옵션들을 선택하는데 있어서 충실한 가이드라인이 될 것이다.

  • 데이터용 JSON: 데이터가 구축되었다면 JSON이 제격이다. 적어도 세 개의 파서들이 브라우저에 포함되어 있고(HTML, XML, JavaScript), 이중 가장 빠른 것은 JavaScript 이다. 또한, 데이터가 이미 JavaScript로 되어 있을 경우, JavaScript를 사용하여 데이터를 조작하는 것이 DOM 보다는 낫다. 데이터를 바로 디스플레이 하지 않거나, 데이터가 먼저 수정되어야 한다거나, 또는 데이터가 웹 페이지의 다른 부분에서, 또는 다른 포맷으로 디스플레이 된다면, JSON이 잘 맞는다. 대부분의 언어들에는 JSON용 라이브러리가 있기 때문에, 더 이상 JavaScript만을 위한 것은 아니다.
  • 혼합 콘텐트(문서)를 위한 XML: URL과 같은 메타데이터를 사용하거나, 워드 프로세싱 문서와 블로그 포스트 같은 마크업과 텍스트를 혼합해야 한다면 XML을 사용하라. 데이터가 한 곳에서 직접 디스플레이 된다면, 서버에서 이를 정형화(format)하고, Ajax를 사용하여 검색 및 삽입한다.(이 기법은 'client-side includes'라고 알려졌다.) David가 "MochiKit" (참고자료)에서 언급하였듯이, XML을 브라우저로 전달하고 CSS로 포맷하거나, 또는 HTML을 통해서 이를 스타일링 할 것인지를 선택할 수 있다. 당신이 XML을 사용해야 한다면, 필자는 XHTML, SVG, X3D등과 같은 표준 포맷을 사용하라는 것 외에 많은 가이드라인을 줄 수는 없다. 이러한 포맷들의 서브셋을 사용하여, 시스템들 간 상호 운용성이 뛰어난 데이터를 만들 수 있고, 다른 프로그래머들도 익숙하게 사용할 수 있도록 한다. 가끔은 자신만의 XML 포맷을 만들 수도 있지만, 상호 운용성 부분에서는 더욱 많은 신경을 써야 한다. 그것도 의심스럽다면, HTML을 계속 사용하라.
  • 동기화(Syndication)를 위한 Atom: 여기에서 나는 동기화에 대해 매우 포괄적으로 정의를 내리고자 한다. 데이터를 주기적으로 업데이트 할 것이라면, 데이터에 타임스탬프가 필요하다면, Atom을 사용하는 것이 좋다. 또한, 데이터 흐름에 대한 표준 인벨롭(envelope)으로서 Atom 포맷을 사용하는 것이 좋다. 이렇게 하면, 애그리게이터(aggregator), 뉴스 리더기, 스크립팅 라이브러리를 통해서, 데이터를 추적하고 재사용할 수 있는 많은 툴들을 사용할 수 있을 것이다. 또한, 웹 페이지에 데이터를 삽입만 하면, 크게 노력하지 않아도 동기화 피드가 될 수 있는 효과도 누릴 수 있다.



위로


선택의 파라독스

이제, 다른 포맷들과, 각 포맷의 사용 방법에 대해서 알아보자. 이전 두 개의 칼럼에서는(참고자료) 메커니즘에 초점을 맞추느라 간단한 예제를 사용했지만, 이번에는 실제 예제를 사용해보겠다. 나의 아내인 Daniela는 시인이다. 그녀는 잡지, 콘테스트, 이벤트에 제출한 작품들을 관리해야 했다. 제출한 시가 어떤 단계에 와 있으며, 어떤 것이 채택 또는 탈락 되었는지, 각 작품당 가격은 얼마인지, 이벤트 비용은 얼마인지를 알아야 한다. Listing 1은 데이터 내용이다.


Listing 1
				

Room of One's Own
Submitted May 10, '05
* Hyacinth Blue
* Fabrication
* Thanksgiving
* Spilling the Peas
Accepted Hyacinth Blue
Accepted Sept 2005
Published Oct 2006
Paid Sept 2006
Paid $50 + 2 copies
Postage $1.12
Submission Fee: 0
Journal submission

Surrey International Writer's Contest
Contest submission
Submitted Aug. 31 2006
* 13th Child
Fee: $15
Postage: 1.05
Honorable Mention
Prize: $150 + copy of anthology
Accepted Sept. 26 2006
Publication Date Oct. 20 2006

Word on the Street
Public Reading
Invited speaker
Reading time: 10 minutes
Paid: T-shirt and lunch
Date: Sept 24 2006

Paideusis: The Journal of the Canadian Philosophy of \
    Education Society
Submitted Oct. 13th 2006
* To carry over: metaphor invents us (seven poems)
Email submission
Referreed Journal
Accepted Oct. 16th 2006
Published (Pending) Nov. 2006


어느 정도 까지는 이러한 포맷도 유효했지만, 출품작이 많아지면서, 트래킹(tracking)은 더욱 어려워졌다. 연간 수입과 지출을 가늠하기가 더 어려워졌고, 평균 응답 시간(제출과 채택 또는 탈락까지 걸리는 시간)같은 정보도 받아보고 싶었다. 그래서, 나는 아내에게 "Fame Not Fortune"이라고 하는, Ajax 웹 애플리케이션을 구현 할 것을 제안했다.

물론, 나의 게으름 탓에, 새로운 애플리케이션을 구현하지 않고, 원래 있었던 애플리케이션을 사용하게 되었다. 아내가 시를 편집할 때 Open Office (워드 프로세싱) (참고자료)를 사용하기 때문에, 그림1처럼 트래킹에도 Open Office (spreadsheet)를 사용할 수 있었다.


그림 1. Open Office Spreadsheet 예제
Open Office Spreadsheet example

벌써, 몇 가지 문제가 드러나고 있다. 특히, 스프레드시트는 트래킹에 맞는 인터페이스가 아니다. 대상 데이터는 매우 유연하기 때문에, 많은 칼럼들이 채워지지 않았고, 아내도 스프레드시트를 사용하는 것에 익숙하지 않았다. 웹 애플리케이션을 구현해야 한다는 나의 생각이 옳았다. 물론, Open Office는 문서를 XML로 저장하기 때문에, 복잡한 데이터 마이닝(data-mining) 태스크에는 Open Office를 사용하고, 데이터 입력에는 웹을 사용하는 상황이다. 이러한 경우에는 한 가지 포맷을 결정하는 것이 더 낫다.

Open Office에 저장된 포맷은, 실상은 데이터와 기타 리소스들(삽입된 이미지, 스크립트, 스타일링 정보)을 포함하고 있는 .zip 파일인, .odf 파일이다. 이 문서를 보면서, 다음과 같은 사실들을 발견했다.

  • META-INF는 .odf 문서의 콘텐트 리스트인 manifest.xml을 포함하고 있는 폴더이다.
  • Configurations2는 상태 바, 메뉴 같은 UI를 포함하고 있는 폴더이다. 현재까지는 무시해도 좋다.
  • Thumbnails은 작은 .png 이미지를 포함하고 있는 폴더이다.
  • content.xml은 내가 입력했던 실제 데이터 파일이다.
  • meta.xml은 문서에 대한 정보를 포함하고 있는 파일이다. 생성자, 수정일, 기타 상세 정보를 포함하고 있다.
  • mimetype은 "application/vnd.oasis.opendocument.spreadsheet" 스트링을 포함하고 있는 파일이다.
  • settings.xml은 Open Office 설정 내용들을 포함하고 있는 파일이다.
  • styles.xml은 스프레드시트에 대한 포맷팅 정보를 포함하고 있는 파일이다.

따라서, 웹 애플리케이션과 Open Office간 데이터를 교환해야 한다면, 전체 .odf 파일이 아닌 내부 content.xml 파일에 주목해야 한다. 이 파일에는 무엇이 있을까? 17,629개의 문자와, 23개의 XML 네임스페이스, 63 줄의 스타일링 정보가 포함되어 있고, 모든 셀에는 스타일 정보가 들어있다. 이것은 데스크탑 스프레드시트 애플리케이션에는 합리적인 대안이지만, 네트워크를 통해서까지 이렇게 불필요한 정보를 처리하느라 시간을 허비하고 싶지는 않다. Listing 2는 실제 데이터의 한 행(row)이다.


Listing 2
				<table:table-row table:style-name="ro3">
  <table:table-cell office:value-type="string">
    <text:p>Room of One's Own</text:p>
  </table:table-cell>
  <table:table-cell table:style-name="Default"
  office:value-type="string">
    <text:p>Journal</text:p>
  </table:table-cell>
  <table:table-cell table:style-name="ce2"
  office:value-type="string">
    <text:p>Hyacinth Blue; Fabrication; Thanksgiving;
    Spilling the Peas</text:p>
  </table:table-cell>
  <table:table-cell table:style-name="ce5"
  office:value-type="date" office:date-value="2005-05-10">
    <text:p>10 May 2005</text:p>
  </table:table-cell>
  <table:table-cell table:style-name="ce5"
  office:value-type="date" office:date-value="2005-09-01">
    <text:p>1 Sep 2005</text:p>
  </table:table-cell>
  <table:table-cell table:style-name="ce5"
  office:value-type="date" office:date-value="2006-10-01">
    <text:p>1 Oct 2006</text:p>
  </table:table-cell>
  <table:table-cell table:style-name="ce5"
  office:value-type="date" office:date-value="2006-09-01">
    <text:p>1 Sep 2006</text:p>
  </table:table-cell>
  <table:table-cell office:value-type="string">
    <text:p>Hyacinth Blue</text:p>
  </table:table-cell>
  <table:table-cell table:style-name="ce6"
  office:value-type="currency" office:currency="CAD"
  office:value="50">
    <text:p>50.00 CAD</text:p>
  </table:table-cell>
  <table:table-cell office:value-type="string">
    <text:p>2 Copies of Publication Issue</text:p>
  </table:table-cell>
  <table:table-cell table:style-name="ce7"
  office:value-type="currency" office:currency="CAD"
  office:value="1.12">
    <text:p>1.12 CAD</text:p>
  </table:table-cell>
  <table:table-cell table:style-name="ce7" />
  <table:table-cell table:number-columns-repeated="244" />
</table:table-row>

데이터를 XHTML에 삽입하는 것은 어떨까? 이 같은 경우, 파싱이나 포맷팅을 할 필요 없이, Listing 3처럼, 직접 디스플레이 할 수 있다.


Listing 3
				<html><body><ul>
    <li><dl>
        <dt>publisher</dt><dd>Room of One's Own</dd>
        <dt>type</dt><dd>Journal</dd>
        <dt>titles</dt><dd><ul>
            <li>Hyacinth Blue</li>
            <li>Fabrication</li>
            <li>Thanksgiving</li>
            <li>Spilling the Peas</li>
        </ul></dd>
        <dt>submitted</dt><dd>2005-05-10</dd>
        <dt>accepted</dt><dd>2005-09-01</dd>
        <dt>published</dt><dd>2006-10-01</dd>
        <dt>payment received</dt><dd>2006-09-01</dd>
        <dt>titles accepted</dt><dd><ul>
            <li>Hyacinth Blue</li>
        </ul></dd>
        <dt>expenses</dt><dd><dl>
            <dt>postage</dt><dd>CAD 1.12</dd>
        </dl></dd>
        <dt>payment</dt><dd><ul>
            <li>CAD 50.00</li>
            <li>2 Copies of Publication Issue</li>
        </ul></dd>
    </dl></li>
    <li><dl>
        <dt>publisher</dt>
            <dd>Surrey International Writers' Competition</dd>
        <dt>type</dt><dd>Contest</dd>
        <dt>titles</dt><dd><ul>
            <li>The Thirteenth Child</li>
        </ul></dd>
        <dt>submitted</dt><dd>2006-08-31</dd>
        <dt>accepted</dt><dd>2006-09-26</dd>
        <dt>published</dt><dd>2006-10-20</dd>
        <dt>payment received</dt><dd>2006-10-20</dd>
        <dt>titles accepted</dt><dd><ul>
            <li>The Thirteenth Child</li>
        </ul></dd>
        <dt>expenses</dt><dd><dl>
            <dt>postage</dt><dd>CAD 1.05</dd>
            <dt>entry fee</dt><dd>CAD 15.00</dd>
        </dl></dd>
        <dt>payment</dt><dd><ul>
            <li>CAD 150.00</li>
            <li>Honorable Mention</li>
            <li>Copy of Anthology</li>
        </ul></dd>
    </dl></li>
    <li><dl>
        <dt>publisher</dt><dd>Word on the Street</dd>
        <dt>type</dt><dd>Invited Reader</dd>
        <dt>event</dt><dd>10 Minutes of readings</dd>
        <dt>event date</dt><dd>2006-09-24</dd>
        <dt>payment</dt><dd><ul>
            <li>T-Shirt</li>
            <li>Lunch</li>
        </ul></dd>
    </dl></li>
    <li><dl>
        <dt>publisher</dt><dd>Paideusis: The Journal of the
            Canadian Philosophy of Education Society</dd>
        <dt>type</dt><dd>Refereed Journal</dd>
        <dt>titles</dt><dd><ul>
            <li>To Carry Over: Metaphor Invents Us (seven poems)</li>
        </ul></dd>
        <dt>submitted</dt><dd>2006-10-13</dd>
        <dt>accepted</dt><dd>2006-10-16</dd>
        <dt>published</dt><dd>Pending</dd>
        <dt>titles accepted</dt><dd>All</dd>
    </dl></li>
</ul></body></html>

이것은 데이터를 HTML로 단순히 매핑한 것이다. 기본 스타일링이 충분하지는 않지만, 크로스 플랫폼(cross-platform) 방식으로, CSS를 사용하면 스타일링 하기가 매우 쉽고, DOM을 사용하여 데이터를 쉽게 조작할 수 있다. 추가된 HTML 코드 때문에 약간 부풀려 보이지만, 그렇게 심한 것은 아니다. 이 예제는 XOXO outline Microformat(참고자료)와 매우 비슷하고, class="outline"을 첫 번째 <ul /> 엘리먼트에 붙인다면, XOXO 아웃라인이 될 것이다. 여기에 커스텀 XML을 사용하여 콘텐트를 추가할 수 있고, 디스크립션 리스트를 <submission/> 엘리먼트로 대체했다. 하지만 이 예제의 경우, 간결함이나 가독성 측면에서는 별로 얻은 것이 없다. 간결함을 원한다면, JavaScript Object Notation (JSON)을 고려해 볼 수 있다.


Listing 4
				

    {   "publisher": "Room of One's Own",
        "type": "Journal",
        "titles": ["Hyacinth Blue", "Fabrication", "Thanksgiving",
            "Spilling the Peas"],
        "titles accepted": ["Hyacinth Blue"],
        "submitted": "2005-05-10",
        "accepted": "2005-09-01",
        "published": "2006-10-01",
        "payment received": "2006-09-01",
        "expenses": [{"postage": "CAD 1.12"}],
        "payment": ["CAD 50.00", "2 Copies of Publication Issue"]},
    {   "publisher": "Surrey International Writers' Competition",
        "type": "Contest",
        "titles": ["The Thirteenth Child"],
        "titles accepted": ["The Thirteenth Child"],
        "submitted": "2006-08-31",
        "accepted": "2006-09-26",
        "published": "2006-10-20",
        "payment received": "2006-10-20",
        "expenses": [{"postage": "CAD 1.05"},
            {"postage": "CAD 15.00"}],
        "payment": ["CAD 150.00", "Honorable Mention",
            "Copy of Anthology"]},
    {   "publisher": "Word on the Street",
        "type": "Invited Reader",
        "event": "10 Minutes of readings",
        "event date": "2006-09-24",
        "payment": ["T-Shirt", "Lunch"]},
    {   "publisher": "Paideusis: The Journal of the Canadian\
             Philosophy of Education Society",
        "type": "Refereed Journal",
        "titles": ["To Carry Over: Metaphor Invents Us \
            (seven poems)"],
        "titles accepted": "All",
        "submitted": "2006-10-13",
        "accepted": "2006-10-16",
        "published": "Pending"}
]

Listing 4를 보면, HTML 인코딩과 모두 같은 내용이지만, 이것은 JavaScript의 서브셋(subset)이기 때문에, JavaScript 객체, 리스트(list), 스트링(string)으로서 직접 데이터에 액세스 할 수 있다. 이 포맷은 단순하고 간결하며, 이전 포맷에 있는 모든 정보를 포함하고 있다. 게다가, 구조도 잘 보존하면서 Semi-structured 데이터에도 잘 맞는다. 이것으로 간결성에 대한 해결책은 얻었지만, 이것보다 더 단순해 질 수 있다. 첫 번째 예제로 다시 돌아가서, 스프레드시트에 데이터를 저장해 보자. 한 스프레드시트에서 다른 스프레드시트로 데이터를 옮기는 방식 중에는 Comma-Separated Value (CSV)가 있다. Listing 5를 보자.


Listing 5
				

"Publisher", "Type", "Titles", "Submitted", "Accepted/Rejected", \
"Published", "Payment Received", "Titles Accepted", "Payment", \
"In Kind", "Postage", "Fees"
"Room of One's Own", "Journal", "Hyacinth Blue; Fabrication; \
Thanksgiving; Spilling the Peas", 10 May 2005, 1 Sep 2005, \
1 Oct 2006, 1 Sep 2006, "Hyacinth Blue", 50.00 CAD, \
"2 Copies of Publication Issue", 1.12 CAD,
"Surrey International Writer's Competition", "Contest", \
"The Thirteenth Child", 31 Aug 2006, 26 Sep 2006, 20 Oct 2006, \
20 Oct 2006, "The Thirteenth Child", 150.00 CAD, "Honorable Mention, \
Copy of Anthology", 1.05 CAD, 15.00 CAD
"Word on the Street, Vancouver", "Invited Speaker", \
"10 Minutes of Readings", , , 24 Sep 2006, , , , "T-Shirt, Lunch", ,
"Paideusis: The Journal of the Canadian Philosophy of Education \
Society", "Refereed Journal", "To Carry Over: Metaphor Invents Us \
(seven poems)", 13 Oct 2006, 16 Oct 2006, "(Pending) Nov 2006", , \
"All", , , "Email",


Listing 5는 어느 정도까지 간결해 질 수 있는지를 보여주는 것 같다. JSON과 CSV의 중대한 차이도 보인다. CSV는 일반적인 기술이고, 결코 표준화 되어 있지 않으며, 오직 ASCII 텍스트만을 취하는 반면, JSON은 명확하게 표준화 되었으며, Unicode의 UTF-8 인코딩 사용에 대해서도 정의를 내린다. 따라서, CSV 예제의 경우 ASCII 범위 이외의 어떤 텍스트도 사용하지 않지만, JSON(그리고 XML)은 어떤 텍스트와도 잘 작동한다.




위로


Atom 연결

Atom Syndication Format은 필자, 발행일 등, Fame not Fortune의 정보와 몇 가지 중복되는 사항들이 있다. 이 모든 데이터를 하나의 피드(feed)에 놓고, XML로 포맷하고, 이와 동시에 표준 애그리게이터를 사용하여 이 내용들이 검색되도록 할 수 있다. 바로 이것이 나의 애플리케이션과 다른 툴들을 구별하는 요소가 된다. Listing 6은 Atom 피드의 모습이다. (간략하게 도입 부문만 소개하고자 한다.)


Listing 6
				

<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

  <title>Fame not Fortune</title>
  <subtitle>Recent submissions</subtitle>
  <link href="http://example.org/famenotfortune"/>
  <updated>2006-12-03T20:37:16Z</updated>
  <author>
    <name>Daniela Elza</name>
  </author>
  <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
  <entry>
    <title>Hyacinth Blue</title>
    <link href="http://example.org/famenotfortune/hyacinthblue"/>
    <id>urn:uuid:68C0BAAB-C955-45F9-BDD6-21A22FC809AF</id>
    <updated>2006-12-01T20:37:16Z</updated>
    <published>2006-10-01T12:12:12Z</published>
    <category term="Journal"/>
    <content type="xhtml">
        <div xmlns="http://www.w3.org/1999/xhtml">
            <dl>
                <dt>publisher</dt><dd>Room of One's Own</dd>
                <dt>titles</dt><dd><ul>
                    <li>Hyacinth Blue</li>
                    <li>Fabrication</li>
                    <li>Thanksgiving</li>
                    <li>Spilling the Peas</li>
                </ul></dd>
                <dt>submitted</dt><dd>2005-05-10</dd>
                <dt>accepted</dt><dd>2005-09-01</dd>
                <dt>payment received</dt><dd>2006-09-01</dd>
                <dt>expenses</dt><dd><dl>
                    <dt>postage</dt><dd>CAD 1.12</dd>
                </dl></dd>
                <dt>payment</dt><dd><ul>
                    <li>CAD 50.00</li>
                    <li>2 Copies of Publication Issue</li>
                </ul></dd>
            </dl>
        </div>
    </content>
  </entry>
</feed>


Listing 6이 낯설지가 않다면, Atom Entry 엘리먼트에 데이터에 필요한 모든 필드들이 없고, 대부분의 엔트리가 <content/> 태그로 래핑된 XHTML 예제이기 때문일 것이다. published 필드와 author를 약간 변경할 수도 있었지만, published 필드의 남용일 뿐이다. 고유의 네임스페이스를 만들어서, 추가 필드로 Atom Entry를 확장할 수 있지만, 어떤 기존 애그리게이터나 피드 리더기도 그 정보를 사용할 수 없기 때문에 의미가 없다. 단순히 Atom 인벨롭으로 XHTML 예제를 래핑하여 애플리케이션에 동기화 지원을 할 수 있지만, 순수하게 데이터 지향 관점에서 본다면 Atom은 어떤 장점도 없다. 애플리케이션의 데이터를 이동할 때, Atom Entry로 래핑하고, Atom Publishing Protocol (참고자료)을 사용하면 도움이 될 것이다. Atom을 사용하고 싶다면, 데이터 포맷 선택에 제한이 생긴다. Atom <content/> 태그에는 세 가지 데이터 유형, 텍스트(JSON 포맷), HTML, XHTML이 포함된다. Atom을 먼저 확장하지 않고는, Atom에 임의의 XML 콘텐트를 삽입할 수 없다. 따라서, Atom 통합을 할 경우 다른 데이터 포맷 결정에도 영향을 줄 수 있기 때문에, 데이터에 동기화를 지원할 것인지의 여부를 먼저 결정해야 한다.




위로


예제

Ajax 웹 사이트나 웹 애플리케이션을 구현할 때 결정해야 할 것들이 많다. 기본적으로, 어떤 데이터 포맷을 사용할 것인지를 결정해야 한다. 나는 이 글을 통해서, 그러한 결정들을 내리는데 참조할 수 있는 몇 가지 제안을 했었다. 앞서 언급한 내용을 다시 반복하자면,

  • 데이터에는 JSON
  • 문서에는 XML (XHTML)
  • 신디케이션에는 Atom (Atom Publishing Protocol 지원)
공유 사이트...

digg Digg
del.icio.us del.icio.us
Slashdot Slashdot

여러 가지 대안들과 선택 원칙들을 설명했다. 물론, 모든 사안들 마다 특성을 갖고 있고, 예외는 어디에나 존재하기 때문에 어떤 것도 단정지을 수는 없다. 이 가이드라인이 나에게는 잘 맞았던 것처럼, 여러분에게도 도움이 되길 바란다. 의견이나 제안 사항이 있는 경우, 언제라도 환영한다.

기사의 원문보기



참고자료

교육

제품 및 기술 얻기

토론


필자소개

Photo of Dethe Elza

Dethe Elza는 http://livingcode.org/에서 적극적으로 활동하고 있다. 제안이나 권고 사항은 delza@livingcode.org로 보내기 바란다.


Photo of David Mertz

http://gnosis.cx/publish/를 방문하면 David Mertz(mertz@gnosis.cx)의 열정의 일면을 볼 수 있다. 어떤 제안이나 권고도 환영한다. http//gnosis.cx/TPiP/에서 그의 저서 "Text Processing in Python"을 만나볼 수 있다.



출처 : IBM developerworks
:
Posted by 뽀기

잘못된 유닉스 사용 패턴 고치기

 

JavaScript가 필요한 문서 옵션은 디스플레이되지 않습니다.



난이도 : 중급

Michael Stutz, Author, Consultant

2007 년 1 월 30 일

유닉스® 명령어(Unix Command Line) 조작에 있어서 효율성을 높일 수 있는 10가지 좋은 습관들을 익히고, 그릇된 사용 패턴을 고쳐봅시다. 본 기사는 유닉스 명령어 조작에 있어서 충분히 유용한 것인데도, 간과되는 기술들을 설명합니다. 또한, 본 기사에서 열거한 일반적인 에러 유형과 이를 해결하는 방법을 배우다 보면, 좋은 습관을 들이는 것이 왜 중요한지를 알게 될 것입니다.

머리말

시스템을 사용할 때, 일정한 사용 패턴으로 빠지는 경향이 있고, 가끔은 가장 좋은 방법을 제쳐놓을 때도 있다. 심지어, 좋지 않은 방법을 선택할 때도 있다. 이러한 모순을 타파하는 가장 좋은 방법은 좋은 습관을 의식적으로 익히는 것이다. 이 글에서는, 10 가지 좋은 명령행 사용 습관들을 제안한다. 일반적인 오류를 없앨 수 있는, 효과적인 명령행 작동을 위한 좋은 습관들이다. 이제부터 상세하게 설명하겠다.

10가지 좋은 습관

10가지 좋은 습관은 다음과 같다.

  1. 단 한번에 디렉토리 트리(directory Tree)를 만들어라.
  2. 압축 파일을 이동하지 말고, 경로를 변경하라.
  3. 명령어와 컨트롤 오퍼레이터(control operator)를 함께 사용하라.
  4. 쿼트 변수(Quote Variable)사용에 유의하라.
  5. 이스케이프 시퀀스(escape sequence)를 사용하여 긴 명령을 관리한다.
  6. 명령어들을 하나의 리스트로 그룹핑 한다.
  7. find 밖에서 xargs를 사용한다.
  8. grep이 카운팅을 수행할 때와, grep을 배제할 때를 알아야 한다.
  9. 라인이 아닌, 아웃풋에 특정 필드를 매치한다.
  10. cat 파이핑을 삼가하라.

단 한번에, 디렉토리 트리를 만들어라.

Listing 1은 유닉스 습관을 보여주고 있다. 디렉토리 트리를 한번에 하나씩 정의하고 있다.


Listing 1. 나쁜 습관 #1: 디렉토리 트리를 개별적으로 정의하고 있다.
				
~ $ mkdir tmp
~ $ cd tmp
~/tmp $ mkdir a
~/tmp $ cd a
~/tmp/a $ mkdir b
~/tmp/a $ cd b
~/tmp/a/b/ $ mkdir c
~/tmp/a/b/ $ cd c
~/tmp/a/b/c $

mkdir-p 옵션을 사용하고, 하나의 명령어에 모든 부모 디렉토리와 자식 디렉토리를 만드는 것이 훨씬 빠르다. 하지만 이 방법을 알고 있는 관리자 조차도 이렇게 하지 않는다. 좋은 습관이 몸에 배도록 노력해야 한다.


Listing 2. 좋은 습관 #1: 하나의 명령어로 디렉토리 트리를 정의한다.
				
~ $ mkdir -p tmp/a/b/c

이 옵션을 사용하여 전체적인 디렉토리 트리들을 만들 수 있다. 이것은 단순한 계층뿐만 아니라, 스크립트 내에서도 사용하기에 알맞다. 예를 들어:


Listing 3. 좋은 습관 #1: 하나의 명령어로 복잡한 디렉토리 트리를 정의한다.
				
~ $ mkdir -p project/{lib/ext,bin,src,doc/{html,info,pdf},demo/stat/a}

디렉토리들을 개별적으로 정의하는 것이 허용되는 때는, mkdir가 이 옵션을 지원하지 않았을 때이지만, 대부분의 시스템에서는 이제 지원된다. Single UNIX Specification에 순응하는 IBM, AIX®, mkdir, GNU mkdir 등은 이제 이 옵션이 지원된다.

이 기능이 없는 일부 시스템의 경우, 같은 기능을 수행하는 mkdir용 래퍼(wrapper)인, mkdirhier 스크립트 (참고자료)를 사용한다.

~ $ mkdirhier project/{lib/ext,bin,src,doc/{html,info,pdf},demo/stat/a}

압축 파일을 이동하지 말고, 경로를 변경하라.

또 하나의 나쁜 습관은 '.tar'와 같은 압축 파일을 해당 디렉토리에 압축을 풀려고 하는 경우, '.tar' 파일을 디렉토리에 옮겨 놓고 해당 디렉토리에서 압축 푸는 이중 작업을 하는 것이다.절대로 이렇게 해서는 안된다. 원하는 디렉토리에 .tar 압축 파일을 추출할 수 있다. -C 옵션이 하는 일이 바로 이것이다. 아래 Listing 4에서 알 수 있듯이, tar 명령어에서 -C 옵션은 원하는 디렉토리에 '.tar' 압축 파일을 풀 수 있게 한다.


Listing 4. 좋은 습관 #2: -C 옵션을 사용하여 .tar 압축 파일의 압축을 푼다.
				
~ $ tar xvf -C tmp/a/b/c newarc.tar.gz

-C(-c)는 아카이브 파일을 추출 대상 장소로 옮기고, 그 디렉토리를 변경하고, 내용의 압축을 풀 때 도움이 된다. 압축 파일을 지정 디렉토리에 풀려고 할 때, -c 옵션을 쓰는 습관을 들이는 것이 좋다.




위로


명령어와 컨트롤 오퍼레이터(control operator)를 함께 사용하라.

대부분의 쉘에서, 명령어들 사이에 세미콜론(;)이 있다면 이것이 명령어 결합이라는 것쯤은 알고 있을 것이다. 이 세미콜론은 쉘 컨트롤 오퍼레이터(control operator)이고, 여러 다른 명령어들을 하나의 명령행에 배열하는데 유용하지만, 모든 것에 적용되는 것은 아니다. 예를 들어, 세미콜론을 사용하여 두 개의 명령어들을 결합한다면, 첫 번째 명령어가 성공적으로 완료되었을 경우에만 두 번째 명령어가 올바르게 실행된다. 첫 번째 명령어가 예상했던 대로 종료되지 않았다면, 두 번째 명령어는 실행되지만, 실패하게 된다. 대신, 더 적합한 컨트롤 오퍼레이터(일부는 이 글에서 설명하겠다.)를 사용하라. 쉘이 지원하기만 한다면, 이러한 것을 사용하는 습관을 들이는 것이 좋다.

한 명령어가 Zero Exit Status를 리턴할 경우에만 다른 명령어가 실행된다.

&& 컨트롤 명령어를 사용하여 두 명령어들을 결합하면, 두 번째 명령어는, 첫 번째 명령어가 Zero Exit Status를 리턴할 때에만 실행된다. 다시 말해서, 첫 번째 명령어가 성공적으로 실행되면, 두 번째 명령어도 실행된다. 첫 번째 명령어가 실패하면, 두 번째 명령어는 전혀 실행되지 않는다. 예를 들어,


Listing 5. 좋은 습관 #3: 컨트롤 오퍼레이터를 사용하여 명령어들을 결합한다.
				
~ $ cd tmp/a/b/c && tar xvf ~/archive.tar

이 예제에서, 아카이브의 내용들은, (디렉토리가 존재한다면) ~/tmp/a/b/c 디렉토리로 추출된다. 이 디렉토리가 없다면, tar 명령어는 실행되지 않고, 어떤 것도 추출되지 않는다.

다른 명령어가 Non-zero Exit Status를 리턴할 경우에만 명령어를 실행한다.

마찬가지로, || 컨트롤 오퍼레이터는 두 개의 명령어를 분리하고, 첫 번째 명령어가 Non-zero Exit Status를 리턴할 때에만 두 번째 명령어를 실행한다. 다시 말해서, 첫 번째 명령어가 성공하면, 두 번째 명령어는 실행되지 않는다. 첫 번째 명령어가 실패하면, 두 번째 명령어가 실행된다. 이 오퍼레이터는 해당 디렉토리가 존재하는지 여부를 검사할 때 사용되고, 없을 경우에는 디렉토리를 만든다.


Listing 6. 좋은 습관 #3: 컨트롤 오퍼레이터로 명령어들을 결합한다.
				
~ $ cd tmp/a/b/c || mkdir -p tmp/a/b/c

이 섹션에 설명된 컨트롤 오퍼레이터들을 결합할 수도 있다. 각각 마지막 명령어 실행 시 작동한다.


Listing 7. 좋은 습관 #3: 컨트롤 오퍼레이터로 명령어들을 결합한다.
				
~ $ cd tmp/a/b/c || mkdir -p tmp/a/b/c && tar xvf -C tmp/a/b/c ~/archive.tar




위로


쿼트(quote) 변수 사용에 유의하라!

쉘 확장과 변수 이름에 언제나 주의하라. 특별한 이유가 없다면, 더블 쿼테이션 마크로 변수 호출을 표시하는 것이 좋다. 마찬가지로, 변수 이름 뒤에, 영숫자(alphanumeric) 텍스트를 붙인다면, 변수 이름에 중괄호({})를 사용하여 이것을 주위 텍스트와 구분한다. 그렇지 않으면, 뒤따르는 텍스트를 변수 이름의 일부로 인터프리팅 하고, 대게는 null 값을 리턴할 것이다. Listing 8은 변수에 쿼테이션을 붙이거나 붙이지 않을 경우의 예제와, 그 결과이다.


Listing 8. 좋은 습관 #4: 변수에 쿼테이션 마크 달기 또는 달지 않기
				
~ $ ls tmp/
a b
~ $ VAR="tmp/*"
~ $ echo $VAR
tmp/a tmp/b
~ $ echo "$VAR"
tmp/*
~ $ echo $VARa

~ $ echo "$VARa"

~ $ echo "${VAR}a"
tmp/*a
~ $ echo ${VAR}a
tmp/a
~ $




위로


이스케이프 시퀀스를 사용하여 긴 인풋을 관리한다.

백슬래시(\)를 사용하여 긴 라인을 다음 라인으로 넘기는 코드 예제를 보았을 것이다. 그리고, 대부분의 쉘에서는 백슬래시가 붙은 연속 라인들을 하나의 긴 라인으로 취급한다는 것도 알고 있다. 하지만, 터미널이 멀티 라인(multi-line) 래핑을 적절하게 다루지 못하거나, 명령어 라인이 평균 이하로 작을 때(프롬프트에 긴 경로가 있을 경우,) 백슬래시는 더욱 유용하게 사용된다. 이처럼 백슬래시는 또한 긴 인풋 라인에도 유용하게 사용된다.


Listing 9. 좋은 습관 #5: 긴 인풋에 백슬래시를 사용한다.
				
~ $ cd tmp/a/b/c || \
> mkdir -p tmp/a/b/c && \
> tar xvf -C tmp/a/b/c ~/archive.tar

대신, 다음과 같은 설정도 유효하다.


Listing 10. 좋은 습관 #5: 긴 인풋에 백슬래시를 사용한다.
				
~ $ cd tmp/a/b/c \
>                 || \
> mkdir -p tmp/a/b/c \
>                    && \
> tar xvf -C tmp/a/b/c ~/archive.tar

인풋 라인이 여러 라인들로 나뉘지만, 쉘은 언제나 이것을 하나의 연속 라인으로 취급한다.

주: 대부분의 쉘에서, 위쪽 화살표 키를 누르면, 전체 멀티 라인 엔트리가 하나의 긴 인풋 라인으로 다시 모아진다.




위로


명령어들을 하나의 리스트로 그룹핑 한다.

대부분의 쉘은 명령어들을 하나의 리스트로 그룹핑 하여, 모든 아웃풋을 파이프라인 밑으로 전달하거나, 스트림의 전체 또는 일부를 같은 장소로 보낸다. 일반적으로, 하위 쉘에서 명령어 리스트를 실행하거나, 현재 쉘에서 명령어 리스트를 실행한다.

하위 쉘에서 명령어 리스트를 실행한다.

명령어 리스트를 하나의 그룹으로 묶을 때 괄호를 사용한다. 명령어를 새로운 하위 쉘에서 실행하고, 아웃풋을 리다이렉션 하거나 모을 수 있다.


Listing 11. 좋은 습관 #6: 하위 쉘에서 명령어 리스트를 실행한다.
				
~ $ ( cd tmp/a/b/c/ || mkdir -p tmp/a/b/c && \
> VAR=$PWD; cd ~; tar xvf -C $VAR archive.tar ) \
> | mailx admin -S "Archive contents"

이 예제에서, 아카이브의 콘텐트는 tmp/a/b/c/ 디렉토리로 추출되지만, 추출된 파일 리스트를 포함하여, 그룹으로 나뉜 명령어들의 아웃풋은 admin 주소로 메일링 된다.

명령어 리스트의 환경 변수를 다시 정의하고 있고, 이것이 현재 쉘에 적용되는 것을 원치 않을 경우, 하위 쉘을 사용하는 것이 좋다.

현재 쉘에서 명령어 리스트를 실행한다.

현재 쉘에서 실행할 명령어 리스트를 중괄호({})로 묶는다. 괄호 사이에 스페이스와 실제 명령어가 들어가도록 한다. 그렇지 않으면, 쉘은 괄호를 올바르게 인터프리팅 하지 않는다. 또한, 리스트의 마지막 명령어는 세미콜론으로 끝나야 한다.


Listing 12. 좋은 습관 #6: 현재 쉘에서 명령어 리스트를 실행한다.
				
~ $ { cp ${VAR}a . && chown -R guest.guest a && \
> tar cvf newarchive.tar a; } | mailx admin -S "New archive"




위로


find 밖에서 xargs를 사용한다.

find 명령어에서 모은 아웃풋을 활용하기 위한 필터로서 xargs 툴을 사용하라. find는 일정 기준에 맞는 파일 리스트를 제공한다. 이 리스트는 xargs로 전달되고, 이것은 인자로서 그 파일 리스트와 함께 기타 유용한 명령어를 실행한다.


Listing 13. xargs 툴의 기본적인 사용 예제
				
~ $ find some-file-criteria some-file-path | \
> xargs some-great-command-that-needs-filename-arguments

하지만, xargsfind의 헬퍼 정도로만 생각하지 말라. 이것은 활용도가 너무 낮다. 이것을 사용하는 습관을 들이면, 다음과 같은 사용법을 포함하여 무엇이든 할 수 있다.

공백으로 구분된(space-delimited) 리스트를 전달한다.

가장 단순한 호출에서, xargs는 리스트(한 라인에 각 멤버를 갖고 있음)를 인풋으로서 취하는 필터와 같다. 이 툴은 그러한 멤버들을 공백으로 구분된(space-delimited) 라인에 놓는다.


Listing 14. xargs 툴의 아웃풋 예제
				
~ $ xargs
a
b
c
Control-D
a b c
~ $

xargs를 통해 파일 이름을 만들어 내는 툴의 아웃풋을 보내서, 파일 이름을 인자로서 취하는 다른 툴에 대한 인자 리스트를 얻을 수 있다.


Listing 15. xargs 툴 사용 예제
				
~/tmp $ ls -1 | xargs
December_Report.pdf README a archive.tar mkdirhier.sh
~/tmp $ ls -1 | xargs file
December_Report.pdf: PDF document, version 1.3
README: ASCII text
a: directory
archive.tar: POSIX tar archive
mkdirhier.sh: Bourne shell script text executable
~/tmp $

xargs 명령어는 파일 이름을 전달하는 것 외에도, 유용하게 쓰인다. 텍스트를 한 라인으로 필터링 해야 한다면 언제든지 사용하라.


Listing 16. 좋은 습관 #7: xargs 툴을 사용하여 텍스트를 한 줄로 필터링 한다.
				
~/tmp $ ls -l | xargs
-rw-r--r-- 7 joe joe 12043 Jan 27 20:36 December_Report.pdf -rw-r--r-- 1 \
root root 238 Dec 03 08:19 README drwxr-xr-x 38 joe joe 354082 Nov 02 \
16:07 a -rw-r--r-- 3 joe joe 5096 Dec 14 14:26 archive.tar -rwxr-xr-x 1 \
joe joe 3239 Sep 30 12:40 mkdirhier.sh
~/tmp $

xargs를 사용할 때 주의할 점

드물긴 하지만, xargs 사용할 때 문제가 생기는 경우도 있다. 기본적으로, "end-of-file" 스트링은 언더스코어(_)이다. 이 문자가 인풋 인자로서 보내지면, 이 뒤에 모든 것이 무시된다. 이것에 대한 대응책으로서, -e 플래그를 사용한다.




위로


grep이 카운팅을 수행할 때와, grep을 배제할 때를 알아야 한다.

아웃풋 라인의 수를 세기 위해서 grepwc -l로 파이핑(piping) 하지 말라. -c 옵션이 특정 패턴과 매치되는 라인의 수를 제공하고, 이것이 일반적으로 wc 파이핑 보다 빠르다.


Listing 17. 좋은 습관 #8: grep을 사용하여 라인을 수를 센다.
				

~ $ time grep and tmp/a/longfile.txt | wc -l
2811

real    0m0.097s
user    0m0.006s
sys     0m0.032s
~ $ time grep -c and tmp/a/longfile.txt
2811

real    0m0.013s
user    0m0.006s
sys     0m0.005s
~ $ 

속도 외에도, -c 옵션은 카운팅 능력도 탁월하다. 여러 파일들이 있을 경우, grep-c 옵션은 각 파일에 대한 개별 카운트를 각 라인에 하나씩 리턴하는 반면, wc에 대한 파이프는 결합된 모든 파일들에 대한 총계를 리턴한다.

하지만, 속도와 상관 없이, 이 예제에는 또 다른 에러가 있다. 이 카운팅 메소드는 매칭(matching) 패턴들을 포함하고 있는 라인의 수만 카운팅 한다. 이것을 원했다면 괜찮다. 하지만, 라인들에 특정 패턴에 대한 여러 인스턴스들이 있는 경우, 이러한 메소드들은 실제 매칭 인스턴스들의 수를 리턴하지 않는다. 인스턴스의 수를 카운트 하려면, wc를 사용하여 카운트 해야 한다. 우선, 버전이 지원한다면, grep 명령어와 -o 옵션을 실행하라. 이 옵션은 각 라인에 하나씩, 매칭 패턴만 제공한다. 하지만, -c 옵션과 함께 사용할 수 없기 때문에, wc -l을 사용하여 라인을 카운트 한다.


Listing 18. 좋은 습관 #8: grep으로 패턴 인스턴스를 카운트한다.
				
~ $ grep -o and tmp/a/longfile.txt | wc -l
3402
~ $

이 경우, wc 호출은, 각 라인을 찾아 카운팅 하기 위해 사용된 더미 패턴을 이용한 grep 호출(grep -c) 보다 빠르다.




위로


단순한 라인이 아닌, 아웃풋에 특정 필드를 매치한다.

단순한 라인이 아닌, 아웃풋 라인에 있는 특정 필드에만 있는 패턴과 매치해야 할 때, grep 보다 awk 같은 툴이 더욱 선호된다.

다음 예제는 12월(December)에 수정된 파일들만 리스트 하는 방법이다.


Listing 19. 나쁜 습관 #9: grep을 사용하여 특정 필드에 있는 패턴을 찾는다.
				
~/tmp $ ls -l /tmp/a/b/c | grep Dec
-rw-r--r--  7 joe joe  12043 Jan 27 20:36 December_Report.pdf
-rw-r--r--  1 root root  238 Dec 03 08:19 README
-rw-r--r--  3 joe joe   5096 Dec 14 14:26 archive.tar
~/tmp $

이 예제에서, grep은 라인을 필터링 하면서, 날짜와 이름에 Dec가 있는 모든 파일들을 만들어 낸다. 따라서, 1월(January) 이후에는 수정되지도 않은 December_Report.pdf 같은 파일도 매칭된다. 이것은 우리가 원한 것은 아니다. 특정 필드에서 패턴을 찾으려면, awk를 사용하는 것이 더 낫다. 여기에서 관계형 오퍼레이터가 정확한 필드를 매치한다.


Listing 20. 좋은 습관 #9: 특정 필드에서 패턴을 찾을 때 awk를 사용한다.
				
~/tmp $ ls -l | awk '$6 == "Dec"'
-rw-r--r--  3 joe joe   5096 Dec 14 14:26 archive.tar
-rw-r--r--  1 root root  238 Dec 03 08:19 README
~/tmp $

awk에 대한 자세한 내용은 참고자료를 참조하라.




위로


cat 파이핑을 금한다.

가장 기본적이면서도 일반적인 grep 사용에 대한 오류는 단일 파일의 내용을 검색함에 있어서 cat의 결과를 파이핑하는 예가 있다. 즉, grep은 파일 이름을 인자로 취하기 때문에 굳이 cat 명령어를 취하는 것은 시간낭비이며 불필요한 습관이다. 아래의 Listing 21은 그의 일례를 보여준다.


Listing 21. 좋은 습관과 나쁜 습관 #10: cat 없이 grep 사용하기와 cat과 함께 grep사용하기
				
~ $ time cat tmp/a/longfile.txt | grep and
2811

real    0m0.015s
user    0m0.003s
sys     0m0.013s
~ $ time grep and tmp/a/longfile.txt
2811

real    0m0.010s
user    0m0.006s
sys     0m0.004s
~ $ 

위와 같은 실수는 다른 명령어에도 범하기 쉬운 케이스이다. 대부분의 명령어는 하이픈(-)를 이용하여 표준 입력(standard input)을 인자로 취하기 때문에, 여러 파일을 stdin에 배치하기 위해 cat을 사용할 필요가 없는 것이다. 즉, cat 이후 파이핑을 사용할 때는 오로지 "여러 가지 필터링 옵션과 더불어 cat을 사용할 때"만 사용하라.




위로


결론: 좋은 습관 들이기

자신의 명령행 사용 패턴을 한번 점검해 보라. 나쁜 습관이 본인의 성장을 방해하고, 예기치 못한 에러를 만들 수 있다. 이 글에서는 일반적인 사용 오류를 타파할 수 있는 새로운 습관들을 소개했다. 이러한 좋은 습관들을 익혀서 여러분의 유닉스 명령행 스킬이 더욱 향상될 수 있기를 바란다.

공유 사이트...

digg Digg
del.icio.us del.icio.us
Slashdot Slashdot

기사의 원문보기



참고자료

교육

제품 및 기술 얻기

토론


필자소개

Photo of Michael Stutz

Michael Stutz는 The Linux® Cookbook 의 저자이다. 디지털 출판에 관심을 갖고 있다. 20년 동안 다양한 유닉스 운영 체계를 사용해 왔다. (



출처 : IBM developerworks

'그거 > Tech' 카테고리의 다른 글

05. XML 스트림 (SAX)  (0) 2007.02.14
04. DOM의 활용(고급편)  (0) 2007.02.14
03. XML 문서의 처리 - DOM  (0) 2007.02.14
02. XML 문서와 application의 설계  (0) 2007.02.14
01. XML 문서의 기본 구조  (0) 2007.02.14
:
Posted by 뽀기
2007. 2. 7. 15:21

4년을 준비했다, 디자이너여 오라! 그거/Issue2007. 2. 7. 15:21


조광현 기자 ( ZDNet Korea )   2007/02/07
마이크로소프트가 어도비가 갖고 있는 웹 디자이너 전용 툴 시장에 야심찬 도전장을 내밀었다.

4년의 개발 준비기간을 거친 마이크로소프트의 야심작은 ‘익스프레션 스튜디오(Expression Studio)’이다. 익스프레션 스튜디오는 개발자를 위한 비주얼 스튜디오의 연속선상에 놓여있다. 왜냐하면 MS는 익스프레션 스튜디오가 개발자와 디자이너의 협업을 최적화하고, 프로젝트 시간을 혁신할 수 있다는 점에 초점을 맞추고 있기 때문이다.


마이크로소프트의 UX 담당 포레스트 키(Forest Key) 총괄 책임 이사는 “현재의 프로젝트의 워크플로우를 보면 디자이너가 디자인한 비주얼이 개발자에게 전달되어 작업이 진행되면 최종 결과물이 디자이너의 비주얼을 그대로 나타내지 못하는 경우가 매우 많았다”면서 “이것은 상호간의 협업을 방해하고, 개발 기간을 늘리는 결과를 초래해 프로젝트 전체에 큰 압박을 주었다”고 지적했다.

익스프레션 스튜디오는 이런 문제를 해결하는 최적의 통합 패키지라는 것. MS가 제시하는 해결 방안의 핵심 기술은 XAML(eXtensible Application Markup Language)과 WPF(Windows Presentation Foundation)이다.

XAML이 핵심 기술인 것은 기존에는 디자이너의 디자인 작업 결과를 개발자에게 넘겨 주면 비주얼을 보고 그에 해당하는 개발 과정을 진행하는 방식이었다. 하지만 익스프레션 스튜디오를 이용하면 디자인 결과물이 바로 XAML 코드로 곧바로 생성되기 때문에 개발자는 이 코드를 그대로 전달받아 개발 작업을 진행하면 된다는 것이다.

익스프레션 스튜디오 패키지의 하나인 익스프레션 블렌드(Expression Blend)가 바로 이런 작업을 수행하는 툴로 풍부한 UX를 제공하는 인터랙티브 디자인을 가능하게 한다는 것.

WPF는 익스프레션 스튜디오를 위한 기술은 아니지만 .NET 프레임워크에 포함되는 것으로 그래픽 엔진의 일종이다. WPF에 대응하는 애플리케이션은 기존 기술과 다른 발전된 UX를 경험할 수 있게 해주는 기반이 될 것으로 기대되고 있다.

포레스트 키 이사는 익스프레션 스튜디오를 발표하는 자리에서 WPF 기반으로 개발된 뉴욕타임즈의 웹 사이트를 시연해 보였다.

익스프레션 스튜디오는 익스프레션 웹(Expression Web), 익스프레션 블렌드(Expression Blend), 익스프레션 디자인(Expression Design), 익스프레션 미디어(Expression Media)로 구성된 통합 패키지의 총칭이다.

익스프레션 웹은 위지윅(WYSIWYG) 툴로 XML, HTML 등 표준화된 웹 사이트 구축 전문 툴로 프런트페이지의 상위 버전 격이다.

익스프레션 블렌드도 역시 위지윅 툴이고, XAML을 지원해 디자이너와 개발자의 공동 작업용 툴이다.

익스프레션 디자인은 그래픽 전용 툴로 벡터와 비트맵을 동시에 지원한다. 퓨처하우스 익스프레션이라는 기업을 인수하면서 내놓게 된 제품이다.

익스프레션 미디어는 디지털 자산관리 및 인코딩 툴이다. 이것도 역시 영국의 작은 기업을 인수해 내놓은 제품이다.

어도비와의 경쟁 불가피
원하든 원하지 않든 MS는 익스프레션 스튜디오를 내놓음으로써 어도비와 경쟁할 수밖에 없는 입장에 놓이게 되었다.

양사의 경쟁은 풍부한 UX를 위한 사용자의 선택을 가져오게 됐고, 결과적으로는 더 풍부한 UX 즉, RIA(Rich Internet Application)의 개발을 유도하게 될 것으로 예상된다.

경쟁의 포인트는 개발자에게 취약점을 갖고 있는 어도비와 디자이너에게는 이제 새롭게 선보이는 MS의 익스프레션 스튜디오가 어떻게 상호간의 취약점을 극복하느냐에 있다.

어도비 역시 이런 문제를 극복하기 위해 플렉스, 아폴로 등 새로운 기술과 비전을 발표하고 나섰기 때문에 경쟁의 양상은 더욱 흥미롭게 전개되고 있다.

이에 대해 포레스트 키 이사는 “디자이너와 개발자가 원하는 가치를 제공하겠다. 성공하기 위해서는 디자이너를 위한 성공적인 성능을 제공해야 할 것인데, 어도비가 현재 그렇다고 말할 수는 없다. 이제부터 시작이다. “라고 말했다.

현재 익스프레션 웹은 이미 출시된 상태로 제품 구입이 가능하며, 나머지 제품은 5월 28일 발표될 예정이다. 익스프레션 스튜디오 통합 패키지의 가격은 60만원 대로 알려졌으며, 개별 제품으로 구입하면 익스프레션 웹은 30만원대(프런트페이지를 보유한 경우 10만원대), 익프레션 블렌드, 익스프레션 미디어는 각각 50만원대, 30만원 대이다. @
출처 : ZDNet Korea.
:
Posted by 뽀기
2007. 2. 6. 18:07

words that make me crazy....... 그거/Issue2007. 2. 6. 18:07

XML
DOM
AJAX
POJO
JSTL
Struts
Spring
EJB
Taglib
Expression Language
Velocity
Freemaker
FLEX
Ant
Avalon
Excalibur
Logging
POI
Regexp

these make me crazy.... ㅜㅜ
:
Posted by 뽀기
2007. 2. 6. 17:24

Daily English 2007.02.06 생활/영어2007. 2. 6. 17:24

have a picky taste
=> 눈이 높다. 까다롭다.
=> She is too picky
=> She has a picky taste about shoes.

I am going to watch TV tonight
I will watch TV tonight
I would like to watch TV tonight
How fas were you dring when you were hit?
Briteny Spears has been singing since she was a child

benefit
=> something that gives you advantages or imporves your life in some way
=> an aid program that has brought lasting benefits to the region

profit
=> money that you gain by selling or doing business
an advantage that you gain from doing something

A : Ally left Seoul for good. Do you know why?
B : I don't know
A : Then, do you have any idea why she cried the last day at the office?
B : Beats me. I didn't even notice she was there.

Beats me
=> I have no idea.
=> I haven't got a slice of idea.

The world is your oyster!
=> 세상을 다 가져라
one's oyster
=> (사람이 이용할 수 있는) 유리한 것, 마음대로 할 수 있는 것


entrepreneur
=> a person who organizes and manages an enterprise , esp. a business, usu. with considerable initiative and risk
=> His achievements rivaled those of an earlier generation of entrepreneur

subject
=> matter, topic, person, dependent; ruled by a monarch or goverment
=> The subject of my talk will be "Marketing in Lating America" and I hope it will be of interest to your advertising executives.
=> Participation in Midwest Airline's frequent flier's program is subject to the terms and conditions of the program rulers.

flashy
=> marked by conspicuous display
=> Several directors cringed a trecalling their first sight of the bank's new headquarters late last year,
   with its marble panels, mirrored ceilings and flashy panoply of sculptures and wall hangings.

delinquency
=> an antisocial misdeed in violation of the law by a minor
=> Many criminologists believe that today's stronger family contributes to the decline in delinquency.

condense
=> to decrease the volume, size or density of, to concentrate something
=> When condensing gas, keep the following points in mind

drab
=> dreary
=> The hypnotist told him in drab tones that he was becoming more relased and sleepy.

misuse
=> improper use, excessive use
=> There is little that can be done to prevent this kind of misuse of computer power.
=> Misuse of credit cards can cause terrible financial problems.

outstanding balance
=> a fee that hasn't been paid yet
=> According to our records, your account shows an outstanding balance of $866.25 for 150 sacks of Portland cement that were delivered on April 8(invoice #2587; your purchase order #BS851, copies enclosed)

'생활 > 영어' 카테고리의 다른 글

Daily English 2007.02.15  (0) 2007.02.15
Daily English 2007.02.13  (0) 2007.02.13
Daily English 07.02.12  (0) 2007.02.12
Daily English 07.02.01  (0) 2007.02.01
Daily English 07.01.30  (0) 2007.01.30
:
Posted by 뽀기

류준영 기자 ( ZDNet Korea )   2007/02/05
한국후지필름은 디지털 렌즈 교환식 카메라(DSLR) ‘파인픽스 S5Pro’를 출시한다고 5일 밝혔다.

한국후지필름 관계자는 “파인픽스 S5Pro는 파인픽스S3Pro을 선보인 이후 2년 만에 내놓은 제품으로 총 1,234만 유효화소를 지원하며, ISO 3200의 고감도에서도 해상력 손실 없이 노이즈가 최대한 억제된 고화질 사진을 촬영할 수 있다.”고 설명했다.



파인픽스 S3Pro부터 400%까지 지원해온 다이나믹 레인지는 S5Pro에서는 네거티브 필름에 육박하는 관용도를 지원해, 기존의 3단계에서 7단계로 세분화된 설정 모드로 늘렸다.

이 제품의 이색적인 기능은 바로 ‘필름 시뮬레이션 모드’. 필름과 같은 이미지 촬영을 지원하는 이 기능은 사용자의 촬영 의도에 맞춰 특수한 필름을 선택해 촬영하는 것과 같은 연출이 가능하다. 파인픽스 S5Pro의 판매가는 198만원@

편집자주:
- 23.0mm × 15.5mm 허니컴 SuperCCD SR Pro 탑재
- 5가지의 필름 시뮬레이션 모드
- S화소 617만, R화소 617만 화소 등 총 1234만 유효화소
- ISO3200 초고감도 지원
- 페이스 줌인 기능
- RAW/JPEG 동시 기록
- XD 메모리카드/CF Type 1,2 지원
- 11점 측거 AF 모듈
- 0.94배율의 넓은 파인더
- 2.5인치, 23만 컬러의 LCD 모니터
- 경량 마그네슘 합금 바디
- 고속 동조 가능
- i-ttl 가능한 조광 시스템
- Face Detection(얼짱나비) / Wireless Lan 전송 / 컬러 라이브뷰 가능
출처 : ZDNet Korea.
:
Posted by 뽀기

조광현 기자 ( ZDNet Korea )   2007/02/05
국 내 소프트웨어(SW) 테스팅 전문가 그룹인 STEN(Software Test Engineers Network, 대표 권원일)과 테스트 컨설팅 전문 회사인 STA(Software Testing Alliances)는 SW 테스팅 분야의 세계적인 권위자인 에릭 반 비넨달(Erik van Veenendaal)을 초청, 2007년 3월 5일부터 9일까지 5일간 고급 SW 테스팅 교육 과정을 한국 IBM 빌딩에서 진행한다.

SW 테스팅 경험이 있는 기초과정(Foundation Level)의 능력을 갖춘 실무자들을 대상으로 하는 이번 전문가 교육과정은 고급과정(Advanced Level) 테스팅 실습 강의를 중심으로 국제적으로 널리 인정받는 ISTQB Advanced Level 자격증 취득준비를 지원하며 SW 테스팅의 세계적인 모범사례와 새로운 테스팅 트렌드를 공유하는 자리가 될 것이다.

이번 교육 과정의 강사인 에릭 반 비넨달은 이 분야 베스트셀러인 ‘테스팅 프랙티셔너(The Testing Practitioner)’의 저자로 20여 년간의 테스팅 실무 및 컨설팅 경험이 있는 전문가다. 그는 지멘스 VDO와 필립스 반도체의 임베디드 소프트웨어 테스트 프로젝트에 참여했으며, 현재 소프트웨어 테스팅 국제자격위원회(ISTQB)의 부의장직과 네덜란드 테스팅 국제자격위원회(DTQB)의 의장직을 겸하고 있다.

STEN의 권원일 대표는 “이번 교육 과정은 일본·중국에서도 아직 진행된 적이 없는 국제적인 SW 테스팅 전문가에 의한 강의로, 실무능력을 고급수준으로 향상시키고 다양한 정보와 관련지식을 공유할 수 있는 좋은 기회” 라며 “전세계적으로 공인되는 ISTQB의 고급 레벨 자격증을 국내에서 최초로 취득하기 위한 좋은 준비과정으로, SW 테스팅 전문가로서의 경력관리에도 도움이 될 것이다” 라고 덧붙였다.

교육 내용은 테스트 관리와 리뷰&인스펙션, 테스트 기법과 테스트 개선, 자격증 실험 훈련의 총 5개 영역으로 구분되어 진행된다. 이번 교육과정에는 우리나라 테스팅업계의 실무 전문가들 다수가 참여하므로 SW 테스팅에 대한 다양한 현업 사례와 최신기법들을 공유하는 자리로 인적 네트워크를 형성할 수 있는 좋은 기회가 될 전망이다. 또한 5일간의 일정으로 진행되는 교육 기간 동안 세계적 수준의 전문가와 다른 참여자들과의 커뮤니케이션을 통해 현업에서 부딪치는 SW 테스팅과 관련된 궁금증이나 문제들을 해결할 수 있는 간접적인 컨설팅을 받을 수 있다는 것도 하나의 메리트이다.

2월 3일 마감된 조기등록에 이은 정상등록기간은 2월 4일부터 3월 4일까지로, STEN 홈페이지(www.sten.or.kr)에서 등록 가능하다. 교육비용은 미국과 유럽에서 동일한 교육 이수시 소요되는 비용 보다 약 40% 저렴한 275만원(부가세 포함)이다. (강의관련 문의:02-6203-6775) @

출처 : ZDNet Korea
:
Posted by 뽀기

유윤정 기자 ( ZDNet Korea )   2007/02/05
다음커뮤니케이션 (www.daum.net)과 NHN(www.naver.com)이 오픈 API에 대한 이용자들의 관심과 참여를 확대하기 위해 ‘2007 대한민국 매쉬업 경진대회’를 공동 개최한다.

이번 경진대회는 국내 인터넷 선도업체인 네이버와 다음이 공동으로 진행하는 첫번째 대회로 전문 개발자 뿐만 아니라 학생 및 일반 이용자를 대상으로 진행되며, 참가를 원하는 이용자는 3월 31일까지 다음과 네이버 및 국내외 공개된 다양한 API로 자신만의 참신한 매쉬업을 제작해 대회 공식 홈페이지(www.mashupkorea.org)에 등록하면 된다.

다음과 NHN은 2월 25일과 3월 1일에 각각 서울 연세대와 대전 KAIST에서 매쉬업 캠프를 개최해 오픈 API 및 매쉬업에 대한 정보를 제공할 뿐 아니라, 간단한 아이디어 코드를 구현해보는 기회를 제공함으로써, 이용자들이 경진대회를 보다 알차게 준비할 수 있도록 지원한다.

또한, 양사는 공식 홈페이지를 통해 접수된 이용자들의 매쉬업을 전문 심사위원단의 심사를 거쳐 우수 8개팀을 선정하고, 4월 5일 분당에 위치한 NHN 본사에서 본선대회를 진행할 예정이다.

본선참가자들의 매쉬업 코드는 전문 웹 개발자들과 일반 이용자들이 참고할 수 있도록 공개돼, 이들의 아이디어를 통해 또다른 편리한 매쉬업이 제작될 수 있을 것으로 기대된다.

이번 대회의 본선 참가자들은 향후 양사 입사지원시 서류전형 통과의 특혜를 받게 되며, 대상(1팀), 우수상(2팀), 장려상(4팀), 특별상(1팀)에게는 각각 300만원, 200만원, 100만원씩의 상금이 주어진다.

NHN 함종민 NSO(Naver Strategy Officer)는 “이용자들이 직접 서비스를 제작하고 공유하는 것이야말로 개방과 참여, 소통의 웹 2.0 시대의 핵심”이라며, “이번 대회를 통해 오픈 API에 대한 이용자들의 관심과 참여가 확대돼, 이용자들이 누구나 자신에게 최적화된 서비스를 제작하고 이용할 수 있게 되기를 기대한다”고 밝혔다.

다음 원종필 TR(Tech Resource)본부장은 “차세대 기술 트렌드를 주도해 나갈 개발자를 꿈꾸는 일반인 및 대학생들에게 새로운 교육 기회를 제공하고자 이번 경진대회를 주최하게 되었다”며, “향후에도 국내 오픈 API의 지속적인 저변 확대로 웹 2.0 트렌드를 주도해 나갈 수 있는 창의적 서비스 개발에 다양한 노력을 펼쳐나갈 것”이라고 밝혔다.@

출처 : ZDNet Korea
:
Posted by 뽀기
Martin LaMonica ( CNET News.com )   2007/02/01  

IBM은 전세계에 분산해 일하는 팀들의 프로그래밍 작업을 촉진시키기 위해 재즈(Jazz)라는 이름의 오픈 소스 프로젝트를 준비하고 있다.

오는 6월 재즈닷넷(Jazz.net)에서 시작하게 될 이 프로젝트는 지리적으로 분산된 협업 소프트웨어 개발과 관련된 IBM 리서치 및 IBM의 레이셔널(Rational) 툴 사업부의 연구 결과를 토대로 삼을 예정이다.

IBM 레이셔널의 총괄 매니저인 대니 사바(Danny Sabbah)는 이 프로젝트의 주목표는 현재 규범화되고 있는 분산된 소프트웨어 개발 작업의 표준을 확립하는 것이라고 말했다.

그 동안 개발 툴은 주로 개별적인 프로그래머들이 더 생산적이 되게 하는 것에 초점을 맞추었다. 하지만 소프트웨어 개발이 점점 복잡해지면서 IBM, 마이크로소프트(MS) 및 기타 회사들은 응용프로그램 요구사항 수집부터 테스트에 이르기까지 전체 개발 사이클이 관련된 제품을 만드는 데 초점을 맞추게 됐다.

뿐만 아니라 사바가 언급한 것처럼 해외 팀이나 서로 다른 장소에서 일하는 비즈니스 파트너들과 함께 소프트웨어를 개발하는 일이 점점 많아지고 있다.

사바는 “그렇기 때문에 개발 방식을 근본적으로 다시 생각해야 한다”면서 “더 이상 개별적인 개발자 툴을 다루는 것은 생각하지 않는다. 그것은 정해진 것이다. 훨씬 더 흥미 있는 것은 전체 소프트웨어 개발 프로세스를 더 잘 이해하는 것”이라고 말했다.

사바는 재즈 소프트웨어는 기존의 협업 툴과 프로토콜을 분산형 개발에 맞춰 협업 소프트웨어 개발을 향상시키려는 것이라고 설명했다.
대니 사바 IBM 레이셔널 총괄 매니저

예를 들어 재즈 소프트웨어에서는 프로그래머가 소스 코드에 대해 동료에게 인스턴트 메시지를 보낼 수 있다. 수신인은 정적인 텍스트를 보는 것이 아니라 그 코드가 그 응용 프로그램에 끼워지는 부분, 원래의 요구 사항 및 관련된 테스트를 보게 된다.

사바는 IBM이 재즈 소프트웨어를 애드온 제품으로 확장하고 소비자 가전제품을 위한 코드 개발과 같은 구체적인 목적에 맞춰 수정할 수 있는 모델을 개발하고 있다고 말했다.

그는 6월이 되면 IBM이 재즈를 기존의 레이셔널 개발 패키지에 집어넣는 방법도 검토할 것이라고 말했다. 그는 이 소프트웨어의 무료 버전을 재즈닷넷에서 구할 수 있을 것이며 기능이 더 많은 유료 버전도 나올 것으로 내다봤다.

레드몽크(RedMonk)의 분석가인 스티븐 오그래디(Stephen O'Grady)는 재즈가 인터넷을 통해 작업하는 팀들에게 더욱 도움이 되도록 툴을 수정하는 전체 시장의 추세를 반영한다고 말했다.

오그래디는 “전부는 아니라도 꽤 많은 개발자들이 지리적으로 분산된 방식으로 일을 한다”며 “재즈 덕분에 개발 프로세스에 서로 일하는 방식을 느낄 수 있는 수단이 덧붙여지는 것”이라고 말했다.

그는 재즈가 지닌 그 외의 첨단 요소들은 에이젝스(Ajax)를 사용해 구축한 멋진 웹 기반 사용자 인터페이스와 인스턴트 메시징과의 통합이라고 덧붙였다.

이클립스의 재등장?
IBM은 재즈 프로젝트에서 소프트웨어 판매업체들과 프로그래머들이 널리 사용하던 오픈 소스 개발 프레임워크인 이클립스(Eclipse)에서 거둔 성공을 발판으로 삼으려고 하고 있다.

2001년 IBM은 개발 툴 애드온을 만드는 프레임워크 역할을 하는 이클립스 소프트웨어와 관련된 컨소시엄을 창설했다. 현재 오픈 소스 단체 하나와 IBM을 포함한 많은 소프트웨어 회사들이 이클립스를 채택했고 데이터베이스 작업이나 에이젝스식 웹 응용프로그램을 만드는 것과 같은 특정한 목적을 위한 플러그인을 제작했다.

사바는 IBM의 의도가 재즈를 통해「프레임워크」를 오픈 소스화해 제3자가 확장 버전을 개발할 수 있게 하려는 것이라고 설명했다. 예를 들어 다른 회사들은 재즈 소프트웨어 보완판을 만들어서 팀을 더욱 생산적으로 만들거나 특정 산업 분야에 맞는 애드온을 만들 수 있다.

재즈 소프트웨어는 이클립스와 함께 사용하게 돼 있지만 MS의 비주얼 스튜디오(Visual Studio)와 같은 이클립스 기반이 아닌 소프트웨어에서도 사용하도록 설계되었다.

사바는 재즈 프로젝트에서 웹 서비스 보안 프로토콜과 같은 기존의 웹 표준을 사용하는 것이 목표라고 말했다. 그는 그 소프트웨어 자체는 인터넷을 통해 호스팅 방식으로 실행할 수도 있고 회사의 네트워크에 설치할 수도 있다고 덧붙였다.

오그래디는 썬마이크로시스템즈의 넷빈즈(NetBeans)와 같은 인터넷 기반 소스 코드 관리 시스템과 툴 프로젝트가 점점 협업 기능을 추가하고 있다고 설명했다.

콜랩넷(CollabNet)이라는 회사는 분산된 프로그래머 팀들을 위한 호스팅 방식 소프트웨어 개발 서비스를 제공하고 있다. IBM의 사바는 재즈 프로젝트가 콜라브넷의 현재 서비스보다 훨씬 더 큰 범위를 염두에 두고 있다고 말했다.

오그래디는 대부분의 개발 툴이 에이젝스 또는 심지어 인스턴트 메시징과 같은 웹 기술까지도 널리 퍼지기 전에 만들어졌기 때문에 재즈가 잠재력이 있다고 말했다.

하지만 오픈 소스 재즈 프로젝트가 궁극적으로 시장에 미칠 영향은 대체로 IBM이 무엇을 내놓기로 결정하느냐에 달려 있다.

오그래디는 “원격으로 일하는 사람들의 개발 환경을 훨씬 더 자연스럽게 연결해 주는 오픈 소스 배경을 마련하는 것은 이클립스 커뮤니티에게 멋진 일이 될 것”이라며 “문제는 그들이 오픈 소스인 것과 비밀 무기로 감추어 두려는 것 사이에서 어디에 선을 긋느냐다”라고 말했다. @

출처 : ZDNet Korea.
:
Posted by 뽀기