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/] [xmldoclet/] [Driver.java] - Blame information for rev 779

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 779 jeremybenn
/* gnu.classpath.tools.doclets.xmldoclet.Driver
2
   Copyright (C) 2001 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.xmldoclet;
39
 
40
import com.sun.javadoc.*;
41
import java.io.*;
42
 
43
import com.sun.tools.doclets.Taglet;
44
 
45
import java.lang.reflect.InvocationTargetException;
46
import java.lang.reflect.Method;
47
import java.lang.reflect.Modifier;
48
 
49
import java.text.DateFormat;
50
 
51
import java.util.ArrayList;
52
import java.util.Arrays;
53
import java.util.Comparator;
54
import java.util.HashSet;
55
import java.util.TreeSet;
56
import java.util.Iterator;
57
import java.util.LinkedHashMap;
58
import java.util.LinkedList;
59
import java.util.List;
60
import java.util.Locale;
61
import java.util.Map;
62
import java.util.HashMap;
63
import java.util.Properties;
64
import java.util.Set;
65
import java.util.SortedSet;
66
import java.util.StringTokenizer;
67
import java.util.TreeMap;
68
 
69
import gnu.classpath.tools.gjdoc.TemporaryStore;
70
import gnu.classpath.tools.gjdoc.GjdocPackageDoc;
71
 
72
import gnu.classpath.tools.doclets.PackageGroup;
73
import gnu.classpath.tools.doclets.PackageMatcher;
74
import gnu.classpath.tools.doclets.InvalidPackageWildcardException;
75
 
76
import gnu.classpath.tools.doclets.xmldoclet.doctranslet.DocTranslet;
77
import gnu.classpath.tools.doclets.xmldoclet.doctranslet.DocTransletOptions;
78
 
79
import gnu.classpath.tools.taglets.AuthorTaglet;
80
import gnu.classpath.tools.taglets.VersionTaglet;
81
import gnu.classpath.tools.taglets.SinceTaglet;
82
import gnu.classpath.tools.taglets.DeprecatedTaglet;
83
import gnu.classpath.tools.taglets.GenericTaglet;
84
import gnu.classpath.tools.doclets.StandardTaglet;
85
 
86
import gnu.classpath.tools.java2xhtml.Java2xhtml;
87
 
88
import gnu.classpath.tools.IOToolkit;
89
import gnu.classpath.tools.FileSystemClassLoader;
90
 
91
/**
92
 *  A Doclet which retrieves all information presented by the Doclet
93
 *  API, dumping it to stdout in XML format.
94
 *
95
 *  @author Julian Scheid
96
 */
