2010년 3월 10일 수요일

[03] 관련노트 셋

:: 참조문서 ::


★ OSGi 에서의 이벤트 시스템

OSGi 라이프사이클 레이어에서는 BundleEvent, FrameworkEvent를 서비스 레이터에서는 ServiceEvent라는 형태의 EventType객체를 정의하고 있다.

이벤트설명
BundleEvent번들의 Life Cycle 변경을 알리기 위한 이벤트
ServiceEvent서비스의 변경사항등을 알리기 위한 이벤트
FrameworkEventOSGi 프레임워크의 변경사항을 알리기 위한 이벤트

이 이벤트가 발생하면 번들컨텍스트에 각 타입에 대한 리스너를 등록할 수 있다. 이 이벤트들은 주로 OSGi의 동적인 환경을 이용하는 Extender를 개발할 때 주로 쓰이게 된다.

번들이 동적으로 설치되는 환경이라면, 설치할 때 각 번들마다 해줘야 할 일들을 Extender에 만들어 줌으로써 각 번들마다 각각 코딩할 필요가 없게 되어 중복된 코드를 줄이고 한 곳에서 관리할 수 있다.

※ Extender
Extender는 OSGi상에서 종종 사용되는 개념으로, 동적으로 설치되는 다른 번들/서비스의 설치/삭제 시 이벤트를 받아서 특정 동작을 수행하는 형태를 말한다. 특히 SpringDM이 Extender 개념을 아주 잘 활용한 예라고 볼 수 있다.

★ BundleEvent

BundleEvent는 번들의 라이프 사이클 변경을 알려주는 이벤트, BundleListener인터페이스를 구현한 객체를 생성하여 BundleContext.addBundleListener를 호출하여 등록한다.

public class MyListener implements BundleListener {
    public void bundleChanged(BundleEvent event) {
    }
}

또는 Activator에 BundleListener 인터페이스를 구현하면 간단히 핸들링 할 수 있다.

public class Activator implements BundleActivator, BundleListener {

    public void start(BundleContext context) throws Exception {
        context.addBundleListener(this);
    }

    public void stop(BundleContext context) throws Exception {
        context.removeBundleListener(this);
    }

    public void bundleChanged(BundleEvent event) {
        ...
        ...
    }
}

번들을 설치할 때는 INSTALLED ▷ RESOLVED ▷ start() 메소드 실행 ▷ STARTED 순으로 이벤트가 진행된다. 번들을 삭제할 때는 stop() ▷ STOPPED ▷ RESOLVED ▷ UNINSTALLED 순으로 이벤트가 진행된다.

★ FrameworkEvent

FrameworkEvent는 프레임워크에서 일어나는 주요 이벤트로, BundleEvent와 마찬가지로 아래와 같이 FrameworkListener 인터페이스를 구현한 객체를 생성한 후 BundleContext.addFrameworkListener메소드를 호출하여 등록한다.

public class MyListener implements FrameworkListener {
    public void frameworkEvent(FrameworkEvent event) {
    }
}

FrameworkEvent는 일반적으로 잘 일어나지 않는 이벤트이며, 다음과 같은 이벤트가 존재한다.

번호이벤트설명
1STARTED프레임워크를 시작할 때 발생하는 이벤트
2ERROR프레임워크가 오류가 발생했을 때 던져주는 이벤트
3PACKAGES_REFRESHED각 번들이 임포트/익스포트하는 패키지가 리프레시되었을때 발생하는 이벤트
4STARTLEVEL_CHANGED각 번들의 ServiceLevel이 변경되었을 때마다 발생하는 이벤트
5WARNING번들에 관련하여 경고가 있을 때 발생

★ ServiceEvent

ServiceEvent는 서비스가 등록/수정/삭제되었을 때 알려주는 이벤트로 BundleEvent/FrameworkEvent와 마찬가지로 ServiceListener를 등록하면 프레임워크로부터 받을 수 있다.

public class MyListener implements ServiceListener {
    public void serviceChanged(ServiceEvent event) {
    }
}

이벤트설명
1REGISTERED서비스가 등록된 후에 발생하는 이벤트
2MODIFIED서비스가 변경된 후에 발생하는 이벤트
3UNREGISTERING서비스가 삭제되기 전에 발생하는 이벤트

