2009년 9월 4일 금요일

Aspect Oriented Programming (AOP) in Spring Framework


1. 정의
AOP는 Spring Framework의 중요한 특징 중 하나입니다.
AOP란, 기능을 핵심 비지니스 로직과과 공통 모듈로 구분하고, 핵심 로직에 영향을 미치지 않고 사이사이에 공통 모듈을 효과적으로 잘 끼워넣도록 하는 개발 방법입니다.
공통 모듈은 보안 인증, 로깅 같은 요소들이 해당됩니다.

예를 들어 다시 설명하면, 로그를 찍기위해 로그 출력 모듈을 만들어서 직접 코드 사이사이에 집어 넣을 수 있겠지요? 이런건 AOP 적이지 않은 개발입니다.
반면에 로그 출력 모듈을 만든 후에 코드 밖에서 이 모듈을 비지니스 로직에 삽입하는 것이 바로 AOP 적인 개발입니다. 코드 밖에서 설정된다는 것이 핵심입니다.

2. 예제
1) AOP스럽지 못한 코드
public class InventoryController implements Controller {
    protected final Log logger = LogFactory.getLog(getClass());
    private ProductManager productManager;
    public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        String now = (new java.util.Date()).toString();
        logger.info("returning hello view with " + now);
        Map<String, Object> myModel = new HashMap<String, Object>();
        myModel.put("now", now);
        myModel.put("products", this.productManager.getProducts());
        return new ModelAndView("hello", "model", myModel);
    }
    public void setProductManager(ProductManager productManager) {
        this.productManager = productManager;
    }
}

로그를 찍고 싶은 지점에 로깅 코드를 직접 삽입하는 방법입니다. 물론 이렇게 하는 것이 효율적일 수도 있습니다. 하지만, 클래스 진입 시점마다 로그를 찍는 것과 같이 동일한 패턴이 있는 경우에는 rule을 정의하고 여기에 따라서 동일한 모듈이 호출된다고 하면 매우 직관적이고 간결하면서 유지 보수가 편하게 구현이 될것으로 생각됩니다. 이것을 지원하는 것이 바로  AOP이며 spring에서는 이를 지원하고 있습니다.

2) Spring에서 AOP를 사용하는 방법
Spring에서는 크게
 - Spring API를 이용하는 방법
 - XML schema을 이용하는 방법
 - Annotation 기능을 이용한 방법
이 있습니다.
여기서는 2번째 XML schema를 이용하는 방법의 예제를 소개합니다.
전체 소스를 첨부합니다.


loggingaspect.java

package springapp.common;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.aspectj.lang.JoinPoint;
public class LoggingAspect {
 protected final Log logger = LogFactory.getLog(getClass());
// pointcut method 호출 전에 실행 시킬 로깅 함수
public String beforeLogging(JoinPoint joinPoint) {
  String methodName = joinPoint.getSignature().getName();
  logger.info("calling: " + methodName);
  return methodName;
 }

// pointcut method 결과 리턴 후에 실행 시킬 로깅 함수
 public void returningLogging(JoinPoint joinPoint, Object ret) {
  String methodName = joinPoint.getSignature().getName();
  logger.info("called successfully: " + methodName + " returns " + ret);
 }

// pointcut method에서 예외 발생시에 실행 시킬 로깅 함수
 public void throwingLogging(JoinPoint joinPoint, Throwable ex) {
  String methodName = joinPoint.getSignature().getName();
  logger.info("exception occured: " + methodName + " throws "
     + ex.getClass().getName());
 }

// pointcut method 종료 후에 실행 시킬 로깅 함수
 public void afterLogging(JoinPoint joinPoint) {
  String methodName = joinPoint.getSignature().getName();
  logger.info("finish call: " + methodName);
 }
}


applicationContext.xml

.... (다른 설정 생략)

<bean id="logging" class="springapp.common.LoggingAspect" />
 
<aop:config>
  <aop:pointcut id="publicMethod" expression="execution(public * springapp.service..*.*(..))" />
  <aop:aspect id="loggingAspect" ref="logging">
      <aop:before pointcut-ref="publicMethod" method="beforeLogging" />
      <aop:after-returning pointcut-ref="publicMethod" method="returningLogging" returning="ret" />
      <aop:after-throwing pointcut-ref="publicMethod" method="throwingLogging" throwing="ex" />
      <aop:after pointcut-ref="publicMethod" method="afterLogging" />
  </aop:aspect>
