PackageInfo.java revision 920dbbbaca6aa578f3b26d89e99d12754c26ed60
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  }
43
44  public PackageInfo(String name) {
45    super("", null);
46    mName = name;
47  }
48
49  public PackageInfo(String name, SourcePositionInfo position) {
50    super("", position);
51
52    if (name.isEmpty()) {
53      mName = "default package";
54    } else {
55      mName = name;
56    }
57  }
58
59  public String htmlPage() {
60    String s = mName;
61    s = s.replace('.', '/');
62    s += "/package-summary.html";
63    s = Doclava.javadocDir + s;
64    return s;
65  }
66
67  public String fullDescriptionHtmlPage() {
68    String s = mName;
69    s = s.replace('.', '/');
70    s += "/package-descr.html";
71    s = Doclava.javadocDir + s;
72    return s;
73  }
74
75  @Override
76  public ContainerInfo parent() {
77    return null;
78  }
79
80  @Override
81  public boolean isHidden() {
82    return comment().isHidden();
83  }
84
85  public boolean checkLevel() {
86    // TODO should return false if all classes are hidden but the package isn't.
87    // We don't have this so I'm not doing it now.
88    return !isHidden();
89  }
90
91  public String name() {
92    return mName;
93  }
94
95  public String qualifiedName() {
96    return mName;
97  }
98
99  public TagInfo[] inlineTags() {
100    return comment().tags();
101  }
102
103  public TagInfo[] firstSentenceTags() {
104    return comment().briefTags();
105  }
106
107  public static ClassInfo[] filterHidden(ClassInfo[] classes) {
108    ArrayList<ClassInfo> out = new ArrayList<ClassInfo>();
109
110    for (ClassInfo cl : classes) {
111      if (!cl.isHidden()) {
112        out.add(cl);
113      }
114    }
115
116    return out.toArray(new ClassInfo[0]);
117  }
118
119  public void makeLink(Data data, String base) {
120    if (checkLevel()) {
121      data.setValue(base + ".link", htmlPage());
122    }
123    data.setValue(base + ".name", name());
124    data.setValue(base + ".since", getSince());
125  }
126
127  public void makeClassLinkListHDF(Data data, String base) {
128    makeLink(data, base);
129    ClassInfo.makeLinkListHDF(data, base + ".interfaces", interfaces());
130    ClassInfo.makeLinkListHDF(data, base + ".classes", ordinaryClasses());
131    ClassInfo.makeLinkListHDF(data, base + ".enums", enums());
132    ClassInfo.makeLinkListHDF(data, base + ".exceptions", exceptions());
133    ClassInfo.makeLinkListHDF(data, base + ".errors", errors());
134    data.setValue(base + ".since", getSince());
135  }
136
137  public ClassInfo[] interfaces() {
138    if (mInterfaces == null) {
139      mInterfaces =
140          ClassInfo.sortByName(filterHidden(Converter.convertClasses(mPackage.interfaces())));
141    }
142    return mInterfaces;
143  }
144
145  public ClassInfo[] ordinaryClasses() {
146    if (mOrdinaryClasses == null) {
147      mOrdinaryClasses =
148          ClassInfo.sortByName(filterHidden(Converter.convertClasses(mPackage.ordinaryClasses())));
149    }
150    return mOrdinaryClasses;
151  }
152
153  public ClassInfo[] enums() {
154    if (mEnums == null) {
155      mEnums = ClassInfo.sortByName(filterHidden(Converter.convertClasses(mPackage.enums())));
156    }
157    return mEnums;
158  }
159
160  public ClassInfo[] exceptions() {
161    if (mExceptions == null) {
162      mExceptions =
163          ClassInfo.sortByName(filterHidden(Converter.convertClasses(mPackage.exceptions())));
164    }
165    return mExceptions;
166  }
167
168  public ClassInfo[] errors() {
169    if (mErrors == null) {
170      mErrors = ClassInfo.sortByName(filterHidden(Converter.convertClasses(mPackage.errors())));
171    }
172    return mErrors;
173  }
174
175  // in hashed containers, treat the name as the key
176  @Override
177  public int hashCode() {
178    return mName.hashCode();
179  }
180
181  private String mName;
182  private PackageDoc mPackage;
183  private ClassInfo[] mInterfaces;
184  private ClassInfo[] mOrdinaryClasses;
185  private ClassInfo[] mEnums;
186  private ClassInfo[] mExceptions;
187  private ClassInfo[] mErrors;
188
189  // TODO: Leftovers from ApiCheck that should be better merged.
190  private HashMap<String, ClassInfo> mClasses = new HashMap<String, ClassInfo>();
191
192  public void addClass(ClassInfo cl) {
193    mClasses.put(cl.name(), cl);
194  }
195
196  public HashMap<String, ClassInfo> allClasses() {
197    return mClasses;
198  }
199
200  public boolean isConsistent(PackageInfo pInfo) {
201    boolean consistent = true;
202    for (ClassInfo cInfo : mClasses.values()) {
203      if (pInfo.mClasses.containsKey(cInfo.name())) {
204        if (!cInfo.isConsistent(pInfo.mClasses.get(cInfo.name()))) {
205          consistent = false;
206        }
207      } else {
208        Errors.error(Errors.REMOVED_CLASS, cInfo.position(), "Removed public class "
209            + cInfo.qualifiedName());
210        consistent = false;
211      }
212    }
213    for (ClassInfo cInfo : pInfo.mClasses.values()) {
214      if (!mClasses.containsKey(cInfo.name())) {
215        Errors.error(Errors.ADDED_CLASS, cInfo.position(), "Added class " + cInfo.name()
216            + " to package " + pInfo.name());
217        consistent = false;
218      }
219    }
220    return consistent;
221  }
222}
223