<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-11240984</id><updated>2011-11-08T20:29:01.576-08:00</updated><category term='Printing'/><category term='JPA'/><category term='Wordpress'/><category term='Architecture'/><category term='SQL'/><category term='javascript'/><category term='JSP'/><category term='Orbeon XForms'/><category term='NIX administration'/><category term='Matlab'/><category term='DIY'/><category term='perl'/><category term='Hibernate'/><category term='AJAX'/><category term='browser quirks'/><category term='Windows'/><category term='Oracle'/><category term='Reporting'/><category term='Arduino'/><category term='Networking'/><category term='Mobile Development'/><category term='Solaris'/><category term='XHTML'/><category term='JUnit'/><category term='Virtualization'/><category term='Android'/><category term='Video'/><category term='XForms'/><category term='Scalability'/><category term='Struts'/><category term='SSH'/><category term='XSL'/><category term='CSS'/><category term='JSTL'/><category term='XML'/><category term='Design'/><category term='Java'/><category term='CouchDB'/><category term='PHP'/><category term='Tomcat'/><category term='Netbeans'/><category term='Web Graphics'/><category term='Mirth Project'/><category term='LAMPS'/><category term='Eclipse'/><category term='HTML'/><category term='Tools'/><category term='Audio Recording'/><category term='SVN'/><title type='text'>Peter's Notes</title><subtitle type='html'>Demystifying open source</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://petersnotes.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://petersnotes.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default?start-index=101&amp;max-results=100'/><author><name>Peter V</name><uri>http://www.blogger.com/profile/17919841991959605501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>229</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-11240984.post-8778705377816356790</id><published>2011-11-08T11:11:00.000-08:00</published><updated>2011-11-08T11:15:34.076-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Arduino'/><title type='text'>Using an AVR ISP Mk II with the Arduino IDE</title><content type='html'>It is possible to program an AVR on an Arduino board using the AVR ISP Mk II programmer directly from the Arduino IDE.  The process is faster and an Arduino bootloader is not required to be loaded on the AVR, so you can program AVRs purchased from Mouser, Digikey, etc and then transfer them to a permanent circuit board.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Simply edit boards.txt (location varies-- try searching your root arduino software folder) and add:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;atmega328ii.name=Arduino Duemilanove ATmega328 AVR ISP Mk II&lt;br /&gt;&lt;br /&gt;atmega328ii.upload.protocol=stk500&lt;br /&gt;atmega328ii.upload.maximum_size=30720&lt;br /&gt;atmega328ii.upload.speed=57600&lt;br /&gt;&lt;br /&gt;atmega328ii.upload.using=avrispmkii&lt;br /&gt;atmega328ii.build.mcu=atmega328p&lt;br /&gt;atmega328ii.build.f_cpu=16000000L&lt;br /&gt;atmega328ii.build.core=arduino&lt;br /&gt;&lt;br /&gt;##############################################################&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Then you can go to Tools&amp;gt;Boards&amp;gt; and select ATMega 328 ISP from the list.  Attach your AVR ISP Mk II to the Arduino board (make sure the orientation is correct-- both of the AVR and the ISP cable).  Hit program as normal. Voila!&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11240984-8778705377816356790?l=petersnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petersnotes.blogspot.com/feeds/8778705377816356790/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11240984&amp;postID=8778705377816356790' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/8778705377816356790'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/8778705377816356790'/><link rel='alternate' type='text/html' href='http://petersnotes.blogspot.com/2011/11/using-avr-isp-mk-ii-with-arduino-ide.html' title='Using an AVR ISP Mk II with the Arduino IDE'/><author><name>Peter V</name><uri>http://www.blogger.com/profile/17919841991959605501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11240984.post-592373973566679924</id><published>2011-10-14T15:08:00.000-07:00</published><updated>2011-10-14T15:09:36.172-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='CSS'/><title type='text'>CSS Radial Backgrounds</title><content type='html'>&lt;div&gt;CSS3 allows you to make radial gradients fairly easily.  Unfortunately, you need six lines to cover all the browsers that support CSS3, but luckily all but the old webkit syntax are very similar.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;a href="http://www.impressivewebs.com/css3-radial-gradient-syntax/"&gt;http://www.impressivewebs.com/css3-radial-gradient-syntax/&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11240984-592373973566679924?l=petersnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petersnotes.blogspot.com/feeds/592373973566679924/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11240984&amp;postID=592373973566679924' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/592373973566679924'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/592373973566679924'/><link rel='alternate' type='text/html' href='http://petersnotes.blogspot.com/2011/10/css-radial-backgrounds.html' title='CSS Radial Backgrounds'/><author><name>Peter V</name><uri>http://www.blogger.com/profile/17919841991959605501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11240984.post-8866743527663347133</id><published>2011-10-14T15:05:00.001-07:00</published><updated>2011-10-14T15:07:40.425-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='CSS'/><title type='text'>Full Screen Background Image with CSS</title><content type='html'>&lt;div&gt;Since the height attribute doesn't work so well in CSS backgrounds (100% will not actually cause your background image to scale to the full height of the window, for example), if you want a full screen background you'll have to go another route. Luckily, this solution is written up cleanly:&lt;/div&gt;&lt;a href="http://paulmason.name/blog/item/full-screen-background-image-pure-css-code"&gt;http://paulmason.name/blog/item/full-screen-background-image-pure-css-code&lt;/a&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Simply copy #&lt;span class="Apple-style-span" style="color: rgb(42, 96, 38); font-family: Consolas, 'Lucida Console', monospace; font-size: 15px; white-space: pre-wrap; background-color: rgb(255, 255, 255); "&gt;full-screen-background-image &lt;/span&gt;and you're good to go.  The styling also works for DIVs.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11240984-8866743527663347133?l=petersnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petersnotes.blogspot.com/feeds/8866743527663347133/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11240984&amp;postID=8866743527663347133' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/8866743527663347133'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/8866743527663347133'/><link rel='alternate' type='text/html' href='http://petersnotes.blogspot.com/2011/10/full-screen-background-image-with-css.html' title='Full Screen Background Image with CSS'/><author><name>Peter V</name><uri>http://www.blogger.com/profile/17919841991959605501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11240984.post-6701164288905058824</id><published>2011-02-07T22:43:00.000-08:00</published><updated>2011-02-07T22:46:34.195-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='HTML'/><title type='text'>Google Chrome Keeps Caching Code</title><content type='html'>Google Chrome is nice for mobile apps because it has decent developer tools and can render webkit css properties (otherwise, Firefox has better debugging facilities).&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;What is maddening is that Chrome randomly seems to cache pages regardless of header settings.  During development, pages are updated very often-- making debugging in Chrome supremely frustrating.  I've only found two solutions:&lt;/div&gt;&lt;div&gt;&lt;ol&gt;&lt;li&gt;Reboot&lt;/li&gt;&lt;li&gt;Append a dummy variable to the page URL (for example, myapp.com/index.php?google_sucks=1&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11240984-6701164288905058824?l=petersnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petersnotes.blogspot.com/feeds/6701164288905058824/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11240984&amp;postID=6701164288905058824' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/6701164288905058824'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/6701164288905058824'/><link rel='alternate' type='text/html' href='http://petersnotes.blogspot.com/2011/02/google-chrome-keeps-caching-code.html' title='Google Chrome Keeps Caching Code'/><author><name>Peter V</name><uri>http://www.blogger.com/profile/17919841991959605501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11240984.post-1976329836065301786</id><published>2011-02-07T17:44:00.000-08:00</published><updated>2011-02-07T17:48:01.822-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='HTML'/><title type='text'>JSLint</title><content type='html'>Lint is a tool which finds common errors in Java code.  It's very handy and is usually able to find *something* you ought to fix.  Well, there's a JSLint for Javascript too!&lt;div&gt;&lt;a href="http://www.jslint.com/"&gt;http://www.jslint.com&lt;/a&gt;&lt;/div&gt;&lt;div&gt;Note, it will complain about globals (like alert).  You can, at the top of your javascript, put a comment and define a comma delimited list of globals to ignore:&lt;/div&gt;&lt;div&gt;&lt;pre&gt;/*global alert, console, $, $$ */&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11240984-1976329836065301786?l=petersnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petersnotes.blogspot.com/feeds/1976329836065301786/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11240984&amp;postID=1976329836065301786' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/1976329836065301786'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/1976329836065301786'/><link rel='alternate' type='text/html' href='http://petersnotes.blogspot.com/2011/02/jslint.html' title='JSLint'/><author><name>Peter V</name><uri>http://www.blogger.com/profile/17919841991959605501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11240984.post-2578428404254018804</id><published>2011-02-01T23:14:00.001-08:00</published><updated>2011-02-01T23:16:16.708-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PHP'/><title type='text'>Admin Pages Generator</title><content type='html'>Writing pages to administer tables is a pain, even if they're basic.  But no more. &lt;a href="http://www.phpscaffold.com/"&gt; See the attached generator&lt;/a&gt;.  Doesn't work for more complex stuff needing joins etc but its a good quick start.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11240984-2578428404254018804?l=petersnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petersnotes.blogspot.com/feeds/2578428404254018804/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11240984&amp;postID=2578428404254018804' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/2578428404254018804'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/2578428404254018804'/><link rel='alternate' type='text/html' href='http://petersnotes.blogspot.com/2011/02/admin-pages-generator.html' title='Admin Pages Generator'/><author><name>Peter V</name><uri>http://www.blogger.com/profile/17919841991959605501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11240984.post-7893493322439555927</id><published>2011-02-01T23:10:00.000-08:00</published><updated>2011-02-01T23:14:10.161-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PHP'/><title type='text'>PHP Data Access Object Generator</title><content type='html'>When coding in Java, I always used Netbean's auto generation of entity beans.  In minutes you can have a couple dozen entity beans created (add the CXF generator and you get the CRUD services to access those entities also!).&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;With PHP, things aren't so advanced.  &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;But, I did &lt;a href="http://phpdao.com/"&gt;find a PHP script&lt;/a&gt; to generate DAOs for MySQL.  The trouble is it comes with no documentation!&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Luckily someone on devx &lt;a href="http://www.devx.com/webdev/Article/42625/0/"&gt;wrote a tutorial&lt;/a&gt;.  You do need to login, but that's what &lt;a href="http://bugmenot.com/view/devx.com"&gt;bugmenot is for&lt;/a&gt;.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11240984-7893493322439555927?l=petersnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petersnotes.blogspot.com/feeds/7893493322439555927/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11240984&amp;postID=7893493322439555927' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/7893493322439555927'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/7893493322439555927'/><link rel='alternate' type='text/html' href='http://petersnotes.blogspot.com/2011/02/php-data-access-object-generator.html' title='PHP Data Access Object Generator'/><author><name>Peter V</name><uri>http://www.blogger.com/profile/17919841991959605501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11240984.post-4076726243206333425</id><published>2011-01-17T22:58:00.000-08:00</published><updated>2011-01-17T23:16:30.943-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Mobile Development'/><title type='text'>iPhone Cookie Hell</title><content type='html'>I was having a hell of a time getting a mobile website to logout iPhone users.  The website uses cookies to keep track of logged in users, and the cookies would simply not delete on an iPhone.  Worked fine on Android, Chrome, Safari (on the desktop), etc.  The app used the textbook method for deleting cookies in PHP, setting the expiration to a time in the past:&lt;br /&gt;&lt;br /&gt;setcookie($usercookie, '', time()-3600);&lt;br /&gt;&lt;br /&gt;And then redirected the user to a page with a check for a logged in user which started with;&lt;br /&gt;&lt;br /&gt;if(!isset($_COOKIE[$usercookie])) { ... }&lt;br /&gt;&lt;br /&gt;Which always said the cookie WAS set.  Hey, I just deleted it!&lt;br /&gt;&lt;br /&gt;After much pulling of hair, I realized that Mobile Safari won't delete cookies until the user returns from the browser to the home screen.  You can ask it to delete the cookie, but those requests just seem to queue up until that return to the home screen.  But, it will update their values immediately.  So now my logout php looks like:&lt;br /&gt;&lt;br /&gt;setcookie($usercookie, ''); // null the cookie value, without specifying a time, for the iPhone&lt;br /&gt;setcookie($usercookie, '', time()-3600, '/');  // delete the cookie, for all other browsers&lt;br /&gt;&lt;br /&gt;And the auth check looks like:&lt;br /&gt;&lt;br /&gt;if(!isset($_COOKIE[$usercookie]) || empty($_COOKIE[$usercookie])) { ... }&lt;br /&gt;&lt;br /&gt;Voila.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11240984-4076726243206333425?l=petersnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petersnotes.blogspot.com/feeds/4076726243206333425/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11240984&amp;postID=4076726243206333425' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/4076726243206333425'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/4076726243206333425'/><link rel='alternate' type='text/html' href='http://petersnotes.blogspot.com/2011/01/iphone-cookie-hell.html' title='iPhone Cookie Hell'/><author><name>Peter V</name><uri>http://www.blogger.com/profile/17919841991959605501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11240984.post-2443528037595349213</id><published>2010-11-15T19:26:00.001-08:00</published><updated>2011-05-07T08:25:19.974-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Printing'/><title type='text'>Constant Ink Injection System (CISS) for Canon MX860</title><content type='html'>I bought a Canon all-in-one MX860 from a Slickdeal.  This printer is like a miniature version of the excellent Canon ImageClass models at work.  &lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;However, the ink ran out in no time and costs a fortune.  This printer uses 5 of the CLI-221/PGI-220 ink cartridges which contain less ink than previous models. A brief history of the cartridges can be found &lt;a href="http://www.nifty-stuff.com/forum/viewtopic.php?pid=37908"&gt;here&lt;/a&gt;. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The CLI cartridges also keep track ink level unlike prior cartridges, so they need to be reset after refilling.  &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Three options were open to me:&lt;/div&gt;&lt;div&gt;&lt;ol&gt;&lt;li&gt;Refill - I would need ink, syringes, needles, and a reset tool (see &lt;a href="http://www.nifty-stuff.com/forum/viewtopic.php?id=4315."&gt;this link for refilling with syringes&lt;/a&gt;)&lt;/li&gt;&lt;li&gt;Purchase refillable cartridges and ink (&lt;a href="https://secure.datatekusa.com/product_info.php?cPath=281&amp;amp;products_id=2050"&gt;this supplier&lt;/a&gt; seemed to be well regarded on nifty-stuff and the website is clear on the parts you need to order)  ~$100&lt;/li&gt;&lt;li&gt;CISS system - from reading the forums, most of these systems work, it's just that the better ones are less of a headache to setup ~$200&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;I could not actually find a well reputed dealer for CISS systems for Canon MX860.  I found a general list &lt;a href="http://www.nifty-stuff.com/forum/viewtopic.php?pid=37908"&gt;here&lt;/a&gt;. I'm sure they exist, but in two hours scouring forums and company websites, I couldn't figure out what to buy on these sites...  So I went for a kit out of Australia.  &lt;a href="http://www.rihac.com.au/"&gt;Rihac&lt;/a&gt; was not only well regarded by the Aussies, but their web site is a dream compared to the other companies.  They wouldn't take my Amex, but a Visa card worked, though it's $45 for shipping to California!&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;A few other tid bits I picked up:&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;Pigment based inks are better for quality, but tend to gum up the works on converted printers&lt;/li&gt;&lt;li&gt;Dye based inks aren't as good as pigment based, but less maintenance is required&lt;/li&gt;&lt;li&gt;The height of the ink tanks in a CISS is important; place them either level with the printer or raised.  If they are too low, not enough ink will come out (EDIT: Do NOT raise above the print head!!! I just did this for 3 pages and my orange ink was ALL used on a long, wet smear... arg!).&lt;/li&gt;&lt;li&gt;Make sure the tubing for the CISS is not getting squeezed.  Not enough ink will come out, or in the worst case, the heads will overheat.&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;In the USA, you can get ink to refill after the CISS runs out from Hobbicolors (on eBay) and Precision Colors.&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11240984-2443528037595349213?l=petersnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petersnotes.blogspot.com/feeds/2443528037595349213/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11240984&amp;postID=2443528037595349213' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/2443528037595349213'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/2443528037595349213'/><link rel='alternate' type='text/html' href='http://petersnotes.blogspot.com/2010/11/constant-ink-injection-system-ciss-for.html' title='Constant Ink Injection System (CISS) for Canon MX860'/><author><name>Peter V</name><uri>http://www.blogger.com/profile/17919841991959605501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11240984.post-8002925163550495731</id><published>2010-09-17T14:15:00.000-07:00</published><updated>2010-09-17T14:18:09.145-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Scalability'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Architecture'/><category scheme='http://www.blogger.com/atom/ns#' term='SQL'/><title type='text'>"FriendFeed" Model Schema-Less Data Storage</title><content type='html'>&lt;div&gt;Modern application developers face a challenge ill-suited to traditional RDBMS'.  The data collected by applications is a moving target, with additional data points added often as applications mature.  Also, many applications aggregate data from multiple sources where data points captured may differ or change beyond the control the application developer.  Traditional RDBMS and the tools and checks built into those tools prefer static schemas.  For example, Netbeans has a wizard to create Java entity beans from tables, but no simple way to update the entity beans when the schema changes.  While creating the bean can take 5 minutes, adding a column takes hours.  What's an architect to do?&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;One solution is to stuff an entire record into a LOB column in a traditional RDBMS (or whatever the equivalent of the LOB is in the particular RDBMS).  This, however, makes indexing difficult. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Oracle has built in libraries to allow indexing and searching of XML data in BLOB and CLOB columns, but the performance is poor (though better than extracting the whole LOB and parsing it in, say, Java).  Columns for indexing could be added to the LOB table, however if additional indexes are needed at a further date, the table schema must be altered.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The solution is to the indexing problem is to create separate tables for each index.  Details of how this was accomplished at FriendFeed can be found &lt;a href="http://bret.appspot.com/entry/how-friendfeed-uses-mysql"&gt;here&lt;/a&gt;.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Note also, that if value comparison searches are not needed, a persistent hash map like Project Voldemort can be used instead.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11240984-8002925163550495731?l=petersnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petersnotes.blogspot.com/feeds/8002925163550495731/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11240984&amp;postID=8002925163550495731' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/8002925163550495731'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/8002925163550495731'/><link rel='alternate' type='text/html' href='http://petersnotes.blogspot.com/2010/09/friendfeed-model-schema-less-data.html' title='&quot;FriendFeed&quot; Model Schema-Less Data Storage'/><author><name>Peter V</name><uri>http://www.blogger.com/profile/17919841991959605501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11240984.post-3500700838623658947</id><published>2010-05-04T10:50:00.000-07:00</published><updated>2010-05-04T10:51:05.727-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Web Graphics'/><title type='text'>Illustrator Tutorial</title><content type='html'>Here's a tutorial that is good for those looking to get quickly acquainted with Illustrator:&lt;div&gt;&lt;a href="http://vectips.com/tutorials/create-a-cute-panda-bear-face-icon/"&gt;http://vectips.com/tutorials/create-a-cute-panda-bear-face-icon/&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11240984-3500700838623658947?l=petersnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petersnotes.blogspot.com/feeds/3500700838623658947/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11240984&amp;postID=3500700838623658947' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/3500700838623658947'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/3500700838623658947'/><link rel='alternate' type='text/html' href='http://petersnotes.blogspot.com/2010/05/illustrator-tutorial.html' title='Illustrator Tutorial'/><author><name>Peter V</name><uri>http://www.blogger.com/profile/17919841991959605501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11240984.post-3674507691716946238</id><published>2010-04-09T19:52:00.001-07:00</published><updated>2010-04-09T22:39:41.801-07:00</updated><title type='text'>Starting with the Arduino on Windows</title><content type='html'>&lt;ol&gt;&lt;li&gt;Plug a USB cable into your PC and the Arduino&lt;/li&gt;&lt;li&gt;Download the Arduino software and extract it&lt;/li&gt;&lt;li&gt;Run Arduino.exe &lt;/li&gt;&lt;li&gt;Paste in a program like the following, which writes a constant value to pin 9&lt;br /&gt;foo&lt;/li&gt;&lt;li&gt;Go to Tools&gt;Board and choose your board&lt;/li&gt;&lt;li&gt;Go to Tools&gt;Serial Port and choose a serial port&lt;/li&gt;&lt;li&gt;Press the upload button from the toolbar-- it looks like an arrow pointing to the right&lt;/li&gt;&lt;li&gt;If the upload fails, keep trying serial ports until it does work&lt;/li&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11240984-3674507691716946238?l=petersnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petersnotes.blogspot.com/feeds/3674507691716946238/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11240984&amp;postID=3674507691716946238' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/3674507691716946238'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/3674507691716946238'/><link rel='alternate' type='text/html' href='http://petersnotes.blogspot.com/2010/04/starting-with-arduino-on-windows.html' title='Starting with the Arduino on Windows'/><author><name>Peter V</name><uri>http://www.blogger.com/profile/17919841991959605501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11240984.post-6068265538472138550</id><published>2010-03-16T09:53:00.000-07:00</published><updated>2010-03-16T10:01:16.139-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Audio Recording'/><title type='text'>Using Izotope Vinyl with Audacity in Windows 7 64bit</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_WdpWJO6SGBI/S5-5UMuZdLI/AAAAAAAABXo/GsFyIMmoAi0/s1600-h/izotope+settings.jpg"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 400px; height: 347px;" src="http://3.bp.blogspot.com/_WdpWJO6SGBI/S5-5UMuZdLI/AAAAAAAABXo/GsFyIMmoAi0/s400/izotope+settings.jpg" border="0" alt="" id="BLOGGER_PHOTO_ID_5449277830805943474" /&gt;&lt;/a&gt;&lt;br /&gt;Izotope Vinyl is a great free plugin for making recording sound "old."  It's straightforward and reproduces sounds of records from the past.  Here's how to get it working in Audacity (note, I could not make it work in SoundForge 5.0 or 10.0 in Win7-64)&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Install audacity beta&lt;/li&gt;&lt;li&gt;Install Izotope Vinyl (Windows will say it didn't install right and give you the option to rerun with the correct settings-- go ahead and do that)&lt;/li&gt;&lt;li&gt;Go to Audacity's plugins folder&lt;/li&gt;&lt;li&gt;Copy the Isotype Vinyl VST dll to audacity plugins folder (probably located at C:\Program Files (x86)\Steinberg\VstPlugins)&lt;/li&gt;&lt;li&gt;Start Audacity&lt;/li&gt;&lt;li&gt;A prompt asking for Izotope registration info will appear-- enter in Izotype Vinyl license info (received by email from the Izotope download page)&lt;/li&gt;&lt;li&gt;Apply izotype from Effects menu&lt;/li&gt;&lt;/ol&gt;Some quick usage info:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;The older the time period you set, the thinner the sound gets&lt;/li&gt;&lt;li&gt;"scratches" adds dropped out audio&lt;/li&gt;&lt;li&gt;dust adds good ole hissing sound&lt;/li&gt;&lt;li&gt;wear makes the general quality of the recording sound worse&lt;/li&gt;&lt;li&gt;mechanical noise simulates turn table&lt;/li&gt;&lt;li&gt;electronic noise is 60hz hum&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11240984-6068265538472138550?l=petersnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petersnotes.blogspot.com/feeds/6068265538472138550/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11240984&amp;postID=6068265538472138550' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/6068265538472138550'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/6068265538472138550'/><link rel='alternate' type='text/html' href='http://petersnotes.blogspot.com/2010/03/using-izotope-vinyl-with-audacity-in.html' title='Using Izotope Vinyl with Audacity in Windows 7 64bit'/><author><name>Peter V</name><uri>http://www.blogger.com/profile/17919841991959605501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_WdpWJO6SGBI/S5-5UMuZdLI/AAAAAAAABXo/GsFyIMmoAi0/s72-c/izotope+settings.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11240984.post-660303990853803150</id><published>2010-03-08T16:00:00.000-08:00</published><updated>2010-03-08T16:03:12.915-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Android'/><title type='text'>Install Android 2.1 USB Device Driver on Windows 7 64 bit</title><content type='html'>Windows 7 64 bit has difficulty installing the current USB drivers for Android devices.  You'll need these to actually test Android applications on a phone.&lt;br /&gt;&lt;br /&gt;Feel free to poke around Control Panel for an hour trying to force it to recognize the drivers sitting on your hard drive.  It simply won't comply.&lt;br /&gt;&lt;br /&gt;Luckily there is an easy work around-- install PDANet.  You can remove the program after installation-- it will leave the drivers behind.&lt;br /&gt;&lt;br /&gt;See:&lt;br /&gt; http://forum.xda-developers.com/showthread.php?t=502010&amp;page=22&lt;br /&gt; http://androidforums.com/motorola-droid/35877-cant-get-tether-work.html&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11240984-660303990853803150?l=petersnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petersnotes.blogspot.com/feeds/660303990853803150/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11240984&amp;postID=660303990853803150' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/660303990853803150'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/660303990853803150'/><link rel='alternate' type='text/html' href='http://petersnotes.blogspot.com/2010/03/install-android-21-usb-device-driver-on.html' title='Install Android 2.1 USB Device Driver on Windows 7 64 bit'/><author><name>Peter V</name><uri>http://www.blogger.com/profile/17919841991959605501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11240984.post-5393842754860060530</id><published>2010-02-19T08:58:00.000-08:00</published><updated>2010-02-19T09:01:37.936-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='CSS'/><title type='text'>CSS Selectors</title><content type='html'>I was trying to do some "advanced" CSS and needed a suitable guide (most of the ones out there are very basic).  Here it is:&lt;br /&gt;http://www.smashingmagazine.com/2009/08/17/taming-advanced-css-selectors/&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11240984-5393842754860060530?l=petersnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petersnotes.blogspot.com/feeds/5393842754860060530/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11240984&amp;postID=5393842754860060530' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/5393842754860060530'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/5393842754860060530'/><link rel='alternate' type='text/html' href='http://petersnotes.blogspot.com/2010/02/css-selectors.html' title='CSS Selectors'/><author><name>Peter V</name><uri>http://www.blogger.com/profile/17919841991959605501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11240984.post-5609525839733396556</id><published>2010-01-26T23:04:00.001-08:00</published><updated>2010-01-26T23:11:30.723-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='CouchDB'/><title type='text'>Installing CouchDB on Ubuntu</title><content type='html'>First off, the only reason I'm installing on Ubuntu is that the Windows install is painful.  See&lt;br /&gt;&lt;br /&gt;&lt;div&gt;For installation, the CouchDB wiki is sufficient.&lt;/div&gt;&lt;div&gt;&lt;a href="http://wiki.apache.org/couchdb/Installing_on_Ubuntu"&gt;http://wiki.apache.org/couchdb/Installing_on_Ubuntu&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;However, I dislike running services as root.  Instead, it's better to create a CouchDB user.&lt;/div&gt;&lt;div&gt;I used the following instructions to create the user:&lt;/div&gt;&lt;div&gt;&lt;a href="http://johnpaulett.com/2007/12/24/couchdb-on-ubuntu/"&gt;http://johnpaulett.com/2007/12/24/couchdb-on-ubuntu/&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;pre&gt;sudo adduser couchdb&lt;br /&gt;sudo mkdir -p /usr/local/var/lib/couchdb&lt;br /&gt;sudo chown -R couchdb /usr/local/var/lib/couchdb&lt;br /&gt;sudo mkdir -p /usr/local/var/log/couchdb&lt;br /&gt;sudo chown -R couchdb /usr/local/var/log/couchdb&lt;br /&gt;sudo mkdir -p /usr/local/var/run&lt;br /&gt;sudo chown -R couchdb /usr/local/var/run&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I did accidentally run couchdb as root and just had to execute the chown commands again.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;You can see whether couchdb works by pointing a browser at your server on port 5984.  The output should be something like:&lt;/div&gt;&lt;div&gt;&lt;pre&gt;{"couchdb":"Welcome","version":"0.10.1"}&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11240984-5609525839733396556?l=petersnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petersnotes.blogspot.com/feeds/5609525839733396556/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11240984&amp;postID=5609525839733396556' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/5609525839733396556'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/5609525839733396556'/><link rel='alternate' type='text/html' href='http://petersnotes.blogspot.com/2010/01/installing-couchdb-on-ubuntu.html' title='Installing CouchDB on Ubuntu'/><author><name>Peter V</name><uri>http://www.blogger.com/profile/17919841991959605501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11240984.post-7202927260834897086</id><published>2010-01-14T14:31:00.001-08:00</published><updated>2010-01-14T14:57:36.074-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Windows'/><title type='text'>Relative Directory Listing Batch Script</title><content type='html'>&lt;p&gt;I needed to recreate a directory structure elsewhere, so the first step was to get it from the source. I only wanted directories, but you can get a full file listing by modifying two characters in this script (see comments). &lt;/p&gt;&lt;p&gt;Original script borrowed from &lt;a href="http://forums.techguy.org/windows-vista/741144-dir-command-help.html"&gt;http://forums.techguy.org/windows-vista/741144-dir-command-help.html&lt;/a&gt; and findstr information from &lt;a href="http://technet.microsoft.com/en-us/library/bb490907.aspx"&gt;http://technet.microsoft.com/en-us/library/bb490907.aspx&lt;/a&gt;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;pre&gt;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::&lt;br /&gt;::RDIR -- Relative Directory listing&lt;br /&gt;::Type RDIR /? for usage info&lt;br /&gt;::Written by TheOutcaste 08/18/2008 for TechSupportGuy forum&lt;br /&gt;::http://forums.techguy.org&lt;br /&gt;::MODIFIED by Peter Vieth 01/14/2010 - lists ONLY directories, ignores .svn dirs (see comments)&lt;br /&gt;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::&lt;br /&gt;&lt;br /&gt;@Echo Off&lt;br /&gt;If [%1]==[/?] GoTo Usage&lt;br /&gt;If [%1]==[-?] GoTo Usage&lt;br /&gt;Setlocal EnableDelayedExpansion&lt;br /&gt;If [%1]==[] goto Main&lt;br /&gt;set _tmp=%1&lt;br /&gt;If /I %_tmp:~0,3%==%CD:~0,3% GoTo Error&lt;br /&gt;If /I %_tmp:~0,3%==..\ GoTo Error&lt;br /&gt;&lt;br /&gt;:Main&lt;br /&gt;rem B:bare&lt;br /&gt;rem AD: list dir only&lt;br /&gt;rem S: recursive&lt;br /&gt;rem on:???&lt;br /&gt;rem ^| findstr /v /i "\.svn" : excludes anything containing svn (^ is escape character, v prints lines that dont match, \. escapes .)&lt;br /&gt;Set _t0=1&lt;br /&gt;If ["%CD%"]==["%CD:~0,3%"] Set _t0=0&lt;br /&gt;For /F "tokens=*" %%A In ('DIR "%*" /B /AD /on /S ^| findstr /v /i "\.svn"') Do (&lt;br /&gt;   Set _t1=%%A&lt;br /&gt;   Set _t2=!_t1:%CD%=!&lt;br /&gt;   Echo !_t2:~%_t0%!&lt;br /&gt;)&lt;br /&gt;Endlocal&lt;br /&gt;goto:EOF&lt;br /&gt;&lt;br /&gt;:Error&lt;br /&gt;Echo.&lt;br /&gt;Echo.Error - Drive letter or parent folder was specified.&lt;br /&gt;Echo.        You must specify only subfolders of the current folder&lt;br /&gt;Echo.&lt;br /&gt;&lt;br /&gt;:Usage&lt;br /&gt;Echo.USAGE:&lt;br /&gt;Echo.Generates a Directory listing in bare format relative to the current Folder&lt;br /&gt;Echo.&lt;br /&gt;Echo.RDIR [subfolder]&lt;br /&gt;Echo.&lt;br /&gt;Echo.  subfolder   Name of the subfolder of the current folder that you wish&lt;br /&gt;Echo.              to list. If not specified, lists the current folder and it's&lt;br /&gt;Echo.              subfolders&lt;br /&gt;HTH&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11240984-7202927260834897086?l=petersnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petersnotes.blogspot.com/feeds/7202927260834897086/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11240984&amp;postID=7202927260834897086' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/7202927260834897086'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/7202927260834897086'/><link rel='alternate' type='text/html' href='http://petersnotes.blogspot.com/2010/01/relative-directory-listing-batch-script.html' title='Relative Directory Listing Batch Script'/><author><name>Peter V</name><uri>http://www.blogger.com/profile/17919841991959605501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11240984.post-386783074366781458</id><published>2010-01-12T17:16:00.000-08:00</published><updated>2010-01-12T17:21:21.458-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Tomcat'/><category scheme='http://www.blogger.com/atom/ns#' term='Netbeans'/><title type='text'>Netbeans and Tomcat: Shared Memory Realm problems when Tomcat is started in Debug Mode</title><content type='html'>Tomcat and Netbeans don't play nice.  Everything starts out well, but the situation goes downhill every time the application is deployed, usually necessitating killing of Tomcat's JVM after a few deploys.&lt;br /&gt;&lt;br /&gt;Finally I ran into a show stopper.  It always goes away, yet I don't know what action causes it to go away, and then it comes back again later.  The exact error was:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;ERROR: transport error 202: failed to accept shared memory connection: stream closed&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;It only happens when Tomcat is started via Netbeans in debug mode.  Sometimes there would be no error but no breakpoints were ever triggered.&lt;br /&gt;&lt;br /&gt;How to fix it?  Don't use a shared memory realm for debugging.  The Netbeans and Tomcat JVM need some way to communicate during debugging and Netbeans provides two methods.&lt;br /&gt;&lt;br /&gt;Go to services.  Expand Servers and right click on Tomcat.  Choose properties and select the startup tab.  Change the radio button from Shared Memory Name to Socket Port.  Kill Tomcat and start it in debug mode.  Voila.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11240984-386783074366781458?l=petersnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petersnotes.blogspot.com/feeds/386783074366781458/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11240984&amp;postID=386783074366781458' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/386783074366781458'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/386783074366781458'/><link rel='alternate' type='text/html' href='http://petersnotes.blogspot.com/2010/01/netbeans-and-tomcat-shared-memory-realm.html' title='Netbeans and Tomcat: Shared Memory Realm problems when Tomcat is started in Debug Mode'/><author><name>Peter V</name><uri>http://www.blogger.com/profile/17919841991959605501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11240984.post-1228050997335727446</id><published>2009-12-10T13:18:00.001-08:00</published><updated>2009-12-10T13:19:41.904-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='NIX administration'/><title type='text'>Installing and Configuring SSH Server on Ubuntu</title><content type='html'>Ubuntu does not come with any network services enabled, including SSH.  Since most often you will want SSH, you've got to install and turn it on.  &lt;a href="http://www.cyberciti.biz/tips/howot-install-ubuntu-linux-ssh-server.html"&gt;Click here&lt;/a&gt; for a really good, succinct post on how to configure SSH and make it a bit more secure too.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11240984-1228050997335727446?l=petersnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petersnotes.blogspot.com/feeds/1228050997335727446/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11240984&amp;postID=1228050997335727446' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/1228050997335727446'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/1228050997335727446'/><link rel='alternate' type='text/html' href='http://petersnotes.blogspot.com/2009/12/installing-and-configuring-ssh-server.html' title='Installing and Configuring SSH Server on Ubuntu'/><author><name>Peter V</name><uri>http://www.blogger.com/profile/17919841991959605501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11240984.post-3822295532277323310</id><published>2009-12-03T14:01:00.000-08:00</published><updated>2009-12-03T14:54:31.391-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Virtualization'/><title type='text'>Desktop Virtualization Network Modes</title><content type='html'>Both VMWare workstation and Sun VirtualBox have several modes for guest operating systems to use networks. The names below are in the format VMWare terminology/Sun terminology - explanation&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Host only/Network adapter mode - a virtual network adapter is created on the host and used by the guest that is only accessible on the host. Inbound access to the guest is only possible through a proxy server run on the host.&lt;/li&gt;&lt;li&gt;Network Address Translation (NAT) mode - a virtual network adapter is created on the host and used by the guest; traffic from outside the host can reach the guest via mapping of ports on the host to the guest (handled by the virtualization software). Outbound traffic is unaffected. &lt;/li&gt;&lt;li&gt;Bridged/Internal mode - a virtual network adapter is created on the host and used by the guest; the adapter works just as if another physical network card were present in the host machine and devoted to the guest OS.&lt;/li&gt;&lt;/ul&gt;Some diagrams are available &lt;a href="http://en.kioskea.net/faq/sujet-1166-vmware-the-different-modes-of-vmware-network"&gt;here&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11240984-3822295532277323310?l=petersnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petersnotes.blogspot.com/feeds/3822295532277323310/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11240984&amp;postID=3822295532277323310' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/3822295532277323310'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/3822295532277323310'/><link rel='alternate' type='text/html' href='http://petersnotes.blogspot.com/2009/12/desktop-virtualization-network-modes.html' title='Desktop Virtualization Network Modes'/><author><name>Peter V</name><uri>http://www.blogger.com/profile/17919841991959605501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11240984.post-2700031480790876930</id><published>2009-12-03T11:20:00.000-08:00</published><updated>2009-12-03T11:49:07.190-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SVN'/><title type='text'>Locking SVN Branches</title><content type='html'>&lt;p&gt;There are two methods that can be used:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Access control lists&lt;/li&gt;&lt;li&gt;Pre-commit hooks&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;Access control lists can be used to take away write permission for users.  SVN uses two files to configure access: authz and passwd (both located in the conf directory of your repository).  Passwd defines users + their passwords and groups of users.  Authz defines permissions on repos and their contents for the users and groups defined in passwd.  &lt;a href="http://stackoverflow.com/questions/81361/how-to-setup-access-control-in-svn"&gt;Here&lt;/a&gt; is a sample.&lt;/p&gt;&lt;p&gt;Pre-commit hooks can be applied to a path and will reject any write actions.  &lt;a href="http://svnbook.red-bean.com/nightly/en/svn.reposadmin.create.html#svn.reposadmin.create.hooks"&gt;Here&lt;/a&gt; is documentation on how to create hooks. &lt;a href="http://svn.collab.net/repos/svn/trunk/tools/hook-scripts/svnperms.py"&gt;Here&lt;/a&gt; is python code for a hook and &lt;a href="http://svn.collab.net/repos/svn/trunk/tools/hook-scripts/svnperms.conf.example"&gt;here&lt;/a&gt; is a sample configuration for said hook.  Basically you put an executable file into svn's repos/hooks folder and give it the name of a hook (the names are based on the operation being performed).  Command line parameters are given to the executable by SVN and the executable can perform validation, etc.  SVN comes with sample hooks that have a .tmpl filename extension.  You can remove this extension to enable the default hook.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11240984-2700031480790876930?l=petersnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petersnotes.blogspot.com/feeds/2700031480790876930/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11240984&amp;postID=2700031480790876930' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/2700031480790876930'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/2700031480790876930'/><link rel='alternate' type='text/html' href='http://petersnotes.blogspot.com/2009/12/locking-svn-branches.html' title='Locking SVN Branches'/><author><name>Peter V</name><uri>http://www.blogger.com/profile/17919841991959605501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11240984.post-4577706388259216087</id><published>2009-12-03T11:13:00.000-08:00</published><updated>2009-12-03T11:19:52.408-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SVN'/><title type='text'>SVN Conventions</title><content type='html'>The conventional layout for a new SVN repo is to contain three directories: trunk, branches, and tags.  There are standard ways to use each of these folders.  Gavin Baumanis described this fairly succinctly &lt;a href="http://old.nabble.com/Lock-a-branch-td7209400.html"&gt;here&lt;/a&gt;:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;The trunk / branches / tags folders are a naming convention to assist&lt;br /&gt;humans in managing their code.&lt;br /&gt;&lt;br /&gt;...&lt;br /&gt;&lt;br /&gt;The convention says;&lt;br /&gt;Do all your work in a directory named "trunk".&lt;br /&gt;Do anything that might&lt;br /&gt;break the trunk in a branch (a sub-directory of&lt;br /&gt;the "branches" directory) -&lt;br /&gt;so as not to break the trunk with&lt;br /&gt;experimental code.&lt;br /&gt;Use the "tags"&lt;br /&gt;directory for a snapshot in time of the trunk at a&lt;br /&gt;particular revision -&lt;br /&gt;(File releases / some other milestone you want&lt;br /&gt;to track).&lt;br /&gt;&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11240984-4577706388259216087?l=petersnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petersnotes.blogspot.com/feeds/4577706388259216087/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11240984&amp;postID=4577706388259216087' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/4577706388259216087'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/4577706388259216087'/><link rel='alternate' type='text/html' href='http://petersnotes.blogspot.com/2009/12/svn-conventions.html' title='SVN Conventions'/><author><name>Peter V</name><uri>http://www.blogger.com/profile/17919841991959605501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11240984.post-8205222775013081526</id><published>2009-12-03T10:42:00.000-08:00</published><updated>2009-12-22T15:19:42.680-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='NIX administration'/><category scheme='http://www.blogger.com/atom/ns#' term='SVN'/><title type='text'>Installing SVN Serve on Ubuntu</title><content type='html'>Note: if you get an error about the subversion package not being available, change the Ubuntu package repository&lt;br /&gt;[Change Package Repository]&lt;br /&gt;Open System -&gt; Administration -&gt; Synaptic Package Manager -&gt; Settings -&gt; Repositories&lt;br /&gt;Select from the drop down Main server&lt;br /&gt;Click OK&lt;br /&gt;Press the Reload Button and wait for the packages to download&lt;br /&gt;close the Synaptic Package Manager&lt;br /&gt;&lt;br /&gt;[Create an svn user]&lt;br /&gt;vi /etc/group&lt;br /&gt;add&lt;br /&gt;svn:x:1000:&lt;br /&gt;or use an available number if 1000 is used&lt;br /&gt;&lt;br /&gt;vi /etc/passwd&lt;br /&gt;add&lt;br /&gt;svn:x:1000:GROUP_ID:svn,,,:/home/svn:/bin/bash&lt;br /&gt;replace 1000 with an available user id if 1000 is used&lt;br /&gt;&lt;br /&gt;[Install Subversion]&lt;br /&gt;sudo apt-get install subversion&lt;br /&gt;Answer Y to the prompts&lt;br /&gt;&lt;br /&gt;[Create Repository Root]&lt;br /&gt;sudo mkdir /var/svn&lt;br /&gt;&lt;br /&gt;[Assign SVN ownership to SVN user]&lt;br /&gt;sudo chown -R svn:svn /var/svn&lt;br /&gt;&lt;br /&gt;[Start SVN Server]&lt;br /&gt;svnserve -d -r /var/svn&lt;br /&gt;&lt;br /&gt;[Create Repository]&lt;br /&gt;svnadmin create /var/svn/YOUR_REPO_NAME&lt;br /&gt;&lt;br /&gt;[Modify SVN Server Config]&lt;br /&gt;vi /var/svn/YOUR_REPO_NAME/conf/svnserve.confuncomment the line specifying that username/passwords are stored in a file named passwduncomment the line containing anon-access and set it to none&lt;br /&gt;&lt;br /&gt;[Edit list of users]&lt;br /&gt;vi /var/svn/YOUR_REPOSITORY_NAME/conf/passwd&lt;br /&gt;After the line that says [users] you can add users by adding lines in the format&lt;br /&gt;username = password&lt;br /&gt;&lt;br /&gt;(optional)[Make SVN start at boot]&lt;br /&gt;[Make SVN start at boot]&lt;br /&gt;&lt;br /&gt;Create start script&lt;br /&gt;sudo vi /etc/init.d/svnserve&lt;br /&gt;&lt;br /&gt;Paste the following:&lt;br /&gt;svnserve -d -r /var/svn/YOUR_REPOSITORY_NAME&lt;br /&gt;OR&lt;br /&gt;&lt;pre&gt;#! /bin/sh&lt;br /&gt;PATH=/sbin:/bin:/usr/sbin:/usr/bin&lt;br /&gt;DAEMON=/usr/bin/svnserve&lt;br /&gt;NAME=svnserve&lt;br /&gt;DESC="SVN Repository Server Daemon"&lt;br /&gt;test -x $DAEMON || exit 0&lt;br /&gt;# Set your repository root here!&lt;br /&gt;OPTIONS="-d -r /var/svn"&lt;br /&gt;# Get lsb functions&lt;br /&gt;#. /lib/lsb/init-functions&lt;br /&gt;. /etc/default/rcS&lt;br /&gt;start() {&lt;br /&gt;       echo "Starting $DESC... "&lt;br /&gt;       #       echo "Starting $DESC: "&lt;br /&gt;       if ! start-stop-daemon --chuid svn --start --quiet --oknodo --exec $DAEMON -- $OPTIONS&lt;br /&gt;&gt;/dev/null 2&gt;&amp;1; then&lt;br /&gt;               status=$?&lt;br /&gt;               echo $status&lt;br /&gt;               return $status&lt;br /&gt;       fi&lt;br /&gt;       log_end_msg 0&lt;br /&gt;       return 0&lt;br /&gt;}&lt;br /&gt;case "$1" in&lt;br /&gt; start)&lt;br /&gt;       start&lt;br /&gt;       ;;&lt;br /&gt; stop)&lt;br /&gt;       echo "Stopping $DESC: "&lt;br /&gt;       start-stop-daemon --stop --quiet --oknodo --exec $DAEMON&lt;br /&gt;       echo $?&lt;br /&gt;       ;;&lt;br /&gt; restart|force-reload)&lt;br /&gt;       $0 stop&lt;br /&gt;       sleep 1&lt;br /&gt;       start&lt;br /&gt;       #echo "$NAME."&lt;br /&gt;       ;;&lt;br /&gt; *)&lt;br /&gt;       N=/etc/init.d/$NAME&lt;br /&gt;       echo "Usage: $N {start|stop|restart|force-reload}" &gt;&amp;2&lt;br /&gt;       exit 1&lt;br /&gt;       ;;&lt;br /&gt;esac&lt;br /&gt;exit 0&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Make the script executable:&lt;br /&gt;sudo chmod +x /etc/init.d/svnserve&lt;br /&gt;&lt;br /&gt;Add the script to the boot sequence:&lt;br /&gt;sudo update-rc.d svnserve defaults&lt;br /&gt;&lt;br /&gt;Key thing in the script is to make sure the svn serve user and group is correct or when svnserve runs it will not have permission to modify the repository&lt;br /&gt;&lt;br /&gt;(optional) [Perform Initial Import]&lt;br /&gt;sudo svn import /PATH/TO/FOLDER/TO/IMPORT file:///var/svn/YOUR_REPO_NAME -m "Initial Import"&lt;br /&gt;&lt;br /&gt;(random) [Restart SVN Server]&lt;br /&gt;sudo pkill -9 svnserve&lt;br /&gt;sudo restart svnserve&lt;br /&gt;&lt;br /&gt;You can access the SVN repository at&lt;br /&gt;[Connect To Repository]&lt;br /&gt;URL: svn://YOUR_HOSTNAME_OR_IP/YOUR_REPO_NAME&lt;br /&gt;&lt;br /&gt;See http://svnbook.red-bean.com/en/1.1/ch05s02.html for more svnadmin create options&lt;br /&gt;&lt;br /&gt;[User permissions]&lt;br /&gt;Edit Users -&gt; must be specified in svnserve.confvi /var/svn/YOUR_REPO_NAME/conf/passwd&lt;br /&gt;Edit permissions -&gt; must be enabled in svnserve.conf&lt;br /&gt;vi /var/svn/YOUR_REPO_NAME/conf/authz&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11240984-8205222775013081526?l=petersnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petersnotes.blogspot.com/feeds/8205222775013081526/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11240984&amp;postID=8205222775013081526' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/8205222775013081526'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/8205222775013081526'/><link rel='alternate' type='text/html' href='http://petersnotes.blogspot.com/2009/12/installing-svn-serve-on-ubuntu.html' title='Installing SVN Serve on Ubuntu'/><author><name>Peter V</name><uri>http://www.blogger.com/profile/17919841991959605501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11240984.post-5402085402513308424</id><published>2009-12-01T15:37:00.000-08:00</published><updated>2009-12-01T16:22:04.653-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Android'/><title type='text'>Install and Uninstall Applications on an Android Device</title><content type='html'>&lt;div&gt;&lt;div&gt;Adding an application&lt;/div&gt;&lt;ol&gt;&lt;li&gt;Change directory to the Android SDK directory/tools&lt;/li&gt;&lt;li&gt;Make sure either the phone is connected or the emulator is running&lt;/li&gt;&lt;li&gt;Double check the connection by typing&lt;br /&gt;&lt;code&gt;android list&lt;/code&gt;&lt;br /&gt;Make sure your device is in the list (you can also type adb devices but this doesn't give as much information)&lt;/li&gt;&lt;li&gt;Type &lt;code&gt;adb install yourapkfile.apk&lt;/code&gt;&lt;/li&gt;&lt;li&gt;You will see output such as:&lt;br /&gt;&lt;code&gt;1227 KB/s (982154 bytes in 0.781s)&lt;br /&gt;pkg: /data/loca/tmp/yourapkfile.apk&lt;br /&gt;Success&lt;/code&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;div&gt;Removing Applications&lt;/div&gt;&lt;div&gt;&lt;ol&gt;&lt;li&gt;Turn on the phone or run the emulator&lt;/li&gt;&lt;li&gt;Open the tray&lt;/li&gt;&lt;li&gt;Go to settings&lt;/li&gt;&lt;li&gt;Click Applications&lt;/li&gt;&lt;li&gt;Click "Manage Applications"&lt;/li&gt;&lt;li&gt;Click the name of the application you wish to uninstall&lt;/li&gt;&lt;li&gt;Click the button "Uninstall"&lt;/li&gt;&lt;li&gt;You should get a message confirming the application was uninstalled&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://developer.android.com/guide/developing/tools/adb.html"&gt;http://developer.android.com/guide/developing/tools/adb.html&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11240984-5402085402513308424?l=petersnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petersnotes.blogspot.com/feeds/5402085402513308424/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11240984&amp;postID=5402085402513308424' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/5402085402513308424'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/5402085402513308424'/><link rel='alternate' type='text/html' href='http://petersnotes.blogspot.com/2009/12/install-and-uninstall-applications-on.html' title='Install and Uninstall Applications on an Android Device'/><author><name>Peter V</name><uri>http://www.blogger.com/profile/17919841991959605501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11240984.post-5882926390893890889</id><published>2009-12-01T09:58:00.000-08:00</published><updated>2009-12-01T09:59:39.004-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Oracle'/><category scheme='http://www.blogger.com/atom/ns#' term='SQL'/><title type='text'>Database Partitioning</title><content type='html'>&lt;b&gt;Partitioning&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;What is it?&lt;br /&gt;Splitting storage of data based on a key into different tables.  End users of data don't generally "see" the partitioning, but do receive performance benefits.  The key should be a value that is always available, such as user id.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Oracle Partitioning&lt;/b&gt;&lt;br /&gt;Oracle partitioning creates sub tables for a given table and is defined when the table is created.  Records are put into sub tables based on a key defined when the table is created.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;CREATE TABLE mytable(&lt;br /&gt;    my_id                         NUMBER( 20 ) NOT NULL,&lt;br /&gt;    ...&lt;br /&gt;   )&lt;br /&gt;   PARTITION BY HASH (MY_ID)     -- Hash on MY_ID&lt;br /&gt;   PARTITIONS ???&lt;br /&gt;   STORE IN (tablespace_name)&lt;br /&gt;/&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Oracle partitioning limits:&lt;br /&gt;- cannot span across hosts&lt;br /&gt;- can't do an update to a row that would change which sub table the row is stored in-- if you want to move the record to another subtable, you must deleted the row and insert it again&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Partitioning schemes&lt;/b&gt;&lt;br /&gt;hash(column_name) (must understand Oracle hash function well to debug)&lt;br /&gt;integer_column mod 10 (easy to debug, but can only span 2 or 5 sub tables)&lt;br /&gt;integer_column mod 12 (harder to debug, but can be spanned across 6,4,3 or 2 sub tables)&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Logical Partitioning/Sharding&lt;/b&gt;&lt;br /&gt;It is possible to implement partitioning at the data access layer.  Hibernate calls this sharding. &lt;br /&gt;&lt;br /&gt;&lt;b&gt;Mixing of sharding and partitioning&lt;/b&gt;&lt;br /&gt;Temporal data&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Uses of partitioning&lt;/b&gt;&lt;br /&gt;Partitioning by geographic location (so user data is stored near their physical location)&lt;br /&gt;partition by date&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11240984-5882926390893890889?l=petersnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petersnotes.blogspot.com/feeds/5882926390893890889/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11240984&amp;postID=5882926390893890889' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/5882926390893890889'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/5882926390893890889'/><link rel='alternate' type='text/html' href='http://petersnotes.blogspot.com/2009/12/database-partitioning.html' title='Database Partitioning'/><author><name>Peter V</name><uri>http://www.blogger.com/profile/17919841991959605501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11240984.post-8347674703574332408</id><published>2009-10-28T15:12:00.001-07:00</published><updated>2009-10-28T15:18:49.571-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='JPA'/><title type='text'>Use c3p0 connection pooling with JPA</title><content type='html'>Add the following to your POM:&lt;div&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;       &amp;lt;dependency&amp;gt;&lt;br /&gt;           &amp;lt;groupId&amp;gt;org.hibernate&amp;lt;/groupId&amp;gt;&lt;br /&gt;           &amp;lt;artifactId&amp;gt;hibernate-c3p0&amp;lt;/artifactId&amp;gt;&lt;br /&gt;           &amp;lt;version&amp;gt;3.3.2.GA&amp;lt;/version&amp;gt;&lt;br /&gt;       &amp;lt;/dependency&amp;gt;&lt;br /&gt;&lt;br /&gt;       &amp;lt;dependency&amp;gt;&lt;br /&gt;           &amp;lt;groupId&amp;gt;org.hibernate&amp;lt;/groupId&amp;gt;&lt;br /&gt;           &amp;lt;artifactId&amp;gt;hibernate-tools&amp;lt;/artifactId&amp;gt;&lt;br /&gt;           &amp;lt;version&amp;gt;3.2.3.GA&amp;lt;/version&amp;gt;&lt;br /&gt;       &amp;lt;/dependency&amp;gt;&lt;br /&gt;&lt;br /&gt;       &amp;lt;dependency&amp;gt;&lt;br /&gt;           &amp;lt;groupId&amp;gt;c3p0&amp;lt;/groupId&amp;gt;&lt;br /&gt;           &amp;lt;artifactId&amp;gt;c3p0&amp;lt;/artifactId&amp;gt;&lt;br /&gt;           &amp;lt;version&amp;gt;0.9.1.2&amp;lt;/version&amp;gt;&lt;br /&gt;       &amp;lt;/dependency&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Add the following to your persistence.xml:&lt;/div&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&amp;lt;property name="connection.provider_class" value="org.hibernate.connection.C3P0ConnectionProvider"/&gt;&lt;br /&gt;&amp;lt;property name="hibernate.c3p0.min_size" value="5"/&amp;gt;&lt;br /&gt;&amp;lt;property name="hibernate.c3p0.max_size" value="20"/&amp;gt;&lt;br /&gt;&amp;lt;property name="hibernate.c3p0.timeout" value="300"/&amp;gt;&lt;br /&gt;&amp;lt;property name="hibernate.c3p0.max_statements" value="50"/&amp;gt;&lt;br /&gt;&amp;lt;property name="hibernate.c3p0.idle_test_period" value="300"/&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;div&gt;You can verify c3p0 is working by using jconsole (in your java/bin) and connecting to your running Tomcat instance.  If jmx isn't enabled, you can enable it by providing the following JAVA_OPTS in catalina.sh:&lt;/div&gt;&lt;br /&gt;&lt;code&gt;-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=3000&lt;br /&gt;-Dcom.sun.management.jmxremote.authenticate=false&lt;br /&gt;-Dcom.sun.management.jmxremote.ssl=false&lt;/code&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11240984-8347674703574332408?l=petersnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petersnotes.blogspot.com/feeds/8347674703574332408/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11240984&amp;postID=8347674703574332408' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/8347674703574332408'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/8347674703574332408'/><link rel='alternate' type='text/html' href='http://petersnotes.blogspot.com/2009/10/use-c3p0-connection-pooling-with-jpa.html' title='Use c3p0 connection pooling with JPA'/><author><name>Peter V</name><uri>http://www.blogger.com/profile/17919841991959605501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11240984.post-2030607639087657507</id><published>2009-10-28T12:44:00.000-07:00</published><updated>2009-10-28T15:12:00.848-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Networking'/><title type='text'>VPN using Tomato and OpenSSH</title><content type='html'>&lt;a href="http://blog.johnso.org/2009/08/how-to-setup-openvpn-in-tomato.html"&gt;http://blog.johnso.org/2009/08/how-to-setup-openvpn-in-tomato.html&lt;/a&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11240984-2030607639087657507?l=petersnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petersnotes.blogspot.com/feeds/2030607639087657507/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11240984&amp;postID=2030607639087657507' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/2030607639087657507'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/2030607639087657507'/><link rel='alternate' type='text/html' href='http://petersnotes.blogspot.com/2009/10/vpn-using-tomato-and-openssh.html' title='VPN using Tomato and OpenSSH'/><author><name>Peter V</name><uri>http://www.blogger.com/profile/17919841991959605501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11240984.post-2832272376979578124</id><published>2009-10-16T13:08:00.000-07:00</published><updated>2009-10-16T13:09:05.832-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='NIX administration'/><title type='text'>Run a Script as Another User</title><content type='html'>su - USER_NAME_HERE -c "/path/to/script.sh"&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11240984-2832272376979578124?l=petersnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petersnotes.blogspot.com/feeds/2832272376979578124/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11240984&amp;postID=2832272376979578124' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/2832272376979578124'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/2832272376979578124'/><link rel='alternate' type='text/html' href='http://petersnotes.blogspot.com/2009/10/run-script-as-another-user.html' title='Run a Script as Another User'/><author><name>Peter V</name><uri>http://www.blogger.com/profile/17919841991959605501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11240984.post-2476802119523637703</id><published>2009-10-16T13:05:00.000-07:00</published><updated>2009-10-16T13:08:27.162-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Oracle'/><category scheme='http://www.blogger.com/atom/ns#' term='Design'/><title type='text'>DB Usage Tips from eBay</title><content type='html'>Tip #1: Don't use transactions&lt;br /&gt;instead, each record has a status and a version #&lt;br /&gt;For inserts:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;add parent&lt;/li&gt;&lt;li&gt;add children&lt;/li&gt;&lt;li&gt;set children status to active&lt;/li&gt;&lt;li&gt;set parent status to active&lt;/li&gt;&lt;/ol&gt;For updates:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;insert parent w/ higher version #&lt;/li&gt;&lt;li&gt;insert children w/ higher version #&lt;/li&gt;&lt;li&gt;set children status to active&lt;/li&gt;&lt;li&gt;set parent to active&lt;/li&gt;&lt;/ol&gt;If a failure occurs, clean up orphans.&lt;br /&gt;&lt;br /&gt;Tip #2: no joins allowed&lt;br /&gt;Use lots of tables instead (easier to partition)&lt;div&gt;Joins can easily overload a database.&lt;/div&gt;&lt;div&gt;Offload logic to easily load balanced app servers&lt;br /&gt;db is just data in and out&lt;br /&gt;&lt;br /&gt;&lt;div&gt;Tip #3: Limit # of returned rows using where clause&lt;br /&gt;&gt;20,000 rows returned is threshold&lt;br /&gt;100k allowed in some cases&lt;br /&gt;Even if you could get 100k results, probably can't process them.&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11240984-2476802119523637703?l=petersnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petersnotes.blogspot.com/feeds/2476802119523637703/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11240984&amp;postID=2476802119523637703' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/2476802119523637703'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/2476802119523637703'/><link rel='alternate' type='text/html' href='http://petersnotes.blogspot.com/2009/10/db-usage-tips-from-ebay.html' title='DB Usage Tips from eBay'/><author><name>Peter V</name><uri>http://www.blogger.com/profile/17919841991959605501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11240984.post-5313777171585603128</id><published>2009-10-02T15:39:00.000-07:00</published><updated>2009-10-02T15:40:33.561-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Wordpress'/><title type='text'>Where are my Wordpress Page Templates?</title><content type='html'>You must go to the themes section in the admin panel and select your theme again.  The old page templates are cached.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11240984-5313777171585603128?l=petersnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petersnotes.blogspot.com/feeds/5313777171585603128/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11240984&amp;postID=5313777171585603128' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/5313777171585603128'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/5313777171585603128'/><link rel='alternate' type='text/html' href='http://petersnotes.blogspot.com/2009/10/where-are-my-wordpress-page-templates.html' title='Where are my Wordpress Page Templates?'/><author><name>Peter V</name><uri>http://www.blogger.com/profile/17919841991959605501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11240984.post-7206307478493957909</id><published>2009-10-02T13:38:00.000-07:00</published><updated>2009-10-02T13:40:43.533-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><title type='text'>Quickly Load Values from a Properties File</title><content type='html'>&lt;code&gt;import java.util.ResourceBundle;&lt;br /&gt;...&lt;br /&gt;   // Next line loads myFile.properties from the application's WEB-INF/classes directory&lt;br /&gt;   ResourceBundle resourceBd = ResourceBundle.getBundle("myFile");&lt;br /&gt;   String foo = resourceBd.getString("foo");&lt;/code&gt;&lt;br /&gt;That's it!  All you need is myFile.properties with the following contents:&lt;br /&gt;&lt;code&gt;foo=bar&lt;/code&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11240984-7206307478493957909?l=petersnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petersnotes.blogspot.com/feeds/7206307478493957909/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11240984&amp;postID=7206307478493957909' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/7206307478493957909'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/7206307478493957909'/><link rel='alternate' type='text/html' href='http://petersnotes.blogspot.com/2009/10/quickly-load-values-from-properties.html' title='Quickly Load Values from a Properties File'/><author><name>Peter V</name><uri>http://www.blogger.com/profile/17919841991959605501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11240984.post-6888808338151777723</id><published>2009-09-18T15:53:00.000-07:00</published><updated>2009-09-18T16:29:52.247-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Android'/><title type='text'>Get Started with the Android Emulator</title><content type='html'>&lt;ol&gt;&lt;li&gt;Install SDK (http://developer.android.com/sdk/1.6_r1/index.html)&lt;/li&gt;&lt;li&gt;Open command prompt window&lt;br /&gt;Start&gt;Run&gt;cmd.exe&lt;/li&gt;&lt;li&gt;Change directory to Android SDK folder&lt;/li&gt;&lt;li&gt;List available Android Images from command line&lt;br /&gt;&lt;code&gt;&amp;gt; android list targets&lt;/code&gt;&lt;br /&gt;With the SDK as of September 2009, 1.5 and 1.6 images are available.&lt;/li&gt;&lt;li&gt;The emulator requires an Android Virtual Device to be created which simulates the firmware of an Android device. This is based off one of the images listed by the above command.&lt;/li&gt;&lt;li&gt;Create an AVD by typing&lt;br /&gt;&lt;code&gt;&amp;gt; android create avd -n -t X&lt;/code&gt;&lt;br /&gt;where &lt;code&gt;-t X&lt;/code&gt; specifies the ID of the image to use during creation (replace X with the ID of the desired image to use)&lt;br /&gt;So if you want a version 1.5 AVD, you can create it by&lt;br /&gt;&lt;code&gt;&amp;gt; android create avd -n myavd -t 1&lt;br /&gt;Android 1.5 is a basic Android platform.&lt;br /&gt;Do you wish to create a custom hardware profile [no]&lt;br /&gt;Created AVD 'myavd' based on Android 1.5&lt;/code&gt;&lt;/li&gt;&lt;li&gt;If you should ever want to delete an AVD, type the following&lt;br /&gt;&lt;code&gt;&amp;gt; android delete avd -n&lt;/code&gt;&lt;/li&gt;&lt;li&gt;Start the emulator now with&lt;br /&gt;&lt;code&gt;emulator -avd -sdcard C:\work\software\android\sdcard.img –verbose&lt;/code&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11240984-6888808338151777723?l=petersnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petersnotes.blogspot.com/feeds/6888808338151777723/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11240984&amp;postID=6888808338151777723' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/6888808338151777723'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/6888808338151777723'/><link rel='alternate' type='text/html' href='http://petersnotes.blogspot.com/2009/09/get-started-with-android-emulator.html' title='Get Started with the Android Emulator'/><author><name>Peter V</name><uri>http://www.blogger.com/profile/17919841991959605501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11240984.post-8536207310922182875</id><published>2009-09-17T11:28:00.001-07:00</published><updated>2009-09-17T11:31:02.167-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Wordpress'/><category scheme='http://www.blogger.com/atom/ns#' term='LAMPS'/><category scheme='http://www.blogger.com/atom/ns#' term='Netbeans'/><title type='text'>Running Wordpress Locally and Editing with Netbeans</title><content type='html'>&lt;div&gt;&lt;span class="Apple-style-span" style="text-decoration: underline;"&gt;NetBeans&lt;/span&gt;&lt;/div&gt;&lt;ol&gt;&lt;li&gt;Open Netbeans&lt;/li&gt;&lt;li&gt;Tools&gt;Plugins&gt;Available tab&lt;/li&gt;&lt;li&gt;Choose PHP plugin and install it&lt;/li&gt;&lt;li&gt;File&gt;New Project&lt;/li&gt;&lt;li&gt;Expand the PHP Folder&lt;/li&gt;&lt;li&gt;Choose PHP Project From Existing Source and press Next&lt;/li&gt;&lt;li&gt;Find the root directory of your Wordpress files&lt;/li&gt;&lt;li&gt;Give the project a name and import it&lt;/li&gt;&lt;/ol&gt;&lt;span class="Apple-style-span" style="text-decoration: underline;"&gt;Debugging&lt;/span&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Install XAMPP as detailed in another post&lt;/li&gt;&lt;li&gt;Point XAMPP's Apache to your Wordpress files by editing&lt;br /&gt;xampp\apache\conf\httpd.conf&lt;/li&gt;&lt;li&gt;Search the document for htdocs -- there will be two occurences.&lt;/li&gt;&lt;li&gt;Replace the two paths to point to your wordpress code.&lt;/li&gt;&lt;/ol&gt;Wordpress uses absolute URLs, so it will load pages from the internet if you try to view the local copy of Wordpress&lt;br /&gt;So whenever you need to debug:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Open your hosts file&lt;/li&gt;&lt;li&gt;Add the following entry:&lt;br /&gt;127.0.0.1 your_domain_name&lt;br /&gt;(you can comment it out with a # at the beginning of a line)&lt;/li&gt;&lt;li&gt;Start Mysql using XAMPP control panel&lt;/li&gt;&lt;li&gt;Start Apache&lt;/li&gt;&lt;li&gt;Point your browser at http://localhost&lt;/li&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11240984-8536207310922182875?l=petersnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petersnotes.blogspot.com/feeds/8536207310922182875/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11240984&amp;postID=8536207310922182875' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/8536207310922182875'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/8536207310922182875'/><link rel='alternate' type='text/html' href='http://petersnotes.blogspot.com/2009/09/running-wordpress-locally-and-editing.html' title='Running Wordpress Locally and Editing with Netbeans'/><author><name>Peter V</name><uri>http://www.blogger.com/profile/17919841991959605501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11240984.post-5520179590574605661</id><published>2009-09-17T10:55:00.000-07:00</published><updated>2009-10-02T13:38:47.455-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Web Graphics'/><title type='text'>Rounded Corners for Arbitrary Shapes in Photoshop (and Gimp)</title><content type='html'>There are many tutorials for rounded boxes in Photoshop.  Photoshop CS includes a rounded box drawing tool even.  You can position a rounded box over an image, use the magic wand to select the box, invert selection, select the photo layer, and use edit&gt;cut to round the edges of the photo.&lt;br /&gt;&lt;br /&gt;But if you have an arbitrary shape, what do you do?  The select menu contains "smooth", which sounds appropriate.  Except that the smoothing doesn't work very well at all.  The corners come out jaggedy and make any edge effects applied afterwards look terrible.  Blurring the corners doesn't help.&lt;br /&gt;&lt;br /&gt;The oldest method works best (I've used it since Photoshop 3.0).  Create a channel, make a selection, fill it with white, apply gaussian blur (in CS, I sometimes have to convert my shape to a smart shape to apply the gaussian filter), and then apply levels (CTRL-L) set to 130 1.00 165.  You can now use magic wand to select the resulting rounded shape.  Switch back to the layers list, create a new layer, and fill the selection.&lt;br /&gt;&lt;br /&gt;More detailed steps here:&lt;br /&gt;http://www.stockvault.net/tutorials/photoshop_smooth_your_edges.php&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11240984-5520179590574605661?l=petersnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petersnotes.blogspot.com/feeds/5520179590574605661/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11240984&amp;postID=5520179590574605661' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/5520179590574605661'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/5520179590574605661'/><link rel='alternate' type='text/html' href='http://petersnotes.blogspot.com/2009/09/rounded-corners-for-arbitrary-shapes-in.html' title='Rounded Corners for Arbitrary Shapes in Photoshop (and Gimp)'/><author><name>Peter V</name><uri>http://www.blogger.com/profile/17919841991959605501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11240984.post-6134717434868144660</id><published>2009-09-16T17:29:00.000-07:00</published><updated>2009-09-16T17:35:43.168-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Oracle'/><category scheme='http://www.blogger.com/atom/ns#' term='JPA'/><title type='text'>Using Oracle Sequences with JPA</title><content type='html'>Oracle doesn't allow auto increment like MySQL.  Auto increment, on big applications can cause all sorts of problems.  Most JPA examples are targeted for MySQL.&lt;br /&gt;&lt;br /&gt;First, I use Number(19) for id columns.&lt;br /&gt;&lt;br /&gt;Second, the generator name is not important so long as it is unique and generator in GeneratedValue annotation matches name in SequenceGenerator annotation.&lt;br /&gt;&lt;br /&gt;Sequence Name in SequenceGenerator is the name of your Oracle sequence.&lt;br /&gt;&lt;br /&gt;Example entity code:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;import javax.persistence.Id;&lt;br /&gt;import javax.persistence.GeneratedValue;&lt;br /&gt;import javax.persistence.GenerationType;&lt;br /&gt;import javax.persistence.SequenceGenerator;&lt;br /&gt;...&lt;br /&gt;@Id&lt;br /&gt;@Basic(optional = false)&lt;br /&gt;@Column(name = "MY_ID")&lt;br /&gt;@GeneratedValue(strategy=GenerationType.SEQUENCE, generator = "MYNOTIFSEQ")&lt;br /&gt;@SequenceGenerator(name="MYNOTIFSEQ", sequenceName = "MY_SEQ")&lt;br /&gt;private Long userNotificationId;&lt;br /&gt;...&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Here's a sample sequence:&lt;br /&gt;&lt;pre&gt;------------------------------------&lt;br /&gt;--&lt;br /&gt;-- Sequence MY_SEQ&lt;br /&gt;--&lt;br /&gt;------------------------------------&lt;br /&gt;CREATE SEQUENCE MY_SEQ&lt;br /&gt; INCREMENT BY 1&lt;br /&gt; START WITH 1&lt;br /&gt; MINVALUE 1&lt;br /&gt; MAXVALUE 999999999999999999&lt;br /&gt; NOORDER&lt;br /&gt; CACHE 20&lt;br /&gt; CYCLE&lt;br /&gt;/&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11240984-6134717434868144660?l=petersnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petersnotes.blogspot.com/feeds/6134717434868144660/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11240984&amp;postID=6134717434868144660' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/6134717434868144660'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/6134717434868144660'/><link rel='alternate' type='text/html' href='http://petersnotes.blogspot.com/2009/09/using-oracle-sequences-with-jpa.html' title='Using Oracle Sequences with JPA'/><author><name>Peter V</name><uri>http://www.blogger.com/profile/17919841991959605501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11240984.post-1472355362815357474</id><published>2009-09-16T17:06:00.000-07:00</published><updated>2009-10-02T13:44:58.280-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><title type='text'>Loading a Properties File in a Java Application</title><content type='html'>Most of the examples I found only rely on servletContext, but this is no use if you aren't using a servlet.  Also, there is a quick approach using ResourceBundle, but that approach is limited in how you can load the properties file.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;Properties tempProps = new Properties();&lt;br /&gt;        try {&lt;br /&gt;            URL startupPropsURL = this.getClass().getClassLoader().getResource("/test.properties");&lt;br /&gt;            File startupPropsFl = new File(startupPropsURL.toURI());&lt;br /&gt;&lt;br /&gt;            try {&lt;br /&gt;                InputStreamReader aRdr = new InputStreamReader(new FileInputStream(startupPropsFl));&lt;br /&gt;                tempProps.load(aRdr);&lt;br /&gt;                aRdr.close();&lt;br /&gt;            } catch (Throwable e) {&lt;br /&gt;                System.out.println("Error occured while trying to load test.properties ");&lt;br /&gt;                e.printStackTrace();&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;            System.out.println("Getting log files from "+tempProps.getProperty("foo.baseURL"));&lt;br /&gt;            return tempProps.getProperty("foo.baseURL");&lt;br /&gt;        } catch (Throwable ex) {&lt;br /&gt;            System.out.println("Error occured while trying to read from log.properties ");&lt;br /&gt;            ex.printStackTrace();&lt;br /&gt;        }&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11240984-1472355362815357474?l=petersnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petersnotes.blogspot.com/feeds/1472355362815357474/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11240984&amp;postID=1472355362815357474' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/1472355362815357474'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/1472355362815357474'/><link rel='alternate' type='text/html' href='http://petersnotes.blogspot.com/2009/09/loading-properties-file-in-java.html' title='Loading a Properties File in a Java Application'/><author><name>Peter V</name><uri>http://www.blogger.com/profile/17919841991959605501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11240984.post-3065297728909895466</id><published>2009-09-16T10:40:00.001-07:00</published><updated>2009-09-16T17:06:27.783-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='LAMPS'/><title type='text'>Move Your Wordpress Blog to XAMPP from a Webhost</title><content type='html'>&lt;div&gt;Here it is, step by step:&lt;/div&gt;&lt;ol&gt;&lt;li&gt;download XAMPP EXE installer (&lt;a href="http://www.apachefriends.org/en/xampp-windows.html"&gt;http://www.apachefriends.org/en/xampp-windows.html&lt;/a&gt;)&lt;/li&gt;&lt;li&gt;install to a folder of your choice (I used c:\personal)&lt;/li&gt;&lt;li&gt;XAMPP will be installed into c:\personal\xampp&lt;/li&gt;&lt;li&gt;You will be asked some questions at the command line, choose as you wish... the final prompt will be a menu.  Choice #1 is start control panel (1. start XAMPP Control Panel) or you can start via the Start&gt;All Programs&gt;XAMPP menu.&lt;/li&gt;&lt;li&gt;type 1 and enter to start control panel&lt;/li&gt;&lt;li&gt;start mysql (unblock if windows prompts)&lt;/li&gt;&lt;li&gt;start apache (unblock if windows prompts)&lt;/li&gt;&lt;li&gt;click the admin button next to mysql (this will open a new browser window)&lt;/li&gt;&lt;/ol&gt;Copying your PHP files from your web host&lt;br /&gt;&lt;ol&gt;&lt;li&gt;download WinSCP&lt;/li&gt;&lt;li&gt;you may have to configure FTP or SSH access with your webhost&lt;/li&gt;&lt;li&gt;connect to your domain name with username/pass and download your wordpress files&lt;/li&gt;&lt;li&gt;copy these files to ${XAMP__INSTALL_DIR}\htdocs&lt;/li&gt;&lt;li&gt;Open wp-config.php&lt;/li&gt;&lt;li&gt;Note down the username and password and database name&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;Exporting the DB&lt;/div&gt;&lt;div&gt;&lt;ol&gt;&lt;li&gt;Open PHPMyAdmin for your Webhost&lt;/li&gt;&lt;li&gt;Select the database&lt;/li&gt;&lt;li&gt;Select the Export tab&lt;/li&gt;&lt;li&gt;Select the option to ZIP your export&lt;/li&gt;&lt;li&gt;Select the option to export as SQL inserts&lt;/li&gt;&lt;li&gt;Press Go&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;div&gt;Creating a New DB and User&lt;/div&gt;&lt;div&gt;&lt;ol&gt;&lt;li&gt;Open PHPMyAdmin for your XAMPP install by pressing the Admin button in XAMPP control panel for MySQL&lt;/li&gt;&lt;li&gt;At the top of the page, click the server level link&lt;/li&gt;&lt;li&gt;Click the Privileges tab&lt;/li&gt;&lt;li&gt;Click (in the middle of the page) Add a new User&lt;/li&gt;&lt;li&gt;use same values for username,pass as your webhost&lt;/li&gt;&lt;li&gt;Select the radio button "create database with same name and grant all privileges"&lt;/li&gt;&lt;li&gt;Click "Go"&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;Importing the DB&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Open PHPMyAdmin for your XAMPP install by pressing the Admin button in XAMPP control panel for MySQL&lt;/li&gt;&lt;li&gt;Click the databases tab&lt;/li&gt;&lt;li&gt;Click your database&lt;/li&gt;&lt;li&gt;Go to import tab&lt;/li&gt;&lt;li&gt;Choose file, find the ZIP file you downloaded earlier&lt;/li&gt;&lt;li&gt;Click "Go"&lt;/li&gt;&lt;/ol&gt;Open a web browser and navigate to http://localhost&lt;br /&gt;&lt;br /&gt;Voila!&lt;br /&gt;&lt;br /&gt;Here's how to create a DB without creating a user (though you'll have to sort out all the grants then!)&lt;br /&gt;Near the bottom of the PHPMyAdmin page is 'Create new database'&lt;br /&gt;Type in the name of the database your webhost has configured&lt;br /&gt;Leave the drop down set to 'Collation'&lt;br /&gt;Press create&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11240984-3065297728909895466?l=petersnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petersnotes.blogspot.com/feeds/3065297728909895466/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11240984&amp;postID=3065297728909895466' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/3065297728909895466'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/3065297728909895466'/><link rel='alternate' type='text/html' href='http://petersnotes.blogspot.com/2009/09/move-your-wordpress-blog-to-xampp-from.html' title='Move Your Wordpress Blog to XAMPP from a Webhost'/><author><name>Peter V</name><uri>http://www.blogger.com/profile/17919841991959605501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11240984.post-5004329018170434980</id><published>2009-09-12T12:01:00.000-07:00</published><updated>2009-09-12T12:03:42.658-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Networking'/><title type='text'>DynDNS and VPN using a Tomato Router and Dynamic IP</title><content type='html'>Configuring DynDNS:&lt;br /&gt;http://blog.dreamdevil.com/index.php/2008/10/23/tomato-firmware_dynamic-dns-with-dyndns/&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;How to configure VPN:&lt;br /&gt;(basically, go download Open VPN http://www.openvpn.net/index.php/open-source/downloads.html and follow these intructions)&lt;br /&gt;http://blog.johnso.org/2009/08/how-to-setup-openvpn-in-tomato.html&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11240984-5004329018170434980?l=petersnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petersnotes.blogspot.com/feeds/5004329018170434980/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11240984&amp;postID=5004329018170434980' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/5004329018170434980'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/5004329018170434980'/><link rel='alternate' type='text/html' href='http://petersnotes.blogspot.com/2009/09/dyndns-and-vpn-using-tomato-router-and.html' title='DynDNS and VPN using a Tomato Router and Dynamic IP'/><author><name>Peter V</name><uri>http://www.blogger.com/profile/17919841991959605501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11240984.post-7642197901915350304</id><published>2009-09-11T13:13:00.000-07:00</published><updated>2009-09-11T13:19:23.166-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><title type='text'>Running Java Code when a Web App Starts or Stops</title><content type='html'>You can run Java code when a web application starts and stops by implementing ServletContextListener in your class.  ServletContextListener requires two methods (an init and a destroy) and an entry in web.xml configuring the listener.&lt;br /&gt;&lt;br /&gt;If you like, you can persist data beyond the initialization by creating static variables in your class.&lt;br /&gt;&lt;br /&gt;See details here:  http://www.java-tips.org/java-ee-tips/java-servlet/how-to-work-with-servletcontextlistener.html&lt;br /&gt;&lt;br /&gt;Here's a quick version&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;package org.peter;&lt;br /&gt;import javax.servlet.ServletContext;&lt;br /&gt;import javax.servlet.ServletContextListener;&lt;br /&gt;import javax.servlet.ServletContextEvent;&lt;br /&gt;&lt;br /&gt;public class ServletListener implements ServletContextListener {&lt;br /&gt;&lt;br /&gt;    private ServletContext context = null;&lt;br /&gt;    static ArrayList&lt;String&gt; lf = null;&lt;br /&gt;&lt;br /&gt;    /*This method is invoked when the Web Application has been removed&lt;br /&gt;    and is no longer able to accept requests&lt;br /&gt;     */&lt;br /&gt;    public void contextDestroyed(ServletContextEvent event) {&lt;br /&gt;        //Output a simple message to the server's console&lt;br /&gt;        System.out.println("The web app has been removed");&lt;br /&gt;        this.context = null;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    //This method is invoked when the Web Application&lt;br /&gt;    //is ready to service requests&lt;br /&gt;    public void contextInitialized(ServletContextEvent event) {&lt;br /&gt;        this.context = event.getServletContext();&lt;br /&gt;        System.out.println("Web app started up");&lt;br /&gt;        lf.add("foo");&lt;br /&gt;    } // end of Initialized&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;And the entry in web.xml:&lt;br /&gt;&lt;pre&gt;&amp;lt;listener&amp;gt;&lt;br /&gt;        &amp;lt;listener-class&amp;gt;&lt;br /&gt;          org.peter.ServletListener&lt;br /&gt;        &amp;lt;/listener-class&amp;gt;&lt;br /&gt;    &amp;lt;/listener&amp;gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11240984-7642197901915350304?l=petersnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petersnotes.blogspot.com/feeds/7642197901915350304/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11240984&amp;postID=7642197901915350304' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/7642197901915350304'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/7642197901915350304'/><link rel='alternate' type='text/html' href='http://petersnotes.blogspot.com/2009/09/starting.html' title='Running Java Code when a Web App Starts or Stops'/><author><name>Peter V</name><uri>http://www.blogger.com/profile/17919841991959605501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11240984.post-5820582765307018643</id><published>2009-09-11T13:11:00.000-07:00</published><updated>2009-09-11T13:13:46.238-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><title type='text'>Set a limit on the size of a LinkedHashMap</title><content type='html'>LinkedHashMap allows you to override the removeEldestEntry function so that whenever a put is executed, you can specify whether to remove the oldest entry or not, thus allowing implementation of an LRU.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;LogMessages = new LinkedHashMap&amp;lt;Long,String&amp;gt;() {&lt;br /&gt;  protected boolean removeEldestEntry(Map.Entry eldest) {&lt;br /&gt;      if(this.size()&amp;gt;10000)&lt;br /&gt;          return true;&lt;br /&gt;      else&lt;br /&gt;          return false;&lt;br /&gt;  }&lt;br /&gt;};&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11240984-5820582765307018643?l=petersnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petersnotes.blogspot.com/feeds/5820582765307018643/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11240984&amp;postID=5820582765307018643' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/5820582765307018643'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/5820582765307018643'/><link rel='alternate' type='text/html' href='http://petersnotes.blogspot.com/2009/09/set-limit-on-size-of-linkedhashmap.html' title='Set a limit on the size of a LinkedHashMap'/><author><name>Peter V</name><uri>http://www.blogger.com/profile/17919841991959605501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11240984.post-6876894543644383728</id><published>2009-09-08T21:18:00.002-07:00</published><updated>2009-09-08T21:19:30.653-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Video'/><title type='text'>Get film look on HV20</title><content type='html'>Taken from the following thread:&lt;br /&gt;http://hv20.com/showthread.php?t=441&amp;page=8&lt;br /&gt;&lt;br /&gt;The way to do that is to lock the HV20 at whatever aperture you want- yes, it's limited to f1.8 but that's not far off of what the largest aperture the still-cam lenses are delivering- ie- f1.2. f1.4 or f1.8. Using ND filters to control exposure and fixing shutter at 1/48th.&lt;br /&gt;Plan D (Fixed Shutter &amp; Gain Variable Aperture)&lt;br /&gt;ACTION: EXP lock function&lt;br /&gt;1) Zoom to Full Wide- With Fixed Illumination Cap&lt;br /&gt;2) Cine Mode &lt;br /&gt;3) HDV 24P&lt;br /&gt;RESULT&gt; Fixed Shutter Speed &amp; Varied aperture range&lt;br /&gt;&lt;br /&gt;EXP Shutter Iris Gain&lt;br /&gt;+6 1/48 1.8 0dB&lt;br /&gt;+5 1/48 2.0 0dB&lt;br /&gt;+4 1/48 2.2 0dB&lt;br /&gt;+3 1/48 2.4 0dB&lt;br /&gt;+2 1/48 2.6 0dB&lt;br /&gt;+1 1/48 2.8 0dB&lt;br /&gt;0 1/48 2.8 0dB = Default Based On Target Illuminator&lt;br /&gt;-1 1/48 3.4 0dB&lt;br /&gt;-2 1/48 3.4 0dB&lt;br /&gt;-3 1/48 4.0 0dB&lt;br /&gt;-4 1/48 4.0 0dB&lt;br /&gt;-5 1/48 4.8 0dB&lt;br /&gt;-6 1/48 4.8 0dB&lt;br /&gt;-7 1/48 5.6 0dB&lt;br /&gt;-8 1/48 5.6 0dB&lt;br /&gt;-9 1/48 5.6 0dB&lt;br /&gt;-10 1/48 5.6 0dB&lt;br /&gt;-11 1/48 5.6 0dB&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11240984-6876894543644383728?l=petersnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petersnotes.blogspot.com/feeds/6876894543644383728/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11240984&amp;postID=6876894543644383728' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/6876894543644383728'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/6876894543644383728'/><link rel='alternate' type='text/html' href='http://petersnotes.blogspot.com/2009/09/get-film-look-on-hv20.html' title='Get film look on HV20'/><author><name>Peter V</name><uri>http://www.blogger.com/profile/17919841991959605501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11240984.post-321866335836183311</id><published>2009-09-08T21:18:00.001-07:00</published><updated>2009-09-08T21:18:44.553-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Android'/><title type='text'>Replace Android Browser Binary</title><content type='html'>Installation Instructions (you must have root access):&lt;br /&gt;&lt;br /&gt;Download the updated Browser.apk&lt;br /&gt;Run the following from the command prompt to back up your current Browser file to your sdcard and install the new one:&lt;br /&gt;adb remount&lt;br /&gt;adb pull /system/app/Browser.apk BrowserBackup.apk&lt;br /&gt;adb push BrowserBackup.apk /sdcard&lt;br /&gt;adb shell rm /system/app/Browser.odex&lt;br /&gt;adb push Browser.apk /system/app&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11240984-321866335836183311?l=petersnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petersnotes.blogspot.com/feeds/321866335836183311/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11240984&amp;postID=321866335836183311' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/321866335836183311'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/321866335836183311'/><link rel='alternate' type='text/html' href='http://petersnotes.blogspot.com/2009/09/replace-android-browser-binary.html' title='Replace Android Browser Binary'/><author><name>Peter V</name><uri>http://www.blogger.com/profile/17919841991959605501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11240984.post-5369282405591697617</id><published>2009-09-08T20:40:00.000-07:00</published><updated>2009-09-08T21:02:22.845-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><title type='text'>Tuning ehcache and hibernate</title><content type='html'>Hibernate mapping files are mapped to cache "regions" and each region has some configuration options that is configured in the ehcache.xml.  A simple strategy for tuning is to create three different classes of objects:&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;short lived entities&lt;/li&gt;&lt;li&gt;long lived, but not eternal entities&lt;/li&gt;&lt;li&gt;eternal entities&lt;/li&gt;&lt;/ol&gt;Which class does your entity fit into?  Eternal entities will never change while your system is running.  Long lived entities are accessed repeatedly, for example by a logged in user, for an extended period of time.  Most other objects are short lived, and usage is confined to a relatively short period of time, perhaps across only a handful of transactions.&lt;br /&gt;&lt;br /&gt;The number of elements stored in a cache region will vary by your application and the entity.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Short Lived Entity&lt;/span&gt;&lt;br /&gt;Notice that the time to live is on the order of seconds to a few minutes&lt;br /&gt;&lt;pre&gt;&amp;lt;cache&lt;br /&gt;               name="myregion"&lt;br /&gt;               maxElementsInMemory="10000"&lt;br /&gt;               eternal="false"&lt;br /&gt;               timeToIdleSeconds="30"&lt;br /&gt;               timeToLiveSeconds="120"&lt;br /&gt;               overflowToDisk="false"&lt;br /&gt;               diskSpoolBufferSizeMB="0"&lt;br /&gt;               maxElementsOnDisk="0"&lt;br /&gt;               diskPersistent="false"&lt;br /&gt;               diskExpiryThreadIntervalSeconds="0"&lt;br /&gt;               memoryStoreEvictionPolicy="LRU" /&amp;gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Long lived Entity&lt;/span&gt;&lt;br /&gt;Notice that the time to live is on the order of minutes to hours&lt;br /&gt;&lt;pre&gt;&amp;lt;cache&lt;br /&gt;               name="myRegion"&lt;br /&gt;               maxElementsInMemory="10000"&lt;br /&gt;               eternal="false"&lt;br /&gt;               timeToIdleSeconds="1800"&lt;br /&gt;               timeToLiveSeconds="3600"&lt;br /&gt;               overflowToDisk="false"&lt;br /&gt;               diskSpoolBufferSizeMB="0"&lt;br /&gt;               maxElementsOnDisk="0"&lt;br /&gt;               diskPersistent="false"&lt;br /&gt;               diskExpiryThreadIntervalSeconds="0"&lt;br /&gt;               memoryStoreEvictionPolicy="LRU"&lt;br /&gt;       /&amp;gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Eternal Entity&lt;/span&gt;&lt;br /&gt;Time to live is set to 0 so that the cache entries persist forever.&lt;br /&gt;&lt;pre&gt;&amp;lt;cache&lt;br /&gt;         name="myRegion"&lt;br /&gt;               maxElementsInMemory="10000"&lt;br /&gt;               eternal="true"&lt;br /&gt;               timeToIdleSeconds="0"&lt;br /&gt;               timeToLiveSeconds="0"&lt;br /&gt;               overflowToDisk="false"&lt;br /&gt;               diskSpoolBufferSizeMB="0"&lt;br /&gt;               maxElementsOnDisk="0"&lt;br /&gt;               diskPersistent="false"&lt;br /&gt;               diskExpiryThreadIntervalSeconds="0"&lt;br /&gt;               memoryStoreEvictionPolicy="LRU"&lt;br /&gt;       /&amp;gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Verifying your Settings&lt;br /&gt;Well with the above information you can make some pretty good guesses, but you can actually check how well things are working using JConsole.  &lt;br /&gt;&lt;br /&gt;JConsole can connect to Tomcat instances and cache statistics can be monitored.  You must configure Tomcat to open a port for JConsole to connect.  Add the following to Catalina OPTS in your startup script:&lt;br /&gt;&lt;br /&gt;-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=1612 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.snmp.port=16666 -Dcom.sun.management.snmp.acl=true&lt;br /&gt;&lt;br /&gt;You will also have to configure a management bean for your application.  For Spring applications, you can use the following XML:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&amp;lt;!-- Stuff for hibernate and ehcache mbeans --&amp;gt;&lt;br /&gt;&lt;br /&gt;        &amp;lt;bean id="ehCacheMBeanRegistration"&lt;br /&gt;                class="org.springframework.beans.factory.config.MethodInvokingFactoryBean"&amp;gt;&lt;br /&gt;&lt;br /&gt;                &amp;lt;property name="staticMethod"&lt;br /&gt;                        value="net.sf.ehcache.management.ManagementService.registerMBeans"/&amp;gt;&lt;br /&gt;                &amp;lt;property name="arguments"&amp;gt;&lt;br /&gt;                        &amp;lt;list&amp;gt;&lt;br /&gt;                                &amp;lt;ref bean="cacheManager"/&amp;gt;&lt;br /&gt;                                &amp;lt;ref bean="mbeanServer"/&amp;gt;&lt;br /&gt;                                &amp;lt;value&amp;gt;true&amp;lt;/value&amp;gt;&lt;br /&gt;                                &amp;lt;value&amp;gt;true&amp;lt;/value&amp;gt;&lt;br /&gt;                                &amp;lt;value&amp;gt;true&amp;lt;/value&amp;gt;&lt;br /&gt;                                &amp;lt;value&amp;gt;true&amp;lt;/value&amp;gt;&lt;br /&gt;                        &amp;lt;/list&amp;gt;&lt;br /&gt;                &amp;lt;/property&amp;gt;&lt;br /&gt;        &amp;lt;/bean&amp;gt;&lt;br /&gt;&lt;br /&gt;        &amp;lt;bean id="mbeanServer" class="org.springframework.jmx.support.MBeanServerFactoryBean"&amp;gt;&lt;br /&gt;                &amp;lt;property name="locateExistingServerIfPossible" value="true"/&amp;gt;&lt;br /&gt;        &amp;lt;/bean&amp;gt;&lt;br /&gt;&lt;br /&gt;        &amp;lt;bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"&amp;gt;&lt;br /&gt;                &amp;lt;property name="configLocation" value="classpath:ehcache.xml"/&amp;gt;&lt;br /&gt;                &amp;lt;property name="shared" value="true"/&amp;gt;&lt;br /&gt;        &amp;lt;/bean&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;!-- end of stuff for hibernate and ehcache mbeans --&amp;gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Now start Tomcat.  &lt;br /&gt;&lt;br /&gt;Navigate to your JDK's bin directory.  Type jconsole tomcat_hostname:port.&lt;br /&gt;&lt;br /&gt;A dialog will appear asking you to login.  Enter username/password credentials (configured in Tomcat_home/conf/tomcat-users.xml -- connect as a user with the manager role).&lt;br /&gt;&lt;br /&gt;Navigate to the MBeans tab.&lt;br /&gt;&lt;br /&gt;Expand net.sf.ehcache&lt;br /&gt;&lt;br /&gt;Expand cachestatistics&lt;br /&gt;&lt;br /&gt;There will be one more sub folder within which your regions will be listed.  Each region will have a set of Attributes.  You can monitor cache hits and misses and tune your settings to minimize the number of misses.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11240984-5369282405591697617?l=petersnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petersnotes.blogspot.com/feeds/5369282405591697617/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11240984&amp;postID=5369282405591697617' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/5369282405591697617'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/5369282405591697617'/><link rel='alternate' type='text/html' href='http://petersnotes.blogspot.com/2009/09/tuning-ehcache-and-hibernate.html' title='Tuning ehcache and hibernate'/><author><name>Peter V</name><uri>http://www.blogger.com/profile/17919841991959605501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11240984.post-9129074257662521972</id><published>2009-09-08T20:35:00.001-07:00</published><updated>2009-09-08T20:39:57.190-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Tools'/><title type='text'>WGET an entire directory</title><content type='html'>wget -r -l 1 -np http://blah.com/foo&lt;br /&gt;&lt;br /&gt;-r downloads recursively, -l X downloads follows links to the X-1 level.&lt;br /&gt;&lt;br /&gt;--no-parent  prevents (or -np) stops wget from following links to parent directories.&lt;br /&gt;&lt;br /&gt;-p downloads images, etc necessary to render HTML files.&lt;br /&gt;&lt;br /&gt;See the following link for more info:&lt;br /&gt;http://linuxreviews.org/quicktips/wget/&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11240984-9129074257662521972?l=petersnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petersnotes.blogspot.com/feeds/9129074257662521972/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11240984&amp;postID=9129074257662521972' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/9129074257662521972'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/9129074257662521972'/><link rel='alternate' type='text/html' href='http://petersnotes.blogspot.com/2009/09/wget-entire-directory.html' title='WGET an entire directory'/><author><name>Peter V</name><uri>http://www.blogger.com/profile/17919841991959605501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11240984.post-8231220842727470365</id><published>2009-09-08T20:25:00.000-07:00</published><updated>2009-09-08T20:34:41.154-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Tomcat'/><category scheme='http://www.blogger.com/atom/ns#' term='NIX administration'/><title type='text'>Quickly Tuning Tomcat JVM Options</title><content type='html'>Tomcat runs decently with default settings, but it's performance can be improved by tuning the CATALINA_OPTS string in Tomcat's startup file.&lt;br /&gt;&lt;br /&gt;The parameters you'll want to play with most are -Xms and -Xmx which set the Java memory usage bounds.  These can be tuned by starting the server and observing whether the Tomcat Java processes cause the server to access swap space.  Tune –Xms and –Xmx to maximize the memory given to Tomcat without using swap space.&lt;br /&gt;&lt;br /&gt;The -Dserver options hints to Tomcat that the machine is a server that won't be used as a desktop machine.&lt;br /&gt;&lt;br /&gt;--XX:PermSize sets the size of the perm gen heap.  I have found that this heap reaches some steady state.  If the size is too small, when JSPs compile you'll get a PermGen space error.  100M-120M has worked well for the various applications I have worked on.&lt;br /&gt;&lt;br /&gt;There are far more in depth tuning resources available if you Google around, but the above should get your started.&lt;br /&gt;&lt;br /&gt;Here is a sample Catalina Opts string:&lt;br /&gt;&lt;br /&gt;CATALINA_OPTS="-Dserver -Xms2048M -Xmx2048M -XX:PermSize=100M -XX:MaxGCPauseMillis=1000 -XX:GCTimeRatio=8 -DXlp -XX:+UseConcMarkSweepGC -XX:+CMSIncrementalMode -XX:+CMSIncrementalPacing -XX:CMSIncrementalDutyCycleMin=0 -XX:CMSIncrementalDutyCycle=25 -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=1612 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.snmp.port=16666 -Dcom.sun.management.snmp.acl=true"&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11240984-8231220842727470365?l=petersnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petersnotes.blogspot.com/feeds/8231220842727470365/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11240984&amp;postID=8231220842727470365' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/8231220842727470365'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/8231220842727470365'/><link rel='alternate' type='text/html' href='http://petersnotes.blogspot.com/2009/09/quickly-tuning-tomcat-jvm-options.html' title='Quickly Tuning Tomcat JVM Options'/><author><name>Peter V</name><uri>http://www.blogger.com/profile/17919841991959605501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11240984.post-3944875225666916768</id><published>2009-09-03T16:58:00.001-07:00</published><updated>2009-09-03T17:07:16.319-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Video'/><title type='text'>Wide Angle Lenses for Camcorders</title><content type='html'>Canon and Sony hawk some expensive wide angle lenses for their camcorders.  But, it is actually possible to buy some cheaper and better lenses easily.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;First, the Canon HV series cameras have a 43mm mount.  Almost all lenses have a larger diameter.  So you will need to buy a step up converter.  Adorama and B&amp;amp;H have plenty of these for $6+.  These have no optics, so the only difference is color and their length, which might affect how your camera focuses.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Raynox makes some good wide angle lenses in the $130 range.  The model numbers are based on the zoom.  The 5000 series is 0.50x, the 6600 series is 0.66x, and the 7000 series is 0.70x.  The various Raynox 6600 models are all the same optics but with different threads on the lenses.  They come in 43mm, 52mm, and 58mm thread on the camera end and have a 67mm thread on the front.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;If you want a cheap wide angle lens, Merkury Optics makes a decent 0.45x lens that can be had on eBay for $15 and Amazon for $30.  It is actually two pieces of glass-- a very wide angle and a macro lens.  It comes with either a 52mm or 58mm thread on the camera end and 62mm or 67mm on the front.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11240984-3944875225666916768?l=petersnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petersnotes.blogspot.com/feeds/3944875225666916768/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11240984&amp;postID=3944875225666916768' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/3944875225666916768'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/3944875225666916768'/><link rel='alternate' type='text/html' href='http://petersnotes.blogspot.com/2009/09/wide-angle-lenses-for-camcorders.html' title='Wide Angle Lenses for Camcorders'/><author><name>Peter V</name><uri>http://www.blogger.com/profile/17919841991959605501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11240984.post-4914744336206867958</id><published>2009-09-03T16:52:00.001-07:00</published><updated>2009-09-03T17:08:34.340-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Hibernate'/><title type='text'>How to Debug Hibernate Mapping Problems</title><content type='html'>If you are using Hibernate in Tomcat with XML configuration files (rather than annotations) you probably have had an instance where there was a problem with a mapping file and Tomcat will not start correctly.  The catalina log will show the mappings being loaded over and over again.  Since there is no clear order to what will be loaded next, it's not possible to tell which file is causing the issue.&lt;br /&gt;&lt;br /&gt;What you can do on a UNIX system is install strace.  strace will show you all the system calls being executed by a process.  You can attach strace to a running process and log output and then inspect which file Tomcat loaded (if you're lucky, there will be a SEGFAULT or some other problem).  The mapping files be loaded over and over again, so you just need to find where they start to loop and the last mapping is the one that is causing the problem.  To do that, you can find the first mapping file that is loaded and simply search in the log for the next occurrence.  Scroll up and you'll find the culprit.&lt;br /&gt;&lt;br /&gt;Step by step:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Start Tomcat&lt;/li&gt;&lt;li&gt;Press CTRL-Z to suspend Tomcat&lt;/li&gt;&lt;li&gt;ps -ef | grep juli to find all instances of Tomcat; note down the PID (usually the first of two similar, adjacent numbers)&lt;/li&gt;&lt;li&gt;Execute "bg 1" to resume execution of Tomcat&lt;/li&gt;&lt;li&gt;Execute "strace -fF -p YOUR_PID_HERE &amp;amp;&gt; strace.log" to trace Tomcat&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;That's it... good luck!&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11240984-4914744336206867958?l=petersnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petersnotes.blogspot.com/feeds/4914744336206867958/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11240984&amp;postID=4914744336206867958' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/4914744336206867958'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/4914744336206867958'/><link rel='alternate' type='text/html' href='http://petersnotes.blogspot.com/2009/09/how-to-debug-hibernate-mapping-problems.html' title='How to Debug Hibernate Mapping Problems'/><author><name>Peter V</name><uri>http://www.blogger.com/profile/17919841991959605501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11240984.post-4987203529938270866</id><published>2009-07-30T09:17:00.000-07:00</published><updated>2009-07-30T09:31:11.004-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Hibernate'/><category scheme='http://www.blogger.com/atom/ns#' term='JPA'/><title type='text'>Using Named Queries</title><content type='html'>Named queries make it easy to reuse SQL queries in JPA Entity Beans &amp; Controllers and they are also more readable than inline SQL.  I'm not sure, but my guess is they probably run faster too.&lt;br /&gt;&lt;br /&gt;There are two steps.&lt;br /&gt;&lt;br /&gt;1. Add Named Queries as a comma delimited list before your Entity bean's class definition, like so (Remember that the queries are in QL, not SQL.  It's SQL like syntax, but you're manipulating the Java objects, not the underlying SQL, so name your "tables" and "columns" appropriately):&lt;br /&gt;&lt;pre&gt;@Entity&lt;br /&gt;@Table(name = "MY_TABLE", catalog = "", schema = "")&lt;br /&gt;@NamedQueries({&lt;br /&gt;    @NamedQuery(name = "SchedJob.findAll", query = "SELECT s FROM SchedJob s"),&lt;br /&gt;    ...&lt;br /&gt;)})&lt;br /&gt;public class MyObject implements Serializable {&lt;br /&gt;    ...&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;2. Use the named query in your controller by calling createNamedQuery on your entity manager.&lt;br /&gt;&lt;pre&gt;    public List&lt;MyObject&gt; findByText(String text) {&lt;br /&gt;        EntityManager em = getEntityManager();&lt;br /&gt;        try {&lt;br /&gt;            Query q = em.createNamedQuery("MyObject.findByText");&lt;br /&gt;            q.setParameter("text", text);&lt;br /&gt;            return q.getResultList();&lt;br /&gt;        } finally {&lt;br /&gt;            em.close();&lt;br /&gt;        }&lt;br /&gt;    }&lt;/pre&gt;&lt;br /&gt;You can also return a single result and some other things (Google for the Javadocs).&lt;br /&gt;&lt;br /&gt;A more compact format is:&lt;br /&gt;&lt;pre&gt;Teachers teacher = (Teachers) &lt;br /&gt;em.createNamedQuery("Teachers.findByGName").setParameter("gName", &lt;br /&gt;gNameString).getSingleResult(); &lt;/pre&gt;&lt;br /&gt;or &lt;br /&gt;&lt;pre&gt;List&lt;Teachers&gt; teachers = (Teachers) &lt;br /&gt;em.createNamedQuery("Teachers.findByGName").setParameter("gName", &lt;br /&gt;gNameString).getResultList(); &lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11240984-4987203529938270866?l=petersnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petersnotes.blogspot.com/feeds/4987203529938270866/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11240984&amp;postID=4987203529938270866' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/4987203529938270866'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/4987203529938270866'/><link rel='alternate' type='text/html' href='http://petersnotes.blogspot.com/2009/07/using-named-queries.html' title='Using Named Queries'/><author><name>Peter V</name><uri>http://www.blogger.com/profile/17919841991959605501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11240984.post-9082136109336842186</id><published>2009-07-23T14:35:00.000-07:00</published><updated>2009-07-23T16:27:27.262-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><title type='text'>Iterating Collections in Java</title><content type='html'>&lt;div&gt;There are a number of ways to iterate over Collections.  The old and tedious method is to use iterators and a for loop or while hasNext().  In recent years you can instead use an EntrySet.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Here's a pretty good sampling of the methods available:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;a href="http://hanuska.blogspot.com/2006/08/improved-map-iteration_13.html"&gt;http://hanuska.blogspot.com/2006/08/improved-map-iteration_13.html&lt;/a&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;And my own iteration over a set:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;pre&gt;// assumes Map&amp;lt;String, String&amp;gt; stuffAttributes exists in scope&lt;br /&gt;            Set&amp;lt;Stuff&amp;gt; attributes = new HashSet&amp;lt;Stuff&amp;gt;();&lt;br /&gt;            Boolean success = true;&lt;br /&gt;&lt;br /&gt;            for (Map.Entry&amp;lt;String, String&amp;gt; prmEntry : stuffAttributes.entrySet()) {&lt;br /&gt;                StuffAttribute attribute = new UserNotificationsAttribute();&lt;br /&gt;                attribute.setAttributeKey(prmEntry.getKey());&lt;br /&gt;                attribute.setAttributeValue(prmEntry.getValue());&lt;br /&gt;                if (!attributes.add(attribute)) {&lt;br /&gt;                    success = false;&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;            un.setStuffAttributeSet(attributes);&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11240984-9082136109336842186?l=petersnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petersnotes.blogspot.com/feeds/9082136109336842186/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11240984&amp;postID=9082136109336842186' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/9082136109336842186'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/9082136109336842186'/><link rel='alternate' type='text/html' href='http://petersnotes.blogspot.com/2009/07/iterating-collections-in-java.html' title='Iterating Collections in Java'/><author><name>Peter V</name><uri>http://www.blogger.com/profile/17919841991959605501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11240984.post-4652471326230157093</id><published>2009-07-23T14:32:00.000-07:00</published><updated>2009-07-23T14:35:29.513-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Struts'/><title type='text'>Getting Request and Response objects in a Struts Action Class</title><content type='html'>&lt;div&gt;Basically, you need to make your action class implement two interfaces-- ServletRequestAware, ServletResponseAware, add an HttpServletRequest and HttpServletResponse object, then implement the necessary getters and setters for each.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;See full code:&lt;/div&gt;&lt;a href="http://www.roseindia.net/struts/struts2/strutsresources/access-request-response.shtml"&gt;http://www.roseindia.net/struts/struts2/strutsresources/access-request-response.shtml&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11240984-4652471326230157093?l=petersnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petersnotes.blogspot.com/feeds/4652471326230157093/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11240984&amp;postID=4652471326230157093' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/4652471326230157093'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/4652471326230157093'/><link rel='alternate' type='text/html' href='http://petersnotes.blogspot.com/2009/07/getting-request-and-response-objects-in.html' title='Getting Request and Response objects in a Struts Action Class'/><author><name>Peter V</name><uri>http://www.blogger.com/profile/17919841991959605501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11240984.post-4277601892810562753</id><published>2009-06-10T10:05:00.000-07:00</published><updated>2009-06-10T10:08:27.685-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='XSL'/><category scheme='http://www.blogger.com/atom/ns#' term='XML'/><title type='text'>Sort a Whole XML Document using XSL</title><content type='html'>This is a variation of an identity transformation that sorts all nodes and attributes alphabetically.&lt;br /&gt;&lt;pre&gt;&amp;lt;xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&amp;gt;&lt;br /&gt;&amp;lt;xsl:output indent="yes"/&amp;gt;&lt;br /&gt;&amp;lt;xsl:output method="xml" omit-xml-declaration="no"/&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;xsl:template match="@*|node()" priority="1"&amp;gt;&lt;br /&gt;  &amp;lt;xsl:copy&amp;gt;&lt;br /&gt;    &amp;lt;xsl:apply-templates select="@*|node()"&amp;gt;&lt;br /&gt;      &amp;lt;xsl:sort select="name()" data-type="text" order="ascending"/&amp;gt;&lt;br /&gt;    &amp;lt;/xsl:apply-templates&amp;gt;&lt;br /&gt;  &amp;lt;/xsl:copy&amp;gt;&lt;br /&gt;&amp;lt;/xsl:template&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;/xsl:stylesheet&amp;gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11240984-4277601892810562753?l=petersnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petersnotes.blogspot.com/feeds/4277601892810562753/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11240984&amp;postID=4277601892810562753' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/4277601892810562753'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/4277601892810562753'/><link rel='alternate' type='text/html' href='http://petersnotes.blogspot.com/2009/06/sort-whole-xml-document-using-xsl.html' title='Sort a Whole XML Document using XSL'/><author><name>Peter V</name><uri>http://www.blogger.com/profile/17919841991959605501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11240984.post-9095416863189669166</id><published>2009-05-18T16:08:00.000-07:00</published><updated>2009-05-18T16:12:14.117-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Windows'/><title type='text'>Recursive File Listing</title><content type='html'>Here's how to create a recursive file listing in Windows from the command shell:&lt;br /&gt;&lt;pre&gt;dir /a /s /-p /b /o:gen *.cdg &gt; filelisting.txt&lt;/pre&gt;&lt;br /&gt;Check out &lt;a href="http://www.theeldergeek.com/file_list_generator.htm"&gt;this link&lt;/a&gt; for adding it to the context menu.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11240984-9095416863189669166?l=petersnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petersnotes.blogspot.com/feeds/9095416863189669166/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11240984&amp;postID=9095416863189669166' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/9095416863189669166'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/9095416863189669166'/><link rel='alternate' type='text/html' href='http://petersnotes.blogspot.com/2009/05/recursive-file-listing.html' title='Recursive File Listing'/><author><name>Peter V</name><uri>http://www.blogger.com/profile/17919841991959605501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11240984.post-5950374771557530609</id><published>2009-05-15T17:31:00.000-07:00</published><updated>2009-05-15T17:37:48.814-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='DIY'/><title type='text'>Improving your WiFi Reception</title><content type='html'>I hate wi-fi and wi-fi products with a passion, but it's here to stay.  And if you're stuck with it, the following upgrades might just make it more usable.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.freeantennas.com/projects/template/"&gt;This link&lt;/a&gt; provides a template for a simple focusing antenna attachment for routers&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.engadget.com/2005/11/15/how-to-build-a-wifi-biquad-dish-antenna/"&gt;This link&lt;/a&gt; has a really crazy satellite dish setup as does &lt;a href="http://martybugs.net/wireless/biquad/"&gt;this one&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;I've tried the simple version using a cereal box, aluminum foil, and duct tape and it works.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11240984-5950374771557530609?l=petersnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petersnotes.blogspot.com/feeds/5950374771557530609/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11240984&amp;postID=5950374771557530609' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/5950374771557530609'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/5950374771557530609'/><link rel='alternate' type='text/html' href='http://petersnotes.blogspot.com/2009/05/improving-your-wifi-reception.html' title='Improving your WiFi Reception'/><author><name>Peter V</name><uri>http://www.blogger.com/profile/17919841991959605501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11240984.post-4722123249475392325</id><published>2009-05-15T17:15:00.000-07:00</published><updated>2009-05-15T17:29:07.161-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='perl'/><title type='text'>Perl and Variables</title><content type='html'>Perl out C++s' C++ when it comes to variables.  Rather than just some confusing concepts it adds hard to remember syntax (not as bad as regular expressions though).&lt;br /&gt;&lt;br /&gt;Want to pass a hash as an argument to a sub routine in a package, and then pass it to another routine?  Iterate through a list inside a hash?  What about passing globs around?  The number of combinations is just too many and I recommend you refer to the following link:&lt;br /&gt;&lt;br /&gt;http://oreilly.com/catalog/advperl/excerpt/ch01.html&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11240984-4722123249475392325?l=petersnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petersnotes.blogspot.com/feeds/4722123249475392325/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11240984&amp;postID=4722123249475392325' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/4722123249475392325'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/4722123249475392325'/><link rel='alternate' type='text/html' href='http://petersnotes.blogspot.com/2009/05/perl-and-variables.html' title='Perl and Variables'/><author><name>Peter V</name><uri>http://www.blogger.com/profile/17919841991959605501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11240984.post-6906057787877740657</id><published>2009-05-14T15:45:00.001-07:00</published><updated>2009-05-15T17:31:34.141-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='perl'/><title type='text'>Quickly Create an Object Oriented Perl Module</title><content type='html'>&lt;ol&gt;&lt;li&gt;Create a directory under the current directory for your module&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Create a file called &lt;span class="Apple-style-span" style="font-style: italic;"&gt;yourmodule&lt;/span&gt;.pm&lt;/li&gt;&lt;li&gt;Put the following line at the top:&lt;br /&gt;package &lt;span class="Apple-style-span" style="font-style: italic;"&gt;yourmodule&lt;/span&gt;;&lt;/li&gt;&lt;li&gt;Now paste the following and edit the require code to include all the libraries your package needs&lt;br /&gt;&lt;pre&gt;use 5.0;&lt;br /&gt;#use strict;&lt;br /&gt;use warnings;&lt;br /&gt;&lt;br /&gt;require Win32::GuiTest, HTTP::Request, XML::Smart, Exporter;&lt;br /&gt;our @ISA = qw(Exporter);&lt;br /&gt;our %EXPORT_TAGS = ( 'all' =&amp;gt; [ qw() ] );&lt;br /&gt;our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );&lt;br /&gt;our @EXPORT = qw( );&lt;br /&gt;&lt;br /&gt;our $VERSION = '1.00';&lt;/pre&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Create a constructor subroutine; it needs to bless a reference to the object as its last line (put whatever you like before that)&lt;br /&gt;&lt;pre&gt;sub new {&lt;br /&gt; my $self = { FOO =&amp;gt; 1, BAR =&amp;gt; 0};&lt;br /&gt; bless $self, "yourmodule";&lt;br /&gt;}&lt;/pre&gt;&lt;/li&gt;&lt;li&gt;Load the module in your Perl file&lt;br /&gt;&lt;br /&gt;use lib './yourmodule'; # this adds the module directory to your include path&lt;br /&gt;use &lt;span class="Apple-style-span" style="font-style: italic;"&gt;yourmodule&lt;/span&gt;; # this loads your module&lt;/li&gt;&lt;li&gt;You can now call your module from your perl file:&lt;br /&gt;&lt;pre&gt;my $barf = yourmodule-&amp;gt;new();&lt;br /&gt;print $barf-&amp;gt;get_stuff() . "\n";&lt;br /&gt;exit(0);&lt;/pre&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Remember! when you call your package's methods using an object ($object-&gt;method()), the first argument is a reference to the object-- you can restore 'normal' operation (if you just pasted the sub routine from within a normal perl file) by just adding my $self=shift; to the top of your sub routine.&lt;/li&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11240984-6906057787877740657?l=petersnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petersnotes.blogspot.com/feeds/6906057787877740657/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11240984&amp;postID=6906057787877740657' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/6906057787877740657'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/6906057787877740657'/><link rel='alternate' type='text/html' href='http://petersnotes.blogspot.com/2009/05/quickly-create-object-oriented-perl.html' title='Quickly Create an Object Oriented Perl Module'/><author><name>Peter V</name><uri>http://www.blogger.com/profile/17919841991959605501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11240984.post-2084130523210773952</id><published>2009-05-12T10:33:00.001-07:00</published><updated>2009-05-12T14:27:41.501-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='XSL'/><category scheme='http://www.blogger.com/atom/ns#' term='XML'/><title type='text'>How to Get XPath to an XML Node</title><content type='html'>There are several XSL templates floating around that get a human readable path to a node.  However, I found none that cover the case when there are multiple nodes of the same element at the same level.  I came up with a complicated solution that kept the output human readable, but the solution for something machine readable is actually simple.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&amp;lt;xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&amp;gt;&lt;br /&gt;  &amp;lt;xsl:output indent="yes"/&amp;gt;&lt;br /&gt;  &amp;lt;xsl:template match="@*|node()"&amp;gt;&lt;br /&gt;      &amp;lt;xsl:copy&amp;gt;        &lt;br /&gt;        &amp;lt;xsl:attribute name="position"&amp;gt;&amp;lt;xsl:call-template name="xpath.position"&amp;gt;&amp;lt;/xsl:call-template&amp;lt;/xsl:attribute&amp;gt;&lt;br /&gt;        &amp;lt;xsl:apply-templates select="@*|node()"/&amp;gt;&lt;br /&gt;      &amp;lt;/xsl:copy&amp;gt;&lt;br /&gt;  &amp;lt;/xsl:template&amp;gt;&lt;br /&gt;&lt;br /&gt;  &amp;lt;xsl:template name="xpath.position"&amp;gt;&lt;br /&gt;    &amp;lt;xsl:param name="node" select="."&amp;gt;&amp;lt;/xsl:param&amp;gt; &amp;lt;!-- default value is current node --&amp;gt;&lt;br /&gt;    &amp;lt;xsl:param name="path" select="''"&amp;gt;&amp;lt;/xsl:param&amp;gt; &amp;lt;!-- default value is empty string --&amp;gt;&lt;br /&gt;&lt;br /&gt;    &amp;lt;!-- prepend the current position to $path, save it as next.path --&amp;gt;&lt;br /&gt;    &amp;lt;xsl:variable name="next.path"&amp;gt;&amp;lt;xsl:text&amp;gt;*[position()=&amp;lt;/xsl:text&amp;gt;&amp;lt;xsl:value-of select="$node/count(preceding-sibling::*)+1"/&amp;gt;&amp;lt;xsl:text&amp;gt;]&amp;lt;/xsl:text&amp;gt;&lt;br /&gt;      &amp;lt;xsl:if test="$path != ''"&amp;gt;/&amp;lt;/xsl:if&amp;gt;&lt;br /&gt;      &amp;lt;xsl:value-of select="$path"&amp;gt;&amp;lt;/xsl:value-of&amp;gt;&lt;br /&gt;    &amp;lt;/xsl:variable&amp;gt;&lt;br /&gt;&lt;br /&gt;    &amp;lt;xsl:choose&amp;gt;&lt;br /&gt;      &amp;lt;xsl:when test="$node/parent::*"&amp;gt; &amp;lt;!-- when there is a parent node --&amp;gt;&lt;br /&gt;        &amp;lt;xsl:call-template name="xpath.position"&amp;gt;&lt;br /&gt;          &amp;lt;xsl:with-param name="node" select="$node/parent::*"&amp;gt;&amp;lt;/xsl:with-param&amp;gt;&lt;br /&gt;          &amp;lt;xsl:with-param name="path" select="$next.path"&amp;gt;&amp;lt;/xsl:with-param&amp;gt;&lt;br /&gt;        &amp;lt;/xsl:call-template&amp;gt;&lt;br /&gt;      &amp;lt;/xsl:when&amp;gt;&lt;br /&gt;      &amp;lt;xsl:otherwise&amp;gt;&lt;br /&gt;        &amp;lt;xsl:text&amp;gt;/&amp;lt;/xsl:text&amp;gt;&lt;br /&gt;        &amp;lt;xsl:value-of select="$next.path"&amp;gt;&amp;lt;/xsl:value-of&amp;gt;&lt;br /&gt;      &amp;lt;/xsl:otherwise&amp;gt;&lt;br /&gt;    &amp;lt;/xsl:choose&amp;gt;&lt;br /&gt;  &amp;lt;/xsl:template&amp;gt;&lt;br /&gt;  &lt;br /&gt;&amp;lt;/xsl:stylesheet&amp;gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11240984-2084130523210773952?l=petersnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petersnotes.blogspot.com/feeds/2084130523210773952/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11240984&amp;postID=2084130523210773952' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/2084130523210773952'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/2084130523210773952'/><link rel='alternate' type='text/html' href='http://petersnotes.blogspot.com/2009/05/how-to-get-xpath-to-xml-node.html' title='How to Get XPath to an XML Node'/><author><name>Peter V</name><uri>http://www.blogger.com/profile/17919841991959605501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11240984.post-6336273311013469491</id><published>2009-05-12T10:28:00.000-07:00</published><updated>2009-05-12T10:29:53.652-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='XSL'/><category scheme='http://www.blogger.com/atom/ns#' term='XML'/><title type='text'>Identity Transformation that Removes Empty Nodes</title><content type='html'>Sometimes its handy to remove XML nodes that have no content other than whitespace.  The following XSL does exactly that.&lt;br /&gt;&lt;pre&gt;&amp;lt;xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&amp;gt;&lt;br /&gt;  &amp;lt;xsl:template match="@*|node()"&amp;gt;&lt;br /&gt;    &amp;lt;xsl:if test=". != '' or ./@* != ''"&amp;gt;&lt;br /&gt;     &amp;lt;xsl:if test="not(contains(name(), 'temp'))"&amp;gt;&lt;br /&gt;      &amp;lt;xsl:copy&amp;gt;&lt;br /&gt;        &amp;lt;xsl:apply-templates select="@*|node()"/&amp;gt;&lt;br /&gt;      &amp;lt;/xsl:copy&amp;gt;&lt;br /&gt;     &amp;lt;/xsl:if&amp;gt;&lt;br /&gt;    &amp;lt;/xsl:if&amp;gt;&lt;br /&gt;  &amp;lt;/xsl:template&amp;gt;&lt;br /&gt;&amp;lt;/xsl:stylesheet&amp;gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11240984-6336273311013469491?l=petersnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petersnotes.blogspot.com/feeds/6336273311013469491/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11240984&amp;postID=6336273311013469491' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/6336273311013469491'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/6336273311013469491'/><link rel='alternate' type='text/html' href='http://petersnotes.blogspot.com/2009/05/identity-transformation-that-removes.html' title='Identity Transformation that Removes Empty Nodes'/><author><name>Peter V</name><uri>http://www.blogger.com/profile/17919841991959605501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11240984.post-4158487745327968788</id><published>2009-05-11T15:56:00.001-07:00</published><updated>2009-05-11T15:57:05.619-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='perl'/><title type='text'>Appending to a File</title><content type='html'>The secret to this is just to open the file with &amp;gt;&amp;gt; prefixed to the filename.&lt;br /&gt;&lt;pre&gt;$logfile="appendtext.lo";&lt;br /&gt;open(DAT,"&amp;gt;&amp;gt;$logfile") || die("Cannot Open File $logfile: $!");&lt;br /&gt;&lt;br /&gt;print DAT "\nfarq=foo";&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11240984-4158487745327968788?l=petersnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petersnotes.blogspot.com/feeds/4158487745327968788/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11240984&amp;postID=4158487745327968788' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/4158487745327968788'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/4158487745327968788'/><link rel='alternate' type='text/html' href='http://petersnotes.blogspot.com/2009/05/appending-to-file.html' title='Appending to a File'/><author><name>Peter V</name><uri>http://www.blogger.com/profile/17919841991959605501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11240984.post-4384467807514352045</id><published>2009-05-11T14:53:00.000-07:00</published><updated>2009-05-11T14:56:38.073-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='perl'/><title type='text'>Load a .properties file into a hash</title><content type='html'>Given the following file: &lt;pre&gt;[blah]&lt;br /&gt;stuff1=farqasaur&lt;br /&gt;stuff2=loud sucking sound&lt;/pre&gt; lets load it into a perl hash where we can get values by using the key as an index.&lt;br /&gt;&lt;pre&gt;my $textfile = "properties.properties";&lt;br /&gt;my %properties;&lt;br /&gt;&lt;br /&gt;open TEXTFILE, $textfile or die("Could not open text file '" . $textfile . "': $!");&lt;br /&gt;foreach $line (&amp;lt;TEXTFILE&amp;gt;) {&lt;br /&gt;    chomp($line);              # remove the newline from $line.&lt;br /&gt;    @tokens = split(/=/, $line);&lt;br /&gt;    # do line-by-line processing.&lt;br /&gt;    printf(@tokens . "\n");&lt;br /&gt;    if(@tokens == 2 ) { # if this is a key value pair, save it to the hash&lt;br /&gt;      $properties{@tokens[0]}=@tokens[1];&lt;br /&gt;      printf("\n Saving " . @tokens[0]);&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;Now you can access the hash like so:&lt;pre&gt;foreach $kv (%properties) {&lt;br /&gt;  printf($kv[0] . "\n");&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;printf("\nstuff1:" . $properties{'stuff1'});&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11240984-4384467807514352045?l=petersnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petersnotes.blogspot.com/feeds/4384467807514352045/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11240984&amp;postID=4384467807514352045' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/4384467807514352045'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/4384467807514352045'/><link rel='alternate' type='text/html' href='http://petersnotes.blogspot.com/2009/05/load-properties-file-into-hash.html' title='Load a .properties file into a hash'/><author><name>Peter V</name><uri>http://www.blogger.com/profile/17919841991959605501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11240984.post-7097763853672230977</id><published>2009-05-11T12:56:00.000-07:00</published><updated>2009-05-11T12:58:57.911-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='perl'/><title type='text'>Delete or Zero a File or Files</title><content type='html'>&lt;h3&gt;Zero a File&lt;/h3&gt;&lt;pre&gt;#&lt;br /&gt;# ------ zero an existing file -----------&lt;br /&gt;#&lt;br /&gt;# just pass in a string file name&lt;br /&gt;&lt;br /&gt;sub zerofile { &lt;br /&gt;  foreach (@_) { &lt;br /&gt;    open FH, "&gt;", $_ or die "Couldn't open '$filename': $!";&lt;br /&gt;    close FH;&lt;br /&gt;  }&lt;br /&gt;}&lt;/pre&gt;&lt;h3&gt;Delete Files&lt;/h3&gt;&lt;pre&gt;unlink &lt;$path/*.txt&gt;;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11240984-7097763853672230977?l=petersnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petersnotes.blogspot.com/feeds/7097763853672230977/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11240984&amp;postID=7097763853672230977' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/7097763853672230977'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/7097763853672230977'/><link rel='alternate' type='text/html' href='http://petersnotes.blogspot.com/2009/05/delete-or-zero-file-or-files.html' title='Delete or Zero a File or Files'/><author><name>Peter V</name><uri>http://www.blogger.com/profile/17919841991959605501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11240984.post-8746862700621409503</id><published>2009-05-11T12:52:00.000-07:00</published><updated>2009-05-11T13:07:20.598-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='perl'/><title type='text'>Reading a File in Perl</title><content type='html'>Two approaches are shown here.  Reading the whole file and reading it line by line.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;The whole file&lt;/h3&gt;&lt;br /&gt;&lt;pre&gt;sub ReadFile {&lt;br /&gt;       my ($filename) = @_;&lt;br /&gt;       &lt;br /&gt;       open TMP,$filename or die "Couldn't open '$filename': $!";&lt;br /&gt;       local $/ = undef; # eat the whole file&lt;br /&gt;       my $text = &lt;TMP&gt;;&lt;br /&gt;       close TMP;&lt;br /&gt;       return $text;&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Line by line&lt;/h3&gt;&lt;br /&gt;&lt;pre&gt;my $textfile = "blah.txt";&lt;br /&gt;&lt;br /&gt;open TEXTFILE, $textfile or die("Could not open text file '" . $textfile . "': $!");&lt;br /&gt;foreach $line (&amp;lt;TEXTFILE&amp;gt;) {&lt;br /&gt;    chomp($line);              # remove the newline from $line.&lt;br /&gt;    # do line-by-line processing.&lt;br /&gt;    if($line =~ [insert some regexp here]) {&lt;br /&gt;      # you can now access the results of your regexp using $1,$2,...&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11240984-8746862700621409503?l=petersnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petersnotes.blogspot.com/feeds/8746862700621409503/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11240984&amp;postID=8746862700621409503' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/8746862700621409503'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/8746862700621409503'/><link rel='alternate' type='text/html' href='http://petersnotes.blogspot.com/2009/05/reading-file-in-perl.html' title='Reading a File in Perl'/><author><name>Peter V</name><uri>http://www.blogger.com/profile/17919841991959605501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11240984.post-2791468110936848811</id><published>2009-05-11T12:46:00.000-07:00</published><updated>2009-05-11T12:50:00.455-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='perl'/><title type='text'>Sending Mouse Clicks via Win32::GuiTest</title><content type='html'>This is a little more difficult than key presses.  Many thanks to George Nistorica for his article which you can &lt;a href="http://www.perl.com/pub/a/2005/08/11/win32guitest.html?page=2"&gt;read here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;# click_mouse ( window, xoffset, yoffset)&lt;br /&gt;sub click_mouse {&lt;br /&gt;    my $window = shift;&lt;br /&gt;    my $x_offset = shift;&lt;br /&gt;    my $y_offset = shift;&lt;br /&gt;  &lt;br /&gt;    my ( $left, $top, $right, $bottom ) = GetWindowRect($window);&lt;br /&gt; &lt;br /&gt;    MouseMoveAbsPix( ( $left + $x_offset ), ( $top + $y_offset) );&lt;br /&gt;&lt;br /&gt;    SendMouse("{LeftClick}");&lt;br /&gt;}&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11240984-2791468110936848811?l=petersnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petersnotes.blogspot.com/feeds/2791468110936848811/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11240984&amp;postID=2791468110936848811' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/2791468110936848811'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/2791468110936848811'/><link rel='alternate' type='text/html' href='http://petersnotes.blogspot.com/2009/05/sending-mouse-clicks-via-win32guitest.html' title='Sending Mouse Clicks via Win32::GuiTest'/><author><name>Peter V</name><uri>http://www.blogger.com/profile/17919841991959605501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11240984.post-7125592535881113730</id><published>2009-05-11T12:44:00.000-07:00</published><updated>2009-05-11T14:26:46.873-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='perl'/><title type='text'>Using Win32::GuiTest to send a keystroke</title><content type='html'>Sending keystrokes with Win32::GuiTest is straightforward.  Really straightforward.&lt;br /&gt;&lt;br /&gt;One key:&lt;br /&gt;&lt;code&gt;SendKeys('{ENTER}');&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Multiple keys: &lt;br /&gt;&lt;pre&gt;my @keys = ( "%{F}", "{RIGHT}", "E", );&lt;br /&gt;my $pause_between_keypress = 1;&lt;br /&gt;for my $key (@keys) {&lt;br /&gt;    SendKeys( $key, $pause_between_keypress );&lt;br /&gt;}&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11240984-7125592535881113730?l=petersnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petersnotes.blogspot.com/feeds/7125592535881113730/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11240984&amp;postID=7125592535881113730' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/7125592535881113730'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/7125592535881113730'/><link rel='alternate' type='text/html' href='http://petersnotes.blogspot.com/2009/05/using-win32guitest-to-send-keystroke.html' title='Using Win32::GuiTest to send a keystroke'/><author><name>Peter V</name><uri>http://www.blogger.com/profile/17919841991959605501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11240984.post-3966188696523614192</id><published>2009-05-11T12:37:00.000-07:00</published><updated>2009-05-11T12:52:01.576-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='perl'/><title type='text'>Loading Perl's Win32::GuiTest</title><content type='html'>The Win32::GuiTest allows perl scripts run under Windows to send keyboard and mouse events to Win32 programs.  George Nistorica wrote an &lt;a href="http://www.perl.com/pub/a/2005/08/11/win32guitest.html?page=2"&gt;article&lt;/a&gt; on how to do this; I've summarized what you need to do here.  &lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;ol&gt;&lt;li&gt;Run ppm (the perl package manager)&lt;/li&gt;&lt;li&gt;Type 'install Win32::GuiTest'&lt;/li&gt;&lt;li&gt;Add the following code to your perl script:&lt;br /&gt;&lt;pre&gt;use Win32::GuiTest qw(IsWindow FindWindowLike SendKeys&lt;br /&gt;       PushButton SetActiveWindow SetForegroundWindow GetWindowRect MouseMoveAbsPix SendMouse);&lt;/pre&gt;(Note that each function you need to call should be listed in this enum-- I've listed the most common ones&lt;/li&gt;&lt;li&gt;Bring your window to the foreground:&lt;br /&gt;&lt;pre&gt;sub bring_window_to_front {&lt;br /&gt;     my $window  = shift;&lt;br /&gt;     my $success = 1;&lt;br /&gt;&lt;br /&gt;     if ( SetActiveWindow($window) ) {&lt;br /&gt;         print "* Successfully set the window id: $window active\n";&lt;br /&gt;     }&lt;br /&gt;     else {&lt;br /&gt;         print "* Could not set the window id: $window active\n";&lt;br /&gt;         $success = 0;&lt;br /&gt;     }&lt;br /&gt;     if ( SetForegroundWindow($window) ) {&lt;br /&gt;         print "* Window id: $window brought to foreground\n";&lt;br /&gt;     }&lt;br /&gt;     else {&lt;br /&gt;         print "* Window id: $window could not be brought to foreground\n";&lt;br /&gt;         $success = 0;&lt;br /&gt;     }&lt;br /&gt;&lt;br /&gt;     return $success;&lt;br /&gt; }&lt;/pre&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11240984-3966188696523614192?l=petersnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petersnotes.blogspot.com/feeds/3966188696523614192/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11240984&amp;postID=3966188696523614192' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/3966188696523614192'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/3966188696523614192'/><link rel='alternate' type='text/html' href='http://petersnotes.blogspot.com/2009/05/loading-perls-win32guitest.html' title='Loading Perl&apos;s Win32::GuiTest'/><author><name>Peter V</name><uri>http://www.blogger.com/profile/17919841991959605501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11240984.post-5284551074680175920</id><published>2009-05-07T10:15:00.000-07:00</published><updated>2009-05-07T15:25:31.628-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='perl'/><title type='text'>Make an HTTP Request to an Address Protected by HTTP Basic Authentication</title><content type='html'>There are a number of tutorials using LWP and credentials, but none of those worked for me-- additionally I had no idea what the realm was (the server never sent it!).&lt;br /&gt;&lt;br /&gt;It's possible to modify the request using authorization_basic which does not require a realm.  This is what I used successfully.&lt;br /&gt;&lt;br /&gt;Fiddler2, which can sniff packets from IE or Google Chrome, was invaluable here.&lt;br /&gt;&lt;br /&gt;This is the code:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;use HTTP::Request::Common;&lt;br /&gt;use HTTP::Headers;&lt;br /&gt;use LWP::UserAgent;&lt;br /&gt;use LWP::Debug qw(+); #get the most logging available&lt;br /&gt;  my $username = 'usernamehere';&lt;br /&gt;  my $password = 'passwordhere';&lt;br /&gt;  my $host = 'blah.blha.com';&lt;br /&gt;  my %cookies = ();&lt;br /&gt;    &lt;br /&gt;  my $path = '/path/to/your/page';&lt;br /&gt;  &lt;br /&gt;  printf("Creating User Agent\n");&lt;br /&gt;  my $browser = LWP::UserAgent-&gt;new;&lt;br /&gt;  $browser-&amp;gt;cookie_jar( {} );&lt;br /&gt;  &lt;br /&gt;  printf("Creating Request\n");  &lt;br /&gt;  my $request = HTTP::Request-&gt;new(GET =&amp;gt; '$host$path');&lt;br /&gt;  printf("Add auth data\n");  &lt;br /&gt;  $request-&amp;gt;authorization_basic($username, $password);&lt;br /&gt;  &lt;br /&gt;  printf("Sending Request\n");&lt;br /&gt;  my $response = $browser-&amp;gt;request($request);&lt;br /&gt;&lt;br /&gt;  die "Error: ", $response-&amp;gt;header('WWW-Authenticate') || &lt;br /&gt;    'Error accessing',&lt;br /&gt;    #  ('WWW-Authenticate' is the realm-name)&lt;br /&gt;    "\n ", $response-&amp;gt;status_line, "\n at $url\n Aborting"&lt;br /&gt;   unless $response-&amp;gt;is_success;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;One other note.  The syntax for the other types of requests can get a bid unwieldy.  A list of key=value pairs is straightforward:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;$ua-&gt;request(POST 'http://somewhere/foo', [foo =&gt; bar, bar =&gt; foo]);&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;But what about sending XML?  I created the following if statement for a request wrapper.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;  if($method eq 'GET') {&lt;br /&gt;    $request = HTTP::Request-&amp;gt;new(GET =&amp;gt; $url);&lt;br /&gt;  } else {&lt;br /&gt;    $request = HTTP::Request-&amp;gt;new($method =&amp;gt; $url);&lt;br /&gt;    $request-&amp;gt;content_type( 'application/xml' );&lt;br /&gt;    $request-&amp;gt;content( $body );&lt;br /&gt;  }&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11240984-5284551074680175920?l=petersnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petersnotes.blogspot.com/feeds/5284551074680175920/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11240984&amp;postID=5284551074680175920' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/5284551074680175920'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/5284551074680175920'/><link rel='alternate' type='text/html' href='http://petersnotes.blogspot.com/2009/05/make-http-request-to-address-protected.html' title='Make an HTTP Request to an Address Protected by HTTP Basic Authentication'/><author><name>Peter V</name><uri>http://www.blogger.com/profile/17919841991959605501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11240984.post-366585995164927997</id><published>2009-04-10T10:27:00.000-07:00</published><updated>2009-04-10T10:32:54.710-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Tomcat'/><category scheme='http://www.blogger.com/atom/ns#' term='NIX administration'/><title type='text'>Tomcat's Catalina base and Catalina home</title><content type='html'>&lt;div&gt;Sometimes you see references to tomcat/catalina home and tomcat/catalina base.  What's the difference.  The answer comes from Alessandro A. Garbagnati who writes:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;blockquote&gt;"The first properties (catalina.home) points to the location of the common information, while the other property (catalina.base) points to the directory where all the instance specific information are held."&lt;/blockquote&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;Basically, this way you can keep one copy of the Tomcat binaries yet use a different configuration by changing the directory to which base points (this directory must contain conf, logs, webapps, work, and temp).&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11240984-366585995164927997?l=petersnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petersnotes.blogspot.com/feeds/366585995164927997/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11240984&amp;postID=366585995164927997' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/366585995164927997'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/366585995164927997'/><link rel='alternate' type='text/html' href='http://petersnotes.blogspot.com/2009/04/tomcats-catalina-base-and-catalina-home.html' title='Tomcat&apos;s Catalina base and Catalina home'/><author><name>Peter V</name><uri>http://www.blogger.com/profile/17919841991959605501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11240984.post-1602629719126275155</id><published>2009-01-15T15:57:00.000-08:00</published><updated>2009-01-15T16:10:43.449-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='JUnit'/><title type='text'>Getting Started with JUnit</title><content type='html'>I'm going to skip installation.  Eclipse EE has it built in; and you can Google how to install JUnit too.&lt;br /&gt;&lt;br /&gt;JUnit makes unit testing of Java classes pretty easy.  The idea is to actually write your tests before you start coding based on written specs, but you can also do it afterwards too.  Good unit testing should make it easy to change code with confidence.  It's also something you can hand to your boss to say "my code works."&lt;br /&gt;&lt;br /&gt;Load up Eclipse and make sure the Package Explorer is open.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Right Click on a class, then New,  JUnit Test Case&lt;/li&gt;&lt;li&gt;Make sure the checkboxes for generating setUp and tearDown&lt;/li&gt;&lt;/ul&gt;Here's how it works:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;setUp() will be run once at the start of your test.  In it you should create an instance of your object.  You can declare a variable to hold your object inside the JUnit test case (like private myObjectsName = null).&lt;/li&gt;&lt;li&gt;Eclipse automatically makes a stub function for each function in your class-- for example, getName() will have a corresponding testGetName() function&lt;/li&gt;&lt;li&gt;You fill out each stub.  Remove fail("Not yet implemented") and replace using normal Java code and the macros listed at the following URL (scroll down a bit to all the assert and fail macros):&lt;br /&gt;http://open.ncsu.edu/se/tutorials/junit/&lt;/li&gt;&lt;li&gt;Right click on your JUnitTestCase-- it should be YourObjectNameTest.java-- Run As, JUnit Test (or you can do Debug As instead)&lt;/li&gt;&lt;li&gt;The result will be a new pane in Eclipse called JUnit.  It will list all the test functions and put an icon next to them indicating if they were successful or if they errored out or failed.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;I found assertTrue and assertEquals to be the most useful.&lt;br /&gt;&lt;br /&gt;As an example, you could test a get function by using assertEquals to check that the value of the attribute is the same as what you set it to be in Setup.  To test a set function, set the value to something else and then assertEquals that the return value is the new value (don't forget to set the value back).&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;    public void testSetPatientid() {&lt;br /&gt;       myObject.setStuff(2); // set a new value&lt;br /&gt;       assertEquals("Stuff is incorrect", new Integer(2), (java.lang.Integer) myObject.getStuff()); // check that it's right&lt;br /&gt;       myObject.setStuff(1); // set it back&lt;br /&gt;   }&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Some things are a bit more tricky.  For example, I used assertTrue to check that the return of a function was of the right type-- assertTrue("message", myObject.getSomething() instanceof org.blah.blah.Stuff)&lt;br /&gt;&lt;br /&gt;For more info, look at:&lt;br /&gt;http://clarkware.com/articles/JUnitPrimer.html&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11240984-1602629719126275155?l=petersnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petersnotes.blogspot.com/feeds/1602629719126275155/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11240984&amp;postID=1602629719126275155' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/1602629719126275155'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/1602629719126275155'/><link rel='alternate' type='text/html' href='http://petersnotes.blogspot.com/2009/01/getting-started-with-junit.html' title='Getting Started with JUnit'/><author><name>Peter V</name><uri>http://www.blogger.com/profile/17919841991959605501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11240984.post-4085871651532914242</id><published>2009-01-07T10:39:00.001-08:00</published><updated>2009-01-07T10:42:53.527-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Reporting'/><title type='text'>Read this first when you install BIRT</title><content type='html'>BIRT is great, but there is just one... annoying... thing... that no one seems to talk about.&lt;br /&gt;&lt;br /&gt;You install BIRT, open the report perspective, create an element... and then HOW THE $!()#$ DO YOU EDIT IT'S PROPERTIES?&lt;br /&gt;&lt;br /&gt;It's not the properties tab-- BIRT has a special properties tab.  Here's how to load it up (and why oh why is this missing from the default report perspective?)&lt;br /&gt;&lt;br /&gt;Window-&gt;Show View-&gt;Other...-&gt;Report Design&gt;Property Editor&lt;br /&gt;&lt;br /&gt;Now all of a sudden you have control over each element including adding hyperlinks.  Whew!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11240984-4085871651532914242?l=petersnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petersnotes.blogspot.com/feeds/4085871651532914242/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11240984&amp;postID=4085871651532914242' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/4085871651532914242'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/4085871651532914242'/><link rel='alternate' type='text/html' href='http://petersnotes.blogspot.com/2009/01/read-this-first-when-you-install-birt.html' title='Read this first when you install BIRT'/><author><name>Peter V</name><uri>http://www.blogger.com/profile/17919841991959605501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11240984.post-1086525061311457985</id><published>2009-01-07T10:27:00.001-08:00</published><updated>2009-01-07T10:58:16.995-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Reporting'/><category scheme='http://www.blogger.com/atom/ns#' term='CSS'/><title type='text'>Using styles from a CSS stylesheet in BIRT 2.3+</title><content type='html'>In BIRT 2.2, I would import a stylesheet and then apply the styles to my report.  Unfortunately, this isn't very maintainable.  Luckily Ben has found a solution to load styles from an external CSS file though there are contraints:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;You must use BIRT 2.3+&lt;/li&gt;&lt;li&gt;Tag styling won't work-- for example, tr { color:red } will throw an error-- you have to give the style a name like .myrow { color:red }&lt;/li&gt;&lt;li&gt;The stylesheet must be in the same Eclipse project (project references are not good enough) at design time-- you can load from another location after deploying the report&lt;/li&gt;&lt;li&gt;Your style names must be all lowercase-- BIRT saves the names in your report as lower case even if they have uppercase characters and then they won't work once deployed&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;Here is the procedure:&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Upgrade Eclipse BIRT report designer to version 2.3.1&lt;/li&gt;&lt;li&gt;If fixing an existing report, delete all currently used styles&lt;/li&gt;&lt;li&gt;Right-click on "styles" in the outline, and choose "Use CSS file..."&lt;/li&gt;&lt;li&gt;Choose your css file&lt;/li&gt;&lt;li&gt;Check the box for "Include CSS file at view time" and enter&lt;br /&gt;/path/when/deployed/your.css as the URI (note: this option is &lt;span style="font-style: italic;"&gt;missing&lt;/span&gt; in BIRT 2.2; if you tried to upgrade 2.2 to 2.3 read my other blog entry about how this is basically impossible)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;There will be some errors if your css defines styles for tag names because BIRT doesn't like that.  It only accepts class names.  Just ignore it.&lt;/li&gt;&lt;li&gt;Format the report by right-clicking and applying styles from your css&lt;/li&gt;&lt;li&gt;Deploy the report&lt;/li&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11240984-1086525061311457985?l=petersnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petersnotes.blogspot.com/feeds/1086525061311457985/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11240984&amp;postID=1086525061311457985' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/1086525061311457985'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/1086525061311457985'/><link rel='alternate' type='text/html' href='http://petersnotes.blogspot.com/2009/01/using-styles-from-css-stylesheet-in.html' title='Using styles from a CSS stylesheet in BIRT 2.3+'/><author><name>Peter V</name><uri>http://www.blogger.com/profile/17919841991959605501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11240984.post-4172601836699111068</id><published>2009-01-06T11:54:00.000-08:00</published><updated>2009-01-07T10:56:41.887-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Reporting'/><title type='text'>Upgrading BIRT 2.2 to 2.3</title><content type='html'>Or let's be honest, reinstalling Eclipse.&lt;br /&gt;&lt;br /&gt;It should be possible, using Eclipse Help&gt;Software Updates&gt;Find and Install to update BIRT.  However, it never works.&lt;br /&gt;&lt;br /&gt;If you try to update, it will look like it worked, but when you go to Help&gt;About&gt;Plugin Details BIRT will still be at 2.2.&lt;br /&gt;&lt;br /&gt;You can go and delete BIRT out of the plugins directory and then try to install it, but then I found one of two things happens:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Eclipse spins forever&lt;/li&gt;&lt;li&gt;Eclipse throws the error "Eclipse BIRT Chart Runtime Feature (2.3.1...) requires feature 'org.eclipse.datatools.enablement.oda.feature (1.6.0)', or later version."  The latter can be fixed by updating the Data Tools Platform.  Then you can update BIRT.  But it will still be at 2.2 after you restart.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;It's easier to just start with a fresh install of Eclipse.  Thank's BIRT!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11240984-4172601836699111068?l=petersnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petersnotes.blogspot.com/feeds/4172601836699111068/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11240984&amp;postID=4172601836699111068' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/4172601836699111068'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/4172601836699111068'/><link rel='alternate' type='text/html' href='http://petersnotes.blogspot.com/2009/01/upgrading-birt-22-to-23.html' title='Upgrading BIRT 2.2 to 2.3'/><author><name>Peter V</name><uri>http://www.blogger.com/profile/17919841991959605501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11240984.post-4141048471120089432</id><published>2009-01-06T11:35:00.000-08:00</published><updated>2009-01-06T11:43:55.319-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Oracle'/><title type='text'>Accessing HTTPS pages using Oracle's UTL_HTTP package</title><content type='html'>The change needed to your PL/SQL is straightforward.  Simply configure UTL_HTTP to use the "Oracle wallet":&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;UTL_HTTP.SET_WALLET(v_wallet_path,v_wallet_password);&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The hard bit is importing certificates into a wallet.&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Start Oracle Wallet Manager&lt;br /&gt;# xhost +&lt;br /&gt;access control disabled, clients can connect from any host&lt;br /&gt;# su - oracle&lt;br /&gt;Sun Microsystems Inc.   SunOS 5.10      Generic January 2005&lt;br /&gt;-bash-3.00$ export DISPLAY=:1  &lt;span style="font-style: italic;"&gt;(if you are using VNC)&lt;/span&gt;&lt;br /&gt;-bash-3.00$ owm&lt;br /&gt;&lt;br /&gt;If the DB is on another machine, do the following:&lt;br /&gt;-bash-3.00$ export DISPLAY=192.168.1.58:1&lt;br /&gt;-bash-3.00$ owm&lt;/li&gt;&lt;li&gt;Hit the new wallet button&lt;/li&gt;&lt;li&gt;"Your default wallet does not exist, do you want to create it?"&lt;br /&gt;No&lt;/li&gt;&lt;li&gt;Prompt for wallet password. Enter whatever you prefer.&lt;/li&gt;&lt;li&gt;"A new empty wallet has been created.  Do you want to create a new certificate request at this time?"&lt;br /&gt;No&lt;/li&gt;&lt;li&gt;Right click on trusted certificates in the hierarchy on the left&lt;/li&gt;&lt;li&gt;Choose Import Certificate&lt;/li&gt;&lt;li&gt;"Choose a method to select the certificate"&lt;br /&gt;( ) Paste the certificate&lt;br /&gt;(x) Load the certificate from a file&lt;/li&gt;&lt;li&gt;Go to another terminal&lt;br /&gt;&lt;br /&gt;Here are the instructions for Sun Appserver&lt;br /&gt;&lt;/li&gt;&lt;li&gt;# cd /var/opt/SUNWappserver/domains/domain1/config&lt;/li&gt;&lt;li&gt;List certificates:&lt;br /&gt;/opt/SUNWappserver/appserver/lib/certutil -L -d .&lt;/li&gt;&lt;li&gt;You should see s1as in the list.  Then type:&lt;br /&gt;/opt/SUNWappserver/appserver/lib/pk12util -o ascerts.p12 -n s1as -d .&lt;/li&gt;&lt;li&gt;This spits out a pkcs12 format certificate.&lt;br /&gt;&lt;br /&gt;Now onto OpenSSL:&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Oracle wallet requires x509, you need to use openssl to convert to pem and then to x509.&lt;br /&gt;# ./openssl pkcs12 -in /export/home/admin/ascerts.p12 -clcerts -nokeys -out satin.acceleresystems.com.cert.pem&lt;br /&gt;Enter Import Password:&lt;br /&gt;MAC verified OK&lt;br /&gt;# ./openssl pkcs12 -in /export/home/admin/ascerts.p12 -nocerts -nodes -out satin.acceleresystems.com.key.pem&lt;br /&gt;&lt;br /&gt;Enter Import Password:&lt;br /&gt;MAC verified OK&lt;/li&gt;&lt;li&gt;Now convert to X509&lt;br /&gt;# ./openssl x509 -in satin.acceleresystems.com.cert.pem  -out satin.acceleresystems.com.cert.x509&lt;/li&gt;&lt;li&gt;Copy file to the machine with Oracle, and finish the import using OWM&lt;/li&gt;&lt;li&gt;Save the wallet to /export/home/oracle/wallets.  You can't set the name, but it will be ewallet.p12.  To use the wallet you only need the directory name (see next step).&lt;/li&gt;&lt;li&gt;You can now access the wallet from Oracle using UTL_HTTP.set_wallet('file:/export/home/oracle/wallets','password');&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;You MUST use the absolute path to the cert when using openssl, or you will get an error about TRUSTED certificate on the last step of openssl x509.&lt;br /&gt;&lt;br /&gt;If editing an existing wallet, you need to hit open and navigate to the wallets directory.  Continue even though you have no default set.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11240984-4141048471120089432?l=petersnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petersnotes.blogspot.com/feeds/4141048471120089432/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11240984&amp;postID=4141048471120089432' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/4141048471120089432'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/4141048471120089432'/><link rel='alternate' type='text/html' href='http://petersnotes.blogspot.com/2009/01/accessing-https-pages-using-oracles.html' title='Accessing HTTPS pages using Oracle&apos;s UTL_HTTP package'/><author><name>Peter V</name><uri>http://www.blogger.com/profile/17919841991959605501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11240984.post-7823134203244710908</id><published>2009-01-06T11:06:00.000-08:00</published><updated>2009-01-06T11:09:27.597-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Oracle'/><title type='text'>"Printf" Debugging XML in Oracle</title><content type='html'>Oracle has a package called "DBMS_OUTPUT" which has a function called put_line that is handy for doing "printf" debugging.  Unfortunately it doesn't work with XML.  Here's a procedure that does it for you.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;create or replace procedure dbms_output_xml (p_xml in xmltype)&lt;br /&gt;  is&lt;br /&gt;     l_str long;&lt;br /&gt;  begin&lt;br /&gt;     l_str := p_xml.extract('/*').getstringval();&lt;br /&gt;     loop&lt;br /&gt;        exit when l_str is null;&lt;br /&gt;        dbms_output.put_line (substr (l_str, 1, instr (l_str, chr(10)) - 1));&lt;br /&gt;        l_str := substr (l_str, instr (l_str, chr(10)) + 1);&lt;br /&gt;     end loop;&lt;br /&gt;end dbms_output_xml;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11240984-7823134203244710908?l=petersnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petersnotes.blogspot.com/feeds/7823134203244710908/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11240984&amp;postID=7823134203244710908' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/7823134203244710908'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/7823134203244710908'/><link rel='alternate' type='text/html' href='http://petersnotes.blogspot.com/2009/01/printf-debugging-xml-in-oracle.html' title='&quot;Printf&quot; Debugging XML in Oracle'/><author><name>Peter V</name><uri>http://www.blogger.com/profile/17919841991959605501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11240984.post-5932743224548090156</id><published>2009-01-06T11:03:00.001-08:00</published><updated>2009-01-06T14:53:51.449-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Oracle'/><title type='text'>Grabbing a Webpage Greater than 32k using UTL_HTTP</title><content type='html'>The UTL_HTTP package in Oracle allows PL/SQL to grab a webpage and save it into an Oracle variable.  The trouble is, it returns a Varchar2 and this can be up to 32k.  The solution is to use the DBMS_LOB package to write to a CLOB.  A loop gets the 32k chunks and appends them to the CLOB.  Straightforward enough but it takes some time to get it all working.  Here's the code:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;CREATE OR REPLACE PROCEDURE load_html_from_url (p_url  IN  VARCHAR2, p_html out clob) AS&lt;br /&gt; l_http_request   UTL_HTTP.req;&lt;br /&gt; l_http_response  UTL_HTTP.resp;&lt;br /&gt; l_clob           CLOB;&lt;br /&gt; l_text           VARCHAR2(32767);&lt;br /&gt;BEGIN&lt;br /&gt; -- Initialize the CLOB.&lt;br /&gt; DBMS_LOB.createtemporary(l_clob, FALSE);&lt;br /&gt;&lt;br /&gt; -- Make a HTTP request and get the response.&lt;br /&gt; l_http_request  := UTL_HTTP.begin_request(p_url);&lt;br /&gt; l_http_response := UTL_HTTP.get_response(l_http_request);&lt;br /&gt;&lt;br /&gt; -- Copy the response into the CLOB.&lt;br /&gt; BEGIN&lt;br /&gt;   LOOP&lt;br /&gt;     UTL_HTTP.read_text(l_http_response, l_text, 32767);&lt;br /&gt;     DBMS_LOB.writeappend (l_clob, LENGTH(l_text), l_text);&lt;br /&gt;   END LOOP;&lt;br /&gt; EXCEPTION&lt;br /&gt;   WHEN UTL_HTTP.end_of_body THEN&lt;br /&gt;     UTL_HTTP.end_response(l_http_response);&lt;br /&gt; END;&lt;br /&gt;&lt;br /&gt; p_html:= l_clob;&lt;br /&gt;EXCEPTION&lt;br /&gt; WHEN OTHERS THEN&lt;br /&gt;   UTL_HTTP.end_response(l_http_response);&lt;br /&gt;   -- Relase the resources associated with the temporary LOB.&lt;br /&gt;   DBMS_LOB.freetemporary(l_clob);&lt;br /&gt;   RAISE;&lt;br /&gt;END load_html_from_url;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Note: if you want to use HTTP POST instead of GET, you will need to create your request differently.  Use&lt;br /&gt;&lt;pre&gt;l_http_request := UTL_HTTP.begin_request(v_url, 'POST', 'HTTP/1.1');&lt;br /&gt;utl_http.write_text(l_http_request, v_message);&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;It may also be necessary to specify the content length like so:&lt;br /&gt;&lt;pre&gt;utl_http.set_header(l_http_request, 'Content-Length', length(v_message));&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11240984-5932743224548090156?l=petersnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petersnotes.blogspot.com/feeds/5932743224548090156/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11240984&amp;postID=5932743224548090156' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/5932743224548090156'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/5932743224548090156'/><link rel='alternate' type='text/html' href='http://petersnotes.blogspot.com/2009/01/grabbing-webpage-greater-than-32k-using.html' title='Grabbing a Webpage Greater than 32k using UTL_HTTP'/><author><name>Peter V</name><uri>http://www.blogger.com/profile/17919841991959605501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11240984.post-7355291440156128279</id><published>2009-01-06T09:54:00.000-08:00</published><updated>2009-01-06T09:59:13.138-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='XML'/><category scheme='http://www.blogger.com/atom/ns#' term='Oracle'/><title type='text'>Oracle XML Queries and Namespaces</title><content type='html'>Oracle XML functions have trouble dealing with namespaces.  It seems the best way it to simply strip them out but if you can't, you might try and use the optional namespace argument in many of the functions.  Trouble is that Oracle's documentation doesn't actually explain what the syntax is.&lt;br /&gt;&lt;br /&gt;The &lt;a href="http://oraclequirks.blogspot.com/2008/05/oracles-xml-sql-functions-and-default.html"&gt;answer&lt;/a&gt; comes from Flavio Casetta at his &lt;a href="http://oraclequirks.blogspot.com/"&gt;oraclequirks&lt;/a&gt; blog:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;select &lt;br /&gt;     extractValue(content,'/path/here','xmlns="http://www.w3.org/2005/Atom"') contentname &lt;br /&gt;   from &lt;br /&gt;     table&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11240984-7355291440156128279?l=petersnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petersnotes.blogspot.com/feeds/7355291440156128279/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11240984&amp;postID=7355291440156128279' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/7355291440156128279'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/7355291440156128279'/><link rel='alternate' type='text/html' href='http://petersnotes.blogspot.com/2009/01/oracle-xml-queries-and-namespaces.html' title='Oracle XML Queries and Namespaces'/><author><name>Peter V</name><uri>http://www.blogger.com/profile/17919841991959605501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11240984.post-4104167201969113469</id><published>2009-01-06T09:41:00.000-08:00</published><updated>2009-01-06T09:51:29.648-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Web Graphics'/><title type='text'>"Harmonious" Colors</title><content type='html'>Some colors just seem to go together.  If you've got an eye for those harmonious color choices, you can pick them out manually.  Otherwise, here are some pages that will do it for you.&lt;br /&gt;&lt;br /&gt;There's a huge list at&lt;br /&gt;http://veerle.duoh.com/index.php/blog/comments/colors_part_ii_the_color_calculator/&lt;br /&gt;&lt;br /&gt;with lots of different color pickers.  These are basically color wheels for colors that go together, usually using different (selectable) methods to choose colors.  I went through the entire list are here are my favorites:&lt;br /&gt;Best: http://wellstyled.com/tools/colorscheme2/index-en.html#&lt;br /&gt;OK: http://www.sessions.edu/ilu/#/&lt;br /&gt;Simplest: http://www.colorschemer.com/online.html&lt;br /&gt;&lt;br /&gt;Another technique that I have found to work well is to grab colors from a pleasing photograph.  Here's a quickie on using colors from good pictures of nature:&lt;br /&gt;http://www.boxesandarrows.com/view/natural_selections_colors_found_in_nature_and_interface_design&lt;br /&gt;&lt;br /&gt;And a quote:&lt;br /&gt;&lt;br /&gt;"Thanks for the comments… on the topic of background colors… Cool colors (blues, greens) work well as backgrounds because they recede. Have a small room in your house that you'd like to make seem bigger… use a light blue. Got a big room you'd like to make more cozy… go with a warm color like red (warm colors come forward.) Color psychology also plays a role here. We associate blues with the sky and oceans (lots of depth in both), hence its calming effect and associations with depth and dependability.&lt;br /&gt;&lt;br /&gt;Some color characteristics:&lt;br /&gt;&lt;br /&gt;Red: Vibrant, passionate, love, war. A very strong and attention-grabbing color, red is charged with emotions.&lt;br /&gt;&lt;br /&gt;Violet: Regal, sacred, sensual. In deep shades, violet is luxurious. When lightly tinted, it is aromatic and spiritual.&lt;br /&gt;&lt;br /&gt;Blue: Cool, dependable, sophisticated, sky, water. Blue is full of depth, constant yet dynamic.&lt;br /&gt;&lt;br /&gt;Green: Fresh, relaxing, earth. Green is very balanced and calm, a natural color.&lt;br /&gt;&lt;br /&gt;Yellow: Sun, energy, warmth. Yellow is welcoming and full of life, a happy color.&lt;br /&gt;&lt;br /&gt;Orange: Strong, vital, hot. Orange is the warmest of colors, a healing and playful hue."&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11240984-4104167201969113469?l=petersnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petersnotes.blogspot.com/feeds/4104167201969113469/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11240984&amp;postID=4104167201969113469' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/4104167201969113469'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/4104167201969113469'/><link rel='alternate' type='text/html' href='http://petersnotes.blogspot.com/2009/01/harmonious-colors.html' title='&quot;Harmonious&quot; Colors'/><author><name>Peter V</name><uri>http://www.blogger.com/profile/17919841991959605501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11240984.post-392086183311505997</id><published>2009-01-06T09:33:00.001-08:00</published><updated>2009-01-06T09:41:02.598-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Web Graphics'/><category scheme='http://www.blogger.com/atom/ns#' term='HTML'/><title type='text'>Web 2.0 Style Guide and Some Photoshop Links</title><content type='html'>About a year ago I read a Web 2.0 style guide and was very impressed with it.  What advice I remembered I implemented on my projects at work.  Now, planning a redesign of my personal site, I tracked the site down again.&lt;br /&gt;&lt;br /&gt;http://www.webdesignfromscratch.com/web-2.0-design-style-guide.php&lt;br /&gt;&lt;br /&gt;Along with that guide I found a few links to help on the photoshop end of implementing the style recommendations.  Photoshoplab's Web 2.0 Design Kit takes you through some of the common procedures in making graphics for sites.&lt;br /&gt;http://www.photoshoplab.com/web20-design-kit.html&lt;br /&gt;http://www.photoshoplab.com/web-20-design-kit-part-2.html&lt;br /&gt;http://www.photoshoplab.com/website-design-mockup-tips.html&lt;br /&gt;&lt;br /&gt;Another page talks more about masks (which are covered somewhat in the last link above):&lt;br /&gt;http://www.photoshoplab.com/the-masks.html&lt;br /&gt;&lt;br /&gt;Want to make an image that looks like the Apple iPod ads? &lt;br /&gt;http://www.graphic-design.com/Photoshop/ipod.html&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11240984-392086183311505997?l=petersnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petersnotes.blogspot.com/feeds/392086183311505997/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11240984&amp;postID=392086183311505997' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/392086183311505997'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/392086183311505997'/><link rel='alternate' type='text/html' href='http://petersnotes.blogspot.com/2009/01/web-20-style-guide-and-some-photoshop.html' title='Web 2.0 Style Guide and Some Photoshop Links'/><author><name>Peter V</name><uri>http://www.blogger.com/profile/17919841991959605501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11240984.post-7461619857641304674</id><published>2008-12-23T14:13:00.001-08:00</published><updated>2008-12-23T14:16:31.963-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='browser quirks'/><category scheme='http://www.blogger.com/atom/ns#' term='CSS'/><title type='text'>IE6 Quirks When Sizing HTML Elements</title><content type='html'>IE6 rolls with another party foul at the HTML kegger.&lt;br /&gt;&lt;br /&gt;You can set the height and width of elements in Mozilla browsers to be 100%, or some percentage thereof.&lt;br /&gt;&lt;br /&gt;Guess what.&lt;br /&gt;&lt;br /&gt;In IE6 these elements will not appear.  It doesn't seem to be enough to then use JavaScript to set the element width and height to a fixed value.  They've got to start fixed.&lt;br /&gt;&lt;br /&gt;IE6 actually allows a percentage width, but the height had better start out absolute or your element will just disappear-- in fact it will have a height of 0px, no matter what the IE debugger tells you.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11240984-7461619857641304674?l=petersnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petersnotes.blogspot.com/feeds/7461619857641304674/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11240984&amp;postID=7461619857641304674' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/7461619857641304674'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/7461619857641304674'/><link rel='alternate' type='text/html' href='http://petersnotes.blogspot.com/2008/12/ie6-quirks-when-sizing-html-elements.html' title='IE6 Quirks When Sizing HTML Elements'/><author><name>Peter V</name><uri>http://www.blogger.com/profile/17919841991959605501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11240984.post-4136492264718925403</id><published>2008-12-23T14:11:00.001-08:00</published><updated>2008-12-23T14:13:12.289-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='browser quirks'/><title type='text'>IE Bug - Dynamically Created Elements Have No Name</title><content type='html'>IE fails to set the name of elements generated using createElement correctly:&lt;br /&gt;http://www.easy-reader.net/archives/2005/09/02/death-to-bad-dom-implementations/&lt;br /&gt;&lt;br /&gt;The solution is to butcher createElement and use it like createElement("&lt;input name='IE_stinks'&gt;"); but this doesn't work in sensible browsers.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11240984-4136492264718925403?l=petersnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petersnotes.blogspot.com/feeds/4136492264718925403/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11240984&amp;postID=4136492264718925403' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/4136492264718925403'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/4136492264718925403'/><link rel='alternate' type='text/html' href='http://petersnotes.blogspot.com/2008/12/ie-bug-dynamically-created-elements.html' title='IE Bug - Dynamically Created Elements Have No Name'/><author><name>Peter V</name><uri>http://www.blogger.com/profile/17919841991959605501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11240984.post-5526839924298519117</id><published>2008-12-23T14:06:00.000-08:00</published><updated>2008-12-23T14:11:18.532-08:00</updated><title type='text'>Dynamically Adding Styles via Link using JavaScript</title><content type='html'>So you want to add CSS styles using a URL to a stylesheet?  That's different than adding inline styles.  Luckily, it's pretty straightforward except for IE's party foul which prevents adding styles the standard way (it has to do everything its own special way).  &lt;br /&gt;&lt;br /&gt;Answer brought to you by Mark McLaren:&lt;br /&gt;http://cse-mjmcl.cse.bris.ac.uk/blog/2005/08/18/1124396539593.html&lt;br /&gt;&lt;br /&gt;Here is the code should his blog disappear from the internet:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;if(document.createStyleSheet) {&lt;br /&gt;   document.createStyleSheet('http://server/stylesheet.css');&lt;br /&gt;} else {&lt;br /&gt;   var styles = "@import url(' http://server/stylesheet.css ');";&lt;br /&gt;   var newSS=document.createElement('link');&lt;br /&gt;   newSS.rel='stylesheet';&lt;br /&gt;   newSS.href='data:text/css,'+escape(styles);&lt;br /&gt;   document.getElementsByTagName("head")[0].appendChild(newSS);&lt;br /&gt;}&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11240984-5526839924298519117?l=petersnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petersnotes.blogspot.com/feeds/5526839924298519117/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11240984&amp;postID=5526839924298519117' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/5526839924298519117'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/5526839924298519117'/><link rel='alternate' type='text/html' href='http://petersnotes.blogspot.com/2008/12/dynamically-adding-styles-via-link.html' title='Dynamically Adding Styles via Link using JavaScript'/><author><name>Peter V</name><uri>http://www.blogger.com/profile/17919841991959605501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11240984.post-1297806965016600620</id><published>2008-12-23T14:01:00.000-08:00</published><updated>2008-12-23T14:05:24.951-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='browser quirks'/><category scheme='http://www.blogger.com/atom/ns#' term='CSS'/><title type='text'>Dynamically Adding Styles via JavaScript</title><content type='html'>This one is straight forward but then IE has to go and spoil the party.  The idea is to create a style element and then append a text node containing your style information to it;  then append the style element to the head of the page.  Trouble is, IE blows up when you try to run createElement("style").  So you have to use MS' proprietary function.  I won't bore you more, here is the code (replace YOURCSSTEXT):&lt;br /&gt;&lt;pre&gt;var ss = null;&lt;br /&gt;        if(document.createStyleSheet) // IE&lt;br /&gt;        {&lt;br /&gt;                ss = document.createStyleSheet();&lt;br /&gt;                ss.cssText=YOURCSSTEXT;&lt;br /&gt;        } else {  // All other browsers&lt;br /&gt;                ss = document.createElement("style");&lt;br /&gt;                ss.type="text/css";                ss.appendChild(document.createTextNode(YOURCSSTEXT));&lt;br /&gt;                document.getElementsByTagName("head")[0].appendChild(ss);&lt;br /&gt;        }&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11240984-1297806965016600620?l=petersnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petersnotes.blogspot.com/feeds/1297806965016600620/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11240984&amp;postID=1297806965016600620' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/1297806965016600620'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/1297806965016600620'/><link rel='alternate' type='text/html' href='http://petersnotes.blogspot.com/2008/12/dynamically-adding-styles-via.html' title='Dynamically Adding Styles via JavaScript'/><author><name>Peter V</name><uri>http://www.blogger.com/profile/17919841991959605501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11240984.post-3569628276612939802</id><published>2008-12-19T11:23:00.000-08:00</published><updated>2008-12-19T12:56:04.263-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='XML'/><title type='text'>Parsing a Document into a DomDocument in JavaScript</title><content type='html'>XMLHttpRequest includes an attribute called responseXML besides responseText which should be populated when the returned data is XML.  But actually often this doesn't work right because the headers are set right.  Found this post by Darko in Google Groups about how to force parsing:&lt;br /&gt;&lt;br /&gt;http://groups.google.com/group/comp.lang.javascript/browse_thread/thread/762990f37ae218a3/6e0d948e1820bf24?pli=1&lt;br /&gt;&lt;br /&gt;I called this in my "showResponse" function called by prototype.js' Ajax.Request onSuccess event.  showResponse(originalRequest) receives the original XMLHttpRequest object and you need to call Darko's code using originalRequest.&lt;br /&gt;&lt;br /&gt;However of course it didn't work for me-- in Firefox, the script runs forever. Turns out there was actually an error parsing the doc, but there's no way to tell what it is.&lt;br /&gt;&lt;br /&gt;Time to add error output, which is defined nicely here:&lt;br /&gt;http://www.faqts.com/knowledge_base/entry/versions/index.phtml?aid=15302&lt;br /&gt;&lt;br /&gt;Haven't finished this yet :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11240984-3569628276612939802?l=petersnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petersnotes.blogspot.com/feeds/3569628276612939802/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11240984&amp;postID=3569628276612939802' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/3569628276612939802'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/3569628276612939802'/><link rel='alternate' type='text/html' href='http://petersnotes.blogspot.com/2008/12/parsing-document-into-domdocument-in.html' title='Parsing a Document into a DomDocument in JavaScript'/><author><name>Peter V</name><uri>http://www.blogger.com/profile/17919841991959605501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11240984.post-7956125020035293048</id><published>2008-12-18T17:24:00.001-08:00</published><updated>2008-12-18T17:34:48.282-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><title type='text'>Passing Arguments to Prototype.js' onSuccess</title><content type='html'>Ready to have your head spin?  Most of the prototype.js examples define the function that will handle onSuccess as an anonymous function, that is, it has no name as is defined inline.  Like so:&lt;br /&gt;&lt;pre&gt;var myAjax = new Ajax.Request(&lt;br /&gt;                                url,&lt;br /&gt;                                {&lt;br /&gt;                                        method: 'get',&lt;br /&gt;                                        parameters: paramstring,&lt;br /&gt;                                        onSuccess: function(transport) {$('myhtmlelement').innerHTML=transport.responseText;}&lt;br /&gt;                                });&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;That code would find the element with name 'myhtmlelement' and set its contents to the page returned by url.  That's great, but what if you want to pass in some values from wherever you are creating the Ajax Request?&lt;br /&gt;&lt;br /&gt;For example, I created a prototype constructor for a class.  Part of its job is dynamically creating a div that I want to stuff with responseText.  &lt;br /&gt;&lt;br /&gt;&lt;pre&gt;var divObj = document.createElement( "DIV" ); &lt;br /&gt;document.body.appendChild(divObj);&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;So then I tried to access divObj from inside the anonymous function. Guess what, all the attributes are null or undefined.  Hmm.  I tried all sorts of combos of stuff but no go.  Finally I hit on something works.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;var divObj = document.createElement( "DIV" ); &lt;br /&gt;document.body.appendChild(divObj);&lt;br /&gt;divObj.name='foo';&lt;br /&gt;var name=divObj.name;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Then I created an anonymous function and stuff it in a variable.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;this.showResponse = function(transport) { $(name).innerHTML = transport.responseText;};&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Prototype's $() function is a shortcut for document.getElementById().  Got that so far?  Now just create the Ajax request.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;var myAjax = new Ajax.Request(&lt;br /&gt;                                url,&lt;br /&gt;                                {&lt;br /&gt;                                        method: 'get',&lt;br /&gt;                                        parameters: paramstring,&lt;br /&gt;                                        onSuccess: this.showResponse&lt;br /&gt;                                });&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;And go figure, that works.  For some reason accessing an object in the anonymous function doesn't work, but a simple string does.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11240984-7956125020035293048?l=petersnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petersnotes.blogspot.com/feeds/7956125020035293048/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11240984&amp;postID=7956125020035293048' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/7956125020035293048'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/7956125020035293048'/><link rel='alternate' type='text/html' href='http://petersnotes.blogspot.com/2008/12/passing-arguments-to-prototypejs.html' title='Passing Arguments to Prototype.js&apos; onSuccess'/><author><name>Peter V</name><uri>http://www.blogger.com/profile/17919841991959605501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11240984.post-1525832029590277519</id><published>2008-12-18T17:21:00.000-08:00</published><updated>2008-12-18T17:22:47.471-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Reporting'/><title type='text'>Changing the default styling of Birt</title><content type='html'>This is actually quite easy.  Birt uses some JSP fragments for the loading bar and other stuff.  You can find these in&lt;br /&gt;birt.war/webcontent/birt/pages/control&lt;br /&gt;&lt;br /&gt;And the associated styles are in styles.css in&lt;br /&gt;birt.war/webcontent/birt/styles&lt;br /&gt;&lt;br /&gt;There is also an images directory where you can change things such as the progress bar image.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11240984-1525832029590277519?l=petersnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petersnotes.blogspot.com/feeds/1525832029590277519/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11240984&amp;postID=1525832029590277519' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/1525832029590277519'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/1525832029590277519'/><link rel='alternate' type='text/html' href='http://petersnotes.blogspot.com/2008/12/changing-default-styling-of-birt.html' title='Changing the default styling of Birt'/><author><name>Peter V</name><uri>http://www.blogger.com/profile/17919841991959605501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11240984.post-8015101132282087177</id><published>2008-12-17T16:45:00.000-08:00</published><updated>2009-01-06T10:01:12.088-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='browser quirks'/><title type='text'>IE Bug - Dynamically Created IFrames have No Name</title><content type='html'>IE has an annoying bug that when you use JavaScript to create an IFrame (or, as Jeff Norton points out in the comments, ANY element!), you can't set the name using .name or setAttribute.  It just doesn't work.&lt;br /&gt;&lt;br /&gt;I had tried to submit a form and set the target to the IFrame, and a new window popped open.  WTF?&lt;br /&gt;&lt;br /&gt;Solution is here:&lt;br /&gt;http://terminalapp.net/submitting-a-form-with-target-set-to-a-script-generated-iframe-on-ie/&lt;br /&gt;&lt;br /&gt;So instead of &lt;span style="font-style: italic;"&gt;document.createElement("IFRAME");&lt;/span&gt; do &lt;span style="font-style: italic;"&gt;document.createElement("&amp;lt;iframe name="'blah'"&amp;gt;");&lt;/span&gt;  and catch the exception on good browsers.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11240984-8015101132282087177?l=petersnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petersnotes.blogspot.com/feeds/8015101132282087177/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11240984&amp;postID=8015101132282087177' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/8015101132282087177'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/8015101132282087177'/><link rel='alternate' type='text/html' href='http://petersnotes.blogspot.com/2008/12/ie-bug-dynamically-created-iframes-have.html' title='IE Bug - Dynamically Created IFrames have No Name'/><author><name>Peter V</name><uri>http://www.blogger.com/profile/17919841991959605501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11240984.post-1998837333456903530</id><published>2008-12-16T11:35:00.000-08:00</published><updated>2008-12-16T12:47:18.345-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='CSS'/><category scheme='http://www.blogger.com/atom/ns#' term='HTML'/><title type='text'>Browser Development Tools</title><content type='html'>&lt;span style="font-weight: bold;"&gt;Firefox&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Venkman - JavaScript debugger.  Bit of a head scratcher at first-- you need to navigate to your source, set a breakpoint, and then load the page in FireFox.  Execution will stop when the breakpoint is reached (note this means you also can't look up other webpages will debugging)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;DOM Inspector - allows you to navigate the DOM of a page loaded in Firefox. Just press Ctrl-Shift-I to load the Inspector&lt;/li&gt;&lt;li&gt;Developer Toolbar - really handy tool bar that outlines elements and shows all sorts of other handy info; also allows editing of source and CSS in real time&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-weight: bold;"&gt;Interner Explorer&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Script debugger - IE6 only - very buggy debugger.  Crashes often.  But it's the only way to see into IE's crazy mind.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Fiddler and Fiddler 2 - plug-in that intercepts communications between IE and sites and logs it.  You can inspect all sorts of data and edit it.  I found Fiddler to be more stable, but Fiddler 2 has some limited support for HTTPS.&lt;/li&gt;&lt;li&gt;IE Developer Toolbar - IE6 only - kind of like the DOM inspector for Firefox but in a toolbar&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11240984-1998837333456903530?l=petersnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petersnotes.blogspot.com/feeds/1998837333456903530/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11240984&amp;postID=1998837333456903530' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/1998837333456903530'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/1998837333456903530'/><link rel='alternate' type='text/html' href='http://petersnotes.blogspot.com/2008/12/browser-development-tools.html' title='Browser Development Tools'/><author><name>Peter V</name><uri>http://www.blogger.com/profile/17919841991959605501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11240984.post-2191075156892692854</id><published>2008-11-03T10:54:00.000-08:00</published><updated>2008-11-03T11:00:44.426-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='Web Graphics'/><category scheme='http://www.blogger.com/atom/ns#' term='CSS'/><category scheme='http://www.blogger.com/atom/ns#' term='HTML'/><title type='text'>More CSS Styling</title><content type='html'>the format for styling elements is&lt;br /&gt;&lt;br /&gt;element.class { property: value; property: value /* comment */ }&lt;br /&gt;&lt;br /&gt;either element or class can be blank, but one of them has to be present, and if class is missing omit the period.  this applies the properties and values you list inside the curly braces to all HTML elements which have class attribute set equal to the class you put after the period (if class is omitted, then it applies to all elements of that type).&lt;br /&gt;&lt;br /&gt;For example&lt;br /&gt;&lt;br /&gt;tr.poo { ... }&lt;br /&gt;&lt;br /&gt;applies to all table rows which have class="poo" attribute on them. &lt;br /&gt;&lt;br /&gt;tr { ... }&lt;br /&gt;&lt;br /&gt;applies to all table rows, regardless of the class you set.  Many CSS stylesheets you inherit style all elements of a certain type.  You should be able to override the default (you probably don't want to screw with the default because it will screw up the rest of the stylesheet) by creating your own classes of elements.&lt;br /&gt;&lt;br /&gt;There's one other variation on the element.class { .. } which is you can use a pound sign (#)&lt;br /&gt;&lt;br /&gt;element.class#id { .. }&lt;br /&gt;&lt;br /&gt;(you can even omit element.class and just have #id)&lt;br /&gt;&lt;br /&gt;This applies the style to just elements with an attribute id equal to the name you put after the # sign&lt;br /&gt;&lt;br /&gt;so tr id="fun" ... /tr (sorry I can't put the greater than or less than since it will be interpreted as html) could be styled with #fun { color: #775544 }&lt;br /&gt;&lt;br /&gt;Look up w3schools on google to get a list of all the &lt;span class="nfakPe"&gt;css&lt;/span&gt; properties.  Common ones I use are:&lt;br /&gt;font-size, font-face, font (this one combines all the font-... properties into one, the syntax is hard to remember though), padding (sets padding around a whole box), padding-left, padding-right..., margin, border (border: Xpx linestyle color), color (sets foreground text color format is hexadecimal #rrggbb), background-color and background (the one gotcha with background is if you want a background image, use the function url(...) but don't enclose the argument to url in quotes), width, height&lt;br /&gt;&lt;br /&gt;if you want to understand padding, margin and border look up &lt;span class="nfakPe"&gt;css&lt;/span&gt; box model.  I believe padding is the space between the border and content inside a box;  margin the area between the border and any neighboring content; border is just like word, you can set the thickness and dashed, solid, etc. &lt;br /&gt;&lt;br /&gt;One other thing different from old school html is DIV and SPAN elements;  a DIV is a box that can contain anything, a SPAN is an inline element, meaning its primarily intended for styling sections of text (like if you wanted to make the first few words of a paragraph bigger span style="font-size:20pt; color:grey" In the beginning /span there was nothing, OR, another handy one is to put an indent in a paragraph, use a span with a padding-left of like 15px that contains just some   whitespace);  a lot of the properties don't apply to SPAN.  My products template mostly uses tables though because they are a lot easier to work with but I think the spans are really handy.&lt;br /&gt;&lt;br /&gt;That's pretty much all I know.  you can access the &lt;span class="nfakPe"&gt;CSS&lt;/span&gt; properties using JavaScript via document.getElementById('&lt;div dir="ltr"&gt;&lt;wbr&gt;idofyourelement').style.&lt;wbr&gt;propertyname   &lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11240984-2191075156892692854?l=petersnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petersnotes.blogspot.com/feeds/2191075156892692854/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11240984&amp;postID=2191075156892692854' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/2191075156892692854'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/2191075156892692854'/><link rel='alternate' type='text/html' href='http://petersnotes.blogspot.com/2008/11/more-css-styling.html' title='More CSS Styling'/><author><name>Peter V</name><uri>http://www.blogger.com/profile/17919841991959605501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11240984.post-1638335075999303133</id><published>2008-11-03T09:04:00.000-08:00</published><updated>2008-11-03T11:39:24.011-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Web Graphics'/><title type='text'>Quick and Easy Aqua Button</title><content type='html'>If you search Google for "Aqua button tutorial" you will get back a truckload of tutorials.  Many of these come out looking very pretty.  Most, however, have 20+ rather involved steps and the pill part of the button is very much linked to the graphic you are placing within the button, so that making a bunch of buttons is very time consuming since you have to go back to step 5 or 6 for each new button.  Also, if you don't use the dimensions of the tutorial, figuring out what tweaks to make to step 8 of 20 is a little hard to gauge.&lt;br /&gt;&lt;br /&gt;The following tutorial makes a roughly square button that you can just dump an image or text into.  It's fairly simple so different sizes should be achievable without much work.&lt;br /&gt;&lt;br /&gt;Couple of tips:&lt;ol&gt;&lt;li&gt;Have a color in mind for your button; write down the hex value for this color.  Then create a darker version (this will be used for shading).&lt;/li&gt;&lt;li&gt;Ideally, make the image much bigger than you need and scale it down later.  It ends up looking better.  I *didn't* do this in the tutorial unfortunately.&lt;/li&gt;&lt;li&gt;The button consists of a body which has an inner shadow applied, another two layers that make the bottom part of the button "glow", and yet another layer above your text or image that adds highlights (a white colored reflection) to the top of the button.&lt;/li&gt;&lt;li&gt;Use "Save for Web" to save the pill, and save it using either GIF-128 or PNG format.  PNG looks better but is not supported by older browsers.&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;Ok, lets get to the step by step instructions:&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;create a box with rounded edges by using the pencil tool, size 17, in the 4 corners use the box marquee selection tool and paint bucket with a dark version of your color&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_WdpWJO6SGBI/SQ84qiuevLI/AAAAAAAAAkk/h_rydOytzyU/s1600-h/nice-black-aqua-button-1.png"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer; width: 170px; height: 70px;" src="http://2.bp.blogspot.com/_WdpWJO6SGBI/SQ84qiuevLI/AAAAAAAAAkk/h_rydOytzyU/s320/nice-black-aqua-button-1.png" alt="" id="BLOGGER_PHOTO_ID_5264488792946818226" border="0" /&gt;&lt;/a&gt;  (fill with #636363 for me).  I call this the "pill body"&lt;br /&gt;&lt;/li&gt;&lt;li&gt;if you're fancy, fill the pill body with a gradient from a lighter version of your color or the color itself to the darker version; #636363 to the dark version #484848 worked for me&lt;/li&gt;&lt;li&gt;add inner shadow via blending properties. Use the dark version of your color, in my case, #484848 (make sure to set "global light" to off on the shadow! or further steps will break this step)&lt;/li&gt;&lt;li&gt;the inner shadow should create shadow at bottom and sides only (not the top); so adjust the light angle to be vertical up and down and adjust the "size" parameter u&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_WdpWJO6SGBI/SQ85VtwWhmI/AAAAAAAAAk0/h_RsqBTmbQI/s1600-h/nice-black-aqua-button-2.png"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer; width: 170px; height: 70px;" src="http://2.bp.blogspot.com/_WdpWJO6SGBI/SQ85VtwWhmI/AAAAAAAAAk0/h_RsqBTmbQI/s320/nice-black-aqua-button-2.png" alt="" id="BLOGGER_PHOTO_ID_5264489534641833570" border="0" /&gt;&lt;/a&gt;ntil it looks good for your size of button&lt;/li&gt;&lt;li&gt;create a new layer, this will be the first glow layer (the bottom of the button glows)&lt;/li&gt;&lt;li&gt;create a radial gradient within the boundaries of the pill body, centered at the bottom, white to black. Transform width by 200% to make it wider&lt;/li&gt;&lt;li&gt;set blending mode to color dodge, 10% opacity (screen and overlay also work, though overlay gives a more pronounced effect)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;transform by 200% again, this will create a new layer, glow layer #2&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_WdpWJO6SGBI/SQ85fac4qzI/AAAAAAAAAk8/oNRndcsDzq0/s1600-h/nice-black-aqua-button-3.png"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer; width: 170px; height: 70px;" src="http://3.bp.blogspot.com/_WdpWJO6SGBI/SQ85fac4qzI/AAAAAAAAAk8/oNRndcsDzq0/s320/nice-black-aqua-button-3.png" alt="" id="BLOGGER_PHOTO_ID_5264489701258603314" border="0" /&gt;&lt;/a&gt;&lt;/li&gt;&lt;li&gt;set blending mode to linear dodge, 10% opacity&lt;/li&gt;&lt;li&gt;select the original pill layer boundaries with the magic wand; select&gt;invert and switch your layer selection to the two glow layers on top and delete their content outside the pill boundaries you selected with the magic wand&lt;/li&gt;&lt;li&gt;change primary color to white, and create a new layer-- this will be the highlight at the top of the button&lt;/li&gt;&lt;li&gt;select the original pill body shape with the magic wand and then switch back to highlight layer in the layer list&lt;/li&gt;&lt;li&gt;fill the highlight layer with a linear gradient; white at top, to transparent at about 75% down the height of the pill body&lt;/li&gt;&lt;li&gt;use the elliptical marquee (making a circle much bigger than the pill itself) to select the top half of the linear gradient, losing off a bit at the left and right side within the boundaries of your pill; then select&gt;invert, cut the lower half of the highlight layer off, and about another quarter off the sides (you just want the top half to have the white reflection, and having a perfectly horizontal cut in the reflection doesn't look as good)&lt;/li&gt;&lt;li&gt;shrink the highlight layer to 93% width and 98% height, move the layer down a &lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_WdpWJO6SGBI/SQ85lKRcAMI/AAAAAAAAAlE/bEiixUPW9LU/s1600-h/nice-black-aqua-button-4.png"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer; width: 170px; height: 70px;" src="http://2.bp.blogspot.com/_WdpWJO6SGBI/SQ85lKRcAMI/AAAAAAAAAlE/bEiixUPW9LU/s320/nice-black-aqua-button-4.png" alt="" id="BLOGGER_PHOTO_ID_5264489799994835138" border="0" /&gt;&lt;/a&gt;little so it doesn't touch the edges of the pill body&lt;/li&gt;&lt;li&gt;gaussian blur 0.5 the highlight layer to give it fuzzy edges&lt;/li&gt;&lt;li&gt;add your image or text below the highlight layer, but above the original pill and the glow layers&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;You may or may not want your button to have a shadow.  I tried using the blending properties drop shadow effect, but it never looked really good.  Measure out how much room you have and then follow these steps:&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;select the original pill body again with the magic wand&lt;/li&gt;&lt;li&gt;create a new layer&lt;/li&gt;&lt;li&gt;fill with a very dark version of your color (I just used black since my button is dark grey)&lt;/li&gt;&lt;li&gt;distort the top left and top right corners inwards so the shape has perspective-- the guides Photoshop shows should be a trapezoid shape&lt;/li&gt;&lt;li&gt;gaussian blur by 3.0&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_WdpWJO6SGBI/SQ85qGvE9nI/AAAAAAAAAlM/_3yJ971aQJ4/s1600-h/nice-black-aqua-button.png"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer; width: 170px; height: 70px;" src="http://2.bp.blogspot.com/_WdpWJO6SGBI/SQ85qGvE9nI/AAAAAAAAAlM/_3yJ971aQJ4/s320/nice-black-aqua-button.png" alt="" id="BLOGGER_PHOTO_ID_5264489884944758386" border="0" /&gt;&lt;/a&gt;&lt;/li&gt;&lt;li&gt;set opacity to 50 to 70 %, whatever you like&lt;/li&gt;&lt;li&gt;voila&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;That's all!  The best part is you can reuse your button without much effort.&lt;br /&gt;&lt;br /&gt;The following tutorial looks better but is more time consuming: http://www.webdesign.org/cat/photoshop/tutorials/aqua-style-button-with-photoshop.35.html&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11240984-1638335075999303133?l=petersnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petersnotes.blogspot.com/feeds/1638335075999303133/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11240984&amp;postID=1638335075999303133' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/1638335075999303133'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/1638335075999303133'/><link rel='alternate' type='text/html' href='http://petersnotes.blogspot.com/2008/11/quick-and-easy-aqua-button.html' title='Quick and Easy Aqua Button'/><author><name>Peter V</name><uri>http://www.blogger.com/profile/17919841991959605501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_WdpWJO6SGBI/SQ84qiuevLI/AAAAAAAAAkk/h_rydOytzyU/s72-c/nice-black-aqua-button-1.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11240984.post-1773116988778313052</id><published>2008-10-27T11:12:00.000-07:00</published><updated>2008-11-12T10:17:32.876-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Solaris'/><category scheme='http://www.blogger.com/atom/ns#' term='NIX administration'/><title type='text'>Watchdog Script for a Process</title><content type='html'>Many long running processes like to just disappear at random intervals, especially late in the day on Friday so that a client calls you at 5pm to fix it.  While the following script doesn't solve the root cause of why your program is dying, sometimes there is no reasonable way to fix the root cause and a watchdog timer script will do the job.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Watchdog Script&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I've written this with the intention of restarting a Tomcat based service, but if you fiddle with the arguments to FIND_PROC, you can find whatever you want.  Just ONE BIG caveat: don't name your watchdog script so that the watchdog finds itself.&lt;br /&gt;&lt;br /&gt;The first version of this script works on Solaris:&lt;br /&gt;&lt;pre&gt;#!/bin/sh&lt;br /&gt;&lt;br /&gt;# Find the pid of the process (PPID will be the shell that started it&lt;br /&gt;)  remember no spaces allowed between varnames, just equals sign, and the value&lt;br /&gt;FIND_PROC=`pgrep myprocess`&lt;br /&gt;#FIND_PROC='pgrep testscript`&lt;br /&gt;# if FIND_PROC is empty, the process has died; restart it&lt;br /&gt;&lt;br /&gt;if [ -z "${FIND_PROC}" ]; then&lt;br /&gt;      echo myprocess failed at `date`&lt;br /&gt;      nohup /export/home/path/to/your/process.sh&lt;br /&gt;      #nohup /export/home/admin/testscript.sh&lt;br /&gt;fi&lt;br /&gt;&lt;br /&gt;exit 0&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;If you can't use pgrep, there's another way to do this.  You can use grep and awk.&lt;br /&gt;&lt;pre&gt;FIND_PROC=`ps -ef |grep myprocess | awk '{if ($8 !~ /grep/) print $2}'`&lt;/pre&gt;&lt;br /&gt;ps picks up the grep process, so the awk script removes this from the listing.  The column numbers will likely need adjusting-- just change "print $2" to "print" and run the command from the command line and you will see the whole like.  Determine which column holds the PID.&lt;br /&gt;&lt;br /&gt;You can read more about awk &lt;a href="http://www.grymoire.com/Unix/Awk.html"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;You might also need to make the ps listing wider than the default 80 characters to avoid having the process name cut off.  In this case, your ps may support the --columns argument.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Cron Entry&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;To edit the cron file, you may first need to set the correct editor.  I am assuming this is vi (Solaris likes you to use the absolutely atrocious "ed" by default-- even now in 2008... as if vi isn't archaic enough).  If you get stuck inside ed, just type "quit".&lt;br /&gt;&lt;pre&gt;export EDITOR="vi"&lt;/pre&gt;Then run the crontab program&lt;br /&gt;&lt;pre&gt;crontab -e&lt;/pre&gt;It may very well be empty if you haven't set up an cron jobs.  The format is a columns separated by spaces.  Minute, hour, day of month, month, day of week, command to execute.  You can either put a number for the time columns, a list of numbers (separated by commas), a range (using a dash) or an asterisk (*) to specify all. &lt;br /&gt;&lt;br /&gt;I used the following line for my watchdog script (which logs normal and error output to watchdog.log):&lt;br /&gt;&lt;pre&gt;0,10,20,30,40,50 * * * * /export/home/admin/watchdog.sh &gt;&gt; /export/home/admin/wa&lt;br /&gt;tchdog.log 2&gt;&amp;1&lt;/pre&gt;&lt;br /&gt;(note, I couldn't paste the above line into crontab -e, but I could retype it no problem... go figure)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11240984-1773116988778313052?l=petersnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petersnotes.blogspot.com/feeds/1773116988778313052/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11240984&amp;postID=1773116988778313052' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/1773116988778313052'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/1773116988778313052'/><link rel='alternate' type='text/html' href='http://petersnotes.blogspot.com/2008/10/watchdog-script-for-process.html' title='Watchdog Script for a Process'/><author><name>Peter V</name><uri>http://www.blogger.com/profile/17919841991959605501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11240984.post-3658213406296798638</id><published>2008-10-20T12:52:00.000-07:00</published><updated>2008-10-20T12:55:26.475-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Video'/><title type='text'>Easy Vignette (and other effects) in Adobe After Effects</title><content type='html'>http://www.estrellastudios.com/blog/blog-video/after-effects-tip-quick-vignettes/&lt;br /&gt;&lt;br /&gt;Here's a good tutorial.  Basically, you create a layer mask above all other clips, double click the ellipse tool (which creates an ellipse that just fits inside your video), and expand the Mask settings and alter them (increase feather to 180, expansion down to -40).  Then you can add an effect to get darker corners-- like Exposure, and set it to, say, -1.50.  Of course you can add other effects too such as blurring.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11240984-3658213406296798638?l=petersnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petersnotes.blogspot.com/feeds/3658213406296798638/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11240984&amp;postID=3658213406296798638' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/3658213406296798638'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/3658213406296798638'/><link rel='alternate' type='text/html' href='http://petersnotes.blogspot.com/2008/10/easy-vignette-and-other-effects-in.html' title='Easy Vignette (and other effects) in Adobe After Effects'/><author><name>Peter V</name><uri>http://www.blogger.com/profile/17919841991959605501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11240984.post-1605461798167491680</id><published>2008-10-13T16:46:00.000-07:00</published><updated>2008-10-13T16:47:51.404-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='XML'/><category scheme='http://www.blogger.com/atom/ns#' term='Oracle'/><title type='text'>Exporting Table Data as Oracle XML</title><content type='html'>If you are using dbms xmlsave, you might want to capture data from a table into Oracle's format as well.  This is actually very straightforward with dbms_xmlgen.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;SELECT dbms_xmlgen.getXml(&lt;br /&gt;  'SELECT *&lt;br /&gt;     FROM your_table_name_goes_here'&lt;br /&gt;  , 0&lt;br /&gt;  ) FROM dual;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11240984-1605461798167491680?l=petersnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petersnotes.blogspot.com/feeds/1605461798167491680/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11240984&amp;postID=1605461798167491680' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/1605461798167491680'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/1605461798167491680'/><link rel='alternate' type='text/html' href='http://petersnotes.blogspot.com/2008/10/exporting-table-data-as-oracle-xml.html' title='Exporting Table Data as Oracle XML'/><author><name>Peter V</name><uri>http://www.blogger.com/profile/17919841991959605501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11240984.post-3470464775760579625</id><published>2008-10-13T11:18:00.001-07:00</published><updated>2008-10-13T11:26:03.077-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Oracle'/><category scheme='http://www.blogger.com/atom/ns#' term='SQL'/><title type='text'>Oracle SQL predefined exceptions</title><content type='html'>If you've written PL/SQL stored procedures and functions, you may have use BEGIN/END blocks with EXCEPTION.  Basically, this is kind of like try/catch in Java, and you can catch different exceptions and handle them.  The syntax is like this:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;BEGIN&lt;br /&gt; -- your code goes here.  If there isn't any, put NULL;&lt;br /&gt; NULL;&lt;br /&gt;EXCEPTION&lt;br /&gt; WHEN NO_DATA_FOUND OR BLAHBLAH THEN&lt;br /&gt;   ...&lt;br /&gt; WHEN OTHERS THEN&lt;br /&gt;END;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;To get a list of the constants ("predefined exceptions") that you can catch, look &lt;a href="http://209.85.173.104/search?q=cache:ZwOohvILIFcJ:www.saddleback.edu/faculty/mbhimaraju/Predefined.pdf+oracle+when+predefined+exceptions&amp;hl=en&amp;ct=clnk&amp;cd=1&amp;gl=us&amp;client=firefox-a"&gt;here&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11240984-3470464775760579625?l=petersnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petersnotes.blogspot.com/feeds/3470464775760579625/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11240984&amp;postID=3470464775760579625' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/3470464775760579625'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/3470464775760579625'/><link rel='alternate' type='text/html' href='http://petersnotes.blogspot.com/2008/10/oracle-sql-predefined-exceptions.html' title='Oracle SQL predefined exceptions'/><author><name>Peter V</name><uri>http://www.blogger.com/profile/17919841991959605501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11240984.post-692620601167298919</id><published>2008-10-07T15:11:00.000-07:00</published><updated>2008-10-07T15:48:36.638-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='XML'/><category scheme='http://www.blogger.com/atom/ns#' term='Oracle'/><title type='text'>Looping over a Set of Nodes with PL/SQL</title><content type='html'>Oracle's XMLType has the handy member function 'extract' which evaluates an XPath.  Except it won't work if you XPath is a function call.  So, if you want to count how many children there are of a node so you can iterate over them, &lt;pre&gt;extract('count(/xpath/here/*)')&lt;/pre&gt; won't work.  Here's the solution:&lt;br /&gt;&lt;pre&gt;select count(*) into v_maxi from TABLE(XMLSequence(extract(p_xml,'/xpath/here')));               &lt;br /&gt;  FOR v_i IN 0..v_maxi-1 LOOP&lt;br /&gt;      v_xmlfrag := p_xml.extract('/xpath/here[count(preceding-sibling::*)='||v_i||']');&lt;br /&gt;      v_text := v_xmlfrag.extract('/record/stuff/text()').getStringVal();&lt;br /&gt;  END LOOP;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11240984-692620601167298919?l=petersnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petersnotes.blogspot.com/feeds/692620601167298919/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11240984&amp;postID=692620601167298919' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/692620601167298919'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/692620601167298919'/><link rel='alternate' type='text/html' href='http://petersnotes.blogspot.com/2008/10/looping-over-set-of-nodes-with-plsql.html' title='Looping over a Set of Nodes with PL/SQL'/><author><name>Peter V</name><uri>http://www.blogger.com/profile/17919841991959605501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11240984.post-2734489299147970115</id><published>2008-10-07T15:08:00.000-07:00</published><updated>2008-11-06T10:47:34.870-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='XML'/><category scheme='http://www.blogger.com/atom/ns#' term='Oracle'/><title type='text'>Insert, Append, or Update an XML element to an XML document using Oracle PL/SQL</title><content type='html'>Oracle allows you to quickly insert or append an XML element to a path inside an XML document using insertchildxml.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;select&lt;br /&gt;   insertchildxml(v_xmltype,&lt;br /&gt;        '/my/xpath',&lt;br /&gt;        lower('elementname'),&lt;br /&gt;        XMLType('&lt;elementname&gt;stuff&lt;/elementname&gt;'))&lt;br /&gt;   from dual;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Gotchas: You must use a select statement.  Argument 3 must match the element inside argument 4.&lt;br /&gt;&lt;br /&gt;If you are modifying attributes, you can use updatexml-- but it is obnoxious because if the attribute doesn't exist, updatexml fails silently.  So, if unsure, you need to user insertxml to add the attribute and if it throws an exception, then attempt an update.  Like so:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;   BEGIN&lt;br /&gt;        select insertchildxml(v_xml, '//myxpath', '@myattribute',&lt;br /&gt;               v_newvalue) into v_xml from dual;&lt;br /&gt;   EXCEPTION -- if @myattribute attribute exists, insert will fail, so update instead&lt;br /&gt;   WHEN OTHERS THEN&lt;br /&gt;        select updatexml(v_xml, '//myxpath/@myattribute', v_newvalue)&lt;br /&gt;               into v_xml from dual;&lt;br /&gt;   END;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11240984-2734489299147970115?l=petersnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petersnotes.blogspot.com/feeds/2734489299147970115/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11240984&amp;postID=2734489299147970115' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/2734489299147970115'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/2734489299147970115'/><link rel='alternate' type='text/html' href='http://petersnotes.blogspot.com/2008/10/insert-or-append-xml-element-to-xml.html' title='Insert, Append, or Update an XML element to an XML document using Oracle PL/SQL'/><author><name>Peter V</name><uri>http://www.blogger.com/profile/17919841991959605501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11240984.post-24541644337079143</id><published>2008-10-07T14:49:00.000-07:00</published><updated>2008-10-07T15:08:05.971-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='XML'/><category scheme='http://www.blogger.com/atom/ns#' term='Oracle'/><title type='text'>Extending DBMS.XMLSave to Insert into Multiple Tables</title><content type='html'>Oracle, through the DBMS.XMLSave package, is able to take XML in a specific format and insert it into normal relational tables.  This package has two major limitations in my opinion: 1) The values of rows are NOT evaluated, so functions do not work and sequences don't work.  2) Only one target table can be specified.&lt;br /&gt;&lt;br /&gt;I've written a procedure which wraps Oracle's format inside some higher level XML elements to allow insertion into multiple tables.  My solution for sequences and functions is not very flexible, but it will work for specific applications, and I can make some recommendations on how to improve the flexibility.&lt;br /&gt;&lt;br /&gt;Let's start with inserting into multiple tables.  If you look at my previous post, you will see Oracle's format for the DBMS.XMLSave function.  I wrap it in two higher level elements, records (the new root) and the record element which contains a rowset.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&amp;lt;records&amp;gt;&lt;br /&gt;  &amp;lt;record table="tablenamegoeshere"&amp;gt;&lt;br /&gt;    &amp;lt;rowset&amp;gt;&lt;br /&gt;      &amp;lt;row&amp;gt;&lt;br /&gt;        &amp;lt;columnname&amp;gt;value&amp;lt;/columnname&amp;gt;&lt;br /&gt;      &amp;lt;/row&amp;gt;&lt;br /&gt;    &amp;lt;/rowset&amp;gt;&lt;br /&gt;  &amp;lt;/record&amp;gt;&lt;br /&gt;&amp;lt;records&amp;gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;A stored procedure to handle these XML files must loop through each record and call Oracle's XMLSave on the rowset contained within.  Each record element has an attribute, table, which specifies which table to insert into.&lt;br /&gt;&lt;br /&gt;The next step is to implement sequences.  We could take a cue from Hibernate and add an attribute to the column that uses a sequence.  I didn't have time to implement this, so what I've done is update one column in each row with the results of an execute immediate.  This assumes that there is only one sequence that needs updating and that it's name &amp;amp; and the containing column's name is based on the table attribute in the record element. &lt;br /&gt;&lt;br /&gt;I use a similar procedure for function calls-- use XPath to update columns.  The structure of the data is very rigid unfortunately because of this.&lt;br /&gt;&lt;br /&gt;One gotcha -- make sure rowset and row elements are LOWER CASE.  Oracle's procedures are case sensitive.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;create or replace procedure PARSE_RECORD_XML(p_xml in xmltype, p_xmlid in integer) is&lt;br /&gt;   v_i            INTEGER;&lt;br /&gt;   v_j            INTEGER;&lt;br /&gt;   v_func_arg    INTEGER;&lt;br /&gt;   v_seqnum       INTEGER;&lt;br /&gt;   v_func_result          VARCHAR2(50);&lt;br /&gt;   v_xmlfrag      XMLTYPE;&lt;br /&gt;   v_tablename    VARCHAR2(50);&lt;br /&gt;   v_seqname      VARCHAR2(100);&lt;br /&gt;   v_maxi         INTEGER;&lt;br /&gt;   v_maxj         INTEGER;&lt;br /&gt;  &lt;br /&gt;begin&lt;br /&gt;  select count(*) into v_maxi from TABLE(XMLSequence(extract(p_xml,'/records/record')));               &lt;br /&gt;  FOR v_i IN 0..v_maxi-1 LOOP&lt;br /&gt;      v_xmlfrag := p_xml.extract('/records/record[count(preceding-sibling::*)='||v_i||']');&lt;br /&gt;      v_tablename := v_xmlfrag.extract('/record/@table').getStringVal();&lt;br /&gt;      v_seqname := v_tablename || 'ID'; -- sequence name is a concatenation of table attribute and ID&lt;br /&gt;     &lt;br /&gt;      select count(*) into v_maxj from TABLE(XMLSequence(extract(v_xmlfrag,'/record/rowset/row')));               &lt;br /&gt; &lt;br /&gt;      FOR v_j in 0..v_maxj-1 LOOP&lt;br /&gt;        -- Get sequence number&lt;br /&gt;        execute immediate 'SELECT ' || v_seqname || '.nextval from dual' into v_seqnum;&lt;br /&gt;       &lt;br /&gt;        -- Execute a function on some data&lt;br /&gt;        v_func_result := v_xmlfrag.extract('/record/rowset/row[count(preceding-sibling::*)='||v_j||']/func_arg/text()').getStringVal();&lt;br /&gt;       &lt;br /&gt;        -- Insert the parent id&lt;br /&gt;        select insertchildxml(v_xmlfrag, '/record/rowset/row[count(preceding-sibling::*)='||v_j||']', 'parentid',&lt;br /&gt;                    XMLType('&lt;parentid&gt;' || p_xmlid || '&lt;/parentid&gt;')) into v_xmlfrag from dual;&lt;br /&gt;       &lt;br /&gt;        -- Insert function result           &lt;br /&gt;        select insertchildxml(v_xmlfrag, '/record/rowset/row[count(preceding-sibling::*)='||v_j||']', 'func_result',&lt;br /&gt;                    XMLType('&lt;func_result&gt;' || getMRN(v_patientid) || '&lt;/func_result&gt;')) into v_xmlfrag from dual;&lt;br /&gt;&lt;br /&gt;        -- Insert sequence id&lt;br /&gt;        select insertchildxml(v_xmlfrag, '/record/rowset/row[count(preceding-sibling::*)='||v_j||']', lower(v_seqname),&lt;br /&gt;                    XMLType('&lt;' || lower(v_seqname) || '&gt;' || v_seqnum || '&lt;/' || lower(v_seqname) || '&gt;')) into v_xmlfrag from dual;&lt;br /&gt;             &lt;br /&gt;       &lt;br /&gt;      END LOOP;&lt;br /&gt;      InsertXML(v_xmlfrag.extract('/record/rowset'), v_tablename);&lt;br /&gt;  END LOOP;&lt;br /&gt;end PARSE_RECORD_XML;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11240984-24541644337079143?l=petersnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petersnotes.blogspot.com/feeds/24541644337079143/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11240984&amp;postID=24541644337079143' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/24541644337079143'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/24541644337079143'/><link rel='alternate' type='text/html' href='http://petersnotes.blogspot.com/2008/10/extending-dbmsxmlsave-to-insert-into.html' title='Extending DBMS.XMLSave to Insert into Multiple Tables'/><author><name>Peter V</name><uri>http://www.blogger.com/profile/17919841991959605501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11240984.post-4556320004510879627</id><published>2008-10-07T14:41:00.000-07:00</published><updated>2008-10-07T14:49:40.797-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='XSL'/><category scheme='http://www.blogger.com/atom/ns#' term='XML'/><category scheme='http://www.blogger.com/atom/ns#' term='Oracle'/><title type='text'>Inserting XML data into an Oracle Table</title><content type='html'>Oracle has a package DBMS_XMLsave that can take an XML document and insert it into a normal relational table.  The format for the XML document is&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&amp;lt;ROWSET&amp;gt;&lt;br /&gt;  &amp;lt;ROW&amp;gt;&lt;br /&gt;    &amp;lt;COLUMNNAME&amp;gt;&lt;br /&gt;      value&lt;br /&gt;    &amp;lt;/COLUMNNAME&amp;gt;&lt;br /&gt;  &amp;lt;/ROW&amp;gt;&lt;br /&gt;&amp;lt;/ROWSET&amp;gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The other argument to the save function is the table name.  Two gotchas: 1) by default, the element names are case sensitive.  I think this is a nightmare with table column names, so luckily there is a flag to disable case sensitivity (why do developer's inflict case sensitivity on each other?) 2) The format is very barebones.  Attributes are ignored and you can't use functions within the values for columns.  You can only insert into one table as well.  I've created some code to get around this, which is the topic of another post.&lt;br /&gt;&lt;br /&gt;At least, though, you CAN use XSLT to transform your document to something that Oracle can handle natively. &lt;br /&gt;&lt;br /&gt;Here is a stored procedure that inserts such an XML document:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;CREATE OR REPLACE PROCEDURE InsertXML (p_xml in xmltype, p_tablename in varchar2) is&lt;br /&gt;&lt;br /&gt;   queryCtx DBMS_XMLsave.ctxType;&lt;br /&gt;&lt;br /&gt;   rowsInserted INT;&lt;br /&gt;&lt;br /&gt;BEGIN&lt;br /&gt;&lt;br /&gt;   --Defines the query&lt;br /&gt;&lt;br /&gt;   queryCtx := SYS.DBMS_XMLSave.newContext(p_tablename);&lt;br /&gt;  &lt;br /&gt;   DBMS_XMLSave.setIgnoreCase(queryCtx, 1);&lt;br /&gt;  &lt;br /&gt;   rowsInserted := DBMS_XMLSave.insertXML(queryCtx,p_xml.getCLOBval());&lt;br /&gt;  &lt;br /&gt;   DBMS_XMLSave.closeContext(queryCtx);&lt;br /&gt;  &lt;br /&gt;   commit;&lt;br /&gt;&lt;br /&gt;END;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11240984-4556320004510879627?l=petersnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petersnotes.blogspot.com/feeds/4556320004510879627/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11240984&amp;postID=4556320004510879627' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/4556320004510879627'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/4556320004510879627'/><link rel='alternate' type='text/html' href='http://petersnotes.blogspot.com/2008/10/inserting-xml-data-into-oracle-table.html' title='Inserting XML data into an Oracle Table'/><author><name>Peter V</name><uri>http://www.blogger.com/profile/17919841991959605501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11240984.post-5162005243314423502</id><published>2008-09-04T15:40:00.000-07:00</published><updated>2008-09-04T15:47:54.934-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JSP'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><title type='text'>How to Split a String Based on a Delimeter using Java</title><content type='html'>&lt;pre&gt;&lt;br /&gt;&amp;lt;form action="testdissect.jsp" method="POST"&amp;gt;&lt;br /&gt;&amp;lt;textarea name="stuff"&amp;gt;&amp;lt;/textarea&amp;gt;&lt;br /&gt;&amp;lt;input type="submit" value="split"/&amp;gt;&lt;br /&gt;&amp;lt;/form&amp;gt;&lt;br /&gt;output:&amp;lt;br/&amp;gt;&lt;br /&gt;&amp;lt;%&lt;br /&gt;if(request.getParameter("stuff")!=null) {&lt;br /&gt;        String stuff = (java.lang.String) request.getParameter("stuff");&lt;br /&gt;        stuff = stuff.replaceAll("\\n|\\r",""); // (optional) remove line breaks&lt;br /&gt;        String[] chunks = stuff.split(";");&lt;br /&gt;        for(int i=0; i &amp;lt; chunks.length; i++)&lt;br /&gt;                out.println("["+i+"] "+chunks[i]);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;%&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11240984-5162005243314423502?l=petersnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petersnotes.blogspot.com/feeds/5162005243314423502/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11240984&amp;postID=5162005243314423502' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/5162005243314423502'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/5162005243314423502'/><link rel='alternate' type='text/html' href='http://petersnotes.blogspot.com/2008/09/how-to-split-string-based-on-delimeter.html' title='How to Split a String Based on a Delimeter using Java'/><author><name>Peter V</name><uri>http://www.blogger.com/profile/17919841991959605501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11240984.post-6706131779454219498</id><published>2008-08-20T10:33:00.000-07:00</published><updated>2008-08-20T11:34:18.495-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Oracle'/><category scheme='http://www.blogger.com/atom/ns#' term='SQL'/><title type='text'>Creating User Defined Types in Oracle</title><content type='html'>You can roll your own types in Oracle (and Postgres and mysql also) that include member variables and procedures though the procedures won't be portable.  Here is how to create and use a type that has no procedures:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;create or replace type MYUDT as object&lt;br /&gt;(&lt;br /&gt;  -- Author  : HELMUT&lt;br /&gt;  -- Created : 8/20/2008 10:36:10 AM&lt;br /&gt;  -- Purpose : example user defined type&lt;br /&gt; &lt;br /&gt;  -- Attributes&lt;br /&gt;  SILLY NUMBER,&lt;br /&gt;  FOO VARCHAR2(200)&lt;br /&gt; &lt;br /&gt;  -- Member functions and procedures&lt;br /&gt; &lt;br /&gt;)&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Create a table like normal:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;-- Create table&lt;br /&gt;create table DUMMYTABLE&lt;br /&gt;(&lt;br /&gt;  USERTYPECOLUMN MYUDT&lt;br /&gt;)&lt;br /&gt;;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;You can then insert into the table like so:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;INSERT INTO DUMMYTABLE (USERTYPECOLUMN) VALUES ( MYUDT(10,'Obamarama') );&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;and read from the table like so:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;SELECT USERTYPECOLUMN.FOO FROM DUMMYTABLE WHERE USERTYPECOLUMN.SILLY &gt; 5;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11240984-6706131779454219498?l=petersnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petersnotes.blogspot.com/feeds/6706131779454219498/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11240984&amp;postID=6706131779454219498' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/6706131779454219498'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/6706131779454219498'/><link rel='alternate' type='text/html' href='http://petersnotes.blogspot.com/2008/08/creating-user-defined-types-in-oracle.html' title='Creating User Defined Types in Oracle'/><author><name>Peter V</name><uri>http://www.blogger.com/profile/17919841991959605501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11240984.post-4477900111744903128</id><published>2008-08-13T15:11:00.001-07:00</published><updated>2008-08-13T15:16:31.660-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Mirth Project'/><title type='text'>Accessing a Message in Different Parts of Mirth</title><content type='html'>Depending on which part of Mirth you are writing JavaScript code, you need to use different objects to access the same data.  It's pretty annoying.&lt;br /&gt;&lt;br /&gt;Objects&lt;br /&gt;messageObject.getRawData() - gets raw data - works in transformer, filter, and connector javascript&lt;br /&gt;messageObject.getEncodedData() - works in transformer, filter, and connector javascript&lt;br /&gt;messageObject.getTransformedData() - works in transformer, filter and connector javascript IFF there is a transformer, otherwise returns null&lt;br /&gt;msg - gets array representing XML - works only in transformer and filter, no equivalent in connector&lt;br /&gt;&lt;br /&gt;In other scripting situations (like SQL) you can use ${message.rawData} and the like to get rawData, encodedData, and transformedData. &lt;br /&gt;&lt;br /&gt;To get a msg object in a connector, check out this posting by ChrisL on the Mirth forum:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;If you are using this on the DB Writer Javascript, then the error is occurring because MSG isn't valid there. msg is only available in the transformer and filter.&lt;br /&gt;&lt;br /&gt;You can store msg in the transformer with&lt;br /&gt;&lt;br /&gt;channelMap.put('msg', msg)&lt;br /&gt;&lt;br /&gt;then in your destination DB Writer do:&lt;br /&gt;&lt;table align="center" border="0" cellpadding="3" cellspacing="1" width="90%"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;b&gt;Code:&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;pre&gt;&lt;code&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 187);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;var &lt;/span&gt;&lt;span style="color: rgb(0, 0, 187);"&gt;msg &lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;= &lt;/span&gt;&lt;span style="color: rgb(0, 0, 187);"&gt;channelMap&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;.&lt;/span&gt;&lt;span style="color: rgb(0, 0, 187);"&gt;get&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(221, 0, 0);"&gt;'msg'&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/blockquote&gt;&lt;table align="center" border="0" cellpadding="3" cellspacing="1" width="90%"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;pre&gt;&lt;code&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11240984-4477900111744903128?l=petersnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petersnotes.blogspot.com/feeds/4477900111744903128/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11240984&amp;postID=4477900111744903128' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/4477900111744903128'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/4477900111744903128'/><link rel='alternate' type='text/html' href='http://petersnotes.blogspot.com/2008/08/accessing-message-in-different-parts-of.html' title='Accessing a Message in Different Parts of Mirth'/><author><name>Peter V</name><uri>http://www.blogger.com/profile/17919841991959605501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11240984.post-6656063576677459069</id><published>2008-08-11T14:19:00.000-07:00</published><updated>2008-08-11T14:32:32.653-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Video'/><title type='text'>Archiving 8mm Video</title><content type='html'>I have a box of Video8 cassettes with various home videos on them.  Not having seen any 8mm camcorder in some years, I decided I had better back these tapes up before there are no devices left to play the tapes.&lt;br /&gt;&lt;br /&gt;The best way to back the tapes up is to use a Digital8 camcorder and capture via Firewire.  The perfectionists will recommend using dedicated tape decks, but these are very expensive and the Sony ones break down quickly.&lt;br /&gt;&lt;br /&gt;I borrowed a Video8 camcorder with composite outs (a yellow RCA jack and a red RCA audio jack).  I have a Hauppage WinTV card from the late 90s which can capture video.  I connected the audio to my PreSonus Firepod.  I disabled all other sound devices on the PC via the BIOS since Windows likes to randomly choose which device is active.&lt;br /&gt;&lt;br /&gt;I followed the tutorial at this location: http://arstechnica.com/guides/tweaks/vidcap.ars&lt;br /&gt;&lt;br /&gt;Briefly, NTSC 8mm resolution is at a minimum 352x288.  That's only marginally useful information because your camcorder may have done better than that.  I went with capturing at 640x480.  I downloaded VirtuaDUB+VCR. I first started capturing with HuffyUV using YUY2 colorspace, but while HuffyUV is great because it can do lossless 2:1 compression, that's still a whole lot of data and I realized that even with 1 terabyte of storage, I would likely run out of space.&lt;br /&gt;So I switched over to the lossy MJPEG encoder for some 8:1 compression.  The quality of the tape from 1992 is not exactly stellar and MJPEG does a good job of capturing it all.  I found I had to check each video afterwards to see if the audio stays in sync.  About 1 in 5 captures would lose sync.&lt;br /&gt;The only remaining issue is deinterlacing.  I started reading about how to do it properly, and my head began to spin.  It would be preferable to deinterlace BEFORE doing lossy encoding, since adding deinterlacing later would cause yet more lossy compression, introducing more generation loss.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11240984-6656063576677459069?l=petersnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petersnotes.blogspot.com/feeds/6656063576677459069/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11240984&amp;postID=6656063576677459069' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/6656063576677459069'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/6656063576677459069'/><link rel='alternate' type='text/html' href='http://petersnotes.blogspot.com/2008/08/archiving-8mm-video.html' title='Archiving 8mm Video'/><author><name>Peter V</name><uri>http://www.blogger.com/profile/17919841991959605501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11240984.post-1499264354676328400</id><published>2008-08-11T14:09:00.000-07:00</published><updated>2008-08-11T14:15:12.812-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Mirth Project'/><title type='text'>Common Mirth Functions</title><content type='html'>&lt;span style="font-weight: bold;"&gt;Inside a transformer&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Convert XML to HL7&lt;br /&gt;&lt;span style="font-style: italic;"&gt;SerializerFactory.getHL7Serializer(useStrictParser, useStrictValidation, handleRepetitions).fromXML(message);&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Access parts of an XML message&lt;br /&gt;&lt;span style="font-style: italic;"&gt;msg['MSH']['MSH.4']['MSH.4.1'] = 'TEST12345';&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Set the transformedData to a new value&lt;br /&gt;&lt;span style="font-style: italic;"&gt;msg = "&lt;blah/&gt;&lt;/span&gt;&lt;blah&gt;&lt;span style="font-style: italic;"&gt;"&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Inside a Message Template&lt;/span&gt;&lt;br /&gt;Get raw message data: &lt;span style="font-style: italic;"&gt;${message.rawData}&lt;/span&gt;&lt;br /&gt;Get transformed data (if a transformer exists-- you can create an empty javascript transformer): &lt;span style="font-style: italic;"&gt;${message.transformedData}&lt;/span&gt;&lt;br /&gt;Get encoded data, which has special characters encoded: &lt;span style="font-style: italic;"&gt;${message.encodedData}&lt;/span&gt;&lt;br /&gt;&lt;/blah&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11240984-1499264354676328400?l=petersnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://petersnotes.blogspot.com/feeds/1499264354676328400/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=11240984&amp;postID=1499264354676328400' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/1499264354676328400'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11240984/posts/default/1499264354676328400'/><link rel='alternate' type='text/html' href='http://petersnotes.blogspot.com/2008/08/common-mirth-functions.html' title='Common Mirth Functions'/><author><name>Peter V</name><uri>http://www.blogger.com/profile/17919841991959605501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry></feed>
