OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libjava/] [classpath/] [tools/] [gnu/] [classpath/] [tools/] [doclets/] [htmldoclet/] [HtmlDoclet.java] - Blame information for rev 779

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 779 jeremybenn
/* gnu.classpath.tools.doclets.htmldoclet.HtmlDoclet
2
   Copyright (C) 2004 Free Software Foundation, Inc.
3
 
4
This file is part of GNU Classpath.
5
 
6
GNU Classpath is free software; you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation; either version 2, or (at your option)
9
any later version.
10
 
11
GNU Classpath is distributed in the hope that it will be useful, but
12
WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
General Public License for more details.
15
 
16
You should have received a copy of the GNU General Public License
17
along with GNU Classpath; see the file COPYING.  If not, write to the
18
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19
02111-1307 USA.
20
 
21
Linking this library statically or dynamically with other modules is
22
making a combined work based on this library.  Thus, the terms and
23
conditions of the GNU General Public License cover the whole
24
combination.
25
 
26
As a special exception, the copyright holders of this library give you
27
permission to link this library with independent modules to produce an
28
executable, regardless of the license terms of these independent
29
modules, and to copy and distribute the resulting executable under
30
terms of your choice, provided that you also meet, for each linked
31
independent module, the terms and conditions of the license of that
32
module.  An independent module is a module which is not derived from
33
or based on this library.  If you modify this library, you may extend
34
this exception to your version of the library, but you are not
35
obligated to do so.  If you do not wish to do so, delete this
36
exception statement from your version. */
37
 
38
package gnu.classpath.tools.doclets.htmldoclet;
39
 
40
import gnu.classpath.tools.IOToolkit;
41
 
42
import gnu.classpath.tools.doclets.AbstractDoclet;
43
import gnu.classpath.tools.doclets.DocletConfigurationException;
44
import gnu.classpath.tools.doclets.DocletOption;
45
import gnu.classpath.tools.doclets.DocletOptionFile;
46
import gnu.classpath.tools.doclets.DocletOptionFlag;
47
import gnu.classpath.tools.doclets.DocletOptionString;
48
import gnu.classpath.tools.doclets.PackageGroup;
49
import gnu.classpath.tools.doclets.TagletPrinter;
50
import gnu.classpath.tools.doclets.InlineTagRenderer;
51
 
52
import gnu.classpath.tools.doclets.xmldoclet.HtmlRepairer;
53
 
54
import gnu.classpath.tools.taglets.GnuExtendedTaglet;
55
import gnu.classpath.tools.taglets.TagletContext;
56
 
57
import gnu.classpath.tools.java2xhtml.Java2xhtml;
58
 
59
import gnu.classpath.tools.StringToolkit;
60
 
61
import com.sun.javadoc.*;
62
import com.sun.tools.doclets.Taglet;
63
 
64
import java.io.ByteArrayInputStream;
65
import java.io.File;
66
import java.io.FileInputStream;
67
import java.io.FileNotFoundException;
68
import java.io.FileOutputStream;
69
import java.io.FileReader;
70
import java.io.FileWriter;
71
import java.io.InputStream;
72
import java.io.InputStreamReader;
73
import java.io.IOException;
74
import java.io.OutputStreamWriter;
75
import java.io.PrintWriter;
76
import java.io.StringWriter;
77
 
78
import java.net.MalformedURLException;
79
 
80
import java.nio.charset.Charset;
81
 
82
import java.text.DateFormat;
83
import java.text.MessageFormat;
84
 
85
import java.util.Arrays;
86
import java.util.Calendar;
87
import java.util.Collection;
88
import java.util.Date;
89
import java.util.HashMap;
90
import java.util.Iterator;
91
import java.util.LinkedHashSet;
92
import java.util.LinkedList;
93
import java.util.List;
94
import java.util.ListIterator;
95
import java.util.Locale;
96
import java.util.Map;
97
import java.util.Properties;
98
import java.util.Set;
99
import java.util.SortedSet;
100
import java.util.TimeZone;
101
import java.util.TreeSet;
102
 
103
public class HtmlDoclet
104
   extends AbstractDoclet
105
   implements InlineTagRenderer
