<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <id>http://stephenviles.com/</id>
  <title>Stephen Viles</title>
  <updated>2011-08-20T12:00:00Z</updated>
  <link rel="alternate" href="http://stephenviles.com/"/>
  <link rel="self" href="http://stephenviles.com/articles/atom.xml"/>
  <author>
    <name>Stephen Viles</name>
    <uri>http://stephenviles.com/</uri>
  </author>
  <entry>
    <id>tag:stephenviles.com,2011-08-21:/articles/producing-csv-files-from-java-for-french-and-german/</id>
    <title type="html">Producing CSV files from Java for French and German</title>
    <published>2011-08-20T12:00:00Z</published>
    <updated>2011-08-20T12:00:00Z</updated>
    <link rel="alternate" href="http://stephenviles.com/articles/producing-csv-files-from-java-for-french-and-german/"/>
    <content type="html">&lt;p&gt;I&amp;#8217;ve been applying some limited internationalization to my work&amp;#8217;s US-centric
Java-based web app: producing CSV files that give intelligible results when
opened in Excel, without having to switch your Windows regional settings from
&amp;#8220;French (France)&amp;#8221; or &amp;#8220;German (Germany)&amp;#8221; to &amp;#8220;English (United States)&amp;#8221;, as our
long-suffering (and English-speaking) customers have to do.&lt;/p&gt;

&lt;p&gt;I&amp;#8217;m using Java&amp;#8217;s built-in &lt;a href="http://download.oracle.com/javase/7/docs/api/java/util/Locale.html"&gt;Locale&lt;/a&gt;, &lt;a href="http://download.oracle.com/javase/7/docs/api/java/text/DateFormat.html"&gt;DateFormat&lt;/a&gt;, and &lt;a href="http://download.oracle.com/javase/7/docs/api/java/text/NumberFormat.html"&gt;NumberFormat&lt;/a&gt;
classes. Here are a few things I&amp;#8217;ve learned along the way.&lt;/p&gt;

&lt;h2&gt;Excel can expect ; (semi-colon) as the separator in a &amp;#8220;comma-separated values&amp;#8221; file&lt;/h2&gt;

&lt;p&gt;The character that Excel expects as the separator in a CSV file is controlled
by the &amp;#8220;list separator&amp;#8221; setting in Windows regional settings. The possible
values are , (comma) and ; (semi-colon).&lt;/p&gt;

&lt;p&gt;Here are instructions for finding the &amp;#8220;list separator&amp;#8221; setting in different
versions of Windows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Windows XP: &lt;a href="http://support.microsoft.com/kb/307938"&gt;How to change date, time, number, and currency value displays in Windows XP&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Windows Vista: &lt;a href="http://windows.microsoft.com/en-US/windows-vista/Change-the-display-of-dates-times-currency-and-measurements"&gt;Change the display of dates, times, currency, and measurements&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Windows 7: &lt;a href="http://windows.microsoft.com/en-US/windows7/Change-the-display-of-dates-times-currency-and-measurements"&gt;Change the display of dates, times, currency, and measurements&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Note that even if the Windows regional settings are &amp;#8220;French (France)&amp;#8221;, the user
can change the &amp;#8220;list separator&amp;#8221; setting between ; (semi-colon) and , (comma).
So I added a separate &amp;#8220;list separator&amp;#8221; user preference in our web app.&lt;/p&gt;

&lt;h2&gt;Excel can&amp;#8217;t handle Java&amp;#8217;s French month abbreviations&lt;/h2&gt;

&lt;p&gt;I&amp;#8217;d hoped that Java&amp;#8217;s DateFormat for Locale &amp;#8220;French (France)&amp;#8221; would produce
formatted dates that can be parsed by Excel with Windows regional settings of
&amp;#8220;French (France)&amp;#8221;. Sadly, that&amp;#8217;s not the case for the MEDIUM date format. Java
puts a &amp;#8216;.&amp;#8217; character at the end of month abbreviations e.g. &amp;#8220;1 sept. 2011&amp;#8221;,
which Excel can&amp;#8217;t handle; it only parses the months that have four letters or
less, such as &amp;#8220;mai&amp;#8221;.&lt;/p&gt;

