Project Report: fawkez

Packagesummary org.jcoderz.commons.doclet

org.jcoderz.commons.doclet.XmlDoclet

LineHitsNoteSource
1  /*
2   * $Id: XmlDoclet.java 1011 2008-06-16 17:57:36Z amandel $
3   *
4   * Copyright 2006, The jCoderZ.org Project. All rights reserved.
5   *
6   * Redistribution and use in source and binary forms, with or without
7   * modification, are permitted provided that the following conditions are
8   * met:
9   *
10   *    * Redistributions of source code must retain the above copyright
11   *      notice, this list of conditions and the following disclaimer.
12   *    * Redistributions in binary form must reproduce the above
13   *      copyright notice, this list of conditions and the following
14   *      disclaimer in the documentation and/or other materials
15   *      provided with the distribution.
16   *    * Neither the name of the jCoderZ.org Project nor the names of
17   *      its contributors may be used to endorse or promote products
18   *      derived from this software without specific prior written
19   *      permission.
20   *
21   * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS" AND
22   * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24   * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS
25   * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26   * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27   * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
28   * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29   * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
30   * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
31   * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32   */
33  package org.jcoderz.commons.doclet;
34  
35  import java.io.File;
36  import java.io.FileOutputStream;
37  import java.io.IOException;
38  import java.io.OutputStreamWriter;
39  import java.io.Writer;
40  import java.util.Arrays;
41  import java.util.HashMap;
42  import java.util.HashSet;
43  import java.util.Iterator;
44  import java.util.Map;
45  import java.util.Set;
46  import java.util.logging.Level;
47  import java.util.logging.Logger;
48  
49  import org.jcoderz.commons.ArgumentMalformedException;
50  import org.jcoderz.commons.util.ArraysUtil;
51  import org.jcoderz.commons.util.IoUtil;
52  import org.jcoderz.commons.util.StringUtil;
53  import org.jcoderz.commons.util.XmlUtil;
54  
55  import com.sun.javadoc.ClassDoc;
56  import com.sun.javadoc.ConstructorDoc;
57  import com.sun.javadoc.Doc;
58  import com.sun.javadoc.DocErrorReporter;
59  import com.sun.javadoc.Doclet;
60  import com.sun.javadoc.ExecutableMemberDoc;
61  import com.sun.javadoc.FieldDoc;
62  import com.sun.javadoc.MemberDoc;
63  import com.sun.javadoc.MethodDoc;
64  import com.sun.javadoc.PackageDoc;
65  import com.sun.javadoc.ParamTag;
66  import com.sun.javadoc.Parameter;
67  import com.sun.javadoc.ProgramElementDoc;
68  import com.sun.javadoc.RootDoc;
69  import com.sun.javadoc.SeeTag;
70  import com.sun.javadoc.SourcePosition;
71  import com.sun.javadoc.Tag;
72  import com.sun.javadoc.ThrowsTag;
73  
74  /**
75   * A generic doclet that writes out all javadoc information as XML.
76   *
77   * @author Andreas Mandel
78   */
79  public class XmlDoclet
80        extends Doclet
81  {
82     /** The full qualified name of this class. */
830    private static final String CLASSNAME = XmlDoclet.class.getName();
84  
85     /** The logger to use. */
860    private static final Logger logger = Logger.getLogger(CLASSNAME);
87  
88     /** Static collector for doclet configuration. */
890    private static XmlDocletConfig sConfig = new XmlDocletConfig();
90  
91     /** Concrete configuration for this xml doclet instance. */
92     private final XmlDocletConfig mConfig;
93  
94     /** Output writer for current doclet. */
950    private Writer mOut = null;
96  
97     private RootDoc mRootDoc;
98  
99     /**
100      * Creates a new XmlDoclet with the given (fix) configuration.
101      * @param config the config to use.
102      */
103     public XmlDoclet (XmlDocletConfig config)
1040    {
105        try
106        {
1070          mConfig = (XmlDocletConfig) config.clone();
108        }
1090       catch (CloneNotSupportedException e)
110        {
1110(1)         throw new RuntimeException("Clone must be supported by config.", e);
1120       }
1130    }
114  
115     /** {@inheritDoc} */
116 (2)   public static boolean start (RootDoc root)
117     {
1180       if (logger.isLoggable(Level.FINER))
119        {
1200          logger.entering(CLASSNAME, "start(RootDoc)", root);
121        }
1220       boolean result = true;
123        try
124        {
1250          final XmlDoclet handler = new XmlDoclet(sConfig);
1260          handler.handle(root);
127        }
1280       catch (Exception ex)
129        {
130 (3)         // CHECKME:
1310          result = false;
1320          root.printError(ex.getMessage());
1330(4)         throw new RuntimeException("Internal processing error.", ex);
1340       }
1350       if (logger.isLoggable(Level.FINER))
136        {
1370          logger.exiting(CLASSNAME, "start(RootDoc)", Boolean.valueOf(result));
138        }
1390       return result;
140     }
141  
142     /** @see XmlDocletConfig#optionLength(String) */
143 (5)(6)   public static int optionLength (String option)
144     {
1450       if (logger.isLoggable(Level.FINER))
146        {
1470          logger.entering(CLASSNAME, "optionLength(String)", option);
148        }
1490       final int result = sConfig.optionLength(option);
1500       if (logger.isLoggable(Level.FINER))
151        {
1520          logger.exiting(CLASSNAME, "optionLength(String)",
153                 new Integer(result));
154        }
1550       return result;
156     }
157  
158 (7)   public static boolean validOptions (String[][] arguments,
159           DocErrorReporter reporter)
160     {
1610       if (logger.isLoggable(Level.FINER))
162        {
1630          logger.entering(CLASSNAME,
164                 "validOptions(String[][], DocErrorReporter)",
165                 new Object[] {ArraysUtil.toString(arguments), reporter});
166        }
1670       boolean result = true;
1680       final Iterator i = Arrays.asList(arguments).iterator();
1690       while (i.hasNext())
170        {
1710          final String[] arg = (String[]) i.next();
1720          if (logger.isLoggable(Level.FINER))
173           {
1740             logger.finest("About to parse argument: "
175                    + ArraysUtil.toString(arg));
176           }
1770          final String[] options = new String[arg.length - 1];
1780          System.arraycopy(arg, 1, options, 0, options.length);
179           try
180           {
1810             sConfig.parseOption(arg[0], options);
182           }
1830          catch (ArgumentMalformedException ex)
184           {
1850             reporter.printError(ex.getMessage());
1860             result = false;
1870          }
1880       }
1890       if (logger.isLoggable(Level.FINER))
190        {
1910          logger.exiting(CLASSNAME,
192                 "validOptions(String[][], DocErrorReporter)",
193                 Boolean.valueOf(result));
194        }
1950       return result;
196     }
197  
198  
199     private void handle (RootDoc root)
200           throws IOException
201     {
202        // create XML file
2030       FileOutputStream streamOut = null;
2040       mRootDoc = root;
205        try
206        {
2070          streamOut = new FileOutputStream(
208                 new File(mConfig.getOutputDirectory(), "javadoc.xml"), false);
209  
2100          mOut = new OutputStreamWriter(streamOut, "utf-8");
211  
2120          mOut.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
2130          mOut.write("<javadoc>\n");
214  
2150          final Set handledPackages = new HashSet();
216  
2170          final PackageDoc[] packages = root.specifiedPackages();
2180          for (int i = 0; i < packages.length; ++i)
219           {
2200             generatePackageElement(packages[i]);
2210             handledPackages.add(packages[i].name());
222           }
2230          final ClassDoc[] classes = root.specifiedClasses();
2240          for (int i = 0; i < classes.length; ++i)
225           {
2260             if (!handledPackages.contains(
227                    classes[i].containingPackage().name()))
228              {
2290                generatePackageElement(classes[i].containingPackage());
2300                handledPackages.add(classes[i].containingPackage().name());
231              }
232           }
2330          mOut.write("</javadoc>");
234  
235  
236        }
237        finally
238        {
2390          IoUtil.close(mOut);
2400          IoUtil.close(streamOut);
2410          mOut = null;
2420       }
2430    }
244  
245     private void generatePackageElement (PackageDoc pkg)
246           throws IOException
247     {
2480       mOut.write("<package");
2490       generateDocHeader(pkg);
2500       mOut.write(">");
2510       generateDocBody(pkg);
2520       final ClassDoc[] classes = pkg.allClasses();
2530       for (int i = 0; i < classes.length; ++i)
254        {
2550          generateClassElement(classes[i]);
256        }
2570       mOut.write("</package>");
2580    }
259  
260     private void generateClassElement (ClassDoc cd)
261           throws IOException
262     {
2630       mOut.write("<class");
2640       generateClassHeader(cd);
2650       mOut.write(">\n");
2660       generateClassBody(cd);
2670       mOut.write("</class>\n");
2680    }
269  
270     private void generateClassBody (ClassDoc cd)
271           throws IOException
272     {
2730       generateProgramElementBody(cd);
274  
275        // Interfaces
2760       final ClassDoc[] interfaces = cd.interfaces();
2770       for (int i = 0; i < interfaces.length; ++i)
278        {
2790          mOut.write("<interface");
2800(8)         addAttribute("name", interfaces[i].qualifiedName());
2810          mOut.write("/>\n");
282        }
283  
284        // InnerClasses
2850       final ClassDoc[] innerClass = cd.innerClasses();
2860       for (int i = 0; i < innerClass.length; ++i)
287        {
2880          mOut.write("<inner");
2890          addAttribute("name", innerClass[i].qualifiedName());
2900          mOut.write("/>\n");
291        }
292  
293  
294        // Fields
2950       final FieldDoc[] fields = cd.fields();
2960       for (int i = 0; i < fields.length; ++i)
297        {
2980          final FieldDoc field = fields[i];
2990          generateFieldHeader(field);
3000          generateFieldBody(field);
3010          mOut.write("</field>\n");
302        }
303  
304        // Constructors
3050       final ConstructorDoc[] constructors = cd.constructors();
3060       for (int i = 0; i < constructors.length; ++i)
307        {
3080          final ConstructorDoc constructor = constructors[i];
3090          generateConstructorHeader(constructor);
3100          generateConstructorBody(constructor);
3110          mOut.write("</constructor>\n");
312        }
313  
314        // Methods.
3150       final MethodDoc[] methods = cd.methods();
3160       for (int i = 0; i < methods.length; ++i)
317        {
3180          final MethodDoc method = methods[i];
3190          generateMethodHeader(method);
3200          generateMethodBody(method);
3210          mOut.write("</method>\n");
322        }
3230    }
324  
325     private void generateMethodHeader (MethodDoc method)
326           throws IOException
327     {
3280       mOut.write("<method");
329  
3300       addAttribute("abstract", method.isAbstract());
3310       if (method.overriddenClass() != null)
332        {
3330          addAttribute("overridden-class",
334                 method.overriddenClass().qualifiedName());
335        }
336  
3370       if (method.overriddenMethod() != null)
338        {
3390          addAttribute("overridden-method",
340                 method.overriddenMethod().qualifiedName());
341        }
342  
3430       generateExecutableMemberHeader(method);
3440       mOut.write(">\n");
3450    }
346  
347     private void generateMethodBody (MethodDoc method)
348           throws IOException
349     {
3500(9)      if (method.returnType() != null
351              && !method.returnType().qualifiedTypeName().equals("void"))
352        {
3530          mOut.write("<return");
3540(10)         addAttribute("type",
355                 method.returnType().qualifiedTypeName()
356                    + method.returnType().dimension());
3570          mOut.write(">");
3580          final Tag[] returnTag = method.tags("return");
3590          if (returnTag != null && returnTag.length > 0)
360           {
3610             generatedTagedTextElement(returnTag[0].inlineTags());
362           }
3630          mOut.write("</return>\n");
364        }
3650       generateExecutableMemberDocBody(method);
3660    }
367  
368     private void generatedTagedTextElement (final Tag[] tags)
369           throws IOException
370     {
3710       mOut.write("<doc>");
3720       generateTagedDoc(tags);
3730       mOut.write("</doc>\n");
3740    }
375  
376     private void generateConstructorBody (ConstructorDoc constructor)
377           throws IOException
378     {
3790       generateExecutableMemberDocBody(constructor);
3800    }
381  
382 (11)   private void generateExecutableMemberDocBody (
383           ExecutableMemberDoc executableMemberDoc)
384           throws IOException
385     {
3860       generateMemberBody(executableMemberDoc);
387  
388        // Parameter
3890       final ParamTag[] tags = executableMemberDoc.paramTags();
3900       final Map parameterTags = new HashMap();
3910       for (int i = 0; i < tags.length; ++i)
392        {
3930          if (parameterTags.containsKey(tags[i].parameterName()))
394           {
3950             warn(tags[i].position(),
396                    "Duplicate parameter ignored. " + tags[i],
397                    executableMemberDoc);
398           }
399           else
400           {
401              // ONLY on tag per parametername
4020             parameterTags.put(tags[i].parameterName(), tags[i]);
403           }
404        }
405  
4060       final Parameter[] parameters = executableMemberDoc.parameters();
4070       for (int i = 0; i < parameters.length; ++i)
408        {
4090          final ParamTag parameterTag
410                 = (ParamTag) parameterTags.get(parameters[i].name());
411  //         if (parameterTag == null)
412  //         {
413  //            warn("No tag for parameter " + parameters[i].hashCode(),
414  //                  executableMemberDoc);
415  //         }
4160          generateParameterHeader(parameters[i], parameterTag);
4170          generateParameterBody(parameters[i], parameterTag);
4180          mOut.write("</parameter>\n");
4190          parameterTags.remove(parameters[i].name());
420        }
421  
4220       if (!parameterTags.isEmpty())
423        {
4240          warn(executableMemberDoc.position(),
425                 "Unused parameter tags: " + parameterTags, executableMemberDoc);
426        }
427  
428        // Exceptions
4290       final ThrowsTag[] tTags = executableMemberDoc.throwsTags();
4300       final Map throwsTags = new HashMap();
4310       for (int i = 0; i < tTags.length; ++i)
432        {
4330          if (throwsTags.containsKey(tTags[i].exceptionName()))
434           {
4350             warn(tTags[i].position(),
436                    "Duplicate throws Tags ignored." + tTags[i].exceptionName(),
437                    executableMemberDoc);
438           }
439           else
440           {
4410             throwsTags.put(tTags[i].exceptionName(), tTags[i]);
442           }
443        }
444  
4450       final ClassDoc[] exceptions = executableMemberDoc.thrownExceptions();
4460       for (int i = 0; i < exceptions.length; ++i)
447        {
4480          ThrowsTag exceptionTag
449                 = (ThrowsTag) throwsTags.remove(exceptions[i].qualifiedName());
4500          if (exceptionTag == null)
451           {
4520             exceptionTag = (ThrowsTag) throwsTags.remove(exceptions[i].name());
453           }
4540(12)         if (exceptionTag == null)
455           {
456  //            warn(executableMemberDoc.position(),
457  //                  "No tag for exception " + exceptions[i].name(),
458  //                  executableMemberDoc);
459           }
4600          generateThrowsHeader(exceptions[i], exceptionTag);
4610          generateThrowsBody(exceptions[i], exceptionTag);
4620          mOut.write("</throws>\n");
463        }
464  
4650       if (!throwsTags.isEmpty())
466        {
4670          warn(executableMemberDoc.position(),
468                 "Unused throws tags: " + throwsTags, executableMemberDoc);
469        }
4700    }
471  
472     private void generateMemberBody (MemberDoc member)
473           throws IOException
474     {
4750       generateProgramElementBody(member);
4760    }
477  
478     private void generateProgramElementBody (ProgramElementDoc programElement)
479           throws IOException
480     {
4810       generateDocBody(programElement);
4820    }
483  
484     private void generateThrowsHeader (ClassDoc parameter,
485           ThrowsTag exceptionTag)
486           throws IOException
487     {
4880       mOut.write("<throws");
4890       addAttribute("type", parameter.qualifiedName());
4900       generateTagHeader(exceptionTag);
4910       mOut.write(">");
4920    }
493  
494     private void generateThrowsBody (ClassDoc parameter,
495           ThrowsTag exceptionTag)
496           throws IOException
497     {
4980       if (exceptionTag != null)
499        {
5000          generateTagBody(exceptionTag);
501        }
5020    }
503  
504     private void generateParameterBody (Parameter parameter,
505           ParamTag parameterTag)
506           throws IOException
507     {
5080       if (parameterTag != null)
509        {
5100          generateTagBody(parameterTag);
511        }
5120    }
513  
514     private void generateParameterHeader (Parameter parameter,
515           ParamTag parameterTag)
516           throws IOException
517     {
5180       mOut.write("<parameter");
5190       addAttribute("name", parameter.name());
5200       addAttribute("type",
521              parameter.type().qualifiedTypeName()
522                 + parameter.type().dimension());
5230       mOut.write(">");
5240    }
525  
526     private void generateConstructorHeader (ConstructorDoc cd)
527           throws IOException
528     {
5290       mOut.write("<constructor");
5300       generateExecutableMemberHeader(cd);
5310       mOut.write(">");
5320    }
533  
534     private void generateExecutableMemberHeader (ExecutableMemberDoc emd)
535           throws IOException
536     {
5370       addAttribute("flat-signature", emd.flatSignature());
5380       addAttribute("signature", emd.signature());
5390       addAttribute("native", emd.isNative());
5400       addAttribute("synchronized", emd.isSynchronized());
5410       generateMemberHeader(emd);
5420    }
543  
544     private void generateMemberHeader (MemberDoc md)
545           throws IOException
546     {
5470       addAttribute("synthetic", md.isSynthetic());
5480       generateProgramElementHeader(md);
5490    }
550  
551     private void generateFieldBody (FieldDoc fd)
552           throws IOException
553     {
5540       generateMemberBody(fd);
555 (13)      // TODO: cd.serialFieldTags()
5560    }
557  
558     private void generateFieldHeader (FieldDoc cd)
559           throws IOException
560     {
5610       mOut.write("<field");
5620       addAttribute("type",
563              cd.type().qualifiedTypeName() + cd.type().dimension());
564  
5650       final String constant = cd.constantValueExpression();
5660       if (constant != null)
567        {
5680          addAttribute("constant", true);
5690          addAttribute("value", constant);
570        }
5710       addAttribute("volatile", cd.isVolatile());
5720       addAttribute("transient", cd.isTransient());
5730       generateMemberHeader(cd);
5740       mOut.write(">");
5750    }
576  
577     private void generateDocBody (Doc doc)
578           throws IOException
579     {
5800       mOut.write("<doc>");
5810       generateTagedDoc(doc.inlineTags());
5820       mOut.write("</doc>");
583  
5840       final Tag[] tags = doc.tags();
5850       for (int i = 0; i < tags.length; i++)
586        {
5870          final Tag tag = tags[i];
588           // these tags are handled directly
5890(14)         if (!tag.kind().equals("@param")
590                 && !tag.kind().equals("@return")
591                 && !tag.kind().equals("@throws"))
592           {
5930             generateTagElement(tag);
594           }
595        }
5960    }
597  
598     private void generateTagHeader (Tag tag)
599           throws IOException
600     {
6010       if (tag != null)
602        {
6030          if (tag.position() != null)
604           {
6050             generateSourcePositionHeader(tag.position());
606           }
6070          addAttribute("name", tag.name());
608  
6090          if (tag instanceof SeeTag)
610           {
6110             final SeeTag seeTag = (SeeTag) tag;
6120             addAttribute("label", seeTag.label());
6130             addAttribute("referenced-class", seeTag.referencedClassName());
6140             addAttribute("referenced-member", seeTag.referencedMemberName());
6150             if (seeTag.referencedPackage() != null)
616              {
6170                addAttribute("referenced-package",
618                       seeTag.referencedPackage().name());
619              }
6200          }
621           else
622           {
6230             addAttribute("kind", tag.kind());
624           }
625        }
6260    }
627  
628     private void generateTagElement (Tag tag)
629           throws IOException
630     {
6310       if (tag instanceof SeeTag)
632        {
6330          generateSeeElement((SeeTag) tag);
634        }
6350       else if (tag != null)
636        {
6370          mOut.write("<tag");
6380          generateTagHeader(tag);
6390          mOut.write(">");
6400          generateTagBody(tag);
6410          mOut.write("</tag>");
642        }
6430    }
644  
645     private void generateTagBody (Tag tag)
646           throws IOException
647     {
6480       mOut.write("<doc>");
6490       generateTagedDoc(tag.inlineTags());
6500       mOut.write("</doc>");
6510    }
652  
653     private void generateTagedDoc (Tag[] tags)
654           throws IOException
655     {
656        // build string to be tidied up
6570       final StringBuffer data = new StringBuffer();
6580       for (int i = 0; i < tags.length; i++)
659        {
6600          final Tag inlineTag = tags[i];
6610          if (inlineTag instanceof SeeTag)
662           {
6630             data.append("<a id='SEE_TAG_");
6640             data.append(Integer.toString(i));
6650(15)            data.append("'></a>");
666           }
667           else
668           {
6690             data.append(inlineTag.text());
670           }
671        }
6720       final String input = data.toString();
673        final String clean;
6740       if (input.indexOf('<') != -1 || input.indexOf('&') != -1)
675        {
6760          final HtmlCleaner cleaner = new HtmlCleaner();
6770          clean = cleaner.clean(data);
6780          final String warnings = cleaner.getWarnings();
6790          if (!StringUtil.isEmptyOrNull(warnings))
680           {
6810             mRootDoc.printWarning("Input:" + input);
6820             mRootDoc.printWarning("Clean:" + clean);
6830             if (cleaner.hasErrors())
684              {
6850(16)               mRootDoc.printWarning(tags[0].position(), warnings);
686                 // mRootDoc.printError(tags[0].position(), warnings);
687              }
688              else
689              {
6900                mRootDoc.printWarning(tags[0].position(), warnings);
691              }
692           }
6930       }
694        else
695        {
6960          clean = input;
697        }
6980       data.setLength(0);
6990       data.append(clean);
700  
701        // now replace the a tag back...
702        int pos;
7030       while ((pos = data.indexOf("<a id='SEE_TAG_")) != -1)
704        {
7050          mOut.write(data.substring(0, pos));
7060          final int i = Integer.parseInt(data.substring(pos
707                 + "<a id='SEE_TAG_".length(), data.indexOf("'></a>", pos)));
7080          generateSeeElement((SeeTag) tags[i]);
7090          data.delete(0, data.indexOf("'></a>", pos) + "'></a>".length());
7100       }
7110       mOut.write(data.toString());
7120    }
713  
714     private void generateSeeElement (SeeTag tag)
715           throws IOException
716     {
7170       mOut.write("<see ");
7180       generateTagHeader(tag);
7190       mOut.write(">");
720        final String label;
7210       if (!StringUtil.isNullOrEmpty(tag.label()))
722        {
7230          label = tag.label();
724        }
7250       else if (tag.referencedClassName() != null
726              && tag.referencedMemberName() != null)
727        {
7280          label = tag.referencedClassName() + "#" + tag.referencedMemberName();
729        }
7300       else if (tag.referencedClassName() != null)
731        {
7320          label = tag.referencedClassName();
733        }
7340       else if (tag.referencedPackage() != null)
735        {
7360          label = tag.referencedPackage().name();
737        }
7380       else if (tag.referencedMemberName() != null)
739        {
7400          label = tag.referencedMemberName();
741        }
742        else
743        {
7440          label = "";
745        }
7460       mOut.write(XmlUtil.escape(label));
7470       mOut.write("</see>");
7480    }
749  
750     private void generateSourcePositionHeader (SourcePosition position)
751           throws IOException
752     {
7530       if (position.file() != null)
754        {
7550          addAttribute("file", position.file().getPath());
756        }
7570       addAttribute("line", position.line());
7580       addAttribute("column", position.column());
7590    }
760  
761     private void generateClassHeader (ClassDoc cd)
762           throws IOException
763     {
7640       generateProgramElementHeader(cd);
7650       addAttribute("abstract", cd.isAbstract());
7660       addAttribute("externalizable", cd.isExternalizable());
7670       addAttribute("serializable", cd.isSerializable());
7680       if (cd.superclass() != null)
769        {
7700          addAttribute("superclass", cd.superclass().qualifiedName());
771        }
7720    }
773  
774     private void generateProgramElementHeader (ProgramElementDoc pe)
775           throws IOException
776     {
7770       addAttribute("qualified-name", pe.qualifiedName());
778  
7790       if (pe.containingClass() != null)
780        {
7810          addAttribute("containing-class",
782                 pe.containingClass().qualifiedName());
783        }
784  
785        final String visibility;
7860       if (pe.isPrivate())
787        {
7880          visibility = "private";
789        }
7900       else if (pe.isProtected())
791        {
7920          visibility = "protected";
793        }
7940       else if (pe.isPackagePrivate())
795        {
7960          visibility = "package private";
797        }
7980       else if (pe.isPublic())
799        {
8000          visibility = "public";
801        }
802        else
803        {
8040          throw new RuntimeException("Could not detect access right " + pe);
805        }
8060       addAttribute("visibility", visibility);
8070       addAttribute("static", pe.isStatic());
8080       addAttribute("final", pe.isFinal());
8090       addAttribute("modifiers", pe.modifiers());
8100       addAttribute("modifier-specifier",
811              String.valueOf(pe.modifierSpecifier()));
812  
8130       generateDocHeader(pe);
8140    }
815  
816     private void generateDocHeader (Doc doc)
817           throws IOException
818     {
8190       addAttribute("name", doc.name());
8200       addAttribute("exception", doc.isException());
8210       addAttribute("error", doc.isError());
8220       addAttribute("ordinary-class", doc.isOrdinaryClass());
8230       if (doc.position() != null)
824        {
8250          generateSourcePositionHeader(doc.position());
826        }
8270       if (doc.isInterface())
828        {
8290          addAttribute("type", "interface");
830        }
8310       else if (doc.isClass())
832        {
8330          addAttribute("type", "class");
834        }
8350    }
836  
837     private void addAttribute (String name, boolean value)
838           throws IOException
839     {
8400       if (value)
841        {
8420          mOut.write(" ");
8430          mOut.write(name);
8440          mOut.write("='");
8450          mOut.write(name);
8460          mOut.write("'");
847        }
8480    }
849  
850     private void addAttribute (String name, int value)
851           throws IOException
852     {
8530       addAttribute(name, Integer.toString(value));
8540    }
855  
856     private void addAttribute (String name, String value)
857           throws IOException
858     {
8590       if (!StringUtil.isEmptyOrNull(value))
860        {
8610          mOut.write(" ");
8620          mOut.write(name);
8630          mOut.write("='");
8640          mOut.write(XmlUtil.attributeEscape(value));
8650          mOut.write("'");
866        }
8670    }
868  
869     private void warn (SourcePosition pos, String string, Object parameter)
870     {
8710       mRootDoc.printWarning(pos, string + " at " + parameter);
8720    }
873  
874  }

