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