106
{
107
   private static String filenameExtension = ".html";
108
 
109
   /**
110
    *  Contains ExternalDocSet.
111
    */
112
   private List externalDocSets = new LinkedList();
113
 
114
   /**
115
    *  Contains String->ExternalDocSet.
116
    */
117
   private Map packageNameToDocSet = new HashMap();
118
 
119
   /**
120
    *  Cache for version string from resource /version.properties
121
    */
122
   private String docletVersion;
123
 
124
   /**
125
    *  For now, do not output a help page.
126
    */
127
   private static final boolean outputHelpPage = false;
128
 
129
   /**
130
    *  Stores the output encoding (either the one specified using
131
    *  -charset, or the platform default encoding).
132
    */
133
   private String outputCharset;
134
 
135
   private void printNavBar(HtmlPage output, String currentPage, ClassDoc currentClass)
136
   {
137
         output.beginDiv(CssClass.NAVBAR_TOP);
138
 
139
         boolean overviewLevel
140
            = ("overview".equals(currentPage)
141
               || "full-tree".equals(currentPage)
142
               || "index".equals(currentPage)
143
               || "split-index".equals(currentPage)
144
               || "serialized".equals(currentPage)
145
               || "deprecated".equals(currentPage)
146
               || "about".equals(currentPage)
147
               );
148
 
149
         if (!isSinglePackage()) {
150
            if ("overview".equals(currentPage)) {
151
               output.beginSpan(CssClass.NAVBAR_ITEM_ACTIVE);
152
               output.print("Overview");
153
               output.endSpan(CssClass.NAVBAR_ITEM_ACTIVE);
154
            }
155
            else {
156
               output.beginSpan(CssClass.NAVBAR_ITEM_ENABLED);
157
               output.beginAnchor(output.getPathToRoot() + "/overview-summary" + filenameExtension);
158
               output.print("Overview");
159
               output.endAnchor();
160
               output.endSpan(CssClass.NAVBAR_ITEM_ENABLED);
161
            }
162
 
163
            output.print(" ");
164
         }
165
 
166
         if (!overviewLevel || isSinglePackage()) {
167
            if ("package".equals(currentPage)) {
168
               output.beginSpan(CssClass.NAVBAR_ITEM_ACTIVE);
169
               output.print("Package");
170
               output.endSpan(CssClass.NAVBAR_ITEM_ACTIVE);
171
            }
172
            else {
173
               output.beginSpan(CssClass.NAVBAR_ITEM_ENABLED);
174
               String packageHref;
175
               if (isSinglePackage()) {
176
                  packageHref = output.getPathToRoot() + "/" + getPackageURL(getSinglePackage()) + "package-summary" + filenameExtension;
177
               }
178
               else {
179
                  packageHref = "package-summary" + filenameExtension;
180
               }
181
               output.beginAnchor(packageHref);
182
               output.print("Package");
183
               output.endAnchor();
184
               output.endSpan(CssClass.NAVBAR_ITEM_ENABLED);
185
            }
186
         }
187
         else {
188
            output.beginSpan(CssClass.NAVBAR_ITEM_DISABLED);
189
            output.print("Package");
190
            output.endSpan(CssClass.NAVBAR_ITEM_DISABLED);
191
         }
192
 
193
         if (optionUse.getValue() || optionLinkSource.getValue()) {
194
            output.print(" ");
195
 
196
            if (null != currentClass) {
197
               if ("class".equals(currentPage)) {
198
                  output.beginSpan(CssClass.NAVBAR_ITEM_ACTIVE);
199
                  output.print("Class");
200
                  output.endSpan(CssClass.NAVBAR_ITEM_ACTIVE);
201
               }
202
               else {
203
                  output.beginSpan(CssClass.NAVBAR_ITEM_ENABLED);
204
                  output.beginAnchor(currentClass.name() + filenameExtension);
205
                  output.print("Class");
206
                  output.endAnchor();
207
                  output.endSpan(CssClass.NAVBAR_ITEM_ENABLED);
208
               }
209
            }
210
            else {
211
               output.beginSpan(CssClass.NAVBAR_ITEM_DISABLED);
212
               output.print("Class");
213
               output.endSpan(CssClass.NAVBAR_ITEM_DISABLED);
214
            }
215
 
216
            if (optionUse.getValue()) {
217
               output.print(" ");
218
 
219
               if (null != currentClass) {
220
                  if ("uses".equals(currentPage)) {
221
                     output.beginSpan(CssClass.NAVBAR_ITEM_ACTIVE);
222
                     output.print("Use");
223
                     output.endSpan(CssClass.NAVBAR_ITEM_ACTIVE);
224
                  }
225
                  else {
226
                     output.beginSpan(CssClass.NAVBAR_ITEM_ENABLED);
227
                     output.beginAnchor(currentClass.name() + "-uses" + filenameExtension);
228
                     output.print("Use");
229
                     output.endAnchor();
230
                     output.endSpan(CssClass.NAVBAR_ITEM_ENABLED);
231
                  }
232
               }
233
               else {
234
                  output.beginSpan(CssClass.NAVBAR_ITEM_DISABLED);
235
                  output.print("Use");
236
                  output.endSpan(CssClass.NAVBAR_ITEM_DISABLED);
237
               }
238
            }
239
 
240
            if (optionLinkSource.getValue()) {
241
               output.print(" ");
242
 
243
 
244
               if ("source".equals(currentPage)) {
245
                  output.beginSpan(CssClass.NAVBAR_ITEM_ACTIVE);
246
                  output.print("Source");
247
                  output.endSpan(CssClass.NAVBAR_ITEM_ACTIVE);
248
               }
249
               else {
250
 
251
                  if (null != currentClass) {
252
 
253
                     output.beginSpan(CssClass.NAVBAR_ITEM_ENABLED);
254
                     String targetClassName = currentClass.name();
255
                     String targetAnchor = "";
256
                     if (null != currentClass.containingClass()) {
257
                        targetClassName = getOuterClassDoc(currentClass).name();
258
                        targetAnchor = "#line." + currentClass.position().line();
259
                     }
260
                     output.beginAnchor(targetClassName + "-source" + filenameExtension + targetAnchor);
261
                     output.print("Source");
262
                     output.endAnchor();
263
                     output.endSpan(CssClass.NAVBAR_ITEM_ENABLED);
264
                  }
265
                  else {
266
                     output.beginSpan(CssClass.NAVBAR_ITEM_DISABLED);
267
                     output.print("Source");
268
                     output.endSpan(CssClass.NAVBAR_ITEM_DISABLED);
269
                  }
270
               }
271
            }
272
         }
273
 
274
 
275
         if (!optionNoTree.getValue()) {
276
            output.print(" ");
277
 
278
            if ("full-tree".equals(currentPage)
279
                || "package-tree".equals(currentPage)) {
280
               output.beginSpan(CssClass.NAVBAR_ITEM_ACTIVE);
281
               output.print("Tree");
282
               output.endSpan(CssClass.NAVBAR_ITEM_ACTIVE);
283
            }
284
            else {
285
               output.beginSpan(CssClass.NAVBAR_ITEM_ENABLED);
286
               String treeHref;
287
               if (isSinglePackage() && overviewLevel) {
288
                  treeHref = getPackageURL(getSinglePackage()) + "tree" + filenameExtension;
289
               }
290
               else {
291
                  treeHref = "tree" + filenameExtension;
292
               }
293
 
294
               output.beginAnchor(treeHref);
295
               output.print("Tree");
296
               output.endAnchor();
297
               output.endSpan(CssClass.NAVBAR_ITEM_ENABLED);
298
            }
299
         }
300
 
301
         output.print(" ");
302
 
303
         String indexName;
304
         if (optionSplitIndex.getValue()) {
305
            indexName = "alphaindex-1";
306
         }
307
         else {
308
            indexName = "alphaindex";
309
         }
310
 
311
         if ("index".equals(currentPage) || "split-index".equals(currentPage)) {
312
            output.beginSpan(CssClass.NAVBAR_ITEM_ACTIVE);
313
            output.print("Index");
314
            output.endSpan(CssClass.NAVBAR_ITEM_ACTIVE);
315
         }
316
         else {
317
            output.beginSpan(CssClass.NAVBAR_ITEM_ENABLED);
318
            output.beginAnchor(output.getPathToRoot() + "/" + indexName + filenameExtension);
319
            output.print("Index");
320
            output.endAnchor();
321
            output.endSpan(CssClass.NAVBAR_ITEM_ENABLED);
322
         }
323
 
324
         if (!optionNoDeprecatedList.getValue()) {
325
            output.print(" ");
326
 
327
            if ("deprecated".equals(currentPage)) {
328
               output.beginSpan(CssClass.NAVBAR_ITEM_ACTIVE);
329
               output.print("Deprecated");
330
               output.endSpan(CssClass.NAVBAR_ITEM_ACTIVE);
331
            }
332
            else {
333
               output.beginSpan(CssClass.NAVBAR_ITEM_ENABLED);
334
               output.beginAnchor(output.getPathToRoot() + "/deprecated" + filenameExtension);
335
               output.print("Deprecated");
336
               output.endAnchor();
337
               output.endSpan(CssClass.NAVBAR_ITEM_ENABLED);
338
            }
339
         }
340
 
341
         if (outputHelpPage) {
342
            if (!optionNoHelp.getValue()) {
343
               output.print(" ");
344
 
345
               if ("help".equals(currentPage)) {
346
                  output.beginSpan(CssClass.NAVBAR_ITEM_ACTIVE);
347
                  output.print("Help");
348
                  output.endSpan(CssClass.NAVBAR_ITEM_ACTIVE);
349
               }
350
               else {
351
                  output.beginSpan(CssClass.NAVBAR_ITEM_ENABLED);
352
                  output.beginAnchor(output.getPathToRoot() + "/help" + filenameExtension);
353
                  output.print("Help");
354
                  output.endAnchor();
355
                  output.endSpan(CssClass.NAVBAR_ITEM_ENABLED);
356
               }
357
            }
358
         }
359
 
360
         output.print(" ");
361
 
362
         if ("about".equals(currentPage)) {
363
            output.beginSpan(CssClass.NAVBAR_ITEM_ACTIVE);
364
            output.print("About");
365
            output.endSpan(CssClass.NAVBAR_ITEM_ACTIVE);
366
         }
367
         else {
368
            output.beginSpan(CssClass.NAVBAR_ITEM_ENABLED);
369
            output.beginAnchor(output.getPathToRoot() + "/about" + filenameExtension);
370
            output.print("About");
371
            output.endAnchor();
372
            output.endSpan(CssClass.NAVBAR_ITEM_ENABLED);
373
         }
374
 
375
         output.endDiv(CssClass.NAVBAR_TOP);
376
   }
377
 
378
   private void printNavBarTopRow(HtmlPage output, String currentPage, ClassDoc currentClass)
379
   {
380
      output.beginRow();
381
      output.beginCell(CssClass.NAVBAR_TOP);
382
      printNavBar(output, currentPage, currentClass);
383
      output.endCell();
384
      if (null != optionHeader.getValue()) {
385
         output.beginCell(CssClass.NAVBAR_TOP_HEADER);
386
         output.print(replaceDocRoot(output, optionHeader.getValue()));
387
         output.endCell();
388
      }
389
      output.endRow();
390
   }
391
 
392
   private void printNavBarTopNaviCell(HtmlPage output)
393
   {
394
      output.beginCell(CssClass.NAVBAR_TOP_NAVI);
395
      output.beginAnchor(output.getPathToRoot() + "/index" + filenameExtension, "Show in a frameset", "_top");
396
      output.print("Frames");
397
      output.endAnchor();
398
      output.print(" | ");
399
 
400
      output.beginAnchor(output.getFile().getName(), "Show without frames", "_top");
401
      output.print("No Frames");
402
      output.endAnchor();
403
      output.print(" ");
404
 
405
      output.endCell();
406
   }
407
 
408
   private void printNavBarTop(HtmlPage output, String currentPage)
409
   {
410
      printNavBarTop(output, currentPage, null, null, null);
411
   }
412
 
413
   private void printNavBarTop(HtmlPage output, String currentPage,
414
                               ClassDoc currentClass, Object prev, Object next)
415
   {
416
      if (!optionNoNavBar.getValue()) {
417
         output.beginTable(CssClass.NAVBAR_TOP);
418
         printNavBarTopRow(output, currentPage, currentClass);
419
         output.beginRow();
420
         if ("class".equals(currentPage)) {
421
            output.beginCell(CssClass.NAVBAR_TOP_NAVI);
422
            ClassDoc prevClass = (ClassDoc)prev;
423
            ClassDoc nextClass = (ClassDoc)next;
424
            if (null != prevClass) {
425
               output.anchor(getClassDocURL(output, prevClass), "Prev Class");
426
            }
427
            else {
428
               output.print("Prev Class");
429
            }
430
            output.print(" | ");
431
            if (null != nextClass) {
432
               output.anchor(getClassDocURL(output, nextClass), "Next Class");
433
            }
434
            else {
435
               output.print("Next Class");
436
            }
437
            output.endCell();
438
         }
439
         else if ("split-index".equals(currentPage)) {
440
            output.beginCell(CssClass.NAVBAR_TOP_NAVI);
441
            Integer prevLetter = (Integer)prev;
442
            Integer nextLetter = (Integer)next;
443
            if (null != prevLetter) {
444
               output.anchor("alphaindex-" + prevLetter + filenameExtension, "Prev Letter");
445
            }
446
            else {
447
               output.print("Prev Letter");
448
            }
449
            output.print(" | ");
450
            if (null != nextLetter) {
451
               output.anchor("alphaindex-" + nextLetter + filenameExtension, "Next Letter");
452
            }
453
            else {
454
               output.print("Next Letter");
455
            }
456
            output.endCell();
457
         }
458
         else {
459
            output.beginCell(CssClass.NAVBAR_TOP_NAVI);
460
            output.endCell();
461
         }
462
 
463
         printNavBarTopNaviCell(output);
464
         output.endRow();
465
 
466
         if ("class".equals(currentPage)) {
467
            output.beginRow();
468
 
469
            output.beginCell(CssClass.NAVBAR_TOP_NAVI);
470
            output.print("Summary: ");
471
 
472
            if (currentClass.innerClasses().length > 0) {
473
               output.anchor("#summary-inner", "Nested");
474
            }
475
            else {
476
               output.print("Nested");
477
            }
478
 
479
            output.print(" | ");
480
 
481
            if (currentClass.fields().length > 0) {
482
               output.anchor("#summary-fields", "Field");
483
            }
484
            else {
485
               output.print("Field");
486
            }
487
 
488
            output.print(" | ");
489
 
490
            if (currentClass.methods().length > 0) {
491
               output.anchor("#summary-methods", "Method");
492
            }
493
            else {
494
               output.print("Method");
495
            }
496
 
497
            output.print(" | ");
498
 
499
            if (currentClass.constructors().length > 0) {
500
               output.anchor("#summary-constructors", "Constr");
501
            }
502
            else {
503
               output.print("Constr");
504
            }
505
 
506
            output.endCell();
507
 
508
            output.beginCell(CssClass.NAVBAR_TOP_NAVI);
509
            output.print("Detail: ");
510
 
511
            if (currentClass.innerClasses().length > 0) {
512
               output.anchor("#detail-inner", "Nested");
513
            }
514
            else {
515
               output.print("Nested");
516
            }
517
 
518
            output.print(" | ");
519
 
520
            if (currentClass.fields().length > 0) {
521
               output.anchor("#detail-fields", "Field");
522
            }
523
            else {
524
               output.print("Field");
525
            }
526
 
527
            output.print(" | ");
528
 
529
            if (currentClass.methods().length > 0) {
530
               output.anchor("#detail-methods", "Method");
531
            }
532
            else {
533
               output.print("Method");
534
            }
535
 
536
            output.print(" | ");
537
 
538
            if (currentClass.constructors().length > 0) {
539
               output.anchor("#detail-constructors", "Constr");
540
            }
541
            else {
542
               output.print("Constr");
543
            }
544
 
545
            output.endCell();
546
            output.endRow();
547
         }
548
         output.endTable();
549
      }
550
   }
551
 
552
   private void printNavBarTopPackage(HtmlPage output, String currentPage,
553
                                      PackageDoc prevPackage, PackageDoc nextPackage)
554
   {
555
      if (!optionNoNavBar.getValue()) {
556
         output.beginTable(CssClass.NAVBAR_TOP);
557
         printNavBarTopRow(output, currentPage, null);
558
 
559
         output.beginRow();
560
         output.beginCell(CssClass.NAVBAR_TOP_NAVI);
561
         if (null != prevPackage) {
562
            output.anchor(output.getPathToRoot() + "/" + getPackageURL(prevPackage) + "package-summary" + filenameExtension, "Prev Package");
563
         }
564
         else {
565
            output.print("Prev Package");
566
         }
567
         output.print(" | ");
568
         if (null != nextPackage) {
569
            output.anchor(output.getPathToRoot() + "/" + getPackageURL(nextPackage) + "package-summary" + filenameExtension, "Next Package");
570
         }
571
         else {
572
            output.print("Next Package");
573
         }
574
         output.endCell();
575
 
576
         printNavBarTopNaviCell(output);
577
         output.endRow();
578
 
579
         output.endTable();
580
      }
581
   }
582
 
583
   private void printNavBarBottom(HtmlPage output, String currentPage)
584
   {
585
      printNavBarBottom(output, currentPage, null);
586
   }
587
 
588
   private void printNavBarBottom(HtmlPage output, String currentPage, ClassDoc currentClass)
589
   {
590
      if ("class".equals(currentPage)) {
591
         String boilerplate = null;
592
         Tag[] boilerplateTags = getOuterClassDoc(currentClass).tags("@boilerplate");
593
         if (boilerplateTags.length > 0) {
594
            boilerplate = boilerplateTags[0].text();
595
         }
596
         if (null != boilerplate) {
597
            output.hr();
598
            output.beginDiv(CssClass.CLASS_BOILERPLATE);
599
            output.print(boilerplate);
600
            output.endDiv(CssClass.CLASS_BOILERPLATE);
601
            output.hr();
602
         }
603
      }
604
 
605
      if (!optionNoNavBar.getValue()) {
606
         output.beginDiv(CssClass.NAVBAR_BOTTOM_SPACER);
607
         output.print(" ");
608
         output.endDiv(CssClass.NAVBAR_BOTTOM_SPACER);
609
         output.beginTable(CssClass.NAVBAR_BOTTOM);
610
         output.beginRow();
611
         output.beginCell();
612
         printNavBar(output, currentPage, currentClass);
613
         output.endCell();
614
         if (null != optionFooter.getValue()) {
615
            output.beginCell();
616
            output.print(replaceDocRoot(output, optionFooter.getValue()));
617
            output.endCell();
618
         }
619
         output.endRow();
620
         output.endTable();
621
      }
622
 
623
      if (null != optionBottom.getValue()) {
624
         output.hr();
625
         output.print(replaceDocRoot(output, optionBottom.getValue()));
626
      }
627
   }
628
 
629
   private void printPackagePageClasses(HtmlPage output, ClassDoc[] classDocs, String header)
630
   {
631
      if (classDocs.length > 0) {
632
         output.beginDiv(CssClass.TABLE_CONTAINER);
633
         output.beginTable(CssClass.PACKAGE_SUMMARY, new String[] { "border", "width" }, new String[] { "1", "100%" });
634
         output.rowDiv(CssClass.TABLE_HEADER, header);
635
 
636
         for (int i=0; i<classDocs.length; ++i) {
637
            ClassDoc classDoc = classDocs[i];
638
            if (classDoc.isIncluded()) {
639
               output.beginRow();
640
 
641
               output.beginCell(CssClass.PACKAGE_SUMMARY_LEFT);
642
               printType(output, classDoc);
643
               output.endCell();
644
 
645
               output.beginCell(CssClass.PACKAGE_SUMMARY_RIGHT);
646
               printTags(output, classDoc, classDoc.firstSentenceTags(), true);
647
               output.endCell();
648
               output.endRow();
649
            }
650
         }
651
         output.endTable();
652
         output.endDiv(CssClass.TABLE_CONTAINER);
653
         output.print("\n");
654
      }
655
   }
656
 
657
   private void printPackagesListFile()
658
      throws IOException
659
   {
660
      PrintWriter out
661
         = new PrintWriter(new OutputStreamWriter(new FileOutputStream(new File(getTargetDirectory(),
662
                                                                                "package-list")),
663
                                                  "UTF-8"));
664
 
665
      PackageDoc[] packages = getRootDoc().specifiedPackages();
666
      for (int i=0; i<packages.length; ++i) {
667
         String packageName = packages[i].name();
668
         if (packageName.length() > 0) {
669
            out.println(packageName);
670
         }
671
      }
672
 
673
      out.close();
674
   }
675
 
676
   private void printPackagePage(File packageDir, String pathToRoot,
677
                                 PackageDoc packageDoc,
678
                                 PackageDoc prevPackageDoc,
679
                                 PackageDoc nextPackageDoc)
680
      throws IOException
681
   {
682
      HtmlPage output = newHtmlPage(new File(packageDir, "package-summary" + filenameExtension),
683
                                    pathToRoot);
684
 
685
      Set keywords = new LinkedHashSet();
686
      keywords.add(packageDoc.name() + " packages");
687
 
688
      output.beginPage(getPageTitle(packageDoc.name()), getOutputCharset(),
689
                       keywords, getStylesheets());
690
      output.beginBody(CssClass.BODY_CONTENT_PACKAGE);
691
      printNavBarTopPackage(output, "package", prevPackageDoc, nextPackageDoc);
692
 
693
      output.beginDiv(CssClass.PACKAGE_TITLE);
694
      output.print("Package ");
695
      if (packageDoc.name().length() > 0) {
696
         output.print(packageDoc.name());
697
      }
698
      else {
699
         output.print("&lt;Unnamed&gt;");
700
      }
701
      output.endDiv(CssClass.PACKAGE_TITLE);
702
 
703
      output.beginDiv(CssClass.PACKAGE_DESCRIPTION_TOP);
704
      printTags(output, packageDoc, packageDoc.firstSentenceTags(), true);
705
      output.endDiv(CssClass.PACKAGE_DESCRIPTION_TOP);
706
 
707
      printPackagePageClasses(output, packageDoc.interfaces(),
708
                              "Interface Summary");
709
      printPackagePageClasses(output, packageDoc.ordinaryClasses(),
710
                              "Class Summary");
711
      printPackagePageClasses(output, packageDoc.exceptions(),
712
                              "Exception Summary");
713
      printPackagePageClasses(output, packageDoc.errors(),
714
                              "Error Summary");
715
 
716
      output.anchorName("description");
717
      output.beginDiv(CssClass.PACKAGE_DESCRIPTION_FULL);
718
      printTags(output, packageDoc, packageDoc.inlineTags(), false);
719
      output.endDiv(CssClass.PACKAGE_DESCRIPTION_FULL);
720
 
721
      printNavBarBottom(output, "package");
722
      output.endBody();
723
      output.endPage();
724
      output.close();
725
   }
726
 
727
   static class TreeNode
728
      implements Comparable
729
   {
730
      ClassDoc classDoc;
731
      SortedSet children = new TreeSet();
732
 
733
      TreeNode(ClassDoc classDoc) {
734
         TreeNode.this.classDoc = classDoc;
735
      }
736
 
737
      public boolean equals(Object other)
738
      {
739
         return classDoc.equals(((TreeNode)other).classDoc);
740
      }
741
 
742
      public int compareTo(Object other)
743
      {
744
         return classDoc.compareTo(((TreeNode)other).classDoc);
745
      }
746
 
747
      public int hashCode()
748
      {
749
         return classDoc.hashCode();
750
      }
751
   }
752
 
753
   private TreeNode addClassTreeNode(Map treeMap, ClassDoc classDoc)
754
   {
755
      TreeNode node = (TreeNode)treeMap.get(classDoc.qualifiedName());
756
      if (null == node) {
757
         node = new TreeNode(classDoc);
758
         treeMap.put(classDoc.qualifiedName(), node);
759
 
760
         ClassDoc superClassDoc = (ClassDoc)classDoc.superclass();
761
         if (null != superClassDoc) {
762
            TreeNode parentNode = addClassTreeNode(treeMap, superClassDoc);
763
            parentNode.children.add(node);
764
         }
765
      }
766
      return node;
767
   }
768
 
769
   private TreeNode addInterfaceTreeNode(Map treeMap, ClassDoc classDoc)
770
   {
771
      TreeNode node = (TreeNode)treeMap.get(classDoc.qualifiedName());
772
      if (null == node) {
773
         node = new TreeNode(classDoc);
774
         treeMap.put(classDoc.qualifiedName(), node);
775
 
776
         ClassDoc[] superInterfaces = classDoc.interfaces();
777
         if (null != superInterfaces && superInterfaces.length > 0) {
778
            for (int i=0; i<superInterfaces.length; ++i) {
779
               TreeNode parentNode = addInterfaceTreeNode(treeMap, superInterfaces[i]);
780
               parentNode.children.add(node);
781
            }
782
         }
783
         else {
784
            TreeNode rootNode = (TreeNode)treeMap.get("<root>");
785
            if (null == rootNode) {
786
               rootNode = new TreeNode(null);
787
               treeMap.put("<root>", rootNode);
788
            }
789
            rootNode.children.add(node);
790
         }
791
      }
792
      return node;
793
   }
794
 
795
   private void printPackageTreeRec(HtmlPage output, TreeNode node, TreeNode parentNode)
796
   {
797
      output.beginElement("li", "class", "node");
798
      output.beginElement("div");
799
      if (node.classDoc.isIncluded()) {
800
         String packageName = node.classDoc.containingPackage().name();
801
         if (packageName.length() > 0) {
802
            output.print(packageName);
803
            output.print(".");
804
         }
805
         output.beginSpan(CssClass.TREE_LINK);
806
         printType(output, node.classDoc);
807
         output.endSpan(CssClass.TREE_LINK);
808
      }
809
      else {
810
         output.print(possiblyQualifiedName(node.classDoc));
811
      }
812
      ClassDoc[] interfaces = node.classDoc.interfaces();
813
      ClassDoc parentClassDoc = null;
814
      if (null != parentNode) {
815
         parentClassDoc = parentNode.classDoc;
816
      }
817
      if (interfaces.length > 0
818
          && !(interfaces.length == 1 && interfaces[0].equals(parentClassDoc))) {
819
         if (node.classDoc.isInterface()) {
820
            output.print(" (also implements ");
821
         }
822
         else {
823
            output.print(" (implements ");
824
         }
825
 
826
         boolean firstItem = true;
827
         for (int i=0; i<interfaces.length; ++i) {
828
            ClassDoc implemented = interfaces[i];
829
            if (!implemented.equals(parentClassDoc)) {
830
               if (!firstItem) {
831
                  output.print(", ");
832
               }
833
               firstItem = false;
834
               if (implemented.isIncluded()) {
835
                  output.print(implemented.containingPackage().name());
836
                  output.print(".");
837
                  printType(output, implemented);
838
               }
839
               else {
840
                  output.print(possiblyQualifiedName(implemented));
841
               }
842
            }
843
         }
844
         output.print(")");
845
      }
846
 
847
      output.endElement("div");
848
      output.endElement("li");
849
      if (!node.children.isEmpty()) {
850
         output.beginElement("li", "class", "level");
851
         output.beginElement("ul");
852
         Iterator it = node.children.iterator();
853
         while (it.hasNext()) {
854
            TreeNode child = (TreeNode)it.next();
855
            printPackageTreeRec(output, child, node);
856
         }
857
         output.endElement("ul");
858
         output.endElement("li");
859
      }
860
   }
861
 
862
   private void printClassTree(HtmlPage output, ClassDoc[] classDocs)
863
   {
864
      Map classTreeMap = new HashMap();
865
 
866
      for (int i=0; i<classDocs.length; ++i) {
867
         ClassDoc classDoc = classDocs[i];
868
         if (!classDoc.isInterface()) {
869
            addClassTreeNode(classTreeMap, classDoc);
870
         }
871
      }
872
 
873
      TreeNode root = (TreeNode)classTreeMap.get("java.lang.Object");
874
      if (null != root) {
875
         output.div(CssClass.PACKAGE_TREE_SECTION_TITLE, "Class Hierarchy");
876
         output.beginDiv(CssClass.PACKAGE_TREE);
877
         printPackageTreeRec(output, root, null);
878
         output.endDiv(CssClass.PACKAGE_TREE);
879
      }
880
   }
881
 
882
   private void printInterfaceTree(HtmlPage output, ClassDoc[] classDocs)
883
   {
884
      Map interfaceTreeMap = new HashMap();
885
 
886
      for (int i=0; i<classDocs.length; ++i) {
887
         ClassDoc classDoc = classDocs[i];
888
         if (classDoc.isInterface()) {
889
            addInterfaceTreeNode(interfaceTreeMap, classDoc);
890
         }
891
      }
892
 
893
      TreeNode interfaceRoot = (TreeNode)interfaceTreeMap.get("<root>");
894
      if (null != interfaceRoot) {
895
         Iterator it = interfaceRoot.children.iterator();
896
         if (it.hasNext()) {
897
            output.div(CssClass.PACKAGE_TREE_SECTION_TITLE, "Interface Hierarchy");
898
            output.beginDiv(CssClass.PACKAGE_TREE);
899
            while (it.hasNext()) {
900
               TreeNode node = (TreeNode)it.next();
901
               printPackageTreeRec(output, node, null);
902
            }
903
            output.endDiv(CssClass.PACKAGE_TREE);
904
         }
905
      }
906
 
907
   }
908
 
909
   private void printPackageTreePage(File packageDir, String pathToRoot, PackageDoc packageDoc)
910
      throws IOException
911
   {
912
      HtmlPage output = newHtmlPage(new File(packageDir,
913
                                             "tree" + filenameExtension),
914
                                    pathToRoot);
915
      output.beginPage(getPageTitle(packageDoc.name() + " Hierarchy"),
916
                       getOutputCharset(),
917
                       getStylesheets());
918
      output.beginBody(CssClass.BODY_CONTENT_PACKAGE_TREE);
919
      printNavBarTop(output, "package-tree");
920
 
921
      output.div(CssClass.PACKAGE_TREE_TITLE, "Hierarchy for Package " + packageDoc.name());
922
 
923
      ClassDoc[] classDocs = packageDoc.allClasses();
924
      printClassTree(output, classDocs);
925
      printInterfaceTree(output, classDocs);
926
 
927
      printNavBarBottom(output, "package-tree");
928
      output.endBody();
929
      output.endPage();
930
      output.close();
931
   }
932
 
933
   private void printFullTreePage()
934
      throws IOException
935
   {
936
      HtmlPage output = newHtmlPage(new File(getTargetDirectory(),
937
                                             "tree" + filenameExtension),
938
                                    ".");
939
      output.beginPage(getPageTitle("Hierarchy"),
940
                       getOutputCharset(),
941
                       getStylesheets());
942
      output.beginBody(CssClass.BODY_CONTENT_FULL_TREE);
943
      printNavBarTop(output, "full-tree");
944
 
945
      output.div(CssClass.PACKAGE_TREE_TITLE, "Hierarchy for All Packages");
946
 
947
      output.beginDiv(CssClass.FULL_TREE_PACKAGELIST);
948
      output.div(CssClass.FULL_TREE_PACKAGELIST_HEADER, "Package Hierarchies:");
949
      output.beginDiv(CssClass.FULL_TREE_PACKAGELIST_ITEM);
950
      Set allPackages = getAllPackages();
951
      Iterator it = allPackages.iterator();
952
      while (it.hasNext()) {
953
         PackageDoc packageDoc = (PackageDoc)it.next();
954
         output.beginAnchor(getPackageURL(packageDoc) + "tree" + filenameExtension);
955
         output.print(packageDoc.name());
956
         output.endAnchor();
957
         if (it.hasNext()) {
958
            output.print(", ");
959
         }
960
      }
961
      output.endDiv(CssClass.FULL_TREE_PACKAGELIST_ITEM);
962
      output.endDiv(CssClass.FULL_TREE_PACKAGELIST);
963
 
964
      ClassDoc[] classDocs = getRootDoc().classes();
965
      printClassTree(output, classDocs);
966
      printInterfaceTree(output, classDocs);
967
 
968
      printNavBarBottom(output, "full-tree");
969
      output.endBody();
970
      output.endPage();
971
      output.close();
972
   }
973
 
974
   private void printIndexEntry(HtmlPage output, Doc entry)
975
   {
976
      output.beginDiv(CssClass.INDEX_ENTRY);
977
      output.beginDiv(CssClass.INDEX_ENTRY_KEY);
978
      String anchor = null;
979
      String description = null;
980
      if (entry instanceof PackageDoc) {
981
         output.beginAnchor(getPackageURL((PackageDoc)entry) + "package-summary" + filenameExtension);
982
         output.print(entry.name());
983
         output.endAnchor();
984
         output.print(" - package");
985
      }
986
      else if (entry instanceof ClassDoc) {
987
         ClassDoc classDoc = (ClassDoc)entry;
988
         output.beginAnchor(getClassURL(classDoc));
989
         output.print(entry.name() + getTypeParameters(classDoc));
990
         output.endAnchor();
991
         output.print(" - ");
992
         if (entry.isInterface()) {
993
            output.print("interface ");
994
         }
995
         else if (entry.isException()) {
996
            output.print("exception ");
997
         }
998
         else if (entry.isError()) {
999
            output.print("error ");
1000
         }
1001
         else {
1002
            output.print("class ");
1003
         }
1004
         String packageName = classDoc.containingPackage().name();
1005
         if (packageName.length() > 0) {
1006
            output.print(packageName);
1007
            output.print(".");
1008
         }
1009
         printType(output, classDoc);
1010
      }
1011
      else {
1012
         ProgramElementDoc memberDoc = (ProgramElementDoc)entry;
1013
         output.beginAnchor(getMemberDocURL(output, memberDoc));
1014
         output.print(entry.name());
1015
         if (memberDoc instanceof ExecutableMemberDoc) {
1016
            output.print(((ExecutableMemberDoc)memberDoc).signature());
1017
         }
1018
         output.endAnchor();
1019
         output.print(" - ");
1020
 
1021
         if (memberDoc.isStatic()) {
1022
            output.print("static ");
1023
         }
1024
 
1025
         if (entry.isConstructor()) {
1026
            output.print("constructor for class ");
1027
         }
1028
         else if (entry.isMethod()) {
1029
            output.print("method in class ");
1030
         }
1031
         else if (entry.isField()) {
1032
            output.print("field in class ");
1033
         }
1034
         ClassDoc containingClass = memberDoc.containingClass();
1035
         String packageName = containingClass.containingPackage().name();
1036
         if (packageName.length() > 0) {
1037
            output.print(packageName);
1038
            output.print(".");
1039
         }
1040
         printType(output, containingClass);
1041
      }
1042
      output.endDiv(CssClass.INDEX_ENTRY_KEY);
1043
      output.beginDiv(CssClass.INDEX_ENTRY_DESCRIPTION);
1044
      printTags(output, entry, entry.firstSentenceTags(), true);
1045
      output.endDiv(CssClass.INDEX_ENTRY_DESCRIPTION);
1046
      output.endDiv(CssClass.INDEX_ENTRY);
1047
   }
1048
 
1049
   private void printFrameSetPage()
1050
      throws IOException
1051
   {
1052
      HtmlPage output = newHtmlPage(new File(getTargetDirectory(),
1053
                                             "index" + filenameExtension),
1054
                                    ".",
1055
                                    HtmlPage.DOCTYPE_FRAMESET);
1056
 
1057
      String title = getWindowTitle();
1058
      output.beginPage(title, getOutputCharset(), getStylesheets());
1059
      output.beginElement("frameset", "cols", "20%,80%");
1060
 
1061
      String contentURL;
1062
      if (isSinglePackage()) {
1063
         output.atomicElement("frame",
1064
                              new String[] { "src", "name" },
1065
                              new String[] { getPackageURL(getSinglePackage()) + "classes" + filenameExtension, "classes" });
1066
         contentURL = getPackageURL(getSinglePackage()) + "package-summary.html";
1067
      }
1068
      else {
1069
         output.beginElement("frameset", "rows", "25%,75%");
1070
         output.atomicElement("frame",
1071
                              new String[] { "src", "name" },
1072
                              new String[] { "all-packages" + filenameExtension, "packages" });
1073
         output.atomicElement("frame",
1074
                              new String[] { "src", "name" },
1075
                              new String[] { "all-classes" + filenameExtension, "classes" });
1076
         output.endElement("frameset");
1077
         contentURL = "overview-summary" + filenameExtension;
1078
      }
1079
      output.atomicElement("frame",
1080
                           new String[] { "src", "name" },
1081
                           new String[] { contentURL, "content" });
1082
      output.endElement("frameset");
1083
      output.endPage();
1084
      output.close();
1085
   }
1086
 
1087
   private void printPackagesMenuPage()
1088
      throws IOException
1089
   {
1090
      HtmlPage output = newHtmlPage(new File(getTargetDirectory(),
1091
                                             "all-packages" + filenameExtension),
1092
                                    ".");
1093
      output.beginPage(getPageTitle("Package Menu"), getOutputCharset(), getStylesheets());
1094
      output.beginBody(CssClass.BODY_MENU_PACKAGES, false);
1095
 
1096
      output.beginSpan(CssClass.PACKAGE_MENU_ENTRY);
1097
      output.beginAnchor("all-classes" + filenameExtension,
1098
                         null,
1099
                         "classes");
1100
      output.print("All Classes");
1101
      output.endAnchor();
1102
      output.endSpan(CssClass.PACKAGE_MENU_ENTRY);
1103
 
1104
      output.div(CssClass.PACKAGE_MENU_TITLE, "Packages");
1105
 
1106
      output.beginDiv(CssClass.PACKAGE_MENU_LIST);
1107
 
1108
      Set packageDocs = getAllPackages();
1109
      Iterator it = packageDocs.iterator();
1110
      while (it.hasNext()) {
1111
         PackageDoc packageDoc = (PackageDoc)it.next();
1112
         output.beginSpan(CssClass.PACKAGE_MENU_ENTRY);
1113
         output.beginAnchor(getPackageURL(packageDoc) + "classes" + filenameExtension,
1114
                            null,
1115
                            "classes");
1116
         if (packageDoc.name().length() > 0) {
1117
            output.print(packageDoc.name());
1118
         }
1119
         else {
1120
            output.print("&lt;unnamed package&gt;");
1121
         }
1122
         output.endAnchor();
1123
         output.endSpan(CssClass.PACKAGE_MENU_ENTRY);
1124
         output.br();
1125
      }
1126
 
1127
      output.endDiv(CssClass.PACKAGE_MENU_LIST);
1128
      output.endBody();
1129
      output.endPage();
1130
      output.close();
1131
   }
1132
 
1133
   private void printClassMenuEntry(HtmlPage output, ClassDoc classDoc)
1134
   {
1135
      CssClass entryClass;
1136
      if (classDoc.isInterface()) {
1137
         entryClass = CssClass.CLASS_MENU_ENTRY_INTERFACE;
1138
      }
1139
      else {
1140
         entryClass = CssClass.CLASS_MENU_ENTRY_CLASS;
1141
      }
1142
      output.beginSpan(entryClass);
1143
      output.beginAnchor(getClassDocURL(output, classDoc),
1144
                         classDoc.qualifiedTypeName(),
1145
                         "content");
1146
      output.print(classDoc.name());
1147
      output.endAnchor();
1148
      output.endSpan(entryClass);
1149
      output.br();
1150
   }
1151
 
1152
   private void printClassMenuSection(HtmlPage output, Collection classDocs, String header)
1153
   {
1154
      if (!classDocs.isEmpty()) {
1155
         output.div(CssClass.CLASS_MENU_SUBTITLE, header);
1156
         Iterator it = classDocs.iterator();
1157
         while (it.hasNext()) {
1158
            ClassDoc classDoc = (ClassDoc)it.next();
1159
            printClassMenuEntry(output, classDoc);
1160
         }
1161
      }
1162
   }
1163
 
1164
   private void printClassMenuList(HtmlPage output, ClassDoc[] classDocs, boolean categorized)
1165
   {
1166
      output.beginDiv(CssClass.CLASS_MENU_LIST);
1167
 
1168
      if (categorized) {
1169
         Set classes = new TreeSet();
1170
         Set interfaces = new TreeSet();
1171
         Set exceptions = new TreeSet();
1172
         Set errors = new TreeSet();
1173
 
1174
         for (int i=0; i<classDocs.length; ++i) {
1175
            ClassDoc classDoc = classDocs[i];
1176
            if (classDoc.isInterface()) {
1177
               interfaces.add(classDoc);
1178
            }
1179
            else if (classDoc.isException()) {
1180
               exceptions.add(classDoc);
1181
            }
1182
            else if (classDoc.isError()) {
1183
               errors.add(classDoc);
1184
            }
1185
            else {
1186
               classes.add(classDoc);
1187
            }
1188
         }
1189
         printClassMenuSection(output, interfaces, "Interfaces");
1190
         printClassMenuSection(output, classes, "Classes");
1191
         printClassMenuSection(output, exceptions, "Exceptions");
1192
         printClassMenuSection(output, errors, "Errors");
1193
      }
1194
      else {
1195
         for (int i=0; i<classDocs.length; ++i) {
1196
            ClassDoc classDoc = classDocs[i];
1197
            if (classDoc.isIncluded()) {
1198
               printClassMenuEntry(output, classDoc);
1199
            }
1200
         }
1201
      }
1202
 
1203
      output.endDiv(CssClass.CLASS_MENU_LIST);
1204
   }
1205
 
1206
   private void printAllClassesMenuPage()
1207
      throws IOException
1208
   {
1209
      HtmlPage output = newHtmlPage(new File(getTargetDirectory(),
1210
                                             "all-classes" + filenameExtension),
1211
                                    ".");
1212
      output.beginPage(getPageTitle("Class Menu"), getOutputCharset(), getStylesheets());
1213
      output.beginBody(CssClass.BODY_MENU_CLASSES, false);
1214
 
1215
      output.div(CssClass.CLASS_MENU_TITLE, "All Classes");
1216
 
1217
      printClassMenuList(output, getRootDoc().classes(), false);
1218
 
1219
      output.endBody();
1220
      output.endPage();
1221
      output.close();
1222
   }
1223
 
1224
   private void printPackageClassesMenuPage(File packageDir, String pathToRoot, PackageDoc packageDoc)
1225
      throws IOException
1226
   {
1227
      HtmlPage output = newHtmlPage(new File(packageDir,
1228
                                             "classes" + filenameExtension),
1229
                                    pathToRoot);
1230
 
1231
      output.beginPage(getPageTitle(packageDoc.name() + " Class Menu"),
1232
                       getOutputCharset(), getStylesheets());
1233
      output.beginBody(CssClass.BODY_MENU_CLASSES, false);
1234
 
1235
      output.beginDiv(CssClass.CLASS_MENU_TITLE);
1236
      output.beginAnchor("package-summary" + filenameExtension, "", "content");
1237
      if (packageDoc.name().length() > 0) {
1238
         output.print(packageDoc.name());
1239
      }
1240
      else {
1241
         output.print("&lt;Unnamed&gt;");
1242
      }
1243
      output.endAnchor();
1244
      output.endDiv(CssClass.CLASS_MENU_TITLE);
1245
 
1246
      printClassMenuList(output, packageDoc.allClasses(), true);
1247
 
1248
      output.endBody();
1249
      output.endPage();
1250
      output.close();
1251
   }
1252
 
1253
   private void printSplitIndex()
1254
      throws IOException
1255
   {
1256
      Map categorizedIndex = getCategorizedIndex();
1257
      Iterator it = categorizedIndex.keySet().iterator();
1258
      int n = 1;
1259
      int count = categorizedIndex.size();
1260
      while (it.hasNext()) {
1261
         Character c = (Character)it.next();
1262
         List classList = (List)categorizedIndex.get(c);
1263
         printIndexPage(n++, count, c, classList);
1264
      }
1265
   }
1266
 
1267
   private void printIndexPage()
1268
      throws IOException
1269
   {
1270
      printIndexPage(0, 0, null, null);
1271
   }
1272
 
1273
   private void printIndexPage(int index, int maxIndex, Character letter, List classList)
1274
      throws IOException
1275
   {
1276
      String pageName = "alphaindex";
1277
      if (null != letter) {
1278
         pageName += "-" + index;
1279
      }
1280
      HtmlPage output = newHtmlPage(new File(getTargetDirectory(),
1281
                                             pageName + filenameExtension),
1282
                                    ".");
1283
      output.beginPage(getPageTitle("Alphabetical Index"),
1284
                       getOutputCharset(),
1285
                       getStylesheets());
1286
      output.beginBody(CssClass.BODY_CONTENT_INDEX);
1287
      if (null == letter) {
1288
         printNavBarTop(output, "index");
1289
      }
1290
      else {
1291
         printNavBarTop(output, "split-index", null,
1292
                        (index > 1) ? new Integer(index - 1) : null,
1293
                        (index < maxIndex) ? new Integer(index + 1) : null);
1294
      }
1295
 
1296
      {
1297
         String title;
1298
         if (null == letter) {
1299
            title = "Alphabetical Index";
1300
         }
1301
         else {
1302
            title = "Alphabetical Index: " + letter;
1303
         }
1304
         output.div(CssClass.INDEX_TITLE, title);
1305
 
1306
         if (null != letter || getCategorizedIndex().keySet().size() > 1) {
1307
            output.beginDiv(CssClass.INDEX_LETTERS);
1308
 
1309
            Iterator it = getCategorizedIndex().keySet().iterator();
1310
            int n = 1;
1311
            while (it.hasNext()) {
1312
               Character c = (Character)it.next();
1313
               output.beginSpan(CssClass.INDEX_LETTER);
1314
               if (letter != null) {
1315
                  output.beginAnchor("alphaindex-" + n + filenameExtension);
1316
               }
1317
               else {
1318
                  output.beginAnchor("#" + c);
1319
               }
1320
               output.print(c.toString());
1321
               output.endAnchor();
1322
               output.endSpan(CssClass.INDEX_LETTER);
1323
               output.beginSpan(CssClass.INDEX_LETTER_SPACER);
1324
               output.print(" ");
1325
               output.endSpan(CssClass.INDEX_LETTER_SPACER);
1326
               ++n;
1327
            }
1328
         }
1329
 
1330
         output.endDiv(CssClass.INDEX_LETTERS);
1331
      }
1332
 
1333
      if (null != letter) {
1334
         printIndexCategory(output, letter, classList);
1335
      }
1336
      else {
1337
         Map categorizedIndex = getCategorizedIndex();
1338
         Iterator categoryIt = categorizedIndex.keySet().iterator();
1339
 
1340
         while (categoryIt.hasNext()) {
1341
            letter = (Character)categoryIt.next();
1342
            classList = (List)categorizedIndex.get(letter);
1343
            output.anchorName(letter.toString());
1344
            printIndexCategory(output, letter, classList);
1345
         }
1346
      }
1347
 
1348
      printNavBarBottom(output, "index");
1349
      output.endBody();
1350
      output.endPage();
1351
      output.close();
1352
   }
1353
 
1354
   private void printIndexCategory(HtmlPage output, Character letter, List classList)
1355
   {
1356
      Iterator it = classList.iterator();
1357
 
1358
      output.div(CssClass.INDEX_CATEGORY_HEADER, letter.toString());
1359
      output.beginDiv(CssClass.INDEX_CATEGORY);
1360
      while (it.hasNext()) {
1361
         Doc entry = (Doc)it.next();
1362
         printIndexEntry(output, entry);
1363
      }
1364
      output.endDiv(CssClass.INDEX_CATEGORY);
1365
   }
1366
 
1367
   private void printDeprecationSummary(HtmlPage output, List docs, String header)
1368
   {
1369
      if (!docs.isEmpty()) {
1370
         output.beginDiv(CssClass.TABLE_CONTAINER);
1371
         output.beginTable(CssClass.DEPRECATION_SUMMARY, new String[] { "border", "width" }, new String[] { "1", "100%" });
1372
         output.rowDiv(CssClass.TABLE_HEADER, header);
1373
 
1374
         Iterator it = docs.iterator();
1375
         while (it.hasNext()) {
1376
            Doc doc = (Doc)it.next();
1377
            output.beginRow();
1378
 
1379
            output.beginCell(CssClass.DEPRECATION_SUMMARY_LEFT);
1380
            if (doc instanceof Type) {
1381
               printType(output, (Type)doc);
1382
            }
1383
            else {
1384
               ProgramElementDoc memberDoc = (ProgramElementDoc)doc;
1385
               output.beginAnchor(getMemberDocURL(output, memberDoc));
1386
               output.print(memberDoc.containingClass().qualifiedName());
1387
               output.print(".");
1388
               output.print(memberDoc.name());
1389
               if (memberDoc instanceof ExecutableMemberDoc) {
1390
                  output.print(((ExecutableMemberDoc)memberDoc).flatSignature());
1391
               }
1392
               output.endAnchor();
1393
            }
1394
            output.beginDiv(CssClass.DEPRECATION_SUMMARY_DESCRIPTION);
1395
            printTags(output, doc, doc.tags("deprecated")[0].firstSentenceTags(), true);
1396
            output.endDiv(CssClass.DEPRECATION_SUMMARY_DESCRIPTION);
1397
 
1398
            output.endCell();
1399
 
1400
            output.endRow();
1401
         }
1402
         output.endTable();
1403
         output.endDiv(CssClass.TABLE_CONTAINER);
1404
         output.print("\n");
1405
      }
1406
   }
1407
 
1408
 
1409
   private void printSerializationPage()
1410
      throws IOException
1411
   {
1412
      HtmlPage output = newHtmlPage(new File(getTargetDirectory(),
1413
                                             "serialized-form" + filenameExtension),
1414
                                    ".");
1415
      output.beginPage(getPageTitle("Serialized Form"),
1416
                       getOutputCharset(),
1417
                       getStylesheets());
1418
      output.beginBody(CssClass.BODY_CONTENT_DEPRECATED);
1419
      printNavBarTop(output, "serialized");
1420
 
1421
      output.div(CssClass.SERIALIZED_TITLE, "Serialized Form");
1422
 
1423
      Iterator it = getAllPackages().iterator();
1424
 
1425
      while (it.hasNext()) {
1426
 
1427
         PackageDoc packageDoc = (PackageDoc)it.next();
1428
 
1429
         List serializableClasses = new LinkedList();
1430
         ClassDoc[] classes = packageDoc.allClasses();
1431
         for (int i=0; i<classes.length; ++i) {
1432
            ClassDoc classDoc = classes[i];
1433
            if (classDoc.isSerializable() || classDoc.isExternalizable()) {
1434
               serializableClasses.add(classDoc);
1435
            }
1436
         }
1437
 
1438
         if (!serializableClasses.isEmpty()) {
1439
            output.div(CssClass.SERIALIZED_PACKAGE_HEADER, "Package " + packageDoc.name());
1440
 
1441
            Iterator cit = serializableClasses.iterator();
1442
            while (cit.hasNext()) {
1443
               ClassDoc classDoc = (ClassDoc)cit.next();
1444
 
1445
               output.anchorName(classDoc.qualifiedTypeName());
1446
 
1447
               output.beginDiv(CssClass.SERIALIZED_CLASS_HEADER);
1448
               output.print("Class ");
1449
               printType(output, classDoc, true);
1450
               output.print(" extends ");
1451
               printType(output, classDoc.superclass());
1452
               output.print(" implements Serializable");
1453
               output.endDiv(CssClass.SERIALIZED_CLASS_HEADER);
1454
 
1455
               FieldDoc serialVersionUidField = findField(classDoc, "serialVersionUID");
1456
               if (null != serialVersionUidField
1457
                   && serialVersionUidField.isFinal()
1458
                   && serialVersionUidField.isStatic()
1459
                   && serialVersionUidField.type().typeName().equals("long")) {
1460
 
1461
                  String fieldValue = serialVersionUidField.constantValueExpression();
1462
                  if (null != fieldValue) {
1463
                     output.beginDiv(CssClass.SERIALIZED_SVUID_OUTER);
1464
                     output.span(CssClass.SERIALIZED_SVUID_HEADER, "serialVersionUID: ");
1465
                     output.span(CssClass.SERIALIZED_SVUID_VALUE, fieldValue);
1466
                     output.endDiv(CssClass.SERIALIZED_SVUID_OUTER);
1467
                  }
1468
               }
1469
               printMemberDetails(output,
1470
                                  classDoc.serializationMethods(),
1471
                                  "Serialization Methods",
1472
                                  true, null);
1473
               printMemberDetails(output,
1474
                                  classDoc.serializableFields(),
1475
                                  "Serialized Fields",
1476
                                  true, null);
1477
            }
1478
         }
1479
      }
1480
 
1481
      printNavBarBottom(output, "serialized");
1482
 
1483
      output.endBody();
1484
      output.endPage();
1485
      output.close();
1486
   }
1487
 
1488
 
1489
   private void printDeprecationPage()
1490
      throws IOException
1491
   {
1492
      HtmlPage output = newHtmlPage(new File(getTargetDirectory(),
1493
                                             "deprecated" + filenameExtension),
1494
                                    ".");
1495
      output.beginPage(getPageTitle("Deprecated API"),
1496
                       getOutputCharset(),
1497
                       getStylesheets());
1498
      output.beginBody(CssClass.BODY_CONTENT_DEPRECATED);
1499
      printNavBarTop(output, "deprecated");
1500
 
1501
      output.div(CssClass.DEPRECATION_TITLE, "Deprecated API");
1502
 
1503
      List deprecatedInterfaces = new LinkedList();
1504
      List deprecatedExceptions = new LinkedList();
1505
      List deprecatedErrors = new LinkedList();
1506
      List deprecatedClasses = new LinkedList();
1507
      List deprecatedFields = new LinkedList();
1508
      List deprecatedMethods = new LinkedList();
1509
      List deprecatedConstructors = new LinkedList();
1510
 
1511
      ClassDoc[] classDocs = getRootDoc().classes();
1512
      for (int i=0; i<classDocs.length; ++i) {
1513
         ClassDoc classDoc = classDocs[i];
1514
         {
1515
            Tag[] deprecatedTags = classDoc.tags("deprecated");
1516
            if (null != deprecatedTags && deprecatedTags.length > 0) {
1517
               if (classDoc.isInterface()) {
1518
                  deprecatedInterfaces.add(classDoc);
1519
               }
1520
               else if (classDoc.isException()) {
1521
                  deprecatedExceptions.add(classDoc);
1522
               }
1523
               else if (classDoc.isError()) {
1524
                  deprecatedErrors.add(classDoc);
1525
               }
1526
               else {
1527
                  deprecatedClasses.add(classDoc);
1528
               }
1529
            }
1530
         }
1531
         ConstructorDoc[] constructors = classDoc.constructors();
1532
         for (int j=0; j<constructors.length; ++j) {
1533
            Tag[] deprecatedTags = constructors[j].tags("deprecated");
1534
            if (null != deprecatedTags && deprecatedTags.length > 0) {
1535
               deprecatedConstructors.add(constructors[j]);
1536
            }
1537
         }
1538
         MethodDoc[] methods = classDoc.methods();
1539
         for (int j=0; j<methods.length; ++j) {
1540
            Tag[] deprecatedTags = methods[j].tags("deprecated");
1541
            if (null != deprecatedTags && deprecatedTags.length > 0) {
1542
               deprecatedMethods.add(methods[j]);
1543
            }
1544
         }
1545
         FieldDoc[] fields = classDoc.fields();
1546
         for (int j=0; j<fields.length; ++j) {
1547
            Tag[] deprecatedTags = fields[j].tags("deprecated");
1548
            if (null != deprecatedTags && deprecatedTags.length > 0) {
1549
               deprecatedFields.add(fields[j]);
1550
            }
1551
         }
1552
      }
1553
 
1554
      if (!deprecatedInterfaces.isEmpty()
1555
          || !deprecatedClasses.isEmpty()
1556
          || !deprecatedExceptions.isEmpty()
1557
          || !deprecatedErrors.isEmpty()
1558
          || !deprecatedFields.isEmpty()
1559
          || !deprecatedMethods.isEmpty()
1560
          || !deprecatedConstructors.isEmpty()) {
1561
 
1562
         output.beginDiv(CssClass.DEPRECATION_TOC);
1563
         output.div(CssClass.DEPRECATION_TOC_HEADER, "Contents");
1564
         output.beginDiv(CssClass.DEPRECATION_TOC_LIST);
1565
         if (!deprecatedInterfaces.isEmpty()) {
1566
            output.beginDiv(CssClass.DEPRECATION_TOC_ENTRY);
1567
            output.anchor("#interfaces", "Deprecated Interfaces");
1568
            output.endDiv(CssClass.DEPRECATION_TOC_ENTRY);
1569
         }
1570
         if (!deprecatedClasses.isEmpty()) {
1571
            output.beginDiv(CssClass.DEPRECATION_TOC_ENTRY);
1572
            output.anchor("#classes", "Deprecated Classes");
1573
            output.endDiv(CssClass.DEPRECATION_TOC_ENTRY);
1574
         }
1575
         if (!deprecatedExceptions.isEmpty()) {
1576
            output.beginDiv(CssClass.DEPRECATION_TOC_ENTRY);
1577
            output.anchor("#exceptions", "Deprecated Exceptions");
1578
            output.endDiv(CssClass.DEPRECATION_TOC_ENTRY);
1579
         }
1580
         if (!deprecatedErrors.isEmpty()) {
1581
            output.beginDiv(CssClass.DEPRECATION_TOC_ENTRY);
1582
            output.anchor("#errors", "Deprecated Errors");
1583
            output.endDiv(CssClass.DEPRECATION_TOC_ENTRY);
1584
         }
1585
         if (!deprecatedFields.isEmpty()) {
1586
            output.beginDiv(CssClass.DEPRECATION_TOC_ENTRY);
1587
            output.anchor("#fields", "Deprecated Fields");
1588
            output.endDiv(CssClass.DEPRECATION_TOC_ENTRY);
1589
         }
1590
         if (!deprecatedMethods.isEmpty()) {
1591
            output.beginDiv(CssClass.DEPRECATION_TOC_ENTRY);
1592
            output.anchor("#methods", "Deprecated Methods");
1593
            output.endDiv(CssClass.DEPRECATION_TOC_ENTRY);
1594
         }
1595
         if (!deprecatedConstructors.isEmpty()) {
1596
            output.beginDiv(CssClass.DEPRECATION_TOC_ENTRY);
1597
            output.anchor("#constructors", "Deprecated Constructors");
1598
            output.endDiv(CssClass.DEPRECATION_TOC_ENTRY);
1599
         }
1600
         output.endDiv(CssClass.DEPRECATION_TOC_LIST);
1601
         output.endDiv(CssClass.DEPRECATION_TOC);
1602
         output.beginDiv(CssClass.DEPRECATION_LIST);
1603
 
1604
         output.anchorName("interfaces");
1605
         printDeprecationSummary(output, deprecatedInterfaces, "Deprecated Interfaces");
1606
 
1607
         output.anchorName("classes");
1608
         printDeprecationSummary(output, deprecatedClasses, "Deprecated Classes");
1609
 
1610
         output.anchorName("exceptions");
1611
         printDeprecationSummary(output, deprecatedExceptions, "Deprecated Exceptions");
1612
 
1613
         output.anchorName("errors");
1614
         printDeprecationSummary(output, deprecatedErrors, "Deprecated Errors");
1615
 
1616
         output.anchorName("fields");
1617
         printDeprecationSummary(output, deprecatedFields, "Deprecated Fields");
1618
 
1619
         output.anchorName("methods");
1620
         printDeprecationSummary(output, deprecatedMethods, "Deprecated Methods");
1621
 
1622
         output.anchorName("constructors");
1623
         printDeprecationSummary(output, deprecatedConstructors, "Deprecated Constructors");
1624
 
1625
         output.endDiv(CssClass.DEPRECATION_LIST);
1626
      }
1627
      else {
1628
         output.beginDiv(CssClass.DEPRECATION_EMPTY);
1629
         output.print("No deprecated classes or class members in this API.");
1630
         output.endDiv(CssClass.DEPRECATION_EMPTY);
1631
 
1632
      }
1633
 
1634
      printNavBarBottom(output, "deprecated");
1635
      output.endBody();
1636
      output.endPage();
1637
      output.close();
1638
   }
1639
 
1640
   private void printAboutPage()
1641
      throws IOException
1642
   {
1643
      HtmlPage output = newHtmlPage(new File(getTargetDirectory(),
1644
                                             "about" + filenameExtension),
1645
                                    ".");
1646
      output.beginPage(getPageTitle("About"),
1647
                       getOutputCharset(),
1648
                       getStylesheets());
1649
      output.beginBody(CssClass.BODY_CONTENT_ABOUT);
1650
 
1651
      printNavBarTop(output, "about");
1652
 
1653
      output.div(CssClass.ABOUT_TITLE, "About");
1654
 
1655
      output.beginDiv(CssClass.ABOUT_GENERATOR);
1656
      output.print("Generated by ");
1657
      output.print("Gjdoc");
1658
      output.print(" HtmlDoclet ");
1659
      output.print(getDocletVersion());
1660
      output.print(", part of ");
1661
      output.beginAnchor("http://www.gnu.org/software/classpath/cp-tools/", "", "_top");
1662
      output.print("GNU Classpath Tools");
1663
      output.endAnchor();
1664
      output.print(", on ");
1665
      DateFormat format = DateFormat.getDateTimeInstance(DateFormat.LONG,
1666
                                                         DateFormat.LONG,
1667
                                                         Locale.US);
1668
      Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC"),
1669
                                          Locale.US);
1670
      format.setCalendar(cal);
1671
      output.print(format.format(new Date()));
1672
      output.print(".");
1673
      output.endDiv(CssClass.ABOUT_GENERATOR);
1674
 
1675
      printNavBarBottom(output, "about");
1676
 
1677
      output.endBody();
1678
      output.endPage();
1679
      output.close();
1680
   }
