19 October 2006

XSL FTW!

Just got a new project at work. We need to interface to another company's information system, and they want us to use web services. OK, cool, I'm all about the SOA (or will be once I do a little research), let's see what they've got. Interface specs, XML-RPC, all looks good until I get to the sample data they're sending. All their data is expressed as XML attributes. I know there's no hard consensus on elements vs. attributes, but I personally hold to the idea that attributes are for meta-data, and data itself should be in elements. I tried to ignore it, but it kept bugging me. I know that for the project I'm on, I'll just wind up working with what they give me, and suck it up. But I deperately wanted to convert it. Hey, it should be easy with XSL, right? Well, I suppose if you actually knew XSL, it probably would be. It took me a couple of hours to figure out the proper incantations of selectors and elements to get it done, but finally I did. And just on the off chance there's some other attribute-hater out there, here it is (sorry about the formatting!):

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

<xsl:template match="*">
<xsl:variable name="tagName" select="name()"/>
<xsl:element name="{$tagName}">
<xsl:text>
</xsl:text>
<xsl:for-each select="@*">
<xsl:variable name="tagName" select="name()"/>
<xsl:element name="{$tagName}"><xsl:value-of select="."/></xsl:element>
<xsl:text>
</xsl:text>
</xsl:for-each>
<xsl:apply-templates/>
</xsl:element>
</xsl:template>

<xsl:template match="@*|processing-instruction()|comment()">
<xsl:copy>
<xsl:apply-templates
select="@*|node()|processing-instruction()|comment()"/>
</xsl:copy>
</xsl:template>

</xsl:stylesheet>

Invoke it with Xalan (or your XSLT processor of choice). I use the command "java org.apache.xalan.xslt.Process -in stuff.xml -xsl cvtAttrs.xsl" (where the script is in 'cvtAttrs.xsl', of course).

Share and enjoy!

24 July 2006

Hybrid Opinion

Well, just hit a new high in the Honda: 53.7 MPG over 550 miles. These were all in-town miles, average speed was probably somewhere around 30-35. Not bad, all things considered. For some reason, my mileage always seems to improve in the summer. I assume it's got something to do with "summer blend" gas, either more or less ethanol, I don't know. I do know that I'm hard-pressed to break 47 during the winter.

Random thoughts on the hybrid debate:

I've been seeing a fair amount of commentary on how economical hybrids are, with a lot of people opining that you'll never make back the "premium" you pay to buy a hybrid. I've read analyses that show that it takes longer to recoup the additional money spent to buy a hybrid than that average driver owns a car. That the published numbers don't reflect the actual mileage you'll get. Well, that just doesn't seem to be the case, at least here at Chez Random (which has a three-car garage).

First, the hybrid wasn't really more expensive than the non-hybrid. Yes, it was more expensive than a base-model Civic, but it also comes with a lot of features you didn't get on the base model: anti-lock brakes, side-impact air bags, and an AM/FM/CD radio with subwoofer are the ones that jump immediately to mind. Add it all up, and you're close to the starting price for the high-end model. One thing I have to mention, though, is that you really don't have any choice on the hybrid options: I think the only choices I had were the color, whether I wanted a CD changer in the trunk and whether I wanted splash guards. No sunroof, no electric seats, no leather interior, nada. Oh, I did get some nifty mag wheels, but only because they're a special lightweight alloy that contributed to the gas mileage. Anyway, the point is, the price was right in line for a similarly-configured gas-only model, so I don't think I paid any more for the car (certainly not after the hybrid-purchase tax rebates, which totalled a cool couple thousand).

And mileage not making the published figures? Um, frankly I can't remember what the advertised mileage was on the Civic, but I doubt it was much over 50 (I seem to recall that the Insight, Honda's cramped two-seat serious hybrid, gets about 60, so I'm sure the 4-seat, 4-door Civic gets less than that). And that's about what I'm getting, so there's no problem there. I do know that when I gas up, it's considerably cheaper than filling either of the other two cars (which can break $50 with today's prices). Of course, a big part of that is the Civic's tank size (about twelve gallons), which is about two-thirds the size of the tanks in the other cars. But if I drive either of the other two daily, I wind up filling them about once a week. I fill they Honda maybe once a month, and then it's more of an inconvenience than a trial.