초기 OSGi 설계당시에는 ServiceListener를 구현함으로써 각 번들은 자신이 원하는 서비스가 등록되었는지를 동적으로 알아내어 사용할 수 있었지만, 지금은 ServiceTracker를 이용하면 간단히 자신이 원하는 서비스에 대한 Tracking이 가능함으로 ServiceListener는 이제 별도 의미가 없어졌다.

★ OSGi 애플리케이션 이벤트

기존 자바에서 사용하던 일반적인 리스너 객체는 아래와 같은 방식이다.


그림1. 일반적인 리스너 객체

▶ 절차

1. 이벤트를 받고자 하는 Client가 이벤트 리스너를 생성해서 이벤트를 실제 생성하는 이벤트 객체에 자신을

   등록

2. 이벤트 소스는 OSGi 프레임워크가 되고, 작성한 번들의 액티베이터가 이벤트 리스너이다.

3. Add Listener 함수에서 이벤트 소스는 전달받은 이벤트 리스너들은 자신이 관리하는 리스너 객체 리스트

    에 추가한다.

4. 이벤트소스는 이벤트 발생시 이벤트 객체를 생성하고, 자신이 관리하는 리스너 리스트에 있는 모든 리스너

    객체들의 handleEvent 메소드를 호출하여 이벤트가 발생했음을 통보


위와 같은 구조는 자바에서 많이 사용하는 구조로 AWT와 같은 데에서는 매우 많이 쓰이고 있다. 하지만 OSGi 환경에서는 약간 부담이 되는 구조이다.

문제1. 각각의 이벤트와 리스너를 위해 클래스 또는 인터페이스를 작성해야 하는데, 클래스 개수가 늘어나는
         것은 관리상으로나 성능상으로나 문제가 있다.

문제2. 대부분의 경우 이벤트 리스너를 여러 개 관리(Stored Event Listeners)해야 하므로 이벤트 소스마다
         이를 저장하기 위한 컬렉션 개체가 하나씩 필요

문제3. 동적인 OSGi에서는 이벤트소스나 이벤트 리스너가 언제라도 없어질 수 있으므로, 이벤트 리스너 번들
         이 제거되었을 때 이벤트 소스에서 삭제하는 역할이 반드시 필요하며, 이벤트 소스는 매번 이벤트 리스
         너 존재여부를 체크해야 한다.


상기와 같은 문제로 OSGi에서는 주로 화이트보드 패턴을 이용한 이벤트 전달방식을 사용한다.



그림2. 화이트보드 패턴

화이트보드 패턴은 OSGi 프레임워크의 서비스 레지스트리를 이용하는 것으로, 각각의 이벤트 소스들에 이벤트 리스너를 등록하는 방식이 아니라 이벤트를 받고자 하는 번들이 이벤트 리스너를 서비스 레지스트리에 등록하고 이벤트 소스는 이벤트를 발생하고자 할 때, 서비스 레지스트리에서 이벤트를 받은 리스너들을 가져와서 이벤트를 던져주는 방식이다.

장점1. 이벤트 소스와 이벤트 리스너 사이의 직접적인 의존관계가 없다.

장점2. 이벤트 리스너가 모두 서비스 레지스트리에 등록되므로, 관계가 외부에 공개되며 통합적인 디버깅 툴
         의 지원이 가능하다.

장점3. 이벤트 리스너에 대한 다양한 테스트가 가능하여 개발작업이 용이하다.

장점4. 공개된 레지스트리를 이용하게 되므로, 이벤트소스나 이벤트 리스너 양측의 소스코드양이 줄어든다.

★ Event Admin 서비스

화이트보드 패턴은 쉽게 사용할 수 있지만 여전히 문제점이 남아 있다.

문제1. 이벤트 소스와 이벤트 리스너가 완벽히 분지되지 않는다. 즉, 이벤트 소스가 특정한 리스너, 특정한 이
         벤트 객체를 알고 있어야 한다는 것은 변함이 없다.

문제2. 서비스 레지스트리로부터 리스너 서비스를 얻어오고 트래킹하는 등의 코드를 이벤트 소스에 추가해야
         한다.

상기와 같은 문제점을 해결하고자 추가된 서비스가 OSGi Event Admin이다.




그림3. Event Admin 서비스

설명1. 각 번들은 Event Admin 서비스가 제공하는 EventHandler라는 인터페이스를 구현하여 이것을 서비스  
        레지스트리에 등록한다.

설명2. 이벤트 소스 번들에서 이벤트를 생성하여 Event Admin 서비스에게 Event를 보낸다.