&lt;p&gt;The solution was to use the LONG date format. This causes Java to emit &amp;#8220;1
septembre 2011&amp;#8221;, which Excel parses and renders as &amp;#8220;01-sept-11&amp;#8221;.&lt;/p&gt;

&lt;h2&gt;Excel expects UTF16-LE character encoding, not UTF-8&lt;/h2&gt;

&lt;p&gt;Accented (non-ASCII) characters in month names were garbled in Excel.  Great, a
character encoding mismatch. It seems that Excel expects UTF16-LE character
encoding, which is easy enough to set using an OutputStreamWriter:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Writer writer = new BufferedWriter(new OutputStreamWriter(response.getOutputStream(), "UTF-16LE"));
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;although you&amp;#8217;ll need to &lt;a href="http://stackoverflow.com/questions/6030059/url-decoding-unsupportedencodingexception-in-java"&gt;catch UnsupportedEncodingException&lt;/a&gt;, unless you
use &lt;a href="http://code.google.com/p/guava-libraries/"&gt;Guava&lt;/a&gt;&amp;#8217;s &lt;a href="http://guava-libraries.googlecode.com/svn/trunk/javadoc/com/google/common/base/Charsets.html"&gt;Charsets&lt;/a&gt;.&lt;/p&gt;</content>
    <summary type="html">I've been applying some limited internationalization to a US-centric Java-based web app: producing CSV files that give intelligible results when opened in Excel, without having to switch your Windows regional settings. Here are a few things I've learned along the way.</summary>
  </entry>
  <entry>
    <id>tag:stephenviles.com,2011-06-22:/articles/new-york-city-travel-tips/</id>
    <title type="html">New York City travel tips</title>
    <published>2011-06-21T12:00:00Z</published>
    <updated>2011-06-21T12:00:00Z</updated>
    <link rel="alternate" href="http://stephenviles.com/articles/new-york-city-travel-tips/"/>
    <content type="html">&lt;p&gt;Here&amp;#8217;s a few tips on Manhattan street layout, getting around, security, eating and drinking, and swimming.&lt;/p&gt;

&lt;h2&gt;5th Avenue divides East and West (Streets)&lt;/h2&gt;

&lt;p&gt;Most of Manhattan has a grid layout of numbered avenues running north-south and
numbered streets running east-west (in reality, about 30&amp;deg; clockwise from
the compass point). While almost as unimaginative as naming New Zealand&amp;#8217;s two
main islands &lt;a href="http://maps.google.com/maps?f=q&amp;amp;q=North+Island,+New+Zealand&amp;amp;z=6"&gt;North Island&lt;/a&gt; and &lt;a href="http://maps.google.com/maps?f=q&amp;amp;q=South+Island,+New+Zealand&amp;amp;z=6"&gt;South Island&lt;/a&gt;, it shares the same
advantage: it&amp;#8217;s easy to work out which direction you are heading.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;But&lt;/em&gt; you need to know that numbered streets are divided into East and West at
5th Avenue, and that building numbers are specific to the East and West parts of
the street. So you don&amp;#8217;t say &amp;#8220;1 43rd St&amp;#8221;, you say &amp;#8220;1 East 43rd St&amp;#8221; or &amp;#8220;1 West
43rd St&amp;#8221;. To make things more fun, building numbers start at 5th Avenue and
increase in the same direction as the street name &amp;#8211; to the west for West
streets, to the east for East streets. So 1 East 43rd St and 1 West 43rd St are
&lt;a href="http://maps.google.com/maps?f=d&amp;amp;saddr=1+East+43rd+Street,+New+York,+NY,+United+States&amp;amp;daddr=1+West+43rd+Street,+New+York,+NY,+United+States&amp;amp;dirflg=w"&gt;across 5th Ave from each other&lt;/a&gt;, but 500 East 43rd St and 500 West 43rd St
are &lt;a href="http://maps.google.com/maps?f=d&amp;amp;saddr=500+East+43rd+Street,+New+York,+NY,+United+States&amp;amp;daddr=500+West+43rd+Street,+New+York,+NY,+United+States&amp;amp;dirflg=w"&gt;on opposite sides of the island&lt;/a&gt;. You &lt;strong&gt;must&lt;/strong&gt; know the East or West
part of the street name to get to the right building.&lt;/p&gt;

