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