설명3. Event Admin 서비스가 이벤트를 받은 시점에 등록된 이벤트 핸들러들의 스냅샷스냅샷을 만든다는 의미는, 이벤트를 받았을 떄 마치 사진을 찍듯이 등록된 이벤트 핸들러들의 리스트를 복사해두고 전달을 시작하고, 전달하는 작업 중간에 새로운 핸들러가 등록이 되더라도 그 핸들러는 현재 전달중인 이벤트를 받을 수 없다. 을 만들고 그 이벤트
         핸들러들에게 이벤트 객체를 전달한다.


상기와 같이 Event Admin 서비스를 구현한 Equinox 구현체는 org.osgi.service.event에 들어 있다.

★ Event Object


이벤트 객체는 다음과 같은 2개의 속성을 가진다.

1. Topic

이벤트 타입을 표시하기 위한 주제 속성. [주로 Event Listener들이 자신이 원하는 이벤트만 받고자 할 때 필터링시 사용]
- '/'로 분리된 Reverse Domain 형태의 계층 구조 스트링을 사용
- 일반적으로 fully/qualified/package/ClassName/ACTION 형태의 구조를 가진다.

2. Properties

이벤트에 대한 추가적인 속성을 가지는 컬렉션 개체.
다음은 주로 사용하는 속성들이며 이 상수에 대한 정의는 org.osgi.service.event.EventConstants에 정의


값의 형식키 이름 문자열속성 상수설명
BUNDLEbundleBundle해당 이벤트와 관련된 번들
BUNDLE_IDbuild.idLong번들의 ID
BUNDLE_SYMBOLINAMEbundle.symbolicNameStringManifest에 정의된 번들의 SymbolicName
EVENTeventObject이벤트 재전송을 위해 쓸 수 있는 현재 이벤트 객체 자체
EVENT_TOPICevent.topicsString[]이벤트가 해당하는 Topic 값, Event개체의 topic 변수와 중복되는 값이지만, 필터링할 때 사용할 수 있도록 Properties안에도 들어 있다.
EXCEPTIONexceptionThrowable발생한 Exception 또는 Error 개체
EXCEPTION_CLASSexception.classStringException 클래스 이름
EXCEPTION_MESSAGEexception.messageStringException.getMessage()에서 얻어지는 Exception 문자열
MESSAGEmessageString이벤트의 내용을 설명하는 문자열
SERVICEserviceServiceReference등록되거나 수정된 Service에 대한 ServiceReference
SERVICE_IDservice.idLongService의 ID
SERVICE_OBJECTCLASSservice.objectClassString[]서비스의 실제 객체인 objectClass의 이름배열
SERVICE_PIDservice.pidString프레임워크에서 부여한 Service의 Persistent ID값
TIMESTAMPtimestampLong이벤트가 일어난 시간

EventHandler를 등록할 때 EVENT_TOPIC과 EVENT_FILTER 두 가지 옵션을 통해 필터링이 가능하다.

1. EVENT_TOPIC

'*'을 지정하면 모든 이벤트를 받을 수 있으며 'org/osgi/framework/BundleEvent/*'과 같이 세부 항목에 '*'을 지정하면 그 패키지에 해당하는 모든 이벤트를 받을 수 있다. 중간에는 '*'이 올 수 없으며 배열형태로 원하는 이벤트만 지정하여 받을 수도 있다.

2. EVENT_FILTER

RFC2254 "The String Representation of LDAPLDAP(Lightweight Directory Access Protocol)은 TCP/IP 위에서 디렉토리 서비스를 조회하고 수정하는 응용프로토콜  Search Filters." 에 기반한 필터 문자열을 지정하여 원하는 속성의 이벤트만 필터링이 가능하다.

예를 들면 SymbolicName이 Google인 것만 : bundle.symbolicName=*.Google로 지정하면 되며 번들 id가 4이하 중에서, symbolic name에 eclipse인 것은 (&(bundle.id<=4)(bundle.symbolicName=*eclipse*))라고 하면 된다.

★ Event Admin에게 이벤트 보내기

Event Admin 서비스에게 이벤트를 전송하기 위해서는, 서비스 레지스트리로 부터 Event Admin 서비스를 가져와야 한다. 이를 위해서는 BundleContext.getServiceReference 함수나 4장에서 배운 ServiceTracker를 이용해서 손쉽게 가져와서 사용할 수 있다.

