2011. 6. 23. 10:36 IT
1. XML Node 의text property
ex) <test>value<test>
ie : .text
etc : .textContent

2. selectbox 관련 
reInitializeSelectBox : 정확한 이유를 밝히진 못했지만 ie에서만 먹는듯 

3. selectNodes, selectSingleNode 메소드 ( ie only)
대체기능
selectNodes -> getElementsByTagName
selectSingleNode -> 미지원 기능으로 다음 함수로 대체
function selectSingleNode(xmlDoc, elementPath){   
if(document.implementation && document.implementation.createDocument){
var nodes = document.evaluate(elementPath, xmlDoc, null, XPathResult.ANY_TYPE, null);
var results=nodes.iterateNext();
     return results;
    }
}

4. select element의 method reInitializeSelectBox ( ie only )
제거..

5. window.createPopup() ( ie only)

6. style='cursor:hand' (ie only)
-> style='cursor:pointer'

7. form.elements[N].maxLength == null , form.elements[N].minLength == null (ie)
but other browser : form.elements[N].maxLength = -1

8. document.all  (IE only)
document.getElementById(XXX) (ALL)
ex) document.all.xxx -> document.getElementById('xxx');


9. elem.innerText ( IE only)
-> elem.textContent (other IE)
아래처럼 호환되는 함수를 이용 
function getText(elem){
return elem.textContent || elem.innerText;
}

10. elem.style.display='block';
-> elem.style.display='';

11. xml 을 client로 전송할때 <xml 앞에 공백이나 캐리지리턴값 등이 들어 있으면 정상적인 xml로 인식하지 못함( Firefox 등에서)
-> jsp인 경우 out.clear(); 를 호출하여 앞에 쌓인 공백, 빈라인피드 등을 제거한다음 출력처리... 
만약 OutputStream을 사용하는 경우에는 다음과 같이 작성 
out.clear();
out = pageContentx.pushBody(); 
out.flush();

http://www.w3schools.com/dom/dom_nodes_access.asp
reference : http://semin.tistory.com/entry/XML-Dom-Object-IE-Firefox-Supported  
posted by smplnote
2011. 6. 20. 16:46 IT

web.xml 에서 명시적으로 log4j 설정파일 경로를 명시하여 작업하는 경우
junit만 실행할때는 web.xml 을 참조하지 않고 실행되므로
다음과 같은 에러 메세지가 콘솔에 찍힌다. (당연히 눈에 거슬린다.)

log4j:WARN No appenders could be found for logger(...

해결책으로는 
test 소스 폴더의 디폴트 패키지 위치에 log4j.properties 를 두면 끝.

출처 : http://blog.naver.com/goethe1004/80034130033
posted by smplnote
2011. 6. 16. 12:29 IT

Frame으로 구성되어 있는 기존 시스템에
메뉴를 숨기는 기능을 추가하기로 했다.

어떻게 할까? 

1. frame size 를 조절할 수 있어야 하고,
2. 숨기기 버튼이 지정된 위치에 고정되어 표시되어야 하고,
3. 숨기기/보이기 버튼이 상황에 따라 활성화 되어야 한다. 

solution)
1. frameset 의 attribute에는 cols, rows 가 있다.
이 값들을 자바스크립트에서 설정할 경우 변경이 가능하다.
[Frame page]
// for menu frame size restore
function res() {
 var fs = document.getElementById('fset2');
 if (fs) {
   fs.rows = '1*';
   fs.cols = '205,*,1';
 }
}
// for menu frame size minimize
function min() {
 var fs = document.getElementById('fset2');
 if (fs) {
     fs.cols = '5%,95%';
 }
}
frameset 은 다음과 같다.
[Frame page]
<frameset id='fset2' cols='205,*,1' rows='1*'>
2. 숨기기 버튼의 위치 고정
컨텐츠 영역과 버튼 영역을 구별하고
[Menu page]
<div class="left_lnb_wrap" id="target">
... menu contents here
</div>
<div class="fold_button_area">
<div id="foldButton" class="fold_button">
<button type="button" class="button" onclick="foldSideBar('up');" title="왼쪽영역 닫기"><img src="/images/btn_left_close.jpg" width="25" height="28" alt="왼쪽영역 닫기" /></button>
</div>
<div id="unFoldButton" class="unfold_button">
<button type="button" class="button" onclick="foldSideBar('down');" title="왼쪽영역 열기"><img src="/images/btn_left_open.jpg" width="25" height="28" alt="왼쪽영역 열기" /></button>
</div>
</div>
스타일을 적용한다.  
[Menu page] 
/* 레이아웃 - 영역 열기버튼, 닫기버튼 */
#container #content_wrap.width_full {margin-left:0; margin-right:0;}
.fold_button {position:absolute; top:150px; left:150px;}
.unfold_button {display:none; position:absolute; top:150px; left:0;}
.fold_button_up {position:absolute; top:90px; right:0;}
.unfold_button_down {display:none; position:absolute; top:0; right:0;}
.fold_button_right {position:absolute; top:150px; right:150px;}
.unfold_button_right {display:none; position:absolute; top:150px; right:0;}
.fold_button_right2 {position:absolute; top:150px; right:139px;}
.unfold_button_right2 {display:none; position:absolute; top:150px; right:0;}
3. 버튼 액션 구현
선택값에 따라 메뉴 컨텐츠를 숨기거나 보이고, 버튼 이미지를 교체할 수 있게 구현한다.
물론 frameset 이 있는 페이지에서 정의한 메소드를 호출하는 것을 잊으면 안된다.
frameset page 가 최상단일 경우, window.parent 대신 window.top 을 사용할 수 있다. 
[Menu page]
function foldSideBar(togle){
var targetArea = document.getElementById("target");
if(togle == "up"){
targetArea.style.display = "none";
document.getElementById("foldButton").style.display = "none";
document.getElementById("unFoldButton").style.display = "block";
window.parent.min();
}else{
targetArea.style.display = "block";
document.getElementById("foldButton").style.display = "block";
document.getElementById("unFoldButton").style.display = "none";
window.parent.res();
}

뭐 요즘을 조금 둘러보면 나오는 기술이지만, 적용가이드 쓰는 겸해서 정리해본다. 
 
reference : http://www.cross-browser.com/toys/frame_resize.html
posted by smplnote
2011. 6. 10. 08:15 IT

비효율 SQL을 찾아내기 위해 FullTableScan 을 찾는 작업을 준비중이다.


실제 실행결과를 가지고 해볼 수 도 있지만 
소스코드로 정적으로 도출할 수 있는 방법으로 먼저 접근해보았다.

물론 ORACLE을 대상으로 하고 있으며 타 DB (ORACLE과 구조상 거의 유사한 Tibero는 제외)는
어떻게 유사한 기능을 제공하는지 확인하지 못했다.  
 
기본적으로 Oracle은 SQL문장을 파싱한 뒤에 선정된 Optimizer를 기반으로 실행계획을 세우게 된다.
실행계획은 PLAN_TABLE 에 기록되므로 
이 내용을 정리하면 예상되는 실행 경로를 추적하면서 비효율적으로 수행될 가능성을 찾아낼 수 있다.


장점은 다음과 같다.
1) 실행결과 없이 SQL 문장만으로 비효율성을 검사할 수 있다. ( 정적 검사)
2) 추정이 아닌 DBMS가 제공하는 기능을 이용해 높은 정확도를 제공한다. 
3) 자동화가 가능함

