<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-628035614856412995</id><updated>2012-02-16T20:45:33.787-08:00</updated><category term='ruby'/><category term='scripting'/><category term='haml'/><category term='git'/><category term='gem'/><category term='shell'/><category term='tips'/><category term='rails'/><category term='qnap'/><category term='jruby'/><category term='architecture'/><category term='nas'/><category term='database'/><title type='text'>Cutting Edge Meltdown</title><subtitle type='html'>Rainbow road addict</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://shenie.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/628035614856412995/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://shenie.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>shenie</name><uri>http://www.blogger.com/profile/09978796132519594310</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_GObCDyHXZns/Sxzw0r3OyNI/AAAAAAAAAPM/V0tjcbB67sM/s1600-R/b03b44e1aadb59c9515a6433069b3523.png'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>24</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-628035614856412995.post-3960218423347048025</id><published>2011-06-09T20:39:00.001-07:00</published><updated>2011-06-09T20:39:16.006-07:00</updated><title type='text'>Grails, spring-ws, SOAP &amp; HTTP request's content type</title><content type='html'>&lt;div class='posterous_autopost'&gt;&lt;p&gt;If you ever have to use Grails to process a fucked up SOAP request with a content type of&amp;nbsp;application/x-www-form-urlencoded then this post is for you.&lt;/p&gt;  &lt;p&gt;p.s. eventually we will stop processing that kind of requests but for now we need it to work so client has time to fix their shit up&lt;/p&gt;  &lt;p&gt;Problem with&amp;nbsp;application/x-www-form-urlencoded requests &amp;amp; spring-ws' message factory is that it does not like requests with that content type. Rightly so!&lt;/p&gt;  &lt;p&gt;The message factory content type issue is obvious since the exception that it throws at you is pretty self-explanatory. The work-around is pretty easy, define your own messageFactory spring bean that is more lenient on the content type.&lt;/p&gt;  &lt;p&gt;But after the content type is sorted you would face the second problem "Premature end of file". It took me a while to figure out what is happening. In retrospect it is actually quite logical. The end of file is referring to the request's input stream which has been consumed by Grails filters before it gets to the message factory. The following filters are responsible for parsing the request and routing, luckily they are also subclasses of OncePerRequestFilter which means you can easily bypass them to avoid input stream been consumed.&lt;/p&gt;  &lt;ol&gt;  &lt;li&gt;grailsWebRequest&lt;/li&gt;  &lt;li&gt;urlMapping&lt;/li&gt;  &lt;li&gt;hiddenHttpMethod&lt;/li&gt;  &lt;/ol&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/628035614856412995-3960218423347048025?l=shenie.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shenie.blogspot.com/feeds/3960218423347048025/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=628035614856412995&amp;postID=3960218423347048025' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/628035614856412995/posts/default/3960218423347048025'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/628035614856412995/posts/default/3960218423347048025'/><link rel='alternate' type='text/html' href='http://shenie.blogspot.com/2011/06/grails-spring-ws-soap-http-request.html' title='Grails, spring-ws, SOAP &amp;amp; HTTP request&amp;#39;s content type'/><author><name>shenie</name><uri>http://www.blogger.com/profile/09978796132519594310</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_GObCDyHXZns/Sxzw0r3OyNI/AAAAAAAAAPM/V0tjcbB67sM/s1600-R/b03b44e1aadb59c9515a6433069b3523.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-628035614856412995.post-1398485655747145928</id><published>2011-06-09T16:58:00.001-07:00</published><updated>2011-06-09T16:58:31.590-07:00</updated><title type='text'>How to use Groovy categories in gsp's</title><content type='html'>&lt;div class='posterous_autopost'&gt;&lt;p&gt;You use &lt;a href="http://docs.codehaus.org/display/GROOVY/Groovy+Categories"&gt;Groovy categories&lt;/a&gt;&amp;nbsp;in a canonical way in gsp's. i.e. by surrounding all your gsp code inside a call to&lt;/p&gt;  &lt;p style="padding-left: 30px;"&gt;&amp;lt;% use(YourCategoryClass) { %&amp;gt;&lt;/p&gt;  &lt;p style="padding-left: 30px;"&gt;&amp;lt;% } %&amp;gt;&lt;/p&gt;  &lt;p&gt;But it gets troublesome quite soon, especially if the main gsp renders other partial templates.&lt;/p&gt;  &lt;p&gt;Luckily there is a way to hook into the view rendering workflow. The trick is to provide your own implementation of View that invoke the call to use categories around the view.render method. To do that you also need to override the default jspViewResolver spring bean with your own implementation of ViewResolver which uses your own implementation of View. Lastly if you need dynamically decide what categories classes to use then you can pass it in the model attribute inside your controller.&lt;/p&gt;  &lt;p&gt;The result will look something like this.&lt;/p&gt;  &lt;p&gt;&lt;div class="data type-groovy"&gt;  &lt;table cellspacing="0" cellpadding="0"&gt; &lt;tr&gt; &lt;td&gt; &lt;pre class="line_numbers"&gt;&lt;span rel="#L1" id="L1"&gt;1&lt;/span&gt; &lt;span rel="#L2" id="L2"&gt;2&lt;/span&gt; &lt;span rel="#L3" id="L3"&gt;3&lt;/span&gt; &lt;span rel="#L4" id="L4"&gt;4&lt;/span&gt; &lt;span rel="#L5" id="L5"&gt;5&lt;/span&gt; &lt;span rel="#L6" id="L6"&gt;6&lt;/span&gt; &lt;span rel="#L7" id="L7"&gt;7&lt;/span&gt; &lt;span rel="#L8" id="L8"&gt;8&lt;/span&gt; &lt;span rel="#L9" id="L9"&gt;9&lt;/span&gt; &lt;span rel="#L10" id="L10"&gt;10&lt;/span&gt; &lt;span rel="#L11" id="L11"&gt;11&lt;/span&gt; &lt;span rel="#L12" id="L12"&gt;12&lt;/span&gt; &lt;span rel="#L13" id="L13"&gt;13&lt;/span&gt; &lt;span rel="#L14" id="L14"&gt;14&lt;/span&gt; &lt;span rel="#L15" id="L15"&gt;15&lt;/span&gt; &lt;span rel="#L16" id="L16"&gt;16&lt;/span&gt; &lt;span rel="#L17" id="L17"&gt;17&lt;/span&gt; &lt;span rel="#L18" id="L18"&gt;18&lt;/span&gt; &lt;span rel="#L19" id="L19"&gt;19&lt;/span&gt; &lt;span rel="#L20" id="L20"&gt;20&lt;/span&gt; &lt;span rel="#L21" id="L21"&gt;21&lt;/span&gt; &lt;span rel="#L22" id="L22"&gt;22&lt;/span&gt; &lt;span rel="#L23" id="L23"&gt;23&lt;/span&gt; &lt;span rel="#L24" id="L24"&gt;24&lt;/span&gt; &lt;span rel="#L25" id="L25"&gt;25&lt;/span&gt; &lt;span rel="#L26" id="L26"&gt;26&lt;/span&gt; &lt;span rel="#L27" id="L27"&gt;27&lt;/span&gt; &lt;span rel="#L28" id="L28"&gt;28&lt;/span&gt; &lt;span rel="#L29" id="L29"&gt;29&lt;/span&gt; &lt;span rel="#L30" id="L30"&gt;30&lt;/span&gt; &lt;/pre&gt; &lt;/td&gt; &lt;td width="100%"&gt;   &lt;div class="highlight"&gt;&lt;pre /&gt;&lt;div class="line" id="LC1"&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyGrailsViewResolver&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;GrailsViewResolver&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC2"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="line" id="LC3"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="nd"&gt;@Override&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC4"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="kd"&gt;protected&lt;/span&gt; &lt;span class="n"&gt;View&lt;/span&gt; &lt;span class="nf"&gt;loadView&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt; &lt;span class="n"&gt;viewName&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Locale&lt;/span&gt; &lt;span class="n"&gt;locale&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC5"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;MyView&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;super&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;loadView&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;viewName&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;locale&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC6"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="o"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC7"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="line" id="LC8"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyView&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="n"&gt;View&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC9"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="n"&gt;def&lt;/span&gt; &lt;span class="n"&gt;View&lt;/span&gt; &lt;span class="n"&gt;view&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC10"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="line" id="LC11"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="nf"&gt;MyView&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;View&lt;/span&gt; &lt;span class="n"&gt;view&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC12"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;view&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;view&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC13"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="o"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC14"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="line" id="LC15"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="n"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;getContentType&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC16"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="n"&gt;view&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getContentType&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC17"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="o"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC18"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="line" id="LC19"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="o"&gt;?&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;HttpServletRequest&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;HttpServletResponse&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC20"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;categories&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC21"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="n"&gt;use&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;remove&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;&amp;#39;&lt;/span&gt;&lt;span class="n"&gt;categories&lt;/span&gt;&lt;span class="err"&gt;&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC22"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="n"&gt;view&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;render&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC23"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="o"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC24"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC25"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="n"&gt;view&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;render&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC26"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="o"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC27"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="o"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC28"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="o"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC29"&gt;&lt;span class="o"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC30"&gt;&lt;br /&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;   &lt;/td&gt; &lt;/tr&gt; &lt;/table&gt;  &lt;/div&gt;&lt;/p&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/628035614856412995-1398485655747145928?l=shenie.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shenie.blogspot.com/feeds/1398485655747145928/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=628035614856412995&amp;postID=1398485655747145928' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/628035614856412995/posts/default/1398485655747145928'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/628035614856412995/posts/default/1398485655747145928'/><link rel='alternate' type='text/html' href='http://shenie.blogspot.com/2011/06/how-to-use-groovy-categories-in-gsp.html' title='How to use Groovy categories in gsp&amp;#39;s'/><author><name>shenie</name><uri>http://www.blogger.com/profile/09978796132519594310</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_GObCDyHXZns/Sxzw0r3OyNI/AAAAAAAAAPM/V0tjcbB67sM/s1600-R/b03b44e1aadb59c9515a6433069b3523.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-628035614856412995.post-1731192115521143378</id><published>2010-11-25T21:27:00.001-08:00</published><updated>2010-11-25T21:34:22.842-08:00</updated><title type='text'>Convert GPathResult to String without tag0</title><content type='html'>&lt;div class="posterous_autopost"&gt;In Groovy, you can use groovy.xml.XmlUtil.serialize(GPathResult node)&lt;br /&gt;to convert node to XML String. &lt;p&gt; But sometimes the XML you end up with contains tag0 namespace all over&lt;br /&gt;the elements. It happens because the doc contains default namespace&lt;br /&gt;with empty prefix, so groovy uses a default prefix which is "tag0".&lt;br /&gt;The XML is still correct but it would be nice to not have to see that&lt;br /&gt;crap. To do so you need to create a new closure with the node and&lt;br /&gt;explicitly declare an empty string namespace. Then use&lt;br /&gt;StreamingMarkupBuilder to convert the newly created closure to String.&lt;br /&gt;The following code is how you would implement that logic. &lt;/p&gt;&lt;p&gt;&lt;script src="https://gist.github.com/716310.js"&gt;&lt;/script&gt;&lt;/p&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/628035614856412995-1731192115521143378?l=shenie.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shenie.blogspot.com/feeds/1731192115521143378/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=628035614856412995&amp;postID=1731192115521143378' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/628035614856412995/posts/default/1731192115521143378'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/628035614856412995/posts/default/1731192115521143378'/><link rel='alternate' type='text/html' href='http://shenie.blogspot.com/2010/11/convert-gpathresult-to-string-without.html' title='Convert GPathResult to String without tag0'/><author><name>shenie</name><uri>http://www.blogger.com/profile/09978796132519594310</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_GObCDyHXZns/Sxzw0r3OyNI/AAAAAAAAAPM/V0tjcbB67sM/s1600-R/b03b44e1aadb59c9515a6433069b3523.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-628035614856412995.post-2124039377762568843</id><published>2010-07-08T02:57:00.001-07:00</published><updated>2010-07-08T02:57:39.545-07:00</updated><title type='text'>Overwrite Inploy app servers' restart command</title><content type='html'>&lt;div class='posterous_autopost'&gt;Inploy (&lt;a href="http://github.com/dcrec1/inploy)"&gt;http://github.com/dcrec1/inploy)&lt;/a&gt; is a rails deployment &lt;br /&gt;solution. It comes with integration to restart 4 app servers: &lt;br /&gt;* mongrel &lt;br /&gt;* passenger &lt;br /&gt;* thin &lt;br /&gt;* unicorn &lt;p /&gt; I needed a way to change how Inploy restarts passenger since our &lt;br /&gt;passenger's restart file is at a different location. &lt;p /&gt; I could've changed the command inside Inploy's passenger.rb but I &lt;br /&gt;wanted to avoid that as there's good chance that someone in the future &lt;br /&gt;won't know to re-apply the change when they upgrade Inploy. &lt;p /&gt; So I needed a way to monkey patch Inploy's passenger module. My first &lt;br /&gt;attempt was to create my version of the Passenger module and require &lt;br /&gt;the file in rails' environment.rb. That was no good because Inploy's &lt;br /&gt;update command does not seem to bootstrap the whole rails environment &lt;br /&gt;so my override simply wasn't getting loaded. &lt;p /&gt; I had to find another way in to load my module for the deployment &lt;br /&gt;process. It turns out the solution I was looking for is in rake. Since &lt;br /&gt;Inploy's update is just a rake task, I could create a passenger.rake &lt;br /&gt;in Rails.root/lib/tasks and define my restart_server override inside &lt;br /&gt;my custom passenger.rake. &lt;p /&gt; Please let me know if there is a better / proper way to achieve what I &lt;br /&gt;needed. Otherwise hope this helps someone else.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/628035614856412995-2124039377762568843?l=shenie.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shenie.blogspot.com/feeds/2124039377762568843/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=628035614856412995&amp;postID=2124039377762568843' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/628035614856412995/posts/default/2124039377762568843'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/628035614856412995/posts/default/2124039377762568843'/><link rel='alternate' type='text/html' href='http://shenie.blogspot.com/2010/07/overwrite-inploy-app-servers-restart.html' title='Overwrite Inploy app servers&amp;#39; restart command'/><author><name>shenie</name><uri>http://www.blogger.com/profile/09978796132519594310</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_GObCDyHXZns/Sxzw0r3OyNI/AAAAAAAAAPM/V0tjcbB67sM/s1600-R/b03b44e1aadb59c9515a6433069b3523.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-628035614856412995.post-7145862834686402144</id><published>2009-12-09T17:42:00.001-08:00</published><updated>2009-12-09T17:42:13.227-08:00</updated><title type='text'>My shortcut to open any gem in TextMate with 1 command</title><content type='html'>Using the&amp;nbsp;&lt;a href="http://blog.peepcode.com/tutorials/2009/shell-method-missing/shell_method_missing.rb"&gt;implementation&lt;/a&gt;&amp;nbsp;from @peepcode's&amp;nbsp;&lt;a href="http://blog.peepcode.com/tutorials/2009/shell-method-missing"&gt;blog on shell method missing&lt;/a&gt;&amp;nbsp;as a base.&lt;div&gt;I've added another action (code snippet below) to open a gem library in TextMate by typing in the name of the gem followed by ".mate".&lt;/div&gt;&lt;p /&gt;&lt;div&gt;&lt;div&gt;&lt;span style="font-size: 12px;"&gt;when /^[A-Za-z0-9_\-\/]+\.mate$/&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-size: 12px;"&gt;&amp;nbsp;&amp;nbsp;# Open the gem in textmate&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-size: 12px;"&gt;&amp;nbsp;&amp;nbsp;# @example&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-size: 12px;"&gt;&amp;nbsp;&amp;nbsp;# &amp;nbsp; haml.mate&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-size: 12px;"&gt;&amp;nbsp;&amp;nbsp;gem_to_open = command.first.gsub(/\.mate$/, '')&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-size: 12px;"&gt;&amp;nbsp;&amp;nbsp;run "gem which #{gem_to_open} | tail -1 | xargs dirname | sed -e's/$/\\/../' | xargs mate"&lt;/span&gt;&lt;/div&gt;&lt;p /&gt;&lt;/div&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/628035614856412995-7145862834686402144?l=shenie.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shenie.blogspot.com/feeds/7145862834686402144/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=628035614856412995&amp;postID=7145862834686402144' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/628035614856412995/posts/default/7145862834686402144'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/628035614856412995/posts/default/7145862834686402144'/><link rel='alternate' type='text/html' href='http://shenie.blogspot.com/2009/12/my-shortcut-to-open-any-gem-in-textmate.html' title='My shortcut to open any gem in TextMate with 1 command'/><author><name>shenie</name><uri>http://www.blogger.com/profile/09978796132519594310</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_GObCDyHXZns/Sxzw0r3OyNI/AAAAAAAAAPM/V0tjcbB67sM/s1600-R/b03b44e1aadb59c9515a6433069b3523.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-628035614856412995.post-53336413678706304</id><published>2009-11-25T22:05:00.001-08:00</published><updated>2009-11-25T22:05:41.582-08:00</updated><title type='text'>Download sources jar from maven</title><content type='html'>We use Maven, when Maven downloads dependencies it doesn't download sources, which I rely on when learn and debug programs.... &lt;br /&gt;I was expecting, for what seem a simple thing to me, a flag that I can add in maven's settings files or an option to pass to mvn command.... but I couldn't find the solution (or anything close to it). Don't get me wrong, there are solutions out there, but I just feel it is too much hassle for the task. &lt;p /&gt; So I wrote a little script that go thru my repo and downloads any jar that doesn't have its respective sources :p &lt;br /&gt;&lt;script src="http://gist.github.com/243263.js"&gt;&lt;/script&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/628035614856412995-53336413678706304?l=shenie.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shenie.blogspot.com/feeds/53336413678706304/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=628035614856412995&amp;postID=53336413678706304' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/628035614856412995/posts/default/53336413678706304'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/628035614856412995/posts/default/53336413678706304'/><link rel='alternate' type='text/html' href='http://shenie.blogspot.com/2009/11/download-sources-jar-from-maven.html' title='Download sources jar from maven'/><author><name>shenie</name><uri>http://www.blogger.com/profile/09978796132519594310</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_GObCDyHXZns/Sxzw0r3OyNI/AAAAAAAAAPM/V0tjcbB67sM/s1600-R/b03b44e1aadb59c9515a6433069b3523.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-628035614856412995.post-8739072732188170545</id><published>2009-11-23T16:51:00.001-08:00</published><updated>2009-11-23T22:33:23.960-08:00</updated><title type='text'>ImageMagick and JPEG on OSX</title><content type='html'>I am not a fan of port or fink so I always install ImageMagick from source.&lt;div&gt;Recently I came across a problem where ImageMagick fails to identify JPEG's.&lt;/div&gt;&lt;div&gt;The error looks something like this&lt;/div&gt;&lt;div&gt;identify: no decode delegate for this image format&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;div&gt;After some digging around it appears I need to install libjpeg and reinstall ImageMagick for JPEG support.&lt;/div&gt;&lt;div&gt;So I downloaded &lt;a href="http://www.imagemagick.org/download/delegates/jpegsrc.v7.tar.gz"&gt;jpegsrc.v7.tar.gz&lt;/a&gt; and just run thru the standard configure, make &amp;amp; make install then reinstalled ImageMagick.&lt;/div&gt;&lt;div&gt;After the installation you should be able to see JPEG as one of the supported format via the command "identify -list format".&lt;/div&gt;&lt;div&gt;It should contain something like this.&lt;/div&gt;&lt;div&gt;     JPEG* JPEG      rw-   Joint Photographic Experts Group JFIF format (70)&lt;p&gt;&lt;/p&gt;&lt;/div&gt; &lt;p style="font-size: 10px;"&gt;&lt;br /&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/628035614856412995-8739072732188170545?l=shenie.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shenie.blogspot.com/feeds/8739072732188170545/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=628035614856412995&amp;postID=8739072732188170545' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/628035614856412995/posts/default/8739072732188170545'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/628035614856412995/posts/default/8739072732188170545'/><link rel='alternate' type='text/html' href='http://shenie.blogspot.com/2009/11/imagemagick-and-jpeg-on-osx.html' title='ImageMagick and JPEG on OSX'/><author><name>shenie</name><uri>http://www.blogger.com/profile/09978796132519594310</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_GObCDyHXZns/Sxzw0r3OyNI/AAAAAAAAAPM/V0tjcbB67sM/s1600-R/b03b44e1aadb59c9515a6433069b3523.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-628035614856412995.post-2684702570205238885</id><published>2009-09-08T03:19:00.000-07:00</published><updated>2009-09-08T03:21:00.892-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='haml'/><title type='text'>Mass erb to haml conversion</title><content type='html'>&lt;div&gt;Do this in your application's root folder.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;span class="Apple-style-span"  style="color:#CC0000;"&gt;find . -name "*.erb" | while read f; do html2haml -r $f ${f%.erb}.haml; done;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/628035614856412995-2684702570205238885?l=shenie.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shenie.blogspot.com/feeds/2684702570205238885/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=628035614856412995&amp;postID=2684702570205238885' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/628035614856412995/posts/default/2684702570205238885'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/628035614856412995/posts/default/2684702570205238885'/><link rel='alternate' type='text/html' href='http://shenie.blogspot.com/2009/09/mass-erb-to-haml-conversion.html' title='Mass erb to haml conversion'/><author><name>shenie</name><uri>http://www.blogger.com/profile/09978796132519594310</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_GObCDyHXZns/Sxzw0r3OyNI/AAAAAAAAAPM/V0tjcbB67sM/s1600-R/b03b44e1aadb59c9515a6433069b3523.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-628035614856412995.post-2210547788228631257</id><published>2009-08-27T18:29:00.000-07:00</published><updated>2009-08-27T18:31:14.917-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='shell'/><category scheme='http://www.blogger.com/atom/ns#' term='scripting'/><title type='text'>How to stop unix read command escape backslashes</title><content type='html'>If you want to pipe any output that has backslashes in it (or make 'read' take a string with backslashes) to the read command then you will need to stop the &lt;span style="font-weight: bold;"&gt;read&lt;/span&gt; command treating backslash as escape character by using &lt;b&gt;read -r&lt;/b&gt;&lt;br /&gt;e.g.&lt;br /&gt;&lt;pre&gt;&lt;span style="color: rgb(153, 0, 0);"&gt;cleartool ls | while read -r file&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(153, 0, 0);"&gt;do&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(153, 0, 0);"&gt;  # do something to file&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(153, 0, 0);"&gt;done&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/628035614856412995-2210547788228631257?l=shenie.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shenie.blogspot.com/feeds/2210547788228631257/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=628035614856412995&amp;postID=2210547788228631257' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/628035614856412995/posts/default/2210547788228631257'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/628035614856412995/posts/default/2210547788228631257'/><link rel='alternate' type='text/html' href='http://shenie.blogspot.com/2009/08/how-to-stop-unix-read-command-escape.html' title='How to stop unix read command escape backslashes'/><author><name>shenie</name><uri>http://www.blogger.com/profile/09978796132519594310</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_GObCDyHXZns/Sxzw0r3OyNI/AAAAAAAAAPM/V0tjcbB67sM/s1600-R/b03b44e1aadb59c9515a6433069b3523.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-628035614856412995.post-325243792507104925</id><published>2009-08-24T18:10:00.000-07:00</published><updated>2009-08-24T18:11:38.607-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='architecture'/><title type='text'>Software design or code design</title><content type='html'>&lt;span class="Apple-style-span" style="font-family: 'Lucida Grande', 'Trebuchet MS', 'Bitstream Vera Sans', Verdana, Helvetica, sans-serif; font-size: 14px; line-height: 19px; "&gt;&lt;h2 style="margin-top: 5px; margin-right: 0px; margin-bottom: 5px; margin-left: 0px; padding-top: 2px; padding-right: 10px; padding-bottom: 2px; padding-left: 10px; font-weight: bold; background-image: initial; background-repeat: initial; background-attachment: initial; -webkit-background-clip: initial; -webkit-background-origin: initial; background-color: rgb(238, 238, 238); font-size: 1.2em; background-position: initial initial; "&gt;Software design&lt;/h2&gt;Generally high level, a.k.a.&lt;br /&gt;&lt;ul style="margin-top: 5px; margin-right: 0px; margin-bottom: 12px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 30px; "&gt;&lt;li style="margin-top: 3px; margin-right: 0px; margin-bottom: 3px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "&gt;architecture&lt;br /&gt;&lt;/li&gt;&lt;li style="margin-top: 3px; margin-right: 0px; margin-bottom: 3px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "&gt;infrastructure&lt;br /&gt;e.g. 3-tiers or client server, ejb or not&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h2 style="margin-top: 5px; margin-right: 0px; margin-bottom: 5px; margin-left: 0px; padding-top: 2px; padding-right: 10px; padding-bottom: 2px; padding-left: 10px; font-weight: bold; background-image: initial; background-repeat: initial; background-attachment: initial; -webkit-background-clip: initial; -webkit-background-origin: initial; background-color: rgb(238, 238, 238); font-size: 1.2em; background-position: initial initial; "&gt;Code design&lt;/h2&gt;&lt;ul style="margin-top: 5px; margin-right: 0px; margin-bottom: 12px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 30px; "&gt;&lt;li style="margin-top: 3px; margin-right: 0px; margin-bottom: 3px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "&gt;domain design&lt;br /&gt;&lt;/li&gt;&lt;li style="margin-top: 3px; margin-right: 0px; margin-bottom: 3px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "&gt;flow design&lt;br /&gt;&lt;/li&gt;&lt;li style="margin-top: 3px; margin-right: 0px; margin-bottom: 3px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "&gt;good code design means clean, maintainable code&lt;br /&gt;&lt;/li&gt;&lt;li style="margin-top: 3px; margin-right: 0px; margin-bottom: 3px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "&gt;code design issues are easier to fix than software design&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;The following extract from Domain Driven Design applies regardless the type of project (waterfall or agile).&lt;br /&gt;&lt;blockquote style="margin-top: 5px; margin-right: 5px; margin-bottom: 5px; margin-left: 5px; padding-top: 5px; padding-right: 5px; padding-bottom: 5px; padding-left: 5px; border-left-width: 3px; border-left-style: solid; border-left-color: rgb(119, 119, 119); width: 633px; "&gt;Any technical person contributing to the model must spend some &lt;br /&gt;time touching the code, whatever primary role he or she plays on &lt;br /&gt;the project. Anyone responsible for changing code must learn to &lt;br /&gt;express a model through the code. Every developer must be &lt;br /&gt;involved in some level of discussion about the model and have &lt;br /&gt;contact with domain experts. Those who contribute in different &lt;br /&gt;ways must consciously engage those who touch the code in a &lt;br /&gt;dynamic exchange of model ideas through the Ubiquitous &lt;br /&gt;Language.&lt;br /&gt;&lt;/blockquote&gt;A solution consultant should touch the code (or at least know the code if they don't want to touch it).&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/628035614856412995-325243792507104925?l=shenie.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shenie.blogspot.com/feeds/325243792507104925/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=628035614856412995&amp;postID=325243792507104925' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/628035614856412995/posts/default/325243792507104925'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/628035614856412995/posts/default/325243792507104925'/><link rel='alternate' type='text/html' href='http://shenie.blogspot.com/2009/08/software-design-or-code-design.html' title='Software design or code design'/><author><name>shenie</name><uri>http://www.blogger.com/profile/09978796132519594310</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_GObCDyHXZns/Sxzw0r3OyNI/AAAAAAAAAPM/V0tjcbB67sM/s1600-R/b03b44e1aadb59c9515a6433069b3523.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-628035614856412995.post-6751785261311953670</id><published>2009-08-24T17:03:00.000-07:00</published><updated>2009-08-24T17:28:32.147-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='rails'/><title type='text'>Rails Rumble after thoughts</title><content type='html'>&lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica"&gt;Building an application in &lt;a href="http://railsrumble.com/"&gt;48 hrs&lt;/a&gt; is hard. Time flies when you are not prepared.&lt;/p&gt;&lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica; min-height: 14.0px"&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica; min-height: 14.0px"&gt;Here are some of the things that you want to touch on before the competition starts.&lt;/p&gt;&lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica; min-height: 14.0px"&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;application security / access - who has access to what&lt;/li&gt;&lt;li&gt;model / resource routes - what models are required and how are they connected from browser / UI perspective&lt;/li&gt;&lt;li&gt;fields &amp;amp; columns in models&lt;/li&gt;&lt;li&gt;model validation / mandatory fields&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica; min-height: 14.0px"&gt;For the initial first few models that you add to the application, the effort to add each one does not increases in linear fashion.&lt;/p&gt;&lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica; min-height: 14.0px"&gt;Because with each model, you need CRUD pages / functionality. Each additional page needs to be styled therefore more visual design required, also more thoughts required for workflow / navigation design.&lt;/p&gt;&lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica; min-height: 14.0px"&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica; min-height: 14.0px"&gt;Often we have to just implement some crude pages to test / visualise our app (particular for workflow) while our designer work thru the markup, which means we usually have to go back and cleanup those pages' markup to fit with the design.&lt;/p&gt;&lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica; min-height: 14.0px"&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica; min-height: 14.0px"&gt;Overall, it was exhausting but I learnt heaps of cool tricks this year building &lt;a href="http://techmeets.com/"&gt;TechMeets.com&lt;/a&gt;.&lt;/p&gt;&lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica"&gt;&lt;br /&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/628035614856412995-6751785261311953670?l=shenie.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shenie.blogspot.com/feeds/6751785261311953670/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=628035614856412995&amp;postID=6751785261311953670' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/628035614856412995/posts/default/6751785261311953670'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/628035614856412995/posts/default/6751785261311953670'/><link rel='alternate' type='text/html' href='http://shenie.blogspot.com/2009/08/rails-rumble-after-thoughts.html' title='Rails Rumble after thoughts'/><author><name>shenie</name><uri>http://www.blogger.com/profile/09978796132519594310</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_GObCDyHXZns/Sxzw0r3OyNI/AAAAAAAAAPM/V0tjcbB67sM/s1600-R/b03b44e1aadb59c9515a6433069b3523.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-628035614856412995.post-8513746917968035459</id><published>2009-08-17T20:01:00.000-07:00</published><updated>2009-08-17T20:09:16.737-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='gem'/><title type='text'>Using google_ajax_library when offline.</title><content type='html'>&lt;div&gt;As I mentioned in &lt;a href="http://blog.shenie.net/2009/02/how-do-i-automatically-revert-to-loca.html"&gt;How do I automatically revert to local javascript when offline?&lt;/a&gt;, I eventually forked &lt;a href="http://github.com/shenie/google_ajax_libraries_api/tree/master"&gt;google_ajax_library&lt;/a&gt; gem and added support for working offline.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I sent a pull request to Ryan Heath, the &lt;a href="http://github.com/rpheath/google_ajax_libraries_api/tree/master"&gt;original&lt;/a&gt; author the gem and he liked the feature but implemented it slightly differently to what I have done.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/628035614856412995-8513746917968035459?l=shenie.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shenie.blogspot.com/feeds/8513746917968035459/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=628035614856412995&amp;postID=8513746917968035459' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/628035614856412995/posts/default/8513746917968035459'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/628035614856412995/posts/default/8513746917968035459'/><link rel='alternate' type='text/html' href='http://shenie.blogspot.com/2009/08/using-googleajaxlibrary-when-offline.html' title='Using google_ajax_library when offline.'/><author><name>shenie</name><uri>http://www.blogger.com/profile/09978796132519594310</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_GObCDyHXZns/Sxzw0r3OyNI/AAAAAAAAAPM/V0tjcbB67sM/s1600-R/b03b44e1aadb59c9515a6433069b3523.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-628035614856412995.post-5290746481457286248</id><published>2009-08-17T19:52:00.000-07:00</published><updated>2009-08-17T19:55:33.010-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='tips'/><title type='text'>How to use WinMerge as ClearCase compare &amp; merge tool?</title><content type='html'>WinMerge made ClearCase much more bearable to work with.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;When installing WinMerge make sure you tick the 'Integrate with ClearCase' option.&lt;/div&gt;&lt;div&gt;That will make ClearCase use WinMerge as the compare program but ClearCase still uses its own merge program when resolving conflicts.&lt;/div&gt;&lt;div&gt;To change that setting you have to modify ClearCase configuration file manually.&lt;/div&gt;&lt;div&gt;The configuration file is usually in the lib managers' folder of the ClearCase installation.&lt;/div&gt;&lt;div&gt;e.g. C:\Program Files\Rational\ClearCase\lib\mgrs\map&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The change to the map file is based on what WinMerge did to the xcompare value&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&lt;span class="Apple-style-span"  style="color:#CC0000;"&gt;;text_file_delta&lt;/span&gt;&lt;span class="Apple-style-span" style="white-space: pre;"&gt;&lt;span class="Apple-style-span"  style="color:#CC0000;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&lt;span class="Apple-style-span"  style="color:#CC0000;"&gt;xmerge&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&lt;span class="Apple-style-span"  style="color:#CC0000;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&lt;span class="Apple-style-span"  style="color:#CC0000;"&gt;..\..\bin\cleardiffmrg.exe&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&lt;span class="Apple-style-span"  style="color:#CC0000;"&gt;text_file_delta xmerge C:\work\tools\WinMerge\WinMergeU.exe&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/628035614856412995-5290746481457286248?l=shenie.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shenie.blogspot.com/feeds/5290746481457286248/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=628035614856412995&amp;postID=5290746481457286248' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/628035614856412995/posts/default/5290746481457286248'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/628035614856412995/posts/default/5290746481457286248'/><link rel='alternate' type='text/html' href='http://shenie.blogspot.com/2009/08/how-to-use-winmerge-as-clearcase.html' title='How to use WinMerge as ClearCase compare &amp; merge tool?'/><author><name>shenie</name><uri>http://www.blogger.com/profile/09978796132519594310</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_GObCDyHXZns/Sxzw0r3OyNI/AAAAAAAAAPM/V0tjcbB67sM/s1600-R/b03b44e1aadb59c9515a6433069b3523.png'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-628035614856412995.post-5133801911750951072</id><published>2009-08-04T05:21:00.001-07:00</published><updated>2009-08-04T05:22:21.063-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='rails'/><title type='text'>How to validate money amount in ActiveRecord?</title><content type='html'>&lt;div&gt;This is how I validate money amount in Romey.&lt;/div&gt;&lt;div&gt;Basically an regex that allows up to 2 decimal points or whole integers.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;span class="Apple-style-span"  style="color:#CC0000;"&gt;validates_format_of :amount, :with =&amp;gt; /^\d+$|^\d+\.\d\d?$/&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/628035614856412995-5133801911750951072?l=shenie.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shenie.blogspot.com/feeds/5133801911750951072/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=628035614856412995&amp;postID=5133801911750951072' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/628035614856412995/posts/default/5133801911750951072'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/628035614856412995/posts/default/5133801911750951072'/><link rel='alternate' type='text/html' href='http://shenie.blogspot.com/2009/08/how-to-validate-money-amount-in.html' title='How to validate money amount in ActiveRecord?'/><author><name>shenie</name><uri>http://www.blogger.com/profile/09978796132519594310</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_GObCDyHXZns/Sxzw0r3OyNI/AAAAAAAAAPM/V0tjcbB67sM/s1600-R/b03b44e1aadb59c9515a6433069b3523.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-628035614856412995.post-4685287137790380416</id><published>2009-04-29T03:13:00.001-07:00</published><updated>2009-11-27T03:55:09.471-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='rails'/><category scheme='http://www.blogger.com/atom/ns#' term='nas'/><category scheme='http://www.blogger.com/atom/ns#' term='qnap'/><title type='text'>How I installed ruby and run RoR on QNAP TS-219</title><content type='html'>&lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica"&gt;Set LD_LIBRARY_PATH to be /opt/lib so libssl.so.0.9.8 and libcrypto.so.0.9.8 can be found. Alternatively symlink them to /usr/lib might work as well.&lt;/p&gt;&lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica; min-height: 14.0px"&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica; min-height: 14.0px"&gt;Install ruby &amp;amp; rubygems from source, using default options.&lt;/p&gt;&lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica; min-height: 14.0px"&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica"&gt;Then run this to install mysql gem.&lt;/p&gt;&lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica"&gt;&lt;/p&gt;&lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica"&gt;gem install mysql -- --with-mysql-dir=/usr/local/mysql&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/628035614856412995-4685287137790380416?l=shenie.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shenie.blogspot.com/feeds/4685287137790380416/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=628035614856412995&amp;postID=4685287137790380416' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/628035614856412995/posts/default/4685287137790380416'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/628035614856412995/posts/default/4685287137790380416'/><link rel='alternate' type='text/html' href='http://shenie.blogspot.com/2009/04/how-i-install-ruby-and-run-ror-on-qnap.html' title='How I installed ruby and run RoR on QNAP TS-219'/><author><name>shenie</name><uri>http://www.blogger.com/profile/09978796132519594310</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_GObCDyHXZns/Sxzw0r3OyNI/AAAAAAAAAPM/V0tjcbB67sM/s1600-R/b03b44e1aadb59c9515a6433069b3523.png'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-628035614856412995.post-8679006920161808902</id><published>2009-02-19T19:44:00.001-08:00</published><updated>2009-02-19T19:52:25.458-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><title type='text'>How do I automatically revert to local javascript when offline?</title><content type='html'>&lt;div&gt;  I work on Rails applications that include jquery javascript files from ajax.googleapis.com. Every now and then I have to work on those apps offline.&lt;/div&gt;&lt;div&gt;  e.g. when I commute on trains.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;  The application has the same jquery javascript files locally so the old way of working offline was to comment out the google jquery include calls and uncomment the local javascript include calls.&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;I decided I didn't want to have to bother with that so I implemented something that will check if I am connected online or not and make the appropriate javascript include calls.&lt;/div&gt;&lt;br /&gt;The code looks like this:&lt;code&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: rgb(255, 0, 0);"&gt;- if Ping.pingecho("ajax.googleapis.com", 10, 80)&lt;br /&gt;  = google_jquery&lt;br /&gt;- else&lt;br /&gt;  = javascript_include_tag 'jquery-1.2.6.min.js'&lt;/span&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;div&gt;  The added bonus is that if ever ajax.googleapis.com goes down then our apps won't be affected.&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;  p.s. the above code is markup in &lt;a href="http://haml.hamptoncatlin.com/" id="ezwc" title="haml"&gt;haml&lt;/a&gt; and uses google_ajax_libraries_api plugin and ping.rb which comes with standard ruby installation. Down the track I might modify the plugin to support the offline backup.&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/628035614856412995-8679006920161808902?l=shenie.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shenie.blogspot.com/feeds/8679006920161808902/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=628035614856412995&amp;postID=8679006920161808902' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/628035614856412995/posts/default/8679006920161808902'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/628035614856412995/posts/default/8679006920161808902'/><link rel='alternate' type='text/html' href='http://shenie.blogspot.com/2009/02/how-do-i-automatically-revert-to-loca.html' title='How do I automatically revert to local javascript when offline?'/><author><name>shenie</name><uri>http://www.blogger.com/profile/09978796132519594310</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_GObCDyHXZns/Sxzw0r3OyNI/AAAAAAAAAPM/V0tjcbB67sM/s1600-R/b03b44e1aadb59c9515a6433069b3523.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-628035614856412995.post-5074119708423040594</id><published>2009-01-12T20:14:00.001-08:00</published><updated>2009-01-12T20:14:02.704-08:00</updated><title type='text'>How to remove windows carriage return (^M) on Mac</title><content type='html'>I don't want to install dos2unix via port and I know it's just a matter of search and replace those ^M chars.&lt;br&gt;&lt;br&gt;Here are a couple of command that should do the job of removing those trailing ^M (carriage return) chars.&lt;br&gt;&lt;br&gt;&lt;span style="color: rgb(204, 0, 0);"&gt;perl -pi -e's/\r//g' filename&lt;/span&gt;&lt;br style="color: rgb(204, 0, 0);"&gt;&lt;span style="color: rgb(204, 0, 0);"&gt;sed -e's/^M//g' filename &amp;gt; newfile&lt;/span&gt;&lt;br&gt;&lt;br&gt;To type ^M in Terminal do Ctrl+V then Ctrl+M.&lt;br&gt;&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/628035614856412995-5074119708423040594?l=shenie.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shenie.blogspot.com/feeds/5074119708423040594/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=628035614856412995&amp;postID=5074119708423040594' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/628035614856412995/posts/default/5074119708423040594'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/628035614856412995/posts/default/5074119708423040594'/><link rel='alternate' type='text/html' href='http://shenie.blogspot.com/2009/01/how-to-remove-windows-carriage-return-m.html' title='How to remove windows carriage return (^M) on Mac'/><author><name>shenie</name><uri>http://www.blogger.com/profile/09978796132519594310</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_GObCDyHXZns/Sxzw0r3OyNI/AAAAAAAAAPM/V0tjcbB67sM/s1600-R/b03b44e1aadb59c9515a6433069b3523.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-628035614856412995.post-5817199812160455508</id><published>2009-01-09T22:02:00.001-08:00</published><updated>2009-01-11T00:43:44.372-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='jruby'/><category scheme='http://www.blogger.com/atom/ns#' term='database'/><title type='text'>Use ActiveRecord migration to manage database changes in Java projects</title><content type='html'>A sort of sequel to &lt;a href="http://blog.shenie.net/2009/01/use-jruby-to-dump-db-schema-to-ruby.html" id="tvup" title="dumping schema into ruby"&gt;dumping schema into ruby&lt;/a&gt;. I am going to show how we can use ActiveRecord migration to manage our database change in Java projects.&lt;br /&gt;&lt;br /&gt;&lt;div&gt;  &lt;b&gt;Problem:&lt;/b&gt;&lt;br /&gt;&lt;/div&gt;Automatically track which schema change has been made to a database.&lt;br /&gt;Make it easy to recreate another database with the same schema.&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;b&gt;Requirements:&lt;/b&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family:'Lucida Grande';"&gt;&lt;span style="font-size:100%;"&gt;bsf.jar (from jruby binary download)&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family:'Lucida Grande';"&gt;&lt;span style="font-size:100%;"&gt;jruby-complete jar&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px;"&gt;jdbc jar&lt;/div&gt;&lt;div&gt;activerecord gem&lt;br /&gt;activerecord-jdbc-adapter gem&lt;/div&gt;&lt;br /&gt;&lt;b&gt;Resources:&lt;/b&gt;&lt;br /&gt;&lt;a href="http://www.ics.muni.cz/%7Emakub/ruby/#c2" id="d9bp" title="http://www.ics.muni.cz/~makub/ruby/#c2"&gt;http://www.ics.muni.cz/~makub/ruby/#c2&lt;/a&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;b&gt;Steps:&lt;/b&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;install jruby&lt;/div&gt;&lt;div&gt;jruby -S gem install --no-rdoc --no-ri activerecord&lt;br /&gt;jruby -S gem install --no-rdoc --no-ri activerecord-jdbc-adapter&lt;/div&gt;&lt;br /&gt;&lt;div&gt;See some code at &lt;a id="jaet" href="http://github.com/shenie/base_java_project/tree/master" title="http://github.com/shenie/base_java_project/tree/master"&gt;http://github.com/shenie/base_java_project/tree/master&lt;/a&gt; &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Known issues:&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px;"&gt;The &lt;span style="font-family:'Lucida Grande';"&gt;&lt;span style="font-size:100%;"&gt;jruby-complete jar contains rubygems and you can package up the other gems (above) into the jruby-complete jar and distribute it (check it into vcs) that way.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px;"&gt;&lt;a href="http://www.nabble.com/Packaging-up-gems-with-jruby-complete-td21188167.html" id="huf5" title="http://www.nabble.com/Packaging-up-gems-with-jruby-complete-td21188167.html" style="color: rgb(85, 26, 139);"&gt;http://www.nabble.com/Packaging-up-gems-with-jruby-complete-td21188167.html&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px;"&gt;Another way is to set GEM_PATH env variable to the location of the jruby gem directory.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px;"&gt;e.g. /Users/andy/dev/tools/jruby/lib/ruby/gems/1.8&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px;"&gt;&lt;a id="uhsw" href="http://www.ruby-forum.com/topic/163251" title="http://www.ruby-forum.com/topic/163251" style="color: rgb(85, 26, 139);"&gt;http://www.ruby-forum.com/topic/163251&lt;/a&gt; &lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;At the moment, you need to set GEM_PATH to be the jruby gem directory, which means each machine will require jruby to be installed plus the gems used.&lt;/div&gt;&lt;div&gt;It would be more ideal if we can just repackage jruby-complete jar with the additional gems to make deployment easier.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;Update: Thanks to &lt;/span&gt;&lt;a style="color: rgb(0, 102, 0);" href="http://blog.nicksieger.com/articles/2009/01/10/jruby-1-1-6-gems-in-a-jar"&gt;Nick's blog&lt;/a&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;, you no longer have to set GEM_PATH to get the gems required included by the &lt;/span&gt;&lt;a style="color: rgb(0, 102, 0);" href="http://github.com/shenie/base_java_project/tree/master"&gt;base application&lt;/a&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;.&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/628035614856412995-5817199812160455508?l=shenie.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shenie.blogspot.com/feeds/5817199812160455508/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=628035614856412995&amp;postID=5817199812160455508' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/628035614856412995/posts/default/5817199812160455508'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/628035614856412995/posts/default/5817199812160455508'/><link rel='alternate' type='text/html' href='http://shenie.blogspot.com/2009/01/use-activerecord-migration-to-manage.html' title='Use ActiveRecord migration to manage database changes in Java projects'/><author><name>shenie</name><uri>http://www.blogger.com/profile/09978796132519594310</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_GObCDyHXZns/Sxzw0r3OyNI/AAAAAAAAAPM/V0tjcbB67sM/s1600-R/b03b44e1aadb59c9515a6433069b3523.png'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-628035614856412995.post-9097535588427903418</id><published>2009-01-09T03:20:00.000-08:00</published><updated>2009-01-09T03:21:44.794-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='shell'/><category scheme='http://www.blogger.com/atom/ns#' term='scripting'/><title type='text'>How to do mass renaming of file extension</title><content type='html'>&lt;span style="font-weight: bold;"&gt;Problem:&lt;/span&gt;&lt;br /&gt;You want to rename all the .wiki files to be .textile instead.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Solution:&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(204, 0, 0);"&gt;\ls -1 *.wiki | while read f; do mv $f ${f%.wiki}.textile; done&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/628035614856412995-9097535588427903418?l=shenie.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shenie.blogspot.com/feeds/9097535588427903418/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=628035614856412995&amp;postID=9097535588427903418' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/628035614856412995/posts/default/9097535588427903418'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/628035614856412995/posts/default/9097535588427903418'/><link rel='alternate' type='text/html' href='http://shenie.blogspot.com/2009/01/how-to-do-mass-renaming-of-file.html' title='How to do mass renaming of file extension'/><author><name>shenie</name><uri>http://www.blogger.com/profile/09978796132519594310</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_GObCDyHXZns/Sxzw0r3OyNI/AAAAAAAAAPM/V0tjcbB67sM/s1600-R/b03b44e1aadb59c9515a6433069b3523.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-628035614856412995.post-7997495577856741966</id><published>2009-01-09T03:16:00.001-08:00</published><updated>2009-01-09T03:23:47.770-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='git'/><title type='text'>Easy way to backup codebase on USB key with git</title><content type='html'>&lt;b&gt;Requirements:&lt;/b&gt;&lt;br /&gt;&lt;div&gt;git (via cygwin)&lt;br /&gt;$ git --version&lt;br /&gt;git version 1.6.0.4&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;On USB key&lt;/b&gt;&lt;br /&gt;mkdir project.init and cd into it&lt;br /&gt;git --bare init&lt;br /&gt;&lt;br /&gt;&lt;b&gt;In project codebase's directory&lt;/b&gt;&lt;br /&gt;&lt;span style="color: rgb(106, 168, 79);"&gt;git init&lt;br /&gt;git add .&lt;br /&gt;git ci -m'first commit'&lt;br /&gt;git remote add origin /path/to/project.git&lt;br /&gt;git push origin master&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Modify you local master to track remote by appending the following to your project's .git/config file:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;span style="color: rgb(61, 133, 198);"&gt;&lt;span style="font-family:Verdana;"&gt;[branch "master"]&lt;br /&gt;remote = origin&lt;br /&gt;merge = refs/heads/master&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Verdana;"&gt;&lt;br /&gt;Then you can just do the following in the future to push new files to your USB.&lt;br /&gt;&lt;span style="color: rgb(106, 168, 79);"&gt;git add .&lt;br /&gt;git ci -m'update repos'&lt;br /&gt;git push&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;&lt;b&gt;Gotchas when using git on cygwin&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(224, 102, 102);"&gt;$ git push origin master&lt;br /&gt;Counting objects: 6669, done.&lt;br /&gt;Compressing objects: 100% (6570/6570), done.&lt;br /&gt;Writing objects: 100% (6669/6669), 7.90 MiB | 348 KiB/s, done.&lt;br /&gt;Total 6669 (delta 4488), reused 0 (delta 0)&lt;br /&gt;*** Project description file hasn't been set&lt;br /&gt;error: hooks/update exited with error code 1&lt;br /&gt;error: hook declined to update refs/heads/master&lt;br /&gt;To /cygdrive/e/westpac/compass.git&lt;br /&gt;! [remote rejected] master -&gt; master (hook declined)&lt;br /&gt;error: failed to push some refs to '/cygdrive/e/project.git'&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The above problem is caused by a hook script (.git/hooks/update).&lt;br /&gt;Rename update to something like update.bak so it does not get executed solves the above problem.&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;p.s. with the newer version of cygwin git the hook scripts are all suffixed with .sample in the file name, which means they don't get executed hence won't have the above problem.&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/628035614856412995-7997495577856741966?l=shenie.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shenie.blogspot.com/feeds/7997495577856741966/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=628035614856412995&amp;postID=7997495577856741966' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/628035614856412995/posts/default/7997495577856741966'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/628035614856412995/posts/default/7997495577856741966'/><link rel='alternate' type='text/html' href='http://shenie.blogspot.com/2009/01/easy-way-to-backup-codebase-on-usb-key.html' title='Easy way to backup codebase on USB key with git'/><author><name>shenie</name><uri>http://www.blogger.com/profile/09978796132519594310</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_GObCDyHXZns/Sxzw0r3OyNI/AAAAAAAAAPM/V0tjcbB67sM/s1600-R/b03b44e1aadb59c9515a6433069b3523.png'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-628035614856412995.post-4535792364329709793</id><published>2009-01-09T02:05:00.001-08:00</published><updated>2009-01-09T03:48:17.869-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='jruby'/><title type='text'>Use jruby to dump DB schema to ruby</title><content type='html'>&lt;b&gt;Problem:&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;I have a database that rails doesn't have an easy way to connect to.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Solution:&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Use jruby &amp;amp; JDBC&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Requirements:&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;jruby&lt;div&gt;activerecord&lt;/div&gt;&lt;div&gt;activerecord-jdbc-adapter&lt;/div&gt;&lt;div&gt;jdbc driver for the database you want to connect to&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Resources:&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;a id="iokw" href="http://jruby-extras.rubyforge.org/activerecord-jdbc-adapter/" title="http://jruby-extras.rubyforge.org/activerecord-jdbc-adapter/"&gt;http://jruby-extras.rubyforge.org/activerecord-jdbc-adapter/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Steps:&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;jruby -S gem install activerecord&lt;br /&gt;jruby -S gem install activerecord-jdbc-adapter&lt;br /&gt;&lt;br /&gt;Put the jdbc jar in Classpath for jruby. e.g. inside C:\work\tools\jruby-1.1.6\lib&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Run this script:&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(204, 0, 0);"&gt;require 'rubygems'&lt;br /&gt;gem 'activerecord-jdbc-adapter'&lt;br /&gt;require 'jdbc_adapter'&lt;br /&gt;require 'active_record'&lt;br /&gt;&lt;br /&gt;ActiveRecord::Base.establish_connection(&lt;br /&gt; :adapter =&gt; 'jdbc',&lt;br /&gt; :driver =&gt; 'com.microsoft.sqlserver.jdbc.SQLServerDriver',&lt;br /&gt; :url =&gt; 'jdbc:sqlserver://localhost:1433;DatabaseName=FineosSixApp',&lt;br /&gt; :username =&gt; 'username',&lt;br /&gt; :password =&gt; 'password'&lt;br /&gt;)&lt;br /&gt;&lt;br /&gt;ActiveRecord::SchemaDumper.dump&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;To load the schema into say mysql&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(204, 0, 0);"&gt;require 'rubygems'&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(204, 0, 0);"&gt;require 'active_record'&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(204, 0, 0);"&gt;ActiveRecord::Base.establish_connection(&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(204, 0, 0);"&gt;  :adapter  =&gt; "mysql",&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(204, 0, 0);"&gt;  :host     =&gt; "localhost",&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(204, 0, 0);"&gt;  :username =&gt; 'username',&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(204, 0, 0);"&gt;  :password =&gt; 'password',&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(204, 0, 0);"&gt;  :database =&gt; 'database'&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(204, 0, 0);"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(204, 0, 0);"&gt;load('schema.rb')&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Future Improvements:&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Instead of using jruby on command line, create an ant task that uses jruby.jar and do the same thing.&lt;br /&gt;Basically integrating the schema dump into the build file.&lt;br /&gt;&lt;br /&gt;It'll be useful to store the client code base along with schema that runs with the code base.&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/628035614856412995-4535792364329709793?l=shenie.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shenie.blogspot.com/feeds/4535792364329709793/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=628035614856412995&amp;postID=4535792364329709793' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/628035614856412995/posts/default/4535792364329709793'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/628035614856412995/posts/default/4535792364329709793'/><link rel='alternate' type='text/html' href='http://shenie.blogspot.com/2009/01/use-jruby-to-dump-db-schema-to-ruby.html' title='Use jruby to dump DB schema to ruby'/><author><name>shenie</name><uri>http://www.blogger.com/profile/09978796132519594310</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_GObCDyHXZns/Sxzw0r3OyNI/AAAAAAAAAPM/V0tjcbB67sM/s1600-R/b03b44e1aadb59c9515a6433069b3523.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-628035614856412995.post-3716650296137777267</id><published>2007-09-25T04:19:00.000-07:00</published><updated>2009-01-09T02:11:20.020-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='gem'/><title type='text'>How to copy gems to a different ruby installation</title><content type='html'>Assume the following:&lt;br /&gt;old ruby 1.8.4 installed in /opt/local/lib/ruby&lt;br /&gt;new ruby 1.8.6 installed in /usr/local/lib/ruby&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;cd /opt/local/lib/ruby&lt;br /&gt;sudo cp -r gems /usr/local/lib/ruby&lt;br /&gt;cd site_ruby/1.8/&lt;br /&gt;sudo cp -r gemconfigure.rb rubygems rubygems.rb ubygems.rb rbconfig /usr/local/lib/ruby/site_ruby/1.8/&lt;br /&gt;&lt;br /&gt;cd /opt/local/bin&lt;br /&gt;sudo rm irb gem ruby rake&lt;br /&gt;sudo rm erb gem_mirror gem_server gemwhich generate_yaml_index.rb rails rdoc ri testrb update_rubygems&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;restart terminal&lt;br /&gt;&lt;br /&gt;this is for emergency cos you should really re-install ruby related things since we might not have moved everything&lt;br /&gt;&lt;br /&gt;done&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/628035614856412995-3716650296137777267?l=shenie.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shenie.blogspot.com/feeds/3716650296137777267/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=628035614856412995&amp;postID=3716650296137777267' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/628035614856412995/posts/default/3716650296137777267'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/628035614856412995/posts/default/3716650296137777267'/><link rel='alternate' type='text/html' href='http://shenie.blogspot.com/2007/09/how-to-copy-gems-to-different-ruby.html' title='How to copy gems to a different ruby installation'/><author><name>shenie</name><uri>http://www.blogger.com/profile/09978796132519594310</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_GObCDyHXZns/Sxzw0r3OyNI/AAAAAAAAAPM/V0tjcbB67sM/s1600-R/b03b44e1aadb59c9515a6433069b3523.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-628035614856412995.post-7148205530408084647</id><published>2007-09-23T05:13:00.000-07:00</published><updated>2009-01-09T03:23:13.212-08:00</updated><title type='text'>What blogging app should I user?</title><content type='html'>Word press seems like a better application for my need...&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;2009 Update: after discovering google document's publishing feature I've decided to use blogger.com&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/628035614856412995-7148205530408084647?l=shenie.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shenie.blogspot.com/feeds/7148205530408084647/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=628035614856412995&amp;postID=7148205530408084647' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/628035614856412995/posts/default/7148205530408084647'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/628035614856412995/posts/default/7148205530408084647'/><link rel='alternate' type='text/html' href='http://shenie.blogspot.com/2007/09/what-blogging-app-should-i-user.html' title='What blogging app should I user?'/><author><name>shenie</name><uri>http://www.blogger.com/profile/09978796132519594310</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_GObCDyHXZns/Sxzw0r3OyNI/AAAAAAAAAPM/V0tjcbB67sM/s1600-R/b03b44e1aadb59c9515a6433069b3523.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-628035614856412995.post-807403232933647207</id><published>2007-02-02T16:51:00.000-08:00</published><updated>2009-01-09T03:22:52.647-08:00</updated><title type='text'>Muhahahaha I'm back</title><content type='html'>The loser that hi-jacked my blog address (after I deleted it) for advertising is gone so I decided to take blog back so it can't be used to do evil things :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/628035614856412995-807403232933647207?l=shenie.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shenie.blogspot.com/feeds/807403232933647207/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=628035614856412995&amp;postID=807403232933647207' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/628035614856412995/posts/default/807403232933647207'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/628035614856412995/posts/default/807403232933647207'/><link rel='alternate' type='text/html' href='http://shenie.blogspot.com/2007/02/muhahahaha-im-back.html' title='Muhahahaha I&apos;m back'/><author><name>shenie</name><uri>http://www.blogger.com/profile/09978796132519594310</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_GObCDyHXZns/Sxzw0r3OyNI/AAAAAAAAAPM/V0tjcbB67sM/s1600-R/b03b44e1aadb59c9515a6433069b3523.png'/></author><thr:total>0</thr:total></entry></feed>