</aop:config>

.... (다른 설정 생략)


먼저 AOP 관련 용어를 설명하도록 하겠습니다.
 - advice : 언제 어떤 기능을 적용할 지에 대한 정의
 - joinpoint : 공통 기능 적용 가능 지점 (spring에서는 메서드 호출만이 가능합니다.)
 - pointcut : joinpoint 중에 실제로 적용할 지점
 - weaving : 핵심 로직에 공통 로직을 삽입하는것
 - aspect : 여러 객체에 공통으로 적용되는 공통 관심 사항

설정 정보는 아래의 구조로 생성합니다.
<aop:config>
    <aop:aspect> : aspect를 설정
        <aop:before> : method 실행 전
        <aop:after-returning> : method 정상 실행 후
        <aop:after-throwing> : method 예외 발생 시
        <aop:after> : method 실행 후 (예외 발생 예부 상관 없음)
        <aop:around> : 모든 시점 적용 가능
    <aop:pointcut> : pointcut 설정

pointcut 설정은 AspectJ의 표현식에 따릅니다.

execution( 수식어패턴 리턴타입패턴 패키지패턴.메소드이름패턴(파라미터패턴) )


이제 모든 설정은 끝났습니다. 그닥 힘들이지 않고 설정할 수 있습니다. 하지만 joinpoint에 해당되는 지점만 적용이 가능하기 때문에 사용해야 할 시점을 잘 선택해야 할 듯 합니다.

3. 맺음말
지금까지 필터같은 기술을 이용해서 이와 비슷한 기능을 구현 했었지요. 실제 대형 과제를 할 경우에는 더욱더 필요한 기능이 아닌가 싶습니다. 아무리 모듈화를 하고 그 모듈을 적용한다 하더라도 일일이 코드에 적용하는 것은 정말 귀찮은 일일뿐 아니라 오류의 소지도 많아지게 됩니다. 그렇기 때문에 AOP는 정말 유용한 기능이 아닐 수 없습니다. 개인적인 생각으로는 이거 하나만으로도 spring을 써야할 이유가 아닐까 합니다. 제가 드린 예제를 기반으로 꼭 여러분의 과제에 적용해 보시길 바랍니다. 감사합니다.

4. 참조
마지막으로 AOP를 이해하는 것에 많은 도움을 준 칼럼을 소개하고자 합니다. 한빛미디어에 김대곤님이 기고하신 글입니다.

Inversion of Control in Spring Framework


IoC는 Spring Framework의 장점을 꼽으라면 가장 먼저 언급되는 개념입니다. 한국어로 변역하면 '제어의 역행'! 한국어가 더 어려워 보입니다. 비슷한 말로 Dependency Injection(DI)라는 말고 있습니다. 한국말로는 의존성 삽입! 아하~ 조금 이해가 되시나요?

간단하게 이해하기 쉽게 같이 알아보지요.

1. 개념
 객체 간의 의존관계를 객체 내부에 선언 또는 정의하지 않고, 외부의 조립기를 이용하여 의존 관계를 설명한다는 것

2. 예제
객체간의 연관성을 선언하는 3가지 방법을 보고, 문제점이 어떻게 IoC(DI)를 이용해서 해결되는 지 알아보지요.

1) 직접 선언하는 방법
public class WriteArticleServiceImpl {
    private ArticleDao articleDao = new MysqlArticleDao();
    ...
}

 - 쉽습니다.
 - 하지만, 이를 테스트하기 위해서는 MySqlArticleDao가 정상적으로 동작해야 합니다. 어렵습니다.
 - 또한, OracleArticleDao를 사용하기로 바뀌었다면 코드를 고쳐야 하지요~ 물론 컴파일도 다시요. 귀찮습니다.

2) Factory 패턴, JNDI를이용하는 방법

public class WriteArticleServiceImpl {
    private ArticleDao articleDao = ArticleDaoFactory.create();
    ...
}

 - 조금 나아졌나요? 최소한 Oracle로 바뀌어도 코드 수정은 안해도 되겠네요~ ^^
 - 근데 테스트 측면에서는 전혀! 나아진게 없어 보입니다. 올바르게 동작하는 Factory와 JNDI에 등록된 객체가 필요합니다.

