Sunday, December 31, 2006

2007 Resolutions

  1. Continue to lose weight. I should get down to my target weight of 185 lbs. this year.
  2. Run a half-marathon. Maybe the SF Marathon this summer?
  3. Pay off college loans. Finally...
  4. Scripting languages. I've dabbled in Groovy, and have written some small webapps with Ruby (and Rails of course.) Time to write something that's actually complex this year.
  5. Organize my documentation. I write a lot of documentation, I can't help it. I need to be more organized with it, though. Documentation (always before coding) really helps me think through my design, but the lack of organization makes it less than useful to others.
  6. Play more chess. I started to play a little this year, but then stopped. I need to hone my skills, since I'll need to teach it to Michael, Jr. pretty soon.
  7. Bike to work. Not everyday, but at least once or twice this year when it's warmer. My big problem with it is not biking to work, but biking back home at the end of the day. I'll just need to bike home before dark one day, or early enough to catch the train.

Favorite CDs of 2006

I mentioned before that the Red Hot Chili Peppers' Stadium Arcadium had to be my favorite CD of the year. I bought it in May, and the two discs have continuously occupied slots #3 and #4 in my car's changer pretty much ever since (after I had ripped the discs with CDex of course.) A lot of people criticize it for being a double-CD. Double-CDs are always a little indulgent, and everyone can always make their personal list of what songs should have been included in an-even-better single CD. Of course usually everyone's list are slightly different. Stadium Arcadium has a ton of really great songs that are more and more rewarding on subsequent listens. That defines a great CD to me. My favorite songs on it are "Especially in Michigan," "Snow (Hey Oh)," "Wet Sand," "Desecration Smile," "Stadium Arcadium," "Tell Me Baby," and yes, "Dani California." Here's my other favorites, in no particular order:

Hip Hop is Dead by Nas -- My favorite CD of 2005 was Kanye West's Late Registration. I wondered if it represented a return of great hip hop CDs. The answer is no. Hip Hop is Dead is a very good CD, but it's pretty much the only really good hip hop CD this year. I kind of like Snoop's new one, too, but it's nothing too special.

The Crane Wife by The Decemberists -- I really liked last year's Picaresque, but The Crane Wife is even better. Much better actually. If it wasn't for the Peppers' opus, this probably would have been my favorite of the year.

St. Elsewhere by Gnarls Barkley -- Yeah there are other songs on here besides "Crazy." None as good, but several very enjoyable ones.

Pearl Jam by Pearl Jam -- Maybe I was biased on this one. This is a very good CD, but I probably like it more just because it's by Pearl Jam and it's their first good CD in awhile. Still, you could make a good case for this being the soundtrack of the political changes in America in 2006.

Taking the Long Way Home by The Dixie Chicks -- What is this, country music on my list? This CD is fun and relaxing at the same time, with several memorable songs. The popular "I'm Not Ready To Make Nice" is a great anthem, but I really love "Lullaby." It makes me think of my two sons. What can I say, I'm getting old.

Boys and Girls in America by The Hold Steady -- This CD rocks. It's great to listen to driving or running. I love the singer's voice.

Friday, December 29, 2006

XML Schema Parsing

You might have heard that XML Schema is dead. I read that, and the article it links to as proof, a couple of weeks ago, and was not overly impressed. Not that I don't agree that RELAX is generally easier, but the proof that "everybody with a choice picks RELAX" just does not cut it as a logical argument. It is a classic appeal-to-authority logical fallacy, where the authority here is the collective unconscious of the technology world.

Recently I had a surprisingly difficult problem to solve. I had an input document that was very simple. It looked like this:

<doc>
<param1>val1</param1>
<param2>val2</param2>
...
</doc>

Then I had metadata that mapped param1 to an XPath for a target document. For example, param1 -> /foo/schmoo/do/wop/dee , etc. I needed to generate an XQuery that would take my input document and produce the target document with the correct values (val1, val2, etc.) inserted into it.

Seems pretty easy. It gets a little harder because this is also possible for the input document:

<doc>
<param1>val1<param1></param1>
<param1>val1a</param1>
<param1>val1b</param1>
...
</doc>

