Wednesday, October 27, 2010

Jsonix - JAXB for JavaScript

Folowing up on the ideas from my previous posts, I've started the project called Jsonix (JSON interfaces for XML):

http://confluence.highsource.org/display/MISC/Jsonix

Jsonix is basically a JAXB analog for JavaScript. With Jsonix you can:
  • parse XML into JSON;
  • serialize JSON into XML;
  • define XML/JSON mappings declaratively;
  • generate Jsonix mappings from XML Schemas.

Here's a small example of how a JSON purchase order could be marshalled in XML:

var context = Jsonix.Context.newInstance([ PO ]);
// Marshal JSON as XML (DOM node)
var unmarshaller = context.createUnmarshaller();

var node = marshaller.marshal({
name: {localPart: "purchaseOrder"},
value: {
shipTo: {
name: "Alice Smith",
street: "123 Maple Street",
city: "Mill Valley",
state: "CA",
zip: 90952
}
}
});


This will produce an XML like:
<purchaseOrder orderDate="1999-10-20">
<shipTo country="US">
<name>Alice Smith</name>
<street>123 Maple Street</street>
<city>Mill Valley</city>
<state>CA</state>
<zip>90952</zip>
</shipTo>
<!-- ... -->
</purchaseOrder>


And here's how you'd unmarshal:

// Unmarshal JSON from XML (retrieved from an URL)
var unmarshaller = context.createUnmarshaller();
unmarshaller.unmarshal({
url : "po.xml",
success : function(po) {
assertEquals("purchaseOrder", po.name.localPart);
assertEquals("Alice Smith", po.value.shipTo.name);
}
});


The project is in development, I'll be working on it next weeks.

Saturday, October 16, 2010

Generating JavaScript Code with JavaScript Code Model

JavaScript Code Model (JSCM for short) is a Java library which precisely models JavaScript grammar as defined in ECMAScript specification. JSCM allows you to programmatically create, analyze and manipulate JavaScript code.

This post demonstrates usage of JSCM to generate JavaScript code from a Java program.

Here's a code snippet which creates a factorial function:

// Instantiate the code model
JSCodeModel codeModel = new CodeModelImpl();
// Create the program
JSProgram program = codeModel.program();
// Add a function declaration
JSFunctionDeclaration factorial = program
.functionDeclaration("factorial");
// Add a function parameter
JSVariable x = factorial.parameter("x");
// Create an integer literal
JSDecimalIntegerLiteral one = codeModel.integer(1);
// Add a return statement to the function body
factorial.getBody()._return(
x.le(one).cond(
one,
x.mul(factorial.getFunctionExpression().i()
.args(x.minus(one)))));

// Write the program code to the System.out
new CodeWriter(System.out).program(program);

This produces the following JavaScript code:

function factorial(x) {
return x <= 1 ? 1 : x * factorial(x - 1); }


In this example we first produce the code model by creating expressions, statements, function declarations and so on and then use code writer to serialize the created program into the System.out. This process almost guarantees that the resulting code is syntactically and grammatically correct - and well-formatted as well. And I hope the API is very convenient - especially if you compare it to the "good old" string concatenation.

In the future I'll also provide a parser which parses JavaScript code and builds its model. It will then be possible to analyze existing JavaScript code and manipulate it - for instance add profiling statements, reformat, restructure, refactor, optimize or obfuscate.

JavaScript Code Model 1.0 released

Last few weeks I've been working on the JavaScript code model, the idea I describe in my previous post.

Now it is ready and released. Here's the project page in my Confluence and a generated Maven Site.

Now I can go on with my idea of JAXB analog for JavaScript. My plans are:
  • Write a JAXB plugin which would generate XML bindings for JavaScript objects in form of JSON. This is analogous to JAXB annotations.
  • Write JavaScript runtime to parse (unmarshal) JSON objects from XML or serialize (marshal) these objects back to XML. This is analogous to JAXBContext.
In the next post I'll give an example of how JSCM can be used to generate JavaScript code.