<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>Letor</title>
    <link>http://www.letor.ca/</link>
    <description>Software consulting and more.</description>
    <language>en-us</language>
    <item>
      <title>Single line Java Logging API download</title>
      <description>&lt;h1&gt;Single line Java Logging API is now available for download&lt;/h1&gt;
&lt;p&gt;You can &lt;a href="../../download/letor.jar"&gt;download&lt;/a&gt; the latest jar for use in your project.&lt;/p&gt;
&lt;p&gt;New version allows you to specify custom time format and filter out repetitive package names&lt;/p&gt;</description>
      <author>Letor</author>
      <pubDate>Tue, 16 Jun 2009 14:58:00 -0400</pubDate>
      <link>http://www.letor.ca/post/single-line-java-logging-api-download</link>
      <guid>http://www.letor.ca/post/single-line-java-logging-api-download</guid>
    </item>
    <item>
      <title>Single line Java Logging</title>
      <description>&lt;p&gt;Before Java Logging API became part of the JDK (1.4) the de facto standard was  the Log4J logging library. It was customizable, easy to setup and configure.&lt;/p&gt;
&lt;p&gt;Along came Java 1.4 and the new &lt;a href="http://java.sun.com/j2se/1.4.2/docs/guide/util/logging/"&gt;Java Logging API&lt;/a&gt;.  Somewhat clumsy and much harder to configure or customize, it has not changed  over the course of the subsequent releases.&lt;/p&gt;
&lt;p&gt;One of the most annoying things about it was that out of the box  it would write out the log message on two lines:&lt;/p&gt;
&lt;pre class="output"&gt;Jun 11, 2009 9:11:21 PM com.letor.example.logging.StandardTest 
INFO: Line 1
Jun 11, 2009 9:11:21 PM com.letor.example.logging.StandardTest 
INFO: Line 2
Jun 11, 2009 9:11:21 PM com.letor.example.logging.StandardTest 
INFO: Line 3
&lt;/pre&gt;
&lt;p&gt;Now, I don't know about you, but I find this very hard on my eyes. It is much harder to get a feel for how many messages were printed,  what is the difference between them and is significantly harder  to spot what you are looking for.&lt;/p&gt;
&lt;p&gt;To rectify this, we can use the following simple, single-line formatter.&lt;/p&gt;
&lt;p&gt;You will need to create two files - a configuration file:&lt;/p&gt;
&lt;div class="comment"&gt;logging.properties&lt;/div&gt;
&lt;pre class="file"&gt;# log everything to the console
handlers = java.util.logging.ConsoleHandler

# set the default logging level for the root logger
.level = FINE
    
# set the default logging level for new ConsoleHandler instances
java.util.logging.ConsoleHandler.level = ALL
java.util.logging.ConsoleHandler.formatter = com.letor.util.SingleLineFormatter
    
# set the default logging level for the logger named com.mycompany
com.letor.level = INFO
&lt;/pre&gt;
&lt;p&gt;And the Formatter class used for formatting the log record&lt;/p&gt;
&lt;div class="comment"&gt;SingleLineFormatter.java&lt;/div&gt;
&lt;pre class="file"&gt;package com.letor.util;

import java.text.SimpleDateFormat;
import java.util.logging.Formatter;
import java.util.logging.LogRecord;

public class SingleLineFormatter extends Formatter
{
    private static SimpleDateFormat FRMT_DATE;
    
    public SingleLineFormatter()
    {
        // check if the date format was specified
        // by default this is used for quick and dirty runs, don't care about the year date
        String dateFormat = System.getProperty("java.util.logging.dateFormat", "HH:mm:ss"); 
        FRMT_DATE = new SimpleDateFormat(dateFormat);
    }
    
    public String format(LogRecord record)
    {
        // use the buffer for optimal string construction
        StringBuffer sb = new StringBuffer();

        // level
        sb.append(record.getLevel().toString().toLowerCase());
        sb.append(": ");

        // format time
        sb.append(FRMT_DATE.format(record.getMillis())).append(" ");

        // thread
        sb.append("[").append(Thread.currentThread().getName()).append("] ");

        // package/class name, logging name
        String name = record.getLoggerName();
        if (name.startsWith("com.letor.")) // truncate the logging name, reduce the clutter
            name = name.substring("com.letor.".length());

        sb.append(name);
        sb.append("   ");
        sb.append(record.getMessage());
        
        // if there was an exception thrown, log it as well
        if (record.getThrown() != null)
        {
            sb.append("\n").append(printThrown(record.getThrown()));
        }

        sb.append("\n");

        return sb.toString();
    }
    
