<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

  <title><![CDATA[Blind Squirrel]]></title>
  <link href="http://bealetech.com/atom.xml" rel="self"/>
  <link href="http://bealetech.com/"/>
  <updated>2013-06-14T14:15:45-07:00</updated>
  <id>http://bealetech.com/</id>
  <author>
    <name><![CDATA[Sean Laurent]]></name>
    
  </author>
  <generator uri="http://octopress.org/">Octopress</generator>

  
  <entry>
    <title type="html"><![CDATA[Custom SSL Certificates with Chef 11 Server]]></title>
    <link href="http://bealetech.com/blog/2013/06/14/custom-ssl-certificates-with-chef-11-server/"/>
    <updated>2013-06-14T14:02:00-07:00</updated>
    <id>http://bealetech.com/blog/2013/06/14/custom-ssl-certificates-with-chef-11-server</id>
    <content type="html"><![CDATA[<p>While setting up <a href="http://www.opscode.com/chef/">Chef</a> 11 Server on a <a href="http://www.centos.org/">CentOS</a> 6.4 box, I realized I wanted that it defaults to using self-signed SSL certificates. Since we have existing wildcard certificates through GoDaddy, I wanted to switch over to those. It look a little bit of digging and some help from IRC #chef to get things working.</p>

<!-- more -->


<p>First, you need to your certificate and key. For completeness, you want to combine your certificate with the certificate chain provided by your signing authority. In the case of GoDaddy, they gave me two files:</p>

<ul>
<li><code>example.com.crt</code></li>
<li><code>gd_bundle.crt</code></li>
</ul>


<p>To create a combined bundle:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>cat example.com.crt gd_bundle.crt &gt; example.com.pem
</span></code></pre></td></tr></table></div></figure>


<p>In addition, you need to make sure that your keyfile does <em>not</em> have a passphrase associated with it, otherwise Nginx will refuse to start up. To remove the passphrase from an existing key file:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>openssl rsa -in example.com.key -out example.com.nopassphrase.key
</span></code></pre></td></tr></table></div></figure>


<p>You need to copy the combined bundle and your key file to your server and place them in a secure location. On a typical CentOS installation, you want to dump the files in <code>/etc/pki/tls/private</code>.</p>

<p>Next, you need to tell Chef to use the custom certificates. Create a file named <code>/etc/chef-server/chef-server.rb</code>, if doesn&#8217;t exist already. Add the following lines to it:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">nginx</span><span class="o">[</span><span class="s1">&#39;ssl_certificate&#39;</span><span class="o">]</span>        <span class="o">=</span> <span class="s2">&quot;/etc/pki/tls/private/example.com.pem&quot;</span>
</span><span class='line'><span class="n">nginx</span><span class="o">[</span><span class="s1">&#39;ssl_certificate_key&#39;</span><span class="o">]</span>    <span class="o">=</span> <span class="s2">&quot;/etc/pki/tls/private/example.com.nopassphrase.key&quot;</span>
</span></code></pre></td></tr></table></div></figure>


<p>Now, reconfigure Chef server:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>chef-server-ctl reconfigure
</span></code></pre></td></tr></table></div></figure>


<p>That will reconfigure Nginx with the new settings (which are stored in <code>/var/opt/chef-server/nginx/etc</code>) and automatically restart Nginx. You can verify that it&#8217;s using the correct certificate by running:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>openssl s_client -connect localhost:443
</span></code></pre></td></tr></table></div></figure>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Asgard and Mater Cookbooks]]></title>
    <link href="http://bealetech.com/blog/2013/04/29/asgard-and-mater-cookbooks/"/>
    <updated>2013-04-29T21:00:00-07:00</updated>
    <id>http://bealetech.com/blog/2013/04/29/asgard-and-mater-cookbooks</id>
    <content type="html"><![CDATA[<p>Over at <a href="http://www.studyblue.com">StudyBlue</a>, we leverage <a href="http://www.opscode.com/chef/">Chef</a> pretty heavily for automation. Today we just open sourced two Chef cookbooks as a way to give back to the community that has supported us.</p>

<!-- more -->


<h2>Asgard</h2>

<p><a href="https://github.com/StudyBlue/chef-asgard">https://github.com/StudyBlue/chef-asgard</a></p>

<ul>
<li>Chef cookbook for installing <a href="https://github.com/Netflix/asgard">Netflix Asgard</a>.</li>
<li>Installs and configures Netflix Asgard with Java 6 and Tomcat 7.</li>
<li>Can also proxy via Apache.</li>
</ul>


<h2>Mater</h2>

<p><a href="https://github.com/StudyBlue/chef-mater">https://github.com/StudyBlue/chef-mater</a></p>

<ul>
<li>Chef cookbook for installing <a href="https://github.com/obfuscurity/mater">Mater</a>, a bridge between <a href="http://panic.com/statusboard/">StatusBoard</a> and <a href="http://graphite.wikidot.com/">Graphite</a>.</li>
<li>Includes support for running Mater under <a href="http://unicorn.bogomips.org/">Unicorn</a> with Apache as a proxy.</li>
</ul>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Pushing to Maven Central with Sonatype]]></title>
    <link href="http://bealetech.com/blog/2013/04/10/pushing-to-maven-central-with-sonatype/"/>
    <updated>2013-04-10T15:07:00-07:00</updated>
    <id>http://bealetech.com/blog/2013/04/10/pushing-to-maven-central-with-sonatype</id>
    <content type="html"><![CDATA[<p>Getting your opensource JAR published to Maven Central is free, but requires a little bit of up front work. I use <a href="https://sonatype.org">Sonatype</a> to help publish the jars for <a href="https://github.com/organicveggie/metrics-statsd">metrics-statsd</a>, which makes life much easier.
Most of the process is documented by Sonatype, which you can read about here:</p>

<p><a href="https://docs.sonatype.org/display/Repository/Sonatype+OSS+Maven+Repository+Usage+Guide">https://docs.sonatype.org/display/Repository/Sonatype+OSS+Maven+Repository+Usage+Guide</a></p>

<p>There were a few tricky parts that either weren&#8217;t documented well or I just found confusing. I have tried to document some of these parts below.</p>

<!-- more -->


<h1>Terminology</h1>

<p>In case you&#8217;re as easily confused as I was, Sonatype uses three different terms when talking about pushing jars:</p>

<ol>
<li><strong>Deploy</strong> refers to deploying <em>snapshots</em> to Sonatype.</li>
<li><strong>Staging</strong> refers to pushing potential release artifacts to Sonatype. Note that <em>staging</em> an artifact does not automatically push it to Maven Central.</li>
<li><strong>Release</strong> refers to marking the artifacts for release on Sonatype&#8217;s Nexus server so that they get pushed to Maven Central.</li>
</ol>


<h1>Required Changes</h1>

<h2>Artifacts</h2>

<p>Pushing jars to Maven Central requires that you produce three artifacts:</p>

<ol>
<li>Main jar with compiled classes</li>
<li>Sources jar</li>
<li>Javadocs jar</li>
</ol>


<p>To automatically generate the second and third artifacts, add the following to the build plugins section of your <code>pom.xml</code>:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
</pre></td><td class='code'><pre><code class='xml'><span class='line'><span class="nt">&lt;plugin&gt;</span>
</span><span class='line'>    <span class="nt">&lt;groupId&gt;</span>org.apache.maven.plugins<span class="nt">&lt;/groupId&gt;</span>
</span><span class='line'>    <span class="nt">&lt;artifactId&gt;</span>maven-source-plugin<span class="nt">&lt;/artifactId&gt;</span>
</span><span class='line'>    <span class="nt">&lt;version&gt;</span>2.1.2<span class="nt">&lt;/version&gt;</span>
</span><span class='line'>    <span class="nt">&lt;executions&gt;</span>
</span><span class='line'>        <span class="nt">&lt;execution&gt;</span>
</span><span class='line'>            <span class="nt">&lt;id&gt;</span>attach-sources<span class="nt">&lt;/id&gt;</span>
</span><span class='line'>            <span class="nt">&lt;goals&gt;</span>
</span><span class='line'>                <span class="nt">&lt;goal&gt;</span>jar<span class="nt">&lt;/goal&gt;</span>
</span><span class='line'>            <span class="nt">&lt;/goals&gt;</span>
</span><span class='line'>        <span class="nt">&lt;/execution&gt;</span>
</span><span class='line'>    <span class="nt">&lt;/executions&gt;</span>
</span><span class='line'><span class="nt">&lt;/plugin&gt;</span>
</span><span class='line'><span class="nt">&lt;plugin&gt;</span>
</span><span class='line'>    <span class="nt">&lt;groupId&gt;</span>org.apache.maven.plugins<span class="nt">&lt;/groupId&gt;</span>
</span><span class='line'>    <span class="nt">&lt;artifactId&gt;</span>maven-javadoc-plugin<span class="nt">&lt;/artifactId&gt;</span>
</span><span class='line'>    <span class="nt">&lt;version&gt;</span>2.8.1<span class="nt">&lt;/version&gt;</span>
</span><span class='line'>    <span class="nt">&lt;executions&gt;</span>
</span><span class='line'>        <span class="nt">&lt;execution&gt;</span>
</span><span class='line'>            <span class="nt">&lt;id&gt;</span>attach-javadocs<span class="nt">&lt;/id&gt;</span>
</span><span class='line'>            <span class="nt">&lt;goals&gt;</span>
</span><span class='line'>                <span class="nt">&lt;goal&gt;</span>jar<span class="nt">&lt;/goal&gt;</span>
</span><span class='line'>            <span class="nt">&lt;/goals&gt;</span>
</span><span class='line'>        <span class="nt">&lt;/execution&gt;</span>
</span><span class='line'>    <span class="nt">&lt;/executions&gt;</span>
</span><span class='line'><span class="nt">&lt;/plugin&gt;</span>
</span></code></pre></td></tr></table></div></figure>


<h2>Artifact Signing</h2>

<p>Maven Central requires that you sign your released artifacts with GPG. Note that <em>snapshots</em> do not need to be signed. Sonatype has a thorough article on signing your artifacts:</p>

<p><a href="https://docs.sonatype.org/display/Repository/How+To+Generate+PGP+Signatures+With+Maven">How to Generate PGP Signatures With Maven</a></p>

<p>The key steps are:</p>

<ol>
<li>Generate a key pair</li>
<li>Distribute your public key</li>
<li>Update your <code>pom.xml</code></li>
</ol>


<p>The first two steps are straightforward. The only trick with the third step is that you <em>only</em> want to sign artifacts during the release process. If you add the <code>maven-gpg-plugin</code> to your main, every single build will get signed and Maven will prompt you for your passphrase with every build. Instead, you can define a Maven profile with a specific name and include the <code>maven-gpg-plugin</code> there.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
</pre></td><td class='code'><pre><code class='xml'><span class='line'><span class="nt">&lt;profiles&gt;</span>
</span><span class='line'>  <span class="nt">&lt;profile&gt;</span>
</span><span class='line'>    <span class="nt">&lt;id&gt;</span>release-sign-artifacts<span class="nt">&lt;/id&gt;</span>
</span><span class='line'>    <span class="nt">&lt;activation&gt;</span>
</span><span class='line'>      <span class="nt">&lt;property&gt;</span>
</span><span class='line'>        <span class="nt">&lt;name&gt;</span>performRelease<span class="nt">&lt;/name&gt;</span>
</span><span class='line'>        <span class="nt">&lt;value&gt;</span>true<span class="nt">&lt;/value&gt;</span>
</span><span class='line'>      <span class="nt">&lt;/property&gt;</span>
</span><span class='line'>    <span class="nt">&lt;/activation&gt;</span>
</span><span class='line'>    <span class="nt">&lt;build&gt;</span>
</span><span class='line'>      <span class="nt">&lt;plugins&gt;</span>
</span><span class='line'>        <span class="nt">&lt;plugin&gt;</span>
</span><span class='line'>          <span class="nt">&lt;groupId&gt;</span>org.apache.maven.plugins<span class="nt">&lt;/groupId&gt;</span>
</span><span class='line'>          <span class="nt">&lt;artifactId&gt;</span>maven-gpg-plugin<span class="nt">&lt;/artifactId&gt;</span>
</span><span class='line'>          <span class="nt">&lt;version&gt;</span>1.1<span class="nt">&lt;/version&gt;</span>
</span><span class='line'>          <span class="nt">&lt;executions&gt;</span>
</span><span class='line'>            <span class="nt">&lt;execution&gt;</span>
</span><span class='line'>              <span class="nt">&lt;id&gt;</span>sign-artifacts<span class="nt">&lt;/id&gt;</span>
</span><span class='line'>              <span class="nt">&lt;phase&gt;</span>verify<span class="nt">&lt;/phase&gt;</span>
</span><span class='line'>              <span class="nt">&lt;goals&gt;</span>
</span><span class='line'>                <span class="nt">&lt;goal&gt;</span>sign<span class="nt">&lt;/goal&gt;</span>
</span><span class='line'>              <span class="nt">&lt;/goals&gt;</span>
</span><span class='line'>            <span class="nt">&lt;/execution&gt;</span>
</span><span class='line'>          <span class="nt">&lt;/executions&gt;</span>
</span><span class='line'>        <span class="nt">&lt;/plugin&gt;</span>
</span><span class='line'>      <span class="nt">&lt;/plugins&gt;</span>
</span><span class='line'>    <span class="nt">&lt;/build&gt;</span>
</span><span class='line'>  <span class="nt">&lt;/profile&gt;</span>
</span><span class='line'><span class="nt">&lt;/profiles&gt;</span>
</span></code></pre></td></tr></table></div></figure>


<h2>distributionManagement</h2>

<p>Following the recommendation from Sonatype, you will remove the <code>&lt;repositories&gt;&lt;/repositories&gt;</code> section of your <code>pom.xml</code>. Once you do that, Maven no longer knows what server to use when <em>deploying</em> or <em>staging</em>. To compensate, you need to add a <code>distributionManagement</code> section:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
</pre></td><td class='code'><pre><code class='xml'><span class='line'><span class="nt">&lt;distributionManagement&gt;</span>
</span><span class='line'>    <span class="nt">&lt;snapshotRepository&gt;</span>
</span><span class='line'>        <span class="nt">&lt;id&gt;</span>sonatype-nexus-snapshots<span class="nt">&lt;/id&gt;</span>
</span><span class='line'>        <span class="nt">&lt;url&gt;</span>https://oss.sonatype.org/content/repositories/snapshots/<span class="nt">&lt;/url&gt;</span>
</span><span class='line'>    <span class="nt">&lt;/snapshotRepository&gt;</span>
</span><span class='line'>    <span class="nt">&lt;repository&gt;</span>
</span><span class='line'>        <span class="nt">&lt;id&gt;</span>sonatype-nexus-staging<span class="nt">&lt;/id&gt;</span>
</span><span class='line'>        <span class="nt">&lt;url&gt;</span>https://oss.sonatype.org/service/local/staging/deploy/maven2/<span class="nt">&lt;/url&gt;</span>
</span><span class='line'>    <span class="nt">&lt;/repository&gt;</span>
</span><span class='line'><span class="nt">&lt;/distributionManagement&gt;</span>
</span></code></pre></td></tr></table></div></figure>


<h2>Sonatype Parent POM</h2>

<p>You need to configure your <code>pom.xml</code> to inherit from the Sonatype Parent POM:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='xml'><span class='line'><span class="nt">&lt;parent&gt;</span>
</span><span class='line'>    <span class="nt">&lt;groupId&gt;</span>org.sonatype.oss<span class="nt">&lt;/groupId&gt;</span>
</span><span class='line'>    <span class="nt">&lt;artifactId&gt;</span>oss-parent<span class="nt">&lt;/artifactId&gt;</span>
</span><span class='line'>    <span class="nt">&lt;version&gt;</span>7<span class="nt">&lt;/version&gt;</span>
</span><span class='line'><span class="nt">&lt;/parent&gt;</span>
</span></code></pre></td></tr></table></div></figure>


<h1>Deploying</h1>

<p>Assuming you&#8217;ve followed the instructions from Sonatype and setup an account, you&#8217;re now ready to deploy snapshots. The process is simple:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>mvn clean deploy
</span></code></pre></td></tr></table></div></figure>


<p>That will automatically clean, build and push your snapshot to Sonatype.</p>

<h1>Releasing</h1>

<p>Pushing a release jar to Maven Central consists of two parts: staging and releasing.</p>

<h2>Staging</h2>

<p>In this part we clean everything up; prepare for the build by creating a tag for the release and updating the pom.xml; perform the build; deploy the artifacts to Sonatype.</p>

<p>The process consists of three commands:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>mvn release:clean
</span><span class='line'>mvn release:prepare
</span><span class='line'>mvn release:perform
</span></code></pre></td></tr></table></div></figure>


<p>The <code>release:prepare</code> step will prompt you for release information. Here is some sample output from the 2.3.0 release of <a href="https://github.com/organicveggie/metrics-statsd">metrics-statsd</a>:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nv">$ </span>mvn release:prepare
</span><span class='line'><span class="o">[</span>INFO<span class="o">]</span> Scanning <span class="k">for </span>projects...
</span><span class='line'><span class="o">[</span>INFO<span class="o">]</span>
</span><span class='line'><span class="o">[</span>INFO<span class="o">]</span> ------------------------------------------------------------------------
</span><span class='line'><span class="o">[</span>INFO<span class="o">]</span> Building Metrics Statsd Support 2.3.0-SNAPSHOT
</span><span class='line'><span class="o">[</span>INFO<span class="o">]</span> ------------------------------------------------------------------------
</span><span class='line'><span class="o">[</span>INFO<span class="o">]</span>
</span><span class='line'><span class="o">[</span>INFO<span class="o">]</span> --- maven-release-plugin:2.2.1:prepare <span class="o">(</span>default-cli<span class="o">)</span> @ metrics-statsd ---
</span><span class='line'><span class="o">[</span>INFO<span class="o">]</span> Verifying that there are no <span class="nb">local </span>modifications...
</span><span class='line'><span class="o">[</span>INFO<span class="o">]</span>   ignoring changes on: pom.xml.next, release.properties, pom.xml.releaseBackup, pom.xml.backup, pom.xml.branch, pom.xml.tag
</span><span class='line'><span class="o">[</span>INFO<span class="o">]</span> Executing: /bin/sh -c <span class="nb">cd</span> /Users/sean/src/metrics-statsd <span class="o">&amp;&amp;</span> git status
</span><span class='line'><span class="o">[</span>INFO<span class="o">]</span> Working directory: /Users/sean/src/metrics-statsd
</span><span class='line'><span class="o">[</span>INFO<span class="o">]</span> Checking dependencies and plugins <span class="k">for </span>snapshots ...
</span><span class='line'>What is the release version <span class="k">for</span> <span class="s2">&quot;Metrics Statsd Support&quot;</span>? <span class="o">(</span>com.bealetech:metrics-statsd<span class="o">)</span> 2.3.0: :
</span><span class='line'>What is SCM release tag or label <span class="k">for</span> <span class="s2">&quot;Metrics Statsd Support&quot;</span>? <span class="o">(</span>com.bealetech:metrics-statsd<span class="o">)</span> v2.3.0: :
</span><span class='line'>What is the new development version <span class="k">for</span> <span class="s2">&quot;Metrics Statsd Support&quot;</span>? <span class="o">(</span>com.bealetech:metrics-statsd<span class="o">)</span> 2.3.1-SNAPSHOT: :
</span></code></pre></td></tr></table></div></figure>


<h2>Releasing</h2>

<p>Once the artifacts are staged on Sonatype&#8217;s Nexus, you need to go through a few annoying steps:</p>

<ul>
<li>Close out the staging release in Sonatype</li>
<li>Release the artifacts in Sonatype</li>
</ul>


<p>That process is well documented (with images) by Sonatype:</p>

<p><a href="https://docs.sonatype.org/display/Repository/Sonatype+OSS+Maven+Repository+Usage+Guide#SonatypeOSSMavenRepositoryUsageGuide-8a.ReleaseIt">https://docs.sonatype.org/display/Repository/Sonatype+OSS+Maven+Repository+Usage+Guide#SonatypeOSSMavenRepositoryUsageGuide-8a.ReleaseIt</a></p>

<p>Within two hours, Sonatype will push the artifacts to Maven Centrl.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Distributed Graphite on EC2]]></title>
    <link href="http://bealetech.com/blog/2012/05/28/distributed-graphite-on-ec2/"/>
    <updated>2012-05-28T14:20:00-07:00</updated>
    <id>http://bealetech.com/blog/2012/05/28/distributed-graphite-on-ec2</id>
    <content type="html"><![CDATA[<p>Some time ago, we switched from <a href="http://www.cacti.net/">Cacti</a> to <a href="http://graphite.wikidot.com/">Graphite</a> for tracking and graphing system metrics. In our <a href="http://aws.amazon.com/ec2/">Amazon EC2 environment</a>, we frequently startup new servers and shut down old servers. While Cacti did a decent job, the amount of manual effort required to setup new graphs made it a challenge to use. Since Graphite simply tracks anything you throw at it and easily handles applying aggregate functions across multiple metrics, we found Graphite to be a much better fit with EC2 and our usage patterns. With a solid web interface and a variety of alternate front-ends and awesome dashboard tools like <a href="http://jondot.github.com/graphene/">Graphene</a>, we quickly fell in love with Graphite.</p>

<!-- more -->


<p>In fact, the more we utilized Graphite, the more data we wanted to push into Graphite. Systems metrics? Check. IO stats? Check. Apache stats? Check. MongoDB stats on a per collection basis? Why not! We quickly found ourselves with over 50,000 metrics and 500GB of data, all of which was getting updated every 15-30 seconds. Unfortunately, we also rapidly hit the limit of how much data we could record on a single instance. Even with a RAID-0 array of 8x EBS volumes on an m2.2xlarge instance, we couldn&#8217;t write the data fast enough. The poor instance began spending more than 50% of it&#8217;s time in I/O wait  and eventually became non-responsive. What we needed was a way to distribute the write load across multiple instances.</p>

<p>Fortunately, Graphite natively supports running in a distributed environment. A successful deployment consists of three key pieces:</p>

<ul>
<li>carbon-cache - This is what actually accepts and stores the metrics.</li>
<li>carbon-relay - Handles sharding the metrics and sending them to the appropriate carbon-cache instances.</li>
<li>webapp - Handles displaying the metrics. Must reside on every instance running a carbon-cache daemon. The webapp queries the other carbon-cache instances for data as necessary.</li>
</ul>


<p>Although there are many different ways you can setup your distributed Graphite environment, we chose to take a straight foward approach:</p>

<ul>
<li>One dedicated instance running carbon-relay that receives metrics from the various server instances, shards the metrics and forwards them on to the carbon-cache servers</li>
<li>Two dedicated instances running both carbon-cache and webapp.</li>
</ul>


<h2>Carbon Relay</h2>

<p>On the carbon-relay server, you need to configure two key files to indicate that this node should run as a relay: carbon.conf and relay.conf.</p>

<p><code>carbon.conf</code></p>

<div>
  <pre><code class='properties'>[relay]
RELAY_METHOD = consistent-hashing

LINE_RECEIVER_INTERFACE = x.x.x.x
LINE_RECEIVER_PORT = 2003

PICKLE_RECEIVER_INTERFACE = 127.0.0.1
PICKLE_RECEIVER_PORT = 2004

DESTINATIONS = cache1:2004:a,cache2:2004:a

MAX_DATAPOINTS_PER_MESSAGE = 500
MAX_QUEUE_SIZE = 10000

USE_FLOW_CONTROL = True</code></pre>
</div>


<p>For simplicity, we&#8217;re using the consistent-hashing method of sharding. The advantage to consistent-hasing is that Graphite will automatically split the metrics evenly across all carbon-cache instances. If you add another carbon-cache node, Graphite will start sending data to it. The disadvantage is that you have absolutely no control over which metric goes to which server. If you start with two nodes and then add a third node, Graphite will not automatically rebalance the data.</p>

<p>A couple key things to note:</p>

<ul>
<li>The RELAY_METHOD value is set to consistent-hashing</li>
<li>The LINE_RECEIVER_INTERFACE must be set to the IP address of the relay node, not localhost</li>
<li>The DESTINATIONS value must contain all of the target carbon-cache nodes</li>
<li>Each server listed in the DESTINATIONS option must include the name or ip address of a carbon-cache instance, the pickle-receiver port for the remote instance and the carbon-cache identifier. If you run multiple carbon-cache daemons on the remote server,  the first instance will be identified as &#8220;a&#8221;, the second instance as &#8220;b&#8221;, etc.</li>
</ul>


<p><code>relay.conf</code></p>

<div>
  <pre><code class='properties'>[default]
default = true
destinations = cache1,cache2</code></pre>
</div>


<p>This sample relay.conf shows us splitting the data automatically across two servers: cache1 and cache2.</p>

<h2>Carbon Cache</h2>

<p>On the carbon-cache servers, we need to configure the carbon-cache daemon to appropriately accept incoming data from the carbon-relay servers.</p>

<p><code>carbon.conf</code></p>

<div>
  <pre><code class='properties'>[cache]
LOCAL_DATA_DIR = /opt/graphite/storage/whisper/

MAX_CACHE_SIZE = inf

MAX_UPDATES_PER_SECOND = 800

MAX_CREATES_PER_MINUTE = 100

LINE_RECEIVER_INTERFACE = y.y.y.y
LINE_RECEIVER_PORT = 2003

PICKLE_RECEIVER_INTERFACE = y.y.y.y
PICKLE_RECEIVER_PORT = 2004

CACHE_QUERY_INTERFACE = 127.0.0.1
CACHE_QUERY_PORT = 7002

LOG_UPDATES = False</code></pre>
</div>


<p>There are several critical settings here. First, the pickle receiver must be configured correctly to allow incoming data from the carbon-relay server. Second, the line receiver must be configured correctly to allow the the webapp to communicate with the other carbon-cache instances.</p>

<ul>
<li>LINE_RECEIVER_INTERFACE must be set to the local ip address (not 127.0.0.1)</li>
<li>LINE_RECEIVER_PORT must be set to 2003</li>
<li>PICKLE_RECEIVER_INTERFACE must be set to the local ip address (not 127.0.0.1)</li>
<li>PICKLE_RECEIVER_PORT must match the port we listed in the DESTINATION line in carbon.conf on the carbon-relay server</li>
</ul>


<p>The other key is configuring the local_settings.py config file for the webapp correctly:</p>

<div>
  <pre><code class='properties'>CLUSTER_SERVERS = [ 'cache1','cache2' ]
MEMCACHE_HOSTS = [ 'memcache1.graphite:11211' ]</code></pre>
</div>


<p>The only mandatory piece of information in local_settings.py is CLUSTER_SERVERS, which must be a Python array containing strings that are the names (or ip address) of every carbon-cache server. You can optionally include an array of memcached instances to improve web performance dramatically. If you choose to utilize memcached, you can either run it locally on each carbon-cache instance or you can run a cluster of one or more memcached servers remotely. In the example above, we&#8217;re using a single memcached instance running on a remote server.</p>

<p>IMPORTANT NOTE: The local_settings.py file MUST be readable by the web server user. If you&#8217;re running Apache, this is typically the apache user. If the local_settings.py file is NOT readable, you will get very very strange errors.</p>

<h2>Firewall Rules</h2>

<p>To get this all working, specific ports must be open on the various firewalls. If you&#8217;re using Amazon EC2, your security groups will need to contain rules explicitly allowing incoming traffic on these ports:</p>

<h3>carbon-relay</h3>

<ol>
<li>Incoming on port 2003</li>
</ol>


<h3>carbon-cache/webapp</h3>

<ol>
<li>Incoming on port 2004 (messages from carbon-relay)</li>
<li>Incoming on port 2003 (requests for data from other carbon-cache servers)</li>
<li>Incoming on port 80 (web requests)</li>
<li>Incoming on port 11211 (if you&#8217;re running memcached locally)</li>
</ol>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Testing Logstash grok filters]]></title>
    <link href="http://bealetech.com/blog/2012/05/15/testing-logstash-grok-filters/"/>
    <updated>2012-05-15T13:25:00-07:00</updated>
    <id>http://bealetech.com/blog/2012/05/15/testing-logstash-grok-filters</id>
    <content type="html"><![CDATA[<p>Logstash is an outstanding tool for collecting and parsing logfiles. In particular, the grok filter is extremely useful to extract specific pieces of data from your logfiles. Once you pull data out of the logfiles into fields, you can easily search on those fields. Unfortunately, I find the format for patterns in grok filter challenging to write correctly. If you mess up your pattern, you will end up with the dreaded &#8220;_grokparsefailure&#8221; tag on your log entry. What you need is a way to test your patterns before adding them to Logstash.</p>

<!-- more -->


<p>As it turns out, you can test your patterns using the grok ruby library. @a1cy demonstrated the basics to me, but I wanted to describe the full process.</p>

<h2>Requirements</h2>

<ul>
<li>Ruby 1.9+</li>
<li>jls-grok gem</li>
</ul>


<p>On my machine, I chose to install Ruby 1.9.2 via RVM, but you can use whatever technique you want. If you try to use Ruby 1.8.7, you will get a syntax error when you load the grok gem.</p>

<h2>Load Grok</h2>

<p>You want to use the &#8220;grok-pure&#8221; library, which is 100% ruby, rather than &#8220;grok&#8221;, which depends on a C library.</p>

<div>
  <pre><code class='ruby'>require 'rubygems'
require 'grok-pure'
grok = Grok.new</code></pre>
</div>


<h2>Loading Patterns</h2>

<p>Since the grok filter in Logstash depends heavily on pattern files, I recommend you download the standard patterns from Github. Either the standard set for Logstash:</p>

<p><a href="https://github.com/logstash/logstash/tree/master/patterns">https://github.com/logstash/logstash/tree/master/patterns</a></p>

<p>Or you can use the ones with grok:</p>

<p><a href="https://github.com/jordansissel/ruby-grok/blob/master/patterns/pure-ruby">https://github.com/jordansissel/ruby-grok/blob/master/patterns/pure-ruby</a></p>

<p>Dump these into a directory so that you can load them with grok.</p>

<div>
  <pre><code class='ruby'>grok.add_patterns_from_file(&quot;/path/to/patterns/grok-patterns&quot;)</code></pre>
</div>


<p>You can use the same technique to load your own pattern files. Or you can manually add patterns by name:</p>

<div>
  <pre><code class='ruby'>grok.add_pattern(&quot;foo&quot;, &quot;.*foo.*&quot;)
grok.add_pattern(&quot;bar&quot;, &quot;.*bar.*&quot;)</code></pre>
</div>


<h2>Testing Patterns</h2>

<p>So, you have successfully loaded a set of patterns. How do you test something? Let&#8217;s take a sample log line from a MongoDB logfile:</p>

<p><code>Tue May 15 11:21:42 [conn1047685] moveChunk deleted: 7157</code></p>

<p>Let&#8217;s say we want to grab the date/time as well as the number of the deleted chunk. Unfortunately, the date/time format doesn&#8217;t match any of the stock patterns. We can build up a new date pattern and test it each step of the way:</p>

<div>
  <pre><code class='ruby'>text = &quot;Tue May 15 11:21:42 [conn1047685] moveChunk deleted: 7157&quot;
pattern = '%{DAY}'
grok.compile(pattern)
grok.match(text)</code></pre>
</div>


<p>The last line returns false if the pattern fails to match the input text. If the pattern matches the input text, Grok.match() returns a Grok::Match object that contains a lot of useful information about the match. You can ask Grok to output the text it capture by using the captures() method:</p>

<div>
  <pre><code class='ruby'>grok.match(text).captures()
 =&gt; {&quot;DAY&quot;=&gt;[&quot;Tue&quot;]}</code></pre>
</div>


<p>You can also test named captures, the same way you would use them in the Logstash grok filter:</p>

<div>
  <pre><code class='ruby'>pattern = '%{DAY:day_of_week}'
grok.compile(pattern)
grok.match(text).captures()
 =&gt; {&quot;DAY:day_of_week&quot;=&gt;[&quot;Tue&quot;]}</code></pre>
</div>


<p>The full date/time pattern for this example looks like the following:</p>

<div>
  <pre><code class='ruby'>pattern = '%{DAY} %{MONTH} %{MONTHDAY} %{TIME}'
grok.compile(pattern)
grok.match(text).capture()
 =&gt; {&quot;DAY&quot;=&gt;[&quot;Tue&quot;], &quot;MONTH&quot;=&gt;[&quot;May&quot;], &quot;MONTHDAY&quot;=&gt;[&quot;15&quot;], &quot;TIME&quot;=&gt;[&quot;11:21:42&quot;], &quot;HOUR&quot;=&gt;[&quot;11&quot;], &quot;MINUTE&quot;=&gt;[&quot;21&quot;], &quot;SECOND&quot;=&gt;[&quot;42&quot;]}</code></pre>
</div>


<p>Now let&#8217;s say we want to re-use this date/time pattern and still extract the chunk id from the log line. We can add a named pattern to the grok object manually and then reuse it, the same way we used patterns from the files:</p>

<div>
  <pre><code class='ruby'>grok.add_pattern(&quot;MONGO_TIMESTAMP&quot;, '%{DAY} %{MONTH} %{MONTHDAY} %{TIME}')
grok.compile(&quot;%{MONGO_TIMESTAMP}&quot;)
pattern = '%{MONGO_TIMESTAMP:timestamp}'
grok.compile(pattern)
grok.match(text).captures()
 =&gt; {&quot;MONGO_TIMESTAMP:timestamp&quot;=&gt;[&quot;Tue May 15 11:21:42&quot;], &quot;DAY&quot;=&gt;[&quot;Tue&quot;], &quot;MONTH&quot;=&gt;[&quot;May&quot;], &quot;MONTHDAY&quot;=&gt;[&quot;15&quot;], &quot;TIME&quot;=&gt;[&quot;11:21:42&quot;], &quot;HOUR&quot;=&gt;[&quot;11&quot;], &quot;MINUTE&quot;=&gt;[&quot;21&quot;], &quot;SECOND&quot;=&gt;[&quot;42&quot;]}</code></pre>
</div>


<p>We still want the chunk id, so we can use additional patterns:</p>

<div>
  <pre><code class='ruby'>pattern = '%{MONGO_TIMESTAMP:timestamp}%{GREEDYDATA} moveChunk deleted: %{NUMBER:chunk_id}'
grok.compile(pattern)
grok.match(text).captures()
 =&gt; {&quot;MONGO_TIMESTAMP:timestamp&quot;=&gt;[&quot;Tue May 15 11:21:42&quot;], &quot;DAY&quot;=&gt;[&quot;Tue&quot;], &quot;MONTH&quot;=&gt;[&quot;May&quot;], &quot;MONTHDAY&quot;=&gt;[&quot;15&quot;], &quot;TIME&quot;=&gt;[&quot;11:21:42&quot;], &quot;HOUR&quot;=&gt;[&quot;11&quot;], &quot;MINUTE&quot;=&gt;[&quot;21&quot;], &quot;SECOND&quot;=&gt;[&quot;42&quot;], &quot;GREEDYDATA&quot;=&gt;[&quot; [conn1047685]&quot;], &quot;NUMBER:chunk_id&quot;=&gt;[&quot;7157&quot;], &quot;BASE10NUM&quot;=&gt;[&quot;7157&quot;]}</code></pre>
</div>


<p>Let&#8217;s say we wanted to grab that connection number inside the square brackets:</p>

<div>
  <pre><code class='ruby'>pattern = '%{MONGO_TIMESTAMP:timestamp} \\[conn%{NUMBER:connection}\\] moveChunk deleted: %{NUMBER:chunk_id}'
grok.compile(pattern)
grok.match(text).captures()
 =&gt; {&quot;MONGO_TIMESTAMP:timestamp&quot;=&gt;[&quot;Tue May 15 11:21:42&quot;], &quot;DAY&quot;=&gt;[&quot;Tue&quot;], &quot;MONTH&quot;=&gt;[&quot;May&quot;], &quot;MONTHDAY&quot;=&gt;[&quot;15&quot;], &quot;TIME&quot;=&gt;[&quot;11:21:42&quot;], &quot;HOUR&quot;=&gt;[&quot;11&quot;], &quot;MINUTE&quot;=&gt;[&quot;21&quot;], &quot;SECOND&quot;=&gt;[&quot;42&quot;], &quot;NUMBER:connection&quot;=&gt;[&quot;1047685&quot;], &quot;BASE10NUM&quot;=&gt;[&quot;1047685&quot;, &quot;7157&quot;], &quot;NUMBER:chunk_id&quot;=&gt;[&quot;7157&quot;]}</code></pre>
</div>


<h2>Full Example</h2>

<div>
  <pre><code class='ruby'>require 'rubygems'
require 'grok-pure'
 
grok = Grok.new
 
text = &quot;Tue May 15 11:21:42 [conn1047685] moveChunk deleted: 7157&quot;
pattern = '%{MONGO_TIMESTAMP:timestamp} \\[conn%{NUMBER:connection}\\] moveChunk deleted: %{NUMBER:chunk_id}'
grok.compile(pattern)
grok.match(text).captures()
 =&gt; {&quot;MONGO_TIMESTAMP:timestamp&quot;=&gt;[&quot;Tue May 15 11:21:42&quot;], &quot;DAY&quot;=&gt;[&quot;Tue&quot;], &quot;MONTH&quot;=&gt;[&quot;May&quot;], &quot;MONTHDAY&quot;=&gt;[&quot;15&quot;], &quot;TIME&quot;=&gt;[&quot;11:21:42&quot;], &quot;HOUR&quot;=&gt;[&quot;11&quot;], &quot;MINUTE&quot;=&gt;[&quot;21&quot;], &quot;SECOND&quot;=&gt;[&quot;42&quot;], &quot;NUMBER:connection&quot;=&gt;[&quot;1047685&quot;], &quot;BASE10NUM&quot;=&gt;[&quot;1047685&quot;, &quot;7157&quot;], &quot;NUMBER:chunk_id&quot;=&gt;[&quot;7157&quot;]}</code></pre>
</div>


<p>You can also find an ultra simple example in the grok example folder on Github: <a href="https://github.com/jordansissel/ruby-grok/blob/master/examples/test.rb">https://github.com/jordansissel/ruby-grok/blob/master/examples/test.rb</a>.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Why PostgreSQL?]]></title>
    <link href="http://bealetech.com/blog/2010/10/14/why-postgresql/"/>
    <updated>2010-10-14T22:49:00-07:00</updated>
    <id>http://bealetech.com/blog/2010/10/14/why-postgresql</id>
    <content type="html"><![CDATA[<p>Quick overview of what PostgreSQL brings to the table that is not available in MySQL.</p>

<!-- more -->


<ul>
<li>Uses MVCC for all tables providing:

<ul>
<li>Fully transactional including ACID compliance for consistency</li>
<li>Nested transactions</li>
</ul>
</li>
<li>SQL 2008 compliant</li>
<li>Foreign keys for any table</li>
<li>Advanced table partitioning</li>
<li>Highly sophisticated query planner/optimizer

<ul>
<li>Can split up a query for execution across multiple CPUs simultaneously</li>
<li>Collects internal statistics for adaptive query planning</li>
<li>Special genetic query optimizer for queries with large numbers of joins</li>
<li>Supports multiple indexes per table per query</li>
</ul>
</li>
<li>Advanced support for query &amp; results caching</li>
<li>Hot/online backup</li>
<li>Point-in-time-recovery</li>
<li>Write-ahead logs for fault-tolerance</li>
<li>Tablespaces for controlling physical disk layout</li>
<li>Native asynchronous replication guaranteeing identical results on all machines. Supports both:

<ul>
<li>Streaming replication</li>
<li>Hot standby</li>
</ul>
</li>
<li>Partial indexes</li>
<li>Index creation/removal does not lock table</li>
<li>Full support for constraints</li>
<li>Transactional DDL - changes like table modifications can placed inside a transaction and rolled back</li>
</ul>


<p>Specific disadvantages to MySQL:</p>

<ul>
<li>Confusion with table types - MyISAM vs InnoDB</li>
<li>Designed to scale out not up - does not utilize larger numbers of cores efficiently and cannot spread queries across cores</li>
<li>Hot backup of is difficult for databases containing both InnoDB and MyISAM</li>
<li>Replication is mediocre and error prone</li>
<li>InnoDB stores the data with the primary key, so any queries using secondary indices are slower</li>
<li>Subqueries not well optimized</li>
<li>Only uses a single index per table per query</li>
<li>Index creation/removal requires an exclusive write lock</li>
<li>MyISAM only offers table level locking which causes severe performance degradation under heavy concurrency</li>
<li>Limited support for constraints</li>
<li>No transactional DDL - changes like table modifications are automatically committed and cannot be rolled back</li>
</ul>


<p>MySQL offers the following advantages over PostgreSQL:</p>

<ul>
<li>MyISAM tables can offer better read performance, specifically for simple SELECT queries, but at the cost of no support for transactions, foreign keys or data guarantees</li>
<li>COUNT(*) on MyISAM is very fast and slow on PostgreSQL</li>
<li>INSERT IGNORE and INSERT&#8230;ON DUPLICATE UPDATE</li>
</ul>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Different content in Rails based on UserAgent]]></title>
    <link href="http://bealetech.com/blog/2010/08/11/different-content-in-rails-based-on-useragent/"/>
    <updated>2010-08-11T10:57:00-07:00</updated>
    <id>http://bealetech.com/blog/2010/08/11/different-content-in-rails-based-on-useragent</id>
    <content type="html"><![CDATA[<p>I was recently working on a website built using Rails that needed to render different content for certain user agents. Specifically, we needed simpler versions of certain pages for BlackBerry devices. Here&#8217;s how I accomplished it.</p>

<!-- more -->


<p>First, I added a new mime-type for BlackBerry by adding the following line to <code>config/initializers/mime_types.rb</code>:</p>

<figure class='code'><figcaption><span>mime_types.rb  </span></figcaption>
 <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="ss">Mime</span><span class="p">:</span><span class="ss">:Type</span><span class="o">.</span><span class="n">register_alias</span> <span class="s2">&quot;text/html&quot;</span><span class="p">,</span> <span class="ss">:blackberry</span>
</span></code></pre></td></tr></table></div></figure>


<p>Next, I added two utility methods to <code>app/controllers/application.rb</code>:</p>

<figure class='code'><figcaption><span>application.rb  </span></figcaption>
 <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="c1"># Checks UserAgent</span>
</span><span class='line'><span class="k">def</span> <span class="nf">is_blackberry?</span>
</span><span class='line'>  <span class="n">ua</span> <span class="o">=</span> <span class="n">request</span><span class="o">.</span><span class="n">user_agent</span>
</span><span class='line'>  <span class="k">return</span> <span class="kp">false</span> <span class="k">if</span> <span class="n">ua</span><span class="o">.</span><span class="n">nil?</span>
</span><span class='line'>  <span class="k">return</span> <span class="kp">false</span> <span class="k">if</span> <span class="o">!</span> <span class="n">ua</span><span class="o">.</span><span class="n">downcase</span><span class="o">.</span><span class="n">index</span><span class="p">(</span><span class="s1">&#39;blackberry&#39;</span><span class="p">)</span>
</span><span class='line'>
</span><span class='line'>  <span class="c1"># Don&#39;t call the BlackBerry 9800 a BlackBerry, since it has a modern browser</span>
</span><span class='line'>  <span class="c1"># based on WebKit:</span>
</span><span class='line'>  <span class="c1"># Mozilla/5.0 (BlackBerry; U; BlackBerry 9800; en) AppleWebKit/534.1+ (KHTML, Like Gecko) Version/6.0.0.141 Mobile Safari/534.1+</span>
</span><span class='line'>  <span class="k">return</span> <span class="kp">false</span> <span class="k">if</span> <span class="n">ua</span><span class="o">.</span><span class="n">downcase</span><span class="o">.</span><span class="n">index</span><span class="p">(</span><span class="s1">&#39;webkit&#39;</span><span class="p">)</span>
</span><span class='line'>
</span><span class='line'>  <span class="c1"># Must be a BlackBerry!</span>
</span><span class='line'>  <span class="kp">true</span>
</span><span class='line'><span class="k">end</span>
</span><span class='line'>
</span><span class='line'><span class="c1"># Sets the respond_to format to blackberry if blackberry</span>
</span><span class='line'><span class="k">def</span> <span class="nf">set_blackberry_format</span>
</span><span class='line'>  <span class="k">if</span> <span class="o">!</span><span class="n">request</span><span class="o">.</span><span class="n">xhr?</span> <span class="o">&amp;</span><span class="n">amp</span><span class="p">;</span><span class="o">&amp;</span><span class="n">amp</span><span class="p">;</span> <span class="n">is_blackberry?</span>
</span><span class='line'>    <span class="n">request</span><span class="o">.</span><span class="n">format</span> <span class="o">=</span> <span class="ss">:blackberry</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>With that in hand, it&#8217;s easy to render BlackBerry specific content on specific pages:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">set_blackberry_format</span>
</span><span class='line'><span class="n">respond_to</span> <span class="k">do</span> <span class="o">|</span><span class="nb">format</span><span class="o">|</span>
</span><span class='line'>  <span class="nb">format</span><span class="o">.</span><span class="n">blackberry</span>
</span><span class='line'>  <span class="nb">format</span><span class="o">.</span><span class="n">html</span>
</span><span class='line'>  <span class="nb">format</span><span class="o">.</span><span class="n">js</span> <span class="p">{</span> <span class="n">render</span> <span class="ss">:layout</span> <span class="o">=&amp;</span><span class="n">gt</span><span class="p">;</span> <span class="kp">false</span> <span class="p">}</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>



]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Tomcat init script for Ubuntu]]></title>
    <link href="http://bealetech.com/blog/2010/07/25/tomcat-init-script-for-ubuntu/"/>
    <updated>2010-07-25T13:06:00-07:00</updated>
    <id>http://bealetech.com/blog/2010/07/25/tomcat-init-script-for-ubuntu</id>
    <content type="html"><![CDATA[<p>Recently I spent some time working on improving my init scripts for Tomcat 6.x in a production environment running Ubuntu. One of the major problems we had encountered was that occasionally Tomcat refuses to shut down completely and requires a <code>kill -9</code> to stop it. The standard init scripts I had seen didn&#8217;t solve this problem at all.</p>

<!-- more -->


<p><a href="http://www.laliluna.de/">Laliluna</a> has a great <a href="http://www.laliluna.de/articles/tomcat-startup-script-linux.html">article</a> that focuses on RedHat, CentOS and Fedora. Unfortunately, their scripts didn&#8217;t work correctly under Ubuntu 8.04 LTS. As a result, I spent some time modifying their scripts to get them to work correctly under Unbuntu. Many thanks to Laliluna for doing the heavy work.</p>

<p>Without any further ado, here&#8217;s what I put together:</p>

<figure class='code'><figcaption><span>/etc/init.dtomcat  </span></figcaption>
 <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
<span class='line-number'>38</span>
<span class='line-number'>39</span>
<span class='line-number'>40</span>
<span class='line-number'>41</span>
<span class='line-number'>42</span>
<span class='line-number'>43</span>
<span class='line-number'>44</span>
<span class='line-number'>45</span>
<span class='line-number'>46</span>
<span class='line-number'>47</span>
<span class='line-number'>48</span>
<span class='line-number'>49</span>
<span class='line-number'>50</span>
<span class='line-number'>51</span>
<span class='line-number'>52</span>
<span class='line-number'>53</span>
<span class='line-number'>54</span>
<span class='line-number'>55</span>
<span class='line-number'>56</span>
<span class='line-number'>57</span>
<span class='line-number'>58</span>
<span class='line-number'>59</span>
<span class='line-number'>60</span>
<span class='line-number'>61</span>
<span class='line-number'>62</span>
<span class='line-number'>63</span>
<span class='line-number'>64</span>
<span class='line-number'>65</span>
<span class='line-number'>66</span>
<span class='line-number'>67</span>
<span class='line-number'>68</span>
<span class='line-number'>69</span>
<span class='line-number'>70</span>
<span class='line-number'>71</span>
<span class='line-number'>72</span>
<span class='line-number'>73</span>
<span class='line-number'>74</span>
<span class='line-number'>75</span>
<span class='line-number'>76</span>
<span class='line-number'>77</span>
<span class='line-number'>78</span>
<span class='line-number'>79</span>
<span class='line-number'>80</span>
<span class='line-number'>81</span>
<span class='line-number'>82</span>
<span class='line-number'>83</span>
<span class='line-number'>84</span>
<span class='line-number'>85</span>
<span class='line-number'>86</span>
<span class='line-number'>87</span>
<span class='line-number'>88</span>
<span class='line-number'>89</span>
<span class='line-number'>90</span>
<span class='line-number'>91</span>
<span class='line-number'>92</span>
<span class='line-number'>93</span>
<span class='line-number'>94</span>
<span class='line-number'>95</span>
<span class='line-number'>96</span>
<span class='line-number'>97</span>
<span class='line-number'>98</span>
<span class='line-number'>99</span>
<span class='line-number'>100</span>
<span class='line-number'>101</span>
<span class='line-number'>102</span>
<span class='line-number'>103</span>
<span class='line-number'>104</span>
<span class='line-number'>105</span>
<span class='line-number'>106</span>
<span class='line-number'>107</span>
<span class='line-number'>108</span>
<span class='line-number'>109</span>
<span class='line-number'>110</span>
<span class='line-number'>111</span>
<span class='line-number'>112</span>
<span class='line-number'>113</span>
<span class='line-number'>114</span>
<span class='line-number'>115</span>
<span class='line-number'>116</span>
<span class='line-number'>117</span>
<span class='line-number'>118</span>
<span class='line-number'>119</span>
<span class='line-number'>120</span>
<span class='line-number'>121</span>
<span class='line-number'>122</span>
<span class='line-number'>123</span>
<span class='line-number'>124</span>
<span class='line-number'>125</span>
<span class='line-number'>126</span>
<span class='line-number'>127</span>
<span class='line-number'>128</span>
<span class='line-number'>129</span>
<span class='line-number'>130</span>
<span class='line-number'>131</span>
<span class='line-number'>132</span>
<span class='line-number'>133</span>
<span class='line-number'>134</span>
<span class='line-number'>135</span>
<span class='line-number'>136</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="c">#!/bin/bash</span>
</span><span class='line'><span class="c">#</span>
</span><span class='line'><span class="c"># Startup script for Jakarta Tomcat</span>
</span><span class='line'><span class="c"># Script should work on Ubuntu Linux.</span>
</span><span class='line'><span class="c"># WARNING: The script does not allow to run Tomcat on privileged ports as non root user. </span>
</span><span class='line'><span class="c"># For this use case try : &lt;a href=&quot;http://tomcat.apache.org/tomcat-6.0-doc/setup.html&quot;&gt;http://tomcat.apache.org/tomcat-6.0-doc/setup.html&lt;/a&gt; and &lt;a href=&quot;http://commons.apache.org/daemon/jsvc.html</span>
</span><span class='line'><span class="c">#&quot;&gt;http://commons.apache.org/daemon/jsvc.html</span>
</span><span class='line'><span class="c">#&lt;/a&gt; </span>
</span><span class='line'><span class="c"># Should start normally after the databases and before http server</span>
</span><span class='line'><span class="c"># chkconfig: 345 80 10</span>
</span><span class='line'><span class="c"># description: Jakarta Tomcat Java Servlet/JSP Container</span>
</span><span class='line'><span class="c"># processname: tomcat</span>
</span><span class='line'><span class="c"># pidfile: /var/run/tomcat/tomcat.pid</span>
</span><span class='line'>
</span><span class='line'><span class="c">##### In this area you can find settings which are likely to change frequently ####</span>
</span><span class='line'>
</span><span class='line'><span class="nv">JAVA</span><span class="o">=</span>/opt/java/current/bin/java
</span><span class='line'><span class="c"># unprivileged user running Tomcat server</span>
</span><span class='line'><span class="nv">tomcatuser</span><span class="o">=</span>tomcat
</span><span class='line'>
</span><span class='line'><span class="c"># servicename used as pidfile and lockfile name, must correspond to &#39;processname:&#39; at the top of this file</span>
</span><span class='line'><span class="c"># If not linux will not detect the running service during runlevel switch and will not shut it down normally</span>
</span><span class='line'><span class="nv">servicename</span><span class="o">=</span>tomcat
</span><span class='line'>
</span><span class='line'><span class="c"># folder where Tomcat is installed</span>
</span><span class='line'><span class="nv">CATALINA_HOME</span><span class="o">=</span>/opt/tomcat
</span><span class='line'>
</span><span class='line'><span class="c"># Options for the JVM</span>
</span><span class='line'><span class="nv">JAVA_OPTS</span><span class="o">=</span><span class="s2">&quot;$JAVA_OPTS -Xms1024m -Xmx2048m -XX:MaxPermSize=512m -XX:PermSize=128m&quot;</span>
</span><span class='line'><span class="nv">JAVA_OPTS</span><span class="o">=</span><span class="s2">&quot;$JAVA_OPTS -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:ParallelGCThreads=4 JAVA_OPTS=&quot;</span>-Djavax.servlet.request.encoding<span class="o">=</span>UTF-8 -Djavax.servlet.response.encoding<span class="o">=</span>UTF-8 -Dfile.encoding<span class="o">=</span>UTF-8 <span class="nv">$JAVA_OPTS</span><span class="s2">&quot;</span>
</span><span class='line'><span class="s2"> </span>
</span><span class='line'><span class="s2">##### End of frequent settings area #####</span>
</span><span class='line'><span class="s2"> </span>
</span><span class='line'><span class="s2">pidfile=/var/run/tomcat/$servicename</span>
</span><span class='line'><span class="s2">lockfile=/var/lock/$servicename</span>
</span><span class='line'><span class="s2"> </span>
</span><span class='line'><span class="s2">#runsecure=1 #starts tomcat with java security</span>
</span><span class='line'><span class="s2">runsecure=0</span>
</span><span class='line'><span class="s2"> </span>
</span><span class='line'><span class="s2"># Optional additional libs you would like to add to the classpath (= JVM Option -classpath)</span>
</span><span class='line'><span class="s2">CLASSPATH=&quot;&quot;</span>
</span><span class='line'><span class="s2"># Optional Java Security Socket extension</span>
</span><span class='line'><span class="s2"># CLASSPATH=&quot;</span><span class="nv">$CLASSPATH</span><span class="s2">&quot;:&quot;</span><span class="nv">$JSSE_HOME</span><span class="s2">&quot;/lib/jcert.jar:&quot;</span><span class="nv">$JSSE_HOME</span><span class="s2">&quot;/lib/jnet.jar:&quot;</span><span class="nv">$JSSE_HOME</span><span class="s2">&quot;/lib/jsse.jar</span>
</span><span class='line'><span class="s2"> </span>
</span><span class='line'><span class="s2"># path to Tomcat lib</span>
</span><span class='line'><span class="s2">CLASSPATH=&quot;</span><span class="nv">$CLASSPATH</span><span class="s2">&quot;:&quot;</span><span class="nv">$CATALINA_HOME</span><span class="s2">&quot;/bin/bootstrap.jar</span>
</span><span class='line'><span class="s2"> </span>
</span><span class='line'><span class="s2"># Directory holding configuration, defaults to CATALINA_HOME</span>
</span><span class='line'><span class="s2"># In a Tomcat cluster you might reuse the servicename to identify the base directory</span>
</span><span class='line'><span class="s2"> </span>
</span><span class='line'><span class="s2">CATALINA_BASE=&quot;</span><span class="nv">$CATALINA_HOME</span><span class="s2">&quot;</span>
</span><span class='line'><span class="s2"># server log during startup / shutdown</span>
</span><span class='line'><span class="s2">logfile=$CATALINA_BASE/logs/catalina.out</span>
</span><span class='line'><span class="s2"># endorsed allows to overwrite JVM libs -&amp;gt; JVM option -Djava.endorsed.dirs </span>
</span><span class='line'><span class="s2">#JAVA_ENDORSED_DIRS=&quot;</span><span class="nv">$CATALINABASEDIR</span><span class="s2">&quot;/endorsed</span>
</span><span class='line'><span class="s2"> </span>
</span><span class='line'><span class="s2"># Define the java.io.tmpdir to use for Catalina</span>
</span><span class='line'><span class="s2">CATALINA_TMPDIR=&quot;</span><span class="nv">$CATALINA_BASE</span><span class="s2">&quot;/temp</span>
</span><span class='line'><span class="s2"> </span>
</span><span class='line'><span class="s2"># Set juli LogManager if it is present</span>
</span><span class='line'><span class="s2">if [ -r &quot;</span><span class="nv">$CATALINA_BASE</span><span class="s2">&quot;/conf/logging.properties ]; then</span>
</span><span class='line'><span class="s2">  JAVA_OPTS=&quot;</span><span class="nv">$JAVA_OPTS</span> -Djava.util.logging.manager<span class="o">=</span>org.apache.juli.ClassLoaderLogManager<span class="s2">&quot;</span>
</span><span class='line'><span class="s2">  LOGGING_CONFIG=&quot;</span>-Djava.util.logging.config.file<span class="o">=</span><span class="nv">$CATALINA_BASE</span>/conf/logging.properties<span class="s2">&quot;</span>
</span><span class='line'><span class="s2">fi</span>
</span><span class='line'><span class="s2"> </span>
</span><span class='line'><span class="s2">#### End of settings #####</span>
</span><span class='line'><span class="s2"> </span>
</span><span class='line'><span class="s2"># build java command to start Tomcat</span>
</span><span class='line'><span class="s2">command=&quot;</span><span class="nv">$JAVA</span> <span class="nv">$JAVA_OPTS</span> <span class="nv">$LOGGING_CONFIG</span> <span class="nv">$CATALINA_OPTS</span> <span class="nv">$LOGGING_CONFIG</span> <span class="se">\</span>
</span><span class='line'>      -Djava.endorsed.dirs<span class="o">=</span><span class="nv">$JAVA_ENDORSED_DIRS</span> -classpath <span class="nv">$CLASSPATH</span> <span class="se">\</span>
</span><span class='line'>      -Dcatalina.base<span class="o">=</span><span class="nv">$CATALINA_BASE</span> <span class="se">\</span>
</span><span class='line'>      -Dcatalina.home<span class="o">=</span><span class="nv">$CATALINA_HOME</span> <span class="se">\</span>
</span><span class='line'>      -Djava.io.tmpdir<span class="o">=</span><span class="nv">$CATALINA_TMPDIR</span><span class="s2">&quot; </span>
</span><span class='line'><span class="s2"> </span>
</span><span class='line'><span class="s2">if [ &quot;</span><span class="nv">$runsecure</span><span class="s2">&quot; = &quot;</span>1<span class="s2">&quot; ]; then</span>
</span><span class='line'><span class="s2">  command=&quot;</span><span class="nv">$command</span> -Djava.security.manager -Djava.security.policy<span class="o">=</span><span class="nv">$CATALINA_BASE</span>/conf/catalina.policy<span class="s2">&quot;</span>
</span><span class='line'><span class="s2">fi</span>
</span><span class='line'><span class="s2"> </span>
</span><span class='line'><span class="s2">command=&quot;</span><span class="nv">$command</span> org.apache.catalina.startup.Bootstrap<span class="s2">&quot;</span>
</span><span class='line'><span class="s2"> </span>
</span><span class='line'><span class="s2"> </span>
</span><span class='line'><span class="s2">start()</span>
</span><span class='line'><span class="s2">{</span>
</span><span class='line'><span class="s2"> echo $&quot;</span>Starting <span class="nv">$servicename</span> based at <span class="nv">$CATALINA_BASE</span> <span class="s2">&quot;</span>
</span><span class='line'><span class="s2"> </span>
</span><span class='line'><span class="s2"> daemon --user=$tomcatuser --pidfile=$pidfile --output=$logfile -- $command start</span>
</span><span class='line'><span class="s2"> RETVAL=$?</span>
</span><span class='line'><span class="s2"> </span>
</span><span class='line'><span class="s2"> [ &quot;</span><span class="nv">$RETVAL</span><span class="s2">&quot; = 0 ] &amp;amp;&amp;amp; touch $lockfile</span>
</span><span class='line'><span class="s2"> echo</span>
</span><span class='line'><span class="s2">}</span>
</span><span class='line'><span class="s2"> </span>
</span><span class='line'><span class="s2">stop()</span>
</span><span class='line'><span class="s2">{</span>
</span><span class='line'><span class="s2"> echo -n $&quot;</span>Stopping <span class="nv">$prog</span>: <span class="s2">&quot;</span>
</span><span class='line'><span class="s2"> if [ ! -r $pidfile ]; then</span>
</span><span class='line'><span class="s2">     echo &quot;</span>Pidfile <span class="nv">$pidfile</span> cannot be <span class="nb">read</span><span class="s2">&quot;</span>
</span><span class='line'><span class="s2">     RETVAL=1</span>
</span><span class='line'><span class="s2">     return</span>
</span><span class='line'><span class="s2"> fi</span>
</span><span class='line'><span class="s2"> # Sends TERM signal first and kills finally after 10 seconds</span>
</span><span class='line'><span class="s2"> start-stop-daemon --pidfile $pidfile -R 10 --stop</span>
</span><span class='line'><span class="s2"> RETVAL=$?</span>
</span><span class='line'><span class="s2"> [ $RETVAL = 0 ] &amp;amp;&amp;amp; rm -f ${lockfile} ${pidfile}</span>
</span><span class='line'><span class="s2"> echo</span>
</span><span class='line'><span class="s2">}</span>
</span><span class='line'><span class="s2"> </span>
</span><span class='line'><span class="s2">version()</span>
</span><span class='line'><span class="s2">{</span>
</span><span class='line'><span class="s2"> $JAVA -classpath $CATALINA_HOME/lib/catalina.jar org.apache.catalina.util.ServerInfo</span>
</span><span class='line'><span class="s2"> RETVAL=$?</span>
</span><span class='line'><span class="s2">}</span>
</span><span class='line'><span class="s2"> </span>
</span><span class='line'><span class="s2">case &quot;</span><span class="nv">$1</span><span class="s2">&quot; in</span>
</span><span class='line'><span class="s2"> start)</span>
</span><span class='line'><span class="s2">     start</span>
</span><span class='line'><span class="s2">     ;;</span>
</span><span class='line'><span class="s2"> stop)</span>
</span><span class='line'><span class="s2">     stop</span>
</span><span class='line'><span class="s2">     ;;</span>
</span><span class='line'><span class="s2"> restart)</span>
</span><span class='line'><span class="s2">     stop</span>
</span><span class='line'><span class="s2">     start</span>
</span><span class='line'><span class="s2">     ;;</span>
</span><span class='line'><span class="s2"> version)</span>
</span><span class='line'><span class="s2">     version</span>
</span><span class='line'><span class="s2">     ;;</span>
</span><span class='line'><span class="s2"> status)</span>
</span><span class='line'><span class="s2">     status -p $pidfile $servicename</span>
</span><span class='line'><span class="s2">     RETVAL=$?</span>
</span><span class='line'><span class="s2">     ;;</span>
</span><span class='line'><span class="s2"> *)</span>
</span><span class='line'><span class="s2">     echo $&quot;</span>Usage: <span class="nv">$0</span> <span class="o">{</span>start|stop|restart|version|status<span class="o">}</span><span class="err">&quot;</span>
</span><span class='line'>      <span class="nv">RETVAL</span><span class="o">=</span>1
</span><span class='line'><span class="k">esac</span>
</span><span class='line'><span class="nb">exit</span> <span class="nv">$RETVAL</span>
</span></code></pre></td></tr></table></div></figure>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Ruby mixin for the Enum pattern]]></title>
    <link href="http://bealetech.com/blog/2010/06/03/ruby-mixin-for-the-enum-pattern/"/>
    <updated>2010-06-03T14:27:00-07:00</updated>
    <id>http://bealetech.com/blog/2010/06/03/ruby-mixin-for-the-enum-pattern</id>
    <content type="html"><![CDATA[<p>Sometimes you just want to use an Enum. Unfortunately, if you&#8217;re a Ruby developer, Ruby does not offer a native enum structure.</p>

<!-- more -->


<p>Here&#8217;s a simple approach using a mixin module:</p>

<figure class='code'><figcaption><span>Enum.rb </span></figcaption>
 <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
</pre></td><td class='code'><pre><code class='rb'><span class='line'><span class="k">module</span> <span class="nn">Enum</span>
</span><span class='line'>  <span class="k">def</span> <span class="nf">const_missing</span><span class="p">(</span><span class="n">key</span><span class="p">)</span>
</span><span class='line'>    <span class="vi">@enum_hash</span><span class="o">[</span><span class="n">key</span><span class="o">]</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'>
</span><span class='line'>  <span class="k">def</span> <span class="nf">add_enum</span><span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="n">value</span><span class="p">)</span>
</span><span class='line'>    <span class="vi">@enum_hash</span> <span class="o">||=</span> <span class="p">{}</span>
</span><span class='line'>    <span class="vi">@enum_hash</span><span class="o">[</span><span class="n">key</span><span class="o">]</span> <span class="o">=</span> <span class="no">NameValuePair</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="n">key</span><span class="o">.</span><span class="n">to_s</span><span class="o">.</span><span class="n">downcase</span><span class="p">)</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'>
</span><span class='line'>  <span class="k">def</span> <span class="nf">each</span>
</span><span class='line'>    <span class="vi">@enum_hash</span><span class="o">.</span><span class="n">each</span> <span class="p">{</span><span class="o">|</span><span class="n">key</span><span class="p">,</span> <span class="n">value</span><span class="o">|</span> <span class="k">yield</span><span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="n">value</span><span class="p">)</span> <span class="p">}</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'>
</span><span class='line'>  <span class="k">def</span> <span class="nf">enums</span>
</span><span class='line'>    <span class="vi">@enum_hash</span><span class="o">.</span><span class="n">keys</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'>
</span><span class='line'>  <span class="k">def</span> <span class="nf">enum_values</span>
</span><span class='line'>    <span class="vi">@enum_hash</span><span class="o">.</span><span class="n">values</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'>
</span><span class='line'>  <span class="k">def</span> <span class="nf">get_enum_hash</span>
</span><span class='line'>    <span class="vi">@enum_hash</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'>
</span><span class='line'>  <span class="k">def</span> <span class="nf">find_by_key</span><span class="p">(</span><span class="n">key</span><span class="p">)</span>
</span><span class='line'>    <span class="vi">@enum_hash</span><span class="o">[</span><span class="n">key</span><span class="o">.</span><span class="n">upcase</span><span class="o">.</span><span class="n">to_sym</span><span class="o">]</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>The <code>Enum</code> mixin depends on a <code>NameValuePair</code> class to hold the data:</p>

