001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 */ 019package org.apache.maven.tools.plugin.javadoc; 020 021import java.util.Objects; 022import java.util.Optional; 023 024/** 025 * Wraps a fully qualified (and resolved) code reference used in javadoc tags {@code see}, {@code link} and 026 * {@code linkplain}. Similar to {@link JavadocReference} but can distinguish between package names and class names. The 027 * package name is always set for a resolved reference (except for references to modules). The member is always the 028 * normalized form containing only fully qualified type names (without argument names), separated by {@code ,} without 029 * any whitespace characters. Also the member type is always resolved to one of {@link MemberType} (in case the 030 * reference contains a member part). 031 */ 032public class FullyQualifiedJavadocReference extends JavadocReference { 033 034 /** if false, points to a class/package which is part of the current classloader (and not any of its parents) */ 035 private final boolean isExternal; 036 037 private final Optional<String> packageName; 038 039 private final Optional<MemberType> memberType; 040 041 /** The type of the member part of the reference. */ 042 public enum MemberType { 043 FIELD, 044 METHOD, 045 CONSTRUCTOR 046 } 047 048 public FullyQualifiedJavadocReference(String packageName, boolean isExternal) { 049 this(packageName, Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty(), isExternal); 050 } 051 052 public FullyQualifiedJavadocReference(String packageName, Optional<String> label, boolean isExternal) { 053 this(packageName, Optional.empty(), Optional.empty(), Optional.empty(), label, isExternal); 054 } 055 056 public FullyQualifiedJavadocReference(String packageName, String className, boolean isExternal) { 057 this(packageName, Optional.of(className), Optional.empty(), Optional.empty(), Optional.empty(), isExternal); 058 } 059 060 public FullyQualifiedJavadocReference( 061 String packageName, String className, String member, MemberType memberType, boolean isExternal) { 062 this( 063 packageName, 064 Optional.of(className), 065 Optional.of(member), 066 Optional.of(memberType), 067 Optional.empty(), 068 isExternal); 069 } 070 071 public FullyQualifiedJavadocReference( 072 String packageName, 073 Optional<String> className, 074 Optional<String> member, 075 Optional<MemberType> memberType, 076 Optional<String> label, 077 boolean isExternal) { 078 this(Optional.empty(), Optional.of(packageName), className, member, memberType, label, isExternal); 079 } 080 081 public FullyQualifiedJavadocReference( 082 Optional<String> moduleName, 083 Optional<String> packageName, 084 Optional<String> className, 085 Optional<String> member, 086 Optional<MemberType> memberType, 087 Optional<String> label, 088 boolean isExternal) { 089 super(moduleName, className, member, label); 090 this.packageName = packageName; 091 this.isExternal = isExternal; 092 if (!moduleName.isPresent() && !packageName.isPresent()) { 093 throw new IllegalArgumentException("At least one of module name or package name needs to be set"); 094 } 095 if (member.isPresent()) { 096 if (!memberType.isPresent()) { 097 throw new IllegalArgumentException("When member is set, also the member type needs to be set"); 098 } 099 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}