97
public class Driver {
98
 
99
   public static final String XMLDOCLET_VERSION = "0.6.1";
100
 
101
   /**
102
    *  Used for redirecting error messages to <code>/dev/null</code>.
103
    */
104
   private static class NullErrorReporter implements DocErrorReporter {
105
      public void printError(String ignore) {}
106
      public void printWarning(String ignore) {}
107
      public void printNotice(String ignore) {}
108
   }
109
 
110
   /*
111
    *  Taglet context constants.
112
    */
113
   private static final int CONTEXT_CONSTRUCTOR  = 1;
114
   private static final int CONTEXT_FIELD        = 2;
115
   private static final int CONTEXT_METHOD       = 3;
116
   private static final int CONTEXT_OVERVIEW     = 4;
117
   private static final int CONTEXT_PACKAGE      = 5;
118
   private static final int CONTEXT_TYPE         = 6;
119
 
120
   /**
121
    *  All XML output will go to this stream.
122
    */
123
   private PrintWriter out;
124
 
125
   /**
126
    *  How many spaces to indent each XML node level,
127
    *  i.e. Tab size for output.
128
    */
129
   private static int indentStep = 1;
130
 
131
   /**
132
    *  Won't output superfluous spaces if set to true.
133
    *  If set to false, output will be more legible.
134
    */
135
   private boolean compress = false;
136
 
137
   /**
138
    *  Won't output warning messages while fixing
139
    *  HTML code if set to true.
140
    */
141
   private boolean noHTMLWarn = false;
142
 
143
   /**
144
    *  Won't output warning messages when encountering tags
145
    *  that look like an email address if set to true.
146
    */
147
   private boolean noEmailWarn = false;
148
 
149
   /**
150
    *  Will fix HTML if necessary so that each comment
151
    *  contains valid XML code if set to true. If set
152
    *  to false, HTML code will not be modified and
153
    *  instead encapsulated in a CDATA section.
154
    */
155
   private boolean fixHTML = true;
156
 
157
   /**
158
    *  User-specified name of the directory where the final version of
159
    *  the generated files will be written to.
160
    *
161
    *  If no XSLT sheet is given, the XML output will go directly into
162
    *  this directory. Otherwise, XML output will go to a temporary
163
    *  directory and XSLT output will go to this directory.
164
    */
165
   private File targetDirectory = null;
166
 
167
   /**
168
    *  Directory where XML output will be written to. If no XSLT
169
    *  sheet was given, this is the target directory specified
170
    *  by the user. Otherwise, this is a temporary directory.
171
    */
172
   private File xmlTargetDirectory;
173
 
174
   /**
175
    *  Contains a number of TargetContexts which describe which XSLT
176
    *  sheet to apply to the output of this doclet, to what directory
177
    *  the XSLT output is written, and which postprocess driver to use
178
    *  to process XSLT output.
179
    */
180
   private List targets = new ArrayList();
181
 
182
   /**
183
    *  XML text to include at the end of every generated page. Read
184
    *  from the file specified on the command line using -bottomnote.
185
    *  If present, this will be written to the main output file
186
    *  (index.xml) in node /gjdoc:rootDoc/gjdoc:bottomnote.
187
    */
188
   private String bottomNote;
189
 
190
   /**
191
    *  Brief description of the package set. Can be specified on the
192
    *  command line using -title.  This will be written to the main
193
    *  output file (index.xml) in node
194
    *  /gjdoc:rootDoc/gjdoc:title. The HTML generating XSLT sheet
195
    *  uses this for example in window titles.
196
    */
197
   private String title;
198
 
199
   /**
200
    *  Path to the directory where temporary files should be stored.
201
    *  Defaults to system tempdir, but can be overridden by user
202
    *  with -workpath.
203
    */
204
   private String workingPath = System.getProperty("java.io.tmpdir");
205
 
206
   /**
207
    *  Temporary directory created by this doclet where all
208
    *  temporary files will be stored in. If no temporary
209
    *  files are needed (i.e. no XSLT postprocessing stage
210
    *  specified by user), this is <code>null</code>.
211
    */
212
    private File workingDirectory;
213
 
214
   /**
215
    *  Whether to deep-copy the doc-files subdirectory.
216
    */
217
    private boolean docFilesSubdirsEnabled = false;
218
 
219
   /**
220
    *  Which direct subdirectories of the doc-files directories to exclude.
221
    *  Set of String.
222
    */
223
    private Set excludeDocFilesSubDirs = new HashSet();
224
 
225
   /**
226
    *  Stores the Doclet API RootDoc we are operating on.
227
    */
228
   private RootDoc rootDoc;
229
 
230
   /**
231
    *  XML namespace prefix used for all tags, except for HTML
232
    *  tags copied from Javadoc comments. Excluding colon.
233
    */
234
   public static final String tagPrefix = "gjdoc";
235
 
236
   /**
237
    *  Classpath for loading Taglet classes.
238
    */
239
   private String tagletPath = null;
240
 
241
   /**
242
    *  The current class that is being processed.
243
    *  Set in outputClassDoc().
244
    */
245
   private ClassDoc currentClass;
246
 
247
   /**
248
    *  The current member that is being processed.
249
    *  Set in outputMemberDoc().
250
    */
251
   private MemberDoc currentMember;
252
 
253
   /**
254
    *  The current constructor/method that is being processed.
255
    *  Set in outputExecutableMemberDoc().
256
    */
257
   private ExecutableMemberDoc currentExecMember;
258
 
259
   /**
260
    *  Mapping from tag type to Taglet for user Taglets specified on
261
    *  the command line.
262
    */
263
   private Map tagletMap = new LinkedHashMap();
264
 
265
   /**
266
    *  Keeps track of the tags mentioned by the user during option
267
    *  processiong so that an error can be emitted if a tag is
268
    *  mentioned more than once.
269
    */
270
   private List mentionedTags = new LinkedList();
271
 
272
   /**
273
    *  Stores options to be passed to the DocTranslet.
274
    */
275
   private DocTransletOptions docTransletOptions = new DocTransletOptions();
276
 
277
   /**
278
    *  Stores the package groups specified in the user
279
    *  options. Contains objects of type PackageGroup.
280
    */
281
   private List packageGroups = new LinkedList();
282
 
283
   private HtmlRepairer htmlRepairer;
284
 
285
   public static boolean start(TemporaryStore _rootDocWrapper) {
286
      return new Driver().instanceStart((RootDoc)_rootDocWrapper.getAndClear());
287
   }
288
 
289
   /**
290
    *  Official Doclet entry point.
291
    */
292
   public static boolean start(RootDoc _rootDoc) {
293
 
294
      // Create a new XmlDoclet instance and delegate control.
295
      TemporaryStore tstore = new TemporaryStore(_rootDoc);
296
      _rootDoc = null;
297
      return new Driver().instanceStart((RootDoc)tstore.getAndClear());
298
   }
299
 
300
   /**
301
    *  Output an XML tag describing a com.sun.javadoc.Type object.
302
    *  Assumes that the tag does not have subtags.
303
    *
304
    *  @param level  Level of indentation. Will be multiplied by
305
    *                <code>indentStep</code> to yield actual amount
306
    *                of whitespace inserted at start of line.
307
    *  @param tag    Identifier for the XML tag being output.
308
    *  @param type   The Javadoc Type to be output.
309
    */
310
   protected void outputType(int level, String tag, Type type) {
311
      outputType(level, tag, type, true);
312
   }
313
 
314
   protected void outputType(int level, String tag, Type type, boolean atomic) {
315
 
316
      boolean isIncluded = false;
317
      ClassDoc typeAsClassDoc = type.asClassDoc();
318
      String packageName = null;
319
      if (null != typeAsClassDoc) {
320
         isIncluded = typeAsClassDoc.isIncluded();
321
         packageName = typeAsClassDoc.containingPackage().name();
322
      }
323
      println(level, "<"+tagPrefix+":"+tag + " typename=\""+type.typeName()+"\""+
324
              " qualifiedtypename=\""+type.qualifiedTypeName()+"\""
325
              +(type.dimension().length()==0?"":" dimension=\""+type.dimension()+"\"")
326
              +(isIncluded?" isIncluded=\"true\"" : "")
327
              +((null != packageName)?" package=\"" + packageName + "\"" : "")
328
              +(atomic?"/":"")+">");
329
   }
330
 
331
   protected void outputExecutableMemberDocBody(int level, ExecutableMemberDoc memberDoc) {
332
 
333
      currentExecMember = memberDoc;
334
 
335
      outputMemberDocBody(level, memberDoc);
336
 
337
      Parameter[] parameters = memberDoc.parameters();
338
      for (int i=0, ilim=parameters.length; i<ilim; ++i) {
339
         Parameter parameter = parameters[i];
340
         outputType(level, "parameter name=\""+parameter.name()+"\"", parameter.type());
341
      }
342
 
343
      ClassDoc[] exceptions = memberDoc.thrownExceptions();
344
      for (int i=0, ilim=exceptions.length; i<ilim; ++i) {
345
         ClassDoc exception = exceptions[i];
346
         outputType(level, "thrownException", exception);
347
       }
348
 
349
      printAtomTag(level, "signature full=\""+memberDoc.signature()+"\" flat=\""+memberDoc.flatSignature()+"\"");
350
 
351
      if (memberDoc.isNative()) {
352
         printAtomTag(level, "isNative");
353
      }
354
 
355
      if (memberDoc.isSynchronized()) {
356
         printAtomTag(level, "isSynchronized");
357
      }
358
   }
359
 
360
   protected void outputMethodDoc(int level, MethodDoc methodDoc) {
361
      println();
362
      printOpenTag(level, "methoddoc name=\""+methodDoc.name()+"\"");
363
      outputExecutableMemberDocBody(level+1, methodDoc);
364
      outputType(level+1, "returns", methodDoc.returnType());
365
      printCloseTag(level, "methoddoc");
366
   }
367
 
368
   protected void outputMemberDocBody(int level, MemberDoc memberDoc) {
369
      currentMember = memberDoc;
370
      outputProgramElementDocBody(level, memberDoc);
371
   }
372
 
373
   protected void outputFieldDocBody(int level, FieldDoc fieldDoc) {
374
      outputType(level, "type", fieldDoc.type());
375
      if (fieldDoc.isTransient()) {
376
         printAtomTag(level, "isTransient");
377
      }
378
      if (fieldDoc.isVolatile()) {
379
         printAtomTag(level, "isVolatile");
380
      }
381
   }
382
 
383
   private void outputFieldDoc(int level, FieldDoc fieldDoc) {
384
      println();
385
      printOpenTag(level, "fielddoc name=\""+fieldDoc.name()+"\"");
386
      outputMemberDocBody(level+1, fieldDoc);
387
      outputFieldDocBody(level+1, fieldDoc);
388
      printCloseTag(level, "fielddoc");
389
   }
390
 
391
   protected void outputConstructorDoc(int level, ConstructorDoc constructorDoc) {
392
      println();
393
      printOpenTag(level, "constructordoc name=\""+constructorDoc.name()+"\"");
394
      outputExecutableMemberDocBody(level+1, constructorDoc);
395
      printCloseTag(level, "constructordoc");
396
   }
397
 
398
   protected void outputSuperInterfacesRec(int level, ClassDoc classDoc) {
399
      if (null!=classDoc) {
400
         ClassDoc[] interfaces = classDoc.interfaces();
401
         if (null != interfaces) {
402
            for (int i=0, ilim=interfaces.length; i<ilim; ++i) {
403
               outputType(level, "superimplements", interfaces[i]);
404
            }
405
         }
406
         outputSuperInterfacesRec(level, classDoc.superclass());
407
      }
408
   }
409
 
410
   protected void outputClassDocSummary(ClassDoc classDoc) {
411
      println();
412
      printOpenTag(1, "classdoc name=\""+classDoc.name()+"\" qualifiedtypename=\""+classDoc.qualifiedName()+"\" isIncluded=\"true\"");
413
      if (null!=classDoc.superclass()) {
414
         outputType(2, "superclass", classDoc.superclass());
415
      }
416
 
417
      ClassDoc[] interfaces = classDoc.interfaces();
418
      for (int i=0, ilim=interfaces.length; i<ilim; ++i) {
419
         outputType(2, "implements", interfaces[i]);
420
      }
421
      outputSuperInterfacesRec(2, classDoc.superclass());
422
 
423
      printAtomTag(2, "containingPackage name=\""+classDoc.containingPackage().name()+"\"");
424
      if (classDoc.isError()) {
425
         printAtomTag(2, "isError");
426
      }
427
      if (classDoc.isException()) {
428
         printAtomTag(2, "isException");
429
      }
430
      if (classDoc.isInterface()) {
431
         printAtomTag(2, "isInterface");
432
      }
433
      if (classDoc.isOrdinaryClass()) {
434
         printAtomTag(2, "isOrdinaryClass");
435
      }
436
 
437
      printCloseTag(1, "classdoc");
438
   }
439
 
440
   protected void outputPackageDoc(PackageDoc packageDoc) {
441
      println();
442
      printOpenTag(1, "packagedoc name=\""+packageDoc.name()+"\"");
443
      if (packageDoc.firstSentenceTags().length > 0) {
444
         printOpenTag(2, "firstSentenceTags", false);
445
         outputTags(3, packageDoc.firstSentenceTags(), true, CONTEXT_PACKAGE);
446
         printCloseTag(0, "firstSentenceTags");
447
         printOpenTag(2, "inlineTags", false);
448
         outputTags(3, packageDoc.inlineTags(), true, CONTEXT_PACKAGE);
449
         printCloseTag(0, "inlineTags");
450
      }
451
 
452
      if (packageDoc.tags().length > 0) {
453
         printOpenTag(2, "tags");
454
         outputTags(3, packageDoc.tags(), true, CONTEXT_PACKAGE);
455
         printCloseTag(2, "tags");
456
      }
457
 
458
      if (packageDoc.seeTags().length > 0) {
459
         printOpenTag(2, "seeTags");
460
         outputTags(3, packageDoc.seeTags(), true, CONTEXT_PACKAGE);
461
         printCloseTag(2, "seeTags");
462
      }
463
 
464
      ClassDoc[] allClasses = (ClassDoc[]) packageDoc.allClasses().clone();
465
      Arrays.sort(allClasses);
466
 
467
      if (false) {
468
         for (int i = 0, ilim = allClasses.length; i < ilim; ++ i) {
469
            printAtomTag(2, "containsClass qualifiedtypename=\""+allClasses[i].qualifiedTypeName()+"\"");
470
         }
471
      }
472
 
473
      printCloseTag(1, "packagedoc");
474
   }
475
 
476
   protected void outputClassDoc(ClassDoc classDoc) throws IOException {
477
 
478
      currentClass = classDoc;
479
 
480
      println();
481
      printOpenTag(1, "classdoc xmlns=\"http://www.w3.org/TR/REC-html40\" xmlns:"+tagPrefix+"=\"http://www.gnu.org/software/cp-tools/gjdocxml\" name=\""+classDoc.name()+"\" qualifiedtypename=\""+classDoc.qualifiedName()+"\"");
482
 
483
      ClassDoc[] interfaces = classDoc.interfaces();
484
      for (int i=0, ilim=interfaces.length; i<ilim; ++i) {
485
         outputType(2, "implements", interfaces[i]);
486
      }
487
      outputSuperInterfacesRec(2, classDoc.superclass());
488
 
489
      outputProgramElementDocBody(2, classDoc);
490
      if (classDoc.isAbstract())
491
         printAtomTag(2, "isAbstract");
492
      if (classDoc.isSerializable())
493
         printAtomTag(2, "isSerializable");
494
      if (classDoc.isExternalizable())
495
         printAtomTag(2, "isExternalizable");
496
      if (classDoc.definesSerializableFields()) {
497
         printAtomTag(2, "definesSerializableFields");
498
      }
499
 
500
      ConstructorDoc[] constructors = classDoc.constructors();
501
      for (int i=0, ilim=constructors.length; i<ilim; ++i) {
502
         outputConstructorDoc(2, constructors[i]);
503
      }
504
 
505
      MethodDoc[] methods = classDoc.methods();
506
      for (int i=0, ilim=methods.length; i<ilim; ++i) {
507
         outputMethodDoc(2, methods[i]);
508
      }
509
 
510
      FieldDoc[] fields = classDoc.fields();
511
      for (int i=0, ilim=fields.length; i<ilim; ++i) {
512
         outputFieldDoc(2, fields[i]);
513
      }
514
 
515
      if (classDoc.serializableFields().length > 0) {
516
         printOpenTag(2, "serializableFields");
517
 
518
         FieldDoc[] sfields = classDoc.serializableFields();
519
         for (int i=0, ilim=sfields.length; i<ilim; ++i) {
520
            outputFieldDoc(2, sfields[i]);
521
         }
522
         printCloseTag(2, "serializableFields");
523
      }
524
 
525
      Java2xhtml java2xhtml = new Java2xhtml();
526
      Properties properties = new Properties();
527
      properties.setProperty("isCodeSnippet", "true");
528
      properties.setProperty("hasLineNumbers", "true");
529
      java2xhtml.setProperties(properties);
530
 
531
      if (null == classDoc.containingClass() && docTransletOptions.linksource) {
532
         printOpenTag(2, "source");
533
         StringWriter sourceBuffer = new StringWriter();
534
         File sourceFile = new File(((GjdocPackageDoc)classDoc.containingPackage()).packageDirectory(),
535
                                    classDoc.name() + ".java");
536
         FileReader sourceReader = new FileReader(sourceFile);
537
         IOToolkit.copyStream(sourceReader, sourceBuffer);
538
         print(java2xhtml.makeHTML(sourceBuffer.getBuffer(), sourceFile.getName()));
539
         printCloseTag(2, "source");
540
      }
541
 
542
      ClassDoc superclassDoc = classDoc.superclass();
543
      while (superclassDoc != null) {
544
         outputType(2, "superclass", superclassDoc, false);
545
 
546
         // FIXME: remove the following after adjusting the XSLT sheets:
547
         printAtomTag(3, "containingPackage name=\"" + superclassDoc.containingPackage().name() + "\"");
548
 
549
         MethodDoc[] superMethods = superclassDoc.methods();
550
         if (null != superMethods) {
551
            for (int i=0, ilim=superMethods.length; i<ilim; ++i) {
552
               printAtomTag(3, "methoddoc name=\"" + superMethods[i].name() + "\" signature=\"" + superMethods[i].signature() + "\"");
553
            }
554
         }
555
 
556
         FieldDoc[] superFields = superclassDoc.fields();
557
         if (null != superFields) {
558
            for (int i=0, ilim=superFields.length; i<ilim; ++i) {
559
               printAtomTag(3, "fielddoc name=\"" + superFields[i].name() + "\"");
560
            }
561
         }
562
         printCloseTag(2, "superclass");
563
 
564
         superclassDoc = superclassDoc.superclass();
565
      }
566
 
567
      outputUsage(classDoc, 2);
568
 
569
      printCloseTag(1, "classdoc");
570
 
571
      currentClass = null;
572
      currentMember = null;
573
      currentExecMember = null;
574
   }
575
 
576
   protected int outputHeritageOpen(int level, ClassDoc classDoc) {
577
 
578
      ClassDoc superClassDoc = classDoc.superclass();
579
      if (null != superClassDoc) {
580
         level = outputHeritageOpen(level, superClassDoc);
581
         ++ level;
582
      }
583
      outputType(level, "heritage", classDoc, false);
584
      return level;
585
   }
586
 
587
   protected void outputHeritageClose(int level, ClassDoc classDoc) {
588
 
589
      ClassDoc superClassDoc = classDoc.superclass();
590
      if (null != superClassDoc) {
591
         outputHeritageClose(level + 1, superClassDoc);
592
      }
593
      printCloseTag(level, "heritage");
594
   }
595
 
596
   protected void outputDocBody(int level, Doc doc) {
597
 
598
      int context = CONTEXT_TYPE;
599
 
600
      if (doc.isClass()) {
601
         printAtomTag(level, "isClass");
602
 
603
         ClassDoc classDoc = (ClassDoc)doc;
604
         ClassDoc[] classes = rootDoc.classes();
605
         for (int i=0, ilim=classes.length; i<ilim; ++i) {
606
            if (classes[i].superclass() == classDoc) {
607
               outputType(level, "extended-by", classes[i]);
608
            }
609
         }
610
 
611
         outputHeritageOpen(level, classDoc);
612
         outputHeritageClose(level, classDoc);
613
      }
614
      if (doc.isConstructor()) {
615
         printAtomTag(level, "isConstructor");
616
         context = CONTEXT_CONSTRUCTOR;
617
      }
618
      if (doc.isError()) {
619
         printAtomTag(level, "isError");
620
      }
621
      if (doc.isException()) {
622
         printAtomTag(level, "isException");
623
      }
624
      if (doc.isField()) {
625
         printAtomTag(level, "isField");
626
         context = CONTEXT_FIELD;
627
      }
628
      if (doc.isIncluded()) {
629
         printAtomTag(level, "isIncluded");
630
      }
631
      if (doc.isInterface()) {
632
         printAtomTag(level, "isInterface");
633
 
634
         ClassDoc classDoc = (ClassDoc)doc;
635
         ClassDoc[] classes = rootDoc.classes();
636
         for (int i=0, ilim=classes.length; i<ilim; ++i) {
637
            ClassDoc[] implementedInterfaces = classes[i].interfaces();
638
            for (int j=0; j<implementedInterfaces.length; ++j) {
639
               if (implementedInterfaces[j] == classDoc) {
640
                  if (classDoc.isInterface()) {
641
                        outputType(level, "subinterface", classes[i]);
642
                  }
643
                  else {
644
                     outputType(level, "implemented-by", classes[i]);
645
                  }
646
                  break;
647
               }
648
            }
649
         }
650
      }
651
      if (doc.isMethod()) {
652
         printAtomTag(level, "isMethod");
653
         context = CONTEXT_METHOD;
654
      }
655
      if (doc.isOrdinaryClass()) {
656
         printAtomTag(level, "isOrdinaryClass");
657
      }
658
 
659
      if (doc.inlineTags().length > 0) {
660
         printOpenTag(level, "inlineTags", false);
661
         outputTags(level+1, doc.inlineTags(), true, context);
662
         printCloseTag(0, "inlineTags");
663
      }
664
 
665
      if (doc.firstSentenceTags().length > 0) {
666
         printOpenTag(level, "firstSentenceTags", false);
667
         outputTags(level+1, doc.firstSentenceTags(), true, context);
668
         printCloseTag(0, "firstSentenceTags");
669
      }
670
 
671
      if (doc.tags().length > 0) {
672
         printOpenTag(level, "tags");
673
         outputTaglets(level+1, doc.tags(), true, context);
674
         printCloseTag(level, "tags");
675
      }
676
 
677
      if (doc.seeTags().length > 0) {
678
         printOpenTag(level, "seeTags");
679
         outputTags(level+1, doc.seeTags(), true, context);
680
         printCloseTag(level, "seeTags");
681
      }
682
 
683
      SourcePosition position = doc.position();
684
      if (null != position) {
685
         printAtomTag(level, "position file=\"" + position.file().getAbsolutePath() + "\" line=\"" + position.line() + "\" column=\"" + position.column() + "\"");
686
      }
687
   }
688
 
689
   protected void outputProgramElementDocBody(int level, ProgramElementDoc programElementDoc) {
690
      outputDocBody(level, programElementDoc);
691
      printAtomTag(level, "containingPackage name=\""+programElementDoc.containingPackage().name()+"\"");
692
      if (null!=programElementDoc.containingClass()) {
693
         outputType(level, "containingClass", programElementDoc.containingClass());
694
      }
695
      String access;
696
      if (programElementDoc.isPublic())
697
         access="public";
698
      else if (programElementDoc.isProtected())
699
         access="protected";
700
      else if (programElementDoc.isPrivate())
701
         access="private";
702
      else if (programElementDoc.isPackagePrivate())
703
         access="package";
704
      else
705
         throw new RuntimeException("Huh? "+programElementDoc+" is neither public, protected, private nor package protected.");
706
      printAtomTag(level, "access scope=\""+access+"\"");
707
      if (programElementDoc.isFinal())
708
         printAtomTag(level, "isFinal");
709
      if (programElementDoc.isStatic())
710
         printAtomTag(level, "isStatic");
711
   }
712
 
713
   protected void outputTags(int level, Tag[] tags, boolean descend, int context) {
714
 
715
      for (int i=0; i<tags.length; ++i) {
716
         outputTag(tags[i], level, descend, context, i == tags.length-1);
717
      }
718
   }
719
 
720
   protected void outputTag(Tag tag, int level, boolean descend, int context, boolean lastTag) {
721
 
722
      if (!"Text".equals(tag.name())) {
723
         printOpenTag(0 /* don't introduce additional whitespace */,
724
                      "tag kind=\""+tag.kind()+"\" name=\""+tag.name()+"\"", false);
725
      }
726
      if (tag instanceof ThrowsTag) {
727
         ThrowsTag throwsTag = (ThrowsTag)tag;
728
         if (null!=throwsTag.exception()) {
729
            outputType(level+1, "exception", throwsTag.exception());
730
         }
731
         else {
732
            StringBuffer sb = new StringBuffer("Exception ");
733
            sb.append(throwsTag.exceptionName());
734
            sb.append(" not found in ");
735
            if (currentExecMember instanceof MethodDoc) {
736
               MethodDoc m = (MethodDoc)currentExecMember;
737
               sb.append(m.returnType().typeName());
738
               sb.append(m.returnType().dimension());
739
               sb.append(' ');
740
            }
741
            sb.append(currentClass.qualifiedName());
742
            sb.append('.');
743
            sb.append(currentExecMember.name());
744
            sb.append('(');
745
            Parameter[] params = currentExecMember.parameters();
746
            for (int j=0; j < params.length; j++) {
747
               sb.append(params[j].type().typeName());
748
               sb.append(params[j].type().dimension());
749
               sb.append(' ');
750
               sb.append(params[j].name());
751
               if (j != params.length-1)
752
                  sb.append(", ");
753
            }
754
            sb.append(')');
755
            printWarning(sb.toString());
756
 
757
            printAtomTag(level+1, "exception typename=\""+throwsTag.exceptionName()+"\"");
758
         }
759
      }
760
      else if (tag instanceof ParamTag) {
761
         ParamTag paramTag = (ParamTag)tag;
762
         printAtomTag(level+1, "parameter name=\""+paramTag.parameterName()+"\"");
763
      }
764
 
765
      if (null != tag.text()) {
766
         //printOpenTag(level+1, "text", false);
767
         if (fixHTML) {
768
            print(htmlRepairer.getWellformedHTML(tag.text()));
769
         }
770
         else {
771
            print("<![CDATA["+cdata(tag.text())+"]]>");
772
         }
773
         //printCloseTag(0 /* don't introduce additional whitespace */, "text");
774
      }
775
      else {
776
         printWarning("Tag got null text: "+tag);
777
      }
778
 
779
      if ((descend && ("@throws".equals(tag.name()) || "@param".equals(tag.name()))) || "@deprecated".equals(tag.name())) {
780
         if (tag.firstSentenceTags().length>0) {
781
            printOpenTag(level+1, "firstSentenceTags", false);
782
            outputTags(level+2, tag.firstSentenceTags(), false, context);
783
            printCloseTag(0, "firstSentenceTags");
784
         }
785
 
786
         if (tag.inlineTags().length>0) {
787
            printOpenTag(level+1, "inlineTags", false);
788
            outputTags(level+2, tag.firstSentenceTags(), false, context);
789
            printCloseTag(0, "inlineTags");
790
         }
791
      }
792
 
793
      if (fixHTML && lastTag) {
794
         String terminateText = htmlRepairer.terminateText();
795
         if (null != terminateText && terminateText.length() > 0) {
796
            print(terminateText);
797
         }
798
      }
799
 
800
      if (!"Text".equals(tag.name())) {
801
 
802
         Taglet inlineTaglet = (Taglet)tagletMap.get(tag.name().substring(1));
803
         if (null != inlineTaglet && inlineTaglet.isInlineTag()) {
804
            printOpenTag(0, "inlineTagletText", false);
805
            print(inlineTaglet.toString(tag));
806
            printCloseTag(0, "inlineTagletText");
807
         }
808
 
809
         printCloseTag(0, "tag", false);
810
      }
811
   }
812
 
813
   void outputTaglets(int level, Tag[] tags, boolean descend, int context)
814
   {
815
      for (Iterator it = tagletMap.keySet().iterator(); it.hasNext(); ) {
816
         String tagName = (String)it.next();
817
         Object o = tagletMap.get(tagName);
818
         Taglet taglet = (Taglet)o;
819
 
820
         if (!taglet.isInlineTag()
821
             && ((context != CONTEXT_CONSTRUCTOR || taglet.inConstructor())
822
                 || (context != CONTEXT_FIELD || taglet.inField())
823
                 || (context != CONTEXT_METHOD || taglet.inMethod())
824
                 || (context != CONTEXT_OVERVIEW || taglet.inOverview())
825
                 || (context != CONTEXT_PACKAGE || taglet.inPackage())
826
                 || (context != CONTEXT_TYPE || taglet.inType()))) {
827
 
828
            List tagsOfThisType = new ArrayList();
829
            for (int i=0, ilim=tags.length; i<ilim; ++i) {
830
               if (tags[i].name().substring(1).equals(tagName)) {
831
                  tagsOfThisType.add(tags[i]);
832
               }
833
            }
834
 
835
            if (!tagsOfThisType.isEmpty()) {
836
               Tag[] tagletTags = (Tag[])tagsOfThisType.toArray(new Tag[tagsOfThisType.size()]);
837
               if (taglet instanceof StandardTaglet) {
838
                  Iterator tagIterator = tagsOfThisType.iterator();
839
                  while (tagIterator.hasNext()) {
840
                     Tag tag = (Tag)tagIterator.next();
841
                     outputTag(tag, level, descend, context, !tagIterator.hasNext());
842
                  }
843
               }
844
               else {
845
                  String tagletString = taglet.toString(tagletTags);
846
                  if (null != tagletString) {
847
                     printOpenTag(0, "tag name=\"" + tagName + "\" taglet-generated=\"true\"");
848
                     if (fixHTML) {
849
                        print(htmlRepairer.getWellformedHTML(tagletString));
850
                        print(htmlRepairer.terminateText());
851
                     }
852
                     else {
853
                        print("<![CDATA["+cdata(tagletString)+"]]>");
854
                     }
855
                     printCloseTag(0, "tag", false);
856
                  }
857
               }
858
            }
859
         }
860
      }
861
   }
862
 
863
   /**
864
    *  Inofficial entry point. We got an instance here.
865
    */
866
   protected boolean instanceStart(RootDoc _rootDoc) {
867
 
868
      this.rootDoc = _rootDoc;
869
      _rootDoc = null;
870
 
871
      boolean xmlOnly = true;
872
 
873
      // Set the default Taglet order
874
 
875
      registerTaglet(new VersionTaglet());
876
      registerTaglet(new AuthorTaglet());
877
      //registerTaglet(new SinceTaglet());
878
      registerTaglet(new StandardTaglet("deprecated"));
879
      registerTaglet(new StandardTaglet("see"));
880
      registerTaglet(new StandardTaglet("param"));
881
 
882
      // Set the built-in Taglet filter
883
 
884
      AuthorTaglet.setTagletEnabled(false);
885
      VersionTaglet.setTagletEnabled(false);
886
      SinceTaglet.setTagletEnabled(true);
887
      DeprecatedTaglet.setTagletEnabled(true);
888
 
889
      try {
890
         {
891
 
892
            // Process command line options passed through to this doclet
893
 
894
            TargetContext targetContext = null;
895
 
896
            TargetContext htmlTargetContext
897
               = new TargetContext(DocTranslet.fromClasspath("/doctranslets/html/gjdoc.xsl"),
898
                                   targetDirectory);
899
 
900
            for (int i=0, ilim=rootDoc.options().length; i<ilim; ++i) {
901
 
902
               String[] option = rootDoc.options()[i];
903
               String optionTag = option[0];
904
 
905
               if ("-d".equals(optionTag)) {
906
                  if (null == targetDirectory) {
907
                     targetDirectory = new File(option[1]);
908
                  }
909
                  if (null != targetContext) {
910
                     targetContext.setTargetDirectory(targetDirectory);
911
                  }
912
               }
913
 
914
               else if ("-nofixhtml".equals(optionTag)) {
915
                  fixHTML = false;
916
                  printError("-nofixhtml currently not supported.");
917
                  return false;
918
               }
919
               else if ("-compress".equals(optionTag)) {
920
                  compress = true;
921
               }
922
               else if ("-nohtmlwarn".equals(optionTag)) {
923
                  noHTMLWarn = true;
924
               }
925
               else if ("-noemailwarn".equals(optionTag)) {
926
                  noEmailWarn = true;
927
               }
928
               else if ("-indentstep".equals(optionTag)) {
929
                  indentStep = Integer.parseInt(option[1]);
930
               }
931
               else if ("-doctranslet".equals(optionTag)) {
932
                  targets.add(targetContext = new TargetContext(DocTranslet.fromJarFile(new File(option[1])),
933
                                                                targetDirectory));
934
               }
935
               else if ("-genhtml".equals(optionTag)) {
936
                  htmlTargetContext.setTargetDirectory(targetDirectory);
937
                  targets.add(targetContext = htmlTargetContext);
938
                  xmlOnly = false;
939
               }
940
               else if ("-geninfo".equals(optionTag)) {
941
                  targetContext
942
                              = new TargetContext(DocTranslet.fromClasspath("/doctranslets/info/gengj.xsl"),
943
                                                  targetDirectory);
944
                  targets.add(targetContext);
945
                  if (!fixHTML) {
946
                     printNotice("NOTE: -geninfo implies -fixhtml.");
947
                     fixHTML = true;
948
                  }
949
                  xmlOnly = false;
950
               }
951
               else if ("-gendocbook".equals(optionTag)) {
952
                  targetContext = new TargetContext(DocTranslet.fromClasspath("/doctranslets/docbook/gengj.xsl"),
953
                                                    targetDirectory);
954
                  targets.add(targetContext);
955
                  if (!fixHTML) {
956
                     printNotice("NOTE: -gendocbook implies -fixhtml.");
957
                     fixHTML = true;
958
                  }
959
               }
960
               else if ("-genpdf".equals(optionTag)) {
961
                  targetContext
962
                     = new TargetContext(DocTranslet.fromClasspath("/doctranslets/docbook/gengj.xsl"),
963
                                         targetDirectory);
964
                                         /** "gnu.classpath.tools.doclets.xmldoclet.DocBookPostprocessor") **/
965
                  targets.add(targetContext);
966
                  if (!fixHTML) {
967
                     printNotice("NOTE: -genpdf implies -fixhtml.");
968
                     fixHTML = true;
969
                  }
970
               }
971
               else if ("-xmlonly".equals(optionTag)) {
972
                  xmlOnly = true;
973
               }
974
               else if ("-bottomnote".equals(optionTag)) {
975
 
976
                  FileReader reader = new FileReader(option[1]);
977
                  StringWriter writer = new StringWriter();
978
                  char[] buf = new char[256];
979
                  int nread;
980
                  while ((nread = reader.read(buf)) >= 0) {
981
                     writer.write(buf, 0, nread);
982
                  }
983
                  writer.flush();
984
                  bottomNote = writer.toString();
985
                  writer.close();
986
                  reader.close();
987
               }
988
               else if ("-title".equals(optionTag)) {
989
 
990
                  title = option[1];
991
               }
992
               else if ("-workpath".equals(optionTag)) {
993
 
994
                  workingPath = option[1];
995
               }
996
               else if ("-tagletpath".equals(optionTag)) {
997
 
998
                  if (null == tagletPath) {
999
                     tagletPath = option[1];
1000
                  }
1001
                  else {
1002
                     tagletPath = tagletPath + File.pathSeparator + option[1];
1003
                  }
1004
               }
1005
               else if ("-taglet".equals(optionTag)) {
1006
 
1007
                  boolean tagletLoaded = false;
1008
 
1009
                  String useTagletPath = this.tagletPath;
1010
                  if (null == useTagletPath) {
1011
                     useTagletPath = System.getProperty("java.class.path");
1012
                  }
1013
 
1014
                  try {
1015
                     Class tagletClass;
1016
                     try {
1017
                        tagletClass
1018
                           = new FileSystemClassLoader(useTagletPath).loadClass(option[1]);
1019
                     }
1020
                     catch (ClassNotFoundException e) {
1021
                        // If not found on specified tagletpath, try default classloader
1022
                        tagletClass
1023
                           = Class.forName(option[1]);
1024
                     }
1025
                     Method registerTagletMethod
1026
                        = tagletClass.getDeclaredMethod("register", new Class[] { java.util.Map.class });
1027
 
1028
                     if (!registerTagletMethod.getReturnType().equals(Void.TYPE)) {
1029
                        printError("Taglet class '" + option[1] + "' found, but register method doesn't return void.");
1030
                     }
1031
                     else if (registerTagletMethod.getExceptionTypes().length > 0) {
1032
                        printError("Taglet class '" + option[1] + "' found, but register method contains throws clause.");
1033
                     }
1034
                     else if ((registerTagletMethod.getModifiers() & (Modifier.STATIC | Modifier.PUBLIC | Modifier.ABSTRACT)) != (Modifier.STATIC | Modifier.PUBLIC)) {
1035
                        printError("Taglet class '" + option[1] + "' found, but register method isn't public static, or is abstract..");
1036
                     }
1037
                     else {
1038
                        Map tempMap = new HashMap();
1039
                        registerTagletMethod.invoke(null, new Object[] { tempMap });
1040
                        tagletLoaded = true;
1041
                        String name = (String)tempMap.keySet().iterator().next();
1042
                        Taglet taglet = (Taglet)tempMap.get(name);
1043
                        tagletMap.put(name, taglet);
1044
                        mentionedTags.add(taglet);
1045
                     }
1046
                  }
1047
                  catch (NoSuchMethodException e) {
1048
                     printError("Taglet class '" + option[1] + "' found, but doesn't contain the register method.");
1049
                  }
1050
                  catch (SecurityException e) {
1051
                     printError("Taglet class '" + option[1] + "' cannot be loaded: " + e.getMessage());
1052
                  }
1053
                  catch (InvocationTargetException e) {
1054
                     printError("Taglet class '" + option[1] + "' found, but register method throws exception: " + e.toString());
1055
                  }
1056
                  catch (IllegalAccessException e) {
1057
                     printError("Taglet class '" + option[1] + "' found, but there was a problem when accessing the register method: " + e.toString());
1058
                  }
1059
                  catch (IllegalArgumentException e) {
1060
                     printError("Taglet class '" + option[1] + "' found, but there was a problem when accessing the register method: " + e.toString());
1061
                  }
1062
                  catch (ClassNotFoundException e) {
1063
                     printError("Taglet class '" + option[1] + "' cannot be found.");
1064
                  }
1065
                  if (!tagletLoaded) {
1066
                     return false;
1067
                  }
1068
               }
1069
               else if ("-author".equals(optionTag)) {
1070
                  AuthorTaglet.setTagletEnabled(true);
1071
               }
1072
               else if ("-version".equals(optionTag)) {
1073
                  VersionTaglet.setTagletEnabled(true);
1074
               }
1075
               else if ("-nosince".equals(optionTag)) {
1076
                  SinceTaglet.setTagletEnabled(false);
1077
               }
1078
               else if ("-nodeprecated".equals(optionTag)) {
1079
                  DeprecatedTaglet.setTagletEnabled(false);
1080
               }
1081
               else if ("-authormail".equals(optionTag)) {
1082
 
1083
                  if ("no-replace".equalsIgnoreCase(option[1])) {
1084
                     AuthorTaglet.setEmailReplacementType(AuthorTaglet.EmailReplacement.NO_REPLACEMENT);
1085
                  }
1086
                  else if ("mailto-name".equalsIgnoreCase(option[1])) {
1087
                     AuthorTaglet.setEmailReplacementType(AuthorTaglet.EmailReplacement.MAILTO_NAME);
1088
                  }
1089
                  else if ("name-mailto-address".equalsIgnoreCase(option[1])) {
1090
                     AuthorTaglet.setEmailReplacementType(AuthorTaglet.EmailReplacement.NAME_MAILTO_ADDRESS);
1091
                  }
1092
                  else if ("name-mangled-address".equalsIgnoreCase(option[1])) {
1093
                     AuthorTaglet.setEmailReplacementType(AuthorTaglet.EmailReplacement.NAME_MANGLED_ADDRESS);
1094
                  }
1095
                  else {
1096
                     printError("Invalid value for option '-authortag-email'. Allowed values are:"
1097
                                + " no-replace, mailto-name, name-mailto-address, name-mangled-address.");
1098
                     return false;
1099
                  }
1100
               }
1101
               else if ("-mailmangledot".equals(optionTag)) {
1102
                  AuthorTaglet.setDotReplacement(option[1]);
1103
               }
1104
               else if ("-mailmangleat".equals(optionTag)) {
1105
                  AuthorTaglet.setAtReplacement(option[1]);
1106
               }
1107
               else if ("-docfilessubdirs".equals(optionTag)) {
1108
                  docFilesSubdirsEnabled = true;
1109
               }
1110
               else if ("-excludedocfilessubdir".equals(optionTag)) {
1111
                  StringTokenizer st = new StringTokenizer(option[1]);
1112
                  while (st.hasMoreTokens()) {
1113
                     excludeDocFilesSubDirs.add(st.nextToken());
1114
                  }
1115
               }
1116
               else if ("-nonavbar".equals(optionTag)) {
1117
                  docTransletOptions.nonavbar = true;
1118
               }
1119
               else if ("-noindex".equals(optionTag)) {
1120
                  docTransletOptions.noindex = true;
1121
               }
1122
               else if ("-notree".equals(optionTag)) {
1123
                  docTransletOptions.notree = true;
1124
               }
1125
               else if ("-nocomment".equals(optionTag)) {
1126
                  docTransletOptions.nocomment = true;
1127
               }
1128
               else if ("-nohelp".equals(optionTag)) {
1129
                  docTransletOptions.nohelp = true;
1130
               }
1131
               else if ("-splitindex".equals(optionTag)) {
1132
                  docTransletOptions.splitindex = true;
1133
               }
1134
               else if ("-linksource".equals(optionTag)) {
1135
                  docTransletOptions.linksource = true;
1136
               }
1137
               else if ("-windowtitle".equals(optionTag)) {
1138
                  docTransletOptions.windowtitle = option[1];
1139
               }
1140
               else if ("-helpfile".equals(optionTag)) {
1141
                  docTransletOptions.helpfile = new File(option[1]).toURL().toString();
1142
               }
1143
               else if ("-stylesheetfile".equals(optionTag)) {
1144
                  docTransletOptions.stylesheetfile = new File(option[1]).toURL().toString();
1145
               }
1146
               else if ("-header".equals(optionTag)) {
1147
                  docTransletOptions.header = option[1];
1148
               }
1149
               else if ("-footer".equals(optionTag)) {
1150
                  docTransletOptions.footer = option[1];
1151
               }
1152
               else if ("-bottom".equals(optionTag)) {
1153
                  docTransletOptions.bottom = option[1];
1154
               }
1155
               else if ("-doctitle".equals(optionTag)) {
1156
                  docTransletOptions.doctitle = option[1];
1157
               }
1158
               else if ("-nodeprecatedlist".equals(optionTag)) {
1159
                  docTransletOptions.nodeprecatedlist = true;
1160
               }
1161
               else if ("-uses".equals(optionTag)) {
1162
                  docTransletOptions.uses = true;
1163
               }
1164
               else if ("-group".equals(optionTag)) {
1165
                  if (!processGroupOption(option[1], option[2])) {
1166
                     printError("Invalid package wildcard list in -group option \"" + option[1] + "\" " + option[2]);
1167
                     return false;
1168
                  }
1169
               }
1170
               else if ("-tag".equals(optionTag)) {
1171
                  String tagSpec = option[1];
1172
                  boolean validTagSpec = false;
1173
                  int ndx1 = tagSpec.indexOf(':');
1174
                  if (ndx1 < 0) {
1175
                     Taglet taglet = (Taglet)tagletMap.get(tagSpec);
1176
                     if (null == taglet) {
1177
                        printError("There is no standard tag '" + tagSpec + "'.");
1178
                     }
1179
                     else {
1180
                        if (mentionedTags.contains(taglet)) {
1181
                           printError("Tag '" + tagSpec + "' has been added or moved before.");
1182
                        }
1183
                        else {
1184
                           mentionedTags.add(taglet);
1185
 
1186
                           // re-append taglet
1187
                           tagletMap.remove(tagSpec);
1188
                           tagletMap.put(tagSpec, taglet);
1189
                        }
1190
                     }
1191
                  }
1192
                  else {
1193
                     int ndx2 = tagSpec.indexOf(':', ndx1 + 1);
1194
                     if (ndx2 > ndx1 && ndx2 < tagSpec.length() - 1) {
1195
                        String tagName = tagSpec.substring(0, ndx1);
1196
                        String tagHead = null;
1197
                        if (tagSpec.charAt(ndx2 + 1) == '\"') {
1198
                           if (tagSpec.charAt(tagSpec.length() - 1) == '\"') {
1199
                              tagHead = tagSpec.substring(ndx2 + 2, tagSpec.length() - 1);
1200
                              validTagSpec = true;
1201
                           }
1202
                        }
1203
                        else {
1204
                           tagHead = tagSpec.substring(ndx2 + 1);
1205
                           validTagSpec = true;
1206
                        }
1207
 
1208
                        boolean tagScopeOverview = false;
1209
                        boolean tagScopePackages = false;
1210
                        boolean tagScopeTypes = false;
1211
                        boolean tagScopeConstructors = false;
1212
                        boolean tagScopeMethods = false;
1213
                        boolean tagScopeFields = false;
1214
                        boolean tagDisabled = false;
1215
 
1216
                     tag_option_loop:
1217
                        for (int n=ndx1+1; n<ndx2; ++n) {
1218
                           switch (tagSpec.charAt(n)) {
1219
                           case 'X':
1220
                              tagDisabled = true;
1221
                              break;
1222
                           case 'a':
1223
                              tagScopeOverview = true;
1224
                              tagScopePackages = true;
1225
                              tagScopeTypes = true;
1226
                              tagScopeConstructors = true;
1227
                              tagScopeMethods = true;
1228
                              tagScopeFields = true;
1229
                              break;
1230
                           case 'o':
1231
                              tagScopeOverview = true;
1232
                              break;
1233
                           case 'p':
1234
                              tagScopePackages = true;
1235
                              break;
1236
                           case 't':
1237
                              tagScopeTypes = true;
1238
                              break;
1239
                           case 'c':
1240
                              tagScopeConstructors = true;
1241
                              break;
1242
                           case 'm':
1243
                              tagScopeMethods = true;
1244
                              break;
1245
                           case 'f':
1246
                              tagScopeFields = true;
1247
                              break;
1248
                           default:
1249
                              validTagSpec = false;
1250
                              break tag_option_loop;
1251
                           }
1252
                        }
1253
 
1254
                        if (validTagSpec) {
1255
                           GenericTaglet taglet
1256
                              = new GenericTaglet(tagName,
1257
                                                  tagHead,
1258
                                                  tagScopeOverview,
1259
                                                  tagScopePackages,
1260
                                                  tagScopeTypes,
1261
                                                  tagScopeConstructors,
1262
                                                  tagScopeMethods,
1263
                                                  tagScopeFields);
1264
                           taglet.setTagletEnabled(!tagDisabled);
1265
                           taglet.register(tagletMap);
1266
                           mentionedTags.add(taglet);
1267
                        }
1268
                     }
1269
                  }
1270
                  if (!validTagSpec) {
1271
                     printError("Value for option -tag must be in format \"<tagname>:Xaoptcmf:<taghead>\".");
1272
                  }
1273
               }
1274
            }
1275
 
1276
            // Use current directory if target directory hasn't been set.
1277
            if (null == targetDirectory) {
1278
               targetDirectory = new File(System.getProperty("user.dir"));
1279
            }
1280
            if (null != targetContext) {
1281
               targetContext.setTargetDirectory(targetDirectory);
1282
            }
1283
 
1284
            // It is illegal to specify targets AND -xmlonly.
1285
 
1286
            if (xmlOnly && targets.size() > 0) {
1287
 
1288
               printError("You can only specify one of -xmlonly and a target format.");
1289
               return false;
1290
            }
1291
 
1292
            // If no target was specified and XML only was not
1293
            // requested, use HTML as default target.
1294
 
1295
            if (!xmlOnly && targets.size() == 0) {
1296
               targets.add(targetContext = htmlTargetContext);
1297
            }
1298
 
1299
            // Set the same target directory for all output.
1300
 
1301
            // FIXME: Allow separate target directories for different
1302
            // output formats.
1303
 
1304
            for (Iterator it = targets.iterator(); it.hasNext(); ) {
1305
               TargetContext t = (TargetContext)it.next();
1306
               t.setTargetDirectory(targetDirectory);
1307
            }
1308
 
1309
            // Create temporary directory if necessary
1310
 
1311
            if (xmlOnly) {
1312
 
1313
               xmlTargetDirectory = targetDirectory;
1314
            }
1315
            else {
1316
 
1317
               File workingTopDirectory = new File(workingPath);
1318
 
1319
               workingDirectory = new File(workingTopDirectory, "gjdoc.tmp."+System.currentTimeMillis());
1320
 
1321
               if (!workingDirectory.mkdir()) {
1322
                  printError("Cannot create temporary directory at "+System.getProperty("java.io.tmpdir"));
1323
                  return false;
1324
               }
1325
 
1326
               File xmlTempDirectory = new File(workingDirectory, "xmloutput");
1327
 
1328
               if (!xmlTempDirectory.mkdir()) {
1329
                  printError("Cannot create temporary directory for XML output at "+System.getProperty("java.io.tmpdir"));
1330
                  return false;
1331
               }
1332
 
1333
               xmlTargetDirectory = xmlTempDirectory;
1334
            }
1335
 
1336
            // Create target directory if necessary
1337
 
1338
            if (!targetDirectory.exists()) {
1339
               printNotice("Creating destination directory: \""
1340
                           + targetDirectory + "\"");
1341
               if (!targetDirectory.mkdirs()) {
1342
                  printError("Failed to create destination directory \""
1343
                             + targetDirectory + "\"");
1344
                  return false;
1345
               }
1346
            }
1347
 
1348
            // Check for deprecation
1349
 
1350
            boolean hasDeprecatedClasses = false;
1351
            boolean hasDeprecatedInterfaces = false;
1352
            boolean hasDeprecatedExceptions = false;
1353
            boolean hasDeprecatedErrors = false;
1354
            boolean hasDeprecatedMethods = false;
1355
            boolean hasDeprecatedFields = false;
1356
 
1357
            {
1358
               ClassDoc[] classes = rootDoc.classes();
1359
               for (int i = 0, ilim = classes.length; i < ilim; ++ i) {
1360
                  ClassDoc c = classes[i];
1361
                  Tag[] deprecatedTags = c.tags("deprecated");
1362
                  if (null != deprecatedTags && 0 != deprecatedTags.length) {
1363
                     if (c.isInterface()) {
1364
                        hasDeprecatedInterfaces = true;
1365
                     }
1366
                     else if (c.isException()) {
1367
                        hasDeprecatedExceptions = true;
1368
                     }
1369
                     else if (c.isError()) {
1370
                        hasDeprecatedErrors = true;
1371
                     }
1372
                     else /*if (c.isOrdinaryClass())*/ {
1373
                        hasDeprecatedClasses = true;
1374
                     }
1375
                  }
1376
 
1377
                  MethodDoc[] methods = c.methods();
1378
                  for (int j = 0, jlim = methods.length; j < jlim; ++ j) {
1379
                     MethodDoc m = methods[j];
1380
                     deprecatedTags = m.tags("deprecated");
1381
                     if (null != deprecatedTags && 0 != deprecatedTags.length) {
1382
                        hasDeprecatedMethods = true;
1383
                     }
1384
                  }
1385
 
1386
                  FieldDoc[] fields = c.fields();
1387
                  for (int j = 0, jlim = fields.length; j < jlim; ++ j) {
1388
                     FieldDoc f = fields[j];
1389
                     deprecatedTags = f.tags("deprecated");
1390
                     if (null != deprecatedTags && 0 != deprecatedTags.length) {
1391
                        hasDeprecatedFields = true;
1392
                     }
1393
                  }
1394
               }
1395
            }
1396
 
1397
            htmlRepairer = new HtmlRepairer(rootDoc, noHTMLWarn, noEmailWarn,
1398
                                            currentClass, currentMember,
1399
                                            false);
1400
 
1401
            collectUsage();
1402
 
1403
            // Begin XML generation
1404
 
1405
            printNotice("Writing XML Index file...");
1406
 
1407
            // Assign output stream
1408
 
1409
            setTargetFile("index.xml");
1410
 
1411
            // Output XML document header
1412
 
1413
            println(0, "<?xml version=\"1.0\"?>");
1414
            println("<!DOCTYPE gjdoc SYSTEM \"dtd/gjdoc.dtd\">");
1415
            println();
1416
            printOpenTag(0, "rootdoc xmlns=\"http://www.w3.org/TR/REC-html40\" xmlns:gjdoc=\"http://www.gnu.org/software/cp-tools/gjdocxml\"");
1417
 
1418
            println();
1419
            println(1, "<!-- Tags from overview page, if available -->");
1420
 
1421
            if (rootDoc.firstSentenceTags().length > 0) {
1422
               printOpenTag(2, "firstSentenceTags", false);
1423
               outputTags(3, rootDoc.firstSentenceTags(), true, CONTEXT_PACKAGE);
1424
               printCloseTag(0, "firstSentenceTags");
1425
            }
1426
 
1427
            if (rootDoc.inlineTags().length > 0) {
1428
               printOpenTag(2, "inlineTags");
1429
               outputTags(3, rootDoc.inlineTags(), true, CONTEXT_PACKAGE);
1430
               printCloseTag(2, "inlineTags");
1431
            }
1432
 
1433
            if (null != bottomNote) {
1434
               printOpenTag(1, "bottomnote");
1435
               print(bottomNote);
1436
               printCloseTag(1, "bottomnote");
1437
            }
1438
 
1439
            if (null != title) {
1440
               printOpenTag(1, "title");
1441
               println(2, title);
1442
               printCloseTag(1, "title");
1443
            }
1444
 
1445
            printOpenTag(1, "created");
1446
            println(2, DateFormat.getDateInstance(DateFormat.LONG, Locale.US).format(new java.util.Date()));
1447
            printCloseTag(1, "created");
1448
 
1449
            if (hasDeprecatedClasses) printAtomTag(1, "hasDeprecatedClasses");
1450
            if (hasDeprecatedInterfaces) printAtomTag(1, "hasDeprecatedInterfaces");
1451
            if (hasDeprecatedExceptions) printAtomTag(1, "hasDeprecatedExceptions");
1452
            if (hasDeprecatedErrors) printAtomTag(1, "hasDeprecatedErrors");
1453
            if (hasDeprecatedMethods) printAtomTag(1, "hasDeprecatedMethods");
1454
            if (hasDeprecatedFields) printAtomTag(1, "hasDeprecatedFields");
1455
 
1456
            // Output summary of all classes specified on command line
1457
 
1458
            println();
1459
            println(1, "<!-- Classes specified by user on command line -->");
1460
            ClassDoc[] specifiedClasses = rootDoc.specifiedClasses();
1461
            for (int i=0, ilim=specifiedClasses.length; i<ilim; ++i) {
1462
               ClassDoc sc = specifiedClasses[i];
1463
               printAtomTag(1, "specifiedclass fqname=\""+sc.qualifiedName()+"\" name=\""+sc.name()+"\"");
1464
            }
1465
            specifiedClasses = null;
1466
 
1467
            // Output summary of all packages specified on command line
1468
 
1469
            println();
1470
            println(1, "<!-- Packages specified by user on command line -->");
1471
            PackageDoc[] specifiedPackages = rootDoc.specifiedPackages();
1472
            for (int i=0, ilim=specifiedPackages.length; i<ilim; ++i) {
1473
               PackageDoc sp = specifiedPackages[i];
1474
               printAtomTag(1, "specifiedpackage name=\""+sp.name()+"\"");
1475
            }
1476
            specifiedPackages = null;
1477
 
1478
            // Output package group information specified on the
1479
            // command line
1480
 
1481
            println();
1482
            println(1, "<!-- Package groups specified by user on command line -->");
1483
            {
1484
               Iterator packageGroupIt = packageGroups.iterator();
1485
               while (packageGroupIt.hasNext()) {
1486
                  PackageGroup packageGroup = (PackageGroup)packageGroupIt.next();
1487
                  SortedSet groupedPackages = packageGroup.getPackages();
1488
                  if (groupedPackages.isEmpty()) {
1489
                     printWarning("Package group named '"
1490
                                  + packageGroup.getName() + "' didn't match any packages.");
1491
                  }
1492
                  else {
1493
                     printOpenTag(1, "packagegroup name=\"" + packageGroup.getName() + "\"");
1494
                     Iterator groupedPackageIt = groupedPackages.iterator();
1495
                     while (groupedPackageIt.hasNext()) {
1496
                        PackageDoc groupedPackageDoc = (PackageDoc)groupedPackageIt.next();
1497
                        printAtomTag(2, "package name=\"" + groupedPackageDoc.name() + "\"");
1498
                     }
1499
                     printCloseTag(1, "packagegroup");
1500
                  }
1501
               }
1502
               packageGroups = null;
1503
            }
1504
 
1505
            // Output information on all packages for which documentation
1506
            // has been made available via the Doclet API
1507
 
1508
            println();
1509
            println(1, "<!-- Documentation for all packages -->");
1510
            PackageDoc[] packages = rootDoc.specifiedPackages();
1511
            for (int i=0, ilim=packages.length; i<ilim; ++i) {
1512
               PackageDoc c = packages[i];
1513
               outputPackageDoc(c);
1514
            }
1515
            packages = null;
1516
 
1517
            // Output brief summary on all classes for which documentation
1518
            // has been made available via the Doclet API.
1519
            //
1520
            // While this is redundant, it can speed up XSLT
1521
            // processing by orders of magnitude
1522
 
1523
            println();
1524
            println(1, "<!-- Brief summary for all classes -->");
1525
            ClassDoc[] sumclasses = rootDoc.classes();
1526
            for (int i=0, ilim=sumclasses.length; i<ilim; ++i) {
1527
               ClassDoc c = sumclasses[i];
1528
               outputClassDocSummary(c);
1529
            }
1530
            sumclasses = null;
1531
 
1532
            // Output closing tag, finish output stream
1533
 
1534
            println();
1535
            printCloseTag(0, "rootdoc");
1536
 
1537
            closeTargetFile();
1538
 
1539
            createIndexByName();
1540
 
1541
 
1542
 
1543
            // Output information on all classes for which documentation
1544
            // has been made available via the Doclet API
1545
 
1546
            println();
1547
            println(1, "<!-- Documentation for all classes -->");
1548
            ClassDoc[] classes = rootDoc.classes();
1549
            String prevPackageName = null;
1550
            for (int i = 0, ilim = classes.length; i < ilim; ++ i) {
1551
               ClassDoc c = classes[i];
1552
 
1553
               if (isVerbose()) {
1554
                  printNotice("Writing XML information for "+c.qualifiedName()+"...");
1555
               }
1556
               else {
1557
                  String packageName = c.containingPackage().name();
1558
                  if (null == prevPackageName || !packageName.equals(prevPackageName)) {
1559
                     printNotice("Writing XML information for "+packageName+"...");
1560
                     prevPackageName = packageName;
1561
                  }
1562
               }
1563
 
1564
               setTargetFile(c.qualifiedName().replace('/','.')+".xml");
1565
 
1566
               println("<?xml version=\"1.0\"?>");
1567
               println("<!DOCTYPE gjdoc SYSTEM \"dtd/gjdoc.dtd\">");
1568
 
1569
               outputClassDoc(c);
1570
 
1571
               closeTargetFile();
1572
            }
1573
            classes = null;
1574
         }
1575
 
1576
         // Copy DTD files to temporary directory
1577
 
1578
         // FIXME: try to solve this via jar: URLs. but this will
1579
         // probably break libxmlj compatibility (?)
1580
 
1581
         String[] resources = new String[] {
1582
            "gjdoc.dtd",
1583
            "gjdoc-alphaindex.dtd",
1584
            "dbcentx.mod",
1585
            "ent/iso-amsa.ent",
1586
            "ent/iso-amsb.ent",
1587
            "ent/iso-amsc.ent",
1588
            "ent/iso-amsn.ent",
1589
            "ent/iso-amso.ent",
1590
            "ent/iso-amsr.ent",
1591
            "ent/iso-box.ent",
1592
            "ent/iso-cyr1.ent",
1593
            "ent/iso-cyr2.ent",
1594
            "ent/iso-dia.ent",
1595
            "ent/iso-grk1.ent",
1596
            "ent/iso-grk2.ent",
1597
            "ent/iso-grk3.ent",
1598
            "ent/iso-grk4.ent",
1599
            "ent/iso-lat1.ent",
1600
            "ent/iso-lat2.ent",
1601
            "ent/iso-num.ent",
1602
            "ent/iso-pub.ent",
1603
            "ent/iso-tech.ent",
1604
         };
1605
 
1606
         File tempDtdDirectory = new File(xmlTargetDirectory, "dtd");
1607
         File tempDtdEntDirectory = new File(tempDtdDirectory, "ent");
1608
 
1609
         if ((tempDtdDirectory.exists() || tempDtdDirectory.mkdir())
1610
             && (tempDtdEntDirectory.exists() || tempDtdEntDirectory.mkdir())) {
1611
            for (int i = 0; i < resources.length; ++ i) {
1612
               copyResourceToFile("/dtd/" + resources[i],
1613
                                  new File(tempDtdDirectory, resources[i]));
1614
            }
1615
         }
1616
         else {
1617
            printError("Cannot create temporary directories for DTD data at " + tempDtdDirectory);
1618
            return false;
1619
         }
1620
 
1621
         // Copy package data-dir directory
1622
 
1623
         {
1624
            PackageDoc[] packages = rootDoc.specifiedPackages();
1625
            for (int i=0, ilim=packages.length; i<ilim; ++i) {
1626
               PackageDoc c = packages[i];
1627
               if (c instanceof GjdocPackageDoc) {
1628
                  copyPackageDataDir((GjdocPackageDoc)c);
1629
               }
1630
            }
1631
         }
1632
 
1633
         // All information has been output. Apply stylesheet if given.
1634
 
1635
         gnu.classpath.tools.gjdoc.Main.releaseRootDoc();
1636
 
1637
         this.currentClass = null;
1638
         this.currentMember = null;
1639
         this.currentExecMember = null;
1640
 
1641
         System.gc();
1642
 
1643
         // From this point we are only operating on files, so we don't
1644
         // need this anymore and can free up some memory
1645
 
1646
         for (Iterator it = targets.iterator(); it.hasNext(); ) {
1647
 
1648
            TargetContext target = (TargetContext)it.next();
1649
 
1650
            // We have XSLT postprocessing, run DocTranslet.
1651
 
1652
            //DocTranslet docTranslet = DocTranslet.fromClasspath("/doctranslets/html/gjdoc.xsl");
1653
 
1654
            //docTranslet.setOptions(docTransletOptions);
1655
 
1656
            target.getDocTranslet().setOptions(docTransletOptions);
1657
 
1658
            target.getDocTranslet().apply(xmlTargetDirectory,
1659
                                          target.getTargetDirectory(),
1660
                                          rootDoc);
1661
         }
1662
 
1663
         // Done
1664
 
1665
         targets = null;
1666
 
1667
         System.gc();
1668
         Runtime.getRuntime().runFinalization();
1669
 
1670
         return true;
1671
      }
1672
      catch (Exception e) {
1673
 
1674
         // Something went wrong. Report to stderr and pass error to
1675
         // Javadoc Reporter
1676
 
1677
         e.printStackTrace();
1678
         printError(e.toString());
1679
 
1680
         Throwable rootCause = e.getCause();
1681
         if (null != rootCause) {
1682
            while (null != rootCause.getCause()) {
1683
               rootCause = rootCause.getCause();
1684
            }
1685
            System.err.println("Root cause:");
1686
            rootCause.printStackTrace();
1687
         }
1688
 
1689
         return false;
1690
      }
1691
      finally {
1692
 
1693
         // In any case, delete the working directory if we created one
1694
 
1695
         if (null != workingDirectory) {
1696
 
1697
            if (!deleteRecursive(workingDirectory)) {
1698
               printWarning("Could not delete temporary directory at "+workingDirectory);
1699
            }
1700
         }
1701
 
1702
         printNotice("Done.");
1703
      }
1704
   }
1705
 
1706
   /**
1707
    * Recursively delete the specified directory and its contents,
1708
    * like <code>rm -Rf directory</code>
1709
    *
1710
    * @return <code>true</code> on success
1711
    */
1712
   private static boolean deleteRecursive(File directory) {
1713
 
1714
      boolean success = true;
1715
 
1716
      File[] files = directory.listFiles();
1717
 
1718
      for (int i=0, ilim=files.length; i<ilim; ++i) {
1719
 
1720
         File file = files[i];
1721
 
1722
         if (file.isDirectory()) {
1723
 
1724
            success = deleteRecursive(file) && success;
1725
         }
1726
         else {
1727
 
1728
            success = file.delete() && success;
1729
         }
1730
      }
1731
 
1732
      return directory.delete() && success;
1733
   }
1734
 
1735
   /**
1736
    *  Prints a string to stdout and appends a newline.  Convenience
1737
    *  method.
1738
    */
1739
   protected void println(String str) {
1740
      out.println(str);
1741
   }
1742
 
1743
   /**
1744
    *  Prints a string to stdout without appending a newline.
1745
    *  Convenience method.
1746
    */
1747
   protected void print(String str) {
1748
      out.print(str);
1749
   }
1750
 
1751
   /**
1752
    *  In standard mode, prints an empty line to stdout.
1753
    *  In thight mode, nothing happens.
1754
    *  Convenience method.
1755
    */
1756
   protected void println() {
1757
      if (!compress) {
1758
         out.println();
1759
      }
1760
   }
1761
 
1762
   /**
1763
    *  In standard mode, prints the given text indented to stdout and appends newline.
1764
    *  In tight mode, doesn't print indentation or newlines.
1765
    */
1766
   protected void print(int indentLevel, String msg) {
1767
      if (compress) {
1768
         out.print(msg);
1769
      }
1770
      else {
1771
         StringBuffer indentation = new StringBuffer();
1772
         for (int i=0; i<indentLevel*indentStep; ++i) {
1773
            indentation.append(' ');
1774
         }
1775
         out.print(indentation+msg);
1776
      }
1777
   }
1778
 
1779
   /**
1780
    *  In tight mode, prints a message at a given indentation level.
1781
    *  In standard mode, appends a newline in addition.
1782
    */
1783
   protected void println(int indentLevel, String msg) {
1784
      print(indentLevel, msg);
1785
      if (!compress) out.println();
1786
   }
1787
 
1788
   /**
1789
    *  Prints an atom tag at the given indentation level.
1790
    */
1791
   protected void printAtomTag(int level, String tag) {
1792
      println(level, "<"+tagPrefix+":"+replaceCharsInTag(tag)+"/>");
1793
   }
1794
 
1795
   /**
1796
    *  Prints an open tag at the given indentation level.
1797
    */
1798
   protected void printOpenTag(int level, String tag) {
1799
      printOpenTag(level, replaceCharsInTag(tag), true);
1800
   }
1801
 
1802
   /**
1803
    *  Prints an open tag at the given indentation level and
1804
    *  conditionally appends a newline (if not in tight mode).
1805
    */
1806
   protected void printOpenTag(int level, String tag, boolean appendNewline) {
1807
      if (appendNewline && !compress) {
1808
         println(level, "<"+tagPrefix+":"+replaceCharsInTag(tag)+">");
1809
      }
1810
      else {
1811
         print(level, "<"+tagPrefix+":"+replaceCharsInTag(tag)+">");
1812
      }
1813
   }
1814
 
1815
   /**
1816
    *  Prints a close tag at the given indentation level.
1817
    */
1818
   protected void printCloseTag(int level, String tag) {
1819
      printCloseTag(level, tag, true);
1820
   }
1821
 
1822
   /**
1823
    *  Prints a close tag at the given indentation level and
1824
    *  conditionally appends a newline (if not in tight mode).
1825
    */
1826
   protected void printCloseTag(int level, String tag, boolean appendNewline) {
1827
      if (appendNewline && !compress) {
1828
         println(level, "</"+tagPrefix+":"+replaceCharsInTag(tag)+">");
1829
      }
1830
      else {
1831
         print(level, "</"+tagPrefix+":"+replaceCharsInTag(tag)+">");
1832
      }
1833
   }
1834
 
1835
   public static int optionLength(String option) {
1836
      if ("-d".equals(option)) return 2;
1837
      else if ("-fixhtml".equals(option)) return 1;
1838
      else if ("-compress".equals(option)) return 1;
1839
      else if ("-nohtmlwarn".equals(option)) return 1;
1840
      else if ("-noemailwarn".equals(option)) return 1;
1841
      else if ("-indentstep".equals(option)) return 2;
1842
      else if ("-xslsheet".equals(option)) return 2;
1843
      else if ("-xsltdriver".equals(option)) return 2;
1844
      else if ("-postprocess".equals(option)) return 2;
1845
      else if ("-genhtml".equals(option)) return 1;
1846
      else if ("-geninfo".equals(option)) return 1;
1847
      else if ("-gendocbook".equals(option)) return 1;
1848
      else if ("-xmlonly".equals(option)) return 1;
1849
      else if ("-bottomnote".equals(option)) return 2;
1850
      else if ("-workpath".equals(option)) return 2;
1851
      else if ("-title".equals(option)) return 2;
1852
      else if ("-tagletpath".equals(option)) return 2;
1853
      else if ("-taglet".equals(option)) return 2;
1854
      else if ("-authormail".equals(option)) return 2;
1855
      else if ("-mailmangledot".equals(option)) return 2;
1856
      else if ("-mailmangleat".equals(option)) return 2;
1857
      else if ("-noindex".equals(option)) return 1;
1858
      else if ("-nocomment".equals(option)) return 1;
1859
      else if ("-notree".equals(option)) return 1;
1860
      else if ("-nohelp".equals(option)) return 1;
1861
      else if ("-nonavbar".equals(option)) return 1;
1862
      else if ("-splitindex".equals(option)) return 1;
1863
      else if ("-author".equals(option)) return 1;
1864
      else if ("-version".equals(option)) return 1;
1865
      else if ("-nosince".equals(option)) return 1;
1866
      else if ("-nodeprecated".equals(option)) return 1;
1867
      else if ("-linksource".equals(option)) return 1;
1868
      else if ("-windowtitle".equals(option)) return 2;
1869
      else if ("-helpfile".equals(option)) return 2;
1870
      else if ("-stylesheetfile".equals(option)) return 2;
1871
      else if ("-tag".equals(option)) return 2;
1872
      else if ("-header".equals(option)) return 2;
1873
      else if ("-footer".equals(option)) return 2;
1874
      else if ("-bottom".equals(option)) return 2;
1875
      else if ("-doctitle".equals(option)) return 2;
1876
      else if ("-nodeprecatedlist".equals(option)) return 1;
1877
      else if ("-uses".equals(option)) return 1;
1878
      else if ("-group".equals(option)) return 3;
1879
 
1880
      else return -1;
1881
   }
1882
 
1883
   public static boolean validOptions(String[][] options) {
1884
      return true;
1885
   }
1886
 
1887
 
1888
   /**
1889
    *  Workaround for non well-formed comments: fix tag contents
1890
    *  by replacing <code>&lt;</code> with <code>&amp;lt;</code>,
1891
    *  <code>&gt;</code> with <code>&amp;gt;</code> and
1892
    *  <code>&amp;</code> with <code>&amp;amp;</code>.
1893
    *
1894
    *  @param tagContent  String to process
1895
    *
1896
    *  @return given String with all special characters replaced by
1897
    *          HTML entities.
1898
    */
1899
   private static String replaceCharsInTag(String tagContent) {
1900
      return
1901
         replaceString(
1902
            replaceString(
1903
               replaceString(
1904
                  tagContent,
1905
                  "<", "&lt;"
1906
                  ),
1907
               ">", "&gt;"
1908
               ),
1909
            "&", "&amp;"
1910
            );
1911
   }
1912
 
1913
   /**
1914
    *  Replaces all occurences of string <code>needle</code> within string
1915
    *  <code>haystack</code> by string <code>replacement</code>.
1916
    *
1917
    *  @param haystack    The string to search and replace in.
1918
    *  @param needle      The string which is searched for.
1919
    *  @param replacement The string by which every occurence of <code>needle</code> is replaced.
1920
    */
1921
   private static String replaceString(String haystack, String needle, String replacement) {
1922
      int ndx = haystack.indexOf(needle);
1923
      if (ndx<0)
1924
         return haystack;
1925
      else
1926
         return haystack.substring(0, ndx) + replacement
1927
            + replaceString(haystack.substring(ndx+needle.length()), needle, replacement);
1928
   }
1929
 
1930
   protected void setTargetFile(String filename) throws IOException {
1931
 
1932
      OutputStream fileOut = new FileOutputStream(new File(xmlTargetDirectory, filename));
1933
      out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(fileOut, "UTF8")));;