&lt;p&gt;Streets are numbered from south to north, and avenues are numbered from east
(1st Ave) to west (12th Ave). 4th Avenue has a short existence from East 9th St
to East 14th St. In its place, north of 23rd St, are Lexington Avenue, Park
Avenue, and Madison Avenue (east to west). There are also avenues to the east
of 1st Avenue, south of 14th St, named Avenue A, Avenue B, Avenue C, Avenue D
&amp;#8211; not Avenue 0 to Avenue -3 as a geek might think.  The area is known as
Alphabet City (which I suppose is better than Negative City).&lt;/p&gt;

&lt;p&gt;It takes about 5 minutes to walk east-west along a street between one avenue
and the next (known as a long block). It takes about 1 minute to walk along an
avenue between one street and the next (known as a short block).&lt;/p&gt;

&lt;p&gt;Most streets and avenues are one-way. Don&amp;#8217;t be surprised if a driver heads past
the avenue or street of your destination.  They will do this to get onto an
avenue or street that goes in the right direction. Major cross streets (yellow
in Google Maps &amp;#8211; 14th, 23rd, 34th, 42nd, 57th) are two-way and have subway
stations on them.&lt;/p&gt;

&lt;h2&gt;Subway orientation: express, local, uptown, downtown&lt;/h2&gt;

&lt;p&gt;See &lt;a href="http://mta.info/nyct/subway/howto_sub.htm"&gt;How to Ride the Subway&lt;/a&gt;, and get a &lt;a href="http://mta.info/metrocard/"&gt;MetroCard&lt;/a&gt;.  Subway maps are free
at the subway station and &lt;a href="http://mta.info/nyct/maps/submap.htm"&gt;online&lt;/a&gt;. The subway map is
schematic and not to scale. &lt;a href="http://www.onnyturf.com/subway/"&gt;OnNYTurf&lt;/a&gt; provides an overlay of subway lines on
a street map.&lt;/p&gt;

&lt;p&gt;Subway lines are identified by a letter or digit, and are grouped by color e.g.
the green-colored 4, 5, and 6 lines all run on the same set of tracks in
Manhattan, but to different endpoints in the Bronx. &lt;em&gt;Express&lt;/em&gt; trains stop only
at stations marked with white circles on the map. &lt;em&gt;Local&lt;/em&gt; trains stop at all
stations. On the paper or PDF versions of the map, the lines that stop at each
station are listed under the station name.&lt;/p&gt;

&lt;p&gt;On the subway map, a line number/letter in a coloured square (rather than a
circle) means the last station for the line.  This is pretty obvious when the
track stops, but the Q and V lines stop in the middle of a track on Manhattan.&lt;/p&gt;

&lt;p&gt;Once in a station, look up for signs directing you to platforms. Often the
platforms for opposite directions on the same line are at different locations
in the station. &lt;em&gt;Uptown&lt;/em&gt; means to the north of Manhattan. &lt;em&gt;Downtown&lt;/em&gt; means to
the south of Manhattan. Once you have the right platform, the express and local
tracks may be across the platform from each other.&lt;/p&gt;

&lt;p&gt;The &amp;#8220;ladder&amp;#8221; on the subway map between Lexington Ave/53rd St (F line) and 59th
St (4/5/6 lines) does not indicate a tunnel or moving footway. It means only
that you can get out to the street and transfer to the other line without
paying another fare.&lt;/p&gt;

&lt;p&gt;NYC is a big city full of busy people, who are mostly friendly, but who don&amp;#8217;t
appreciate people standing around and getting in their way.  If you have to
stop and look up your map, move to one side of the footpath.&lt;/p&gt;

&lt;h2&gt;Search engines&lt;/h2&gt;

&lt;p&gt;The USA has been in a heightened state of security awareness since 9/11/01.
Some of the impacts are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;In air travel, your luggage may be searched by the Transport Security
Administration (TSA). Any locks that cannot be opened by TSA will be cut off
and destroyed &amp;#8211; so use TSA-openable locks. Lock all parts of your luggage,
even empty parts, to deter planting of material in your luggage (this applies
worldwide, not just in the US).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;On entry to the US, your photograph and index fingerprints will be taken
(using a digital scanner, not an ink pad).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In the NYC subway, bags are subject to random search by police. If you do not
consent to search, you will not be allowed on the subway.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Good advice from the &lt;a href="http://mta.info/nyct/safety/"&gt;MTA safety page&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
    &lt;p&gt;As a general precaution, whether you&amp;#8217;re in the subway, the bus, or even in
    the street, appear confident. Always look as if you know where you&amp;#8217;re going
    [another reason not to pull out your subway map], and you&amp;#8217;re better off not
    displaying money in public. Never keep your wallet or money in a back pocket,
    and keep all bags, backpacks, and pocketbooks securely closed.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;Tips on eating and drinking&lt;/h2&gt;

&lt;p&gt;Tipping is the US way of compensating for a low minimum wage. &lt;a href="http://people.howstuffworks.com/tipping2.htm"&gt;Add 15-20% to
your restaurant bill&lt;/a&gt;. When you
pick up your change after being served a drink at a bar, leave one dollar bill
on the bar for each drink.&lt;/p&gt;

&lt;p&gt;New York tap water is &lt;a href="http://www.goaskalice.columbia.edu/0386.html"&gt;&amp;#8220;virtually lead-free&amp;#8221;&lt;/a&gt;. So you may prefer to drink
bottled water, which is available in all supermarkets and corner stores. Large
bottles are much cheaper than small bottles.&lt;/p&gt;

&lt;p&gt;Supermarkets are at the street level of apartment or office buildings, not in
their own separate buildings. Chains include &lt;a href="http://www.dagnyc.com/StoreLocator.aspx"&gt;D&amp;#8217;Agostino&lt;/a&gt; and &lt;a href="http://www.gristedes.com/locator/"&gt;Gristedes&lt;/a&gt;.
&lt;a href="http://wholefoodsmarket.com/stores/"&gt;Whole Foods Market&lt;/a&gt; is not cheap but has good food.&lt;/p&gt;

&lt;h2&gt;Public swimming pools, even outdoors (in the summer)&lt;/h2&gt;

&lt;p&gt;NYC has several &lt;a href="http://www.nycgovparks.org/facilities/pools"&gt;public swimming pools&lt;/a&gt;, including outdoor pools open in the
summer free of charge. Look for &amp;#8216;adult swim&amp;#8217; times if you want to be able to
swim laps. I used &lt;a href="http://www.nycgovparks.org/parks/hamiltonfish"&gt;Hamilton Fish Park&lt;/a&gt; on the Lower East Side and really
enjoyed it. The city even has &lt;a href="http://www.nycgovparks.org/sub_things_to_do/programs/ap_aquatics.html"&gt;free swimming lessons&lt;/a&gt;.  &lt;/p&gt;</content>
    <summary type="html">Here's a few tips on Manhattan street layout, getting around, security, eating and drinking, and swimming.</summary>
  </entry>
  <entry>
    <id>tag:stephenviles.com,2010-06-01:/articles/intro-to-java-web-applications/</id>
    <title type="html">Introduction to Java web applications</title>
    <published>2010-05-31T12:00:00Z</published>
    <updated>2010-05-31T12:00:00Z</updated>
    <link rel="alternate" href="http://stephenviles.com/articles/intro-to-java-web-applications/"/>
    <content type="html">&lt;p&gt;I used the following material to give a one-hour overview of Java and web applications to a group of developers
experienced in the Microsoft ecosystem.&lt;/p&gt;

&lt;h2&gt;The basic Hello World: Java source in .java file compiles to JVM bytecode in .class file&lt;/h2&gt;

&lt;p&gt;See the following sections of this useful
    &lt;a href="http://www.vogella.de/articles/JavaIntroduction/article.html"&gt;Introduction to Java Programming&lt;/a&gt;:
&lt;/p&gt;

&lt;ul style="list-style:none"&gt;
    &lt;li&gt;1. Introduction&lt;/li&gt;
    &lt;li&gt;2. Classpath&lt;/li&gt;
    &lt;li&gt;3. Your first Java program&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Section 13 provides an overview of JAR (Java ARchive) files. More details at the
    &lt;a href="http://java.sun.com/docs/books/tutorial/deployment/jar/index.html"&gt;Java Tutorial Lesson: Packaging
    Programs in JAR Files&lt;/a&gt;.
&lt;/p&gt;

&lt;h2&gt;Using Java for Financial Applications&lt;/h2&gt;

&lt;h3&gt;Dates and Times&lt;/h3&gt;

&lt;p&gt;The standard Java library has two classes for dates and times:
    &lt;a href="http://java.sun.com/javase/6/docs/api/java/util/Date.html"&gt;java.util.Date&lt;/a&gt; and
    &lt;a href="http://java.sun.com/javase/6/docs/api/java/util/Calendar.html"&gt;java.util.Calendar&lt;/a&gt;. Both are mutable
    and difficult to use for common date arithmetic. A much better replacement is
    &lt;a href="http://joda-time.sourceforge.net/"&gt;Joda-Time&lt;/a&gt;. In particular, the
    &lt;a href="http://joda-time.sourceforge.net/api-release/org/joda/time/LocalDate.html"&gt;LocalDate&lt;/a&gt; class is an
    &amp;ldquo;immutable datetime class representing a date without a time zone&amp;rdquo;. Most of the time, this is exactly
    what you need.
&lt;/p&gt;

&lt;h3&gt;Monetary Values&lt;/h3&gt;

&lt;p&gt;Java does not have a built-in decimal data type. Instead, you need to use the
    &lt;a href="http://java.sun.com/javase/6/docs/api/java/math/BigDecimal.html"&gt;BigDecimal&lt;/a&gt; class in the standard
    library for immutable, arbitrary-precision signed decimal numbers with complete control over rounding behavior.
&lt;/p&gt;

&lt;p&gt;Do not use either of the binary floating-point types (float or double). It is impossible to
    represent 0.1 (or any other negative power of ten) as a float or double exactly. The representation errors
    and rounding errors will bite you. See &lt;a href="http://floating-point-gui.de/"&gt;http://floating-point-gui.de/&lt;/a&gt;
    for more details on &amp;ldquo;what every programmer should know about floating-point arithmetic (or why don&amp;rsquo;t my
    numbers add up?)&amp;rdquo;.
&lt;/p&gt;

&lt;p&gt;I recommend carrying the currency with every monetary value, as documented in the
    &lt;a href="http://martinfowler.com/eaaCatalog/money.html"&gt;Money pattern&lt;/a&gt; (Patterns of Enterprise Application
    Architecture, Martin Fowler). The
    &lt;a href="http://java.sun.com/javase/6/docs/api/java/util/Currency.html"&gt;Currency&lt;/a&gt; class in the standard Java
    library represents currencies using their ISO 4217 currency codes.
&lt;/p&gt;

&lt;h2&gt;Programming Guidance: Effective Java and Collections&lt;/h2&gt;

&lt;p&gt;The book &lt;a href="http://java.sun.com/docs/books/effective/"&gt;Effective Java, Second Edition&lt;/a&gt; by Joshua
    Bloch gives much useful programming guidance in bite-sized articles.
&lt;/p&gt;

&lt;p&gt;The Java Collections framework in
    &lt;a href="http://java.sun.com/javase/6/docs/api/java/util/package-summary.html#package_description"&gt;java.util&lt;/a&gt;
    is very useful. See the
    &lt;a href="http://java.sun.com/javase/6/docs/technotes/guides/collections/overview.html"&gt;overview&lt;/a&gt; and
    &lt;a href="http://java.sun.com/javase/6/docs/technotes/guides/collections/reference.html"&gt;annotated outline&lt;/a&gt;.
&lt;/p&gt;

&lt;p&gt;Google have written an
    &lt;a href="http://guava-libraries.googlecode.com/svn/trunk/javadoc/com/google/common/collect/package-summary.html#package_description"&gt;extension
    collection framework&lt;/a&gt; in the &lt;a href="http://code.google.com/p/guava-libraries/"&gt;Guava Google Core Libraries for Java&lt;/a&gt;.
&lt;/p&gt;

&lt;h2&gt;Structure of Java Web Applications&lt;/h2&gt;

&lt;p&gt;The most basic component of a Java web application is the &lt;dfn&gt;servlet&lt;/dfn&gt;: a Java class that responds to HTTP requests.&lt;/p&gt;
&lt;p&gt;Start with the overview page &lt;a href="http://java.sun.com/j2ee/1.4/docs/tutorial/doc/WebApp.html"&gt;Getting Started
    with Web Applications&lt;/a&gt;, then read the following sections of the
    &lt;a href="http://java.sun.com/j2ee/1.4/docs/tutorial/doc/index.html"&gt;J2EE 1.4 tutorial&lt;/a&gt;:
&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;Chapter 1: Overview&lt;/li&gt;
    &lt;li&gt;Chapter 3: Getting Started with Web Applications&lt;/li&gt;
    &lt;li&gt;Chapter 11: Java Servlet Technology&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After that, you&amp;#8217;ll find the other 32 chapters describe many other technology components that you can add to Java
    web applications, including Web services.
&lt;/p&gt;

&lt;h2&gt;A Hello World Web Application using Eclipse, Ant and Tomcat&lt;/h2&gt;

&lt;p&gt;The following pages give detailed instructions on how to build a Hello World web application. Along the way, they
    introduce the Eclipse IDE, the Ant build tool, and the Tomcat servlet container.&lt;/p&gt;
&lt;ol&gt;
    &lt;li&gt;&lt;a href="http://obscuredclarity.blogspot.com/2009/11/hello-world-java-web-application-in.html"&gt;Hello World Java
        Web Application in Eclipse (Part 1)&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="http://obscuredclarity.blogspot.com/2009/11/hello-world-java-web-application-in_12.html"&gt;Hello World
        Java Web Application in Eclipse (Part 2)&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="http://obscuredclarity.blogspot.com/2009/11/hello-world-java-web-application-in_3043.html"&gt;Hello World
        Java Web Application in Eclipse (Part 3)&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The copyright notice on these pages is rather amusing.&lt;/p&gt;

&lt;h2&gt;Web Application Security Issues&lt;/h2&gt;

&lt;p&gt;A public-facing web application has particular security issues. See the
    &lt;a href="http://www.owasp.org/index.php/Category:OWASP_Top_Ten_Project"&gt;Open Web Application Security Project
    (OWASP) Top Ten&lt;/a&gt; for a general overview, and then see the
    &lt;a href="http://www.owasp.org/index.php/Category:OWASP_Enterprise_Security_API#tab=Java_EE"&gt;Enterprise Security
    API for Java EE&lt;/a&gt;, which provides a security framework for Java web applications.
&lt;/p&gt;</content>
    <summary type="html">I used the following material to give a one-hour overview of Java and web applications to a group of developers experienced in the Microsoft ecosystem.</summary>
  </entry>
  <entry>
    <id>tag:stephenviles.com,2010-05-31:/articles/removing-line-noise-with-a-user-style-sheet/</id>
    <title type="html">Removing line noise with a user style sheet</title>
    <published>2010-05-30T12:00:00Z</published>
    <updated>2010-05-30T12:00:00Z</updated>
    <link rel="alternate" href="http://stephenviles.com/articles/removing-line-noise-with-a-user-style-sheet/"/>
    <content type="html">&lt;p&gt;I find text with underlining or strikethough difficult to read, so I use the following
&lt;a href="http://www.w3.org/TR/CSS21/cascade.html#cascade"&gt;user style sheet&lt;/a&gt; to remove it, except when hovering over links:
&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;
/*
 * This file can be used to apply a style to all web pages you view
 * Rules without !important are overruled by author rules if the
 * author sets any.  Rules with !important overrule author rules.
 */

:link, :visited {
  text-decoration : none !important ;
}
:link:hover, :visited:hover {
  text-decoration : underline !important ;
}
del {
  text-decoration : none !important ;
}
strike {
  text-decoration : none !important ;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;In Firefox, the user style sheet file is called chrome/userContent.css in the
&lt;a href="http://www.gemal.dk/mozilla/profile.html"&gt;user profile directory&lt;/a&gt;.&lt;/p&gt;</content>
    <summary type="html">I find text with underlining or strikethough difficult to read, so I use the following user style sheet to remove it, except when hovering over links.</summary>
  </entry>
  <entry>
    <id>tag:stephenviles.com,2010-04-25:/articles/a-pattern-for-scripts-that-update-data/</id>
    <title type="html">A pattern for scripts that update data</title>
    <published>2010-04-24T12:00:00Z</published>
    <updated>2010-04-24T12:00:00Z</updated>
    <link rel="alternate" href="http://stephenviles.com/articles/a-pattern-for-scripts-that-update-data/"/>
    <content type="html">&lt;p&gt;The following Bash script is designed to be run from a crontab entry. It performs a database update (using Oracle&amp;#8217;s
&lt;kbd&gt;sqlplus&lt;/kbd&gt;), checks the output for errors, and adds a success or failure comment to a
&lt;a href="http://www.atlassian.com/software/jira/"&gt;JIRA&lt;/a&gt; ticket by sending an email to the JIRA instance.&lt;/p&gt;

&lt;p&gt;A JIRA instance only accepts email from the addresses of its registered users, so I had to use sendmail with an email
constructed from scratch in order to control the From: address. The issue key is specified in the Subject: line.&lt;/p&gt;

&lt;p&gt;Note the signature block of the email (after the &lt;samp&gt;-- &lt;/samp&gt; line), which identifies where the script is running,
and as which user &amp;mdash; crucial information if you want to modify its behaviour.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Caution:&lt;/em&gt; You don&amp;#8217;t want to use too many of these out-of-band database updates. Like database triggers, they
have their uses, but do not scale well. A system with more than a few of these scripts will be hard to understand, and
harder to modify. Temporary solutions often become permanent, and permanent solutions should be inside your application,
not outside it.&lt;/p&gt;

&lt;pre&gt;&lt;code class='language-bash'&gt;
#! /bin/bash
set -u
SCRIPT_NAME=$(basename $BASH_SOURCE)
SCRIPT_DIR=$(dirname $(readlink -f $0))
SQL_OUTPUT=/tmp/$SCRIPT_NAME-$$.out
DB_CREDENTIALS=

# Do the update
sqlplus $DB_CREDENTIALS 2&gt;&amp;amp;1 &gt;&gt; $SQL_OUTPUT &amp;lt;&amp;lt; EOF
set echo on
@$SCRIPT_DIR/do-it.sql
EOF

# Look for Oracle errors
ERROR_LIST=/tmp/$SCRIPT_NAME-$$.err
grep 'ORA-' $SQL_OUTPUT &gt;&gt; $ERROR_LIST
grep 'SP2-' $SQL_OUTPUT &gt;&gt; $ERROR_LIST

# Look for success messages
function look_for() {
    grep --silent "$1" $SQL_OUTPUT
    RETURNVAL=$?
    if [[ $RETURNVAL -ne 0 ]] ; then
        echo "Did not find expected output: $1" &gt;&gt; $ERROR_LIST
    fi
}

look_for '1 row updated.'
look_for 'Commit complete.'

# Start the log, which is in email format
SCRIPT_LOG=/tmp/$SCRIPT_NAME-$$.log
cat &gt;&gt; $SCRIPT_LOG &amp;lt;&amp;lt; EOF
To: jira@example.com,me@example.com
From: me@example.com
Subject: PRJ-12345

EOF

# Build body of log
if [ -s "$ERROR_LIST" ] ; then
    echo "Errors found while attempting to do it:" &gt;&gt; $SCRIPT_LOG
    cat $ERROR_LIST &gt;&gt; $SCRIPT_LOG
    echo &gt;&gt; $SCRIPT_LOG
    echo "Full command output:" &gt;&gt; $SCRIPT_LOG
    cat $SQL_OUTPUT &gt;&gt; $SCRIPT_LOG
else
    echo "Done it" &gt;&gt; $SCRIPT_LOG
fi

# Add script detail to log and send it to JIRA ticket
cat &gt;&gt; $SCRIPT_LOG &amp;lt;&amp;lt; EOF

--
Sent by script $SCRIPT_DIR/$SCRIPT_NAME running on host `hostname`.`dnsdomainname` as user `whoami`
EOF
/usr/lib/sendmail -t &amp;lt; $SCRIPT_LOG &gt;&gt; $ERROR_LIST 2&gt;&amp;amp;1

RETURNVAL=$?
if [[ $RETURNVAL -ne 0 ]] ; then
    echo "sendmail had a non-zero exit code, see above for output" &gt;&gt; $ERROR_LIST
else
    rm $SQL_OUTPUT $ERROR_LIST $SCRIPT_LOG
fi
&lt;/code&gt;&lt;/pre&gt;</content>
    <summary type="html">The following Bash script is designed to be run from a crontab entry. It performs a database update (using Oracle's sqlplus), checks the output for errors, and adds a success or failure comment to a JIRA ticket by sending an email to the JIRA instance.</summary>
  </entry>
</feed>

