PackageInfo.java revision d6eaacbb9eb56763d38a3815fc509b92ed98a585
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
17package com.google.doclava;
18
19import com.google.clearsilver.jsilver.data.Data;
20
21import com.sun.javadoc.*;
22import java.util.*;
23
24public class PackageInfo extends DocInfo implements ContainerInfo {
25  public static final String DEFAULT_PACKAGE = "default package";
26
27  public static final Comparator<PackageInfo> comparator = new Comparator<PackageInfo>() {
28    public int compare(PackageInfo a, PackageInfo b) {
29      return a.name().compareTo(b.name());
30    }
31  };
32
33  public PackageInfo(PackageDoc pkg, String name, SourcePositionInfo position) {
34    super(pkg.getRawCommentText(), position);
35    if (name.isEmpty()) {
36      mName = DEFAULT_PACKAGE;
37    } else {
38      mName = name;
39    }
40
41    mPackage = pkg;
42    initializeMaps();
43  }
44
45  public PackageInfo(String name) {
46    super("", null);
47    mName = name;
48    initializeMaps();
49  }
50
51  public PackageInfo(String name, SourcePositionInfo position) {
52    super("", position);
53
54    if (name.isEmpty()) {
55      mName = "default package";
56    } else {
57      mName = name;
58    }
59    initializeMaps();
60  }
61
62  private void initializeMaps() {
63      mInterfacesMap = new HashMap<String, ClassInfo>();
64      mOrdinaryClassesMap = new HashMap<String, ClassInfo>();
65      mEnumsMap = new HashMap<String, ClassInfo>();
66      mExceptionsMap = new HashMap<String, ClassInfo>();
67      mErrorsMap = new HashMap<String, ClassInfo>();
68  }
69
70  public String htmlPage() {
71    String s = mName;
72    s = s.replace('.', '/');
73    s += "/package-summary.html";
74    s = Doclava.javadocDir + s;
75    return s;
76  }
77
78  @Override
79  public ContainerInfo parent() {
80    return null;
81  }
82
83  @Override
84  public boolean isHidden() {
85    return comment().isHidden();
86  }
87
88  public boolean checkLevel() {
89    // TODO should return false if all classes are hidden but the package isn't.
90    // We don't have this so I'm not doing it now.
91    return !isHidden();
92  }
93
94  public String name() {
95    return mName;
96  }
97
98  public String qualifiedName() {
99    return mName;
100  }
101
102  public TagInfo[] inlineTags() {
103    return comment().tags();
104  }
105
106  public TagInfo[] firstSentenceTags() {
107    return comment().briefTags();
108  }
109
110  public static ClassInfo[] filterHidden(ClassInfo[] classes) {
111    ArrayList<ClassInfo> out = new ArrayList<ClassInfo>();
112
113    for (ClassInfo cl : classes) {
114      if (!cl.isHidden()) {
115        out.add(cl);
116      }
117    }
118
119    return out.toArray(new ClassInfo[0]);
120  }
121
122  public void makeLink(Data data, String base) {
123    if (checkLevel()) {
124      data.setValue(base + ".link", htmlPage());
125    }
126    data.setValue(base + ".name", name());
127    data.setValue(base + ".since", getSince());
128  }
129
130  public void makeClassLinkListHDF(Data data, String base) {
131    makeLink(data, base);
132    ClassInfo.makeLinkListHDF(data, base + ".interfaces", interfaces());
133    ClassInfo.makeLinkListHDF(data, base + ".classes", ordinaryClasses());
134    ClassInfo.makeLinkListHDF(data, base + ".enums", enums());
135    ClassInfo.makeLinkListHDF(data, base + ".exceptions", exceptions());
136    ClassInfo.makeLinkListHDF(data, base + ".errors", errors());
137    data.setValue(base + ".since", getSince());
138  }
139
140  public ClassInfo[] interfaces() {
141    if (mInterfaces == null) {
142      mInterfaces =
143          ClassInfo.sortByName(filterHidden(Converter.convertClasses(mPackage.interfaces())));
144    }
145    return mInterfaces;
146  }
147
148  public ClassInfo[] ordinaryClasses() {
149    if (mOrdinaryClasses == null) {
150      mOrdinaryClasses =
151          ClassInfo.sortByName(filterHidden(Converter.convertClasses(mPackage.ordinaryClasses())));
152    }
153    return mOrdinaryClasses;
154  }
155
156  public ClassInfo[] enums() {
157    if (mEnums == null) {
158      mEnums = ClassInfo.sortByName(filterHidden(Converter.convertClasses(mPackage.enums())));
159    }
160    return mEnums;
161  }
162
163  public ClassInfo[] exceptions() {
164    if (mExceptions == null) {
165      mExceptions =
166          ClassInfo.sortByName(filterHidden(Converter.convertClasses(mPackage.exceptions())));
167    }
168    return mExceptions;
169  }
170
171  public ClassInfo[] errors() {
172    if (mErrors == null) {
173      mErrors = ClassInfo.sortByName(filterHidden(Converter.convertClasses(mPackage.errors())));
174    }
175    return mErrors;
176  }
177
178  // in hashed containers, treat the name as the key
179  @Override
180  public int hashCode() {
181    return mName.hashCode();
182  }
183
184  private String mName;
185  private PackageDoc mPackage;
186  private ClassInfo[] mInterfaces;
187  private ClassInfo[] mOrdinaryClasses;
188  private ClassInfo[] mEnums;
189  private ClassInfo[] mExceptions;
190  private ClassInfo[] mErrors;
191
192  private HashMap<String, ClassInfo> mInterfacesMap;
193  private HashMap<String, ClassInfo> mOrdinaryClassesMap;
194  private HashMap<String, ClassInfo> mEnumsMap;
195  private HashMap<String, ClassInfo> mExceptionsMap;
196  private HashMap<String, ClassInfo> mErrorsMap;
197
198
199  public ClassInfo getClass(String className) {
200      ClassInfo cls = mInterfacesMap.get(className);
201
202      if (cls != null) {
203          return cls;
204      }
205
206      cls = mOrdinaryClassesMap.get(className);
207
208      if (cls != null) {
209          return cls;
210      }
211
212      cls = mEnumsMap.get(className);
213
214      if (cls != null) {
215          return cls;
216      }
217
218      cls = mEnumsMap.get(className);
219
220      if (cls != null) {
221          return cls;
222      }
223
224      return mErrorsMap.get(className);
225  }
226
227  public void addInterface(ClassInfo cls) {
228      mInterfacesMap.put(cls.name(), cls);
229  }
230
231  public ClassInfo getInterface(String interfaceName) {
232      return mInterfacesMap.get(interfaceName);
233  }
234
235  public ClassInfo getOrdinaryClass(String className) {
236      return mOrdinaryClassesMap.get(className);
237  }
238
239  public void addOrdinaryClass(ClassInfo cls) {
240      mOrdinaryClassesMap.put(cls.name(), cls);
241  }
242
243  public ClassInfo getEnum(String enumName) {
244      return mEnumsMap.get(enumName);
245  }
246
247  public void addEnum(ClassInfo cls) {
248      this.mEnumsMap.put(cls.name(), cls);
249  }
250
251  public ClassInfo getException(String exceptionName) {
252      return mExceptionsMap.get(exceptionName);
253  }
254
255  public ClassInfo getError(String errorName) {
256      return mErrorsMap.get(errorName);
257  }
258
259  // TODO: Leftovers from ApiCheck that should be better merged.
260  private HashMap<String, ClassInfo> mClasses = new HashMap<String, ClassInfo>();
261
262  public void addClass(ClassInfo cl) {
263    mClasses.put(cl.name(), cl);
264  }
265
266  public HashMap<String, ClassInfo> allClasses() {
267    return mClasses;
268  }
269
270  public boolean isConsistent(PackageInfo pInfo) {
271    boolean consistent = true;
272    for (ClassInfo cInfo : mClasses.values()) {
273      if (pInfo.mClasses.containsKey(cInfo.name())) {
274        if (!cInfo.isConsistent(pInfo.mClasses.get(cInfo.name()))) {
275          consistent = false;
276        }
277      } else {
278        Errors.error(Errors.REMOVED_CLASS, cInfo.position(), "Removed public class "
279            + cInfo.qualifiedName());
280        consistent = false;
281      }
282    }
283    for (ClassInfo cInfo : pInfo.mClasses.values()) {
284      if (!mClasses.containsKey(cInfo.name())) {
285        Errors.error(Errors.ADDED_CLASS, cInfo.position(), "Added class " + cInfo.name()
286            + " to package " + pInfo.name());
287        consistent = false;
288      }
289    }
290    return consistent;
291  }
292}
293