1681
 
1682
   private void printSourcePage(File packageDir, ClassDoc classDoc, String sourceXhtml)
1683
      throws IOException
1684
   {
1685
      HtmlPage output = newHtmlPage(new File(packageDir,
1686
                                             classDoc.name() + "-source" + filenameExtension),
1687
                                    getPathToRoot(packageDir, getTargetDirectory()));
1688
      output.beginPage(getPageTitle("Source for " + classDoc.qualifiedTypeName()),
1689
                       getOutputCharset(),
1690
                       getStylesheets());
1691
 
1692
      output.beginBody(CssClass.BODY_CONTENT_SOURCE);
1693
 
1694
      printNavBarTop(output, "source", classDoc, null, null);
1695
 
1696
      output.div(CssClass.SOURCE_TITLE, "Source for " + classDoc.qualifiedTypeName());
1697
      output.beginDiv(CssClass.SOURCE);
1698
      output.print(sourceXhtml);
1699
      output.endDiv(CssClass.SOURCE);
1700
 
1701
      printNavBarBottom(output, "source", classDoc);
1702
 
1703
      output.endBody();
1704
      output.endPage();
1705
 
1706
      output.close();
1707
   }
1708
 
1709
   private void printHelpPage()
1710
      throws IOException
1711
   {
1712
      HtmlPage output = newHtmlPage(new File(getTargetDirectory(),
1713
                                             "help" + filenameExtension),
1714
                                    ".");
1715
      output.beginPage(getPageTitle("Help"),
1716
                       getOutputCharset(),
1717
                       getStylesheets());
1718
      output.beginBody(CssClass.BODY_CONTENT_HELP);
1719
 
1720
      printNavBarTop(output, "help");
1721
 
1722
      InputStream helpIn;
1723
      if (null != optionHelpFile.getValue()){
1724
         helpIn = new FileInputStream(optionHelpFile.getValue());
1725
      }
1726
      else {
1727
         helpIn = getClass().getResourceAsStream("/htmldoclet/help.xhtml");
1728
      }
1729
      output.insert(new InputStreamReader(helpIn, "utf-8"));
1730
      helpIn.close();
1731
 
1732
      printNavBarBottom(output, "help");
1733
 
1734
      output.endBody();
1735
      output.endPage();
1736
      output.close();
1737
   }
