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