1934
   }
1935
 
1936
   protected void closeTargetFile() {
1937
 
1938
      out.flush();
1939
      out.close();
1940
   }
1941
 
1942
   private String cdata(String str) {
1943
 
1944
      if (null==str) {
1945
         return str;
1946
      } // end of if ((null==str)
1947
 
1948
      StringBuffer rc = new StringBuffer();
1949
      for (int i=0; i<str.length(); ++i) {
1950
         char c = str.charAt(i);
1951
         if (c==0x09 || c==0x0a || c==0x0d || (c>=0x20 && c<=0xd7ff) || (c>=0xe000 && c<=0xfffd) || (c>=0x10000 && c<=0x10ffff)) {
1952
            rc.append(c);
1953
         }
1954
         else {
1955
            printWarning("Invalid Unicode character 0x"+Integer.toString(c, 16)+" in javadoc markup has been stripped.");
1956
         } // end of else
1957
 
1958
      }
1959
      return rc.toString();
1960
   }
1961
 
1962
   static void copyResourceToFile(String resourceName, File target) throws IOException {
1963
 
1964
      InputStream in = Driver.class.getResourceAsStream(resourceName);
1965
 
1966
      if (null != in) {
1967
 
1968
         FileOutputStream out = new FileOutputStream(target);
1969
         int size;
1970
         byte[] buffer = new byte[512];
1971
         while ((size = in.read(buffer)) >= 0) {
1972
            out.write(buffer, 0, size);
1973
         }
1974
         out.close();
1975
      }
1976
      else {
1977
 
1978
         throw new IOException("Can't find resource named "+resourceName);
1979
      }
1980
   }
