miercuri, 22 iulie 2015

Use OmniFaces Tree to render JSON

Let's suppose that we have the following JSON representation:

And we want to render this JSON as a tree hierarchy. For this we can use:

- Jackson JSON Processor and Google Collections for parsing and processing the JSON
- OmniFaces Tree component to render the result

The JSF page can be:

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://xmlns.jcp.org/jsf/html"
      xmlns:o="http://omnifaces.org/ui">
 <h:head>
  <title></title>               
 </h:head>
 <h:body>                                    
  <h:panelGroup id="jsonTree">           
   <h:form id="form">              
    <o:tree value="#{treeBean.tree}" var="t" varNode="node">
     <o:treeNode>
      <ul>
       <o:treeNodeItem>
        <li>                                                 
         #{t}                               
         <o:treeInsertChildren />   
        </li>
       </o:treeNodeItem>
      </ul>
     </o:treeNode>                   
    </o:tree>
   </h:form>
  </h:panelGroup>           
 </h:body>
</html>

And the TreeBean is:

@Named
@ViewScoped
public class TreeBean implements Serializable {

 private static final long serialVersionUID = 1L;
 private static final String example = "{ JSON }";
 private TreeModel<String> tree;

 @PostConstruct
 public void init() {

  tree = new ListTreeModel<>();

  ObjectMapper mapper = new ObjectMapper();
  try {
      JsonNode jsonNode = mapper.readTree(example);
      walker(null, jsonNode, tree);
  } catch (IOException ex) {
      Logger.getLogger(TreeBean.class.getName()).log(Level.SEVERE, null, ex);
  }
 }

 private void walker(String name, JsonNode node, TreeModel<String> tree) {

  if (node.isObject()) {
      Iterator<Map.Entry<String, JsonNode>> iterator = node.fields();
      ArrayList<Map.Entry<String, JsonNode>> nodesList = Lists.newArrayList(iterator);
      for (Map.Entry<String, JsonNode> nodEntry : nodesList) {
           String nameName = nodEntry.getKey();
           JsonNode newNode = nodEntry.getValue();
           if (newNode.isObject()) {
               walker(null, newNode, tree.addChild(nameName));
           } else if (newNode.isValueNode()) {
               tree.addChild(nameName + ":" + newNode.asText());
           } else {
               walker(nameName, newNode, tree);
           }
      }
  } else if (node.isArray()) {
             TreeModel<String> treea = tree.addChild(name);
             Iterator<JsonNode> arrayItemsIterator = node.elements();
             ArrayList<JsonNode> arrayItemsList =   
             Lists.newArrayList(arrayItemsIterator);
             for (JsonNode arrayNode : arrayItemsList) {
                  walker(null, arrayNode, treea);
             }
  } else {
      if (node.isValueNode()) {
          tree.addChild(node.asText());
      } else {
          tree.addChild("OTHER_TYPE");
      }
  }
 }

 public TreeModel<String> getTree() {
  return tree;
 }

}

The rendered output will be:


The complete code is available on GitHub.

You may be also interested in:
Expose a path as an OmniFaces tree (<o:tree>)
Building dynamic responsive multi-level menus with plain HTML and OmniFaces by Oleg Varaksin

Niciun comentariu:

Trimiteți un comentariu