1 /*
2  * Copyright (C) 2010 Google Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.google.doclava;
18 
19 import com.google.clearsilver.jsilver.data.Data;
20 
21 import java.util.ArrayList;
22 import java.util.Arrays;
23 
24 public class AnnotationInstanceInfo implements Resolvable {
25   private ClassInfo mType;
26   private String mAnnotationName; // for debugging purposes TODO - remove
27   private ArrayList<AnnotationValueInfo> mElementValues;
28   private ArrayList<Resolution> mResolutions;
29 
AnnotationInstanceInfo()30   public AnnotationInstanceInfo() {
31       mType = null;
32       mElementValues = new ArrayList<AnnotationValueInfo>();
33     }
34 
AnnotationInstanceInfo(ClassInfo type, AnnotationValueInfo[] elementValues)35   public AnnotationInstanceInfo(ClassInfo type, AnnotationValueInfo[] elementValues) {
36     mType = type;
37     mElementValues = new ArrayList<AnnotationValueInfo>(Arrays.asList(elementValues));
38   }
39 
type()40   ClassInfo type() {
41     return mType;
42   }
43 
setClass(ClassInfo cl)44   public void setClass(ClassInfo cl) {
45       mType = cl;
46   }
47 
setSimpleAnnotationName(String name)48   public void setSimpleAnnotationName(String name) {
49       mAnnotationName = name;
50   }
51 
elementValues()52   ArrayList<AnnotationValueInfo> elementValues() {
53     return mElementValues;
54   }
55 
addElementValue(AnnotationValueInfo info)56   public void addElementValue(AnnotationValueInfo info) {
57       mElementValues.add(info);
58   }
59 
60   @Override
toString()61   public String toString() {
62     StringBuilder str = new StringBuilder();
63     str.append("@");
64     if (mType == null) {
65         str.append(mAnnotationName);
66     } else {
67         str.append(mType.qualifiedName());
68     }
69     str.append("(");
70 
71     for (AnnotationValueInfo value : mElementValues) {
72       if (value.element() != null) {
73           str.append(value.element().name());
74           str.append("=");
75       }
76 
77       str.append(value.valueString());
78       if (value != mElementValues.get(mElementValues.size()-1)) {
79         str.append(",");
80       }
81     }
82     str.append(")");
83     return str.toString();
84   }
85 
addResolution(Resolution resolution)86   public void addResolution(Resolution resolution) {
87       if (mResolutions == null) {
88           mResolutions = new ArrayList<Resolution>();
89       }
90 
91       mResolutions.add(resolution);
92   }
93 
printResolutions()94   public void printResolutions() {
95       System.out.println("Resolutions for Annotation:");
96       for (Resolution r : mResolutions) {
97           System.out.println(r);
98       }
99   }
100 
resolveResolutions()101   public boolean resolveResolutions() {
102       ArrayList<Resolution> resolutions = mResolutions;
103       mResolutions = new ArrayList<Resolution>();
104 
105       boolean allResolved = true;
106       for (Resolution resolution : resolutions) {
107           StringBuilder qualifiedClassName = new StringBuilder();
108           InfoBuilder.resolveQualifiedName(resolution.getValue(), qualifiedClassName,
109                   resolution.getInfoBuilder());
110 
111           // if we still couldn't resolve it, save it for the next pass
112           if ("".equals(qualifiedClassName.toString())) {
113               mResolutions.add(resolution);
114               allResolved = false;
115           } else if ("annotationTypeName".equals(resolution.getVariable())) {
116               setClass(InfoBuilder.Caches.obtainClass(qualifiedClassName.toString()));
117           }
118       }
119 
120       return allResolved;
121   }
122 
123   /**
124    * Convert the specified list of {@code AnnotationInstanceInfo} into an HDF-formatted list, and
125    * add the HDF list into the specified {@code Data}.
126    */
makeLinkListHDF(Data data, String base, AnnotationInstanceInfo[] annotations)127   public static void makeLinkListHDF(Data data, String base, AnnotationInstanceInfo[] annotations) {
128     if (annotations == null) return;
129 
130     final int N = annotations.length;
131     for (int i = 0; i < N; i++) {
132       AnnotationInstanceInfo aii = annotations[i];
133       final String aiiBase = base + "." + i;
134 
135       // Serialize data about the annotation element values
136       for (int elemIdx = 0; elemIdx < aii.elementValues().size(); ++elemIdx) {
137         final String elemBase = aiiBase + ".elementValues." + elemIdx;
138         final AnnotationValueInfo value = aii.elementValues().get(elemIdx);
139         data.setValue(elemBase + ".name", value.element().name());
140         data.setValue(elemBase + ".value", value.valueString());
141       }
142 
143       aii.type().makeShortDescrHDF(data, aiiBase);
144     }
145   }
146 
147   /**
148    * Get a new list containing the set of annotations that are shared between
149    * the input annotations collection and the names of annotations passed in
150    * the showAnnotations parameter
151    */
getShowAnnotationsIntersection( ArrayList<AnnotationInstanceInfo> annotations)152   public static ArrayList<AnnotationInstanceInfo> getShowAnnotationsIntersection(
153           ArrayList<AnnotationInstanceInfo> annotations) {
154     ArrayList<AnnotationInstanceInfo> list = new ArrayList<AnnotationInstanceInfo>();
155     if (annotations != null) {
156       for (AnnotationInstanceInfo info : annotations) {
157         if (Doclava.showAnnotations.contains(info.type().qualifiedName())) {
158           list.add(info);
159         }
160       }
161     }
162     return list;
163   }
164 }
165