Event Admin의 이벤트 전송 함수는 sendEvent와 postEvent 두 가지가 있다.

1. sendEvent : 동기 전송

sendEvent를 호출할 때, 해당 Event를 받는 쪽에서 모든 처리를 할 동안 호출하는 쪽으로 리턴되지 않는다. 이 경우 받는쪽에 문제가 발생하면 호출하는 쪽까지 위험하므로 반드시 스레드 처리를 해주는 것이 좋다.

2. postEvent : 비동기 전송

postEvent를 호출할 때는 EventAdmin 내부에서 해당 Event를 받을 핸들러로 보내는 비동기처리가 되므로,
postEvent를 호출하는 쪽으로 바로 리턴된다.

2010년 3월 8일 월요일

[02] 관련노트 둘

:: 참조문서 ::
http://docs.google.com/Doc?docid=0AUlUhxYWZkIKZGZwNGRnMmdfN2NkcnE1cGRz&hl=en

★ SOA(Service Oriented Architecture)


SOA는 '서비스'와 '이를 조합하여 하나의 애플리케이션을 구축하는 것'이라고 볼수 있다. 웹서비스 기반의 SOA와는 다르게 OSGi는 현재로서는 하나의 JVM 인스턴스(한 대의 컴퓨터)안에서 구성한는 Java Object based SOA라고 볼 수 있다.




그림1. SOA 아키텍처

그림1과 같은 SOA구조를 Publish, Find & Bind 모델이라고도 하며 OSGi도 이 모델을 따르고 있다.

★ OSGi에서의서비스

OSGi에서는 이렇게 만들어진 서비스를 서비스 레지스트리라고 하는 곳에 등록함으로써 서로 다른 번들 간에 서비스를 이용할 수 있다. 여기서 서비스 레지스트리(Service Registry)는 서비스 중계자의 역할을 한다.

★ OSGi 서비스 등록과 해지

번들 컨텍스트 개체에는 다음과 같은 두가지 메소드가 있다.

1. public ServiceRegistration registerService(String clazz, Object service, Dictionary properties);

2. public ServiceRegistration registerService(String[] clazzes, Object service, Dictionary
    properties);

위의 메소드를 통해 STARTING, ACTIVE, STOPPING 단계 중 아무 때나 서비스를 등록할 수 있다.
(STOPPING 단계에서 번들이 중단되면 자동으로 서비스가 해지되기 떄문에 별 의미가 없다.)

서비스 등록시에 필요한 3가지 인자

  • 해당 서비스 객체의 인터페이스
  • 인터페이스 구현 객체
  • 서비스 속성 Dictionary

3번째 인자인 Dictionary는 키/값의 쌍으로 된 컬렉션 개체를 지정한다. 모든 서비스는 service.id라는 값을 가지며 이 값은 프레임워크에 의해 자동으로 지정되어 변경될 수 없다.

서비스를 등록하면 각 서비스당 하나의 ServiceRegistration 객체를 가지며 이 객체는 등록된 서비스와 직접적으로 연결되는 인터페이스로 서비스에 대한 접근자인 serviceReference를 읽어오거나, Service의 등록을 해지할 때 사용된다. 여기서 주의 할것은 서비스 해지는 반드시 serviceReference를 통해서만 가능하다는 것이다. (이것은 서비스를 등록한 번들만이 해지할 수 있게 하기 위해서 이다.)

★ OSGi 서비스 사용하기

등록된 서비스는 serviceReference라는 객체로 참조된다. 이 객체는 서비스의 속성정보나 등록한 번들에 대한 객체, 사용 중인 번들의 정보를 읽어올 뿐 서비스객체는 얻어오지 못하지만, 아래 메소드를 이용하면 실제 서비스 객체를 얻어올 수 있다.

BundleContext객체의 getService() 함수

이와같이 번들컨텍스트를 통하여 서비스 객체를 얻는 이유는 프레임워크가 실제로 서비스를 사용 중인 객체에 대한 의존성 정보를 유지/관리하기 위함이다.

번들 사이에는 의존관계가 있을수 있는데, 이를 제대로 처리하지 않으면 우리가 의도한 결과가 나오지 않을 수도 있다. OSGi는 동적인 환경이므로, 내가 사용하려는 서비스가 원하는 시점에는 없다가, 그 시점 이후에 등록이 될 수도 있다. 즉, 사용하고자 하는 서비스에 동적으로 대응하도록 코딩이 필요하다.

