001    /**
002     * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.tools;
016    
017    import com.liferay.portal.kernel.io.unsync.UnsyncStringReader;
018    import com.liferay.portal.kernel.util.StringPool;
019    import com.liferay.portal.kernel.util.StringUtil;
020    import com.liferay.portal.kernel.util.Validator;
021    import com.liferay.portal.kernel.xml.Document;
022    import com.liferay.portal.kernel.xml.Element;
023    import com.liferay.portal.util.FileImpl;
024    import com.liferay.portal.xml.SAXReaderImpl;
025    import com.liferay.util.xml.DocUtil;
026    
027    import com.thoughtworks.qdox.JavaDocBuilder;
028    import com.thoughtworks.qdox.model.AbstractJavaEntity;
029    import com.thoughtworks.qdox.model.DocletTag;
030    import com.thoughtworks.qdox.model.JavaClass;
031    import com.thoughtworks.qdox.model.JavaField;
032    import com.thoughtworks.qdox.model.JavaMethod;
033    import com.thoughtworks.qdox.model.JavaParameter;
034    import com.thoughtworks.qdox.model.Type;
035    
036    import jargs.gnu.CmdLineParser;
037    
038    import java.io.File;
039    import java.io.Reader;
040    
041    import java.util.ArrayList;
042    import java.util.HashMap;
043    import java.util.HashSet;
044    import java.util.List;
045    import java.util.Map;
046    import java.util.Set;
047    import java.util.TreeMap;
048    
049    import org.apache.tools.ant.DirectoryScanner;
050    
051    /**
052     * @author Brian Wing Shun Chan
053     */
054    public class JavadocBuilder {
055    
056            public static void main(String[] args) {
057                    try {
058                            new JavadocBuilder(args);
059                    }
060                    catch (Exception e) {
061                            e.printStackTrace();
062                    }
063            }
064    
065            public JavadocBuilder(String[] args) throws Exception {
066                    CmdLineParser cmdLineParser = new CmdLineParser();
067    
068                    cmdLineParser.parse(args);
069    
070                    CmdLineParser.Option commandOption = cmdLineParser.addStringOption(
071                            "command");
072    
073                    String command = (String)cmdLineParser.getOptionValue(commandOption);
074    
075                    CmdLineParser.Option limitOption = cmdLineParser.addStringOption(
076                            "limit");
077    
078                    String limit = (String)cmdLineParser.getOptionValue(limitOption);
079    
080                    CmdLineParser.Option ignoreAutogeneratedOption =
081                            cmdLineParser.addBooleanOption("ignoreAutogenerated");
082    
083                    Boolean ignoreAutogenerated = (Boolean)cmdLineParser.getOptionValue(
084                            ignoreAutogeneratedOption);
085    
086                    _process(command, limit, ignoreAutogenerated);
087            }
088    
089            private void _addClassCommentElement(
090                    Element rootElement, JavaClass javaClass) {
091    
092                    Element commentElement = rootElement.addElement("comment");
093    
094                    String comment = _getCDATA(javaClass);
095    
096                    if (comment.startsWith("Copyright (c) 2000-2010 Liferay, Inc.")) {
097                            comment = StringPool.BLANK;
098                    }
099    
100                    if (comment.startsWith(
101                                    "<a href=\"" + javaClass.getName() + ".java.html\">")) {
102    
103                            int pos = comment.indexOf("</a>");
104    
105                            comment = comment.substring(pos + 4).trim();
106                    }
107    
108                    commentElement.addCDATA(comment);
109            }
110    
111            private void _addDocletElements(
112                    Element parentElement, AbstractJavaEntity abstractJavaEntity,
113                    String name) {
114    
115                    DocletTag[] docletTags = abstractJavaEntity.getTagsByName(name);
116    
117                    for (DocletTag docletTag : docletTags) {
118                            String value = docletTag.getValue();
119    
120                            if (name.equals("author") || name.equals("see") ||
121                                    name.equals("since") || name.equals("version")) {
122    
123                                    /*if (value.startsWith("Raymond Aug")) {
124                                            value = "Raymond Aug\u00c3\u00a9";
125                                    }*/
126    
127                                    DocUtil.add(parentElement, name, value);
128                            }
129                            else {
130                                    Element element = parentElement.addElement(name);
131    
132                                    element.addCDATA(value);
133                            }
134                    }
135            }
136    
137            private void _addDocletTags(
138                    Element parentElement, String name, String indent, StringBuilder sb) {
139    
140                    List<Element> elements = parentElement.elements(name);
141    
142                    for (Element element : elements) {
143                            sb.append(indent);
144                            sb.append(" * @");
145                            sb.append(name);
146                            sb.append(" ");
147    
148                            Element commentElement = element.element("comment");
149    
150                            if (commentElement != null) {
151                                    sb.append(element.elementText("name"));
152                                    sb.append(" ");
153                                    sb.append(_getCDATA(element.elementText("comment")));
154                            }
155                            else {
156                                    sb.append(_getCDATA(element.getText()));
157                            }
158    
159                            sb.append("\n");
160                    }
161            }
162    
163            private void _addFieldElement(Element rootElement, JavaField javaField) {
164                    Element fieldElement = rootElement.addElement("field");
165    
166                    DocUtil.add(fieldElement, "name", javaField.getName());
167    
168                    Element commentElement = fieldElement.addElement("comment");
169    
170                    commentElement.addCDATA(_getCDATA(javaField));
171    
172                    _addDocletElements(fieldElement, javaField, "deprecated");
173                    _addDocletElements(fieldElement, javaField, "see");
174                    _addDocletElements(fieldElement, javaField, "since");
175                    _addDocletElements(fieldElement, javaField, "version");
176            }
177    
178            private void _addMethodElement(Element rootElement, JavaMethod javaMethod) {
179                    Element methodElement = rootElement.addElement("method");
180    
181                    DocUtil.add(methodElement, "name", javaMethod.getName());
182    
183                    Element commentElement = methodElement.addElement("comment");
184    
185                    commentElement.addCDATA(_getCDATA(javaMethod));
186    
187                    _addDocletElements(methodElement, javaMethod, "deprecated");
188                    _addParamElements(methodElement, javaMethod);
189                    _addReturnElement(methodElement, javaMethod);
190                    _addDocletElements(methodElement, javaMethod, "see");
191                    _addDocletElements(methodElement, javaMethod, "since");
192                    _addThrowsElements(methodElement, javaMethod);
193                    _addDocletElements(methodElement, javaMethod, "version");
194            }
195    
196            private void _addParamElement(
197                    Element methodElement, JavaParameter javaParameter,
198                    DocletTag[] paramDocletTags) {
199    
200                    String name = javaParameter.getName();
201                    String type = javaParameter.getType().getValue();
202                    String value = null;
203    
204                    for (DocletTag paramDocletTag : paramDocletTags) {
205                            String curValue = paramDocletTag.getValue();
206    
207                            if (!curValue.startsWith(name)) {
208                                    continue;
209                            }
210                            else {
211                                    curValue = value;
212    
213                                    break;
214                            }
215                    }
216    
217                    Element paramElement = methodElement.addElement("param");
218    
219                    DocUtil.add(paramElement, "name", name);
220                    DocUtil.add(paramElement, "type", type);
221    
222                    if (value != null) {
223                            value = value.substring(name.length());
224                    }
225    
226                    Element commentElement = paramElement.addElement("comment");
227    
228                    commentElement.addCDATA(_getCDATA(value));
229            }
230    
231            private void _addParamElements(
232                    Element methodElement, JavaMethod javaMethod) {
233    
234                    JavaParameter[] javaParameters = javaMethod.getParameters();
235    
236                    DocletTag[] paramDocletTags = javaMethod.getTagsByName("param");
237    
238                    for (JavaParameter javaParameter : javaParameters) {
239                            _addParamElement(methodElement, javaParameter, paramDocletTags);
240                    }
241            }
242    
243            private void _addReturnElement(
244                    Element methodElement, JavaMethod javaMethod) {
245    
246                    Type returns = javaMethod.getReturns();
247    
248                    if ((returns == null) || returns.getValue().equals("void")) {
249                            return;
250                    }
251    
252                    _addDocletElements(methodElement, javaMethod, "return");
253            }
254    
255            private void _addThrowsElement(
256                    Element methodElement, Type exception, DocletTag[] throwsDocletTags) {
257    
258                    String name = exception.getJavaClass().getName();
259                    String value = null;
260    
261                    for (DocletTag throwsDocletTag : throwsDocletTags) {
262                            String curValue = throwsDocletTag.getValue();
263    
264                            if (!curValue.startsWith(name)) {
265                                    continue;
266                            }
267                            else {
268                                    curValue = value;
269    
270                                    break;
271                            }
272                    }
273    
274                    Element throwsElement = methodElement.addElement("throws");
275    
276                    DocUtil.add(throwsElement, "name", name);
277                    DocUtil.add(throwsElement, "type", exception.getValue());
278    
279                    if (value != null) {
280                            value = value.substring(name.length());
281                    }
282    
283                    Element commentElement = throwsElement.addElement("comment");
284    
285                    commentElement.addCDATA(_getCDATA(value));
286    
287            }
288    
289            private void _addThrowsElements(
290                    Element methodElement, JavaMethod javaMethod) {
291    
292                    Type[] exceptions = javaMethod.getExceptions();
293    
294                    DocletTag[] throwsDocletTags = javaMethod.getTagsByName("throws");
295    
296                    for (Type exception : exceptions) {
297                            _addThrowsElement(methodElement, exception, throwsDocletTags);
298                    }
299            }
300    
301            private String _getCDATA(AbstractJavaEntity abstractJavaEntity) {
302                    return _getCDATA(abstractJavaEntity.getComment());
303            }
304    
305            private String _getCDATA(String cdata) {
306                    if (cdata == null) {
307                            return StringPool.BLANK;
308                    }
309    
310                    cdata = StringUtil.replace(
311                            cdata, new String[] {"\n", "<p>", "</p>"},
312                            new String[] {" ", " <p> ", " </p> "});
313    
314                    while (cdata.contains("  ")) {
315                            cdata = StringUtil.replace(cdata, "  ", " ");
316                    }
317    
318                    return cdata.trim();
319            }
320    
321            private String _getFieldKey(Element fieldElement) {
322                    return fieldElement.elementText("name");
323            }
324    
325            private String _getFieldKey(JavaField javaField) {
326                    return javaField.getName();
327            }
328    
329            private JavaClass _getJavaClass(String fileName) throws Exception {
330                    return _getJavaClass(fileName, null);
331            }
332    
333            private JavaClass _getJavaClass(String fileName, Reader reader)
334                    throws Exception {
335    
336                    int pos = fileName.indexOf("src/");
337    
338                    if (pos == -1) {
339                            pos = fileName.indexOf("test/");
340                    }
341    
342                    if (pos == -1) {
343                            throw new RuntimeException(fileName);
344                    }
345    
346                    pos = fileName.indexOf("/", pos);
347    
348                    String srcFile = fileName.substring(pos + 1);
349                    String className = StringUtil.replace(
350                            srcFile.substring(0, srcFile.length() - 5), "/", ".");
351    
352                    JavaDocBuilder builder = new JavaDocBuilder();
353    
354                    if (reader == null) {
355                            File file = new File(fileName);
356    
357                            if (!file.exists()) {
358                                    return null;
359                            }
360    
361                            builder.addSource(file);
362                    }
363                    else {
364                            builder.addSource(reader);
365                    }
366    
367                    return builder.getClassByName(className);
368            }
369    
370            private String _getJavaClassComment(
371                    Element rootElement, JavaClass javaClass) {
372    
373                    StringBuilder sb = new StringBuilder();
374    
375                    sb.append("/**\n");
376                    sb.append(" * ");
377                    sb.append(_getCDATA(rootElement.elementText("comment")));
378                    sb.append("\n");
379                    sb.append(" *\n");
380    
381                    String indent = StringPool.BLANK;
382    
383                    _addDocletTags(rootElement, "author", indent, sb);
384                    _addDocletTags(rootElement, "deprecated", indent, sb);
385                    _addDocletTags(rootElement, "see", indent, sb);
386                    _addDocletTags(rootElement, "serial", indent, sb);
387                    _addDocletTags(rootElement, "since", indent, sb);
388                    _addDocletTags(rootElement, "version", indent, sb);
389    
390                    sb.append(" */\n");
391    
392                    return sb.toString();
393            }
394    
395            private String _getJavadocXml(JavaClass javaClass) throws Exception {
396                    Element rootElement = _saxReaderUtil.createElement("javadoc");
397    
398                    Document document = _saxReaderUtil.createDocument(rootElement);
399    
400                    DocUtil.add(rootElement, "name", javaClass.getName());
401                    DocUtil.add(rootElement, "type", javaClass.getFullyQualifiedName());
402    
403                    _addClassCommentElement(rootElement, javaClass);
404                    _addDocletElements(rootElement, javaClass, "author");
405                    _addDocletElements(rootElement, javaClass, "deprecated");
406                    _addDocletElements(rootElement, javaClass, "see");
407                    _addDocletElements(rootElement, javaClass, "serial");
408                    _addDocletElements(rootElement, javaClass, "since");
409                    _addDocletElements(rootElement, javaClass, "version");
410    
411                    JavaMethod[] javaMethods = javaClass.getMethods();
412    
413                    for (JavaMethod javaMethod : javaMethods) {
414                            _addMethodElement(rootElement, javaMethod);
415                    }
416    
417                    JavaField[] javaFields = javaClass.getFields();
418    
419                    for (JavaField javaField : javaFields) {
420                            _addFieldElement(rootElement, javaField);
421                    }
422    
423                    return document.formattedString();
424            }
425    
426            private String _getJavaFieldComment(
427                    String[] lines, Map<String, Element> fieldElementsMap,
428                    JavaField javaField) {
429    
430                    String fieldKey = _getFieldKey(javaField);
431    
432                    Element fieldElement = fieldElementsMap.get(fieldKey);
433    
434                    if (fieldElement == null) {
435                            return null;
436                    }
437    
438                    String line = lines[javaField.getLineNumber() - 1];
439    
440                    String indent = StringPool.BLANK;
441    
442                    for (char c : line.toCharArray()) {
443                            if (Character.isWhitespace(c)) {
444                                    indent += c;
445                            }
446                            else {
447                                    break;
448                            }
449                    }
450    
451                    StringBuilder sb = new StringBuilder();
452    
453                    sb.append(indent);
454                    sb.append("/**\n");
455                    sb.append(indent);
456                    sb.append(" * ");
457                    sb.append(fieldElement.elementText("comment"));
458                    sb.append("\n");
459                    sb.append(indent);
460                    sb.append(" *\n");
461    
462                    _addDocletTags(fieldElement, "deprecated", indent, sb);
463                    _addDocletTags(fieldElement, "see", indent, sb);
464                    _addDocletTags(fieldElement, "since", indent, sb);
465                    _addDocletTags(fieldElement, "version", indent, sb);
466    
467                    sb.append(indent);
468                    sb.append(" */\n");
469    
470                    return sb.toString();
471            }
472    
473            private String _getJavaMethodComment(
474                    String[] lines, Map<String, Element> methodElementsMap,
475                    JavaMethod javaMethod) {
476    
477                    String methodKey = _getMethodKey(javaMethod);
478    
479                    Element methodElement = methodElementsMap.get(methodKey);
480    
481                    if (methodElement == null) {
482                            return null;
483                    }
484    
485                    String line = lines[javaMethod.getLineNumber() - 1];
486    
487                    String indent = StringPool.BLANK;
488    
489                    for (char c : line.toCharArray()) {
490                            if (Character.isWhitespace(c)) {
491                                    indent += c;
492                            }
493                            else {
494                                    break;
495                            }
496                    }
497    
498                    StringBuilder sb = new StringBuilder();
499    
500                    sb.append(indent);
501                    sb.append("/**\n");
502                    sb.append(indent);
503                    sb.append(" * ");
504                    sb.append(methodElement.elementText("comment"));
505                    sb.append("\n");
506                    sb.append(indent);
507                    sb.append(" *\n");
508    
509                    _addDocletTags(methodElement, "deprecated", indent, sb);
510                    _addDocletTags(methodElement, "param", indent, sb);
511                    _addDocletTags(methodElement, "return", indent, sb);
512                    _addDocletTags(methodElement, "see", indent, sb);
513                    _addDocletTags(methodElement, "since", indent, sb);
514                    _addDocletTags(methodElement, "throws", indent, sb);
515                    _addDocletTags(methodElement, "version", indent, sb);
516    
517                    sb.append(indent);
518                    sb.append(" */\n");
519    
520                    return sb.toString();
521            }
522    
523            private String _getMethodKey(Element methodElement) {
524                    StringBuilder sb = new StringBuilder();
525    
526                    sb.append(methodElement.elementText("name"));
527                    sb.append(StringPool.OPEN_PARENTHESIS);
528    
529                    List<Element> paramElements = methodElement.elements("param");
530    
531                    for (Element paramElement : paramElements) {
532                            sb.append(paramElement.elementText("name"));
533                            sb.append("|");
534                            sb.append(paramElement.elementText("type"));
535                            sb.append(",");
536                    }
537    
538                    sb.append(StringPool.CLOSE_PARENTHESIS);
539    
540                    return sb.toString();
541            }
542    
543            private String _getMethodKey(JavaMethod javaMethod) {
544                    StringBuilder sb = new StringBuilder();
545    
546                    sb.append(javaMethod.getName());
547                    sb.append(StringPool.OPEN_PARENTHESIS);
548    
549                    JavaParameter[] javaParameters = javaMethod.getParameters();
550    
551                    for (JavaParameter javaParameter : javaParameters) {
552                            sb.append(javaParameter.getName());
553                            sb.append("|");
554                            sb.append(javaParameter.getType().getValue());
555                            sb.append(",");
556                    }
557    
558                    sb.append(StringPool.CLOSE_PARENTHESIS);
559    
560                    return sb.toString();
561            }
562    
563            private boolean _isGenerated(String content) {
564                    if (content.contains("<javadoc autogenerated=\"true\">")) {
565                            return true;
566                    }
567                    else {
568                            return false;
569                    }
570            }
571    
572            private void _process(
573                            String command, String limit, Boolean ignoreAutogenerated)
574                    throws Exception {
575    
576                    DirectoryScanner ds = new DirectoryScanner();
577    
578                    ds.setBasedir(_basedir);
579                    ds.setExcludes(
580                            new String[] {
581                                    "**\\classes\\**", "**\\portal-client\\**", "**\\portal-web\\**"
582                            });
583    
584                    List<String> includes = new ArrayList<String>();
585    
586                    if (Validator.isNotNull(limit) && !limit.startsWith("$")) {
587                            String[] limitArray = StringUtil.split(limit, '/');
588    
589                            for (String curLimit : limitArray) {
590                                    includes.add(
591                                            "**\\" + StringUtil.replace(curLimit, ".", "\\") +
592                                                    "\\**\\*.java");
593                                    includes.add("**\\" + curLimit + ".java");
594                            }
595                    }
596                    else {
597                            includes.add("**\\*.java");
598                    }
599    
600                    ds.setIncludes(includes.toArray(new String[includes.size()]));
601    
602                    ds.scan();
603    
604                    String[] fileNames = ds.getIncludedFiles();
605    
606                    for (String fileName : fileNames) {
607                            fileName = StringUtil.replace(fileName, "\\", "/");
608    
609                            /*if (!fileName.endsWith("Isolation.java")) {
610                                    continue;
611                            }*/
612    
613                            if ((ignoreAutogenerated != null) &&
614                                    ignoreAutogenerated.booleanValue()) {
615    
616                                    File file = new File(_basedir + fileName);
617    
618                                    if (file.exists()) {
619                                            String oldContent = _fileUtil.read(
620                                                    _basedir + fileName + "doc");
621    
622                                            if (_isGenerated(oldContent)) {
623                                                    continue;
624                                            }
625                                    }
626                            }
627    
628                            if (command.equals("cleanup")) {
629                                    _processGet(fileName);
630                                    _processSave(fileName);
631                                    _processDelete(fileName);
632                            }
633                            else if (command.equals("commit")) {
634                                    _processSave(fileName);
635                                    _processDelete(fileName);
636                            }
637                            else if (command.equals("delete")) {
638                                    _processDelete(fileName);
639                            }
640                            else if (command.equals("get")) {
641                                    _processGet(fileName);
642                            }
643                            else if (command.equals("save")) {
644                                    _processSave(fileName);
645                            }
646                    }
647            }
648    
649            private void _processDelete(String fileName) throws Exception {
650                    _removeJavadocFromJava(fileName, true);
651            }
652    
653            private void _processGet(String fileName) throws Exception {
654                    File javadocFile = new File(_basedir + fileName + "doc");
655    
656                    if (!javadocFile.exists()) {
657                            _updateJavadocFromJava(fileName);
658                    }
659    
660                    String javaWithoutJavadoc = _removeJavadocFromJava(fileName, false);
661    
662                    _updateJavaFromJavadoc(fileName, javaWithoutJavadoc);
663            }
664    
665            private void _processSave(String fileName) throws Exception {
666                    _updateJavadocFromJava(fileName);
667            }
668    
669            private String _removeJavadocFromJava(String fileName, boolean log)
670                    throws Exception {
671    
672                    File file = new File(_basedir + fileName);
673    
674                    String oldContent = _fileUtil.read(file);
675    
676                    String[] lines = StringUtil.splitLines(oldContent);
677    
678                    JavaClass javaClass = _getJavaClass(
679                            fileName, new UnsyncStringReader(oldContent));
680    
681                    Set<Integer> lineNumbers = new HashSet<Integer>();
682    
683                    lineNumbers.add(javaClass.getLineNumber());
684    
685                    JavaMethod[] javaMethods = javaClass.getMethods();
686    
687                    for (JavaMethod javaMethod : javaMethods) {
688                            lineNumbers.add(javaMethod.getLineNumber());
689                    }
690    
691                    JavaField[] javaFields = javaClass.getFields();
692    
693                    for (JavaField javaField : javaFields) {
694                            lineNumbers.add(javaField.getLineNumber());
695                    }
696    
697                    for (int lineNumber : lineNumbers) {
698                            int pos = lineNumber - 2;
699    
700                            String line = lines[pos].trim();
701    
702                            if (line.endsWith("*/")) {
703                                    while (true) {
704                                            lines[pos] = null;
705    
706                                            if (line.startsWith("/**")) {
707                                                    break;
708                                            }
709    
710                                            line = lines[--pos].trim();
711                                    }
712                            }
713                    }
714    
715                    StringBuilder sb = new StringBuilder(oldContent.length());
716    
717                    for (String line : lines) {
718                            if (line != null) {
719                                    sb.append(line);
720                                    sb.append("\n");
721                            }
722                    }
723    
724                    String newContent = sb.toString().trim();
725    
726                    if ((oldContent == null) || !oldContent.equals(newContent)) {
727                            _fileUtil.write(file, newContent);
728    
729                            if (log) {
730                                    System.out.println("Writing " + file);
731                            }
732                    }
733    
734                    return newContent;
735            }
736    
737            private void _updateJavadocFromJava(String fileName) throws Exception {
738                    File file = new File(_basedir + fileName + "doc");
739    
740                    String oldContent = null;
741    
742                    if (file.exists()) {
743                            oldContent = _fileUtil.read(file);
744    
745                            if (_isGenerated(oldContent)) {
746                                    return;
747                            }
748                    }
749    
750                    JavaClass javaClass = _getJavaClass(fileName);
751    
752                    String newContent = _getJavadocXml(javaClass);
753    
754                    if ((oldContent == null) || !oldContent.equals(newContent)) {
755                            _fileUtil.write(file, newContent.getBytes());
756    
757                            System.out.println("Writing " + file);
758                    }
759            }
760    
761            private void _updateJavaFromJavadoc(String fileName, String oldContent)
762                    throws Exception {
763    
764                    File javadocFile = new File(_basedir + fileName + "doc");
765    
766                    if (!javadocFile.exists()) {
767                            return;
768                    }
769    
770                    File file = new File(_basedir + fileName);
771    
772                    if (oldContent == null) {
773                            oldContent = _fileUtil.read(file);
774                    }
775    
776                    String[] lines = StringUtil.splitLines(oldContent);
777    
778                    JavaClass javaClass = _getJavaClass(
779                            fileName, new UnsyncStringReader(oldContent));
780    
781                    Document document = _saxReaderUtil.read(javadocFile);
782    
783                    Element rootElement = document.getRootElement();
784    
785                    Map<Integer, String> commentsMap = new TreeMap<Integer, String>();
786    
787                    commentsMap.put(
788                            javaClass.getLineNumber(),
789                            _getJavaClassComment(rootElement, javaClass));
790    
791                    Map<String, Element> methodElementsMap = new HashMap<String, Element>();
792    
793                    List<Element> methodElements = rootElement.elements("method");
794    
795                    for (Element methodElement : methodElements) {
796                            String methodKey = _getMethodKey(methodElement);
797    
798                            methodElementsMap.put(methodKey, methodElement);
799                    }
800    
801                    JavaMethod[] javaMethods = javaClass.getMethods();
802    
803                    for (JavaMethod javaMethod : javaMethods) {
804                            if (commentsMap.containsKey(javaMethod.getLineNumber())) {
805                                    continue;
806                            }
807    
808                            commentsMap.put(
809                                    javaMethod.getLineNumber(),
810                                    _getJavaMethodComment(lines, methodElementsMap, javaMethod));
811                    }
812    
813                    Map<String, Element> fieldElementsMap = new HashMap<String, Element>();
814    
815                    List<Element> fieldElements = rootElement.elements("field");
816    
817                    for (Element fieldElement : fieldElements) {
818                            String fieldKey = _getFieldKey(fieldElement);
819    
820                            fieldElementsMap.put(fieldKey, fieldElement);
821                    }
822    
823                    JavaField[] javaFields = javaClass.getFields();
824    
825                    for (JavaField javaField : javaFields) {
826                            if (commentsMap.containsKey(javaField.getLineNumber())) {
827                                    continue;
828                            }
829    
830                            commentsMap.put(
831                                    javaField.getLineNumber(),
832                                    _getJavaFieldComment(lines, fieldElementsMap, javaField));
833                    }
834    
835                    StringBuilder sb = new StringBuilder(oldContent.length());
836    
837                    for (int lineNumber = 1; lineNumber <= lines.length; lineNumber++) {
838                            String line = lines[lineNumber - 1];
839    
840                            String comments = commentsMap.get(lineNumber);
841    
842                            if (comments != null) {
843                                    sb.append(comments);
844                            }
845    
846                            sb.append(line);
847                            sb.append("\n");
848                    }
849    
850                    String newContent = sb.toString().trim();
851    
852                    if ((oldContent == null) || !oldContent.equals(newContent)) {
853                            _fileUtil.write(file, newContent);
854    
855                            System.out.println("Writing " + file);
856                    }
857            }
858    
859            private static FileImpl _fileUtil = FileImpl.getInstance();
860            private static SAXReaderImpl _saxReaderUtil = SAXReaderImpl.getInstance();
861    
862            private String _basedir = "./";
863    
864    }