3) 외부 조립자를 이용하는 방법

public class WriteArticleServiceImpl {
    private ArticleDao articleDao;
    public WriteArticleServiceImpl(ArticleDao articleDao) {
        this.articleDao = articleDao;
    }
    ...
}

외부 설정 파일 (applicationContext.xml)
<bean name="writeArticleService" class="com.sec.service.WriteArticleServiceImpl">
    <constructor-arg><ref-bean="articleDao" /></constructor-arg>
</bean>

 - 외부 설정(applicationContext.xml)에서 객체간의 의존성을 설명하고 있다는 감이 오시지요? 바로 이겁니다. 외부에서 객체 의존성을 정의하고 있는 것이지요. 책에서는 조립한다고 설명하더군요. (Nice!)
 - 여기서는 생성자를 이용한 방법을 사용하지만 setter를 이용하는 방법도 있습니다. 요건 나중에 차차..
 - 이제 위에서 말한 2가지 문제점이 다 해결되어 보이지요? 아하~ 굳입니다. ^^

3. 참조
1) 웹 개발자를 위한 스프링 2.5 프로그래밍
2) http://martinfowler.com/articles/injection.html
 - 다음은 IoC 설명의 정석으로 불려지는 Martin Fowler의 글입니다. 시간이 되시면 읽어보세요. 위의 설명이 좀 더 잘 이해되실 겁니다.

Java Conversion.


Dealing with nulls

UtilFactory.convertNull

 

Java – comparing strings

Use == for primitive data types like int

If (mystring == null)

 

Use the equals() method to compare objects

Use .equals for strings  : if (a.equals(“cat”))

 

Java - Converting int to string

 

String myString = Integer.toString(my int value)

   or

   String str = "" + i

 

Java - Converting String to int

 

int i = Integer.parseInt(str);

   or
int i = Integer.valueOf(str).intValue();

 

 

double to String :

   String str = Double.toString(i);

 

long to String :

String str = Long.toString(l);

 

 

float to String :

String str = Float.toString(f);

 

 

String to double :

double d = Double.valueOf(str).doubleValue();

 

String to long :

long l = Long.valueOf(str).longValue();
   or

   long l = Long.parseLong(str);

 

String to float :

float f = Float.valueOf(str).floatValue();


decimal to binary :

   int i = 42;

   String binstr = Integer.toBinaryString(i);


decimal to hexadecimal :

   int i = 42;
   String hexstr = Integer.toString(i, 16);
 
   or
   String hexstr = Integer.toHexString(i);
 
   or (with leading zeroes and uppercase)
   public class Hex {
     public static void main(String args[]){
       int i = 42;
       System.out.print
         (Integer.toHexString( 0x10000 | i).substring(1).toUpperCase());
      }
     }

 


hexadecimal (String) to integer :

int i = Integer.valueOf("B8DA3", 16).intValue();
   or

   int i = Integer.parseInt("B8DA3", 16);    



ASCII code to String

int i = 64;

   String aChar = new Character((char)i).toString();


integer to ASCII code (byte)

char c = 'A';

   int i = (int) c; // i will have the value 65 decimal



integer to boolean

   b = (i != 0);

 

boolean to integer

i = (b)?1:0;

* 출처
http://stuff.mit.edu/people/ele/Javaconversion.htm

JAVA GEF


 * 목 차

 

Code Conventions for the Java Programming Language



This Code Conventions for the Java Programming Language document contains the standard conventions that we at Sun follow and recommend that others follow. It covers filenames, file organization, indentation, comments, declarations, statements, white space, naming conventions, programming practices and includes a code example.

Why have code conventions? Code conventions are important to programmers for a number of reasons:

  • 80% of the lifetime cost of a piece of software goes to maintenance.
  • Hardly any software is maintained for its whole life by the original author.
  • Code conventions improve the readability of the software, allowing engineers to understand new code more quickly and thoroughly.

The Code Conventions for the Java Programming Language document was revised and updated on April 20, 1999.


* Sun 자료 참고
http://java.sun.com/docs/codeconv/

2009년 5월 11일 월요일

CMS 개념 및 방향


컨텐츠는 인터넷 시대를 살아가는 기업에게 있어 가장 중요한 자산이다. 이러한 방대한 양 의 컨텐츠를 효율적으로 관리하지 못하면, 빛의 속도로 바뀌는 비즈니스 환경에서는 존립 자체가 위협을 받을 수 있다. 최근 초고속 인터넷의 발전과 더불어 영화, 게임, 음악, e- Book 등과 같은 다양한 형태의 디지털 컨텐츠(digital contents) 산업의 발전으로 바야흐 로 21세기는 컨텐츠가 하드웨어를 지배하는 시대이며, 동시에 가치를 창출하는 시대로 변 화할 것으로 전망되고 있다. 통신망, 디지털방송망, 디지털 저장매체 등을 통해 활용되는 정보의 제작, 가공, 보호, 유통, 서비스하는 산업을 총칭하는 디지털 컨텐츠 산업은 세계 최고 수준의 국내 인프라를 바탕으로 다양한 분야에서의 고급 컨텐츠 생산 능력이 뒷받침 되어진다면, 국내 IT 산업의 수준이 한 단계 더 발전될 뿐만 아니라 고부가가치의 수출상 품으로 자리매김할 수 있다.

 

cms 란?
cms(Content Management System)는 글자 그대로 컨텐츠를 관리하는 시스템이다. IT 시장조사 전문 기관인 오범(Ovum)에서는 cms에 대해 'e비즈니스에 포함되는 모든 컨텐 츠를 생성, 보관, 관리하는 일련의 작업(Task)과 과정(Process)'이라고 정의했다. 일반적 으로는 '기업 내에 존재하는 다양한 포맷의 컨텐츠인 문서, 이미지, 동영상, 소리 등을 제 작, 출판, 관리하는 솔루션으로 보통 컨텐츠 생성,출판, 배포, 보관 등으로 정리되는 컨텐 츠 라이프스타일 전체를 관리하는 것'으로 규정된다.


여기까지 말하다 보면 KM/EIP 업무를 하고 있는 필자는 보통 다음과 같은 질문을 받게 된 다. 그럼 KMS(지식관리 시스템, Knowledge Management System)와 cms의 차이점은? 그때마다 필자는 농담반 진담반으로 ‘C와 K를 서로 바꾸시면 됩니다’라고 말하곤 한 다. 실제 cms에서 말하는 Contents는 KMS에서 지칭하는 Knowledge와 유사하다. 굳이 차이점을 말하자면 배포대상의 범위인데, KMS는 배포 대상이 주로 기업내부 관계자에 한 정된 반면, cms는 기업 내 관계자는 물론 거래업체, 일반 고객 등으로 기업 외부까지 포 괄하고 있다는 점이다.
국내에 처음으로 cms가 소개된 것은 지난 1999년 말경으로 당시에는 단지 방대한 컨텐츠 에 대한 관리를 해주는 개념으로 받아 들였다. 이후 국내 IT시장의 호황과 함께 해외 MS 전문 업체들이 합세하면서 시장이 열리기 시작했다. 그러나 현재까지 cms에 대한 올바 른 인식이 부족한 상황이다. 넓은 의미로서의 cms에는 다음과 같은 솔루션을 포함할 수 있다. 먼저 EDMS(Electronic Document Management System)를 들 수있다. cms의 원 조격인 EDMS는 기업 내 문서를 중심으로 하는 컨텐츠의 생성과 흐름을 효율적으로 관리 해 주는 솔루션이다. 보험이나 제약회사와 같이 문서 위주의 작업이 이루어지는 산업분야 에 많이 쓰이고 있다.


다음으로 DAM(Digital Asset Management)이 있다. DAM은 mam(Media Asset Management) 혹은 AM(Asset Management)이라고도불린다. 주로 동영상, 사운드, 그 래픽 등의 멀티미디어 자산들을 효율적으로 생성, 관리하는 방법을 제공한다. 엔터테인먼 트나 미디어 기업의 자산 관리 시스템에 적합하다. 그러나, 북미 시장에 비해 국내에는 아 직 낯선 분야이다. CM 즉 Catalogue Management는 기업이 만드는 제품의 가격이나 사 양, 서비스 정보 등을 표준화된 포맷으로 관리하기 위한 솔루션으로 B2B 마켓플레이스의 도입과 함께 활성화되었다.