I am a bit worried about resale value. The battery pack is supposed to last for about eight years, and cost around $3000 to replace (2004 prices). So if I sell it after seven years, I expect the price drop to be considerable. Hopefully, this won't be a problem, since I tend to keep cars for awhile (my other car is an '87), and I bought the extended warranty expressly because it will cover the battery pack replacement. But if for some reason I do have to sell it, then that may be an issue. Or not, depending on how much the battery packs cost by then. I will be surprised if they haven't come up with an idea or two on making it more economical, but I also won't be surprised if the gummint hasn't slapped some kind of disposal or recycling fee on the new packs. If worst comes to worst, I hear that the pack is really just a couple hundred rechargable D batteries, maybe I'll just fire up the ol' soldering iron and fix it myself! Of course, a couple hundred rechargable D batteries will cost a bit, maybe I should start collecting them now...

27 June 2006

Party like it's 1972!

Dick Nixon's in the White House, inflation's threatening to go double-digit, and you've got a deadline on that payroll-processing code. You head to the office, sit down at your VT-100 (no more VT-52, w00t!) and log in to the development PDP-11. In a few seconds you're staring at the familiar command prompt of V7 Unix...

How can you relive those thrilling days of yesteryear? Can't help with the White House or the economy, but I can put you in the driver's seat of your own V7 Unix machine running on a simulated PDP-11.

First, get a copy of the SIMH simulator from Trailing Edge Technologies. Under "Software Kits to run on SIMH", grab the PDP-11 Unix V7 file. Extract the files to the same directory you loaded the simulators into.

Once you've got everything loaded, fire up the PDP-11 simulator and enter the following commands:

sim> set cpu u18
sim> set rl0 RL02
sim> at rl0 unix_v7_rl.dsk
sim> set rl1 RL02
sim> at rl1 unix_r1_diska.dsk
RL creating new file
Create bad block table on last track? [N]
sim> boot rl0
@boot
New Boot, known devices are hp ht rk rl rp rm vt
: rl(0,0)rl2unix
mem = 177856
#

And there you are! PDP-11 Unix V7 in single-user mode. Creating additional terminals and bringing the system up in multi-user mode is left as an exercise for the reader.

I realize this information is probably only interesting to old Unix geeks, but I wanted to put it out there because I had to do a lot of digging to find out how to make this work. I've used V[67] Unix, but I've never had to boot it, and I've certainly never had to configure a PDP-11 before. I figure a lot of people are in a similar situation, and hopefully this information will help someone.

Now, all I need to do is get VMS up and running on the simulated VAX and I'll be a happy camper! Although this emulator seems to emulate the speed of the old hardware as well, so I may not be terribly happy with the result...

02 May 2006

Le plus ca change...

Quick update: left the State, took up with FACTS Management , now doing "data integration". Basically I'm in charge of making sure clients (schools) can seamlessly connect to our systems and we can share data with them. Right now I'm attempting to install Oracle 10gR2 on a scavenged box (dual 3Ghz Xeons w/2.5G) that I've put Solaris 10 on. "Standing up in a canoe", as the joke goes.

It's a good company, and getting better (they were just purchased by Nelnet). And it's soooo much nicer than working for the State. No offense, Staties, but the private sector has bigger and better toys. I'm currently on a three-month contract-to-hire, but just this morning my boss asked if I was happy, and when I indicated I was he said he was going to see about converting me early. Nelnet has some good benefits, so things may get even better. Have to see, have to see....

07 March 2006

Suck-a-doodle doo

<whine>Had to do a complete reinstall of Solaris which wiped out my user partition and I lost all my stored email, my resume and web site</whine>