1738
 
1739
   private void printOverviewPage()
1740
      throws IOException
1741
   {
1742
      HtmlPage output = newHtmlPage(new File(getTargetDirectory(),
1743
                                             "overview-summary" + filenameExtension),
1744
                                    ".");
1745
      output.beginPage(getWindowTitle(),
1746
                       getOutputCharset(),
1747
                       getStylesheets());
1748
      output.beginBody(CssClass.BODY_CONTENT_OVERVIEW);
1749
 
1750
      printNavBarTop(output, "overview");
1751
 
1752
      String overviewHeader;
1753
      if (null != optionDocTitle.getValue()) {
1754
         overviewHeader = optionDocTitle.getValue();
1755
      }
1756
      else if (null != optionTitle.getValue()) {
1757
         overviewHeader = optionTitle.getValue();
1758
      }
1759
      else {
1760
         overviewHeader = null;
1761
      }
1762
 
1763
      if (null != overviewHeader) {
1764
         output.div(CssClass.OVERVIEW_TITLE, overviewHeader);
1765
      }
1766
 
1767
      output.beginDiv(CssClass.OVERVIEW_DESCRIPTION_TOP);
1768
      printTags(output, getRootDoc(), getRootDoc().firstSentenceTags(), true);
1769
      output.endDiv(CssClass.OVERVIEW_DESCRIPTION_TOP);
1770
 
1771
      List packageGroups = getPackageGroups();
1772
 
1773
      if (packageGroups.isEmpty()) {
1774
 
1775
         printOverviewPackages(output, getAllPackages(),
1776
                               "All Packages");
1777
      }
1778
      else {
1779
         Set otherPackages = new LinkedHashSet();
1780
         otherPackages.addAll(getAllPackages());
1781
 
1782
         Iterator it = packageGroups.iterator();
1783
         while (it.hasNext()) {
1784
            PackageGroup packageGroup = (PackageGroup)it.next();
1785
            printOverviewPackages(output,
1786
                                  packageGroup.getPackages(),
1787
                                  packageGroup.getName());
1788
            otherPackages.removeAll(packageGroup.getPackages());
1789
         }
1790
 
1791
         if (!otherPackages.isEmpty()) {
1792
            printOverviewPackages(output,
1793
                                  otherPackages,
1794
                                  "Other Packages");
1795
         }
1796
      }
1797
 
1798
      output.anchorName("description");
1799
      output.beginDiv(CssClass.OVERVIEW_DESCRIPTION_FULL);
1800
      printTags(output, getRootDoc(), getRootDoc().inlineTags(), false);
1801
      output.endDiv(CssClass.OVERVIEW_DESCRIPTION_FULL);
1802
 
1803
      printNavBarBottom(output, "overview");
1804
      output.endBody();
1805
      output.endPage();
1806
      output.close();
1807
   }
1808
 
1809
   private void printOverviewPackages(HtmlPage output, Collection packageDocs, String header)
1810
   {
1811
      output.beginDiv(CssClass.TABLE_CONTAINER);
1812
      output.beginTable(CssClass.OVERVIEW_SUMMARY, new String[] { "border", "width" }, new String[] { "1", "100%" });
1813
      output.rowDiv(CssClass.TABLE_HEADER, header);
1814
 
1815
      Iterator it = packageDocs.iterator();
1816
      while (it.hasNext()) {
1817
         PackageDoc packageDoc = (PackageDoc)it.next();
1818
         output.beginRow();
1819
 
1820
         output.beginCell(CssClass.OVERVIEW_SUMMARY_LEFT);
1821
         output.beginAnchor(getPackageURL(packageDoc) + "package-summary" + filenameExtension);
1822
         output.print(packageDoc.name());
1823
         output.endAnchor();
1824
         output.endCell();
1825
 
1826
         output.beginCell(CssClass.OVERVIEW_SUMMARY_RIGHT);
1827
         printTags(output, packageDoc, packageDoc.firstSentenceTags(), true);
1828
         output.endCell();
1829
         output.endRow();
1830
      }
1831
      output.endTable();
1832
      output.endDiv(CssClass.TABLE_CONTAINER);
1833
   }
1834
 
1835
   private void printClassUsagePage(File packageDir, String pathToRoot, ClassDoc classDoc)
1836
      throws IOException
1837
   {
1838
      HtmlPage output = newHtmlPage(new File(packageDir,
1839
                                             classDoc.name() + "-uses" + filenameExtension),
1840
                                    pathToRoot);
1841
      output.beginPage(getPageTitle(classDoc.name()), getOutputCharset(), getStylesheets());
1842
      output.beginBody(CssClass.BODY_CONTENT_USES);
1843
      printNavBarTop(output, "uses", classDoc, null, null);
1844
 
1845
      output.div(CssClass.USAGE_TITLE,
1846
                 "Uses of " + getClassTypeName(classDoc)
1847
                 + " " + classDoc.qualifiedName());
1848
 
1849
      Map packageToUsageTypeMap = getUsageOfClass(classDoc);
1850
      if (null != packageToUsageTypeMap && !packageToUsageTypeMap.isEmpty()) {
1851
 
1852
         Iterator packagesIterator = packageToUsageTypeMap.keySet().iterator();
1853
         while (packagesIterator.hasNext()) {
1854
            PackageDoc packageDoc = (PackageDoc)packagesIterator.next();
1855
 
1856
            output.div(CssClass.USAGE_PACKAGE_TITLE, "Uses in package " + packageDoc.name());
1857
 
1858
            Map usageTypeToUsersMap = (Map)packageToUsageTypeMap.get(packageDoc);
1859
            Iterator usageTypeIterator = usageTypeToUsersMap.keySet().iterator();
1860
            while (usageTypeIterator.hasNext()) {
1861
               UsageType usageType = (UsageType)usageTypeIterator.next();
1862
 
1863
               output.beginTable(CssClass.USAGE_SUMMARY, new String[] { "border", "width" }, new String[] { "1", "100%" });
1864
               output.rowDiv(CssClass.USAGE_TABLE_HEADER, format("usagetype." + usageType.getId(),
1865
                                                                 classDoc.qualifiedName()));
1866
 
1867
               Set users = (Set)usageTypeToUsersMap.get(usageType);
1868
               Iterator userIterator = users.iterator();
1869
               while (userIterator.hasNext()) {
1870
                  Doc user = (Doc)userIterator.next();
1871
 
1872
                  output.beginRow();
1873
 
1874
                  if (user instanceof ClassDoc) {
1875
                     output.beginCell(CssClass.USAGE_SUMMARY_LEFT);
1876
                     output.print("class");
1877
                     output.endCell();
1878
 
1879
                     output.beginCell(CssClass.USAGE_SUMMARY_RIGHT);
1880
                     output.beginDiv(CssClass.USAGE_SUMMARY_SYNOPSIS);
1881
                     printType(output, ((ClassDoc)user));
1882
                     output.endDiv(CssClass.USAGE_SUMMARY_SYNOPSIS);
1883
                     output.beginDiv(CssClass.USAGE_SUMMARY_DESCRIPTION);
1884
                     printTags(output, ((ClassDoc)user), ((ClassDoc)user).firstSentenceTags(), true);
1885
                     output.endDiv(CssClass.USAGE_SUMMARY_DESCRIPTION);
1886
                     output.endCell();
1887
                  }
1888
                  else if (user instanceof FieldDoc) {
1889
                     FieldDoc fieldDoc = (FieldDoc)user;
1890
 
1891
                     output.beginCell(CssClass.USAGE_SUMMARY_LEFT);
1892
                     printType(output, ((FieldDoc)user).type());
1893
                     output.endCell();
1894
 
1895
                     output.beginCell(CssClass.USAGE_SUMMARY_RIGHT);
1896
                     output.beginDiv(CssClass.USAGE_SUMMARY_SYNOPSIS);
1897
                     printType(output, ((FieldDoc)user).containingClass());
1898
                     output.print(".");
1899
                     output.beginAnchor(getMemberDocURL(output, (FieldDoc)user));
1900
                     output.print(((FieldDoc)user).name());
1901
                     output.endAnchor();
1902
                     output.endDiv(CssClass.USAGE_SUMMARY_SYNOPSIS);
1903
                     output.beginDiv(CssClass.USAGE_SUMMARY_DESCRIPTION);
1904
                     printTags(output, ((FieldDoc)user), ((FieldDoc)user).firstSentenceTags(), true);
1905
                     output.endDiv(CssClass.USAGE_SUMMARY_DESCRIPTION);
1906
                     output.endCell();
1907
                  }
1908
                  else if (user instanceof MethodDoc) {
1909
                     MethodDoc methodDoc = (MethodDoc)user;
1910
 
1911
                     output.beginCell(CssClass.USAGE_SUMMARY_LEFT);
1912
                     printType(output, ((MethodDoc)user).returnType());
1913
                     output.endCell();
1914
 
1915
                     output.beginCell(CssClass.USAGE_SUMMARY_RIGHT);
1916
                     output.beginDiv(CssClass.USAGE_SUMMARY_SYNOPSIS);
1917
                     printType(output, ((MethodDoc)user).containingClass());
1918
                     output.print(".");
1919
                     output.beginAnchor(getMemberDocURL(output, (MethodDoc)user));
1920
                     output.print(((MethodDoc)user).name());
1921
                     output.endAnchor();
1922
                     printParameters(output, (ExecutableMemberDoc)user);
1923
                     output.endDiv(CssClass.USAGE_SUMMARY_SYNOPSIS);
1924
                     output.beginDiv(CssClass.USAGE_SUMMARY_DESCRIPTION);
1925
                     printTags(output, ((MethodDoc)user), ((MethodDoc)user).firstSentenceTags(), true);
1926
                     output.endDiv(CssClass.USAGE_SUMMARY_DESCRIPTION);
1927
                     output.endCell();
1928
                  }
1929
                  else if (user instanceof ConstructorDoc) {
1930
                     ConstructorDoc constructorDoc = (ConstructorDoc)user;
1931
 
1932
                     output.beginCell(CssClass.USAGE_SUMMARY_RIGHT);
1933
                     output.beginDiv(CssClass.USAGE_SUMMARY_SYNOPSIS);
1934
                     printType(output, ((ConstructorDoc)user).containingClass());
1935
                     output.print(".");
1936
                     output.beginAnchor(getMemberDocURL(output, (ConstructorDoc)user));
1937
                     output.print(((ConstructorDoc)user).name());
1938
                     output.endAnchor();
1939
                     printParameters(output, (ExecutableMemberDoc)user);
1940
                     output.endDiv(CssClass.USAGE_SUMMARY_SYNOPSIS);
1941
                     output.beginDiv(CssClass.USAGE_SUMMARY_DESCRIPTION);
1942
                     printTags(output, ((ConstructorDoc)user),
1943
                               ((ConstructorDoc)user).firstSentenceTags(), true);
1944
                     output.endDiv(CssClass.USAGE_SUMMARY_DESCRIPTION);
1945
                     output.endCell();
1946
                  }
1947
 
1948
                  output.endRow();
1949
               }
1950
               output.endTable();
1951
            }
1952
         }
1953
      }
1954
      else {
1955
         output.div(CssClass.USAGE_EMPTY,
1956
                    getClassTypeName(classDoc)
1957
                    + " " + classDoc.qualifiedName() + " is not used by any class in this documentation set.");
1958
      }
1959
      printNavBarBottom(output, "uses", classDoc);
1960
      output.endBody();
1961
      output.endPage();
1962
      output.close();
1963
   }
