Friday, March 27, 2009

JAXB xjc & maven2

I'm a fan of the Metro Web Services products (JAX-WS and JAXB). Not a fanboy, but a fan. I am a fanboy of maven though, and if you're not you just suck. Its the sauce that makes the world go round. That said, more often than not when using an xml to java compiler you don't have a need to have it automated. An ant task would suffice. And there are a bunch of great resources out there on that. But sometimes you want/need new classes based on an ever changed xml schema. WOOT MAVEN!

So first you'll need the plugin. Unfortunately as of now its not in a maven repo (which I think is mostly due to the minimal need for maven automation), but you can download the plugin here and add it to your local repo or local/companies repository.

Now you need some stchuff in your pom.
<plugin>
<groupId>com.sun.tools.xjc.maven2</groupId>
<artifactId>maven-jaxb-plugin</artifactId>
<version>1.1</version>
<executions>
   <execution>
       <goals>
           <goal>generate</goal>
       </goals>
   </execution>
</executions>
<configuration>
   <generatePackage>com.noviidesign.xjcexample</generatePackage>
   <includeSchemas>
       <includeSchema>**/*.xsd</includeSchema>
   </includeSchemas>
   <includeBindings>
       <includeBinding>*.xjb</includeBinding>
   </includeBindings>
   <strict>true</strict>
   <verbose>true</verbose>
   <removeOldOutput>true</removeOldOutput>
</configuration>
</plugin>
This will remove your old classes and creating code whenever you run a maven goal.

Now when you run this you should have your *.xsd schema in your /resources folder (for a webapp). I also have an *.xjb file in the plugin configuration above. First, lets look at what an xsd schema would look like that'd need the xjb file.
<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.noviidesign.com/xjcexample/train" xmlns:tns="http://www.noviidesign.com/xjcexample/train" elementFormDefault="qualified">
 <element name="train" type="tns:train" />
 <complexType name="train">
  <sequence>
   <element name="car" type="tns:car" minOccurs="1" maxOccurs="unbounded" />
  </sequence>
  <attribute type="string" name="name" use="required" />
  <attribute type="string" name="id" use="required" />
  <attribute type="string" name="color" use="required" />
 </complexType>
 <complexType name="car">
  <attribute type="string" name="name" use="required" />
  <attribute type="string" name="id" use="required" />
  <attribute type="string" name="maxPassengers" use="required" />
 </complexType>
</schema>
Now this schema is just for example purposes but should get the point across. If needed you can find more information than you could care about on xml schemas on le internet. So, now when the classes are created you'll have the following
package com.noviidesign.xjcexample;

import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlType;

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "train", propOrder = {"car"} )
public class Train {

 @XmlElement(required = true)
 protected List car;
 @XmlAttribute(required = true)
 protected String color;
 @XmlAttribute(required = true)
 protected String id;
 @XmlAttribute(required = true)
 protected String name;
 
 public List getCar() {
  if (car == null) {
   car = new ArrayList();
  }
  return this.car;
 }
 
 public String getColor() {
  return color;
 }
 
 public void setColor(String value) {
  this.color = value;
 }
 
 public String getId() {
  return id;
 }
 
 public void setId(String value) {
  this.id = value;
 }
 
 public String getName() {
  return name;
 }
 
 public void setName(String value) {
  this.name = value;
 }
}

package com.noviidesign.xjcexample;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlType;

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "car")

public class Car {

 @XmlAttribute(required = true)
 protected String id;
 @XmlAttribute(required = true)
 protected String maxPassengers;
 @XmlAttribute(required = true)
 protected String name;
 
 public String getId() {
  return id;
 }
 
 public void setId(String value) {
  this.id = value;
 }
 
 public String getMaxPassengers() {
  return maxPassengers;
 }
 public void setMaxPassengers(String value) {
  this.maxPassengers = value;
 }
 
 public String getName() {
  return name;
 }
 
 public void setName(String value) {
  this.name = value;
 }
}
So nothing mind blowing, just some regular ol' classes w/some xml annotation. But what I don't like is in Train.java we have protected List car; and subsequently public List getCar(); I'd much rather have List cars; and public List getCars(); And this is where our *.xjb file comes in. It'd look as follows
<jaxb:bindings xmlns:xsd="http://www.w3.org/2001/XMLSchema"
 xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
 version="1.0">
 <jaxb:bindings schemaLocation="train.xsd" node="//xsd:element[@name='car']">
  <jaxb:property name="cars" />
 </jaxb:bindings>
</jaxb:bindings>
And thats really it. Now again you'd usually do this with an ant task, but if you have a need for maven hopefully this will help get you going in the right direction.

In a bit I'll cover how to read in xml into your classes you created.

Thursday, March 26, 2009

Regi's American Bistro

So it was my birfday earlier this week and Rani wanted to take me out to dinner. Fat kid won't object. Where to go? I was feeling kind of beat from work so I decided to keep it local, we'd hit up Thai Arroy which has arguable the best Thai food this side of the mississippi. Or something. Anyway, we walked there to find it closed. Damn Mondays and their closings. So we'll settle for some pretty decent Mexican food from Blue Agave. Also closed on Mondays.

So by this point I'm getting annoyed at our luck (or should I have taken a hint?). So I say "I've always wanted to try Regi's" to which I was told "I've been there and it was terrible". Well, being the smart one I is I decided "mneh, might as well try" and being my birthday, Rani didn't object. Unfortunately.

So, we got seated at their outside but enclosed by some plastic tent thingy and heated with heaters thing area. It was kinda cool actually. So we got the lobster mac & cheese and crab dip. I never did find any lobster in the mac and cheese but it had chunks of tomato in it and was pretty good (or maybe I was just starving). The crab dip was so-so. For the main course we got the turkey and brie sandwhich and a special that had arctic char in it. The turkey brie sandwhich was pretty lame, but the arctic char was alright. It had a cucumber and vinigar salad bed which was tastie taste.

And then came dessert. I don't know if I was more annoyed at the dessert or our waiter. We were there for maybe and hour and a half and saw him three or so times. MAN. I needs me some more water, but he's no where to be found. And we had to hunt him down after we paid to find our leftovers (not because they were that good but because they meant free lunch for the next day). And then there was the dessert. Red velvet cake. It had some cream cheese frosting. And tasted like a twinkie. Thats immediately what I thought when I took a bite. This tastes like a twinkie...except I remember liking twinkies as a kid...and I don't like this. After about four bites between us it was abandoned.

Regi's...I may be back. What? Yeah well, IF it were a nice day out and IF I wanted to sit outside and IF I wanted to have a few drinks while doing so and IF I maybe also wanted an assumable mediocre salad while I did it...then yeah, I might go back. So I guess I'll probably never be back because there are other places around that I could do that at that wouldn't suck.

Friday, March 20, 2009

8,600 reasons to not buy an HP Printer

I'll make this short and sweet.  I'm the 'computer guy' in the family and my sisters laptop is running slow.  So here I am doing my best Karen Carpenter impression (with the help of the o so slick Revo Unistaller) and I get to HP - Shop for Supplies.  Sometimes you find stuff such as TeaTime.exe (a process of Spybot) and you're like 'wtf mate' and bust out the Goog.  Well, being the astute nerd that I is I know that there is no reason that some hp related shopping thing needs to be installed.  So I kills it.  After the uninstall (byfar the best reason to use Revo) it tells me there are over 8600 leftover windows registry items.  Are you serious?!?  There is no reason for 1 to be on the machine let alone 8600.  Now there is sloppy programming.  And there is bad programming.  And then there is programming that I can only assume would be done to see how terrible you could make something.  I think this falls into the latter.

Take a step back.  Anyone who's seen an HP printer or any device for that matter has seen how bloated and bumtarded their software is.  Why do I need 17 different applications installed?  Why do they all need to search for updates?  But I've learned to make concessions in life.  But 8600 registry items for something that'll just say "OH SNAP YOUR OUTTA INK.  Go to hp.com and get more."  Jerks.