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