I still have the same XPath for param1, i.e. something like /foo/schmoo/do/wop/dee. Obviously there's some repeating elements in my target document, but where does the repeating occur? From the above information, you could have a target doc like:

<foo>
<schmoo>
<do>
<wop>
<dee>val1</dee>
<dee>val1a</dee>
<dee>val1b</dee>
...

Or:

<foo>
<schmoo>
<do>
<wop>
<dee>val1</dee>
</wop>
<wop>
<dee>val1a</dee>
</wop>
<wop>
<dee>val1b</dee>
</wop>
...

Obviously there are even more possibilities than this, but you get the point. There's no way to be sure. But I was armed with two more bits of information.

First, and this is big, I knew that there could only be one repeating element in a given XPath. Of course this is not true in the abstract, but for my particular problem it was true. So either wop repeated or dee repeated, but not both. Next, I knew the XML Schema of the target document. So I could figure out if it was wop or dee that repeated. That is enough information to create the XQuery.

Now all I had to do was parse the XML Schema for the target document. No problem, right? There are a lot of Java XML Schema parsers out there. I was already using Sun's JAXB Reference Implementation, and it included Sun's XSON XML Schema Parser. So I decided to give that a try.

XSON is a pretty pure implementation of the XML Schema specification. It's objects correspond directly the ones you see in the spec, as do the relationships between these objects. And there's the problem. The spec is very complex. It has the smell of a class "design by committee" spec.

In a design by committee, everybody has their own ideas on how to do things. So the design winds up being "all-inclusive" so that everyone's ideas are present, and nobody gets their feelings hurt. Such all-inclusive designs are complete Frankensteins. XML Schema is definitely a Frankenstein.

My task was really simple. I knew the name of an element from the XPath. I just needed to get the cardinality of this element. First thing first though, I had to parse the schema. This wound up being trickier than I expected. The schema I needed to parse referenced two other schemas. Here's its references:

<xs:include schemalocation="includedSchema.xsd">
<xs:import namespace="urn:my:namespace" schemalocation="importedSchema.xsd">

The schemas were sitting in the same package as the schema I was parsing. I knew that this was going to be an issue, so I wrote a simple EntityResolver that would use a ClassLoader to load these schemas. Only that did not work. My EntityResolver would not get invoked at all. Instead, XSOM would throw an exception complaining about relative URLs being used with no base URL being set.

This was aggravating. If it would only give the EntityResolver chain a chance, then all would be resolved. But no. So I had to change the include and import statements:

<xs:include schemalocation="http://complete.garbage/includedSchema.xsd">
<xs:import namespace="urn:my:namespace" schemalocation="http://complete.garbage/importedSchema.xsd">

Amazingly this worked. Now it invoked the EntityResolver chain, and my custom resolver loaded the referenced schemas. Here's my parsing code:

EntityResolver resolver = new MyCustomResolver();
XSOMParser parser = new XSOMParser();
parser.setEntityResolver(resolver);
// load the initial schema into an InputStream
parser.parse(myInputStream);
XSSchemaSet schemaSet = parser.getResult();
XSSchema mySchema = parser.getSchema("myNamespace");

Now back to finding the cardinality of the element. To find the root element turned out to be very easy:

XSElementDecl rootElement = mySchema.getElementDecl("root_from_xpath");

That's easy. No need to check the cardinality of the root element, as it cannot be greater than one. It turns out that even if I wanted to check it, I could not. Why? Because in XSD, Elements do not have cardinality. Only Particles have cardinality. A Particle can be an Element, but the relationship is not reflexive, i.e an Element cannot be a Particle.

Unless you are already familiar with XSD, you're probably thinking what I thought: WTF!?!? What is the point of this non-reflexivity? Every Element except the root one is in fact a Particle. So by disallowing a symmetric relationship, you've only made sure that you can't get a Particle for the root Element. That's all you've bought. And what have you suffered? Well instead of finding an Element and getting it's Particle to get its cardinality, you must find a Particle that happens to be the Element that you want, and check that Particle's cardinality. It's like you descend to the lowest level of a tree to check some metadata, then go back up a level to get the other metadata that you need. I did find a nice diagram that shows this relationship, though it doesn't make it look as diabolical as it really is:



So back to the problem. As I descend an XPath, I need to find the Particle in the tree representing to the Element whose name corresponds to the name in the XPath. So I need the ComplexType of the current parent Element. Obviously some recursion is needed, so I defined a XSComplexType variable called current to use for the recursion:

XSComplexType current = rootElement.getType().asComplexType(); // initial value

Then at each step in the XPath, I had a string localName that was the element name:

XSContentType content = current.getContentType();
XSParticle particle = this.findParticleForElement(content.asParticle(), localName);
XSElementDecl element = particle.getTerm().asElementDecl();
if (particle.isRepeated()){
return element.getName();
} else {
current = element.getType().asComplexType();
}

The key is the findParticleForElement method:

private XSParticle findParticleForElement(XSParticle particle, String elementName){
XSTerm term = particle.getTerm();
if (term.isElementDecl() &&
term.asElementDecl().getName().equals(elementName)){
return particle;
} else if (term.isModelGroup()){
for (XSParticle p : term.asModelGroup().getChildren()){
XSParticle temp = findParticleForElement(p, elementName);
if (temp != null){
return temp;
}
}
} else if (term.isModelGroupDecl()){
for (XSParticle p : term.asModelGroupDecl().getModelGroup().getChildren()){
XSParticle temp = findParticleForElement(p, elementName);
if (temp != null){
return temp;
}
}
}
return null;
}

You might wonder why the extra recursion in the find method. Well XSD allows for inheritance, and this is what causes the extra recursion. An element can have a ModelGroup as a child, and the children of that ModelGroup can be ModelGroups themselves. So you could have to descend several ModelGroups before finding the target element, just to find a direct child element.

Sunday, December 24, 2006

Favorite Songs of 2006

I was picking songs to listen to on my iPod last night, and thought about my favorite songs of the past year. Here they are, in no particular order:

Supermassive Black Hole -- Muse
Vicarious -- Tool
Crazy -- Gnarls Barkley
Where'd You Go? -- Fort Minor
Out Here All Night -- Damone
Had a Bad Day -- Daniel Powter
Upside Down -- Jack Johnson
Hip Hop is Dead -- Nas
Paralyzed -- Rock Kills Kid
Gold Lion -- Yeah Yeah Yeahs
Think I'm in Love -- Beck
The Joker and The Thief -- Wolfmother
Snow (Hey Oh) -- Red Hot Chili Peppers
Especially in Michigan -- Red Hot Chili Peppers

I could probably list a lot more songs from the Red Hot Chili Peppers' Stadium Arcadium. That was definitely my favorite CD of the year. Maybe I'll make a list of other good CDs later next week.

Saturday, December 23, 2006

Bose Quiet Comfort 3 Headphones

My company bought everybody Bose Quiet Comfort 3 Headphones as holiday gifts. I thought that was a pretty nice gift. I think last year my old employer gave me a flashlight as a holiday gift... I wear headphones a lot, especially while programming. So I was pretty happy about this gift. The thing is, I already had some pretty good headphones.

I've been using Sony MDR-V600 headphones since high school. I remember in 1990, when I was a sophomore in high school, and a friend of mine had just gotten back from his first year at UF. He had his Discman with him and told me "dude you have to hear this." It was Nine Inch Nail's Pretty Hate Machine. It blew me away. What also blew me away was my friend's headphones: Sony MDR-V600's. I knew I had to have both that CD and those headphones. I got the CD a couple of days later, and the headphones the next year ($100 headphones aren't the easiest to come by for a high school kid, especially back in 1990.)

I've been a huge NIN fan ever since, and I had those V600's for eleven years. They were with me on numerous cross country trips from my home in Florida back to Caltech in L.A. By 2002, they were in terrible shape, and my girlfriend bought me a new pair (just a few months before we got married.) I've had those for almost five years now. So I've been a V600 listener for almost sixteen years.

But now I have those fancy Bose headphones. At first, I didn't think they sounded as good as my V600's. I think part of that was because I had been listening to the same headphones for sixteen years. Another reason was because the QC3's needed different equalizer settings the V600's. Again, when you've used the same headphones for sixteen years, you forget about changing the equalizer. For what it's worth, the QC3's needed more treble and less midrange than the V600's. Finally, the QC3's are less sensitive than the V600's. It's a common stereo salesman trick to use the higher sensitivity of a speaker as a way to "prove" the speakers sound better and are worth the extra $$$.

Now I actually think the QC3's sound as good as the V600's. I think the midrange and treble are a little clearer on the QC3's, but the V600's have a little more detail on the low-end. The QC3's are punchy on the low-end, but lack some detail. This is pretty typical of Bose, from what I hear. These are the first Bose products I've owned.

The QC3's are really comfortable and the noise cancellation is excellent. They also seem like they will be more durable. I've gotten a lot of use out of the V600's, but their headbands and ear cushions fall apart pretty easily.

Thursday, December 21, 2006

The End of Computer Viruses

Remember back when the news was filled with stories of some new computer virus or worm that was wreaking havoc with corporate networks and home computers all over the country and world? Remember Melissa, I Love You, Code Red, Slammer, Blaster, and MyDoom? Of course you do, it was only two years ago when "malicious" code and "outbreaks" were in the headlines on a regular basis.

Do those days seem long gone? We really haven't seen any kind of "outbreak" in the last two years. The last worm that got any kind of press was Zotob. One can argue that the only reason it got a lot of press was because it hit CNN's website.

So what's happened? Are people much better at keeping their OS updated with the latest security fixes? Do we all have anti-virus software that is also frequently updated? Those things are probably true. You have to give credit to Microsoft, too. The mighty XP Service Pack 2 (and Server 2003 Service Pack 1) plugged a lot of holes. It turned on firewalls and it annoyed the crap out of you if you didn't have the latest patches and an updated anti-virus program always running.

Vista is even more secure than XP-SP2, with Microsoft finally realizing that having every user as an administrator by default is a flawed strategy. However, is the extra security even needed? Maybe it will provide extra deterrence to spyware, but the age of the computer virus appears to be over.

I'm not just saying this because of the lack of notable outbreaks over the last two years. I recently had coffee with a friend of mine who works for a major security software company. He told me the entire emphasis in the company has switched from viruses to spam. It's not nearly as high-profile. There's not going to be a story on CBS about spam making it into your inbox, but that's where the money is now. The only capitalist conclusion is that viruses are dead. Of course to put my money where my mouth is, I should turn off the antivirus software on my computers...

Wednesday, December 20, 2006

Sharefare Update: Ludi Labs & Roost

Six months ago, I posted that I had left Vitria and was working for a start-up called Sharefare. I couldn't say too much about what we were doing at the time, since we were in classic stealth mode. I've gotten some pings from a couple different folks lately about Sharefare, and there's been a lot going on, so I figured it was a good time for an update.


First, Sharefare changed its name to Ludi Labs (I think this still points to the old Sharefare site, be patient.) Ludi Labs comes from Herman Hesse's The Glass Bead Game. The name change was made official about a month ago, and I even have a fancy business card with the new name.

Update, February 2: The CEO of my company has asked me to temporarily remove the information I had provided in this post. I was quite surprised by this request, since I didn't really think there was anything revealing, but c'est la vie.

Sunday, December 17, 2006

Christmas Shopping @ Circuit City

Saturday I finished up my Christmas shopping. I was researching a certain product and found it very cheap at Circuit City. What was bizarre was that it was $10 cheaper to buy online than at the store. Circuit City offers in-store pickup at no extra cost, so basically I could save $10 by buying it online and picking it up at the store. So that's what I did.

They gave me a confirmation number to use. Of course the Circuit City site suggested I print out the confirmation number, I probably would usually (trees be damned, heh.) But at the time, my wife was in the middle of printing a ton of Christmas stuff. The confirmation number was emailed to my GMail account. So I figured that even if I really needed the number, I would just get it off my GMail via my cell phone. However, I didn't really think I would need the confirmation number.

So I went to Circuit City, where I had to battle crazy Christmas traffic just to find a parking spot. I finally did, and waltzed into the store. There I was greeted with a long line to customer service, and there was a sign indicating that customer service was where I needed to go for "web pickup." Fine. So I waited in the line, and finally got the customer service counter. There the clerk asked me for my confirmation number.

I told him I didn't have it, so he asked for the credit card I used to buy the item online. This was exactly what I expected. I handed him my credit card, but after swiping it he said there was "no hit." He asked for the phone number I had used when I placed the order. I gave him this number, but again "no hit." He then preceded to lecture me on how I should have printed out my confirmation number.

At this point, I brought out my cell phone only to see the dreaded "no service" indicator. How could this be? My phone is through Verizon and Circuit City sells Verizon phones! I've had the phone for a year and I've never lost service on it anywhere in the Bay Area. I've taken it to the east bay, San Francisco, all over the penisula, and of course all over Silicon Valley. Never any problems. I've biked in the hills south of San Jose, up to Calero Reservoir, and never had problems there. But for some reason at Circuit City in South San Jose... no service. The ever-so-helpful then suggests that I go use "the broadband terminal" to retrieve the confirmation number from my email.

I was annoyed to say the least. I see the "broadband terminal" and of course there's a ton of people there. So I went outside, where I had some spotty service, and retrieved the number. Then I stood in line -- again -- and finally met with the same clerk, but this time with confirmation number in hand. Finally I got my purchase.

Amazing how I can pick up eTickets for thousand dollar plane tickets with just the credit card used to purchase the tickets, but this is not good enough at Circuit City. I'm not sure what bothers more -- that this did not work, or that the guy tried to use it and it did not work. I'm not so sure I'll be doing the in-store pickup again at Circuit City anytime soon.

Wednesday, December 13, 2006

Hacking My A950

About a year ago, I switched my wireless service to Verizon and bought a Samsung SCH-A950. It has a lot of nice features, but in typical Verizon fashion, some of these were crippled.

First off, it is a music player, but Verizon made it where it could only play WMA files, not MP3s. I had read that Samsung included an MP3 player, but Verizon just disabled.

Next, while it is a Bluetooth phone, it only supports Headset and Hands-free profiles. In particular, it does not support Dial-up networking. That's a real shame given the EVDO network it can connect to.

I had found this link on enabling MP3 and DUN, but it seemed like too much trouble. But today I cam across this gem. I enabled the "Hidden Menu" by simply punching in 1475369126874#*. From there it was easy to enable MP3 playback. I haven't tried the DUN option yet, since it's not over Bluetooth and thus it's not as interesting to me.

Monday, December 04, 2006

BCS -- The Final Chapter

So it was a good weekend for the Gator Nation. I was surprised to see USC fall, though they've really been pretty shaky at many time this year. I was pleased to see how well Florida played against Arkansas, particularly the Florida defense holding Arkansas to 130 yards total on the ground. I still thought that there was a very good chance that Michigan would get a re-match with Ohio State for the BCS Championship.

Then I saw a lot of people lobbying for Florida on Saturday nigth and in the papers on Sunday morning. I think the thing that held weight for a lot of people was that a team playing for the national title should have won it's conference. A Big 10 vs. SEC championship just made a lot of sense to people, so even though they may not have liked Florida, they moved them up to #2 in the polls. That turned out to be enough, and now Florida will play Ohio State on January 8.

I'll be the first to admit that Florida may not be as good as Michigan. However, I don't think Michigan could do any better the second time against Ohio State than they did the first. It is usually harder to beat a team twice, but Michigan was lucky to be within 3 points at the end of that game. A neutral field would help them, no doubt, but I think Ohio State would have won by double digits. Maybe Florida doesn't have a chance either, but I think their defense will give Ohio State some problems. Ohio State has not played against any team with anywhere near the speed of Florida's. But whatever. Florida deserves a shot at the title more than Michigan, who has already had their chance to beat #1. We all know that a playoff is needed, and now they'll be a lot of people from Michigan behind that idea. The entire SEC has been behind the idea ever since what happened to Auburn a few years ago.