Sunday, June 13, 2010

JSOG - JavaScript Object Graph

So I had a project where I was creating a user preferences service. Because the environment in which the preferences service was to be operating is so chaotic (lots of changes are expected), I decided to use JSON as a way to store the user preferences. The service is a glorified document database, if you will.

Now, working with JavaScript objects and arrays in JavaScript is pretty easy. There's a lot of implicit coercion taking place, it's a dynamic language after all. That doesn't translate to Java very well, however. I looked at JSON-lib, FlexJSON, Jackson, and the json.org library. None of them provided the functionality I was looking for. I want to easily navigate a JSON object graph, and manipulate the values within.

Let's look at my particular use case for example. I had a JSON object for a user. Within that JSON object, I basically had the following: (Formatted for readability)


{
"services": {
"xyz": {
// XYZ specific preferences
}
}
}


Except since things are so chaotic, I don't know if the "services" node exists, or if "xyz" exists.

I'll demonstrate with Jackson here, but the process is basically the same for the other libraries I looked at.



In this example, we create the object from scratch:

ObjectNode prefs = nf.objectNode();

ObjectNode services = nf.objectNode();
prefs.put("services", services);

ObjectNode xyz = nf.objectNode();
services.put("xyz", xyz);

xyz.put("foo", "bar");


What does that same code look like in JSOG?

JSOG jsog = JSOG.createObjectNode();
jsog
.get("services")
.get("xyz")
.put("foo", "bar");


A little more straight forward, but Jackson wasn't that bad. What about a more complex example?



Instead of creating everything from scratch, what if we need to parse the existing preferences and add a value? If the JSON object doesn't contain "services", or "xyz" (which we're not sure of), we need to create those nodes.

Let's parse a string, empty in this case, and build up the same object, and add a value to "xyz" called "baz" with value 42.

Here's what you're facing with Jackson:

ObjectMapper om = new ObjectMapper();
JsonNodeFactory nf = om.getNodeFactory();

// Parse the JSON string
JsonNode json = om.readTree("");

// Get or create the prefs container object
ObjectNode prefs;
if (json.isObject()) {
prefs = (ObjectNode) json;
} else {
prefs = nf.objectNode();
json = prefs;
}

// Get or create the services object
JsonNode servicesNode = prefs.path("services");
ObjectNode services;
if (servicesNode.isObject()) {
services = (ObjectNode) servicesNode;
} else {
services = nf.objectNode();
prefs.put("services", services);
}

// Get or create the xyz object
JsonNode xyzNode = services.path("xyz");
ObjectNode xyz;
if (xyzNode.isObject()) {
xyz = (ObjectNode) xyzNode;
} else {
xyz = nf.objectNode();
prefs.put("xyz", xyz);
}

// Set the value
xyz.put("baz", 42);


And here's JSOG doing the same thing:

JSOG jsog = JSOG.parse("");
jsog
.get("services")
.get("xyz")
.put("baz", 42);


Now we're talking! JSOG pulls off in 5 clean, clear, concise lines of code what took Jackson 38 LOC to do. JSOG does the implicit object creation or coercion for you, and to make things even easier, you get builder-style syntax!

I want to point out that I'm not picking on Jackson here, this is a failing of all the libraries I looked at. I think Jackson is actually one of the easier libraries to use, which is why I chose to use it for JSOG's serialization and deserialization.

JSOG is Unlicensed. I've committed it to the public domain. I would love to see JSOG or an equivalent find it's way into each JSON library.

Visit the JSOG site, hosted on SourceForge.net and give it a whirl. I suspect people working with CouchDB will *really* appreciate JSOG.

Wednesday, April 14, 2010

Basic Motorcycle Safety

So I've been going through the work to get a motorcycle, and I was reviewing the Hurt Report findings. I'd recommend going over them yourself, but here's the short-short version for my own reference and yours:
  • Cornering and intersections are deadly.
  • At intersections, expect oncoming traffic to turn in front of you.
  • Under/overbraking are common in the moments preceding an accident - get a bike with ABS/practice emergency stop drills.
  • Be as conspicuous as possible. Orange, yellow, and red colored clothing, helmets, and bike colors are a Good Thing. Keep your headlights on.
  • Wear a full face or modular helmet. Leathers will help you keep your skin where it belongs.
  • Take a motorcycle safety class.
  • Pay attention!
These basic rules cover such an overwhelming percentage of accidents, and they're so simple to follow. Unless you're trying to give your organs away, follow them.

Monday, March 8, 2010

Shooting with the Lensbaby Composer

The following two images are shot using the Lensbaby Composer. They were taken at the Phoenix Art Museum on the March First Friday.







These are using my 18-105mm lens, on the same night.


Thursday, January 21, 2010

Ubuntu's NetworkManager is Flaky

The debate rages on as to what component is actually causing the problem: NetworkManager, wpa_supplicant, drivers, or something else. But the problem is clear: Frequent disconnects, particularly in an environment where multiple access points provide access over a single SSID.

Either way, replacing NetworkManager with wicd resolves the problem.


sudo apt-get install wicd


After you've done that, wicd-client will start in your tray on the next login.

If you want, you can also configure it through the wicd-curses interface. One oddity, though, is that the curses interface is case-sensitive.