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