★ OSGi 서비스 추적하기

서비스를 찾아와서 사용하는 부분은, 그 시점에 서비스가 존재하지 않을 수도 있기 때문에 다시 한 번 확인이 필요하다. 이와 같은 처리 부분은 start 메소드에 구현하기 보다는 작업용 스레드로 구현하는 것이 이롭다.

하지만 동적인 환경에서 서비스가 존재하는지를 체크하는 작업은 매우 빈번한 작업이므로 그때마다 스레드로 구현하는 것은 귀찮은 일이다. 이 작업을 좀 더 유연하게 처리해주기 위해 지원하는 서비스가 ServiceTracker이다. ServiceTracker는 OSGi R2부터 추가된 유틸리티 클래스이다. ServiceTracker의 구현체는 osgi.cmpn.jar파일 안에 들어 있다. ServiceTracker의 주요 메소드는 아래와 같다.

번호메소드설명
1ServiceTracker()생성자
2open(), close()사용전 반드시 open, 사용 후 close
3getService(), getServices()...
4getServiceReference(), getServiceReference()...
5waitForService(timeout)데드락 발생가능성 때문에 반드시 스레드로 작성해서 호출해야 한다.

★ 여러 개의 서비스 사용하기

서비스를 시작하는 순서는 기본값으로 OSGi가 0으로 설정함으로 일정하지 않다. 따라서 Run Configurations에서 Start Level를 정해서 정해진 순서 순으로 시작할 수 있도록 한다.

2010년 3월 6일 토요일

[01] 관련노트 하나


:: 관련 문서 ::





★ Bundle State (번들 상태정보)



그림1. 번들의 전체 라이프 사이클

번들의 상태정보는 그림1에서 처럼 총 6개의 상태정보를 가진다. Bundle.getState() 함수를 호출하면
아래 표와 값은 정보를 얻을 수 있다.

상태정보정의
Installedpublic static final int INSTALLED0x00000002
Resolvedpublic static final int RESOLVED
0x00000004
Uninstalledpublic static final int UNINSTALLED
0x00000001
Startingpublic static final int STARTING
0x00000008
Activepublic static final int ACTIVE
0x00000020
Stoppingpublic static final int STOPPING
0x00000010

표1. 번들 상태정보 상수 정의

1) INSTALLED 상태

OSGi 프레임워크는 번들 인스톨 요청이 들어오면 여러가지 오류가 있는지 확인 후 번들 설치를 완료한다.

2) RESOLVED 상태

ResolvingResolving은 번들 간의 익스포트/임포트를 연결해주는 것을 말한다.  프로세스에 의해 번들이 임포트하는 모든 패키지와 Required 번들이 OSGi 프레임워크상에 존재하는지를 검사한다. 모든 패키지를 성공적으로 찾으면 RESOLVED 상태가 된다.

번들을 인스톨하면 순간적으로 INSTALLED -> RESOLVED로 넘어간다. 만약 INSTALLED 상태로 있는 번들이 존재하면 문제가 있음을 짐작할 수 있으며 보다 상세한 정보를 보기 위해서는 커맨드 창에서 'diag #'을 입력한다.

3) STARTING 상태

RESOLVED 상태의 번들은 start 명령에 의해 시작될 수 있으며, start 명령을 받은 번들은 BundleActivator가 존재시 start이 함수는 OSGi에 의해 호출되는 번들 초기화 함수이다. 이 함수 안에서 예외가 발생하게 되면 번들은 다시 RESOLVED 상태로 돌아간다. 주의할것은 이 함수안에서 시간이 많이 걸리는 작업을 행하면 안된다.  메소드를 호출하여 Activation 단계를 시작한다.

4) ACTIVE 상태

Resolving 및 초기화가 성공적으로 완료되면 번들은 ACTIVE 상태가 된다.

5) STOPPING 상태

콘솔에서 stop 명령에 의해 STOPPING 상태로 들어가며, OSGi 프레임워크가 Activator에 있는 stop() 메소드를 호출한다. stop() 메소드 호출이 끝나면 다시 RESOLVED 상태로 돌아간다.

6) UNINSTALLED 상태

uninstall 명령을 통해 설치된 번들을 삭제할 수 있으며, UNINSTALLED 상태로 변경된 후 번들 정보가 바로 지워지기 때문에 이 상태의 번들을 보는 것은 불가능하다.