Findings in this File

i (1) 111 : 0 method new org.jcoderz.commons.doclet.XmlDoclet(XmlDocletConfig) throws exception with static message string
d (2) 116 : 0 @inheritDoc used but start(RootDoc) does not override or implement any method.
i (3) 130 : 0 Comment matches to-do format '(TODO|FIXME|CHECKME)'.
i (4) 133 : 0 method org.jcoderz.commons.doclet.XmlDoclet.start(RootDoc) throws exception with static message string
c (5) 143 : 0 Expected an @return tag.
c (6) 143 : 43 Expected @param tag for 'option'.
c (7) 158 : 4 Missing a Javadoc comment.
i (8) 280 : 23 The String literal "name" appears 5 times in this file; the first occurrence is on line 280
i (9) 350 : 0 method org.jcoderz.commons.doclet.XmlDoclet.generateMethodBody(MethodDoc) makes literal string comparisons passing the literal as an argument
i (10) 354 : 23 The String literal "type" appears 6 times in this file; the first occurrence is on line 354
c (11) 382 : 12 The method generateExecutableMemberDocBody() has an NPath complexity of 360
i (12) 454 : 0 Useless control flow in org.jcoderz.commons.doclet.XmlDoclet.generateExecutableMemberDocBody(ExecutableMemberDoc)
i (13) 555 : 0 Comment matches to-do format '(TODO|FIXME|CHECKME)'.
i (14) 589 : 0 method org.jcoderz.commons.doclet.XmlDoclet.generateDocBody(Doc) makes literal string comparisons passing the literal as an argument
i (15) 665 : 25 The String literal "'></a>" appears 4 times in this file; the first occurrence is on line 665
w (16) 685 : 0 Method org.jcoderz.commons.doclet.XmlDoclet.generateTagedDoc(Tag[]) uses the same code for two branches