1981
 
1982
   private void printError(String error) {
1983
      if (null != rootDoc) {
1984
         rootDoc.printError(error);
1985
      }
1986
      else {
1987
         System.err.println("ERROR: "+error);
1988
      }
1989
   }
1990
 
1991
   private void printWarning(String warning) {
1992
      if (null != rootDoc) {
1993
         rootDoc.printWarning(warning);
1994
      }
1995
      else {
1996
         System.err.println("WARNING: "+warning);
1997
      }
1998
   }
1999
 
2000
   private void printNotice(String notice) {
2001
      if (null != rootDoc) {
2002
         rootDoc.printNotice(notice);
2003
      }
2004
      else {
2005
         System.err.println(notice);
2006
      }
2007
   }
2008
 
2009
   /**
2010
    *  Copy the contents of the input directory to the output
2011
    *  directory. The output directory must exist.
2012
    */
2013
   private void copyPackageDataDir(GjdocPackageDoc packageDoc) throws IOException {
2014
      File docFilesSourceDirectory
2015
         = new File(packageDoc.packageDirectory(), "doc-files");
2016
      File docFilesTargetDirectory
2017
         = new File(this.targetDirectory,
2018
                    packageDoc.name().replace('.', File.separatorChar));
2019
      if (docFilesSourceDirectory.exists()) {
2020
         printNotice("Copying files from " + docFilesSourceDirectory);
2021
         copyDirectory(docFilesSourceDirectory, docFilesTargetDirectory,
2022
                       docFilesSubdirsEnabled,
2023
                       excludeDocFilesSubDirs);
2024
      }
2025
   }