★ BundleContext

BundleContext는 OSGi 프레임워크와 번들을 연결해주는 객체로 OSGi상에서 현재 번들의 컨텍스트 정보를 제어하는 수단이다. 주요 기능은 아래 도표와 같다.

번호기능
1새로운 번들 설치 : installBundle(...)
2번들정보 얻어오기 : getBundle(...)
3서비스 등록하기 및 서비스 가져오기
4프레임워크 이벤트에 Subscribe 또는 Unsubscribe 하기
5영구저장소에 파일 생성하기 : getDataFile(...)
6시스템 프로퍼티 읽어오기 : getProperty(...)

★ 조각번들 (Fragment Bundle)

조각번들은 OSGi R4에서 새로 추가된 개념으로 특별한 형태의 OSGi 번들이다.  혼자서는 아무런 일도 하지 못하며, 심지어는 Activator가 없어서 start 할 수도 없다. 이 번들들은 Host 또는 Master 번들이라고 불리는 다른 번들에 붙어야만 동작되는 번들이다. 이런 작업들은 Attaching이라고 하며, Resolving하는 도중에 일어나는 작업 중의 하나이다.

이런 조각번들은 다국어 지원 애플리케이션을 작성할 때 각 언어별 파일을 따로 작성해서 호스트 애플리케이션에 붙여서 사용하는 용도로 사용된다.

2010년 3월 3일 수요일

[소개] OSGi & SpringDM

저자 : 권장혁
출판사 : 위키북스 ISBN : 978-89-92939-28-7
가격 : ₩25,000

[목차]

펼쳐두기..


2010년 3월 2일 화요일

[JAVA]SWT 개발환경

java.lang.NoClassDefFoundError: org/eclipse/core/runtime/IProgressMonitor와 같은 에러가 발생할시에는 다음과 같이 조치한다.

org.eclipse.core.runtime_3.5.0.v20090525.jar 라이브러리 추가와 함께

● org.eclipse.core.commands_3.5.0.I20090525-2000.jar
● org.eclipse.equinox.common_3.5.0.v20090520-1800.jar


함께 추가한다.

[02] SWT와 JFace로 시작하기

$1. SWT 프로그래밍

● Display 클래스

Display 클래스가 외관을 보여주진 않지만 GUI 자원을 관리하며 운영체제와의 소통을 담당한다. 즉, 윈도우를 표시하고 이동하며 다시 그리는 방식에 대해 관여한다. 또한 마우스 클릭이나 키보드를 누르는 이벤트를 적절한 위젯에 보내는지를 확인한다.

Display 클래스를 사용하는 부분이 코드 몇 줄에 불과하지만, 그 기능은 반드시 알아둬야 할 정도로 중요하다. Display 클래스는 코드에 있는 SWT/JFace 명령을 하위 수준의 호출로 바꾸어 운영체제에 전달하는 일을 한다. 이 과정은 Display 클래스의 인스턴스를 생성하면 시작되며, Display 객체는 플랫폼의 운영체제를 나타내는 OS 클래스의 인스턴스를 생성하고 자바의 네이티브 메소드를 사용하여 컴퓨터의 하위 수준의 자원에 접근한다. 이후 Display 객체는 이러한 메소드를 이용하여 전화교환원처럼 명령을 운영체제에 전달하고 사용자 입력을 애플리케이션에 전달한다.

만일 운영체제에 SWT와 통합하지 않은 기능이 있으면 JNI를 이용하여 손수 덧붙일 수 있다는 점을 기억하자. 다음은 Display 클래스의 중요 메소드를 보여준다.


● Shell 클래스

Shell 클래스는 GUI의 기본 윈도우처럼 동작한다. 또한 Display 객체와는 달리 Shell 인스턴스는 시각적인 부분을 구현한다. Shell 클래스는 주요 윈도우를 열거나, 활성화, 최대화, 최소화하거나 닫는 것을 추적할 때만 접근한다. 즉, Shell 클래스의 주요기능은 컨테이너, 위젯, 이벤트와 GUI를 연동하기 위한 연결 고리를 제공하는 것이다.

Shell 인스턴스는 여러 속성을 각고 있어 사용자들이 상태를 변경하거나 정보를 읽을 수 있는데 이러한 속성들의 모음을 구성요소의 스타일이라고 한다. GUI에서 셀, 위젯 등의 스타일 비트를 설정할 수 있으며, 각 스타일 비트를 '|' 연산자로 결합할 수 있다.