1964
 
1965
   private void printSuperTreeRec(HtmlPage output, ListIterator it, int level)
1966
   {
1967
      if (it.hasPrevious()) {
1968
         ClassDoc cd = (ClassDoc)it.previous();
1969
         output.beginElement("li", new String[] { "class" }, new String[] { "inheritance " + level });
1970
         output.beginElement("code");
1971
         if (it.hasPrevious()) {
1972
            printType(output, cd, true);
1973
         }
1974
         else {
1975
            output.print(cd.qualifiedName() + getTypeParameters(cd));
1976
         }
1977
         output.endElement("code");
1978
         output.endElement("li");
1979
 
1980
         output.beginElement("li");
1981
 
1982
         if (it.hasPrevious()) {
1983
            output.beginElement("ul", new String[] { "class" }, new String[] { "inheritance " + (level + 1) });
1984
            printSuperTreeRec(output, it, level + 1);
1985
            output.endElement("ul");
1986
         }
1987
 
1988
         output.endElement("li");
1989
      }
1990
   }
1991
 
1992
   private static boolean isSubInterface(ClassDoc classDoc, ClassDoc otherClassDoc)
1993
   {
1994
      ClassDoc[] interfaces = otherClassDoc.interfaces();
1995
      for (int i=0; i<interfaces.length; ++i) {
1996
         if (classDoc == interfaces[i]) {
1997
            return true;
1998
         }
1999
         else if (isSubInterface(classDoc, interfaces[i])) {
2000
            return true;
2001
         }
2002
      }
2003
      return false;
2004
   }
2005
 
2006
   private void printCommaSeparatedTypes(HtmlPage output,
2007
                                         Collection list,
2008
                                         String header,
2009
                                         CssClass cssClass)
2010
   {
2011
      if (!list.isEmpty()) {
2012
         output.beginDiv(cssClass);
2013
         output.div(CssClass.CLASS_KNOWNIMPLEMENTING_HEADER, header);
2014
         output.beginDiv(CssClass.CLASS_KNOWNIMPLEMENTING_ITEM);
2015
         Iterator it = list.iterator();
2016
         while (it.hasNext()) {
2017
            Type type = (Type)it.next();
2018
            printType(output, type);
2019
            if (it.hasNext()) {
2020
               output.print(", ");
2021
            }
2022
         }
2023
         output.endDiv(CssClass.CLASS_KNOWNIMPLEMENTING_ITEM);
2024
         output.endDiv(cssClass);
2025
      }
2026
   }
2027
 
2028
   private void printClassPage(File packageDir, String pathToRoot,
2029
                               ClassDoc classDoc, ClassDoc prevClassDoc, ClassDoc nextClassDoc)
2030
      throws IOException
2031
   {
2032
      HtmlPage output = newHtmlPage(new File(packageDir,
2033
                                             classDoc.name() + filenameExtension),
2034
                                    pathToRoot);
2035
      Set keywords = new LinkedHashSet();
2036
      {
2037
         keywords.add(classDoc.qualifiedName() + " class");
2038
         FieldDoc[] fieldDocs = classDoc.fields();
2039
         for (int i=0; i<fieldDocs.length; ++i) {
2040
            FieldDoc fieldDoc = fieldDocs[i];
2041
            keywords.add(fieldDoc.name());
2042
         }
2043
 
2044
         MethodDoc[] methodDocs = classDoc.methods();
2045
         for (int i=0; i<methodDocs.length; ++i) {
2046
            MethodDoc methodDoc = methodDocs[i];
2047
            keywords.add(methodDoc.name() + "()");
2048
         }
2049
      }
2050
      String parameters = getTypeParameters(classDoc);
2051
 
2052
      output.beginPage(getPageTitle(classDoc.name()), getOutputCharset(),
2053
                       keywords, getStylesheets());
2054
      output.beginBody(CssClass.BODY_CONTENT_CLASS);
2055
      printNavBarTop(output, "class", classDoc, prevClassDoc, nextClassDoc);
2056
 
2057
      output.beginDiv(CssClass.CLASS_TITLE);
2058
      output.div(CssClass.CLASS_TITLE_PACKAGE,
2059
                 classDoc.containingPackage().name());
2060
      output.div(CssClass.CLASS_TITLE_CLASS,
2061
                 getClassTypeName(classDoc)
2062
                 + " " + classDoc.name()
2063
                 + parameters);
2064
      output.endDiv(CssClass.CLASS_TITLE);
2065
 
2066
      boolean needSep = false;
2067
 
2068
      if (classDoc.isInterface()) {
2069
 
2070
         InterfaceRelation relation
2071
            = (InterfaceRelation)getInterfaceRelations().get(classDoc);
2072
 
2073
         printCommaSeparatedTypes(output,
2074
                                  relation.superInterfaces,
2075
                                  "All Superinterfaces:",
2076
                                  CssClass.CLASS_KNOWNIMPLEMENTING);
2077
 
2078
         printCommaSeparatedTypes(output,
2079
                                  relation.subInterfaces,
2080
                                  "Known Subinterfaces:",
2081
                                  CssClass.CLASS_KNOWNIMPLEMENTING);
2082
 
2083
         printCommaSeparatedTypes(output,
2084
                                  relation.implementingClasses,
2085
                                  "Known Implementing Classes:",
2086
                                  CssClass.CLASS_KNOWNIMPLEMENTING);
2087
 
2088
         needSep = !relation.superInterfaces.isEmpty()
2089
            || !relation.subInterfaces.isEmpty()
2090
            || !relation.implementingClasses.isEmpty();
2091
      }
2092
      else {
2093
         needSep = true;
2094
 
2095
         if (!"java.lang.Object".equals(classDoc.qualifiedName())) {
2096
            LinkedList superClasses = new LinkedList();
2097
            for (ClassDoc cd = classDoc; cd != null; cd = cd.superclass()) {
2098
               superClasses.add(cd);
2099
            }
2100
            output.beginDiv(CssClass.CLASS_INHERITANCETREE);
2101
            output.beginElement("ul", new String[] { "class" }, new String[] { "inheritance 0" });
2102
            printSuperTreeRec(output, superClasses.listIterator(superClasses.size()), 0);
2103
            output.endElement("ul");
2104
            output.endDiv(CssClass.CLASS_INHERITANCETREE);
2105
 
2106
            if (null != classDoc.containingClass()) {
2107
               output.beginDiv(CssClass.CLASS_ENCLOSINGCLASS);
2108
               output.div(CssClass.CLASS_ENCLOSINGCLASS_HEADER, "Enclosing Class:");
2109
               output.beginDiv(CssClass.CLASS_ENCLOSINGCLASS_ITEM);
2110
               printType(output, classDoc.containingClass());
2111
               output.endDiv(CssClass.CLASS_ENCLOSINGCLASS_ITEM);
2112
               output.endDiv(CssClass.CLASS_ENCLOSINGCLASS);
2113
            }
2114
 
2115
            Set implementedInterfaces = getImplementedInterfaces(classDoc);
2116
 
2117
            printCommaSeparatedTypes(output,
2118
                                     implementedInterfaces,
2119
                                     "Implemented Interfaces:",
2120
                                     CssClass.CLASS_KNOWNIMPLEMENTING);
2121
 
2122
            List knownDirectSubclasses = getKnownDirectSubclasses(classDoc);
2123
            if (!knownDirectSubclasses.isEmpty()) {
2124
               output.beginDiv(CssClass.CLASS_SUBCLASSES);
2125
               output.div(CssClass.CLASS_SUBCLASSES_HEADER, "Known Direct Subclasses:");
2126
               output.beginDiv(CssClass.CLASS_SUBCLASSES_ITEM);
2127
               Iterator it = knownDirectSubclasses.iterator();
2128
               while (it.hasNext()) {
2129
                  printType(output, (ClassDoc)it.next());
2130
                  if (it.hasNext()) {
2131
                     output.print(", ");
2132
                  }
2133
               }
2134
 
2135
               output.endDiv(CssClass.CLASS_SUBCLASSES_ITEM);
2136
               output.endDiv(CssClass.CLASS_SUBCLASSES_HEADER);
2137
               output.endDiv(CssClass.CLASS_SUBCLASSES);
2138
            }
2139
         }
2140
      }
2141
 
2142
      if (needSep) {
2143
         output.hr();
2144
      }
2145
 
2146
      output.beginDiv(CssClass.CLASS_SYNOPSIS);
2147
      output.beginDiv(CssClass.CLASS_SYNOPSIS_DECLARATION);
2148
      output.print(getFullModifiers(classDoc) + ' ' + getClassTypeKeyword(classDoc)
2149
                   + ' ');
2150
      output.beginSpan(CssClass.CLASS_SYNOPSIS_NAME);
2151
      if (optionLinkSource.getValue() && null != classDoc.position()) {
2152
         output.beginAnchor(getOuterClassDoc(classDoc).name() + "-source" + filenameExtension + "#line." + classDoc.position());
2153
         output.print(classDoc.name() + parameters);
2154
         output.endAnchor();
2155
      }
2156
      else {
2157
         output.print(classDoc.name() + parameters);
2158
      }
2159
      output.endSpan(CssClass.CLASS_SYNOPSIS_NAME);
2160
      output.endDiv(CssClass.CLASS_SYNOPSIS_DECLARATION);
2161
 
2162
      if (!classDoc.isInterface()) {
2163
         if (null != classDoc.superclass()) {
2164
            output.beginDiv(CssClass.CLASS_SYNOPSIS_SUPERCLASS);
2165
            output.print("extends ");
2166
            printType(output, classDoc.superclass());
2167
            output.endDiv(CssClass.CLASS_SYNOPSIS_SUPERCLASS);
2168
         }
2169
      }
2170
 
2171
      ClassDoc[] interfaces = classDoc.interfaces();
2172
      if (interfaces.length > 0) {
2173
         output.beginDiv(CssClass.CLASS_SYNOPSIS_IMPLEMENTS);
2174
         if (!classDoc.isInterface()) {
2175
            output.print("implements ");
2176
         }
2177
         else {
2178
            output.print("extends ");
2179
         }
2180
         for (int i=0; i<interfaces.length; ++i) {
2181
            if (i>0) {
2182
               output.print(", ");
2183
            }
2184
            printType(output, interfaces[i]);
2185
         }
2186
         output.endDiv(CssClass.CLASS_SYNOPSIS_IMPLEMENTS);
2187
      }
2188
      output.endDiv(CssClass.CLASS_SYNOPSIS);
2189
 
2190
      output.hr();
2191
 
2192
      if (!optionNoComment.getValue()) {
2193
         output.beginDiv(CssClass.CLASS_DESCRIPTION);
2194
         printTags(output, classDoc, classDoc.inlineTags(), false);
2195
         output.endDiv(CssClass.CLASS_DESCRIPTION);
2196
 
2197
         printTaglets(output, classDoc.tags(), new HtmlTagletContext(classDoc, output, false));
2198
      }
2199
 
2200
 
2201
      Set implementedInterfaces = getImplementedInterfaces(classDoc);
2202
 
2203
      boolean haveInheritedFields = false;
2204
      boolean haveInheritedMethods = false;
2205
      boolean haveInheritedClasses = false;
2206
      {
2207
         if (!classDoc.isInterface()) {
2208
            ClassDoc superClassDoc = classDoc.superclass();
2209
            while (null != superClassDoc
2210
                   && (!haveInheritedFields
2211
                       || !haveInheritedMethods
2212
                       || !haveInheritedClasses)) {
2213
               if (superClassDoc.fields().length > 0) {
2214
                  haveInheritedFields = true;
2215
               }
2216
               if (superClassDoc.methods().length > 0) {
2217
                  haveInheritedMethods = true;
2218
               }
2219
               if (superClassDoc.innerClasses().length > 0) {
2220
                  haveInheritedClasses = true;
2221
               }
2222
               superClassDoc = superClassDoc.superclass();
2223
            }
2224
         }
2225
      }
2226
 
2227
      printProgramElementDocs(output, getSortedInnerClasses(classDoc),
2228
                              "Nested Class Summary", haveInheritedClasses,
2229
                              "summary-inner");
2230
 
2231
      {
2232
         ClassDoc superClassDoc = classDoc.superclass();
2233
         while (null != superClassDoc) {
2234
            printInheritedMembers(output, getSortedInnerClasses(superClassDoc),
2235
                                  "Nested classes/interfaces inherited from class {0}",
2236
                                  superClassDoc);
2237
            superClassDoc = superClassDoc.superclass();
2238
         }
2239
      }
2240
 
2241
      printProgramElementDocs(output, getSortedFields(classDoc),
2242
                              "Field Summary", haveInheritedFields,
2243
                              "summary-fields");
2244
 
2245
      {
2246
         ClassDoc superClassDoc = classDoc.superclass();
2247
         while (null != superClassDoc) {
2248
            printInheritedMembers(output, getSortedFields(superClassDoc),
2249
                                  "Fields inherited from class {0}",
2250
                                  superClassDoc);
2251
            superClassDoc = superClassDoc.superclass();
2252
         }
2253
      }
2254
 
2255
      {
2256
         Iterator it = implementedInterfaces.iterator();
2257
         while (it.hasNext()) {
2258
            ClassDoc implementedInterface
2259
               = (ClassDoc)it.next();
2260
            if (!"java.io.Serializable".equals(implementedInterface.qualifiedName())
2261
                && !"java.io.Externalizable".equals(implementedInterface.qualifiedName())) {
2262
               printInheritedMembers(output, getSortedFields(implementedInterface),
2263
                                     "Fields inherited from interface {0}",
2264
                                     implementedInterface);
2265
            }
2266
         }
2267
      }
2268
 
2269
      printProgramElementDocs(output, getSortedConstructors(classDoc),
2270
                              "Constructor Summary", false,
2271
                              "summary-constructors");
2272
      printProgramElementDocs(output, getSortedMethods(classDoc),
2273
                              "Method Summary", haveInheritedMethods,
2274
                              "summary-methods");
2275
 
2276
      if (classDoc.isInterface()) {
2277
         InterfaceRelation relation
2278
            = (InterfaceRelation)getInterfaceRelations().get(classDoc);
2279
         Iterator it = relation.superInterfaces.iterator();
2280
         while (it.hasNext()) {
2281
            ClassDoc superClassDoc = (ClassDoc)it.next();
2282
            printInheritedMembers(output, getSortedMethods(superClassDoc),
2283
                                  "Methods inherited from interface {0}",
2284
                                  superClassDoc);
2285
         }
2286
      }
2287
      else {
2288
         ClassDoc superClassDoc = classDoc.superclass();
2289
         while (null != superClassDoc) {
2290
            printInheritedMembers(output, getSortedMethods(superClassDoc),
2291
                                  "Methods inherited from class {0}",
2292
                                  superClassDoc);
2293
            superClassDoc = superClassDoc.superclass();
2294
         }
2295
      }
2296
 
2297
      printMemberDetails(output, getSortedFields(classDoc),
2298
                         "Field Details", false, "detail-fields");
2299
      printMemberDetails(output, getSortedConstructors(classDoc),
2300
                         "Constructor Details", false, "detail-constructors");
2301
      printMemberDetails(output, getSortedMethods(classDoc),
2302
                         "Method Details", false, "detail-methods");
2303
 
2304
      printNavBarBottom(output, "class", classDoc);
2305
 
2306
      output.endBody();
2307
      output.endPage();
2308
      output.close();
2309
   }
2310
 
2311
   private void printInheritedMembers(HtmlPage output,
2312
                                      ProgramElementDoc[] memberDocs,
2313
                                      String headerFormat,
2314
                                      ClassDoc superclass)
2315
   {
2316
      if (memberDocs.length > 0) {
2317
 
2318
         output.beginDiv(CssClass.TABLE_CONTAINER);
2319
         output.beginTable(CssClass.CLASS_SUMMARY, new String[] { "border", "width" }, new String[] { "1", "100%" });
2320
         String superclassLink;
2321
         if (superclass.isIncluded()) {
2322
            superclassLink = superclass.containingPackage().name()
2323
               + "." + createTypeHref(output, superclass, false);
2324
         }
2325
         else {
2326
            superclassLink = createTypeHref(output, superclass, true);
2327
         }
2328
         output.rowDiv(CssClass.TABLE_SUB_HEADER,
2329
                       new MessageFormat(headerFormat).format(new Object[] {
2330
                          superclassLink
2331
                       }));
2332
 
2333
         output.beginRow();
2334
         output.beginCell(CssClass.CLASS_SUMMARY_INHERITED);
2335
         for (int i=0; i<memberDocs.length; ++i) {
2336
            ProgramElementDoc memberDoc = memberDocs[i];
2337
            if (i > 0) {
2338
               output.print(", ");
2339
            }
2340
            String title = null;
2341
            if (memberDoc.isMethod()) {
2342
               title = memberDoc.name() + ((MethodDoc)memberDoc).flatSignature();
2343
            }
2344
            else if (memberDoc.isInterface()) {
2345
               title = "interface " + ((ClassDoc)memberDoc).qualifiedName();
2346
            }
2347
            else if (memberDoc.isClass()) {
2348
               title = "class " + ((ClassDoc)memberDoc).qualifiedName();
2349
            }
2350
            output.beginAnchor(getMemberDocURL(output, memberDoc), title);
2351
            output.beginSpan(CssClass.CLASS_SUMMARY_INHERITED_MEMBER);
2352
            output.print(memberDoc.name());
2353
            output.endSpan(CssClass.CLASS_SUMMARY_INHERITED_MEMBER);
2354
            output.endAnchor();
2355
         }
2356
         output.endCell();
2357
         output.endRow();
2358
         output.endTable();
2359
         output.endDiv(CssClass.TABLE_CONTAINER);
2360
      }
2361
   }
2362
 
2363
   private void collectSpecifiedByRecursive(Set specifyingInterfaces,
2364
                                            ClassDoc classDoc,
2365
                                            MethodDoc methodDoc)
2366
   {
2367
      ClassDoc[] interfaces = classDoc.interfaces();
2368
      for (int i=0; i<interfaces.length; ++i) {
2369
         MethodDoc[] methods = interfaces[i].methods();
2370
         for (int j=0; j<methods.length; ++j) {
2371
            if (methods[j].name().equals(methodDoc.name())
2372
                && methods[j].signature().equals(methodDoc.signature())) {
2373
               specifyingInterfaces.add(methods[j]);
2374
               break;
2375
            }
2376
         }
2377
         collectSpecifiedByRecursive(specifyingInterfaces,
2378
                                     interfaces[i],
2379
                                     methodDoc);
2380
      }
2381
   }
2382
 
2383
   private void printMemberDetails(HtmlPage output,
2384
                                   ProgramElementDoc[] memberDocs, String header,
2385
                                   boolean isOnSerializedPage,
2386
                                   String anchor)
