<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Arc90 Blog &#187; Quick Tips</title>
	<atom:link href="http://blog.arc90.com/category/quick-tips/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.arc90.com</link>
	<description>Web Application Design &#38; Development</description>
	<lastBuildDate>Mon, 23 Jan 2012 19:51:42 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Gmailing Things Done</title>
		<link>http://blog.arc90.com/2012/01/23/gmailing-things-done/</link>
		<comments>http://blog.arc90.com/2012/01/23/gmailing-things-done/#comments</comments>
		<pubDate>Mon, 23 Jan 2012 15:25:36 +0000</pubDate>
		<dc:creator>Alec Munro</dc:creator>
				<category><![CDATA[Quick Tips]]></category>
		<category><![CDATA[Thoughts]]></category>

		<guid isPermaLink="false">http://blog.arc90.com/?p=1682</guid>
		<description><![CDATA[TL;DR I’ve implemented most of the GTD organizational system using just Gmail. You can too! Introduction For many years, I&#8217;ve been a devotee, if not quite an adherent, to the productivity school known as &#8220;Getting Things Done&#8220;, much more commonly referred to as GTD. GTD is based on a book&#8230; <a href="http://blog.arc90.com/2012/01/23/gmailing-things-done/">More</a>]]></description>
			<content:encoded><![CDATA[<div>
<div id="attachment_1693" class="wp-caption alignright" style="width: 276px"><a href="http://blog.arc90.com/2012/01/23/gmailing-things-done/342774437_3a0dce7524-2/" rel="attachment wp-att-1693"><img class=" wp-image-1693 " src="http://blog.arc90.com/files/2012/01/342774437_3a0dce7524.jpg" alt="" width="266" height="400" /></a><p class="wp-caption-text">How do you GTD? (Credit: Carvalho)</p></div>
<p><strong>TL;DR</strong><br />
I’ve implemented most of the GTD organizational system using just Gmail. You can too!</p>
<p><strong>Introduction</strong><br />
For many years, I&#8217;ve been a devotee, if not quite an adherent, to the productivity school known as &#8220;<a href="http://www.davidco.com/about-gtd">Getting Things Done</a>&#8220;, much more commonly referred to as GTD. GTD is based on a <a href="http://www.amazon.com/Getting-Things-Done-Stress-Free-Productivity/dp/0142000280">book of the same name</a>, by <a href="http://www.davidco.com/">David Allen</a>, and boils down productivity into maintaining focus by having trusted systems to deal with maintaining your commitments, and handling potential disruptions.</p>
<p>The book itself lays out some specifics of how these systems could be implemented, but it is stressed that the results are what matter, not the implementation.</p>
<p>In general terms, you need the following to do GTD (messages can refer to any type of communication that you receive):</p>
<ul>
<li>1 or more &#8220;<strong>inboxes</strong>&#8220;. These can be literal email inboxes, or any centralized way to collect messages.</li>
<li>A &#8220;<strong>tickler</strong>&#8221; system that allows you to &#8220;mail&#8221; yourself things in the future (i.e. I don&#8217;t have to pay this bill until 2 weeks from now, so I don&#8217;t want to see it until then). This is where the expression &#8220;43 folders&#8221; came from.</li>
<li>A &#8220;<strong>next action</strong>&#8221; collection. These are actual actions you can do, phrased as decisively as possible, &#8220;wash the floor&#8221; vs. &#8220;clean the house&#8221;.</li>
<li>A &#8220;<strong>projects</strong>&#8221; collection. In GTD, projects are defined as outcomes that require more than one action to complete.</li>
<li>A &#8220;<strong>someday/maybe</strong>&#8221; collection. These are messages or topics that are of interest, but you aren&#8217;t at the point where you want to take any action on them.</li>
<li>A &#8220;<strong>waiting for</strong>&#8221; collection. These are topics that have been delegated to someone else to deal with, and until they do, require no action from you.</li>
</ul>
<p><strong>Implementation challenges</strong><br />
Since I first read GTD about 5 years ago, I&#8217;ve struggled to put together a single system that would actually allow me to do it reliably.</p>
<p>Some of the problems I&#8217;ve encountered:</p>
<ul>
<li>Too many <strong>inboxes</strong>, so I don&#8217;t check them all reliably</li>
<li><strong>Inboxes</strong> and other collections in different media (email vs. paper list, etc.), so transitioning between them is non-trivial</li>
<li>Separate systems for personal vs. work commitments</li>
<li>Getting a usable &#8220;<strong>waiting for</strong>&#8221; collection</li>
<li>Interacting with systems at my desk and on the go</li>
</ul>
<p><strong>Progress</strong><br />
Over the past two years, one of simplest ways I have found to maintain &#8220;<strong>next actions</strong>&#8221; is as email drafts. A good percentage of the actions I take involve sending an email, so there&#8217;s a natural process for those, and my inbox is very frequently referenced, so as long as I can keep focus on those drafts, I can be pretty confident I&#8217;m working on the right thing.</p>
<p>When Google introduced their priority inbox feature, I was excited, because of the potential for making multiple collections of email available up-front. Unfortunately, at the time, it didn&#8217;t allow you to choose &#8220;drafts&#8221; as one of them (more on this later), it only allowed 3 collections with limited customization, and most importantly, my work email was still stuck in Outlook.</p>
<p><strong>A solution</strong><br />
When I started at Arc90, I was pleased to discover they used Gmail for corporate email, and even more pleased to discover that priority inbox had received several enhancements. So I started experimenting, and I&#8217;m now pretty pleased with what I&#8217;ve been able to accomplish.</p>
<p>Here&#8217;s how I have things set up:</p>
<ul>
<ul>
<li>Labels for Done, Waiting For, and Someday</li>
<ul>
<li>Contact entries for my email, +done, +someday, named just &#8220;DONE&#8221; and &#8220;SOMEDAY&#8221; (<a href="http://gmailblog.blogspot.com/2008/03/2-hidden-ways-to-get-more-from-your.html">WTF am I talking about?</a>)</li>
<li>Filters for messages sent to these addresses, to label them appropriately and archive them</li>
</ul>
<li>Priority Inbox:</li>
<ul>
<li>Four inbox sections:</li>
<ul>
<li>Unread</li>
<li>All &#8220;Waiting For&#8221; (usually kept collapsed)</li>
<li>All Drafts</li>
<li>Everything else</li>
</ul>
</ul>
</ul>
</ul>
<p>Whenever I take on a new commitment, I draft an email, with the subject as the project, and lines in the body describing actions. If the action was to send an email, this draft will become that email. If the action is something else, then when it has been completed, I&#8217;ll send it to DONE.</p>
<p>When I receive an email that requires a commitment from me, I&#8217;ll draft a response with the commitment (and try to make sure I hit &#8220;save&#8221; instead of &#8220;send&#8221;).</p>
<p>When I send a message that requires a response, I will open that message and apply the label &#8220;Waiting For&#8221;. When that response comes in, the message shows up in &#8220;Unread&#8221;, and I can process it as appropriate. (This is why Unread has to be above Waiting For).</p>
<p>When I am waiting for something else, I will create a draft, write what I am waiting for, save it, and then label it &#8220;Waiting For&#8221;. When I have an idea for a project, or otherwise become aware of something that interests me, but is not part of my current work, I will draft and (usually) send an email to SOMEDAY.<br />
When I need to be reminded of something in the future, I create a calendar event for that.</p>
<p><strong>Things that could be improved</strong></p>
<ul>
<li>Fewer clicks to create drafts. Right now, it&#8217;s &#8220;compose&#8221;, type, &#8220;save&#8221;, &#8220;back&#8221;. If there was a way I could start typing, and just hit &#8220;save as draft&#8221;, that would be nice.</li>
<li>Applying labels to drafts. Right now you need to save a draft or send the message, and then re-open it, before you can apply a label.</li>
<li>A couple of times, I have sit &#8220;send&#8221; instead of &#8220;save&#8221;. I think I could use &#8220;Undo Send&#8221; in labs to deal with this.</li>
<li>I don&#8217;t have a projects collection right now. I will often use a single draft to track a project, and just make sure the first line is the next action.</li>
<li>Some kind of &#8220;send later&#8221; functionality would be an easier way to remind myself of things at a specific date.</li>
</ul>
<p><strong>Conclusion</strong><br />
If this is your first exposure to GTD, hopefully this has provoked some interest, and provided something of an example for how a GTD system can be implemented. It takes some getting used to, and there’s a bit more to it then I have described here, but nothing that should cause conflict with this system. If there’s interest, I might write a couple more posts covering in-depth set up, and some other GTD aspects.</p>
<p>Thanks for reading!</p>
<p><em>Alec Munro is a QA Engineer at Arc90, where he uses GTD to manage his days of tests plans, infrastructure development, and meetings. He&#8217;s been using GTD for the past 5 or so years, and just recently began to use Gmail as his primary GTD tool. Alec lives in Halifax, Nova Scotia.</em></p>
<p>&nbsp;</p>
</div>
]]></content:encoded>
			<wfw:commentRss>http://blog.arc90.com/2012/01/23/gmailing-things-done/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Use a DVCS to Track Anything Instantly</title>
		<link>http://blog.arc90.com/2009/08/16/use-a-dvcs-to-track-anything-instantly/</link>
		<comments>http://blog.arc90.com/2009/08/16/use-a-dvcs-to-track-anything-instantly/#comments</comments>
		<pubDate>Sun, 16 Aug 2009 15:10:24 +0000</pubDate>
		<dc:creator>Avi Flax</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Quick Tips]]></category>

		<guid isPermaLink="false">http://blog.daniell.acr90-dev-02/2009/08/16/use-a-dvcs-to-track-anything-instantly/</guid>
		<description><![CDATA[<p>I recently stumbled across the essay <a href="http://plasmasturm.org/log/523/">In brief praise of  <abbr title="Distributed Version Control System">DVCSs</abbr></a> by <a href="http://plasmasturm.org/about/">Aristotle Pagaltzis</a>, and it was a revelation for me. I'd been wanting to try a <abbr title="Distributed Version Control System">DVCS</abbr> for a while, but hadn't really gotten around to it — the perceived benefit hadn't justified the perceived effort. But when Aristotle pointed out that "Subversion makes the mental overhead of creating a repository very much greater than any DVCS," something clicked.</p>]]></description>
			<content:encoded><![CDATA[<p>I recently stumbled across the essay <a href="http://plasmasturm.org/log/523/">In brief praise of  <abbr title="Distributed Version Control System">DVCSs</abbr></a> by <a href="http://plasmasturm.org/about/">Aristotle Pagaltzis</a>, and it was a revelation for me. I&#8217;d been wanting to try a <abbr title="Distributed Version Control System">DVCS</abbr> for a while, but hadn&#8217;t really gotten around to it — the perceived benefit hadn&#8217;t justified the perceived effort. But when Aristotle pointed out that <q cite="http://plasmasturm.org/log/523/"><em>Subversion makes the mental overhead of creating a repository very much greater than any <abbr title="Distributed Version Control System">DVCS</abbr>,</em></q> something clicked. I saw an immediate benefit I&#8217;d gain from even simplistic usage of a DVCS, and so I immediately gave it a try.
<p>I had a text file that I wanted to explicitly track versions of — I use Time Machine for incremental backup, which is great, but doesn&#8217;t always give me precise enough control of the snapshots, and I don&#8217;t always have the snapshots available. Once I read Aristotle&#8217;s essay, it only took me a few minutes to download and install <a href="http://mercurial.selenic.com/">Mercurial</a>, and then I started tracking my file with three simple commands: <code>hg init; hg add *; hg commit -m "initial"</code>. Quick, easy, and effective. From that point on, my folder was also a repository, and I could track specific revisions of my files by simply typing <code>hg commit -m "update"</code> at any point.</p>
<p>What I think is the killer realization here is that <em>it is now super easy to make any folder into a repository, and instantly start tracking versions of its contents.</em> I&#8217;ve used Subversion to make local repositories, and track local files in the past — and it really is many more steps, and much more work. It&#8217;s also messier, because the repository and the working copy must be separate entities — you have to think about where the repository should live, as opposed to the actual stuff, the working copy. With a DVSC, no such dichotomy exists. The repository and the actual stuff are one and the same. You can move them, zip them, email them — as long as the metadata directory is preserved (for example, <code>.hg</code> or <code>.git</code>), the folder remains a repository.</p>
<p>I&#8217;m thankful to Aristotle for helping me get past the initial barrier to entry, and start actually using a DVCS. I&#8217;m looking forward to learning more about them, and using them even more going forward.</p>
<p>(Bonus tip: on OS X, some applications save their data using a special type of file called a &#8220;package&#8221;, which is actually a directory with a special flag. One example is <a href="http://www.omnigroup.com/applications/omnigraffle/">OmniGraffle</a>, which I use frequently. Because these &#8220;files&#8221; are actually directories, they can be easily made into self-versioning files with their own self-contained repositories. Just navigate to the directory and run the commands above! From that point on, the file will be a repository and can track its own versions. Pretty useful!)</p>
<p>(I can&#8217;t explain exactly why I decided to try Mercurial first, before <a href="http://git-scm.com/">Git</a> or <a href="http://bazaar-vcs.org/">Bazaar</a>. I&#8217;ve read many comparisons of them, and something about those comparisons just made me want to try it. I&#8217;m not sure exactly how, but I had built up the impression that Mercurial was somehow simpler, cleaner, more elegant, and more approachable than Git or Bazaar. I don&#8217;t know if that&#8217;s actually true, but the impression was enough that that&#8217;s where I started.)</p>
<p>(Aristotle&#8217;s mention of &#8220;mental overhead&#8221; as a decisive factor in using one system over another is something <a href="http://aviflax.com/post/phrase-ive-been-using-frequen/">I&#8217;ve been thinking about lately as well</a>, although I&#8217;ve used the more unwieldy &#8220;cognitive overhead.&#8221;)</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.arc90.com/2009/08/16/use-a-dvcs-to-track-anything-instantly/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>SQL Server Stored Procedure Introspection</title>
		<link>http://blog.arc90.com/2009/02/12/sql-server-stored-procedure-introspection/</link>
		<comments>http://blog.arc90.com/2009/02/12/sql-server-stored-procedure-introspection/#comments</comments>
		<pubDate>Thu, 12 Feb 2009 18:35:01 +0000</pubDate>
		<dc:creator>Michael Helmuth</dc:creator>
				<category><![CDATA[Quick Tips]]></category>

		<guid isPermaLink="false">http://blog.daniell.acr90-dev-02/2009/02/12/sql-server-stored-procedure-introspection/</guid>
		<description><![CDATA[Here at Arc90, a hallmark of our work is extremely dynamic, flexible systems. In the process of building one of our platforms, I found myself calling some ever-evolving stored procedures with large numbers of parameters. Hard coding these calls became tedious, buggy, and generally maddening. I really needed to be&#8230; <a href="http://blog.arc90.com/2009/02/12/sql-server-stored-procedure-introspection/">More</a>]]></description>
			<content:encoded><![CDATA[<p>Here at Arc90, a hallmark of our work is extremely dynamic, flexible systems.  In the process of building one of our platforms, I found myself calling some ever-evolving stored procedures with large numbers of parameters.  Hard coding these calls became tedious, buggy, and generally maddening.  I really needed to be able to dynamically discover all the pertinent info about the parameters for each sproc, and then spin up the call on the fly.  As part of the solution, I created a sproc that brings back a recordset of all input and output parameters and metadata for each.  Basically this sproc looks into the system tables and extracts all of the needed info.</p>
<p>This turns out to be particularly useful if you have large sets of data in which the names can be dynamically mapped to the param names.  It&#8217;s suddenly a concise and simple matter to dynamically make large sproc calls.This procedure is simply called by passing in the name of the sproc that you want to examine.  The sproc code is commented with an explanation of each return field.</p>
<p>This is compatible with Sql Server 2005 and 2008.</p>
<p>Example call:</p>
<pre name="code" class="sql">EXEC    spStoredProcParamLookup @ipSprocName = 'spTestSproc'</pre>
<p><span class="mt-enclosure mt-enclosure-image"><img class="mt-image-left" style="float: left;margin: 0 20px 20px 0" src="http://blog.arc90.com/images/blogImages/sql.png" alt="sql.png" width="635" height="45" /></span></p>
<p><span id="more-174"></span></p>
<hr />
<pre name="code" class="sql">

 /************************************************************************************
 Software License Agreement (BSD License)
 Copyright (c) 2008, Arc90 Inc.
 All rights reserved.
 Redistribution and use of this software in source and binary forms, with or
 without modification, are permitted provided that the following conditions
 are met:
 - Redistributions of source code must retain the above copyright notice,
 this list of conditions and the following disclaimer.
 - Redistributions in binary form must reproduce the above copyright notice,
 this list of conditions and the following disclaimer in the documentation
 and/or other materials provided with the distribution.
 - Neither the name of Arc90 Inc. nor the names of its contributors may be
 used to endorse or promote products derived from this software without
 specific prior written permission of Arc90 Inc.
 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 POSSIBILITY OF SUCH DAMAGE.
 ***********************************************************************************/
 set ANSI_NULLS ON
 set QUOTED_IDENTIFIER ON
 GO
 CREATE PROCEDURE spStoredProcParamLookup
 -- The name of the sproc for which the params are being found
 @ipSprocName    VARCHAR(100)
 AS
 -- ======================================================
 -- Make sure there is a valid value for the sproc name
 -- ======================================================
 -- Check for blank or null
 IF @ipSprocName IS NULL OR @ipSprocName = ''
 BEGIN
 RAISERROR ('There must be a valid (non-empty and non-null) value for the param @ipSprocName',10,1)
 END
 -- Trim off extra spaces when user is typing information
 SELECT    @ipSprocName = LTRIM(RTRIM(@ipSprocName))
 -- ======================================================
 -- Get the data
 -- ======================================================
 SELECT		-- Name of the parameter. Is unique within the object. (includes preceding @)
 -- Datatype: sysname
 sp.name AS ParamName,
 -- ID of the parameter. Is unique within the object.
 -- Datatype: int
 sp.parameter_id AS ParamID,
 -- Maximum length of the parameter, in bytes.
 -- Value = -1 when the column data type is varchar(max), nvarchar(max), varbinary(max), or xml.
 -- Datatype: smallint
 sp.max_length AS MaxLength,
 -- A restatement of the original sproc name (same as value of @ipSprocName)
 -- This is just a convenience
 -- Datatype: sysname
 so.name AS ProcName,
 -- A string denoting the name of the datatype of the param (ie. Varchar)
 -- Datatype: sysname
 st.name AS DataTypeName,
 -- An int denoting the datatype of the param.  Sql Server assigns each datatype a unique int id.
 -- The full list of these types can be found in the table systypes.
 -- Datatype: tinyint
 st.type AS DataTypeID,
 -- Precision of the parameter if numeric-based; otherwise, 0.
 -- Datatype: tinyint
 sp.precision AS ParamPrecision,
 -- This denotes whether or not this is an output param
 -- 1 = an output param / 0 = input param
 -- Datatype: bit
 sp.is_output AS IsOutput,
 -- This denotes where or not there is a default value set for this param.
 -- 1 = Parameter has default value / 0 = does not
 -- This implicitly tells whether or not the param is required. A param with a
 -- default value specified is not required.
 -- Datatype: bit
 sp.has_default_value AS HasDefaultValue
 FROM		sys.objects so
 INNER JOIN	sys.parameters sp ON (so.object_id = sp.object_id)
 INNER JOIN	sys.syscolumns sc ON so.object_id = sc.id
 INNER JOIN	sys.systypes st ON st.xusertype = sc.xusertype
 WHERE		sc.colid = sp.parameter_id
 AND			so.name = @ipSprocName
 ORDER BY	sp.parameter_id
 GO
 </pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.arc90.com/2009/02/12/sql-server-stored-procedure-introspection/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Regexing to extract HTTP status codes</title>
		<link>http://blog.arc90.com/2009/02/04/regexing-to-extract-http-status-codes/</link>
		<comments>http://blog.arc90.com/2009/02/04/regexing-to-extract-http-status-codes/#comments</comments>
		<pubDate>Wed, 04 Feb 2009 18:24:51 +0000</pubDate>
		<dc:creator>Joel Potischman</dc:creator>
				<category><![CDATA[Quick Tips]]></category>

		<guid isPermaLink="false">http://blog.daniell.acr90-dev-02/2009/02/04/regexing-to-extract-http-status-codes/</guid>
		<description><![CDATA[Today I was trying to figure out why a library I called was throwing unhandled exceptions when it called a REST web service that was (correctly) returning 401 Unauthorized. It turns out that the library, which does nothing but handle HTTP requests, throws WebExceptions, not the HttpExceptions I expected. All&#8230; <a href="http://blog.arc90.com/2009/02/04/regexing-to-extract-http-status-codes/">More</a>]]></description>
			<content:encoded><![CDATA[<p>Today I was trying to figure out why a library I called was throwing unhandled exceptions when it called a REST web service that was (correctly) returning 401 Unauthorized. It turns out that the library, which does nothing but handle HTTP requests, throws WebExceptions, not the HttpExceptions I expected. All I had to go on was the exception message text <em>The remote server returned an error: (401) Unauthorized.</em></p>
<p>Since HttpException exposes a GetHttpCode() method and WebException does not, the HTTP status code from the underlying service was being discarded by this library, which made it impossible for me to automate error handling by status code. The <em>right</em> way to solve this problem is to fix the library to throw HttpExceptions to preserve status codes. But the <em>right now</em> way was to use regular expressions to see when these exception messages contained a three-digit number starting with 4 or 5 (e.g. 401, 404, 500) and wrap it in my own HttpException so that the caller further up the chain can process it automatically.</p>
<p>Note that an exception message like <em>404 is not a valid credit card number</em> would get erroneously treated as a 404 File Not Found exception. However, in this case where I know the library and the service involved I think it&#8217;s safe to do. But I&#8217;m still going to fix the offending code ASAP!
</p>
<pre name="code">    // C#
try
{
// call the library that might throw the exception
// that ought to be an HttpException
}
catch(System.Web.HttpException) // it's already an HttpException, so throw it as-is
{
throw;
}
catch(Exception ex) // any other exception
{
// If the exception message contains a 3-digit number starting
// with 4 or 5, assume it's the correct HTTP status code.
// NOTE! Know your library to know if that's a safe assumption!
Regex httpErrorRegex = new Regex("((4|5)\\d{2})(?!\\d)");
if(httpErrorRegex.IsMatch(ex.Message))
{
int httpStatusCode = int.Parse(httpErrorRegex.Match(ex.Message)
.Captures[0].Value);
throw new HttpException(httpStatusCode, ex.Message, ex);
}
// No 3-digit HTTP error code found in the message, so default to a 500 error
throw new HttpException(500, ex.Message, ex);
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.arc90.com/2009/02/04/regexing-to-extract-http-status-codes/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Trac Bookmarklet</title>
		<link>http://blog.arc90.com/2009/01/27/trac-bookmarklet/</link>
		<comments>http://blog.arc90.com/2009/01/27/trac-bookmarklet/#comments</comments>
		<pubDate>Tue, 27 Jan 2009 18:26:12 +0000</pubDate>
		<dc:creator>Joel Potischman</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Quick Tips]]></category>

		<guid isPermaLink="false">http://blog.daniell.acr90-dev-02/2009/01/27/trac-bookmarklet/</guid>
		<description><![CDATA[Already know your Trac ticket number and don&#8217;t want to type a URL, scroll through your browser history, or have to search your Trac tickets? Customize server and path and save this bookmarklet for any Trac you use regularly: If you save the bookmarklet to your browser&#8217;s toolbar you simply&#8230; <a href="http://blog.arc90.com/2009/01/27/trac-bookmarklet/">More</a>]]></description>
			<content:encoded><![CDATA[<p>Already know your <a href="http://trac.edgewall.org/" target="_blank">Trac</a> ticket number and don&#8217;t want to type a URL, scroll through your browser history, or have to search your Trac tickets? Customize <em>server</em> and <em>path</em> and save this bookmarklet for any Trac you use regularly:</p>
</p>
<p>
If you save the bookmarklet to your browser&#8217;s toolbar you simply click once, enter the ticket number, and you&#8217;re in your ticket.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.arc90.com/2009/01/27/trac-bookmarklet/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Encoding and XML</title>
		<link>http://blog.arc90.com/2009/01/06/encoding-and-xml/</link>
		<comments>http://blog.arc90.com/2009/01/06/encoding-and-xml/#comments</comments>
		<pubDate>Tue, 06 Jan 2009 18:22:56 +0000</pubDate>
		<dc:creator>Joel Potischman</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Quick Tips]]></category>

		<guid isPermaLink="false">http://blog.daniell.acr90-dev-02/2009/01/06/encoding-and-xml/</guid>
		<description><![CDATA[In speccing a project last month, we discussed the best way to attach PDFs to the XML documents we send between very distributed systems. We quickly decided it would avoid a whole host of atomicity, reliability, and redesign issues to simply update our XML schema to include Base64 encoded documents&#8230; <a href="http://blog.arc90.com/2009/01/06/encoding-and-xml/">More</a>]]></description>
			<content:encoded><![CDATA[<p>In speccing a project last month, we discussed the best way to attach PDFs to the XML documents we send between very distributed systems. We <a href="http://blog.arc90.com/2008/12/groovy_and_python_for_quick_sc.php" target="_blank">quickly</a> decided it would avoid a whole host of atomicity, reliability, and redesign issues to simply update our XML schema to include Base64 encoded documents inside the body of the XML document itself.</p>
<p>For my half of our application ecosystem I researched .NET&#8217;s Base64 encoding/decoding support, got curious about character set encoding, and set out to write a universal encoder to make it simple, easy, and guaranteed safe to insert any kind of binary or text data into an XML document.</p>
<p>But first, a quick nano-refresher: <a href="http://en.wikipedia.org/wiki/Character_encoding" target="_blank">Character encoding</a> specifies how a string of bytes should be mapped to specific text characters. In the simplest case, ASCII, one byte maps to one of 256 possible characters. 65=A, 66=B, &#8230;. 90=Z, etc. In <a href="http://en.wikipedia.org/wiki/Unicode" target="_blank">Unicode</a>, two (or even four) bytes map to thousands or even (theoretically) billions of characters. So when my program reads four bytes from a text file, I need to know if it represents four 1-byte characters, two 2-byte characters, or one 4-byte character. It&#8217;s actually <a href="http://en.wikipedia.org/wiki/Endianness" target="_blank">even</a> <a href="http://en.wikipedia.org/wiki/Character_encoding" target="_blank">more</a> <a href="http://en.wikipedia.org/wiki/Byte_order_mark" target="_blank">complicated</a> than that, but the basic problem is making sure I don&#8217;t accidentally turn a 400-byte ASCII text file into 200 Japanese characters. Or vice versa. Or garbage.</p>
<p>Fortunately, .NET has robust support for character encoding, so all I have to do is load the correct encoding class and ask it to take care of this for me. If I know I will only ever need to deal with Unicode, that class is <strong>Encoding.Unicode</strong>, but for maximum flexibility I can call <strong>Encoding.GetEncoding(encodingName)</strong> and get any encoding by name. Like so:</p>
<pre class="java" name="code">
public string GetStringFromFile(string myFilename, string encodingName)
{
byte[] fileBytes = System.IO.File.ReadAllBytes(myFilename);
System.Text.Encoding myEncoding = System.Text.Encoding.GetEncoding(encodingName);
return myEncoding.GetString(fileBytes);
}
</pre>
<p>After I&#8217;m done modifying that string I can easily convert it back into a byte array and save it, preserving the original character encoding:</p>
<pre class="java" name="code">
public void SaveStringToFile(string myFilename, string encodingName, string myString)
{
System.Text.Encoding myEncoding = System.Text.Encoding.GetEncoding(encodingName);
byte[] fileBytes = myEncoding.GetBytes(myString);
System.IO.File.WriteAllBytes(myFilename, fileBytes);
}
</pre>
<p>But now let&#8217;s get back to my actual business problem, storing a PDF or other binary data in my XML document. Because the bytes I encounter are not supposed to represent character data, attempting to map them to characters may result in nonsense. For example, whether I decode the byte sequence <strong>00 00 00 00</strong> as ASCII, Unicode, or UTF-32, I get either one, two, or four <a href="http://en.wikipedia.org/wiki/Null_character" target="_blank">null characters</a> that will screw up string processing. Note that use of CDATA sections doesn&#8217;t help. Only being very lucky about which byte sequences I encounter would avert disaster, and I don&#8217;t like writing lucky code.</p>
<p>Enter <a href="http://en.wikipedia.org/wiki/Base64" target="_blank">Base64</a>, which is designed for exactly this purpose: encoding arbitrary binary data into a string guaranteed to consist of only &#8220;safe&#8221; ASCII characters and decoding that string back to bytes with 100% fidelity later. Microsoft places Base64 functionality under the <strong>System.Convert</strong> class, not <strong>System.Text.Encoding</strong> because it&#8217;s more of a conversion and translation process, not a direct byte-to-character encoding like those described above.</p>
<p>To read a file into a Base64 string:</p>
<pre name="code" class="java">
public string GetBase64StringFromFile(string myFilename)
{
byte[] fileBytes = System.IO.File.ReadAllBytes(myFilename);
return Convert.ToBase64String(fileBytes, Base64FormattingOptions.InsertLineBreaks);
}
</pre>
<p>And to decode it and save it back to the filesystem:</p>
<pre name="code" class="java">
public void SaveBase64StringToFile(string myFilename, string myString)
{
byte[] fileBytes = Convert.FromBase64String(myString);
System.IO.File.WriteAllBytes(myFilename, fileBytes);
}
</pre>
<p>I combined both &#8220;real&#8221; character encodings and Base64 encoding in my XmlFileEncoder class (attached) to provide unified access to both encodings when working with XML documents. If you know you&#8217;re dealing with Unicode, simply call <strong>XmlFileEncoder.InsertFileIntoXmlDocument</strong> with the encoding <em>UTF-16</em> and the file will safely be inserted as text. If you don&#8217;t always know the file format, or you are dealing with binary files, simply call the same method with the encoding <em>Base64</em>. In either case, a new node will be added to contain your file data and the <em>encoding</em> attribute will record the encoding method so <strong>XmlFileEncoder.ExtractFileFromXmlDocument</strong> will use the correct character/Base64 decoding automatically.</p>
<p>The demo WinForms app starts up displaying an XML document with some UTF-16 data already encoded into it. Use the controls along the bottom to experiment with inserting differently encoded files (provided, or use your own) using different application character encodings. Some files will clearly look wrong in the XML when you select the wrong encoding. Others may look correct, or almost correct, but when you press the SaveEncodedFile to File button it will report Copy accuracy FAILED when it verifies against the source file. However, the files encoded and decoded using Base64 will <u>always</u> copy accurately. The only downside is that Base64 encoded data is always 1/3 bigger and much less human readable than the source.</p>
<p>You can find the source code here: <span class="mt-enclosure mt-enclosure-file"><a href="http://blog.arc90.com/XmlEncodingDemo.zip">XmlEncodingDemo.zip</a></span></p>
<p>Have a happy, healthy, and correctly encoded 2009!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.arc90.com/2009/01/06/encoding-and-xml/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Gotcha: Adding Metadata to a Flex Component</title>
		<link>http://blog.arc90.com/2008/12/08/gotcha-adding-metadata-to-a-flex-component/</link>
		<comments>http://blog.arc90.com/2008/12/08/gotcha-adding-metadata-to-a-flex-component/#comments</comments>
		<pubDate>Mon, 08 Dec 2008 20:30:27 +0000</pubDate>
		<dc:creator>Javier Julio</dc:creator>
				<category><![CDATA[Quick Tips]]></category>

		<guid isPermaLink="false">http://blog.daniell.acr90-dev-02/2008/12/08/gotcha-adding-metadata-to-a-flex-component/</guid>
		<description><![CDATA[Recently, I noticed that as I was adding event metadata to my custom Flex components, Flex Builder wasn&#8217;t giving me code hints for those configured events. For example, I would do the following: [Event(name='complete', type='flash.events.Event')] Since I wasn&#8217;t seeing the event in the code hints list I looked at some&#8230; <a href="http://blog.arc90.com/2008/12/08/gotcha-adding-metadata-to-a-flex-component/">More</a>]]></description>
			<content:encoded><![CDATA[<p>Recently, I noticed that as I was adding event metadata to my custom Flex components, Flex Builder wasn&#8217;t giving me code hints for those configured events. For example, I would do the following:</p>
<pre name="code">
[Event(name='complete', type='flash.events.Event')]
</pre>
<p>Since I wasn&#8217;t seeing the event in the code hints list I looked at some inner Flex framework components like Button or TextInput to see what I was doing wrong. Everything matched but then I realized the only difference was that they used double quotes. Aha! Once I switched the above metadata example to the following, everything worked out:</p>
<pre name="code">
[Event(name="complete", type="flash.events.Event")]
</pre>
<p>The complete event showed up in the code hints list when trying to add an event listener for my custom component. This isn&#8217;t a complaint on Flex Builder, as I normally  use double quotes&#8211;so I blame this on laziness and copying and pasting the metadata line but to others be careful and note to see the event (or any other metadata type e.g. styles) show up in the code hints list always use double quotes!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.arc90.com/2008/12/08/gotcha-adding-metadata-to-a-flex-component/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Java Quick Tip: Parameterized Logging</title>
		<link>http://blog.arc90.com/2008/12/02/java-quick-tip-parameterized-logging/</link>
		<comments>http://blog.arc90.com/2008/12/02/java-quick-tip-parameterized-logging/#comments</comments>
		<pubDate>Tue, 02 Dec 2008 17:50:10 +0000</pubDate>
		<dc:creator>Doug Burns</dc:creator>
				<category><![CDATA[Quick Tips]]></category>

		<guid isPermaLink="false">http://blog.daniell.acr90-dev-02/2008/12/02/java-quick-tip-parameterized-logging/</guid>
		<description><![CDATA[I hate writing ugly, concatenated logging statements like this: package com.arc90.example; import java.util.logging.Logger; public class LoggingExample1 { public static void main(String[] args) { Logger logger = Logger.getLogger(LoggingExample1.class.getName()); String user = "dougb"; int logins = 17; int purchases = 2; logger.info("User " + user + " has logged in " +&#8230; <a href="http://blog.arc90.com/2008/12/02/java-quick-tip-parameterized-logging/">More</a>]]></description>
			<content:encoded><![CDATA[<p>I hate writing ugly, concatenated logging statements like this:</p>
<pre name="code">
package com.arc90.example;
import java.util.logging.Logger;
public class LoggingExample1
{
public static void main(String[] args)
{
Logger logger = Logger.getLogger(LoggingExample1.class.getName());
String user = "dougb";
int logins = 17;
int purchases = 2;
logger.info("User " + user + " has logged in " + logins +
" times and made " + purchases + " purchases.");
}
}
</pre>
<p><span id="more-175"></span></p>
<p>Fortunately, the Java Logging API gives you the ability to parameterize your statements (similar to JDBC prepared statements) so that you can turn the above into something like this:</p>
<pre name="code">
package com.arc90.example;
import java.util.logging.Level;
import java.util.logging.Logger;
public class LoggingExample2
{
public static void main(String[] args)
{
Logger logger = Logger.getLogger(LoggingExample2.class.getName());
String user = "dougb";
int logins = 17;
int purchases = 2;
// Single parameter
logger.log(Level.INFO, "User {0} successfully logged in.", user);
// Multiple parameters
logger.log(Level.INFO, "User {0} has logged in {1} times and made {2} purchases.",
new Object[] {user, logins, purchases});
}
}
</pre>
<p>
You&#8217;ll need to use the logger.log(&#8230;) method rather than the more convenient logger.fine(&#8230;), logger.info(&#8230;) (etc.) methods, but in the end it makes for much cleaner code.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.arc90.com/2008/12/02/java-quick-tip-parameterized-logging/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Enabling SSL on Windows with PHP and the Zend Framework</title>
		<link>http://blog.arc90.com/2008/11/11/enabling-ssl-on-windows-with-php-and-the-zend-framework/</link>
		<comments>http://blog.arc90.com/2008/11/11/enabling-ssl-on-windows-with-php-and-the-zend-framework/#comments</comments>
		<pubDate>Tue, 11 Nov 2008 18:15:00 +0000</pubDate>
		<dc:creator>Michael Rehse</dc:creator>
				<category><![CDATA[Quick Tips]]></category>

		<guid isPermaLink="false">http://blog.daniell.acr90-dev-02/2008/11/11/enabling-ssl-on-windows-with-php-and-the-zend-framework/</guid>
		<description><![CDATA[Ever tried to use HTTPS with PHP and the Zend Framework on Windows, but only received an error for all your troubles? Perhaps an error like: Unable to Connect to ssl://( your host name):443. Error #175113224: Unable to find the socket transport "ssl" - did you forget to enable it&#8230; <a href="http://blog.arc90.com/2008/11/11/enabling-ssl-on-windows-with-php-and-the-zend-framework/">More</a>]]></description>
			<content:encoded><![CDATA[<p>Ever tried to use HTTPS with PHP and the Zend Framework on Windows, but only received an error for all your troubles? Perhaps an error like: </p>
<pre name="code">
Unable to Connect to ssl://( your host name):443.
Error #175113224: Unable to find the socket transport "ssl" -
did you forget to enable it when you configured PHP?</pre>
<p>The problem lies in your version of OpenSSL and certain configuration parameters.</p>
<p>HTTPS relies on SSL to transport your data securely and PHP usually uses the OpenSSL implementation of SSL. Problems occur when your versions of OpenSSL are out of sync with each other.</p>
<p>The best option is to always keep ALL of your software 100% up-to-date at all times&#8211;but sometimes you are not able to do a full software update for one reason or another.</p>
<p><span id="more-172"></span></p>
<p>This is how to ensure OpenSSL works for you:</p>
<p>There are 4 required files for openSSL: libeay32.dll, ssleay32.dll, php_openssl.dll, and openssl.cnf.</p>
<p>libeay32.dll and ssleay32.dll are usually already installed in multiple places, but are usually in different versions. The safest thing to do is rename all the current files and copy in a known version. Make sure you have the most current version by installing the most current version from this site: <a href="http://www.slproweb.com/products/Win32OpenSSL.html" target="_blank">Shining Light Productions</a></p>
<p>It is probably best to do a search for these files to see all the locations, but they usually live in the following places on a 64-Bit server:</p>
<pre name="code">
C:\Program Files (x86)\PHP
C:\Program Files (x86)\Apache Group\Apache2\bin
C:\Windows\SysWOW64
</pre>
<p>Go to all of these places and rename the files libeay32-old.dll and ssleay32-old.dll, respectively, then copy libeay32.dll and ssleay32.dll to those locations.</p>
<p>If it doesn&#8217;t already exist, copy php_openssl.dll to:</p>
<pre>
C:\Program Files (x86)\PHP\ext 
</pre>
<p>If you do not have php_openssl.dll, one place to find it is <a href="http://www.dlldll.com/php_openssl.dll_download.htm" target="_blank">here.</a></p>
<p>If it doesn&#8217;t already exist, copy openssl.cnf to:</p>
<pre>
C:\Program Files (x86)\PHP\extra\openssl</pre>
<p>Create directories if they do not already exist. If you do not have openssl.cnf, you can download PHP&#8217;s default cnf file <a href="http://arc90.com/temp/openssl.cnf" target="_blank">here.</a></p>
<p>Add the following line to php.ini:</p>
<pre>
extension=php_openssl.dll</pre>
<p>Make sure the following line is uncommented in httpd.conf:</p>
<pre>
LoadModule ssl_module modules/mod_ssl.so</pre>
<p>Restart Apache.</p>
<p>You&#8217;re done!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.arc90.com/2008/11/11/enabling-ssl-on-windows-with-php-and-the-zend-framework/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ignore Double Slashes in URLs in Restlet Applications</title>
		<link>http://blog.arc90.com/2008/11/05/ignore-double-slashes-in-urls-in-restlet-applications/</link>
		<comments>http://blog.arc90.com/2008/11/05/ignore-double-slashes-in-urls-in-restlet-applications/#comments</comments>
		<pubDate>Wed, 05 Nov 2008 21:00:00 +0000</pubDate>
		<dc:creator>Avi Flax</dc:creator>
				<category><![CDATA[Quick Tips]]></category>

		<guid isPermaLink="false">http://blog.daniell.acr90-dev-02/2008/11/05/ignore-double-slashes-in-urls-in-restlet-applications/</guid>
		<description><![CDATA[Every once in a while, people accidentally type two slashes instead of one in their URLs. The Apache httpd server will automatically ignore the double slashes, and treat the URL as if the double slash was a single slash. This is helpful; the server is giving the user what they&#8230; <a href="http://blog.arc90.com/2008/11/05/ignore-double-slashes-in-urls-in-restlet-applications/">More</a>]]></description>
			<content:encoded><![CDATA[<p>Every once in a while, people accidentally type two slashes instead of one in their URLs.</p>
<p>The Apache httpd server will automatically ignore the double slashes, and treat the URL as if the double slash was a single slash. This is helpful; the server is giving the user what they want, even though they technically didn&#8217;t ask for it correctly.</p>
<p>Reslet&#8217;s Router class, however, isn&#8217;t so forgiving. If you accidentally include a double-slash in the URL of a request, a Restlet application will probably return a 404 Not Found status code.
<p>Thankfully, Restlet&#8217;s request handling process is so flexible, we can easily add a Filter which will cause the application to ignore double slashes, just like httpd.</p>
<p>If your application uses a subclass of Restlet&#8217;s Application class, then it is overriding the default <code>getRoot()</code> method to provide your own request handling Restlets.</p>
<p>A standard <code>getRoot()</code> might look something like this:
<pre name="code">
@Override
public Restlet getRoot()
{
Router router = new Router();
// Attach all the routes
router.attach("path", ResourceClass.class);
return router;
}
</pre>
<p>In order to remove double slashes from request URLs before they reach the router, we can create an anonymous Filter class and return it as<br />
the root of the application:
<pre name="code">
@Override
public Restlet getRoot()
{
Filter doubleSlashFilter = new Filter() {
@Override
protected int beforeHandle(Request request, Response response) {
Reference ref = request.getResourceRef();
String originalPath = ref.getPath();
if (originalPath.contains("//"))
{
String newPath = originalPath.replaceAll("//", "/");
ref.setPath(newPath);
}
return Filter.CONTINUE;
}
};
Router router = new Router();
// Attach all the routes
router.attach("path", ResourceClass.class);
doubleSlashFilter.setNext(router);
return doubleSlashFilter;
}
</pre>
<p>And that&#8217;s it! The application will now ignore double slashes, and will successfully serve requests that accidentally include them.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.arc90.com/2008/11/05/ignore-double-slashes-in-urls-in-restlet-applications/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