2026
 
2027
   /**
2028
    *  Recursively copy the contents of the input directory to the
2029
    *  output directory. The output directory must exist.
2030
    */
2031
   private static void copyDirectory(File sourceDir, File targetDir,
2032
                                     boolean recursive,
2033
                                     Set excludeDirs) throws IOException {
2034
      if (!targetDir.exists() && !targetDir.mkdirs()) {
2035
         throw new IOException("Cannot create directory " + targetDir);
2036
      }
2037
 
2038
      File[] sourceFiles = sourceDir.listFiles();
2039
      for (int i=0; i<sourceFiles.length; ++i) {
2040
         if (sourceFiles[i].isDirectory()) {
2041
            if (recursive && (null == excludeDirs
2042
                              || !excludeDirs.contains(sourceFiles[i].getName()))) {
2043
               File targetSubDir = new File(targetDir,
2044
                                            sourceFiles[i].getName());
2045
               if (targetSubDir.exists() || targetSubDir.mkdir()) {
2046
                  copyDirectory(sourceFiles[i], targetSubDir, recursive, null);
2047
               }
2048
               else {
2049
                  throw new IOException("Cannot create directory " + targetSubDir);
2050
               }
2051
            }
2052
         }
2053
         else {
2054
            copyFile(sourceFiles[i], new File(targetDir, sourceFiles[i].getName()));
2055
         }
2056
      }
2057
   }
