Home | History | Annotate | Download | only in printer
      1 package com.github.javaparser.printer;
      2 
      3 import com.github.javaparser.ast.Node;
      4 import com.github.javaparser.ast.NodeList;
      5 import com.github.javaparser.metamodel.NodeMetaModel;
      6 import com.github.javaparser.metamodel.PropertyMetaModel;
      7 
      8 import java.util.ArrayList;
      9 import java.util.List;
     10 import java.util.stream.Collectors;
     11 
     12 import static com.github.javaparser.utils.Utils.assertNotNull;
     13 import static java.util.stream.Collectors.toList;
     14 
     15 /**
     16  * Outputs a JSON file containing the AST meant for inspecting it.
     17  */
     18 public class JsonPrinter {
     19     private final boolean outputNodeType;
     20 
     21     public JsonPrinter(boolean outputNodeType) {
     22         this.outputNodeType = outputNodeType;
     23     }
     24 
     25     public String output(Node node) {
     26         return output(node, null, 0);
     27     }
     28 
     29     public String output(Node node, String name, int level) {
     30         assertNotNull(node);
     31         NodeMetaModel metaModel = node.getMetaModel();
     32         List<PropertyMetaModel> allPropertyMetaModels = metaModel.getAllPropertyMetaModels();
     33         List<PropertyMetaModel> attributes = allPropertyMetaModels.stream().filter(PropertyMetaModel::isAttribute).filter(PropertyMetaModel::isSingular).collect(toList());
     34         List<PropertyMetaModel> subNodes = allPropertyMetaModels.stream().filter(PropertyMetaModel::isNode).filter(PropertyMetaModel::isSingular).collect(toList());
     35         List<PropertyMetaModel> subLists = allPropertyMetaModels.stream().filter(PropertyMetaModel::isNodeList).collect(toList());
     36 
     37         final List<String> content = new ArrayList<>();
     38 
     39         if (outputNodeType) {
     40             content.add(q("type") + ":" + q(metaModel.getTypeName()));
     41         }
     42 
     43         for (PropertyMetaModel attributeMetaModel : attributes) {
     44             content.add(q(attributeMetaModel.getName()) + ":" + q(attributeMetaModel.getValue(node).toString()));
     45         }
     46 
     47         for (PropertyMetaModel subNodeMetaModel : subNodes) {
     48             Node value = (Node) subNodeMetaModel.getValue(node);
     49             if (value != null) {
     50                 content.add(output(value, subNodeMetaModel.getName(), level + 1));
     51             }
     52         }
     53 
     54         for (PropertyMetaModel subListMetaModel : subLists) {
     55             NodeList<? extends Node> subList = (NodeList<? extends Node>) subListMetaModel.getValue(node);
     56             if (subList != null && !subList.isEmpty()) {
     57                 final List<String> listContent = new ArrayList<>();
     58                 for (Node subListNode : subList) {
     59                     listContent.add(output(subListNode, null, level + 1));
     60                 }
     61                 content.add(listContent.stream().collect(Collectors.joining(",", q(subListMetaModel.getName()) + ":[", "]")));
     62             }
     63         }
     64 
     65         if (name == null) {
     66             return content.stream().collect(Collectors.joining(",", "{", "}"));
     67         }
     68         return content.stream().collect(Collectors.joining(",", q(name) + ":{", "}"));
     69     }
     70 
     71     private static String q(String value) {
     72         return "\"" + value.replace("\"", "\\\"").replace("\n", "\\n").replace("\r", "\\r") + "\"";
     73     }
     74 }
     75