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    }