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