    private String printThrown(Throwable thrown)
    {
        StringBuffer sb = new StringBuffer();
        
        sb.append("").append(thrown.getClass().getName());
        sb.append(" - ").append(thrown.getMessage());
        sb.append("\n");

        for (StackTraceElement trace : thrown.getStackTrace())
            sb.append("\tat ").append(trace).append("\n");

        Throwable cause = thrown.getCause();
        if (cause != null)
            sb.append("\n").append(printThrown(cause));
        
        return sb.toString();
    }
}
&lt;/pre&gt;
&lt;p&gt;You will need to pass the configuration file location as a VM argument to your application.&lt;/p&gt;
&lt;pre class="output"&gt;java -Djava.util.logging.config.file=src/logging.properties your.package.YourApplication
&lt;/pre&gt;
&lt;p&gt;Running this will result in the following output&lt;/p&gt;
&lt;pre class="output"&gt;info: 21:25:00 [main] example.logging.StandardTest   Line 1
info: 21:25:00 [main] example.logging.StandardTest   Line 2
info: 21:25:00 [main] example.logging.StandardTest   Line 3
&lt;/pre&gt;
&lt;p&gt;Now that's much nicer! Feel free to modify the Java file to your preferred format.&lt;/p&gt;
&lt;p&gt;The &lt;strong&gt;SingleLineFormatter&lt;/strong&gt; is also capable of logging thrown exceptions and nested exceptions.  Here is an example output:&lt;/p&gt;
&lt;pre class="output"&gt;info: 11 Jun 21:29:03 [main] example.logging.Test   Nice, clean single line output
severe: 11 Jun 21:29:03 [main] example.logging.Test   Divided by zero
java.lang.ArithmeticException - / by zero
	at com.letor.example.logging.Test.(Test.java:21)
	at com.letor.example.logging.Test.main(Test.java:37)

severe: 11 Jun 21:29:03 [main] example.logging.Test   Nested operation threw an exception
java.lang.RuntimeException - Parent exception
	at com.letor.example.logging.Test.(Test.java:26)
	at com.letor.example.logging.Test.main(Test.java:37)

java.lang.ArithmeticException - / by zero
	at com.letor.example.logging.Test.(Test.java:21)
	at com.letor.example.logging.Test.main(Test.java:37)
&lt;/pre&gt;
&lt;p&gt;Hopefully this will your Java Logging experience.&lt;/p&gt;</description>
      <author>Letor</author>
      <pubDate>Thu, 11 Jun 2009 21:30:00 -0400</pubDate>
      <link>http://www.letor.ca/post/single-line-java-logging</link>
      <guid>http://www.letor.ca/post/single-line-java-logging</guid>
    </item>
    <item>
      <title>Calculating the Fair Price of a Bond Online</title>
      <description>&lt;p&gt;First in a series of articles on the fixed-income calculations.&lt;/p&gt;
&lt;p&gt;Learn how to calculate the present value of a fixed-income instrument, such as a bond.&lt;/p&gt;
&lt;p&gt;We will start by calculating the present value of bond's income stream. The present value of a bond's income stream is the sum of the present values of each coupon payment.&lt;/p&gt;
&lt;p&gt;&lt;a href="../../../finance/fixed_income_present_value"&gt;Use an online calculator&lt;/a&gt; to plug in your numbers.&lt;/p&gt;</description>
      <author>Letor</author>
      <pubDate>Mon, 29 Dec 2008 21:39:00 -0500</pubDate>
      <link>http://www.letor.ca/post/fixed-income-present-value-income-stream</link>
      <guid>http://www.letor.ca/post/fixed-income-present-value-income-stream</guid>
    </item>
    <item>
      <title>Rails and Google Mail</title>
      <description>&lt;p&gt;
Configuring Ruby on Rails to use Gmail's SMTP server to send outbound email from your website can be tricky.
&lt;/p&gt;

&lt;p&gt;
Connecting on port 25 does not work, we'll have to use port 587 and TLS (a version of SSL).
To enable TLS in Rails we have to install &lt;strong&gt;action_mailer_tls&lt;/strong&gt; plugin.
&lt;/p&gt;

&lt;pre class="code"&gt;
script/plugin install http://code.openrain.com/rails/action_mailer_tls/
&lt;/pre&gt;

&lt;div class="output"&gt;&amp;darr; output &amp;darr;&lt;/div&gt;

&lt;pre class="output"&gt;
+ ./README
+ ./init.rb
+ ./lib/smtp_tls.rb
+ ./sample/mailer.yml.sample
+ ./sample/smtp_gmail.rb
&lt;/pre&gt;

&lt;p&gt;
Copy files &lt;span class="file"&gt;mailer.yml.sample&lt;/span&gt; and &lt;span class="file"&gt;smtp_gmail.rb&lt;/span&gt; into 
&lt;span class="file"&gt;config/initializers&lt;/span&gt; directory.
&lt;/p&gt;

