1 package com.github.javaparser.metamodel; 2 3 import com.github.javaparser.ast.Node; 4 5 import java.util.ArrayList; 6 import java.util.List; 7 import java.util.Optional; 8 9 import static com.github.javaparser.utils.Utils.decapitalize; 10 11 /** 12 * Meta-data about all classes in the AST. These are all Nodes, except NodeList. 13 */ 14 public abstract class BaseNodeMetaModel { 15 private final Optional<BaseNodeMetaModel> superNodeMetaModel; 16 private final List<PropertyMetaModel> declaredPropertyMetaModels = new ArrayList<>(); 17 private final List<PropertyMetaModel> derivedPropertyMetaModels = new ArrayList<>(); 18 private final List<PropertyMetaModel> constructorParameters = new ArrayList<>(); 19 private final Class<? extends Node> type; 20 private final String name; 21 private final String packageName; 22 private final boolean isAbstract; 23 private final boolean hasWildcard; 24 BaseNodeMetaModel(Optional<BaseNodeMetaModel> superNodeMetaModel, Class<? extends Node> type, String name, String packageName, boolean isAbstract, boolean hasWildcard)25 public BaseNodeMetaModel(Optional<BaseNodeMetaModel> superNodeMetaModel, Class<? extends Node> type, String name, String packageName, boolean isAbstract, boolean hasWildcard) { 26 this.superNodeMetaModel = superNodeMetaModel; 27 this.type = type; 28 this.name = name; 29 this.packageName = packageName; 30 this.isAbstract = isAbstract; 31 this.hasWildcard = hasWildcard; 32 } 33 34 /** 35 * @return is this the meta model for this node class? 36 */ is(Class<? extends Node> c)37 public boolean is(Class<? extends Node> c) { 38 return type.equals(c); 39 } 40 41 /** 42 * @return package name + class name 43 */ getQualifiedClassName()44 public String getQualifiedClassName() { 45 return packageName + "." + name; 46 } 47 48 /** 49 * @return the meta model for the node that this node extends. Note that this is to be used to find properties 50 * defined in superclasses of a Node. 51 */ getSuperNodeMetaModel()52 public Optional<BaseNodeMetaModel> getSuperNodeMetaModel() { 53 return superNodeMetaModel; 54 } 55 56 /** 57 * @return a list of all properties declared directly in this node (not its parent nodes.) These are also available 58 * as fields. 59 */ getDeclaredPropertyMetaModels()60 public List<PropertyMetaModel> getDeclaredPropertyMetaModels() { 61 return declaredPropertyMetaModels; 62 } 63 getDerivedPropertyMetaModels()64 public List<PropertyMetaModel> getDerivedPropertyMetaModels() { 65 return derivedPropertyMetaModels; 66 } 67 68 /** 69 * @return a list of all properties that describe the parameters to the all-fields (but not "range" and "comment") 70 * constructor, in the order of appearance in the constructor parameter list. 71 */ getConstructorParameters()72 public List<PropertyMetaModel> getConstructorParameters() { 73 return constructorParameters; 74 } 75 76 /** 77 * @return a list of all properties in this node and its parents. Note that a new list is created every time this 78 * method is called. 79 */ getAllPropertyMetaModels()80 public List<PropertyMetaModel> getAllPropertyMetaModels() { 81 List<PropertyMetaModel> allPropertyMetaModels = new ArrayList<>(getDeclaredPropertyMetaModels()); 82 BaseNodeMetaModel walkNode = this; 83 while (walkNode.getSuperNodeMetaModel().isPresent()) { 84 walkNode = walkNode.getSuperNodeMetaModel().get(); 85 allPropertyMetaModels.addAll(walkNode.getDeclaredPropertyMetaModels()); 86 } 87 return allPropertyMetaModels; 88 } 89 isInstanceOfMetaModel(BaseNodeMetaModel baseMetaModel)90 public boolean isInstanceOfMetaModel(BaseNodeMetaModel baseMetaModel) { 91 if (this == baseMetaModel) { 92 return true; 93 } 94 if (isRootNode()) { 95 return false; 96 } 97 return getSuperNodeMetaModel().get().isInstanceOfMetaModel(baseMetaModel); 98 } 99 100 /** 101 * @return the class for this AST node type. 102 */ getType()103 public Class<? extends Node> getType() { 104 return type; 105 } 106 107 /** 108 * @return the package containing this AST node class. 109 */ getPackageName()110 public String getPackageName() { 111 return packageName; 112 } 113 114 /** 115 * @return whether this AST node is abstract. 116 */ isAbstract()117 public boolean isAbstract() { 118 return isAbstract; 119 } 120 121 /** 122 * @return whether this AST node has a <?> at the end of its type. 123 */ hasWildcard()124 public boolean hasWildcard() { 125 return hasWildcard; 126 } 127 128 /** 129 * @return whether this AST node is the root node, meaning that it is the meta model for "Node": "NodeMetaModel". 130 */ isRootNode()131 public boolean isRootNode() { 132 return !superNodeMetaModel.isPresent(); 133 } 134 135 @Override equals(Object o)136 public boolean equals(Object o) { 137 if (this == o) return true; 138 if (o == null || getClass() != o.getClass()) return false; 139 140 BaseNodeMetaModel classMetaModel = (BaseNodeMetaModel) o; 141 142 if (!type.equals(classMetaModel.type)) return false; 143 144 return true; 145 } 146 147 @Override hashCode()148 public int hashCode() { 149 return type.hashCode(); 150 } 151 152 @Override toString()153 public String toString() { 154 return name; 155 } 156 157 /** 158 * @return the type name, with generics. 159 */ getTypeNameGenerified()160 public String getTypeNameGenerified() { 161 if (hasWildcard) { 162 return getTypeName() + "<?>"; 163 } 164 return getTypeName(); 165 } 166 167 /** 168 * @return the raw type name, so nothing but the name. 169 */ getTypeName()170 public String getTypeName() { 171 return type.getSimpleName(); 172 } 173 174 /** 175 * The name of the field in JavaParserMetaModel for this node meta model. 176 */ getMetaModelFieldName()177 public String getMetaModelFieldName() { 178 return decapitalize(getClass().getSimpleName()); 179 } 180 } 181