Skip to content

XHTML Builder Example

UnquietCode edited this page May 13, 2012 · 14 revisions

Builders are well suited for working with nested operations, and Flapi provides for this with its concept of blocks. Let's build a descriptor which can be used to generate an XML document. In Java this uses the w3c Document and Element classes primarily.

The descriptor:

	DescriptorGenerator.create(new DescriptorHelperImpl())
		.setPackage("unquietcode.tools.flapi.examples.xhtml.builder")
		.setStartingMethodName("createDocument")
		.setDescriptorName("XHTML")
		.setReturnType(Document.class)

		.addMethod("addComment(String comment)").any()
		.addMethod("done()").last()

		.startBlock("Element", "startElement(String tagName)").any()
			.addMethod("setValue(String value)").once()
			.addMethod("addAttribute(String key, String value)").any()
			.addMethod("addComment(String comment)").any()
			.addMethod("endElement()").last()
			.addBlockReference("Element", "startElement(String tagName)").any()
		.endBlock()
	.build()

We have one block, called Element. Each element can have any number of elements inside of it, just as in XML. We can provide text values of the element once, any number of attributes, and any number of comments.

Implementing the XHTMLHelper isn't so bad in this case, because our actions more or less mirror what we would call on the normal objects.

	final Document document;

	public XHTMLHelperImpl() {
		try {
			document = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
		} catch (Exception ex) {
			throw new RuntimeException(ex);
		}
	}

	@Override
	public Document _getReturnValue() {
		return document;
	}

	@Override
	public void done() {
		// nothing
	}

	@Override
	public void startElement(String tagName, ObjectWrapper<ElementHelper> _helper1) {
		Element element = document.createElement(tagName);
		document.appendChild(element);
		_helper1.set(new ElementHelperImpl(element));
	}


	@Override
	public void addComment(String comment) {
		document.appendChild(document.createComment(comment));
	}

Here, a sample usage building an XML representation of a book library:

	Document doc = XHTMLGenerator.createDocument(new XHTMLHelperImpl())
		.addComment("This is a list of books in my library.")
		.startElement("books")
			.startElement("book")
				.addAttribute("ISBN", "978-0375703768")
				.setValue("House of Leaves")
			.endElement()
			.startElement("book")
				.addAttribute("ISBN", "978-0399533457")
				.setValue("The Cloudspotter's Guide:")
			.endElement()
		.endElement()
	.done();

Which corresponds to the following output:

<!--This is a list of books in my library.-->
<books>
    <book ISBN="978-0375703768">House of Leaves</book>
    <book ISBN="978-0399533457">The Cloudspotter's Guide:</book>
</books>

Clone this wiki locally