2058
 
2059
   /**
2060
    *  Copy the contents of the input file to the output file. The
2061
    *  output file's parent directory must exist.
2062
    */
2063
   private static void copyFile(File sourceFile, File targetFile) throws IOException {
2064
 
2065
      InputStream in = new FileInputStream(sourceFile);
2066
      OutputStream out = new FileOutputStream(targetFile);
2067
      int nread;
2068
      byte[] buf = new byte[512];
2069
      while ((nread = in.read(buf)) >= 0) {
2070
         out.write(buf, 0, nread);
2071
      }
2072
      in.close();
2073
      out.close();
2074
   }
2075
 
2076
   private void createIndexByName() throws IOException {
2077
      // Create index
2078
 
2079
      // Collect index
2080
 
2081
      Map indexMap = new TreeMap(new Comparator() {
2082
            public int compare(Object o1, Object o2) {
2083
               return o1.toString().toLowerCase().compareTo(o2.toString().toLowerCase());
2084
            }
2085
         });
2086
 
2087
      // Add packages to index
2088
 
2089
      PackageDoc[] packages = rootDoc.specifiedPackages();
2090
      for (int i=0, ilim=packages.length; i<ilim; ++i) {
2091
         PackageDoc c = packages[i];
2092
         indexMap.put(c.name(), c);
2093
      }
2094
 
2095
      // Add classes, fields and methods to index
2096
 
2097
      ClassDoc[] sumclasses = rootDoc.classes();
2098
      for (int i=0, ilim=sumclasses.length; i<ilim; ++i) {
2099
         ClassDoc c = sumclasses[i];
2100
         if (null == c.containingClass()) {
2101
            indexMap.put(c.name(), c);
2102
         }
2103
         else {
2104
            indexMap.put(c.name().substring(c.containingClass().name().length() + 1), c);
2105
         }
2106
         FieldDoc[] fields = c.fields();
2107
         for (int j=0, jlim=fields.length; j<jlim; ++j) {
2108
            indexMap.put(fields[j].name(), fields[j]);
2109
         }
2110
         MethodDoc[] methods = c.methods();
2111
         for (int j=0, jlim=methods.length; j<jlim; ++j) {
2112
            MethodDoc method = methods[j];
2113
            StringBuffer signature = new StringBuffer();
2114
            signature.append(method.name());
2115
            signature.append('(');
2116
            Parameter[] parameters = method.parameters();
2117
            for (int k=0, klim=parameters.length; k<klim; ++k) {
2118
               if (k > 0) {
2119
                  signature.append(", ");
2120
               }
2121
               signature.append(parameters[k].typeName());
2122
            }
2123
            signature.append(')');
2124
            indexMap.put(signature.toString(), method);
2125
         }
2126
      }
2127
 
2128
      // Assign output stream
2129
 
2130
      setTargetFile("alphaindex.xml");
2131
 
2132
      // Output XML document header
2133
 
2134
      println(0, "<?xml version=\"1.0\"?>");
2135
      println("<!DOCTYPE gjdoc SYSTEM \"dtd/gjdoc-alphaindex.dtd\">");
2136
      println();
2137
      printOpenTag(0, "alphaindex xmlns=\"http://www.w3.org/TR/REC-html40\" xmlns:gjdoc=\"http://www.gnu.org/software/cp-tools/gjdocxml\"");
2138
 
2139
      Iterator it = indexMap.keySet().iterator();
2140
 
2141
      char previousCategoryLetter = '\0';
2142
      boolean categoryOpen = false;
2143
 
2144
      while (it.hasNext()) {
2145
         String key = (String)it.next();
2146
         Doc entry = (Doc)indexMap.get(key);
2147
 
2148
         char firstChar = Character.toUpperCase(key.charAt(0));
2149
         if (firstChar != previousCategoryLetter) {
2150
            if (categoryOpen) {
2151
               printCloseTag(1, "category");
2152
            }
2153
            printOpenTag(1, "category letter=\"" + firstChar + "\"");
2154
            categoryOpen = true;
2155
            previousCategoryLetter = firstChar;
2156
         }
2157
 
2158
         printOpenTag(2, "entry name=\"" + key + "\"");
2159
         if (entry instanceof PackageDoc) {
2160
            printAtomTag(3, "isPackage");
2161
         }
2162
         else if (entry instanceof ClassDoc) {
2163
            printAtomTag(3, "isClass");
2164
            ClassDoc centry = (ClassDoc)entry;
2165
            currentClass = centry;
2166
            printAtomTag(3, "containingPackage name=\"" + centry.containingPackage().name() + "\"");
2167
            if (null != centry.containingClass()) {
2168
               printAtomTag(3, "containingClass name=\"" + centry.containingClass().name() + "\"");
2169
            }
2170
            if (centry.isInterface()) {
2171
               printAtomTag(3, "isInterface");
2172
            }
2173
            if (centry.isException()) {
2174
               printAtomTag(3, "isException");
2175
            }
2176
            if (centry.isError()) {
2177
               printAtomTag(3, "isError");
2178
            }
2179
            if (centry.isOrdinaryClass()) {
2180
               printAtomTag(3, "isOrdinaryClass");
2181
            }
2182
         }
2183
         else if (entry instanceof ProgramElementDoc) {
2184
            ProgramElementDoc pentry = (ProgramElementDoc)entry;
2185
            currentClass = pentry.containingClass();
2186
            printAtomTag(3, "containingPackage name=\"" + pentry.containingPackage().name() + "\"");
2187
            printAtomTag(3, "containingClass name=\"" + pentry.containingClass().name() + "\"");
2188
            if (pentry.isMethod()) {
2189
               printAtomTag(3, "isMethod");
2190
               ExecutableMemberDoc mentry = (ExecutableMemberDoc)pentry;
2191
               printAtomTag(3, "signature full=\""+mentry.signature()+"\" flat=\""+mentry.flatSignature()+"\"");
2192
               printAtomTag(3, "method name=\"" + mentry.name() + "\"");
2193
            }
2194
            if (pentry.isField()) {
2195
               printAtomTag(3, "isField");
2196
            }
2197
         }
2198
 
2199
         Tag[] tags = entry.firstSentenceTags();
2200
         for (int i=0, ilim=tags.length; i<ilim; ++i) {
2201
            Tag tag = tags[i];
2202
            if (tag.firstSentenceTags().length>0) {
2203
               printOpenTag(3, "firstSentenceTags", false);
2204
               outputTags(4, tag.firstSentenceTags(), false, CONTEXT_TYPE);
2205
               printCloseTag(3, "firstSentenceTags");
2206
            }
2207
         }
2208
 
2209
 
2210
         printCloseTag(2, "entry");
2211
      }
2212
 
2213
      if (categoryOpen) {
2214
         printCloseTag(1, "category");
2215
      }
2216
 
2217
      printCloseTag(0, "alphaindex");
2218
 
2219
      closeTargetFile();
2220
   }
