<?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-5053288836813625185</id><updated>2011-07-08T00:40:47.660-07:00</updated><category term='sparkline'/><category term='ui'/><category term='jsf'/><category term='css'/><category term='java'/><category term='php'/><category term='ajax'/><category term='linux debian admin oop'/><category term='layout'/><category term='unicode'/><category term='float'/><category term='myfaces'/><category term='form'/><title type='text'>Zero to Enterprise</title><subtitle type='html'>Software is built for humans.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://zero-to-enterprise.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5053288836813625185/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://zero-to-enterprise.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Nick</name><uri>http://www.blogger.com/profile/12675339848724787589</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>9</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-5053288836813625185.post-1716282988800275628</id><published>2010-02-15T14:37:00.000-08:00</published><updated>2010-02-15T14:37:02.926-08:00</updated><title type='text'>Parent-Child Relationship in Java Business Logic Beans</title><content type='html'>There must be good tips and info out there on the net about best practices for designing Java beans business objects, etc. I don't mean basic stuff like getters/setters, but much more subtle questions like when to hide constructors, how to deal with parent-child objects and what sort of methods to expose for that, etc.&lt;br /&gt;Somehow I never found good info on that (not that I tried too hard), and my classes didn't cover it.&lt;br /&gt;&lt;br /&gt;Here's my take on the parent-child relationship between Java objects. Say there are two classes: &lt;code&gt;Customer&lt;/code&gt; and &lt;code&gt;Contact&lt;/code&gt; (a typical sales-app situation). Each customer has multiple contacts - a simple one-to-many relationship. The customer object keeps track of the child contacts with a collection, and the contact maintains a parent customer reference.&lt;br /&gt;&lt;br /&gt;Question: how to handle creating new contact objects?&lt;br /&gt;&lt;br /&gt;In contact class:&lt;br /&gt;&lt;pre&gt;// package-private constructor&lt;br /&gt;Contact(Customer c, &lt;i&gt;parameters...&lt;/i&gt;) {&lt;br /&gt;  this.customer = c; // keep parent reference&lt;br /&gt;  // deal with other parameters&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;In customer class:&lt;br /&gt;&lt;pre&gt;public Contact createContact(&lt;i&gt;parameters...&lt;/i&gt;) {&lt;br /&gt;  Contact c = new Contact(this, &lt;i&gt;parameters...&lt;/i&gt;);&lt;br /&gt;  this.contacts.add(c); // update children collection&lt;br /&gt;  return c;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;Why not expose the contact constructor directly and have it update the customer contacts collection? Adding to the children collection is altering object state - it is best to keep that inside the customer class.&lt;br /&gt;&lt;br /&gt;Even in terms of readability this makes more sense. When humans say "customer", the meaning includes all the relevant contacts, etc. When we create a contact we change customer state, first and foremost. So it makes sense to initiate that change with the customer object.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5053288836813625185-1716282988800275628?l=zero-to-enterprise.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zero-to-enterprise.blogspot.com/feeds/1716282988800275628/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5053288836813625185&amp;postID=1716282988800275628' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5053288836813625185/posts/default/1716282988800275628'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5053288836813625185/posts/default/1716282988800275628'/><link rel='alternate' type='text/html' href='http://zero-to-enterprise.blogspot.com/2010/02/parent-child-relationship-in-java.html' title='Parent-Child Relationship in Java Business Logic Beans'/><author><name>Nick</name><uri>http://www.blogger.com/profile/12675339848724787589</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-5053288836813625185.post-6238412179396662756</id><published>2010-02-10T16:44:00.000-08:00</published><updated>2010-02-10T18:13:31.528-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='layout'/><category scheme='http://www.blogger.com/atom/ns#' term='float'/><category scheme='http://www.blogger.com/atom/ns#' term='form'/><category scheme='http://www.blogger.com/atom/ns#' term='css'/><title type='text'>Two-column Form Layout Without Floats</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_WrA9LI79QO8/S3NnOvln5mI/AAAAAAAAAAU/DXqn3O_cjpw/s1600-h/form-screenshot.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="97" src="http://3.bp.blogspot.com/_WrA9LI79QO8/S3NnOvln5mI/AAAAAAAAAAU/DXqn3O_cjpw/s320/form-screenshot.PNG" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;As part of my job, I work with HTML forms almost daily, and styling them is an ever-evolving challenge.&lt;br /&gt;&lt;br /&gt;Clients like it when labels are horizontally aligned with inputs. It's the standard look, and it works well.&lt;br /&gt;&lt;br /&gt;One of the big requirements is &lt;span style="font-weight: bold;"&gt;avoiding floats&lt;/span&gt;. Float behaviour is complicated and buggy, even outside of IE. Normally that's not a big issue, but in apps one can't predict where a given form will end up, what kind of custom widgets (that use their own funky float layout) will need to be part of it, etc. Basically, form CSS has to be &lt;span style="font-style: italic;"&gt;rock-solid&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Markup has to be simple and valid XHTML. So no tricks like placing the input inside the label. And it sucks to litter markup with spans and whatnot.&lt;br /&gt;&lt;br /&gt;There has to be allowance for error messages, help tips, overflowing label text, etc. Basically, no reliance on hand-tweaking content.&lt;br /&gt;&lt;br /&gt;A good method that does not use floats is described in this &lt;span style="font-style: italic;"&gt;A List Apart&lt;/span&gt; article: &lt;a href="http://www.alistapart.com/articles/prettyaccessibleforms/"&gt;http://www.alistapart.com/articles/prettyaccessibleforms/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;It uses inline-block for labels - not great, because it's hard to put properly aligned help text after it. Same with error text.&lt;br /&gt;&lt;br /&gt;The answer? Negative margins. Check this example (forgive the programmer art): &lt;a href="http://sigmaxis.com/simple-forms/"&gt;http://sigmaxis.com/simple-forms/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;First, we keep label content to the left of everything else by assigning a width to it (as a block), and applying a left margin to other content in the form.&lt;br /&gt;&lt;br /&gt;Next, we apply a negative bottom margin to every label. Any content that follows a label is "pulled up" vertically to appear as though they are on the same horizontal line.&lt;br /&gt;&lt;br /&gt;For consistency across fonts and browsers, we assign a generous fixed height to the label, and make the negative margin match it. In theory, the fixed height can be anything, even zero - but IE6's overflow bug puts an end to that theory.&lt;br /&gt;&lt;br /&gt;This brings up a &lt;span style="font-weight: bold;"&gt;big caveat&lt;/span&gt; with this method. If the label contains several lines of text, the browser will not auto-magically shift remaining content down, as it would with normal cleared floats. In the particular case of HTML forms, this is not an issue, given enough vertical spacing between inputs.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5053288836813625185-6238412179396662756?l=zero-to-enterprise.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zero-to-enterprise.blogspot.com/feeds/6238412179396662756/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5053288836813625185&amp;postID=6238412179396662756' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5053288836813625185/posts/default/6238412179396662756'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5053288836813625185/posts/default/6238412179396662756'/><link rel='alternate' type='text/html' href='http://zero-to-enterprise.blogspot.com/2010/02/two-column-form-layout-without-floats.html' title='Two-column Form Layout Without Floats'/><author><name>Nick</name><uri>http://www.blogger.com/profile/12675339848724787589</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/_WrA9LI79QO8/S3NnOvln5mI/AAAAAAAAAAU/DXqn3O_cjpw/s72-c/form-screenshot.PNG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5053288836813625185.post-1942830182838223948</id><published>2009-04-13T12:06:00.000-07:00</published><updated>2009-04-13T12:25:15.882-07:00</updated><title type='text'>NetBeans, Subversion and plink revisited</title><content type='html'>An &lt;a href="http://zero-to-enterprise.blogspot.com/2008/12/netbeans-bundled-subversion-troubles.html"&gt;earlier post&lt;/a&gt; detailed some issues with NetBeans bundled SVN+SSH support. NetBeans allows specifying a different SSH connection command-line (e.g. for plink) for different Subversion URLs - e.g. to set the username, password or other custom connection options; the problem is that it does not actually use that setting after first restart. Instead, a central Subversion config file is consulted; the connection options from there are used for &lt;span style="font-style: italic;"&gt;every&lt;/span&gt; Subversion URL. That's probably a bug.&lt;br /&gt;&lt;br /&gt;The work-around so far has been to just put the settings in the central file. But of course that stops working the moment there is more than one Subversion URL used. Here is my new solution when using &lt;span style="font-style: italic;"&gt;plink.exe&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;In the central Subversion config file, specify the command-line of "&lt;span style="font-weight: bold;"&gt;&lt;..path..&gt;\plink.exe -batch -load&lt;/span&gt;"; firstly, that turns off interactive prompt (and hence annoying hangs), and also &lt;span style="font-style: italic;"&gt;makes plink interpret hostnames passed by Subversion as PuTTY session names&lt;/span&gt;! The next step is to set up a PuTTY session named after that host and put all the appropriate settings there - the auto-login username, the private key for authentication, etc.&lt;br /&gt;&lt;br /&gt;NOTE: this allows using arbitrary "fake" hostnames in Subversion URLs, as long as they correspond to a PuTTY session.&lt;br /&gt;&lt;br /&gt;NOTE: the "-load" option magically works here because the first parameter passed by Subversion after it is the hostname; if that was not the case, the above would fail.&lt;br /&gt;&lt;br /&gt;Unix/Linux SSH users, of course, have always had the option to use session names as pseudo-hostnames - without the "-load" option hackery. But this would not even come up if not for the NetBeans bug.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5053288836813625185-1942830182838223948?l=zero-to-enterprise.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zero-to-enterprise.blogspot.com/feeds/1942830182838223948/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5053288836813625185&amp;postID=1942830182838223948' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5053288836813625185/posts/default/1942830182838223948'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5053288836813625185/posts/default/1942830182838223948'/><link rel='alternate' type='text/html' href='http://zero-to-enterprise.blogspot.com/2009/04/netbeans-subversion-and-plink-revisited.html' title='NetBeans, Subversion and plink revisited'/><author><name>Nick</name><uri>http://www.blogger.com/profile/12675339848724787589</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-5053288836813625185.post-4562568289976038715</id><published>2008-12-31T11:00:00.000-08:00</published><updated>2008-12-31T11:50:21.156-08:00</updated><title type='text'>NetBeans bundled Subversion troubles</title><content type='html'>This is a small note-to-self.&lt;br /&gt;&lt;br /&gt;NetBeans support for Subversion on Windows has an option to use either bundled svn binaries or CollabNet's official installation. The bundled NetBeans svn client works just fine at first - I use it with plink to do ssh tunneling.&lt;br /&gt;&lt;br /&gt;Except that eventually it starts failing with a mysterious exception along the lines of:&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;org.tigris.subversion.javahl.ClientException: The system cannot find the file specified.  &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;Commit failed (details follow):&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;Can't create tunnel: The system cannot find the file specified. &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Long story short, the snafu is likely because in the NetBeans SVN settings, the full path to plink executable has to use &lt;span style="font-weight: bold;"&gt;forward&lt;/span&gt; slashes. Also, it may be prudent to surround whitespace-containing paths with quotation marks.&lt;br /&gt;&lt;br /&gt;Anywho, it may still stop working, but we'll see.&lt;br /&gt;&lt;br /&gt;UPDATE: nope, still doesn't work, heh.&lt;br /&gt;&lt;br /&gt;UPDATE: &lt;span style="font-weight: bold;"&gt;works&lt;/span&gt; now. following NetBeans wiki instructions, it turns out that the bundled svn client doesn't actually listen to tunnel settings given by NetBeans (!). It listens to the .../Application Data/Subversion/config file. Another important caveat that wasted me a lot of time is that any time that file is changed, NetBeans must be restarted for any change to make a difference. And another important caveat is to use the explicit .exe extension on the plink executable file path. I added plink's location to my PATH; I also used Pageant for private-key auth instead of directly specifying the private-key path. Grr, what a stupid NetBeans bug.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5053288836813625185-4562568289976038715?l=zero-to-enterprise.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zero-to-enterprise.blogspot.com/feeds/4562568289976038715/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5053288836813625185&amp;postID=4562568289976038715' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5053288836813625185/posts/default/4562568289976038715'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5053288836813625185/posts/default/4562568289976038715'/><link rel='alternate' type='text/html' href='http://zero-to-enterprise.blogspot.com/2008/12/netbeans-bundled-subversion-troubles.html' title='NetBeans bundled Subversion troubles'/><author><name>Nick</name><uri>http://www.blogger.com/profile/12675339848724787589</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-5053288836813625185.post-5805395813157678172</id><published>2008-11-02T12:28:00.000-08:00</published><updated>2008-11-02T13:00:52.808-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux debian admin oop'/><title type='text'>Computer Science Approach to OS Design</title><content type='html'>So I had to tinker with Debian administration a bit... I can't help but philosophize about how some fairly abstract CS theory can apply to pragmatic admin stuff - packages, admin shell-scripts, etc.&lt;br /&gt;&lt;br /&gt;Debian's dpkg already allows treating software in a fairly declarative OOP fashion. You have concrete "implementation" packages providing functionality guaranteed by special virtual packages, generic system-wide scripts for things like startup/shutdown sequence management, conf.d approach (one of my favourites) for modular "plug-in" configuration, etc. It is all very much interfaces vs classes and design-by-contract.&lt;br /&gt;&lt;br /&gt;So I wonder if there is room to go a step further. Make packages declare their functionality in an abstract IDL/CORBA-like interface language. For example, a /usr/share file is kind of like a read-only property getter. An executable is a method (obviously). A config file is a special variation of user input (where the user is the admin). And so on and so forth.&lt;br /&gt;&lt;br /&gt;Then, packages can declare their prerequisites in a much more granular and consistent way - by indicating individual files and utils that they use. There could be even tools that would automate half the work of a package maintainer. For example, compile the program directly from a SourceForge tarball, run it and sniff out its runtime library dependencies, system file access on the fly. In fact, existing debs and rpms could be scanned and adapted appropriately without a recompile.&lt;br /&gt;&lt;br /&gt;What does that do? The package manager can be much smarter in detecting broken dependencies and software management issues. There is also room to get closer to a nice unified configuration system (not that everyone really cares too much about that). This would also help a lot to make Linux consumer-friendly (although that is still mostly about desktop app usability). It just seems so much... cleaner.&lt;br /&gt;&lt;br /&gt;There is more to this - current Linux kernel allows so much cool admin trickery (such as LUFS) I am surprised core OS maintainers are not using it for more.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5053288836813625185-5805395813157678172?l=zero-to-enterprise.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zero-to-enterprise.blogspot.com/feeds/5805395813157678172/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5053288836813625185&amp;postID=5805395813157678172' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5053288836813625185/posts/default/5805395813157678172'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5053288836813625185/posts/default/5805395813157678172'/><link rel='alternate' type='text/html' href='http://zero-to-enterprise.blogspot.com/2008/11/computer-science-approach-to-os-design.html' title='Computer Science Approach to OS Design'/><author><name>Nick</name><uri>http://www.blogger.com/profile/12675339848724787589</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-5053288836813625185.post-4501433178352883485</id><published>2008-10-26T12:45:00.000-07:00</published><updated>2008-10-26T13:24:20.214-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ajax'/><category scheme='http://www.blogger.com/atom/ns#' term='ui'/><category scheme='http://www.blogger.com/atom/ns#' term='jsf'/><title type='text'></title><content type='html'>So I was thinking about enriching/AJAX-ifying my current JSF UI. The data displayed is very complex; the code is getting big and cumbersome, and the size of each page is reaching 100kb. Actions feel very un-responsive and slow, since it takes 2-3 seconds just to download the HTML itself!&lt;br /&gt;&lt;br /&gt;One option is to not even do HTML+JS, and use a Swing-based downloadable client UI. Another is to use partial page replacement and keep existing JSF code. Also, I could just use bare-bones DWR and jQuery.&lt;br /&gt;&lt;br /&gt;Common things to think about are:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;I have a good POJO model of what the UI is managing, and I want to re-use it&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Wherever the POJO model lives, it has to be able to talk to J2EE service beans&lt;/li&gt;&lt;/ul&gt;A Swing UI would let the model live on client-side JVM, and would require an RPC channel to the J2EE side directly. Promises to be clunky...&lt;br /&gt;&lt;br /&gt;I did some quick Googling on DWR and direct JavaScript &lt;-&gt; server-side session POJO interfacing. Looks very cool because of its simplicity. I am comfortable with using jQuery, and its one-liner minimalism could mesh very well with making simple get/set calls to Java model beans. However, as the UI itself gets complex, one-liners get hairy.&lt;br /&gt;&lt;br /&gt;JSF with PPR could be nice and easy to add to existing code. But since it will still generate huge amounts of HTML, I wonder if it will stay just as slow. The only way it wouldn't be the case is if JSF only rendered the affected parts of HTML.&lt;br /&gt;&lt;br /&gt;Something to ponder...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5053288836813625185-4501433178352883485?l=zero-to-enterprise.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zero-to-enterprise.blogspot.com/feeds/4501433178352883485/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5053288836813625185&amp;postID=4501433178352883485' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5053288836813625185/posts/default/4501433178352883485'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5053288836813625185/posts/default/4501433178352883485'/><link rel='alternate' type='text/html' href='http://zero-to-enterprise.blogspot.com/2008/10/so-i-was-thinking-about-enrichingajax.html' title=''/><author><name>Nick</name><uri>http://www.blogger.com/profile/12675339848724787589</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-5053288836813625185.post-3338035020771143844</id><published>2008-10-15T01:50:00.000-07:00</published><updated>2008-10-15T01:58:43.777-07:00</updated><title type='text'>Nano HTTP server</title><content type='html'>A tiny utility that provides a super-minimalist HTTP server, serving up contents of just one file. I mocked it up in Perl a while back, I think it was supposed to provide a WAR file for remote deployment to Tomcat, or some such.&lt;br /&gt;&lt;br /&gt;Not really that great, but may be useful for quick-and-dirty file transfer or for testing HTTP stuff. The source code follows:&lt;br /&gt;&lt;pre&gt;##&lt;br /&gt;#       listens for HTTP connections and, regardless of request,&lt;br /&gt;#       always returns contents of given file, with given content-type&lt;br /&gt;#       header value&lt;br /&gt;#       useful to serve up some test data as though it was from a real&lt;br /&gt;#       HTTP server&lt;br /&gt;##&lt;br /&gt;&lt;br /&gt;use IO::Socket;&lt;br /&gt;&lt;br /&gt;my($port, $file, $contentType) = @ARGV;&lt;br /&gt;&lt;br /&gt;$port = int($port);&lt;br /&gt;&lt;br /&gt;defined $contentType or die &amp;quot;must supply content type&amp;quot;;&lt;br /&gt;&lt;br /&gt;open(FILE, $file) or die &amp;quot;cannot open file&amp;quot;;&lt;br /&gt;local $/ = undef;&lt;br /&gt;my $data = &amp;lt;FILE&amp;gt;;&lt;br /&gt;close(FILE);&lt;br /&gt;&lt;br /&gt;my $socket = new IO::Socket::INET('LocalPort' =&amp;gt; $port, 'Proto' =&amp;gt; 'tcp', 'Listen' =&amp;gt; 1, 'Reuse' =&amp;gt; 1);&lt;br /&gt;$socket or die &amp;quot;cannot create listener socket&amp;quot;;&lt;br /&gt;&lt;br /&gt;while(1)&lt;br /&gt;{&lt;br /&gt;        my $clientSocket = $socket-&amp;gt;accept();&lt;br /&gt;&lt;br /&gt;        # read a token amount of data, just for appearance's sake&lt;br /&gt;        my $buf;&lt;br /&gt;        $clientSocket-&amp;gt;recv($buf, 5);&lt;br /&gt;&lt;br /&gt;        # print our response&lt;br /&gt;        print $clientSocket &amp;quot;HTTP/1.0 200 OK\r\n&amp;quot;;&lt;br /&gt;        print $clientSocket &amp;quot;Content-Type: &amp;quot;, $contentType, &amp;quot;\r\n&amp;quot;;&lt;br /&gt;        print $clientSocket &amp;quot;Content-Length: &amp;quot;, length($data), &amp;quot;\r\n&amp;quot;;&lt;br /&gt;        print $clientSocket &amp;quot;\r\n&amp;quot;;&lt;br /&gt;        print $clientSocket $data;&lt;br /&gt;&lt;br /&gt;        $clientSocket-&amp;gt;close();&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/5053288836813625185-3338035020771143844?l=zero-to-enterprise.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zero-to-enterprise.blogspot.com/feeds/3338035020771143844/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5053288836813625185&amp;postID=3338035020771143844' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5053288836813625185/posts/default/3338035020771143844'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5053288836813625185/posts/default/3338035020771143844'/><link rel='alternate' type='text/html' href='http://zero-to-enterprise.blogspot.com/2008/10/tiny-utility-that-provides-super.html' title='Nano HTTP server'/><author><name>Nick</name><uri>http://www.blogger.com/profile/12675339848724787589</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-5053288836813625185.post-9151575540704804236</id><published>2008-10-14T16:38:00.000-07:00</published><updated>2008-10-14T16:59:36.669-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sparkline'/><category scheme='http://www.blogger.com/atom/ns#' term='unicode'/><category scheme='http://www.blogger.com/atom/ns#' term='php'/><title type='text'>Unicode Sparklines</title><content type='html'>The concept of Sparklines (&lt;a href="http://sparkline.org"&gt;http://sparkline.org&lt;/a&gt; for examples) has been around for a while. I was reminded of it when browsing the Unicode character map the other day, and coming across the "block shapes" characters. There is a set of 8 characters that are essentially vertical bars with heights ranging from 1/8th to full character height. That allows to create crude but image-less quick spark-lines directly in text.&lt;br /&gt;&lt;br /&gt;I mocked up a quick script that pulls stock data from Yahoo! Finance and converts it into a bar-graph using those Unicode characters. My Debian machine's fonts display those codes, so I assume most browsers out there will, too. Here is an example: ▇█▆▄▄▃▂▁. Link: &lt;a href="http://sigmaxis.com/misc/quote-unicode.php"&gt;http://sigmaxis.com/misc/quote-unicode.php&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;By the way, it was pleasantly surprising to see Unicode support for a lot of other "pragmatic" characters, such as ASCII box-drawing, etc. Heh, reminds me of good old DOS pseudo-GUIs and spreadsheets.&lt;br /&gt;&lt;br /&gt;Script source:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&amp;lt;?php&lt;br /&gt;&lt;br /&gt;$ticker = 'JAVA';&lt;br /&gt;&lt;br /&gt;$handle = fopen(&amp;quot;http://ichart.finance.yahoo.com/table.csv?s=$ticker&amp;amp;g=m&amp;quot;, &amp;quot;r&amp;quot;);&lt;br /&gt;$csvdata = fread($handle, 4000);&lt;br /&gt;$lines = explode(&amp;quot;\n&amp;quot;, $csvdata);&lt;br /&gt;fclose($handle);&lt;br /&gt;&lt;br /&gt;$prices = array();&lt;br /&gt;$max = 0;&lt;br /&gt;$min = 1000000;&lt;br /&gt;$skipped = 0;&lt;br /&gt;foreach($lines as $line) {&lt;br /&gt;        if(!$skipped) { $skipped = 1; continue; }&lt;br /&gt;&lt;br /&gt;        $values = explode(&amp;quot;,&amp;quot;, $line);&lt;br /&gt;        $price = $values[4];&lt;br /&gt;&lt;br /&gt;        if($price &amp;gt; $max) { $max = $price; }&lt;br /&gt;        if($price &amp;lt; $min) { $min = $price; }&lt;br /&gt;        $prices[] = $price;&lt;br /&gt;        if(sizeof($prices) &amp;gt;= 8) { break; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;$prices = array_reverse($prices);&lt;br /&gt;&lt;br /&gt;header(&amp;quot;Content-Type: text/html&amp;quot;);&lt;br /&gt;&lt;br /&gt;echo &amp;quot;Monthly closing price for $ticker: &amp;quot;;&lt;br /&gt;echo '&amp;lt;span style=&amp;quot;background: #cdb&amp;quot;&amp;gt;';&lt;br /&gt;&lt;br /&gt;foreach($prices as $price) {&lt;br /&gt;        $adj = intval(1 + 7 * ($price - $min) / ($max - $min));&lt;br /&gt;        echo &amp;quot;&amp;amp;#960$adj;&amp;quot;;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;echo '&amp;lt;/span&amp;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/5053288836813625185-9151575540704804236?l=zero-to-enterprise.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zero-to-enterprise.blogspot.com/feeds/9151575540704804236/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5053288836813625185&amp;postID=9151575540704804236' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5053288836813625185/posts/default/9151575540704804236'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5053288836813625185/posts/default/9151575540704804236'/><link rel='alternate' type='text/html' href='http://zero-to-enterprise.blogspot.com/2008/10/unicode-sparklines.html' title='Unicode Sparklines'/><author><name>Nick</name><uri>http://www.blogger.com/profile/12675339848724787589</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-5053288836813625185.post-8490914037434807699</id><published>2008-10-14T16:31:00.000-07:00</published><updated>2008-10-14T16:37:50.852-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='myfaces'/><category scheme='http://www.blogger.com/atom/ns#' term='jsf'/><title type='text'>JSF MyFaces tree2 Practice</title><content type='html'>I have tried using the MyFaces Tomahawk custom &lt;span style="font-style: italic;"&gt;tree2&lt;/span&gt; component in a UI project of mine. I had to show a hierarchy of beans; in addition, each bean had several list properties which also had to be editable and shown as part of one big heterogeneous tree structure.&lt;br /&gt;&lt;br /&gt;Here are my observations:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;not nearly as simple and quick to get going as JSF sets the standard for&lt;/li&gt;&lt;li&gt;does not seem to work inside the &lt;span style="font-style: italic;"&gt;h:dataTable&lt;/span&gt; element!&lt;/li&gt;&lt;li&gt;out-of-the-box, client-side node expand/collapse state does not react cleanly to tree modifications&lt;/li&gt;&lt;/ul&gt;Bean model implementation took a couple of tries to get decent, since node objects must implement the &lt;span style="font-style: italic;"&gt;TreeNode&lt;/span&gt; interface. The cleanest result was to just roll a usual bean model, implement a &lt;span style="font-style: italic;"&gt;TreeNodeBase&lt;/span&gt; subclass with a generic &lt;span style="font-style: italic;"&gt;Object&lt;/span&gt; "data" field and then have a "getTreeRoot" method on the top-level element that would walk the model and build a corresponding tree of nodes. That way, I could have JSF tags get directly at the original model bean via the "data" field with no extra fuss.&lt;br /&gt;&lt;br /&gt;The alternative included making model beans directly subclass &lt;span style="font-style: italic;"&gt;TreeNodeBase&lt;/span&gt;, but that got messy fast.&lt;br /&gt;&lt;br /&gt;I don't know if someone implemented that already, but I was aching to have a JSF tree component that would not impose a custom tree node interface model. The cleanest implementation would just take an arbitrary root node bean value and then recursively invoke a special "get child nodes" EL expression on it and its children. For example, assume that you have an "Account" model bean class, and it has a "getChildAccounts" method that returns an array or list. Here is what I'd expect the tag to look like:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;&amp;lt;x:myAwesomeTree nodeVar="acct" value="#{blahblah.rootAccount}" children="#{acct.childAccounts}"&lt;/span&gt;&lt;span style="font-family: courier new;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;... usual JSF tags referencing the acct variable ...&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="font-family: courier new;"&gt;/x:myAwesomeTree&lt;/span&gt;&lt;span style="font-family: courier new;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I should mention that I ended up ditching the tree2 tag after all. I just made a special tree-walker method that returns a list of all nodes in my tree structure in traversal order. That list is shown directly as a bunch of &lt;span style="font-style: italic;"&gt;div&lt;/span&gt;s via &lt;span style="font-style: italic;"&gt;t:dataList&lt;/span&gt; tag. Then, each node tells how many ancestors it has, which sets the CSS left-margin attribute. Yep, that's right. Cheap and dirty won the day.&lt;br /&gt;&lt;br /&gt;In fact, even after that I ran into performance and usability issues... I think that I should have made a Swing-based UI delivered via Java WebStart. For my need - a complex, rarely-accessed administrative interface - it fits the bill best. But oh well, that is a task for another day.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5053288836813625185-8490914037434807699?l=zero-to-enterprise.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zero-to-enterprise.blogspot.com/feeds/8490914037434807699/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5053288836813625185&amp;postID=8490914037434807699' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5053288836813625185/posts/default/8490914037434807699'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5053288836813625185/posts/default/8490914037434807699'/><link rel='alternate' type='text/html' href='http://zero-to-enterprise.blogspot.com/2008/10/jsf-myfaces-tree2-practice.html' title='JSF MyFaces tree2 Practice'/><author><name>Nick</name><uri>http://www.blogger.com/profile/12675339848724787589</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></feed>
