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.CharPool;
020    import com.liferay.portal.kernel.util.ClassUtil;
021    import com.liferay.portal.kernel.util.ListUtil;
022    import com.liferay.portal.kernel.util.PropertiesUtil;
023    import com.liferay.portal.kernel.util.PropsKeys;
024    import com.liferay.portal.kernel.util.StringPool;
025    import com.liferay.portal.kernel.util.StringUtil;
026    import com.liferay.portal.kernel.xml.Document;
027    import com.liferay.portal.kernel.xml.DocumentException;
028    import com.liferay.portal.kernel.xml.Element;
029    import com.liferay.portal.util.ContentUtil;
030    import com.liferay.portal.util.FileImpl;
031    import com.liferay.portal.xml.SAXReaderImpl;
032    
033    import java.io.File;
034    import java.io.IOException;
035    import java.io.InputStream;
036    
037    import java.net.URL;
038    
039    import java.util.ArrayList;
040    import java.util.Arrays;
041    import java.util.Collection;
042    import java.util.List;
043    import java.util.Properties;
044    import java.util.Set;
045    import java.util.TreeSet;
046    import java.util.regex.Matcher;
047    import java.util.regex.Pattern;
048    
049    import org.apache.tools.ant.DirectoryScanner;
050    
051    /**
052     * @author Brian Wing Shun Chan
053     * @author Igor Spasic
054     * @author Wesley Gong
055     */
056    public class SourceFormatter {
057    
058            public static void main(String[] args) {
059                    try {
060                            _sourceFormatterHelper = new SourceFormatterHelper(true);
061    
062                            _sourceFormatterHelper.init();
063    
064                            _readExclusions();
065    
066                            Thread thread1 = new Thread () {
067                                    public void run() {
068                                            try {
069                                                    _checkPersistenceTestSuite();
070                                                    _formatJSP();
071                                                    _formatAntXML();
072                                                    _formatWebXML();
073                                            }
074                                            catch (Exception e) {
075                                                    e.printStackTrace();
076                                            }
077                                    }
078                            };
079    
080                            Thread thread2 = new Thread () {
081                                    public void run() {
082                                            try {
083                                                    _formatJava();
084                                            }
085                                            catch (Exception e) {
086                                                    e.printStackTrace();
087                                            }
088                                    }
089                            };
090    
091                            thread1.start();
092                            thread2.start();
093    
094                            thread1.join();
095                            thread2.join();
096    
097                            _sourceFormatterHelper.close();
098                    }
099                    catch (Exception e) {
100                            e.printStackTrace();
101                    }
102            }
103    
104            public static String stripImports(
105                            String content, String packageDir, String className)
106                    throws IOException {
107    
108                    Pattern pattern = Pattern.compile(
109                            "(^[ \t]*import\\s+.*;\n+)+", Pattern.MULTILINE);
110    
111                    Matcher matcher = pattern.matcher(content);
112    
113                    if (!matcher.find()) {
114                            return content;
115                    }
116    
117                    String imports = _formatImports(matcher.group());
118    
119                    content =
120                            content.substring(0, matcher.start()) + imports +
121                                    content.substring(matcher.end());
122    
123                    Set<String> classes = ClassUtil.getClasses(
124                            new UnsyncStringReader(content), className);
125    
126                    matcher = pattern.matcher(content);
127    
128                    matcher.find();
129    
130                    imports = matcher.group();
131    
132                    StringBuilder sb = new StringBuilder();
133    
134                    UnsyncBufferedReader unsyncBufferedReader = new UnsyncBufferedReader(
135                            new UnsyncStringReader(imports));
136    
137                    String line = null;
138    
139                    while ((line = unsyncBufferedReader.readLine()) != null) {
140                            if (line.indexOf("import ") != -1) {
141                                    int importX = line.indexOf(" ");
142                                    int importY = line.lastIndexOf(".");
143    
144                                    String importPackage = line.substring(importX + 1, importY);
145                                    String importClass = line.substring(
146                                            importY + 1, line.length() - 1);
147    
148                                    if (!packageDir.equals(importPackage)) {
149                                            if (!importClass.equals("*")) {
150                                                    if (classes.contains(importClass)) {
151                                                            sb.append(line);
152                                                            sb.append("\n");
153                                                    }
154                                            }
155                                            else {
156                                                    sb.append(line);
157                                                    sb.append("\n");
158                                            }
159                                    }
160                            }
161                    }
162    
163                    imports = _formatImports(sb.toString());
164    
165                    content =
166                            content.substring(0, matcher.start()) + imports +
167                                    content.substring(matcher.end());
168    
169                    // Ensure a blank line exists between the package and the first import
170    
171                    content = content.replaceFirst(
172                            "(?m)^[ \t]*(package .*;)\\s*^[ \t]*import", "$1\n\nimport");
173    
174                    // Ensure a blank line exists between the last import (or package if
175                    // there are no imports) and the class comment
176    
177                    content = content.replaceFirst(
178                            "(?m)^[ \t]*((?:package|import) .*;)\\s*^[ \t]*/\\*\\*",
179                            "$1\n\n/**");
180    
181                    return content;
182            }
183    
184            private static void _checkPersistenceTestSuite() throws IOException {
185                    String basedir = "./portal-impl/test";
186    
187                    if (!_fileUtil.exists(basedir)) {
188                            return;
189                    }
190    
191                    DirectoryScanner directoryScanner = new DirectoryScanner();
192    
193                    directoryScanner.setBasedir(basedir);
194                    directoryScanner.setIncludes(
195                            new String[] {"**\\*PersistenceTest.java"});
196    
197                    List<String> fileNames = _sourceFormatterHelper.scanForFiles(
198                            directoryScanner);
199    
200                    List<String> persistenceTests = new ArrayList<String>();
201    
202                    for (String fileName : fileNames) {
203                            String persistenceTest = fileName.substring(
204                                    0, fileName.length() - 5);
205    
206                            persistenceTest = persistenceTest.substring(
207                                    persistenceTest.lastIndexOf(File.separator) + 1,
208                                    persistenceTest.length());
209    
210                            persistenceTests.add(persistenceTest);
211                    }
212    
213                    String persistenceTestSuiteFileName =
214                            basedir + "/com/liferay/portal/service/persistence/" +
215                                    "PersistenceTestSuite.java";
216    
217                    String persistenceTestSuiteContent = _fileUtil.read(
218                            persistenceTestSuiteFileName);
219    
220                    for (String persistenceTest : persistenceTests) {
221                            if (!persistenceTestSuiteContent.contains(persistenceTest)) {
222                                    _sourceFormatterHelper.printError(
223                                            persistenceTestSuiteFileName,
224                                            "PersistenceTestSuite: " + persistenceTest);
225                            }
226                    }
227            }
228    
229            private static void _checkXSS(String fileName, String jspContent) {
230                    Matcher matcher = _xssPattern.matcher(jspContent);
231    
232                    while (matcher.find()) {
233                            boolean xssVulnerable = false;
234    
235                            String jspVariable = matcher.group(1);
236    
237                            String inputVulnerability =
238                                    "<input[^<>]*(<[^(/>)]*/>)*[^<>]* value=\"<%= " + jspVariable +
239                                            " %>";
240    
241                            Pattern inputVulnerabilityPattern =
242                                    Pattern.compile(inputVulnerability, Pattern.CASE_INSENSITIVE);
243    
244                            Matcher inputVulnerabilityMatcher =
245                                    inputVulnerabilityPattern.matcher(jspContent);
246    
247                            if (inputVulnerabilityMatcher.find()) {
248                                    xssVulnerable = true;
249                            }
250    
251                            String anchorVulnerability = " href=\"<%= " + jspVariable + " %>";
252    
253                            if (jspContent.indexOf(anchorVulnerability) != -1) {
254                                    xssVulnerable = true;
255                            }
256    
257                            String inlineStringVulnerability1 = "'<%= " + jspVariable + " %>";
258    
259                            if (jspContent.indexOf(inlineStringVulnerability1) != -1) {
260                                    xssVulnerable = true;
261                            }
262    
263                            String inlineStringVulnerability2 = "(\"<%= " + jspVariable + " %>";
264    
265                            if (jspContent.indexOf(inlineStringVulnerability2) != -1) {
266                                    xssVulnerable = true;
267                            }
268    
269                            String inlineStringVulnerability3 = " \"<%= " + jspVariable + " %>";
270    
271                            if (jspContent.indexOf(inlineStringVulnerability3) != -1) {
272                                    xssVulnerable = true;
273                            }
274    
275                            String documentIdVulnerability = ".<%= " + jspVariable + " %>";
276    
277                            if (jspContent.indexOf(documentIdVulnerability) != -1) {
278                                    xssVulnerable = true;
279                            }
280    
281                            if (xssVulnerable) {
282                                    _sourceFormatterHelper.printError(
283                                            fileName, "(xss): " + fileName + " (" + jspVariable + ")");
284                            }
285                    }
286            }
287    
288            private static void _formatAntXML() throws DocumentException, IOException {
289                    String basedir = "./";
290    
291                    DirectoryScanner directoryScanner = new DirectoryScanner();
292    
293                    directoryScanner.setBasedir(basedir);
294                    directoryScanner.setIncludes(new String[] {"**\\b*.xml"});
295                    directoryScanner.setExcludes(new String[] {"**\\tools\\**"});
296    
297                    List<String> fileNames = _sourceFormatterHelper.scanForFiles(
298                            directoryScanner);
299    
300                    for (String fileName : fileNames) {
301                            String content = _fileUtil.read(basedir + fileName);
302    
303                            Document document = _saxReaderUtil.read(content);
304    
305                            Element rootElement = document.getRootElement();
306    
307                            String previousName = StringPool.BLANK;
308    
309                            List<Element> targetElements = rootElement.elements("target");
310    
311                            for (Element targetElement : targetElements) {
312                                    String name = targetElement.attributeValue("name");
313    
314                                    if (name.equals("Test")) {
315                                            name = name.toLowerCase();
316                                    }
317    
318                                    if (name.compareTo(previousName) < -1) {
319                                            _sourceFormatterHelper.printError(
320                                                    fileName, fileName + " has an unordered target " + name);
321    
322                                            break;
323                                    }
324    
325                                    previousName = name;
326                            }
327                    }
328            }
329    
330            private static String _formatImports(String imports) throws IOException {
331                    if ((imports.indexOf("/*") != -1) ||
332                            (imports.indexOf("*/") != -1) ||
333                            (imports.indexOf("//") != -1)) {
334    
335                            return imports + "\n";
336                    }
337    
338                    List<String> importsList = new ArrayList<String>();
339    
340                    UnsyncBufferedReader unsyncBufferedReader = new UnsyncBufferedReader(
341                            new UnsyncStringReader(imports));
342    
343                    String line = null;
344    
345                    while ((line = unsyncBufferedReader.readLine()) != null) {
346                            if (line.indexOf("import ") != -1) {
347                                    if (!importsList.contains(line)) {
348                                            importsList.add(line);
349                                    }
350                            }
351                    }
352    
353                    importsList = ListUtil.sort(importsList);
354    
355                    StringBuilder sb = new StringBuilder();
356    
357                    String temp = null;
358    
359                    for (int i = 0; i < importsList.size(); i++) {
360                            String s = importsList.get(i);
361    
362                            int pos = s.indexOf(".");
363    
364                            pos = s.indexOf(".", pos + 1);
365    
366                            if (pos == -1) {
367                                    pos = s.indexOf(".");
368                            }
369    
370                            String packageLevel = s.substring(7, pos);
371    
372                            if ((i != 0) && (!packageLevel.equals(temp))) {
373                                    sb.append("\n");
374                            }
375    
376                            temp = packageLevel;
377    
378                            sb.append(s);
379                            sb.append("\n");
380                    }
381    
382                    return sb.toString();
383            }
384    
385            private static void _formatJava() throws IOException {
386                    String basedir = "./";
387    
388                    String copyright = _getCopyright();
389                    String oldCopyright = _getOldCopyright();
390    
391                    boolean portalJavaFiles = true;
392    
393                    Collection<String> fileNames = null;
394    
395                    if (_fileUtil.exists(basedir + "portal-impl")) {
396                            fileNames = _getPortalJavaFiles();
397                    }
398                    else {
399                            portalJavaFiles = false;
400    
401                            fileNames = _getPluginJavaFiles();
402                    }
403    
404                    for (String fileName : fileNames) {
405                            File file = new File(fileName);
406    
407                            String content = _fileUtil.read(file);
408    
409                            String className = file.getName();
410    
411                            className = className.substring(0, className.length() - 5);
412    
413                            String packagePath = fileName;
414    
415                            int packagePathX = packagePath.indexOf(
416                                    File.separator + "src" + File.separator);
417                            int packagePathY = packagePath.lastIndexOf(File.separator);
418    
419                            if ((packagePathX + 5) >= packagePathY) {
420                                    packagePath = StringPool.BLANK;
421                            }
422                            else {
423                                    packagePath = packagePath.substring(
424                                            packagePathX + 5, packagePathY);
425                            }
426    
427                            packagePath = StringUtil.replace(
428                                    packagePath, File.separator, StringPool.PERIOD);
429    
430                            if (packagePath.endsWith(".model")) {
431                                    if (content.indexOf(
432                                                    "extends " + className + "Model {") != -1) {
433    
434                                            continue;
435                                    }
436                            }
437    
438                            String newContent = _formatJavaContent(
439                                    fileName, className, content);
440    
441                            if (newContent.indexOf("$\n */") != -1) {
442                                    _sourceFormatterHelper.printError(fileName, "*: " + fileName);
443    
444                                    newContent = StringUtil.replace(
445                                            newContent, "$\n */", "$\n *\n */");
446                            }
447    
448                            if ((oldCopyright != null) && newContent.contains(oldCopyright)) {
449                                    newContent = StringUtil.replace(
450                                            newContent, oldCopyright, copyright);
451    
452                                    _sourceFormatterHelper.printError(
453                                            fileName, "old (c): " + fileName);
454                            }
455    
456                            if (newContent.indexOf(copyright) == -1) {
457                                    _sourceFormatterHelper.printError(fileName, "(c): " + fileName);
458                            }
459    
460                            if (newContent.indexOf(className + ".java.html") != -1) {
461                                    _sourceFormatterHelper.printError(
462                                            fileName, "Java2HTML: " + fileName);
463                            }
464    
465                            if (newContent.contains(" * @author Raymond Aug") &&
466                                    !newContent.contains(" * @author Raymond Aug\u00e9")) {
467    
468                                    newContent = newContent.replaceFirst(
469                                            "Raymond Aug.++", "Raymond Aug\u00e9");
470    
471                                    _sourceFormatterHelper.printError(
472                                            fileName, "UTF-8: " + fileName);
473                            }
474    
475                            if (newContent.contains("com.liferay.portal.PortalException")) {
476                                    newContent = StringUtil.replace(
477                                            newContent, "com.liferay.portal.PortalException",
478                                            "com.liferay.portal.kernel.exception.PortalException");
479                            }
480    
481                            if (newContent.contains("com.liferay.portal.SystemException")) {
482                                    newContent = StringUtil.replace(
483                                            newContent, "com.liferay.portal.SystemException",
484                                            "com.liferay.portal.kernel.exception.SystemException");
485                            }
486    
487                            if (newContent.contains("com.liferay.util.LocalizationUtil")) {
488                                    newContent = StringUtil.replace(
489                                            newContent, "com.liferay.util.LocalizationUtil",
490                                            "com.liferay.portal.kernel.util.LocalizationUtil");
491                            }
492    
493                            newContent = stripImports(newContent, packagePath, className);
494    
495                            if (newContent.indexOf(";\n/**") != -1) {
496                                    newContent = StringUtil.replace(
497                                            newContent,
498                                            ";\n/**",
499                                            ";\n\n/**");
500                            }
501    
502                            if (newContent.indexOf("\t/*\n\t *") != -1) {
503                                    newContent = StringUtil.replace(
504                                            newContent,
505                                            "\t/*\n\t *",
506                                            "\t/**\n\t *");
507                            }
508    
509                            if (newContent.indexOf("if(") != -1) {
510                                    newContent = StringUtil.replace(
511                                            newContent,
512                                            "if(",
513                                            "if (");
514                            }
515    
516                            if (newContent.indexOf("while(") != -1) {
517                                    newContent = StringUtil.replace(
518                                            newContent,
519                                            "while(",
520                                            "while (");
521                            }
522    
523                            if (newContent.indexOf("\n\n\n") != -1) {
524                                    newContent = StringUtil.replace(
525                                            newContent,
526                                            "\n\n\n",
527                                            "\n\n");
528                            }
529    
530                            if (newContent.indexOf("*/\npackage ") != -1) {
531                                    _sourceFormatterHelper.printError(
532                                            fileName, "package: " + fileName);
533                            }
534    
535                            if (newContent.indexOf("    ") != -1) {
536                                    if (!fileName.endsWith("StringPool.java")) {
537                                            _sourceFormatterHelper.printError(
538                                                    fileName, "tab: " + fileName);
539                                    }
540                            }
541    
542                            if (newContent.indexOf("  {") != -1) {
543                                    _sourceFormatterHelper.printError(fileName, "{:" + fileName);
544                            }
545    
546                            if (!newContent.endsWith("\n\n}") &&
547                                    !newContent.endsWith("{\n}")) {
548    
549                                    _sourceFormatterHelper.printError(fileName, "}: " + fileName);
550                            }
551    
552                            if (portalJavaFiles && className.endsWith("ServiceImpl") &&
553                                    (newContent.indexOf("ServiceUtil.") != -1)) {
554    
555                                    _sourceFormatterHelper.printError(
556                                            fileName, "ServiceUtil: " + fileName);
557                            }
558    
559                            if ((newContent != null) && !content.equals(newContent)) {
560                                    _fileUtil.write(file, newContent);
561    
562                                    _sourceFormatterHelper.printError(fileName, file);
563                            }
564                    }
565            }
566    
567            private static String _formatJavaContent(
568                            String fileName, String className, String content)
569                    throws IOException {
570    
571                    boolean longLogFactoryUtil = false;
572    
573                    StringBuilder sb = new StringBuilder();
574    
575                    UnsyncBufferedReader unsyncBufferedReader = new UnsyncBufferedReader(
576                            new UnsyncStringReader(content));
577    
578                    int lineCount = 0;
579    
580                    String line = null;
581    
582                    while ((line = unsyncBufferedReader.readLine()) != null) {
583                            lineCount++;
584    
585                            if (line.trim().length() == 0) {
586                                    line = StringPool.BLANK;
587                            }
588    
589                            line = StringUtil.trimTrailing(line);
590    
591                            line = StringUtil.replace(
592                                    line,
593                                    new String[] {
594                                            "* Copyright (c) 2000-2009 Liferay, Inc."
595                                    },
596                                    new String[] {
597                                            "* Copyright (c) 2000-2010 Liferay, Inc."
598                                    });
599    
600                            sb.append(line);
601                            sb.append("\n");
602    
603                            StringBuilder lineSB = new StringBuilder();
604    
605                            int spacesPerTab = 4;
606    
607                            for (char c : line.toCharArray()) {
608                                    if (c == CharPool.TAB) {
609                                            for (int i = 0; i < spacesPerTab; i++) {
610                                                    lineSB.append(CharPool.SPACE);
611                                            }
612    
613                                            spacesPerTab = 4;
614                                    }
615                                    else {
616                                            lineSB.append(c);
617    
618                                            spacesPerTab--;
619    
620                                            if (spacesPerTab <= 0) {
621                                                    spacesPerTab = 4;
622                                            }
623                                    }
624                            }
625    
626                            line = lineSB.toString();
627    
628                            if (line.endsWith("private static Log _log =")) {
629                                    longLogFactoryUtil = true;
630                            }
631    
632                            String excluded = _exclusions.getProperty(
633                                    StringUtil.replace(fileName, "\\", "/") + StringPool.AT +
634                                            lineCount);
635    
636                            if (excluded == null) {
637                                    excluded = _exclusions.getProperty(
638                                            StringUtil.replace(fileName, "\\", "/"));
639                            }
640    
641                            if ((excluded == null) && (line.length() > 80) &&
642                                    !line.startsWith("import ") && !line.startsWith("package ") &&
643                                    !line.matches("\\s*\\*.*")) {
644    
645                                    if (fileName.endsWith("Table.java") &&
646                                            line.contains("String TABLE_SQL_CREATE = ")) {
647                                    }
648                                    else {
649                                            _sourceFormatterHelper.printError(
650                                                    fileName, "> 80: " + fileName + " " + lineCount);
651                                    }
652                            }
653                    }
654    
655                    unsyncBufferedReader.close();
656    
657                    String newContent = sb.toString();
658    
659                    if (newContent.endsWith("\n")) {
660                            newContent = newContent.substring(0, newContent.length() -1);
661                    }
662    
663                    if (longLogFactoryUtil) {
664                            newContent = StringUtil.replace(
665                                    newContent,
666                                    "private static Log _log =\n\t\tLogFactoryUtil.getLog(",
667                                    "private static Log _log = LogFactoryUtil.getLog(\n\t\t");
668                    }
669    
670                    return newContent;
671            }
672    
673            private static void _formatJSP() throws IOException {
674                    String basedir = "./";
675    
676                    String copyright = _getCopyright();
677                    String oldCopyright = _getOldCopyright();
678    
679                    List<String> list = new ArrayList<String>();
680    
681                    DirectoryScanner directoryScanner = new DirectoryScanner();
682    
683                    directoryScanner.setBasedir(basedir);
684                    directoryScanner.setExcludes(
685                            new String[] {
686                                    "**\\portal\\aui\\**", "**\\bin\\**", "**\\null.jsp",
687                                    "**\\tmp\\**", "**\\tools\\**"
688                            });
689                    directoryScanner.setIncludes(
690                            new String[] {"**\\*.jsp", "**\\*.jspf", "**\\*.vm"});
691    
692                    list.addAll(_sourceFormatterHelper.scanForFiles(directoryScanner));
693    
694                    String[] files = list.toArray(new String[list.size()]);
695    
696                    for (int i = 0; i < files.length; i++) {
697                            File file = new File(basedir + files[i]);
698    
699                            String content = _fileUtil.read(file);
700                            String newContent = _formatJSPContent(files[i], content);
701    
702                            newContent = StringUtil.replace(
703                                    newContent,
704                                    new String[] {
705                                            "<br/>", "\"/>", "\" >", "@page import", "\"%>", ")%>",
706                                            "javascript: "
707                                    },
708                                    new String[] {
709                                            "<br />", "\" />", "\">", "@ page import", "\" %>", ") %>",
710                                            "javascript:"
711                                    });
712    
713                            newContent = StringUtil.replace(
714                                    newContent,
715                                    new String[] {
716                                            "* Copyright (c) 2000-2009 Liferay, Inc."
717                                    },
718                                    new String[] {
719                                            "* Copyright (c) 2000-2010 Liferay, Inc."
720                                    });
721    
722                            if (files[i].endsWith(".jsp") || files[i].endsWith(".jspf")) {
723                                    if ((oldCopyright != null) &&
724                                            newContent.contains(oldCopyright)) {
725    
726                                            newContent = StringUtil.replace(
727                                                    newContent, oldCopyright, copyright);
728    
729                                            _sourceFormatterHelper.printError(
730                                                    files[i], "old (c): " + files[i]);
731                                    }
732    
733                                    if (newContent.indexOf(copyright) == -1) {
734                                            _sourceFormatterHelper.printError(
735                                                    files[i], "(c): " + files[i]);
736                                    }
737                            }
738    
739                            if (newContent.indexOf("alert('<%= LanguageUtil.") != -1) {
740                                    newContent = StringUtil.replace(newContent,
741                                            "alert('<%= LanguageUtil.",
742                                            "alert('<%= UnicodeLanguageUtil.");
743                            }
744    
745                            if (newContent.indexOf("alert(\"<%= LanguageUtil.") != -1) {
746                                    newContent = StringUtil.replace(newContent,
747                                            "alert(\"<%= LanguageUtil.",
748                                            "alert(\"<%= UnicodeLanguageUtil.");
749                            }
750    
751                            if (newContent.indexOf("confirm('<%= LanguageUtil.") != -1) {
752                                    newContent = StringUtil.replace(newContent,
753                                            "confirm('<%= LanguageUtil.",
754                                            "confirm('<%= UnicodeLanguageUtil.");
755                            }
756    
757                            if (newContent.indexOf("confirm(\"<%= LanguageUtil.") != -1) {
758                                    newContent = StringUtil.replace(newContent,
759                                            "confirm(\"<%= LanguageUtil.",
760                                            "confirm(\"<%= UnicodeLanguageUtil.");
761                            }
762    
763                            if (newContent.indexOf("    ") != -1) {
764                                    if (!files[i].endsWith("template.vm")) {
765                                            _sourceFormatterHelper.printError(
766                                                    files[i], "tab: " + files[i]);
767                                    }
768                            }
769    
770                            _checkXSS(files[i], content);
771    
772                            if ((newContent != null) && !content.equals(newContent)) {
773                                    _fileUtil.write(file, newContent);
774                                    _sourceFormatterHelper.printError(files[i], file);
775                            }
776                    }
777    
778            }
779    
780            private static String _formatJSPContent(String fileName, String content)
781                    throws IOException {
782    
783                    StringBuilder sb = new StringBuilder();
784    
785                    UnsyncBufferedReader unsyncBufferedReader = new UnsyncBufferedReader(
786                            new UnsyncStringReader(content));
787    
788                    String line = null;
789    
790                    while ((line = unsyncBufferedReader.readLine()) != null) {
791                            if (line.trim().length() == 0) {
792                                    line = StringPool.BLANK;
793                            }
794    
795                            line = StringUtil.trimTrailing(line);
796    
797                            sb.append(line);
798                            sb.append("\n");
799                    }
800    
801                    unsyncBufferedReader.close();
802    
803                    content = sb.toString();
804    
805                    if (content.endsWith("\n")) {
806                            content = content.substring(0, content.length() -1);
807                    }
808    
809                    content = _formatTaglibQuotes(fileName, content, StringPool.QUOTE);
810                    content = _formatTaglibQuotes(fileName, content, StringPool.APOSTROPHE);
811    
812                    return content;
813            }
814    
815            private static String _formatTaglibQuotes(
816                    String fileName, String content, String quoteType) {
817    
818                    String quoteFix = StringPool.APOSTROPHE;
819    
820                if (quoteFix.equals(quoteType)) {
821                    quoteFix = StringPool.QUOTE;
822                }
823    
824                Pattern pattern = Pattern.compile(_getTaglibRegex(quoteType));
825    
826                    Matcher matcher = pattern.matcher(content);
827    
828                    while (matcher.find()) {
829                            int x = content.indexOf(quoteType + "<%=", matcher.start());
830                            int y = content.indexOf("%>" + quoteType, x);
831    
832                            while ((x != -1) && (y != -1)) {
833                                    String result = content.substring(x + 1, y + 2);
834    
835                                    if (result.indexOf(quoteType) != -1) {
836                                            int lineCount = 1;
837    
838                                            char contentCharArray[] = content.toCharArray();
839    
840                                            for (int i = 0; i < x; i++) {
841                                                    if (contentCharArray[i] == CharPool.NEW_LINE) {
842                                                            lineCount++;
843                                                    }
844                                            }
845    
846                                            if (result.indexOf(quoteFix) == -1) {
847                                                    StringBuilder sb = new StringBuilder();
848    
849                                                    sb.append(content.substring(0, x));
850                                                    sb.append(quoteFix);
851                                                    sb.append(result);
852                                                    sb.append(quoteFix);
853                                                    sb.append(content.substring(y + 3, content.length()));
854    
855                                                    content = sb.toString();
856                                            }
857                                            else {
858                                                    _sourceFormatterHelper.printError(
859                                                            fileName, "taglib: " + fileName + " " + lineCount);
860                                            }
861                                    }
862    
863                                    x = content.indexOf(quoteType + "<%=", y);
864    
865                                    if (x > matcher.end()) {
866                                            break;
867                                    }
868    
869                                    y = content.indexOf("%>" + quoteType, x);
870                            }
871                    }
872    
873                    return content;
874            }
875    
876            private static void _formatWebXML() throws IOException {
877                    String basedir = "./";
878    
879                    if (_fileUtil.exists(basedir + "portal-impl")) {
880                            Properties properties = new Properties();
881    
882                            String propertiesContent = _fileUtil.read(
883                                    basedir + "portal-impl/src/portal.properties");
884    
885                            PropertiesUtil.load(properties, propertiesContent);
886    
887                            String[] locales = StringUtil.split(
888                                    properties.getProperty(PropsKeys.LOCALES));
889    
890                            Arrays.sort(locales);
891    
892                            Set<String> urlPatterns = new TreeSet<String>();
893    
894                            for (String locale : locales) {
895                                    int pos = locale.indexOf(StringPool.UNDERLINE);
896    
897                                    String languageCode = locale.substring(0, pos);
898    
899                                    urlPatterns.add(languageCode);
900                                    urlPatterns.add(locale);
901                            }
902    
903                            StringBuilder sb = new StringBuilder();
904    
905                            for (String urlPattern : urlPatterns) {
906                                    sb.append("\t<servlet-mapping>\n");
907                                    sb.append("\t\t<servlet-name>I18n Servlet</servlet-name>\n");
908                                    sb.append(
909                                            "\t\t<url-pattern>/" + urlPattern +"/*</url-pattern>\n");
910                                    sb.append("\t</servlet-mapping>\n");
911                            }
912    
913                            File file = new File(
914                                    basedir + "portal-web/docroot/WEB-INF/web.xml");
915    
916                            String content = _fileUtil.read(file);
917    
918                            int x = content.indexOf("<servlet-mapping>");
919    
920                            x = content.indexOf("<servlet-name>I18n Servlet</servlet-name>", x);
921    
922                            x = content.lastIndexOf("<servlet-mapping>", x) - 1;
923    
924                            int y = content.lastIndexOf(
925                                    "<servlet-name>I18n Servlet</servlet-name>");
926    
927                            y = content.indexOf("</servlet-mapping>", y) + 19;
928    
929                            String newContent =
930                                    content.substring(0, x) + sb.toString() + content.substring(y);
931    
932                            x = newContent.indexOf("<security-constraint>");
933    
934                            x = newContent.indexOf(
935                                    "<web-resource-name>/c/portal/protected</web-resource-name>",
936                                    x);
937    
938                            x = newContent.indexOf("<url-pattern>", x) - 3;
939    
940                            y = newContent.indexOf("<http-method>", x);
941    
942                            y = newContent.lastIndexOf("</url-pattern>", y) + 15;
943    
944                            sb = new StringBuilder();
945    
946                            sb.append(
947                                    "\t\t\t<url-pattern>/c/portal/protected</url-pattern>\n");
948    
949                            for (String urlPattern : urlPatterns) {
950                                    sb.append(
951                                            "\t\t\t<url-pattern>/" + urlPattern +
952                                                    "/c/portal/protected</url-pattern>\n");
953                            }
954    
955                            newContent =
956                                    newContent.substring(0, x) + sb.toString() +
957                                            newContent.substring(y);
958    
959                            if ((newContent != null) && !content.equals(newContent)) {
960                                    _fileUtil.write(file, newContent);
961    
962                                    System.out.println(file);
963                            }
964                    }
965                    else {
966                            String webXML = ContentUtil.get(
967                                    "com/liferay/portal/deploy/dependencies/web.xml");
968    
969                            DirectoryScanner directoryScanner = new DirectoryScanner();
970    
971                            directoryScanner.setBasedir(basedir);
972                            directoryScanner.setIncludes(new String[] {"**\\web.xml"});
973    
974                            List<String> fileNames = _sourceFormatterHelper.scanForFiles(
975                                    directoryScanner);
976    
977                            for (String fileName : fileNames) {
978                                    String content = _fileUtil.read(basedir + fileName);
979    
980                                    if (content.equals(webXML)) {
981                                            _sourceFormatterHelper.printError(fileName, fileName);
982                                    }
983                            }
984                    }
985            }
986    
987            private static String _getCopyright() throws IOException {
988                    try {
989                            return _fileUtil.read("copyright.txt");
990                    }
991                    catch (Exception e1) {
992                            try {
993                                    return _fileUtil.read("../copyright.txt");
994                            }
995                            catch (Exception e2) {
996                                    return _fileUtil.read("../../copyright.txt");
997                            }
998                    }
999            }
1000    
1001            private static String _getOldCopyright() {
1002                    try {
1003                            return _fileUtil.read("old-copyright.txt");
1004                    }
1005                    catch (Exception e1) {
1006                            try {
1007                                    return _fileUtil.read("../old-copyright.txt");
1008                            }
1009                            catch (Exception e2) {
1010                                    try {
1011                                            return _fileUtil.read("../../old-copyright.txt");
1012                                    }
1013                                    catch (Exception e3) {
1014                                            return null;
1015                                    }
1016                            }
1017                    }
1018            }
1019    
1020            private static Collection<String> _getPluginJavaFiles() {
1021                    String basedir = "./";
1022    
1023                    Collection<String> fileNames = new TreeSet<String>();
1024    
1025                    DirectoryScanner directoryScanner = new DirectoryScanner();
1026    
1027                    directoryScanner.setBasedir(basedir);
1028                    directoryScanner.setExcludes(
1029                            new String[] {
1030                                    "**\\bin\\**", "**\\model\\*Clp.java",
1031                                    "**\\model\\impl\\*ModelImpl.java",
1032                                    "**\\service\\**\\model\\*Model.java",
1033                                    "**\\service\\**\\model\\*Soap.java",
1034                                    "**\\service\\**\\model\\*Wrapper.java",
1035                                    "**\\service\\**\\service\\*Service.java",
1036                                    "**\\service\\**\\service\\*ServiceClp.java",
1037                                    "**\\service\\**\\service\\*ServiceFactory.java",
1038                                    "**\\service\\**\\service\\*ServiceUtil.java",
1039                                    "**\\service\\**\\service\\*ServiceWrapper.java",
1040                                    "**\\service\\**\\service\\ClpSerializer.java",
1041                                    "**\\service\\**\\service\\messaging\\*ClpMessageListener.java",
1042                                    "**\\service\\**\\service\\persistence\\*Finder.java",
1043                                    "**\\service\\**\\service\\persistence\\*Persistence.java",
1044                                    "**\\service\\**\\service\\persistence\\*Util.java",
1045                                    "**\\service\\base\\*ServiceBaseImpl.java",
1046                                    "**\\service\\http\\*JSONSerializer.java",
1047                                    "**\\service\\http\\*ServiceHttp.java",
1048                                    "**\\service\\http\\*ServiceJSON.java",
1049                                    "**\\service\\http\\*ServiceSoap.java",
1050                                    "**\\service\\persistence\\*PersistenceImpl.java",
1051                                    "**\\tmp\\**"
1052                            });
1053                    directoryScanner.setIncludes(new String[] {"**\\*.java"});
1054    
1055                    fileNames.addAll(_sourceFormatterHelper.scanForFiles(directoryScanner));
1056    
1057                    return fileNames;
1058            }
1059    
1060            private static Collection<String> _getPortalJavaFiles() {
1061                    String basedir = "./";
1062    
1063                    Collection<String> fileNames = new TreeSet<String>();
1064    
1065                    DirectoryScanner directoryScanner = new DirectoryScanner();
1066    
1067                    directoryScanner.setBasedir(basedir);
1068                    directoryScanner.setExcludes(
1069                            new String[] {
1070                                    "**\\InstanceWrapperBuilder.java", "**\\*_IW.java",
1071                                    "**\\PropsKeys.java", "**\\PropsValues.java",
1072                                    "**\\ServiceBuilder.java", "**\\SourceFormatter.java",
1073                                    "**\\UserAttributes.java", "**\\WebKeys.java",
1074                                    "**\\bin\\**", "**\\classes\\*", "**\\counter\\service\\**",
1075                                    "**\\jsp\\*", "**\\model\\impl\\*ModelImpl.java",
1076                                    "**\\portal\\service\\**", "**\\portal-client\\**",
1077                                    "**\\portal-service\\**\\model\\*Model.java",
1078                                    "**\\portal-service\\**\\model\\*Soap.java",
1079                                    "**\\portal-service\\**\\model\\*Wrapper.java",
1080                                    "**\\portal-web\\classes\\**\\*.java",
1081                                    "**\\portal-web\\test\\**\\*Test.java",
1082                                    "**\\portlet\\**\\service\\**", "**\\tmp\\**", "**\\tools\\**"
1083                            });
1084                    directoryScanner.setIncludes(new String[] {"**\\*.java"});
1085    
1086                    fileNames.addAll(_sourceFormatterHelper.scanForFiles(directoryScanner));
1087    
1088                    directoryScanner = new DirectoryScanner();
1089    
1090                    directoryScanner.setBasedir(basedir);
1091                    directoryScanner.setExcludes(
1092                            new String[] {
1093                                    "**\\bin\\**", "**\\portal-client\\**",
1094                                    "**\\tools\\ext_tmpl\\**", "**\\*_IW.java",
1095                                    "**\\test\\**\\*PersistenceTest.java"
1096                            });
1097                    directoryScanner.setIncludes(
1098                            new String[] {
1099                                    "**\\com\\liferay\\portal\\service\\ServiceContext*.java",
1100                                    "**\\model\\BaseModel.java",
1101                                    "**\\model\\impl\\BaseModelImpl.java",
1102                                    "**\\service\\base\\PrincipalBean.java",
1103                                    "**\\service\\http\\*HttpTest.java",
1104                                    "**\\service\\http\\*SoapTest.java",
1105                                    "**\\service\\http\\TunnelUtil.java",
1106                                    "**\\service\\impl\\*.java", "**\\service\\jms\\*.java",
1107                                    "**\\service\\permission\\*.java",
1108                                    "**\\service\\persistence\\BasePersistence.java",
1109                                    "**\\service\\persistence\\BatchSession*.java",
1110                                    "**\\service\\persistence\\*FinderImpl.java",
1111                                    "**\\service\\persistence\\*Query.java",
1112                                    "**\\service\\persistence\\impl\\BasePersistenceImpl.java",
1113                                    "**\\portal-impl\\test\\**\\*.java",
1114                                    "**\\portal-service\\**\\liferay\\documentlibrary\\**.java",
1115                                    "**\\portal-service\\**\\liferay\\lock\\**.java",
1116                                    "**\\portal-service\\**\\liferay\\mail\\**.java",
1117                                    "**\\util-bridges\\**\\*.java"
1118                            });
1119    
1120                    fileNames.addAll(_sourceFormatterHelper.scanForFiles(directoryScanner));
1121    
1122                    return fileNames;
1123            }
1124    
1125            private static String _getTaglibRegex(String quoteType) {
1126                    StringBuilder sb = new StringBuilder();
1127    
1128                    sb.append("<(");
1129    
1130                    for (int i = 0; i < _TAG_LIBRARIES.length; i++) {
1131                            sb.append(_TAG_LIBRARIES[i]);
1132                            sb.append(StringPool.PIPE);
1133                    }
1134    
1135                    sb.deleteCharAt(sb.length() - 1);
1136                    sb.append("):([^>]|%>)*");
1137                    sb.append(quoteType);
1138                    sb.append("<%=.*");
1139                    sb.append(quoteType);
1140                    sb.append(".*%>");
1141                    sb.append(quoteType);
1142                    sb.append("([^>]|%>)*>");
1143    
1144                    return sb.toString();
1145            }
1146    
1147            private static void _readExclusions() throws IOException {
1148                    _exclusions = new Properties();
1149    
1150                    ClassLoader classLoader = SourceFormatter.class.getClassLoader();
1151    
1152                    String sourceFormatterExclusions = System.getProperty(
1153                            "source-formatter-exclusions",
1154                            "com/liferay/portal/tools/dependencies/" +
1155                                    "source_formatter_exclusions.properties");
1156    
1157                    URL url = classLoader.getResource(sourceFormatterExclusions);
1158    
1159                    if (url == null) {
1160                            return;
1161                    }
1162    
1163                    InputStream is = url.openStream();
1164    
1165                    _exclusions.load(is);
1166    
1167                    is.close();
1168            }
1169    
1170            private static final String[] _TAG_LIBRARIES = new String[] {
1171                    "aui", "c", "html", "jsp", "liferay-portlet", "liferay-security",
1172                    "liferay-theme", "liferay-ui", "liferay-util", "portlet", "struts",
1173                    "tiles"
1174            };
1175    
1176            private static Properties _exclusions;
1177            private static FileImpl _fileUtil = FileImpl.getInstance();
1178            private static SAXReaderImpl _saxReaderUtil = SAXReaderImpl.getInstance();
1179            private static SourceFormatterHelper _sourceFormatterHelper;
1180            private static Pattern _xssPattern = Pattern.compile(
1181                    "String\\s+([^\\s]+)\\s*=\\s*(Bean)?ParamUtil\\.getString\\(");
1182    
1183    }