2387
   {
2388
      if (memberDocs.length > 0) {
2389
 
2390
         if (null != anchor) {
2391
            output.anchorName(anchor);
2392
         }
2393
 
2394
         CssClass sectionClass;
2395
         CssClass headerClass;
2396
         if (isOnSerializedPage) {
2397
            sectionClass = CssClass.SERIALIZED_SECTION;
2398
            headerClass = CssClass.SERIALIZED_SECTION_HEADER;
2399
         }
2400
         else {
2401
            sectionClass = CssClass.SECTION;
2402
            headerClass = CssClass.SECTION_HEADER;
2403
         }
2404
         output.div(headerClass, header);
2405
         output.beginDiv(sectionClass);
2406
 
2407
         for (int i=0; i<memberDocs.length; ++i) {
2408
            if (i>0) {
2409
               output.hr();
2410
            }
2411
 
2412
            ProgramElementDoc memberDoc = memberDocs[i];
2413
 
2414
            output.anchorName(getMemberAnchor(memberDoc));
2415
 
2416
            output.beginDiv(CssClass.MEMBER_DETAIL);
2417
            output.div(CssClass.MEMBER_DETAIL_NAME, memberDoc.name());
2418
 
2419
            StringBuffer synopsis = new StringBuffer();
2420
            int synopsisLength = 0;
2421
 
2422
            if (!isOnSerializedPage || !memberDoc.isField()) {
2423
               String fullModifiers = getFullModifiers(memberDoc);
2424
               synopsis.append(fullModifiers);
2425
               synopsisLength += fullModifiers.length();
2426
 
2427
            }
2428
            if (memberDoc.isMethod() || memberDoc.isField()) {
2429
               Type type;
2430
               if (memberDoc.isMethod()) {
2431
                  type = ((MethodDoc)memberDoc).returnType();
2432
               }
2433
               else {
2434
                  type = ((FieldDoc)memberDoc).type();
2435
               }
2436
 
2437
               synopsis.append(" ");
2438
               synopsisLength ++;
2439
               synopsis.append(createTypeHref(output, type, false));
2440
               if (null != type.asClassDoc() && type.asClassDoc().isIncluded()) {
2441
                  synopsisLength += type.asClassDoc().name().length();
2442
               }
2443
               else {
2444
                  synopsisLength += type.qualifiedTypeName().length();
2445
               }
2446
               synopsisLength += type.dimension().length();
2447
            }
2448
 
2449
            synopsis.append(" ");
2450
            synopsisLength ++;
2451
 
2452
            if (optionLinkSource.getValue() && null != memberDoc.position()) {
2453
               ClassDoc containingClass = memberDoc.containingClass();
2454
               while (null != containingClass.containingClass()) {
2455
                  containingClass = containingClass.containingClass();
2456
               }
2457
               String href = containingClass.name() + "-source" + filenameExtension + "#line." + memberDoc.position().line();
2458
               synopsis.append(output.createHrefString(href, memberDoc.name()));
2459
            }
2460
            else {
2461
               synopsis.append(memberDoc.name());
2462
            }
2463
            synopsisLength += memberDoc.name().length();
2464
 
2465
            if (memberDoc.isConstructor() || memberDoc.isMethod()) {
2466
               //printParameters(output, (ExecutableMemberDoc)memberDoc);
2467
               synopsis.append("(");
2468
               ++ synopsisLength;
2469
               StringBuffer paddingLeft = new StringBuffer();
2470
               for (int j=0; j<synopsisLength; ++j) {
2471
                  paddingLeft.append(' ');
2472
               }
2473
               Parameter[] parameters = ((ExecutableMemberDoc)memberDoc).parameters();
2474
               for (int j=0; j<parameters.length; ++j) {
2475
                  Parameter parameter = parameters[j];
2476
                  synopsis.append(createTypeHref(output, parameter.type(), false));
2477
                  synopsis.append(" ");
2478
                  synopsis.append(parameter.name());
2479
                  if (j < parameters.length - 1) {
2480
                     synopsis.append(",\n");
2481
                     synopsis.append(paddingLeft);
2482
                  }
2483
               }
2484
               synopsis.append(")");
2485
               ClassDoc[] exceptions = ((ExecutableMemberDoc)memberDoc).thrownExceptions();
2486
               if (exceptions.length > 0) {
2487
                  synopsis.append("\n            throws ");
2488
                  for (int j=0; j<exceptions.length; ++j) {
2489
                     ClassDoc exception = exceptions[j];
2490
                     synopsis.append(createTypeHref(output, exception, false));
2491
                     if (j < exceptions.length - 1) {
2492
                        synopsis.append(",\n                   ");
2493
                     }
2494
                  }
2495
               }
2496
            }
2497
 
2498
            output.beginDiv(CssClass.MEMBER_DETAIL_SYNOPSIS);
2499
            output.print(synopsis.toString());
2500
            output.endDiv(CssClass.MEMBER_DETAIL_SYNOPSIS);
2501
 
2502
            output.beginDiv(CssClass.MEMBER_DETAIL_BODY);
2503
 
2504
            Tag[] deprecatedTags = memberDoc.tags("deprecated");
2505
            if (deprecatedTags.length > 0) {
2506
               output.beginDiv(CssClass.DEPRECATED_INLINE);
2507
               output.beginSpan(CssClass.DEPRECATED_HEADER);
2508
               output.print("Deprecated. ");
2509
               output.endSpan(CssClass.DEPRECATED_HEADER);
2510
               output.beginSpan(CssClass.DEPRECATED_BODY);
2511
            }
2512
            for (int j=0; j<deprecatedTags.length; ++j) {
2513
               printTags(output, memberDoc, deprecatedTags[j].inlineTags(), true);
2514
            }
2515
            if (deprecatedTags.length > 0) {
2516
               output.endSpan(CssClass.DEPRECATED_BODY);
2517
               output.beginDiv(CssClass.DEPRECATED_INLINE);
2518
            }
2519
 
2520
            output.beginDiv(CssClass.MEMBER_DETAIL_DESCRIPTION);
2521
            printTags(output, memberDoc, memberDoc.inlineTags(), false);
2522
            output.endDiv(CssClass.MEMBER_DETAIL_DESCRIPTION);
2523
 
2524
            if (memberDoc.isConstructor() || memberDoc.isMethod()) {
2525
 
2526
               if (memberDoc.isMethod()) {
2527
                  Set specifyingInterfaces = new LinkedHashSet();
2528
                  if (memberDoc.containingClass().isInterface()) {
2529
                     collectSpecifiedByRecursive(specifyingInterfaces,
2530
                                                 memberDoc.containingClass(),
2531
                                                 (MethodDoc)memberDoc);
2532
                  }
2533
                  else {
2534
                     for (ClassDoc cd = memberDoc.containingClass();
2535
                          null != cd; cd = cd.superclass()) {
2536
                        collectSpecifiedByRecursive(specifyingInterfaces,
2537
                                                    cd,
2538
                                                    (MethodDoc)memberDoc);
2539
                     }
2540
                  }
2541
 
2542
                  if (!specifyingInterfaces.isEmpty()
2543
                      && !isOnSerializedPage) {
2544
                     output.beginDiv(CssClass.MEMBER_DETAIL_SPECIFIED_BY_LIST);
2545
                     output.div(CssClass.MEMBER_DETAIL_SPECIFIED_BY_HEADER, "Specified by:");
2546
                     Iterator it = specifyingInterfaces.iterator();
2547
                     while (it.hasNext()) {
2548
                        MethodDoc specifyingInterfaceMethod = (MethodDoc)it.next();
2549
                        output.beginDiv(CssClass.MEMBER_DETAIL_SPECIFIED_BY_ITEM);
2550
                        output.beginAnchor(getMemberDocURL(output,
2551
                                                           specifyingInterfaceMethod));
2552
                        output.print(memberDoc.name());
2553
                        output.endAnchor();
2554
                        output.print(" in interface ");
2555
                        printType(output, specifyingInterfaceMethod.containingClass());
2556
                        output.endDiv(CssClass.MEMBER_DETAIL_SPECIFIED_BY_ITEM);
2557
                     }
2558
                     output.endDiv(CssClass.MEMBER_DETAIL_SPECIFIED_BY_LIST);
2559
                  }
2560
 
2561
                  ClassDoc overriddenClassDoc = null;
2562
                  MemberDoc specifyingSuperMethod = null;
2563
 
2564
                  for (ClassDoc superclassDoc = memberDoc.containingClass().superclass();
2565
                       null != superclassDoc && null == overriddenClassDoc;
2566
                       superclassDoc = superclassDoc.superclass()) {
2567
 
2568
                     MethodDoc[] methods = superclassDoc.methods();
2569
                     for (int j=0; j<methods.length; ++j) {
2570
                        if (methods[j].name().equals(memberDoc.name())
2571
                            && methods[j].signature().equals(((MethodDoc)memberDoc).signature())) {
2572
                           overriddenClassDoc = superclassDoc;
2573
                           specifyingSuperMethod = methods[j];
2574
                           break;
2575
                        }
2576
                     }
2577
                  }
2578
 
2579
                  if (null != overriddenClassDoc) {
2580
                     output.beginDiv(CssClass.MEMBER_DETAIL_OVERRIDDEN_LIST);
2581
                     output.div(CssClass.MEMBER_DETAIL_OVERRIDDEN_HEADER, "Overrides:");
2582
                     output.beginDiv(CssClass.MEMBER_DETAIL_OVERRIDDEN_ITEM);
2583
 
2584
                     output.beginAnchor(getMemberDocURL(output,
2585
                                                        specifyingSuperMethod));
2586
                     output.print(memberDoc.name());
2587
                     output.endAnchor();
2588
                     output.print(" in interface ");
2589
                     printType(output, overriddenClassDoc);
2590
 
2591
                     output.endDiv(CssClass.MEMBER_DETAIL_OVERRIDDEN_ITEM);
2592
                     output.endDiv(CssClass.MEMBER_DETAIL_OVERRIDDEN_LIST);
2593
                  }
2594
               }
2595
 
2596
               if (!optionNoComment.getValue()) {
2597
 
2598
                  ExecutableMemberDoc execMemberDoc
2599
                     = (ExecutableMemberDoc)memberDoc;
2600
 
2601
                  if (execMemberDoc.paramTags().length > 0) {
2602
                     output.beginDiv(CssClass.MEMBER_DETAIL_PARAMETER_LIST);
2603
                     output.div(CssClass.MEMBER_DETAIL_PARAMETER_HEADER, "Parameters:");
2604
                     Parameter[] parameters = execMemberDoc.parameters();
2605
                     for (int j=0; j<parameters.length; ++j) {
2606
                        Parameter parameter = parameters[j];
2607
                        ParamTag[] paramTags = execMemberDoc.paramTags();
2608
                        ParamTag paramTag = null;
2609
                        for (int k=0; k<paramTags.length; ++k) {
2610
                           if (paramTags[k].parameterName().equals(parameter.name())) {
2611
                              paramTag = paramTags[k];
2612
                              break;
2613
                           }
2614
                        }
2615
 
2616
                        if (null != paramTag) {
2617
                           output.beginDiv(CssClass.MEMBER_DETAIL_PARAMETER_ITEM);
2618
                           output.beginSpan(CssClass.MEMBER_DETAIL_PARAMETER_ITEM_NAME);
2619
                           output.print(parameter.name());
2620
                           output.endSpan(CssClass.MEMBER_DETAIL_PARAMETER_ITEM_NAME);
2621
                           output.beginSpan(CssClass.MEMBER_DETAIL_PARAMETER_ITEM_SEPARATOR);
2622
                           output.print(" - ");
2623
                           output.endSpan(CssClass.MEMBER_DETAIL_PARAMETER_ITEM_SEPARATOR);
2624
                           output.beginSpan(CssClass.MEMBER_DETAIL_PARAMETER_ITEM_DESCRIPTION);
2625
                           printTags(output, execMemberDoc, paramTag.inlineTags(), false);
2626
                           output.endSpan(CssClass.MEMBER_DETAIL_PARAMETER_ITEM_DESCRIPTION);
2627
                           output.endDiv(CssClass.MEMBER_DETAIL_PARAMETER_ITEM);
2628
                        }
2629
                     }
2630
                     output.endDiv(CssClass.MEMBER_DETAIL_PARAMETER_LIST);
2631
                  }
2632
 
2633
                  if (execMemberDoc.isMethod()
2634
                      && !"void".equals(((MethodDoc)execMemberDoc).returnType().typeName())) {
2635
 
2636
                     Tag[] returnTags = execMemberDoc.tags("return");
2637
                     if (returnTags.length > 0) {
2638
                        Tag returnTag = returnTags[0];
2639
 
2640
                        output.beginDiv(CssClass.MEMBER_DETAIL_RETURN_LIST);
2641
                        output.div(CssClass.MEMBER_DETAIL_RETURN_HEADER, "Returns:");
2642
                        output.beginDiv(CssClass.MEMBER_DETAIL_RETURN_ITEM);
2643
 
2644
                        printTags(output, execMemberDoc, returnTag.inlineTags(), false);
2645
 
2646
                        output.endDiv(CssClass.MEMBER_DETAIL_RETURN_ITEM);
2647
                        output.endDiv(CssClass.MEMBER_DETAIL_RETURN_LIST);
2648
                     }
2649
                  }
2650
 
2651
                  Set thrownExceptions = getThrownExceptions(execMemberDoc);
2652
                  boolean haveThrowsInfo = false;
2653
                  ThrowsTag[] throwsTags = execMemberDoc.throwsTags();
2654
                  for (int k=0; k<throwsTags.length; ++k) {
2655
                     ThrowsTag throwsTag = throwsTags[k];
2656
                     if (null != throwsTags[k].exception()
2657
                         && (isUncheckedException(throwsTags[k].exception())
2658
                             || thrownExceptions.contains(throwsTag.exception()))) {
2659
                        haveThrowsInfo = true;
2660
                        break;
2661
                     }
2662
                  }
2663
 
2664
                  if (haveThrowsInfo) {
2665
                     output.beginDiv(CssClass.MEMBER_DETAIL_THROWN_LIST);
2666
                     output.div(CssClass.MEMBER_DETAIL_THROWN_HEADER, "Throws:");
2667
 
2668
                     for (int k=0; k<throwsTags.length; ++k) {
2669
                        ThrowsTag throwsTag = throwsTags[k];
2670
                        if (null != throwsTag.exception()
2671
                            && (isUncheckedException(throwsTag.exception())
2672
                                || thrownExceptions.contains(throwsTag.exception()))) {
2673
                           output.beginDiv(CssClass.MEMBER_DETAIL_THROWN_ITEM);
2674
                           output.beginSpan(CssClass.MEMBER_DETAIL_THROWN_ITEM_NAME);
2675
                           printType(output, throwsTags[k].exception());
2676
                           output.endSpan(CssClass.MEMBER_DETAIL_THROWN_ITEM_NAME);
2677
                           if (null != throwsTag) {
2678
                              output.beginSpan(CssClass.MEMBER_DETAIL_THROWN_ITEM_SEPARATOR);
2679
                              output.print(" - ");
2680
                              output.endSpan(CssClass.MEMBER_DETAIL_THROWN_ITEM_SEPARATOR);
2681
                              output.beginSpan(CssClass.MEMBER_DETAIL_THROWN_ITEM_DESCRIPTION);
2682
                              printTags(output, execMemberDoc, throwsTag.inlineTags(), false);
2683
                              output.endSpan(CssClass.MEMBER_DETAIL_THROWN_ITEM_DESCRIPTION);
2684
                           }
2685
                           output.endDiv(CssClass.MEMBER_DETAIL_THROWN_ITEM);
2686
                        }
2687
                     }
2688
                     output.endDiv(CssClass.MEMBER_DETAIL_THROWN_LIST);
2689
                  }
2690
               }
2691
            }
2692
 
2693
            if (!optionNoComment.getValue()) {
2694
 
2695
               if (memberDoc.isField()) {
2696
                  FieldDoc fieldDoc = ((FieldDoc)memberDoc);
2697
                  if (null != fieldDoc.constantValue()) {
2698
                     output.beginDiv(CssClass.MEMBER_DETAIL_THROWN_LIST);
2699
                     output.div(CssClass.MEMBER_DETAIL_THROWN_HEADER, "Field Value:");
2700
                     output.div(CssClass.MEMBER_DETAIL_THROWN_ITEM,
2701
                                fieldDoc.constantValueExpression().toString());
2702
                     output.endDiv(CssClass.MEMBER_DETAIL_THROWN_LIST);
2703
                  }
2704
               }
2705
 
2706
               TagletContext context = new HtmlTagletContext(memberDoc, output, isOnSerializedPage);
2707
               printTaglets(output, memberDoc.tags(), context);
2708
            }
2709
 
2710
            output.endDiv(CssClass.MEMBER_DETAIL_BODY);
2711
            output.endDiv(CssClass.MEMBER_DETAIL);
2712
         }
2713
         output.endDiv(sectionClass);
2714
      }
2715
   }
2716
 
2717
 
2718
   private void printParameters(HtmlPage output, ExecutableMemberDoc memberDoc)
2719
   {
2720
      Parameter[] parameters = memberDoc.parameters();
2721
      output.print("(");
2722
      for (int j=0; j<parameters.length; ++j) {
2723
         if (j > 0) {
2724
            output.print(", ");
2725
         }
2726
         printType(output, parameters[j].type());
2727
         output.print("&nbsp;");
2728
         output.print(parameters[j].name());
2729
      }
2730
      output.print(")");
2731
   }
2732
 
2733
   private void printProgramElementDocs(HtmlPage output,
2734
                                        ProgramElementDoc[] memberDocs,
2735
                                        String header,
2736
                                        boolean forceOutputHeader,
2737
                                        String anchor)
2738
   {
2739
      if (memberDocs.length > 0 || forceOutputHeader) {
2740
         output.anchorName(anchor);
2741
         output.beginDiv(CssClass.TABLE_CONTAINER);
2742
         output.beginTable(CssClass.CLASS_SUMMARY, new String[] { "border", "width" }, new String[] { "1", "100%" });
2743
         output.rowDiv(CssClass.TABLE_HEADER, header);
2744
 
2745
         for (int i=0; i<memberDocs.length; ++i) {
2746
            ProgramElementDoc memberDoc = memberDocs[i];
2747
            output.beginRow();
2748
 
2749
            if (!memberDoc.isConstructor()) {
2750
               output.beginCell(CssClass.CLASS_SUMMARY_LEFT);
2751
               output.beginDiv(CssClass.CLASS_SUMMARY_LEFT_SYNOPSIS);
2752
               output.print(getSummaryModifiers(memberDoc) + " ");
2753
               if (memberDoc.isMethod()) {
2754
                  printType(output, ((MethodDoc)memberDoc).returnType());
2755
               }
2756
               else if (memberDoc.isField()) {
2757
                  printType(output, ((FieldDoc)memberDoc).type());
2758
               }
2759
               else if (memberDoc.isInterface()) {
2760
                  output.print(" interface");
2761
               }
2762
               else if (memberDoc.isClass()) {
2763
                  output.print(" class");
2764
               }
2765
               output.endDiv(CssClass.CLASS_SUMMARY_LEFT_SYNOPSIS);
2766
               output.endCell();
2767
            }
2768
 
2769
            output.beginCell(CssClass.CLASS_SUMMARY_RIGHT);
2770
            output.beginDiv(CssClass.CLASS_SUMMARY_RIGHT_LIST);
2771
            output.beginDiv(CssClass.CLASS_SUMMARY_RIGHT_SYNOPSIS);
2772
            if (memberDoc.isClass() || memberDoc.isInterface()) {
2773
               output.beginAnchor(getClassDocURL(output, (ClassDoc)memberDoc));
2774
            }
2775
            else {
2776
               output.beginAnchor("#" + getMemberAnchor(memberDoc));
2777
            }
2778
            output.print(memberDoc.name());
2779
            output.endAnchor();
2780
            if (memberDoc.isConstructor() || memberDoc.isMethod()) {
2781
               printParameters(output, (ExecutableMemberDoc)memberDoc);
2782
            }
2783
            output.endDiv(CssClass.CLASS_SUMMARY_RIGHT_SYNOPSIS);
2784
            Tag[] firstSentenceTags;
2785
            Tag[] deprecatedTags = memberDoc.tags("deprecated");
2786
            if (deprecatedTags.length > 0) {
2787
               firstSentenceTags = deprecatedTags[0].firstSentenceTags();
2788
            }
2789
            else {
2790
               firstSentenceTags = memberDoc.firstSentenceTags();
2791
            }
2792
 
2793
            if (null != firstSentenceTags && firstSentenceTags.length > 0) {
2794
               output.beginDiv(CssClass.CLASS_SUMMARY_RIGHT_DESCRIPTION);
2795
               if (deprecatedTags.length > 0) {
2796
                  output.beginDiv(CssClass.DEPRECATED);
2797
                  output.beginSpan(CssClass.DEPRECATED_HEADER);
2798
                  output.print("Deprecated. ");
2799
                  output.endSpan(CssClass.DEPRECATED_HEADER);
2800
                  output.beginSpan(CssClass.DEPRECATED_BODY);
2801
               }
2802
               printTags(output, memberDoc, firstSentenceTags, true);
2803
               if (deprecatedTags.length > 0) {
2804
                  output.endSpan(CssClass.DEPRECATED_BODY);
2805
                  output.beginDiv(CssClass.DEPRECATED);
2806
               }
2807
               output.endDiv(CssClass.CLASS_SUMMARY_RIGHT_DESCRIPTION);
2808
            }
2809
            output.endDiv(CssClass.CLASS_SUMMARY_RIGHT_LIST);
2810
            output.endCell();
2811
            output.endRow();
2812
         }
2813
         output.endTable();
2814
         output.endDiv(CssClass.TABLE_CONTAINER);
2815
      }
2816
   }
