<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>힘껏 차라</title>
	<atom:link href="http://tzara.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://tzara.wordpress.com</link>
	<description>TFYQA</description>
	<lastBuildDate>Wed, 11 Jan 2012 02:41:17 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='tzara.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>힘껏 차라</title>
		<link>http://tzara.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://tzara.wordpress.com/osd.xml" title="힘껏 차라" />
	<atom:link rel='hub' href='http://tzara.wordpress.com/?pushpress=hub'/>
		<item>
		<title>Scala &#8211; $tag method</title>
		<link>http://tzara.wordpress.com/2012/01/06/scala-tag-method/</link>
		<comments>http://tzara.wordpress.com/2012/01/06/scala-tag-method/#comments</comments>
		<pubDate>Fri, 06 Jan 2012 07:12:58 +0000</pubDate>
		<dc:creator>tzara</dc:creator>
				<category><![CDATA[blah blah]]></category>
		<category><![CDATA[scala]]></category>

		<guid isPermaLink="false">http://tzara.wordpress.com/?p=602</guid>
		<description><![CDATA[참고 : 스칼라의 Class 1. age_$eq(int) 위 글에 설명되어 있듯 age_=()는 setter입니다. 즉, 실제 사용 시 outsider.age = 30 이라고 할 때 이것은 아래와 같이 호출하고 있다고 할 수 있습니다. outsider.age_=(30) 그런데 왜 age_= 가 아니고 age_$eq 로 바뀌었냐면 JVM 에서는 &#8216;=&#8217; 기호를 메서드명에 사용하는 것이 허용되지 않기 때문입니다. 2. $tag() public int $tag() throws java.rmi.RemoteException; 뭐 하는 놈일까? [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tzara.wordpress.com&amp;blog=32636&amp;post=602&amp;subd=tzara&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>참고 : <a href="http://blog.outsider.ne.kr/477?category=40" target="_blank">스칼라의 Class</a></p>
<p>1. <code>age_$eq(</code><code>int</code><code>)</code></p>
<p>위 글에 설명되어 있듯 age_=()는 setter입니다.</p>
<p>즉, 실제 사용 시</p>
<p>outsider.age = 30</p>
<p>이라고 할 때 이것은 아래와 같이 호출하고 있다고 할 수 있습니다.</p>
<p>outsider.age_=(30)</p>
<p>그런데 왜 age_= 가 아니고 age_$eq 로 바뀌었냐면 JVM 에서는 &#8216;=&#8217; 기호를 메서드명에 사용하는 것이 허용되지 않기 때문입니다.</p>
<p>2. $tag()</p>
<pre>public int $tag() throws java.rmi.RemoteException;</pre>
<p>뭐 하는 놈일까? &#8230; 이렇다는군요.</p>
<blockquote><p>This(=$tag()) is a method defined within the ScalaObject trait designed to help optimize pattern matching. Unfortunately, it also means yet another abstract method which must be defined when implementing Scala traits which contain method definitions. ( via <a href="http://www.codecommit.com/blog/java/interop-between-java-and-scala">Interop Between Java and Scala</a> )</p></blockquote>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/tzara.wordpress.com/602/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/tzara.wordpress.com/602/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/tzara.wordpress.com/602/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/tzara.wordpress.com/602/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/tzara.wordpress.com/602/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/tzara.wordpress.com/602/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/tzara.wordpress.com/602/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/tzara.wordpress.com/602/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/tzara.wordpress.com/602/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/tzara.wordpress.com/602/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/tzara.wordpress.com/602/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/tzara.wordpress.com/602/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/tzara.wordpress.com/602/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/tzara.wordpress.com/602/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tzara.wordpress.com&amp;blog=32636&amp;post=602&amp;subd=tzara&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://tzara.wordpress.com/2012/01/06/scala-tag-method/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/384c298fccb743beb3a5f8946c8ae2c1?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">tzara</media:title>
		</media:content>
	</item>
		<item>
		<title>최대공약수 &#8211; java, scala</title>
		<link>http://tzara.wordpress.com/2012/01/06/%ec%b5%9c%eb%8c%80%ea%b3%b5%ec%95%bd%ec%88%98-java-scala/</link>
		<comments>http://tzara.wordpress.com/2012/01/06/%ec%b5%9c%eb%8c%80%ea%b3%b5%ec%95%bd%ec%88%98-java-scala/#comments</comments>
		<pubDate>Fri, 06 Jan 2012 06:31:03 +0000</pubDate>
		<dc:creator>tzara</dc:creator>
				<category><![CDATA[blah blah]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[scala]]></category>

		<guid isPermaLink="false">http://tzara.wordpress.com/?p=598</guid>
		<description><![CDATA[Greatest Common Divisor // java public long gcd(long a, long b) { return (b == 0)? a : gcd(b, a % b); } // scala def gcd(a: Long, b: Long): Long = if (b == 0) a else gcd(b, a % b) 아, 산수가 안되어서 &#8230; ㅜㅠ<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tzara.wordpress.com&amp;blog=32636&amp;post=598&amp;subd=tzara&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Greatest Common Divisor</p>
<pre>// java
public long gcd(long a, long b) {
    return (b == 0)? a : gcd(b, a % b);
}

// scala
def gcd(a: Long, b: Long): Long =
  if (b == 0) a else gcd(b, a % b)</pre>
<p>아, 산수가 안되어서 &#8230; ㅜㅠ</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/tzara.wordpress.com/598/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/tzara.wordpress.com/598/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/tzara.wordpress.com/598/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/tzara.wordpress.com/598/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/tzara.wordpress.com/598/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/tzara.wordpress.com/598/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/tzara.wordpress.com/598/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/tzara.wordpress.com/598/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/tzara.wordpress.com/598/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/tzara.wordpress.com/598/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/tzara.wordpress.com/598/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/tzara.wordpress.com/598/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/tzara.wordpress.com/598/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/tzara.wordpress.com/598/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tzara.wordpress.com&amp;blog=32636&amp;post=598&amp;subd=tzara&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://tzara.wordpress.com/2012/01/06/%ec%b5%9c%eb%8c%80%ea%b3%b5%ec%95%bd%ec%88%98-java-scala/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/384c298fccb743beb3a5f8946c8ae2c1?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">tzara</media:title>
		</media:content>
	</item>
		<item>
		<title>gpath 로 값 뽑을 때 포함된 tag 를 보존하려면</title>
		<link>http://tzara.wordpress.com/2011/12/27/gpath-%eb%a1%9c-%ea%b0%92-%eb%bd%91%ec%9d%84-%eb%95%8c-%ed%8f%ac%ed%95%a8%eb%90%9c-tag-%eb%a5%bc-%eb%b3%b4%ec%a1%b4%ed%95%98%eb%a0%a4%eb%a9%b4/</link>
		<comments>http://tzara.wordpress.com/2011/12/27/gpath-%eb%a1%9c-%ea%b0%92-%eb%bd%91%ec%9d%84-%eb%95%8c-%ed%8f%ac%ed%95%a8%eb%90%9c-tag-%eb%a5%bc-%eb%b3%b4%ec%a1%b4%ed%95%98%eb%a0%a4%eb%a9%b4/#comments</comments>
		<pubDate>Tue, 27 Dec 2011 01:31:20 +0000</pubDate>
		<dc:creator>tzara</dc:creator>
				<category><![CDATA[blah blah]]></category>
		<category><![CDATA[gpath]]></category>
		<category><![CDATA[groovy]]></category>

		<guid isPermaLink="false">http://tzara.wordpress.com/?p=595</guid>
		<description><![CDATA[gpath 의 간편함에 감탄한지 채 얼마 안되어 예상치않은 문제에 직면. &#8230; &#60;contenttitle&#62;End of Grace Period&#60;/contenttitle&#62; &#60;viewdate&#62;2011-06-24 08&#60;/viewdate&#62; &#60;contents&#62; &#60;contentimg/&#62; &#60;content&#62; &#60;p&#62;&#60;b&#62;tag test&#60;/b&#62;&#60;/p&#62; &#60;/content&#62; &#60;/contents&#62; &#8230;     def xml = new XmlSlurper().parse(xmlFile)     assert &#8220;&#60;p&#62;&#60;b&#62;tag test&#60;/b&#62;&#60;/p&#62;&#8221; == xml.contents.content.text()     어찌나 간편하고 깔끔하던지 값에 포함된 태그들을 알아서 다 날려버리더군요. 결국 이번 같은 경우나 CDATA  값을 그대로 가져오려는 경우 [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tzara.wordpress.com&amp;blog=32636&amp;post=595&amp;subd=tzara&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>gpath 의 간편함에 감탄한지 채 얼마 안되어 예상치않은 문제에 직면.</p>
<p>&#8230;<br />
&lt;contenttitle&gt;End of Grace Period&lt;/contenttitle&gt;<br />
&lt;viewdate&gt;2011-06-24 08&lt;/viewdate&gt;<br />
&lt;contents&gt;<br />
&lt;contentimg/&gt;<br />
&lt;content&gt;<br />
&lt;p&gt;&lt;b&gt;tag test&lt;/b&gt;&lt;/p&gt;<br />
&lt;/content&gt;<br />
&lt;/contents&gt;<br />
&#8230;</p>
<blockquote><p>    def xml = new XmlSlurper().parse(xmlFile)<br />
    assert &#8220;&lt;p&gt;&lt;b&gt;tag test&lt;/b&gt;&lt;/p&gt;&#8221; == xml.contents.content.text()<br />
   </p></blockquote>
<p>어찌나 간편하고 깔끔하던지 값에 포함된 태그들을 알아서 다 날려버리더군요.</p>
<p>결국 이번 같은 경우나 CDATA  값을 그대로 가져오려는 경우 gpath 사용 시 문제가 있네요.</p>
<p>XmlSlurper 대신 XmlParser 를 이용해도 쉽게 해결할 수 있을 것 같지 않고 결국 Xml 파서를 JDOM 이나 이런 것으로 바꿔야하나 갈등하다가 약간 꽁수를 써봤습니다.</p>
<blockquote><p>    def xml = new XmlSlurper().parse(xmlFile)<br />
    content = XmlUtil.serialize(xml.contents.content)<br />
    def matches = content =~ /(?s)&lt;content&gt;(.*?)&lt;\/content&gt;/<br />
    matches.each { assert &#8220;&lt;p&gt;&lt;b&gt;tag test&lt;/b&gt;&lt;/p&gt;&#8221; == it[1] }</p></blockquote>
<p>핵심은 GPathResult 를 groovy.xml.XmlUtil.serialize 를 이용해서 XML string 으로 재변환한 뒤 정규식으로 값을 재추출하는거.</p>
<p>p.s. 기본 아이디어는 &#8216;<a href="http://shenie.posterous.com/convert-gpathresult-to-string-without-tag0" target="_blank">Convert GPathResult to String without tag0</a>&#8216;에서 구했습니다.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/tzara.wordpress.com/595/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/tzara.wordpress.com/595/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/tzara.wordpress.com/595/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/tzara.wordpress.com/595/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/tzara.wordpress.com/595/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/tzara.wordpress.com/595/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/tzara.wordpress.com/595/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/tzara.wordpress.com/595/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/tzara.wordpress.com/595/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/tzara.wordpress.com/595/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/tzara.wordpress.com/595/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/tzara.wordpress.com/595/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/tzara.wordpress.com/595/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/tzara.wordpress.com/595/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tzara.wordpress.com&amp;blog=32636&amp;post=595&amp;subd=tzara&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://tzara.wordpress.com/2011/12/27/gpath-%eb%a1%9c-%ea%b0%92-%eb%bd%91%ec%9d%84-%eb%95%8c-%ed%8f%ac%ed%95%a8%eb%90%9c-tag-%eb%a5%bc-%eb%b3%b4%ec%a1%b4%ed%95%98%eb%a0%a4%eb%a9%b4/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/384c298fccb743beb3a5f8946c8ae2c1?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">tzara</media:title>
		</media:content>
	</item>
		<item>
		<title>groovy CharsetToolkit 보충</title>
		<link>http://tzara.wordpress.com/2011/12/19/groovy-charsettoolkit-%eb%b3%b4%ec%b6%a9/</link>
		<comments>http://tzara.wordpress.com/2011/12/19/groovy-charsettoolkit-%eb%b3%b4%ec%b6%a9/#comments</comments>
		<pubDate>Mon, 19 Dec 2011 02:29:05 +0000</pubDate>
		<dc:creator>tzara</dc:creator>
				<category><![CDATA[blah blah]]></category>
		<category><![CDATA[groovy]]></category>

		<guid isPermaLink="false">http://tzara.wordpress.com/?p=583</guid>
		<description><![CDATA[groovy CharsetToolkit 으로 구현했던 스크립트에 약간 문제가 있어 그거 보충하느라 &#8230; ****** 1. groovy CharsetToolkit 얼마 전 groovy의 CharsetToolkit 을 이용한 방법을 소개해드렸는데 이걸로 테스트해보던 어떤 분이 문제점을 하나 발견하고 원인까지 찾아내주셨습니다. http://groovy.codehaus.org/api/groovy/util/CharsetToolkit.html Uicode files encoded in UTF-16 (low or big endian) or UTF-8 files with a Byte Order Marker are correctly discovered. For UTF-8 files [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tzara.wordpress.com&amp;blog=32636&amp;post=583&amp;subd=tzara&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>groovy CharsetToolkit 으로 구현했던 스크립트에 약간 문제가 있어 그거 보충하느라 &#8230;</p>
<p>******</p>
<p>1. groovy CharsetToolkit</p>
<p>얼마 전 groovy의 CharsetToolkit 을 이용한 방법을 소개해드렸는데 이걸로 테스트해보던 어떤 분이 문제점을 하나 발견하고 원인까지 찾아내주셨습니다.</p>
<p><a href="http://groovy.codehaus.org/api/groovy/util/CharsetToolkit.html">http://groovy.codehaus.org/api/groovy/util/CharsetToolkit.html</a></p>
<blockquote><p>Uicode files encoded in UTF-16 (low or big endian) or UTF-8 files with a Byte Order Marker are correctly discovered. For UTF-8 files with no BOM, if the buffer is wide enough, the charset should also be discovered.</p>
<p>A byte buffer of 4KB is used to be able to guess the encoding.</p></blockquote>
<p>이 문서에 언급된 저 설명에 비추어보면 4KB 이내에 파일 charset 을 정확히 판단할 수 있는 문자가 포함되어 있지 않은 경우는 제대로 추정 못할 수 있을 수 있음을 알 수 있습니다.</p>
<p>그 분이 발견해서 지적해 준 문제가 이에 해당하는 거였는데</p>
<ul>
<li>파일 앞 부분에 영문만 있다가 나중에야 한글 문자가 포함되어 있는 어떤 파일에서 charset 을 제대로 찾아내지 못함.</li>
<li>파일 내용 앞 부분에 한글 문자를 임의로 하나 삽입해보니 제대로 charset 감지함.</li>
</ul>
<p>문제 피드백 받고 좀 더 찾아본 과정에서 몇가지 알게된 점을 간단히 정리해봅니다.</p>
<ul>
<li>BOM 이 있는 UTF 문서는 잘 처리된다. 하지만 BOM 이 없는 파일은 파일에 들어있는 문자로 charset  을 추정한다.
<ul>
<li>BOM에 대해선 가볍게 이 글 한 번 읽어보셔도 좋겠네요. &#8217;UTF-8 인코딩에서의 BOM(Byte Order Mark) 문제&#8217; <a href="http://blog.wystan.net/2007/08/18/bom-byte-order-mark-problem">http://blog.wystan.net/2007/08/18/bom-byte-order-mark-problem</a></li>
</ul>
</li>
<li>CharsetToolkit 구현 소스 내용 보면 byte[] bytes = new byte[4096]; 라고 되어 있다. 즉, 문서에 언급되어 있듯 4KB 의 문자열로만 추정하게끔 애초에 구현되어있다.
<ul>
<li><a href="http://grepcode.com/file/repo1.maven.org/maven2/org.codehaus.groovy/groovy-all/1.8.4/groovy/util/CharsetToolkit.java#CharsetToolkit">http://grepcode.com/file/repo1.maven.org/maven2/org.codehaus.groovy/groovy-all/1.8.4/groovy/util/CharsetToolkit.java#CharsetToolkit</a></li>
</ul>
</li>
</ul>
<p>결국은 용량이 4K 가 넘지 않는 텍스트 파일에 대해서는 groovy 의 CharsetToolkit 을 쓰면 쉽게 처리 가능하지만 그렇지 않은 경우에 대해서는 좀 더 고민이 필요할 것 같습니다.</p>
<p>2. java 의 encoding detector</p>
<p>이왕 이렇게 된거 조금 더 진행해보기록 했습니다.</p>
<p>java에서 charset 을 알아내는 것을 편하게 해주는 오픈소스 라이브러리로 몇 가지를 찾을 수 있었습니다.</p>
<ul>
<li>What is the most accurate encoding detector? <a href="http://stackoverflow.com/questions/3759356/what-is-the-most-accurate-encoding-detector">http://stackoverflow.com/questions/3759356/what-is-the-most-accurate-encoding-detector</a></li>
</ul>
<p>언급된 라이브러리 중에서 juniversalchardet을 이용해서 간단히 테스트를 해보았습니다.</p>
<blockquote><p>import groovy.io.FileType<br />
import org.mozilla.universalchardet.UniversalDetector</p>
<p>folder = &#8220;E:\\encoding_test\\data&#8221;</p>
<p>def guessEncoding(byte[] bytes) {<br />
        def DEFAULT_ENCODING = &#8220;UTF-8&#8243;<br />
        detector = new UniversalDetector(null)<br />
        detector.handleData(bytes, 0, bytes.length)<br />
        detector.dataEnd()<br />
        encoding = detector.getDetectedCharset()<br />
        detector.reset()</p>
<p>        if (encoding == null) {<br />
              encoding = DEFAULT_ENCODING<br />
        }</p>
<p>         return encoding<br />
}</p>
<p>def detectCharset() {<br />
        new File(folder).traverse(type:FileType.FILES, nameFilter:~/.*\.java|.*\.xml/) {<br />
                charSet = guessEncoding(it.getBytes())<br />
                 println &#8220;$it.name : $charSet&#8221;<br />
        }<br />
}</p>
<p>detectCharset()</p></blockquote>
<p>지난 번 짰던 소스를 그대로 이용하느라 groovy 에서 테스트해보긴 했으나 guessEncoding 메서드 부분에서 키워드 몇 개만 바꾸면 당연히 자바에서 그대로 사용 가능합니다.</p>
<p>테스트해본 바로는 위 1번에서 문제가 되었던 파일도 제대로 charset 을 찾아내네요.</p>
<p>다양한 charset 형태 파일로 테스트해보진 않았는데 관심있는 분들 있다면 한 번 테스트해보고 피드백 부탁드립니다.</p>
<p>그리고 universalchardet, jchardet, cpdetector, ICU4J  외에 괜찮은 다른 오픈 소스 추천해주셔도 고맙구요.</p>
<p>3. groovy 스크립트를 자바에서 사용하는 방법</p>
<blockquote>
<div>
<p>*** GroovyCharSetTest.groovy</p>
</div>
<div>
<p>package groovy;</p>
</div>
<div>
<p>import groovy.io.FileType<br />
import groovy.util.CharsetToolkit</p>
</div>
<div>
<p>public class GroovyCharSetTest {<br />
         def getCharSet() {<br />
               def folder = &#8220;D:\\charSetTest&#8221;</p>
</div>
<div>
<p>               def charSet = [:]</p>
<p>               new File(folder).traverse(type:FileType.FILES) {<br />
                       charSet[it.name] = new CharsetToolkit(it).getCharset().toString()<br />
               }</p>
<p>               return charSet<br />
        }<br />
}</p>
</div>
<div>
<p> *** TestCharSet.java</p>
</div>
<div>
<p>package groovy;</p>
</div>
<div>
<p>import java.util.Iterator;<br />
import java.util.Map;</p>
</div>
<div>
<p>public class TestCharSet {<br />
        public static void main(String args[]) {<br />
                GroovyCharSetTest gcst = new GroovyCharSetTest();</p>
<p>                Map map = (Map)gcst.getCharSet();<br />
                Iterator iterator = map.keySet().iterator();<br />
                while (iterator.hasNext()) {<br />
                        String key = (String) iterator.next();<br />
                        System.out.println(key + &#8221; : &#8221; + map.get(key));<br />
                }<br />
        }<br />
}</p>
</div>
</blockquote>
<div>지난 번 글에 올렸던 샘플을 자바에서 호출해서 사용해보려고 하신 분이 있어서 간단히 샘플을 만들어 보았습니다.</div>
<div>그 샘플을 직접 이용하는 경우 약간의 문제가 있어서 그에 대한 부분 (  def 키워드 관련 )에 대해서 답변 메일로 보냈던 내용을 그대로 옮겨 봅니다.</div>
<ol>
<li>No such property: folder for class: groovy.GroovyCharSetTest
<ul>
<li>groovy 에는 def 라는 변수나 함수 선언 시 사용하는 타입명을 대체해주는 키워드가 있는데 이걸 붙여주지 않아도 보통 때(?)는 상관 없습니다.
<ul>
<li>이렇게 구문의 편리성을 제공하는 걸 Syntatic sugar 라고들 합니다. 특히 ruby, python 등의 스크립트 언어들에서 Syntatic sugar 가 많이 제공됩니다.</li>
<li>일반 스크립트 구문에서는 def 붙이는 것과 그렇지 않은 것이 차이 없으나 변수를 class 안에서 사용할 때는 달라집니다.</li>
</ul>
</li>
<li>이건 groovy 에서의 closure 등과 관련되는 문제인데 &#8230; 일단 여기서는 간단하게 변수의 통용 범위 문제라고 이해하셔도 될 것 같네요.</li>
<li>핵심은 이번 처럼 Class 안에서 사용하는 변수에는 명시적으로 def 를 붙여주셔야 합니다.</li>
</ul>
</li>
<li>자바에서 소스 수정한 부분
<ul>
<li>groovy에서 제공하는 Map 이라는 타입( def charSet = [:] 부분 ) 으로 처리값 리턴하게 해주고 java 에서는 이걸 역시 java.util.Map 으로 받아 처리해주도록 했습니다.</li>
</ul>
</li>
</ol>
<div>
<p>추가로  groovy 로 만든 프로그램을 일반 자바 프로젝트에서 사용하는 방법은 몇 가지가 있는데 그 중 간단한 방법은 다음과 같습니다.</p>
</div>
<ol>
<li>groovy 설치 후 bin 디렉토리에 보면 groovyc 라는게 있습니다. groovyc 이용해서 그루비 스크립트를 자바 클래스 파일로 컴파일.</li>
</ol>
<ol>
<ul>
<li>가령 groovyc GroovyCharSetTest.groovy 와 같이 해주면 패키지명에 맞추어 알아서 클래스 파일 생성해줍니다.</li>
</ul>
</ol>
<ol start="2">
<li>groovy 설치 디렉토리 아래 embeddable 에 있는 groovy-all-***.jar 파일을 자바 프로젝트의 클래스패스에 추가해주면 1에서 컴파일한 클래스 파일을 사용 가능합니다.</li>
</ol>
<p>p.s :  충분한 예는  아니나 groovy 에서 java 라이브러리를 이용하는 방법은 2번을, java 에서 groovy 스크립트 이용하는 방법은 3번을 참고해볼 수 있을겁니다.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/tzara.wordpress.com/583/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/tzara.wordpress.com/583/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/tzara.wordpress.com/583/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/tzara.wordpress.com/583/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/tzara.wordpress.com/583/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/tzara.wordpress.com/583/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/tzara.wordpress.com/583/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/tzara.wordpress.com/583/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/tzara.wordpress.com/583/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/tzara.wordpress.com/583/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/tzara.wordpress.com/583/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/tzara.wordpress.com/583/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/tzara.wordpress.com/583/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/tzara.wordpress.com/583/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tzara.wordpress.com&amp;blog=32636&amp;post=583&amp;subd=tzara&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://tzara.wordpress.com/2011/12/19/groovy-charsettoolkit-%eb%b3%b4%ec%b6%a9/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/384c298fccb743beb3a5f8946c8ae2c1?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">tzara</media:title>
		</media:content>
	</item>
		<item>
		<title>groovy &#8211; CharsetToolkit 등등</title>
		<link>http://tzara.wordpress.com/2011/12/19/groovy-charsettoolkit-%eb%93%b1%eb%93%b1/</link>
		<comments>http://tzara.wordpress.com/2011/12/19/groovy-charsettoolkit-%eb%93%b1%eb%93%b1/#comments</comments>
		<pubDate>Mon, 19 Dec 2011 02:22:01 +0000</pubDate>
		<dc:creator>tzara</dc:creator>
				<category><![CDATA[blah blah]]></category>
		<category><![CDATA[groovy]]></category>

		<guid isPermaLink="false">http://tzara.wordpress.com/?p=576</guid>
		<description><![CDATA[이번에도 groovy. 간단한 작업 위해 만든 스크립트인데 나중에 써먹을 만한게 몇가지 있어서 적어봅니다. 작업 개요 : 특정 폴더 하위에 있는 모든 폴더의 자바 파일의 인코딩을 MS949 에서 UTF-8 로 전환 간단하니 일단 소스 부터. import groovy.io.FileType import groovy.util.CharsetToolkit folder = &#8220;E:\\encoding_test\\data&#8221; result = &#8220;E:\\encoding_test\\result&#8221; new File(folder).eachDirRecurse {                            // (1) subDir = it.path.replace(folder, &#8220;&#8221;) new File(&#8220;${result}\\${subDir}&#8221;).mkdirs()           // [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tzara.wordpress.com&amp;blog=32636&amp;post=576&amp;subd=tzara&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>이번에도 groovy.</p>
<p>간단한 작업 위해 만든 스크립트인데 나중에 써먹을 만한게 몇가지 있어서 적어봅니다.</p>
<p>작업 개요 : 특정 폴더 하위에 있는 모든 폴더의 자바 파일의 인코딩을 MS949 에서 UTF-8 로 전환</p>
<p>간단하니 일단 소스 부터.</p>
<blockquote><p>import groovy.io.FileType<br />
import groovy.util.CharsetToolkit</p>
<p>folder = &#8220;E:\\encoding_test\\data&#8221;<br />
result = &#8220;E:\\encoding_test\\result&#8221;</p>
<p>new File(folder).eachDirRecurse {                            // (1)<br />
subDir = it.path.replace(folder, &#8220;&#8221;)<br />
new File(&#8220;${result}\\${subDir}&#8221;).mkdirs()           // (2)<br />
}</p>
<p>new File(folder).traverse(type:FileType.FILES, nameFilter:~/.*\.java/) {<br />
charSet = new CharsetToolkit(it).getCharset();          // (3)<br />
target = result + it.path.replace(folder, &#8220;&#8221;)</p>
<p>if(charSet.toString() != &#8220;UTF-8&#8243;) {<br />
new FileOutputStream(target).withWriter(&#8216;UTF-8&#8242;) { writer -&gt;        // (4)<br />
new FileInputStream(it).withReader(&#8216;MS949&#8242;) { reader -&gt;<br />
writer &lt;&lt; reader<br />
}<br />
}<br />
}<br />
else {<br />
new AntBuilder().copy (file : it , tofile : target)                           // (5)<br />
}<br />
}</p></blockquote>
<p>(1)의 eachDirRecurse() 는 recursive 하게 디렉토리 정보를 구하는 메서드입니다.</p>
<p>( 제 컴 환경에서는 그냥 eachDir() 만으로도 되던데 딴 분 컴에서는 제일 상위의 서브 디렉토리만 찾는 문제가 있더군요. OS 차이 때문일까요? )</p>
<p>(2)에서는 mkdirs() 를 이용해서 결과 파일 저장할 디렉토리 하위에 작업 대상 디렉토리 구조와 동일하게 서브 디렉토리를 만들어 주었습니다.</p>
<p>(3)이 이번 작업하면서 알게된 꽤 유용한 groovy 에서 지원되는 기능인데 &#8230; groovy.util.CharsetToolkit 라는 캐릭터셋 처리 위한 패키지가 있더군요.</p>
<p>CharsetToolkit 에서 제공되는 getCharset()이란 메서드를 이용해서 파일의 캐릭터셋을 쉽게 알아낼 수 있습니다.</p>
<p>이걸 쓴 이유는 작업하려는 파일들에 MS949, UTF-8 파일이 섞여 있어서 무조건 인코딩을 바꿔주면 원래 UTF-8 형식이었던 파일은 한글이 깨지는 문제가 발생하더군요.</p>
<p>그래서 처리 전 파일의 캐릭터셋을 미리 확인해서 UTF-8인 경우에는 그냥 인코딩 변환 없이 결과 디렉토리로 복사만 해주었습니다.</p>
<p>(4) 이하 몇 줄은 &#8216;MS949&#8242; 형식 파일을 UTF-8로 변환해주는거구요.</p>
<p>(5)번은 파일 복사하는 부분입니다.</p>
<p>자바와 마찬가지로 File 클래스에 보면 renameTo()  라는 메서드가 있어서 rename 이나 move 등의 용도로 쓸 수 있습니다. (renameTo 쓰는 예는 지난 번 글에 있으니 참고하세요)</p>
<p>하지만 copy 를 위한 메서드는 따로 있지 않으므로 직접 구현해야 하는데 대신 AntBuilder의 copy 기능을 이용하면 쉽게 처리할 수 있습니다.</p>
<p>( AntBuilder는 별도로 import 처리할 필요도 없습니다 )</p>
<p>이게 전부입니다. 딴거야 자바로 처리해도 크게 아쉬운거 없지만 groovy.util.CharsetToolkit 은 알아두면 꽤 유용하게 쓸 수 있을 듯 싶네요.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/tzara.wordpress.com/576/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/tzara.wordpress.com/576/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/tzara.wordpress.com/576/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/tzara.wordpress.com/576/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/tzara.wordpress.com/576/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/tzara.wordpress.com/576/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/tzara.wordpress.com/576/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/tzara.wordpress.com/576/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/tzara.wordpress.com/576/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/tzara.wordpress.com/576/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/tzara.wordpress.com/576/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/tzara.wordpress.com/576/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/tzara.wordpress.com/576/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/tzara.wordpress.com/576/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tzara.wordpress.com&amp;blog=32636&amp;post=576&amp;subd=tzara&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://tzara.wordpress.com/2011/12/19/groovy-charsettoolkit-%eb%93%b1%eb%93%b1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/384c298fccb743beb3a5f8946c8ae2c1?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">tzara</media:title>
		</media:content>
	</item>
		<item>
		<title>groovy 사용 간단 예 &#8211; gpath, withBatch 등</title>
		<link>http://tzara.wordpress.com/2011/12/19/groovy-%ec%82%ac%ec%9a%a9-%ea%b0%84%eb%8b%a8-%ec%98%88-gpath-withbatch-%eb%93%b1/</link>
		<comments>http://tzara.wordpress.com/2011/12/19/groovy-%ec%82%ac%ec%9a%a9-%ea%b0%84%eb%8b%a8-%ec%98%88-gpath-withbatch-%eb%93%b1/#comments</comments>
		<pubDate>Mon, 19 Dec 2011 02:12:58 +0000</pubDate>
		<dc:creator>tzara</dc:creator>
				<category><![CDATA[blah blah]]></category>
		<category><![CDATA[groovy]]></category>

		<guid isPermaLink="false">http://tzara.wordpress.com/?p=574</guid>
		<description><![CDATA[이번에는 groovy. ****** 프로젝트 지원 나와서 간단한 작업 하나를 받았습니다. 특정 디렉토리 안에 있는 동일한 구조의 xml 파일들에서 몇 개의 element 값을 추출해서 DB 에 넣는거랍니다. 일단 뭘로 짤까 잠시 고민했는데 텍스트 파일 처리하는 이 정도의 작업이면 역시나 스크립트 언어가 적격이라 판단했습니다. 그리고 이 작업 맡을 분이 자바 사용자니 딴거보다는 적응이 용이하겠다 싶어서 스크립트 언어 중에서 groovy [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tzara.wordpress.com&amp;blog=32636&amp;post=574&amp;subd=tzara&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>이번에는 groovy.</p>
<p>******</p>
<p>프로젝트 지원 나와서 간단한 작업 하나를 받았습니다.<br />
특정 디렉토리 안에 있는 동일한 구조의 xml 파일들에서 몇 개의 element 값을 추출해서 DB 에 넣는거랍니다.</p>
<p>일단 뭘로 짤까 잠시 고민했는데 텍스트 파일 처리하는 이 정도의 작업이면 역시나 스크립트 언어가 적격이라 판단했습니다.<br />
그리고 이 작업 맡을 분이 자바 사용자니 딴거보다는 적응이 용이하겠다 싶어서 스크립트 언어 중에서 groovy 를 선택했습니다.</p>
<p>그럼 본격적으로 &#8230;</p>
<p>xml 은 대충 이런 식.</p>
<blockquote><p><!--?xml version="1.0" encoding="UTF-8"?--><!--?xml version="1.0" encoding="UTF-8"?-->&lt;?xml version=&#8221;1.0&#8243; encoding=&#8221;UTF-8&#8243;?&gt;<br />
&lt;abouthjs&gt;<br />
&lt;titleimg&gt;../img/news/tit_notice.gif&lt;/titleimg&gt;<br />
&lt;contenttitle&gt;어쩌구 저쩌구 24HR FAQ)&lt;/contenttitle&gt;<br />
&lt;appendimg/&gt; &lt;viewdate&gt;2010-11-10 13&lt;/viewdate&gt;<br />
&lt;contents&gt;<br />
&lt;contentimg/&gt;<br />
&lt;content&gt;어쩌구 저저꾸 24HR rule 관련 Customer Advisory&#8230;&lt;/content&gt;<br />
&lt;/contents&gt;<br />
&lt;servicekind&gt;T&lt;/servicekind&gt;<br />
&lt;localekind/&gt;<br />
&#8230;<br />
&lt;/abouthjs&gt;</p></blockquote>
<p>여기서 contenttitle, content, viewdate 등의 값을 추출해야 합니다.</p>
<p>groovy 소스부터 보겠습니다.</p>
<blockquote><p>import groovy.io.FileType<br />
import groovy.sql.*</p>
<p>def getXmlElement(xmlFile) {<br />
def xml = new XmlSlurper().parse((xmlFile.path).replace(&#8220;\\&#8221;, &#8220;/&#8221;))   // (3)<br />
def eleList = []<br />
eleList.add(xml.contenttitle.text())                                  // (4)<br />
eleList.add(xml.contents.content.text())<br />
eleList.add(xml.viewdate.text())<br />
return eleList<br />
}</p>
<p>def insertDb(resultMap) {<br />
def db = Sql.newInstance(&#8220;jdbc:oracle:thin:@dbUrl:port:dbSid&#8221;, &#8220;id&#8221;, &#8220;pw&#8221;, &#8220;oracle.jdbc.driver.OracleDriver&#8221;) // (5)<br />
db.withBatch(100, &#8220;INSERT INTO test (val1, val2, val3) VALUES (?, ?, ?)&#8221;) { ps -&gt;                               // (6)<br />
resultMap.each { k, v -&gt;<br />
ps.addBatch(v)                                                // (6-1)<br />
}<br />
}</p>
<p>db.close()<br />
}</p>
<p>def folder = args?.size() ? args[0] : &#8220;.&#8221;                            // (1)<br />
resultMap = [:]<br />
new File(folder).traverse(type:FileType.FILES, nameFilter:~/.*\.xml/, maxDepth:0) {    // (2)<br />
resultMap[it.getName()] = getXmlElement(it)                                                         // (2-1)<br />
}</p>
<p>insertDb(resultMap)</p></blockquote>
<p>단순한 작업이라 달랑 이게 전부입니다.</p>
<p>groovy 의 아주 기초 문법들은 일단 패스하고 이 작업에 사용한 groovy 의 몇가지 기능만 추려보겠습니다.</p>
<ul>
<li>job1. 디렉토리에서 파일 목록 구하기 : File</li>
<li>job2. XML 에서 데이타 추출 : gpath</li>
<li>job3. DB 처리 : groovy sql</li>
</ul>
<p dir="ltr">소스 실행 방법은</p>
<blockquote>
<p dir="ltr">C:\&gt;groovy XmlTest.groovy C:\data\xml</p>
</blockquote>
<p>( 소스 파일명은 XmlTest.groovy, XML 파일이 있는 디렉토리는 C:\data\xml 이라고 했습니다. )</p>
<p>소스 실행하면 진입점은 (1)이 됩니다.<br />
인자로 준 디렉토리를, 인자가 없을 경우에는 현재 디렉토리를  변수로 받습니다.</p>
<p>job1에 해당하는게 (2)입니다.<br />
지정한 디렉토리에서 파일 목록 구하는 방법은 꽤 많은데 이번 경우에는 traverse(&#8230;)라는 함수를 사용해봤습니다.<br />
xml 파일 목록만 구하기 위해 nameFilter:~/.*\.xml/ 를, 검색할 디렉토리의 하위 디렉토리는 찾을 필요 없기에 maxDepth:0 등의 패러미터를 주었습니다.<br />
(2-1)에서는 루프 돌면서 각각의 파일 정보(it)를 넘겨서 원하는 element 값들을 되돌려받아 resultMap 이라는 Map 에 파일명을 키값으로 담습니다.</p>
<p>job2에 관련된게 getXmlElement(&#8230;)입니다.<br />
(3)의 XmlSlurper().parse 에서 xml 파일 읽어들였고 (4)에서 원하는 element 값들 추출합니다.</p>
<p>(4)에서 쓰인게 gpath 란 기능인데 이건 xpath 의 groovy 구현체라고 생각하면 됩니다.<br />
xml 샘플의 구조와 xml.contents.content.text() 를 매칭시켜보면 gpath 가 얼마나 간편하게 특정 노드의 데이타를 가져올 수 있는지 알 수 있습니다.<br />
xpath 란거 이름만 들어봤지 실제 써보지 않았는데 xml 데이타 추출하는데서 만큼은 DOM이나 SAX 쓰는 것보다 무지 편한 것 같습니다.<br />
자바5 부터는 javax.xml.xpath 패키지가 기본 포함되었다 하니 앞으로 자바 코딩할 일 있을 때면 xpath 를 애용하게 될 것 같네요.</p>
<p>job3에 해당하는건 insertDb(&#8230;)입니다.<br />
groovy 역시 sql 사용 위해서는 jdbc 쓰므로 자바 코딩할 때 처럼 (5)번 써주면 되고 기타 groovy sql 기본 사용법은 패스.<br />
이번 코딩에서는 groovy 1.8.1 버전 부터 지원되기 시작한 자바의 batchUpdate 에 해당하는 withBatch를 써보았습니다.</p>
<p>자바의 batchUpdate는 아시다시피 다수의 sql문을 배열에 담은 후 한꺼번에 처리해주어 성능상의 이점을 얻을 수 있죠.<br />
마찬가지로 (6-1) addBatch 를 통해 복수의 xml 파일에서 추출한 값들을 순차적으로 넣어줍니다.</p>
<p>(6)의 insert 문 보면 필요한 bind 변수가 3개 인데 (6-1) ps.addBatch(v) 한 줄로 처리되었나 궁금하신 분도 계실겁니다.<br />
여기서 v 는 소스 따라가보면 getXmlElement 에서 리턴한 eleList 라는 List 타입의 변수값입니다.<br />
즉, v 에는 ["Test page", "테스트 컨텐츠", "2011-11-10 13"] 과 같은 형태로 값이 들어가 있는 셈이므로 저 한 줄 깔끔하게 처리됩니다.</p>
<p>batchUpdate 안쓰고 일반적인 방식으로 하자면 다음 정도로 하면 될겁니다.</p>
<blockquote><p>def db = Sql.newInstance(&#8230;)<br />
new File(folder).traverse(<br />
type:FileType.FILES,<br />
nameFilter:~/.*\.xml/,<br />
maxDepth:0<br />
) {<br />
resultList = getXmlElement(it)<br />
db.execute &#8220;INSERT INTO test (val1, val2, val3) VALUES (?, ?, ?)&#8221;, resultList<br />
};db.close()</p></blockquote>
<p>이상입니다.</p>
<p>*****</p>
<p>위 내용은 프로토타입으로 작성한거고 실제 구현했던거는 제약 조건이 꽤 많아서 소스 전면 수정( 한 300백 라인 정도)했습니다.</p>
<p>이 때 추가된 걸로 몇가지 간단하지만 나중에 재활용할만한거 두 어가지만 추가 정리</p>
<blockquote><p>def getDurationTime() {<br />
def timeStart = new Date()</p>
<p>&#8230;.</p>
<p>def timeStop = new Date()<br />
TimeDuration duration = TimeCategory.minus(timeStop, timeStart)</p>
<p>log.info duration<br />
}</p></blockquote>
<p>첨부 파일 처리할 때 쓴거로 유니크한 파일명 부여 위해서 uuid 사용한거</p>
<blockquote><p>def getUuidFileName(fExt) {<br />
uuid32 = getUUID()<br />
if (!fExt.isAllWhitespace() &amp;&amp; fExt.size() &lt; 4) {<br />
uuid32 = uuid32.substring(0, uuid32.size() &#8211; fExt.size() &#8211; 1) + &#8220;.&#8221; + fExt<br />
}</p>
<p>return uuid32<br />
}</p></blockquote>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/tzara.wordpress.com/574/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/tzara.wordpress.com/574/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/tzara.wordpress.com/574/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/tzara.wordpress.com/574/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/tzara.wordpress.com/574/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/tzara.wordpress.com/574/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/tzara.wordpress.com/574/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/tzara.wordpress.com/574/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/tzara.wordpress.com/574/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/tzara.wordpress.com/574/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/tzara.wordpress.com/574/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/tzara.wordpress.com/574/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/tzara.wordpress.com/574/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/tzara.wordpress.com/574/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tzara.wordpress.com&amp;blog=32636&amp;post=574&amp;subd=tzara&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://tzara.wordpress.com/2011/12/19/groovy-%ec%82%ac%ec%9a%a9-%ea%b0%84%eb%8b%a8-%ec%98%88-gpath-withbatch-%eb%93%b1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/384c298fccb743beb3a5f8946c8ae2c1?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">tzara</media:title>
		</media:content>
	</item>
		<item>
		<title>java properties 추출 위한 엑셀 매크로</title>
		<link>http://tzara.wordpress.com/2011/12/19/java-properties-%ec%b6%94%ec%b6%9c-%ec%9c%84%ed%95%9c-%ec%97%91%ec%85%80-%eb%a7%a4%ed%81%ac%eb%a1%9c/</link>
		<comments>http://tzara.wordpress.com/2011/12/19/java-properties-%ec%b6%94%ec%b6%9c-%ec%9c%84%ed%95%9c-%ec%97%91%ec%85%80-%eb%a7%a4%ed%81%ac%eb%a1%9c/#comments</comments>
		<pubDate>Mon, 19 Dec 2011 01:59:17 +0000</pubDate>
		<dc:creator>tzara</dc:creator>
				<category><![CDATA[blah blah]]></category>
		<category><![CDATA[excel]]></category>
		<category><![CDATA[macro]]></category>

		<guid isPermaLink="false">http://tzara.wordpress.com/?p=572</guid>
		<description><![CDATA[이번에는 excel macro. 급조한거라 함수명이나 로직이 조악하기는 하지만 &#8230; ********** 자바 웹 개발 시 웹상의 다국어 페이지 관리 등을 위해 ResourceBundle 방식을 이용해서 메시지나 레이블 등을 properties 파일에 넣어 활용하곤 합니다. 그런데 보통 실제 웹 디플로이 전에는 관리를 위해 이 컨텐츠들을 엑셀로 취합 관리하는 경우가 일반적이고 변경 시에는 여기 내용을 복사해서 텍스트 파일에 붙여 넣은 [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tzara.wordpress.com&amp;blog=32636&amp;post=572&amp;subd=tzara&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>이번에는 excel macro. 급조한거라 함수명이나 로직이 조악하기는 하지만 &#8230;</p>
<p>**********</p>
<p>자바 웹 개발 시 웹상의 다국어 페이지 관리 등을 위해 ResourceBundle 방식을 이용해서 메시지나 레이블 등을 properties 파일에 넣어 활용하곤 합니다.</p>
<p>그런데 보통 실제 웹 디플로이 전에는 관리를 위해 이 컨텐츠들을 엑셀로 취합 관리하는 경우가 일반적이고 변경 시에는 여기 내용을 복사해서</p>
<ul>
<li>텍스트 파일에 붙여 넣은 후 한글 등의 경우에는 native2ascii 를 실행해서 변환해주거나</li>
<li>이클립스 사용자들은 이 추가 작업이 불편해서 PropetiesEditor 등을 사용하는 듯 합니다.</li>
</ul>
<p>(옛날에는 보통 이런 식으로 했었지만 아마 요즘은 진일보한 방법 쓰고 있겠죠? 방법 공유 좀 해주세요 )</p>
<p>오늘은 엑셀에서 관리하는 내용을 properties 파일로 자동 추출하기 위해 짜본 간단한 매크로를 공유 차원에서 적어봅니다.</p>
<p>( 물론 POI 나 JExcelApi 등 이용해서 자바로도 충분히 가능한 작업입니다만 이 작업을 수행할 담당자가 개발자가 아니란 점을 고려하면 &#8230; )</p>
<table cellspacing="1">
<tbody>
<tr>
<td> </td>
<td>A</td>
<td>B</td>
<td>C</td>
<td>D</td>
</tr>
<tr>
<td>1</td>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
</tr>
<tr>
<td>2</td>
<td> </td>
<td>메시지 관리</td>
<td> </td>
<td> </td>
</tr>
<tr>
<td>3</td>
<td>일련번호</td>
<td>영문</td>
<td>국문</td>
<td>중문</td>
</tr>
<tr>
<td>4</td>
<td>EST00001</td>
<td>Detail Schedule</td>
<td>상세 스케줄</td>
<td>详细船期</td>
</tr>
<tr>
<td>5</td>
<td>EST00002</td>
<td>Route Information</td>
<td>라우트 정보</td>
<td>路径信息</td>
</tr>
</tbody>
</table>
<p>가령 엑셀의 문서 형식이 위와 같다고 할 때 매크로 소스는 아래와 같습니다.</p>
<p>소스의 VBA 문법에 관해서 설명은 건너뛰겠습니다.</p>
<p>데이타 추출해서 텍스트 파일로 저장 시 유니코드 값으로 전환하는 기능은 get_codepoints(&#8230;)에 구현해 놓았습니다. 여기서 핵심은 Hex(AscW(Mid$(msg, i, 1))) 입니다.</p>
<p>이 매크로 그런대로 잘 잘동했습니다만 중문의 간체의 유니코드를 처리 못하는 문제가 있더군요.</p>
<p>위 엑셀 샘플에서 详细船期 란 데이타 중 &#8216;详细&#8217;가 간자체입니다. 해당 글자의 번자는 &#8216;詳細&#8217;라고 하던데 아무튼 위에 언급한 Hex(&#8230;) 구문만으로는 &#8216;详细&#8217;의 정확한 값을 못가져옵니다.</p>
<p>그래서 간체 문제는 중문의 LocaleID (LCID) 값을 지정해주는 것으로 일단 해결했습니다 .</p>
<p>txt = txt &amp; StrConv(Hex(Asc(Mid$(msg, i, 1))), vbFromUnicode, 1028) 이런 식으로 하면 되네요.</p>
<p>대충 기본적인 문제들 해결한 VAB 매크로 소스는 다음과 같습니다.</p>
<blockquote><p>Sub ExportText()<br />
    Dim fso As Object<br />
    Dim dict As Dictionary, dict1 As Dictionary<br />
    Dim v As Variant<br />
    Dim sPath As String<br />
    Dim key_col As String</p>
<p>    title_str = GetTitle()<br />
  <br />
    Set dict = New Dictionary<br />
    With dict<br />
       .Add &#8220;en&#8221;, title_str<br />
       .Add &#8220;ko&#8221;, title_str<br />
       .Add &#8220;zh&#8221;, title_str<br />
    End With<br />
   <br />
    Set dict1 = New Dictionary<br />
    With dict1<br />
       .Add &#8220;ko&#8221;, Array(4, 4)<br />
       .Add &#8220;en&#8221;, Array(5, 5)<br />
       .Add &#8220;zh&#8221;, Array(6, 6)<br />
    End With</p>
<p>    es_pos = pFindRowPos(&#8220;ESW&#8221;)<br />
    es_title = vbCrLf &amp; &#8220;#ES(e-Service)&#8221; &amp; vbCrLf<br />
   <br />
    last_row = GetLastRow(&#8220;Sheet1&#8243;, &#8220;A&#8221;)<br />
    For i = 3 To last_row<br />
        key_col = Cells(i, 1)<br />
        If i = es_pos Then<br />
            For Each v In dict.keys<br />
                dict(v) = dict(v) &amp; es_title<br />
            Next<br />
        End If<br />
       <br />
        If key_col &lt;&gt; &#8220;&#8221; Then<br />
            For Each v In dict.keys<br />
                dict(v) = GetPropertieString(dict(v), key_col, Cells(i, dict1(v)(0)), v)<br />
            Next<br />
        End If<br />
    Next i<br />
   <br />
    sPath = ActiveWorkbook.Path</p>
<p>    Workbooks.Open sPath &amp; &#8220;\contents_v1.0.xlsx&#8221;<br />
        find_pos = pFindRowPos(&#8220;WS&#8221;)<br />
        last_row = GetLastRow(&#8220;Sheet1&#8243;, &#8220;A&#8221;)<br />
       <br />
        For i = find_pos To last_row<br />
            key_col = Cells(i, 1)<br />
            If key_col &lt;&gt; &#8220;&#8221; Then<br />
                For Each v In dict.keys<br />
                    dict(v) = GetPropertieString(dict(v), key_col, Cells(i, dict1(v)(1)), v)<br />
                Next<br />
            End If<br />
        Next i<br />
    ActiveWorkbook.Close</p>
<p>    Set fso = CreateObject(&#8220;scripting.filesystemobject&#8221;)<br />
    For Each v In dict.keys<br />
        r = CreateFile(fso, sPath, v, dict.Item(v))<br />
    Next<br />
    Set fso = Nothing<br />
   <br />
    MsgBox &#8220;done&#8221;<br />
End Sub</p>
<p>Function GetTitle()<br />
    GetTitle = &#8220;##############################&#8221; &amp; vbCrLf _<br />
             &amp; &#8220;# Message Properties&#8221; &amp; vbCrLf<br />
             &amp; &#8220;# 1. AM(Admin)&#8221; &amp; vbCrLf _<br />
             &amp; &#8220;#################################&#8221; &amp; vbCrLf _<br />
             &amp; &#8220;#CM(Common)&#8221; &amp; vbCrLf<br />
End Function</p>
<p>Private Function pFindRowPos(stext As Variant, _<br />
  Optional searchdirection As XlSearchDirection = xlNext, _<br />
  Optional searchorder As XlSearchOrder = xlByRows) As Long</p>
<p>    Dim lresult As Long, org As Range</p>
<p>    Set org = Cells.Find(what:=stext, LookIn:=xlValues, _<br />
    lookat:=xlPart, searchorder:=searchorder, _<br />
                 searchdirection:=searchdirection, _<br />
    MatchCase:=False, searchformat:=False)</p>
<p>    If Not org Is Nothing Then lresult = org.Row</p>
<p>    pFindRowPos = lresult</p>
<p>    Set org = Nothing</p>
<p>End Function</p>
<p>Function GetLastRow(data_sheet As String, key_column As String)<br />
    Worksheets(data_sheet).Activate<br />
    With ActiveSheet<br />
        LastRow = .Cells(.Rows.Count, key_column).End(xlUp).Row<br />
    End With<br />
   <br />
    GetLastRow = LastRow<br />
End Function</p>
<p>Function GetPropertieString(curr_txt As String, key_col As String, cel_val As String, lang As Variant)<br />
    Dim result As String<br />
    result = curr_txt &amp; key_col &amp; &#8221; = &#8221; &amp; GetCodePoints(cel_val, lang) &amp; vbCrLf<br />
   <br />
    GetPropertieString = result<br />
End Function</p>
<p>Private Function CreateFile(fso As Object, sPath As String, prop_file As Variant, msg_str As String)<br />
    Set lang_prop = fso.CreateTextFile(sPath &amp; &#8220;\message_&#8221; &amp; prop_file &amp; &#8220;.properties&#8221;, True)<br />
    With lang_prop<br />
        .Write msg_str<br />
        .Close<br />
    End With<br />
End Function</p>
<p>Function GetCodePoints(msg As String, lang As Variant)<br />
    Dim txt As String<br />
    Dim iChar As Integer<br />
   <br />
    msg = Replace(msg, Chr(10), &#8221; &#8220;)<br />
    For i = 1 To Len(msg)</p>
<p>        iChar = AscW(Mid$(msg, i, 1))</p>
<p>        If iChar = 63 Then<br />
            If lang = &#8220;zh&#8221; Then<br />
                If Mid$(msg, i, 1) = &#8220;?&#8221; Then<br />
                    txt = txt &amp; &#8220;?&#8221;<br />
                Else<br />
                    txt = txt &amp; StrConv(Hex(Asc(Mid$(msg, i, 1))), vbFromUnicode, 1028)  &#8216;간체<br />
                End If<br />
            Else<br />
                txt = txt &amp; &#8220;?&#8221;<br />
            End If<br />
        ElseIf iChar = 160 Then              &#8216;공백 특수문자 처리<br />
            txt = txt &amp; &#8221; &#8220;<br />
        ElseIf (iChar &lt; 128 And iChar &gt; 0) Then &#8216;Or (iChar &gt; 8210 And iChar &lt; 8304) Then   &#8216;“ ” ‘ ’ 처리<br />
            txt = txt &amp; Mid$(msg, i, 1)<br />
        Else<br />
            uni = StrConv(Hex(AscW(Mid$(msg, i, 1))), vbLowerCase)<br />
            If Len(uni) = 2 Then<br />
                uni = &#8220;00&#8243; &amp; uni             &#8216;ub7, ub0, ue1<br />
            End If<br />
            txt = txt &amp; &#8220;\u&#8221; &amp; uni<br />
        End If<br />
    Next i</p>
<p>    GetCodePoints = txt<br />
End Function</p></blockquote>
<ol>
<li>Dictionary 란걸 사용했는데 이걸 쓰려면 scrrun.dll 을 사용할 수 있도록 엑셀의 &#8216;도구 &gt; 참조&#8217;에서 Microsoft Scripting Runtime&#8217; 을 선택해주어야만 합니다. </li>
<li>pFindRowPos 라고 특정 문자열이 들어있는 셀의 row 위치 구하는 함수는 <a href="http://excelvbamacro.com/how-to-find-row-position-of-a-particular-text.html">http://excelvbamacro.com/how-to-find-row-position-of-a-particular-text.html</a> 에서 구했습니다.</li>
</ol>
<p> 덤으로 이 기능을 ruby 로 간단하게 구현한 테스트 코드도 적어 봅니다.</p>
<blockquote>
<div>require &#8216;win32ole&#8217;<br />
require &#8216;active_support&#8217;</div>
<div> </div>
<div>#excel = WIN32OLE::new(&#8216;excel.Application&#8217;)<br />
#sheet = excel.Workbooks.Open(&#8216;E:\test1.xlsx&#8217;).Worksheets(&#8216;Sheet3&#8242;)</div>
<div> </div>
<div>excel = WIN32OLE::connect(&#8216;excel.Application&#8217;)<br />
sheet = excel.activesheet</div>
<div>sheet.Range(&#8216;B4:E200&#8242;).columns.each { |col| col.cells.each { |cell| puts cell.Value + &#8221; : &#8221; + ActiveSupport::JSON.encode(cell.Value) } }</div>
<div> </div>
</blockquote>
<div>루비 소스는 제대로 쓰려면 한참 다듬어야 하지만 그래도 기본 기능은 들어가 있으니 &#8230; ( ActiveSupport::JSON.encode(cell.Value)가 unicode 의 code print 값 구하는 부분입니다.)</div>
<div>아직 간자 문제 등은 처리하지 않은 상태인데 엑셀에서 해결한 방식처럼 encode 함수 사용 시에 Locale 코드값을 설정하는 방법이 있는지 좀 찾아봐야겠습니다.</div>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/tzara.wordpress.com/572/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/tzara.wordpress.com/572/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/tzara.wordpress.com/572/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/tzara.wordpress.com/572/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/tzara.wordpress.com/572/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/tzara.wordpress.com/572/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/tzara.wordpress.com/572/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/tzara.wordpress.com/572/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/tzara.wordpress.com/572/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/tzara.wordpress.com/572/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/tzara.wordpress.com/572/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/tzara.wordpress.com/572/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/tzara.wordpress.com/572/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/tzara.wordpress.com/572/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tzara.wordpress.com&amp;blog=32636&amp;post=572&amp;subd=tzara&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://tzara.wordpress.com/2011/12/19/java-properties-%ec%b6%94%ec%b6%9c-%ec%9c%84%ed%95%9c-%ec%97%91%ec%85%80-%eb%a7%a4%ed%81%ac%eb%a1%9c/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/384c298fccb743beb3a5f8946c8ae2c1?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">tzara</media:title>
		</media:content>
	</item>
		<item>
		<title>ruby 기초 예 &#8211; multiple values return, Variable Arguments</title>
		<link>http://tzara.wordpress.com/2011/12/19/ruby-%ea%b8%b0%ec%b4%88-%ec%98%88-multiple-values-return-variable-arguments/</link>
		<comments>http://tzara.wordpress.com/2011/12/19/ruby-%ea%b8%b0%ec%b4%88-%ec%98%88-multiple-values-return-variable-arguments/#comments</comments>
		<pubDate>Mon, 19 Dec 2011 01:50:18 +0000</pubDate>
		<dc:creator>tzara</dc:creator>
				<category><![CDATA[blah blah]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://tzara.wordpress.com/?p=570</guid>
		<description><![CDATA[수작업으로 해야할 일 생겨서 스크립트로 처리하고 간단히 메모했던 몇 건들을 블로그에 나눠서 옮겨 적어본다. 처음 건은 간만에 ruby 로 했던 &#8230; ********************* 서버 쪽 구성이 변경되면서 이 틈을 타고 데이타 재 인터페이스에 대한 요청이 몰려드네요. 수작업으로 건별 처리하다 짜증나서 간만에 루비 스크립트를 짜봤습니다. 수작업으로 하려면 잔손이 많이 가서 그렇지 작업 패턴은 단순해서 구현에는 그다지 특별한 [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tzara.wordpress.com&amp;blog=32636&amp;post=570&amp;subd=tzara&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>수작업으로 해야할 일 생겨서 스크립트로 처리하고 간단히 메모했던 몇 건들을 블로그에 나눠서 옮겨 적어본다.</p>
<p>처음 건은 간만에 ruby 로 했던 &#8230;</p>
<p>*********************</p>
<p>서버 쪽 구성이 변경되면서 이 틈을 타고 데이타 재 인터페이스에 대한 요청이 몰려드네요. 수작업으로 건별 처리하다 짜증나서 간만에 루비 스크립트를 짜봤습니다.<br />
수작업으로 하려면 잔손이 많이 가서 그렇지 작업 패턴은 단순해서 구현에는 그다지 특별한 내용은 없었습니다. 그래도 몇가지 기초적이지만 재미난 것들만 뽑아서 적어봅니다.</p>
<p>1. ruby는 복수의 값 리턴이 가능합니다. 이런 식이죠.</p>
<blockquote><p>def getSql(msg_id)<br />
case msg_id<br />
when &#8220;M025&#8243;<br />
sql = &#8220;select &#8230;. from goods&#8221;<br />
module_name = &#8220;goods&#8221;<br />
when &#8220;M001&#8243;<br />
sql = &#8220;select &#8230;. from customer&#8221;<br />
module_name = &#8220;customer&#8221;<br />
end</p>
<p>return module_name, sql<br />
end</p>
<p>module_name, sql = getSql(&#8220;M025&#8243;)</p></blockquote>
<p>&nbsp;</p>
<p>자바 등에서는 이런 경우에 array 나 collection 등을 쓰겠지만 루비에서는 이렇게 간편하게 &#8230;</p>
<p>2. 루비는 Variable Arguments(가변인수)를 쓸 수 있습니다.</p>
<blockquote><p>def fetchIf(dbh, msg_id, *seg)<br />
&#8230;.<br />
end</p>
<p>fetchIf(dbh, &#8220;MDM001&#8243;, &#8220;US000025&#8243;)<br />
fetchIf(dbh, &#8220;MDM001&#8243;, &#8220;GOODS&#8221;, &#8220;TR01&#8243;)</p></blockquote>
<p>&nbsp;</p>
<p>위의 함수 선언부에 *seg 라고 한 부분 보이시죠? 이런 식으로 &#8220;*&#8221;을 붙여서 가변인수를 사용할 수 있답니다.<br />
가변 인수로 지정된 인자들은 배열 형태로 처리되므로 쉽게 사용 가능하죠.</p>
<p>그런데 여기서 제가 꽤 헤메었습니다.</p>
<blockquote><p>def fetchIf(dbh, msg_id, *seg)<br />
module_name, sql = getSql(msg_id)<br />
rs = dbh.prepare(sql)</p>
<p>if seg.length == 1<br />
rs.execute(seg[0])<br />
else<br />
rs.execute(seg[0], seg[1])<br />
end<br />
&#8230;<br />
end</p></blockquote>
<p>&nbsp;</p>
<p>가변인자로 넘겨받은 값들을 sql 의 바인드 변수값으로 넣어주려고 하는데 도무지 깔끔하게 안되더군요.</p>
<p>seg.join(&#8220;,&#8221;) 과 같은 식으로 값 분리해서 넘겨주어도 안되고 기타 등등 &#8230;<br />
그런데 허무하게도 넘겨줄 때도 그냥 가변인자 방식으로 하면 되더군요. 이렇게 한 줄로.</p>
<blockquote><p>rs.execute(*seg)</p></blockquote>
<p>execute 메서드에 이리 넘겨주어도 알아서 잘 처리해줍니다.</p>
<p>공부하는 셈치고 dbi 라이브러리 소스 파일에서 execute 구현된 부분은 찾아보니</p>
<blockquote><p>        def execute(*bindvars)<br />
&#8230;</p>
<p>@handle.bind_params(*bindvars)<br />
@handle.execute</p>
<p>&#8230;<br />
@row = DBI::Row.new(column_names, column_types, nil, @convert_types)<br />
#end<br />
return nil<br />
end</p></blockquote>
<p>대충 저런 식으로 구현되어 있습니다. 역시나 sql 바인딩할 변수를 몇 개 넘겨줄지 모르니 가변인자를 쓴 듯.</p>
<p>내친 김에 execute 에서 가변인자를 또다시 넘겨 호출하는 bind_params 는 또 어떻게 구현되었나 찾아보았습니다.</p>
<blockquote><p>       def bind_params(*bindvars)<br />
bindvars.each_with_index {|val,i| bind_param(i+1, val, nil) }<br />
self<br />
end</p></blockquote>
<p>이제 대략 응용할 방법 알 듯 합니다.</p>
<p>( 정말 혹시나 해서 첨언하자면 1.5 부터는 java 에서도 가변인자 지원합니다. void sum(int &#8230; i) 같은 식으로요. 역시나 배열로 처리됩니다 )</p>
<p>3. 수작업의 마지막 단계는 DB 에서 필요한 정보값들 구한 다음에 이 값들을 get 방식으로 구성해서 브라우저에서 웹서비스를 호출하는 것입니다.<br />
루비에서 이 작업을 자동으로 처리하기 위해 HTTP 클라이언트 API 를 사용했습니다.<br />
( <a href="http://ruby-doc.org/stdlib-1.9.3/libdoc/net/http/rdoc/Net/HTTP.html">http://ruby-doc.org/stdlib-1.9.3/libdoc/net/http/rdoc/Net/HTTP.html</a> 여기보면 잘 정리되어 있습니다. )</p>
<blockquote><p>params  = { :ModuleName =&gt; module_name, :InterfaceType =&gt; if_type, :TransactionStatus =&gt; &#8220;U&#8221;, :TransactionId =&gt; tran_id }<br />
uri.query = URI.parse(URI.encode_www_form(params))</p>
<p>res = Net::HTTP.get_response(uri)</p></blockquote>
<p>&nbsp;</p>
<p>잘 되는 듯 싶더니 수시로 URI::InvalidURIError 에러가 나더군요.</p>
<p>원인 찾아보니 :TransactionId =&gt; tran_id 에서 trans_id 변수에 넘어가는 인자값이 종종 &#8217;103|8230032&#8242; 과 같은 형태가 되는데 &#8220;|&#8221; 가 범인인 듯.</p>
<p>RFC 2396 section 2.4.3 에 이런 내용이 있다고 하네요.</p>
<blockquote><p>Other characters are excluded because gateways and other transport agents are known to sometimes modify such characters, or they are used as delimiters.<br />
unwise = &#8220;{&#8221; | &#8220;}&#8221; | &#8220;|&#8221; | &#8220;\&#8221; | &#8220;^&#8221; | &#8220;[" | "]&#8221; | &#8220;`&#8221;<br />
Data corresponding to excluded characters must be escaped in order to be properly represented within a URI.</p></blockquote>
<p>&nbsp;</p>
<p>예전에도 이 문제 피해가기 위해 트릭 쓴 적 있었는데 오래되어서 기억이 전혀 안나서 또 괜한 고생.</p>
<p>해법은 역시나 너무 간단했는데 bad URI 에러니 문제되는 인자값을 get 방식으로 넘겨주지 않고 다른 방식으로 넘겨주면 되는 것, 그냥 post 방식으로 넘겨주면 됩니다.</p>
<p>앞에 링크한 문서에 post 방식예도 잘 설명되어 있으므로 더 이상의 설명은 패스. libcurl 등으로 cURL 을 사용하는 방법도 고려해볼 수 있을텐데 이것 역시 패스.</p>
<p>&nbsp;</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/tzara.wordpress.com/570/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/tzara.wordpress.com/570/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/tzara.wordpress.com/570/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/tzara.wordpress.com/570/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/tzara.wordpress.com/570/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/tzara.wordpress.com/570/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/tzara.wordpress.com/570/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/tzara.wordpress.com/570/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/tzara.wordpress.com/570/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/tzara.wordpress.com/570/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/tzara.wordpress.com/570/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/tzara.wordpress.com/570/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/tzara.wordpress.com/570/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/tzara.wordpress.com/570/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tzara.wordpress.com&amp;blog=32636&amp;post=570&amp;subd=tzara&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://tzara.wordpress.com/2011/12/19/ruby-%ea%b8%b0%ec%b4%88-%ec%98%88-multiple-values-return-variable-arguments/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/384c298fccb743beb3a5f8946c8ae2c1?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">tzara</media:title>
		</media:content>
	</item>
		<item>
		<title>XWiki Setting</title>
		<link>http://tzara.wordpress.com/2011/09/28/xwiki-setting/</link>
		<comments>http://tzara.wordpress.com/2011/09/28/xwiki-setting/#comments</comments>
		<pubDate>Wed, 28 Sep 2011 01:17:29 +0000</pubDate>
		<dc:creator>tzara</dc:creator>
				<category><![CDATA[blah blah]]></category>
		<category><![CDATA[Xwiki]]></category>

		<guid isPermaLink="false">http://tzara.wordpress.com/?p=565</guid>
		<description><![CDATA[standalone 다운 받아서 잠시 써오다 팀 공용 PC 로 이전하면서 tomcat, MySQL 로 변경 작업을 했다. 일단 WAR 파일을 이용한 기본 설치 방법은 XWiki 공식 설치 문서를 참고하면 된다. http://platform.xwiki.org/xwiki/bin/view/AdminGuide/Installation 다음으로 MySQL 설정은 이 문서 ( http://platform.xwiki.org/xwiki/bin/view/AdminGuide/InstallationMySQL ) 보고 작업해주면 되는데 이 부분에서 의외로 발목 잡혀서 그 내용을 집중 정리해본다. MySQL 이용하기 위해서는 우선 /WEB-INF/hibernate.cfg.xml 에서 hsqldb [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tzara.wordpress.com&amp;blog=32636&amp;post=565&amp;subd=tzara&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>standalone 다운 받아서 잠시 써오다 팀 공용 PC 로 이전하면서 tomcat, MySQL 로 변경 작업을 했다.</p>
<p>일단 WAR 파일을 이용한 기본 설치 방법은 XWiki 공식 설치 문서를 참고하면 된다.</p>
<ul>
<li><a href="http://platform.xwiki.org/xwiki/bin/view/AdminGuide/Installation">http://platform.xwiki.org/xwiki/bin/view/AdminGuide/Installation</a></li>
</ul>
<div>다음으로 MySQL 설정은 이 문서 ( <a href="http://platform.xwiki.org/xwiki/bin/view/AdminGuide/InstallationMySQL">http://platform.xwiki.org/xwiki/bin/view/AdminGuide/InstallationMySQL</a> ) 보고 작업해주면 되는데 이 부분에서 의외로 발목 잡혀서 그 내용을 집중 정리해본다.</div>
<div>MySQL 이용하기 위해서는 우선 /WEB-INF/hibernate.cfg.xml 에서 hsqldb 로 설정 활성화되어 있던 부분을 코멘트 처리하고 MySQL 설정 부분을 활성화 시켜주어야 한다.</div>
<div>이것만 해주면 될 줄 알았다.  브라우져에서 접속해보니</div>
<blockquote>
<div>javax.servlet.ServletException: Error number 3 in 0: Could not initialize main XWiki context<br />
Wrapped Exception: Error number 3001 in 3: Cannot load class com.xpn.xwiki.store.migration.hibernate.XWikiHibernateMigrationManager from param xwiki.store.migration.manager.class</div>
</blockquote>
<p>500 에러만 나고 실행되지 않는다.</p>
<p>복잡하게 이것 저것 고민했는데 당연하다고 여긴 것 부터 의심했어야 했다.</p>
<p>MySQL jdbc 드라이버가 배포 WAR 에는 들어 있지 않다. ( 위 MySQL 문서에도 언급되어 있는데 놓쳤다 ㅜㅠ )</p>
<p>/WEB-INF/lib 디렉토리에  jdbc 드라이버 파일을 집어 넣고 다시 실행해봤다.</p>
<p>이것만 해주면 정말 될 줄 알았다&#8230; 또 500 에러. DB 풀 생성 못했다며 hibernate.cfg.xml 설정 이상 없는지 점검해보라는데 아무리 봐도 이상없다.</p>
<p>이 에러 때문에 정말 한참 고생하다가 /WEB-INF/xwiki.cfg 파일에서 아래 부분 활성화해 주었다.</p>
<blockquote><p>xwiki.store.hibernate.path=/WEB-INF/hibernate.cfg.xml</p></blockquote>
<p>혹시 몰라서 이것도 활성화</p>
<blockquote><p>xwiki.store.migration.manager.class=com.xpn.xwiki.store.migration.hibernate.XWikiHibernateMigrationManager</p></blockquote>
<p>여전히 에러 &#8230;<br />
hibernate.cfg.xml 에서 connection.url 기본 설정값을 인자없이 설정해보았다.</p>
<blockquote><p>기본 : jdbc:mysql://localhost/xwiki?useServerPrepStmts=false&amp;useUnicode=true&amp;characterEncoding=UTF-8&amp;sessionVariables=sql_mode=&#8221;<br />
변경 : jdbc:mysql://localhost/xwiki</p></blockquote>
<p>다시 실행. 드디어 텅빈 메인 화면이 뜬다.</p>
<p>기본 위키 문서 등이 포함되어 있는 xwiki-enterprise-wiki-**.xar 을 import 기능을 이용해서 설치하니 ( 기본 설치 시 처음에는 Admin 계정으로 로긴 안해도 이 기능 사용하게 되어 있다 ) 이제야 Xwiki 기본 꼴은 갖추고 표시된다.</p>
<ul>
<li>주 : import 하려고 xar 파일 선택해서 upload 버튼 눌러도 파일 선택하라는 메시지만 표시되고 아무 변화 없다면 위에 링크해 둔 MySQL 설정 문서에서 &#8220;max_allowed_packet&#8221; 부분 참고해서 패킷 크기를 늘여주어야 한다.</li>
</ul>
<p>자, 이제 후속 작업.</p>
<p>기존 standalone 에 작성했던 컨텐츠들을 이전해와야 하는데 Xwiki 의 안내 문서에 따르면 &#8220;Administrater Wiki &gt; Content &gt; Export&#8221; 에서 xar 파일로 내보낸 뒤 import 하면 된다고 나와 있던데 &#8230;</p>
<p>아뿔싸! standalone 에 추가로 뭘 설정(치)해야 되는지 Export 화면이 텅 비어 있어서 아무 것도 할 수 없었다 ㅜㅠ</p>
<p>작성한 컨텐츠도 얼마 안되고 해서 단순 무식한 방법을 선택했다. 각 페이지 마다에서 제공하는 &#8220;Export as XAR&#8221; 기능 이용해서 페이지 단위로 export 한 후 &#8220;Administrater Wiki &gt; Content &gt; Import&#8221; 로 이전.</p>
<p>그럭저럭 등록사용자/그룹 정보 외에는 이전 완료.</p>
<p>기타</p>
<ul>
<li>기본 관리자 계정은 Admin/admin (대소문자 구분하니 주의)</li>
<li>Admin 로긴 정보를 잊어 먹거나 했을 때는 xwiki.cfg  에서 &#8220;xwiki.superadminpassword=&#8221; 부분을 활성화 시킨 후 superadmin 계정으로 로긴해서 처리하면 된다.</li>
</ul>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/tzara.wordpress.com/565/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/tzara.wordpress.com/565/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/tzara.wordpress.com/565/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/tzara.wordpress.com/565/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/tzara.wordpress.com/565/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/tzara.wordpress.com/565/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/tzara.wordpress.com/565/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/tzara.wordpress.com/565/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/tzara.wordpress.com/565/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/tzara.wordpress.com/565/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/tzara.wordpress.com/565/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/tzara.wordpress.com/565/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/tzara.wordpress.com/565/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/tzara.wordpress.com/565/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tzara.wordpress.com&amp;blog=32636&amp;post=565&amp;subd=tzara&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://tzara.wordpress.com/2011/09/28/xwiki-setting/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/384c298fccb743beb3a5f8946c8ae2c1?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">tzara</media:title>
		</media:content>
	</item>
		<item>
		<title>Jolt Awards 20th (2010 &#8211; 2011) &#8211; The Best Books 수상작</title>
		<link>http://tzara.wordpress.com/2011/08/17/jolt-awards-20th-2010-2011-the-best-books-%ec%88%98%ec%83%81%ec%9e%91/</link>
		<comments>http://tzara.wordpress.com/2011/08/17/jolt-awards-20th-2010-2011-the-best-books-%ec%88%98%ec%83%81%ec%9e%91/#comments</comments>
		<pubDate>Wed, 17 Aug 2011 03:18:54 +0000</pubDate>
		<dc:creator>tzara</dc:creator>
				<category><![CDATA[book]]></category>

		<guid isPermaLink="false">http://tzara.wordpress.com/?p=563</guid>
		<description><![CDATA[Jolt Awards: The Best Books 분야 수상작이 발표되었군요. http://drdobbs.com/joltawards/231500080?pgno=1 6권이 최종 후보에 올라왔고 이 중 Continuous Delivery 가 Excellence Award 를 수상했습니다. Domain-Specific Languages, by Martin Fowler with Rebecca Parsons The Art of Computer Programming, Volume 4A: Combinatorial Algorithms, Part 1, by Donald E. Knuth The Joy of Clojure: Thinking the Clojure Way, by Michael [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tzara.wordpress.com&amp;blog=32636&amp;post=563&amp;subd=tzara&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Jolt Awards: The Best Books 분야 수상작이 발표되었군요. http://drdobbs.com/joltawards/231500080?pgno=1</p>
<p>6권이 최종 후보에 올라왔고 이 중 Continuous Delivery 가 Excellence Award 를 수상했습니다.</p>
<ul>
<li>Domain-Specific Languages, by Martin Fowler with Rebecca Parsons</li>
<li>The Art of Computer Programming, Volume 4A: Combinatorial Algorithms, Part 1, by Donald E. Knuth</li>
<li>The Joy of Clojure: Thinking the Clojure Way, by Michael Fogus and Chris Houser</li>
<li>Productivity Award #1: Seven Languages in Seven Weeks: A Pragmatic Guide to Learning Programming Languages, by Bruce A. Tate</li>
<li>Productivity Award #2: Mining the Social Web: Analyzing Data from Facebook, Twitter, LinkedIn, and Other Social Media Sites, by Matthew A. Russell</li>
<li>Excellence Award: Continuous Delivery: Reliable Software Releases through Build, Test, and Deployment Automation, by Jez Humble and David Farley</li>
</ul>
<div>&#8216;The Joy of Clojure&#8217;, &#8216;Seven Languages in Seven Weeks&#8217; 이 두 권을 상반기에 좀 읽다 말았네요.</div>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/tzara.wordpress.com/563/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/tzara.wordpress.com/563/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/tzara.wordpress.com/563/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/tzara.wordpress.com/563/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/tzara.wordpress.com/563/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/tzara.wordpress.com/563/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/tzara.wordpress.com/563/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/tzara.wordpress.com/563/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/tzara.wordpress.com/563/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/tzara.wordpress.com/563/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/tzara.wordpress.com/563/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/tzara.wordpress.com/563/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/tzara.wordpress.com/563/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/tzara.wordpress.com/563/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tzara.wordpress.com&amp;blog=32636&amp;post=563&amp;subd=tzara&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://tzara.wordpress.com/2011/08/17/jolt-awards-20th-2010-2011-the-best-books-%ec%88%98%ec%83%81%ec%9e%91/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/384c298fccb743beb3a5f8946c8ae2c1?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">tzara</media:title>
		</media:content>
	</item>
	</channel>
</rss>