이슈가 될만한 사항
1) 실행계획과 실제 수행시의 경로는 달라질 수 있다. ( cf-1 참조)
2) TEST DB와 REAL DB의 환경차이로 인해 다른 결과를 얻을 수 있다.
3) FullTableScan이 허용되어야 할 경우도 존재한다. (예를 들어 코드성 테이블이나 의도적으로 FullTableScan을 유도하는 SQL 등 )
 
이슈에 대한 생각
1) 정적 검사방식의 근본적인 제약이므로 한계를 인정 ( 실행결과 기반 검사로 해결하는게 맞다. ) 
2) 달라지는게 걱정이라면 명시적인 힌트를 부여해주는 것이 더 바람직하다.
3) 문제가 될 소지가 있는 Table들만을 대상으로 검사를 한정하고, 검사결과에서도 예외를 처리한다.
(마스터성, 히스토리성 테이블, 데이터 증가율이 지나치게 높은 테이블 등이 대상이 될 수 있다.) 

확장 아이디어
1) FullTableScan인 경우에 대해 효과적인 인덱스 전략 추천 (이건 가능성 여부를 DBA와 타진해야 할듯.. )



/* 개인적으로는 Hibernate나 nosql 쪽을 해보고 싶은데 기회가 없다. */


기타 참고사항
===================================== 
- plan 생성 스크립트 : $ORACLE_HOME/rdbms/admin/utlxplan.sql
cf) SYSTEM tablespace에서 수행하지 않도록 주의 할 것

- plan 실행방법
EXPLAIN PLAN (INTO {NEW_PLAN_TABLE} ) SET STATEMENT_ID = 'plan_id' FOR {SQL}
ex) 
EXPLAIN PLAN
SET STATEMENT_ID = 'my_ex_01'
FOR
SELECT * FROM XXX
WHERE Y=100; 
 
- plan table 조회
utlxpls.sql (with serial processing), utlxplp.sql (with parallel execution)
또는 직접 SQL 조회
SELECT * FROM PLAN_TABLE WHERE STATEMENT_ID = :QUERY_ID

CF) RBO 사용시에는 COST 컬럼이 NULL 이 됨 

cf-1) PLAN과 달리 실제 수행시에 실행 경로가 변경될 수 있는데, 다음과 같은 조건에 따른다.
- bind variable type
- data volume
- accuracy & timeliness of statistics
- indexing differences
- global parameter setting, static or dynamic modified
- session parameter setting 

 
- plan 사용 절차
1. setup : connection.autocommit = false
2. execute plan : explain plan SET STATEMENT_ID = 'PLAN_ID' for {sql}
3. select plan : select * from PLAN_TABLE WHERE OPERATION = 'TABLE ACCESS' AND STATEMENT_ID ='PLAN_ID'
4. tearDown: connection.rollback; connection.autocommit = true;
 