&lt;p&gt;Rename file &lt;span class="file"&gt;mailer.yml.sample&lt;/span&gt; into &lt;span class="file"&gt;mailer.yml&lt;/span&gt;. 
Update file with your credentials. Notice that we are using port &lt;strong&gt;587&lt;/strong&gt; and &lt;strong&gt;plain&lt;/strong&gt; authentication.

&lt;/p&gt;

&lt;div class="comment"&gt;mailer.yml&lt;/div&gt;
&lt;pre class="file"&gt;
--- 
  :address: smtp.gmail.com
  :port: 587
  :user_name: email@dress.com
  :password: h@ckme
  :authentication: :plain
&lt;/pre&gt;

&lt;p&gt;The newly copied &lt;span class="file"&gt;smtp_gmail.rb&lt;/span&gt; will be executed when server starts and 
will load &lt;span class="file"&gt;mail.yml&lt;/span&gt; to setup ActionMailer.&lt;/p&gt;

&lt;div class="comment"&gt;smtp_gmail.rb&lt;/div&gt;
&lt;pre class="file"&gt;
require "smtp_tls"

mailer_config = File.open("#{RAILS_ROOT}/config/mailer.yml") 
mailer_options = YAML.load(mailer_config) 
ActionMailer::Base.smtp_settings = mailer_options 
&lt;/pre&gt;

&lt;p&gt;Another thing to keep in mind, is that there's a limit of 500 messages per day&lt;/p&gt;</description>
      <author>Letor</author>
      <pubDate>Fri, 19 Dec 2008 21:48:00 -0500</pubDate>
      <link>http://www.letor.ca/post/rails-and-google-mail</link>
      <guid>http://www.letor.ca/post/rails-and-google-mail</guid>
    </item>
    <item>
      <title>Case study: toronto.com</title>
      <description>&lt;p&gt;Trying to look up a restaurant at &lt;a href="http://www.toronto.com"&gt;toronto.com&lt;/a&gt; website  we were surprised with a particular way the phone number is displayed for a business listing.&lt;/p&gt;
&lt;p&gt;We've successfully found the listing we searched for.  Having clicked on the business name we are presented with important information about the business: restaurant's name, address (with a convenient map link) and categorization tags.&lt;/p&gt;
&lt;p&gt;However, the most important information about the restaurant - their phone number,  is located off to the side as a link that says &lt;strong&gt;"Phone"&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src="../../../images/posts/szechuan1.jpg" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;Clicking on the link "Phone" will then change its name to an actual phone number.  For some strange reason, this number is still shown as a link, but clicking it does nothing.&lt;/p&gt;
&lt;p&gt;&lt;img src="../../../images/posts/szechuan2.jpg" alt="" /&gt;&lt;/p&gt;
&lt;h2&gt;What went wrong?&lt;/h2&gt;
&lt;p&gt;This is clearly is a case when adding some designer bells and whistles to the website has severed the functionality and has impacted the end-user experience.&lt;/p&gt;
&lt;p&gt;The word "Phone" is shown as a link and blends with all other links that are very unlikely to be clicked on by the user.  This results in user "not seeing" the word phone and not even realizing that it is present on the page.&lt;/p&gt;
&lt;p&gt;Once the user has scanned the whole page, the word "Phone" could be found. But now we expect that the user will realize that  the "Phone" is clickable and that clicking it will result in displaying of the number.  That's a lot to expect - a more tech savvy user will probably connect the dots, but there will be a number of users that will  not be as lucky.&lt;/p&gt;
&lt;h2&gt;Suggestion&lt;/h2&gt;
&lt;p&gt;This interface could be dramatically improved simply by displaying the phone number as text right from the start.  No link is necessary.&lt;/p&gt;
&lt;p&gt;This example can still be &lt;a href="http://www.toronto.com/restaurants/listing/213176"&gt;found&lt;/a&gt; on the website&lt;/p&gt;</description>
      <author>Letor</author>
      <pubDate>Wed, 15 Oct 2008 10:23:00 -0400</pubDate>
      <link>http://www.letor.ca/post/case-study-toronto-com</link>
      <guid>http://www.letor.ca/post/case-study-toronto-com</guid>
    </item>
    <item>
      <title>Cleaning up left over Subversion files</title>
      <description>&lt;p&gt;When working with directories that have been checked in to Subversion one may wish to get rid of  all left-over subversion information (metadata). If you are using Unix/Linux/Mac OS X, you are in luck.&lt;/p&gt;
&lt;p&gt;This can be especially useful when copying directory that is already under Subversion to a new place.&lt;/p&gt;
&lt;p&gt;Subversion metadata is stored in &lt;span class="file"&gt;.svn&lt;/span&gt; directory recursively in the project structure. Our task is to remove all of it.&lt;/p&gt;
&lt;p&gt;Let's start with finding out all of the metadata present. In the root directory of your project run this:&lt;/p&gt;
&lt;pre class="code"&gt;find . -type d -name .svn
&lt;/pre&gt;
&lt;div class="output"&gt;&amp;darr; output &amp;darr;&lt;/div&gt;
&lt;pre class="output"&gt;./tmp/.svn
./tmp/cache/.svn
./tmp/sockets/.svn
./tmp/sessions/.svn
./tmp/pids/.svn
./public/images/.svn
./public/images/work/.svn
./public/stylesheets/.svn
./public/.svn
&lt;/pre&gt;
&lt;p&gt;Now we can safely run the following command to remove all these &lt;span class="file"&gt;.svn&lt;/span&gt; directories. We suggest that you copy this command or be extremely careful when typing it, as it can be quite powerful and if typed incorrectly could damage your system.&lt;/p&gt;
&lt;pre class="code"&gt;rm -rf `find . -type d -name .svn`
&lt;/pre&gt;
&lt;p&gt;That's it, we are done.&lt;/p&gt;</description>
      <author>Letor</author>
      <pubDate>Wed, 16 Jul 2008 15:53:00 -0400</pubDate>
      <link>http://www.letor.ca/post/subversion-cleanup</link>
      <guid>http://www.letor.ca/post/subversion-cleanup</guid>
    </item>
    <item>
      <title>Setting Ruby on Rails Time Zone</title>
      <description>&lt;p&gt;By default Ruby on Rails is configured for UTC time zone.  For people living in the other 23 time zones this may be not very convenient.&lt;/p&gt;
&lt;p&gt;In Rails 2.1 time zone support is turned on by default in &lt;strong&gt;environment.rb&lt;/strong&gt;:&lt;/p&gt;
&lt;div class="comment"&gt;config/environment.rb&lt;/div&gt;
&lt;pre class="file"&gt;config.time_zone = 'UTC'
&lt;/pre&gt;
&lt;p&gt;To change this to the appropriate time zone you'll need to display a list of all available timezones. The first thing to try is to display the list of all local timezones - Rails will use your system local time to determine these.&lt;/p&gt;
&lt;pre class="code"&gt;$ rake time:zones:local
&lt;/pre&gt;
&lt;div class="output"&gt;&amp;darr; output &amp;darr;&lt;/div&gt;
&lt;pre class="output"&gt;* UTC +00:00 *
Casablanca
Dublin
Edinburgh
Lisbon
London
Monrovia
UTC
&lt;/pre&gt;
&lt;p&gt;Notice, that we see a list of cities local to UTC time zone, we'll get to this shortly&lt;/p&gt;
&lt;p&gt;If you require a larger scope, you can use &lt;strong&gt;time:zones:us&lt;/strong&gt; (US time zones) or &lt;strong&gt;time:zones:all&lt;/strong&gt; (All available timezones).&lt;/p&gt;
&lt;p&gt;Now that we know what locale to use we can update &lt;strong&gt;environment.rb&lt;/strong&gt; file.&lt;/p&gt;
&lt;div class="comment"&gt;config/environment.rb&lt;/div&gt;
&lt;pre class="file"&gt;config.time_zone = 'Eastern Time (US &amp;amp; Canada)'
&lt;/pre&gt;
&lt;p&gt;After all of these steps you may still find out that your &lt;strong&gt;production.log&lt;/strong&gt; is displaying wrong time. The culprit in this case is your system local time. If you are running Linux you can change this with ease, this example is done for Canadian locale, Toronto. You may wish to backup your current &lt;strong&gt;/etc/localtime&lt;/strong&gt; file since we'll be changing it to point to another file.&lt;/p&gt;
&lt;pre class="code"&gt;$sudo ln -sf /usr/share/zoneinfo/America/Toronto /etc/localtime
&lt;/pre&gt;
&lt;p&gt;We've just set up a link for &lt;strong&gt;/etc/localtime&lt;/strong&gt; file to an appropriate time zone &lt;strong&gt;/usr/share/zoneinfo/America/Toronto&lt;/strong&gt;. After all manipulations your Rails application should be fully aware of your time zone.&lt;/p&gt;</description>
      <author>Letor</author>
      <pubDate>Mon, 07 Jan 2008 12:07:00 -0500</pubDate>
      <link>http://www.letor.ca/post/rails-timezone</link>
      <guid>http://www.letor.ca/post/rails-timezone</guid>
    </item>
  </channel>
</rss>