이 같은 cms의 인접 솔루션 이외에도 cms 업계나 IT 리서치 기관을 통해 생긴 용어도 있다. 미국 cms 업계가 닷컴 몰락을 거치면서 만들어낸 ECM(Enterprise Content Management)은 기업 조직 내 다른 정보 시스템과의 연계나 컨텐츠 관리의 체계성을 강 조한 마케팅적인 개념이다. 즉 웹을 포함한 모든 형태의 데이터, 정보, 지식 등의 컨텐츠 를 관리 대상으로 한다. 특히 웹을 기반으로 하는 솔루션은 WCM(Web Content Management) 혹은 Wcms(Web Content Management System)로 따로 분류하는 경향 이 나타났는데 비교적 국내에 널리 알려진 부분이 바로 이 Wcms 분야이다.

 

cms 필요성
급변하는 e-비즈니스 환경에서 컨텐츠를 관리하는데 있어서 부딪힐 수 있는 문제들을 다 음과 같이 요약할 수 있다.
첫째는 컨텐츠의 양이다. 전세계적으로 웹사이트의 수는 매년 80%의 증가율을 보이고 있 다. 또 웹사이트 당 서비스되는 웹페이지의 수는 평균 10만 페이지에 이른다고 한다. 사이 트의 규모가 커질수록 폭발적으로 늘어나는 컨텐츠들을 어떻게 관리할 것인가?
둘째, 웹사이트가 커질수록 컨텐츠 운영자들도 따라서 늘어날 수밖에 없다. 이러한 컨텐 츠 운영자들의 작업을 어떻게 관리할 것인가? 또 컨텐츠 제공자들이 전세계적으로 확산되 어 있을 경우 어떻게 컨텐츠를 관리할 것인가?
셋째, 비 기술자인 컨텐츠 제공자들이 어떻게 하면 자신들이 익숙한 방식으로 컨텐츠를 제 공할 수 있을 것인가?
넷째, 분 단위, 혹은 실시간으로 바뀌는 컨텐츠들을 어떻게 일관성 있게 제공할 것인가?
다섯째, 현재의 e-비즈니스의 개념은 고객중심으로 바뀌고 있다. 그렇다면 우리 고객에 게 어떠한 방법으로 잘 맞는 컨텐츠를 필요로 하는 고객에게 필요한 시간에 전달할 수 있 을 것인가? 또 그것의 효과는 어떻게 측정할 것인가?
여섯째, 웹뿐만 아니라 다양한 통신채널을 통해 어떻게 컨텐츠를 전달할 것인가? 웹, 이메 일, WAP, PDA 등을 통해 서비스되는 컨텐츠들을 어떻게 효율적으로 관리할 것인가?
이러한 것들이 컨텐츠 관리의 위협적인 요소들이다. 컨텐츠관리 툴을 사용하지 않는다면 이러한 작업을 하기 위해서는 수십, 수백명의 웹마스터가 필요할 것이며, 실제로 수작업으 로는 불가능한 것도 있을 수 있다.

 


 

CMS(Contents Management System)


블로깅 툴을 얘기하다 보면 심심찮게 등장하는 CMS(Content Management System)란 용어는 무엇을 의미할까요?

일단 사전적인 의미로는 컨텐츠를 관리하는 시스템을 말합니다. 그런데 의미가 너무 포괄적이지요. 사실 CMS에 대한 정의는 명확하지가 않습니다. 특정한 규격이 정해져 있는 개념도 아니고요. 처음부터 CMS라는 정의하에 만들어진 것이 아니라 컨텐츠를 효율적으로 관리하기 위한 여러가지 방법들이 개발되면서 포괄적으로 CMS란 용어가 정립된 것이기 때문입니다.

그러므로 CMS의 의미를 알기 위해서는 컨텐츠란 무엇이고, 왜 컨텐츠를 관리할 필요가 생겨났는지, 그리고 어떤 방법들이 도입되었는지 알아야 합니다. CMS에 대한 설명을 담고 있는 위키피디아 문서와 CMS 솔루션 개발 업체인 콘텐츠와이즈에서 제공하는 PDF 문서를 참고로 해서 정리해봤습니다.

컨텐츠(Content)란?