Now that I've got that off my chest, I just wanted to share a very interesting idea I ran across today. It's a post on Dave Thomas' blog (now a wiki entry) talking about practicing. Practice seems to be more of a, well, a practice with people who have vocations requiring physicals skills (musicians, athletes, etc.). But shouldn't programmers practice too? Dave says yes, and after reading what he has to say, I'm inclined to agree. Especially for those of us who aren't in "agile" shops, and who perhaps spend two months designing, six weeks coding and two months testing. After spending the last couple of years honing my skills with design patterns, UML and other high-level concerns, Dave's katas have brought me "back down to earth", with their focus on the basics: what is the best data structure to use, how do I decide what's the best algorithm for this situation, is it better to write some code or just invoke a system utility?

Maybe it's just me (stuck in the middle of the "two months of testing" leg of the cycle), but thinking about these aspects of system design really brought home the essence of development: deliver a system that solves someone's problem(s). Not that I haven't been doing that, but lately I've been more focused on delivering solutions using "industry best practices" than I have with actually solving the problem. I'll defend myself by saying that the design artifacts are, on my current project, a deliverable, and so I spent a large amount of time making sure that I followed The Process. But in the end, it's the solution that matters, and I wonder if I might not have been led, perhaps by hype, somewhat astray.

23 February 2006

Solaris upgrades

Well, the blush is off the rose, Solaris-wise. I have spent the last couple of nights whacking my Ultra 20 with a blunt installer, to little effect. First, I installed the Ultra 20 1.2 supplemental update (updates the BIOS and installed new drivers for the built-in hardware). That went all right, but when I rebooted I couldn't get the network interface working. I quickly figured out it was something with DNS (I could ping my router and print server just fine, but anything not in /etc/hosts was unreachable). So after a couple of hours tweaking this and poking that and whacking the other, I found out that Solaris doesn't like the DNS server that RoadRunner provides. It's there, and my wife's Windows box doesn't seem to have a problem with it, but Solaris won't talk to it. Fortunately, I have an alternate public DNS server configured, but unfortunately Solaris won't use it. For some reason, it thinks that the RR server sends it a valid 'domain not found' response. Once it gets a response from a server, it uses that server for all further requests. I finally used nslookup(1) to query my alternate name server, and then Solaris started to use it. Chalk up two hours to "learning experience".

Last night, glutton for punishment that I am, I installed the new Solaris Update utility. It analyzed my system, then ran off to Sun to find out what I needed. 57 patches! So I let it download them all and install what it could. Then it said I needed to reboot to install the rest. Since I'd already blown my uptime (148 days), I didn't think it was any big deal. So I reboot, and the box says it's in system maintenance mode and starts installing patches. It installs a bunch, then seems to just sit there. It looks like all the patches have been successfully installed, so I go ahead and reboot. When the system comes back up, it's a lot different: it's now using the Grub boot loader, and no longer shows the boot messages as it comes up. It also tells me that it can't initialize nge0 (the network interface), which I'm not looking forward to digging into again. Then, it tells me to wait while the X server starts, followed in a few seconds by the notice that the X server cannot be started. Not Good. I've got a job application to fill out, and my email to check, I really can't be wasting hours sorting out some system misconfiguration issue. So I scarf the wife's laptop and go trolling for clues. While dredging through the Sun "Miscellaneous hardware" forum (where all the workstation issues go), I find a mention of a Yahoo! newsgroup dedicated to x86 Solaris. So I hie myself over there, and lo and behold, someone else has reported this same issue! Unfortunately, there was no resolution posted, but someone did point out there was a utility (kdmconfig) that would allow you to switch to the Sun X server (Solaris 10 uses the X.org server by default). I did that, and was able to get X up (albeit at 1024x768 instead of the 1600x1200 I favor). So I got back into the patch tool and backed out the two patches that looked most likely to be responsible. When I rebooted, the Sun X server started, so I went in and set the default back to the X.org server. Which then failed to start again. I checked the log file, and it seems to indicate that the nVidia driver (I am using an NVS280 card) was found and initialized itself, but it can't find or initialize the graphics card. So I switched back to the Sun server and resolved to call Sun Support.