reference) Toad Knowledge Xpert

 
posted by smplnote
2011. 6. 3. 10:13 IT
Gr8Conf Europe gaelyk ppt

 PAAS 인 google app engine에서 사용 가능한 groovy toolkit 

한가해지면 해보겠다고 생각한게 2년 전이다.... 이거 뭐 게으름이..

http://slidesha.re/iBi29J 
posted by smplnote
2011. 6. 3. 08:49 IT
GR8Conf Euro 2011 에 Guillaume Laforge가 발표한 slide 자료

기억에 남는 것들
command chain : 영어에 가깝게? 그럼 영어 못하는 나는!
GPars bundle : 이거 언제 한번 써먹어야 하는데.. 최근엔 실패(효과를 못보기도 했고.. JDK 버전을 타기도 하고.. )
new AST Transformation : @Log 는 바로 써먹었다.
 



http://goo.gl/PN0xN
posted by smplnote
2011. 6. 2. 08:10 IT
요즘 트위터로 groovy 등 몇개 정보에 대해 눈팅을 하고 있는데,
역시 게으름의 미학으로 썬더버드에서 묶어서 볼수 없을까 찾아보았다.

site : http://mesquilla.com/extensions/tweequilla/

그런데 다운로드를 찾지 못한다.
조금 뒤져보니...

모질라의 addon 리뷰절차가 변경되어 아직 공식 사이트 addon으로는 등록되지 않아 다음 URL로 직접 다운 받아야 한다. (작성일 현재 상태)
download : http://mesquilla.com/tweequilla.0.1.1.xpi
( from http://mesquilla.com/2011/01/04/twitter-for-thunderbird/ )



posted by smplnote
2011. 5. 28. 11:06 IT

java.util.Hashtable은 map객체 안의 null값을 저장하지 못함
따라서 hashtableVariable.putAll(map)은 예외를 던질수 있다.

방법1. map에 널값이 저장되지 않게 한다 ex) IsNull(xx,"")  또는 ORMapping때는 공백치환처리 (QueryService의 NullChecks 와 같은 방식)

방법2. map을 hashtable에 옮길때 putAll 대신 루프를 돌리면서 널값체크해서 처리를 한다.

cf) 가능하면 Hashtable 을 사용하는 방식 자체를 지양해라. 구습 아닌가!!!
 


cf) Anyframe QueryService를 사용하면 VARCHAR, CHAR type에 대해서는 NullChecks를 이용하여 Null을 빈문자열로 자동 치환해주는데, 숫자타입이나 LOB 타입을 null로 반환된다.
(왜 구현을 안한걸까?)
 
posted by smplnote
2011. 5. 26. 13:34 IT


1. manage plugins 에서 install 후 exit
cf) serena로 검색

2. copy jar
from : /java_api/lib/ or /AdminConsole/lib/
to : /WEB-INF/lib
darius.jar
dmclient.jar
dmfile.jar
dmnet.jar

cf) Dimensions CM 2009 R1.x and R2 이상의 library 를 사용해야 문제가 없음 
(이전버전일 경우 java.lang.NoSuchMethodError: com.serena.dmclient.api.DimensionsObjectFactory.getServerVersion(I)Ljava/util/List; 메세지 발생 )
 

jenkins start

3. 전역정보 설정
jenkins 관리 > configure system > Dimensions
 
ref) https://wiki.jenkins-ci.org/display/JENKINS/Dimensions+Plugin 
posted by smplnote
2011. 5. 25. 18:48 IT
jenkins 
이전까지 hudson으로 알려져 있던 build server
반복적인 작업들의 실행을 모니터링 해준다.  ( from https://wiki.jenkins-ci.org/display/JENKINS/Meet+Jenkins )

site : http://jenkins-ci.org/ 
version : 1.413

cf) window service 등록을 금지하는 경우 윈도우용 installer를 사용해선 안됨
jdk : 1.6 이상 1.5에서는 오류 메시지 발생

주요 argument ( from http://winstone.sourceforge.net/#commandLine )
JENKINS_HOME : war가 풀릴 공간. default는 ${user.home}/.jenkins
--httpPort : default 8080
--ajp13Port : default 8009 , no use -1
--logfile : 콘솔 로그를 redirect 하여 저장할 파일 

실행스크립트 샘플 (윈도우용 => 서비스 등록하는게 더 편하지만 여건상 안되서.. )
set JENKINS_HOME=c:\my
set JAVA_HOME=c:\my\jdk1.6.0_25
set PATH=%JAVA_HOME%\bin
set HTTP_PORT=6666
set AJp13PORT=9999
set WEBROOT=c:\my\mywebroot
set LOGFILE=c:\my\log.log
start "jenkins" /B /d c:\my -jar c:\jenkins.war --httpPort=%HTTP_PORT --ajp13Port=%AJP13PORT% --webroot=%WEBROOT% --logfile=%LOGFILE%


 
posted by smplnote