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