끝으로 모든 플랫폼이 GUI 구성요소의 속성을 제공하지는 않으므로, SWT가 스타일 설정을 규정이 아닌 가이드라인으로만 다룬다른 것을 이해해야 한다.

$2. SWT/JFace 프로그래밍

● 모델 기반 어댑터

JFace 클래스를 언급할 떄 Helper classes와 모델 기반 어댑터라는 두 가지 용어를 사용한다. 여기에서는 모델 기반 어댑터(JFace 어댑터)라는 용어만 사용하기로 한다. 어댑터는 다음과 같이 분류할 수 있다.


가장 많이 사용하는 모델 기반 어댑터의 부류는 Viewer 클래스이며 이에 대해서는 추후에 상세히 다루도록 한다.

$3. JFace와 SWT/JFace의 코딩

SWT만으로 구현한 코드와 SWT와 JFace를 모두 사용한 코드의 차이점을 살펴보자. 주요한 차이점은 SWT는 Shell 클래스에서 GUI의 외양과 동작을 함께 기술하는 반면에, SWT/JFace는 GUI의 외양과 동작을 분리한다. 이런 모듈화된 구조로 코드를 재사용할 수 있고, 한 개발자가 윈도우 뷰를 설계하면서 다른 개발자는 윈도우 동작을 구현할 수 있다.

윈도우 외양은 createContents() 메소드의 환경을 설정하는 Composite에서 제어한다.

$4.
ApplicationWindow
ApplicationWindow 클래스

윈도우 작동을 수행하는 클래스인 ApplicationWindow 클래스는 SWT/JFace에서 매우 중요하다.
ApplicationWindow 클래스는 자체적으로 생성하는 Shell 만들고 SWT/JFace는 개발자 Shell을 만들어 준다. 이처럼 JFace 윈도우를 사용하는 이점은 큰 사용자 인터페이스를 구축할 때 명확하게 보인다. 이점을 구체적으로 이야기 해보면 ApplicationWindow는 GUI의 외양과 동작을 분리한다. 또한 설계자에게 유용한 윈도우를 설정하는 여러 방법을 제공한다. Shell 클래스가 크기와 스타일을 변경하는 메소드를 가지고 있지만,
ApplicationWindow
ApplicationWindow 클래스의 메소드를 사용해서 휠씬 더 편리하게 설정시킬 수 있다. 다음 표에서 보듯이 ApplicationWindow 클래스 메소드를 보면 알 수 있다.













[01] SWT와 JFace의 개요

$ 스윙과 SWT/JFace 좀 더 깊이 살펴보기

스윙은 GUI 설계 과정에서 MVC를 구현하도록 되어있다. 즉 사용자 인터페이스 컴포넌트를 그 상태 정보, 화면에 보이는 모습, 외부 이벤트에 응답하는 능력의 세 부분으로 나눈다. 이러한 관점을 Model, View, Controller라고 명한다. 스윙 설계자는 아래그림과 같이 MVC 아키텍처를 수정하여 모델위임자 아키텍처를 작성했다.


모델 정보를 외양과 분리함으로써, 스윙은 프로그래밍 방법론적으로 좀더 유연하고 재사용 가능한 코드를 산출할 수 있도록 했다.

느려 터진 스윙에 대한 불만을 가진 이클립스 설계자들은 네이티브 애플리케이션과 같은 성능으로 자바 UI를 실행할 수 있는 도구인 SWT와 JFace를 직접 만들기로 하였다.

SWT/JFace의 가장 탁월한 면은 운영체제에 직접 접근이 가능하다는 것이다. 즉, SWT/JFace와 운영체제의 상호 소통은 자바 네이티브 인터페이스(JNI)를 사용하여 수행한다.

SWT/JFace의 또 다른 중요한 특성은 자동 가비지 콜렉션에 의존하지 않는 점이다. 이는 다음과 같은 두가지 이유에서이다.

1. 프로그램이 작동하는 동안 메모리 할당을 자동적으로 해제하는 과정은 예측할 수 없고, 할당을 해제     한 자원을 언제 사용할 수 있는지에 대해서도 알 수 있는 방법이 없다.

2. 운영체제 자원을 위해 자동 가비지 컬렉션을 사용하는 것은 어렵다. 상위 수준에 있는 가벼운 컴포넌     트를 사용할 때는 문제가 되지 않지만, 낮은 수준의 자원에 대한 자동 처리는 에러를 일으키기 쉽고,     플랫폼이 다를 경우 정상적으로 동작하지 않을 수도 있다.

