001
014
015 package com.liferay.portal.tools;
016
017 import com.liferay.portal.kernel.io.unsync.UnsyncStringReader;
018 import com.liferay.portal.kernel.util.GetterUtil;
019 import com.liferay.portal.kernel.util.StringBundler;
020 import com.liferay.portal.kernel.util.StringPool;
021 import com.liferay.portal.kernel.util.StringUtil;
022 import com.liferay.portal.kernel.util.Tuple;
023 import com.liferay.portal.kernel.util.Validator;
024 import com.liferay.portal.kernel.xml.Document;
025 import com.liferay.portal.kernel.xml.Element;
026 import com.liferay.portal.tools.servicebuilder.ServiceBuilder;
027 import com.liferay.portal.util.FileImpl;
028 import com.liferay.portal.xml.SAXReaderImpl;
029 import com.liferay.util.xml.DocUtil;
030
031 import com.thoughtworks.qdox.JavaDocBuilder;
032 import com.thoughtworks.qdox.model.AbstractBaseJavaEntity;
033 import com.thoughtworks.qdox.model.AbstractJavaEntity;
034 import com.thoughtworks.qdox.model.Annotation;
035 import com.thoughtworks.qdox.model.DocletTag;
036 import com.thoughtworks.qdox.model.JavaClass;
037 import com.thoughtworks.qdox.model.JavaField;
038 import com.thoughtworks.qdox.model.JavaMethod;
039 import com.thoughtworks.qdox.model.JavaPackage;
040 import com.thoughtworks.qdox.model.JavaParameter;
041 import com.thoughtworks.qdox.model.Type;
042
043 import jargs.gnu.CmdLineParser;
044
045 import java.io.File;
046 import java.io.FileInputStream;
047 import java.io.InputStream;
048 import java.io.Reader;
049
050 import java.util.ArrayList;
051 import java.util.Collection;
052 import java.util.HashMap;
053 import java.util.HashSet;
054 import java.util.List;
055 import java.util.Map;
056 import java.util.Set;
057 import java.util.TreeMap;
058 import java.util.regex.Matcher;
059 import java.util.regex.Pattern;
060
061 import org.apache.tools.ant.DirectoryScanner;
062
063
068 public class JavadocFormatter {
069
070 public static void main(String[] args) {
071 try {
072 new JavadocFormatter(args);
073 }
074 catch (Exception e) {
075 e.printStackTrace();
076 }
077 }
078
079 public JavadocFormatter(String[] args) throws Exception {
080 CmdLineParser cmdLineParser = new CmdLineParser();
081
082 CmdLineParser.Option limitOption = cmdLineParser.addStringOption(
083 "limit");
084 CmdLineParser.Option initOption = cmdLineParser.addStringOption(
085 "init");
086 CmdLineParser.Option updateOption = cmdLineParser.addStringOption(
087 "update");
088
089 cmdLineParser.parse(args);
090
091 String limit = (String)cmdLineParser.getOptionValue(limitOption);
092 String init = (String)cmdLineParser.getOptionValue(initOption);
093 String update = (String)cmdLineParser.getOptionValue(updateOption);
094
095 if (Validator.isNotNull(init) && !init.startsWith("$")) {
096 _initializeMissingJavadocs = GetterUtil.getBoolean(init);
097 }
098
099 if (Validator.isNotNull(update) && !update.startsWith("$")) {
100 _updateJavadocs = GetterUtil.getBoolean(update);
101 }
102
103 DirectoryScanner ds = new DirectoryScanner();
104
105 ds.setBasedir(_basedir);
106 ds.setExcludes(
107 new String[] {"**\\classes\\**", "**\\portal-client\\**"});
108
109 List<String> includes = new ArrayList<String>();
110
111 if (Validator.isNotNull(limit) && !limit.startsWith("$")) {
112 System.out.println("Limit on " + limit);
113
114 String[] limitArray = StringUtil.split(limit, '/');
115
116 for (String curLimit : limitArray) {
117 includes.add(
118 "**\\" + StringUtil.replace(curLimit, ".", "\\") +
119 "\\**\\*.java");
120 includes.add("**\\" + curLimit + ".java");
121 }
122 }
123 else {
124 includes.add("**\\*.java");
125 }
126
127 ds.setIncludes(includes.toArray(new String[includes.size()]));
128
129 ds.scan();
130
131 String[] fileNames = ds.getIncludedFiles();
132
133 if ((fileNames.length == 0) && Validator.isNotNull(limit) &&
134 !limit.startsWith("$")) {
135
136 StringBundler sb = new StringBundler("Limit file not found: ");
137
138 sb.append(limit);
139
140 if (limit.contains(".")) {
141 sb.append(" Specify limit filename without package path or ");
142 sb.append("file type suffix.");
143 }
144
145 System.out.println(sb.toString());
146 }
147
148 for (String fileName : fileNames) {
149 fileName = StringUtil.replace(fileName, "\\", "/");
150
151 _format(fileName);
152 }
153
154 for (Map.Entry<String, Tuple> entry : _javadocxXmlTuples.entrySet()) {
155 Tuple javadocsXmlTuple = entry.getValue();
156
157 File javadocsXmlFile = (File)javadocsXmlTuple.getObject(1);
158 String oldJavadocsXmlContent =
159 (String)javadocsXmlTuple.getObject(2);
160 Document javadocsXmlDocument =
161 (Document)javadocsXmlTuple.getObject(3);
162
163 Element javadocsXmlRootElement =
164 javadocsXmlDocument.getRootElement();
165
166 javadocsXmlRootElement.sortElementsByChildElement(
167 "javadoc", "type");
168
169 String newJavadocsXmlContent =
170 javadocsXmlDocument.formattedString();
171
172 if (!oldJavadocsXmlContent.equals(newJavadocsXmlContent)) {
173 _fileUtil.write(javadocsXmlFile, newJavadocsXmlContent);
174 }
175 }
176 }
177
178 private void _addClassCommentElement(
179 Element rootElement, JavaClass javaClass) {
180
181 Element commentElement = rootElement.addElement("comment");
182
183 String comment = _getCDATA(javaClass);
184
185 if (comment.startsWith("Copyright (c) 2000-2010 Liferay, Inc.")) {
186 comment = StringPool.BLANK;
187 }
188
189 commentElement.addCDATA(comment);
190 }
191
192 private void _addDocletElements(
193 Element parentElement, AbstractJavaEntity abstractJavaEntity,
194 String name)
195 throws Exception {
196
197 DocletTag[] docletTags = abstractJavaEntity.getTagsByName(name);
198
199 for (DocletTag docletTag : docletTags) {
200 String value = docletTag.getValue();
201
202 value = _trimMultilineText(value);
203
204 value = StringUtil.replace(value, " </", "</");
205
206 Element element = parentElement.addElement(name);
207
208 element.addCDATA(value);
209 }
210
211 if ((docletTags.length == 0) && name.equals("author")) {
212 Element element = parentElement.addElement(name);
213
214 element.addCDATA(ServiceBuilder.AUTHOR);
215 }
216 }
217
218 private String _addDocletTags(
219 Element parentElement, String[] names, String indent,
220 boolean publicAccess) {
221
222 StringBundler sb = new StringBundler();
223
224 int maxNameLength = 0;
225
226 for (String name : names) {
227 if (name.length() < maxNameLength) {
228 continue;
229 }
230
231 List<Element> elements = parentElement.elements(name);
232
233 for (Element element : elements) {
234 Element commentElement = element.element("comment");
235
236 String comment = null;
237
238 if (commentElement != null) {
239 comment = commentElement.getText();
240 }
241 else {
242 comment = element.getText();
243 }
244
245 if (!name.equals("deprecated") && !_initializeMissingJavadocs &&
246 Validator.isNull(comment)) {
247
248 continue;
249 }
250
251 maxNameLength = name.length();
252
253 break;
254 }
255 }
256
257
258
259 maxNameLength += 2;
260
261 String nameIndent = _getSpacesIndent(maxNameLength);
262
263 boolean hasComments = false;
264
265 for (String name : names) {
266 List<Element> elements = parentElement.elements(name);
267
268 for (Element element : elements) {
269 Element commentElement = element.element("comment");
270
271 String comment = null;
272
273 if (commentElement != null) {
274 comment = commentElement.getText();
275 }
276 else {
277 comment = element.getText();
278 }
279
280 if (Validator.isNotNull(comment)) {
281 hasComments = true;
282 }
283
284 if (!name.equals("deprecated") && !_initializeMissingJavadocs &&
285 !_updateJavadocs && Validator.isNull(comment)) {
286
287 continue;
288 }
289
290 if (commentElement != null) {
291 String elementName = element.elementText("name");
292
293 if (Validator.isNotNull(elementName)) {
294 if (Validator.isNotNull(comment)) {
295 comment = elementName + " " + comment;
296 }
297 else {
298 comment = elementName;
299 }
300 }
301 }
302
303 if (Validator.isNull(comment)) {
304 sb.append(indent);
305 sb.append(StringPool.AT);
306 sb.append(name);
307 sb.append(StringPool.NEW_LINE);
308 }
309 else {
310 comment = _wrapText(comment, indent + nameIndent);
311
312 String firstLine = indent + "@" + name;
313
314 comment = firstLine + comment.substring(firstLine.length());
315
316 sb.append(comment);
317 }
318 }
319 }
320
321 if (!publicAccess && !hasComments) {
322 return null;
323 }
324
325 if (!_initializeMissingJavadocs && !hasComments) {
326 return null;
327 }
328
329 return sb.toString();
330 }
331
332 private void _addFieldElement(Element rootElement, JavaField javaField)
333 throws Exception {
334
335 Element fieldElement = rootElement.addElement("field");
336
337 DocUtil.add(fieldElement, "name", javaField.getName());
338
339 Element commentElement = fieldElement.addElement("comment");
340
341 commentElement.addCDATA(_getCDATA(javaField));
342
343 _addDocletElements(fieldElement, javaField, "version");
344 _addDocletElements(fieldElement, javaField, "see");
345 _addDocletElements(fieldElement, javaField, "since");
346 _addDocletElements(fieldElement, javaField, "deprecated");
347 }
348
349 private void _addMethodElement(Element rootElement, JavaMethod javaMethod)
350 throws Exception {
351
352 Element methodElement = rootElement.addElement("method");
353
354 DocUtil.add(methodElement, "name", javaMethod.getName());
355
356 Element commentElement = methodElement.addElement("comment");
357
358 commentElement.addCDATA(_getCDATA(javaMethod));
359
360 _addDocletElements(methodElement, javaMethod, "version");
361 _addParamElements(methodElement, javaMethod);
362 _addReturnElement(methodElement, javaMethod);
363 _addThrowsElements(methodElement, javaMethod);
364 _addDocletElements(methodElement, javaMethod, "see");
365 _addDocletElements(methodElement, javaMethod, "since");
366 _addDocletElements(methodElement, javaMethod, "deprecated");
367 }
368
369 private void _addParamElement(
370 Element methodElement, JavaParameter javaParameter,
371 DocletTag[] paramDocletTags) {
372
373 String name = javaParameter.getName();
374
375 String value = null;
376
377 for (DocletTag paramDocletTag : paramDocletTags) {
378 String curValue = paramDocletTag.getValue();
379
380 if (!curValue.startsWith(name)) {
381 continue;
382 }
383 else {
384 value = curValue;
385
386 break;
387 }
388 }
389
390 Element paramElement = methodElement.addElement("param");
391
392 DocUtil.add(paramElement, "name", name);
393 DocUtil.add(paramElement, "type", _getTypeValue(javaParameter));
394
395 if (value != null) {
396 value = value.substring(name.length());
397 }
398
399 value = _trimMultilineText(value);
400
401 Element commentElement = paramElement.addElement("comment");
402
403 commentElement.addCDATA(value);
404 }
405
406 private void _addParamElements(
407 Element methodElement, JavaMethod javaMethod) {
408
409 JavaParameter[] javaParameters = javaMethod.getParameters();
410
411 DocletTag[] paramDocletTags = javaMethod.getTagsByName("param");
412
413 for (JavaParameter javaParameter : javaParameters) {
414 _addParamElement(methodElement, javaParameter, paramDocletTags);
415 }
416 }
417
418 private void _addReturnElement(
419 Element methodElement, JavaMethod javaMethod)
420 throws Exception {
421
422 Type returns = javaMethod.getReturns();
423
424 if (returns == null) {
425 return;
426 }
427
428 String returnsValue = returns.getValue();
429
430 if (returnsValue.equals("void")) {
431 return;
432 }
433
434 Element returnElement = methodElement.addElement("return");
435
436 Element commentElement = returnElement.addElement("comment");
437
438 DocletTag[] returnDocletTags = javaMethod.getTagsByName("return");
439
440 String comment = StringPool.BLANK;
441
442 if (returnDocletTags.length > 0) {
443 DocletTag returnDocletTag = returnDocletTags[0];
444
445 comment = GetterUtil.getString(returnDocletTag.getValue());
446 }
447
448 comment = _trimMultilineText(comment);
449
450 commentElement.addCDATA(comment);
451 }
452
453 private void _addThrowsElement(
454 Element methodElement, Type exceptionType,
455 DocletTag[] throwsDocletTags) {
456
457 JavaClass javaClass = exceptionType.getJavaClass();
458
459 String name = javaClass.getName();
460
461 String value = null;
462
463 for (DocletTag throwsDocletTag : throwsDocletTags) {
464 String curValue = throwsDocletTag.getValue();
465
466 if (!curValue.startsWith(name)) {
467 continue;
468 }
469 else {
470 value = curValue;
471
472 break;
473 }
474 }
475
476 Element throwsElement = methodElement.addElement("throws");
477
478 DocUtil.add(throwsElement, "name", name);
479 DocUtil.add(throwsElement, "type", exceptionType.getValue());
480
481 if (value != null) {
482 value = value.substring(name.length());
483 }
484
485 value = _trimMultilineText(value);
486
487 Element commentElement = throwsElement.addElement("comment");
488
489 commentElement.addCDATA(_getCDATA(value));
490
491 }
492
493 private void _addThrowsElements(
494 Element methodElement, JavaMethod javaMethod) {
495
496 Type[] exceptionTypes = javaMethod.getExceptions();
497
498 DocletTag[] throwsDocletTags = javaMethod.getTagsByName("throws");
499
500 for (Type exceptionType : exceptionTypes) {
501 _addThrowsElement(methodElement, exceptionType, throwsDocletTags);
502 }
503 }
504
505 private void _format(String fileName) throws Exception {
506 InputStream inputStream = new FileInputStream(_basedir + fileName);
507
508 byte[] bytes = new byte[inputStream.available()];
509
510 inputStream.read(bytes);
511
512 inputStream.close();
513
514 String originalContent = new String(bytes, StringPool.UTF8);
515
516 if (fileName.endsWith("JavadocFormatter.java") ||
517 fileName.endsWith("SourceFormatter.java") ||
518 _isGenerated(originalContent)) {
519
520 return;
521 }
522
523 JavaClass javaClass = _getJavaClass(
524 fileName, new UnsyncStringReader(originalContent));
525
526 String javadocLessContent = _removeJavadocFromJava(
527 javaClass, originalContent);
528
529 Document document = _getJavadocDocument(javaClass);
530
531 _updateJavadocsXmlFile(fileName, javaClass, document);
532
533 _updateJavaFromDocument(
534 fileName, originalContent, javadocLessContent, document);
535 }
536
537 private String _formatInlines(String text) {
538
539
540
541 text = text.replaceAll("(?i)\\bid(s)?\\b", "ID$1");
542
543
544
545 text = text.replaceAll(
546 "(?i)(?<!<code>|\\w)(null|false|true)(?!\\w)", "<code>$1</code>");
547
548 return text;
549 }
550
551 private List<JavaClass> _getAncestorJavaClasses(JavaClass javaClass) {
552 List<JavaClass> ancestorJavaClasses = new ArrayList<JavaClass>();
553
554 while ((javaClass = javaClass.getSuperJavaClass()) != null) {
555 ancestorJavaClasses.add(javaClass);
556 }
557
558 return ancestorJavaClasses;
559 }
560
561 private String _getCDATA(AbstractJavaEntity abstractJavaEntity) {
562 return _getCDATA(abstractJavaEntity.getComment());
563 }
564
565 private String _getCDATA(String cdata) {
566 if (cdata == null) {
567 return StringPool.BLANK;
568 }
569
570 cdata = cdata.replaceAll(
571 "(?s)\\s*<(p|pre|[ou]l)>\\s*(.*?)\\s*</\\1>\\s*",
572 "\n\n<$1>\n$2\n</$1>\n\n");
573 cdata = cdata.replaceAll(
574 "(?s)\\s*<li>\\s*(.*?)\\s*</li>\\s*", "\n<li>\n$1\n</li>\n");
575 cdata = StringUtil.replace(cdata, "</li>\n\n<li>", "</li>\n<li>");
576 cdata = cdata.replaceAll("\n\\s+\n", "\n\n");
577 cdata = cdata.replaceAll(" +", " ");
578
579
580
581 Pattern pattern = Pattern.compile(
582 "(^.*?(?=\n\n|$)+|(?<=<p>\n).*?(?=\n</p>))", Pattern.DOTALL);
583
584 Matcher matcher = pattern.matcher(cdata);
585
586 StringBuffer sb = new StringBuffer();
587
588 while (matcher.find()) {
589 String trimmed = _trimMultilineText(matcher.group());
590
591
592
593 trimmed = trimmed.replaceAll("\\$", "\\\\\\$");
594
595 matcher.appendReplacement(sb, trimmed);
596 }
597
598 matcher.appendTail(sb);
599
600 cdata = sb.toString();
601
602 return cdata.trim();
603 }
604
605 private String _getClassName(String fileName) {
606 int pos = fileName.indexOf("src/");
607
608 if (pos == -1) {
609 pos = fileName.indexOf("test/");
610 }
611
612 if (pos == -1) {
613 pos = fileName.indexOf("service/");
614 }
615
616 if (pos == -1) {
617 throw new RuntimeException(fileName);
618 }
619
620 pos = fileName.indexOf("/", pos);
621
622 String srcFile = fileName.substring(pos + 1, fileName.length());
623
624 return StringUtil.replace(
625 srcFile.substring(0, srcFile.length() - 5), "/", ".");
626 }
627
628 private String _getFieldKey(Element fieldElement) {
629 return fieldElement.elementText("name");
630 }
631
632 private String _getFieldKey(JavaField javaField) {
633 return javaField.getName();
634 }
635
636 private String _getIndent(
637 String[] lines, AbstractBaseJavaEntity abstractBaseJavaEntity) {
638
639 String line = lines[abstractBaseJavaEntity.getLineNumber() - 1];
640
641 String indent = StringPool.BLANK;
642
643 for (char c : line.toCharArray()) {
644 if (Character.isWhitespace(c)) {
645 indent += c;
646 }
647 else {
648 break;
649 }
650 }
651
652 return indent;
653 }
654
655 private int _getIndentLength(String indent) {
656 int indentLength = 0;
657
658 for (char c : indent.toCharArray()) {
659 if (c == '\t') {
660 indentLength = indentLength + 4;
661 }
662 else {
663 indentLength++;
664 }
665 }
666
667 return indentLength;
668 }
669
670 private JavaClass _getJavaClass(String fileName, Reader reader)
671 throws Exception {
672
673 String className = _getClassName(fileName);
674
675 JavaDocBuilder javadocBuilder = new JavaDocBuilder();
676
677 if (reader == null) {
678 File file = new File(fileName);
679
680 if (!file.exists()) {
681 return null;
682 }
683
684 javadocBuilder.addSource(file);
685 }
686 else {
687 javadocBuilder.addSource(reader);
688 }
689
690 return javadocBuilder.getClassByName(className);
691 }
692
693 private String _getJavaClassComment(
694 Element rootElement, JavaClass javaClass) {
695
696 StringBundler sb = new StringBundler();
697
698 String indent = StringPool.BLANK;
699
700 sb.append("\n");
724
725 return sb.toString();
726 }
727
728 private int _getJavaClassLineNumber(JavaClass javaClass) {
729 int lineNumber = javaClass.getLineNumber();
730
731 Annotation[] annotations = javaClass.getAnnotations();
732
733 if (annotations.length == 0) {
734 return lineNumber;
735 }
736
737 for (Annotation annotation : annotations) {
738 int annotationLineNumber = annotation.getLineNumber();
739
740 Map<String, String> propertyMap = annotation.getPropertyMap();
741
742 if (propertyMap.isEmpty()) {
743 annotationLineNumber--;
744 }
745
746 if (annotationLineNumber < lineNumber) {
747 lineNumber = annotationLineNumber;
748 }
749 }
750
751 return lineNumber;
752 }
753
754 private Document _getJavadocDocument(JavaClass javaClass) throws Exception {
755 Element rootElement = _saxReaderUtil.createElement("javadoc");
756
757 Document document = _saxReaderUtil.createDocument(rootElement);
758
759 DocUtil.add(rootElement, "name", javaClass.getName());
760 DocUtil.add(rootElement, "type", javaClass.getFullyQualifiedName());
761
762 _addClassCommentElement(rootElement, javaClass);
763 _addDocletElements(rootElement, javaClass, "author");
764 _addDocletElements(rootElement, javaClass, "version");
765 _addDocletElements(rootElement, javaClass, "see");
766 _addDocletElements(rootElement, javaClass, "since");
767 _addDocletElements(rootElement, javaClass, "serial");
768 _addDocletElements(rootElement, javaClass, "deprecated");
769
770 JavaMethod[] javaMethods = javaClass.getMethods();
771
772 for (JavaMethod javaMethod : javaMethods) {
773 _addMethodElement(rootElement, javaMethod);
774 }
775
776 JavaField[] javaFields = javaClass.getFields();
777
778 for (JavaField javaField : javaFields) {
779 _addFieldElement(rootElement, javaField);
780 }
781
782 return document;
783 }
784
785 private Tuple _getJavadocsXmlTuple(String fileName) throws Exception {
786 File file = new File(fileName);
787
788 String absolutePath = file.getAbsolutePath();
789
790 absolutePath = StringUtil.replace(absolutePath, "\\", "/");
791
792 int pos = absolutePath.indexOf("/portal-impl/src/");
793
794 String srcDirName = null;
795
796 if (pos != -1) {
797 srcDirName = absolutePath.substring(0, pos + 17);
798 }
799 else {
800 pos = absolutePath.indexOf("/WEB-INF/src/");
801
802 if (pos != -1) {
803 srcDirName = absolutePath.substring(0, pos + 13);
804 }
805 }
806
807 if (srcDirName == null) {
808 return null;
809 }
810
811 Tuple tuple = _javadocxXmlTuples.get(srcDirName);
812
813 if (tuple != null) {
814 return tuple;
815 }
816
817 File javadocsXmlFile = new File(srcDirName, "META-INF/javadocs.xml");
818
819 if (!javadocsXmlFile.exists()) {
820 _fileUtil.write(
821 javadocsXmlFile,
822 "<?xml version=\"1.0\"?>\n\n<javadocs>\n</javadocs>");
823 }
824
825 String javadocsXmlContent = _fileUtil.read(javadocsXmlFile);
826
827 Document javadocsXmlDocument = _saxReaderUtil.read(javadocsXmlContent);
828
829 tuple = new Tuple(
830 srcDirName, javadocsXmlFile, javadocsXmlContent,
831 javadocsXmlDocument);
832
833 _javadocxXmlTuples.put(srcDirName, tuple);
834
835 return tuple;
836 }
837
838 private String _getJavaFieldComment(
839 String[] lines, Map<String, Element> fieldElementsMap,
840 JavaField javaField) {
841
842 String fieldKey = _getFieldKey(javaField);
843
844 Element fieldElement = fieldElementsMap.get(fieldKey);
845
846 if (fieldElement == null) {
847 return null;
848 }
849
850 String indent = _getIndent(lines, javaField);
851
852 StringBundler sb = new StringBundler();
853
854 sb.append(indent);
855 sb.append("\n");
879
880 if (!_initializeMissingJavadocs && Validator.isNull(comment) &&
881 Validator.isNull(docletTags)) {
882
883 return null;
884 }
885
886 if (!_hasPublicModifier(javaField) && Validator.isNull(comment) &&
887 Validator.isNull(docletTags)) {
888
889 return null;
890 }
891
892 return sb.toString();
893 }
894
895 private String _getJavaMethodComment(
896 String[] lines, Map<String, Element> methodElementsMap,
897 JavaMethod javaMethod) {
898
899 String methodKey = _getMethodKey(javaMethod);
900
901 Element methodElement = methodElementsMap.get(methodKey);
902
903 if (methodElement == null) {
904 return null;
905 }
906
907 String indent = _getIndent(lines, javaMethod);
908
909 StringBundler sb = new StringBundler();
910
911 sb.append(indent);
912 sb.append("\n");
939
940 if (!_initializeMissingJavadocs && Validator.isNull(comment) &&
941 Validator.isNull(docletTags)) {
942
943 return null;
944 }
945
946 if (!_hasPublicModifier(javaMethod) && Validator.isNull(comment) &&
947 Validator.isNull(docletTags)) {
948
949 return null;
950 }
951
952 return sb.toString();
953 }
954
955 private String _getMethodKey(Element methodElement) {
956 StringBundler sb = new StringBundler();
957
958 sb.append(methodElement.elementText("name"));
959 sb.append("(");
960
961 List<Element> paramElements = methodElement.elements("param");
962
963 for (Element paramElement : paramElements) {
964 sb.append(paramElement.elementText("name"));
965 sb.append("|");
966 sb.append(paramElement.elementText("type"));
967 sb.append(",");
968 }
969
970 sb.append(")");
971
972 return sb.toString();
973 }
974
975 private String _getMethodKey(JavaMethod javaMethod) {
976 StringBundler sb = new StringBundler();
977
978 sb.append(javaMethod.getName());
979 sb.append("(");
980
981 JavaParameter[] javaParameters = javaMethod.getParameters();
982
983 for (JavaParameter javaParameter : javaParameters) {
984 sb.append(javaParameter.getName());
985 sb.append("|");
986 sb.append(_getTypeValue(javaParameter));
987 sb.append(",");
988 }
989
990 sb.append(")");
991
992 return sb.toString();
993 }
994
995 private String _getSpacesIndent(int length) {
996 String indent = StringPool.BLANK;
997
998 for (int i = 0; i < length; i++) {
999 indent += StringPool.SPACE;
1000 }
1001
1002 return indent;
1003 }
1004
1005 private String _getTypeValue(JavaParameter javaParameter) {
1006 Type type = javaParameter.getType();
1007
1008 String typeValue = type.getValue();
1009
1010 if (type.isArray()) {
1011 typeValue += "[]";
1012 }
1013
1014 return typeValue;
1015 }
1016
1017 private boolean _hasAnnotation(
1018 AbstractBaseJavaEntity abstractBaseJavaEntity, String annotationName) {
1019
1020 Annotation[] annotations = abstractBaseJavaEntity.getAnnotations();
1021
1022 if (annotations == null) {
1023 return false;
1024 }
1025
1026 for (int i = 0; i < annotations.length; i++) {
1027 Type type = annotations[i].getType();
1028
1029 JavaClass javaClass = type.getJavaClass();
1030
1031 if (annotationName.equals(javaClass.getName())) {
1032 return true;
1033 }
1034 }
1035
1036 return false;
1037 }
1038
1039 private boolean _isGenerated(String content) {
1040 if (content.contains("* @generated") || content.contains("$ANTLR")) {
1041 return true;
1042 }
1043 else {
1044 return false;
1045 }
1046 }
1047
1048 private boolean _hasPublicModifier(AbstractJavaEntity abstractJavaEntity) {
1049 String[] modifiers = abstractJavaEntity.getModifiers();
1050
1051 if (modifiers == null) {
1052 return false;
1053 }
1054
1055 for (String modifier : modifiers) {
1056 if (modifier.equals("public")) {
1057 return true;
1058 }
1059 }
1060
1061 return false;
1062 }
1063
1064 private boolean _isOverrideMethod(
1065 JavaClass javaClass, JavaMethod javaMethod,
1066 Collection<JavaClass> ancestorJavaClasses) {
1067
1068 if (javaClass.isInterface() || javaMethod.isConstructor() ||
1069 javaMethod.isPrivate() || javaMethod.isStatic()) {
1070
1071 return false;
1072 }
1073
1074 String methodName = javaMethod.getName();
1075
1076 JavaParameter[] javaParameters = javaMethod.getParameters();
1077
1078 Type[] types = new Type[javaParameters.length];
1079
1080 for (int i = 0; i < javaParameters.length; i++) {
1081 types[i] = javaParameters[i].getType();
1082 }
1083
1084
1085
1086 for (JavaClass ancestorJavaClass : ancestorJavaClasses) {
1087 JavaMethod ancestorJavaMethod =
1088 ancestorJavaClass.getMethodBySignature(methodName, types);
1089
1090 if (ancestorJavaMethod == null) {
1091 continue;
1092 }
1093
1094 boolean samePackage = false;
1095
1096 JavaPackage ancestorJavaPackage = ancestorJavaClass.getPackage();
1097
1098 if (ancestorJavaPackage != null) {
1099 samePackage = ancestorJavaPackage.equals(
1100 javaClass.getPackage());
1101 }
1102
1103
1104
1105 if (samePackage) {
1106 return !ancestorJavaMethod.isPrivate();
1107 }
1108 else {
1109 if (ancestorJavaMethod.isProtected() ||
1110 ancestorJavaMethod.isPublic()) {
1111
1112 return true;
1113 }
1114 else {
1115 return false;
1116 }
1117 }
1118 }
1119
1120 return false;
1121 }
1122
1123 private String _removeJavadocFromJava(
1124 JavaClass javaClass, String content) {
1125
1126 Set<Integer> lineNumbers = new HashSet<Integer>();
1127
1128 lineNumbers.add(_getJavaClassLineNumber(javaClass));
1129
1130 JavaMethod[] javaMethods = javaClass.getMethods();
1131
1132 for (JavaMethod javaMethod : javaMethods) {
1133 lineNumbers.add(javaMethod.getLineNumber());
1134 }
1135
1136 JavaField[] javaFields = javaClass.getFields();
1137
1138 for (JavaField javaField : javaFields) {
1139 lineNumbers.add(javaField.getLineNumber());
1140 }
1141
1142 String[] lines = StringUtil.splitLines(content);
1143
1144 for (int lineNumber : lineNumbers) {
1145 if (lineNumber == 0) {
1146 continue;
1147 }
1148
1149 int pos = lineNumber - 2;
1150
1151 String line = lines[pos];
1152
1153 if (line == null) {
1154 continue;
1155 }
1156
1157 line = line.trim();
1158
1159 if (line.endsWith("*/")) {
1160 while (true) {
1161 lines[pos] = null;
1162
1163 if (line.startsWith("