‘컨텐츠’란 ‘내용물’이라는 뜻으로 상당히 포괄적인 용어입니다. 하지만 일반적으로 컴퓨터나 인터넷 분야에서는 ‘컴퓨터 파일’, ‘이미지나 오디오 등의 멀티미디어 파일’, ‘전자 문서’, ‘웹 컨텐츠’ 등을 말합니다. 현재는 웹(World Wide Web)의 성장과 더불어서 ‘웹 컨텐츠’가 다양한 멀티미디어 파일과 전자 문서를 포괄하는 개념으로 확대되었지요. 넓은 의미의 ‘웹 컨텐츠”는 HTML를 이용하는 모든 문서와 서비스(블로그, 게시판, 검색 엔진 등), 그리고 그 안에 포함된 모든 파일과 데이타를 뜻합니다.

컨텐츠 관리의 시작

초기의 CMS는 기업에서 서로 다른 부서간에(inter-office) 네트웍(또는 웹)을 통해서 컨텐츠를 공동으로 이용할 목적으로 시작되었습니다. 많은 기업들이 공통 양식(non-proprietary form)으로 만들어진 문서들의 저장소(archival)로 CMS를 활용했는데 서버 기반의 소프트웨어로 운영되었기 때문에 이런 문서들을 쉽게 공유할 수 있기 때문이었지요.

웹의 중요성이 커지고 웹 컨텐츠나 웹 사이트 관리의 비중이 높아지면서 ‘웹 컨텐츠 관리 시스템(Web Content Management System)’이 도입되었는데 WCMS에는 웹 관련 작업의 효율성을 높여주는 다양한 기능들이 추가되었습니다. 엄밀하게 말해서 CMS는 WCMS를 포함하는 상위 개념이지만 최근에는 WCMS의 대체 용어로 많이 사용됩니다.

† 앞으로의 글은 WCMS에 초점을 맞추고 있습니다. 따라서 CMS란 용어는 WCMS를 의미합니다.

컨텐츠 관리가 필요한 이유

초기의 웹 문서와 웹 사이트는 HTML 마크업을 문서 편집기(text editor)로 입력해서 만들어졌습니다. 따라서 관련 기술에 대한 전문적인 지식 없이는 웹 컨텐츠를 만들기가 어려웠지요. 예를 들어서 기업에서 판매하는 제품의 사용자 매뉴얼을 웹에 게시하려면 먼저 실무자가 매뉴얼을 일반 문서 형식으로 만들고 상급자나 경영진의 승인을 받은 다음 웹 사이트를 관리하는 담당자에게 전달하면 웹 관리자는 이 문서를 HTML 형식으로 바꾸고 FTP 등을 이용해서 올리는(upload) 과정을 거쳐야만 했습니다.

전체적인 효율을 높이려면 누구나 쉽게 문서를 만들거나 수정하고 게시할 수 있어야 하는데 바로 이것이 CMS의 핵심 기능입니다. 많은 블로깅 툴이 CMS 툴(소프트웨어)로도 분류되는 것은 바로 이런 핵심 기능을 지원하기 때문인데 예를 들어서 태터툴즈나 워드프레스는 직접 HTML 마크업을 입력할 필요 없이 브라우저 내에서 이지윅(WYSIWYG (What You See Is What You Get)) 편집기로 쉽게 문서를 작성할 수 있도록 해줍니다. 완성된 문서는 버튼 하나만 클릭하면 FTP 프로그램 없이도 웹에 올릴 수 있지요.

CMS가 지원하는 기능

CMS는 일반적으로 새로운 소식을 알리는 글이나 관리자 매뉴얼, 기술 문서, 판매 지침, 상품 소개 페이지와 같은 컨텐츠의 보관과 버전 관리, 배포에 주로 사용되며, 효율성 향상을 위해 다음과 같은 기능들을 지원합니다.

  • 각종 문서와 멀티미디어 자료(이미지, 오디오 비디오 등)를 작성하거나 외부에서 불러올(import) 수 있음.
  • 컨텐츠 관리에 참여하는 사용자들의 역할(role)과 권한 차이를 인식할 수 있음.
  • 컨텐츠의 형태나 분류에 따라서 사용자들의 역할과 책임을 부여할 수 있음.
  • 컨텐츠에 대한 작업 흐름(workflow)을 설정하고 필요에 따라서 컨텐츠 내용 변경시 관리자에게 알려줄 수 있음.
  • 하나의 컨텐츠에 대한 다양한 버전의 관리와 추적(tracking) 가능.
  • 컨텐츠를 쉽게 수정, 관리할 수 있도록 검색 기능이 통합된 문서 저장소에 보관하도록 함.
  • 일부 CMS는 디자인적인 요소를 제외한 텍스트 컨텐츠만을 받아들인 다음 기본 글꼴이나 색상, 레이아웃 등을 통합적으로 설정할 수 있도록 해줌.

