001 /** 002 * Copyright (c) 2000-2012 Liferay, Inc. All rights reserved. 003 * 004 * This library is free software; you can redistribute it and/or modify it under 005 * the terms of the GNU Lesser General Public License as published by the Free 006 * Software Foundation; either version 2.1 of the License, or (at your option) 007 * any later version. 008 * 009 * This library is distributed in the hope that it will be useful, but WITHOUT 010 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 011 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 012 * details. 013 */ 014 015 package com.liferay.portal.tools; 016 017 import com.liferay.portal.kernel.io.unsync.UnsyncBufferedReader; 018 import com.liferay.portal.kernel.io.unsync.UnsyncStringReader; 019 import com.liferay.portal.kernel.util.ArrayUtil; 020 import com.liferay.portal.kernel.util.CharPool; 021 import com.liferay.portal.kernel.util.ClassUtil; 022 import com.liferay.portal.kernel.util.GetterUtil; 023 import com.liferay.portal.kernel.util.ListUtil; 024 import com.liferay.portal.kernel.util.PropertiesUtil; 025 import com.liferay.portal.kernel.util.PropsKeys; 026 import com.liferay.portal.kernel.util.StringBundler; 027 import com.liferay.portal.kernel.util.StringPool; 028 import com.liferay.portal.kernel.util.StringUtil; 029 import com.liferay.portal.kernel.util.Tuple; 030 import com.liferay.portal.kernel.util.Validator; 031 import com.liferay.portal.kernel.xml.Document; 032 import com.liferay.portal.kernel.xml.DocumentException; 033 import com.liferay.portal.kernel.xml.Element; 034 import com.liferay.util.ContentUtil; 035 import com.liferay.portal.util.FileImpl; 036 import com.liferay.portal.xml.SAXReaderImpl; 037 038 import java.io.File; 039 import java.io.IOException; 040 import java.io.InputStream; 041 import java.net.URL; 042 import java.util.ArrayList; 043 import java.util.Arrays; 044 import java.util.Collection; 045 import java.util.Collections; 046 import java.util.HashMap; 047 import java.util.HashSet; 048 import java.util.List; 049 import java.util.Map; 050 import java.util.Properties; 051 import java.util.Set; 052 import java.util.TreeSet; 053 import java.util.regex.Matcher; 054 import java.util.regex.Pattern; 055 056 import org.apache.tools.ant.DirectoryScanner; 057 058 /** 059 * @author Brian Wing Shun Chan 060 * @author Igor Spasic 061 * @author Wesley Gong 062 * @author Hugo Huijser 063 */ 064 public class SourceFormatter { 065 066 public static void main(String[] args) { 067 try { 068 _excludes = StringUtil.split( 069 GetterUtil.getString( 070 System.getProperty("source.formatter.excludes"))); 071 072 _sourceFormatterHelper = new SourceFormatterHelper(false); 073 074 _sourceFormatterHelper.init(); 075 076 _javaTermAlphabetizeExclusionsProperties = _getExclusionsProperties( 077 "source_formatter_javaterm_alphabetize_exclusions.properties"); 078 _lineLengthExclusionsProperties = _getExclusionsProperties( 079 "source_formatter_line_length_exclusions.properties"); 080 081 Thread thread1 = new Thread () { 082 @Override 083 public void run() { 084 try { 085 _checkPersistenceTestSuite(); 086 _formatJSP(); 087 _formatAntXML(); 088 _formatDDLStructuresXML(); 089 _formatFriendlyURLRoutesXML(); 090 _formatPortletXML(); 091 _formatSH(); 092 _formatWebXML(); 093 } 094 catch (Exception e) { 095 e.printStackTrace(); 096 } 097 } 098 }; 099 100 Thread thread2 = new Thread () { 101 @Override 102 public void run() { 103 try { 104 _formatJava(); 105 } 106 catch (Exception e) { 107 e.printStackTrace(); 108 } 109 } 110 }; 111 112 thread1.start(); 113 thread2.start(); 114 115 thread1.join(); 116 thread2.join(); 117 118 _sourceFormatterHelper.close(); 119 } 120 catch (Exception e) { 121 e.printStackTrace(); 122 } 123 } 124 125 public static String stripJavaImports( 126 String content, String packageDir, String className) 127 throws IOException { 128 129 Matcher matcher = _javaImportPattern.matcher(content); 130 131 if (!matcher.find()) { 132 return content; 133 } 134 135 String imports = matcher.group(); 136 137 Set<String> classes = ClassUtil.getClasses( 138 new UnsyncStringReader(content), className); 139 140 StringBundler sb = new StringBundler(); 141 142 UnsyncBufferedReader unsyncBufferedReader = new UnsyncBufferedReader( 143 new UnsyncStringReader(imports)); 144 145 String line = null; 146 147 while ((line = unsyncBufferedReader.readLine()) != null) { 148 if (line.contains("import ")) { 149 int importX = line.indexOf(" "); 150 int importY = line.lastIndexOf("."); 151 152 String importPackage = line.substring(importX + 1, importY); 153 String importClass = line.substring( 154 importY + 1, line.length() - 1); 155 156 if (!packageDir.equals(importPackage)) { 157 if (!importClass.equals("*")) { 158 if (classes.contains(importClass)) { 159 sb.append(line); 160 sb.append("\n"); 161 } 162 } 163 else { 164 sb.append(line); 165 sb.append("\n"); 166 } 167 } 168 } 169 } 170 171 imports = _formatImports(sb.toString(), 7); 172 173 content = 174 content.substring(0, matcher.start()) + imports + 175 content.substring(matcher.end()); 176 177 // Ensure a blank line exists between the package and the first import 178 179 content = content.replaceFirst( 180 "(?m)^[ \t]*(package .*;)\\s*^[ \t]*import", "$1\n\nimport"); 181 182 // Ensure a blank line exists between the last import (or package if 183 // there are no imports) and the class comment 184 185 content = content.replaceFirst( 186 "(?m)^[ \t]*((?:package|import) .*;)\\s*^[ \t]*/\\*\\*", 187 "$1\n\n/**"); 188 189 return content; 190 } 191 192 private static void _addJSPIncludeFileNames( 193 String fileName, Set<String> includeFileNames) { 194 195 String content = _jspContents.get(fileName); 196 197 if (Validator.isNull(content)) { 198 return; 199 } 200 201 for (int x = 0;;) { 202 x = content.indexOf("<%@ include file=", x); 203 204 if (x == -1) { 205 break; 206 } 207 208 x = content.indexOf(StringPool.QUOTE, x); 209 210 if (x == -1) { 211 break; 212 } 213 214 int y = content.indexOf(StringPool.QUOTE, x + 1); 215 216 if (y == -1) { 217 break; 218 } 219 220 String includeFileName = content.substring(x + 1, y); 221 222 Matcher matcher = _jspIncludeFilePattern.matcher(includeFileName); 223 224 if (!matcher.find()) { 225 throw new RuntimeException( 226 "Invalid include " + includeFileName); 227 } 228 229 String docrootPath = fileName.substring( 230 0, fileName.indexOf("docroot") + 7); 231 232 includeFileName = docrootPath + includeFileName; 233 234 if ((includeFileName.endsWith("jsp") || 235 includeFileName.endsWith("jspf")) && 236 !includeFileNames.contains(includeFileName) && 237 !includeFileName.contains("html/portlet/init.jsp")) { 238 239 includeFileNames.add(includeFileName); 240 } 241 242 x = y; 243 } 244 } 245 246 private static void _addJSPReferenceFileNames( 247 String fileName, Set<String> includeFileNames) { 248 249 for (Map.Entry<String, String> entry : _jspContents.entrySet()) { 250 String referenceFileName = entry.getKey(); 251 String content = entry.getValue(); 252 253 if (content.contains("<%@ include file=\"" + fileName) && 254 !includeFileNames.contains(referenceFileName)) { 255 256 includeFileNames.add(referenceFileName); 257 } 258 } 259 } 260 261 private static void _addJSPUnusedImports( 262 String fileName, List<String> importLines, 263 List<String> unneededImports) { 264 265 for (String importLine : importLines) { 266 Set<String> includeFileNames = new HashSet<String>(); 267 268 includeFileNames.add(fileName); 269 270 Set<String> checkedFileNames = new HashSet<String>(); 271 272 int x = importLine.indexOf(StringPool.QUOTE); 273 int y = importLine.indexOf(StringPool.QUOTE, x + 1); 274 275 if ((x == -1) || (y == -1)) { 276 continue; 277 } 278 279 String className = importLine.substring(x + 1, y); 280 281 className = className.substring( 282 className.lastIndexOf(StringPool.PERIOD) + 1); 283 284 if (!_isJSPImportRequired( 285 fileName, className, includeFileNames, checkedFileNames)) { 286 287 unneededImports.add(importLine); 288 } 289 } 290 } 291 292 private static List<String> _addMethodParameterTypes( 293 String line, List<String> methodParameterTypes) { 294 295 int x = line.indexOf(StringPool.OPEN_PARENTHESIS); 296 297 if (x != -1) { 298 line = line.substring(x + 1); 299 300 if (Validator.isNull(line) || 301 line.startsWith(StringPool.CLOSE_PARENTHESIS)) { 302 303 return methodParameterTypes; 304 } 305 } 306 307 for (x = 0;;) { 308 x = line.indexOf(StringPool.SPACE); 309 310 if (x == -1) { 311 return methodParameterTypes; 312 } 313 314 String parameterType = line.substring(0, x); 315 316 if (parameterType.equals("throws")) { 317 return methodParameterTypes; 318 } 319 320 methodParameterTypes.add(parameterType); 321 322 int y = line.indexOf(StringPool.COMMA); 323 int z = line.indexOf(StringPool.CLOSE_PARENTHESIS); 324 325 if ((y == -1) || ((z != -1) && (z < y))) { 326 return methodParameterTypes; 327 } 328 329 line = line.substring(y + 1); 330 line = line.trim(); 331 } 332 } 333 334 private static void _checkJSPAttributes( 335 String fileName, String line, int lineCount) { 336 337 int x = line.indexOf(StringPool.SPACE); 338 339 if (x == -1) { 340 return; 341 } 342 343 line = line.substring(x + 1); 344 345 String previousAttribute = null; 346 347 for (x = 0;;) { 348 x = line.indexOf(StringPool.EQUAL); 349 350 if ((x == -1) || (line.length() <= (x + 1))) { 351 return; 352 } 353 354 String attribute = line.substring(0, x); 355 356 if (!_isJSPAttributName(attribute)) { 357 return; 358 } 359 360 if (Validator.isNotNull(previousAttribute) && 361 (previousAttribute.compareTo(attribute) > 0)) { 362 363 //_sourceFormatterHelper.printError( 364 // fileName, "sort: " + fileName + " " + lineCount); 365 366 return; 367 } 368 369 line = line.substring(x + 1); 370 371 char delimeter = line.charAt(0); 372 373 if ((delimeter != CharPool.APOSTROPHE) && 374 (delimeter != CharPool.QUOTE)) { 375 376 _sourceFormatterHelper.printError( 377 fileName, "delimeter: " + fileName + " " + lineCount); 378 379 return; 380 } 381 382 line = line.substring(1); 383 384 int y = line.indexOf(delimeter); 385 386 if ((y == -1) || (line.length() <= (y + 1))) { 387 return; 388 } 389 390 line = line.substring(y + 1); 391 392 line = StringUtil.trimLeading(line); 393 394 previousAttribute = attribute; 395 } 396 } 397 398 private static void _checkPersistenceTestSuite() throws IOException { 399 String basedir = "./portal-impl/test"; 400 401 if (!_fileUtil.exists(basedir)) { 402 return; 403 } 404 405 DirectoryScanner directoryScanner = new DirectoryScanner(); 406 407 directoryScanner.setBasedir(basedir); 408 directoryScanner.setIncludes( 409 new String[] {"**\\*PersistenceTest.java"}); 410 411 List<String> fileNames = _sourceFormatterHelper.scanForFiles( 412 directoryScanner); 413 414 List<String> persistenceTests = new ArrayList<String>(); 415 416 for (String fileName : fileNames) { 417 String persistenceTest = fileName.substring( 418 0, fileName.length() - 5); 419 420 persistenceTest = persistenceTest.substring( 421 persistenceTest.lastIndexOf(File.separator) + 1, 422 persistenceTest.length()); 423 424 persistenceTests.add(persistenceTest); 425 } 426 427 String persistenceTestSuiteFileName = 428 basedir + "/com/liferay/portal/service/persistence/" + 429 "PersistenceTestSuite.java"; 430 431 String persistenceTestSuiteContent = _fileUtil.read( 432 persistenceTestSuiteFileName); 433 434 for (String persistenceTest : persistenceTests) { 435 if (!persistenceTestSuiteContent.contains(persistenceTest)) { 436 _sourceFormatterHelper.printError( 437 persistenceTestSuiteFileName, 438 "PersistenceTestSuite: " + persistenceTest); 439 } 440 } 441 } 442 443 private static boolean _checkTaglibVulnerability( 444 String jspContent, String vulnerability) { 445 446 int pos1 = -1; 447 448 do { 449 pos1 = jspContent.indexOf(vulnerability, pos1 + 1); 450 451 if (pos1 != -1) { 452 int pos2 = jspContent.lastIndexOf(CharPool.LESS_THAN, pos1); 453 454 while ((pos2 > 0) && 455 (jspContent.charAt(pos2 + 1) == CharPool.PERCENT)) { 456 457 pos2 = jspContent.lastIndexOf(CharPool.LESS_THAN, pos2 - 1); 458 } 459 460 String tagContent = jspContent.substring(pos2, pos1); 461 462 if (!tagContent.startsWith("<aui:") && 463 !tagContent.startsWith("<liferay-portlet:") && 464 !tagContent.startsWith("<liferay-util:") && 465 !tagContent.startsWith("<portlet:")) { 466 467 return true; 468 } 469 } 470 } 471 while (pos1 != -1); 472 473 return false; 474 } 475 476 private static void _checkXSS(String fileName, String jspContent) { 477 Matcher matcher = _xssPattern.matcher(jspContent); 478 479 while (matcher.find()) { 480 boolean xssVulnerable = false; 481 482 String jspVariable = matcher.group(1); 483 484 String anchorVulnerability = " href=\"<%= " + jspVariable + " %>"; 485 486 if (_checkTaglibVulnerability(jspContent, anchorVulnerability)) { 487 xssVulnerable = true; 488 } 489 490 String inputVulnerability = " value=\"<%= " + jspVariable + " %>"; 491 492 if (_checkTaglibVulnerability(jspContent, inputVulnerability)) { 493 xssVulnerable = true; 494 } 495 496 String inlineStringVulnerability1 = "'<%= " + jspVariable + " %>"; 497 498 if (jspContent.contains(inlineStringVulnerability1)) { 499 xssVulnerable = true; 500 } 501 502 String inlineStringVulnerability2 = "(\"<%= " + jspVariable + " %>"; 503 504 if (jspContent.contains(inlineStringVulnerability2)) { 505 xssVulnerable = true; 506 } 507 508 String inlineStringVulnerability3 = " \"<%= " + jspVariable + " %>"; 509 510 if (jspContent.contains(inlineStringVulnerability3)) { 511 xssVulnerable = true; 512 } 513 514 String documentIdVulnerability = ".<%= " + jspVariable + " %>"; 515 516 if (jspContent.contains(documentIdVulnerability)) { 517 xssVulnerable = true; 518 } 519 520 if (xssVulnerable) { 521 _sourceFormatterHelper.printError( 522 fileName, "(xss): " + fileName + " (" + jspVariable + ")"); 523 } 524 } 525 } 526 527 private static void _compareJavaTermNames( 528 String fileName, String previousJavaTermName, String javaTermName, 529 int lineCount) { 530 531 if (Validator.isNull(previousJavaTermName) || 532 Validator.isNull(javaTermName)) { 533 534 return; 535 } 536 537 if (javaTermName.equals("_log")) { 538 _sourceFormatterHelper.printError( 539 fileName, "sort: " + fileName + " " + lineCount); 540 541 return; 542 } 543 544 if (previousJavaTermName.equals("_instance") || 545 previousJavaTermName.equals("_log")) { 546 547 return; 548 } 549 550 if (javaTermName.equals("_instance")) { 551 _sourceFormatterHelper.printError( 552 fileName, "sort: " + fileName + " " + lineCount); 553 554 return; 555 } 556 557 if (previousJavaTermName.compareToIgnoreCase(javaTermName) <= 0) { 558 return; 559 } 560 561 String javaTermNameLowerCase = javaTermName.toLowerCase(); 562 String previousJavaTermNameLowerCase = 563 previousJavaTermName.toLowerCase(); 564 565 if (fileName.contains("persistence") && 566 (previousJavaTermName.startsWith("doCount") && 567 javaTermName.startsWith("doCount")) || 568 (previousJavaTermName.startsWith("doFind") && 569 javaTermName.startsWith("doFind")) || 570 (previousJavaTermNameLowerCase.startsWith("count") && 571 javaTermNameLowerCase.startsWith("count")) || 572 (previousJavaTermNameLowerCase.startsWith("filter") && 573 javaTermNameLowerCase.startsWith("filter")) || 574 (previousJavaTermNameLowerCase.startsWith("find") && 575 javaTermNameLowerCase.startsWith("find")) || 576 (previousJavaTermNameLowerCase.startsWith("join") && 577 javaTermNameLowerCase.startsWith("join"))) { 578 579 return; 580 } 581 582 _sourceFormatterHelper.printError( 583 fileName, "sort: " + fileName + " " + lineCount); 584 } 585 586 private static void _compareMethodParameterTypes( 587 String fileName, List<String> previousMethodParameterTypes, 588 List<String> methodParameterTypes, int lineCount) { 589 590 if (methodParameterTypes.isEmpty()) { 591 _sourceFormatterHelper.printError( 592 fileName, "sort: " + fileName + " " + lineCount); 593 594 return; 595 } 596 597 for (int i = 0; i < previousMethodParameterTypes.size(); i++) { 598 if (methodParameterTypes.size() < i + 1) { 599 _sourceFormatterHelper.printError( 600 fileName, "sort: " + fileName + " " + lineCount); 601 602 return; 603 } 604 605 String previousParameterType = previousMethodParameterTypes.get(i); 606 607 if (previousParameterType.endsWith("...")) { 608 previousParameterType = StringUtil.replaceLast( 609 previousParameterType, "...", StringPool.BLANK); 610 } 611 612 String parameterType = methodParameterTypes.get(i); 613 614 if (parameterType.endsWith("...")) { 615 parameterType = StringUtil.replaceLast( 616 parameterType, "...", StringPool.BLANK); 617 } 618 619 if (previousParameterType.compareToIgnoreCase(parameterType) < 0) { 620 return; 621 } 622 623 if (previousParameterType.compareToIgnoreCase(parameterType) > 0) { 624 _sourceFormatterHelper.printError( 625 fileName, "sort: " + fileName + " " + lineCount); 626 627 return; 628 } 629 630 if (previousParameterType.compareTo(parameterType) > 0) { 631 return; 632 } 633 634 if (previousParameterType.compareTo(parameterType) < 0) { 635 _sourceFormatterHelper.printError( 636 fileName, "sort: " + fileName + " " + lineCount); 637 638 return; 639 } 640 } 641 } 642 643 private static String _fixAntXMLProjectName( 644 String basedir, String fileName, String content) 645 throws IOException { 646 647 int x = 0; 648 649 if (fileName.endsWith("-ext/build.xml")) { 650 x = fileName.indexOf("ext/"); 651 652 if (x == -1) { 653 x = 0; 654 } 655 else { 656 x = x + 4; 657 } 658 } 659 else if (fileName.endsWith("-hook/build.xml")) { 660 x = fileName.indexOf("hooks/"); 661 662 if (x == -1) { 663 x = 0; 664 } 665 else { 666 x = x + 6; 667 } 668 } 669 else if (fileName.endsWith("-layouttpl/build.xml")) { 670 x = fileName.indexOf("layouttpl/"); 671 672 if (x == -1) { 673 x = 0; 674 } 675 else { 676 x = x + 10; 677 } 678 } 679 else if (fileName.endsWith("-portlet/build.xml")) { 680 x = fileName.indexOf("portlets/"); 681 682 if (x == -1) { 683 x = 0; 684 } 685 else { 686 x = x + 9; 687 } 688 } 689 else if (fileName.endsWith("-theme/build.xml")) { 690 x = fileName.indexOf("themes/"); 691 692 if (x == -1) { 693 x = 0; 694 } 695 else { 696 x = x + 7; 697 } 698 } 699 else if (fileName.endsWith("-web/build.xml") && 700 !fileName.endsWith("/ext-web/build.xml")) { 701 702 x = fileName.indexOf("webs/"); 703 704 if (x == -1) { 705 x = 0; 706 } 707 else { 708 x = x + 5; 709 } 710 } 711 else { 712 return content; 713 } 714 715 int y = fileName.indexOf("/", x); 716 717 String correctProjectElementText = 718 "<project name=\"" + fileName.substring(x, y) + "\""; 719 720 if (!content.contains(correctProjectElementText)) { 721 x = content.indexOf("<project name=\""); 722 723 y = content.indexOf("\"", x) + 1; 724 y = content.indexOf("\"", y) + 1; 725 726 content = 727 content.substring(0, x) + correctProjectElementText + 728 content.substring(y); 729 730 _sourceFormatterHelper.printError( 731 fileName, fileName + " has an incorrect project name"); 732 733 _fileUtil.write(basedir + fileName, content); 734 } 735 736 return content; 737 } 738 739 private static void _formatAntXML() throws DocumentException, IOException { 740 String basedir = "./"; 741 742 DirectoryScanner directoryScanner = new DirectoryScanner(); 743 744 directoryScanner.setBasedir(basedir); 745 directoryScanner.setIncludes(new String[] {"**\\b*.xml"}); 746 directoryScanner.setExcludes(new String[] {"**\\tools\\**"}); 747 748 List<String> fileNames = _sourceFormatterHelper.scanForFiles( 749 directoryScanner); 750 751 for (String fileName : fileNames) { 752 fileName = StringUtil.replace(fileName, "\\", "/"); 753 754 String content = _fileUtil.read(basedir + fileName); 755 756 content = _fixAntXMLProjectName(basedir, fileName, content); 757 758 Document document = _saxReaderUtil.read(content); 759 760 Element rootElement = document.getRootElement(); 761 762 String previousName = StringPool.BLANK; 763 764 List<Element> targetElements = rootElement.elements("target"); 765 766 for (Element targetElement : targetElements) { 767 String name = targetElement.attributeValue("name"); 768 769 if (name.equals("Test")) { 770 name = name.toLowerCase(); 771 } 772 773 if (name.compareTo(previousName) < -1) { 774 _sourceFormatterHelper.printError( 775 fileName, 776 fileName + " has an unordered target " + name); 777 778 break; 779 } 780 781 previousName = name; 782 } 783 } 784 } 785 786 private static void _formatDDLStructuresXML() 787 throws DocumentException, IOException { 788 789 String basedir = 790 "./portal-impl/src/com/liferay/portal/events/dependencies/"; 791 792 if (!_fileUtil.exists(basedir)) { 793 return; 794 } 795 796 DirectoryScanner directoryScanner = new DirectoryScanner(); 797 798 directoryScanner.setBasedir(basedir); 799 directoryScanner.setIncludes(new String[] {"**\\*structures.xml"}); 800 801 List<String> fileNames = _sourceFormatterHelper.scanForFiles( 802 directoryScanner); 803 804 for (String fileName : fileNames) { 805 File file = new File(basedir + fileName); 806 807 String content = _fileUtil.read(file); 808 809 String newContent = _formatDDLStructuresXML(content); 810 811 if ((newContent != null) && !content.equals(newContent)) { 812 _fileUtil.write(file, newContent); 813 814 _sourceFormatterHelper.printError(fileName, file); 815 } 816 } 817 } 818 819 private static String _formatDDLStructuresXML(String content) 820 throws DocumentException, IOException { 821 822 Document document = _saxReaderUtil.read(content); 823 824 Element rootElement = document.getRootElement(); 825 826 rootElement.sortAttributes(true); 827 828 rootElement.sortElementsByChildElement("structure", "name"); 829 830 List<Element> structureElements = rootElement.elements("structure"); 831 832 for (Element structureElement : structureElements) { 833 Element structureRootElement = structureElement.element("root"); 834 835 structureRootElement.sortElementsByAttribute( 836 "dynamic-element", "name"); 837 838 List<Element> dynamicElementElements = 839 structureRootElement.elements("dynamic-element"); 840 841 for (Element dynamicElementElement : dynamicElementElements) { 842 Element metaDataElement = dynamicElementElement.element( 843 "meta-data"); 844 845 metaDataElement.sortElementsByAttribute("entry", "name"); 846 } 847 } 848 849 return document.formattedString(); 850 } 851 852 private static void _formatFriendlyURLRoutesXML() 853 throws DocumentException, IOException { 854 855 String basedir = "./"; 856 857 DirectoryScanner directoryScanner = new DirectoryScanner(); 858 859 directoryScanner.setBasedir(basedir); 860 directoryScanner.setIncludes(new String[] {"**\\*routes.xml"}); 861 directoryScanner.setExcludes( 862 new String[] {"**\\classes\\**", "**\\bin\\**"}); 863 864 List<String> fileNames = _sourceFormatterHelper.scanForFiles( 865 directoryScanner); 866 867 for (String fileName : fileNames) { 868 File file = new File(basedir + fileName); 869 870 String content = _fileUtil.read(file); 871 872 if (content.contains("<!-- SourceFormatter.Ignore -->")) { 873 continue; 874 } 875 876 String newContent = _formatFriendlyURLRoutesXML(content); 877 878 if ((newContent != null) && !content.equals(newContent)) { 879 _fileUtil.write(file, newContent); 880 881 _sourceFormatterHelper.printError(fileName, file); 882 } 883 } 884 } 885 886 private static String _formatFriendlyURLRoutesXML(String content) 887 throws DocumentException { 888 889 Document document = _saxReaderUtil.read(content); 890 891 Element rootElement = document.getRootElement(); 892 893 List<ComparableRoute> comparableRoutes = 894 new ArrayList<ComparableRoute>(); 895 896 for (Element routeElement : rootElement.elements("route")) { 897 String pattern = routeElement.elementText("pattern"); 898 899 ComparableRoute comparableRoute = new ComparableRoute(pattern); 900 901 for (Element generatedParameterElement : 902 routeElement.elements("generated-parameter")) { 903 904 String name = generatedParameterElement.attributeValue("name"); 905 String value = generatedParameterElement.getText(); 906 907 comparableRoute.addGeneratedParameter(name, value); 908 } 909 910 for (Element ignoredParameterElement : 911 routeElement.elements("ignored-parameter")) { 912 913 String name = ignoredParameterElement.attributeValue("name"); 914 915 comparableRoute.addIgnoredParameter(name); 916 } 917 918 for (Element implicitParameterElement : 919 routeElement.elements("implicit-parameter")) { 920 921 String name = implicitParameterElement.attributeValue("name"); 922 String value = implicitParameterElement.getText(); 923 924 comparableRoute.addImplicitParameter(name, value); 925 } 926 927 for (Element overriddenParameterElement : 928 routeElement.elements("overridden-parameter")) { 929 930 String name = overriddenParameterElement.attributeValue("name"); 931 String value = overriddenParameterElement.getText(); 932 933 comparableRoute.addOverriddenParameter(name, value); 934 } 935 936 comparableRoutes.add(comparableRoute); 937 } 938 939 Collections.sort(comparableRoutes); 940 941 StringBundler sb = new StringBundler(); 942 943 sb.append("<?xml version=\"1.0\"?>\n"); 944 sb.append("<!DOCTYPE routes PUBLIC \"-//Liferay//DTD Friendly URL "); 945 sb.append("Routes 6.1.0//EN\" \"http://www.liferay.com/dtd/"); 946 sb.append("liferay-friendly-url-routes_6_1_0.dtd\">\n\n<routes>\n"); 947 948 for (ComparableRoute comparableRoute : comparableRoutes) { 949 sb.append("\t<route>\n"); 950 sb.append("\t\t<pattern>"); 951 sb.append(comparableRoute.getPattern()); 952 sb.append("</pattern>\n"); 953 954 Map<String, String> generatedParameters = 955 comparableRoute.getGeneratedParameters(); 956 957 for (Map.Entry<String, String> entry : 958 generatedParameters.entrySet()) { 959 960 sb.append("\t\t<generated-parameter name=\""); 961 sb.append(entry.getKey()); 962 sb.append("\">"); 963 sb.append(entry.getValue()); 964 sb.append("</generated-parameter>\n"); 965 } 966 967 Set<String> ignoredParameters = 968 comparableRoute.getIgnoredParameters(); 969 970 for (String entry : ignoredParameters) { 971 sb.append("\t\t<ignored-parameter name=\""); 972 sb.append(entry); 973 sb.append("\" />\n"); 974 } 975 976 Map<String, String> implicitParameters = 977 comparableRoute.getImplicitParameters(); 978 979 for (Map.Entry<String, String> entry : 980 implicitParameters.entrySet()) { 981 982 sb.append("\t\t<implicit-parameter name=\""); 983 sb.append(entry.getKey()); 984 sb.append("\">"); 985 sb.append(entry.getValue()); 986 sb.append("</implicit-parameter>\n"); 987 } 988 989 Map<String, String> overriddenParameters = 990 comparableRoute.getOverriddenParameters(); 991 992 for (Map.Entry<String, String> entry : 993 overriddenParameters.entrySet()) { 994 995 sb.append("\t\t<overridden-parameter name=\""); 996 sb.append(entry.getKey()); 997 sb.append("\">"); 998 sb.append(entry.getValue()); 999 sb.append("</overridden-parameter>\n"); 1000 } 1001 1002 sb.append("\t</route>\n"); 1003 } 1004 1005 sb.append("</routes>"); 1006 1007 return sb.toString(); 1008 } 1009 1010 private static String _formatImports(String imports, int classStartPos) 1011 throws IOException { 1012 1013 if (imports.contains("/*") || imports.contains("*/") || 1014 imports.contains("//")) { 1015 1016 return imports + "\n"; 1017 } 1018 1019 List<String> importsList = new ArrayList<String>(); 1020 1021 UnsyncBufferedReader unsyncBufferedReader = new UnsyncBufferedReader( 1022 new UnsyncStringReader(imports)); 1023 1024 String line = null; 1025 1026 while ((line = unsyncBufferedReader.readLine()) != null) { 1027 if ((line.contains("import=") || line.contains("import ")) && 1028 !importsList.contains(line)) { 1029 1030 importsList.add(line); 1031 } 1032 } 1033 1034 importsList = ListUtil.sort(importsList); 1035 1036 StringBundler sb = new StringBundler(); 1037 1038 String temp = null; 1039 1040 for (int i = 0; i < importsList.size(); i++) { 1041 String s = importsList.get(i); 1042 1043 int pos = s.indexOf("."); 1044 1045 pos = s.indexOf(".", pos + 1); 1046 1047 if (pos == -1) { 1048 pos = s.indexOf("."); 1049 } 1050 1051 String packageLevel = s.substring(classStartPos, pos); 1052 1053 if ((i != 0) && (!packageLevel.equals(temp))) { 1054 sb.append("\n"); 1055 } 1056 1057 temp = packageLevel; 1058 1059 sb.append(s); 1060 sb.append("\n"); 1061 } 1062 1063 return sb.toString(); 1064 } 1065 1066 private static void _formatJava() throws IOException { 1067 String basedir = "./"; 1068 1069 String copyright = _getCopyright(); 1070 String oldCopyright = _getOldCopyright(); 1071 1072 boolean portalJavaFiles = true; 1073 1074 Collection<String> fileNames = null; 1075 1076 if (_fileUtil.exists(basedir + "portal-impl")) { 1077 fileNames = _getPortalJavaFiles(); 1078 } 1079 else { 1080 portalJavaFiles = false; 1081 1082 fileNames = _getPluginJavaFiles(); 1083 } 1084 1085 for (String fileName : fileNames) { 1086 File file = new File(fileName); 1087 1088 String content = _fileUtil.read(file); 1089 1090 if (_isGenerated(content)) { 1091 continue; 1092 } 1093 1094 String className = file.getName(); 1095 1096 className = className.substring(0, className.length() - 5); 1097 1098 String packagePath = fileName; 1099 1100 int packagePathX = packagePath.indexOf( 1101 File.separator + "src" + File.separator); 1102 int packagePathY = packagePath.lastIndexOf(File.separator); 1103 1104 if ((packagePathX + 5) >= packagePathY) { 1105 packagePath = StringPool.BLANK; 1106 } 1107 else { 1108 packagePath = packagePath.substring( 1109 packagePathX + 5, packagePathY); 1110 } 1111 1112 packagePath = StringUtil.replace( 1113 packagePath, File.separator, StringPool.PERIOD); 1114 1115 if (packagePath.endsWith(".model")) { 1116 if (content.contains("extends " + className + "Model")) { 1117 continue; 1118 } 1119 } 1120 1121 String newContent = _formatJavaContent(fileName, content); 1122 1123 if (newContent.contains("$\n */")) { 1124 _sourceFormatterHelper.printError(fileName, "*: " + fileName); 1125 1126 newContent = StringUtil.replace( 1127 newContent, "$\n */", "$\n *\n */"); 1128 } 1129 1130 if ((oldCopyright != null) && newContent.contains(oldCopyright)) { 1131 newContent = StringUtil.replace( 1132 newContent, oldCopyright, copyright); 1133 1134 _sourceFormatterHelper.printError( 1135 fileName, "old (c): " + fileName); 1136 } 1137 1138 if (!newContent.contains(copyright)) { 1139 String customCopyright = _getCustomCopyright(file); 1140 1141 if (Validator.isNull(customCopyright) || 1142 !newContent.contains(customCopyright)) { 1143 1144 _sourceFormatterHelper.printError( 1145 fileName, "(c): " + fileName); 1146 } 1147 } 1148 1149 if (newContent.contains(className + ".java.html")) { 1150 _sourceFormatterHelper.printError( 1151 fileName, "Java2HTML: " + fileName); 1152 } 1153 1154 if (newContent.contains(" * @author Raymond Aug") && 1155 !newContent.contains(" * @author Raymond Aug\u00e9")) { 1156 1157 newContent = newContent.replaceFirst( 1158 "Raymond Aug.++", "Raymond Aug\u00e9"); 1159 1160 _sourceFormatterHelper.printError( 1161 fileName, "UTF-8: " + fileName); 1162 } 1163 1164 newContent = StringUtil.replace( 1165 newContent, 1166 new String[] { 1167 "com.liferay.portal.PortalException", 1168 "com.liferay.portal.SystemException", 1169 "com.liferay.util.LocalizationUtil" 1170 }, 1171 new String[] { 1172 "com.liferay.portal.kernel.exception.PortalException", 1173 "com.liferay.portal.kernel.exception.SystemException", 1174 "com.liferay.portal.kernel.util.LocalizationUtil" 1175 }); 1176 1177 newContent = stripJavaImports(newContent, packagePath, className); 1178 1179 newContent = StringUtil.replace( 1180 newContent, 1181 new String[] { 1182 ";\n/**", 1183 "\t/*\n\t *", 1184 "if(", 1185 "for(", 1186 "while(", 1187 "List <", 1188 "){\n", 1189 "]{\n", 1190 "\n\n\n" 1191 }, 1192 new String[] { 1193 ";\n\n/**", 1194 "\t/**\n\t *", 1195 "if (", 1196 "for (", 1197 "while (", 1198 "List<", 1199 ") {\n", 1200 "] {\n", 1201 "\n\n" 1202 }); 1203 1204 if (newContent.contains("*/\npackage ")) { 1205 _sourceFormatterHelper.printError( 1206 fileName, "package: " + fileName); 1207 } 1208 1209 if (!newContent.endsWith("\n\n}") && 1210 !newContent.endsWith("{\n}")) { 1211 1212 _sourceFormatterHelper.printError(fileName, "}: " + fileName); 1213 } 1214 1215 if (portalJavaFiles && className.endsWith("ServiceImpl") && 1216 newContent.contains("ServiceUtil.")) { 1217 1218 _sourceFormatterHelper.printError( 1219 fileName, "ServiceUtil: " + fileName); 1220 } 1221 1222 if ((newContent != null) && !content.equals(newContent)) { 1223 _fileUtil.write(file, newContent); 1224 1225 _sourceFormatterHelper.printError(fileName, file); 1226 } 1227 } 1228 } 1229 1230 private static String _formatJavaContent(String fileName, String content) 1231 throws IOException { 1232 1233 boolean longLogFactoryUtil = false; 1234 1235 StringBundler sb = new StringBundler(); 1236 1237 UnsyncBufferedReader unsyncBufferedReader = new UnsyncBufferedReader( 1238 new UnsyncStringReader(content)); 1239 1240 int lineCount = 0; 1241 1242 String line = null; 1243 1244 String previousLine = StringPool.BLANK; 1245 1246 int lineToSkipIfEmpty = 0; 1247 1248 String javaTermName = null; 1249 int javaTermType = 0; 1250 1251 String previousJavaTermName = null; 1252 int previousJavaTermType = 0; 1253 1254 List<String> methodParameterTypes = new ArrayList<String>(); 1255 List<String> previousMethodParameterTypes = null; 1256 1257 boolean readMethodParameterTypes = false; 1258 boolean hasSameMethodName = false; 1259 1260 while ((line = unsyncBufferedReader.readLine()) != null) { 1261 lineCount++; 1262 1263 if (line.trim().length() == 0) { 1264 line = StringPool.BLANK; 1265 } 1266 1267 line = StringUtil.trimTrailing(line); 1268 1269 line = StringUtil.replace( 1270 line, 1271 new String[] { 1272 "* Copyright (c) 2000-2011 Liferay, Inc." 1273 }, 1274 new String[] { 1275 "* Copyright (c) 2000-2012 Liferay, Inc." 1276 }); 1277 1278 line = _replacePrimitiveWrapperInstantiation( 1279 fileName, line, lineCount); 1280 1281 String trimmedLine = StringUtil.trimLeading(line); 1282 1283 String excluded = 1284 _javaTermAlphabetizeExclusionsProperties.getProperty( 1285 StringUtil.replace( 1286 fileName, "\\", "/") + StringPool.AT + lineCount); 1287 1288 if (excluded == null) { 1289 excluded = _javaTermAlphabetizeExclusionsProperties.getProperty( 1290 StringUtil.replace(fileName, "\\", "/")); 1291 } 1292 1293 if (line.startsWith(StringPool.TAB + "private ") || 1294 line.startsWith(StringPool.TAB + "protected ") || 1295 line.startsWith(StringPool.TAB + "public ")) { 1296 1297 hasSameMethodName = false; 1298 1299 Tuple tuple = _getJavaTermTuple(line); 1300 1301 if (tuple != null) { 1302 javaTermName = (String)tuple.getObject(0); 1303 1304 if (Validator.isNotNull(javaTermName)) { 1305 javaTermType = (Integer)tuple.getObject(1); 1306 1307 boolean isMethod = _isInJavaTermTypeGroup( 1308 javaTermType, _TYPE_METHOD); 1309 boolean isPrivateMethodOrVariable = 1310 _isInJavaTermTypeGroup( 1311 javaTermType, _TYPE_PRIVATE_METHOD_OR_VARIABLE); 1312 1313 if (isMethod) { 1314 readMethodParameterTypes = true; 1315 } 1316 1317 if ((isPrivateMethodOrVariable && 1318 !javaTermName.startsWith(StringPool.UNDERLINE) && 1319 !javaTermName.equals("serialVersionUID")) || 1320 (!isPrivateMethodOrVariable && 1321 javaTermName.startsWith(StringPool.UNDERLINE))) { 1322 1323 _sourceFormatterHelper.printError( 1324 fileName, 1325 "underscore: " + fileName + " " + lineCount); 1326 } 1327 1328 if (_isInJavaTermTypeGroup( 1329 javaTermType, _TYPE_VARIABLE_NOT_STATIC)) { 1330 1331 char firstChar = javaTermName.charAt(0); 1332 1333 if (firstChar == CharPool.UNDERLINE) { 1334 firstChar = javaTermName.charAt(1); 1335 } 1336 1337 if (Character.isUpperCase(firstChar)) { 1338 _sourceFormatterHelper.printError( 1339 fileName, 1340 "final: " + fileName + " " + lineCount); 1341 } 1342 } 1343 1344 if (Validator.isNotNull(previousJavaTermName) && 1345 (excluded == null)) { 1346 1347 if (previousJavaTermType > javaTermType) { 1348 _sourceFormatterHelper.printError( 1349 fileName, 1350 "order: " + fileName + " " + lineCount); 1351 } 1352 else if (previousJavaTermType == javaTermType) { 1353 if (isMethod && 1354 previousJavaTermName.equals(javaTermName)) { 1355 1356 hasSameMethodName = true; 1357 } 1358 else { 1359 _compareJavaTermNames( 1360 fileName, previousJavaTermName, 1361 javaTermName, lineCount); 1362 } 1363 } 1364 } 1365 1366 previousJavaTermName = javaTermName; 1367 previousJavaTermType = javaTermType; 1368 } 1369 } 1370 } 1371 1372 if (readMethodParameterTypes) { 1373 methodParameterTypes = _addMethodParameterTypes( 1374 trimmedLine, methodParameterTypes); 1375 1376 if (trimmedLine.contains(StringPool.CLOSE_PARENTHESIS)) { 1377 if (hasSameMethodName) { 1378 _compareMethodParameterTypes( 1379 fileName, previousMethodParameterTypes, 1380 methodParameterTypes, lineCount); 1381 } 1382 1383 readMethodParameterTypes = false; 1384 1385 previousMethodParameterTypes = ListUtil.copy( 1386 methodParameterTypes); 1387 1388 methodParameterTypes.clear(); 1389 } 1390 } 1391 1392 if (!trimmedLine.contains(StringPool.DOUBLE_SLASH) && 1393 !trimmedLine.startsWith(StringPool.STAR)) { 1394 1395 while (trimmedLine.contains(StringPool.TAB)) { 1396 line = StringUtil.replaceLast( 1397 line, StringPool.TAB, StringPool.SPACE); 1398 1399 trimmedLine = StringUtil.replaceLast( 1400 trimmedLine, StringPool.TAB, StringPool.SPACE); 1401 } 1402 1403 while (trimmedLine.contains(StringPool.DOUBLE_SPACE) && 1404 !trimmedLine.contains( 1405 StringPool.QUOTE + StringPool.DOUBLE_SPACE) && 1406 !fileName.contains("Test")) { 1407 1408 line = StringUtil.replaceLast( 1409 line, StringPool.DOUBLE_SPACE, StringPool.SPACE); 1410 1411 trimmedLine = StringUtil.replaceLast( 1412 trimmedLine, StringPool.DOUBLE_SPACE, StringPool.SPACE); 1413 } 1414 1415 if (!line.contains(StringPool.QUOTE)) { 1416 if ((trimmedLine.startsWith("private ") || 1417 trimmedLine.startsWith("protected ") || 1418 trimmedLine.startsWith("public ")) && 1419 line.contains(" (")) { 1420 1421 line = StringUtil.replace(line, " (", "("); 1422 } 1423 1424 if (line.contains(" [")) { 1425 line = StringUtil.replace(line, " [", "["); 1426 } 1427 1428 for (int x = -1;;) { 1429 x = line.indexOf(StringPool.COMMA, x + 1); 1430 1431 if (x == -1) { 1432 break; 1433 } 1434 1435 if (line.length() > (x + 1)) { 1436 char nextChar = line.charAt(x + 1); 1437 1438 if ((nextChar != CharPool.SPACE) && 1439 (nextChar != CharPool.APOSTROPHE)) { 1440 1441 line = StringUtil.insert( 1442 line, StringPool.SPACE, x + 1); 1443 } 1444 } 1445 1446 if (x > 0) { 1447 char previousChar = line.charAt(x - 1); 1448 1449 if (previousChar == CharPool.SPACE) { 1450 line = line.substring(0, x - 1).concat( 1451 line.substring(x)); 1452 } 1453 } 1454 } 1455 } 1456 } 1457 1458 if (line.contains(" ") && !line.matches("\\s*\\*.*")) { 1459 if (!fileName.endsWith("StringPool.java")) { 1460 _sourceFormatterHelper.printError( 1461 fileName, "tab: " + fileName + " " + lineCount); 1462 } 1463 } 1464 1465 if (line.contains(" {") && !line.matches("\\s*\\*.*")) { 1466 _sourceFormatterHelper.printError( 1467 fileName, "{:" + fileName + " " + lineCount); 1468 } 1469 1470 if (line.endsWith("private static Log _log =")) { 1471 longLogFactoryUtil = true; 1472 } 1473 1474 excluded = _lineLengthExclusionsProperties.getProperty( 1475 StringUtil.replace( 1476 fileName, "\\", "/") + StringPool.AT + lineCount); 1477 1478 if (excluded == null) { 1479 excluded = _lineLengthExclusionsProperties.getProperty( 1480 StringUtil.replace(fileName, "\\", "/")); 1481 } 1482 1483 String combinedLines = null; 1484 1485 if ((excluded == null) && 1486 !line.startsWith("import ") && !line.startsWith("package ") && 1487 !line.matches("\\s*\\*.*")) { 1488 1489 if (fileName.endsWith("Table.java") && 1490 line.contains("String TABLE_SQL_CREATE = ")) { 1491 } 1492 else if (fileName.endsWith("Table.java") && 1493 line.contains("String TABLE_SQL_DROP = ")) { 1494 } 1495 else if (fileName.endsWith("Table.java") && 1496 line.contains(" index IX_")) { 1497 } 1498 else { 1499 if (_getLineLength(line) > 80) { 1500 _sourceFormatterHelper.printError( 1501 fileName, "> 80: " + fileName + " " + lineCount); 1502 } 1503 else { 1504 combinedLines = _getCombinedLines( 1505 trimmedLine, previousLine); 1506 } 1507 } 1508 } 1509 1510 if (Validator.isNotNull(combinedLines)) { 1511 previousLine = combinedLines; 1512 1513 if (line.endsWith(StringPool.OPEN_CURLY_BRACE)) { 1514 lineToSkipIfEmpty = lineCount + 1; 1515 } 1516 } 1517 else { 1518 if ((lineCount > 1) && 1519 (Validator.isNotNull(previousLine) || 1520 (lineToSkipIfEmpty != lineCount - 1))) { 1521 1522 sb.append(previousLine); 1523 sb.append("\n"); 1524 } 1525 1526 previousLine = line; 1527 } 1528 } 1529 1530 sb.append(previousLine); 1531 1532 unsyncBufferedReader.close(); 1533 1534 String newContent = sb.toString(); 1535 1536 if (newContent.endsWith("\n")) { 1537 newContent = newContent.substring(0, newContent.length() - 1); 1538 } 1539 1540 if (longLogFactoryUtil) { 1541 newContent = StringUtil.replace( 1542 newContent, 1543 "private static Log _log =\n\t\tLogFactoryUtil.getLog(", 1544 "private static Log _log = LogFactoryUtil.getLog(\n\t\t"); 1545 } 1546 1547 return newContent; 1548 } 1549 1550 private static void _formatJSP() throws IOException { 1551 String basedir = "./"; 1552 1553 String copyright = _getCopyright(); 1554 String oldCopyright = _getOldCopyright(); 1555 1556 List<String> list = new ArrayList<String>(); 1557 1558 DirectoryScanner directoryScanner = new DirectoryScanner(); 1559 1560 directoryScanner.setBasedir(basedir); 1561 1562 String[] excludes = { 1563 "**\\portal\\aui\\**", "**\\bin\\**", "**\\null.jsp", 1564 "**\\tmp\\**", "**\\tools\\**" 1565 }; 1566 1567 excludes = ArrayUtil.append(excludes, _excludes); 1568 1569 directoryScanner.setExcludes(excludes); 1570 1571 directoryScanner.setIncludes( 1572 new String[] {"**\\*.jsp", "**\\*.jspf", "**\\*.vm"}); 1573 1574 list.addAll(_sourceFormatterHelper.scanForFiles(directoryScanner)); 1575 1576 String[] fileNames = list.toArray(new String[list.size()]); 1577 1578 for (String fileName : fileNames) { 1579 File file = new File(basedir + fileName); 1580 1581 String content = _fileUtil.read(file); 1582 1583 fileName = fileName.replace( 1584 CharPool.BACK_SLASH, CharPool.FORWARD_SLASH); 1585 1586 _jspContents.put(fileName, content); 1587 } 1588 1589 boolean stripJSPImports = true; 1590 1591 for (String fileName : fileNames) { 1592 File file = new File(basedir + fileName); 1593 1594 String content = _fileUtil.read(file); 1595 1596 String newContent = _formatJSPContent(fileName, content); 1597 1598 newContent = StringUtil.replace( 1599 newContent, 1600 new String[] { 1601 "<br/>", "\"/>", "\" >", "@page import", "\"%>", ")%>", 1602 "javascript: " 1603 }, 1604 new String[] { 1605 "<br />", "\" />", "\">", "@ page import", "\" %>", ") %>", 1606 "javascript:" 1607 }); 1608 1609 if (stripJSPImports) { 1610 try { 1611 newContent = _stripJSPImports(fileName, newContent); 1612 } 1613 catch (RuntimeException re) { 1614 stripJSPImports = false; 1615 } 1616 } 1617 1618 newContent = StringUtil.replace( 1619 newContent, 1620 new String[] { 1621 "* Copyright (c) 2000-2011 Liferay, Inc." 1622 }, 1623 new String[] { 1624 "* Copyright (c) 2000-2012 Liferay, Inc." 1625 }); 1626 1627 if (fileName.endsWith(".jsp") || fileName.endsWith(".jspf")) { 1628 if ((oldCopyright != null) && 1629 newContent.contains(oldCopyright)) { 1630 1631 newContent = StringUtil.replace( 1632 newContent, oldCopyright, copyright); 1633 1634 _sourceFormatterHelper.printError( 1635 fileName, "old (c): " + fileName); 1636 } 1637 1638 if (!newContent.contains(copyright)) { 1639 String customCopyright = _getCustomCopyright(file); 1640 1641 if (Validator.isNull(customCopyright) || 1642 !newContent.contains(customCopyright)) { 1643 1644 _sourceFormatterHelper.printError( 1645 fileName, "(c): " + fileName); 1646 } 1647 else { 1648 newContent = StringUtil.replace( 1649 newContent, "<%\n" + customCopyright + "\n%>", 1650 "<%--\n" + customCopyright + "\n--%>"); 1651 } 1652 } 1653 else { 1654 newContent = StringUtil.replace( 1655 newContent, "<%\n" + copyright + "\n%>", 1656 "<%--\n" + copyright + "\n--%>"); 1657 } 1658 } 1659 1660 newContent = StringUtil.replace( 1661 newContent, 1662 new String[] { 1663 "alert('<%= LanguageUtil.", 1664 "alert(\"<%= LanguageUtil.", 1665 "confirm('<%= LanguageUtil.", 1666 "confirm(\"<%= LanguageUtil." 1667 }, 1668 new String[] { 1669 "alert('<%= UnicodeLanguageUtil.", 1670 "alert(\"<%= UnicodeLanguageUtil.", 1671 "confirm('<%= UnicodeLanguageUtil.", 1672 "confirm(\"<%= UnicodeLanguageUtil." 1673 }); 1674 1675 if (newContent.contains(" ")) { 1676 if (!fileName.endsWith("template.vm")) { 1677 _sourceFormatterHelper.printError( 1678 fileName, "tab: " + fileName); 1679 } 1680 } 1681 1682 if (fileName.endsWith("init.jsp")) { 1683 int x = newContent.indexOf("<%@ page import="); 1684 1685 int y = newContent.lastIndexOf("<%@ page import="); 1686 1687 y = newContent.indexOf("%>", y); 1688 1689 if ((x != -1) && (y != -1) && (y > x)) { 1690 1691 // Set compressImports to false to decompress imports 1692 1693 boolean compressImports = true; 1694 1695 if (compressImports) { 1696 String imports = newContent.substring(x, y); 1697 1698 imports = StringUtil.replace( 1699 imports, new String[] {"%>\r\n<%@ ", "%>\n<%@ "}, 1700 new String[] {"%><%@\r\n", "%><%@\n"}); 1701 1702 newContent = 1703 newContent.substring(0, x) + imports + 1704 newContent.substring(y); 1705 } 1706 } 1707 } 1708 1709 _checkXSS(fileName, newContent); 1710 1711 if ((newContent != null) && !content.equals(newContent)) { 1712 _fileUtil.write(file, newContent); 1713 1714 _sourceFormatterHelper.printError(fileName, file); 1715 } 1716 } 1717 } 1718 1719 private static String _formatJSPContent(String fileName, String content) 1720 throws IOException { 1721 1722 StringBundler sb = new StringBundler(); 1723 1724 UnsyncBufferedReader unsyncBufferedReader = new UnsyncBufferedReader( 1725 new UnsyncStringReader(content)); 1726 1727 int lineCount = 0; 1728 1729 String line = null; 1730 1731 String previousAttribute = null; 1732 boolean readAttributes = false; 1733 1734 while ((line = unsyncBufferedReader.readLine()) != null) { 1735 lineCount++; 1736 1737 if (line.trim().length() == 0) { 1738 line = StringPool.BLANK; 1739 } 1740 1741 line = StringUtil.trimTrailing(line); 1742 1743 if (line.contains("<aui:button ") && 1744 line.contains("type=\"button\"")) { 1745 1746 _sourceFormatterHelper.printError( 1747 fileName, "aui:button " + fileName + " " + lineCount); 1748 } 1749 1750 String trimmedLine = StringUtil.trimLeading(line); 1751 1752 if (readAttributes) { 1753 if (!trimmedLine.startsWith(StringPool.FORWARD_SLASH) && 1754 !trimmedLine.startsWith(StringPool.GREATER_THAN)) { 1755 1756 int pos = trimmedLine.indexOf(StringPool.EQUAL); 1757 1758 if (pos != -1) { 1759 String attribute = trimmedLine.substring(0, pos); 1760 1761 if (Validator.isNotNull(previousAttribute)) { 1762 if (!_isJSPAttributName(attribute)) { 1763 _sourceFormatterHelper.printError( 1764 fileName, 1765 "attribute: " + fileName + " " + lineCount); 1766 } 1767 else if (previousAttribute.compareTo( 1768 attribute) > 0) { 1769 1770 /* 1771 _sourceFormatterHelper.printError( 1772 fileName, 1773 "sort: " + fileName + " " + lineCount); 1774 */ 1775 } 1776 } 1777 1778 previousAttribute = attribute; 1779 } 1780 } 1781 else { 1782 previousAttribute = null; 1783 readAttributes = false; 1784 } 1785 } 1786 1787 if (trimmedLine.startsWith(StringPool.LESS_THAN) && 1788 !trimmedLine.startsWith("<%") && 1789 !trimmedLine.startsWith("<!")) { 1790 1791 if (!trimmedLine.contains(StringPool.GREATER_THAN) && 1792 !trimmedLine.contains(StringPool.SPACE)) { 1793 1794 readAttributes = true; 1795 } 1796 else { 1797 _checkJSPAttributes(fileName, trimmedLine, lineCount); 1798 } 1799 } 1800 1801 if (!trimmedLine.contains(StringPool.DOUBLE_SLASH) && 1802 !trimmedLine.startsWith(StringPool.STAR)) { 1803 1804 while (trimmedLine.contains(StringPool.TAB)) { 1805 line = StringUtil.replaceLast( 1806 line, StringPool.TAB, StringPool.SPACE); 1807 1808 trimmedLine = StringUtil.replaceLast( 1809 trimmedLine, StringPool.TAB, StringPool.SPACE); 1810 } 1811 1812 while (trimmedLine.contains(StringPool.DOUBLE_SPACE) && 1813 !trimmedLine.contains( 1814 StringPool.QUOTE + StringPool.DOUBLE_SPACE) && 1815 !fileName.endsWith(".vm")) { 1816 1817 line = StringUtil.replaceLast( 1818 line, StringPool.DOUBLE_SPACE, StringPool.SPACE); 1819 1820 trimmedLine = StringUtil.replaceLast( 1821 trimmedLine, StringPool.DOUBLE_SPACE, StringPool.SPACE); 1822 } 1823 } 1824 1825 int x = line.indexOf("<%@ include file"); 1826 1827 if (x != -1) { 1828 x = line.indexOf(StringPool.QUOTE, x); 1829 1830 int y = line.indexOf(StringPool.QUOTE, x + 1); 1831 1832 if (y != -1) { 1833 String includeFileName = line.substring(x + 1, y); 1834 1835 Matcher matcher = _jspIncludeFilePattern.matcher( 1836 includeFileName); 1837 1838 if (!matcher.find()) { 1839 _sourceFormatterHelper.printError( 1840 fileName, 1841 "include: " + fileName + " " + lineCount); 1842 } 1843 } 1844 } 1845 1846 line = _replacePrimitiveWrapperInstantiation( 1847 fileName, line, lineCount); 1848 1849 sb.append(line); 1850 sb.append("\n"); 1851 } 1852 1853 unsyncBufferedReader.close(); 1854 1855 content = sb.toString(); 1856 1857 if (content.endsWith("\n")) { 1858 content = content.substring(0, content.length() -1); 1859 } 1860 1861 content = _formatTaglibQuotes(fileName, content, StringPool.QUOTE); 1862 content = _formatTaglibQuotes(fileName, content, StringPool.APOSTROPHE); 1863 1864 return content; 1865 } 1866 1867 private static void _formatPortletXML() 1868 throws DocumentException, IOException { 1869 1870 String basedir = "./"; 1871 1872 if (_fileUtil.exists(basedir + "portal-impl")) { 1873 File file = new File( 1874 basedir + "portal-web/docroot/WEB-INF/portlet-custom.xml"); 1875 1876 String content = _fileUtil.read(file); 1877 1878 String newContent = _formatPortletXML(content); 1879 1880 if ((newContent != null) && !content.equals(newContent)) { 1881 _fileUtil.write(file, newContent); 1882 1883 _sourceFormatterHelper.printError(file.toString(), file); 1884 } 1885 } 1886 else { 1887 DirectoryScanner directoryScanner = new DirectoryScanner(); 1888 1889 directoryScanner.setBasedir(basedir); 1890 directoryScanner.setIncludes(new String[] {"**\\portlet.xml"}); 1891 1892 List<String> fileNames = _sourceFormatterHelper.scanForFiles( 1893 directoryScanner); 1894 1895 for (String fileName : fileNames) { 1896 File file = new File(basedir + fileName); 1897 1898 String content = _fileUtil.read(file); 1899 1900 String newContent = _formatPortletXML(content); 1901 1902 if ((newContent != null) && !content.equals(newContent)) { 1903 _fileUtil.write(file, newContent); 1904 1905 _sourceFormatterHelper.printError(fileName, file); 1906 } 1907 } 1908 } 1909 } 1910 1911 private static String _formatPortletXML(String content) 1912 throws DocumentException, IOException { 1913 1914 Document document = _saxReaderUtil.read(content); 1915 1916 Element rootElement = document.getRootElement(); 1917 1918 rootElement.sortAttributes(true); 1919 1920 List<Element> portletElements = rootElement.elements("portlet"); 1921 1922 for (Element portletElement : portletElements) { 1923 portletElement.sortElementsByChildElement("init-param", "name"); 1924 1925 Element portletPreferencesElement = portletElement.element( 1926 "portlet-preferences"); 1927 1928 if (portletPreferencesElement != null) { 1929 portletPreferencesElement.sortElementsByChildElement( 1930 "preference", "name"); 1931 } 1932 } 1933 1934 return document.formattedString(); 1935 } 1936 1937 private static void _formatSH() throws IOException { 1938 _formatSH("ext/create.sh"); 1939 _formatSH("hooks/create.sh"); 1940 _formatSH("layouttpl/create.sh"); 1941 _formatSH("portlets/create.sh"); 1942 _formatSH("themes/create.sh"); 1943 } 1944 1945 private static void _formatSH(String fileName) throws IOException { 1946 File file = new File(fileName); 1947 1948 if (!file.exists()) { 1949 return; 1950 } 1951 1952 String content = _fileUtil.read(new File(fileName), true); 1953 1954 if (content.contains("\r")) { 1955 _sourceFormatterHelper.printError( 1956 fileName, "Invalid new line character"); 1957 1958 content = StringUtil.replace(content, "\r", ""); 1959 1960 _fileUtil.write(fileName, content); 1961 } 1962 } 1963 1964 private static String _formatTaglibQuotes( 1965 String fileName, String content, String quoteType) { 1966 1967 String quoteFix = StringPool.APOSTROPHE; 1968 1969 if (quoteFix.equals(quoteType)) { 1970 quoteFix = StringPool.QUOTE; 1971 } 1972 1973 Pattern pattern = Pattern.compile(_getTaglibRegex(quoteType)); 1974 1975 Matcher matcher = pattern.matcher(content); 1976 1977 while (matcher.find()) { 1978 int x = content.indexOf(quoteType + "<%=", matcher.start()); 1979 int y = content.indexOf("%>" + quoteType, x); 1980 1981 while ((x != -1) && (y != -1)) { 1982 String result = content.substring(x + 1, y + 2); 1983 1984 if (result.contains(quoteType)) { 1985 int lineCount = 1; 1986 1987 char contentCharArray[] = content.toCharArray(); 1988 1989 for (int i = 0; i < x; i++) { 1990 if (contentCharArray[i] == CharPool.NEW_LINE) { 1991 lineCount++; 1992 } 1993 } 1994 1995 if (!result.contains(quoteFix)) { 1996 StringBundler sb = new StringBundler(5); 1997 1998 sb.append(content.substring(0, x)); 1999 sb.append(quoteFix); 2000 sb.append(result); 2001 sb.append(quoteFix); 2002 sb.append(content.substring(y + 3, content.length())); 2003 2004 content = sb.toString(); 2005 } 2006 else { 2007 _sourceFormatterHelper.printError( 2008 fileName, "taglib: " + fileName + " " + lineCount); 2009 } 2010 } 2011 2012 x = content.indexOf(quoteType + "<%=", y); 2013 2014 if (x > matcher.end()) { 2015 break; 2016 } 2017 2018 y = content.indexOf("%>" + quoteType, x); 2019 } 2020 } 2021 2022 return content; 2023 } 2024 2025 private static void _formatWebXML() throws IOException { 2026 String basedir = "./"; 2027 2028 if (_fileUtil.exists(basedir + "portal-impl")) { 2029 Properties properties = new Properties(); 2030 2031 String propertiesContent = _fileUtil.read( 2032 basedir + "portal-impl/src/portal.properties"); 2033 2034 PropertiesUtil.load(properties, propertiesContent); 2035 2036 String[] locales = StringUtil.split( 2037 properties.getProperty(PropsKeys.LOCALES)); 2038 2039 Arrays.sort(locales); 2040 2041 Set<String> urlPatterns = new TreeSet<String>(); 2042 2043 for (String locale : locales) { 2044 int pos = locale.indexOf(StringPool.UNDERLINE); 2045 2046 String languageCode = locale.substring(0, pos); 2047 2048 urlPatterns.add(languageCode); 2049 urlPatterns.add(locale); 2050 } 2051 2052 StringBundler sb = new StringBundler(); 2053 2054 for (String urlPattern : urlPatterns) { 2055 sb.append("\t<servlet-mapping>\n"); 2056 sb.append("\t\t<servlet-name>I18n Servlet</servlet-name>\n"); 2057 sb.append( 2058 "\t\t<url-pattern>/" + urlPattern +"/*</url-pattern>\n"); 2059 sb.append("\t</servlet-mapping>\n"); 2060 } 2061 2062 File file = new File( 2063 basedir + "portal-web/docroot/WEB-INF/web.xml"); 2064 2065 String content = _fileUtil.read(file); 2066 2067 int x = content.indexOf("<servlet-mapping>"); 2068 2069 x = content.indexOf("<servlet-name>I18n Servlet</servlet-name>", x); 2070 2071 x = content.lastIndexOf("<servlet-mapping>", x) - 1; 2072 2073 int y = content.lastIndexOf( 2074 "<servlet-name>I18n Servlet</servlet-name>"); 2075 2076 y = content.indexOf("</servlet-mapping>", y) + 19; 2077 2078 String newContent = 2079 content.substring(0, x) + sb.toString() + content.substring(y); 2080 2081 x = newContent.indexOf("<security-constraint>"); 2082 2083 x = newContent.indexOf( 2084 "<web-resource-name>/c/portal/protected</web-resource-name>", 2085 x); 2086 2087 x = newContent.indexOf("<url-pattern>", x) - 3; 2088 2089 y = newContent.indexOf("<http-method>", x); 2090 2091 y = newContent.lastIndexOf("</url-pattern>", y) + 15; 2092 2093 sb = new StringBundler(); 2094 2095 sb.append( 2096 "\t\t\t<url-pattern>/c/portal/protected</url-pattern>\n"); 2097 2098 for (String urlPattern : urlPatterns) { 2099 sb.append( 2100 "\t\t\t<url-pattern>/" + urlPattern + 2101 "/c/portal/protected</url-pattern>\n"); 2102 } 2103 2104 newContent = 2105 newContent.substring(0, x) + sb.toString() + 2106 newContent.substring(y); 2107 2108 if ((newContent != null) && !content.equals(newContent)) { 2109 _fileUtil.write(file, newContent); 2110 2111 System.out.println(file); 2112 } 2113 } 2114 else { 2115 String webXML = ContentUtil.get( 2116 "com/liferay/portal/deploy/dependencies/web.xml"); 2117 2118 DirectoryScanner directoryScanner = new DirectoryScanner(); 2119 2120 directoryScanner.setBasedir(basedir); 2121 directoryScanner.setIncludes(new String[] {"**\\web.xml"}); 2122 2123 List<String> fileNames = _sourceFormatterHelper.scanForFiles( 2124 directoryScanner); 2125 2126 for (String fileName : fileNames) { 2127 String content = _fileUtil.read(basedir + fileName); 2128 2129 if (content.equals(webXML)) { 2130 _sourceFormatterHelper.printError(fileName, fileName); 2131 } 2132 } 2133 } 2134 } 2135 2136 private static String _getClassName(String line) { 2137 int pos = line.indexOf(" implements "); 2138 2139 if (pos == -1) { 2140 pos = line.indexOf(" extends "); 2141 } 2142 2143 if (pos == -1) { 2144 pos = line.indexOf(StringPool.OPEN_CURLY_BRACE); 2145 } 2146 2147 if (pos != -1) { 2148 line = line.substring(0, pos); 2149 } 2150 2151 line = line.trim(); 2152 2153 pos = line.lastIndexOf(StringPool.SPACE); 2154 2155 return line.substring(pos + 1); 2156 } 2157 2158 private static String _getCombinedLines(String line, String previousLine) { 2159 if (Validator.isNull(previousLine)) { 2160 return null; 2161 } 2162 2163 int previousLineLength = _getLineLength(previousLine); 2164 String trimmedPreviousLine = StringUtil.trimLeading(previousLine); 2165 2166 if ((line.length() + previousLineLength) < 80) { 2167 if (trimmedPreviousLine.startsWith("for ") && 2168 previousLine.endsWith(StringPool.COLON) && 2169 line.endsWith(StringPool.OPEN_CURLY_BRACE)) { 2170 2171 return previousLine + StringPool.SPACE + line; 2172 } 2173 2174 if (previousLine.endsWith(StringPool.EQUAL) && 2175 line.endsWith(StringPool.SEMICOLON)) { 2176 2177 return previousLine + StringPool.SPACE + line; 2178 } 2179 2180 if ((trimmedPreviousLine.startsWith("if ") || 2181 trimmedPreviousLine.startsWith("else ")) && 2182 (previousLine.endsWith("||") || previousLine.endsWith("&&")) && 2183 line.endsWith(StringPool.OPEN_CURLY_BRACE)) { 2184 2185 return previousLine + StringPool.SPACE + line; 2186 } 2187 } 2188 2189 if (!previousLine.endsWith(StringPool.OPEN_PARENTHESIS)) { 2190 return null; 2191 } 2192 2193 if ((line.length() + previousLineLength) > 80) { 2194 return null; 2195 } 2196 2197 if (line.endsWith(StringPool.SEMICOLON)) { 2198 return previousLine + line; 2199 } 2200 2201 if ((line.endsWith(StringPool.OPEN_CURLY_BRACE) || 2202 line.endsWith(StringPool.CLOSE_PARENTHESIS)) && 2203 (trimmedPreviousLine.startsWith("else ") || 2204 trimmedPreviousLine.startsWith("if ") || 2205 trimmedPreviousLine.startsWith("private ") || 2206 trimmedPreviousLine.startsWith("protected ") || 2207 trimmedPreviousLine.startsWith("public "))) { 2208 2209 return previousLine + line; 2210 } 2211 2212 return null; 2213 } 2214 2215 private static String _getConstructorOrMethodName(String line, int pos) { 2216 line = line.substring(0, pos); 2217 2218 int x = line.lastIndexOf(StringPool.SPACE); 2219 2220 return line.substring(x + 1); 2221 } 2222 2223 private static String _getCopyright() throws IOException { 2224 String copyright = _fileUtil.read("copyright.txt"); 2225 2226 if (Validator.isNull(copyright)) { 2227 copyright = _fileUtil.read("../copyright.txt"); 2228 } 2229 2230 if (Validator.isNull(copyright)) { 2231 copyright = _fileUtil.read("../../copyright.txt"); 2232 } 2233 2234 return copyright; 2235 } 2236 2237 private static String _getCustomCopyright(File file) 2238 throws IOException { 2239 2240 String absolutePath = _fileUtil.getAbsolutePath(file); 2241 2242 for (int x = absolutePath.length();;) { 2243 x = absolutePath.lastIndexOf(StringPool.SLASH, x); 2244 2245 if (x == -1) { 2246 break; 2247 } 2248 2249 String copyright = _fileUtil.read( 2250 absolutePath.substring(0, x + 1) + "copyright.txt"); 2251 2252 if (Validator.isNotNull(copyright)) { 2253 return copyright; 2254 } 2255 2256 x = x - 1; 2257 } 2258 2259 return null; 2260 } 2261 2262 private static Properties _getExclusionsProperties(String fileName) 2263 throws IOException { 2264 2265 Properties exclusionsProperties = new Properties(); 2266 2267 ClassLoader classLoader = SourceFormatter.class.getClassLoader(); 2268 2269 String sourceFormatterExclusions = System.getProperty( 2270 "source-formatter-exclusions", 2271 "com/liferay/portal/tools/dependencies/" + fileName); 2272 2273 URL url = classLoader.getResource(sourceFormatterExclusions); 2274 2275 if (url == null) { 2276 return null; 2277 } 2278 2279 InputStream inputStream = url.openStream(); 2280 2281 exclusionsProperties.load(inputStream); 2282 2283 inputStream.close(); 2284 2285 return exclusionsProperties; 2286 } 2287 2288 private static Tuple _getJavaTermTuple(String line) { 2289 int pos = line.indexOf(StringPool.OPEN_PARENTHESIS); 2290 2291 if (line.startsWith(StringPool.TAB + "public static final ") && 2292 (line.endsWith(StringPool.SEMICOLON) || 2293 line.contains(StringPool.EQUAL))) { 2294 2295 return new Tuple( 2296 _getVariableName(line), _TYPE_VARIABLE_PUBLIC_STATIC_FINAL); 2297 } 2298 else if (line.startsWith(StringPool.TAB + "public static ")) { 2299 if (line.endsWith(StringPool.SEMICOLON) || 2300 line.contains(StringPool.EQUAL)) { 2301 2302 return new Tuple( 2303 _getVariableName(line), _TYPE_VARIABLE_PUBLIC_STATIC); 2304 } 2305 2306 if (pos != -1) { 2307 return new Tuple( 2308 _getConstructorOrMethodName(line, pos), 2309 _TYPE_METHOD_PUBLIC_STATIC); 2310 } 2311 2312 if (line.startsWith(StringPool.TAB + "public static class ")) { 2313 return new Tuple( 2314 _getClassName(line), _TYPE_CLASS_PUBLIC_STATIC); 2315 } 2316 } 2317 else if (line.startsWith(StringPool.TAB + "public ")) { 2318 if (line.contains(StringPool.EQUAL) || 2319 (line.endsWith(StringPool.SEMICOLON) && 2320 !line.contains(StringPool.OPEN_PARENTHESIS))) { 2321 2322 return new Tuple(_getVariableName(line), _TYPE_VARIABLE_PUBLIC); 2323 } 2324 2325 if (pos != -1) { 2326 int spaceCount = StringUtil.count( 2327 line.substring(0, pos), StringPool.SPACE); 2328 2329 if (spaceCount == 1) { 2330 return new Tuple( 2331 _getConstructorOrMethodName(line, pos), 2332 _TYPE_CONSTRUCTOR_PUBLIC); 2333 } 2334 2335 if (spaceCount > 1) { 2336 return new Tuple( 2337 _getConstructorOrMethodName(line, pos), 2338 _TYPE_METHOD_PUBLIC); 2339 } 2340 } 2341 else if (line.startsWith(StringPool.TAB + "public class ")) { 2342 return new Tuple(_getClassName(line), _TYPE_CLASS_PUBLIC); 2343 } 2344 } 2345 else if (line.startsWith(StringPool.TAB + "protected static final ")) { 2346 if (line.endsWith(StringPool.SEMICOLON) || 2347 line.contains(StringPool.EQUAL)) { 2348 2349 return new Tuple( 2350 _getVariableName(line), 2351 _TYPE_VARIABLE_PROTECTED_STATIC_FINAL); 2352 } 2353 } 2354 else if (line.startsWith(StringPool.TAB + "protected static ")) { 2355 if (line.endsWith(StringPool.SEMICOLON) || 2356 line.contains(StringPool.EQUAL)) { 2357 2358 return new Tuple( 2359 _getVariableName(line), _TYPE_VARIABLE_PROTECTED_STATIC); 2360 } 2361 2362 if (pos != -1) { 2363 return new Tuple( 2364 _getConstructorOrMethodName(line, pos), 2365 _TYPE_METHOD_PROTECTED_STATIC); 2366 } 2367 } 2368 else if (line.startsWith(StringPool.TAB + "protected ")) { 2369 if ((pos != -1) && !line.contains(StringPool.EQUAL)) { 2370 int spaceCount = StringUtil.count( 2371 line.substring(0, pos), StringPool.SPACE); 2372 2373 if (spaceCount == 1) { 2374 return new Tuple( 2375 _getConstructorOrMethodName(line, pos), 2376 _TYPE_CONSTRUCTOR_PROTECTED); 2377 } 2378 2379 if (spaceCount > 1) { 2380 return new Tuple( 2381 _getConstructorOrMethodName(line, pos), 2382 _TYPE_METHOD_PROTECTED); 2383 } 2384 } 2385 2386 return new Tuple(_getVariableName(line), _TYPE_VARIABLE_PROTECTED); 2387 } 2388 else if (line.startsWith(StringPool.TAB + "private static final ")) { 2389 if (line.endsWith(StringPool.SEMICOLON) || 2390 line.contains(StringPool.EQUAL)) { 2391 2392 return new Tuple( 2393 _getVariableName(line), 2394 _TYPE_VARIABLE_PRIVATE_STATIC_FINAL); 2395 } 2396 } 2397 else if (line.startsWith(StringPool.TAB + "private static ")) { 2398 if (line.endsWith(StringPool.SEMICOLON) || 2399 line.contains(StringPool.EQUAL)) { 2400 2401 return new Tuple( 2402 _getVariableName(line), _TYPE_VARIABLE_PRIVATE_STATIC); 2403 } 2404 2405 if (pos != -1) { 2406 return new Tuple( 2407 _getConstructorOrMethodName(line, pos), 2408 _TYPE_METHOD_PRIVATE_STATIC); 2409 } 2410 2411 if (line.startsWith(StringPool.TAB + "private static class ")) { 2412 return new Tuple( 2413 _getClassName(line), _TYPE_CLASS_PRIVATE_STATIC); 2414 } 2415 } 2416 else if (line.startsWith(StringPool.TAB + "private ")) { 2417 if (line.endsWith(StringPool.SEMICOLON) || 2418 line.contains(StringPool.EQUAL)) { 2419 2420 return new Tuple( 2421 _getVariableName(line), _TYPE_VARIABLE_PRIVATE); 2422 } 2423 2424 if (pos != -1) { 2425 int spaceCount = StringUtil.count( 2426 line.substring(0, pos), StringPool.SPACE); 2427 2428 if (spaceCount == 1) { 2429 return new Tuple( 2430 _getConstructorOrMethodName(line, pos), 2431 _TYPE_CONSTRUCTOR_PRIVATE); 2432 } 2433 2434 if (spaceCount > 1) { 2435 return new Tuple( 2436 _getConstructorOrMethodName(line, pos), 2437 _TYPE_METHOD_PRIVATE); 2438 } 2439 } 2440 else if (line.startsWith(StringPool.TAB + "private class ")) { 2441 return new Tuple(_getClassName(line), _TYPE_CLASS_PRIVATE); 2442 } 2443 } 2444 2445 return null; 2446 } 2447 2448 private static List<String> _getJSPDuplicateImports( 2449 String fileName, String content, List<String> importLines) { 2450 2451 List<String> duplicateImports = new ArrayList<String>(); 2452 2453 for (String importLine : importLines) { 2454 int x = content.indexOf("<%@ include file="); 2455 2456 if (x == -1) { 2457 continue; 2458 } 2459 2460 int y = content.indexOf("<%@ page import="); 2461 2462 if (y == -1) { 2463 continue; 2464 } 2465 2466 if ((x < y) && _isJSPDuplicateImport(fileName, importLine, false)) { 2467 duplicateImports.add(importLine); 2468 } 2469 } 2470 2471 return duplicateImports; 2472 } 2473 2474 private static int _getLineLength(String line) { 2475 int lineLength = 0; 2476 2477 int tabLength = 4; 2478 2479 for (char c : line.toCharArray()) { 2480 if (c == CharPool.TAB) { 2481 for (int i = 0; i < tabLength; i++) { 2482 lineLength++; 2483 } 2484 2485 tabLength = 4; 2486 } 2487 else { 2488 lineLength++; 2489 2490 tabLength--; 2491 2492 if (tabLength <= 0) { 2493 tabLength = 4; 2494 } 2495 } 2496 } 2497 2498 return lineLength; 2499 } 2500 2501 private static String _getOldCopyright() throws IOException { 2502 String copyright = _fileUtil.read("old-copyright.txt"); 2503 2504 if (Validator.isNull(copyright)) { 2505 copyright = _fileUtil.read("../old-copyright.txt"); 2506 } 2507 2508 if (Validator.isNull(copyright)) { 2509 copyright = _fileUtil.read("../../old-copyright.txt"); 2510 } 2511 2512 return copyright; 2513 } 2514 2515 private static Collection<String> _getPluginJavaFiles() { 2516 String basedir = "./"; 2517 2518 Collection<String> fileNames = new TreeSet<String>(); 2519 2520 DirectoryScanner directoryScanner = new DirectoryScanner(); 2521 2522 directoryScanner.setBasedir(basedir); 2523 2524 String[] excludes = { 2525 "**\\bin\\**", "**\\model\\*Clp.java", 2526 "**\\model\\impl\\*BaseImpl.java", 2527 "**\\model\\impl\\*Model.java", 2528 "**\\model\\impl\\*ModelImpl.java", 2529 "**\\service\\**\\model\\*Model.java", 2530 "**\\service\\**\\model\\*Soap.java", 2531 "**\\service\\**\\model\\*Wrapper.java", 2532 "**\\service\\**\\service\\*Service.java", 2533 "**\\service\\**\\service\\*ServiceClp.java", 2534 "**\\service\\**\\service\\*ServiceFactory.java", 2535 "**\\service\\**\\service\\*ServiceUtil.java", 2536 "**\\service\\**\\service\\*ServiceWrapper.java", 2537 "**\\service\\**\\service\\ClpSerializer.java", 2538 "**\\service\\**\\service\\messaging\\*ClpMessageListener.java", 2539 "**\\service\\**\\service\\persistence\\*Finder.java", 2540 "**\\service\\**\\service\\persistence\\*Persistence.java", 2541 "**\\service\\**\\service\\persistence\\*Util.java", 2542 "**\\service\\base\\*ServiceBaseImpl.java", 2543 "**\\service\\http\\*JSONSerializer.java", 2544 "**\\service\\http\\*ServiceHttp.java", 2545 "**\\service\\http\\*ServiceJSON.java", 2546 "**\\service\\http\\*ServiceSoap.java", 2547 "**\\service\\persistence\\*PersistenceImpl.java", "**\\tmp\\**" 2548 }; 2549 2550 excludes = ArrayUtil.append(excludes, _excludes); 2551 2552 directoryScanner.setExcludes(excludes); 2553 2554 directoryScanner.setIncludes(new String[] {"**\\*.java"}); 2555 2556 fileNames.addAll(_sourceFormatterHelper.scanForFiles(directoryScanner)); 2557 2558 return fileNames; 2559 } 2560 2561 private static Collection<String> _getPortalJavaFiles() { 2562 String basedir = "./"; 2563 2564 Collection<String> fileNames = new TreeSet<String>(); 2565 2566 DirectoryScanner directoryScanner = new DirectoryScanner(); 2567 2568 directoryScanner.setBasedir(basedir); 2569 2570 String[] excludes = { 2571 "**\\InstanceWrapperBuilder.java", "**\\*_IW.java", 2572 "**\\PropsKeys.java", "**\\PropsValues.java", 2573 "**\\ServiceBuilder.java", "**\\SourceFormatter.java", 2574 "**\\WebKeys.java", "**\\bin\\**", "**\\classes\\*", 2575 "**\\counter\\service\\**", "**\\jsp\\*", 2576 "**\\model\\impl\\*BaseImpl.java", "**\\model\\impl\\*Model.java", 2577 "**\\model\\impl\\*ModelImpl.java", "**\\portal\\service\\**", 2578 "**\\portal-client\\**", 2579 "**\\portal-service\\**\\model\\*Model.java", 2580 "**\\portal-service\\**\\model\\*Soap.java", 2581 "**\\portal-service\\**\\model\\*Wrapper.java", 2582 "**\\portal-web\\classes\\**\\*.java", 2583 "**\\portal-web\\test\\**\\*Test.java", 2584 "**\\portal-web\\test\\**\\*Tests.java", 2585 "**\\portlet\\**\\service\\**", "**\\tmp\\**", "**\\tools\\tck\\**" 2586 }; 2587 2588 excludes = ArrayUtil.append(excludes, _excludes); 2589 2590 directoryScanner.setExcludes(excludes); 2591 2592 directoryScanner.setIncludes(new String[] {"**\\*.java"}); 2593 2594 fileNames.addAll(_sourceFormatterHelper.scanForFiles(directoryScanner)); 2595 2596 directoryScanner = new DirectoryScanner(); 2597 2598 directoryScanner.setBasedir(basedir); 2599 2600 excludes = new String[] { 2601 "**\\bin\\**", "**\\portal-client\\**", "**\\tools\\ext_tmpl\\**", 2602 "**\\*_IW.java", "**\\test\\**\\*PersistenceTest.java" 2603 }; 2604 2605 excludes = ArrayUtil.append(excludes, _excludes); 2606 2607 directoryScanner.setExcludes(excludes); 2608 2609 directoryScanner.setIncludes( 2610 new String[] { 2611 "**\\com\\liferay\\portal\\service\\ServiceContext*.java", 2612 "**\\model\\BaseModel.java", 2613 "**\\model\\impl\\BaseModelImpl.java", 2614 "**\\service\\PersistedModelLocalService*.java", 2615 "**\\service\\base\\PrincipalBean.java", 2616 "**\\service\\http\\*HttpTest.java", 2617 "**\\service\\http\\*SoapTest.java", 2618 "**\\service\\http\\TunnelUtil.java", 2619 "**\\service\\impl\\*.java", "**\\service\\jms\\*.java", 2620 "**\\service\\permission\\*.java", 2621 "**\\service\\persistence\\BasePersistence.java", 2622 "**\\service\\persistence\\BatchSession*.java", 2623 "**\\service\\persistence\\*FinderImpl.java", 2624 "**\\service\\persistence\\*Query.java", 2625 "**\\service\\persistence\\impl\\BasePersistenceImpl.java", 2626 "**\\portal-impl\\test\\**\\*.java", 2627 "**\\portal-service\\**\\liferay\\documentlibrary\\**.java", 2628 "**\\portal-service\\**\\liferay\\lock\\**.java", 2629 "**\\portal-service\\**\\liferay\\mail\\**.java", 2630 "**\\util-bridges\\**\\*.java" 2631 }); 2632 2633 fileNames.addAll(_sourceFormatterHelper.scanForFiles(directoryScanner)); 2634 2635 return fileNames; 2636 } 2637 2638 private static String _getTaglibRegex(String quoteType) { 2639 StringBuilder sb = new StringBuilder(); 2640 2641 sb.append("<("); 2642 2643 for (int i = 0; i < _TAG_LIBRARIES.length; i++) { 2644 sb.append(_TAG_LIBRARIES[i]); 2645 sb.append(StringPool.PIPE); 2646 } 2647 2648 sb.deleteCharAt(sb.length() - 1); 2649 sb.append("):([^>]|%>)*"); 2650 sb.append(quoteType); 2651 sb.append("<%=.*"); 2652 sb.append(quoteType); 2653 sb.append(".*%>"); 2654 sb.append(quoteType); 2655 sb.append("([^>]|%>)*>"); 2656 2657 return sb.toString(); 2658 } 2659 2660 private static String _getVariableName(String line) { 2661 int x = line.indexOf(StringPool.EQUAL); 2662 int y = line.lastIndexOf(StringPool.SPACE); 2663 2664 if (x != -1) { 2665 line = line.substring(0, x); 2666 line = StringUtil.trim(line); 2667 2668 y = line.lastIndexOf(StringPool.SPACE); 2669 2670 return line.substring(y + 1); 2671 } 2672 2673 if (line.endsWith(StringPool.SEMICOLON)) { 2674 return line.substring(y + 1, line.length() - 1); 2675 } 2676 2677 return StringPool.BLANK; 2678 } 2679 2680 private static boolean _isGenerated(String content) { 2681 if (content.contains("* @generated") || content.contains("$ANTLR")) { 2682 return true; 2683 } 2684 else { 2685 return false; 2686 } 2687 } 2688 2689 private static boolean _isJSPAttributName(String attributeName) { 2690 if (Validator.isNull(attributeName)) { 2691 return false; 2692 } 2693 2694 Matcher matcher = _jspAttributeNamePattern.matcher(attributeName); 2695 2696 return matcher.matches(); 2697 } 2698 2699 private static boolean _isJSPDuplicateImport( 2700 String fileName, String importLine, boolean checkFile) { 2701 2702 String content = _jspContents.get(fileName); 2703 2704 if (Validator.isNull(content)) { 2705 return false; 2706 } 2707 2708 int x = importLine.indexOf("page"); 2709 2710 if (x == -1) { 2711 return false; 2712 } 2713 2714 if (checkFile && content.contains(importLine.substring(x))) { 2715 return true; 2716 } 2717 2718 int y = content.indexOf("<%@ include file="); 2719 2720 if (y == -1) { 2721 return false; 2722 } 2723 2724 y = content.indexOf(StringPool.QUOTE, y); 2725 2726 if (y == -1) { 2727 return false; 2728 } 2729 2730 int z = content.indexOf(StringPool.QUOTE, y + 1); 2731 2732 if (z == -1) { 2733 return false; 2734 } 2735 2736 String includeFileName = content.substring(y + 1, z); 2737 2738 String docrootPath = fileName.substring( 2739 0, fileName.indexOf("docroot") + 7); 2740 2741 includeFileName = docrootPath + includeFileName; 2742 2743 return _isJSPDuplicateImport(includeFileName, importLine, true); 2744 } 2745 2746 private static boolean _isJSPImportRequired( 2747 String fileName, String className, Set<String> includeFileNames, 2748 Set<String> checkedFileNames) { 2749 2750 if (checkedFileNames.contains(fileName)) { 2751 return false; 2752 } 2753 2754 checkedFileNames.add(fileName); 2755 2756 String content = _jspContents.get(fileName); 2757 2758 if (Validator.isNull(content)) { 2759 return false; 2760 } 2761 2762 Pattern pattern = Pattern.compile( 2763 "[^A-Za-z0-9_]" + className + "[^A-Za-z0-9_\"]"); 2764 2765 Matcher matcher = pattern.matcher(content); 2766 2767 if (matcher.find()) { 2768 return true; 2769 } 2770 2771 _addJSPIncludeFileNames(fileName, includeFileNames); 2772 2773 String docrootPath = fileName.substring( 2774 0, fileName.indexOf("docroot") + 7); 2775 2776 fileName = fileName.replaceFirst(docrootPath, StringPool.BLANK); 2777 2778 if (fileName.endsWith("init.jsp") || 2779 fileName.contains("init-ext.jsp")) { 2780 2781 _addJSPReferenceFileNames(fileName, includeFileNames); 2782 } 2783 2784 String[] includeFileNamesArray = includeFileNames.toArray( 2785 new String[includeFileNames.size()]); 2786 2787 for (String includeFileName : includeFileNamesArray) { 2788 if (!checkedFileNames.contains(includeFileName) && 2789 _isJSPImportRequired( 2790 includeFileName, className, includeFileNames, 2791 checkedFileNames)) { 2792 2793 return true; 2794 } 2795 } 2796 2797 return false; 2798 } 2799 2800 private static boolean _isInJavaTermTypeGroup( 2801 int javaTermType, int[] javaTermTypeGroup) { 2802 2803 for (int type : javaTermTypeGroup) { 2804 if (javaTermType == type) { 2805 return true; 2806 } 2807 } 2808 2809 return false; 2810 } 2811 2812 private static String _replacePrimitiveWrapperInstantiation( 2813 String fileName, String line, int lineCount) { 2814 2815 if (true) { 2816 return line; 2817 } 2818 2819 String newLine = StringUtil.replace( 2820 line, 2821 new String[] { 2822 "new Boolean(", "new Byte(", "new Character(", 2823 "new Integer(", "new Long(", "new Short(" 2824 }, 2825 new String[] { 2826 "Boolean.valueOf(", "Byte.valueOf(", "Character.valueOf(", 2827 "Integer.valueOf(", "Long.valueOf(", "Short.valueOf(" 2828 }); 2829 2830 if (!line.equals(newLine)) { 2831 _sourceFormatterHelper.printError( 2832 fileName, "> new Primitive(: " + fileName + " " + lineCount); 2833 } 2834 2835 return newLine; 2836 } 2837 2838 private static String _stripJSPImports(String fileName, String content) 2839 throws IOException { 2840 2841 fileName = fileName.replace( 2842 CharPool.BACK_SLASH, CharPool.FORWARD_SLASH); 2843 2844 if (!fileName.contains("docroot") || 2845 fileName.endsWith("init-ext.jsp")) { 2846 2847 return content; 2848 } 2849 2850 Matcher matcher = _jspImportPattern.matcher(content); 2851 2852 if (!matcher.find()) { 2853 return content; 2854 } 2855 2856 String imports = matcher.group(); 2857 2858 imports = StringUtil.replace( 2859 imports, new String[] {"%><%@\r\n", "%><%@\n"}, 2860 new String[] {"%>\r\n<%@ ", "%>\n<%@ "}); 2861 2862 if (!fileName.endsWith("html/common/init.jsp") && 2863 !fileName.endsWith("html/portal/init.jsp")) { 2864 2865 List<String> importLines = new ArrayList<String>(); 2866 2867 UnsyncBufferedReader unsyncBufferedReader = 2868 new UnsyncBufferedReader(new UnsyncStringReader(imports)); 2869 2870 String line = null; 2871 2872 while ((line = unsyncBufferedReader.readLine()) != null) { 2873 if (line.contains("import=")) { 2874 importLines.add(line); 2875 } 2876 } 2877 2878 List<String> unneededImports = _getJSPDuplicateImports( 2879 fileName, content, importLines); 2880 2881 _addJSPUnusedImports(fileName, importLines, unneededImports); 2882 2883 for (String unneededImport : unneededImports) { 2884 imports = StringUtil.replace( 2885 imports, unneededImport, StringPool.BLANK); 2886 } 2887 } 2888 2889 imports = _formatImports(imports, 17); 2890 2891 String beforeImports = content.substring(0, matcher.start()); 2892 2893 if (Validator.isNull(imports)) { 2894 beforeImports = StringUtil.replaceLast( 2895 beforeImports, "\n", StringPool.BLANK); 2896 } 2897 2898 String afterImports = content.substring(matcher.end()); 2899 2900 if (Validator.isNull(afterImports)) { 2901 imports = StringUtil.replaceLast(imports, "\n", StringPool.BLANK); 2902 2903 content = beforeImports + imports; 2904 2905 return content; 2906 } 2907 2908 content = beforeImports + imports + "\n" + afterImports; 2909 2910 return content; 2911 } 2912 2913 private static final String[] _TAG_LIBRARIES = new String[] { 2914 "aui", "c", "html", "jsp", "liferay-portlet", "liferay-security", 2915 "liferay-theme", "liferay-ui", "liferay-util", "portlet", "struts", 2916 "tiles" 2917 }; 2918 2919 private static final int _TYPE_CLASS_PRIVATE = 22; 2920 2921 private static final int _TYPE_CLASS_PRIVATE_STATIC = 21; 2922 2923 private static final int _TYPE_CLASS_PUBLIC = 8; 2924 2925 private static final int _TYPE_CLASS_PUBLIC_STATIC = 7; 2926 2927 private static final int _TYPE_CONSTRUCTOR_PRIVATE = 16; 2928 2929 private static final int _TYPE_CONSTRUCTOR_PROTECTED = 10; 2930 2931 private static final int _TYPE_CONSTRUCTOR_PUBLIC = 5; 2932 2933 private static final int[] _TYPE_METHOD = { 2934 SourceFormatter._TYPE_METHOD_PRIVATE, 2935 SourceFormatter._TYPE_METHOD_PRIVATE_STATIC, 2936 SourceFormatter._TYPE_METHOD_PROTECTED, 2937 SourceFormatter._TYPE_METHOD_PROTECTED_STATIC, 2938 SourceFormatter._TYPE_METHOD_PUBLIC, 2939 SourceFormatter._TYPE_METHOD_PUBLIC_STATIC 2940 }; 2941 2942 private static final int _TYPE_METHOD_PRIVATE = 17; 2943 2944 private static final int _TYPE_METHOD_PRIVATE_STATIC = 15; 2945 2946 private static final int _TYPE_METHOD_PROTECTED = 11; 2947 2948 private static final int _TYPE_METHOD_PROTECTED_STATIC = 9; 2949 2950 private static final int _TYPE_METHOD_PUBLIC = 6; 2951 2952 private static final int _TYPE_METHOD_PUBLIC_STATIC = 4; 2953 2954 private static final int[] _TYPE_PRIVATE_METHOD_OR_VARIABLE = { 2955 SourceFormatter._TYPE_METHOD_PRIVATE, 2956 SourceFormatter._TYPE_METHOD_PRIVATE_STATIC, 2957 SourceFormatter._TYPE_VARIABLE_PRIVATE, 2958 SourceFormatter._TYPE_VARIABLE_PRIVATE_STATIC, 2959 SourceFormatter._TYPE_VARIABLE_PRIVATE_STATIC_FINAL 2960 }; 2961 2962 private static final int[] _TYPE_VARIABLE_NOT_STATIC = { 2963 SourceFormatter._TYPE_VARIABLE_PRIVATE, 2964 SourceFormatter._TYPE_VARIABLE_PRIVATE_STATIC, 2965 SourceFormatter._TYPE_VARIABLE_PROTECTED, 2966 SourceFormatter._TYPE_VARIABLE_PROTECTED_STATIC, 2967 SourceFormatter._TYPE_VARIABLE_PUBLIC, 2968 SourceFormatter._TYPE_VARIABLE_PUBLIC_STATIC 2969 }; 2970 2971 private static final int _TYPE_VARIABLE_PRIVATE = 20; 2972 2973 private static final int _TYPE_VARIABLE_PRIVATE_STATIC = 19; 2974 2975 private static final int _TYPE_VARIABLE_PRIVATE_STATIC_FINAL = 18; 2976 2977 private static final int _TYPE_VARIABLE_PROTECTED = 14; 2978 2979 private static final int _TYPE_VARIABLE_PROTECTED_STATIC = 13; 2980 2981 private static final int _TYPE_VARIABLE_PROTECTED_STATIC_FINAL = 12; 2982 2983 private static final int _TYPE_VARIABLE_PUBLIC = 3; 2984 2985 private static final int _TYPE_VARIABLE_PUBLIC_STATIC = 2; 2986 2987 private static final int _TYPE_VARIABLE_PUBLIC_STATIC_FINAL = 1; 2988 2989 private static String[] _excludes; 2990 private static FileImpl _fileUtil = FileImpl.getInstance(); 2991 private static Pattern _javaImportPattern = Pattern.compile( 2992 "(^[ \t]*import\\s+.*;\n+)+", Pattern.MULTILINE); 2993 private static Properties _javaTermAlphabetizeExclusionsProperties; 2994 private static Pattern _jspAttributeNamePattern = Pattern.compile( 2995 "[a-z]+[-_a-zA-Z0-9]*"); 2996 private static Map<String, String> _jspContents = 2997 new HashMap<String, String>(); 2998 private static Pattern _jspImportPattern = Pattern.compile( 2999 "(<.*\n*page.import=\".*>\n*)+", Pattern.MULTILINE); 3000 private static Pattern _jspIncludeFilePattern = Pattern.compile( 3001 "/.*[.]jsp[f]?"); 3002 private static Properties _lineLengthExclusionsProperties; 3003 private static SAXReaderImpl _saxReaderUtil = SAXReaderImpl.getInstance(); 3004 private static SourceFormatterHelper _sourceFormatterHelper; 3005 private static Pattern _xssPattern = Pattern.compile( 3006 "String\\s+([^\\s]+)\\s*=\\s*(Bean)?ParamUtil\\.getString\\("); 3007 3008 }