2011. 12. 16. 09:51 IT

2011년 11월 15일자로 grails 2.0.0 정식버전이 공개되었다.
http://blog.springsource.org/2011/12/15/grails-2-0-released/

며칠전부터 groovy 관계자들이 '곧 나옵니다'하고 홍보해대서 별로 놀랍지는 않았다.
 
뭐가 새로운걸까 간단하게 둘러보자.
http://grails.org/doc/2.0.0/guide/introduction.html#whatsNew

A. 개발환경 관련

1. 콘솔 출력 개선 및 인터랙티브 모드 지원
서버사이드에서는 아직도 콘솔 작업이 대세다.
아마존같은 클라우드 벤더도 대부분 콘솔로만 제어할 수 있는 경우가 많다.
단순한 작업에 Web을 구성하는 것도 사실 번거로운 일이고...
Spring ROO 방식도 그렇지만 콘솔화면에 익숙한 사람들을 위한 즐거운 놀잇거리라고 할까...
콘솔에서 탭을 이용하여 명령어를 완성하거나 선택할 수 있게 하는 기능으로 보인다.

2. 리로딩 에이전트
웹 어플리케이션 리로딩 작업에 더이상 클래스로더를 사용하지 않는대신 JVM agent를 사용한다고 한다.
이전엔 설정관련해서도 뭔가 건들면 자주 리로딩이 되던 관계로 좀 귀찮았는데.. 좀 도움이 될까?

3. 에러 리포팅 및 분석 개선
효율적인 오류 해결에 도움을 받는건 늘 좋은 일이다.

B. 핵심기능

1. groovy 1.8 적용

C. Web 기능
1. 컨트롤러의 액션을 클로져가 아닌 메소드 형식으로 작성할수 있게 되었음.
2. primitive type 인자를 액션의 파라미터로 사용할 수 있음
3. 서블릿 3.0 비동기 기능 지원
4. 필터에 제외할 액션, uri를 설정할수 있음
5. html 5 기반 스캐폴딩  - 슬슬 html5를 공부해야할 압박감이 밀려온다.
6. jquery를 디폴트로 포함 - jquery가 대세다...

C. 퍼시스턴스 기능
1. GORM API 제공
2. Criteria, where 쿼리를 분리하여 사용 가능
3. 다중 데이터소스 지원 : 이거 필요한 기능이었다.. - 트릭은 있었지만..
4. DB 역공학 기능 - 뭔지 봐야겠다..
5. Hibernate 3.6 기반

D. 테스팅
1. 개선된 단위테스트 콘솔 출력
2. 단위테스트 API 추가 (Spock0.6 스타일로)
3. 단위테스트 스캐폴딩


이번달 개인적인 일만 처리하면... 탐험을 시작해봐야겠다.
posted by smplnote
2011. 12. 15. 12:57 IT
ITU-T G.1010 에서 웹서핑 시간을 2s/page 이내로 권고함 (preferred)
4s/page 이내를 수용 (acceptable)
posted by smplnote
2011. 12. 1. 21:32 IT

어플리케이션 마이그레이션 작업

1. Thunderbird
a) Win7에 thunderbird 설치
b) XP 기존 C:\Document and Settings\{user}\Application Data\thunderbird\profiles\ 아래 디렉토리를 copy
c) Win7에서 thunderbird.exe -ProfileManager 실행후 profile 경로를 위 프로파일을 copy 한 곳으로 설정

2. eclipse
a) eclipse indigo (3.7) 설치
b) subversion plugin 설치
c) groovy plugin 설치

3. utility
a) clcl 설치 (기존 폴더 복사후 실행)
b) PicPick 설치 (기존 폴더 복사후 실행)
c) tortoisesvn 설치

4. XP IE 북마크, 쿠키 export -> Win7 import 처리

5. 인증서 이동
a) XP C:\Program Files\NPKI 압축후 복사
b) Win7 C:\Program Files\NPKI 생성후 복사