2221
 
2222
   private static class UsageType
2223
   {
2224
      public static final UsageType CLASS_DERIVED_FROM = new UsageType("class-derived-from");
2225
      public static final UsageType FIELD_OF_TYPE = new UsageType("field-of-type");
2226
      public static final UsageType METHOD_WITH_RETURN_TYPE = new UsageType("method-with-return-type");
2227
      public static final UsageType METHOD_WITH_PARAMETER_TYPE = new UsageType("method-with-parameter-type");
2228
      public static final UsageType METHOD_WITH_THROWN_TYPE = new UsageType("method-with-thrown-type");
2229
      public static final UsageType CONSTRUCTOR_WITH_PARAMETER_TYPE = new UsageType("constructor-with-parameter-type");
2230
      public static final UsageType CONSTRUCTOR_WITH_THROWN_TYPE = new UsageType("constructor-with-thrown-type");
2231
      private String id;
2232
 
2233
      private UsageType(String id)
2234
      {
2235
         this.id = id;
2236
      }
2237
 
2238
      public String toString() {
2239
         return "UsageType{id=" + id + "}";
2240
      }
2241
 
2242
      public String getId() {
2243
         return id;
2244
      }
2245
   }
2246
 
2247
   /**
2248
    *  ClassDoc -> (PackageDoc -> (UsageType -> (Set of Doc)))
2249
    */