2817
 
2818
   private void printTag(final HtmlPage output,
2819
                         HtmlRepairer repairer,
2820
                         Tag tag, boolean firstSentence,
2821
                         boolean inline,
2822
                         Doc contextDoc)
2823
   {
2824
      TagletContext context = new HtmlTagletContext(contextDoc, output, false);
2825
      if (firstSentence) {
2826
         output.print(renderInlineTags(tag.firstSentenceTags(), context));
2827
      }
2828
      else {
2829
         output.print(renderInlineTags(tag.inlineTags(), context));
2830
      }
2831
   }
2832
 
2833
   private void printTags(HtmlPage output, Doc contextDoc, Tag[] tags, boolean firstSentence)
2834
   {
2835
      printTags(output, contextDoc, tags, firstSentence, false);
2836
   }
2837
 
2838
   private void printTags(HtmlPage output, Doc contextDoc, Tag[] tags, boolean firstSentence, boolean inline)
2839
   {
2840
      if (!optionNoComment.getValue()) {
2841
         output.print(renderInlineTags(tags, new HtmlTagletContext(contextDoc, output, false)));
2842
      }
2843
 
2844
      /*
2845
      if (!optionNoComment.getValue()) {
2846
         output.print(renderInlineTags(tag.firstSentenceTags(), output));
2847
         HtmlRepairer repairer = new HtmlRepairer(getRootDoc(),
2848
                                                  true, false,
2849
                                                  null, null,
2850
                                                  true);
2851
         for (int i=0; i<tags.length; ++i) {
2852
            printTag(output, repairer, tags[i], firstSentence, inline);
2853
         }
2854
         output.print(repairer.terminateText());
2855
      }
2856
      */
2857
   }
2858
 
2859
   private String getClassDocURL(HtmlPage output, ClassDoc classDoc)
2860
   {
2861
      return output.getPathToRoot()
2862
         + "/"
2863
         + getPackageURL(classDoc.containingPackage())
2864
         + classDoc.name() + filenameExtension;
2865
   }
2866
 
2867
   private String getMemberDocURL(HtmlPage output, ProgramElementDoc memberDoc)
2868
   {
2869
      ClassDoc classDoc = memberDoc.containingClass();
2870
      PackageDoc packageDoc = classDoc.containingPackage();
2871
      ExternalDocSet externalDocSet = null;
2872
      if (classDoc.containingPackage().name().length() > 0) {
2873
         externalDocSet = (ExternalDocSet)packageNameToDocSet.get(packageDoc.name());
2874
      }
2875
      StringBuffer result = new StringBuffer();
2876
      result.append(getClassDocURL(output, classDoc));
2877
      result.append('#');
2878
      if (null == externalDocSet) {
2879
         result.append(getMemberAnchor(memberDoc));
2880
      }
2881
      else {
2882
         result.append(getMemberAnchor(memberDoc, externalDocSet.isJavadocCompatible()));
2883
      }
2884
      return result.toString();
2885
   }
2886
 
2887
   private void printType(HtmlPage output, Type type)
2888
   {
2889
      printType(output, type, false);
2890
   }
2891
 
2892
   private void printType(HtmlPage output, Type type, boolean fullyQualified)
2893
   {
2894
      output.print(createTypeHref(output, type, fullyQualified));
2895
   }
2896
 
2897
   private String createTypeHref(HtmlPage output, Type type, boolean fullyQualified)
2898
   {
2899
      ClassDoc asClassDoc = type.asClassDoc();
2900
      String url = null;
2901
      if (null != asClassDoc && asClassDoc.isIncluded()) {
2902
         url = getClassDocURL(output, asClassDoc);
2903
      }
2904
      else if (!type.isPrimitive()) {
2905
         if (type.qualifiedTypeName().length() > type.typeName().length()) {
2906
            String packageName = type.qualifiedTypeName();
2907
            packageName = packageName.substring(0, packageName.length() - type.typeName().length() - 1);
2908
 
2909
            ExternalDocSet externalDocSet
2910
               = (ExternalDocSet)packageNameToDocSet.get(packageName);
2911
            if (null != externalDocSet) {
2912
               url = externalDocSet.getClassDocURL(packageName, type.typeName());
2913
            }
2914
         }
2915
      }
2916
 
2917
      StringBuffer result = new StringBuffer();
2918
 
2919
      if (null != url && null != asClassDoc) {
2920
        String parameters = getTypeParameters(asClassDoc);
2921
         if (fullyQualified) {
2922
            result.append(output.createHrefString(url,possiblyQualifiedName(asClassDoc) + parameters));
2923
         }
2924
         else {
2925
            StringBuffer title = new StringBuffer();
2926
            title.append(getClassTypeName(asClassDoc));
2927
            title.append(" in ");
2928
            title.append(asClassDoc.containingPackage().name());
2929
            result.append(output.createHrefString(url, asClassDoc.name() + parameters, title.toString()));
2930
         }
2931
      }
2932
      else {
2933
         result.append(possiblyQualifiedName(type));
2934
      }
2935
      result.append(type.dimension());
2936
      return result.toString();
2937
   }
2938
 
2939
   private void printTaglets(final HtmlPage output, Tag[] tags, TagletContext context)
2940
   {
2941
      super.printMainTaglets(tags, context, new TagletPrinter() {
2942
            public void printTagletString(String tagletString) {
2943
               output.beginDiv(CssClass.TAGLET);
2944
               output.print(tagletString);
2945
               output.endDiv(CssClass.TAGLET);
2946
            }
2947
         });
2948
   }
2949
 
2950
   private String getPackageURL(PackageDoc packageDoc)
2951
   {
2952
      if (packageDoc.name().length() > 0) {
2953
         ExternalDocSet externalDocSet = (ExternalDocSet)packageNameToDocSet.get(packageDoc.name());
2954
         String url;
2955
         if (null != externalDocSet) {
2956
            url = externalDocSet.getPackageDocURL(packageDoc.name());
2957
         }
2958
         else {
2959
            url = packageDoc.name().replace('.', '/');
2960
         }
2961
         if (!url.endsWith("/")) {
2962
            return url + '/';
2963
         }
2964
         else {
2965
            return url;
2966
         }
2967
     }
2968
      else {
2969
         return "";
2970
      }
2971
   }
2972
 
2973
   private String getClassURL(ClassDoc classDoc)
2974
   {
2975
      ExternalDocSet externalDocSet = null;
2976
      if (classDoc.containingPackage().name().length() > 0) {
2977
         externalDocSet = (ExternalDocSet)packageNameToDocSet.get(classDoc.containingPackage().name());
2978
      }
2979
      if (null != externalDocSet) {
2980
         return externalDocSet.getClassDocURL(classDoc.containingPackage().name(),
2981
                                              classDoc.name());
2982
      }
2983
      else {
2984
         return getPackageURL(classDoc.containingPackage()) + classDoc.name() + filenameExtension;
2985
      }
2986
   }
2987
 
2988
   protected void run()
2989
      throws DocletConfigurationException, IOException
2990
   {
2991
      if (optionSerialWarn.getValue()) {
2992
         printWarning("Option -serialwarn is currently ignored.");
2993
      }
2994
 
2995
      if (null != optionTitle.getValue()) {
2996
         printWarning("Option -title is deprecated.");
2997
      }
2998
 
2999
      if (!optionValidHtml.getValue()) {
3000
         printWarning("Option -validhtml hasn't been specified. Generated HTML will not validate.");
3001
      }
3002
 
3003
 
3004
      {
3005
         boolean warningEmitted = false;
3006
         Iterator it = externalDocSets.iterator();
3007
         while (it.hasNext()) {
3008
            ExternalDocSet externalDocSet = (ExternalDocSet)it.next();
3009
            printNotice("Fetching package list for external documentation set.");
3010
            try {
3011
               externalDocSet.load(getTargetDirectory());
3012
               if (!isJavadocCompatibleNames() && externalDocSet.isJavadocCompatible()
3013
                   && !warningEmitted) {
3014
                  printWarning("Linking to javadoc-compatible documentation. Generated HTML will not validate ");
3015
                  warningEmitted = true;
3016
               }
3017
            }
3018
            catch (FileNotFoundException e) {
3019
               printWarning("Cannot fetch package list from " + externalDocSet.getPackageListDir());
3020
            }
3021
            Iterator pit = externalDocSet.getPackageNames().iterator();
3022
            while (pit.hasNext()) {
3023
               String packageName = (String)pit.next();
3024
               packageNameToDocSet.put(packageName, externalDocSet);
3025
            }
3026
         }
3027
      }
3028
      printNotice("Building cross-reference information...");
3029
      getInterfaceRelations();
3030
      getAllSubClasses();
3031
 
3032
      printNotice("Writing overview files...");
3033
      printFrameSetPage();
3034
      if (!isSinglePackage()) {
3035
         printPackagesMenuPage();
3036
         printAllClassesMenuPage();
3037
         printOverviewPage();
3038
         if (!optionNoTree.getValue()) {
3039
            printNotice("Writing full tree...");
3040
            printFullTreePage();
3041
         }
3042
      }
3043
      printPackagesListFile();
3044
      printAboutPage();
3045
      if (!optionNoIndex.getValue()) {
3046
         printNotice("Writing index...");
3047
         if (!optionSplitIndex.getValue()) {
3048
            printIndexPage();
3049
         }
3050
         else {
3051
            printSplitIndex();
3052
         }
3053
      }
3054
      if (outputHelpPage && !optionNoHelp.getValue()) {
3055
         printHelpPage();
3056
      }
3057
 
3058
      // Copy resources
3059
 
3060
      File resourcesDir = new File(getTargetDirectory(),
3061
                                   "resources");
3062
 
3063
      if ((resourcesDir.exists() && !resourcesDir.isDirectory())
3064
          || (!resourcesDir.exists() && !resourcesDir.mkdirs())) {
3065
         throw new IOException("Cannot create directory " + resourcesDir);
3066
      }
3067
 
3068
      // Copy resources
3069
 
3070
      String[] resourceNames = {
3071
         "gjdoc.js",
3072
         "gjdochtml-clean-layout.css",
3073
         "gjdochtml-clean-color1.css",
3074
         "inherit.png",
3075
         "xhtml11-target10.dtd",
3076
      };
3077
 
3078
      for (int i=0; i<resourceNames.length; ++i) {
3079
         String resourceName = resourceNames[i];
3080
         File targetFile = new File(resourcesDir,
3081
                                    resourceName);
3082
         InputStream in = getClass().getResourceAsStream("/htmldoclet/" + resourceName);
3083
         if (in == null) {
3084
                in = new FileInputStream("src/resources/htmldoclet/" + resourceName);
3085
         }
3086
         FileOutputStream out = new FileOutputStream(targetFile);
3087
         IOToolkit.copyStream(in, out);
3088
         in.close();
3089
         out.close();
3090
      }
3091
 
3092
      // Copy stylesheets
3093
 
3094
      if (null != optionAddStylesheet.getValue()) {
3095
         File addStylesheetTargetFile = new File(resourcesDir,
3096
                                                 "user.css");
3097
 
3098
         IOToolkit.copyFile(optionAddStylesheet.getValue(),
3099
                            addStylesheetTargetFile);
3100
      }
3101
 
3102
      if (null != optionStylesheetFile.getValue()) {
3103
         File stylesheetTargetFile = new File(resourcesDir,
3104
                                              "user.css");
3105
 
3106
         IOToolkit.copyFile(optionStylesheetFile.getValue(),
3107
                            stylesheetTargetFile);
3108
      }
3109
 
3110
      // Write gjdoc.properties
3111
 
3112
      File gjdocPropertiesTargetFile = new File(getTargetDirectory(),
3113
                                                "gjdoc.properties");
3114
      writeGjdocProperties(gjdocPropertiesTargetFile);
3115
 
3116
      /*
3117
      else {
3118
         InputStream cssIn = getClass().getResourceAsStream("/htmldoclet/gjdochtml-vanilla.css");
3119
         FileOutputStream cssOut = new FileOutputStream(stylesheetTargetFile);
3120
         IOToolkit.copyStream(cssIn, cssOut);
3121
         cssIn.close();
3122
         cssOut.close();
3123
      }
3124
      */
3125
 
3126
      if (!optionNoDeprecatedList.getValue()) {
3127
         printDeprecationPage();
3128
      }
3129
 
3130
      printSerializationPage();
3131
 
3132
      Collection packageDocsCollection = getAllPackages();
3133
      PackageDoc[] packageDocs
3134
         = (PackageDoc[])packageDocsCollection.toArray(new PackageDoc[0]);
3135
 
3136
      for (int i=0; i<packageDocs.length; ++i) {
3137
         PackageDoc packageDoc = packageDocs[i];
3138
         File packageDir = new File(getTargetDirectory(),
3139
                                    packageDoc.name().replace('.', File.separatorChar));
3140
         if (!packageDir.exists() && !packageDir.mkdirs()) {
3141
            throw new IOException("Couldn't create directory " + packageDir);
3142
         }
3143
         try {
3144
            List packageSourceDirs = getPackageSourceDirs(packageDoc);
3145
            Iterator pdIt = packageSourceDirs.iterator();
3146
            while (pdIt.hasNext()) {
3147
               File sourcePackageDir = (File)pdIt.next();
3148
               copyDocFiles(sourcePackageDir, packageDir);
3149
            }
3150
         }
3151
         catch (IOException ignore) {
3152
         }
3153
         String pathToRoot = getPathToRoot(packageDir, getTargetDirectory());
3154
         String packageName = packageDoc.name();
3155
         if (0 == packageName.length()) {
3156
            packageName = "<unnamed>";
3157
         }
3158
         printNotice("Writing HTML files for package " + packageName);
3159
         printPackagePage(packageDir, pathToRoot, packageDoc,
3160
                          (i > 0) ? packageDocs[i - 1] : null,
3161
                          (i < packageDocs.length - 1) ? packageDocs[i + 1] : null);
3162
         if (!optionNoTree.getValue()) {
3163
            printPackageTreePage(packageDir, pathToRoot, packageDoc);
3164
         }
3165
         printPackageClassesMenuPage(packageDir, pathToRoot, packageDoc);
3166
         ClassDoc[] classDocs = packageDoc.allClasses();
3167
         for (int j=0; j<classDocs.length; ++j) {
3168
            ClassDoc classDoc = classDocs[j];
3169
            if (classDoc.isIncluded()) {
3170
               printClassPage(packageDir, pathToRoot,
3171
                              classDocs[j],
3172
                              (j > 0) ? classDocs[j - 1] : null,
3173
                              (j < classDocs.length - 1) ? classDocs[j + 1] : null
3174
                              );
3175
               if (optionUse.getValue()) {
3176
                  printClassUsagePage(packageDir, pathToRoot, classDocs[j]);
3177
               }
3178
               if (optionLinkSource.getValue() && null == classDoc.containingClass()) {
3179
                  try {
3180
                     File sourceFile = getSourceFile(classDoc);
3181
 
3182
                     Java2xhtml java2xhtml = new Java2xhtml();
3183
                     Properties properties = new Properties();
3184
                     properties.setProperty("isCodeSnippet", "true");
3185
                     properties.setProperty("hasLineNumbers", "true");
3186
                     java2xhtml.setProperties(properties);
3187
 
3188
                     StringWriter sourceBuffer = new StringWriter();
3189
                     FileReader sourceReader = new FileReader(sourceFile);
3190
                     IOToolkit.copyStream(sourceReader, sourceBuffer);
3191
                     sourceReader.close();
3192
                     String result = java2xhtml.makeHTML(sourceBuffer.getBuffer(), sourceFile.getName());
3193
 
3194
                     printSourcePage(packageDir,
3195
                                     classDoc,
3196
                                     result);
3197
                  }
3198
                  catch (IOException e) {
3199
                     printWarning("Cannot locate source file for class " + classDoc.qualifiedTypeName());
3200
                  }
3201
               }
3202
            }
3203
         }
3204
      }
3205
   }
3206
 
3207
   private String getPathToRoot(File subDir, File rootDir)
3208
   {
3209
      StringBuffer result = new StringBuffer();
3210
      while (!subDir.equals(rootDir)) {
3211
         if (result.length() > 0) {
3212
            result.append("/");
3213
         }
3214
         subDir = subDir.getParentFile();
3215
         result.append("..");
3216
      }
3217
      if (0 == result.length()) {
3218
         result.append(".");
3219
      }
3220
      return result.toString();
3221
   }
3222
 
3223
   private String getClassTypeName(ClassDoc classDoc)
3224
   {
3225
      if (classDoc.isInterface()) {
3226
         return "Interface";
3227
      }
3228
      else {
3229
         return "Class";
3230
      }
3231
   }
3232
 
3233
   private String getClassTypeKeyword(ClassDoc classDoc)
3234
   {
3235
      if (classDoc.isInterface()) {
3236
         return "interface";
3237
      }
3238
      else {
3239
         return "class";
3240
      }
3241
   }
3242
 
3243
   private String getMemberAnchor(ProgramElementDoc memberDoc)
3244
   {
3245
      return getMemberAnchor(memberDoc, isJavadocCompatibleNames());
3246
   }
3247
 
3248
   private String getMemberAnchor(ProgramElementDoc memberDoc, boolean javadocCompatibility)
3249
   {
3250
      StringBuffer anchor = new StringBuffer();
3251
      anchor.append(memberDoc.name());
3252
      if (memberDoc.isConstructor() || memberDoc.isMethod()) {
3253
         if (javadocCompatibility) {
3254
            anchor.append(((ExecutableMemberDoc)memberDoc).signature());
3255
         }
3256
         else {
3257
            anchor.append(':');
3258
            Parameter[] parameters = ((ExecutableMemberDoc)memberDoc).parameters();
3259
            for (int i=0; i<parameters.length; ++i) {
3260
               anchor.append(parameters[i].type().typeName());
3261
               for (int j=0; j<parameters[i].type().dimension().length()/2; ++j) {
3262
                  anchor.append('-');
3263
               }
3264
               if (i < parameters.length - 1) {
3265
                  anchor.append(':');
3266
               }
3267
            }
3268
         }
3269
      }
3270
      return anchor.toString();
3271
   }
3272
 
3273
   private String getFullModifiers(ProgramElementDoc memberDoc)
3274
   {
3275
      StringBuffer result = new StringBuffer();
3276
      if (memberDoc.isPackagePrivate()) {
3277
         result.append("(package private) ");
3278
      }
3279
      result.append(memberDoc.modifiers());
3280
      if ((memberDoc.isClass() && ((ClassDoc)memberDoc).isAbstract())
3281
          || (memberDoc.isMethod() && ((MethodDoc)memberDoc).isAbstract())) {
3282
         result.append(" abstract");
3283
      }
3284
      return result.toString();
3285
   }
3286
 
3287
   private String getSummaryModifiers(ProgramElementDoc memberDoc)