생각보다 쉽게 이전하고 있는듯.. (물론 ActiveX 새로 까는 삽질이 시작중이다.  크롬도 깔아야 하나.. )
posted by smplnote
2011. 11. 29. 15:35 IT

SQL Inspection 을 다루다보니 필요해진게 iBatis Framework의 XML파일에서 SQL 문장을 추출하는일.

이리저리 찾아보다보니 나오더라.



import java.io.Reader;
import groovy.lang.Singleton;
import com.ibatis.sqlmap.client.SqlMapClientBuilder;
import com.ibatis.sqlmap.client.SqlMapException
import com.ibatis.sqlmap.engine.impl.SqlMapClientImpl;
import com.ibatis.sqlmap.engine.mapping.sql.Sql;
import com.ibatis.sqlmap.engine.mapping.statement.MappedStatement;
import com.ibatis.sqlmap.engine.scope.RequestScope;
@Singleton
class IbatisUtil {
static SqlMapClientImpl mapClient;
static RequestScope request;
static{
request = new RequestScope(); // 고정값으로 미리 생성해둔다. 
}
       // 초기화 작업 (sqlmapImpl 생성) 
public static void init(String file){
getIbatisMapClient(file);

        // ibatis의 SqlMapClientImpl을 생성한다.  
private static void getIbatisMapClient(String resource) {
Reader reader = getDynamicReader(resource);
try{
mapClient = (SqlMapClientImpl) SqlMapClientBuilder.buildSqlMapClient(reader);
}catch(Exception e){ 
// classpath 상에 VO 가 없을 경우 예외가 발생할 수 있다. 
}
}
        // 특정 ID에 대하여 sql 을 반환한다. 
public static String getSql(String id){
if(mapClient==null){
return null;
}else{
try{
MappedStatement mappedStatement = mapClient.getMappedStatement(id); 
mappedStatement.initRequest(request);
Sql sql = mappedStatement.getSql();
return sql.getSql(request,null);
}catch(Exception e){ // 동적변수의 값이 null이거나, ID가 없거나 등의 예외가 발생할 수 있다. 
return null;
}
}
}
        // 더미로 sqlMapConfig을 생성해준다. 여기서는 로컬 sqlMap 파일을 연결하므로 url=file 방식을 사용한다. 
private static Reader getDynamicReader(String resource) {
StringBuffer value = new StringBuffer();
value.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
value.append("<!DOCTYPE sqlMapConfig PUBLIC \"-//ibatis.apache.org//DTD SQL Map Config 2.0//EN\" \"http://ibatis.apache.org/dtd/sql-map-config-2.dtd\">");
value.append("<sqlMapConfig>");
println resource.replaceAll("\\\\", "/")
value.append("<sqlMap url=\"file:///" + resource.replaceAll("\\\\", "/") + "\"/>");
value.append("</sqlMapConfig>");
return new java.io.StringReader(value.toString());
}
}
posted by smplnote
2011. 9. 21. 08:23 IT
method & tools 2011 03 에서 나온 기사  "Dialogue Sheets for Retrospectives and Beyond" / Allan Kelly 에서 소개한 자료.


간략하게 정리해보면..
1. 진행방식설명 -  한자리에 모여 한번에 한개씩, 번호앞에 있는 사람이 읽는다. (skip도 가능)
2. timebox 정하기 (얼마동안 할지)
3. ground rule 확인 ( sheet에서는 Kerth's Prime Directive 를 제시)
4. 타임라인 작성 (상징적인, 기억에 남는 이벤트들)
5. 가장 성공적이었다고 생각하는것
6. 어려웠던것 / 곤란했던것  / 장애
7. 계속 유지하고 싶은 것
8. 다음번이라면 더 좋게 하기 위해서 다르게 할 것 같은 일
9. 8번 항목중에서 다음에 할일 3개 고르기
10. 참여자 서명 


A1 용지 크기로 출력할 수 있으면 좋은데, 여기에 맞는 프린터를 가진곳이 많지는 않으니...
대신 각 항목부분만 따로 출력해서 A1용지에 순서대로 붙이는 방법도 생각해 볼 수 있겠다.
활용사례를 보니 유리를 깔아서 양식을 재사용하는 경우도 있었다. (유리를 사야한다!)


타임라인 방식으로 진행되는 양식이다. 

다운로드는 다음 http://www.softwarestrategy.co.uk/dlgsheets/index.html 

사용안내서는 여기 http://www.softwarestrategy.co.uk/static/dlgs/RDS_HowTo.pdf 

지난 프로젝트때는 아주 자유분방하게 개발을 진행했었는데, 이런 양식이 있어도 처음 시작하는 사람들에게 도움이 될것 같다. 

아직 베타 테스팅 중이고 타임라인 외에도 다양한 형태의 양식이 나올것으로 기대한다. 
posted by smplnote
2011. 8. 31. 09:11 IT
- web browsing
chrome
IE

- OFFICE
ms office
foxit reader http://www.foxitsoftware.com/ -> 보안문제로 안쓰게됨..
primo pdf -> 보안문제로 안쓰게됨

- mail client
mozilla thunderbird

- desktop util
clcl  http://www.nakka.com : clipboard
multimon taskbar : multimonitor
picPick : screencapture -> 요즘은 Win7 에서 기본 제공하는 "캡쳐 도구" 를 사용한다 (2012/02/08)
free ip switcher -> 쓸일이 딱히 없음.

- multimedia
itunes
handbrake -> dvd to m4v (movie for iphone, ipad, android phone)
dvd shrink http://www1.ifccfbi.gov -> dvd backup tool

- change management
tortoisesvn -> subversion client
posted by smplnote
2011. 7. 14. 08:24 IT
// 예전에 쓴 자료 (2004) // 기록을 위해 남깁니다. 

클라이언트의 정보를 얻는 방법은

http request에서 제공되는 정보, client 스크립트(자바스크립트,VB스크립트)에서 제공해주는 정보, Form에서 전송되는 고객이 선택한 정보. 이 세가지가 일반적이고 그 이상의 정보를 얻기 위해서는 applet, activeX 등을 직접 제작해야  합니다.

 

1. 먼저 다국어와 로케일시간을 처리하는 방법을 보자면

단순한 쿠키세팅값을 읽어와 출력해주는 것입니다.

-----------
timeNameObj = new Array("사모아", "하와이",
 "알래스카", "태평양 표준시",
 "애리조나", "미국(중부)",
 "미국(동부)", "상파울로",
 "브라질리아", "중부-대서양",
 "아조레스", "런던",
 "로마", "아테네",
 "모스크바", "두바이",
 "이슬라마바드", "아스타나",
 "자카르타", "북경",
 "서울", "시드니",
 "마가단", "오클랜드");
timeObj = new Array("GMT-11","GMT-10","GMT-9","GMT-8","GMT-7","GMT-6","GMT-5","GMT-4","GMT-3","GMT-2","GMT-1","GMT","GMT+1",
 "GMT+2","GMT+3","GMT+4","GMT+5","GMT+6","GMT+7","GMT+8","GMT+9","GMT+10","GMT+11","GMT+12");

// body on Load시 호출
f unction init(){
  saveTimezone = getCookie("saveTimezone");
  for (i=0;i<24;i++) {
    if (saveTimezone==timeObj[i]) {
      xform.TIMEZONE2.value = timeNameObj[i] + " (" + timeObj[i] + ")";
    }
    else
      xform.TIMEZONE2.value = timeNameObj[20] + " (" + timeObj[20] + ")";
  }
}
----------------------

위의 내용을 설명하자면 자바스크립트 배열로 GMT시간을 저장해놓고

saveTimezone 이란 이름의 쿠키에 값이 있는경우 해당 값을 화면에 출력해주는 것입니다.

쿠키에 값이 없는 경우엔 디폴트로 20번 배열(한국)을 보여줍니다.

 

다국어 처리도 마찬가지군요

<select name="LANG">
  <OPTION value="en_US.EUC-KR" >영어</OPTION>
  <OPTION value="ko_KR.EUC-KR" selected>한국어</OPTION>
  <OPTION value="ja_JP.SJIS" >일본어</OPTION>
  <OPTION value="zh_CN.GB2312" >중국어</OPTION>
</select>

기본값을 영어로 하고 쿠키에 셋팅되어있는 값을 읽어 언어 로케일을 설정한뒤
이 값을 가지고 이후에 resource bundle에 적용하게 됩니다.

 

2. resource bundle을 사용하는 방법
 먼저 언어별 properties file을 생성. (test.properties, test_fr.properties, test_de.properties )
 
 java application에서 bundle 사용 코드 작성
 ---------------------
 ResourceBundle labels = null;
 
 String localeString = "fr"; // 프랑스어로 설정
 
 Locale currentLocale = new Locale(localeString);
 
 labels = ResourceBundle.getBundle("test",currentLocale);

 String value  = labels.getString("xxx");
 
 localeString = "de"; // 독일어로 변경
 
 labels = ResourceBundle.getBundle("test",currentLocale);

 보다 자세한 내용은 .. http://java.sun.com/jdc/TechTips/1998/tt0521.html#tip2

 

3. 그러나 실제로 web application의 경우 ResourceBundle 클래스를 바로 쓰지 않고
 struts 의 경우와 같이 MessageResources 클래스를 이용합니다.
 (struts site를 참조하세요 ) http://jakarta.apache-korea.org/struts/doc-1.0.2/userGuide/building_view.html

 

posted by smplnote
2011. 7. 8. 14:07 IT
Cross Platform을 위해 기존 파일 업로드 모듈을 변경하게 되었다. 

기존 ActiveX 모듈이 제공하는 기능은 다음과 같다.
- Drag & Drop 
- 첨부갯수, 용량제한 지원
- 이미지 업로드 연계 (게시판에서 전달한 인자를 이용하여 추가 업로드 수행)
- 첨부제외 파일 확장자 리스트 지원
- 업로드시 프로그레스 바 제공
- 다운로드시 일괄 파일저장 기능 제공 

우선 웹표준을 적용할때 제공할 수 없는 것을 정리해보면
- Drag & Drop ( 로컬 파일에 대해서는 보안위배사항)
- 용량제한 확인 불가 (역시 로컬 접근이 안되므로 서버 측에서 검사해야함)
- 이미지 업로드 연계 불가 ( file type 의 input 은 value 값이 readOnly 다. 역시 보안상의 이유)
- 프로그레스바 미제공 (이건 좀 찾아보면 나올지도... )
- 일괄파일 저장 기능 미지원 ( 이것도 좀 트릭을 쓰면 될지도... )

하여튼 이런저런 시간 낭비를 거쳐 마침내 대충 정리했다. 

적용 솔루션은 다음과 같다.
1. UI : jquery , multiple-file-upload plugin 
http://www.jquery.com 
http://www.fyneworks.com/jquery/multiple-file-upload
 
2. Server : com.oreilly.servlet
http://www.servlets.com/cos/

- 준비물 
jquery.js , jquery.MultiFile.js , WEB-INF/lib/cos.jar

- 등록 페이지
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="jquery.MultiFile.js"></script>
<script>
function upload(){
        var fileTags = document.body.getElementsByTagName('input');
var arr = new Array();
var cnt = 0;
for (var tg = 0; tg< fileTags.length; tg++) {
   var tag = fileTags[tg];
   if (tag.name =='Filename') {
    tag.name = tag.id;   // tag.name이 모두 Filename 으로 된 것을 바꾸도록 처리함 (MultiFile.js 의 버그? )
    }
}
        document.getElementById("
frmFile").submit(); 
}
function  onUploadDone(msg){
   alert(msg);
</script>
<!-- 업로드용 폼 --> 
<form name="frmFile" action="your_server_page" 
    id="frmFile" method="post" 
    target="upload_target" encoding="multipart/form-data" enctype="multipart/form-data">
    <!-- 업로드용 file input -->
    <input class="multi"  type="file"  id="Filename" name="Filename"
              accept="jpg|png|gif|tif|xls|doc|hwp|int|zip" style="width:400">
    <!-- 업로드 타겟용 frame --> 
    <iframe id="upload_target" name="upload_target" src="#" style="width:0;height:0;border:0px solid #fff;">
    <input  type="button" value="upload" onclick="upload();"/>
</iframe>

- 서버측
<%@ page language="java" contentType="text/html; charset=utf-8" import="com.oreilly.servlet.*" %>
<%
String fileDir = "/upload";
String encoding = "euc-kr";

int attachSize = 1; // Megabyte
String retVal = "":
if(request.getContentLength()>attachSize* 1024 * 1024){
        retVal = "upload file size is over";
}else{
        MultipartRequest mr = new MultipartRequest(request, fileDir, request.getContentLength(),
encoding,new DefaultFileRenamePolicy());
        Enumeration fileNames = mr.getFileNames();
        List fileInputNames = new ArrayList();
        while(fileNames.hasMoreElements()) {  
         String str = fileNames.nextElement().toString();
                fileInputNames.add(str);
        }
        for(int i=0;i<fileInputNames.size();i++){
                String inputName = (String)fileInputNames.get(i);
                String fileNm = mr.getFilesystemName(inputName);
                File file = mr.getFile(inputName);
                String orgFileName = mr.getOriginalFileName(inputName);
                retVal += fileName +" ";
        }
}
out.print("<script>parent.onUploadDone('" + retVal + "');</script>"); 
%>



[기타 기록사항]
- ajax form 비정상 작동 : ajax form 을 이용하려고 했으나 어떤 이유인지 모르지만 정상적으로 파일을 전달하지 못했다. 별수없이 iframe을 직접 작성했다. 
- multifile.js 의 name 동일성 문제 : id는 XXX1, XXX2 처럼 늘어나는데 name은 XXX, XXX 로 되는 버그가 있다. 
- file type의 input은 보안상의 이유로 value 값을 readonly로만 지원한다. 따라서 외부 게시판을 이용한 이미지 업로드 와 같은 기능은 적용할 수 없다.
- cos.jar 대신에 apache common-fileupload 를 이용하는 경우도 많은데, 내 경우에는 이미 기존에 cos.jar 를 잘 사용하고 있었고, 중복 파일에 대한 처리기능을 별도로 구현하기 귀찮고... 추가로 필요한 기능은 없어서 기존 코드를 그대로 재사용 했다.
 

 
posted by smplnote
2011. 6. 24. 13:39 IT
posted by smplnote
2011. 6. 24. 12:41 IT
Oracle 성능측정용 리포트 도구
10g 부터 지원 / 
Enterprise Edition에서만 사용 가능 
60분 간격으로 7일간의 데이터 보관 (기본정책)

License: 
Diagnostic Pack(진단 팩)에 대한 추가적인 라이센스 비용. (기본 설치는 되지만 공식적인 사용이나 기술지원은 불가 )


SYS 계정의 dba_hist_* 뷰를 이용
보고서 출력기능 제공 


9i 는 Statspack 이 유사한 역할을 함.
기타 툴 : Maxgauge
 

references
http://blog.naver.com/PostView.nhn?blogId=s70097&logNo=70079607465
http://www.sqlgate.com/kr/product/oracle/tutorial_AWR+Report_2
http://www.gurubee.net/display/DBSTUDY/AWR
http://121.254.172.39:8080/pls/apex/f?p=101:11:0::::P11_QUESTION_ID:4326300346619264
http://ukja.tistory.com/300
http://energ.tistory.com/entry/AWR-%EC%9D%B4%EB%9E%80
posted by smplnote