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.sourceformatter; 016 017 import com.liferay.portal.kernel.io.unsync.UnsyncBufferedReader; 018 import com.liferay.portal.kernel.io.unsync.UnsyncStringReader; 019 import com.liferay.portal.kernel.util.StringPool; 020 import com.liferay.portal.kernel.util.StringUtil; 021 import com.liferay.portal.kernel.util.Tuple; 022 import com.liferay.portal.kernel.util.Validator; 023 024 import java.util.ArrayList; 025 import java.util.Iterator; 026 import java.util.List; 027 import java.util.Set; 028 import java.util.TreeSet; 029 import java.util.regex.Matcher; 030 import java.util.regex.Pattern; 031 032 /** 033 * @author Hugo Huijser 034 */ 035 public class JavaClass { 036 037 public static final int[] TYPE_CLASS = { 038 JavaClass.TYPE_CLASS_PRIVATE, JavaClass.TYPE_CLASS_PRIVATE_STATIC, 039 JavaClass.TYPE_CLASS_PROTECTED, JavaClass.TYPE_CLASS_PROTECTED_STATIC, 040 JavaClass.TYPE_CLASS_PUBLIC, JavaClass.TYPE_CLASS_PUBLIC_STATIC 041 }; 042 043 public static final int TYPE_CLASS_PRIVATE = 24; 044 045 public static final int TYPE_CLASS_PRIVATE_STATIC = 23; 046 047 public static final int TYPE_CLASS_PROTECTED = 16; 048 049 public static final int TYPE_CLASS_PROTECTED_STATIC = 15; 050 051 public static final int TYPE_CLASS_PUBLIC = 8; 052 053 public static final int TYPE_CLASS_PUBLIC_STATIC = 7; 054 055 public static final int[] TYPE_CONSTRUCTOR = { 056 JavaClass.TYPE_CONSTRUCTOR_PRIVATE, 057 JavaClass.TYPE_CONSTRUCTOR_PROTECTED, JavaClass.TYPE_CONSTRUCTOR_PUBLIC 058 }; 059 060 public static final int TYPE_CONSTRUCTOR_PRIVATE = 18; 061 062 public static final int TYPE_CONSTRUCTOR_PROTECTED = 10; 063 064 public static final int TYPE_CONSTRUCTOR_PUBLIC = 4; 065 066 public static final int[] TYPE_METHOD = { 067 JavaClass.TYPE_METHOD_PRIVATE, JavaClass.TYPE_METHOD_PRIVATE_STATIC, 068 JavaClass.TYPE_METHOD_PROTECTED, JavaClass.TYPE_METHOD_PROTECTED_STATIC, 069 JavaClass.TYPE_METHOD_PUBLIC, JavaClass.TYPE_METHOD_PUBLIC_STATIC 070 }; 071 072 public static final int TYPE_METHOD_PRIVATE = 19; 073 074 public static final int TYPE_METHOD_PRIVATE_STATIC = 17; 075 076 public static final int TYPE_METHOD_PROTECTED = 11; 077 078 public static final int TYPE_METHOD_PROTECTED_STATIC = 9; 079 080 public static final int TYPE_METHOD_PUBLIC = 5; 081 082 public static final int TYPE_METHOD_PUBLIC_STATIC = 3; 083 084 public static final int TYPE_STATIC_BLOCK = 21; 085 086 public static final int[] TYPE_VARIABLE = { 087 JavaClass.TYPE_VARIABLE_PRIVATE, JavaClass.TYPE_VARIABLE_PRIVATE_STATIC, 088 JavaClass.TYPE_VARIABLE_PROTECTED, 089 JavaClass.TYPE_VARIABLE_PROTECTED_STATIC, 090 JavaClass.TYPE_VARIABLE_PUBLIC, JavaClass.TYPE_VARIABLE_PUBLIC_STATIC, 091 }; 092 093 public static final int TYPE_VARIABLE_PRIVATE = 22; 094 095 public static final int TYPE_VARIABLE_PRIVATE_STATIC = 20; 096 097 public static final int TYPE_VARIABLE_PROTECTED = 14; 098 099 public static final int TYPE_VARIABLE_PROTECTED_STATIC = 12; 100 101 public static final int TYPE_VARIABLE_PUBLIC = 6; 102 103 public static final int TYPE_VARIABLE_PUBLIC_STATIC = 1; 104 105 public static final int[] TYPE_VARIABLE_STATIC = { 106 JavaClass.TYPE_VARIABLE_PRIVATE_STATIC, 107 JavaClass.TYPE_VARIABLE_PROTECTED_STATIC, 108 JavaClass.TYPE_VARIABLE_PUBLIC_STATIC 109 }; 110 111 public JavaClass( 112 String fileName, String absolutePath, String content, int lineCount, 113 String indent) 114 throws Exception { 115 116 _fileName = fileName; 117 _absolutePath = absolutePath; 118 _content = content; 119 _lineCount = lineCount; 120 _indent = indent; 121 122 _staticBlocks = new ArrayList<JavaTerm>(); 123 } 124 125 public String formatJavaTerms( 126 List<String> javaTermAccessLevelModifierExclusions, 127 List<String> javaTermSortExclusions, 128 List<String> testAnnotationsExclusions) 129 throws Exception { 130 131 Set<JavaTerm> javaTerms = getJavaTerms( 132 javaTermAccessLevelModifierExclusions); 133 134 if (javaTerms == null) { 135 return _content; 136 } 137 138 String originalContent = _content; 139 140 javaTerms = addStaticBlocks(javaTerms); 141 142 if (!originalContent.equals(_content)) { 143 return _content; 144 } 145 146 JavaTerm previousJavaTerm = null; 147 148 Iterator<JavaTerm> itr = javaTerms.iterator(); 149 150 while (itr.hasNext()) { 151 JavaTerm javaTerm = itr.next(); 152 153 if (isInJavaTermTypeGroup(javaTerm.getType(), TYPE_CLASS)) { 154 String javaTermContent = javaTerm.getContent(); 155 156 int pos = javaTermContent.indexOf("\n" + _indent + "static {"); 157 158 if (pos != -1) { 159 javaTermContent = javaTermContent.substring(0, pos); 160 } 161 162 JavaClass innerClass = new JavaClass( 163 _fileName, _absolutePath, javaTermContent, 164 javaTerm.getLineCount(), _indent + StringPool.TAB); 165 166 String newJavaTermContent = innerClass.formatJavaTerms( 167 javaTermAccessLevelModifierExclusions, 168 javaTermSortExclusions, testAnnotationsExclusions); 169 170 if (!javaTermContent.equals(newJavaTermContent)) { 171 _content = StringUtil.replace( 172 _content, javaTermContent, newJavaTermContent); 173 174 return _content; 175 } 176 } 177 178 sortJavaTerms(previousJavaTerm, javaTerm, javaTermSortExclusions); 179 fixTabsAndIncorrectEmptyLines(javaTerm); 180 formatAnnotations(javaTerm, testAnnotationsExclusions); 181 182 if (!originalContent.equals(_content)) { 183 return _content; 184 } 185 186 previousJavaTerm = javaTerm; 187 } 188 189 fixJavaTermsDividers(javaTerms, javaTermSortExclusions); 190 191 return _content; 192 } 193 194 protected static boolean isInJavaTermTypeGroup( 195 int javaTermType, int[] javaTermTypeGroup) { 196 197 for (int type : javaTermTypeGroup) { 198 if (javaTermType == type) { 199 return true; 200 } 201 } 202 203 return false; 204 } 205 206 protected Set<JavaTerm> addStaticBlocks(Set<JavaTerm> javaTerms) { 207 Set<JavaTerm> newJavaTerms = new TreeSet<JavaTerm>( 208 new JavaTermComparator()); 209 210 Iterator<JavaTerm> javaTermsIterator = javaTerms.iterator(); 211 212 while (javaTermsIterator.hasNext()) { 213 JavaTerm javaTerm = javaTermsIterator.next(); 214 215 if (!isInJavaTermTypeGroup( 216 javaTerm.getType(), TYPE_VARIABLE_STATIC)) { 217 218 newJavaTerms.add(javaTerm); 219 220 continue; 221 } 222 223 Iterator<JavaTerm> staticBlocksIterator = _staticBlocks.iterator(); 224 225 while (staticBlocksIterator.hasNext()) { 226 JavaTerm staticBlock = staticBlocksIterator.next(); 227 228 String staticBlockContent = staticBlock.getContent(); 229 230 if (staticBlockContent.contains(javaTerm.getName())) { 231 staticBlock.setType(javaTerm.getType() + 1); 232 233 newJavaTerms.add(staticBlock); 234 235 staticBlocksIterator.remove(); 236 } 237 } 238 239 newJavaTerms.add(javaTerm); 240 } 241 242 if (!_staticBlocks.isEmpty()) { 243 newJavaTerms.addAll(_staticBlocks); 244 } 245 246 return newJavaTerms; 247 } 248 249 protected void checkAnnotationForMethod( 250 JavaTerm javaTerm, String annotation, String requiredMethodNameRegex, 251 int requiredMethodType, String fileName) { 252 253 String methodContent = javaTerm.getContent(); 254 String methodName = javaTerm.getName(); 255 256 Pattern pattern = Pattern.compile(requiredMethodNameRegex); 257 258 Matcher matcher = pattern.matcher(methodName); 259 260 if (methodContent.contains( 261 _indent + StringPool.AT + annotation + "\n") || 262 methodContent.contains( 263 _indent + StringPool.AT + annotation + 264 StringPool.OPEN_PARENTHESIS)) { 265 266 if (!matcher.find()) { 267 BaseSourceProcessor.processErrorMessage( 268 fileName, 269 "LPS-36303: Incorrect method name: " + methodName + " " + 270 fileName); 271 } 272 else if (javaTerm.getType() != requiredMethodType) { 273 BaseSourceProcessor.processErrorMessage( 274 fileName, 275 "LPS-36303: Incorrect method type for " + methodName + " " + 276 fileName); 277 } 278 } 279 else if (matcher.find() && 280 !methodContent.contains(_indent + "@Override")) { 281 282 BaseSourceProcessor.processErrorMessage( 283 fileName, 284 "Annotation @" + annotation + " required for " + methodName + 285 " " + fileName); 286 } 287 } 288 289 protected void checkTestAnnotations(JavaTerm javaTerm) { 290 int methodType = javaTerm.getType(); 291 292 if ((methodType != TYPE_METHOD_PUBLIC) && 293 (methodType != TYPE_METHOD_PUBLIC_STATIC)) { 294 295 return; 296 } 297 298 checkAnnotationForMethod( 299 javaTerm, "After", "^.*tearDown\\z", TYPE_METHOD_PUBLIC, _fileName); 300 checkAnnotationForMethod( 301 javaTerm, "AfterClass", "^.*tearDownClass\\z", 302 TYPE_METHOD_PUBLIC_STATIC, _fileName); 303 checkAnnotationForMethod( 304 javaTerm, "Before", "^.*setUp\\z", TYPE_METHOD_PUBLIC, _fileName); 305 checkAnnotationForMethod( 306 javaTerm, "BeforeClass", "^.*setUpClass\\z", 307 TYPE_METHOD_PUBLIC_STATIC, _fileName); 308 checkAnnotationForMethod( 309 javaTerm, "Test", "^.*test", TYPE_METHOD_PUBLIC, _fileName); 310 } 311 312 protected void fixJavaTermsDividers( 313 Set<JavaTerm> javaTerms, List<String> javaTermSortExclusions) { 314 315 JavaTerm previousJavaTerm = null; 316 317 Iterator<JavaTerm> itr = javaTerms.iterator(); 318 319 while (itr.hasNext()) { 320 JavaTerm javaTerm = itr.next(); 321 322 if (previousJavaTerm == null) { 323 previousJavaTerm = javaTerm; 324 325 continue; 326 } 327 328 String javaTermContent = javaTerm.getContent(); 329 330 if (javaTermContent.startsWith(_indent + "//")) { 331 previousJavaTerm = javaTerm; 332 333 continue; 334 } 335 336 String previousJavaTermContent = previousJavaTerm.getContent(); 337 338 if (previousJavaTermContent.startsWith(_indent + "//")) { 339 previousJavaTerm = javaTerm; 340 341 continue; 342 } 343 344 String javaTermName = javaTerm.getName(); 345 346 if (BaseSourceProcessor.isExcluded( 347 javaTermSortExclusions, _absolutePath, 348 javaTerm.getLineCount(), javaTermName)) { 349 350 previousJavaTerm = javaTerm; 351 352 continue; 353 } 354 355 String previousJavaTermName = previousJavaTerm.getName(); 356 357 boolean requiresEmptyLine = false; 358 359 if (previousJavaTerm.getType() != javaTerm.getType()) { 360 requiresEmptyLine = true; 361 } 362 else if (!isInJavaTermTypeGroup( 363 javaTerm.getType(), TYPE_VARIABLE)) { 364 365 requiresEmptyLine = true; 366 } 367 else if ((StringUtil.isUpperCase(javaTermName) && 368 !StringUtil.isLowerCase(javaTermName)) || 369 (StringUtil.isUpperCase(previousJavaTermName) && 370 !StringUtil.isLowerCase(previousJavaTermName))) { 371 372 requiresEmptyLine = true; 373 } 374 else if (hasAnnotationCommentOrJavadoc(javaTermContent) || 375 hasAnnotationCommentOrJavadoc(previousJavaTermContent)) { 376 377 requiresEmptyLine = true; 378 } 379 else if ((previousJavaTerm.getType() == 380 TYPE_VARIABLE_PRIVATE_STATIC) && 381 (previousJavaTermName.equals("_instance") || 382 previousJavaTermName.equals("_log") || 383 previousJavaTermName.equals("_logger"))) { 384 385 requiresEmptyLine = true; 386 } 387 else if (previousJavaTermContent.contains("\n\n\t") || 388 javaTermContent.contains("\n\n\t")) { 389 390 requiresEmptyLine = true; 391 } 392 393 if (requiresEmptyLine) { 394 if (!_content.contains("\n\n" + javaTermContent)) { 395 _content = StringUtil.replace( 396 _content, "\n" + javaTermContent, 397 "\n\n" + javaTermContent); 398 399 return; 400 } 401 } 402 else if (_content.contains("\n\n" + javaTermContent)) { 403 _content = StringUtil.replace( 404 _content, "\n\n" + javaTermContent, "\n" + javaTermContent); 405 406 return; 407 } 408 409 previousJavaTerm = javaTerm; 410 } 411 } 412 413 protected String fixLeadingTabs( 414 String content, String line, int expectedTabCount) { 415 416 int leadingTabCount = JavaSourceProcessor.getLeadingTabCount(line); 417 418 String newLine = line; 419 420 while (leadingTabCount != expectedTabCount) { 421 if (leadingTabCount > expectedTabCount) { 422 newLine = StringUtil.replaceFirst( 423 newLine, StringPool.TAB, StringPool.BLANK); 424 425 leadingTabCount--; 426 } 427 else { 428 newLine = StringPool.TAB + newLine; 429 430 leadingTabCount++; 431 } 432 } 433 434 return StringUtil.replace(content, line, newLine); 435 } 436 437 protected void fixTabsAndIncorrectEmptyLines(JavaTerm javaTerm) { 438 if (!isInJavaTermTypeGroup(javaTerm.getType(), TYPE_METHOD)) { 439 return; 440 } 441 442 String javaTermContent = "\n" + javaTerm.getContent(); 443 444 Pattern methodNameAndParametersPattern = Pattern.compile( 445 "\n" + _indent + "(private |protected |public )(.|\n)*?(\\{|;)\n"); 446 447 Matcher matcher = methodNameAndParametersPattern.matcher( 448 javaTermContent); 449 450 if (!matcher.find()) { 451 return; 452 } 453 454 String methodNameAndParameters = matcher.group(); 455 456 String[] lines = StringUtil.splitLines(methodNameAndParameters); 457 458 if (lines.length == 1) { 459 if (methodNameAndParameters.endsWith("{\n") && 460 javaTermContent.contains(methodNameAndParameters + "\n") && 461 !javaTermContent.contains( 462 methodNameAndParameters + "\n" + _indent + StringPool.TAB + 463 "/*") && 464 !javaTermContent.contains( 465 methodNameAndParameters + "\n" + _indent + StringPool.TAB + 466 "// ")) { 467 468 String trimmedJavaTermContent = StringUtil.trimTrailing( 469 javaTermContent); 470 471 if (!trimmedJavaTermContent.endsWith( 472 "\n\n" + _indent + StringPool.CLOSE_CURLY_BRACE)) { 473 474 _content = StringUtil.replace( 475 _content, methodNameAndParameters + "\n", 476 methodNameAndParameters); 477 } 478 } 479 480 return; 481 } 482 483 if (methodNameAndParameters.endsWith("{\n") && 484 !javaTermContent.contains(methodNameAndParameters + "\n") && 485 !javaTermContent.contains( 486 methodNameAndParameters + _indent + 487 StringPool.CLOSE_CURLY_BRACE)) { 488 489 _content = StringUtil.replace( 490 _content, methodNameAndParameters, 491 methodNameAndParameters + "\n"); 492 } 493 494 boolean throwsException = methodNameAndParameters.contains( 495 _indent + "throws "); 496 497 String newMethodNameAndParameters = methodNameAndParameters; 498 499 int expectedTabCount = -1; 500 501 for (int i = 0; i < lines.length; i++) { 502 String line = lines[i]; 503 504 if (line.contains(_indent + "throws ")) { 505 newMethodNameAndParameters = fixLeadingTabs( 506 newMethodNameAndParameters, line, _indent.length() + 1); 507 508 break; 509 } 510 511 if (expectedTabCount == -1) { 512 if (line.endsWith(StringPool.OPEN_PARENTHESIS)) { 513 expectedTabCount = 514 Math.max( 515 JavaSourceProcessor.getLeadingTabCount(line), 516 _indent.length()) + 517 1; 518 519 if (throwsException && 520 (expectedTabCount == (_indent.length() + 1))) { 521 522 expectedTabCount += 1; 523 } 524 } 525 } 526 else { 527 String previousLine = lines[i - 1]; 528 529 if (previousLine.endsWith(StringPool.COMMA) || 530 previousLine.endsWith(StringPool.OPEN_PARENTHESIS)) { 531 532 newMethodNameAndParameters = fixLeadingTabs( 533 newMethodNameAndParameters, line, expectedTabCount); 534 } 535 else { 536 newMethodNameAndParameters = fixLeadingTabs( 537 newMethodNameAndParameters, line, 538 JavaSourceProcessor.getLeadingTabCount(previousLine) + 539 1); 540 } 541 } 542 } 543 544 _content = StringUtil.replace( 545 _content, methodNameAndParameters, newMethodNameAndParameters); 546 } 547 548 protected void formatAnnotations( 549 JavaTerm javaTerm, List<String> testAnnotationsExclusions) 550 throws Exception { 551 552 if ((_indent.length() == 1) && _fileName.contains("/test/") && 553 !BaseSourceProcessor.isExcluded( 554 testAnnotationsExclusions, _absolutePath) && 555 !_fileName.endsWith("TestCase.java")) { 556 557 checkTestAnnotations(javaTerm); 558 } 559 560 String javaTermContent = javaTerm.getContent(); 561 562 String newJavaTermContent = JavaSourceProcessor.sortAnnotations( 563 javaTermContent, _indent); 564 565 if (!javaTermContent.equals(newJavaTermContent)) { 566 _content = _content.replace(javaTermContent, newJavaTermContent); 567 } 568 } 569 570 protected String getClassName(String line) { 571 int pos = line.indexOf(" extends "); 572 573 if (pos == -1) { 574 pos = line.indexOf(" implements "); 575 } 576 577 if (pos == -1) { 578 pos = line.indexOf(StringPool.OPEN_CURLY_BRACE); 579 } 580 581 if (pos != -1) { 582 line = line.substring(0, pos); 583 } 584 585 pos = line.indexOf(StringPool.LESS_THAN); 586 587 if (pos != -1) { 588 line = line.substring(0, pos); 589 } 590 591 line = line.trim(); 592 593 pos = line.lastIndexOf(StringPool.SPACE); 594 595 return line.substring(pos + 1); 596 } 597 598 protected String getConstructorOrMethodName(String line, int pos) { 599 line = line.substring(0, pos); 600 601 int x = line.lastIndexOf(StringPool.SPACE); 602 603 return line.substring(x + 1); 604 } 605 606 protected Set<JavaTerm> getJavaTerms( 607 List<String> javaTermAccessLevelModifierExclusions) 608 throws Exception { 609 610 Set<JavaTerm> javaTerms = new TreeSet<JavaTerm>( 611 new JavaTermComparator(false)); 612 613 UnsyncBufferedReader unsyncBufferedReader = new UnsyncBufferedReader( 614 new UnsyncStringReader(_content)); 615 616 int index = 0; 617 int lineCount = _lineCount - 1; 618 619 String line = null; 620 621 JavaTerm javaTerm = null; 622 623 String javaTermName = null; 624 int javaTermLineCount = -1; 625 int javaTermStartPosition = -1; 626 int javaTermType = -1; 627 628 int lastCommentOrAnnotationPos = -1; 629 630 while ((line = unsyncBufferedReader.readLine()) != null) { 631 lineCount++; 632 633 if (JavaSourceProcessor.getLeadingTabCount(line) != 634 _indent.length()) { 635 636 index = index + line.length() + 1; 637 638 continue; 639 } 640 641 if (line.startsWith(_indent + "private ") || 642 line.equals(_indent + "private") || 643 line.startsWith(_indent + "protected ") || 644 line.equals(_indent + "protected") || 645 line.startsWith(_indent + "public ") || 646 line.equals(_indent + "public") || 647 line.equals(_indent + "static {")) { 648 649 Tuple tuple = getJavaTermTuple(line, _content, index); 650 651 if (tuple == null) { 652 return null; 653 } 654 655 int javaTermEndPosition = 0; 656 657 if (lastCommentOrAnnotationPos == -1) { 658 javaTermEndPosition = index; 659 } 660 else { 661 javaTermEndPosition = lastCommentOrAnnotationPos; 662 } 663 664 if ((javaTermStartPosition != -1) && 665 (javaTermEndPosition < _content.length())) { 666 667 String javaTermContent = _content.substring( 668 javaTermStartPosition, javaTermEndPosition); 669 670 if (!isValidJavaTerm(javaTermContent)) { 671 return null; 672 } 673 674 if (Validator.isNotNull(javaTermName)) { 675 javaTerm = new JavaTerm( 676 javaTermName, javaTermType, javaTermContent, 677 javaTermLineCount); 678 679 if (javaTermType == JavaClass.TYPE_STATIC_BLOCK) { 680 _staticBlocks.add(javaTerm); 681 } 682 else { 683 javaTerms.add(javaTerm); 684 } 685 } 686 } 687 688 javaTermLineCount = lineCount; 689 javaTermName = (String)tuple.getObject(0); 690 javaTermStartPosition = javaTermEndPosition; 691 javaTermType = (Integer)tuple.getObject(1); 692 693 lastCommentOrAnnotationPos = -1; 694 } 695 else if (hasAnnotationCommentOrJavadoc(line)) { 696 if (lastCommentOrAnnotationPos == -1) { 697 lastCommentOrAnnotationPos = index; 698 } 699 } 700 else if (!line.startsWith(_indent + StringPool.CLOSE_CURLY_BRACE) && 701 !line.startsWith(_indent + StringPool.CLOSE_PARENTHESIS) && 702 !line.startsWith(_indent + "extends") && 703 !line.startsWith(_indent + "implements") && 704 !BaseSourceProcessor.isExcluded( 705 javaTermAccessLevelModifierExclusions, _absolutePath, 706 lineCount)) { 707 708 Matcher matcher = _classPattern.matcher(_content); 709 710 if (matcher.find()) { 711 String insideClass = _content.substring(matcher.end()); 712 713 if (insideClass.contains(line)) { 714 BaseSourceProcessor.processErrorMessage( 715 _fileName, 716 "Missing access level modifier: " + _fileName + 717 " " + lineCount); 718 } 719 } 720 } 721 722 index = index + line.length() + 1; 723 } 724 725 if (javaTermStartPosition != -1) { 726 int javaTermEndPosition = 727 _content.lastIndexOf(StringPool.CLOSE_CURLY_BRACE) - 728 _indent.length(); 729 730 String javaTermContent = _content.substring( 731 javaTermStartPosition, javaTermEndPosition); 732 733 if (!isValidJavaTerm(javaTermContent)) { 734 return null; 735 } 736 737 javaTerm = new JavaTerm( 738 javaTermName, javaTermType, javaTermContent, javaTermLineCount); 739 740 if (javaTermType == JavaClass.TYPE_STATIC_BLOCK) { 741 _staticBlocks.add(javaTerm); 742 } 743 else { 744 javaTerms.add(javaTerm); 745 } 746 } 747 748 return javaTerms; 749 } 750 751 protected Tuple getJavaTermTuple(String line, String content, int index) { 752 int posStartNextLine = index; 753 754 while (!line.endsWith(StringPool.OPEN_CURLY_BRACE) && 755 !line.endsWith(StringPool.SEMICOLON)) { 756 757 posStartNextLine = 758 content.indexOf(StringPool.NEW_LINE, posStartNextLine) + 1; 759 760 int posEndNextline = content.indexOf( 761 StringPool.NEW_LINE, posStartNextLine); 762 763 String nextLine = content.substring( 764 posStartNextLine, posEndNextline); 765 766 nextLine = StringUtil.trimLeading(nextLine); 767 768 if (line.endsWith(StringPool.OPEN_PARENTHESIS)) { 769 line += nextLine; 770 } 771 else { 772 line += StringPool.SPACE + nextLine; 773 } 774 } 775 776 line = StringUtil.replace(line, " synchronized " , StringPool.SPACE); 777 778 int pos = line.indexOf(StringPool.OPEN_PARENTHESIS); 779 780 if (line.startsWith(_indent + "public static ")) { 781 if (line.contains(" class ") || line.contains(" enum ")) { 782 return new Tuple(getClassName(line), TYPE_CLASS_PUBLIC_STATIC); 783 } 784 785 if (line.contains(StringPool.EQUAL) || 786 (line.endsWith(StringPool.SEMICOLON) && (pos == -1))) { 787 788 return new Tuple( 789 getVariableName(line), TYPE_VARIABLE_PUBLIC_STATIC); 790 } 791 792 if (pos != -1) { 793 return new Tuple( 794 getConstructorOrMethodName(line, pos), 795 TYPE_METHOD_PUBLIC_STATIC); 796 } 797 } 798 else if (line.startsWith(_indent + "public ")) { 799 if (line.contains(" @interface ") || line.contains(" class ") || 800 line.contains(" enum ") || line.contains(" interface ")) { 801 802 return new Tuple(getClassName(line), TYPE_CLASS_PUBLIC); 803 } 804 805 if (line.contains(StringPool.EQUAL) || 806 (line.endsWith(StringPool.SEMICOLON) && (pos == -1))) { 807 808 return new Tuple(getVariableName(line), TYPE_VARIABLE_PUBLIC); 809 } 810 811 if (pos != -1) { 812 int spaceCount = StringUtil.count( 813 line.substring(0, pos), StringPool.SPACE); 814 815 if (spaceCount == 1) { 816 return new Tuple( 817 getConstructorOrMethodName(line, pos), 818 TYPE_CONSTRUCTOR_PUBLIC); 819 } 820 821 if (spaceCount > 1) { 822 return new Tuple( 823 getConstructorOrMethodName(line, pos), 824 TYPE_METHOD_PUBLIC); 825 } 826 } 827 } 828 else if (line.startsWith(_indent + "protected static ")) { 829 if (line.contains(" class ") || line.contains(" enum ")) { 830 return new Tuple( 831 getClassName(line), TYPE_CLASS_PROTECTED_STATIC); 832 } 833 834 if (line.contains(StringPool.EQUAL) || 835 (line.endsWith(StringPool.SEMICOLON) && (pos == -1))) { 836 837 return new Tuple( 838 getVariableName(line), TYPE_VARIABLE_PROTECTED_STATIC); 839 } 840 841 if (pos != -1) { 842 return new Tuple( 843 getConstructorOrMethodName(line, pos), 844 TYPE_METHOD_PROTECTED_STATIC); 845 } 846 } 847 else if (line.startsWith(_indent + "protected ")) { 848 if (line.contains(" @interface ") || line.contains(" class ") || 849 line.contains(" enum ") || line.contains(" interface ")) { 850 851 return new Tuple(getClassName(line), TYPE_CLASS_PROTECTED); 852 } 853 854 if (pos != -1) { 855 if (!line.contains(StringPool.EQUAL)) { 856 int spaceCount = StringUtil.count( 857 line.substring(0, pos), StringPool.SPACE); 858 859 if (spaceCount == 1) { 860 return new Tuple( 861 getConstructorOrMethodName(line, pos), 862 TYPE_CONSTRUCTOR_PROTECTED); 863 } 864 865 if (spaceCount > 1) { 866 return new Tuple( 867 getConstructorOrMethodName(line, pos), 868 TYPE_METHOD_PROTECTED); 869 } 870 } 871 } 872 873 return new Tuple(getVariableName(line), TYPE_VARIABLE_PROTECTED); 874 } 875 else if (line.startsWith(_indent + "private static ")) { 876 if (line.contains(" class ") || line.contains(" enum ")) { 877 return new Tuple(getClassName(line), TYPE_CLASS_PRIVATE_STATIC); 878 } 879 880 if (line.contains(StringPool.EQUAL) || 881 (line.endsWith(StringPool.SEMICOLON) && (pos == -1))) { 882 883 return new Tuple( 884 getVariableName(line), TYPE_VARIABLE_PRIVATE_STATIC); 885 } 886 887 if (pos != -1) { 888 return new Tuple( 889 getConstructorOrMethodName(line, pos), 890 TYPE_METHOD_PRIVATE_STATIC); 891 } 892 } 893 else if (line.startsWith(_indent + "private ")) { 894 if (line.contains(" @interface ") || line.contains(" class ") || 895 line.contains(" enum ") || line.contains(" interface ")) { 896 897 return new Tuple(getClassName(line), TYPE_CLASS_PRIVATE); 898 } 899 900 if (line.contains(StringPool.EQUAL) || 901 (line.endsWith(StringPool.SEMICOLON) && (pos == -1))) { 902 903 return new Tuple(getVariableName(line), TYPE_VARIABLE_PRIVATE); 904 } 905 906 if (pos != -1) { 907 int spaceCount = StringUtil.count( 908 line.substring(0, pos), StringPool.SPACE); 909 910 if (spaceCount == 1) { 911 return new Tuple( 912 getConstructorOrMethodName(line, pos), 913 TYPE_CONSTRUCTOR_PRIVATE); 914 } 915 916 if (spaceCount > 1) { 917 return new Tuple( 918 getConstructorOrMethodName(line, pos), 919 TYPE_METHOD_PRIVATE); 920 } 921 } 922 } 923 else if (line.startsWith(_indent + "static {")) { 924 return new Tuple("static", TYPE_STATIC_BLOCK); 925 } 926 927 return null; 928 } 929 930 protected String getVariableName(String line) { 931 int x = line.indexOf(StringPool.EQUAL); 932 int y = line.lastIndexOf(StringPool.SPACE); 933 934 if (x != -1) { 935 line = line.substring(0, x); 936 line = StringUtil.trim(line); 937 938 y = line.lastIndexOf(StringPool.SPACE); 939 940 return line.substring(y + 1); 941 } 942 943 if (line.endsWith(StringPool.SEMICOLON)) { 944 return line.substring(y + 1, line.length() - 1); 945 } 946 947 return StringPool.BLANK; 948 } 949 950 protected boolean hasAnnotationCommentOrJavadoc(String s) { 951 if (s.startsWith(_indent + StringPool.AT) || 952 s.startsWith(_indent + StringPool.SLASH) || 953 s.startsWith(_indent + " *")) { 954 955 return true; 956 } 957 else { 958 return false; 959 } 960 } 961 962 protected boolean isValidJavaTerm(String content) { 963 if (content.startsWith(_indent + "static {")) { 964 return true; 965 } 966 967 while (!content.startsWith(_indent + "private") && 968 !content.startsWith(_indent + "protected") && 969 !content.startsWith(_indent + "public")) { 970 971 content = content.substring(content.indexOf("\n") + 1); 972 } 973 974 int indentLinesCount = 975 StringUtil.count(content, "\n" + _indent) - 976 StringUtil.count(content, "\n" + _indent + StringPool.TAB); 977 978 content = StringUtil.trim(content); 979 980 if (content.endsWith(StringPool.CLOSE_CURLY_BRACE) && 981 ((indentLinesCount == 1) || 982 (((indentLinesCount == 2) || (indentLinesCount == 3)) && 983 content.contains("\n" + _indent + "static {")))) { 984 985 return true; 986 } 987 else if ((content.endsWith("};") && (indentLinesCount == 1)) || 988 (content.endsWith(StringPool.SEMICOLON) && 989 (indentLinesCount == 0))) { 990 991 return true; 992 } 993 994 return false; 995 } 996 997 protected void sortJavaTerms( 998 JavaTerm previousJavaTerm, JavaTerm javaTerm, 999 List<String> javaTermSortExclusions) { 1000 1001 if (previousJavaTerm == null) { 1002 return; 1003 } 1004 1005 String javaTermName = javaTerm.getName(); 1006 1007 if (BaseSourceProcessor.isExcluded( 1008 javaTermSortExclusions, _absolutePath, -1, javaTermName)) { 1009 1010 return; 1011 } 1012 1013 if (previousJavaTerm.getLineCount() <= javaTerm.getLineCount()) { 1014 return; 1015 } 1016 1017 String previousJavaTermName = previousJavaTerm.getName(); 1018 1019 String javaTermNameLowerCase = StringUtil.toLowerCase(javaTermName); 1020 String previousJavaTermNameLowerCase = StringUtil.toLowerCase( 1021 previousJavaTermName); 1022 1023 if (_fileName.contains("persistence") && 1024 ((previousJavaTermName.startsWith("doCount") && 1025 javaTermName.startsWith("doCount")) || 1026 (previousJavaTermName.startsWith("doFind") && 1027 javaTermName.startsWith("doFind")) || 1028 (previousJavaTermNameLowerCase.startsWith("count") && 1029 javaTermNameLowerCase.startsWith("count")) || 1030 (previousJavaTermNameLowerCase.startsWith("filter") && 1031 javaTermNameLowerCase.startsWith("filter")) || 1032 (previousJavaTermNameLowerCase.startsWith("find") && 1033 javaTermNameLowerCase.startsWith("find")) || 1034 (previousJavaTermNameLowerCase.startsWith("join") && 1035 javaTermNameLowerCase.startsWith("join")))) { 1036 } 1037 else { 1038 _content = StringUtil.replaceFirst( 1039 _content, "\n" + javaTerm.getContent(), 1040 "\n" + previousJavaTerm.getContent()); 1041 _content = StringUtil.replaceLast( 1042 _content, "\n" + previousJavaTerm.getContent(), 1043 "\n" + javaTerm.getContent()); 1044 } 1045 } 1046 1047 private String _absolutePath; 1048 private Pattern _classPattern = Pattern.compile( 1049 "(private |protected |public )(static )*class ([\\s\\S]*?) \\{\n"); 1050 private String _content; 1051 private String _fileName; 1052 private String _indent; 1053 private int _lineCount; 1054 private List<JavaTerm> _staticBlocks; 1055 1056 }