열거한 기능 중에서 중요한 기능에 대한 보충 설명을 해봤습니다.

컨텐츠 제작

HTML을 사용하지 않고도 컨텐츠를 만드는 것은 CMS의 기본 기능입니다. 따라서 대부분의 CMS 툴이 이지윅 에디터나 Textile이나 Markdown, BBCode 등의 가벼운 마크업 언어(lightweight markup language)를 이용한 문서 작성을 지원합니다.

역할 관리

역할(role) 관리는 CMS의 핵심 기능 중 하나입니다. 아래 설명할 작업 흐름 관리와 함께 사용되며 초안(draft) 작성 권한만을 갖는 실무자가 문서를 작성하면 발행 권한이 있는 상위 관리자가 문서에 대한 수정을 요청하거나 최종 배포를 결정하는 방식이지요. 간단한 역할 관리의 예는 이전에 포스팅한 Textpattern 사용자 타입이라는 글에서 볼 수 있습니다.

작업 흐름 관리

작업 흐름(workflow) 관리 역시 CMS의 핵심 기능으로 기업 내에서 이루어지는 오프라인 결제 시스템을 떠올리면 이해하기가 쉽습니다. 즉, 컨텐츠가 한 번의 작업으로 완성되고 게시되는 것이 아니라 여러 과정을 거치며 수정과 검토, 승인이 이루어진 다음 최종 완성본이 배포되는 것을 의미하지요. 많은 CMS 툴은 작업 흐름 관리를 위해 진행 과정을 이메일로 알려주거나, 다음 과정으로 자동 전달해주는 기능을 지원하고 있습니다.

CMS가 적용되는 곳

기본적으로 CMS는 개인 사용자를 위해 만들어지지 않았습니다. 처음부터 기업 환경의 효율성 재고를 위해 도입된 것이니까요. 또한 수시로 바뀌는 게시판 같은 커뮤니케이션 용로도로 적합하지 않습니다. CMS의 효능이 최대한 발휘되는 곳은 기업의 제품 소개나 안내 페이지 같은 정적인 정보성 페이지입니다.

CMS로서의 텍스트패턴

제가 사용중인 텍스트패턴은 공식적으로 CMS 툴임을 표방하고 있습니다. 비록 전문적인 CMS 툴로 보기에는 기능상의 한계가 있지만 기본적인 기능들은 갖추어져 있다고 생각합니다. 하나씩 열거해보지요.

  • 쉬운 문서 작성: 거의 모든 HTML 태그를 대체할 수 있는 Textile은 텍스트패턴의 큰 장점입니다. Textile에 관한 자세한 설명은 Textile 시작하기를 참고하세요.
  • 역할 관리: 앞서 설명한 기능입니다. 사용자들이 각각 권한이 다른 여섯 부류로 나누어지며 각각의 권한을 원하는대로 수정할 수도 있습니다.
  • 작업 흐름 관리: 문서를 ‘초안(draft)’, ‘숨김(hidden)’, ‘미결(pending)’, ‘발행(live)’, ‘고정(sticky)’ 상태로 저장할 수 있습니다. 또한 upm_pending_notify 플러그인을 이용하면 상태가 바뀔 때 자동으로 작성자나 승인자에게 이메일로 통보합니다.
  • 버전 관리: 자체적으로 지원하지 않지만 md_versions 플러그인을 사용하면 하나의 글을 여러 버전으로 관리할 수 있습니다.
  • 각종 파일 관리: 텍스트패턴은 글이나 댓글처럼 이미지와 파일, 링크 목록을 독립적으로 관리합니다. 관리자 페이지에서 각각의 목록을 볼 수 있으며 다양한 조건으로 검색할 수도 있습니다.