Friday, March 29, 2013

A DIV and AngularJS Based Dropdown List Box


I have been doing research into using AngularJS.  One of the first things I needed for my website was some nice fancy dropdown list boxes.  Of course I did not want to use regular old <select>, what would be the fun in that.  So I set out to build one using DIVs and AngularJS.  This little demo shows the results of my research.

Download Source Code:


Below the demo is running in an IFRAME. It may not display the best. If you want you can visit the full page demo at

Monday, March 11, 2013

JAXB Unmarshalling To a Sorted Map


While using JAXB for my last project, I came across the need to access a list of data in two ways.  First, the data was to be accessed as a sorted list with the sort order being determined by the /Book[@SortOrder] attribute. Second, the data was to be access as a map, supplying a key value from /Book[@Id] to get a specific book by key. With these two requirements, a LinkedHashMap object is clearly the way to go. Book objects are added to the LinkedHashMap in /Book[@SortOrder] order and /Book[@Id] is the map key. My initial thought was to let JAXB unmarshal the XML into a regular List then as a post processing step I would reorder the list and create a map.  But the more I thought about this the more I didn't like this solution.  Since JAXB is doing the work of unmarshalling the XML, I figured JAXB should be able to put it into a LinkedHashMap like I wanted. The purpose of this article is to demonstrate how to get JAXB to create a LinkedHashMap for you so you can access a list of data in both by key and as a correctly sorted list.


 Let's first consider a simple XML document to demonstrate what's needed.  Below is sample XML document representing search results for books. The list of books has a [@SortOrder] and an [@Id].  The application will need to be able to display the books in the correct sort order but also be able to lookup books quickly by id.
        <Book Id="794N-98" SortOrder="5">
            <Title>Open to the Sky</Title>
        <Book Id="998X-78" SortOrder="2">
            <Title>Mars, Friend or Foe?</Title>
        <Book Id="445M-09" SortOrder="3">
            <Title>Jumping Beans Jump</Title>
        <Book Id="002I-11" SortOrder="1">
            <Title>Little Worms Go To School</Title>
        <Book Id="951G-42" SortOrder="4">
            <Title>America, The Early Years</Title>

The Classes

In order to get JAXB to create a LinkedHashMap for you automatically, you will need need the following classes, with the BooksAdapter class one really doing all of the work for you:

Unmarshalled object for the <SearchResults> tag
public class SearchResults 
	private Map<String, Book> books;
	public Map<String, Book> getBooksMap() {
		return books;
	public List<Book> getBooksList() {
		return new ArrayList<Book>(books.values());

Unmarshalled object for the <Books> tag. This is initially needed by JAXB to convert all of the <Book>  elements into a list.  This class is then later used by BooksAdapter to convert it into a LinkedHashMap.
public class Books 
	private List<Book> books;
	public List<Book> getBooks() {
		return books;
	public void setBooks(List<Book> books) {
		this.books = books;

Unmarshalled object for the <Book> tag
public class Book 
	private Integer sortOrder;
	public Integer getSortOrder() {
		return sortOrder;

	private String id;
	public String getId() {
		return id;
	private String title;
	public String getTitle() {
		return title;

An XmlAdapter implementation which converts the Books object into a LinkedHashMap object where the Book objects are put into the map by key /Book[@Id] and in the order specified by /Book[@SortOrder]. 
public class BooksAdapter extends XmlAdapter<Books, Map<String, Book>> {
	public Map<String, Book> unmarshal(Books books) throws Exception {
		Collections.sort(books.getBooks(), new BookComparatorBySortOrder());
		Map<String, Book> map = new LinkedHashMap<String,Book>();
        for (Book book : books.getBooks()) {
            map.put(book.getId(), book);
        return map;

	public Books marshal(Map<String, Book> map) throws Exception {
		Books books = new Books();
		books.setBooks(new LinkedList<Book>(map.values()));
		return books;

class BookComparatorBySortOrder implements Comparator<Book> {
	public int compare(Book o1, Book o2) {
		return o1.getSortOrder().compareTo(o2.getSortOrder());



Testing this is pretty easy, just supply the XML document and have JAXB do it's thing. Here is a unit test: 

public class SearchResultsTest 
	private SearchResults searchResults; 
	public void before() throws Exception 
		// Read file from classpath
		String filename = "/SearchResults.xml";
    	InputStream istream = getClass().getResourceAsStream(filename);
    	assertNotNull(String.format("Cannot find classpath resource \"%s\"", filename), istream);
    	// Prepare JAXB objects
		JAXBContext jc = JAXBContext.newInstance(SearchResults.class);
		Unmarshaller u = jc.createUnmarshaller();

		// Prepare the input
		InputSource isource = new InputSource(istream);

		// Do unmarshalling
		searchResults = (SearchResults)u.unmarshal(isource);
        assertNotNull(String.format("Unmarshal returned null for SearchResults object"), searchResults);
        istream = null;
	public void testBookFindById() 
		Map<String, Book> books = searchResults.getBooksMap();
		assertEquals(5, books.size());
		assertEquals("Little Worms Go To School",books.get("002I-11").getTitle());
		assertEquals("Mars, Friend or Foe?", 	 books.get("998X-78").getTitle());
		assertEquals("Jumpping Beans Jump", 	 books.get("445M-09").getTitle());
		assertEquals("America, The Early Years", books.get("951G-42").getTitle());
		assertEquals("Open to the Sky", 		 books.get("794N-98").getTitle());	
	public void testBookSorted() 
		List<Book> books = searchResults.getBooksList();
		assertEquals(5, books.size());
		assertEquals(new Integer(1), books.get(0).getSortOrder());
		assertEquals(new Integer(2), books.get(1).getSortOrder());
		assertEquals(new Integer(3), books.get(2).getSortOrder());
		assertEquals(new Integer(4), books.get(3).getSortOrder());
		assertEquals(new Integer(5), books.get(4).getSortOrder());		



You can download a Maven project of this from sourceforge: