1 /*
   2  * Copyright 2004 Sun Microsystems, Inc.  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.  Sun designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
  22  * CA 95054 USA or visit www.sun.com if you need additional information or
  23  * have any questions.
  24  */
  25 
  26 package com.sun.tools.apt.mirror.declaration;
  27 
  28 
  29 import java.util.LinkedHashMap;
  30 import java.util.Map;
  31 
  32 import com.sun.mirror.declaration.*;
  33 import com.sun.mirror.type.AnnotationType;
  34 import com.sun.mirror.util.SourcePosition;
  35 import com.sun.tools.apt.mirror.AptEnv;
  36 import com.sun.tools.javac.code.Attribute;
  37 import com.sun.tools.javac.code.Symbol.*;
  38 import com.sun.tools.javac.util.Name;
  39 import com.sun.tools.javac.util.Pair;
  40 
  41 
  42 /**
  43  * Implementation of AnnotationMirror
  44  */
  45 @SuppressWarnings("deprecation")
  46 public class AnnotationMirrorImpl implements AnnotationMirror {
  47 
  48     protected final AptEnv env;
  49     protected final Attribute.Compound anno;
  50     protected final Declaration decl;
  51 
  52 
  53     AnnotationMirrorImpl(AptEnv env, Attribute.Compound anno, Declaration decl) {
  54         this.env = env;
  55         this.anno = anno;
  56         this.decl = decl;
  57     }
  58 
  59 
  60     /**
  61      * Returns a string representation of this annotation.
  62      * String is of one of the forms:
  63      *     @com.example.foo(name1=val1, name2=val2)
  64      *     @com.example.foo(val)
  65      *     @com.example.foo
  66      * Omit parens for marker annotations, and omit "value=" when allowed.
  67      */
  68     public String toString() {
  69         StringBuilder sb = new StringBuilder("@");
  70         Constants.Formatter fmtr = Constants.getFormatter(sb);
  71 
  72         fmtr.append(anno.type.tsym);
  73 
  74         int len = anno.values.length();
  75         if (len > 0) {          // omit parens for marker annotations
  76             sb.append('(');
  77             boolean first = true;
  78             for (Pair<MethodSymbol, Attribute> val : anno.values) {
  79                 if (!first) {
  80                     sb.append(", ");
  81                 }
  82                 first = false;
  83 
  84                 Name name = val.fst.name;
  85                 if (len > 1 || name != env.names.value) {
  86                     fmtr.append(name);
  87                     sb.append('=');
  88                 }
  89                 sb.append(new AnnotationValueImpl(env, val.snd, this));
  90             }
  91             sb.append(')');
  92         }
  93         return fmtr.toString();
  94     }
  95 
  96     /**
  97      * {@inheritDoc}
  98      */
  99     public AnnotationType getAnnotationType() {
 100         return (AnnotationType) env.typeMaker.getType(anno.type);
 101     }
 102 
 103     /**
 104      * {@inheritDoc}
 105      */
 106     public Map<AnnotationTypeElementDeclaration, AnnotationValue>
 107                                                         getElementValues() {
 108         Map<AnnotationTypeElementDeclaration, AnnotationValue> res =
 109             new LinkedHashMap<AnnotationTypeElementDeclaration,
 110                                                    AnnotationValue>(); // whew!
 111         for (Pair<MethodSymbol, Attribute> val : anno.values) {
 112             res.put(getElement(val.fst),
 113                     new AnnotationValueImpl(env, val.snd, this));
 114         }
 115         return res;
 116     }
 117 
 118     public SourcePosition getPosition() {
 119         // Return position of the declaration on which this annotation
 120         // appears.
 121         return (decl == null) ? null : decl.getPosition();
 122 
 123     }
 124 
 125     public Declaration getDeclaration() {
 126         return this.decl;
 127     }
 128 
 129     /**
 130      * Returns the annotation type element for a symbol.
 131      */
 132     private AnnotationTypeElementDeclaration getElement(MethodSymbol m) {
 133         return (AnnotationTypeElementDeclaration)
 134                     env.declMaker.getExecutableDeclaration(m);
 135     }
 136 }