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.Validator; 030 import com.liferay.portal.kernel.xml.Document; 031 import com.liferay.portal.kernel.xml.DocumentException; 032 import com.liferay.portal.kernel.xml.Element; 033 import com.liferay.util.ContentUtil; 034 import com.liferay.portal.util.FileImpl; 035 import com.liferay.portal.xml.SAXReaderImpl; 036 037 import java.io.File; 038 import java.io.IOException; 039 import java.io.InputStream; 040 import java.net.URL; 041 import java.util.ArrayList; 042 import java.util.Arrays; 043 import java.util.Collection; 044 import java.util.Collections; 045 import java.util.HashMap; 046 import java.util.HashSet; 047 import java.util.List; 048 import java.util.Map; 049 import java.util.Properties; 050 import java.util.Set; 051 import java.util.TreeSet; 052 import java.util.regex.Matcher; 053 import java.util.regex.Pattern; 054 055 import org.apache.tools.ant.DirectoryScanner; 056 057 /** 058 * @author Brian Wing Shun Chan 059 * @author Igor Spasic 060 * @author Wesley Gong 061 * @author Hugo Huijser 062 */ 063 public class SourceFormatter { 064 065 public static void main(String[] args) { 066 try { 067 _excludes = StringUtil.split( 068 GetterUtil.getString( 069 System.getProperty("source.formatter.excludes"))); 070 071 _sourceFormatterHelper = new SourceFormatterHelper(false); 072 073 _sourceFormatterHelper.init(); 074 075 _readExclusions(); 076 077 Thread thread1 = new Thread () { 078 @Override 079 public void run() { 080 try { 081 _checkPersistenceTestSuite(); 082 _formatJSP(); 083 _formatAntXML(); 084 _formatDDLStructuresXML(); 085 _formatFriendlyURLRoutesXML(); 086 _formatPortletXML(); 087 _formatSH(); 088 _formatWebXML(); 089 } 090 catch (Exception e) { 091 e.printStackTrace(); 092 } 093 } 094 }; 095 096 Thread thread2 = new Thread () { 097 @Override 098 public void run() { 099 try { 100 _formatJava(); 101 } 102 catch (Exception e) { 103 e.printStackTrace(); 104 } 105 } 106 }; 107 108 thread1.start(); 109 thread2.start(); 110 111 thread1.join(); 112 thread2.join(); 113 114 _sourceFormatterHelper.close(); 115 } 116 catch (Exception e) { 117 e.printStackTrace(); 118 } 119 } 120 121 public static String stripJavaImports( 122 String content, String packageDir, String className) 123 throws IOException { 124 125 Matcher matcher = _javaImportPattern.matcher(content); 126 127 if (!matcher.find()) { 128 return content; 129 } 130 131 String imports = matcher.group(); 132 133 Set<String> classes = ClassUtil.getClasses( 134 new UnsyncStringReader(content), className); 135 136 StringBundler sb = new StringBundler(); 137 138 UnsyncBufferedReader unsyncBufferedReader = new UnsyncBufferedReader( 139 new UnsyncStringReader(imports)); 140 141 String line = null; 142 143 while ((line = unsyncBufferedReader.readLine()) != null) { 144 if (line.contains("import ")) { 145 int importX = line.indexOf(" "); 146 int importY = line.lastIndexOf("."); 147 148 String importPackage = line.substring(importX + 1, importY); 149 String importClass = line.substring( 150 importY + 1, line.length() - 1); 151 152 if (!packageDir.equals(importPackage)) { 153 if (!importClass.equals("*")) { 154 if (classes.contains(importClass)) { 155 sb.append(line); 156 sb.append("\n"); 157 } 158 } 159 else { 160 sb.append(line); 161 sb.append("\n"); 162 } 163 } 164 } 165 } 166 167 imports = _formatImports(sb.toString(), 7); 168 169 content = 170 content.substring(0, matcher.start()) + imports + 171 content.substring(matcher.end()); 172 173 // Ensure a blank line exists between the package and the first import 174 175 content = content.replaceFirst( 176 "(?m)^[ \t]*(package .*;)\\s*^[ \t]*import", "$1\n\nimport"); 177 178 // Ensure a blank line exists between the last import (or package if 179 // there are no imports) and the class comment 180 181 content = content.replaceFirst( 182 "(?m)^[ \t]*((?:package|import) .*;)\\s*^[ \t]*/\\*\\*", 183 "$1\n\n/**"); 184 185 return content; 186 } 187 188 private static void _addJSPIncludeFileNames( 189 String fileName, Set<String> includeFileNames) { 190 191 String content = _jspContents.get(fileName); 192 193 if (Validator.isNull(content)) { 194 return; 195 } 196 197 for (int x = 0;;) { 198 x = content.indexOf("<%@ include file=", x); 199 200 if (x == -1) { 201 break; 202 } 203 204 x = content.indexOf(StringPool.QUOTE, x); 205 206 if (x == -1) { 207 break; 208 } 209 210 int y = content.indexOf(StringPool.QUOTE, x + 1); 211 212 if (y == -1) { 213 break; 214 } 215 216 String includeFileName = content.substring(x + 1, y); 217 218 Matcher matcher = _jspIncludeFilePattern.matcher(includeFileName); 219 220 if (!matcher.find()) { 221 throw new RuntimeException( 222 "Invalid include " + includeFileName); 223 } 224 225 String docrootPath = fileName.substring( 226 0, fileName.indexOf("docroot") + 7); 227 228 includeFileName = docrootPath + includeFileName; 229 230 if ((includeFileName.endsWith("jsp") || 231 includeFileName.endsWith("jspf")) && 232 !includeFileNames.contains(includeFileName) && 233 !includeFileName.contains("html/portlet/init.jsp")) { 234 235 includeFileNames.add(includeFileName); 236 } 237 238 x = y; 239 } 240 } 241 242 private static void _addJSPReferenceFileNames( 243 String fileName, Set<String> includeFileNames) { 244 245 for (Map.Entry<String, String> entry : _jspContents.entrySet()) { 246 String referenceFileName = entry.getKey(); 247 String content = entry.getValue(); 248 249 if (content.contains("<%@ include file=\"" + fileName) && 250 !includeFileNames.contains(referenceFileName)) { 251 252 includeFileNames.add(referenceFileName); 253 } 254 } 255 } 256 257 private static void _addJSPUnusedImports( 258 String fileName, List<String> importLines, 259 List<String> unneededImports) { 260 261 for (String importLine : importLines) { 262 Set<String> includeFileNames = new HashSet<String>(); 263 264 includeFileNames.add(fileName); 265 266 Set<String> checkedFileNames = new HashSet<String>(); 267 268 int x = importLine.indexOf(StringPool.QUOTE); 269 int y = importLine.indexOf(StringPool.QUOTE, x + 1); 270 271 if ((x == -1) || (y == -1)) { 272 continue; 273 } 274 275 String className = importLine.substring(x + 1, y); 276 277 className = className.substring( 278 className.lastIndexOf(StringPool.PERIOD) + 1); 279 280 if (!_isJSPImportRequired( 281 fileName, className, includeFileNames, checkedFileNames)) { 282 283 unneededImports.add(importLine); 284 } 285 } 286 } 287 288 private static void _checkPersistenceTestSuite() throws IOException { 289 String basedir = "./portal-impl/test"; 290 291 if (!_fileUtil.exists(basedir)) { 292 return; 293 } 294 295 DirectoryScanner directoryScanner = new DirectoryScanner(); 296 297 directoryScanner.setBasedir(basedir); 298 directoryScanner.setIncludes( 299 new String[] {"**\\*PersistenceTest.java"}); 300 301 List<String> fileNames = _sourceFormatterHelper.scanForFiles( 302 directoryScanner); 303 304 List<String> persistenceTests = new ArrayList<String>(); 305 306 for (String fileName : fileNames) { 307 String persistenceTest = fileName.substring( 308 0, fileName.length() - 5); 309 310 persistenceTest = persistenceTest.substring( 311 persistenceTest.lastIndexOf(File.separator) + 1, 312 persistenceTest.length()); 313 314 persistenceTests.add(persistenceTest); 315 } 316 317 String persistenceTestSuiteFileName = 318 basedir + "/com/liferay/portal/service/persistence/" + 319 "PersistenceTestSuite.java"; 320 321 String persistenceTestSuiteContent = _fileUtil.read( 322 persistenceTestSuiteFileName); 323 324 for (String persistenceTest : persistenceTests) { 325 if (!persistenceTestSuiteContent.contains(persistenceTest)) { 326 _sourceFormatterHelper.printError( 327 persistenceTestSuiteFileName, 328 "PersistenceTestSuite: " + persistenceTest); 329 } 330 } 331 } 332 333 private static boolean _checkTaglibVulnerability( 334 String jspContent, String vulnerability) { 335 336 int pos1 = -1; 337 338 do { 339 pos1 = jspContent.indexOf(vulnerability, pos1 + 1); 340 341 if (pos1 != -1) { 342 int pos2 = jspContent.lastIndexOf(CharPool.LESS_THAN, pos1); 343 344 while ((pos2 > 0) && 345 (jspContent.charAt(pos2 + 1) == CharPool.PERCENT)) { 346 347 pos2 = jspContent.lastIndexOf(CharPool.LESS_THAN, pos2 - 1); 348 } 349 350 String tagContent = jspContent.substring(pos2, pos1); 351 352 if (!tagContent.startsWith("<aui:") && 353 !tagContent.startsWith("<liferay-portlet:") && 354 !tagContent.startsWith("<liferay-util:") && 355 !tagContent.startsWith("<portlet:")) { 356 357 return true; 358 } 359 } 360 } 361 while (pos1 != -1); 362 363 return false; 364 } 365 366 private static void _checkXSS(String fileName, String jspContent) { 367 Matcher matcher = _xssPattern.matcher(jspContent); 368 369 while (matcher.find()) { 370 boolean xssVulnerable = false; 371 372 String jspVariable = matcher.group(1); 373 374 String anchorVulnerability = " href=\"<%= " + jspVariable + " %>"; 375 376 if (_checkTaglibVulnerability(jspContent, anchorVulnerability)) { 377 xssVulnerable = true; 378 } 379 380 String inputVulnerability = " value=\"<%= " + jspVariable + " %>"; 381 382 if (_checkTaglibVulnerability(jspContent, inputVulnerability)) { 383 xssVulnerable = true; 384 } 385 386 String inlineStringVulnerability1 = "'<%= " + jspVariable + " %>"; 387 388 if (jspContent.contains(inlineStringVulnerability1)) { 389 xssVulnerable = true; 390 } 391 392 String inlineStringVulnerability2 = "(\"<%= " + jspVariable + " %>"; 393 394 if (jspContent.contains(inlineStringVulnerability2)) { 395 xssVulnerable = true; 396 } 397 398 String inlineStringVulnerability3 = " \"<%= " + jspVariable + " %>"; 399 400 if (jspContent.contains(inlineStringVulnerability3)) { 401 xssVulnerable = true; 402 } 403 404 String documentIdVulnerability = ".<%= " + jspVariable + " %>"; 405 406 if (jspContent.contains(documentIdVulnerability)) { 407 xssVulnerable = true; 408 } 409 410 if (xssVulnerable) { 411 _sourceFormatterHelper.printError( 412 fileName, "(xss): " + fileName + " (" + jspVariable + ")"); 413 } 414 } 415 } 416 417 private static String _fixAntXMLProjectName( 418 String basedir, String fileName, String content) 419 throws IOException { 420 421 int x = 0; 422 423 if (fileName.endsWith("-ext/build.xml")) { 424 x = fileName.indexOf("ext/"); 425 426 if (x == -1) { 427 x = 0; 428 } 429 else { 430 x = x + 4; 431 } 432 } 433 else if (fileName.endsWith("-hook/build.xml")) { 434 x = fileName.indexOf("hooks/"); 435 436 if (x == -1) { 437 x = 0; 438 } 439 else { 440 x = x + 6; 441 } 442 } 443 else if (fileName.endsWith("-layouttpl/build.xml")) { 444 x = fileName.indexOf("layouttpl/"); 445 446 if (x == -1) { 447 x = 0; 448 } 449 else { 450 x = x + 10; 451 } 452 } 453 else if (fileName.endsWith("-portlet/build.xml")) { 454 x = fileName.indexOf("portlets/"); 455 456 if (x == -1) { 457 x = 0; 458 } 459 else { 460 x = x + 9; 461 } 462 } 463 else if (fileName.endsWith("-theme/build.xml")) { 464 x = fileName.indexOf("themes/"); 465 466 if (x == -1) { 467 x = 0; 468 } 469 else { 470 x = x + 7; 471 } 472 } 473 else if (fileName.endsWith("-web/build.xml") && 474 !fileName.endsWith("/ext-web/build.xml")) { 475 476 x = fileName.indexOf("webs/"); 477 478 if (x == -1) { 479 x = 0; 480 } 481 else { 482 x = x + 5; 483 } 484 } 485 else { 486 return content; 487 } 488 489 int y = fileName.indexOf("/", x); 490 491 String correctProjectElementText = 492 "<project name=\"" + fileName.substring(x, y) + "\""; 493 494 if (!content.contains(correctProjectElementText)) { 495 x = content.indexOf("<project name=\""); 496 497 y = content.indexOf("\"", x) + 1; 498 y = content.indexOf("\"", y) + 1; 499 500 content = 501 content.substring(0, x) + correctProjectElementText + 502 content.substring(y); 503 504 _sourceFormatterHelper.printError( 505 fileName, fileName + " has an incorrect project name"); 506 507 _fileUtil.write(basedir + fileName, content); 508 } 509 510 return content; 511 } 512 513 private static void _formatAntXML() throws DocumentException, IOException { 514 String basedir = "./"; 515 516 DirectoryScanner directoryScanner = new DirectoryScanner(); 517 518 directoryScanner.setBasedir(basedir); 519 directoryScanner.setIncludes(new String[] {"**\\b*.xml"}); 520 directoryScanner.setExcludes(new String[] {"**\\tools\\**"}); 521 522 List<String> fileNames = _sourceFormatterHelper.scanForFiles( 523 directoryScanner); 524 525 for (String fileName : fileNames) { 526 fileName = StringUtil.replace(fileName, "\\", "/"); 527 528 String content = _fileUtil.read(basedir + fileName); 529 530 content = _fixAntXMLProjectName(basedir, fileName, content); 531 532 Document document = _saxReaderUtil.read(content); 533 534 Element rootElement = document.getRootElement(); 535 536 String previousName = StringPool.BLANK; 537 538 List<Element> targetElements = rootElement.elements("target"); 539 540 for (Element targetElement : targetElements) { 541 String name = targetElement.attributeValue("name"); 542 543 if (name.equals("Test")) { 544 name = name.toLowerCase(); 545 } 546 547 if (name.compareTo(previousName) < -1) { 548 _sourceFormatterHelper.printError( 549 fileName, 550 fileName + " has an unordered target " + name); 551 552 break; 553 } 554 555 previousName = name; 556 } 557 } 558 } 559 560 private static void _formatDDLStructuresXML() 561 throws DocumentException, IOException { 562 563 String basedir = 564 "./portal-impl/src/com/liferay/portal/events/dependencies/"; 565 566 if (!_fileUtil.exists(basedir)) { 567 return; 568 } 569 570 DirectoryScanner directoryScanner = new DirectoryScanner(); 571 572 directoryScanner.setBasedir(basedir); 573 directoryScanner.setIncludes(new String[] {"**\\*structures.xml"}); 574 575 List<String> fileNames = _sourceFormatterHelper.scanForFiles( 576 directoryScanner); 577 578 for (String fileName : fileNames) { 579 File file = new File(basedir + fileName); 580 581 String content = _fileUtil.read(file); 582 583 String newContent = _formatDDLStructuresXML(content); 584 585 if ((newContent != null) && !content.equals(newContent)) { 586 _fileUtil.write(file, newContent); 587 588 _sourceFormatterHelper.printError(fileName, file); 589 } 590 } 591 } 592 593 private static String _formatDDLStructuresXML(String content) 594 throws DocumentException, IOException { 595 596 Document document = _saxReaderUtil.read(content); 597 598 Element rootElement = document.getRootElement(); 599 600 rootElement.sortAttributes(true); 601 602 rootElement.sortElementsByChildElement("structure", "name"); 603 604 List<Element> structureElements = rootElement.elements("structure"); 605 606 for (Element structureElement : structureElements) { 607 Element structureRootElement = structureElement.element("root"); 608 609 structureRootElement.sortElementsByAttribute( 610 "dynamic-element", "name"); 611 612 List<Element> dynamicElementElements = 613 structureRootElement.elements("dynamic-element"); 614 615 for (Element dynamicElementElement : dynamicElementElements) { 616 Element metaDataElement = dynamicElementElement.element( 617 "meta-data"); 618 619 metaDataElement.sortElementsByAttribute("entry", "name"); 620 } 621 } 622 623 return document.formattedString(); 624 } 625 626 private static void _formatFriendlyURLRoutesXML() 627 throws DocumentException, IOException { 628 629 String basedir = "./"; 630 631 DirectoryScanner directoryScanner = new DirectoryScanner(); 632 633 directoryScanner.setBasedir(basedir); 634 directoryScanner.setIncludes(new String[] {"**\\*routes.xml"}); 635 directoryScanner.setExcludes( 636 new String[] {"**\\classes\\**", "**\\bin\\**"}); 637 638 List<String> fileNames = _sourceFormatterHelper.scanForFiles( 639 directoryScanner); 640 641 for (String fileName : fileNames) { 642 File file = new File(basedir + fileName); 643 644 String content = _fileUtil.read(file); 645 646 if (content.contains("<!-- SourceFormatter.Ignore -->")) { 647 continue; 648 } 649 650 String newContent = _formatFriendlyURLRoutesXML(content); 651 652 if ((newContent != null) && !content.equals(newContent)) { 653 _fileUtil.write(file, newContent); 654 655 _sourceFormatterHelper.printError(fileName, file); 656 } 657 } 658 } 659 660 private static String _formatFriendlyURLRoutesXML(String content) 661 throws DocumentException { 662 663 Document document = _saxReaderUtil.read(content); 664 665 Element rootElement = document.getRootElement(); 666 667 List<ComparableRoute> comparableRoutes = 668 new ArrayList<ComparableRoute>(); 669 670 for (Element routeElement : rootElement.elements("route")) { 671 String pattern = routeElement.elementText("pattern"); 672 673 ComparableRoute comparableRoute = new ComparableRoute(pattern); 674 675 for (Element generatedParameterElement : 676 routeElement.elements("generated-parameter")) { 677 678 String name = generatedParameterElement.attributeValue("name"); 679 String value = generatedParameterElement.getText(); 680 681 comparableRoute.addGeneratedParameter(name, value); 682 } 683 684 for (Element ignoredParameterElement : 685 routeElement.elements("ignored-parameter")) { 686 687 String name = ignoredParameterElement.attributeValue("name"); 688 689 comparableRoute.addIgnoredParameter(name); 690 } 691 692 for (Element implicitParameterElement : 693 routeElement.elements("implicit-parameter")) { 694 695 String name = implicitParameterElement.attributeValue("name"); 696 String value = implicitParameterElement.getText(); 697 698 comparableRoute.addImplicitParameter(name, value); 699 } 700 701 for (Element overriddenParameterElement : 702 routeElement.elements("overridden-parameter")) { 703 704 String name = overriddenParameterElement.attributeValue("name"); 705 String value = overriddenParameterElement.getText(); 706 707 comparableRoute.addOverriddenParameter(name, value); 708 } 709 710 comparableRoutes.add(comparableRoute); 711 } 712 713 Collections.sort(comparableRoutes); 714 715 StringBundler sb = new StringBundler(); 716 717 sb.append("<?xml version=\"1.0\"?>\n"); 718 sb.append("<!DOCTYPE routes PUBLIC \"-//Liferay//DTD Friendly URL "); 719 sb.append("Routes 6.1.0//EN\" \"http://www.liferay.com/dtd/"); 720 sb.append("liferay-friendly-url-routes_6_1_0.dtd\">\n\n<routes>\n"); 721 722 for (ComparableRoute comparableRoute : comparableRoutes) { 723 sb.append("\t<route>\n"); 724 sb.append("\t\t<pattern>"); 725 sb.append(comparableRoute.getPattern()); 726 sb.append("</pattern>\n"); 727 728 Map<String, String> generatedParameters = 729 comparableRoute.getGeneratedParameters(); 730 731 for (Map.Entry<String, String> entry : 732 generatedParameters.entrySet()) { 733 734 sb.append("\t\t<generated-parameter name=\""); 735 sb.append(entry.getKey()); 736 sb.append("\">"); 737 sb.append(entry.getValue()); 738 sb.append("</generated-parameter>\n"); 739 } 740 741 Set<String> ignoredParameters = 742 comparableRoute.getIgnoredParameters(); 743 744 for (String entry : ignoredParameters) { 745 sb.append("\t\t<ignored-parameter name=\""); 746 sb.append(entry); 747 sb.append("\" />\n"); 748 } 749 750 Map<String, String> implicitParameters = 751 comparableRoute.getImplicitParameters(); 752 753 for (Map.Entry<String, String> entry : 754 implicitParameters.entrySet()) { 755 756 sb.append("\t\t<implicit-parameter name=\""); 757 sb.append(entry.getKey()); 758 sb.append("\">"); 759 sb.append(entry.getValue()); 760 sb.append("</implicit-parameter>\n"); 761 } 762 763 Map<String, String> overriddenParameters = 764 comparableRoute.getOverriddenParameters(); 765 766 for (Map.Entry<String, String> entry : 767 overriddenParameters.entrySet()) { 768 769 sb.append("\t\t<overridden-parameter name=\""); 770 sb.append(entry.getKey()); 771 sb.append("\">"); 772 sb.append(entry.getValue()); 773 sb.append("</overridden-parameter>\n"); 774 } 775 776 sb.append("\t</route>\n"); 777 } 778 779 sb.append("</routes>"); 780 781 return sb.toString(); 782 } 783 784 private static String _formatImports(String imports, int classStartPos) 785 throws IOException { 786 787 if (imports.contains("/*") || imports.contains("*/") || 788 imports.contains("//")) { 789 790 return imports + "\n"; 791 } 792 793 List<String> importsList = new ArrayList<String>(); 794 795 UnsyncBufferedReader unsyncBufferedReader = new UnsyncBufferedReader( 796 new UnsyncStringReader(imports)); 797 798 String line = null; 799 800 while ((line = unsyncBufferedReader.readLine()) != null) { 801 if ((line.contains("import=") || line.contains("import ")) && 802 !importsList.contains(line)) { 803 804 importsList.add(line); 805 } 806 } 807 808 importsList = ListUtil.sort(importsList); 809 810 StringBundler sb = new StringBundler(); 811 812 String temp = null; 813 814 for (int i = 0; i < importsList.size(); i++) { 815 String s = importsList.get(i); 816 817 int pos = s.indexOf("."); 818 819 pos = s.indexOf(".", pos + 1); 820 821 if (pos == -1) { 822 pos = s.indexOf("."); 823 } 824 825 String packageLevel = s.substring(classStartPos, pos); 826 827 if ((i != 0) && (!packageLevel.equals(temp))) { 828 sb.append("\n"); 829 } 830 831 temp = packageLevel; 832 833 sb.append(s); 834 sb.append("\n"); 835 } 836 837 return sb.toString(); 838 } 839 840 private static void _formatJava() throws IOException { 841 String basedir = "./"; 842 843 String copyright = _getCopyright(); 844 String oldCopyright = _getOldCopyright(); 845 846 boolean portalJavaFiles = true; 847 848 Collection<String> fileNames = null; 849 850 if (_fileUtil.exists(basedir + "portal-impl")) { 851 fileNames = _getPortalJavaFiles(); 852 } 853 else { 854 portalJavaFiles = false; 855 856 fileNames = _getPluginJavaFiles(); 857 } 858 859 for (String fileName : fileNames) { 860 File file = new File(fileName); 861 862 String content = _fileUtil.read(file); 863 864 if (_isGenerated(content)) { 865 continue; 866 } 867 868 String className = file.getName(); 869 870 className = className.substring(0, className.length() - 5); 871 872 String packagePath = fileName; 873 874 int packagePathX = packagePath.indexOf( 875 File.separator + "src" + File.separator); 876 int packagePathY = packagePath.lastIndexOf(File.separator); 877 878 if ((packagePathX + 5) >= packagePathY) { 879 packagePath = StringPool.BLANK; 880 } 881 else { 882 packagePath = packagePath.substring( 883 packagePathX + 5, packagePathY); 884 } 885 886 packagePath = StringUtil.replace( 887 packagePath, File.separator, StringPool.PERIOD); 888 889 if (packagePath.endsWith(".model")) { 890 if (content.contains("extends " + className + "Model")) { 891 continue; 892 } 893 } 894 895 String newContent = _formatJavaContent(fileName, content); 896 897 if (newContent.contains("$\n */")) { 898 _sourceFormatterHelper.printError(fileName, "*: " + fileName); 899 900 newContent = StringUtil.replace( 901 newContent, "$\n */", "$\n *\n */"); 902 } 903 904 if ((oldCopyright != null) && newContent.contains(oldCopyright)) { 905 newContent = StringUtil.replace( 906 newContent, oldCopyright, copyright); 907 908 _sourceFormatterHelper.printError( 909 fileName, "old (c): " + fileName); 910 } 911 912 if (!newContent.contains(copyright)) { 913 String customCopyright = _getCustomCopyright(file); 914 915 if (Validator.isNull(customCopyright) || 916 !newContent.contains(customCopyright)) { 917 918 _sourceFormatterHelper.printError( 919 fileName, "(c): " + fileName); 920 } 921 } 922 923 if (newContent.contains(className + ".java.html")) { 924 _sourceFormatterHelper.printError( 925 fileName, "Java2HTML: " + fileName); 926 } 927 928 if (newContent.contains(" * @author Raymond Aug") && 929 !newContent.contains(" * @author Raymond Aug\u00e9")) { 930 931 newContent = newContent.replaceFirst( 932 "Raymond Aug.++", "Raymond Aug\u00e9"); 933 934 _sourceFormatterHelper.printError( 935 fileName, "UTF-8: " + fileName); 936 } 937 938 newContent = StringUtil.replace( 939 newContent, 940 new String[] { 941 "com.liferay.portal.PortalException", 942 "com.liferay.portal.SystemException", 943 "com.liferay.util.LocalizationUtil" 944 }, 945 new String[] { 946 "com.liferay.portal.kernel.exception.PortalException", 947 "com.liferay.portal.kernel.exception.SystemException", 948 "com.liferay.portal.kernel.util.LocalizationUtil" 949 }); 950 951 newContent = stripJavaImports(newContent, packagePath, className); 952 953 newContent = StringUtil.replace( 954 newContent, 955 new String[] { 956 ";\n/**", 957 "\t/*\n\t *", 958 "if(", 959 "for(", 960 "while(", 961 "List <", 962 "){\n", 963 "]{\n", 964 "\n\n\n" 965 }, 966 new String[] { 967 ";\n\n/**", 968 "\t/**\n\t *", 969 "if (", 970 "for (", 971 "while (", 972 "List<", 973 ") {\n", 974 "] {\n", 975 "\n\n" 976 }); 977 978 if (newContent.contains("*/\npackage ")) { 979 _sourceFormatterHelper.printError( 980 fileName, "package: " + fileName); 981 } 982 983 if (!newContent.endsWith("\n\n}") && 984 !newContent.endsWith("{\n}")) { 985 986 _sourceFormatterHelper.printError(fileName, "}: " + fileName); 987 } 988 989 if (portalJavaFiles && className.endsWith("ServiceImpl") && 990 newContent.contains("ServiceUtil.")) { 991 992 _sourceFormatterHelper.printError( 993 fileName, "ServiceUtil: " + fileName); 994 } 995 996 if ((newContent != null) && !content.equals(newContent)) { 997 _fileUtil.write(file, newContent); 998 999 _sourceFormatterHelper.printError(fileName, file); 1000 } 1001 } 1002 } 1003 1004 private static String _formatJavaContent(String fileName, String content) 1005 throws IOException { 1006 1007 boolean longLogFactoryUtil = false; 1008 1009 StringBundler sb = new StringBundler(); 1010 1011 UnsyncBufferedReader unsyncBufferedReader = new UnsyncBufferedReader( 1012 new UnsyncStringReader(content)); 1013 1014 int lineCount = 0; 1015 1016 String line = null; 1017 1018 String previousLine = StringPool.BLANK; 1019 1020 int lineToSkipIfEmpty = 0; 1021 1022 while ((line = unsyncBufferedReader.readLine()) != null) { 1023 lineCount++; 1024 1025 if (line.trim().length() == 0) { 1026 line = StringPool.BLANK; 1027 } 1028 1029 line = StringUtil.trimTrailing(line); 1030 1031 line = StringUtil.replace( 1032 line, 1033 new String[] { 1034 "* Copyright (c) 2000-2011 Liferay, Inc." 1035 }, 1036 new String[] { 1037 "* Copyright (c) 2000-2012 Liferay, Inc." 1038 }); 1039 1040 line = _replacePrimitiveWrapperInstantiation( 1041 fileName, line, lineCount); 1042 1043 String trimmedLine = StringUtil.trimLeading(line); 1044 1045 if (!trimmedLine.contains(StringPool.DOUBLE_SLASH) && 1046 !trimmedLine.startsWith(StringPool.STAR)) { 1047 1048 while (trimmedLine.contains(StringPool.TAB)) { 1049 line = StringUtil.replaceLast( 1050 line, StringPool.TAB, StringPool.SPACE); 1051 1052 trimmedLine = StringUtil.replaceLast( 1053 trimmedLine, StringPool.TAB, StringPool.SPACE); 1054 } 1055 1056 while (trimmedLine.contains(StringPool.DOUBLE_SPACE) && 1057 !trimmedLine.contains( 1058 StringPool.QUOTE + StringPool.DOUBLE_SPACE) && 1059 !fileName.contains("Test")) { 1060 1061 line = StringUtil.replaceLast( 1062 line, StringPool.DOUBLE_SPACE, StringPool.SPACE); 1063 1064 trimmedLine = StringUtil.replaceLast( 1065 trimmedLine, StringPool.DOUBLE_SPACE, StringPool.SPACE); 1066 } 1067 1068 if (!line.contains(StringPool.QUOTE)) { 1069 if ((trimmedLine.startsWith("private ") || 1070 trimmedLine.startsWith("protected ") || 1071 trimmedLine.startsWith("public ")) && 1072 line.contains(" (")) { 1073 1074 line = StringUtil.replace(line, " (", "("); 1075 } 1076 1077 if (line.contains(" [")) { 1078 line = StringUtil.replace(line, " [", "["); 1079 } 1080 1081 for (int x = -1;;) { 1082 x = line.indexOf(StringPool.COMMA, x + 1); 1083 1084 if (x == -1) { 1085 break; 1086 } 1087 1088 if (line.length() > (x + 1)) { 1089 char nextChar = line.charAt(x + 1); 1090 1091 if ((nextChar != CharPool.SPACE) && 1092 (nextChar != CharPool.APOSTROPHE)) { 1093 1094 line = StringUtil.insert( 1095 line, StringPool.SPACE, x + 1); 1096 } 1097 } 1098 1099 if (x > 0) { 1100 char previousChar = line.charAt(x - 1); 1101 1102 if (previousChar == CharPool.SPACE) { 1103 line = line.substring(0, x - 1).concat( 1104 line.substring(x)); 1105 } 1106 } 1107 } 1108 } 1109 } 1110 1111 if (line.contains(" ") && !line.matches("\\s*\\*.*")) { 1112 if (!fileName.endsWith("StringPool.java")) { 1113 _sourceFormatterHelper.printError( 1114 fileName, "tab: " + fileName + " " + lineCount); 1115 } 1116 } 1117 1118 if (line.contains(" {") && !line.matches("\\s*\\*.*")) { 1119 _sourceFormatterHelper.printError( 1120 fileName, "{:" + fileName + " " + lineCount); 1121 } 1122 1123 if (line.endsWith("private static Log _log =")) { 1124 longLogFactoryUtil = true; 1125 } 1126 1127 String excluded = _exclusionsProperties.getProperty( 1128 StringUtil.replace(fileName, "\\", "/") + StringPool.AT + 1129 lineCount); 1130 1131 if (excluded == null) { 1132 excluded = _exclusionsProperties.getProperty( 1133 StringUtil.replace(fileName, "\\", "/")); 1134 } 1135 1136 String combinedLines = null; 1137 1138 if ((excluded == null) && 1139 !line.startsWith("import ") && !line.startsWith("package ") && 1140 !line.matches("\\s*\\*.*")) { 1141 1142 if (fileName.endsWith("Table.java") && 1143 line.contains("String TABLE_SQL_CREATE = ")) { 1144 } 1145 else if (fileName.endsWith("Table.java") && 1146 line.contains("String TABLE_SQL_DROP = ")) { 1147 } 1148 else if (fileName.endsWith("Table.java") && 1149 line.contains(" index IX_")) { 1150 } 1151 else { 1152 if (_getLineLength(line) > 80) { 1153 _sourceFormatterHelper.printError( 1154 fileName, "> 80: " + fileName + " " + lineCount); 1155 } 1156 else { 1157 combinedLines = _getCombinedLines( 1158 trimmedLine, previousLine); 1159 } 1160 } 1161 } 1162 1163 if (Validator.isNotNull(combinedLines)) { 1164 previousLine = combinedLines; 1165 1166 if (line.endsWith(StringPool.OPEN_CURLY_BRACE)) { 1167 lineToSkipIfEmpty = lineCount + 1; 1168 } 1169 } 1170 else { 1171 if ((lineCount > 1) && 1172 (Validator.isNotNull(previousLine) || 1173 (lineToSkipIfEmpty != lineCount - 1))) { 1174 1175 sb.append(previousLine); 1176 sb.append("\n"); 1177 } 1178 1179 previousLine = line; 1180 } 1181 } 1182 1183 sb.append(previousLine); 1184 1185 unsyncBufferedReader.close(); 1186 1187 String newContent = sb.toString(); 1188 1189 if (newContent.endsWith("\n")) { 1190 newContent = newContent.substring(0, newContent.length() - 1); 1191 } 1192 1193 if (longLogFactoryUtil) { 1194 newContent = StringUtil.replace( 1195 newContent, 1196 "private static Log _log =\n\t\tLogFactoryUtil.getLog(", 1197 "private static Log _log = LogFactoryUtil.getLog(\n\t\t"); 1198 } 1199 1200 return newContent; 1201 } 1202 1203 private static void _formatJSP() throws IOException { 1204 String basedir = "./"; 1205 1206 String copyright = _getCopyright(); 1207 String oldCopyright = _getOldCopyright(); 1208 1209 List<String> list = new ArrayList<String>(); 1210 1211 DirectoryScanner directoryScanner = new DirectoryScanner(); 1212 1213 directoryScanner.setBasedir(basedir); 1214 1215 String[] excludes = { 1216 "**\\portal\\aui\\**", "**\\bin\\**", "**\\null.jsp", 1217 "**\\tmp\\**", "**\\tools\\**" 1218 }; 1219 1220 excludes = ArrayUtil.append(excludes, _excludes); 1221 1222 directoryScanner.setExcludes(excludes); 1223 1224 directoryScanner.setIncludes( 1225 new String[] {"**\\*.jsp", "**\\*.jspf", "**\\*.vm"}); 1226 1227 list.addAll(_sourceFormatterHelper.scanForFiles(directoryScanner)); 1228 1229 String[] fileNames = list.toArray(new String[list.size()]); 1230 1231 for (String fileName : fileNames) { 1232 File file = new File(basedir + fileName); 1233 1234 String content = _fileUtil.read(file); 1235 1236 fileName = fileName.replace( 1237 CharPool.BACK_SLASH, CharPool.FORWARD_SLASH); 1238 1239 _jspContents.put(fileName, content); 1240 } 1241 1242 boolean stripJSPImports = true; 1243 1244 for (String fileName : fileNames) { 1245 File file = new File(basedir + fileName); 1246 1247 String content = _fileUtil.read(file); 1248 1249 String newContent = _formatJSPContent(fileName, content); 1250 1251 newContent = StringUtil.replace( 1252 newContent, 1253 new String[] { 1254 "<br/>", "\"/>", "\" >", "@page import", "\"%>", ")%>", 1255 "javascript: " 1256 }, 1257 new String[] { 1258 "<br />", "\" />", "\">", "@ page import", "\" %>", ") %>", 1259 "javascript:" 1260 }); 1261 1262 if (stripJSPImports) { 1263 try { 1264 newContent = _stripJSPImports(fileName, newContent); 1265 } 1266 catch (RuntimeException re) { 1267 stripJSPImports = false; 1268 } 1269 } 1270 1271 newContent = StringUtil.replace( 1272 newContent, 1273 new String[] { 1274 "* Copyright (c) 2000-2011 Liferay, Inc." 1275 }, 1276 new String[] { 1277 "* Copyright (c) 2000-2012 Liferay, Inc." 1278 }); 1279 1280 if (fileName.endsWith(".jsp") || fileName.endsWith(".jspf")) { 1281 if ((oldCopyright != null) && 1282 newContent.contains(oldCopyright)) { 1283 1284 newContent = StringUtil.replace( 1285 newContent, oldCopyright, copyright); 1286 1287 _sourceFormatterHelper.printError( 1288 fileName, "old (c): " + fileName); 1289 } 1290 1291 if (!newContent.contains(copyright)) { 1292 String customCopyright = _getCustomCopyright(file); 1293 1294 if (Validator.isNull(customCopyright) || 1295 !newContent.contains(customCopyright)) { 1296 1297 _sourceFormatterHelper.printError( 1298 fileName, "(c): " + fileName); 1299 } 1300 else { 1301 newContent = StringUtil.replace( 1302 newContent, "<%\n" + customCopyright + "\n%>", 1303 "<%--\n" + customCopyright + "\n--%>"); 1304 } 1305 } 1306 else { 1307 newContent = StringUtil.replace( 1308 newContent, "<%\n" + copyright + "\n%>", 1309 "<%--\n" + copyright + "\n--%>"); 1310 } 1311 } 1312 1313 newContent = StringUtil.replace( 1314 newContent, 1315 new String[] { 1316 "alert('<%= LanguageUtil.", 1317 "alert(\"<%= LanguageUtil.", 1318 "confirm('<%= LanguageUtil.", 1319 "confirm(\"<%= LanguageUtil." 1320 }, 1321 new String[] { 1322 "alert('<%= UnicodeLanguageUtil.", 1323 "alert(\"<%= UnicodeLanguageUtil.", 1324 "confirm('<%= UnicodeLanguageUtil.", 1325 "confirm(\"<%= UnicodeLanguageUtil." 1326 }); 1327 1328 if (newContent.contains(" ")) { 1329 if (!fileName.endsWith("template.vm")) { 1330 _sourceFormatterHelper.printError( 1331 fileName, "tab: " + fileName); 1332 } 1333 } 1334 1335 if (fileName.endsWith("init.jsp")) { 1336 int x = newContent.indexOf("<%@ page import="); 1337 1338 int y = newContent.lastIndexOf("<%@ page import="); 1339 1340 y = newContent.indexOf("%>", y); 1341 1342 if ((x != -1) && (y != -1) && (y > x)) { 1343 1344 // Set compressImports to false to decompress imports 1345 1346 boolean compressImports = true; 1347 1348 if (compressImports) { 1349 String imports = newContent.substring(x, y); 1350 1351 imports = StringUtil.replace( 1352 imports, new String[] {"%>\r\n<%@ ", "%>\n<%@ "}, 1353 new String[] {"%><%@\r\n", "%><%@\n"}); 1354 1355 newContent = 1356 newContent.substring(0, x) + imports + 1357 newContent.substring(y); 1358 } 1359 } 1360 } 1361 1362 _checkXSS(fileName, newContent); 1363 1364 if ((newContent != null) && !content.equals(newContent)) { 1365 _fileUtil.write(file, newContent); 1366 1367 _sourceFormatterHelper.printError(fileName, file); 1368 } 1369 } 1370 } 1371 1372 private static String _formatJSPContent(String fileName, String content) 1373 throws IOException { 1374 1375 StringBundler sb = new StringBundler(); 1376 1377 UnsyncBufferedReader unsyncBufferedReader = new UnsyncBufferedReader( 1378 new UnsyncStringReader(content)); 1379 1380 int lineCount = 0; 1381 1382 String line = null; 1383 1384 while ((line = unsyncBufferedReader.readLine()) != null) { 1385 lineCount++; 1386 1387 if (line.trim().length() == 0) { 1388 line = StringPool.BLANK; 1389 } 1390 1391 line = StringUtil.trimTrailing(line); 1392 1393 if (line.contains("<aui:button ") && 1394 line.contains("type=\"button\"")) { 1395 1396 _sourceFormatterHelper.printError( 1397 fileName, "aui:button " + fileName + " " + lineCount); 1398 } 1399 1400 String trimmedLine = StringUtil.trimLeading(line); 1401 1402 if (!trimmedLine.contains(StringPool.DOUBLE_SLASH) && 1403 !trimmedLine.startsWith(StringPool.STAR)) { 1404 1405 while (trimmedLine.contains(StringPool.TAB)) { 1406 line = StringUtil.replaceLast( 1407 line, StringPool.TAB, StringPool.SPACE); 1408 1409 trimmedLine = StringUtil.replaceLast( 1410 trimmedLine, StringPool.TAB, StringPool.SPACE); 1411 } 1412 1413 while (trimmedLine.contains(StringPool.DOUBLE_SPACE) && 1414 !trimmedLine.contains( 1415 StringPool.QUOTE + StringPool.DOUBLE_SPACE) && 1416 !fileName.endsWith(".vm")) { 1417 1418 line = StringUtil.replaceLast( 1419 line, StringPool.DOUBLE_SPACE, StringPool.SPACE); 1420 1421 trimmedLine = StringUtil.replaceLast( 1422 trimmedLine, StringPool.DOUBLE_SPACE, StringPool.SPACE); 1423 } 1424 } 1425 1426 int x = line.indexOf("<%@ include file"); 1427 1428 if (x != -1) { 1429 x = line.indexOf(StringPool.QUOTE, x); 1430 1431 int y = line.indexOf(StringPool.QUOTE, x + 1); 1432 1433 if (y != -1) { 1434 String includeFileName = line.substring(x + 1, y); 1435 1436 Matcher matcher = _jspIncludeFilePattern.matcher( 1437 includeFileName); 1438 1439 if (!matcher.find()) { 1440 _sourceFormatterHelper.printError( 1441 fileName, 1442 "include: " + fileName + " " + lineCount); 1443 } 1444 } 1445 } 1446 1447 line = _replacePrimitiveWrapperInstantiation( 1448 fileName, line, lineCount); 1449 1450 sb.append(line); 1451 sb.append("\n"); 1452 } 1453 1454 unsyncBufferedReader.close(); 1455 1456 content = sb.toString(); 1457 1458 if (content.endsWith("\n")) { 1459 content = content.substring(0, content.length() -1); 1460 } 1461 1462 content = _formatTaglibQuotes(fileName, content, StringPool.QUOTE); 1463 content = _formatTaglibQuotes(fileName, content, StringPool.APOSTROPHE); 1464 1465 return content; 1466 } 1467 1468 private static void _formatPortletXML() 1469 throws DocumentException, IOException { 1470 1471 String basedir = "./"; 1472 1473 if (_fileUtil.exists(basedir + "portal-impl")) { 1474 File file = new File( 1475 basedir + "portal-web/docroot/WEB-INF/portlet-custom.xml"); 1476 1477 String content = _fileUtil.read(file); 1478 1479 String newContent = _formatPortletXML(content); 1480 1481 if ((newContent != null) && !content.equals(newContent)) { 1482 _fileUtil.write(file, newContent); 1483 1484 _sourceFormatterHelper.printError(file.toString(), file); 1485 } 1486 } 1487 else { 1488 DirectoryScanner directoryScanner = new DirectoryScanner(); 1489 1490 directoryScanner.setBasedir(basedir); 1491 directoryScanner.setIncludes(new String[] {"**\\portlet.xml"}); 1492 1493 List<String> fileNames = _sourceFormatterHelper.scanForFiles( 1494 directoryScanner); 1495 1496 for (String fileName : fileNames) { 1497 File file = new File(basedir + fileName); 1498 1499 String content = _fileUtil.read(file); 1500 1501 String newContent = _formatPortletXML(content); 1502 1503 if ((newContent != null) && !content.equals(newContent)) { 1504 _fileUtil.write(file, newContent); 1505 1506 _sourceFormatterHelper.printError(fileName, file); 1507 } 1508 } 1509 } 1510 } 1511 1512 private static String _formatPortletXML(String content) 1513 throws DocumentException, IOException { 1514 1515 Document document = _saxReaderUtil.read(content); 1516 1517 Element rootElement = document.getRootElement(); 1518 1519 rootElement.sortAttributes(true); 1520 1521 List<Element> portletElements = rootElement.elements("portlet"); 1522 1523 for (Element portletElement : portletElements) { 1524 portletElement.sortElementsByChildElement("init-param", "name"); 1525 1526 Element portletPreferencesElement = portletElement.element( 1527 "portlet-preferences"); 1528 1529 if (portletPreferencesElement != null) { 1530 portletPreferencesElement.sortElementsByChildElement( 1531 "preference", "name"); 1532 } 1533 } 1534 1535 return document.formattedString(); 1536 } 1537 1538 private static void _formatSH() throws IOException { 1539 _formatSH("ext/create.sh"); 1540 _formatSH("hooks/create.sh"); 1541 _formatSH("layouttpl/create.sh"); 1542 _formatSH("portlets/create.sh"); 1543 _formatSH("themes/create.sh"); 1544 } 1545 1546 private static void _formatSH(String fileName) throws IOException { 1547 File file = new File(fileName); 1548 1549 if (!file.exists()) { 1550 return; 1551 } 1552 1553 String content = _fileUtil.read(new File(fileName), true); 1554 1555 if (content.contains("\r")) { 1556 _sourceFormatterHelper.printError( 1557 fileName, "Invalid new line character"); 1558 1559 content = StringUtil.replace(content, "\r", ""); 1560 1561 _fileUtil.write(fileName, content); 1562 } 1563 } 1564 1565 private static String _formatTaglibQuotes( 1566 String fileName, String content, String quoteType) { 1567 1568 String quoteFix = StringPool.APOSTROPHE; 1569 1570 if (quoteFix.equals(quoteType)) { 1571 quoteFix = StringPool.QUOTE; 1572 } 1573 1574 Pattern pattern = Pattern.compile(_getTaglibRegex(quoteType)); 1575 1576 Matcher matcher = pattern.matcher(content); 1577 1578 while (matcher.find()) { 1579 int x = content.indexOf(quoteType + "<%=", matcher.start()); 1580 int y = content.indexOf("%>" + quoteType, x); 1581 1582 while ((x != -1) && (y != -1)) { 1583 String result = content.substring(x + 1, y + 2); 1584 1585 if (result.contains(quoteType)) { 1586 int lineCount = 1; 1587 1588 char contentCharArray[] = content.toCharArray(); 1589 1590 for (int i = 0; i < x; i++) { 1591 if (contentCharArray[i] == CharPool.NEW_LINE) { 1592 lineCount++; 1593 } 1594 } 1595 1596 if (!result.contains(quoteFix)) { 1597 StringBundler sb = new StringBundler(5); 1598 1599 sb.append(content.substring(0, x)); 1600 sb.append(quoteFix); 1601 sb.append(result); 1602 sb.append(quoteFix); 1603 sb.append(content.substring(y + 3, content.length())); 1604 1605 content = sb.toString(); 1606 } 1607 else { 1608 _sourceFormatterHelper.printError( 1609 fileName, "taglib: " + fileName + " " + lineCount); 1610 } 1611 } 1612 1613 x = content.indexOf(quoteType + "<%=", y); 1614 1615 if (x > matcher.end()) { 1616 break; 1617 } 1618 1619 y = content.indexOf("%>" + quoteType, x); 1620 } 1621 } 1622 1623 return content; 1624 } 1625 1626 private static void _formatWebXML() throws IOException { 1627 String basedir = "./"; 1628 1629 if (_fileUtil.exists(basedir + "portal-impl")) { 1630 Properties properties = new Properties(); 1631 1632 String propertiesContent = _fileUtil.read( 1633 basedir + "portal-impl/src/portal.properties"); 1634 1635 PropertiesUtil.load(properties, propertiesContent); 1636 1637 String[] locales = StringUtil.split( 1638 properties.getProperty(PropsKeys.LOCALES)); 1639 1640 Arrays.sort(locales); 1641 1642 Set<String> urlPatterns = new TreeSet<String>(); 1643 1644 for (String locale : locales) { 1645 int pos = locale.indexOf(StringPool.UNDERLINE); 1646 1647 String languageCode = locale.substring(0, pos); 1648 1649 urlPatterns.add(languageCode); 1650 urlPatterns.add(locale); 1651 } 1652 1653 StringBundler sb = new StringBundler(); 1654 1655 for (String urlPattern : urlPatterns) { 1656 sb.append("\t<servlet-mapping>\n"); 1657 sb.append("\t\t<servlet-name>I18n Servlet</servlet-name>\n"); 1658 sb.append( 1659 "\t\t<url-pattern>/" + urlPattern +"/*</url-pattern>\n"); 1660 sb.append("\t</servlet-mapping>\n"); 1661 } 1662 1663 File file = new File( 1664 basedir + "portal-web/docroot/WEB-INF/web.xml"); 1665 1666 String content = _fileUtil.read(file); 1667 1668 int x = content.indexOf("<servlet-mapping>"); 1669 1670 x = content.indexOf("<servlet-name>I18n Servlet</servlet-name>", x); 1671 1672 x = content.lastIndexOf("<servlet-mapping>", x) - 1; 1673 1674 int y = content.lastIndexOf( 1675 "<servlet-name>I18n Servlet</servlet-name>"); 1676 1677 y = content.indexOf("</servlet-mapping>", y) + 19; 1678 1679 String newContent = 1680 content.substring(0, x) + sb.toString() + content.substring(y); 1681 1682 x = newContent.indexOf("<security-constraint>"); 1683 1684 x = newContent.indexOf( 1685 "<web-resource-name>/c/portal/protected</web-resource-name>", 1686 x); 1687 1688 x = newContent.indexOf("<url-pattern>", x) - 3; 1689 1690 y = newContent.indexOf("<http-method>", x); 1691 1692 y = newContent.lastIndexOf("</url-pattern>", y) + 15; 1693 1694 sb = new StringBundler(); 1695 1696 sb.append( 1697 "\t\t\t<url-pattern>/c/portal/protected</url-pattern>\n"); 1698 1699 for (String urlPattern : urlPatterns) { 1700 sb.append( 1701 "\t\t\t<url-pattern>/" + urlPattern + 1702 "/c/portal/protected</url-pattern>\n"); 1703 } 1704 1705 newContent = 1706 newContent.substring(0, x) + sb.toString() + 1707 newContent.substring(y); 1708 1709 if ((newContent != null) && !content.equals(newContent)) { 1710 _fileUtil.write(file, newContent); 1711 1712 System.out.println(file); 1713 } 1714 } 1715 else { 1716 String webXML = ContentUtil.get( 1717 "com/liferay/portal/deploy/dependencies/web.xml"); 1718 1719 DirectoryScanner directoryScanner = new DirectoryScanner(); 1720 1721 directoryScanner.setBasedir(basedir); 1722 directoryScanner.setIncludes(new String[] {"**\\web.xml"}); 1723 1724 List<String> fileNames = _sourceFormatterHelper.scanForFiles( 1725 directoryScanner); 1726 1727 for (String fileName : fileNames) { 1728 String content = _fileUtil.read(basedir + fileName); 1729 1730 if (content.equals(webXML)) { 1731 _sourceFormatterHelper.printError(fileName, fileName); 1732 } 1733 } 1734 } 1735 } 1736 1737 private static String _getCombinedLines(String line, String previousLine) { 1738 if (Validator.isNull(previousLine)) { 1739 return null; 1740 } 1741 1742 int previousLineLength = _getLineLength(previousLine); 1743 String trimmedPreviousLine = StringUtil.trimLeading(previousLine); 1744 1745 if ((line.length() + previousLineLength) < 80) { 1746 if (trimmedPreviousLine.startsWith("for ") && 1747 previousLine.endsWith(StringPool.COLON) && 1748 line.endsWith(StringPool.OPEN_CURLY_BRACE)) { 1749 1750 return previousLine + StringPool.SPACE + line; 1751 } 1752 1753 if (previousLine.endsWith(StringPool.EQUAL) && 1754 line.endsWith(StringPool.SEMICOLON)) { 1755 1756 return previousLine + StringPool.SPACE + line; 1757 } 1758 1759 if ((trimmedPreviousLine.startsWith("if ") || 1760 trimmedPreviousLine.startsWith("else ")) && 1761 (previousLine.endsWith("||") || previousLine.endsWith("&&")) && 1762 line.endsWith(StringPool.OPEN_CURLY_BRACE)) { 1763 1764 return previousLine + StringPool.SPACE + line; 1765 } 1766 } 1767 1768 if (!previousLine.endsWith(StringPool.OPEN_PARENTHESIS)) { 1769 return null; 1770 } 1771 1772 if ((line.length() + previousLineLength) > 80) { 1773 return null; 1774 } 1775 1776 if (line.endsWith(StringPool.SEMICOLON)) { 1777 return previousLine + line; 1778 } 1779 1780 if ((line.endsWith(StringPool.OPEN_CURLY_BRACE) || 1781 line.endsWith(StringPool.CLOSE_PARENTHESIS)) && 1782 (trimmedPreviousLine.startsWith("else ") || 1783 trimmedPreviousLine.startsWith("if ") || 1784 trimmedPreviousLine.startsWith("private ") || 1785 trimmedPreviousLine.startsWith("protected ") || 1786 trimmedPreviousLine.startsWith("public "))) { 1787 1788 return previousLine + line; 1789 } 1790 1791 return null; 1792 } 1793 1794 private static String _getCopyright() throws IOException { 1795 String copyright = _fileUtil.read("copyright.txt"); 1796 1797 if (Validator.isNull(copyright)) { 1798 copyright = _fileUtil.read("../copyright.txt"); 1799 } 1800 1801 if (Validator.isNull(copyright)) { 1802 copyright = _fileUtil.read("../../copyright.txt"); 1803 } 1804 1805 return copyright; 1806 } 1807 1808 private static String _getCustomCopyright(File file) 1809 throws IOException { 1810 1811 String absolutePath = _fileUtil.getAbsolutePath(file); 1812 1813 for (int x = absolutePath.length();;) { 1814 x = absolutePath.lastIndexOf(StringPool.SLASH, x); 1815 1816 if (x == -1) { 1817 break; 1818 } 1819 1820 String copyright = _fileUtil.read( 1821 absolutePath.substring(0, x + 1) + "copyright.txt"); 1822 1823 if (Validator.isNotNull(copyright)) { 1824 return copyright; 1825 } 1826 1827 x = x - 1; 1828 } 1829 1830 return null; 1831 } 1832 1833 private static List<String> _getJSPDuplicateImports( 1834 String fileName, String content, List<String> importLines) { 1835 1836 List<String> duplicateImports = new ArrayList<String>(); 1837 1838 for (String importLine : importLines) { 1839 int x = content.indexOf("<%@ include file="); 1840 1841 if (x == -1) { 1842 continue; 1843 } 1844 1845 int y = content.indexOf("<%@ page import="); 1846 1847 if (y == -1) { 1848 continue; 1849 } 1850 1851 if ((x < y) && _isJSPDuplicateImport(fileName, importLine, false)) { 1852 duplicateImports.add(importLine); 1853 } 1854 } 1855 1856 return duplicateImports; 1857 } 1858 1859 private static int _getLineLength(String line) { 1860 int lineLength = 0; 1861 1862 int tabLength = 4; 1863 1864 for (char c : line.toCharArray()) { 1865 if (c == CharPool.TAB) { 1866 for (int i = 0; i < tabLength; i++) { 1867 lineLength++; 1868 } 1869 1870 tabLength = 4; 1871 } 1872 else { 1873 lineLength++; 1874 1875 tabLength--; 1876 1877 if (tabLength <= 0) { 1878 tabLength = 4; 1879 } 1880 } 1881 } 1882 1883 return lineLength; 1884 } 1885 1886 private static String _getOldCopyright() throws IOException { 1887 String copyright = _fileUtil.read("old-copyright.txt"); 1888 1889 if (Validator.isNull(copyright)) { 1890 copyright = _fileUtil.read("../old-copyright.txt"); 1891 } 1892 1893 if (Validator.isNull(copyright)) { 1894 copyright = _fileUtil.read("../../old-copyright.txt"); 1895 } 1896 1897 return copyright; 1898 } 1899 1900 private static Collection<String> _getPluginJavaFiles() { 1901 String basedir = "./"; 1902 1903 Collection<String> fileNames = new TreeSet<String>(); 1904 1905 DirectoryScanner directoryScanner = new DirectoryScanner(); 1906 1907 directoryScanner.setBasedir(basedir); 1908 1909 String[] excludes = { 1910 "**\\bin\\**", "**\\model\\*Clp.java", 1911 "**\\model\\impl\\*BaseImpl.java", 1912 "**\\model\\impl\\*Model.java", 1913 "**\\model\\impl\\*ModelImpl.java", 1914 "**\\service\\**\\model\\*Model.java", 1915 "**\\service\\**\\model\\*Soap.java", 1916 "**\\service\\**\\model\\*Wrapper.java", 1917 "**\\service\\**\\service\\*Service.java", 1918 "**\\service\\**\\service\\*ServiceClp.java", 1919 "**\\service\\**\\service\\*ServiceFactory.java", 1920 "**\\service\\**\\service\\*ServiceUtil.java", 1921 "**\\service\\**\\service\\*ServiceWrapper.java", 1922 "**\\service\\**\\service\\ClpSerializer.java", 1923 "**\\service\\**\\service\\messaging\\*ClpMessageListener.java", 1924 "**\\service\\**\\service\\persistence\\*Finder.java", 1925 "**\\service\\**\\service\\persistence\\*Persistence.java", 1926 "**\\service\\**\\service\\persistence\\*Util.java", 1927 "**\\service\\base\\*ServiceBaseImpl.java", 1928 "**\\service\\http\\*JSONSerializer.java", 1929 "**\\service\\http\\*ServiceHttp.java", 1930 "**\\service\\http\\*ServiceJSON.java", 1931 "**\\service\\http\\*ServiceSoap.java", 1932 "**\\service\\persistence\\*PersistenceImpl.java", "**\\tmp\\**" 1933 }; 1934 1935 excludes = ArrayUtil.append(excludes, _excludes); 1936 1937 directoryScanner.setExcludes(excludes); 1938 1939 directoryScanner.setIncludes(new String[] {"**\\*.java"}); 1940 1941 fileNames.addAll(_sourceFormatterHelper.scanForFiles(directoryScanner)); 1942 1943 return fileNames; 1944 } 1945 1946 private static Collection<String> _getPortalJavaFiles() { 1947 String basedir = "./"; 1948 1949 Collection<String> fileNames = new TreeSet<String>(); 1950 1951 DirectoryScanner directoryScanner = new DirectoryScanner(); 1952 1953 directoryScanner.setBasedir(basedir); 1954 1955 String[] excludes = { 1956 "**\\InstanceWrapperBuilder.java", "**\\*_IW.java", 1957 "**\\PropsKeys.java", "**\\PropsValues.java", 1958 "**\\ServiceBuilder.java", "**\\SourceFormatter.java", 1959 "**\\WebKeys.java", "**\\bin\\**", "**\\classes\\*", 1960 "**\\counter\\service\\**", "**\\jsp\\*", 1961 "**\\model\\impl\\*BaseImpl.java", "**\\model\\impl\\*Model.java", 1962 "**\\model\\impl\\*ModelImpl.java", "**\\portal\\service\\**", 1963 "**\\portal-client\\**", 1964 "**\\portal-service\\**\\model\\*Model.java", 1965 "**\\portal-service\\**\\model\\*Soap.java", 1966 "**\\portal-service\\**\\model\\*Wrapper.java", 1967 "**\\portal-web\\classes\\**\\*.java", 1968 "**\\portal-web\\test\\**\\*Test.java", 1969 "**\\portlet\\**\\service\\**", "**\\tmp\\**", "**\\tools\\tck\\**" 1970 }; 1971 1972 excludes = ArrayUtil.append(excludes, _excludes); 1973 1974 directoryScanner.setExcludes(excludes); 1975 1976 directoryScanner.setIncludes(new String[] {"**\\*.java"}); 1977 1978 fileNames.addAll(_sourceFormatterHelper.scanForFiles(directoryScanner)); 1979 1980 directoryScanner = new DirectoryScanner(); 1981 1982 directoryScanner.setBasedir(basedir); 1983 1984 excludes = new String[] { 1985 "**\\bin\\**", "**\\portal-client\\**", "**\\tools\\ext_tmpl\\**", 1986 "**\\*_IW.java", "**\\test\\**\\*PersistenceTest.java" 1987 }; 1988 1989 excludes = ArrayUtil.append(excludes, _excludes); 1990 1991 directoryScanner.setExcludes(excludes); 1992 1993 directoryScanner.setIncludes( 1994 new String[] { 1995 "**\\com\\liferay\\portal\\service\\ServiceContext*.java", 1996 "**\\model\\BaseModel.java", 1997 "**\\model\\impl\\BaseModelImpl.java", 1998 "**\\service\\PersistedModelLocalService*.java", 1999 "**\\service\\base\\PrincipalBean.java", 2000 "**\\service\\http\\*HttpTest.java", 2001 "**\\service\\http\\*SoapTest.java", 2002 "**\\service\\http\\TunnelUtil.java", 2003 "**\\service\\impl\\*.java", "**\\service\\jms\\*.java", 2004 "**\\service\\permission\\*.java", 2005 "**\\service\\persistence\\BasePersistence.java", 2006 "**\\service\\persistence\\BatchSession*.java", 2007 "**\\service\\persistence\\*FinderImpl.java", 2008 "**\\service\\persistence\\*Query.java", 2009 "**\\service\\persistence\\impl\\BasePersistenceImpl.java", 2010 "**\\portal-impl\\test\\**\\*.java", 2011 "**\\portal-service\\**\\liferay\\documentlibrary\\**.java", 2012 "**\\portal-service\\**\\liferay\\lock\\**.java", 2013 "**\\portal-service\\**\\liferay\\mail\\**.java", 2014 "**\\util-bridges\\**\\*.java" 2015 }); 2016 2017 fileNames.addAll(_sourceFormatterHelper.scanForFiles(directoryScanner)); 2018 2019 return fileNames; 2020 } 2021 2022 private static String _getTaglibRegex(String quoteType) { 2023 StringBuilder sb = new StringBuilder(); 2024 2025 sb.append("<("); 2026 2027 for (int i = 0; i < _TAG_LIBRARIES.length; i++) { 2028 sb.append(_TAG_LIBRARIES[i]); 2029 sb.append(StringPool.PIPE); 2030 } 2031 2032 sb.deleteCharAt(sb.length() - 1); 2033 sb.append("):([^>]|%>)*"); 2034 sb.append(quoteType); 2035 sb.append("<%=.*"); 2036 sb.append(quoteType); 2037 sb.append(".*%>"); 2038 sb.append(quoteType); 2039 sb.append("([^>]|%>)*>"); 2040 2041 return sb.toString(); 2042 } 2043 2044 private static boolean _isGenerated(String content) { 2045 if (content.contains("* @generated") || content.contains("$ANTLR")) { 2046 return true; 2047 } 2048 else { 2049 return false; 2050 } 2051 } 2052 2053 private static boolean _isJSPDuplicateImport( 2054 String fileName, String importLine, boolean checkFile) { 2055 2056 String content = _jspContents.get(fileName); 2057 2058 if (Validator.isNull(content)) { 2059 return false; 2060 } 2061 2062 int x = importLine.indexOf("page"); 2063 2064 if (x == -1) { 2065 return false; 2066 } 2067 2068 if (checkFile && content.contains(importLine.substring(x))) { 2069 return true; 2070 } 2071 2072 int y = content.indexOf("<%@ include file="); 2073 2074 if (y == -1) { 2075 return false; 2076 } 2077 2078 y = content.indexOf(StringPool.QUOTE, y); 2079 2080 if (y == -1) { 2081 return false; 2082 } 2083 2084 int z = content.indexOf(StringPool.QUOTE, y + 1); 2085 2086 if (z == -1) { 2087 return false; 2088 } 2089 2090 String includeFileName = content.substring(y + 1, z); 2091 2092 String docrootPath = fileName.substring( 2093 0, fileName.indexOf("docroot") + 7); 2094 2095 includeFileName = docrootPath + includeFileName; 2096 2097 return _isJSPDuplicateImport(includeFileName, importLine, true); 2098 } 2099 2100 private static boolean _isJSPImportRequired( 2101 String fileName, String className, Set<String> includeFileNames, 2102 Set<String> checkedFileNames) { 2103 2104 if (checkedFileNames.contains(fileName)) { 2105 return false; 2106 } 2107 2108 checkedFileNames.add(fileName); 2109 2110 String content = _jspContents.get(fileName); 2111 2112 if (Validator.isNull(content)) { 2113 return false; 2114 } 2115 2116 Pattern pattern = Pattern.compile( 2117 "[^A-Za-z0-9_]" + className + "[^A-Za-z0-9_\"]"); 2118 2119 Matcher matcher = pattern.matcher(content); 2120 2121 if (matcher.find()) { 2122 return true; 2123 } 2124 2125 _addJSPIncludeFileNames(fileName, includeFileNames); 2126 2127 String docrootPath = fileName.substring( 2128 0, fileName.indexOf("docroot") + 7); 2129 2130 fileName = fileName.replaceFirst(docrootPath, StringPool.BLANK); 2131 2132 if (fileName.endsWith("init.jsp") || 2133 fileName.contains("init-ext.jsp")) { 2134 2135 _addJSPReferenceFileNames(fileName, includeFileNames); 2136 } 2137 2138 String[] includeFileNamesArray = includeFileNames.toArray( 2139 new String[includeFileNames.size()]); 2140 2141 for (String includeFileName : includeFileNamesArray) { 2142 if (!checkedFileNames.contains(includeFileName) && 2143 _isJSPImportRequired( 2144 includeFileName, className, includeFileNames, 2145 checkedFileNames)) { 2146 2147 return true; 2148 } 2149 } 2150 2151 return false; 2152 } 2153 2154 private static void _readExclusions() throws IOException { 2155 _exclusionsProperties = new Properties(); 2156 2157 ClassLoader classLoader = SourceFormatter.class.getClassLoader(); 2158 2159 String sourceFormatterExclusions = System.getProperty( 2160 "source-formatter-exclusions", 2161 "com/liferay/portal/tools/dependencies/" + 2162 "source_formatter_exclusions.properties"); 2163 2164 URL url = classLoader.getResource(sourceFormatterExclusions); 2165 2166 if (url == null) { 2167 return; 2168 } 2169 2170 InputStream inputStream = url.openStream(); 2171 2172 _exclusionsProperties.load(inputStream); 2173 2174 inputStream.close(); 2175 } 2176 2177 private static String _replacePrimitiveWrapperInstantiation( 2178 String fileName, String line, int lineCount) { 2179 2180 if (true) { 2181 return line; 2182 } 2183 2184 String newLine = StringUtil.replace( 2185 line, 2186 new String[] { 2187 "new Boolean(", "new Byte(", "new Character(", 2188 "new Integer(", "new Long(", "new Short(" 2189 }, 2190 new String[] { 2191 "Boolean.valueOf(", "Byte.valueOf(", "Character.valueOf(", 2192 "Integer.valueOf(", "Long.valueOf(", "Short.valueOf(" 2193 }); 2194 2195 if (!line.equals(newLine)) { 2196 _sourceFormatterHelper.printError( 2197 fileName, "> new Primitive(: " + fileName + " " + lineCount); 2198 } 2199 2200 return newLine; 2201 } 2202 2203 private static String _stripJSPImports(String fileName, String content) 2204 throws IOException { 2205 2206 fileName = fileName.replace( 2207 CharPool.BACK_SLASH, CharPool.FORWARD_SLASH); 2208 2209 if (!fileName.contains("docroot") || 2210 fileName.endsWith("init-ext.jsp")) { 2211 2212 return content; 2213 } 2214 2215 Matcher matcher = _jspImportPattern.matcher(content); 2216 2217 if (!matcher.find()) { 2218 return content; 2219 } 2220 2221 String imports = matcher.group(); 2222 2223 imports = StringUtil.replace( 2224 imports, new String[] {"%><%@\r\n", "%><%@\n"}, 2225 new String[] {"%>\r\n<%@ ", "%>\n<%@ "}); 2226 2227 if (!fileName.endsWith("html/common/init.jsp") && 2228 !fileName.endsWith("html/portal/init.jsp")) { 2229 2230 List<String> importLines = new ArrayList<String>(); 2231 2232 UnsyncBufferedReader unsyncBufferedReader = 2233 new UnsyncBufferedReader(new UnsyncStringReader(imports)); 2234 2235 String line = null; 2236 2237 while ((line = unsyncBufferedReader.readLine()) != null) { 2238 if (line.contains("import=")) { 2239 importLines.add(line); 2240 } 2241 } 2242 2243 List<String> unneededImports = _getJSPDuplicateImports( 2244 fileName, content, importLines); 2245 2246 _addJSPUnusedImports(fileName, importLines, unneededImports); 2247 2248 for (String unneededImport : unneededImports) { 2249 imports = StringUtil.replace( 2250 imports, unneededImport, StringPool.BLANK); 2251 } 2252 } 2253 2254 imports = _formatImports(imports, 17); 2255 2256 String beforeImports = content.substring(0, matcher.start()); 2257 2258 if (Validator.isNull(imports)) { 2259 beforeImports = StringUtil.replaceLast( 2260 beforeImports, "\n", StringPool.BLANK); 2261 } 2262 2263 String afterImports = content.substring(matcher.end()); 2264 2265 if (Validator.isNull(afterImports)) { 2266 imports = StringUtil.replaceLast(imports, "\n", StringPool.BLANK); 2267 2268 content = beforeImports + imports; 2269 2270 return content; 2271 } 2272 2273 content = beforeImports + imports + "\n" + afterImports; 2274 2275 return content; 2276 } 2277 2278 private static final String[] _TAG_LIBRARIES = new String[] { 2279 "aui", "c", "html", "jsp", "liferay-portlet", "liferay-security", 2280 "liferay-theme", "liferay-ui", "liferay-util", "portlet", "struts", 2281 "tiles" 2282 }; 2283 2284 private static String[] _excludes; 2285 private static Properties _exclusionsProperties; 2286 private static FileImpl _fileUtil = FileImpl.getInstance(); 2287 private static Pattern _javaImportPattern = Pattern.compile( 2288 "(^[ \t]*import\\s+.*;\n+)+", Pattern.MULTILINE); 2289 private static Map<String, String> _jspContents = 2290 new HashMap<String, String>(); 2291 private static Pattern _jspImportPattern = Pattern.compile( 2292 "(<.*\n*page.import=\".*>\n*)+", Pattern.MULTILINE); 2293 private static Pattern _jspIncludeFilePattern = Pattern.compile( 2294 "/.*[.]jsp[f]?"); 2295 private static SAXReaderImpl _saxReaderUtil = SAXReaderImpl.getInstance(); 2296 private static SourceFormatterHelper _sourceFormatterHelper; 2297 private static Pattern _xssPattern = Pattern.compile( 2298 "String\\s+([^\\s]+)\\s*=\\s*(Bean)?ParamUtil\\.getString\\("); 2299 2300 }