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.CharPool; 020 import com.liferay.portal.kernel.util.ClassUtil; 021 import com.liferay.portal.kernel.util.GetterUtil; 022 import com.liferay.portal.kernel.util.StringBundler; 023 import com.liferay.portal.kernel.util.StringPool; 024 import com.liferay.portal.kernel.util.StringUtil; 025 import com.liferay.portal.kernel.util.Validator; 026 027 import com.thoughtworks.qdox.JavaDocBuilder; 028 import com.thoughtworks.qdox.model.JavaSource; 029 030 import java.io.File; 031 import java.io.IOException; 032 033 import java.util.ArrayList; 034 import java.util.Collection; 035 import java.util.List; 036 import java.util.Set; 037 import java.util.TreeSet; 038 import java.util.regex.Matcher; 039 import java.util.regex.Pattern; 040 041 /** 042 * @author Hugo Huijser 043 */ 044 public class JavaSourceProcessor extends BaseSourceProcessor { 045 046 public static String stripJavaImports( 047 String content, String packageDir, String className) 048 throws IOException { 049 050 Matcher matcher = _importsPattern.matcher(content); 051 052 if (!matcher.find()) { 053 return content; 054 } 055 056 String imports = matcher.group(); 057 058 Set<String> classes = ClassUtil.getClasses( 059 new UnsyncStringReader(content), className); 060 061 StringBundler sb = new StringBundler(); 062 063 UnsyncBufferedReader unsyncBufferedReader = new UnsyncBufferedReader( 064 new UnsyncStringReader(imports)); 065 066 String line = null; 067 068 while ((line = unsyncBufferedReader.readLine()) != null) { 069 if (!line.contains("import ")) { 070 continue; 071 } 072 073 int importX = line.indexOf(" "); 074 int importY = line.lastIndexOf("."); 075 076 String importPackage = line.substring(importX + 1, importY); 077 078 if (importPackage.equals(packageDir) || 079 importPackage.equals("java.lang")) { 080 081 continue; 082 } 083 084 String importClass = line.substring(importY + 1, line.length() - 1); 085 086 if (importClass.equals("*") || classes.contains(importClass)) { 087 sb.append(line); 088 sb.append("\n"); 089 } 090 } 091 092 ImportsFormatter importsFormatter = new JavaImportsFormatter(); 093 094 imports = importsFormatter.format(sb.toString()); 095 096 content = 097 content.substring(0, matcher.start()) + imports + 098 content.substring(matcher.end()); 099 100 // Ensure a blank line exists between the package and the first import 101 102 content = content.replaceFirst( 103 "(?m)^[ \t]*(package .*;)\\s*^[ \t]*import", "$1\n\nimport"); 104 105 // Ensure a blank line exists between the last import (or package if 106 // there are no imports) and the class comment 107 108 content = content.replaceFirst( 109 "(?m)^[ \t]*((?:package|import) .*;)\\s*^[ \t]*/\\*\\*", 110 "$1\n\n/**"); 111 112 return content; 113 } 114 115 protected static int getLeadingTabCount(String line) { 116 int leadingTabCount = 0; 117 118 while (line.startsWith(StringPool.TAB)) { 119 line = line.substring(1); 120 121 leadingTabCount++; 122 } 123 124 return leadingTabCount; 125 } 126 127 protected static String sortAnnotations(String content, String indent) 128 throws IOException { 129 130 UnsyncBufferedReader unsyncBufferedReader = new UnsyncBufferedReader( 131 new UnsyncStringReader(content)); 132 133 String line = null; 134 135 String annotation = StringPool.BLANK; 136 String previousAnnotation = StringPool.BLANK; 137 138 while ((line = unsyncBufferedReader.readLine()) != null) { 139 if (line.equals(indent + StringPool.CLOSE_CURLY_BRACE)) { 140 return content; 141 } 142 143 if (StringUtil.count(line, StringPool.TAB) == indent.length()) { 144 if (Validator.isNotNull(previousAnnotation) && 145 (previousAnnotation.compareTo(annotation) > 0)) { 146 147 content = StringUtil.replaceFirst( 148 content, previousAnnotation, annotation); 149 content = StringUtil.replaceLast( 150 content, annotation, previousAnnotation); 151 152 return sortAnnotations(content, indent); 153 } 154 155 if (line.startsWith(indent + StringPool.AT)) { 156 if (Validator.isNotNull(annotation)) { 157 previousAnnotation = annotation; 158 } 159 160 annotation = line + "\n"; 161 } 162 else { 163 annotation = StringPool.BLANK; 164 previousAnnotation = StringPool.BLANK; 165 } 166 } 167 else { 168 if (Validator.isNull(annotation)) { 169 return content; 170 } 171 172 annotation += line + "\n"; 173 } 174 } 175 176 return content; 177 } 178 179 protected String applyDiamondOperator(String content) { 180 Matcher matcher = _diamondOperatorPattern.matcher(content); 181 182 while (matcher.find()) { 183 String parameterType = matcher.group(5); 184 185 if (parameterType.contains("Object")) { 186 String constructorParameter = matcher.group(6); 187 188 if (Validator.isNotNull(constructorParameter)) { 189 continue; 190 } 191 } 192 193 String match = matcher.group(); 194 195 String replacement = StringUtil.replaceFirst( 196 match, "<" + parameterType + ">", "<>"); 197 198 return StringUtil.replace(content, match, replacement); 199 } 200 201 return content; 202 } 203 204 protected void checkFinderCacheInterfaceMethod( 205 String fileName, String content) { 206 207 if (!fileName.endsWith("FinderImpl.java") || 208 !content.contains("public static final FinderPath")) { 209 210 return; 211 } 212 213 Matcher matcher = _fetchByPrimaryKeysMethodPattern.matcher(content); 214 215 if (!matcher.find()) { 216 processErrorMessage( 217 fileName, 218 "LPS-49552: Missing override of BasePersistenceImpl." + 219 "fetchByPrimaryKeys(Set<Serializable>): " + fileName); 220 } 221 } 222 223 protected String checkIfClause( 224 String ifClause, String fileName, int lineCount) 225 throws IOException { 226 227 String ifClauseSingleLine = StringUtil.replace( 228 ifClause, 229 new String[] { 230 StringPool.TAB + StringPool.SPACE, StringPool.TAB, 231 StringPool.OPEN_PARENTHESIS + StringPool.NEW_LINE, 232 StringPool.NEW_LINE 233 }, 234 new String[] { 235 StringPool.TAB, StringPool.BLANK, StringPool.OPEN_PARENTHESIS, 236 StringPool.SPACE 237 }); 238 239 checkIfClauseParentheses(ifClauseSingleLine, fileName, lineCount); 240 241 return checkIfClauseTabsAndSpaces(ifClause); 242 } 243 244 protected String checkIfClauseTabsAndSpaces(String ifClause) 245 throws IOException { 246 247 if (ifClause.contains("!(") || 248 ifClause.contains(StringPool.TAB + "//")) { 249 250 return ifClause; 251 } 252 253 UnsyncBufferedReader unsyncBufferedReader = new UnsyncBufferedReader( 254 new UnsyncStringReader(ifClause)); 255 256 String line = null; 257 258 String previousLine = null; 259 int previousLineLeadingWhiteSpace = 0; 260 261 int lastCriteriumLineLeadingWhiteSpace = 0; 262 263 int closeParenthesesCount = 0; 264 int openParenthesesCount = 0; 265 266 while ((line = unsyncBufferedReader.readLine()) != null) { 267 String originalLine = line; 268 269 line = StringUtil.replace( 270 line, StringPool.TAB, StringPool.FOUR_SPACES); 271 272 int leadingWhiteSpace = 273 line.length() - StringUtil.trimLeading(line).length(); 274 275 if (Validator.isNull(previousLine)) { 276 lastCriteriumLineLeadingWhiteSpace = line.indexOf( 277 StringPool.OPEN_PARENTHESIS); 278 } 279 else if (previousLine.endsWith("|") || previousLine.endsWith("&") || 280 previousLine.endsWith("^")) { 281 282 int expectedLeadingWhiteSpace = 283 lastCriteriumLineLeadingWhiteSpace + 284 openParenthesesCount - closeParenthesesCount; 285 286 if (leadingWhiteSpace != expectedLeadingWhiteSpace) { 287 return fixIfClause( 288 ifClause, originalLine, 289 leadingWhiteSpace - expectedLeadingWhiteSpace); 290 } 291 292 lastCriteriumLineLeadingWhiteSpace = leadingWhiteSpace; 293 294 closeParenthesesCount = 0; 295 openParenthesesCount = 0; 296 } 297 else { 298 int expectedLeadingWhiteSpace = 0; 299 300 if (previousLine.contains(StringPool.TAB + "if (")) { 301 expectedLeadingWhiteSpace = 302 previousLineLeadingWhiteSpace + 8; 303 } 304 else if (previousLine.contains(StringPool.TAB + "else if (") || 305 previousLine.contains(StringPool.TAB + "while (")) { 306 307 expectedLeadingWhiteSpace = 308 previousLineLeadingWhiteSpace + 12; 309 } 310 311 if ((expectedLeadingWhiteSpace != 0) && 312 (leadingWhiteSpace != expectedLeadingWhiteSpace)) { 313 314 return fixIfClause( 315 ifClause, originalLine, 316 leadingWhiteSpace - expectedLeadingWhiteSpace); 317 } 318 } 319 320 if (line.endsWith(") {")) { 321 return ifClause; 322 } 323 324 line = stripQuotes(line, CharPool.QUOTE); 325 line = stripQuotes(line, CharPool.APOSTROPHE); 326 327 closeParenthesesCount += StringUtil.count( 328 line, StringPool.CLOSE_PARENTHESIS); 329 openParenthesesCount += StringUtil.count( 330 line, StringPool.OPEN_PARENTHESIS); 331 332 previousLine = originalLine; 333 previousLineLeadingWhiteSpace = leadingWhiteSpace; 334 } 335 336 return ifClause; 337 } 338 339 protected void checkLogLevel( 340 String content, String fileName, String logLevel) { 341 342 if (fileName.contains("Log")) { 343 return; 344 } 345 346 Pattern pattern = Pattern.compile("\n(\t+)_log." + logLevel + "\\("); 347 348 Matcher matcher = pattern.matcher(content); 349 350 while (matcher.find()) { 351 int pos = matcher.start(); 352 353 while (true) { 354 pos = content.lastIndexOf( 355 StringPool.NEW_LINE + StringPool.TAB, pos - 1); 356 357 char c = content.charAt(pos + 2); 358 359 if (c != CharPool.TAB) { 360 break; 361 } 362 } 363 364 String codeBlock = content.substring(pos, matcher.start()); 365 String s = 366 "_log.is" + StringUtil.upperCaseFirstLetter(logLevel) + 367 "Enabled()"; 368 369 if (!codeBlock.contains(s)) { 370 int lineCount = StringUtil.count( 371 content.substring(0, matcher.start(1)), 372 StringPool.NEW_LINE); 373 374 lineCount += 1; 375 376 processErrorMessage( 377 fileName, "Use " + s + ": " + fileName + " " + lineCount); 378 } 379 } 380 381 return; 382 } 383 384 protected void checkRegexPattern( 385 String regexPattern, String fileName, int lineCount) { 386 387 int i = regexPattern.indexOf("Pattern.compile("); 388 389 if (i == -1) { 390 return; 391 } 392 393 regexPattern = regexPattern.substring(i + 16); 394 395 regexPattern = stripQuotes(regexPattern, CharPool.QUOTE); 396 397 i = regexPattern.indexOf(StringPool.COMMA); 398 399 if (i != -1) { 400 regexPattern = regexPattern.substring(0, i); 401 } 402 else { 403 regexPattern = StringUtil.replaceLast( 404 regexPattern, ");", StringPool.BLANK); 405 } 406 407 regexPattern = StringUtil.replace( 408 regexPattern, StringPool.PLUS, StringPool.BLANK); 409 410 if (Validator.isNull(regexPattern)) { 411 processErrorMessage( 412 fileName, 413 "create pattern as global var: " + fileName + " " + lineCount); 414 } 415 } 416 417 protected void checkSystemEventAnnotations(String content, String fileName) 418 throws Exception { 419 420 if (!portalSource || !fileName.endsWith("PortletDataHandler.java")) { 421 return; 422 } 423 424 int pos = content.indexOf("setDeletionSystemEventStagedModelTypes"); 425 426 if (pos == -1) { 427 return; 428 } 429 430 String deletionSystemEventStagedModelTypes = content.substring( 431 pos, content.indexOf(");", pos)); 432 433 Matcher matcher = _stagedModelTypesPattern.matcher( 434 deletionSystemEventStagedModelTypes); 435 436 while (matcher.find()) { 437 String stagedModelTypeClassName = matcher.group(1); 438 439 pos = stagedModelTypeClassName.indexOf(".class"); 440 441 if (pos == -1) { 442 pos = stagedModelTypeClassName.indexOf("Constants"); 443 } 444 445 if (pos == -1) { 446 return; 447 } 448 449 String className = stagedModelTypeClassName.substring(0, pos); 450 451 Pattern packageNamePattern = Pattern.compile( 452 "import (com\\.liferay\\.[a-zA-Z\\.]*)\\.model\\." + 453 className + ";"); 454 455 Matcher packageNameMatcher = packageNamePattern.matcher(content); 456 457 if (!packageNameMatcher.find()) { 458 return; 459 } 460 461 StringBundler sb = new StringBundler(6); 462 463 sb.append(BASEDIR); 464 sb.append(fileName.substring(0, fileName.indexOf("/src/") + 5)); 465 sb.append( 466 StringUtil.replace( 467 packageNameMatcher.group(1), StringPool.PERIOD, 468 StringPool.SLASH)); 469 sb.append("/service/impl/"); 470 sb.append(className); 471 sb.append("LocalServiceImpl.java"); 472 473 String localServiceImplFileName = sb.toString(); 474 475 String localServiceImplContent = fileUtil.read( 476 localServiceImplFileName); 477 478 if (localServiceImplContent == null) { 479 System.out.println( 480 "Unable to read " + localServiceImplFileName); 481 482 return; 483 } 484 485 if (!localServiceImplContent.contains("@SystemEvent")) { 486 processErrorMessage( 487 fileName, 488 "Missing deletion system event: " + 489 localServiceImplFileName); 490 } 491 } 492 } 493 494 protected void checkUnprocessedExceptions( 495 String content, File file, String packagePath, String fileName) 496 throws IOException { 497 498 List<String> importedExceptionClassNames = null; 499 JavaDocBuilder javaDocBuilder = null; 500 501 for (int lineCount = 1;;) { 502 Matcher catchExceptionMatcher = _catchExceptionPattern.matcher( 503 content); 504 505 if (!catchExceptionMatcher.find()) { 506 return; 507 } 508 509 String beforeCatchCode = content.substring( 510 0, catchExceptionMatcher.start()); 511 512 lineCount = lineCount + StringUtil.count(beforeCatchCode, "\n") + 1; 513 514 String exceptionClassName = catchExceptionMatcher.group(2); 515 String exceptionVariableName = catchExceptionMatcher.group(3); 516 String tabs = catchExceptionMatcher.group(1); 517 518 int pos = content.indexOf( 519 "\n" + tabs + StringPool.CLOSE_CURLY_BRACE, 520 catchExceptionMatcher.end() - 1); 521 522 String insideCatchCode = content.substring( 523 catchExceptionMatcher.end(), pos + 1); 524 525 Pattern exceptionVariablePattern = Pattern.compile( 526 "\\W" + exceptionVariableName + "\\W"); 527 528 Matcher exceptionVariableMatcher = exceptionVariablePattern.matcher( 529 insideCatchCode); 530 531 if (exceptionVariableMatcher.find()) { 532 content = content.substring(catchExceptionMatcher.start() + 1); 533 534 continue; 535 } 536 537 if (javaDocBuilder == null) { 538 javaDocBuilder = new JavaDocBuilder(); 539 540 javaDocBuilder.addSource(file); 541 } 542 543 if (importedExceptionClassNames == null) { 544 importedExceptionClassNames = getImportedExceptionClassNames( 545 javaDocBuilder); 546 } 547 548 String originalExceptionClassName = exceptionClassName; 549 550 if (!exceptionClassName.contains(StringPool.PERIOD)) { 551 for (String exceptionClass : importedExceptionClassNames) { 552 if (exceptionClass.endsWith( 553 StringPool.PERIOD + exceptionClassName)) { 554 555 exceptionClassName = exceptionClass; 556 557 break; 558 } 559 } 560 } 561 562 if (!exceptionClassName.contains(StringPool.PERIOD)) { 563 exceptionClassName = 564 packagePath + StringPool.PERIOD + exceptionClassName; 565 } 566 567 com.thoughtworks.qdox.model.JavaClass exceptionClass = 568 javaDocBuilder.getClassByName(exceptionClassName); 569 570 while (true) { 571 String packageName = exceptionClass.getPackageName(); 572 573 if (!packageName.contains("com.liferay")) { 574 break; 575 } 576 577 exceptionClassName = exceptionClass.getName(); 578 579 if (exceptionClassName.equals("PortalException") || 580 exceptionClassName.equals("SystemException")) { 581 582 processErrorMessage( 583 fileName, 584 "Unprocessed " + originalExceptionClassName + ": " + 585 fileName + " " + lineCount); 586 587 break; 588 } 589 590 com.thoughtworks.qdox.model.JavaClass exceptionSuperClass = 591 exceptionClass.getSuperJavaClass(); 592 593 if (exceptionSuperClass == null) { 594 break; 595 } 596 597 exceptionClass = exceptionSuperClass; 598 } 599 600 content = content.substring(catchExceptionMatcher.start() + 1); 601 } 602 } 603 604 @Override 605 protected String doFormat( 606 File file, String fileName, String absolutePath, String content) 607 throws Exception { 608 609 if (isGenerated(content)) { 610 return content; 611 } 612 613 String className = file.getName(); 614 615 int pos = className.lastIndexOf(StringPool.PERIOD); 616 617 className = className.substring(0, pos); 618 619 String packagePath = fileName; 620 621 int packagePathX = packagePath.indexOf("/src/"); 622 623 if (packagePathX == -1) { 624 packagePathX = packagePath.indexOf("/integration/") + 8; 625 } 626 627 int packagePathY = packagePath.lastIndexOf(StringPool.SLASH); 628 629 if ((packagePathX + 5) >= packagePathY) { 630 packagePath = StringPool.BLANK; 631 } 632 else { 633 packagePath = packagePath.substring(packagePathX + 5, packagePathY); 634 } 635 636 packagePath = StringUtil.replace( 637 packagePath, StringPool.SLASH, StringPool.PERIOD); 638 639 if (packagePath.endsWith(".model")) { 640 if (content.contains("extends " + className + "Model")) { 641 return content; 642 } 643 } 644 645 String newContent = content; 646 647 if (newContent.contains("$\n */")) { 648 processErrorMessage(fileName, "*: " + fileName); 649 650 newContent = StringUtil.replace(newContent, "$\n */", "$\n *\n */"); 651 } 652 653 newContent = fixCopyright(newContent, absolutePath, fileName); 654 655 if (newContent.contains(className + ".java.html")) { 656 processErrorMessage(fileName, "Java2HTML: " + fileName); 657 } 658 659 if (newContent.contains(" * @author Raymond Aug") && 660 !newContent.contains(" * @author Raymond Aug\u00e9")) { 661 662 newContent = newContent.replaceFirst( 663 "Raymond Aug.++", "Raymond Aug\u00e9"); 664 665 processErrorMessage(fileName, "UTF-8: " + fileName); 666 } 667 668 newContent = fixDataAccessConnection(className, newContent); 669 newContent = fixSessionKey(fileName, newContent, sessionKeyPattern); 670 671 newContent = StringUtil.replace( 672 newContent, 673 new String[] { 674 "com.liferay.portal.PortalException", 675 "com.liferay.portal.SystemException", 676 "com.liferay.util.LocalizationUtil" 677 }, 678 new String[] { 679 "com.liferay.portal.kernel.exception.PortalException", 680 "com.liferay.portal.kernel.exception.SystemException", 681 "com.liferay.portal.kernel.util.LocalizationUtil" 682 }); 683 684 newContent = StringUtil.replace( 685 newContent, " final static ", " static final "); 686 687 newContent = fixCompatClassImports(absolutePath, newContent); 688 689 newContent = stripJavaImports(newContent, packagePath, className); 690 691 newContent = StringUtil.replace( 692 newContent, 693 new String[] { 694 ";\n/**", "\t/*\n\t *", "catch(", "else{", "if(", "for(", 695 "while(", "List <", "){\n", "]{\n", ";;\n" 696 }, 697 new String[] { 698 ";\n\n/**", "\t/**\n\t *", "catch (", "else {", "if (", "for (", 699 "while (", "List<", ") {\n", "] {\n", ";\n" 700 }); 701 702 while (true) { 703 Matcher matcher = _incorrectLineBreakPattern1.matcher(newContent); 704 705 if (matcher.find()) { 706 newContent = StringUtil.replaceFirst( 707 newContent, StringPool.NEW_LINE, StringPool.BLANK, 708 matcher.start()); 709 710 continue; 711 } 712 713 matcher = _incorrectLineBreakPattern2.matcher(newContent); 714 715 if (matcher.find()) { 716 newContent = StringUtil.replaceFirst( 717 newContent, StringPool.NEW_LINE, StringPool.BLANK, 718 matcher.start()); 719 720 continue; 721 } 722 723 break; 724 } 725 726 newContent = sortAnnotations(newContent, StringPool.BLANK); 727 728 Matcher matcher = _logPattern.matcher(newContent); 729 730 if (matcher.find()) { 731 String logClassName = matcher.group(1); 732 733 if (!logClassName.equals(className)) { 734 newContent = StringUtil.replaceLast( 735 newContent, logClassName + ".class)", 736 className + ".class)"); 737 } 738 } 739 740 if (!isExcluded(_staticLogVariableExclusions, absolutePath)) { 741 newContent = StringUtil.replace( 742 newContent, "private Log _log", 743 "private static final Log _log"); 744 } 745 746 if (newContent.contains("*/\npackage ")) { 747 processErrorMessage(fileName, "package: " + fileName); 748 } 749 750 if (portalSource && 751 !_allowUseServiceUtilInServiceImpl && 752 !className.equals("BaseServiceImpl") && 753 className.endsWith("ServiceImpl") && 754 newContent.contains("ServiceUtil.")) { 755 756 processErrorMessage(fileName, "ServiceUtil: " + fileName); 757 } 758 759 // LPS-34911 760 761 if (portalSource && 762 !isExcluded(_upgradeServiceUtilExclusions, absolutePath) && 763 fileName.contains("/portal/upgrade/") && 764 !fileName.contains("/test/") && 765 newContent.contains("ServiceUtil.")) { 766 767 processErrorMessage(fileName, "ServiceUtil: " + fileName); 768 } 769 770 if (!isRunsOutsidePortal(absolutePath) && 771 !isExcluded(_proxyExclusions, absolutePath) && 772 newContent.contains("import java.lang.reflect.Proxy;")) { 773 774 processErrorMessage(fileName, "Proxy: " + fileName); 775 } 776 777 if (newContent.contains("import edu.emory.mathcs.backport.java")) { 778 processErrorMessage( 779 fileName, "edu.emory.mathcs.backport.java: " + fileName); 780 } 781 782 if (newContent.contains("import jodd.util.StringPool")) { 783 processErrorMessage(fileName, "jodd.util.StringPool: " + fileName); 784 } 785 786 // LPS-45027 787 788 if (newContent.contains( 789 "com.liferay.portal.kernel.util.UnmodifiableList")) { 790 791 processErrorMessage( 792 fileName, 793 "Use java.util.Collections.unmodifiableList instead of " + 794 "com.liferay.portal.kernel.util.UnmodifiableList: " + 795 fileName); 796 } 797 798 // LPS-28266 799 800 for (int pos1 = -1;;) { 801 pos1 = newContent.indexOf(StringPool.TAB + "try {", pos1 + 1); 802 803 if (pos1 == -1) { 804 break; 805 } 806 807 int pos2 = newContent.indexOf(StringPool.TAB + "try {", pos1 + 1); 808 int pos3 = newContent.indexOf("\"select count(", pos1); 809 810 if ((pos2 != -1) && (pos3 != -1) && (pos2 < pos3)) { 811 continue; 812 } 813 814 int pos4 = newContent.indexOf("rs.getLong(1)", pos1); 815 int pos5 = newContent.indexOf(StringPool.TAB + "finally {", pos1); 816 817 if ((pos3 == -1) || (pos4 == -1) || (pos5 == -1)) { 818 break; 819 } 820 821 if ((pos3 < pos4) && (pos4 < pos5)) { 822 processErrorMessage( 823 fileName, "Use getInt(1) for count: " + fileName); 824 } 825 } 826 827 // LPS-33070 828 829 matcher = _processCallablePattern.matcher(content); 830 831 if (matcher.find() && 832 !content.contains("private static final long serialVersionUID")) { 833 834 processErrorMessage( 835 fileName, 836 "Assign ProcessCallable implementation a serialVersionUID: " + 837 fileName); 838 } 839 840 checkLanguageKeys(fileName, newContent, languageKeyPattern); 841 842 newContent = StringUtil.replace( 843 newContent, StringPool.TAB + "for (;;) {", 844 StringPool.TAB + "while (true) {"); 845 846 // LPS-36174 847 848 if (_checkUnprocessedExceptions && !fileName.contains("/test/")) { 849 checkUnprocessedExceptions(newContent, file, packagePath, fileName); 850 } 851 852 // LPS-39508 853 854 if (!isExcluded(_secureRandomExclusions, absolutePath) && 855 !isRunsOutsidePortal(absolutePath) && 856 content.contains("java.security.SecureRandom") && 857 !content.contains("javax.crypto.KeyGenerator")) { 858 859 processErrorMessage( 860 fileName, 861 "Use SecureRandomUtil or com.liferay.portal.kernel.security." + 862 "SecureRandom instead of java.security.SecureRandom: " + 863 fileName); 864 } 865 866 // LPS-41315 867 868 checkLogLevel(newContent, fileName, "debug"); 869 checkLogLevel(newContent, fileName, "info"); 870 checkLogLevel(newContent, fileName, "trace"); 871 checkLogLevel(newContent, fileName, "warn"); 872 873 // LPS-46632 874 875 checkSystemEventAnnotations(newContent, fileName); 876 877 // LPS-41205 878 879 if (fileName.contains("/upgrade/") && 880 newContent.contains("LocaleUtil.getDefault()")) { 881 882 processErrorMessage( 883 fileName, 884 "Use UpgradeProcessUtil.getDefaultLanguageId(companyId) " + 885 "instead of LocaleUtil.getDefault(): " + fileName); 886 } 887 888 // LPS-46017 889 890 newContent = StringUtil.replace( 891 newContent, " static interface ", " interface "); 892 893 // LPS-47055 894 895 newContent = fixSystemExceptions(newContent); 896 897 // LPS-47648 898 899 if (portalSource && fileName.contains("/test/integration/")) { 900 newContent = StringUtil.replace( 901 newContent, "FinderCacheUtil.clearCache();", StringPool.BLANK); 902 } 903 904 // LPS-47682 905 906 newContent = fixIncorrectParameterTypeForLanguageUtil( 907 newContent, false, fileName); 908 909 if (portalSource && fileName.contains("/portal-service/") && 910 content.contains("import javax.servlet.jsp.")) { 911 912 processErrorMessage( 913 fileName, 914 "Never import javax.servlet.jsp.* from portal-service " + 915 fileName); 916 } 917 918 // LPS-48153 919 920 //newContent = applyDiamondOperator(newContent); 921 922 // LPS-49552 923 924 checkFinderCacheInterfaceMethod(fileName, newContent); 925 926 newContent = fixIncorrectEmptyLineBeforeCloseCurlyBrace( 927 newContent, fileName); 928 929 pos = newContent.indexOf("\npublic "); 930 931 if (pos != -1) { 932 String javaClassContent = newContent.substring(pos + 1); 933 934 String beforeJavaClass = newContent.substring(0, pos + 1); 935 936 int javaClassLineCount = 937 StringUtil.count(beforeJavaClass, "\n") + 1; 938 939 newContent = formatJavaTerms( 940 className, packagePath, file, fileName, absolutePath, 941 newContent, javaClassContent, javaClassLineCount, 942 _checkJavaFieldTypesExclusions, 943 _javaTermAccessLevelModifierExclusions, _javaTermSortExclusions, 944 _testAnnotationsExclusions); 945 } 946 947 newContent = formatJava(fileName, absolutePath, newContent); 948 949 return StringUtil.replace(newContent, "\n\n\n", "\n\n"); 950 } 951 952 protected String fixDataAccessConnection(String className, String content) { 953 int x = content.indexOf("package "); 954 955 int y = content.indexOf(CharPool.SEMICOLON, x); 956 957 if ((x == -1) || (y == -1)) { 958 return content; 959 } 960 961 String packageName = content.substring(x + 8, y); 962 963 if (!packageName.startsWith("com.liferay.portal.kernel.upgrade") && 964 !packageName.startsWith("com.liferay.portal.kernel.verify") && 965 !packageName.startsWith("com.liferay.portal.upgrade") && 966 !packageName.startsWith("com.liferay.portal.verify")) { 967 968 return content; 969 } 970 971 content = StringUtil.replace( 972 content, "DataAccess.getConnection", 973 "DataAccess.getUpgradeOptimizedConnection"); 974 975 return content; 976 } 977 978 protected String fixIfClause(String ifClause, String line, int delta) { 979 String newLine = line; 980 981 String whiteSpace = StringPool.BLANK; 982 int whiteSpaceLength = Math.abs(delta); 983 984 while (whiteSpaceLength > 0) { 985 if (whiteSpaceLength >= 4) { 986 whiteSpace += StringPool.TAB; 987 988 whiteSpaceLength -= 4; 989 } 990 else { 991 whiteSpace += StringPool.SPACE; 992 993 whiteSpaceLength -= 1; 994 } 995 } 996 997 if (delta > 0) { 998 if (!line.contains(StringPool.TAB + whiteSpace)) { 999 newLine = StringUtil.replaceLast( 1000 newLine, StringPool.TAB, StringPool.FOUR_SPACES); 1001 } 1002 1003 newLine = StringUtil.replaceLast( 1004 newLine, StringPool.TAB + whiteSpace, StringPool.TAB); 1005 } 1006 else { 1007 newLine = StringUtil.replaceLast( 1008 newLine, StringPool.TAB, StringPool.TAB + whiteSpace); 1009 } 1010 1011 newLine = StringUtil.replaceLast( 1012 newLine, StringPool.FOUR_SPACES, StringPool.TAB); 1013 1014 return StringUtil.replace(ifClause, line, newLine); 1015 } 1016 1017 protected String fixIncorrectEmptyLineBeforeCloseCurlyBrace( 1018 String content, String fileName) { 1019 1020 Matcher matcher1 = _incorrectCloseCurlyBracePattern1.matcher(content); 1021 1022 while (matcher1.find()) { 1023 String lastLine = StringUtil.trimLeading(matcher1.group(1)); 1024 1025 if (lastLine.startsWith("// ")) { 1026 continue; 1027 } 1028 1029 String tabs = matcher1.group(2); 1030 int tabCount = tabs.length(); 1031 1032 int pos = matcher1.start(); 1033 1034 while (true) { 1035 pos = content.lastIndexOf("\n" + tabs, pos - 1); 1036 1037 if (content.charAt(pos + tabCount + 1) == CharPool.TAB) { 1038 continue; 1039 } 1040 1041 String codeBlock = content.substring(pos + 1, matcher1.end()); 1042 1043 String firstLine = codeBlock.substring( 1044 0, codeBlock.indexOf("\n")); 1045 1046 Matcher matcher2 = _incorrectCloseCurlyBracePattern2.matcher( 1047 firstLine); 1048 1049 if (matcher2.find()) { 1050 break; 1051 } 1052 1053 return StringUtil.replaceFirst( 1054 content, "\n\n" + tabs + "}\n", "\n" + tabs + "}\n", pos); 1055 } 1056 } 1057 1058 return content; 1059 } 1060 1061 protected String fixSystemExceptions(String content) { 1062 Matcher matcher = _throwsSystemExceptionPattern.matcher(content); 1063 1064 if (!matcher.find()) { 1065 return content; 1066 } 1067 1068 String match = matcher.group(); 1069 String replacement = null; 1070 1071 String afterException = matcher.group(3); 1072 String beforeException = matcher.group(2); 1073 1074 if (Validator.isNull(beforeException) && 1075 Validator.isNull(afterException)) { 1076 1077 replacement = matcher.group(4); 1078 1079 String beforeThrows = matcher.group(1); 1080 1081 if (Validator.isNotNull(StringUtil.trim(beforeThrows))) { 1082 replacement = beforeThrows + replacement; 1083 } 1084 } 1085 else if (Validator.isNull(beforeException)) { 1086 replacement = StringUtil.replaceFirst( 1087 match, "SystemException, ", StringPool.BLANK); 1088 } 1089 else { 1090 replacement = StringUtil.replaceFirst( 1091 match, ", SystemException", StringPool.BLANK); 1092 } 1093 1094 if (match.equals(replacement)) { 1095 return content; 1096 } 1097 1098 return fixSystemExceptions( 1099 StringUtil.replaceFirst(content, match, replacement)); 1100 } 1101 1102 @Override 1103 protected void format() throws Exception { 1104 Collection<String> fileNames = null; 1105 1106 if (portalSource) { 1107 fileNames = getPortalJavaFiles(); 1108 1109 _checkUnprocessedExceptions = GetterUtil.getBoolean( 1110 System.getProperty( 1111 "source.formatter.check.unprocessed.exceptions")); 1112 } 1113 else { 1114 fileNames = getPluginJavaFiles(); 1115 } 1116 1117 _addMissingDeprecationReleaseVersion = GetterUtil.getBoolean( 1118 getProperty("add.missing.deprecation.release.version")); 1119 _allowUseServiceUtilInServiceImpl = GetterUtil.getBoolean( 1120 getProperty("allow.use.service.util.in.service.impl")); 1121 _checkJavaFieldTypesExclusions = getPropertyList( 1122 "check.java.field.types.excludes.files"); 1123 _fitOnSingleLineExclusions = getPropertyList( 1124 "fit.on.single.line.excludes.files"); 1125 _hibernateSQLQueryExclusions = getPropertyList( 1126 "hibernate.sql.query.excludes.files"); 1127 _javaTermAccessLevelModifierExclusions = getPropertyList( 1128 "javaterm.access.level.modifier.excludes.files"); 1129 _javaTermSortExclusions = getPropertyList( 1130 "javaterm.sort.excludes.files"); 1131 _lineLengthExclusions = getPropertyList("line.length.excludes.files"); 1132 _proxyExclusions = getPropertyList("proxy.excludes.files"); 1133 _secureRandomExclusions = getPropertyList( 1134 "secure.random.excludes.files"); 1135 _staticLogVariableExclusions = getPropertyList( 1136 "static.log.excludes.files"); 1137 _testAnnotationsExclusions = getPropertyList( 1138 "test.annotations.excludes.files"); 1139 _upgradeServiceUtilExclusions = getPropertyList( 1140 "upgrade.service.util.excludes.files"); 1141 1142 for (String fileName : fileNames) { 1143 format(fileName); 1144 } 1145 } 1146 1147 protected String formatJava( 1148 String fileName, String absolutePath, String content) 1149 throws Exception { 1150 1151 StringBundler sb = new StringBundler(); 1152 1153 try (UnsyncBufferedReader unsyncBufferedReader = 1154 new UnsyncBufferedReader(new UnsyncStringReader(content))) { 1155 1156 String line = null; 1157 String previousLine = StringPool.BLANK; 1158 1159 int lineCount = 0; 1160 1161 String ifClause = StringPool.BLANK; 1162 String packageName = StringPool.BLANK; 1163 String regexPattern = StringPool.BLANK; 1164 1165 while ((line = unsyncBufferedReader.readLine()) != null) { 1166 lineCount++; 1167 1168 line = trimLine(line, false); 1169 1170 if (line.startsWith("package ")) { 1171 packageName = line.substring(8, line.length() - 1); 1172 } 1173 1174 if (line.startsWith("import ")) { 1175 if (line.endsWith(".*;")) { 1176 processErrorMessage( 1177 fileName, "import: " + fileName + " " + lineCount); 1178 } 1179 1180 int pos = line.lastIndexOf(StringPool.PERIOD); 1181 1182 if (pos != -1) { 1183 String importPackageName = line.substring(7, pos); 1184 1185 if (importPackageName.equals(packageName)) { 1186 continue; 1187 } 1188 } 1189 } 1190 1191 if (line.contains(StringPool.TAB + "for (") && 1192 line.contains(":") && !line.contains(" :")) { 1193 1194 line = StringUtil.replace(line, ":" , " :"); 1195 } 1196 1197 // LPS-42924 1198 1199 if (line.contains("PortalUtil.getClassNameId(") && 1200 fileName.endsWith("ServiceImpl.java")) { 1201 1202 processErrorMessage( 1203 fileName, 1204 "Use classNameLocalService.getClassNameId: " + 1205 fileName + " " + lineCount); 1206 } 1207 1208 // LPS-42599 1209 1210 if (!isExcluded(_hibernateSQLQueryExclusions, absolutePath) && 1211 line.contains("= session.createSQLQuery(") && 1212 content.contains( 1213 "com.liferay.portal.kernel.dao.orm.Session")) { 1214 1215 line = StringUtil.replace( 1216 line, "createSQLQuery", "createSynchronizedSQLQuery"); 1217 } 1218 1219 line = replacePrimitiveWrapperInstantiation( 1220 fileName, line, lineCount); 1221 1222 String trimmedLine = StringUtil.trimLeading(line); 1223 1224 // LPS-45649 1225 1226 if (trimmedLine.startsWith("throw new IOException(") && 1227 line.contains("e.getMessage()")) { 1228 1229 line = StringUtil.replace( 1230 line, ".getMessage()", StringPool.BLANK); 1231 } 1232 1233 // LPS-45492 1234 1235 if (trimmedLine.contains("StopWatch stopWatch = null;")) { 1236 processErrorMessage( 1237 fileName, 1238 "Do not set stopwatch to null: " + fileName + " " + 1239 lineCount); 1240 } 1241 1242 checkStringBundler(trimmedLine, fileName, lineCount); 1243 1244 checkEmptyCollection(trimmedLine, fileName, lineCount); 1245 1246 if (trimmedLine.startsWith("* @deprecated") && 1247 _addMissingDeprecationReleaseVersion) { 1248 1249 if (!trimmedLine.startsWith("* @deprecated As of ")) { 1250 line = StringUtil.replace( 1251 line, "* @deprecated", 1252 "* @deprecated As of " + getMainReleaseVersion()); 1253 } 1254 else { 1255 String version = trimmedLine.substring(20); 1256 1257 version = StringUtil.split( 1258 version, StringPool.SPACE)[0]; 1259 1260 version = StringUtil.replace( 1261 version, StringPool.COMMA, StringPool.BLANK); 1262 1263 if (StringUtil.count(version, StringPool.PERIOD) == 1) { 1264 line = StringUtil.replaceFirst( 1265 line, version, version + ".0"); 1266 } 1267 } 1268 } 1269 1270 if (trimmedLine.startsWith("* @see ") && 1271 (StringUtil.count(trimmedLine, StringPool.AT) > 1)) { 1272 1273 processErrorMessage( 1274 fileName, 1275 "Do not use @see with another annotation: " + fileName + 1276 " " + lineCount); 1277 } 1278 1279 checkInefficientStringMethods( 1280 line, fileName, absolutePath, lineCount); 1281 1282 if (trimmedLine.startsWith(StringPool.EQUAL)) { 1283 processErrorMessage( 1284 fileName, "line break: " + fileName + " " + lineCount); 1285 } 1286 1287 if (line.contains("ActionForm form")) { 1288 processErrorMessage( 1289 fileName, 1290 "Rename form to actionForm: " + fileName + " " + 1291 lineCount); 1292 } 1293 1294 if (line.contains("ActionMapping mapping")) { 1295 processErrorMessage( 1296 fileName, 1297 "Rename mapping to ActionMapping: " + fileName + " " + 1298 lineCount); 1299 } 1300 1301 if (fileName.contains("/upgrade/") && 1302 line.contains("rs.getDate(")) { 1303 1304 processErrorMessage( 1305 fileName, 1306 "Use rs.getTimeStamp: " + fileName + " " + lineCount); 1307 } 1308 1309 if (!trimmedLine.equals("{") && line.endsWith("{") && 1310 !line.endsWith(" {")) { 1311 1312 line = StringUtil.replaceLast(line, "{", " {"); 1313 } 1314 1315 line = sortExceptions(line); 1316 1317 if (trimmedLine.startsWith("Pattern ") || 1318 Validator.isNotNull(regexPattern)) { 1319 1320 regexPattern = regexPattern + trimmedLine; 1321 1322 if (trimmedLine.endsWith(");")) { 1323 1324 // LPS-41084 1325 1326 checkRegexPattern(regexPattern, fileName, lineCount); 1327 1328 regexPattern = StringPool.BLANK; 1329 } 1330 } 1331 1332 if (!trimmedLine.startsWith(StringPool.DOUBLE_SLASH) && 1333 !trimmedLine.startsWith(StringPool.STAR)) { 1334 1335 String strippedQuotesLine = stripQuotes( 1336 trimmedLine, CharPool.QUOTE); 1337 1338 for (int x = 0;;) { 1339 x = strippedQuotesLine.indexOf(StringPool.EQUAL, x + 1); 1340 1341 if (x == -1) { 1342 break; 1343 } 1344 1345 char c = strippedQuotesLine.charAt(x - 1); 1346 1347 if (Character.isLetterOrDigit(c)) { 1348 line = StringUtil.replace(line, c + "=", c + " ="); 1349 1350 break; 1351 } 1352 1353 if (x == (strippedQuotesLine.length() - 1)) { 1354 break; 1355 } 1356 1357 c = strippedQuotesLine.charAt(x + 1); 1358 1359 if (Character.isLetterOrDigit(c)) { 1360 line = StringUtil.replace(line, "=" + c, "= " + c); 1361 1362 break; 1363 } 1364 } 1365 1366 if (!line.contains(StringPool.DOUBLE_SLASH)) { 1367 while (trimmedLine.contains(StringPool.TAB)) { 1368 line = StringUtil.replaceLast( 1369 line, StringPool.TAB, StringPool.SPACE); 1370 1371 trimmedLine = StringUtil.replaceLast( 1372 trimmedLine, StringPool.TAB, StringPool.SPACE); 1373 } 1374 } 1375 1376 if (line.contains(StringPool.TAB + StringPool.SPACE) && 1377 !previousLine.endsWith("&&") && 1378 !previousLine.endsWith("||") && 1379 !previousLine.contains(StringPool.TAB + "((") && 1380 !previousLine.contains( 1381 StringPool.TAB + StringPool.LESS_THAN) && 1382 !previousLine.contains( 1383 StringPool.TAB + StringPool.SPACE) && 1384 !previousLine.contains(StringPool.TAB + "for (") && 1385 !previousLine.contains( 1386 StringPool.TAB + "implements ") && 1387 !previousLine.contains(StringPool.TAB + "throws ")) { 1388 1389 line = StringUtil.replace( 1390 line, StringPool.TAB + StringPool.SPACE, 1391 StringPool.TAB); 1392 } 1393 1394 if (line.contains(StringPool.SPACE + StringPool.TAB)) { 1395 line = StringUtil.replace( 1396 line, StringPool.SPACE + StringPool.TAB, 1397 StringPool.TAB); 1398 } 1399 1400 while (trimmedLine.contains(StringPool.DOUBLE_SPACE) && 1401 !trimmedLine.contains( 1402 StringPool.QUOTE + StringPool.DOUBLE_SPACE) && 1403 !fileName.contains("Test")) { 1404 1405 line = StringUtil.replaceLast( 1406 line, StringPool.DOUBLE_SPACE, StringPool.SPACE); 1407 1408 trimmedLine = StringUtil.replaceLast( 1409 trimmedLine, StringPool.DOUBLE_SPACE, 1410 StringPool.SPACE); 1411 } 1412 1413 if (!line.contains(StringPool.AT) && 1414 !line.contains(StringPool.DOUBLE_SLASH) && 1415 !line.contains(StringPool.QUOTE)) { 1416 1417 int pos = line.indexOf(") "); 1418 1419 if (pos != -1) { 1420 String linePart = line.substring(pos + 2); 1421 1422 if (Character.isLetter(linePart.charAt(0)) && 1423 !linePart.startsWith("default") && 1424 !linePart.startsWith("instanceof") && 1425 !linePart.startsWith("throws")) { 1426 1427 line = StringUtil.replaceLast( 1428 line, StringPool.SPACE + linePart, 1429 linePart); 1430 } 1431 } 1432 1433 if ((trimmedLine.startsWith("private ") || 1434 trimmedLine.startsWith("protected ") || 1435 trimmedLine.startsWith("public ")) && 1436 !line.contains(StringPool.EQUAL) && 1437 line.contains(" (")) { 1438 1439 line = StringUtil.replace(line, " (", "("); 1440 } 1441 1442 if (line.contains(" [")) { 1443 line = StringUtil.replace(line, " [", "["); 1444 } 1445 1446 for (int x = -1;;) { 1447 int posComma = line.indexOf( 1448 StringPool.COMMA, x + 1); 1449 int posSemicolon = line.indexOf( 1450 StringPool.SEMICOLON, x + 1); 1451 1452 if ((posComma == -1) && (posSemicolon == -1)) { 1453 break; 1454 } 1455 1456 x = Math.min(posComma, posSemicolon); 1457 1458 if (x == -1) { 1459 x = Math.max(posComma, posSemicolon); 1460 } 1461 1462 if (line.length() > (x + 1)) { 1463 char nextChar = line.charAt(x + 1); 1464 1465 if ((nextChar != CharPool.APOSTROPHE) && 1466 (nextChar != CharPool.CLOSE_PARENTHESIS) && 1467 (nextChar != CharPool.SPACE) && 1468 (nextChar != CharPool.STAR)) { 1469 1470 line = StringUtil.insert( 1471 line, StringPool.SPACE, x + 1); 1472 } 1473 } 1474 1475 if (x > 0) { 1476 char previousChar = line.charAt(x - 1); 1477 1478 if (previousChar == CharPool.SPACE) { 1479 line = line.substring(0, x - 1).concat( 1480 line.substring(x)); 1481 } 1482 } 1483 } 1484 } 1485 1486 if ((line.contains(" && ") || line.contains(" || ")) && 1487 line.endsWith(StringPool.OPEN_PARENTHESIS)) { 1488 1489 processErrorMessage( 1490 fileName, "line break: " + fileName + " " + 1491 lineCount); 1492 } 1493 1494 if (trimmedLine.endsWith(StringPool.PLUS) && 1495 !trimmedLine.startsWith(StringPool.OPEN_PARENTHESIS)) { 1496 1497 int closeParenthesisCount = StringUtil.count( 1498 strippedQuotesLine, StringPool.CLOSE_PARENTHESIS); 1499 int openParenthesisCount = StringUtil.count( 1500 strippedQuotesLine, StringPool.OPEN_PARENTHESIS); 1501 1502 if (openParenthesisCount > closeParenthesisCount) { 1503 processErrorMessage( 1504 fileName, 1505 "line break: " + fileName + " " + lineCount); 1506 } 1507 } 1508 1509 int x = strippedQuotesLine.indexOf(", "); 1510 1511 if (x != -1) { 1512 String linePart = strippedQuotesLine.substring(0, x); 1513 1514 int closeParenthesisCount = StringUtil.count( 1515 linePart, StringPool.CLOSE_PARENTHESIS); 1516 int openParenthesisCount = StringUtil.count( 1517 linePart, StringPool.OPEN_PARENTHESIS); 1518 1519 if (closeParenthesisCount > openParenthesisCount) { 1520 processErrorMessage( 1521 fileName, 1522 "line break: " + fileName + " " + lineCount); 1523 } 1524 } 1525 else if (trimmedLine.endsWith(StringPool.COMMA) && 1526 !trimmedLine.startsWith("for (")) { 1527 1528 int closeParenthesisCount = StringUtil.count( 1529 strippedQuotesLine, StringPool.CLOSE_PARENTHESIS); 1530 int openParenthesisCount = StringUtil.count( 1531 strippedQuotesLine, StringPool.OPEN_PARENTHESIS); 1532 1533 if (closeParenthesisCount < openParenthesisCount) { 1534 processErrorMessage( 1535 fileName, 1536 "line break: " + fileName + " " + lineCount); 1537 } 1538 } 1539 1540 if (line.contains(StringPool.COMMA) && 1541 !line.contains(StringPool.CLOSE_PARENTHESIS) && 1542 !line.contains(StringPool.GREATER_THAN) && 1543 !line.contains(StringPool.QUOTE) && 1544 line.endsWith(StringPool.OPEN_PARENTHESIS)) { 1545 1546 processErrorMessage( 1547 fileName, "line break: " + fileName + " " + 1548 lineCount); 1549 } 1550 1551 if (line.endsWith(" +") || line.endsWith(" -") || 1552 line.endsWith(" *") || line.endsWith(" /")) { 1553 1554 x = line.indexOf(" = "); 1555 1556 if (x != -1) { 1557 int y = line.indexOf(StringPool.QUOTE); 1558 1559 if ((y == -1) || (x < y)) { 1560 processErrorMessage( 1561 fileName, 1562 "line break: " + fileName + " " + 1563 lineCount); 1564 } 1565 } 1566 } 1567 1568 if (line.endsWith(" throws") || 1569 (previousLine.endsWith( 1570 StringPool.OPEN_PARENTHESIS) && 1571 line.contains(" throws " ) && 1572 line.endsWith(StringPool.OPEN_CURLY_BRACE))) { 1573 1574 processErrorMessage( 1575 fileName, "line break: " + fileName + " " + 1576 lineCount); 1577 } 1578 1579 if (trimmedLine.startsWith(StringPool.PERIOD) || 1580 (line.endsWith(StringPool.PERIOD) && 1581 line.contains(StringPool.EQUAL))) { 1582 1583 processErrorMessage( 1584 fileName, "line break: " + fileName + " " + 1585 lineCount); 1586 } 1587 1588 if (trimmedLine.startsWith(StringPool.CLOSE_CURLY_BRACE) && 1589 line.endsWith(StringPool.OPEN_CURLY_BRACE)) { 1590 1591 Matcher matcher = _lineBreakPattern.matcher( 1592 trimmedLine); 1593 1594 if (!matcher.find()) { 1595 processErrorMessage( 1596 fileName, "line break: " + fileName + " " + 1597 lineCount); 1598 } 1599 } 1600 } 1601 1602 if (line.contains(" ") && !line.matches("\\s*\\*.*")) { 1603 if (!fileName.endsWith("StringPool.java")) { 1604 processErrorMessage( 1605 fileName, "tab: " + fileName + " " + lineCount); 1606 } 1607 } 1608 1609 if (line.contains(" {") && !line.matches("\\s*\\*.*")) { 1610 processErrorMessage( 1611 fileName, "{:" + fileName + " " + lineCount); 1612 } 1613 1614 if (trimmedLine.startsWith("if (") || 1615 trimmedLine.startsWith("else if (") || 1616 trimmedLine.startsWith("while (") || 1617 Validator.isNotNull(ifClause)) { 1618 1619 ifClause = ifClause + line + StringPool.NEW_LINE; 1620 1621 if (line.endsWith(") {")) { 1622 String newIfClause = checkIfClause( 1623 ifClause, fileName, lineCount); 1624 1625 if (!ifClause.equals(newIfClause) && 1626 content.contains(ifClause)) { 1627 1628 return StringUtil.replace( 1629 content, ifClause, newIfClause); 1630 } 1631 1632 ifClause = StringPool.BLANK; 1633 } 1634 else if (line.endsWith(StringPool.SEMICOLON)) { 1635 ifClause = StringPool.BLANK; 1636 } 1637 } 1638 1639 int lineLength = getLineLength(line); 1640 1641 if (!line.startsWith("import ") && 1642 !line.startsWith("package ") && 1643 !line.matches("\\s*\\*.*")) { 1644 1645 if (fileName.endsWith("Table.java") && 1646 line.contains("String TABLE_SQL_CREATE = ")) { 1647 } 1648 else if (fileName.endsWith("Table.java") && 1649 line.contains("String TABLE_SQL_DROP = ")) { 1650 } 1651 else if (fileName.endsWith("Table.java") && 1652 line.contains(" index IX_")) { 1653 } 1654 else if (lineLength > _MAX_LINE_LENGTH) { 1655 if (!isExcluded( 1656 _lineLengthExclusions, absolutePath, 1657 lineCount) && 1658 !isAnnotationParameter(content, trimmedLine)) { 1659 1660 String truncateLongLinesContent = 1661 getTruncateLongLinesContent( 1662 content, line, trimmedLine, lineCount); 1663 1664 if (truncateLongLinesContent != null) { 1665 return truncateLongLinesContent; 1666 } 1667 1668 processErrorMessage( 1669 fileName, "> 80: " + fileName + " " + 1670 lineCount); 1671 } 1672 } 1673 else { 1674 int lineLeadingTabCount = getLeadingTabCount(line); 1675 int previousLineLeadingTabCount = getLeadingTabCount( 1676 previousLine); 1677 1678 if (!trimmedLine.startsWith("//")) { 1679 if (previousLine.endsWith(StringPool.COMMA) && 1680 previousLine.contains( 1681 StringPool.OPEN_PARENTHESIS) && 1682 !previousLine.contains("for (") && 1683 (lineLeadingTabCount > 1684 previousLineLeadingTabCount)) { 1685 1686 processErrorMessage( 1687 fileName, 1688 "line break: " + fileName + " " + 1689 lineCount); 1690 } 1691 1692 if ((lineLeadingTabCount == 1693 previousLineLeadingTabCount) && 1694 (previousLine.endsWith(StringPool.EQUAL) || 1695 previousLine.endsWith( 1696 StringPool.OPEN_PARENTHESIS))) { 1697 1698 processErrorMessage( 1699 fileName, "tab: " + fileName + " " + 1700 lineCount); 1701 } 1702 1703 if (Validator.isNotNull(trimmedLine)) { 1704 if (((previousLine.endsWith(StringPool.COLON) && 1705 previousLine.contains( 1706 StringPool.TAB + "for ")) || 1707 (previousLine.endsWith( 1708 StringPool.OPEN_PARENTHESIS) && 1709 previousLine.contains( 1710 StringPool.TAB + "if "))) && 1711 ((previousLineLeadingTabCount + 2) != 1712 lineLeadingTabCount)) { 1713 1714 processErrorMessage( 1715 fileName, 1716 "line break: " + fileName + " " + 1717 lineCount); 1718 } 1719 1720 if (previousLine.endsWith( 1721 StringPool.OPEN_CURLY_BRACE) && 1722 !trimmedLine.startsWith( 1723 StringPool.CLOSE_CURLY_BRACE) && 1724 ((previousLineLeadingTabCount + 1) != 1725 lineLeadingTabCount)) { 1726 1727 processErrorMessage( 1728 fileName, 1729 "tab: " + fileName + " " + lineCount); 1730 } 1731 } 1732 1733 if (previousLine.endsWith(StringPool.PERIOD)) { 1734 int x = trimmedLine.indexOf( 1735 StringPool.OPEN_PARENTHESIS); 1736 1737 if ((x != -1) && 1738 ((getLineLength(previousLine) + x) < 1739 _MAX_LINE_LENGTH) && 1740 (trimmedLine.endsWith( 1741 StringPool.OPEN_PARENTHESIS) || 1742 (trimmedLine.charAt(x + 1) != 1743 CharPool.CLOSE_PARENTHESIS))) { 1744 1745 processErrorMessage( 1746 fileName, 1747 "line break: " + fileName + " " + 1748 lineCount); 1749 } 1750 } 1751 1752 int diff = 1753 lineLeadingTabCount - 1754 previousLineLeadingTabCount; 1755 1756 if (trimmedLine.startsWith("throws ") && 1757 ((diff == 0) || (diff > 1))) { 1758 1759 processErrorMessage( 1760 fileName, "tab: " + fileName + " " + 1761 lineCount); 1762 } 1763 1764 if ((diff == 2) && 1765 (previousLineLeadingTabCount > 0) && 1766 line.endsWith(StringPool.SEMICOLON) && 1767 !previousLine.contains( 1768 StringPool.TAB + "for (") && 1769 !previousLine.contains( 1770 StringPool.TAB + "try (")) { 1771 1772 line = StringUtil.replaceFirst( 1773 line, StringPool.TAB, StringPool.BLANK); 1774 } 1775 1776 if ((previousLine.contains(" class " ) || 1777 previousLine.contains(" enum ")) && 1778 previousLine.endsWith( 1779 StringPool.OPEN_CURLY_BRACE) && 1780 Validator.isNotNull(line) && 1781 !trimmedLine.startsWith( 1782 StringPool.CLOSE_CURLY_BRACE)) { 1783 1784 processErrorMessage( 1785 fileName, 1786 "line break: " + fileName + " " + 1787 lineCount); 1788 } 1789 } 1790 1791 String combinedLinesContent = getCombinedLinesContent( 1792 content, fileName, absolutePath, line, trimmedLine, 1793 lineLength, lineCount, previousLine, 1794 lineLeadingTabCount, previousLineLeadingTabCount); 1795 1796 if ((combinedLinesContent != null) && 1797 !combinedLinesContent.equals(content)) { 1798 1799 return combinedLinesContent; 1800 } 1801 } 1802 } 1803 1804 if (lineCount > 1) { 1805 sb.append(previousLine); 1806 1807 if (Validator.isNotNull(previousLine) && 1808 Validator.isNotNull(trimmedLine) && 1809 !previousLine.contains("/*") && 1810 !previousLine.endsWith("*/")) { 1811 1812 String trimmedPreviousLine = StringUtil.trimLeading( 1813 previousLine); 1814 1815 if ((trimmedPreviousLine.startsWith("// ") && 1816 !trimmedLine.startsWith("// ")) || 1817 (!trimmedPreviousLine.startsWith("// ") && 1818 trimmedLine.startsWith("// "))) { 1819 1820 sb.append("\n"); 1821 } 1822 else if (!trimmedPreviousLine.endsWith( 1823 StringPool.OPEN_CURLY_BRACE) && 1824 !trimmedPreviousLine.endsWith( 1825 StringPool.COLON) && 1826 (trimmedLine.startsWith("for (") || 1827 trimmedLine.startsWith("if (") || 1828 trimmedLine.startsWith("try {"))) { 1829 1830 sb.append("\n"); 1831 } 1832 else if (previousLine.endsWith( 1833 StringPool.TAB + 1834 StringPool.CLOSE_CURLY_BRACE) && 1835 !trimmedLine.startsWith( 1836 StringPool.CLOSE_CURLY_BRACE) && 1837 !trimmedLine.startsWith( 1838 StringPool.CLOSE_PARENTHESIS) && 1839 !trimmedLine.startsWith( 1840 StringPool.DOUBLE_SLASH) && 1841 !trimmedLine.equals("*/") && 1842 !trimmedLine.startsWith("catch ") && 1843 !trimmedLine.startsWith("else ") && 1844 !trimmedLine.startsWith("finally ") && 1845 !trimmedLine.startsWith("while ")) { 1846 1847 sb.append("\n"); 1848 } 1849 } 1850 1851 sb.append("\n"); 1852 } 1853 1854 previousLine = line; 1855 } 1856 1857 sb.append(previousLine); 1858 } 1859 1860 String newContent = sb.toString(); 1861 1862 if (newContent.endsWith("\n")) { 1863 newContent = newContent.substring(0, newContent.length() - 1); 1864 } 1865 1866 return newContent; 1867 } 1868 1869 protected String getCombinedLinesContent( 1870 String content, String fileName, String line, String trimmedLine, 1871 int lineLength, int lineCount, String previousLine, String linePart, 1872 int tabDiff, boolean addToPreviousLine, boolean extraSpace, 1873 boolean removeTabOnNextLine) { 1874 1875 if (linePart == null) { 1876 String combinedLine = previousLine; 1877 1878 if (extraSpace) { 1879 combinedLine += StringPool.SPACE; 1880 } 1881 1882 combinedLine += trimmedLine; 1883 1884 String nextLine = getNextLine(content, lineCount); 1885 1886 if (nextLine == null) { 1887 return null; 1888 } 1889 1890 if (removeTabOnNextLine) { 1891 return StringUtil.replace( 1892 content, 1893 "\n" + previousLine + "\n" + line + "\n" + nextLine + "\n", 1894 "\n" + combinedLine + "\n" + nextLine.substring(1) + "\n"); 1895 } 1896 1897 if (line.endsWith(StringPool.OPEN_CURLY_BRACE) && 1898 (tabDiff != 0) && !previousLine.contains(" class ") && 1899 Validator.isNull(nextLine)) { 1900 1901 return StringUtil.replace( 1902 content, "\n" + previousLine + "\n" + line + "\n", 1903 "\n" + combinedLine); 1904 } 1905 1906 return StringUtil.replace( 1907 content, "\n" + previousLine + "\n" + line + "\n", 1908 "\n" + combinedLine + "\n"); 1909 } 1910 1911 String firstLine = previousLine; 1912 String secondLine = line; 1913 1914 if (addToPreviousLine) { 1915 if (extraSpace) { 1916 firstLine += StringPool.SPACE; 1917 } 1918 1919 firstLine += linePart; 1920 1921 secondLine = StringUtil.replaceFirst( 1922 line, linePart, StringPool.BLANK); 1923 } 1924 else { 1925 if (((linePart.length() + lineLength) <= _MAX_LINE_LENGTH) && 1926 (line.endsWith(StringPool.OPEN_CURLY_BRACE) || 1927 line.endsWith(StringPool.SEMICOLON))) { 1928 1929 firstLine = StringUtil.replaceLast( 1930 firstLine, StringUtil.trim(linePart), StringPool.BLANK); 1931 1932 secondLine = StringUtil.replaceLast( 1933 line, StringPool.TAB, StringPool.TAB + linePart); 1934 } 1935 else { 1936 processErrorMessage( 1937 fileName, "line break: " + fileName + " " + lineCount); 1938 1939 return null; 1940 } 1941 } 1942 1943 firstLine = StringUtil.trimTrailing(firstLine); 1944 1945 return StringUtil.replace( 1946 content, "\n" + previousLine + "\n" + line + "\n", 1947 "\n" + firstLine + "\n" + secondLine + "\n"); 1948 } 1949 1950 protected String getCombinedLinesContent( 1951 String content, String fileName, String absolutePath, String line, 1952 String trimmedLine, int lineLength, int lineCount, String previousLine, 1953 int lineTabCount, int previousLineTabCount) { 1954 1955 if (Validator.isNull(line) || Validator.isNull(previousLine) || 1956 isExcluded(_fitOnSingleLineExclusions, absolutePath, lineCount)) { 1957 1958 return null; 1959 } 1960 1961 String trimmedPreviousLine = StringUtil.trimLeading(previousLine); 1962 1963 if (line.contains("// ") || line.contains("*/") || 1964 line.contains("*/") || previousLine.contains("// ") || 1965 previousLine.contains("*/") || previousLine.contains("*/")) { 1966 1967 return null; 1968 } 1969 1970 int tabDiff = lineTabCount - previousLineTabCount; 1971 1972 if (previousLine.endsWith(" extends")) { 1973 return getCombinedLinesContent( 1974 content, fileName, line, trimmedLine, lineLength, lineCount, 1975 previousLine, "extends", tabDiff, false, false, false); 1976 } 1977 1978 if (previousLine.endsWith(" implements")) { 1979 return getCombinedLinesContent( 1980 content, fileName, line, trimmedLine, lineLength, lineCount, 1981 previousLine, "implements ", tabDiff, false, false, false); 1982 } 1983 1984 if (trimmedLine.startsWith("+ ") || trimmedLine.startsWith("- ") || 1985 trimmedLine.startsWith("|| ") || trimmedLine.startsWith("&& ")) { 1986 1987 int pos = trimmedLine.indexOf(StringPool.SPACE); 1988 1989 String linePart = trimmedLine.substring(0, pos); 1990 1991 return getCombinedLinesContent( 1992 content, fileName, line, trimmedLine, lineLength, lineCount, 1993 previousLine, linePart, tabDiff, true, true, false); 1994 } 1995 1996 int previousLineLength = getLineLength(previousLine); 1997 1998 if ((trimmedLine.length() + previousLineLength) < _MAX_LINE_LENGTH) { 1999 if (trimmedPreviousLine.startsWith("for ") && 2000 previousLine.endsWith(StringPool.COLON) && 2001 line.endsWith(StringPool.OPEN_CURLY_BRACE)) { 2002 2003 return getCombinedLinesContent( 2004 content, fileName, line, trimmedLine, lineLength, lineCount, 2005 previousLine, null, tabDiff, false, true, false); 2006 } 2007 2008 if (line.endsWith(StringPool.SEMICOLON) && 2009 !previousLine.endsWith(StringPool.COLON) && 2010 !previousLine.endsWith(StringPool.OPEN_BRACKET) && 2011 !previousLine.endsWith(StringPool.OPEN_CURLY_BRACE) && 2012 !previousLine.endsWith(StringPool.OPEN_PARENTHESIS) && 2013 !previousLine.endsWith(StringPool.PERIOD) && 2014 (lineTabCount == (previousLineTabCount + 1))) { 2015 2016 return getCombinedLinesContent( 2017 content, fileName, line, trimmedLine, lineLength, lineCount, 2018 previousLine, null, tabDiff, false, true, false); 2019 } 2020 2021 if ((trimmedPreviousLine.startsWith("if ") || 2022 trimmedPreviousLine.startsWith("else ")) && 2023 (previousLine.endsWith("||") || previousLine.endsWith("&&")) && 2024 line.endsWith(StringPool.OPEN_CURLY_BRACE)) { 2025 2026 return getCombinedLinesContent( 2027 content, fileName, line, trimmedLine, lineLength, lineCount, 2028 previousLine, null, tabDiff, false, true, false); 2029 } 2030 2031 if ((trimmedLine.startsWith("extends ") || 2032 trimmedLine.startsWith("implements ") || 2033 trimmedLine.startsWith("throws")) && 2034 (line.endsWith(StringPool.OPEN_CURLY_BRACE) || 2035 line.endsWith(StringPool.SEMICOLON)) && 2036 (lineTabCount == (previousLineTabCount + 1))) { 2037 2038 return getCombinedLinesContent( 2039 content, fileName, line, trimmedLine, lineLength, lineCount, 2040 previousLine, null, tabDiff, false, true, false); 2041 } 2042 2043 if (previousLine.endsWith(StringPool.EQUAL)) { 2044 if (line.endsWith(StringPool.OPEN_CURLY_BRACE)) { 2045 processErrorMessage( 2046 fileName, "line break: " + fileName + " " + lineCount); 2047 } 2048 else if (line.endsWith(StringPool.OPEN_PARENTHESIS)) { 2049 String nextLine = getNextLine(content, lineCount); 2050 2051 if (nextLine.endsWith(StringPool.SEMICOLON)) { 2052 return getCombinedLinesContent( 2053 content, fileName, line, trimmedLine, lineLength, 2054 lineCount, previousLine, null, tabDiff, false, true, 2055 true); 2056 } 2057 } 2058 } 2059 } 2060 2061 if (((trimmedLine.length() + previousLineLength) <= _MAX_LINE_LENGTH) && 2062 (previousLine.endsWith(StringPool.OPEN_BRACKET) || 2063 previousLine.endsWith(StringPool.OPEN_PARENTHESIS) || 2064 previousLine.endsWith(StringPool.PERIOD)) && 2065 line.endsWith(StringPool.SEMICOLON)) { 2066 2067 return getCombinedLinesContent( 2068 content, fileName, line, trimmedLine, lineLength, lineCount, 2069 previousLine, null, tabDiff, false, false, false); 2070 } 2071 2072 if (previousLine.endsWith(StringPool.EQUAL) && 2073 line.endsWith(StringPool.SEMICOLON)) { 2074 2075 String tempLine = trimmedLine; 2076 2077 for (int pos = 0;;) { 2078 pos = tempLine.indexOf(StringPool.DASH); 2079 2080 if (pos == -1) { 2081 pos = tempLine.indexOf(StringPool.PLUS); 2082 } 2083 2084 if (pos == -1) { 2085 pos = tempLine.indexOf(StringPool.SLASH); 2086 } 2087 2088 if (pos == -1) { 2089 pos = tempLine.indexOf(StringPool.STAR); 2090 } 2091 2092 if (pos == -1) { 2093 pos = tempLine.indexOf("||"); 2094 } 2095 2096 if (pos == -1) { 2097 pos = tempLine.indexOf("&&"); 2098 } 2099 2100 if (pos == -1) { 2101 break; 2102 } 2103 2104 String linePart = tempLine.substring(0, pos); 2105 2106 int openParenthesisCount = StringUtil.count( 2107 linePart, StringPool.OPEN_PARENTHESIS); 2108 int closeParenthesisCount = StringUtil.count( 2109 linePart, StringPool.CLOSE_PARENTHESIS); 2110 2111 if (openParenthesisCount == closeParenthesisCount) { 2112 return null; 2113 } 2114 2115 tempLine = 2116 tempLine.substring(0, pos) + tempLine.substring(pos + 1); 2117 } 2118 2119 int x = trimmedLine.indexOf(StringPool.OPEN_PARENTHESIS); 2120 2121 if (x == 0) { 2122 x = trimmedLine.indexOf(StringPool.OPEN_PARENTHESIS, 1); 2123 } 2124 2125 if (x != -1) { 2126 int y = trimmedLine.indexOf(StringPool.CLOSE_PARENTHESIS, x); 2127 int z = trimmedLine.indexOf(StringPool.QUOTE); 2128 2129 if (((x + 1) != y) && ((z == -1) || (z > x))) { 2130 char previousChar = trimmedLine.charAt(x - 1); 2131 2132 if ((previousChar != CharPool.CLOSE_PARENTHESIS) && 2133 (previousChar != CharPool.OPEN_PARENTHESIS) && 2134 (previousChar != CharPool.SPACE) && 2135 (previousLineLength + 1 + x) < _MAX_LINE_LENGTH) { 2136 2137 String linePart = trimmedLine.substring(0, x + 1); 2138 2139 if (linePart.startsWith(StringPool.OPEN_PARENTHESIS) && 2140 !linePart.contains( 2141 StringPool.CLOSE_PARENTHESIS)) { 2142 2143 return null; 2144 } 2145 2146 return getCombinedLinesContent( 2147 content, fileName, line, trimmedLine, lineLength, 2148 lineCount, previousLine, linePart, tabDiff, true, 2149 true, false); 2150 } 2151 } 2152 } 2153 } 2154 2155 if (previousLine.endsWith(StringPool.COMMA) && 2156 (previousLineTabCount == lineTabCount) && 2157 !previousLine.contains(StringPool.CLOSE_CURLY_BRACE) && 2158 (line.endsWith(") {") || 2159 !line.endsWith(StringPool.OPEN_CURLY_BRACE))) { 2160 2161 int x = trimmedLine.indexOf(StringPool.COMMA); 2162 2163 if (x != -1) { 2164 while ((previousLineLength + 1 + x) < _MAX_LINE_LENGTH) { 2165 String linePart = trimmedLine.substring(0, x + 1); 2166 2167 if (isValidJavaParameter(linePart)) { 2168 if (trimmedLine.equals(linePart)) { 2169 return getCombinedLinesContent( 2170 content, fileName, line, trimmedLine, 2171 lineLength, lineCount, previousLine, null, 2172 tabDiff, false, true, false); 2173 } 2174 else { 2175 return getCombinedLinesContent( 2176 content, fileName, line, trimmedLine, 2177 lineLength, lineCount, previousLine, 2178 linePart + StringPool.SPACE, tabDiff, true, 2179 true, false); 2180 } 2181 } 2182 2183 String partAfterComma = trimmedLine.substring(x + 1); 2184 2185 int pos = partAfterComma.indexOf(StringPool.COMMA); 2186 2187 if (pos == -1) { 2188 break; 2189 } 2190 2191 x = x + pos + 1; 2192 } 2193 } 2194 else if (!line.endsWith(StringPool.OPEN_PARENTHESIS) && 2195 !line.endsWith(StringPool.PLUS) && 2196 !line.endsWith(StringPool.PERIOD) && 2197 (!trimmedLine.startsWith("new ") || 2198 !line.endsWith(StringPool.OPEN_CURLY_BRACE)) && 2199 ((trimmedLine.length() + previousLineLength) < 2200 _MAX_LINE_LENGTH)) { 2201 2202 return getCombinedLinesContent( 2203 content, fileName, line, trimmedLine, lineLength, lineCount, 2204 previousLine, null, tabDiff, false, true, false); 2205 } 2206 } 2207 2208 if (!previousLine.endsWith(StringPool.OPEN_PARENTHESIS)) { 2209 return null; 2210 } 2211 2212 if (StringUtil.count(previousLine, StringPool.OPEN_PARENTHESIS) > 1) { 2213 int pos = trimmedPreviousLine.lastIndexOf( 2214 StringPool.OPEN_PARENTHESIS, trimmedPreviousLine.length() - 2); 2215 2216 if ((pos > 0) && 2217 Character.isLetterOrDigit( 2218 trimmedPreviousLine.charAt(pos -1 ))) { 2219 2220 String filePart = trimmedPreviousLine.substring(pos + 1); 2221 2222 if (!filePart.contains(StringPool.CLOSE_PARENTHESIS) && 2223 !filePart.contains(StringPool.QUOTE)) { 2224 2225 return getCombinedLinesContent( 2226 content, fileName, line, trimmedLine, lineLength, 2227 lineCount, previousLine, filePart, tabDiff, false, 2228 false, false); 2229 } 2230 } 2231 } 2232 2233 if ((trimmedLine.length() + previousLineLength) > _MAX_LINE_LENGTH) { 2234 return null; 2235 } 2236 2237 if (line.endsWith(StringPool.COMMA)) { 2238 String strippedQuotesLine = stripQuotes( 2239 trimmedLine, CharPool.QUOTE); 2240 2241 int openParenthesisCount = StringUtil.count( 2242 strippedQuotesLine, StringPool.OPEN_PARENTHESIS); 2243 int closeParenthesisCount = StringUtil.count( 2244 strippedQuotesLine, StringPool.CLOSE_PARENTHESIS); 2245 2246 if (closeParenthesisCount > openParenthesisCount) { 2247 return getCombinedLinesContent( 2248 content, fileName, line, trimmedLine, lineLength, lineCount, 2249 previousLine, null, tabDiff, false, false, false); 2250 } 2251 } 2252 2253 if (((line.endsWith(StringPool.OPEN_CURLY_BRACE) && 2254 !trimmedLine.startsWith("new ")) || 2255 line.endsWith(StringPool.CLOSE_PARENTHESIS)) && 2256 (trimmedPreviousLine.startsWith("else ") || 2257 trimmedPreviousLine.startsWith("if ") || 2258 trimmedPreviousLine.startsWith("private ") || 2259 trimmedPreviousLine.startsWith("protected ") || 2260 trimmedPreviousLine.startsWith("public "))) { 2261 2262 return getCombinedLinesContent( 2263 content, fileName, line, trimmedLine, lineLength, lineCount, 2264 previousLine, null, tabDiff, false, false, false); 2265 } 2266 2267 return null; 2268 } 2269 2270 protected List<String> getImportedExceptionClassNames( 2271 JavaDocBuilder javaDocBuilder) { 2272 2273 List<String> exceptionClassNames = new ArrayList<String>(); 2274 2275 JavaSource javaSource = javaDocBuilder.getSources()[0]; 2276 2277 for (String importClassName : javaSource.getImports()) { 2278 if (importClassName.endsWith("Exception") && 2279 !exceptionClassNames.contains(importClassName)) { 2280 2281 exceptionClassNames.add(importClassName); 2282 } 2283 } 2284 2285 return exceptionClassNames; 2286 } 2287 2288 protected int getLineLength(String line) { 2289 int lineLength = 0; 2290 2291 int tabLength = 4; 2292 2293 for (char c : line.toCharArray()) { 2294 if (c == CharPool.TAB) { 2295 for (int i = 0; i < tabLength; i++) { 2296 lineLength++; 2297 } 2298 2299 tabLength = 4; 2300 } 2301 else { 2302 lineLength++; 2303 2304 tabLength--; 2305 2306 if (tabLength <= 0) { 2307 tabLength = 4; 2308 } 2309 } 2310 } 2311 2312 return lineLength; 2313 } 2314 2315 protected String getNextLine(String content, int lineCount) { 2316 int x = -1; 2317 2318 for (int i = 0; i < lineCount; i++) { 2319 x = content.indexOf("\n", x + 1); 2320 } 2321 2322 if (x == -1) { 2323 return null; 2324 } 2325 2326 int y = content.indexOf("\n", x + 1); 2327 2328 if (y == -1) { 2329 return content.substring(x + 1); 2330 } 2331 2332 return content.substring(x + 1, y); 2333 } 2334 2335 protected Collection<String> getPluginJavaFiles() { 2336 Collection<String> fileNames = new TreeSet<String>(); 2337 2338 String[] excludes = new String[] { 2339 "**\\model\\*Clp.java", "**\\model\\impl\\*BaseImpl.java", 2340 "**\\model\\impl\\*Model.java", "**\\model\\impl\\*ModelImpl.java", 2341 "**\\service\\**\\service\\*Service.java", 2342 "**\\service\\**\\service\\*ServiceClp.java", 2343 "**\\service\\**\\service\\*ServiceFactory.java", 2344 "**\\service\\**\\service\\*ServiceUtil.java", 2345 "**\\service\\**\\service\\*ServiceWrapper.java", 2346 "**\\service\\**\\service\\ClpSerializer.java", 2347 "**\\service\\**\\service\\messaging\\*ClpMessageListener.java", 2348 "**\\service\\**\\service\\persistence\\*Finder.java", 2349 "**\\service\\**\\service\\persistence\\*Util.java", 2350 "**\\service\\base\\*ServiceBaseImpl.java", 2351 "**\\service\\base\\*ServiceClpInvoker.java", 2352 "**\\service\\http\\*JSONSerializer.java", 2353 "**\\service\\http\\*ServiceHttp.java", 2354 "**\\service\\http\\*ServiceJSON.java", 2355 "**\\service\\http\\*ServiceSoap.java" 2356 }; 2357 String[] includes = new String[] {"**\\*.java"}; 2358 2359 fileNames.addAll(getFileNames(excludes, includes)); 2360 2361 return fileNames; 2362 } 2363 2364 protected Collection<String> getPortalJavaFiles() { 2365 Collection<String> fileNames = new TreeSet<String>(); 2366 2367 String[] excludes = new String[] { 2368 "**\\*_IW.java", "**\\PropsValues.java", "**\\counter\\service\\**", 2369 "**\\jsp\\*", "**\\model\\impl\\*BaseImpl.java", 2370 "**\\model\\impl\\*Model.java", "**\\model\\impl\\*ModelImpl.java", 2371 "**\\portal\\service\\**", "**\\portal-client\\**", 2372 "**\\portal-web\\test\\**\\*Test.java", 2373 "**\\portlet\\**\\service\\**", "**\\test\\*-generated\\**", 2374 "**\\tools\\sourceformatter\\**" 2375 }; 2376 String[] includes = new String[] {"**\\*.java"}; 2377 2378 fileNames.addAll(getFileNames(excludes, includes)); 2379 2380 excludes = new String[] { 2381 "**\\JavaDocFormatter.java", "**\\portal-client\\**", 2382 "**\\tools\\ext_tmpl\\**", "**\\*_IW.java", 2383 "**\\test\\**\\*PersistenceTest.java", 2384 "**\\tools\\sourceformatter\\**" 2385 }; 2386 includes = new String[] { 2387 "**\\com\\liferay\\portal\\service\\ServiceContext*.java", 2388 "**\\model\\BaseModel.java", "**\\model\\impl\\BaseModelImpl.java", 2389 "**\\portal-test\\**\\portal\\service\\**\\*.java", 2390 "**\\service\\Base*.java", 2391 "**\\service\\PersistedModelLocalService*.java", 2392 "**\\service\\base\\PrincipalBean.java", 2393 "**\\service\\http\\*HttpTest.java", 2394 "**\\service\\http\\*SoapTest.java", 2395 "**\\service\\http\\TunnelUtil.java", "**\\service\\impl\\*.java", 2396 "**\\service\\jms\\*.java", "**\\service\\permission\\*.java", 2397 "**\\service\\persistence\\BasePersistence.java", 2398 "**\\service\\persistence\\BatchSession*.java", 2399 "**\\service\\persistence\\*FinderImpl.java", 2400 "**\\service\\persistence\\*Query.java", 2401 "**\\service\\persistence\\impl\\*.java", 2402 "**\\portal-impl\\test\\**\\*.java", "**\\util-bridges\\**\\*.java" 2403 }; 2404 2405 fileNames.addAll(getFileNames(excludes, includes)); 2406 2407 return fileNames; 2408 } 2409 2410 protected String getTruncateLongLinesContent( 2411 String content, String line, String trimmedLine, int lineCount) { 2412 2413 String indent = StringPool.BLANK; 2414 2415 for (int i = 0; i < getLeadingTabCount(line); i++) { 2416 indent += StringPool.TAB; 2417 } 2418 2419 if (line.endsWith(StringPool.OPEN_PARENTHESIS) || 2420 line.endsWith(StringPool.SEMICOLON)) { 2421 2422 int x = line.indexOf(" = "); 2423 2424 if (x != -1) { 2425 String firstLine = line.substring(0, x + 2); 2426 2427 if (firstLine.contains(StringPool.QUOTE)) { 2428 return null; 2429 } 2430 2431 String secondLine = 2432 indent + StringPool.TAB + line.substring(x + 3); 2433 2434 if (line.endsWith(StringPool.SEMICOLON)) { 2435 return StringUtil.replace( 2436 content, "\n" + line + "\n", 2437 "\n" + firstLine + "\n" + secondLine + "\n"); 2438 } 2439 else if (Validator.isNotNull(getNextLine(content, lineCount))) { 2440 return StringUtil.replace( 2441 content, "\n" + line + "\n", 2442 "\n" + firstLine + "\n" + secondLine + "\n" + 2443 StringPool.TAB); 2444 } 2445 } 2446 } 2447 2448 if (line.endsWith(StringPool.CLOSE_PARENTHESIS) || 2449 line.endsWith(StringPool.COMMA) || 2450 line.endsWith(StringPool.OPEN_CURLY_BRACE) || 2451 line.endsWith(StringPool.SEMICOLON)) { 2452 2453 int x = 0; 2454 2455 while (true) { 2456 x = line.indexOf(", ", x + 1); 2457 2458 if (x == -1) { 2459 break; 2460 } 2461 2462 if (isValidJavaParameter(line.substring(0, x))) { 2463 String firstLine = line.substring(0, x + 1); 2464 String secondLine = indent + line.substring(x + 2); 2465 2466 return StringUtil.replace( 2467 content, "\n" + line + "\n", 2468 "\n" + firstLine + "\n" + secondLine + "\n"); 2469 } 2470 } 2471 } 2472 2473 if ((line.endsWith(StringPool.OPEN_CURLY_BRACE) || 2474 line.endsWith(StringPool.SEMICOLON)) && 2475 (trimmedLine.startsWith("private ") || 2476 trimmedLine.startsWith("protected ") || 2477 trimmedLine.startsWith("public "))) { 2478 2479 String firstLine = null; 2480 2481 int x = 0; 2482 2483 while (true) { 2484 int y = line.indexOf(" extends ", x); 2485 2486 if (y != -1) { 2487 firstLine = line.substring(0, y); 2488 2489 if (StringUtil.count(firstLine, StringPool.GREATER_THAN) != 2490 StringUtil.count(firstLine, StringPool.LESS_THAN)) { 2491 2492 x = y + 1; 2493 2494 continue; 2495 } 2496 } 2497 else { 2498 y = line.indexOf(" implements "); 2499 2500 if (y == -1) { 2501 y = line.indexOf(" throws "); 2502 } 2503 2504 if (y == -1) { 2505 break; 2506 } 2507 2508 firstLine = line.substring(0, y); 2509 } 2510 2511 String secondLine = 2512 indent + StringPool.TAB + line.substring(y + 1); 2513 2514 return StringUtil.replace( 2515 content, "\n" + line + "\n", 2516 "\n" + firstLine + "\n" + secondLine + "\n"); 2517 } 2518 } 2519 2520 if ((line.endsWith(StringPool.CLOSE_PARENTHESIS) || 2521 line.endsWith(StringPool.OPEN_CURLY_BRACE)) && 2522 (trimmedLine.startsWith("private ") || 2523 trimmedLine.startsWith("protected ") || 2524 trimmedLine.startsWith("public "))) { 2525 2526 int x = line.indexOf(StringPool.OPEN_PARENTHESIS); 2527 2528 if ((x != -1) && 2529 (line.charAt(x + 1) != CharPool.CLOSE_PARENTHESIS)) { 2530 2531 String secondLineIndent = indent + StringPool.TAB; 2532 2533 if (line.endsWith(StringPool.CLOSE_PARENTHESIS)) { 2534 secondLineIndent += StringPool.TAB; 2535 } 2536 2537 String firstLine = line.substring(0, x + 1); 2538 String secondLine = secondLineIndent + line.substring(x + 1); 2539 2540 return StringUtil.replace( 2541 content, "\n" + line + "\n", 2542 "\n" + firstLine + "\n" + secondLine + "\n"); 2543 } 2544 } 2545 2546 if (line.endsWith(StringPool.SEMICOLON)) { 2547 int x = line.indexOf(StringPool.OPEN_PARENTHESIS); 2548 2549 if (x != -1) { 2550 char c = line.charAt(x - 1); 2551 2552 if ((c != CharPool.SPACE) && (c != CharPool.TAB) && 2553 (line.charAt(x + 1) != CharPool.CLOSE_PARENTHESIS)) { 2554 2555 String firstLine = line.substring(0, x + 1); 2556 2557 if (firstLine.contains(StringPool.QUOTE)) { 2558 return null; 2559 } 2560 2561 String secondLine = 2562 indent + StringPool.TAB + line.substring(x + 1); 2563 2564 return StringUtil.replace( 2565 content, "\n" + line + "\n", 2566 "\n" + firstLine + "\n" + secondLine + "\n"); 2567 } 2568 } 2569 } 2570 2571 if (line.contains(StringPool.TAB + "for (") && line.endsWith(" {")) { 2572 int x = line.indexOf(" : "); 2573 2574 if (x != -1) { 2575 String firstLine = line.substring(0, x + 2); 2576 String secondLine = 2577 indent + StringPool.TAB + StringPool.TAB + 2578 line.substring(x + 3); 2579 2580 return StringUtil.replace( 2581 content, "\n" + line + "\n", 2582 "\n" + firstLine + "\n" + secondLine + "\n" + "\n"); 2583 } 2584 } 2585 2586 return null; 2587 } 2588 2589 protected boolean isAnnotationParameter(String content, String line) { 2590 if (!line.contains(" = ") && !line.startsWith(StringPool.QUOTE)) { 2591 return false; 2592 } 2593 2594 Matcher matcher = _annotationPattern.matcher(content); 2595 2596 while (matcher.find()) { 2597 String annotationParameters = matcher.group(3); 2598 2599 if (annotationParameters.contains(line)) { 2600 return true; 2601 } 2602 } 2603 2604 return false; 2605 } 2606 2607 protected boolean isGenerated(String content) { 2608 if (content.contains("* @generated") || content.contains("$ANTLR")) { 2609 return true; 2610 } 2611 else { 2612 return false; 2613 } 2614 } 2615 2616 protected boolean isValidJavaParameter(String javaParameter) { 2617 if (javaParameter.contains(" implements ") || 2618 javaParameter.contains(" throws ")) { 2619 2620 return false; 2621 } 2622 2623 int quoteCount = StringUtil.count(javaParameter, StringPool.QUOTE); 2624 2625 if ((quoteCount % 2) == 1) { 2626 return false; 2627 } 2628 2629 javaParameter = stripQuotes(javaParameter, CharPool.QUOTE); 2630 2631 int openParenthesisCount = StringUtil.count( 2632 javaParameter, StringPool.OPEN_PARENTHESIS); 2633 int closeParenthesisCount = StringUtil.count( 2634 javaParameter, StringPool.CLOSE_PARENTHESIS); 2635 int lessThanCount = StringUtil.count( 2636 javaParameter, StringPool.LESS_THAN); 2637 int greaterThanCount = StringUtil.count( 2638 javaParameter, StringPool.GREATER_THAN); 2639 int openCurlyBraceCount = StringUtil.count( 2640 javaParameter, StringPool.OPEN_CURLY_BRACE); 2641 int closeCurlyBraceCount = StringUtil.count( 2642 javaParameter, StringPool.CLOSE_CURLY_BRACE); 2643 2644 if ((openParenthesisCount == closeParenthesisCount) && 2645 (lessThanCount == greaterThanCount) && 2646 (openCurlyBraceCount == closeCurlyBraceCount)) { 2647 2648 return true; 2649 } 2650 2651 return false; 2652 } 2653 2654 protected String sortExceptions(String line) { 2655 if (!line.endsWith(StringPool.OPEN_CURLY_BRACE) && 2656 !line.endsWith(StringPool.SEMICOLON)) { 2657 2658 return line; 2659 } 2660 2661 int x = line.indexOf("throws "); 2662 2663 if (x == -1) { 2664 return line; 2665 } 2666 2667 String previousException = StringPool.BLANK; 2668 2669 String[] exceptions = StringUtil.split( 2670 line.substring(x), CharPool.SPACE); 2671 2672 for (int i = 1; i < exceptions.length; i++) { 2673 String exception = exceptions[i]; 2674 2675 if (exception.equals(StringPool.OPEN_CURLY_BRACE)) { 2676 break; 2677 } 2678 2679 if (exception.endsWith(StringPool.COMMA) || 2680 exception.endsWith(StringPool.SEMICOLON)) { 2681 2682 exception = exception.substring(0, exception.length() - 1); 2683 } 2684 2685 if (Validator.isNotNull(previousException) && 2686 (previousException.compareToIgnoreCase(exception) > 0)) { 2687 2688 line = StringUtil.replace( 2689 line, previousException + ", " + exception, 2690 exception + ", " + previousException); 2691 2692 return sortExceptions(line); 2693 } 2694 2695 previousException = exception; 2696 } 2697 2698 return line; 2699 } 2700 2701 private static final int _MAX_LINE_LENGTH = 80; 2702 2703 private static Pattern _importsPattern = Pattern.compile( 2704 "(^[ \t]*import\\s+.*;\n+)+", Pattern.MULTILINE); 2705 2706 private boolean _addMissingDeprecationReleaseVersion; 2707 private boolean _allowUseServiceUtilInServiceImpl; 2708 private Pattern _annotationPattern = Pattern.compile( 2709 "\n(\t*)@(.+)\\(\n([\\s\\S]*?)\n(\t*)\\)"); 2710 private Pattern _catchExceptionPattern = Pattern.compile( 2711 "\n(\t+)catch \\((.+Exception) (.+)\\) \\{\n"); 2712 private List<String> _checkJavaFieldTypesExclusions; 2713 private boolean _checkUnprocessedExceptions; 2714 private Pattern _diamondOperatorPattern = Pattern.compile( 2715 "(return|=)\n?(\t+| )new ([A-Za-z]+)(Map|Set|List)<(.+)>" + 2716 "\\(\n*\t*(.*)\\);\n"); 2717 private Pattern _fetchByPrimaryKeysMethodPattern = Pattern.compile( 2718 "@Override\n\tpublic Map<(.+)> fetchByPrimaryKeys\\("); 2719 private List<String> _fitOnSingleLineExclusions; 2720 private List<String> _hibernateSQLQueryExclusions; 2721 private Pattern _incorrectCloseCurlyBracePattern1 = Pattern.compile( 2722 "\n(.+)\n\n(\t+)}\n"); 2723 private Pattern _incorrectCloseCurlyBracePattern2 = Pattern.compile( 2724 "(\t| )@?(class |enum |interface |new )"); 2725 private Pattern _incorrectLineBreakPattern1 = Pattern.compile( 2726 "\t(catch |else |finally |for |if |try |while ).*\\{\n\n\t+\\w"); 2727 private Pattern _incorrectLineBreakPattern2 = Pattern.compile( 2728 "\\{\n\n\t*\\}"); 2729 private List<String> _javaTermAccessLevelModifierExclusions; 2730 private List<String> _javaTermSortExclusions; 2731 private Pattern _lineBreakPattern = Pattern.compile("\\}(\\)+) \\{"); 2732 private List<String> _lineLengthExclusions; 2733 private Pattern _logPattern = Pattern.compile( 2734 "\n\tprivate static final Log _log = LogFactoryUtil.getLog\\(\n*" + 2735 "\t*(.+)\\.class\\)"); 2736 private Pattern _processCallablePattern = Pattern.compile( 2737 "implements ProcessCallable\\b"); 2738 private List<String> _proxyExclusions; 2739 private List<String> _secureRandomExclusions; 2740 private Pattern _stagedModelTypesPattern = Pattern.compile( 2741 "StagedModelType\\(([a-zA-Z.]*(class|getClassName[\\(\\)]*))\\)"); 2742 private List<String> _staticLogVariableExclusions; 2743 private List<String> _testAnnotationsExclusions; 2744 private Pattern _throwsSystemExceptionPattern = Pattern.compile( 2745 "(\n\t+.*)throws(.*) SystemException(.*)( \\{|;\n)"); 2746 private List<String> _upgradeServiceUtilExclusions; 2747 2748 }