3288
   {
3289
      StringBuffer result = new StringBuffer();
3290
      if (memberDoc.isPackagePrivate()) {
3291
         result.append("(package private) ");
3292
      }
3293
      else if (memberDoc.isPrivate()) {
3294
         result.append("private ");
3295
      }
3296
      else if (memberDoc.isProtected()) {
3297
         result.append("protected ");
3298
      }
3299
      if (memberDoc.isStatic()) {
3300
         result.append("static");
3301
      }
3302
      else if ((memberDoc.isClass() && ((ClassDoc)memberDoc).isAbstract())
3303
          || (memberDoc.isMethod() && ((MethodDoc)memberDoc).isAbstract())) {
3304
         result.append("abstract");
3305
      }
3306
      return result.toString();
3307
   }
3308
 
3309
   protected DocletOption[] getOptions()
3310
   {
3311
      return options;
3312
   }
3313
 
3314
   private DocletOptionFlag optionNoNavBar =
3315
     new DocletOptionFlag("-nonavbar");
3316
 
3317
   private DocletOptionFlag optionNoTree =
3318
     new DocletOptionFlag("-notree");
3319
 
3320
   private DocletOptionFlag optionNoDeprecatedList =
3321
     new DocletOptionFlag("-nodeprecatedlist");
3322
 
3323
   private DocletOptionFlag optionNoIndex =
3324
     new DocletOptionFlag("-noindex");
3325
 
3326
   private DocletOptionFlag optionUse =
3327
     new DocletOptionFlag("-use");
3328
 
3329
   private DocletOptionFlag optionNoHelp =
3330
     new DocletOptionFlag("-nohelp");
3331
 
3332
   private DocletOptionFlag optionNoComment =
3333
     new DocletOptionFlag("-nocomment");
3334
 
3335
   private DocletOptionFlag optionSerialWarn =
3336
     new DocletOptionFlag("-serialwarn");
3337
 
3338
   private DocletOptionFlag optionSplitIndex =
3339
     new DocletOptionFlag("-splitindex");
3340
 
3341
   private DocletOptionString optionHeader =
3342
     new DocletOptionString("-header");
3343
 
3344
   private DocletOptionString optionFooter =
3345
     new DocletOptionString("-footer");
3346
 
3347
   private DocletOptionString optionBottom =
3348
     new DocletOptionString("-bottom");
3349
 
3350
   private DocletOptionString optionWindowTitle =
3351
     new DocletOptionString("-windowtitle");
3352
 
3353
   private DocletOptionString optionDocTitle =
3354
     new DocletOptionString("-doctitle");
3355
 
3356
   private DocletOptionString optionTitle =
3357
     new DocletOptionString("-title");
3358
 
3359
   private DocletOptionFile optionHelpFile =
3360
     new DocletOptionFile("-helpfile");
3361
 
3362
   private DocletOptionFile optionStylesheetFile =
3363
     new DocletOptionFile("-stylesheetfile");
3364
 
3365
   private DocletOptionFlag optionLinkSource =
3366
     new DocletOptionFlag("-linksource");
3367
 
3368
   private DocletOption optionLink =
3369
     new DocletOption("-link") {
3370
 
3371
        public int getLength()
3372
        {
3373
           return 2;
3374
        }
3375
 
3376
        public boolean set(String[] optionArr)
3377
        {
3378
           externalDocSets.add(new ExternalDocSet(optionArr[1], null));
3379
           return true;
3380
        }
3381
     };
3382
 
3383
   private DocletOption optionLinkOffline =
3384
     new DocletOption("-linkoffline") {
3385
 
3386
        public int getLength()
3387
        {
3388
           return 3;
3389
        }
3390
 
3391
        public boolean set(String[] optionArr)
3392
        {
3393
           externalDocSets.add(new ExternalDocSet(optionArr[1], optionArr[2]));
3394
           return true;
3395
        }
3396
     };
3397
 
3398
   private DocletOptionString optionDocEncoding =
3399
     new DocletOptionString("-docencoding");
3400
 
3401
   private DocletOptionString optionEncoding =
3402
     new DocletOptionString("-encoding");
3403
 
3404
   private DocletOptionString optionCharset =
3405
     new DocletOptionString("-charset");
3406
 
3407
   private DocletOptionFile optionAddStylesheet =
3408
     new DocletOptionFile("-addstylesheet");
3409
 
3410
   private DocletOptionFlag optionValidHtml =
3411
     new DocletOptionFlag("-validhtml");
3412
 
3413
   private DocletOptionString optionBaseUrl =
3414
     new DocletOptionString("-baseurl");
3415
 
3416
   private DocletOption[] options =
3417
      {
3418
         optionNoNavBar,
3419
         optionNoTree,
3420
         optionNoDeprecatedList,
3421
         optionNoIndex,
3422
         optionNoHelp,
3423
         optionNoComment,
3424
         optionUse,
3425
         optionSplitIndex,
3426
         optionHeader,
3427
         optionFooter,
3428
         optionBottom,
3429
         optionHelpFile,
3430
         optionStylesheetFile,
3431
         optionWindowTitle,
3432
         optionDocTitle,
3433
         optionTitle,
3434
         optionLinkSource,
3435
         optionLink,
3436
         optionLinkOffline,
3437
         optionDocEncoding,
3438
         optionEncoding,
3439
         optionCharset,
3440
         optionAddStylesheet,
3441
         optionValidHtml,
3442
         optionBaseUrl,
3443
      };
3444
 
3445
   static {
3446
      setInstance(new HtmlDoclet());
3447
   }
3448
 
3449
   private static String replaceDocRoot(HtmlPage output, String str)
3450
   {
3451
      return StringToolkit.replace(str, "{@docRoot}", output.getPathToRoot());
3452
   }
3453
 
3454
   private String getOutputDocEncoding()
3455
   {
3456
      String encoding = optionDocEncoding.getValue();
3457
 
3458
      if (null == encoding) {
3459
         encoding = optionEncoding.getValue();
3460
      }
3461
 
3462
      return encoding;
3463
   }
3464
 
3465
   private String getOutputCharset()
3466
   {
3467
      if (null == outputCharset) {
3468
 
3469
         if (null != optionCharset.getValue()) {
3470
            outputCharset = optionCharset.getValue();
3471
         }
3472
         else {
3473
            String fileEncoding = System.getProperty("file.encoding");
3474
            if (null != fileEncoding) {
3475
               try {
3476
                  outputCharset = Charset.forName(fileEncoding).name();
3477
               }
3478
               catch (Exception ignore) {
3479
               }
3480
            }
3481
 
3482
            if (null == outputCharset) {
3483
               printWarning("Cannot determine platform default charset, falling back to ISO-8859-1.");
3484
               outputCharset = "ISO-8859-1";
3485
            }
3486
         }
3487
      }
3488
      return outputCharset;
3489
   }
3490
 
3491
   public InlineTagRenderer getInlineTagRenderer()
3492
   {
3493
      return this;
3494
   }
3495
 
3496
   public String renderInlineTags(Tag[] tags, TagletContext context)
3497
   {
3498
      StringBuffer result = new StringBuffer();
3499
 
3500
      HtmlRepairer repairer = new HtmlRepairer(getRootDoc(),
3501
                                               true, false,
3502
                                               null, null,
3503
                                               true);
3504
 
3505
      for (int i=0; i<tags.length; ++i) {
3506
 
3507
         Tag tag = tags[i];
3508
 
3509
         if ("Text".equals(tag.name())) {
3510
            result.append(repairer.getWellformedHTML(tag.text()));
3511
         }
3512
         else if ("@link".equals(tag.name())) {
3513
            result.append(renderSeeTag((SeeTag)tag, context, false));
3514
         }
3515
         else if ("@linkplain".equals(tag.name())) {
3516
            result.append(renderSeeTag((SeeTag)tag, context, true));
3517
         }
3518
         else if ("@docRoot".equals(tag.name())) {
3519
            result.append(((HtmlTagletContext)context).getOutput().getPathToRoot());
3520
         }
3521
         else {
3522
            //TagletContext context = TagletContext.OVERVIEW; // FIXME
3523
            Taglet taglet = (Taglet)tagletMap.get(tag.name().substring(1));
3524
            if (null != taglet) {
3525
               if (taglet instanceof GnuExtendedTaglet) {
3526
                  result.append(((GnuExtendedTaglet)taglet).toString(tag, context));
3527
               }
3528
               else {
3529
                  result.append(taglet.toString(tag));
3530
               }
3531
            }
3532
         }
3533
      }
3534
      result.append(repairer.terminateText());
3535
      return result.toString();
3536
   }
3537
 
3538
   public String renderSeeTag(SeeTag seeTag, TagletContext context, boolean plainFont)
3539
   {
3540
      StringBuffer result = new StringBuffer();
3541
 
3542
      String href = null;
3543
      String label = null;
3544
      MemberDoc referencedMember = seeTag.referencedMember();
3545
      if (null != seeTag.referencedClass()) {
3546
 
3547
         href = getClassDocURL(((HtmlTagletContext)context).getOutput(), seeTag.referencedClass());
3548
 
3549
         Doc doc = context.getDoc();
3550
         ClassDoc classDoc = null;
3551
         if (doc.isClass() || doc.isInterface()) {
3552
            classDoc = (ClassDoc)doc;
3553
         }
3554
         else if (doc.isField() || doc.isMethod() || doc.isConstructor()) {
3555
            classDoc = ((MemberDoc)doc).containingClass();
3556
         }
3557
 
3558
         if (null == referencedMember
3559
             || seeTag.referencedClass() != classDoc
3560
             || ((HtmlTagletContext)context).isOnSerializedPage()) {
3561
 
3562
            if (!seeTag.referencedClass().isIncluded()) {
3563
               label = possiblyQualifiedName(seeTag.referencedClass());
3564
            }
3565
            else {
3566
               label = seeTag.referencedClass().typeName();
3567
            }
3568
            if (null != referencedMember) {
3569
               label += '.';
3570
            }
3571
         }
3572
         else {
3573
            label = "";
3574
         }
3575
 
3576
         if (null != referencedMember) {
3577
            label += referencedMember.name();
3578
            if (referencedMember.isMethod() || referencedMember.isConstructor()) {
3579
               label += ((ExecutableMemberDoc)referencedMember).flatSignature();
3580
            }
3581
            href  += '#' + getMemberAnchor(referencedMember);
3582
         }
3583
         else if (null != seeTag.referencedMemberName()) {
3584
            href = null;
3585
         }
3586
      }
3587
      else {
3588
         String referencedClassName = seeTag.referencedClassName();
3589
 
3590
         if (null != referencedClassName) {
3591
 
3592
            String referencedPackageName = null;
3593
 
3594
            Iterator it = packageNameToDocSet.keySet().iterator();
3595
            while (it.hasNext()) {
3596
               String packageName = (String)it.next();
3597
               if ((null == referencedPackageName
3598
                    || packageName.length() > referencedPackageName.length())
3599
                   && referencedClassName.startsWith(packageName + '.')) {
3600
                  referencedPackageName = packageName;
3601
               }
3602
            }
3603
 
3604
            if (null != referencedPackageName) {
3605
               ExternalDocSet externalDocSet
3606
                  = (ExternalDocSet)packageNameToDocSet.get(referencedPackageName);
3607
 
3608
               String className = referencedClassName.substring(referencedPackageName.length() + 1);
3609
               href = externalDocSet.getClassDocURL(referencedPackageName,
3610
                                                    className);
3611
               label = className;
3612
 
3613
               String referencedMemberName = seeTag.referencedMemberName();
3614
 
3615
               if (null != referencedMemberName) {
3616
                  label += '.';
3617
                  label += referencedMemberName;
3618
                  href  += '#' + transformReferencedMemberName(referencedMemberName,
3619
                                                               externalDocSet.isJavadocCompatible());
3620
               }
3621
               else if (null != seeTag.referencedMemberName()) {
3622
                  href = null;
3623
               }
3624
            }
3625
         }
3626
      }
3627
 
3628
      if (null != seeTag.label()
3629
          && seeTag.label().length() > 0) {
3630
         label = seeTag.label();
3631
      }
3632
 
3633
      if (null == label) {
3634
         label = seeTag.text();
3635
         if (label.startsWith("#")) {
3636
            label = label.substring(1);
3637
         }
3638
         else {
3639
            label = label.replace('#', '.');
3640
         }
3641
         label.trim();
3642
      }
3643
 
3644
      if (null != href) {
3645
         result.append("<a href=\"");
3646
         result.append(href);
3647
         result.append("\">");
3648
         if (!plainFont) {
3649
            result.append("<code>");
3650
         }
3651
         result.append(label);
3652
         if (!plainFont) {
3653
            result.append("</code>");
3654
         }
3655
         result.append("</a>");
3656
      }
3657
      else {
3658
         if (!plainFont) {
3659
            result.append("<code>");
3660
         }
3661
         result.append(label);
3662
         if (!plainFont) {
3663
            result.append("</code>");
3664
         }
3665
      }
3666
 
3667
      return result.toString();
3668
   }
3669
 
3670
   protected String renderTag(String tagName, Tag[] tags, TagletContext context)
3671
   {
3672
      Doc doc = context.getDoc();
3673
 
3674
      if ("see".equals(tagName)
3675
          && ((tags.length > 0)
3676
              || (doc.isClass()
3677
                  && (((ClassDoc)doc).isSerializable()
3678
                      || ((ClassDoc)doc).isExternalizable())))) {
3679
 
3680
         StringBuffer result = new StringBuffer();
3681
         result.append("<dl class=\"tag list\">");
3682
         result.append("<dt class=\"tag section header\"><b>");
3683
         result.append("See Also:");
3684
         result.append("</b></dt>");
3685
 
3686
         boolean oneLine = true;
3687
 
3688
         if (oneLine) {
3689
            result.append("<dd>");
3690
         }
3691
 
3692
         for (int i = 0; i < tags.length; ++i) {
3693
            if (oneLine) {
3694
               if (i > 0) {
3695
                  result.append(", ");
3696
               }
3697
            }
3698
            else {
3699
               result.append("<dd>");
3700
            }
3701
            result.append(renderSeeTag((SeeTag)tags[i], context, false));
3702
            if (!oneLine) {
3703
               result.append("</dd>");
3704
            }
3705
         }
3706
 
3707
         if ((doc instanceof ClassDoc)
3708
             && (((ClassDoc)doc).isSerializable() || ((ClassDoc)doc).isExternalizable())) {
3709
            if (tags.length > 0) {
3710
               result.append(", ");
3711
            }
3712
            HtmlPage output = ((HtmlTagletContext)context).getOutput();
3713
            result.append("<a href=\"" + output.getPathToRoot() + "/serialized-form" + filenameExtension + "#" + ((ClassDoc)doc).qualifiedName() + "\">Serialized Form</a>");
3714
         }
3715
 
3716
         if (oneLine) {
3717
            result.append("</dd>");
3718
         }
3719
         result.append("</dl>");
3720
         return result.toString();
3721
      }
3722
      else if (tags.length > 0
3723
               && "serial".equals(tagName)
3724
               && ((HtmlTagletContext)context).isOnSerializedPage()) {
3725
 
3726
         return renderInlineTags(tags[0].inlineTags(), context);
3727
      }
3728
      else {
3729
         return "";
3730
      }
3731
   }
3732
 
3733
   private String getWindowTitle()
3734
   {
3735
      if (null == optionWindowTitle.getValue()) {
3736
         return "Generated API Documentation";
3737
      }
3738
      else {
3739
         return optionWindowTitle.getValue();
3740
      }
3741
   }
3742
 
3743
   private String getPageTitle(String title)
3744
   {
3745
      if (null == optionWindowTitle.getValue()) {
3746
         return title;
3747
      }
3748
      else {
3749
         return title + " (" + optionWindowTitle.getValue() + ")";
3750
      }
3751
   }
3752
 
3753
   protected String getDocletVersion()
3754
   {
3755
      if (null == docletVersion) {
3756
         docletVersion = gnu.classpath.Configuration.CLASSPATH_VERSION;
3757
      }
3758
      return docletVersion;
3759
   }
3760
 
3761
   private Map getStylesheets()
3762
   {
3763
      Map sheets = new HashMap();
3764
      if (null != optionStylesheetFile.getValue()) {
3765
         sheets.put("User-specified", new String[] {
3766
            "resources/user.css"
3767
         });
3768
      }
3769
      else {
3770
         List cleanSheets = new LinkedList();
3771
         cleanSheets.add("resources/gjdochtml-clean-layout.css");
3772
         cleanSheets.add("resources/gjdochtml-clean-color1.css");
3773
         if (null != optionAddStylesheet.getValue()) {
3774
            cleanSheets.add("resources/user.css");
3775
         }
3776
         sheets.put("GNU Clean", cleanSheets.toArray(new String[0]));
3777
      }
3778
      return sheets;
3779
   }
3780
 
3781
   protected boolean isSinglePackage()
3782
   {
3783
      if (getRootDoc().firstSentenceTags().length > 0) {
3784
         return false;
3785
      }
3786
      else if (null != optionDocTitle.getValue()
3787
               || null != optionTitle.getValue()) {
3788
         return false;
3789
      }
3790
      else {
3791
         return super.isSinglePackage();
3792
      }
3793
   }
3794
 
3795
  private String getTypeParameters(ClassDoc classDoc)
3796
  {
3797
    String parameters = "";
3798
    TypeVariable[] params = classDoc.typeParameters();
3799
    if (params != null && params.length > 0)
3800
      {
3801
        parameters = "&lt;";
3802
        for (int a = 0; a < params.length; ++a)
3803
          {
3804
            parameters += params[a].typeName();
3805
            Type[] bounds = params[a].bounds();
3806
            if (bounds != null)
3807
              {
3808
                parameters += " extends ";
3809
                for (int b = 0; a < bounds.length; ++b)
3810
                  {
3811
                    parameters += bounds[a];
3812
                    if (b != bounds.length - 1)
3813
                      parameters += " & ";
3814
                  }
3815
              }
3816
            if (a != params.length - 1)
3817
              parameters += ",";
3818
          }
3819
        parameters += "&gt;";
3820
      }
3821
    return parameters;
3822
  }
3823
 
3824
   private String transformReferencedMemberName(String referencedMemberName,
3825
                                                boolean javadocCompatibility)
3826
   {
3827
      if (!javadocCompatibility) {
3828
         StringBuffer result = new StringBuffer();
3829
         for (int i=0; i<referencedMemberName.length(); ++i) {
3830
            char c = referencedMemberName.charAt(i);
3831
            switch (c) {
3832
            case '(': result.append(':'); break;
3833
            case ')': break;
3834
            case ',': result.append(':'); break;
3835
            case '[': result.append('-'); break;
3836
            case ']': break;
3837
            default:  result.append(c); break;
3838
            }
3839
         }
3840
         return result.toString();
3841
      }
3842
      else {
3843
         return referencedMemberName;
3844
      }
3845
   }
3846
 
3847
   public void writeGjdocProperties(File outputFile)
3848
      throws IOException
3849
   {
3850
      Properties properties = new Properties();
3851
      properties.setProperty("gjdoc.version", getDocletVersion());
3852
      properties.setProperty("gjdoc.compat", Boolean.toString(isJavadocCompatibleNames()));
3853
 
3854
      FileOutputStream out = new FileOutputStream(outputFile);
3855
      properties.store(out, "GNU Gjdoc API Documentation Set Descriptor");
3856
      out.close();
3857
   }
3858
 
3859
   public boolean isJavadocCompatibleNames()
3860
   {
3861
      return !optionValidHtml.getValue();
3862
   }
3863
 
3864
   private HtmlPage newHtmlPage(File file,
3865
                                String pathToRoot)
3866
      throws IOException
3867
   {
3868
      return new HtmlPage(file,
3869
                          pathToRoot,
3870
                          getOutputDocEncoding(),
3871
                          optionBaseUrl.getValue(),
3872
                          getTargetDirectory());
3873
   }
3874
 
3875
   private HtmlPage newHtmlPage(File file,
3876
                                String pathToRoot,
3877
                                String docType)
3878
      throws IOException
3879
   {
3880
      return new HtmlPage(file,
3881
                          pathToRoot,
3882
                          getOutputDocEncoding(),
3883
                          optionBaseUrl.getValue(),
3884
                          getTargetDirectory(),
3885
                          docType);
3886
   }
3887
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.