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 &lt;?&gt; 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