07 February 2006

Hack of the day

Well, this hasn't happened in a while. I had an idea, wrote it up in vi, then compiled and ran it, and it compiled cleanly and worked the first time! Obviously it's a trivial example, but it's kind of neat, so I thought I'd share.

Background: On my current project, we have some boilerplate logging code that has to go into every method. It looks something like this:
logEvent("Module", ErrorConstants.EVENT_START, "Method name");
I got a comment on a code review that I should be defining string constants for my module and method names, since string constants should never be directly used in code (yes, that's the kind of shop we have here...)

The idea: I had had another idea regarding allocation tracing, and I remember that (since Java 1.4) you could get access to the call stack via a Throwable. A quick glance at the JavaDocs showed that you can get both the class and method names from the stack trace. This led to the quick&dirty code shown here:


private String getMethodName() {
Throwable t = new Throwable();
StackTraceElement[] ste = t.getStackTrace();

String methodName = ste[1].getMethodName();

return methodName;
}

private String getModuleName() {
Throwable t = new Throwable();
StackTraceElement[] ste = t.getStackTrace();

String moduleName = ste[1].getClassName();

return moduleName;
}


Quick & dirty == no JavaDoc or comments. Could be worse, I could have written it all on one line!

Denoumont: "Warning: may contain code which is too intense for young programmers". Turns our my solution (replacing all hard-coded strings with dynamic code to obtain the module and method names) was too...something for my team. They never really said what, just that they didn't think it was a good idea. This is a CMM Level 5 crew, and they don't really accept outside ideas well. Oh well, it'll go into my bag of tricks, and I'm sure I'll find a use for it on another project.

06 February 2006

Parse error: brain halted

My daughter got me the other day. We were poking around in the library downstairs, and she found a shelf of books that we had picked up at the Lincoln Public Library's annual shelf-clearing sale. They were all books that looked nice, but that we thought she wasn't old enough for yet (ratio of pictures to text wasn't high enough). Anyway, she picked up a copy of Curious George Rides a Bike. I read her the title, and she asked, "Daddy, what's curious mean?"

My brain vapor-locked for a second.

Then I explained, and we read the book, and she enjoyed it. So then we spent the next half-hour or so reviewing the books on the "not-yet" shelf and picked out several to take upstairs to put in her library.

23 January 2006

On the road again...

Well, what an enchanting winter it's been! Took a trip out to LA (cold, rainy, not at all as advertised), then out to Philadelpha for Thanksgiving with Fran's family. Then a quick trip out to Pueblo to see my folks as my Dad had, not emergency, but certainly short-notice heart surgery (he had a cardio stress test, and they stopped him about ten minutes into it and had him go straight up to pre-op). So, we were pretty much travelled out come Christmas, so we spent it quietly at home. I did the traditional stay-up-late-assembling-toys Dad thing (since Fran had done the traditional go-all-out-buying-toys-for-the-only-child thing), which was cool.

My big post-holiday buzz has been getting the 944 back on the road again. It had been languishing in the garage with a stuck (down, of course) drivers side window, and I was going to fix it in my Copious Free Time (SM). Then Fran's car developed an oil leak. Turned out to be gaskets that I didn't have the tools, time or shop manuals to fix. So, we bundled it off to the Audi dealer in Omaha. We took it in on a Saturday and couldn't pick it up until the following Monday, which meant that Fran would have to take the Honda to work and I would have to get the Porsche running. So I spent Sunday evening tearing the door apart and fixing the window (turned out to be a bad window switch) and charging the battery and installing the car seat for Gabrielle. She loves it (she gets to sit in the front seat), and I get to drive like I mean it again.