2250
   private Map usedClassToPackagesMap = new HashMap();
2251
 
2252
   private void addUsedBy(ClassDoc usedClass, UsageType usageType, Doc user, PackageDoc userPackage)
2253
   {
2254
      Map packageToUsageTypeMap = (Map)usedClassToPackagesMap.get(usedClass);
2255
      if (null == packageToUsageTypeMap) {
2256
         packageToUsageTypeMap = new HashMap();
2257
         usedClassToPackagesMap.put(usedClass, packageToUsageTypeMap);
2258
      }
2259
 
2260
      Map usageTypeToUsersMap = (Map)packageToUsageTypeMap.get(userPackage);
2261
      if (null == usageTypeToUsersMap) {
2262
         usageTypeToUsersMap = new HashMap();
2263
         packageToUsageTypeMap.put(userPackage, usageTypeToUsersMap);
2264
      }
2265
 
2266
      Set userSet = (Set)usageTypeToUsersMap.get(usageType);
2267
      if (null == userSet) {
2268
         userSet = new TreeSet(); // FIXME: we need the collator from Main here
2269
         usageTypeToUsersMap.put(usageType, userSet);
2270
      }
2271
      userSet.add(user);
2272
   }
2273
 
2274
   /**
2275
    *  Create the cross reference database.
2276
    */
2277
   private void collectUsage() {
2278
 
2279
      ClassDoc[] classes = rootDoc.classes();
2280
      for (int i = 0, ilim = classes.length; i < ilim; ++ i) {
2281
         ClassDoc clazz = classes[i];
2282
 
2283
         // classes derived from
2284
         for (ClassDoc superclass = clazz.superclass(); superclass != null;
2285
              superclass = superclass.superclass()) {
2286
            addUsedBy(superclass, UsageType.CLASS_DERIVED_FROM, clazz, clazz.containingPackage());
2287
         }
2288
 
2289
         FieldDoc[] fields = clazz.fields();
2290
         for (int j = 0, jlim = fields.length; j < jlim; ++ j) {
2291
            FieldDoc field = fields[j];
2292
 
2293
            // fields of type
2294
            ClassDoc fieldType = field.type().asClassDoc();
2295
            if (null != fieldType) {
2296
               addUsedBy(fieldType, UsageType.FIELD_OF_TYPE,
2297
                         field, clazz.containingPackage());
2298
            }
2299
         }
2300
 
2301
         MethodDoc[] methods = clazz.methods();
2302
         for (int j = 0, jlim = methods.length; j < jlim; ++ j) {
2303
            MethodDoc method = methods[j];
2304
 
2305
            // methods with return type
2306
 
2307
            ClassDoc returnType = method.returnType().asClassDoc();
2308
            if (null != returnType) {
2309
               addUsedBy(returnType, UsageType.METHOD_WITH_RETURN_TYPE,
2310
                         method, clazz.containingPackage());
2311
            }
2312
            Parameter[] parameters = method.parameters();
2313
            for (int k=0; k<parameters.length; ++k) {
2314
 
2315
               // methods with parameter type
2316
 
2317
               Parameter parameter = parameters[k];
2318
               ClassDoc parameterType = parameter.type().asClassDoc();
2319
               if (null != parameterType) {
2320
                  addUsedBy(parameterType, UsageType.METHOD_WITH_PARAMETER_TYPE,
2321
                            method, clazz.containingPackage());
2322
               }
2323
            }
2324
 
2325
            // methods which throw
2326
 
2327
            ClassDoc[] thrownExceptions = method.thrownExceptions();
2328
            for (int k = 0, klim = thrownExceptions.length; k < klim; ++ k) {
2329
               ClassDoc thrownException = thrownExceptions[k];
2330
               addUsedBy(thrownException, UsageType.METHOD_WITH_THROWN_TYPE,
2331
                         method, clazz.containingPackage());
2332
            }
2333
         }
2334
 
2335
         ConstructorDoc[] constructors = clazz.constructors();
2336
         for (int j = 0, jlim = constructors.length; j < jlim; ++ j) {
2337
 
2338
            ConstructorDoc constructor = constructors[j];
2339
 
2340
            Parameter[] parameters = constructor.parameters();
2341
            for (int k = 0, klim = parameters.length; k < klim; ++ k) {
2342
 
2343
               // constructors with parameter type
2344
 
2345
               Parameter parameter = parameters[k];
2346
               ClassDoc parameterType = parameter.type().asClassDoc();
2347
               if (null != parameterType) {
2348
                  addUsedBy(parameterType, UsageType.CONSTRUCTOR_WITH_PARAMETER_TYPE,
2349
                            constructor, clazz.containingPackage());
2350
               }
2351
            }
2352
 
2353
            // constructors which throw
2354
 
2355
            ClassDoc[] thrownExceptions = constructor.thrownExceptions();
2356
            for (int k = 0, klim = thrownExceptions.length; k < klim; ++ k) {
2357
               ClassDoc thrownException = thrownExceptions[k];
2358
               addUsedBy(thrownException, UsageType.CONSTRUCTOR_WITH_THROWN_TYPE,
2359
                         constructor, clazz.containingPackage());
2360
            }
2361
         }
2362
      }
2363
   }
2364
 
2365
   private void outputUsage(ClassDoc clazz, int level) {
2366
 
2367
      Map packageToUsageTypeMap = (Map)usedClassToPackagesMap.get(clazz);
2368
      if (null != packageToUsageTypeMap) {
2369
         printOpenTag(level, "references");
2370
 
2371
         Iterator packagesIterator = packageToUsageTypeMap.keySet().iterator();
2372
 
2373
         while (packagesIterator.hasNext()) {
2374
            PackageDoc packageDoc = (PackageDoc)packagesIterator.next();
2375
            printOpenTag(level + 1, "referencing-package name=\"" + packageDoc.name() + "\"");
2376
            Map usageTypeToUsersMap = (Map)packageToUsageTypeMap.get(packageDoc);
2377
            Iterator usageTypeIterator = usageTypeToUsersMap.keySet().iterator();
2378
            while (usageTypeIterator.hasNext()) {
2379
               UsageType usageType = (UsageType)usageTypeIterator.next();
2380
               printOpenTag(level + 2, "usage-type id=\"" + usageType.getId() + "\"");
2381
               Set users = (Set)usageTypeToUsersMap.get(usageType);
2382
               Iterator userIterator = users.iterator();
2383
               while (userIterator.hasNext()) {
2384
                  Doc user = (Doc)userIterator.next();
2385
                  if (user instanceof ClassDoc) {
2386
                     printAtomTag(level + 3, "user"
2387
                                  + " class=\"" + ((ClassDoc)user).name() + "\"");
2388
                  }
2389
                  else if (user instanceof FieldDoc) {
2390
                     FieldDoc fieldDoc = (FieldDoc)user;
2391
                     printAtomTag(level + 3, "user"
2392
                                  + " class=\"" + fieldDoc.containingClass().name() + "\""
2393
                                  + " field=\"" + fieldDoc.name() + "\"");
2394
                  }
2395
                  else if (user instanceof MethodDoc) {
2396
                     MethodDoc methodDoc = (MethodDoc)user;
2397
                     printAtomTag(level + 3, "user"
2398
                                  + " class=\"" + methodDoc.containingClass().name() + "\""
2399
                                  + " method=\"" + methodDoc.name() + "\""
2400
                                  + " signature=\"" + methodDoc.signature() + "\""
2401
                                  + " flatSignature=\"" + methodDoc.flatSignature() + "\"");
2402
                  }
2403
                  else if (user instanceof ConstructorDoc) {
2404
                     ConstructorDoc constructorDoc = (ConstructorDoc)user;
2405
                     printAtomTag(level + 3, "user"
2406
                                  + " class=\"" + constructorDoc.containingClass().name() + "\""
2407
                                  + " signature=\"" + constructorDoc.signature() + "\""
2408
                                  + " flatSignature=\"" + constructorDoc.flatSignature() + "\"");
2409
                  }
2410
               }
2411
               printCloseTag(level +2, "usage-type");
2412
            }
2413
            printCloseTag(level + 1, "referencing-package");
2414
         }
2415
 
2416
         printCloseTag(level, "references");
2417
      }
2418
   }
2419
 
2420
   private boolean processGroupOption(String groupName, String colonSeparatedPackageList)
2421
   {
2422
      try {
2423
         PackageMatcher packageMatcher = new PackageMatcher();
2424
 
2425
         StringTokenizer tokenizer = new StringTokenizer(colonSeparatedPackageList, ":");
2426
         while (tokenizer.hasMoreTokens()) {
2427
            String packageWildcard = tokenizer.nextToken();
2428
            packageMatcher.addWildcard(packageWildcard);
2429
         }
2430
 
2431
         SortedSet groupPackages = packageMatcher.filter(rootDoc.specifiedPackages());
2432
 
2433
         packageGroups.add(new PackageGroup(groupName, groupPackages));
2434
 
2435
         return true;
2436
      }
2437
      catch (InvalidPackageWildcardException e) {
2438
         return false;
2439
      }
2440
   }
2441
 
2442
   private void registerTaglet(Taglet taglet)
2443
   {
2444
      tagletMap.put(taglet.getName(), taglet);
2445
   }
2446
 
2447
   private boolean isVerbose()
2448
   {
2449
      return false;
2450
   }
2451
}

powered by: WebSVN 2.1.0

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