따라서 할당과 해제를 SWT/JFace에서는 개발자가 결정해야 하며, 이러한 과정을 단순화하기 위해 컴포넌트 클래스에서 dispose() 메소드를 제공한다. 또한 부모 자원에 대한 할당을 해제하면, 자식자원들도 자동적으로 할당 해제된다.

이렇게 자동해제를 하지 않음을 강조하지만 실제 애플리케이션에서 명시적으로 해제하는 호출은 거의 필요하지 않다. 따라서 SWT/JFace 자원관리는 반자동이라고 할 수 있다.

$ 라이센싱과 플랫폼 지원

EPL(Eclipse Public License)하에 이클립스를 공개했다. 이 라이센스는 OSI 라이센싱 개념과 호환가능하며, 완전한 상업적인 사용을 허락하고 로열티에서 자유로운 소스코드와 전 세계에 배포가능한 권리를 허가한다.


$ WidgetWindow

앞으로 전체를 설계한 애플리케이션을 WidgetWIndow라고 부르겠다.





2010년 3월 1일 월요일

[01] HTML5 동향

$1. HTML 5 의 발전

2002년에 제정된 XHTML1.0 표준이후 XHTML 2.0표준 개발에 대한 시도가 사장으로 부터 외면을 받았다. 이러한 시점에서 주요 브라우저 업체인 애플, 모질라, 오페라는 2004년에 WHATWG (Web Hypertext Application Technology Working Group)을 결성해서 리치 웹 응용의 실용적 플랫폼에 목적을 둔 HTML, CSS, DOM 및 자바스크립트 개선 표준 개발을 시작하였으며, 2007년부터 W3C가 WHATWG의 결과물을 인계를 받아 현재까지 표준 개발을 진행하고 있다.

$2. HTML5 표준의 범위

● HTML 5 : vocabulary and associated APIs for HTML and XHTML
가장 기본적인 HTML5 표준안으로 표준 전체에 대한 공통적인 부분에 대한 내용과 마크업 부분에 대한 표준

● HTML Microdata
시맨틱 마크업을 간단히 내장시키기 위한 메커니즘에 대한 표준

● Canvas 2D API
웹에서 immediate mode로 2차원 그래픽을 그리기 위한 2D Canvas Drawing API표준

● Server-Sent Events
서버가 데이터를 웹페이지로 푸쉬할 때 사용하기 위한 EventSource 인터페이스에 대한 표준

● Web Storage
웹 클라이언트에서 키와 값이 쌍으로 구성된 데이터를 영구적으로 저장하기 위한 API표준

● HTML5 Communications
문서들 간에 커뮤니케이션을 가능하게 하는 메시징  메커니즘 표준

● Web Workers
웹 응용 개발자가 쓰레드와 같은 개념으로 백그라운드 워커를 생성할 수 있도록 하는 API표준

● Web SQL Database
다양한 SQL을 사용해 질의할 수 있는 데이터베이스에 저장된 데이터를 위한 API표준

● Web Sockets API
웹 응용이 서버 측의 프로세스와 직접적인 양방향 통신을 위한 API 표준

● WebSimpleDB API
트랜젝션 데이터베이스에서 정렬된 키와 값이 쌍으로 구성된 데이터를 저장하거나 검색하기 위한 API

● Geolocation API
디바이스의 지리적 위치 정보를 제공하는 API표준

● File API
웹 응용이 파일정보, 파일리스트에 대한 정보 접근 그리고 파일 자체의 데이터를 읽기 위한 API표준

$3. HTML5 표준 개발 일정


상기 그림과 같은 표준 개발 일정하에 개발하고 있으나, 예상일정보다는 다소 지연되어 진행중에 있다.


$4. 결론

최근 열린 MWC(Mobile World Congress) 2010에서 최고의 화두 중 하나가 모바일 플랫폼의 분열 문제였으며, HTML5는 이를 해결할 수 있는 웹 표준 플랫폼의 핵심적인 표준이 될 것으로 예상된다. 또한ActiveX로 구현된 기능을 HTML5를 이용하여 대체할 수 있는 것으로 기대되며, 업체 종속적인 RIA 플랫폼 기능이 HTML5로 대체될 것으로 예상된다.