Thu, 18 Sep 2008 18:39:44 -0700
6744408: Extra ouput is appearing in stderr
Reviewed-by: bpatel
1 /*
2 * Copyright 1997-2006 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 */
26 package com.sun.tools.javadoc;
28 import com.sun.javadoc.*;
30 import java.io.File;
31 import java.io.InputStream;
32 import java.io.FileInputStream;
33 import java.io.IOException;
34 import java.util.zip.ZipFile;
35 import java.util.zip.ZipEntry;
37 import com.sun.tools.javac.code.Attribute;
38 import com.sun.tools.javac.code.Scope;
39 import com.sun.tools.javac.code.Symbol.ClassSymbol;
40 import com.sun.tools.javac.code.Symbol.PackageSymbol;
41 import com.sun.tools.javac.comp.AttrContext;
42 import com.sun.tools.javac.comp.Env;
43 import com.sun.tools.javac.tree.JCTree;
44 import com.sun.tools.javac.util.List;
45 import com.sun.tools.javac.util.ListBuffer;
46 import com.sun.tools.javac.util.Name;
47 import com.sun.tools.javac.util.Position;
49 import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
52 /**
53 * Represents a java package. Provides access to information
54 * about the package, the package's comment and tags, and the
55 * classes in the package.
56 *
57 * @since 1.2
58 * @author Kaiyang Liu (original)
59 * @author Robert Field (rewrite)
60 * @author Neal Gafter (rewrite)
61 * @author Scott Seligman (package-info.java)
62 */
64 public class PackageDocImpl extends DocImpl implements PackageDoc {
66 private static final String PACKAGE_HTML_FILE_NAME = "package.html";
68 protected PackageSymbol sym;
69 private JCCompilationUnit tree = null; // for source position
71 public String docPath = null;
72 public String zipDocPath = null;
73 public String zipDocEntry = null;
74 private boolean foundDoc; // found a doc comment in either
75 // package.html or package-info.java
77 boolean isIncluded = false; // Set in RootDocImpl.
78 public boolean setDocPath = false; //Flag to avoid setting doc path multiple times.
80 /**
81 * Constructor
82 */
83 public PackageDocImpl(DocEnv env, PackageSymbol sym) {
84 this(env, sym, null, null);
85 }
87 /**
88 * Constructor
89 */
90 public PackageDocImpl(DocEnv env, PackageSymbol sym,
91 String documentation, JCTree tree) {
92 super(env, documentation);
93 this.sym = sym;
94 this.tree = (JCCompilationUnit) tree;
95 foundDoc = (documentation != null);
96 }
98 void setTree(JCTree tree) {
99 this.tree = (JCCompilationUnit) tree;
100 }
102 public void setRawCommentText(String rawDocumentation) {
103 super.setRawCommentText(rawDocumentation);
104 checkDoc();
105 }
107 /**
108 * Do lazy initialization of "documentation" string.
109 */
110 String documentation() {
111 if (documentation != null) return documentation;
112 if (zipDocPath != null) {
113 try {
114 ZipFile f = new ZipFile(zipDocPath);
115 ZipEntry entry = f.getEntry(zipDocEntry);
116 if (entry != null) {
117 InputStream s = f.getInputStream(entry);
118 return (documentation = readHTMLDocumentation(s,
119 zipDocPath + File.separatorChar + zipDocEntry));
120 }
121 } catch (IOException exc) {
122 documentation = "";
123 env.error(null, "javadoc.File_Read_Error",
124 zipDocPath + File.separatorChar + zipDocEntry);
125 }
126 }
127 if (docPath != null) {
128 // read from file
129 try {
130 InputStream s = new FileInputStream(docPath);
131 documentation = readHTMLDocumentation(s, docPath);
132 } catch (IOException exc) {
133 documentation = "";
134 env.error(null, "javadoc.File_Read_Error", docPath);
135 }
136 } else {
137 // no doc file to be had
138 documentation = "";
139 }
140 return documentation;
141 }
143 /**
144 * Cache of all classes contained in this package, including
145 * member classes of those classes, and their member classes, etc.
146 * Includes only those classes at the specified protection level
147 * and weaker.
148 */
149 private List<ClassDocImpl> allClassesFiltered = null;
151 /**
152 * Cache of all classes contained in this package, including
153 * member classes of those classes, and their member classes, etc.
154 */
155 private List<ClassDocImpl> allClasses = null;
157 /**
158 * Return a list of all classes contained in this package, including
159 * member classes of those classes, and their member classes, etc.
160 */
161 private List<ClassDocImpl> getClasses(boolean filtered) {
162 if (allClasses != null && !filtered) {
163 return allClasses;
164 }
165 if (allClassesFiltered != null && filtered) {
166 return allClassesFiltered;
167 }
168 ListBuffer<ClassDocImpl> classes = new ListBuffer<ClassDocImpl>();
169 for (Scope.Entry e = sym.members().elems; e != null; e = e.sibling) {
170 if (e.sym != null) {
171 ClassSymbol s = (ClassSymbol)e.sym;
172 ClassDocImpl c = env.getClassDoc(s);
173 if (c != null && !c.isSynthetic())
174 c.addAllClasses(classes, filtered);
175 }
176 }
177 if (filtered)
178 return allClassesFiltered = classes.toList();
179 else
180 return allClasses = classes.toList();
181 }
183 /**
184 * Add all included classes (including Exceptions and Errors)
185 * and interfaces.
186 */
187 public void addAllClassesTo(ListBuffer<ClassDocImpl> list) {
188 list.appendList(getClasses(true));
189 }
191 /**
192 * Get all classes (including Exceptions and Errors)
193 * and interfaces.
194 * @since J2SE1.4.
195 *
196 * @return all classes and interfaces in this package, filtered to include
197 * only the included classes if filter==true.
198 */
199 public ClassDoc[] allClasses(boolean filter) {
200 List<ClassDocImpl> classes = getClasses(filter);
201 return classes.toArray(new ClassDocImpl[classes.length()]);
202 }
204 /**
205 * Get all included classes (including Exceptions and Errors)
206 * and interfaces. Same as allClasses(true).
207 *
208 * @return all included classes and interfaces in this package.
209 */
210 public ClassDoc[] allClasses() {
211 return allClasses(true);
212 }
214 /**
215 * Get ordinary classes (that is, exclude exceptions, errors,
216 * enums, interfaces, and annotation types) in this package.
217 *
218 * @return included ordinary classes in this package.
219 */
220 public ClassDoc[] ordinaryClasses() {
221 ListBuffer<ClassDocImpl> ret = new ListBuffer<ClassDocImpl>();
222 for (ClassDocImpl c : getClasses(true)) {
223 if (c.isOrdinaryClass()) {
224 ret.append(c);
225 }
226 }
227 return ret.toArray(new ClassDocImpl[ret.length()]);
228 }
230 /**
231 * Get Exception classes in this package.
232 *
233 * @return included Exceptions in this package.
234 */
235 public ClassDoc[] exceptions() {
236 ListBuffer<ClassDocImpl> ret = new ListBuffer<ClassDocImpl>();
237 for (ClassDocImpl c : getClasses(true)) {
238 if (c.isException()) {
239 ret.append(c);
240 }
241 }
242 return ret.toArray(new ClassDocImpl[ret.length()]);
243 }
245 /**
246 * Get Error classes in this package.
247 *
248 * @return included Errors in this package.
249 */
250 public ClassDoc[] errors() {
251 ListBuffer<ClassDocImpl> ret = new ListBuffer<ClassDocImpl>();
252 for (ClassDocImpl c : getClasses(true)) {
253 if (c.isError()) {
254 ret.append(c);
255 }
256 }
257 return ret.toArray(new ClassDocImpl[ret.length()]);
258 }
260 /**
261 * Get included enum types in this package.
262 *
263 * @return included enum types in this package.
264 */
265 public ClassDoc[] enums() {
266 ListBuffer<ClassDocImpl> ret = new ListBuffer<ClassDocImpl>();
267 for (ClassDocImpl c : getClasses(true)) {
268 if (c.isEnum()) {
269 ret.append(c);
270 }
271 }
272 return ret.toArray(new ClassDocImpl[ret.length()]);
273 }
275 /**
276 * Get included interfaces in this package, omitting annotation types.
277 *
278 * @return included interfaces in this package.
279 */
280 public ClassDoc[] interfaces() {
281 ListBuffer<ClassDocImpl> ret = new ListBuffer<ClassDocImpl>();
282 for (ClassDocImpl c : getClasses(true)) {
283 if (c.isInterface()) {
284 ret.append(c);
285 }
286 }
287 return ret.toArray(new ClassDocImpl[ret.length()]);
288 }
290 /**
291 * Get included annotation types in this package.
292 *
293 * @return included annotation types in this package.
294 */
295 public AnnotationTypeDoc[] annotationTypes() {
296 ListBuffer<AnnotationTypeDocImpl> ret =
297 new ListBuffer<AnnotationTypeDocImpl>();
298 for (ClassDocImpl c : getClasses(true)) {
299 if (c.isAnnotationType()) {
300 ret.append((AnnotationTypeDocImpl)c);
301 }
302 }
303 return ret.toArray(new AnnotationTypeDocImpl[ret.length()]);
304 }
306 /**
307 * Get the annotations of this package.
308 * Return an empty array if there are none.
309 */
310 public AnnotationDesc[] annotations() {
311 AnnotationDesc res[] = new AnnotationDesc[sym.getAnnotationMirrors().length()];
312 int i = 0;
313 for (Attribute.Compound a : sym.getAnnotationMirrors()) {
314 res[i++] = new AnnotationDescImpl(env, a);
315 }
316 return res;
317 }
320 /**
321 * Lookup for a class within this package.
322 *
323 * @return ClassDocImpl of found class, or null if not found.
324 */
325 public ClassDoc findClass(String className) {
326 final boolean filtered = true;
327 for (ClassDocImpl c : getClasses(filtered)) {
328 if (c.name().equals(className)) {
329 return c;
330 }
331 }
332 return null;
333 }
335 /**
336 * Return true if this package is included in the active set.
337 */
338 public boolean isIncluded() {
339 return isIncluded;
340 }
342 /**
343 * Get package name.
344 *
345 * Note that we do not provide a means of obtaining the simple
346 * name of a package -- package names are always returned in their
347 * uniquely qualified form.
348 */
349 public String name() {
350 return qualifiedName();
351 }
353 /**
354 * Get package name.
355 */
356 public String qualifiedName() {
357 Name fullname = sym.getQualifiedName();
358 // Some bogus tests depend on the interned "" being returned.
359 // See 6457276.
360 return fullname.isEmpty() ? "" : fullname.toString();
361 }
363 /**
364 * set doc path for an unzipped directory
365 */
366 public void setDocPath(String path) {
367 setDocPath = true;
368 if (path == null)
369 return;
370 String newDocPath = path + File.separatorChar + PACKAGE_HTML_FILE_NAME;
371 if (!newDocPath.equals(docPath)) {
372 docPath = newDocPath;
373 checkDoc();
374 }
375 }
377 /**
378 * set the doc path for zipped directory
379 */
380 public void setDocPath(String path, String entry) {
381 if (!path.equals(zipDocPath)) {
382 zipDocPath = path;
383 zipDocEntry = entry + PACKAGE_HTML_FILE_NAME;
384 checkDoc();
385 }
386 }
388 // Has checkDoc() sounded off yet?
389 private boolean checkDocWarningEmitted = false;
391 /**
392 * Invoked when a source of package doc comments is located.
393 * Emits a diagnostic if this is the second one.
394 */
395 private void checkDoc() {
396 if (foundDoc) {
397 if (!checkDocWarningEmitted) {
398 env.warning(null, "javadoc.Multiple_package_comments", name());
399 checkDocWarningEmitted = true;
400 }
401 } else {
402 foundDoc = true;
403 }
404 }
406 /**
407 * Return the source position of the entity, or null if
408 * no position is available.
409 */
410 public SourcePosition position() {
411 return (tree != null)
412 ? SourcePositionImpl.make(tree.sourcefile + "", tree.pos, tree.lineMap)
413 : SourcePositionImpl.make(docPath, Position.NOPOS, null);
414 }
415 }