1 /* 2 * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package com.sun.tools.javadoc.main; 27 28 import com.sun.javadoc.*; 29 30 import com.sun.tools.javac.code.Attribute; 31 import com.sun.tools.javac.code.Symbol.*; 32 import com.sun.tools.javac.util.List; 33 import com.sun.tools.javac.util.Pair; 34 35 36 /** 37 * Represents an annotation. 38 * An annotation associates a value with each element of an annotation type. 39 * Sure it ought to be called "Annotation", but that clashes with 40 * java.lang.annotation.Annotation. 41 * 42 * <p><b>This is NOT part of any supported API. 43 * If you write code that depends on this, you do so at your own risk. 44 * This code and its internal interfaces are subject to change or 45 * deletion without notice.</b> 46 * 47 * @author Scott Seligman 48 * @since 1.5 49 */ 50 51 @Deprecated(since="9", forRemoval=true) 52 @SuppressWarnings("removal") 53 public class AnnotationDescImpl implements AnnotationDesc { 54 55 private final DocEnv env; 56 private final Attribute.Compound annotation; 57 58 AnnotationDescImpl(DocEnv env, Attribute.Compound annotation)59 AnnotationDescImpl(DocEnv env, Attribute.Compound annotation) { 60 this.env = env; 61 this.annotation = annotation; 62 } 63 64 /** 65 * Returns the annotation type of this annotation. 66 */ annotationType()67 public AnnotationTypeDoc annotationType() { 68 ClassSymbol atsym = (ClassSymbol)annotation.type.tsym; 69 if (annotation.type.isErroneous()) { 70 env.warning(null, "javadoc.class_not_found", annotation.type.toString()); 71 return new AnnotationTypeDocImpl(env, atsym); 72 } else { 73 return (AnnotationTypeDoc)env.getClassDoc(atsym); 74 } 75 } 76 77 /** 78 * Returns this annotation's elements and their values. 79 * Only those explicitly present in the annotation are 80 * included, not those assuming their default values. 81 * Returns an empty array if there are none. 82 */ elementValues()83 public ElementValuePair[] elementValues() { 84 List<Pair<MethodSymbol,Attribute>> vals = annotation.values; 85 ElementValuePair res[] = new ElementValuePair[vals.length()]; 86 int i = 0; 87 for (Pair<MethodSymbol,Attribute> val : vals) { 88 res[i++] = new ElementValuePairImpl(env, val.fst, val.snd); 89 } 90 return res; 91 } 92 93 /** 94 * Check for the synthesized bit on the annotation. 95 * 96 * @return true if the annotation is synthesized. 97 */ isSynthesized()98 public boolean isSynthesized() { 99 return annotation.isSynthesized(); 100 } 101 102 /** 103 * Returns a string representation of this annotation. 104 * String is of one of the forms: 105 * <pre> 106 * {@code @com.example.foo(name1=val1, name2=val2)} 107 * {@code @com.example.foo(val)} 108 * {@code @com.example.foo} 109 * </pre> 110 * Omit parens for marker annotations, and omit "value=" when allowed. 111 */ 112 @Override toString()113 public String toString() { 114 StringBuilder sb = new StringBuilder("@"); 115 sb.append(annotation.type.tsym); 116 117 ElementValuePair vals[] = elementValues(); 118 if (vals.length > 0) { // omit parens for marker annotation 119 sb.append('('); 120 boolean first = true; 121 for (ElementValuePair val : vals) { 122 if (!first) { 123 sb.append(", "); 124 } 125 first = false; 126 127 String name = val.element().name(); 128 if (vals.length == 1 && name.equals("value")) { 129 sb.append(val.value()); 130 } else { 131 sb.append(val); 132 } 133 } 134 sb.append(')'); 135 } 136 return sb.toString(); 137 } 138 139 140 /** 141 * Represents an association between an annotation type element 142 * and one of its values. 143 */ 144 public static class ElementValuePairImpl implements ElementValuePair { 145 146 private final DocEnv env; 147 private final MethodSymbol meth; 148 private final Attribute value; 149 ElementValuePairImpl(DocEnv env, MethodSymbol meth, Attribute value)150 ElementValuePairImpl(DocEnv env, MethodSymbol meth, Attribute value) { 151 this.env = env; 152 this.meth = meth; 153 this.value = value; 154 } 155 156 /** 157 * Returns the annotation type element. 158 */ element()159 public AnnotationTypeElementDoc element() { 160 return env.getAnnotationTypeElementDoc(meth); 161 } 162 163 /** 164 * Returns the value associated with the annotation type element. 165 */ value()166 public AnnotationValue value() { 167 return new AnnotationValueImpl(env, value); 168 } 169 170 /** 171 * Returns a string representation of this pair 172 * of the form "name=value". 173 */ 174 @Override toString()175 public String toString() { 176 return meth.name + "=" + value(); 177 } 178 } 179 } 180