Home | History | Annotate | Download | only in observer
      1 /*
      2  * Copyright (C) 2007-2010 Jlio Vilmar Gesser.
      3  * Copyright (C) 2011, 2013-2016 The JavaParser Team.
      4  *
      5  * This file is part of JavaParser.
      6  *
      7  * JavaParser can be used either under the terms of
      8  * a) the GNU Lesser General Public License as published by
      9  *     the Free Software Foundation, either version 3 of the License, or
     10  *     (at your option) any later version.
     11  * b) the terms of the Apache License
     12  *
     13  * You should have received a copy of both licenses in LICENCE.LGPL and
     14  * LICENCE.APACHE. Please refer to those files for details.
     15  *
     16  * JavaParser is distributed in the hope that it will be useful,
     17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     19  * GNU Lesser General Public License for more details.
     20  */
     21 package com.github.javaparser.ast.observer;
     22 
     23 import com.github.javaparser.ast.Node;
     24 import com.github.javaparser.ast.NodeList;
     25 import com.github.javaparser.utils.Utils;
     26 import java.lang.reflect.InvocationTargetException;
     27 import java.util.Collection;
     28 import java.util.Optional;
     29 import java.util.Arrays;
     30 import javax.annotation.Generated;
     31 
     32 /**
     33  * Properties considered by the AstObserver
     34  */
     35 @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
     36 public enum ObservableProperty {
     37 
     38     ANNOTATIONS(Type.MULTIPLE_REFERENCE),
     39     ANONYMOUS_CLASS_BODY(Type.MULTIPLE_REFERENCE),
     40     ARGUMENTS(Type.MULTIPLE_REFERENCE),
     41     ASTERISK(Type.SINGLE_ATTRIBUTE),
     42     BODY(Type.SINGLE_REFERENCE),
     43     CATCH_CLAUSES(Type.MULTIPLE_REFERENCE),
     44     CHECK(Type.SINGLE_REFERENCE),
     45     CLASS_BODY(Type.MULTIPLE_REFERENCE),
     46     CLASS_DECLARATION(Type.SINGLE_REFERENCE),
     47     CLASS_EXPR(Type.SINGLE_REFERENCE),
     48     COMMENT(Type.SINGLE_REFERENCE),
     49     COMPARE(Type.SINGLE_REFERENCE),
     50     COMPONENT_TYPE(Type.SINGLE_REFERENCE),
     51     CONDITION(Type.SINGLE_REFERENCE),
     52     CONTENT(Type.SINGLE_ATTRIBUTE),
     53     DEFAULT_VALUE(Type.SINGLE_REFERENCE),
     54     DIMENSION(Type.SINGLE_REFERENCE),
     55     ELEMENTS(Type.MULTIPLE_REFERENCE),
     56     ELEMENT_TYPE(Type.SINGLE_REFERENCE),
     57     ELSE_EXPR(Type.SINGLE_REFERENCE),
     58     ELSE_STMT(Type.SINGLE_REFERENCE),
     59     ENCLOSING_PARAMETERS(Type.SINGLE_ATTRIBUTE),
     60     ENTRIES(Type.MULTIPLE_REFERENCE),
     61     EXPRESSION(Type.SINGLE_REFERENCE),
     62     EXTENDED_TYPE(Type.SINGLE_REFERENCE),
     63     EXTENDED_TYPES(Type.MULTIPLE_REFERENCE),
     64     FINALLY_BLOCK(Type.SINGLE_REFERENCE),
     65     IDENTIFIER(Type.SINGLE_ATTRIBUTE),
     66     IMPLEMENTED_TYPES(Type.MULTIPLE_REFERENCE),
     67     IMPORTS(Type.MULTIPLE_REFERENCE),
     68     INDEX(Type.SINGLE_REFERENCE),
     69     INITIALIZATION(Type.MULTIPLE_REFERENCE),
     70     INITIALIZER(Type.SINGLE_REFERENCE),
     71     INNER(Type.SINGLE_REFERENCE),
     72     INTERFACE(Type.SINGLE_ATTRIBUTE),
     73     ITERABLE(Type.SINGLE_REFERENCE),
     74     LABEL(Type.SINGLE_REFERENCE),
     75     LEFT(Type.SINGLE_REFERENCE),
     76     LEVELS(Type.MULTIPLE_REFERENCE),
     77     MEMBERS(Type.MULTIPLE_REFERENCE),
     78     MEMBER_VALUE(Type.SINGLE_REFERENCE),
     79     MESSAGE(Type.SINGLE_REFERENCE),
     80     MODIFIERS(Type.MULTIPLE_ATTRIBUTE),
     81     MODULE(Type.SINGLE_REFERENCE),
     82     MODULE_NAMES(Type.MULTIPLE_REFERENCE),
     83     MODULE_STMTS(Type.MULTIPLE_REFERENCE),
     84     NAME(Type.SINGLE_REFERENCE),
     85     OPEN(Type.SINGLE_ATTRIBUTE),
     86     OPERATOR(Type.SINGLE_ATTRIBUTE),
     87     ORIGIN(Type.SINGLE_ATTRIBUTE),
     88     PACKAGE_DECLARATION(Type.SINGLE_REFERENCE),
     89     PAIRS(Type.MULTIPLE_REFERENCE),
     90     PARAMETER(Type.SINGLE_REFERENCE),
     91     PARAMETERS(Type.MULTIPLE_REFERENCE),
     92     QUALIFIER(Type.SINGLE_REFERENCE),
     93     RECEIVER_PARAMETER(Type.SINGLE_REFERENCE),
     94     RESOURCES(Type.MULTIPLE_REFERENCE),
     95     RIGHT(Type.SINGLE_REFERENCE),
     96     SCOPE(Type.SINGLE_REFERENCE),
     97     SELECTOR(Type.SINGLE_REFERENCE),
     98     STATEMENT(Type.SINGLE_REFERENCE),
     99     STATEMENTS(Type.MULTIPLE_REFERENCE),
    100     STATIC(Type.SINGLE_ATTRIBUTE),
    101     SUPER_TYPE(Type.SINGLE_REFERENCE),
    102     TARGET(Type.SINGLE_REFERENCE),
    103     THEN_EXPR(Type.SINGLE_REFERENCE),
    104     THEN_STMT(Type.SINGLE_REFERENCE),
    105     THIS(Type.SINGLE_ATTRIBUTE),
    106     THROWN_EXCEPTIONS(Type.MULTIPLE_REFERENCE),
    107     TRY_BLOCK(Type.SINGLE_REFERENCE),
    108     TYPE(Type.SINGLE_REFERENCE),
    109     TYPES(Type.MULTIPLE_REFERENCE),
    110     TYPE_ARGUMENTS(Type.MULTIPLE_REFERENCE),
    111     TYPE_BOUND(Type.MULTIPLE_REFERENCE),
    112     TYPE_PARAMETERS(Type.MULTIPLE_REFERENCE),
    113     UPDATE(Type.MULTIPLE_REFERENCE),
    114     VALUE(Type.SINGLE_REFERENCE),
    115     VALUES(Type.MULTIPLE_REFERENCE),
    116     VARIABLE(Type.SINGLE_REFERENCE),
    117     VARIABLES(Type.MULTIPLE_REFERENCE),
    118     VAR_ARGS(Type.SINGLE_ATTRIBUTE),
    119     VAR_ARGS_ANNOTATIONS(Type.MULTIPLE_REFERENCE),
    120     WITH_TYPES(Type.MULTIPLE_REFERENCE),
    121     CASCADING_IF_STMT(Type.SINGLE_ATTRIBUTE, true),
    122     ELSE_BLOCK(Type.SINGLE_ATTRIBUTE, true),
    123     ELSE_BRANCH(Type.SINGLE_ATTRIBUTE, true),
    124     EXPRESSION_BODY(Type.SINGLE_REFERENCE, true),
    125     MAXIMUM_COMMON_TYPE(Type.SINGLE_REFERENCE, true),
    126     POSTFIX(Type.SINGLE_ATTRIBUTE, true),
    127     PREFIX(Type.SINGLE_ATTRIBUTE, true),
    128     THEN_BLOCK(Type.SINGLE_ATTRIBUTE, true),
    129     USING_DIAMOND_OPERATOR(Type.SINGLE_ATTRIBUTE, true),
    130     RANGE,
    131     COMMENTED_NODE;
    132 
    133     enum Type {
    134 
    135         SINGLE_ATTRIBUTE(false, false), SINGLE_REFERENCE(false, true), MULTIPLE_ATTRIBUTE(true, false), MULTIPLE_REFERENCE(true, true);
    136 
    137         private boolean multiple;
    138 
    139         private boolean node;
    140 
    141         Type(boolean multiple, boolean node) {
    142             this.multiple = multiple;
    143             this.node = node;
    144         }
    145     }
    146 
    147     private Type type;
    148 
    149     private boolean derived;
    150 
    151     public static ObservableProperty fromCamelCaseName(String camelCaseName) {
    152         Optional<ObservableProperty> observableProperty = Arrays.stream(values()).filter(v -> v.camelCaseName().equals(camelCaseName)).findFirst();
    153         if (observableProperty.isPresent()) {
    154             return observableProperty.get();
    155         } else {
    156             throw new IllegalArgumentException("No property found with the given camel case name: " + camelCaseName);
    157         }
    158     }
    159 
    160     ObservableProperty(Type type) {
    161         this.type = type;
    162         this.derived = false;
    163     }
    164 
    165     ObservableProperty(Type type, boolean derived) {
    166         this.type = type;
    167         this.derived = derived;
    168     }
    169 
    170     ObservableProperty() {
    171         this(Type.SINGLE_REFERENCE, false);
    172     }
    173 
    174     public boolean isDerived() {
    175         return derived;
    176     }
    177 
    178     public boolean isAboutNodes() {
    179         return type.node;
    180     }
    181 
    182     public boolean isAboutValues() {
    183         return !isAboutNodes();
    184     }
    185 
    186     public boolean isMultiple() {
    187         return type.multiple;
    188     }
    189 
    190     public boolean isSingle() {
    191         return !isMultiple();
    192     }
    193 
    194     public String camelCaseName() {
    195         return Utils.screamingToCamelCase(name());
    196     }
    197 
    198     public Node getValueAsSingleReference(Node node) {
    199         Object rawValue = getRawValue(node);
    200         try {
    201             if (rawValue instanceof Node) {
    202                 return (Node) rawValue;
    203             } else if (rawValue instanceof Optional) {
    204                 Optional<Node> opt = (Optional<Node>) rawValue;
    205                 if (opt.isPresent()) {
    206                     return opt.get();
    207                 } else {
    208                     return null;
    209                 }
    210             } else {
    211                 throw new RuntimeException(String.format("Property %s returned %s (%s)", this.name(), rawValue.toString(), rawValue.getClass().getCanonicalName()));
    212             }
    213         } catch (ClassCastException e) {
    214             throw new RuntimeException(e);
    215         }
    216     }
    217 
    218     private boolean hasMethod(Node node, String name) {
    219         try {
    220             node.getClass().getMethod(name);
    221             return true;
    222         } catch (NoSuchMethodException e) {
    223             return false;
    224         }
    225     }
    226 
    227     public NodeList<? extends Node> getValueAsMultipleReference(Node node) {
    228         Object rawValue = getRawValue(node);
    229         try {
    230             if (rawValue == null) {
    231                 return null;
    232             }
    233             if (rawValue instanceof NodeList) {
    234                 return (NodeList) rawValue;
    235             } else {
    236                 Optional<NodeList> opt = (Optional<NodeList>) rawValue;
    237                 if (opt.isPresent()) {
    238                     return opt.get();
    239                 } else {
    240                     return null;
    241                 }
    242             }
    243         } catch (ClassCastException e) {
    244             throw new RuntimeException("Unable to get list value for " + this.name() + " from " + node + " (class: " + node.getClass().getSimpleName() + ")", e);
    245         }
    246     }
    247 
    248     public Collection<?> getValueAsCollection(Node node) {
    249         Object rawValue = getRawValue(node);
    250         try {
    251             return (Collection) rawValue;
    252         } catch (ClassCastException e) {
    253             throw new RuntimeException("Unable to get list value for " + this.name() + " from " + node + " (class: " + node.getClass().getSimpleName() + ")", e);
    254         }
    255     }
    256 
    257     public String getValueAsStringAttribute(Node node) {
    258         return (String) getRawValue(node);
    259     }
    260 
    261     public Boolean getValueAsBooleanAttribute(Node node) {
    262         return (Boolean) getRawValue(node);
    263     }
    264 
    265     public Object getRawValue(Node node) {
    266         String getterName = "get" + Utils.capitalize(camelCaseName());
    267         if (!hasMethod(node, getterName)) {
    268             getterName = "is" + Utils.capitalize(camelCaseName());
    269             if (!hasMethod(node, getterName)) {
    270                 getterName = "has" + Utils.capitalize(camelCaseName());
    271             }
    272         }
    273         try {
    274             return node.getClass().getMethod(getterName).invoke(node);
    275         } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
    276             throw new RuntimeException("Unable to get value for " + this.name() + " from " + node + " (" + node.getClass().getSimpleName() + ")", e);
    277         }
    278     }
    279 
    280     public boolean isNull(Node node) {
    281         return null == getRawValue(node);
    282     }
    283 
    284     public boolean isNullOrNotPresent(Node node) {
    285         Object result = getRawValue(node);
    286         if (result == null) {
    287             return true;
    288         }
    289         if (result instanceof Optional) {
    290             return !((Optional) result).isPresent();
    291         }
    292         return false;
    293     }
    294 
    295     public boolean isNullOrEmpty(Node node) {
    296         return Utils.valueIsNullOrEmpty(getRawValue(node));
    297     }
    298 }
    299