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