<figure class='code'><figcaption><span>NameValuePair.rb </span></figcaption>
 <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
</pre></td><td class='code'><pre><code class='rb'><span class='line'><span class="k">class</span> <span class="nc">NameValuePair</span>
</span><span class='line'>  <span class="kp">attr_reader</span> <span class="ss">:label</span><span class="p">,</span> <span class="ss">:value</span>
</span><span class='line'>
</span><span class='line'>  <span class="k">def</span> <span class="nf">initialize</span><span class="p">(</span><span class="n">label</span><span class="p">,</span> <span class="n">value</span><span class="p">)</span>
</span><span class='line'>    <span class="vi">@label</span> <span class="o">=</span> <span class="n">label</span>
</span><span class='line'>    <span class="vi">@value</span> <span class="o">=</span> <span class="n">value</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'>
</span><span class='line'>  <span class="k">def</span> <span class="nf">first</span>
</span><span class='line'>    <span class="vi">@label</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'>
</span><span class='line'>  <span class="k">def</span> <span class="nf">last</span>
</span><span class='line'>    <span class="vi">@value</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>I included first and last methods to better support the <code>select</code> and <code>options_for_select</code> helper methods in Rails. Here&#8217;s how you might use it:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="k">class</span> <span class="nc">FooEnum</span>
</span><span class='line'>  <span class="kp">extend</span> <span class="no">Enum</span>
</span><span class='line'>
</span><span class='line'>   <span class="nb">self</span><span class="o">.</span><span class="n">add_enum</span><span class="p">(</span><span class="ss">:APPLE</span><span class="p">,</span> <span class="s2">&quot;Apple&quot;</span><span class="p">)</span>
</span><span class='line'>   <span class="nb">self</span><span class="o">.</span><span class="n">add_enum</span><span class="p">(</span><span class="ss">:PEAR</span><span class="p">,</span> <span class="s2">&quot;Pear&quot;</span><span class="p">)</span>
</span><span class='line'>   <span class="nb">self</span><span class="o">.</span><span class="n">add_enum</span><span class="p">(</span><span class="ss">:ALL</span><span class="p">,</span> <span class="s2">&quot;All Fruit&quot;</span><span class="p">)</span>
</span><span class='line'><span class="k">end</span>
</span><span class='line'>
</span><span class='line'><span class="ss">FooEnum</span><span class="p">:</span><span class="ss">:APPLE</span> <span class="o">==&gt;</span> <span class="c1">#&lt;NameValuePair @value=&quot;apple&quot;, @label=&quot;Apple&quot;&gt;</span>
</span><span class='line'><span class="ss">FooEnum</span><span class="p">:</span><span class="ss">:ALL</span><span class="o">.</span><span class="n">value</span> <span class="o">==&gt;</span> <span class="s2">&quot;all&quot;</span>
</span><span class='line'><span class="ss">FooEnum</span><span class="p">:</span><span class="ss">:ALL</span><span class="o">.</span><span class="n">label</span> <span class="o">==&gt;</span> <span class="s2">&quot;All Fruit&quot;</span>
</span><span class='line'><span class="no">FooEnum</span><span class="o">.</span><span class="n">find_by_key</span><span class="p">(</span><span class="s1">&#39;apple&#39;</span><span class="p">)</span> <span class="o">==&gt;</span> <span class="c1">#&lt;NameValuePair @value=&quot;apple&quot;, @label=&quot;Apple&quot;&gt;</span>
</span></code></pre></td></tr></table></div></figure>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[To Rewrite or Not to Rewrite: The Ugly Question]]></title>
    <link href="http://bealetech.com/blog/2010/04/24/to-rewrite-or-not-to-rewrite-the-ugly-question/"/>
    <updated>2010-04-24T14:07:00-07:00</updated>
    <id>http://bealetech.com/blog/2010/04/24/to-rewrite-or-not-to-rewrite-the-ugly-question</id>
    <content type="html"><![CDATA[<p>I recently had a discussion about the idea of rewriting software from scratch. I actually played the devil&#8217;s advocate and argued against ever throwing out and rewriting, which really got me thinking about the whole concept.</p>

<!-- more -->


<p>The discussion centered around article by Joel Spolsky (of <a href="http://www.joelonsoftware.com/">Joel on Software</a>) titled <a href="http://www.joelonsoftware.com/articles/fog0000000069.html">Things You Should Never Do, Part 1</a>. His points against rewrites include:</p>

<ol>
<li>The ugly code you throw out has been hardened and tested. It&#8217;s filled with bug fixes. You&#8217;re throwing out that knowledge and expertise.</li>
<li>You&#8217;re throwing out market leadership and &#8220;giving a gift of two or three years to your competitors&#8221;.</li>
<li>You&#8217;re not going to do a better job writing the code a second time than you did the first time, especially since it&#8217;s unlikely you have the same team that wrote the earlier version.</li>
<li>You will introduce new bugs.</li>
</ol>


<p>Joel further argues that there are three major reasons developers want to rewrite code and none of them require rewrites:</p>

<ol>
<li>Architectural problems. The &#8220;you got your gui in my business logic&#8221; problem. This can be handled by small but steady code refactorings.</li>
<li>Inefficiency. Again, can be handled by small code refactorings.</li>
<li>The code is fugly. This may be due to complexity and bug fixes, in which case see point #1 above. Or it may be due to poor and changing naming conventions, in which case it can be fixed by a simple Find-Replace.</li>
</ol>


<p>These are all excellent points. On some level, I agree with this entirely. Even many nasty combinations of all three problems can be solved by steady refactorings. I have worked for places where people pushed for rewrites that weren&#8217;t necessary. But these were larger businesses with a well established core product. These were not early startups. That&#8217;s why I believe Joel makes several assumptions which are fatal to his arguments.</p>

<p>First, he assumes the software project is really large and complex. While some of us may have worked on projects of that size and scope, quite of few of us work on much smaller projects. Simply put, it&#8217;s a matter of scale.Second, as a corollary of his first assumption, Joel also assumes that a rewrite requires years not months. Again, this is likely true for a product like Excel or Word&#8230; but this simply isn&#8217;t true for many of the sites and products I&#8217;ve worked on. Furthermore, the use of agile or rapid development technologies such as Ruby on Rails can dramatically shrink this window.</p>

<p>Third, and perhaps most importantly, Joel assumes that the time required to cope with a messy code-base and make steady refactorings is significantly less than the time required to rewrite the app. And he assumes that&#8217;s a worthwhile trade off. This may be clear cut for larger products or companies, but I question whether or not that&#8217;s accurate for a startup. The more tangled your code, the longer it takes you to make changes. The longer it takes to make changes, the less nimble you are and the longer it takes you to respond to changes in company direction or marketplace demands.</p>

<p>It&#8217;s that last point that I believe is most important to those of us working for small startups. We tend to be small young companies who are still striving to find our exact place in the wider world. We&#8217;re often in cutting edge spaces where there is no clear cut path to success. And usually we&#8217;re steadily seeing greater numbers of competitors in our space. It seems to me that agility is vitally important to people us. We need to be able to makes changes rapidly as our knowledge of the space evolves. Fundamentally, I think it&#8217;s better to have a decent product/feature/whatever out in the hands of consumers than it is to have a nearly perfect product that&#8217;s still under development. Don&#8217;t get me wrong, I&#8217;m sure I&#8217;m preaching to the choir. :) But, I think it&#8217;s critical to keep the need for agility and nimbleness in the forefront of our thoughts.</p>

<p>Fourth, Joel assumes any architectural problems can be solved by steady refactoring. Frankly, I disagree. I think there exist serious architectural flaws, especially related to scalability that cannot be easily solved by refactoring. eBay, LinkedIn, Facebook and Yahoo have all had major rewrites in their history that were directly attributed to serious architectural failings.</p>

<p>That is not to say that a full rewrite is necessarily a desirable goal. :) However, it takes careful management and planning to avoid finding yourself in this position. eBay used to employ a strategy they called <a href="http://www.svproduct.com/engineering-wants-to-rewrite/">headroom</a>, which basically set aside 20+% of all development time to refactor code and it keep it in top working order. While I think it may very difficult to employ such a strategy in a startup, it may be worth considering.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[FlashVars broken in IE8]]></title>
    <link href="http://bealetech.com/blog/2010/03/10/flashvars-broken-in-ie8/"/>
    <updated>2010-03-10T10:16:00-08:00</updated>
    <id>http://bealetech.com/blog/2010/03/10/flashvars-broken-in-ie8</id>
    <content type="html"><![CDATA[<p>Unsurprisingly, Internet Explorer 8 broke yet another feature of the web.</p>

<!-- more -->


<p>This time, the folks at Redmond broke how Internet Explorer passes the flashvars parameter into Flash. Typically, when placing a Flash object on an HTML page, you use the following syntax:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
</pre></td><td class='code'><pre><code class='html'><span class='line'><span class="nt">&lt;object</span> <span class="na">id=</span><span class="s">&quot;flv&quot;</span> <span class="na">classid=</span><span class="s">&quot;clsid:d27cdb6e-ae6d-11cf-96b8-444553540000&quot;</span> <span class="na">width=</span><span class="s">&quot;692&quot;</span> <span class="na">height=</span><span class="s">&quot;516&quot;</span> <span class="na">codebase=</span><span class="s">&quot;&lt;a href=&quot;</span><span class="na">http:</span><span class="err">//</span><span class="na">download</span><span class="err">.</span><span class="na">macromedia</span><span class="err">.</span><span class="na">com</span><span class="err">/</span><span class="na">pub</span><span class="err">/</span><span class="na">shockwave</span><span class="err">/</span><span class="na">cabs</span><span class="err">/</span><span class="na">flash</span><span class="err">/</span><span class="na">swflash</span><span class="err">.</span><span class="na">cab</span><span class="err">#</span><span class="na">version=</span><span class="s">9,0,0,0&quot;&quot;</span><span class="nt">&gt;</span>http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#vers...<span class="nt">&lt;/a&gt;</span> align=&quot;middle&quot;&gt;
</span><span class='line'> <span class="nt">&lt;param</span> <span class="na">name=</span><span class="s">&quot;allowScriptAccess&quot;</span> <span class="na">value=</span><span class="s">&quot;sameDomain&quot;</span> <span class="nt">/&gt;</span>
</span><span class='line'> <span class="nt">&lt;param</span> <span class="na">name=</span><span class="s">&quot;allowFullScreen&quot;</span> <span class="na">value=</span><span class="s">&quot;true&quot;</span> <span class="nt">/&gt;</span>
</span><span class='line'> <span class="nt">&lt;param</span> <span class="na">name=</span><span class="s">&quot;quality&quot;</span> <span class="na">value=</span><span class="s">&quot;high&quot;</span> <span class="nt">/&gt;</span>
</span><span class='line'> <span class="nt">&lt;param</span> <span class="na">name=</span><span class="s">&quot;bgcolor&quot;</span> <span class="na">value=</span><span class="s">&quot;#424242&quot;</span> <span class="nt">/&gt;</span>
</span><span class='line'> <span class="nt">&lt;param</span> <span class="na">name=</span><span class="s">&quot;FlashVars&quot;</span> <span class="na">value=</span><span class="s">&quot;name=value&quot;</span> <span class="nt">/&gt;</span>
</span><span class='line'> <span class="nt">&lt;param</span> <span class="na">name=</span><span class="s">&quot;wmode&quot;</span> <span class="na">value=</span><span class="s">&quot;transparent&quot;</span> <span class="nt">/&gt;</span>
</span><span class='line'> <span class="nt">&lt;embed</span> <span class="na">type=</span><span class="s">&quot;application/x-shockwave-flash&quot;</span> <span class="na">width=</span><span class="s">&quot;692&quot;</span> <span class="na">height=</span><span class="s">&quot;516&quot;</span> <span class="na">src=</span><span class="s">&quot;&lt;a href=&quot;</span><span class="na">http:</span><span class="err">//</span><span class="na">www</span><span class="err">.</span><span class="na">example</span><span class="err">.</span><span class="na">com</span><span class="err">/</span><span class="na">mysample</span><span class="err">.</span><span class="na">swf</span><span class="err">&quot;&quot;</span><span class="nt">&gt;</span>http://www.example.com/mysample.swf&quot;<span class="nt">&lt;/a&gt;</span> align=&quot;middle&quot; pluginspage=&quot;<span class="nt">&lt;a</span> <span class="na">href=</span><span class="s">&quot;http://www.macromedia.com/go/getflashplayer&quot;</span><span class="err">&quot;</span><span class="nt">&gt;</span>http://www.macromedia.com/go/getflashplayer&quot;<span class="nt">&lt;/a&gt;</span> flashvars=&quot;name=value&quot; quality=&quot;high&quot; bgcolor=&quot;#424242&quot; wmode=&quot;transparent&quot; allowscriptaccess=&quot;sameDomain&quot; allowfullscreen=&quot;true&quot; name=&quot;flv&quot;&gt;<span class="nt">&lt;/embed&gt;</span>
</span><span class='line'> <span class="nt">&lt;param</span> <span class="na">name=</span><span class="s">&quot;movie&quot;</span> <span class="na">value=</span><span class="s">&quot;&lt;a href=&quot;</span><span class="na">http:</span><span class="err">//</span><span class="na">www</span><span class="err">.</span><span class="na">example</span><span class="err">.</span><span class="na">com</span><span class="err">/</span><span class="na">mysample</span><span class="err">.</span><span class="na">swf</span><span class="err">&quot;&quot;</span><span class="nt">&gt;</span>http://www.example.com/mysample.swf&quot;<span class="nt">&lt;/a&gt;</span> /&gt;
</span><span class='line'><span class="nt">&lt;/object&gt;</span>
</span></code></pre></td></tr></table></div></figure>


<p>The <code>OBJECT</code> tag is used by Internet Explorer and the <code>EMBED</code> tag is used by everyone else (Firefox, Safari, etc.). Although the flashvars paramter is not formally described in the <a href="http://www.w3.org/TR/html4/struct/objects.html#h-13.3.2">HTML 4.0.1 spec</a>, this code worked fine with IE 6 and IE 7. Unfortunately, IE 8 does not pass flashvars into the Flash Player. The only work around is to pass the flashvars parameter as part of the movie name parameter, as shown below:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
</pre></td><td class='code'><pre><code class='html'><span class='line'><span class="nt">&lt;object</span> <span class="na">id=</span><span class="s">&quot;flv&quot;</span> <span class="na">classid=</span><span class="s">&quot;clsid:d27cdb6e-ae6d-11cf-96b8-444553540000&quot;</span> <span class="na">width=</span><span class="s">&quot;692&quot;</span> <span class="na">height=</span><span class="s">&quot;516&quot;</span> <span class="na">codebase=</span><span class="s">&quot;&lt;a href=&quot;</span><span class="na">http:</span><span class="err">//</span><span class="na">download</span><span class="err">.</span><span class="na">macromedia</span><span class="err">.</span><span class="na">com</span><span class="err">/</span><span class="na">pub</span><span class="err">/</span><span class="na">shockwave</span><span class="err">/</span><span class="na">cabs</span><span class="err">/</span><span class="na">flash</span><span class="err">/</span><span class="na">swflash</span><span class="err">.</span><span class="na">cab</span><span class="err">#</span><span class="na">version=</span><span class="s">9,0,0,0&quot;&quot;</span><span class="nt">&gt;</span>http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#vers...<span class="nt">&lt;/a&gt;</span> align=&quot;middle&quot;&gt;
</span><span class='line'> <span class="nt">&lt;param</span> <span class="na">name=</span><span class="s">&quot;allowScriptAccess&quot;</span> <span class="na">value=</span><span class="s">&quot;sameDomain&quot;</span> <span class="nt">/&gt;</span>
</span><span class='line'> <span class="nt">&lt;param</span> <span class="na">name=</span><span class="s">&quot;allowFullScreen&quot;</span> <span class="na">value=</span><span class="s">&quot;true&quot;</span> <span class="nt">/&gt;</span>
</span><span class='line'> <span class="nt">&lt;param</span> <span class="na">name=</span><span class="s">&quot;quality&quot;</span> <span class="na">value=</span><span class="s">&quot;high&quot;</span> <span class="nt">/&gt;</span>
</span><span class='line'> <span class="nt">&lt;param</span> <span class="na">name=</span><span class="s">&quot;bgcolor&quot;</span> <span class="na">value=</span><span class="s">&quot;#424242&quot;</span> <span class="nt">/&gt;</span>
</span><span class='line'> <span class="nt">&lt;param</span> <span class="na">name=</span><span class="s">&quot;FlashVars&quot;</span> <span class="na">value=</span><span class="s">&quot;name=value&quot;</span> <span class="nt">/&gt;</span>
</span><span class='line'> <span class="nt">&lt;param</span> <span class="na">name=</span><span class="s">&quot;wmode&quot;</span> <span class="na">value=</span><span class="s">&quot;transparent&quot;</span> <span class="nt">/&gt;</span>
</span><span class='line'> <span class="nt">&lt;embed</span> <span class="na">type=</span><span class="s">&quot;application/x-shockwave-flash&quot;</span> <span class="na">width=</span><span class="s">&quot;692&quot;</span> <span class="na">height=</span><span class="s">&quot;516&quot;</span> <span class="na">src=</span><span class="s">&quot;&lt;a href=&quot;</span><span class="na">http:</span><span class="err">//</span><span class="na">www</span><span class="err">.</span><span class="na">example</span><span class="err">.</span><span class="na">com</span><span class="err">/</span><span class="na">mysample</span><span class="err">.</span><span class="na">swf</span><span class="err">&quot;&quot;</span><span class="nt">&gt;</span>http://www.example.com/mysample.swf&quot;<span class="nt">&lt;/a&gt;</span> align=&quot;middle&quot; pluginspage=&quot;<span class="nt">&lt;a</span> <span class="na">href=</span><span class="s">&quot;http://www.macromedia.com/go/getflashplayer&quot;</span><span class="err">&quot;</span><span class="nt">&gt;</span>http://www.macromedia.com/go/getflashplayer&quot;<span class="nt">&lt;/a&gt;</span> flashvars=&quot;name=value&quot; quality=&quot;high&quot; bgcolor=&quot;#424242&quot; wmode=&quot;transparent&quot; allowscriptaccess=&quot;sameDomain&quot; allowfullscreen=&quot;true&quot; name=&quot;flv&quot;&gt;<span class="nt">&lt;/embed&gt;</span>
</span><span class='line'> <span class="nt">&lt;param</span> <span class="na">name=</span><span class="s">&quot;movie&quot;</span> <span class="na">value=</span><span class="s">&quot;&lt;a href=&quot;</span><span class="na">http:</span><span class="err">//</span><span class="na">www</span><span class="err">.</span><span class="na">example</span><span class="err">.</span><span class="na">com</span><span class="err">/</span><span class="na">mysample</span><span class="err">.</span><span class="na">swf</span><span class="err">?</span><span class="na">name=</span><span class="s">value&quot;&quot;</span><span class="nt">&gt;</span>http://www.example.com/mysample.swf?name=value&quot;<span class="nt">&lt;/a&gt;</span> /&gt;
</span><span class='line'><span class="nt">&lt;/object&gt;</span>
</span></code></pre></td></tr></table></div></figure>



]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Embedding HTML Document in an IFRAME with GWT]]></title>
    <link href="http://bealetech.com/blog/2010/01/25/embedding-html-document-in-an-iframe-with-gwt/"/>
    <updated>2010-01-25T16:10:00-08:00</updated>
    <id>http://bealetech.com/blog/2010/01/25/embedding-html-document-in-an-iframe-with-gwt</id>
    <content type="html"><![CDATA[<p>While working on a recent project in GWT, I needed to embed a full HTML document inside an IFRAME. And I didn&#8217;t want to specify a remote URL for the IFRAME - I actually wanted to shove the HTML content directly into the IFRAME.</p>

<!-- more -->


<p>Initially I thought it was trivial: create an <code>IFrameElement</code> and call <code>setInnerHTML</code>.</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="nx">IFrameElement</span> <span class="nx">iframe</span> <span class="o">=</span> <span class="nx">Document</span><span class="p">.</span><span class="nx">get</span><span class="p">().</span><span class="nx">createIFrameElement</span><span class="p">();</span>
</span><span class='line'><span class="nx">iframe</span><span class="p">.</span><span class="nx">setInnerHTML</span><span class="p">(</span><span class="nx">htmlContent</span><span class="p">);</span>
</span></code></pre></td></tr></table></div></figure>


<p>Unfortunately, that doesn&#8217;t work. It doesn&#8217;t cause any errors, but it doesn&#8217;t actually fill in the iframe. Instead, you have to use native javascript to write into the document object for the iframe:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="kr">private</span> <span class="kr">final</span> <span class="kr">native</span> <span class="k">void</span> <span class="nx">fillIframe</span><span class="p">(</span><span class="nx">IFrameElement</span> <span class="nx">iframe</span><span class="p">,</span> <span class="nb">String</span> <span class="nx">content</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>  <span class="kd">var</span> <span class="nx">doc</span> <span class="o">=</span> <span class="nx">iframe</span><span class="p">.</span><span class="nb">document</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'>  <span class="k">if</span><span class="p">(</span><span class="nx">iframe</span><span class="p">.</span><span class="nx">contentDocument</span><span class="p">)</span>
</span><span class='line'>    <span class="nx">doc</span> <span class="o">=</span> <span class="nx">iframe</span><span class="p">.</span><span class="nx">contentDocument</span><span class="p">;</span> <span class="c1">// For NS6</span>
</span><span class='line'>  <span class="k">else</span> <span class="k">if</span><span class="p">(</span><span class="nx">iframe</span><span class="p">.</span><span class="nx">contentWindow</span><span class="p">)</span>
</span><span class='line'>    <span class="nx">doc</span> <span class="o">=</span> <span class="nx">iframe</span><span class="p">.</span><span class="nx">contentWindow</span><span class="p">.</span><span class="nb">document</span><span class="p">;</span> <span class="c1">// For IE5.5 and IE6</span>
</span><span class='line'>
</span><span class='line'>   <span class="c1">// Put the content in the iframe</span>
</span><span class='line'>  <span class="nx">doc</span><span class="p">.</span><span class="nx">open</span><span class="p">();</span>
</span><span class='line'>  <span class="nx">doc</span><span class="p">.</span><span class="nx">writeln</span><span class="p">(</span><span class="nx">content</span><span class="p">);</span>
</span><span class='line'>  <span class="nx">doc</span><span class="p">.</span><span class="nx">close</span><span class="p">();</span>
</span><span class='line'><span class="p">};</span>
</span></code></pre></td></tr></table></div></figure>


<p>Voila! However, one of the side effects is that the iframe doesn&#8217;t include any CSS unless your embedded HTML references a stylesheet. If you want to manually add a reference to a specific stylesheet, you can do that through native javascript as well:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="kr">private</span> <span class="kr">final</span> <span class="kr">native</span> <span class="k">void</span> <span class="nx">addHeadElement</span><span class="p">(</span><span class="nx">IFrameElement</span> <span class="nx">iframe</span><span class="p">,</span> <span class="nb">String</span> <span class="nx">cssUrl</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>  <span class="nx">setTimeout</span><span class="p">(</span><span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>
</span><span class='line'>    <span class="kd">var</span> <span class="nx">body</span><span class="p">;</span>
</span><span class='line'>    <span class="k">if</span> <span class="p">(</span> <span class="nx">iframe</span><span class="p">.</span><span class="nx">contentDocument</span> <span class="p">)</span> <span class="p">{</span>
</span><span class='line'>      <span class="c1">// FF</span>
</span><span class='line'>      <span class="nx">iframe</span><span class="p">.</span><span class="nx">contentDocument</span><span class="p">.</span><span class="nx">designMode</span><span class="o">=</span> <span class="s2">&quot;On&quot;</span><span class="p">;</span>
</span><span class='line'>      <span class="nx">iframe</span><span class="p">.</span><span class="nx">contentDocument</span><span class="p">.</span><span class="nx">execCommand</span><span class="p">(</span><span class="s1">&#39;styleWithCSS&#39;</span><span class="p">,</span><span class="kc">false</span><span class="p">,</span><span class="s1">&#39;false&#39;</span><span class="p">);</span>
</span><span class='line'>      <span class="nx">body</span><span class="o">=</span> <span class="nx">iframe</span><span class="p">.</span><span class="nx">contentDocument</span><span class="p">.</span><span class="nx">body</span><span class="p">;</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>    <span class="k">else</span> <span class="k">if</span> <span class="p">(</span> <span class="nx">iframe</span><span class="p">.</span><span class="nx">contentWindow</span> <span class="p">)</span> <span class="p">{</span>
</span><span class='line'>      <span class="c1">// IE</span>
</span><span class='line'>      <span class="nx">body</span> <span class="o">=</span> <span class="nx">iframe</span><span class="p">.</span><span class="nx">contentWindow</span><span class="p">.</span><span class="nb">document</span><span class="p">.</span><span class="nx">body</span><span class="p">;</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>    <span class="k">if</span> <span class="p">(</span><span class="nx">body</span> <span class="o">==</span> <span class="kc">null</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>      <span class="k">return</span><span class="p">;</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>    <span class="nx">body</span><span class="p">.</span><span class="nx">className</span> <span class="o">=</span> <span class="s2">&quot;custom-body-classname&quot;</span><span class="p">;</span>
</span><span class='line'>    <span class="kd">var</span> <span class="nx">head</span> <span class="o">=</span> <span class="nx">body</span><span class="p">.</span><span class="nx">previousSibling</span><span class="p">;</span>
</span><span class='line'>    <span class="k">if</span><span class="p">(</span><span class="nx">head</span> <span class="o">==</span> <span class="kc">null</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>      <span class="nx">head</span> <span class="o">=</span> <span class="nx">iframe</span><span class="p">.</span><span class="nx">contentWindow</span><span class="p">.</span><span class="nb">document</span><span class="p">.</span><span class="nx">createElement</span><span class="p">(</span><span class="s2">&quot;head&quot;</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'>      <span class="nx">iframe</span><span class="p">.</span><span class="nx">contentWindow</span><span class="p">.</span><span class="nb">document</span><span class="p">.</span><span class="nx">childNodes</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="nx">insertBefore</span><span class="p">(</span><span class="nx">head</span><span class="p">,</span> <span class="nx">body</span><span class="p">);</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>    <span class="kd">var</span> <span class="nx">fileref</span> <span class="o">=</span> <span class="nx">iframe</span><span class="p">.</span><span class="nx">contentWindow</span><span class="p">.</span><span class="nb">document</span><span class="p">.</span><span class="nx">createElement</span><span class="p">(</span><span class="s2">&quot;link&quot;</span><span class="p">);</span>
</span><span class='line'>    <span class="nx">fileref</span><span class="p">.</span><span class="nx">setAttribute</span><span class="p">(</span><span class="s2">&quot;rel&quot;</span><span class="p">,</span> <span class="s2">&quot;stylesheet&quot;</span><span class="p">);</span>
</span><span class='line'>    <span class="nx">fileref</span><span class="p">.</span><span class="nx">setAttribute</span><span class="p">(</span><span class="s2">&quot;type&quot;</span><span class="p">,</span> <span class="s2">&quot;text/css&quot;</span><span class="p">);</span>
</span><span class='line'>    <span class="nx">fileref</span><span class="p">.</span><span class="nx">setAttribute</span><span class="p">(</span><span class="s2">&quot;href&quot;</span><span class="p">,</span> <span class="nx">cssUrl</span><span class="p">);</span>
</span><span class='line'>    <span class="nx">head</span><span class="p">.</span><span class="nx">appendChild</span><span class="p">(</span><span class="nx">fileref</span><span class="p">);</span>
</span><span class='line'>  <span class="p">},</span> <span class="mi">50</span><span class="p">);</span>
</span><span class='line'><span class="p">};}</span>
</span></code></pre></td></tr></table></div></figure>


<p>There&#8217;s still one more problem. You can&#8217;t use either of native methods until the IFRAME element has been attached to the DOM. The easiest way around this is to add the IFRAME element to a panel and over the onLoad() method for the panel:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="kr">final</span> <span class="nx">IFrameElement</span> <span class="nx">iframe</span> <span class="o">=</span> <span class="nx">Document</span><span class="p">.</span><span class="nx">get</span><span class="p">().</span><span class="nx">createIFrameElement</span><span class="p">();</span>
</span><span class='line'><span class="nx">FlowPanel</span> <span class="nx">innerBox</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">FlowPanel</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>    <span class="err">@</span><span class="nx">Override</span>
</span><span class='line'>    <span class="kr">protected</span> <span class="k">void</span> <span class="nx">onLoad</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>        <span class="kr">super</span><span class="p">.</span><span class="nx">onLoad</span><span class="p">();</span>
</span><span class='line'>
</span><span class='line'>        <span class="c1">// Fill the IFrame with the content html</span>
</span><span class='line'>        <span class="nx">fillIframe</span><span class="p">(</span><span class="nx">iframe</span><span class="p">,</span> <span class="nx">contentHtml</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'>        <span class="c1">// Add a HEAD element to the IFrame with the appropriate CSS</span>
</span><span class='line'>        <span class="nx">addHeadElement</span><span class="p">(</span><span class="nx">iframe</span><span class="p">,</span> <span class="nx">cssUrl</span><span class="p">);</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'><span class="p">};</span>
</span><span class='line'><span class="nx">innerBox</span><span class="p">.</span><span class="nx">getElement</span><span class="p">().</span><span class="nx">appendChild</span><span class="p">(</span><span class="nx">iframe</span><span class="p">);</span>
</span></code></pre></td></tr></table></div></figure>


<p>I got the idea and the important code from an article titled <a href="http://softwareas.com/injecting-html-into-an-iframe">Inject HTML into an IFrame</a> from <a href="http://softwareas.com/">Software As She&#8217;s Developed</a>.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Subversion: File or directory is out of date; try updating]]></title>
    <link href="http://bealetech.com/blog/2010/01/01/subversion-file-or-directory-is-out-of-date-try-updating/"/>
    <updated>2010-01-01T18:36:00-08:00</updated>
    <id>http://bealetech.com/blog/2010/01/01/subversion-file-or-directory-is-out-of-date-try-updating</id>
    <content type="html"><![CDATA[<p>I recently started encountering a strange problem with Subversion on one of my machines. In larger commits, I would suddenly get an error:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nv">$ </span>svn ci -m <span class="s2">&quot;My commit message.&quot;</span>
</span><span class='line'>Sending        src/Foo.java
</span><span class='line'>svn: Commit failed <span class="o">(</span>details follow<span class="o">)</span>:
</span><span class='line'>svn: File or directory <span class="s1">&#39;src/Foo.java&#39;</span> is out of date; try updating
</span><span class='line'>svn: resource out of date; try updating
</span></code></pre></td></tr></table></div></figure>


<p>Although I was positive the file(s) were up to date, I ran an svn up just to be safe:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nv">$ </span>svn up
</span><span class='line'>At revision 10803.
</span></code></pre></td></tr></table></div></figure>


<p>Nothing changed. If I tried to commit again, I would get the same out of date error. Eventually I figured out that if I delete the folder containing the problematic file, ran svn up to restore the working copy and re-edited (or restored from a backup) the modified file, the problem went away. This suggested an issue with the Subversion metadata, but this <a href="http://pageworthy.com/blog/2009/apr/14/subversion-says-your-file-or-directory-probably-ou/">blog post from Pageworthy</a> describes a much easier work around:</p>

<blockquote><p>Delete the all-wcprops file from the .svn metadata folder for the offending file.</p><footer><strong>Pageworthy</strong> <cite><a href='http://pageworthy.com/blog/2009/apr/14/subversion-says-your-file-or-directory-probably-ou/'>pageworthy.com/blog/2009/apr/14/&hellip;</a></cite></footer></blockquote>


<p>In other words, if Subversion complains about <code>src/com/mycompany/Foo.java</code>, then delete <code>src/com/mycompany/.svn/all-wcprops</code>.</p>

<ul>
<li>OS: Mac 10.6</li>
<li>IDE: Eclipse 20090920-1017</li>
<li>Subversive Team Provider: 0.7.8</li>
<li>Subversive Connectors: 2.2.1</li>
<li>SVNKit 1.3.0: 2.2.1</li>
<li>Subversion: 1.6.6</li>
</ul>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Kubuntu 9.10 Dual Monitors]]></title>
    <link href="http://bealetech.com/blog/2009/12/06/kubuntu-9-dot-10-dual-monitors/"/>
    <updated>2009-12-06T11:12:00-08:00</updated>
    <id>http://bealetech.com/blog/2009/12/06/kubuntu-9-dot-10-dual-monitors</id>
    <content type="html"><![CDATA[<p>A few months back I got a new <a href="http://system76.com/product_info.php?cPath=28&amp;products_id=76">12.1&#8221; System76 Darter laptop</a> and I finally decided to setup dual monitors on Kubuntu 9.10 (Karmic Koala).What I wanted was to have my laptop LCD on the left at 1280x800 and my ViewSonic LCD panel on the right running at 1680x1050. Apparently I&#8217;m old-skool, because I&#8217;m used to hacking away at my <code>xorg.conf</code> just to get dual monitor support to work under Linux. Somehow I never knew about <a href="http://www.x.org/wiki/Projects/XRandR">xrandr</a>, KRandR, etc.</p>

<!-- more -->


<p><a href="http://www.thinkwiki.org/wiki/ThinkWiki">ThinkWiki</a> has a great <a href="http://www.thinkwiki.org/wiki/Xorg_RandR_1.2">article about using XRandR</a> that really helped me out. When I first launched Kubuntu the two screens were mirrored. So, I tried to use KRandR to set the screens side by side. Unfortunately, it seemed to be confused - it saw there were two outputs, but it thought they were the same screen. This is where the ThinkWiki article came in handy.</p>

<p>With the later versions of Xorg, Ubuntu doesn&#8217;t even include an <code>xorg.conf</code>. Instead of even monkeying around with Xorg, I just used xrandr. There were three key steps:</p>

<h2>Identify Outputs</h2>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nv">$ </span>xrandr -q
</span><span class='line'>Screen 0: minimum 320 x 200, current 2960 x 1050, maximum 8192 x 8192
</span><span class='line'>VGA1 connected 1680x1050+1280+0 <span class="o">(</span>normal left inverted right x axis y axis<span class="o">)</span> 474mm x 296mm
</span><span class='line'>   1680x1050      60.0*+
</span><span class='line'>   1280x1024      75.0
</span><span class='line'>   1152x864       75.0
</span><span class='line'>   1024x768       75.1     70.1     60.0
</span><span class='line'>   832x624        74.6
</span><span class='line'>   800x600        72.2     75.0     60.3     56.2
</span><span class='line'>   640x480        72.8     75.0     66.7     60.0
</span><span class='line'>   720x400        70.1
</span><span class='line'>LVDS1 connected 1280x800+0+0 <span class="o">(</span>normal left inverted right x axis y axis<span class="o">)</span> 261mm x 163mm
</span><span class='line'>   1280x800       60.0*+
</span><span class='line'>   1024x768       60.0
</span><span class='line'>   800x600        60.3
</span><span class='line'>   640x480        59.9
</span><span class='line'>DP1 disconnected <span class="o">(</span>normal left inverted right x axis y axis<span class="o">)</span>
</span></code></pre></td></tr></table></div></figure>


<p>This shows I have two main outputs connected right now: VGA1 and LVDS1. Under Ubuntu 9.04 (Jaunty), my outputs were labeled VGA and LVDS.</p>

<h2>Disable secondary output</h2>

<p>Once we know the name of the outputs, we can disable the secondary output. This is the key step to getting a large virtual desktop working without something like Xinerama. If you don&#8217;t disable the secondary output, Xorg never seems to be able to successfully distinguish between the two outputs.</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nv">$ </span>xrandr --output VGA1 --off
</span></code></pre></td></tr></table></div></figure>


<h2>Re-enable both outputs</h2>

<p>When we re-enable the outputs we can specify the location of the secondary display, relative to the primary. We can also let xrandr figure out the best resolution for each:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nv">$ </span>xrandr --output LVDS --auto --output VGA --auto --right-of LVDS
</span></code></pre></td></tr></table></div></figure>


<p>Voila. Finally, if you want to automate this, the <a href="http://www.thinkwiki.org/wiki/Xorg_RandR_1.2">ThinkWiki article</a> has a great little script you can use. However, I did have to modify it slightly &#8230; I had to force the VGA1 output off before setting them both to auto. Without that, the secondary screen remained blank.</p>

<figure class='code'><figcaption><span>/etc/X11/Xsession.d/45custom_xrandr-settings  </span></figcaption>
 <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="c"># If an external monitor is connected, place it with xrandr</span>
</span><span class='line'>
</span><span class='line'><span class="c"># External output may be &quot;VGA&quot; or &quot;VGA-0&quot; or &quot;DVI-0&quot; or &quot;TMDS-1&quot;</span>
</span><span class='line'><span class="nv">EXTERNAL_OUTPUT</span><span class="o">=</span><span class="s2">&quot;VGA1&quot;</span>
</span><span class='line'><span class="nv">INTERNAL_OUTPUT</span><span class="o">=</span><span class="s2">&quot;LVDS1&quot;</span>
</span><span class='line'><span class="c"># EXTERNAL_LOCATION may be one of: left, right, above, or below</span>
</span><span class='line'><span class="nv">EXTERNAL_LOCATION</span><span class="o">=</span><span class="s2">&quot;right&quot;</span>
</span><span class='line'>
</span><span class='line'><span class="k">case</span> <span class="s2">&quot;$EXTERNAL_LOCATION&quot;</span> in
</span><span class='line'>       left|LEFT<span class="o">)</span>
</span><span class='line'>               <span class="nv">EXTERNAL_LOCATION</span><span class="o">=</span><span class="s2">&quot;--left-of $INTERNAL_OUTPUT&quot;</span>
</span><span class='line'>               ;;
</span><span class='line'>       right|RIGHT<span class="o">)</span>
</span><span class='line'>               <span class="nv">EXTERNAL_LOCATION</span><span class="o">=</span><span class="s2">&quot;--right-of $INTERNAL_OUTPUT&quot;</span>
</span><span class='line'>               ;;
</span><span class='line'>       top|TOP|above|ABOVE<span class="o">)</span>
</span><span class='line'>               <span class="nv">EXTERNAL_LOCATION</span><span class="o">=</span><span class="s2">&quot;--above $INTERNAL_OUTPUT&quot;</span>
</span><span class='line'>               ;;
</span><span class='line'>       bottom|BOTTOM|below|BELOW<span class="o">)</span>
</span><span class='line'>               <span class="nv">EXTERNAL_LOCATION</span><span class="o">=</span><span class="s2">&quot;--below $INTERNAL_OUTPUT&quot;</span>
</span><span class='line'>               ;;
</span><span class='line'>       *<span class="o">)</span>
</span><span class='line'>               <span class="nv">EXTERNAL_LOCATION</span><span class="o">=</span><span class="s2">&quot;--left-of $INTERNAL_OUTPUT&quot;</span>
</span><span class='line'>               ;;
</span><span class='line'><span class="k">esac</span>
</span><span class='line'><span class="k"> </span>
</span><span class='line'>xrandr |grep <span class="nv">$EXTERNAL_OUTPUT</span> | grep <span class="s2">&quot; connected &quot;</span>
</span><span class='line'><span class="k">if</span> <span class="o">[</span> <span class="nv">$?</span> -eq 0 <span class="o">]</span>; <span class="k">then</span>
</span><span class='line'><span class="k">    </span>xrandr --output <span class="nv">$EXTERNAL_OUTPUT</span> --off
</span><span class='line'>    xrandr --output <span class="nv">$INTERNAL_OUTPUT</span> --auto --output <span class="nv">$EXTERNAL_OUTPUT</span> --auto <span class="nv">$EXTERNAL_LOCATION</span>
</span><span class='line'>    <span class="c"># Alternative command in case of trouble:</span>
</span><span class='line'>    <span class="c"># (sleep 2; xrandr --output $INTERNAL_OUTPUT --auto --output $EXTERNAL_OUTPUT --auto $EXTERNAL_LOCATION) &amp;amp;</span>
</span><span class='line'><span class="k">else</span>
</span><span class='line'><span class="k">    </span>xrandr --output <span class="nv">$INTERNAL_OUTPUT</span> --auto --output <span class="nv">$EXTERNAL_OUTPUT</span> --off
</span><span class='line'><span class="k">fi</span>
</span></code></pre></td></tr></table></div></figure>


<p>Place this in <code>/etc/X11/Xsession.d</code> as <code>45custom_xrandr-settings</code> and it will automatically run.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Spring PropertyPlaceholderConfigurer beans]]></title>
    <link href="http://bealetech.com/blog/2008/05/04/spring-propertyplaceholderconfigurer-beans/"/>
    <updated>2008-05-04T23:00:00-07:00</updated>
    <id>http://bealetech.com/blog/2008/05/04/spring-propertyplaceholderconfigurer-beans</id>
    <content type="html"><![CDATA[<p>So I found a scenario today where we had two different <code>PropertyPlaceHolderConfigurer</code> beans declared in two separate XML files. Unfortunately, the second property file wasn’t getting loaded, so we would get errors about Spring being unable to resolve particular properties.</p>

<p>I found this great post summarizing the solution:</p>

<p><a href="http://dotal.wordpress.com/2007/09/14/mulitple-propertyplaceholderconfigurer-configurations/">http://dotal.wordpress.com/2007/09/14/mulitple-propertyplaceholderconfigurer-configurations/</a></p>

<p>Basically, you have to update the definition for the first <code>PropertyPlaceHolderConfigurer</code> bean that gets loaded and add the <code>ignoreUnresolvablePlaceholders</code> property:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='xml'><span class='line'><span class="nt">&lt;bean</span> <span class="na">id=</span><span class="s">&quot;mailProps&quot;</span> <span class="na">class=</span><span class="s">&quot;org.springframework.beans.factory.config.PropertyPlaceholderConfigurer&quot;</span><span class="nt">&gt;</span>
</span><span class='line'>         <span class="nt">&lt;property</span> <span class="na">name=</span><span class="s">&quot;location&quot;</span> <span class="na">value=</span><span class="s">&quot;classpath:mail.properties&quot;</span><span class="nt">/&gt;</span>
</span><span class='line'>         <span class="nt">&lt;property</span> <span class="na">name=</span><span class="s">&quot;ignoreUnresolvablePlaceholders&quot;</span> <span class="na">value=</span><span class="s">&quot;true&quot;</span><span class="nt">/&gt;</span>
</span><span class='line'><span class="nt">&lt;/bean&gt;</span> 
</span></code></pre></td></tr></table></div></figure>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[DRY Associations in Rails]]></title>
    <link href="http://bealetech.com/blog/2007/08/19/dry-associations-in-rails/"/>
    <updated>2007-08-19T23:00:00-07:00</updated>
    <id>http://bealetech.com/blog/2007/08/19/dry-associations-in-rails</id>
    <content type="html"><![CDATA[<p>I found a nice little article from a few months ago on <a href="http://therailsway.com/">The Rails Way</a>. Written by koz, <a href="http://therailsway.com/2007/3/26/association-proxies-are-your-friend">Assocation Proxies</a> talks about some Best Practices for using assocations within Rails. I really felt the suggestions hit the proverbial nail on the head in terms of following the DRY principles. The first suggestion was on the best way to restrict access to user specific information. It&#8217;s incredibly useful to take advantage your RESTful patterns and make a single call like:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="vi">@todo_list</span> <span class="o">=</span> <span class="n">current_user</span><span class="o">.</span><span class="n">todo_lists</span><span class="o">.</span><span class="n">find</span><span class="p">(</span><span class="n">params</span><span class="o">[</span><span class="ss">:id</span><span class="o">]</span><span class="p">)</span>
</span></code></pre></td></tr></table></div></figure>


<p>Of course, I also loved the final suggestion in Case Three: using a has_many with a condition on it:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">has_many</span> <span class="ss">:completed_lists</span><span class="p">,</span> <span class="ss">:class_name</span> <span class="o">=&gt;</span> <span class="s2">&quot;TodoList&quot;</span><span class="p">,</span> <span class="ss">:conditions</span> <span class="o">=&gt;</span> <span class="p">{</span> <span class="ss">:completed</span> <span class="o">=&gt;</span> <span class="kp">true</span> <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>Excellent!</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Struts Redirect w/Parameters Part 2]]></title>
    <link href="http://bealetech.com/blog/2006/06/04/struts-redirect-w-slash-parameters-part-2/"/>
    <updated>2006-06-04T23:00:00-07:00</updated>
    <id>http://bealetech.com/blog/2006/06/04/struts-redirect-w-slash-parameters-part-2</id>
    <content type="html"><![CDATA[<p>In an <a href="http://bealetech.com/blog/2006/01/23/struts-redirect-w-slash-parameters/">earlier post</a>, I described a class to handle redirects in Struts and passing parameters along. That technique is not necessary; as of Struts 1.2.7, you can use the <code>ActionRedirect</code> class instead.</p>

<p>Here&#8217;s a basic example from inside the execute method in an Action.</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='java'><span class='line'><span class="n">ActionRedirect</span> <span class="n">redirect</span> <span class="o">=</span> <span class="k">new</span> <span class="n">ActionRedirect</span><span class="o">(</span><span class="n">mapping</span><span class="o">.</span><span class="na">findForward</span><span class="o">(</span><span class="s">&quot;success&quot;</span><span class="o">));</span>
</span><span class='line'><span class="n">redirect</span><span class="o">.</span><span class="na">addParameter</span><span class="o">(</span><span class="s">&quot;myparam&quot;</span><span class="o">,</span><span class="s">&quot;myvalue&quot;</span><span class="o">);</span>
</span><span class='line'><span class="n">redirect</span><span class="o">.</span><span class="na">addParameter</span><span class="o">(</span><span class="s">&quot;something&quot;</span><span class="o">,</span><span class="s">&quot;fornothing&quot;</span><span class="o">);</span>
</span><span class='line'><span class="n">redirect</span><span class="o">.</span><span class="na">addParameter</span><span class="o">(</span><span class="s">&quot;answer&quot;</span><span class="o">,</span><span class="s">&quot;42&quot;</span><span class="o">);</span>
</span><span class='line'><span class="k">return</span> <span class="n">redirect</span><span class="o">;</span>
</span></code></pre></td></tr></table></div></figure>


<p>The <code>ActionRedirect</code> class is basically the same as my ForwardParameter class and is probably preferable.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Exception Handling Framework for J2EE Applications]]></title>
    <link href="http://bealetech.com/blog/2006/05/24/exception-handling-framework-for-j2ee-applications/"/>
    <updated>2006-05-24T23:00:00-07:00</updated>
    <id>http://bealetech.com/blog/2006/05/24/exception-handling-framework-for-j2ee-applications</id>
    <content type="html"><![CDATA[<p>OnJava has an interesting <a href="http://www.onjava.com/pub/a/onjava/2006/01/11/exception-handling-framework-for-j2ee.html">article</a> on generic approach to handling exceptions within a J2EE framework. The basic idea involves creating a generic base class for exceptions and a basic handler for all requests that includes dispatcher to pass the request along to the appropriate method.The fundamental idea is fairly sound and the idea of including a context to allow reuse of generic exceptions seems like a strong idea.</p>

<p>My concern is that in a large project, the use of a &#8220;context&#8221; may make it difficult to figure out which specific message code is used in a given place. The generic exception handling is especially beneficial for the &#8220;this should never happen&#8221; cases where there isn&#8217;t much the app can do about the exception, but should still handle it in a robust manner.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Struts Redirect w/Parameters]]></title>
    <link href="http://bealetech.com/blog/2006/01/23/struts-redirect-w-slash-parameters/"/>
    <updated>2006-01-23T23:00:00-08:00</updated>
    <id>http://bealetech.com/blog/2006/01/23/struts-redirect-w-slash-parameters</id>
    <content type="html"><![CDATA[<p>If you have a Struts Action servlet and you want to redirect to another page, the standard Struts technique is to return an ActionForward and setup an appropriate forward entry in <code>struts-config.xml</code>:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='java'><span class='line'><span class="k">return</span> <span class="n">mapping</span><span class="o">.</span><span class="na">findForward</span><span class="o">(</span><span class="s">&quot;success&quot;</span><span class="o">);</span>
</span></code></pre></td></tr></table></div></figure>


<p>Unfortunately, this doesn’t provide a mechanism for passing request parameters to the target. So what can you do if you want to redirect to another page and pass some parameters along? You use an additional class:</p>

<figure class='code'><figcaption><span>ForwardParameters.java </span></figcaption>
 <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
<span class='line-number'>38</span>
<span class='line-number'>39</span>
<span class='line-number'>40</span>
<span class='line-number'>41</span>
<span class='line-number'>42</span>
<span class='line-number'>43</span>
<span class='line-number'>44</span>
<span class='line-number'>45</span>
<span class='line-number'>46</span>
<span class='line-number'>47</span>
<span class='line-number'>48</span>
<span class='line-number'>49</span>
<span class='line-number'>50</span>
<span class='line-number'>51</span>
<span class='line-number'>52</span>
<span class='line-number'>53</span>
<span class='line-number'>54</span>
<span class='line-number'>55</span>
<span class='line-number'>56</span>
<span class='line-number'>57</span>
<span class='line-number'>58</span>
<span class='line-number'>59</span>
<span class='line-number'>60</span>
<span class='line-number'>61</span>
<span class='line-number'>62</span>
<span class='line-number'>63</span>
<span class='line-number'>64</span>
<span class='line-number'>65</span>
<span class='line-number'>66</span>
<span class='line-number'>67</span>
<span class='line-number'>68</span>
<span class='line-number'>69</span>
<span class='line-number'>70</span>
<span class='line-number'>71</span>
</pre></td><td class='code'><pre><code class='java'><span class='line'><span class="kd">public</span> <span class="kd">class</span> <span class="nc">ForwardParameters</span>
</span><span class='line'><span class="o">{</span>
</span><span class='line'>  <span class="kd">private</span> <span class="n">Map</span> <span class="n">params</span> <span class="o">=</span> <span class="kc">null</span><span class="o">;</span>
</span><span class='line'>
</span><span class='line'>  <span class="kd">public</span> <span class="nf">ForwardParameters</span><span class="o">()</span>
</span><span class='line'>  <span class="o">{</span>
</span><span class='line'>    <span class="n">params</span> <span class="o">=</span> <span class="k">new</span> <span class="n">HashMap</span><span class="o">();</span>
</span><span class='line'>  <span class="o">}</span>
</span><span class='line'>
</span><span class='line'>  <span class="cm">/**</span>
</span><span class='line'><span class="cm">   * Add a single parameter and value.</span>
</span><span class='line'><span class="cm">   *</span>
</span><span class='line'><span class="cm">   * @param paramName     Parameter name</span>
</span><span class='line'><span class="cm">   * @param paramValue    Parameter value</span>
</span><span class='line'><span class="cm">   *</span>
</span><span class='line'><span class="cm">   * @return A reference to this object.</span>
</span><span class='line'><span class="cm">   */</span>
</span><span class='line'>  <span class="kd">public</span> <span class="n">ForwardParameters</span> <span class="nf">add</span><span class="o">(</span><span class="n">String</span> <span class="n">paramName</span><span class="o">,</span> <span class="n">String</span> <span class="n">paramValue</span><span class="o">)</span>
</span><span class='line'>  <span class="o">{</span>
</span><span class='line'>    <span class="n">params</span><span class="o">.</span><span class="na">put</span><span class="o">(</span><span class="n">paramName</span><span class="o">,</span><span class="n">paramValue</span><span class="o">);</span>
</span><span class='line'>    <span class="k">return</span> <span class="k">this</span><span class="o">;</span>
</span><span class='line'>  <span class="o">}</span>
</span><span class='line'>
</span><span class='line'>  <span class="cm">/**</span>
</span><span class='line'><span class="cm">   * Add a set of parameters and values.</span>
</span><span class='line'><span class="cm">   *</span>
</span><span class='line'><span class="cm">   * @param paramMap  Map containing parameter names and values.</span>
</span><span class='line'><span class="cm">   *</span>
</span><span class='line'><span class="cm">   * @return A reference to this object.</span>
</span><span class='line'><span class="cm">   */</span>
</span><span class='line'>  <span class="kd">public</span> <span class="n">ForwardParameters</span> <span class="nf">add</span><span class="o">(</span><span class="n">Map</span> <span class="n">paramMap</span><span class="o">)</span>
</span><span class='line'>  <span class="o">{</span>
</span><span class='line'>    <span class="n">Iterator</span> <span class="n">itr</span> <span class="o">=</span> <span class="n">paramMap</span><span class="o">.</span><span class="na">keySet</span><span class="o">().</span><span class="na">iterator</span><span class="o">();</span>
</span><span class='line'>    <span class="k">while</span> <span class="o">(</span><span class="n">itr</span><span class="o">.</span><span class="na">hasNext</span><span class="o">())</span>
</span><span class='line'>    <span class="o">{</span>
</span><span class='line'>      <span class="n">String</span> <span class="n">paramName</span> <span class="o">=</span> <span class="o">(</span><span class="n">String</span><span class="o">)</span> <span class="n">itr</span><span class="o">.</span><span class="na">next</span><span class="o">();</span>
</span><span class='line'>      <span class="n">params</span><span class="o">.</span><span class="na">put</span><span class="o">(</span><span class="n">paramName</span><span class="o">,</span> <span class="n">paramMap</span><span class="o">.</span><span class="na">get</span><span class="o">(</span><span class="n">paramName</span><span class="o">));</span>
</span><span class='line'>    <span class="o">}</span>
</span><span class='line'>
</span><span class='line'>    <span class="k">return</span> <span class="k">this</span><span class="o">;</span>
</span><span class='line'>  <span class="o">}</span>
</span><span class='line'>
</span><span class='line'>  <span class="cm">/**</span>
</span><span class='line'><span class="cm">   * Add parameters to a provided ActionForward.</span>
</span><span class='line'><span class="cm">   *</span>
</span><span class='line'><span class="cm">   * @param forward    The ActionForward object to add parameters to.</span>
</span><span class='line'><span class="cm">   *</span>
</span><span class='line'><span class="cm">   * @return ActionForward with parameters added to the URL.</span>
</span><span class='line'><span class="cm">   */</span>
</span><span class='line'>  <span class="kd">public</span> <span class="n">ActionForward</span> <span class="nf">forward</span><span class="o">(</span><span class="n">ActionForward</span> <span class="n">forward</span><span class="o">)</span>
</span><span class='line'>  <span class="o">{</span>
</span><span class='line'>    <span class="n">StringBuffer</span> <span class="n">path</span> <span class="o">=</span> <span class="k">new</span> <span class="n">StringBuffer</span><span class="o">(</span><span class="n">forward</span><span class="o">.</span><span class="na">getPath</span><span class="o">());</span>
</span><span class='line'>
</span><span class='line'>    <span class="n">Iterator</span> <span class="n">itr</span> <span class="o">=</span> <span class="n">params</span><span class="o">.</span><span class="na">entrySet</span><span class="o">().</span><span class="na">iterator</span><span class="o">();</span>
</span><span class='line'>    <span class="k">if</span> <span class="o">(</span><span class="n">itr</span><span class="o">.</span><span class="na">hasNext</span><span class="o">())</span>
</span><span class='line'>    <span class="o">{</span>
</span><span class='line'>      <span class="c1">//add first parameter, if avaliable</span>
</span><span class='line'>      <span class="n">Map</span><span class="o">.</span><span class="na">Entry</span> <span class="n">entry</span> <span class="o">=</span> <span class="o">(</span><span class="n">Map</span><span class="o">.</span><span class="na">Entry</span><span class="o">)</span> <span class="n">itr</span><span class="o">.</span><span class="na">next</span><span class="o">();</span>
</span><span class='line'>      <span class="n">path</span><span class="o">.</span><span class="na">append</span><span class="o">(</span><span class="s">&quot;?&quot;</span> <span class="o">+</span> <span class="n">entry</span><span class="o">.</span><span class="na">getKey</span><span class="o">()</span> <span class="o">+</span> <span class="s">&quot;=&quot;</span> <span class="o">+</span> <span class="n">entry</span><span class="o">.</span><span class="na">getValue</span><span class="o">());</span>
</span><span class='line'>
</span><span class='line'>      <span class="c1">//add other parameters</span>
</span><span class='line'>      <span class="k">while</span> <span class="o">(</span><span class="n">itr</span><span class="o">.</span><span class="na">hasNext</span><span class="o">())</span>
</span><span class='line'>      <span class="o">{</span>
</span><span class='line'>        <span class="n">entry</span> <span class="o">=</span> <span class="o">(</span><span class="n">Map</span><span class="o">.</span><span class="na">Entry</span><span class="o">)</span> <span class="n">itr</span><span class="o">.</span><span class="na">next</span><span class="o">();</span>
</span><span class='line'>        <span class="n">path</span><span class="o">.</span><span class="na">append</span><span class="o">(</span><span class="s">&quot;&amp;amp;&quot;</span> <span class="o">+</span> <span class="n">entry</span><span class="o">.</span><span class="na">getKey</span><span class="o">()</span> <span class="o">+</span> <span class="s">&quot;=&quot;</span> <span class="o">+</span> <span class="n">entry</span><span class="o">.</span><span class="na">getValue</span><span class="o">());</span>
</span><span class='line'>      <span class="o">}</span>
</span><span class='line'>    <span class="o">}</span>
</span><span class='line'>
</span><span class='line'>    <span class="k">return</span> <span class="k">new</span> <span class="nf">ActionForward</span><span class="o">(</span><span class="n">path</span><span class="o">.</span><span class="na">toString</span><span class="o">());</span>
</span><span class='line'>  <span class="o">}</span>
</span><span class='line'><span class="o">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>Here are some examples of using ForwardParameters:</p>

<p>Long form:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='java'><span class='line'><span class="n">ActionForward</span> <span class="n">forward</span> <span class="o">=</span> <span class="n">mapping</span><span class="o">.</span><span class="na">findForward</span><span class="o">(</span><span class="s">&quot;success&quot;</span><span class="o">);</span>
</span><span class='line'><span class="n">ForwardParameters</span> <span class="n">fwdParams</span> <span class="o">=</span> <span class="k">new</span> <span class="n">ForwardParameters</span><span class="o">();</span>
</span><span class='line'><span class="n">fwdParams</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="s">&quot;myparam&quot;</span><span class="o">,</span> <span class="s">&quot;myvalue&quot;</span><span class="o">);</span>
</span><span class='line'><span class="n">fwdParams</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="s">&quot;something&quot;</span><span class="o">,</span> <span class="s">&quot;fornothing&quot;</span><span class="o">);</span>
</span><span class='line'><span class="k">return</span> <span class="n">fwdParams</span><span class="o">.</span><span class="na">forward</span><span class="o">(</span><span class="n">forward</span><span class="o">);</span>
</span></code></pre></td></tr></table></div></figure>


<p>Concise form:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='java'><span class='line'><span class="n">ActionForward</span> <span class="n">forward</span> <span class="o">=</span> <span class="n">mapping</span><span class="o">.</span><span class="na">findForward</span><span class="o">(</span><span class="s">&quot;success&quot;</span><span class="o">);</span>
</span><span class='line'><span class="k">return</span> <span class="k">new</span> <span class="nf">ForwardParameters</span><span class="o">().</span><span class="na">add</span><span class="o">(</span><span class="s">&quot;myparam&quot;</span><span class="o">,</span> <span class="s">&quot;myvalue&quot;</span><span class="o">).</span><span class="na">add</span><span class="o">(</span><span class="s">&quot;something&quot;</span><span class="o">,</span> <span class="s">&quot;fornothing&quot;</span><span class="o">).</span><span class="na">forward</span><span class="o">(</span><span class="n">forward</span><span class="o">);</span>
</span></code></pre></td></tr></table></div></figure>


<p>Ultra concise form:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='java'><span class='line'><span class="k">return</span> <span class="k">new</span> <span class="nf">ForwardParameters</span><span class="o">().</span><span class="na">add</span><span class="o">(</span><span class="s">&quot;myparam&quot;</span><span class="o">,</span> <span class="s">&quot;myvalue&quot;</span><span class="o">).</span><span class="na">add</span><span class="o">(</span><span class="s">&quot;something&quot;</span><span class="o">,</span> <span class="s">&quot;fornothing&quot;</span><span class="o">).</span><span class="na">forward</span><span class="o">(</span><span class="n">mapping</span><span class="o">.</span><span class="na">findForward</span><span class="o">(</span><span class="s">&quot;success&quot;</span><span class="o">));</span>
</span></code></pre></td></tr></table></div></figure>


<p>This is based on a suggestion I found on <a href="http://www.experts-exchange.com/">Experts-Exchange</a> by <a href="http://www.experts-exchange.com/Programming/Programming_Languages/Java/Q_20830927.html">dualsoul</a>.</p>

<hr />

<p>Edit June 5th, 2006:</p>

<p>As someone just pointed out to me this morning, you can use the <code>ActionRedirect</code> class instead of my <code>ForwardParameters</code> class. According to the JavaDocs, <code>ActionRedirect</code> was added in Struts 1.2.7 and is:</p>

<blockquote><p>&#8230; a subclass of ActionForward which is designed for use in redirecting requests, with support for adding parameters at runtime.</p><footer><strong>JavaDocs</strong></footer></blockquote>



]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Prefactoring]]></title>
    <link href="http://bealetech.com/blog/2005/12/27/prefactoring/"/>
    <updated>2005-12-27T23:00:00-08:00</updated>
    <id>http://bealetech.com/blog/2005/12/27/prefactoring</id>
    <content type="html"><![CDATA[<p>Prefactoring is the process of using your experience to write better code.  Specifically, writing code that can be refactored more easily, that is easier to read and easier to maintain.</p>

<p>The article is available on <a href="http://www.oreillynet.com/">oreillynet.com</a>:</p>

<p><a href="http://www.oreillynet.com/pub/a/network/2005/11/15/what-is-prefactoring.html">What Is Prefactoring?</a> by Ken Pugh, author of <a href="http://www.oreilly.com/catalog/prefactoring/">Prefactoring</a>.</p>
]]></content>
  </entry>
  
</feed>
