View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.maven.tools.plugin.javadoc;
20  
21  import java.util.Objects;
22  import java.util.Optional;
23  
24  /**
25   * Wraps a fully qualified (and resolved) code reference used in javadoc tags {@code see}, {@code link} and
26   * {@code linkplain}. Similar to {@link JavadocReference} but can distinguish between package names and class names. The
27   * package name is always set for a resolved reference (except for references to modules). The member is always the
28   * normalized form containing only fully qualified type names (without argument names), separated by {@code ,} without
29   * any whitespace characters. Also the member type is always resolved to one of {@link MemberType} (in case the
30   * reference contains a member part).
31   */
32  public class FullyQualifiedJavadocReference extends JavadocReference {
33  
34      /** if false, points to a class/package which is part of the current classloader (and not any of its parents) */
35      private final boolean isExternal;
36  
37      private final Optional<String> packageName;
38  
39      private final Optional<MemberType> memberType;
40  
41      /** The type of the member part of the reference. */
42      public enum MemberType {
43          FIELD,
44          METHOD,
45          CONSTRUCTOR
46      }
47  
48      public FullyQualifiedJavadocReference(String packageName, boolean isExternal) {
49          this(packageName, Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty(), isExternal);
50      }
51  
52      public FullyQualifiedJavadocReference(String packageName, Optional<String> label, boolean isExternal) {
53          this(packageName, Optional.empty(), Optional.empty(), Optional.empty(), label, isExternal);
54      }
55  
56      public FullyQualifiedJavadocReference(String packageName, String className, boolean isExternal) {
57          this(packageName, Optional.of(className), Optional.empty(), Optional.empty(), Optional.empty(), isExternal);
58      }
59  
60      public FullyQualifiedJavadocReference(
61              String packageName, String className, String member, MemberType memberType, boolean isExternal) {
62          this(
63                  packageName,
64                  Optional.of(className),
65                  Optional.of(member),
66                  Optional.of(memberType),
67                  Optional.empty(),
68                  isExternal);
69      }
70  
71      public FullyQualifiedJavadocReference(
72              String packageName,
73              Optional<String> className,
74              Optional<String> member,
75              Optional<MemberType> memberType,
76              Optional<String> label,
77              boolean isExternal) {
78          this(Optional.empty(), Optional.of(packageName), className, member, memberType, label, isExternal);
79      }
80  
81      public FullyQualifiedJavadocReference(
82              Optional<String> moduleName,
83              Optional<String> packageName,
84              Optional<String> className,
85              Optional<String> member,
86              Optional<MemberType> memberType,
87              Optional<String> label,
88              boolean isExternal) {
89          super(moduleName, className, member, label);
90          this.packageName = packageName;
91          this.isExternal = isExternal;
92          if (!moduleName.isPresent() && !packageName.isPresent()) {
93              throw new IllegalArgumentException("At least one of module name or package name needs to be set");
94          }
95          if (member.isPresent()) {
96              if (!memberType.isPresent()) {
97                  throw new IllegalArgumentException("When member is set, also the member type needs to be set");
98              }
99              if (member.get().matches(".*\\s.*")) {
100                 throw new IllegalArgumentException("member must not contain any whitespace characters!");
101             }
102         }
103         this.memberType = memberType;
104     }
105 
106     /**
107      *
108      * @return {@code true} in case this class/package is part of another classloader
109      */
110     public boolean isExternal() {
111         return isExternal;
112     }
113 
114     /** @return the package name of the referenced class */
115     public Optional<String> getPackageName() {
116         return packageName;
117     }
118 
119     /**
120      * @return the simple class name of the referenced class, may be prefixed by the declaring class names, separated by
121      *         '.' (for inner classes)
122      */
123     public Optional<String> getClassName() {
124         return getPackageNameClassName();
125     }
126 
127     /** @return the type of the member. Only empty if no member is set. */
128     public Optional<MemberType> getMemberType() {
129         return memberType;
130     }
131 
132     public Optional<String> getFullyQualifiedClassName() {
133         if (getClassName().isPresent() && getPackageName().isPresent()) {
134             return Optional.of(getPackageName().get() + "." + getClassName().get());
135         } else {
136             return Optional.empty();
137         }
138     }
139 
140     @Override
141     public String toString() {
142         return "FullyQualifiedJavadocReference [moduleName=" + getModuleName() + ", packageName=" + packageName
143                 + ", className=" + getClassName() + ", memberType=" + memberType + ", member=" + getMember()
144                 + ", label="
145                 + getLabel() + ", isExternal=" + isExternal + "]";
146     }
147 
148     @Override
149     public int hashCode() {
150         final int prime = 31;
151         int result = super.hashCode();
152         result = prime * result + Objects.hash(memberType, packageName, isExternal);
153         return result;
154     }
155 
156     @Override
157     public boolean equals(Object obj) {
158         if (this == obj) {
159             return true;
160         }
161         if (!super.equals(obj)) {
162             return false;
163         }
164         if (getClass() != obj.getClass()) {
165             return false;
166         }
167         FullyQualifiedJavadocReference other = (FullyQualifiedJavadocReference) obj;
168         return Objects.equals(memberType, other.memberType)
169                 && Objects.equals(packageName, other.packageName)
170                 && isExternal == other.isExternal;
171     }
172 }