1 /* 2 * Copyright (C) 2007-2010 Júlio 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.expr; 22 23 import com.github.javaparser.TokenRange; 24 import com.github.javaparser.ast.AllFieldsConstructor; 25 import com.github.javaparser.ast.Node; 26 import com.github.javaparser.ast.nodeTypes.NodeWithIdentifier; 27 import com.github.javaparser.ast.observer.ObservableProperty; 28 import com.github.javaparser.ast.visitor.GenericVisitor; 29 import com.github.javaparser.ast.visitor.VoidVisitor; 30 import com.github.javaparser.metamodel.JavaParserMetaModel; 31 import com.github.javaparser.metamodel.NameMetaModel; 32 import com.github.javaparser.metamodel.NonEmptyProperty; 33 import com.github.javaparser.metamodel.OptionalProperty; 34 import java.util.Optional; 35 import static com.github.javaparser.utils.Utils.assertNonEmpty; 36 import com.github.javaparser.ast.visitor.CloneVisitor; 37 import com.github.javaparser.ast.Generated; 38 39 /** 40 * A name that may consist of multiple identifiers. 41 * In other words: it.may.contain.dots. 42 * <p> 43 * The rightmost identifier is "identifier", 44 * The one to the left of it is "qualifier.identifier", etc. 45 * <p> 46 * You can construct one from a String with the name(...) method. 47 * 48 * @author Julio Vilmar Gesser 49 * @see SimpleName 50 */ 51 public class Name extends Node implements NodeWithIdentifier<Name> { 52 53 @NonEmptyProperty 54 private String identifier; 55 56 @OptionalProperty 57 private Name qualifier; 58 Name()59 public Name() { 60 this(null, null, "empty"); 61 } 62 Name(final String identifier)63 public Name(final String identifier) { 64 this(null, null, identifier); 65 } 66 67 @AllFieldsConstructor Name(Name qualifier, final String identifier)68 public Name(Name qualifier, final String identifier) { 69 this(null, qualifier, identifier); 70 } 71 72 /** 73 * This constructor is used by the parser and is considered private. 74 */ 75 @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator") Name(TokenRange tokenRange, Name qualifier, String identifier)76 public Name(TokenRange tokenRange, Name qualifier, String identifier) { 77 super(tokenRange); 78 setQualifier(qualifier); 79 setIdentifier(identifier); 80 customInitialization(); 81 } 82 83 @Override 84 @Generated("com.github.javaparser.generator.core.node.AcceptGenerator") accept(final GenericVisitor<R, A> v, final A arg)85 public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) { 86 return v.visit(this, arg); 87 } 88 89 @Override 90 @Generated("com.github.javaparser.generator.core.node.AcceptGenerator") accept(final VoidVisitor<A> v, final A arg)91 public <A> void accept(final VoidVisitor<A> v, final A arg) { 92 v.visit(this, arg); 93 } 94 95 @Generated("com.github.javaparser.generator.core.node.PropertyGenerator") getIdentifier()96 public String getIdentifier() { 97 return identifier; 98 } 99 100 @Generated("com.github.javaparser.generator.core.node.PropertyGenerator") setIdentifier(final String identifier)101 public Name setIdentifier(final String identifier) { 102 assertNonEmpty(identifier); 103 if (identifier == this.identifier) { 104 return (Name) this; 105 } 106 notifyPropertyChange(ObservableProperty.IDENTIFIER, this.identifier, identifier); 107 this.identifier = identifier; 108 return this; 109 } 110 111 /** 112 * @return the complete qualified name. Only the identifiers and the dots, so no comments or whitespace. 113 */ asString()114 public String asString() { 115 if (qualifier != null) { 116 return qualifier.asString() + "." + identifier; 117 } 118 return identifier; 119 } 120 121 @Generated("com.github.javaparser.generator.core.node.PropertyGenerator") getQualifier()122 public Optional<Name> getQualifier() { 123 return Optional.ofNullable(qualifier); 124 } 125 126 @Generated("com.github.javaparser.generator.core.node.PropertyGenerator") setQualifier(final Name qualifier)127 public Name setQualifier(final Name qualifier) { 128 if (qualifier == this.qualifier) { 129 return (Name) this; 130 } 131 notifyPropertyChange(ObservableProperty.QUALIFIER, this.qualifier, qualifier); 132 if (this.qualifier != null) 133 this.qualifier.setParentNode(null); 134 this.qualifier = qualifier; 135 setAsParentNodeOf(qualifier); 136 return this; 137 } 138 139 @Override 140 @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator") remove(Node node)141 public boolean remove(Node node) { 142 if (node == null) 143 return false; 144 if (qualifier != null) { 145 if (node == qualifier) { 146 removeQualifier(); 147 return true; 148 } 149 } 150 return super.remove(node); 151 } 152 153 @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator") removeQualifier()154 public Name removeQualifier() { 155 return setQualifier((Name) null); 156 } 157 158 @Override 159 @Generated("com.github.javaparser.generator.core.node.CloneGenerator") clone()160 public Name clone() { 161 return (Name) accept(new CloneVisitor(), null); 162 } 163 164 @Override 165 @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator") getMetaModel()166 public NameMetaModel getMetaModel() { 167 return JavaParserMetaModel.nameMetaModel; 168 } 169 170 @Override 171 @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator") replace(Node node, Node replacementNode)172 public boolean replace(Node node, Node replacementNode) { 173 if (node == null) 174 return false; 175 if (qualifier != null) { 176 if (node == qualifier) { 177 setQualifier((Name) replacementNode); 178 return true; 179 } 180 } 181 return super.replace(node, replacementNode); 182 } 183 184 /** 185 * A top level name is a name that is not contained in a larger Name instance. 186 */ isTopLevel()187 public boolean isTopLevel() { 188 return !isInternal(); 189 } 190 191 /** 192 * An internal name is a name that constitutes a part of a larger Name instance. 193 */ isInternal()194 public boolean isInternal() { 195 return getParentNode().filter(parent -> parent instanceof Name).isPresent(); 196 } 197 } 198