001    /**
002     * Copyright (c) 2000-2013 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.sourceformatter.JavaTerm;
020    import com.liferay.portal.kernel.util.ArrayUtil;
021    import com.liferay.portal.kernel.util.CharPool;
022    import com.liferay.portal.kernel.util.ClassUtil;
023    import com.liferay.portal.kernel.util.GetterUtil;
024    import com.liferay.portal.kernel.util.ListUtil;
025    import com.liferay.portal.kernel.util.PropertiesUtil;
026    import com.liferay.portal.kernel.util.PropsKeys;
027    import com.liferay.portal.kernel.util.StringBundler;
028    import com.liferay.portal.kernel.util.StringPool;
029    import com.liferay.portal.kernel.util.StringUtil;
030    import com.liferay.portal.kernel.util.TextFormatter;
031    import com.liferay.portal.kernel.util.Tuple;
032    import com.liferay.portal.kernel.util.Validator;
033    import com.liferay.portal.kernel.xml.Document;
034    import com.liferay.portal.kernel.xml.DocumentException;
035    import com.liferay.portal.kernel.xml.Element;
036    import com.liferay.portal.tools.comparator.JavaTermComparator;
037    import com.liferay.portal.util.FileImpl;
038    import com.liferay.portal.xml.SAXReaderImpl;
039    import com.liferay.util.ContentUtil;
040    
041    import java.io.File;
042    import java.io.FileInputStream;
043    import java.io.FileNotFoundException;
044    import java.io.IOException;
045    import java.io.InputStream;
046    
047    import java.net.URL;
048    
049    import java.util.ArrayList;
050    import java.util.Arrays;
051    import java.util.Collection;
052    import java.util.Collections;
053    import java.util.HashMap;
054    import java.util.HashSet;
055    import java.util.Iterator;
056    import java.util.List;
057    import java.util.Map;
058    import java.util.Properties;
059    import java.util.Set;
060    import java.util.TreeSet;
061    import java.util.regex.Matcher;
062    import java.util.regex.Pattern;
063    
064    import org.apache.tools.ant.DirectoryScanner;
065    
066    /**
067     * @author Brian Wing Shun Chan
068     * @author Igor Spasic
069     * @author Wesley Gong
070     * @author Hugo Huijser
071     */
072    public class SourceFormatter {
073    
074            public static final int _TYPE_CLASS_PRIVATE = 24;
075    
076            public static final int _TYPE_CLASS_PRIVATE_STATIC = 23;
077    
078            public static final int _TYPE_CLASS_PROTECTED = 16;
079    
080            public static final int _TYPE_CLASS_PROTECTED_STATIC = 15;
081    
082            public static final int _TYPE_CLASS_PUBLIC = 8;
083    
084            public static final int _TYPE_CLASS_PUBLIC_STATIC = 7;
085    
086            public static final int[] _TYPE_CONSTRUCTOR = {
087                    SourceFormatter._TYPE_CONSTRUCTOR_PRIVATE,
088                    SourceFormatter._TYPE_CONSTRUCTOR_PROTECTED,
089                    SourceFormatter._TYPE_CONSTRUCTOR_PUBLIC
090            };
091    
092            public static final int _TYPE_CONSTRUCTOR_PRIVATE = 18;
093    
094            public static final int _TYPE_CONSTRUCTOR_PROTECTED = 10;
095    
096            public static final int _TYPE_CONSTRUCTOR_PUBLIC = 4;
097    
098            public static final int[] _TYPE_METHOD = {
099                    SourceFormatter._TYPE_METHOD_PRIVATE,
100                    SourceFormatter._TYPE_METHOD_PRIVATE_STATIC,
101                    SourceFormatter._TYPE_METHOD_PROTECTED,
102                    SourceFormatter._TYPE_METHOD_PROTECTED_STATIC,
103                    SourceFormatter._TYPE_METHOD_PUBLIC,
104                    SourceFormatter._TYPE_METHOD_PUBLIC_STATIC
105            };
106    
107            public static final int _TYPE_METHOD_PRIVATE = 19;
108    
109            public static final int _TYPE_METHOD_PRIVATE_STATIC = 17;
110    
111            public static final int _TYPE_METHOD_PROTECTED = 11;
112    
113            public static final int _TYPE_METHOD_PROTECTED_STATIC = 9;
114    
115            public static final int _TYPE_METHOD_PUBLIC = 5;
116    
117            public static final int _TYPE_METHOD_PUBLIC_STATIC = 3;
118    
119            public static final int[] _TYPE_VARIABLE_NOT_FINAL = {
120                    SourceFormatter._TYPE_VARIABLE_PRIVATE,
121                    SourceFormatter._TYPE_VARIABLE_PRIVATE_STATIC,
122                    SourceFormatter._TYPE_VARIABLE_PROTECTED,
123                    SourceFormatter._TYPE_VARIABLE_PROTECTED_STATIC,
124                    SourceFormatter._TYPE_VARIABLE_PUBLIC,
125                    SourceFormatter._TYPE_VARIABLE_PUBLIC_STATIC
126            };
127    
128            public static final int[] _TYPE_VARIABLE_NOT_STATIC = {
129                    SourceFormatter._TYPE_VARIABLE_PRIVATE,
130                    SourceFormatter._TYPE_VARIABLE_PROTECTED,
131                    SourceFormatter._TYPE_VARIABLE_PUBLIC
132            };
133    
134            public static final int _TYPE_VARIABLE_PRIVATE = 22;
135    
136            public static final int _TYPE_VARIABLE_PRIVATE_STATIC = 21;
137    
138            public static final int _TYPE_VARIABLE_PRIVATE_STATIC_FINAL = 20;
139    
140            public static final int _TYPE_VARIABLE_PROTECTED = 14;
141    
142            public static final int _TYPE_VARIABLE_PROTECTED_STATIC = 13;
143    
144            public static final int _TYPE_VARIABLE_PROTECTED_STATIC_FINAL = 12;
145    
146            public static final int _TYPE_VARIABLE_PUBLIC = 6;
147    
148            public static final int _TYPE_VARIABLE_PUBLIC_STATIC = 2;
149    
150            public static final int _TYPE_VARIABLE_PUBLIC_STATIC_FINAL = 1;
151    
152            public static void main(String[] args) {
153                    try {
154                            new SourceFormatter(false, false);
155                    }
156                    catch (Exception e) {
157                            e.printStackTrace();
158                    }
159            }
160    
161            public static String stripJavaImports(
162                            String content, String packageDir, String className)
163                    throws IOException {
164    
165                    Matcher matcher = _javaImportPattern.matcher(content);
166    
167                    if (!matcher.find()) {
168                            return content;
169                    }
170    
171                    String imports = matcher.group();
172    
173                    Set<String> classes = ClassUtil.getClasses(
174                            new UnsyncStringReader(content), className);
175    
176                    StringBundler sb = new StringBundler();
177    
178                    UnsyncBufferedReader unsyncBufferedReader = new UnsyncBufferedReader(
179                            new UnsyncStringReader(imports));
180    
181                    String line = null;
182    
183                    while ((line = unsyncBufferedReader.readLine()) != null) {
184                            if (!line.contains("import ")) {
185                                    continue;
186                            }
187    
188                            int importX = line.indexOf(" ");
189                            int importY = line.lastIndexOf(".");
190    
191                            String importPackage = line.substring(importX + 1, importY);
192    
193                            if (importPackage.equals(packageDir) ||
194                                    importPackage.equals("java.lang")) {
195    
196                                    continue;
197                            }
198    
199                            String importClass = line.substring(importY + 1, line.length() - 1);
200    
201                            if (importClass.equals("*") || classes.contains(importClass)) {
202                                    sb.append(line);
203                                    sb.append("\n");
204                            }
205                    }
206    
207                    imports = _formatImports(sb.toString(), 7);
208    
209                    content =
210                            content.substring(0, matcher.start()) + imports +
211                                    content.substring(matcher.end());
212    
213                    // Ensure a blank line exists between the package and the first import
214    
215                    content = content.replaceFirst(
216                            "(?m)^[ \t]*(package .*;)\\s*^[ \t]*import", "$1\n\nimport");
217    
218                    // Ensure a blank line exists between the last import (or package if
219                    // there are no imports) and the class comment
220    
221                    content = content.replaceFirst(
222                            "(?m)^[ \t]*((?:package|import) .*;)\\s*^[ \t]*/\\*\\*",
223                            "$1\n\n/**");
224    
225                    return content;
226            }
227    
228            public SourceFormatter(boolean useProperties, boolean throwException)
229                    throws Exception {
230    
231                    _excludes = StringUtil.split(
232                            GetterUtil.getString(
233                                    System.getProperty("source.formatter.excludes")));
234    
235                    _portalSource = _isPortalSource();
236    
237                    _throwException = throwException;
238    
239                    _sourceFormatterHelper = new SourceFormatterHelper(useProperties);
240    
241                    _sourceFormatterHelper.init();
242    
243                    Thread thread1 = new Thread () {
244    
245                            @Override
246                            public void run() {
247                                    try {
248                                            _formatJSP();
249                                            _formatAntXML();
250                                            _formatDDLStructuresXML();
251                                            _formatFriendlyURLRoutesXML();
252                                            _formatFTL();
253                                            _formatJS();
254                                            _formatPortalProperties();
255                                            _formatPortletXML();
256                                            _formatServiceXML();
257                                            _formatSH();
258                                            _formatSQL();
259                                            _formatStrutsConfigXML();
260                                            _formatTilesDefsXML();
261                                            _formatTLD();
262                                            _formatWebXML();
263                                    }
264                                    catch (Exception e) {
265                                            e.printStackTrace();
266                                    }
267                            }
268    
269                    };
270    
271                    Thread thread2 = new Thread () {
272    
273                            @Override
274                            public void run() {
275                                    try {
276                                            _formatJava();
277                                    }
278                                    catch (Exception e) {
279                                            e.printStackTrace();
280                                    }
281                            }
282    
283                    };
284    
285                    thread1.start();
286                    thread2.start();
287    
288                    thread1.join();
289                    thread2.join();
290    
291                    _sourceFormatterHelper.close();
292    
293                    if (_throwException && !_errorMessages.isEmpty()) {
294                            throw new Exception(StringUtil.merge(_errorMessages, "\n"));
295                    }
296            }
297    
298            private static void _addJSPIncludeFileNames(
299                    String fileName, Set<String> includeFileNames) {
300    
301                    String content = _jspContents.get(fileName);
302    
303                    if (Validator.isNull(content)) {
304                            return;
305                    }
306    
307                    for (int x = 0;;) {
308                            x = content.indexOf("<%@ include file=", x);
309    
310                            if (x == -1) {
311                                    break;
312                            }
313    
314                            x = content.indexOf(StringPool.QUOTE, x);
315    
316                            if (x == -1) {
317                                    break;
318                            }
319    
320                            int y = content.indexOf(StringPool.QUOTE, x + 1);
321    
322                            if (y == -1) {
323                                    break;
324                            }
325    
326                            String includeFileName = content.substring(x + 1, y);
327    
328                            Matcher matcher = _jspIncludeFilePattern.matcher(includeFileName);
329    
330                            if (!matcher.find()) {
331                                    throw new RuntimeException(
332                                            "Invalid include " + includeFileName);
333                            }
334    
335                            String docrootPath = fileName.substring(
336                                    0, fileName.indexOf("docroot") + 7);
337    
338                            includeFileName = docrootPath + includeFileName;
339    
340                            if ((includeFileName.endsWith("jsp") ||
341                                     includeFileName.endsWith("jspf")) &&
342                                    !includeFileName.endsWith("html/portlet/init.jsp") &&
343                                    !includeFileName.endsWith("html/taglib/init.jsp") &&
344                                    !includeFileNames.contains(includeFileName)) {
345    
346                                    includeFileNames.add(includeFileName);
347                            }
348    
349                            x = y;
350                    }
351            }
352    
353            private static void _addJSPReferenceFileNames(
354                    String fileName, Set<String> includeFileNames) {
355    
356                    for (Map.Entry<String, String> entry : _jspContents.entrySet()) {
357                            String referenceFileName = entry.getKey();
358                            String content = entry.getValue();
359    
360                            if (content.contains("<%@ include file=\"" + fileName) &&
361                                    !includeFileNames.contains(referenceFileName)) {
362    
363                                    includeFileNames.add(referenceFileName);
364                            }
365                    }
366            }
367    
368            private static void _addJSPUnusedImports(
369                    String fileName, List<String> importLines,
370                    List<String> unneededImports) {
371    
372                    for (String importLine : importLines) {
373                            Set<String> includeFileNames = new HashSet<String>();
374    
375                            includeFileNames.add(fileName);
376    
377                            Set<String> checkedFileNames = new HashSet<String>();
378    
379                            int x = importLine.indexOf(StringPool.QUOTE);
380                            int y = importLine.indexOf(StringPool.QUOTE, x + 1);
381    
382                            if ((x == -1) || (y == -1)) {
383                                    continue;
384                            }
385    
386                            String className = importLine.substring(x + 1, y);
387    
388                            className = className.substring(
389                                    className.lastIndexOf(StringPool.PERIOD) + 1);
390    
391                            if (!_isJSPImportRequired(
392                                            fileName, className, includeFileNames, checkedFileNames)) {
393    
394                                    unneededImports.add(importLine);
395                            }
396                    }
397            }
398    
399            private static List<String> _addParameterTypes(
400                    String line, List<String> parameterTypes) {
401    
402                    int x = line.indexOf(StringPool.OPEN_PARENTHESIS);
403    
404                    if (x != -1) {
405                            line = line.substring(x + 1);
406    
407                            if (Validator.isNull(line) ||
408                                    line.startsWith(StringPool.CLOSE_PARENTHESIS)) {
409    
410                                    return parameterTypes;
411                            }
412                    }
413    
414                    for (x = 0;;) {
415                            x = line.indexOf(StringPool.SPACE);
416    
417                            if (x == -1) {
418                                    return parameterTypes;
419                            }
420    
421                            String parameterType = line.substring(0, x);
422    
423                            if (parameterType.equals("throws")) {
424                                    return parameterTypes;
425                            }
426    
427                            parameterTypes.add(parameterType);
428    
429                            int y = line.indexOf(StringPool.COMMA);
430                            int z = line.indexOf(StringPool.CLOSE_PARENTHESIS);
431    
432                            if ((y == -1) || ((z != -1) && (z < y))) {
433                                    return parameterTypes;
434                            }
435    
436                            line = line.substring(y + 1);
437                            line = line.trim();
438                    }
439            }
440    
441            private static String _checkIfClause(
442                            String ifClause, String fileName, int lineCount)
443                    throws IOException {
444    
445                    String ifClauseSingleLine = StringUtil.replace(
446                            ifClause, 
447                            new String[] {
448                                    StringPool.TAB + StringPool.SPACE, StringPool.TAB,
449                                    StringPool.OPEN_PARENTHESIS + StringPool.NEW_LINE,
450                                    StringPool.NEW_LINE
451                            },
452                            new String[] {
453                                    StringPool.TAB, StringPool.BLANK, StringPool.OPEN_PARENTHESIS,
454                                    StringPool.SPACE
455                            });
456    
457                    _checkIfClauseParentheses(ifClauseSingleLine, fileName, lineCount);
458    
459                    return _checkIfClauseTabsAndSpaces(ifClause);
460            }
461    
462            private static void _checkIfClauseParentheses(
463                    String ifClause, String fileName, int lineCount) {
464    
465                    int quoteCount = StringUtil.count(ifClause, StringPool.QUOTE);
466    
467                    if ((quoteCount % 2) == 1) {
468                            return;
469                    }
470    
471                    ifClause = _stripQuotes(ifClause, StringPool.QUOTE);
472    
473                    ifClause = _stripQuotes(ifClause, StringPool.APOSTROPHE);
474    
475                    if (ifClause.contains(StringPool.DOUBLE_SLASH) ||
476                            ifClause.contains("/*") || ifClause.contains("*/")) {
477    
478                            return;
479                    }
480    
481                    ifClause = _stripRedundantParentheses(ifClause);
482    
483                    int level = 0;
484                    int max = StringUtil.count(ifClause, StringPool.OPEN_PARENTHESIS);
485                    int previousParenthesisPos = -1;
486    
487                    int[] levels = new int[max];
488    
489                    for (int i = 0; i < ifClause.length(); i++) {
490                            char c = ifClause.charAt(i);
491    
492                            if ((c == CharPool.OPEN_PARENTHESIS) ||
493                                    (c == CharPool.CLOSE_PARENTHESIS)) {
494    
495                                    if (previousParenthesisPos != -1) {
496                                            String s = ifClause.substring(
497                                                    previousParenthesisPos + 1, i);
498    
499                                            if (_hasMissingParentheses(s)) {
500                                                    _processErrorMessage(
501                                                            fileName,
502                                                            "missing parentheses: " + fileName + " " +
503                                                                    lineCount);
504                                            }
505                                    }
506    
507                                    previousParenthesisPos = i;
508    
509                                    if (c == CharPool.OPEN_PARENTHESIS) {
510                                            levels[level] = i;
511    
512                                            level += 1;
513                                    }
514                                    else {
515                                            int posOpenParenthesis = levels[level - 1];
516    
517                                            if (level > 1) {
518                                                    char nextChar = ifClause.charAt(i + 1);
519                                                    char previousChar = ifClause.charAt(
520                                                            posOpenParenthesis - 1);
521    
522                                                    if (!Character.isLetterOrDigit(nextChar) &&
523                                                            (nextChar != CharPool.PERIOD) &&
524                                                            !Character.isLetterOrDigit(previousChar)) {
525    
526                                                            String s = ifClause.substring(
527                                                                    posOpenParenthesis + 1, i);
528    
529                                                            if (_hasRedundantParentheses(s)) {
530                                                                    _processErrorMessage(
531                                                                            fileName,
532                                                                            "redundant parentheses: " + fileName + " " +
533                                                                                    lineCount);
534                                                            }
535                                                    }
536    
537                                                    if ((previousChar == CharPool.OPEN_PARENTHESIS) &&
538                                                            (nextChar == CharPool.CLOSE_PARENTHESIS)) {
539    
540                                                            _processErrorMessage(
541                                                                    fileName,
542                                                                    "redundant parentheses: " + fileName + " " +
543                                                                            lineCount);
544                                                    }
545                                            }
546    
547                                            level -= 1;
548                                    }
549                            }
550                    }
551            }
552    
553            private static String _checkIfClauseTabsAndSpaces(String ifClause)
554                    throws IOException {
555    
556                    if (ifClause.contains("!(") ||
557                            ifClause.contains(StringPool.TAB + "//")) {
558    
559                            return ifClause;
560                    }
561    
562                    UnsyncBufferedReader unsyncBufferedReader = new UnsyncBufferedReader(
563                            new UnsyncStringReader(ifClause));
564    
565                    String line = null;
566    
567                    String previousLine = null;
568                    int previousLineLeadingWhiteSpace = 0;
569    
570                    int lastCriteriumLineLeadingWhiteSpace = 0;
571    
572                    int closeParenthesesCount = 0;
573                    int openParenthesesCount = 0;
574    
575                    while ((line = unsyncBufferedReader.readLine()) != null) {
576                            String originalLine = line;
577    
578                            line = StringUtil.replace(
579                                    line, StringPool.TAB, StringPool.FOUR_SPACES);
580    
581                            int leadingWhiteSpace =
582                                    line.length() - StringUtil.trimLeading(line).length();
583    
584                            if (Validator.isNull(previousLine)) {
585                                    lastCriteriumLineLeadingWhiteSpace = line.indexOf(
586                                            StringPool.OPEN_PARENTHESIS);
587                            }
588                            else if (previousLine.endsWith("|") || previousLine.endsWith("&") ||
589                                             previousLine.endsWith("^")) {
590    
591                                    int expectedLeadingWhiteSpace =
592                                            lastCriteriumLineLeadingWhiteSpace +
593                                                    openParenthesesCount - closeParenthesesCount;
594    
595                                    if (leadingWhiteSpace != expectedLeadingWhiteSpace) {
596                                            return _fixIfClause(
597                                                    ifClause, originalLine,
598                                                    leadingWhiteSpace - expectedLeadingWhiteSpace);
599                                    }
600    
601                                    lastCriteriumLineLeadingWhiteSpace = leadingWhiteSpace;
602    
603                                    closeParenthesesCount = 0;
604                                    openParenthesesCount = 0;
605                            }
606                            else {
607                                    int expectedLeadingWhiteSpace = 0;
608    
609                                    if (previousLine.contains(StringPool.TAB + "if (")) {
610                                            expectedLeadingWhiteSpace =
611                                                    previousLineLeadingWhiteSpace + 8;
612                                    }
613                                    else if (previousLine.contains(StringPool.TAB + "else if (") ||
614                                                     previousLine.contains(StringPool.TAB + "while (")) {
615    
616                                            expectedLeadingWhiteSpace =
617                                                    previousLineLeadingWhiteSpace + 12;
618                                    }
619    
620                                    if ((expectedLeadingWhiteSpace != 0) && 
621                                            (leadingWhiteSpace != expectedLeadingWhiteSpace)) {
622    
623                                            return _fixIfClause(
624                                                    ifClause, originalLine,
625                                                    leadingWhiteSpace - expectedLeadingWhiteSpace);
626                                    }
627                            }
628    
629                            if (line.endsWith(") {")) {
630                                    return ifClause;
631                            }
632    
633                            line = _stripQuotes(line, StringPool.QUOTE);
634                            line = _stripQuotes(line, StringPool.APOSTROPHE);
635    
636                            closeParenthesesCount += StringUtil.count(
637                                    line, StringPool.CLOSE_PARENTHESIS);
638                            openParenthesesCount += StringUtil.count(
639                                    line, StringPool.OPEN_PARENTHESIS);
640    
641    
642                            previousLine = originalLine;
643                            previousLineLeadingWhiteSpace = leadingWhiteSpace;
644                    }
645    
646                    return ifClause;
647            }
648    
649            private static void _checkLanguageKeys(
650                            String fileName, String content, Pattern pattern)
651                    throws IOException {
652    
653                    String fileExtension = _fileUtil.getExtension(fileName);
654    
655                    if (!_portalSource || fileExtension.equals("vm")) {
656                            return;
657                    }
658    
659                    if (_portalLanguageKeysProperties == null) {
660                            _portalLanguageKeysProperties = new Properties();
661    
662                            ClassLoader classLoader = SourceFormatter.class.getClassLoader();
663    
664                            InputStream inputStream = classLoader.getResourceAsStream(
665                                    "content/Language.properties");
666    
667                            _portalLanguageKeysProperties.load(inputStream);
668                    }
669    
670                    Matcher matcher = pattern.matcher(content);
671    
672                    while (matcher.find()) {
673                            String[] languageKeys = _getLanguageKeys(matcher);
674    
675                            for (String languageKey : languageKeys) {
676                                    if (Validator.isNumber(languageKey) ||
677                                            languageKey.endsWith(StringPool.DASH) ||
678                                            languageKey.endsWith(StringPool.PERIOD) ||
679                                            languageKey.endsWith(StringPool.UNDERLINE) ||
680                                            languageKey.startsWith(StringPool.DASH) ||
681                                            languageKey.startsWith(StringPool.OPEN_BRACKET) ||
682                                            languageKey.startsWith(StringPool.OPEN_CURLY_BRACE) ||
683                                            languageKey.startsWith(StringPool.PERIOD) ||
684                                            languageKey.startsWith(StringPool.UNDERLINE)) {
685    
686                                            continue;
687                                    }
688    
689                                    if (!_portalLanguageKeysProperties.containsKey(languageKey)) {
690                                            _processErrorMessage(
691                                                    fileName,
692                                                    "missing language key: " + languageKey +
693                                                            StringPool.SPACE + fileName);
694                                    }
695                            }
696                    }
697            }
698    
699            private static boolean _checkTaglibVulnerability(
700                    String jspContent, String vulnerability) {
701    
702                    int pos1 = -1;
703    
704                    do {
705                            pos1 = jspContent.indexOf(vulnerability, pos1 + 1);
706    
707                            if (pos1 != -1) {
708                                    int pos2 = jspContent.lastIndexOf(CharPool.LESS_THAN, pos1);
709    
710                                    while ((pos2 > 0) &&
711                                               (jspContent.charAt(pos2 + 1) == CharPool.PERCENT)) {
712    
713                                            pos2 = jspContent.lastIndexOf(CharPool.LESS_THAN, pos2 - 1);
714                                    }
715    
716                                    String tagContent = jspContent.substring(pos2, pos1);
717    
718                                    if (!tagContent.startsWith("<aui:") &&
719                                            !tagContent.startsWith("<liferay-portlet:") &&
720                                            !tagContent.startsWith("<liferay-util:") &&
721                                            !tagContent.startsWith("<portlet:")) {
722    
723                                            return true;
724                                    }
725                            }
726                    }
727                    while (pos1 != -1);
728    
729                    return false;
730            }
731    
732            private static void _checkXSS(String fileName, String jspContent) {
733                    Matcher matcher = _xssPattern.matcher(jspContent);
734    
735                    while (matcher.find()) {
736                            boolean xssVulnerable = false;
737    
738                            String jspVariable = matcher.group(1);
739    
740                            String anchorVulnerability = " href=\"<%= " + jspVariable + " %>";
741    
742                            if (_checkTaglibVulnerability(jspContent, anchorVulnerability)) {
743                                    xssVulnerable = true;
744                            }
745    
746                            String inputVulnerability = " value=\"<%= " + jspVariable + " %>";
747    
748                            if (_checkTaglibVulnerability(jspContent, inputVulnerability)) {
749                                    xssVulnerable = true;
750                            }
751    
752                            String inlineStringVulnerability1 = "'<%= " + jspVariable + " %>";
753    
754                            if (jspContent.contains(inlineStringVulnerability1)) {
755                                    xssVulnerable = true;
756                            }
757    
758                            String inlineStringVulnerability2 = "(\"<%= " + jspVariable + " %>";
759    
760                            if (jspContent.contains(inlineStringVulnerability2)) {
761                                    xssVulnerable = true;
762                            }
763    
764                            String inlineStringVulnerability3 = " \"<%= " + jspVariable + " %>";
765    
766                            if (jspContent.contains(inlineStringVulnerability3)) {
767                                    xssVulnerable = true;
768                            }
769    
770                            String documentIdVulnerability = ".<%= " + jspVariable + " %>";
771    
772                            if (jspContent.contains(documentIdVulnerability)) {
773                                    xssVulnerable = true;
774                            }
775    
776                            if (xssVulnerable) {
777                                    _processErrorMessage(
778                                            fileName, "(xss): " + fileName + " (" + jspVariable + ")");
779                            }
780                    }
781            }
782    
783            private static String _fixAntXMLProjectName(
784                    String basedir, String fileName, String content) {
785    
786                    int x = 0;
787    
788                    if (fileName.endsWith("-ext/build.xml")) {
789                            x = fileName.indexOf("ext/");
790    
791                            if (x == -1) {
792                                    x = 0;
793                            }
794                            else {
795                                    x = x + 4;
796                            }
797                    }
798                    else if (fileName.endsWith("-hook/build.xml")) {
799                            x = fileName.indexOf("hooks/");
800    
801                            if (x == -1) {
802                                    x = 0;
803                            }
804                            else {
805                                    x = x + 6;
806                            }
807                    }
808                    else if (fileName.endsWith("-layouttpl/build.xml")) {
809                            x = fileName.indexOf("layouttpl/");
810    
811                            if (x == -1) {
812                                    x = 0;
813                            }
814                            else {
815                                    x = x + 10;
816                            }
817                    }
818                    else if (fileName.endsWith("-portlet/build.xml")) {
819                            x = fileName.indexOf("portlets/");
820    
821                            if (x == -1) {
822                                    x = 0;
823                            }
824                            else {
825                                    x = x + 9;
826                            }
827                    }
828                    else if (fileName.endsWith("-theme/build.xml")) {
829                            x = fileName.indexOf("themes/");
830    
831                            if (x == -1) {
832                                    x = 0;
833                            }
834                            else {
835                                    x = x + 7;
836                            }
837                    }
838                    else if (fileName.endsWith("-web/build.xml") &&
839                                     !fileName.endsWith("/ext-web/build.xml")) {
840    
841                            x = fileName.indexOf("webs/");
842    
843                            if (x == -1) {
844                                    x = 0;
845                            }
846                            else {
847                                    x = x + 5;
848                            }
849                    }
850                    else {
851                            return content;
852                    }
853    
854                    int y = fileName.indexOf("/", x);
855    
856                    String correctProjectElementText =
857                            "<project name=\"" + fileName.substring(x, y) + "\"";
858    
859                    if (!content.contains(correctProjectElementText)) {
860                            x = content.indexOf("<project name=\"");
861    
862                            y = content.indexOf("\"", x) + 1;
863                            y = content.indexOf("\"", y) + 1;
864    
865                            content =
866                                    content.substring(0, x) + correctProjectElementText +
867                                            content.substring(y);
868    
869                            _processErrorMessage(
870                                    fileName, fileName + " has an incorrect project name");
871                    }
872    
873                    return content;
874            }
875    
876            private static String _fixCopyright(
877                            String content, String copyright, String oldCopyright, File file,
878                            String fileName)
879                    throws IOException {
880    
881                    if (fileName.endsWith(".vm")) {
882                            return content;
883                    }
884    
885                    if ((oldCopyright != null) && content.contains(oldCopyright)) {
886                            content = StringUtil.replace(content, oldCopyright, copyright);
887    
888                            _processErrorMessage(fileName, "old (c): " + fileName);
889                    }
890    
891                    if (!content.contains(copyright)) {
892                            String customCopyright = _getCustomCopyright(file);
893    
894                            if (Validator.isNotNull(customCopyright)) {
895                                    copyright = customCopyright;
896                            }
897    
898                            if (!content.contains(copyright)) {
899                                    _processErrorMessage(fileName, "(c): " + fileName);
900                            }
901                    }
902    
903                    if (fileName.endsWith(".jsp") || fileName.endsWith(".jspf")) {
904                            content = StringUtil.replace(
905                                    content, "<%\n" + copyright + "\n%>",
906                                    "<%--\n" + copyright + "\n--%>");
907                    }
908    
909                    int x = content.indexOf("* Copyright (c) 2000-20");
910    
911                    if (x == -1) {
912                            return content;
913                    }
914    
915                    int y = copyright.indexOf("* Copyright (c) 2000-20");
916    
917                    if (y == -1) {
918                            return content;
919                    }
920    
921                    String contentCopyrightYear = content.substring(x, x + 25);
922                    String copyrightYear = copyright.substring(y, y + 25);
923    
924                    return StringUtil.replace(content, contentCopyrightYear, copyrightYear);
925            }
926    
927            private static String _fixDataAccessConnection(
928                    String className, String content) {
929    
930                    int x = content.indexOf("package ");
931    
932                    int y = content.indexOf(CharPool.SEMICOLON, x);
933    
934                    if ((x == -1) || (y == -1)) {
935                            return content;
936                    }
937    
938                    String packageName = content.substring(x + 8, y);
939    
940                    if (!packageName.startsWith("com.liferay.portal.kernel.upgrade") &&
941                            !packageName.startsWith("com.liferay.portal.kernel.verify") &&
942                            !packageName.startsWith("com.liferay.portal.upgrade") &&
943                            !packageName.startsWith("com.liferay.portal.verify")) {
944    
945                            return content;
946                    }
947    
948                    content = StringUtil.replace(
949                            content, "DataAccess.getConnection",
950                            "DataAccess.getUpgradeOptimizedConnection");
951    
952                    return content;
953            }
954    
955            private static String _fixIfClause(
956                    String ifClause, String line, int delta) {
957    
958                    String newLine = line;
959    
960                    String whiteSpace = StringPool.BLANK;
961                    int whiteSpaceLength = Math.abs(delta);
962    
963                    while (whiteSpaceLength > 0) {
964                            if (whiteSpaceLength >= 4) {
965                                    whiteSpace += StringPool.TAB;
966    
967                                    whiteSpaceLength -= 4;
968                            }
969                            else {
970                                    whiteSpace += StringPool.SPACE;
971    
972                                    whiteSpaceLength -= 1;
973                            }
974                    }
975    
976                    if (delta > 0) {
977                            if (!line.contains(StringPool.TAB + whiteSpace)) {
978                                    newLine = StringUtil.replaceLast(
979                                            newLine, StringPool.TAB, StringPool.FOUR_SPACES);
980                            }
981    
982                            newLine = StringUtil.replaceLast(
983                                    newLine, StringPool.TAB + whiteSpace, StringPool.TAB);
984                    }
985                    else {
986                            newLine = StringUtil.replaceLast(
987                                    newLine, StringPool.TAB, StringPool.TAB + whiteSpace);
988                    }
989    
990                    return StringUtil.replace(ifClause, line, newLine);
991            }
992    
993            private static String _fixSessionKey(
994                    String fileName, String content, Pattern pattern) {
995    
996                    Matcher matcher = pattern.matcher(content);
997    
998                    if (!matcher.find()) {
999                            return content;
1000                    }
1001    
1002                    String newContent = content;
1003    
1004                    do {
1005                            String match = matcher.group();
1006    
1007                            String s = null;
1008    
1009                            if (pattern.equals(_sessionKeyPattern)) {
1010                                    s = StringPool.COMMA;
1011                            }
1012                            else if (pattern.equals(_taglibSessionKeyPattern)) {
1013                                    s = "key=";
1014                            }
1015    
1016                            int x = match.indexOf(s);
1017    
1018                            if (x == -1) {
1019                                    continue;
1020                            }
1021    
1022                            x = x + s.length();
1023    
1024                            String substring = match.substring(x).trim();
1025    
1026                            String quote = StringPool.BLANK;
1027    
1028                            if (substring.startsWith(StringPool.APOSTROPHE)) {
1029                                    quote = StringPool.APOSTROPHE;
1030                            }
1031                            else if (substring.startsWith(StringPool.QUOTE)) {
1032                                    quote = StringPool.QUOTE;
1033                            }
1034                            else {
1035                                    continue;
1036                            }
1037    
1038                            int y = match.indexOf(quote, x);
1039                            int z = match.indexOf(quote, y + 1);
1040    
1041                            if ((y == -1) || (z == -1)) {
1042                                    continue;
1043                            }
1044    
1045                            String prefix = match.substring(0, y + 1);
1046                            String suffix = match.substring(z);
1047                            String oldKey = match.substring(y + 1, z);
1048    
1049                            boolean alphaNumericKey = true;
1050    
1051                            for (char c : oldKey.toCharArray()) {
1052                                    if (!Validator.isChar(c) && !Validator.isDigit(c) &&
1053                                            (c != CharPool.DASH) && (c != CharPool.UNDERLINE)) {
1054    
1055                                            alphaNumericKey = false;
1056                                    }
1057                            }
1058    
1059                            if (!alphaNumericKey) {
1060                                    continue;
1061                            }
1062    
1063                            String newKey = TextFormatter.format(oldKey, TextFormatter.O);
1064    
1065                            newKey = TextFormatter.format(newKey, TextFormatter.M);
1066    
1067                            if (newKey.equals(oldKey)) {
1068                                    continue;
1069                            }
1070    
1071                            String oldSub = prefix.concat(oldKey).concat(suffix);
1072                            String newSub = prefix.concat(newKey).concat(suffix);
1073    
1074                            newContent = StringUtil.replaceFirst(newContent, oldSub, newSub);
1075                    }
1076                    while (matcher.find());
1077    
1078                    return newContent;
1079            }
1080    
1081            private static void _formatAntXML() throws DocumentException, IOException {
1082                    String basedir = "./";
1083    
1084                    DirectoryScanner directoryScanner = new DirectoryScanner();
1085    
1086                    directoryScanner.setBasedir(basedir);
1087    
1088                    String[] excludes = {"**\\tools\\**"};
1089    
1090                    excludes = ArrayUtil.append(excludes, _excludes);
1091    
1092                    directoryScanner.setExcludes(excludes);
1093    
1094                    directoryScanner.setIncludes(new String[] {"**\\b*.xml"});
1095    
1096                    List<String> fileNames = _sourceFormatterHelper.scanForFiles(
1097                            directoryScanner);
1098    
1099                    for (String fileName : fileNames) {
1100                            File file = new File(basedir + fileName);
1101    
1102                            fileName = StringUtil.replace(
1103                                    fileName, StringPool.BACK_SLASH, StringPool.SLASH);
1104    
1105                            String content = _fileUtil.read(file);
1106    
1107                            String newContent = _trimContent(content, true);
1108    
1109                            newContent = _fixAntXMLProjectName(basedir, fileName, newContent);
1110    
1111                            Document document = _saxReaderUtil.read(newContent);
1112    
1113                            Element rootElement = document.getRootElement();
1114    
1115                            String previousName = StringPool.BLANK;
1116    
1117                            List<Element> targetElements = rootElement.elements("target");
1118    
1119                            for (Element targetElement : targetElements) {
1120                                    String name = targetElement.attributeValue("name");
1121    
1122                                    if (name.equals("Test")) {
1123                                            name = name.toLowerCase();
1124                                    }
1125    
1126                                    if (name.compareTo(previousName) < -1) {
1127                                            _processErrorMessage(
1128                                                    fileName,
1129                                                    fileName + " has an unordered target " + name);
1130    
1131                                            break;
1132                                    }
1133    
1134                                    previousName = name;
1135                            }
1136    
1137                            if ((newContent != null) && !content.equals(newContent)) {
1138                                    _fileUtil.write(file, newContent);
1139    
1140                                    _sourceFormatterHelper.printError(fileName, file);
1141                            }
1142                    }
1143            }
1144    
1145            private static void _formatDDLStructuresXML()
1146                    throws DocumentException, IOException {
1147    
1148                    String basedir =
1149                            "./portal-impl/src/com/liferay/portal/events/dependencies/";
1150    
1151                    if (!_fileUtil.exists(basedir)) {
1152                            return;
1153                    }
1154    
1155                    DirectoryScanner directoryScanner = new DirectoryScanner();
1156    
1157                    directoryScanner.setBasedir(basedir);
1158                    directoryScanner.setExcludes(_excludes);
1159                    directoryScanner.setIncludes(new String[] {"**\\*structures.xml"});
1160    
1161                    List<String> fileNames = _sourceFormatterHelper.scanForFiles(
1162                            directoryScanner);
1163    
1164                    for (String fileName : fileNames) {
1165                            File file = new File(basedir + fileName);
1166    
1167                            String content = _fileUtil.read(file);
1168    
1169                            String newContent = _trimContent(content, false);
1170    
1171                            newContent = _formatDDLStructuresXML(content);
1172    
1173                            if ((newContent != null) && !content.equals(newContent)) {
1174                                    _fileUtil.write(file, newContent);
1175    
1176                                    fileName = StringUtil.replace(
1177                                            fileName, StringPool.BACK_SLASH, StringPool.SLASH);
1178    
1179                                    _sourceFormatterHelper.printError(fileName, file);
1180                            }
1181                    }
1182            }
1183    
1184            private static String _formatDDLStructuresXML(String content)
1185                    throws DocumentException, IOException {
1186    
1187                    Document document = _saxReaderUtil.read(content);
1188    
1189                    Element rootElement = document.getRootElement();
1190    
1191                    rootElement.sortAttributes(true);
1192    
1193                    rootElement.sortElementsByChildElement("structure", "name");
1194    
1195                    List<Element> structureElements = rootElement.elements("structure");
1196    
1197                    for (Element structureElement : structureElements) {
1198                            Element structureRootElement = structureElement.element("root");
1199    
1200                            structureRootElement.sortElementsByAttribute(
1201                                    "dynamic-element", "name");
1202    
1203                            List<Element> dynamicElementElements =
1204                                    structureRootElement.elements("dynamic-element");
1205    
1206                            for (Element dynamicElementElement : dynamicElementElements) {
1207                                    Element metaDataElement = dynamicElementElement.element(
1208                                            "meta-data");
1209    
1210                                    metaDataElement.sortElementsByAttribute("entry", "name");
1211                            }
1212                    }
1213    
1214                    return document.formattedString();
1215            }
1216    
1217            private static void _formatFriendlyURLRoutesXML()
1218                    throws DocumentException, IOException {
1219    
1220                    String basedir = "./";
1221    
1222                    DirectoryScanner directoryScanner = new DirectoryScanner();
1223    
1224                    directoryScanner.setBasedir(basedir);
1225    
1226                    String[] excludes = {"**\\classes\\**", "**\\bin\\**"};
1227    
1228                    excludes = ArrayUtil.append(excludes, _excludes);
1229    
1230                    directoryScanner.setExcludes(excludes);
1231    
1232                    directoryScanner.setIncludes(new String[] {"**\\*routes.xml"});
1233    
1234                    List<String> fileNames = _sourceFormatterHelper.scanForFiles(
1235                            directoryScanner);
1236    
1237                    for (String fileName : fileNames) {
1238                            File file = new File(basedir + fileName);
1239    
1240                            String content = _fileUtil.read(file);
1241    
1242                            if (content.contains("<!-- SourceFormatter.Ignore -->")) {
1243                                    continue;
1244                            }
1245    
1246                            String newContent = _trimContent(content, false);
1247    
1248                            newContent = _formatFriendlyURLRoutesXML(content);
1249    
1250                            if ((newContent != null) && !content.equals(newContent)) {
1251                                    _fileUtil.write(file, newContent);
1252    
1253                                    fileName = StringUtil.replace(
1254                                            fileName, StringPool.BACK_SLASH, StringPool.SLASH);
1255    
1256                                    _sourceFormatterHelper.printError(fileName, file);
1257                            }
1258                    }
1259            }
1260    
1261            private static String _formatFriendlyURLRoutesXML(String content)
1262                    throws DocumentException {
1263    
1264                    Document document = _saxReaderUtil.read(content);
1265    
1266                    Element rootElement = document.getRootElement();
1267    
1268                    List<ComparableRoute> comparableRoutes =
1269                            new ArrayList<ComparableRoute>();
1270    
1271                    for (Element routeElement : rootElement.elements("route")) {
1272                            String pattern = routeElement.elementText("pattern");
1273    
1274                            ComparableRoute comparableRoute = new ComparableRoute(pattern);
1275    
1276                            for (Element generatedParameterElement :
1277                                            routeElement.elements("generated-parameter")) {
1278    
1279                                    String name = generatedParameterElement.attributeValue("name");
1280                                    String value = generatedParameterElement.getText();
1281    
1282                                    comparableRoute.addGeneratedParameter(name, value);
1283                            }
1284    
1285                            for (Element ignoredParameterElement :
1286                                            routeElement.elements("ignored-parameter")) {
1287    
1288                                    String name = ignoredParameterElement.attributeValue("name");
1289    
1290                                    comparableRoute.addIgnoredParameter(name);
1291                            }
1292    
1293                            for (Element implicitParameterElement :
1294                                            routeElement.elements("implicit-parameter")) {
1295    
1296                                    String name = implicitParameterElement.attributeValue("name");
1297                                    String value = implicitParameterElement.getText();
1298    
1299                                    comparableRoute.addImplicitParameter(name, value);
1300                            }
1301    
1302                            for (Element overriddenParameterElement :
1303                                            routeElement.elements("overridden-parameter")) {
1304    
1305                                    String name = overriddenParameterElement.attributeValue("name");
1306                                    String value = overriddenParameterElement.getText();
1307    
1308                                    comparableRoute.addOverriddenParameter(name, value);
1309                            }
1310    
1311                            comparableRoutes.add(comparableRoute);
1312                    }
1313    
1314                    Collections.sort(comparableRoutes);
1315    
1316                    StringBundler sb = new StringBundler();
1317    
1318                    sb.append("<?xml version=\"1.0\"?>\n");
1319                    sb.append("<!DOCTYPE routes PUBLIC \"-//Liferay//DTD Friendly URL ");
1320                    sb.append("Routes 6.2.0//EN\" \"http://www.liferay.com/dtd/");
1321                    sb.append("liferay-friendly-url-routes_6_2_0.dtd\">\n\n<routes>\n");
1322    
1323                    for (ComparableRoute comparableRoute : comparableRoutes) {
1324                            sb.append("\t<route>\n");
1325                            sb.append("\t\t<pattern>");
1326                            sb.append(comparableRoute.getPattern());
1327                            sb.append("</pattern>\n");
1328    
1329                            Map<String, String> generatedParameters =
1330                                    comparableRoute.getGeneratedParameters();
1331    
1332                            for (Map.Entry<String, String> entry :
1333                                            generatedParameters.entrySet()) {
1334    
1335                                    sb.append("\t\t<generated-parameter name=\"");
1336                                    sb.append(entry.getKey());
1337                                    sb.append("\">");
1338                                    sb.append(entry.getValue());
1339                                    sb.append("</generated-parameter>\n");
1340                            }
1341    
1342                            Set<String> ignoredParameters =
1343                                    comparableRoute.getIgnoredParameters();
1344    
1345                            for (String entry : ignoredParameters) {
1346                                    sb.append("\t\t<ignored-parameter name=\"");
1347                                    sb.append(entry);
1348                                    sb.append("\" />\n");
1349                            }
1350    
1351                            Map<String, String> implicitParameters =
1352                                    comparableRoute.getImplicitParameters();
1353    
1354                            for (Map.Entry<String, String> entry :
1355                                            implicitParameters.entrySet()) {
1356    
1357                                    sb.append("\t\t<implicit-parameter name=\"");
1358                                    sb.append(entry.getKey());
1359                                    sb.append("\">");
1360                                    sb.append(entry.getValue());
1361                                    sb.append("</implicit-parameter>\n");
1362                            }
1363    
1364                            Map<String, String> overriddenParameters =
1365                                    comparableRoute.getOverriddenParameters();
1366    
1367                            for (Map.Entry<String, String> entry :
1368                                            overriddenParameters.entrySet()) {
1369    
1370                                    sb.append("\t\t<overridden-parameter name=\"");
1371                                    sb.append(entry.getKey());
1372                                    sb.append("\">");
1373                                    sb.append(entry.getValue());
1374                                    sb.append("</overridden-parameter>\n");
1375                            }
1376    
1377                            sb.append("\t</route>\n");
1378                    }
1379    
1380                    sb.append("</routes>");
1381    
1382                    return sb.toString();
1383            }
1384    
1385            private static void _formatFTL() throws IOException {
1386                    String basedir = "./";
1387    
1388                    DirectoryScanner directoryScanner = new DirectoryScanner();
1389    
1390                    directoryScanner.setBasedir(basedir);
1391    
1392                    String[] excludes = {
1393                            "**\\journal\\dependencies\\template.ftl",
1394                            "**\\servicebuilder\\dependencies\\props.ftl"
1395                    };
1396    
1397                    excludes = ArrayUtil.append(excludes, _excludes);
1398    
1399                    directoryScanner.setExcludes(excludes);
1400    
1401                    directoryScanner.setIncludes(new String[] {"**\\*.ftl"});
1402    
1403                    List<String> fileNames = _sourceFormatterHelper.scanForFiles(
1404                            directoryScanner);
1405    
1406                    for (String fileName : fileNames) {
1407                            File file = new File(basedir + fileName);
1408    
1409                            String content = _fileUtil.read(file);
1410    
1411                            String newContent = _trimContent(content, false);
1412    
1413                            if ((newContent != null) && !content.equals(newContent)) {
1414                                    _fileUtil.write(file, newContent);
1415    
1416                                    fileName = StringUtil.replace(
1417                                            fileName, StringPool.BACK_SLASH, StringPool.SLASH);
1418    
1419                                    _sourceFormatterHelper.printError(fileName, file);
1420                            }
1421                    }
1422            }
1423    
1424            private static String _formatImports(String imports, int classStartPos)
1425                    throws IOException {
1426    
1427                    if (imports.contains("/*") || imports.contains("*/") ||
1428                            imports.contains("//")) {
1429    
1430                            return imports + "\n";
1431                    }
1432    
1433                    List<String> importsList = new ArrayList<String>();
1434    
1435                    UnsyncBufferedReader unsyncBufferedReader = new UnsyncBufferedReader(
1436                            new UnsyncStringReader(imports));
1437    
1438                    String line = null;
1439    
1440                    while ((line = unsyncBufferedReader.readLine()) != null) {
1441                            if ((line.contains("import=") || line.contains("import ")) &&
1442                                    !importsList.contains(line)) {
1443    
1444                                    importsList.add(line);
1445                            }
1446                    }
1447    
1448                    importsList = ListUtil.sort(importsList);
1449    
1450                    StringBundler sb = new StringBundler();
1451    
1452                    String temp = null;
1453    
1454                    for (int i = 0; i < importsList.size(); i++) {
1455                            String s = importsList.get(i);
1456    
1457                            int pos = s.indexOf(".");
1458    
1459                            pos = s.indexOf(".", pos + 1);
1460    
1461                            if (pos == -1) {
1462                                    pos = s.indexOf(".");
1463                            }
1464    
1465                            String packageLevel = s.substring(classStartPos, pos);
1466    
1467                            if ((i != 0) && !packageLevel.equals(temp)) {
1468                                    sb.append("\n");
1469                            }
1470    
1471                            temp = packageLevel;
1472    
1473                            sb.append(s);
1474                            sb.append("\n");
1475                    }
1476    
1477                    return sb.toString();
1478            }
1479    
1480            private static void _formatJava() throws IOException {
1481                    String copyright = _getCopyright();
1482                    String oldCopyright = _getOldCopyright();
1483    
1484                    boolean portalJavaFiles = true;
1485    
1486                    Collection<String> fileNames = null;
1487    
1488                    if (_portalSource) {
1489                            fileNames = _getPortalJavaFiles();
1490    
1491                            _javaTermSortExclusions = _getPortalExclusionsProperties(
1492                                    "source_formatter_javaterm_sort_exclusions.properties");
1493                            _lineLengthExclusions = _getPortalExclusionsProperties(
1494                                    "source_formatter_line_length_exclusions.properties");
1495                    }
1496                    else {
1497                            portalJavaFiles = false;
1498    
1499                            fileNames = _getPluginJavaFiles();
1500    
1501                            _javaTermSortExclusions = _getPluginExclusionsProperties(
1502                                    "source_formatter_javaterm_sort_exclusions.properties");
1503                            _lineLengthExclusions = _getPluginExclusionsProperties(
1504                                    "source_formatter_line_length_exclusions.properties");
1505                    }
1506    
1507                    for (String fileName : fileNames) {
1508                            File file = new File(fileName);
1509    
1510                            fileName = StringUtil.replace(
1511                                    fileName, StringPool.BACK_SLASH, StringPool.SLASH);
1512    
1513                            String content = _fileUtil.read(file);
1514    
1515                            if (_isGenerated(content) &&
1516                                    !fileName.endsWith("JavadocFormatter.java")) {
1517    
1518                                    continue;
1519                            }
1520    
1521                            String className = file.getName();
1522    
1523                            className = className.substring(0, className.length() - 5);
1524    
1525                            String packagePath = fileName;
1526    
1527                            int packagePathX = packagePath.indexOf(
1528                                    File.separator + "src" + File.separator);
1529                            int packagePathY = packagePath.lastIndexOf(File.separator);
1530    
1531                            if ((packagePathX + 5) >= packagePathY) {
1532                                    packagePath = StringPool.BLANK;
1533                            }
1534                            else {
1535                                    packagePath = packagePath.substring(
1536                                            packagePathX + 5, packagePathY);
1537                            }
1538    
1539                            packagePath = StringUtil.replace(
1540                                    packagePath, File.separator, StringPool.PERIOD);
1541    
1542                            if (packagePath.endsWith(".model")) {
1543                                    if (content.contains("extends " + className + "Model")) {
1544                                            continue;
1545                                    }
1546                            }
1547    
1548                            String newContent = content;
1549    
1550                            if (newContent.contains("$\n */")) {
1551                                    _processErrorMessage(fileName, "*: " + fileName);
1552    
1553                                    newContent = StringUtil.replace(
1554                                            newContent, "$\n */", "$\n *\n */");
1555                            }
1556    
1557                            newContent = _fixCopyright(
1558                                    newContent, copyright, oldCopyright, file, fileName);
1559    
1560                            if (newContent.contains(className + ".java.html")) {
1561                                    _processErrorMessage(fileName, "Java2HTML: " + fileName);
1562                            }
1563    
1564                            if (newContent.contains(" * @author Raymond Aug") &&
1565                                    !newContent.contains(" * @author Raymond Aug\u00e9")) {
1566    
1567                                    newContent = newContent.replaceFirst(
1568                                            "Raymond Aug.++", "Raymond Aug\u00e9");
1569    
1570                                    _processErrorMessage(fileName, "UTF-8: " + fileName);
1571                            }
1572    
1573                            newContent = _fixDataAccessConnection(className, newContent);
1574                            newContent = _fixSessionKey(
1575                                    fileName, newContent, _sessionKeyPattern);
1576    
1577                            newContent = StringUtil.replace(
1578                                    newContent,
1579                                    new String[] {
1580                                            "com.liferay.portal.PortalException",
1581                                            "com.liferay.portal.SystemException",
1582                                            "com.liferay.util.LocalizationUtil",
1583                                            "private static final Log _log"
1584                                    },
1585                                    new String[] {
1586                                            "com.liferay.portal.kernel.exception.PortalException",
1587                                            "com.liferay.portal.kernel.exception.SystemException",
1588                                            "com.liferay.portal.kernel.util.LocalizationUtil",
1589                                            "private static Log _log"
1590                                    });
1591    
1592                            newContent = stripJavaImports(newContent, packagePath, className);
1593    
1594                            newContent = StringUtil.replace(
1595                                    newContent,
1596                                    new String[] {
1597                                            ";\n/**", "\t/*\n\t *", "catch(", "else{", "if(", "for(",
1598                                            "while(", "List <", "){\n", "]{\n", "\n\n\n"
1599                                    },
1600                                    new String[] {
1601                                            ";\n\n/**", "\t/**\n\t *", "catch (", "else {", "if (",
1602                                            "for (", "while (", "List<", ") {\n", "] {\n", "\n\n"
1603                                    });
1604    
1605                            if (newContent.contains("*/\npackage ")) {
1606                                    _processErrorMessage(fileName, "package: " + fileName);
1607                            }
1608    
1609                            if (!newContent.endsWith("\n\n}") && !newContent.endsWith("{\n}")) {
1610                                    _processErrorMessage(fileName, "}: " + fileName);
1611                            }
1612    
1613                            if (portalJavaFiles && !className.equals("BaseServiceImpl") &&
1614                                    className.endsWith("ServiceImpl") &&
1615                                    newContent.contains("ServiceUtil.")) {
1616    
1617                                    _processErrorMessage(fileName, "ServiceUtil: " + fileName);
1618                            }
1619    
1620                            if (!className.equals("DeepNamedValueScanner") &&
1621                                    !className.equals("ProxyUtil") &&
1622                                    newContent.contains("import java.lang.reflect.Proxy;")) {
1623    
1624                                    _processErrorMessage(fileName, "Proxy: " + fileName);
1625                            }
1626    
1627                            if (newContent.contains("import edu.emory.mathcs.backport.java")) {
1628                                    _processErrorMessage(
1629                                            fileName, "edu.emory.mathcs.backport.java: " + fileName);
1630                            }
1631    
1632                            // LPS-28266
1633    
1634                            for (int pos1 = -1;;) {
1635                                    pos1 = newContent.indexOf(StringPool.TAB + "try {", pos1 + 1);
1636    
1637                                    if (pos1 == -1) {
1638                                            break;
1639                                    }
1640    
1641                                    int pos2 = newContent.indexOf(
1642                                            StringPool.TAB + "try {", pos1 + 1);
1643                                    int pos3 = newContent.indexOf("\"select count(", pos1);
1644    
1645                                    if ((pos2 != -1) && (pos3 != -1) && (pos2 < pos3)) {
1646                                            continue;
1647                                    }
1648    
1649                                    int pos4 = newContent.indexOf("rs.getLong(1)", pos1);
1650                                    int pos5 = newContent.indexOf(
1651                                            StringPool.TAB + "finally {", pos1);
1652    
1653                                    if ((pos3 == -1) || (pos4 == -1) || (pos5 == -1)) {
1654                                            break;
1655                                    }
1656    
1657                                    if ((pos3 < pos4) && (pos4 < pos5)) {
1658                                            _processErrorMessage(
1659                                                    fileName, "Use getInt(1) for count: " + fileName);
1660                                    }
1661                            }
1662    
1663                            // LPS-33070
1664    
1665                            if (content.contains("implements ProcessCallable") &&
1666                                    !content.contains(
1667                                            "private static final long serialVersionUID")) {
1668    
1669                                    _processErrorMessage(
1670                                            fileName,
1671                                            "Assign ProcessCallable implementation a " +
1672                                                    "serialVersionUID: " + fileName);
1673                            }
1674    
1675                            _checkLanguageKeys(fileName, newContent, _languageKeyPattern);
1676    
1677                            String oldContent = newContent;
1678    
1679                            for (;;) {
1680                                    newContent = _formatJava(fileName, oldContent);
1681    
1682                                    if (oldContent.equals(newContent)) {
1683                                            break;
1684                                    }
1685    
1686                                    oldContent = newContent;
1687                            }
1688    
1689                            if ((newContent != null) && !content.equals(newContent)) {
1690                                    _fileUtil.write(file, newContent);
1691    
1692                                    _sourceFormatterHelper.printError(fileName, file);
1693                            }
1694                    }
1695            }
1696    
1697            private static String _formatJava(String fileName, String content)
1698                    throws IOException {
1699    
1700                    StringBundler sb = new StringBundler();
1701    
1702                    UnsyncBufferedReader unsyncBufferedReader = new UnsyncBufferedReader(
1703                            new UnsyncStringReader(content));
1704    
1705                    int index = 0;
1706                    int lineCount = 0;
1707    
1708                    String line = null;
1709    
1710                    String previousLine = StringPool.BLANK;
1711    
1712                    int lineToSkipIfEmpty = 0;
1713    
1714                    Set<JavaTerm> javaTerms = new TreeSet<JavaTerm>(
1715                            new JavaTermComparator());
1716    
1717                    JavaTerm javaTerm = null;
1718    
1719                    String javaTermName = null;
1720                    int javaTermLineCount = -1;
1721                    int javaTermStartPosition = -1;
1722                    int javaTermType = -1;
1723    
1724                    boolean readParameterTypes = false;
1725                    List<String> parameterTypes = new ArrayList<String>();
1726    
1727                    int lastCommentOrAnnotationPos = -1;
1728    
1729                    String ifClause = StringPool.BLANK;
1730    
1731                    String packageName = StringPool.BLANK;
1732    
1733                    while ((line = unsyncBufferedReader.readLine()) != null) {
1734                            lineCount++;
1735    
1736                            line = _trimLine(line, false);
1737    
1738                            if (line.startsWith("package ")) {
1739                                    packageName = line.substring(8, line.length() - 1);
1740                            }
1741    
1742                            if (line.startsWith("import ")) {
1743                                    if (line.endsWith(".*;")) {
1744                                            _processErrorMessage(
1745                                                    fileName, "import: " + fileName + " " + lineCount);
1746                                    }
1747    
1748                                    int pos = line.lastIndexOf(StringPool.PERIOD);
1749    
1750                                    if (pos != -1) {
1751                                            String importPackageName = line.substring(7, pos);
1752    
1753                                            if (importPackageName.equals(packageName)) {
1754                                                    continue;
1755                                            }
1756                                    }
1757                            }
1758    
1759                            if (line.contains(StringPool.TAB + "for (") && line.contains(":") &&
1760                                    !line.contains(" :")) {
1761    
1762                                    line = StringUtil.replace(line, ":" , " :");
1763                            }
1764    
1765                            line = _replacePrimitiveWrapperInstantiation(
1766                                    fileName, line, lineCount);
1767    
1768                            String trimmedLine = StringUtil.trimLeading(line);
1769    
1770                            if (trimmedLine.startsWith("* @deprecated") &&
1771                                    !trimmedLine.startsWith("* @deprecated As of")) {
1772    
1773                                    line = StringUtil.replace(
1774                                            line, "* @deprecated", "* @deprecated As of 6.2.0");
1775                            }
1776    
1777                            if (trimmedLine.startsWith(StringPool.EQUAL)) {
1778                                    _processErrorMessage(
1779                                            fileName, "equal: " + fileName + " " + lineCount);
1780                            }
1781    
1782                            if (!trimmedLine.equals("{") && line.endsWith("{") &&
1783                                    !line.endsWith(" {")) {
1784    
1785                                    line = StringUtil.replaceLast(line, "{", " {");
1786                            }
1787    
1788                            line = _sortExceptions(line);
1789    
1790                            if (trimmedLine.startsWith("if (") ||
1791                                    trimmedLine.startsWith("else if (") ||
1792                                    trimmedLine.startsWith("while (") ||
1793                                    Validator.isNotNull(ifClause)) {
1794    
1795                                    ifClause = ifClause + line + StringPool.NEW_LINE;
1796    
1797                                    if (line.endsWith(") {")) {
1798                                            String newIfClause = _checkIfClause(
1799                                                    ifClause, fileName, lineCount);
1800    
1801                                            if (!ifClause.equals(newIfClause)) {
1802                                                    return StringUtil.replace(
1803                                                            content, ifClause, newIfClause);
1804                                            }
1805    
1806                                            ifClause = StringPool.BLANK;
1807                                    }
1808                                    else if (line.endsWith(StringPool.SEMICOLON)) {
1809                                            ifClause = StringPool.BLANK;
1810                                    }
1811                            }
1812    
1813                            String excluded = null;
1814    
1815                            if (line.startsWith(StringPool.TAB + "private ") ||
1816                                    line.startsWith(StringPool.TAB + "protected ") ||
1817                                    line.startsWith(StringPool.TAB + "public ")) {
1818    
1819                                    Tuple tuple = _getJavaTermTuple(line);
1820    
1821                                    if (tuple != null) {
1822                                            int javaTermEndPosition = 0;
1823    
1824                                            if (lastCommentOrAnnotationPos == -1) {
1825                                                    javaTermEndPosition = index;
1826                                            }
1827                                            else {
1828                                                    javaTermEndPosition = lastCommentOrAnnotationPos;
1829                                            }
1830    
1831                                            if ((javaTermStartPosition != -1) &&
1832                                                    (javaTermEndPosition < content.length())) {
1833    
1834                                                    String javaTermContent = content.substring(
1835                                                            javaTermStartPosition, javaTermEndPosition);
1836    
1837                                                    if (Validator.isNotNull(javaTermName)) {
1838                                                            javaTerm = new JavaTerm(
1839                                                                    javaTermName, javaTermType, parameterTypes,
1840                                                                    javaTermContent, javaTermLineCount);
1841    
1842                                                            javaTerms.add(javaTerm);
1843                                                    }
1844                                            }
1845    
1846                                            javaTermLineCount = lineCount;
1847                                            javaTermName = (String)tuple.getObject(0);
1848                                            javaTermStartPosition = javaTermEndPosition;
1849                                            javaTermType = (Integer)tuple.getObject(1);
1850    
1851                                            if (Validator.isNotNull(javaTermName)) {
1852                                                    if (_isInJavaTermTypeGroup(
1853                                                                     javaTermType, _TYPE_CONSTRUCTOR) ||
1854                                                             _isInJavaTermTypeGroup(
1855                                                                     javaTermType, _TYPE_METHOD)) {
1856    
1857                                                            readParameterTypes = true;
1858    
1859                                                            parameterTypes = new ArrayList<String>();
1860                                                    }
1861                                            }
1862                                    }
1863    
1864                                    lastCommentOrAnnotationPos = -1;
1865                            }
1866                            else if (_hasAnnotationOrJavadoc(line)) {
1867                                    if (lastCommentOrAnnotationPos == -1) {
1868                                            lastCommentOrAnnotationPos = index;
1869                                    }
1870                            }
1871    
1872                            if (readParameterTypes) {
1873                                    parameterTypes = _addParameterTypes(
1874                                            trimmedLine, parameterTypes);
1875    
1876                                    if (trimmedLine.contains(StringPool.CLOSE_PARENTHESIS)) {
1877                                            readParameterTypes = false;
1878                                    }
1879                            }
1880    
1881                            if (!trimmedLine.contains(StringPool.DOUBLE_SLASH) &&
1882                                    !trimmedLine.startsWith(StringPool.STAR)) {
1883    
1884                                    while (trimmedLine.contains(StringPool.TAB)) {
1885                                            line = StringUtil.replaceLast(
1886                                                    line, StringPool.TAB, StringPool.SPACE);
1887    
1888                                            trimmedLine = StringUtil.replaceLast(
1889                                                    trimmedLine, StringPool.TAB, StringPool.SPACE);
1890                                    }
1891    
1892                                    if (line.contains(StringPool.TAB + StringPool.SPACE) &&
1893                                            !previousLine.endsWith("&&") &&
1894                                            !previousLine.endsWith("||") &&
1895                                            !previousLine.contains(StringPool.TAB + "((") &&
1896                                            !previousLine.contains(StringPool.TAB + StringPool.SPACE) &&
1897                                            !previousLine.contains(StringPool.TAB + "implements ") &&
1898                                            !previousLine.contains(StringPool.TAB + "throws ")) {
1899    
1900                                            line = StringUtil.replace(
1901                                                    line, StringPool.TAB + StringPool.SPACE,
1902                                                    StringPool.TAB);
1903                                    }
1904    
1905                                    while (trimmedLine.contains(StringPool.DOUBLE_SPACE) &&
1906                                               !trimmedLine.contains(
1907                                                       StringPool.QUOTE + StringPool.DOUBLE_SPACE) &&
1908                                               !fileName.contains("Test")) {
1909    
1910                                            line = StringUtil.replaceLast(
1911                                                    line, StringPool.DOUBLE_SPACE, StringPool.SPACE);
1912    
1913                                            trimmedLine = StringUtil.replaceLast(
1914                                                    trimmedLine, StringPool.DOUBLE_SPACE, StringPool.SPACE);
1915                                    }
1916    
1917                                    if (!line.contains(StringPool.QUOTE)) {
1918                                            int pos = line.indexOf(") ");
1919    
1920                                            if (pos != -1) {
1921                                                    String linePart = line.substring(pos + 2);
1922    
1923                                                    if (Character.isLetter(linePart.charAt(0)) &&
1924                                                            !linePart.startsWith("default") &&
1925                                                            !linePart.startsWith("instanceof") &&
1926                                                            !linePart.startsWith("throws")) {
1927    
1928                                                            line = StringUtil.replaceLast(
1929                                                                    line, StringPool.SPACE + linePart, linePart);
1930                                                    }
1931                                            }
1932    
1933                                            if ((trimmedLine.startsWith("private ") ||
1934                                                     trimmedLine.startsWith("protected ") ||
1935                                                     trimmedLine.startsWith("public ")) &&
1936                                                    line.contains(" (")) {
1937    
1938                                                    line = StringUtil.replace(line, " (", "(");
1939                                            }
1940    
1941                                            if (line.contains(" [")) {
1942                                                    line = StringUtil.replace(line, " [", "[");
1943                                            }
1944    
1945                                            for (int x = -1;;) {
1946                                                    int posComma = line.indexOf(StringPool.COMMA, x + 1);
1947                                                    int posSemicolon = line.indexOf(
1948                                                            StringPool.SEMICOLON, x + 1);
1949    
1950                                                    if ((posComma == -1) && (posSemicolon == -1)) {
1951                                                            break;
1952                                                    }
1953    
1954                                                    x = Math.min(posComma, posSemicolon);
1955    
1956                                                    if (x == -1) {
1957                                                            x = Math.max(posComma, posSemicolon);
1958                                                    }
1959    
1960                                                    if (line.length() > (x + 1)) {
1961                                                            char nextChar = line.charAt(x + 1);
1962    
1963                                                            if ((nextChar != CharPool.APOSTROPHE) &&
1964                                                                    (nextChar != CharPool.CLOSE_PARENTHESIS) &&
1965                                                                    (nextChar != CharPool.SPACE) &&
1966                                                                    (nextChar != CharPool.STAR)) {
1967    
1968                                                                    line = StringUtil.insert(
1969                                                                            line, StringPool.SPACE, x + 1);
1970                                                            }
1971                                                    }
1972    
1973                                                    if (x > 0) {
1974                                                            char previousChar = line.charAt(x - 1);
1975    
1976                                                            if (previousChar == CharPool.SPACE) {
1977                                                                    line = line.substring(0, x - 1).concat(
1978                                                                            line.substring(x));
1979                                                            }
1980                                                    }
1981                                            }
1982                                    }
1983    
1984                                    if ((line.contains(" && ") || line.contains(" || ")) &&
1985                                            line.endsWith(StringPool.OPEN_PARENTHESIS)) {
1986    
1987                                            _processErrorMessage(
1988                                                    fileName, "line break: " + fileName + " " + lineCount);
1989                                    }
1990    
1991                                    if (trimmedLine.endsWith(StringPool.PLUS) &&
1992                                            !trimmedLine.startsWith(StringPool.OPEN_PARENTHESIS)) {
1993    
1994                                            String strippedQuotesLine = _stripQuotes(
1995                                                    trimmedLine, StringPool.QUOTE);
1996    
1997                                            int closeParenthesisCount = StringUtil.count(
1998                                                    strippedQuotesLine, StringPool.CLOSE_PARENTHESIS);
1999                                            int openParenthesisCount = StringUtil.count(
2000                                                    strippedQuotesLine, StringPool.OPEN_PARENTHESIS);
2001    
2002                                            if (openParenthesisCount > closeParenthesisCount) {
2003                                                    _processErrorMessage(
2004                                                            fileName,
2005                                                            "line break: " + fileName + " " + lineCount);
2006                                            }
2007                                    }
2008    
2009                                    if (line.contains(StringPool.COMMA) &&
2010                                            !line.contains(StringPool.CLOSE_PARENTHESIS) &&
2011                                            !line.contains(StringPool.GREATER_THAN) &&
2012                                            !line.contains(StringPool.QUOTE) &&
2013                                            line.endsWith(StringPool.OPEN_PARENTHESIS)) {
2014    
2015                                            _processErrorMessage(
2016                                                    fileName, "line break: " + fileName + " " + lineCount);
2017                                    }
2018    
2019                                    if (line.endsWith(" +") || line.endsWith(" -") ||
2020                                            line.endsWith(" *") || line.endsWith(" /")) {
2021    
2022                                            int x = line.indexOf(" = ");
2023    
2024                                            if (x != -1) {
2025                                                    int y = line.indexOf(StringPool.QUOTE);
2026    
2027                                                    if ((y == -1) || (x < y)) {
2028                                                            _processErrorMessage(
2029                                                                    fileName,
2030                                                                    "line break: " + fileName + " " + lineCount);
2031                                                    }
2032                                            }
2033                                    }
2034    
2035                                    if (line.endsWith(" throws") ||
2036                                            (previousLine.endsWith(
2037                                                    StringPool.OPEN_PARENTHESIS) &&
2038                                             line.contains(" throws " ) &&
2039                                             line.endsWith(StringPool.OPEN_CURLY_BRACE))) {
2040    
2041                                            _processErrorMessage(
2042                                                    fileName, "line break: " + fileName + " " + lineCount);
2043                                    }
2044                            }
2045    
2046                            if (line.contains("    ") && !line.matches("\\s*\\*.*")) {
2047                                    if (!fileName.endsWith("StringPool.java")) {
2048                                            _processErrorMessage(
2049                                                    fileName, "tab: " + fileName + " " + lineCount);
2050                                    }
2051                            }
2052    
2053                            if (line.contains("  {") && !line.matches("\\s*\\*.*")) {
2054                                    _processErrorMessage(
2055                                            fileName, "{:" + fileName + " " + lineCount);
2056                            }
2057    
2058                            excluded = null;
2059    
2060                            if (_lineLengthExclusions != null) {
2061                                    excluded = _lineLengthExclusions.getProperty(
2062                                            fileName + StringPool.AT + lineCount);
2063    
2064                                    if (excluded == null) {
2065                                            excluded = _lineLengthExclusions.getProperty(fileName);
2066                                    }
2067                            }
2068    
2069                            Tuple combinedLines = null;
2070                            int lineLength = _getLineLength(line);
2071    
2072                            if ((excluded == null) &&
2073                                    !line.startsWith("import ") && !line.startsWith("package ") &&
2074                                    !line.matches("\\s*\\*.*")) {
2075    
2076                                    if (fileName.endsWith("Table.java") &&
2077                                            line.contains("String TABLE_SQL_CREATE = ")) {
2078                                    }
2079                                    else if (fileName.endsWith("Table.java") &&
2080                                                     line.contains("String TABLE_SQL_DROP = ")) {
2081                                    }
2082                                    else if (fileName.endsWith("Table.java") &&
2083                                                     line.contains(" index IX_")) {
2084                                    }
2085                                    else if (lineLength > 80) {
2086                                            _processErrorMessage(
2087                                                    fileName, "> 80: " + fileName + " " + lineCount);
2088                                    }
2089                                    else {
2090                                            int lineLeadingTabCount = _getLeadingTabCount(line);
2091                                            int previousLineLeadingTabCount = _getLeadingTabCount(
2092                                                    previousLine);
2093    
2094                                            if (!trimmedLine.startsWith("//")) {
2095                                                    if (previousLine.endsWith(StringPool.COMMA) &&
2096                                                            previousLine.contains(
2097                                                                    StringPool.OPEN_PARENTHESIS) &&
2098                                                            !previousLine.contains("for (") &&
2099                                                            (lineLeadingTabCount >
2100                                                                    previousLineLeadingTabCount)) {
2101    
2102                                                            _processErrorMessage(
2103                                                                    fileName,
2104                                                                    "line break: " + fileName + " " + lineCount);
2105                                                    }
2106    
2107                                                    if (Validator.isNotNull(trimmedLine)) {
2108                                                            if (((previousLine.endsWith(StringPool.COLON) &&
2109                                                                      previousLine.contains(
2110                                                                              StringPool.TAB + "for ")) ||
2111                                                                     (previousLine.endsWith(
2112                                                                             StringPool.OPEN_PARENTHESIS) &&
2113                                                                      previousLine.contains(
2114                                                                              StringPool.TAB + "if "))) &&
2115                                                                    ((previousLineLeadingTabCount + 2) !=
2116                                                                            lineLeadingTabCount)) {
2117    
2118                                                            _processErrorMessage(
2119                                                                    fileName,
2120                                                                    "line break: " + fileName + " " + lineCount);
2121                                                            }
2122    
2123                                                            if (previousLine.endsWith(
2124                                                                            StringPool.OPEN_CURLY_BRACE) &&
2125                                                                    !trimmedLine.startsWith(
2126                                                                            StringPool.CLOSE_CURLY_BRACE) &&
2127                                                                    ((previousLineLeadingTabCount + 1) !=
2128                                                                            lineLeadingTabCount)) {
2129    
2130                                                                    _processErrorMessage(
2131                                                                            fileName,
2132                                                                            "tab: " + fileName + " " + lineCount);
2133                                                            }
2134                                                    }
2135    
2136                                                    if (previousLine.endsWith(StringPool.PERIOD)) {
2137                                                            int x = trimmedLine.indexOf(
2138                                                                    StringPool.OPEN_PARENTHESIS);
2139    
2140                                                            if ((x != -1) &&
2141                                                                    ((_getLineLength(previousLine) + x) < 80) &&
2142                                                                    (trimmedLine.endsWith(
2143                                                                            StringPool.OPEN_PARENTHESIS) ||
2144                                                                     (trimmedLine.charAt(x + 1) !=
2145                                                                             CharPool.CLOSE_PARENTHESIS))) {
2146    
2147                                                                    _processErrorMessage(
2148                                                                            fileName,
2149                                                                            "line break: " + fileName + " " +
2150                                                                                    lineCount);
2151                                                            }
2152                                                    }
2153    
2154                                                    if (trimmedLine.startsWith("throws ") &&
2155                                                            (lineLeadingTabCount ==
2156                                                                    previousLineLeadingTabCount)) {
2157    
2158                                                            _processErrorMessage(
2159                                                                    fileName, "tab: " + fileName + " " + lineCount);
2160                                                    }
2161    
2162                                                    if ((previousLine.contains(" class " ) ||
2163                                                             previousLine.contains(" enum ")) &&
2164                                                            previousLine.endsWith(
2165                                                                    StringPool.OPEN_CURLY_BRACE) &&
2166                                                            Validator.isNotNull(line) &&
2167                                                            !trimmedLine.startsWith(
2168                                                                    StringPool.CLOSE_CURLY_BRACE)) {
2169    
2170                                                            _processErrorMessage(
2171                                                                    fileName,
2172                                                                    "new line: " + fileName + " " + lineCount);
2173                                                    }
2174                                            }
2175    
2176                                            combinedLines = _getCombinedLines(
2177                                                    trimmedLine, previousLine, lineLeadingTabCount,
2178                                                    previousLineLeadingTabCount);
2179                                    }
2180                            }
2181    
2182                            if (combinedLines != null) {
2183                                    previousLine = (String)combinedLines.getObject(0);
2184    
2185                                    if (combinedLines.getSize() > 1) {
2186                                            String linePart = (String)combinedLines.getObject(1);
2187                                            boolean addToPreviousLine =
2188                                                    (Boolean)combinedLines.getObject(2);
2189    
2190                                            if (addToPreviousLine) {
2191                                                    previousLine = previousLine + linePart;
2192                                                    line = StringUtil.replaceFirst(
2193                                                            line, linePart, StringPool.BLANK);
2194                                            }
2195                                            else {
2196                                                    if (((linePart.length() + lineLength) <= 80) &&
2197                                                            (line.endsWith(StringPool.OPEN_CURLY_BRACE) ||
2198                                                             line.endsWith(StringPool.SEMICOLON))) {
2199    
2200                                                            previousLine = StringUtil.replaceLast(
2201                                                                    previousLine, StringUtil.trim(linePart),
2202                                                                    StringPool.BLANK);
2203    
2204                                                            line = StringUtil.replaceLast(
2205                                                                    line, StringPool.TAB,
2206                                                                    StringPool.TAB + linePart);
2207                                                    }
2208                                                    else {
2209                                                            _processErrorMessage(
2210                                                                    fileName,
2211                                                                    "line break: " + fileName + " " + lineCount);
2212                                                    }
2213                                            }
2214    
2215                                            sb.append(previousLine);
2216                                            sb.append("\n");
2217    
2218                                            previousLine = line;
2219                                    }
2220                                    else if (line.endsWith(StringPool.OPEN_CURLY_BRACE) &&
2221                                                     !previousLine.contains(" class ")) {
2222    
2223                                            lineToSkipIfEmpty = lineCount + 1;
2224                                    }
2225                            }
2226                            else {
2227                                    if ((lineCount > 1) &&
2228                                            (Validator.isNotNull(previousLine) ||
2229                                             (lineToSkipIfEmpty != (lineCount - 1)))) {
2230    
2231                                            sb.append(previousLine);
2232    
2233                                            if (Validator.isNotNull(previousLine) &&
2234                                                    Validator.isNotNull(trimmedLine) &&
2235                                                    !previousLine.contains("/*") &&
2236                                                    !previousLine.endsWith("*/")) {
2237    
2238                                                    String trimmedPreviousLine = StringUtil.trimLeading(
2239                                                            previousLine);
2240    
2241                                                    if ((trimmedPreviousLine.startsWith("// ") &&
2242                                                             !trimmedLine.startsWith("// ")) ||
2243                                                            (!trimmedPreviousLine.startsWith("// ") &&
2244                                                             trimmedLine.startsWith("// "))) {
2245    
2246                                                            sb.append("\n");
2247                                                    }
2248                                                    else if (!trimmedPreviousLine.endsWith(
2249                                                                            StringPool.OPEN_CURLY_BRACE) &&
2250                                                                     !trimmedPreviousLine.endsWith(
2251                                                                            StringPool.COLON) &&
2252                                                                     (trimmedLine.startsWith("for (") ||
2253                                                                      trimmedLine.startsWith("if ("))) {
2254    
2255                                                            sb.append("\n");
2256                                                    }
2257                                                    else if (previousLine.endsWith(
2258                                                                            StringPool.TAB +
2259                                                                                    StringPool.CLOSE_CURLY_BRACE) &&
2260                                                                     !trimmedLine.startsWith(
2261                                                                             StringPool.CLOSE_CURLY_BRACE) &&
2262                                                                     !trimmedLine.startsWith(
2263                                                                             StringPool.CLOSE_PARENTHESIS) &&
2264                                                                     !trimmedLine.startsWith(
2265                                                                             StringPool.DOUBLE_SLASH) &&
2266                                                                     !trimmedLine.startsWith("catch ") &&
2267                                                                     !trimmedLine.startsWith("else ") &&
2268                                                                     !trimmedLine.startsWith("finally ") &&
2269                                                                     !trimmedLine.startsWith("while ")) {
2270    
2271                                                            sb.append("\n");
2272                                                    }
2273                                            }
2274    
2275                                            sb.append("\n");
2276                                    }
2277    
2278                                    previousLine = line;
2279                            }
2280    
2281                            index = index + line.length() + 1;
2282                    }
2283    
2284                    sb.append(previousLine);
2285    
2286                    unsyncBufferedReader.close();
2287    
2288                    String newContent = sb.toString();
2289    
2290                    if (newContent.endsWith("\n")) {
2291                            newContent = newContent.substring(0, newContent.length() - 1);
2292                    }
2293    
2294                    if (content.equals(newContent)) {
2295                            if (javaTermStartPosition != -1) {
2296                                    int javaTermEndPosition = content.length() - 2;
2297    
2298                                    String javaTermContent = content.substring(
2299                                            javaTermStartPosition, javaTermEndPosition);
2300    
2301                                    javaTerm = new JavaTerm(
2302                                            javaTermName, javaTermType, parameterTypes, javaTermContent,
2303                                            javaTermLineCount);
2304    
2305                                    javaTerms.add(javaTerm);
2306                            }
2307    
2308                            newContent = _sortJavaTerms(fileName, content, javaTerms);
2309                    }
2310    
2311                    return newContent;
2312            }
2313    
2314            private static void _formatJS() throws IOException {
2315                    String basedir = "./";
2316    
2317                    DirectoryScanner directoryScanner = new DirectoryScanner();
2318    
2319                    directoryScanner.setBasedir(basedir);
2320    
2321                    String[] excludes = {
2322                            "**\\js\\aui\\**", "**\\js\\editor\\**", "**\\js\\misc\\**",
2323                            "**\\tools\\**", "**\\VAADIN\\**"
2324                    };
2325    
2326                    excludes = ArrayUtil.append(excludes, _excludes);
2327    
2328                    directoryScanner.setExcludes(excludes);
2329    
2330                    directoryScanner.setIncludes(new String[] {"**\\*.js"});
2331    
2332                    List<String> fileNames = _sourceFormatterHelper.scanForFiles(
2333                            directoryScanner);
2334    
2335                    for (String fileName : fileNames) {
2336                            File file = new File(basedir + fileName);
2337    
2338                            fileName = StringUtil.replace(
2339                                    fileName, StringPool.BACK_SLASH, StringPool.SLASH);
2340    
2341                            String content = _fileUtil.read(file);
2342    
2343                            String newContent = _trimContent(content, false);
2344    
2345                            newContent = StringUtil.replace(
2346                                    newContent,
2347                                    new String[] {
2348                                            "else{", "for(", "function (", "if(", "while(", "){\n",
2349                                            "= new Array();", "= new Object();"
2350                                    },
2351                                    new String[] {
2352                                            "else {", "for (", "function(", "if (", "while (", ") {\n",
2353                                            "= [];", "= {};"
2354                                    });
2355    
2356                            Pattern pattern = Pattern.compile("\t+var \\w+\\, ");
2357    
2358                            for (;;) {
2359                                    Matcher matcher = pattern.matcher(newContent);
2360    
2361                                    if (!matcher.find()) {
2362                                            break;
2363                                    }
2364    
2365                                    String match = newContent.substring(
2366                                            matcher.start(), matcher.end());
2367    
2368                                    int pos = match.indexOf("var ");
2369    
2370                                    StringBundler sb = new StringBundler(4);
2371    
2372                                    sb.append(match.substring(0, match.length() - 2));
2373                                    sb.append(StringPool.SEMICOLON);
2374                                    sb.append("\n");
2375                                    sb.append(match.substring(0, pos + 4));
2376    
2377                                    newContent = StringUtil.replace(
2378                                            newContent, match, sb.toString());
2379                            }
2380    
2381                            if (newContent.endsWith("\n")) {
2382                                    newContent = newContent.substring(0, newContent.length() - 1);
2383                            }
2384    
2385                            _checkLanguageKeys(fileName, newContent, _languageKeyPattern);
2386    
2387                            if ((newContent != null) && !content.equals(newContent)) {
2388                                    _fileUtil.write(file, newContent);
2389    
2390                                    _sourceFormatterHelper.printError(fileName, file);
2391                            }
2392                    }
2393            }
2394    
2395            private static void _formatJSP() throws IOException {
2396                    String basedir = "./";
2397    
2398                    String copyright = _getCopyright();
2399                    String oldCopyright = _getOldCopyright();
2400    
2401                    DirectoryScanner directoryScanner = new DirectoryScanner();
2402    
2403                    directoryScanner.setBasedir(basedir);
2404    
2405                    String[] excludes = {
2406                            "**\\portal\\aui\\**", "**\\bin\\**", "**\\null.jsp", "**\\tmp\\**",
2407                            "**\\tools\\**"
2408                    };
2409    
2410                    excludes = ArrayUtil.append(excludes, _excludes);
2411    
2412                    directoryScanner.setExcludes(excludes);
2413    
2414                    directoryScanner.setIncludes(
2415                            new String[] {"**\\*.jsp", "**\\*.jspf", "**\\*.vm"});
2416    
2417                    List<String> fileNames = _sourceFormatterHelper.scanForFiles(
2418                            directoryScanner);
2419    
2420                    for (String fileName : fileNames) {
2421                            File file = new File(basedir + fileName);
2422    
2423                            fileName = StringUtil.replace(
2424                                    fileName, StringPool.BACK_SLASH, StringPool.SLASH);
2425    
2426                            String content = _fileUtil.read(file);
2427    
2428                            _jspContents.put(fileName, content);
2429                    }
2430    
2431                    boolean stripJSPImports = true;
2432    
2433                    for (String fileName : fileNames) {
2434                            File file = new File(basedir + fileName);
2435    
2436                            fileName = StringUtil.replace(
2437                                    fileName, StringPool.BACK_SLASH, StringPool.SLASH);
2438    
2439                            String content = _fileUtil.read(file);
2440    
2441                            String oldContent = content;
2442                            String newContent = StringPool.BLANK;
2443    
2444                            for (;;) {
2445                                    newContent = _formatJSP(fileName, oldContent);
2446    
2447                                    if (oldContent.equals(newContent)) {
2448                                            break;
2449                                    }
2450    
2451                                    oldContent = newContent;
2452                            }
2453    
2454                            newContent = StringUtil.replace(
2455                                    newContent,
2456                                    new String[] {
2457                                            "<br/>", "\"/>", "\" >", "@page import", "\"%>", ")%>",
2458                                            "javascript: "
2459                                    },
2460                                    new String[] {
2461                                            "<br />", "\" />", "\">", "@ page import", "\" %>", ") %>",
2462                                            "javascript:"
2463                                    });
2464    
2465                            if (stripJSPImports) {
2466                                    try {
2467                                            newContent = _stripJSPImports(fileName, newContent);
2468                                    }
2469                                    catch (RuntimeException re) {
2470                                            stripJSPImports = false;
2471                                    }
2472                            }
2473    
2474                            newContent = _fixCopyright(
2475                                    newContent, copyright, oldCopyright, file, fileName);
2476    
2477                            newContent = StringUtil.replace(
2478                                    newContent,
2479                                    new String[] {
2480                                            "alert('<%= LanguageUtil.",
2481                                            "alert(\"<%= LanguageUtil.", "confirm('<%= LanguageUtil.",
2482                                            "confirm(\"<%= LanguageUtil."
2483                                    },
2484                                    new String[] {
2485                                            "alert('<%= UnicodeLanguageUtil.",
2486                                            "alert(\"<%= UnicodeLanguageUtil.",
2487                                            "confirm('<%= UnicodeLanguageUtil.",
2488                                            "confirm(\"<%= UnicodeLanguageUtil."
2489                                    });
2490    
2491                            if (newContent.contains("    ")) {
2492                                    if (!fileName.matches(".*template.*\\.vm$")) {
2493                                            _processErrorMessage(fileName, "tab: " + fileName);
2494                                    }
2495                            }
2496    
2497                            if (fileName.endsWith("init.jsp")) {
2498                                    int x = newContent.indexOf("<%@ page import=");
2499    
2500                                    int y = newContent.lastIndexOf("<%@ page import=");
2501    
2502                                    y = newContent.indexOf("%>", y);
2503    
2504                                    if ((x != -1) && (y != -1) && (y > x)) {
2505    
2506                                            // Set compressImports to false to decompress imports
2507    
2508                                            boolean compressImports = true;
2509    
2510                                            if (compressImports) {
2511                                                    String imports = newContent.substring(x, y);
2512    
2513                                                    imports = StringUtil.replace(
2514                                                            imports, new String[] {"%>\r\n<%@ ", "%>\n<%@ "},
2515                                                            new String[] {"%><%@\r\n", "%><%@\n"});
2516    
2517                                                    newContent =
2518                                                            newContent.substring(0, x) + imports +
2519                                                                    newContent.substring(y);
2520                                            }
2521                                    }
2522                            }
2523    
2524                            newContent = _fixSessionKey(
2525                                    fileName, newContent, _sessionKeyPattern);
2526                            newContent = _fixSessionKey(
2527                                    fileName, newContent, _taglibSessionKeyPattern);
2528    
2529                            _checkLanguageKeys(fileName, newContent, _languageKeyPattern);
2530                            _checkLanguageKeys(fileName, newContent, _taglibLanguageKeyPattern);
2531                            _checkXSS(fileName, newContent);
2532    
2533                            if ((newContent != null) && !content.equals(newContent)) {
2534                                    _fileUtil.write(file, newContent);
2535    
2536                                    _sourceFormatterHelper.printError(fileName, file);
2537                            }
2538                    }
2539            }
2540    
2541            private static String _formatJSP(String fileName, String content)
2542                    throws IOException {
2543    
2544                    StringBundler sb = new StringBundler();
2545    
2546                    UnsyncBufferedReader unsyncBufferedReader = new UnsyncBufferedReader(
2547                            new UnsyncStringReader(content));
2548    
2549                    int lineCount = 0;
2550    
2551                    String line = null;
2552    
2553                    String previousLine = StringPool.BLANK;
2554    
2555                    String currentAttributeAndValue = null;
2556                    String previousAttribute = null;
2557                    String previousAttributeAndValue = null;
2558    
2559                    boolean readAttributes = false;
2560    
2561                    String currentException = null;
2562                    String previousException = null;
2563    
2564                    boolean hasUnsortedExceptions = false;
2565    
2566                    while ((line = unsyncBufferedReader.readLine()) != null) {
2567                            lineCount++;
2568    
2569                            if (!fileName.contains("jsonw") ||
2570                                    !fileName.endsWith("action.jsp")) {
2571    
2572                                    line = _trimLine(line, false);
2573                            }
2574    
2575                            if (line.contains("<aui:button ") &&
2576                                    line.contains("type=\"button\"")) {
2577    
2578                                    _processErrorMessage(
2579                                            fileName, "aui:button " + fileName + " " + lineCount);
2580                            }
2581    
2582                            String trimmedLine = StringUtil.trimLeading(line);
2583                            String trimmedPreviousLine = StringUtil.trimLeading(previousLine);
2584    
2585                            if (!trimmedLine.equals("%>") && line.contains("%>") &&
2586                                    !line.contains("--%>") && !line.contains(" %>")) {
2587    
2588                                    line = StringUtil.replace(line, "%>", " %>");
2589                            }
2590    
2591                            if (line.contains("<%=") && !line.contains("<%= ")) {
2592                                    line = StringUtil.replace(line, "<%=", "<%= ");
2593                            }
2594    
2595                            if (trimmedPreviousLine.equals("%>") && Validator.isNotNull(line) &&
2596                                    !trimmedLine.equals("-->")) {
2597    
2598                                    sb.append("\n");
2599                            }
2600                            else if (Validator.isNotNull(previousLine) &&
2601                                             !trimmedPreviousLine.equals("<!--") &&
2602                                             trimmedLine.equals("<%")) {
2603    
2604                                    sb.append("\n");
2605                            }
2606                            else if (trimmedPreviousLine.equals("<%") &&
2607                                             Validator.isNull(line)) {
2608    
2609                                    continue;
2610                            }
2611                            else if (trimmedPreviousLine.equals("<%") &&
2612                                             trimmedLine.startsWith("//")) {
2613    
2614                                    sb.append("\n");
2615                            }
2616                            else if (Validator.isNull(previousLine) &&
2617                                             trimmedLine.equals("%>") && (sb.index() > 2)) {
2618    
2619                                    String lineBeforePreviousLine = sb.stringAt(sb.index() - 3);
2620    
2621                                    if (!lineBeforePreviousLine.startsWith("//")) {
2622                                            sb.setIndex(sb.index() - 1);
2623                                    }
2624                            }
2625    
2626                            if ((trimmedLine.startsWith("if (") ||
2627                                     trimmedLine.startsWith("else if (") ||
2628                                     trimmedLine.startsWith("while (")) &&
2629                                    trimmedLine.endsWith(") {")) {
2630    
2631                                    _checkIfClauseParentheses(trimmedLine, fileName, lineCount);
2632                            }
2633    
2634                            if (readAttributes) {
2635                                    if (!trimmedLine.startsWith(StringPool.FORWARD_SLASH) &&
2636                                            !trimmedLine.startsWith(StringPool.GREATER_THAN)) {
2637    
2638                                            int pos = trimmedLine.indexOf(StringPool.EQUAL);
2639    
2640                                            if (pos != -1) {
2641                                                    String attribute = trimmedLine.substring(0, pos);
2642    
2643                                                    if (!trimmedLine.endsWith(StringPool.QUOTE) &&
2644                                                            !trimmedLine.endsWith(StringPool.APOSTROPHE)) {
2645    
2646                                                            _processErrorMessage(
2647                                                                    fileName,
2648                                                                    "attribute: " + fileName + " " + lineCount);
2649    
2650                                                            readAttributes = false;
2651                                                    }
2652                                                    else if (trimmedLine.endsWith(StringPool.APOSTROPHE) &&
2653                                                                     !trimmedLine.contains(StringPool.QUOTE)) {
2654    
2655                                                            line = StringUtil.replace(
2656                                                                    line, StringPool.APOSTROPHE, StringPool.QUOTE);
2657    
2658                                                            readAttributes = false;
2659                                                    }
2660                                                    else if (Validator.isNotNull(previousAttribute)) {
2661                                                            if (!_isJSPAttributName(attribute)) {
2662                                                                    _processErrorMessage(
2663                                                                            fileName,
2664                                                                            "attribute: " + fileName + " " + lineCount);
2665    
2666                                                                    readAttributes = false;
2667                                                            }
2668                                                            else if (Validator.isNull(
2669                                                                                    previousAttributeAndValue) &&
2670                                                                             (previousAttribute.compareTo(
2671                                                                                     attribute) > 0)) {
2672    
2673                                                                    previousAttributeAndValue = previousLine;
2674                                                                    currentAttributeAndValue = line;
2675                                                            }
2676                                                    }
2677    
2678                                                    if (!readAttributes) {
2679                                                            previousAttribute = null;
2680                                                            previousAttributeAndValue = null;
2681                                                    }
2682                                                    else {
2683                                                            previousAttribute = attribute;
2684                                                    }
2685                                            }
2686                                    }
2687                                    else {
2688                                            previousAttribute = null;
2689    
2690                                            readAttributes = false;
2691                                    }
2692                            }
2693    
2694                            if (!hasUnsortedExceptions) {
2695                                    int i = line.indexOf("<liferay-ui:error exception=\"<%=");
2696    
2697                                    if (i != -1) {
2698                                            currentException = line.substring(i + 33);
2699    
2700                                            if (Validator.isNotNull(previousException) &&
2701                                                    (previousException.compareTo(currentException) > 0)) {
2702    
2703                                                    hasUnsortedExceptions = true;
2704                                            }
2705                                    }
2706    
2707                                    if (!hasUnsortedExceptions) {
2708                                            previousException = currentException;
2709                                            currentException = null;
2710                                    }
2711                            }
2712    
2713                            if (trimmedLine.startsWith(StringPool.LESS_THAN) &&
2714                                    !trimmedLine.startsWith("<%") &&
2715                                    !trimmedLine.startsWith("<!")) {
2716    
2717                                    if (!trimmedLine.contains(StringPool.GREATER_THAN) &&
2718                                            !trimmedLine.contains(StringPool.SPACE)) {
2719    
2720                                            readAttributes = true;
2721                                    }
2722                                    else {
2723                                            line = _sortJSPAttributes(fileName, line, lineCount);
2724                                    }
2725                            }
2726    
2727                            if (!trimmedLine.contains(StringPool.DOUBLE_SLASH) &&
2728                                    !trimmedLine.startsWith(StringPool.STAR)) {
2729    
2730                                    while (trimmedLine.contains(StringPool.TAB)) {
2731                                            line = StringUtil.replaceLast(
2732                                                    line, StringPool.TAB, StringPool.SPACE);
2733    
2734                                            trimmedLine = StringUtil.replaceLast(
2735                                                    trimmedLine, StringPool.TAB, StringPool.SPACE);
2736                                    }
2737    
2738                                    while (trimmedLine.contains(StringPool.DOUBLE_SPACE) &&
2739                                               !trimmedLine.contains(
2740                                                       StringPool.QUOTE + StringPool.DOUBLE_SPACE) &&
2741                                               !fileName.endsWith(".vm")) {
2742    
2743                                            line = StringUtil.replaceLast(
2744                                                    line, StringPool.DOUBLE_SPACE, StringPool.SPACE);
2745    
2746                                            trimmedLine = StringUtil.replaceLast(
2747                                                    trimmedLine, StringPool.DOUBLE_SPACE, StringPool.SPACE);
2748                                    }
2749                            }
2750    
2751                            if (!fileName.endsWith("/touch.jsp")) {
2752                                    int x = line.indexOf("<%@ include file");
2753    
2754                                    if (x != -1) {
2755                                            x = line.indexOf(StringPool.QUOTE, x);
2756    
2757                                            int y = line.indexOf(StringPool.QUOTE, x + 1);
2758    
2759                                            if (y != -1) {
2760                                                    String includeFileName = line.substring(x + 1, y);
2761    
2762                                                    Matcher matcher = _jspIncludeFilePattern.matcher(
2763                                                            includeFileName);
2764    
2765                                                    if (!matcher.find()) {
2766                                                            _processErrorMessage(
2767                                                                    fileName,
2768                                                                    "include: " + fileName + " " + lineCount);
2769                                                    }
2770                                            }
2771                                    }
2772                            }
2773    
2774                            line = _replacePrimitiveWrapperInstantiation(
2775                                    fileName, line, lineCount);
2776    
2777                            previousLine = line;
2778    
2779                            sb.append(line);
2780                            sb.append("\n");
2781                    }
2782    
2783                    unsyncBufferedReader.close();
2784    
2785                    content = sb.toString();
2786    
2787                    if (content.endsWith("\n")) {
2788                            content = content.substring(0, content.length() - 1);
2789                    }
2790    
2791                    content = _formatTaglibQuotes(fileName, content, StringPool.QUOTE);
2792                    content = _formatTaglibQuotes(fileName, content, StringPool.APOSTROPHE);
2793    
2794                    if (Validator.isNotNull(previousAttributeAndValue)) {
2795                            content = StringUtil.replaceFirst(
2796                                    content,
2797                                    previousAttributeAndValue + "\n" + currentAttributeAndValue,
2798                                    currentAttributeAndValue + "\n" + previousAttributeAndValue);
2799                    }
2800    
2801                    if (hasUnsortedExceptions) {
2802                            if ((StringUtil.count(content, currentException) > 1) ||
2803                                    (StringUtil.count(content, previousException) > 1)) {
2804    
2805                                    _processErrorMessage(
2806                                            fileName, "unsorted exceptions: " + fileName);
2807                            }
2808                            else {
2809                                    content = StringUtil.replaceFirst(
2810                                            content, previousException, currentException);
2811    
2812                                    content = StringUtil.replaceLast(
2813                                            content, currentException, previousException);
2814                            }
2815                    }
2816    
2817                    return content;
2818            }
2819    
2820            private static void _formatPortalProperties() throws IOException {
2821                    String basedir = "./";
2822    
2823                    String portalPortalProperties = null;
2824    
2825                    if (_portalSource) {
2826                            File portalPortalPropertiesFile = new File(
2827                                    basedir + "portal-impl/src/portal.properties");
2828    
2829                            portalPortalProperties = _fileUtil.read(portalPortalPropertiesFile);
2830                    }
2831                    else {
2832                            portalPortalProperties = ContentUtil.get("portal.properties");
2833                    }
2834    
2835                    DirectoryScanner directoryScanner = new DirectoryScanner();
2836    
2837                    directoryScanner.setBasedir(basedir);
2838    
2839                    String[] excludes = _excludes;
2840    
2841                    if (_portalSource) {
2842                            excludes = ArrayUtil.append(
2843                                    excludes, new String[] {"**\\classes\\**", "**\\bin\\**"});
2844    
2845                            directoryScanner.setIncludes(
2846                                    new String[] {
2847                                            "**\\portal-ext.properties",
2848                                            "**\\portal-legacy-*.properties",
2849                                    });
2850                    }
2851                    else {
2852                            directoryScanner.setIncludes(
2853                                    new String[] {
2854                                            "**\\portal.properties", "**\\portal-ext.properties"
2855                                    });
2856                    }
2857    
2858                    directoryScanner.setExcludes(excludes);
2859    
2860                    List<String> fileNames = _sourceFormatterHelper.scanForFiles(
2861                            directoryScanner);
2862    
2863                    for (String fileName : fileNames) {
2864                            File file = new File(basedir + fileName);
2865    
2866                            fileName = StringUtil.replace(
2867                                    fileName, StringPool.BACK_SLASH, StringPool.SLASH);
2868    
2869                            String content = _fileUtil.read(file);
2870    
2871                            _formatPortalProperties(fileName, content, portalPortalProperties);
2872                    }
2873            }
2874    
2875            private static void _formatPortalProperties(
2876                            String fileName, String content, String portalPortalProperties)
2877                    throws IOException {
2878    
2879                    UnsyncBufferedReader unsyncBufferedReader = new UnsyncBufferedReader(
2880                            new UnsyncStringReader(content));
2881    
2882                    int lineCount = 0;
2883    
2884                    String line = null;
2885    
2886                    int previousPos = -1;
2887    
2888                    while ((line = unsyncBufferedReader.readLine()) != null) {
2889                            lineCount++;
2890    
2891                            int pos = line.indexOf(StringPool.EQUAL);
2892    
2893                            if (pos == -1) {
2894                                    continue;
2895                            }
2896    
2897                            String property = line.substring(0, pos + 1);
2898    
2899                            property = property.trim();
2900    
2901                            pos = portalPortalProperties.indexOf(
2902                                    StringPool.FOUR_SPACES + property);
2903    
2904                            if (pos == -1) {
2905                                    continue;
2906                            }
2907    
2908                            if (pos < previousPos) {
2909                                    _processErrorMessage(
2910                                            fileName, "sort " + fileName + " " + lineCount);
2911                            }
2912    
2913                            previousPos = pos;
2914                    }
2915            }
2916    
2917            private static void _formatPortletXML()
2918                    throws DocumentException, IOException {
2919    
2920                    String basedir = "./";
2921    
2922                    if (_portalSource) {
2923                            File file = new File(
2924                                    basedir + "portal-web/docroot/WEB-INF/portlet-custom.xml");
2925    
2926                            String content = _fileUtil.read(file);
2927    
2928                            String newContent = _formatPortletXML(content);
2929    
2930                            if ((newContent != null) && !content.equals(newContent)) {
2931                                    _fileUtil.write(file, newContent);
2932    
2933                                    _sourceFormatterHelper.printError(file.toString(), file);
2934                            }
2935                    }
2936                    else {
2937                            DirectoryScanner directoryScanner = new DirectoryScanner();
2938    
2939                            directoryScanner.setBasedir(basedir);
2940                            directoryScanner.setExcludes(_excludes);
2941                            directoryScanner.setIncludes(new String[] {"**\\portlet.xml"});
2942    
2943                            List<String> fileNames = _sourceFormatterHelper.scanForFiles(
2944                                    directoryScanner);
2945    
2946                            for (String fileName : fileNames) {
2947                                    File file = new File(basedir + fileName);
2948    
2949                                    String content = _fileUtil.read(file);
2950    
2951                                    String newContent = _trimContent(content, false);
2952    
2953                                    newContent = _formatPortletXML(content);
2954    
2955                                    if ((newContent != null) && !content.equals(newContent)) {
2956                                            _fileUtil.write(file, newContent);
2957    
2958                                            fileName = StringUtil.replace(
2959                                                    fileName, StringPool.BACK_SLASH, StringPool.SLASH);
2960    
2961                                            _sourceFormatterHelper.printError(fileName, file);
2962                                    }
2963                            }
2964                    }
2965            }
2966    
2967            private static String _formatPortletXML(String content)
2968                    throws DocumentException, IOException {
2969    
2970                    Document document = _saxReaderUtil.read(content);
2971    
2972                    Element rootElement = document.getRootElement();
2973    
2974                    rootElement.sortAttributes(true);
2975    
2976                    List<Element> portletElements = rootElement.elements("portlet");
2977    
2978                    for (Element portletElement : portletElements) {
2979                            portletElement.sortElementsByChildElement("init-param", "name");
2980    
2981                            Element portletPreferencesElement = portletElement.element(
2982                                    "portlet-preferences");
2983    
2984                            if (portletPreferencesElement != null) {
2985                                    portletPreferencesElement.sortElementsByChildElement(
2986                                            "preference", "name");
2987                            }
2988                    }
2989    
2990                    return document.formattedString();
2991            }
2992    
2993            private static void _formatServiceXML()
2994                    throws DocumentException, IOException {
2995    
2996                    String basedir = "./";
2997    
2998                    DirectoryScanner directoryScanner = new DirectoryScanner();
2999    
3000                    directoryScanner.setBasedir(basedir);
3001                    directoryScanner.setExcludes(_excludes);
3002                    directoryScanner.setIncludes(new String[] {"**\\service.xml"});
3003    
3004                    List<String> fileNames = _sourceFormatterHelper.scanForFiles(
3005                            directoryScanner);
3006    
3007                    for (String fileName : fileNames) {
3008                            File file = new File(basedir + fileName);
3009    
3010                            fileName = StringUtil.replace(
3011                                    fileName, StringPool.BACK_SLASH, StringPool.SLASH);
3012    
3013                            String content = _fileUtil.read(file);
3014    
3015                            String newContent = _trimContent(content, false);
3016    
3017                            _formatServiceXML(fileName, content);
3018    
3019                            if ((newContent != null) && !content.equals(newContent)) {
3020                                    _fileUtil.write(file, newContent);
3021    
3022                                    _sourceFormatterHelper.printError(fileName, file);
3023                            }
3024                    }
3025            }
3026    
3027            private static void _formatServiceXML(String fileName, String content)
3028                    throws DocumentException {
3029    
3030                    Document document = _saxReaderUtil.read(content);
3031    
3032                    Element rootElement = document.getRootElement();
3033    
3034                    List<Element> entityElements = rootElement.elements("entity");
3035    
3036                    String previousEntityName = StringPool.BLANK;
3037    
3038                    for (Element entityElement : entityElements) {
3039                            String entityName = entityElement.attributeValue("name");
3040    
3041                            if (Validator.isNotNull(previousEntityName) &&
3042                                    (previousEntityName.compareToIgnoreCase(entityName) > 0)) {
3043    
3044                                    _processErrorMessage(
3045                                            fileName, "sort: " + fileName + " " + entityName);
3046                            }
3047    
3048                            String previousReferenceEntity = StringPool.BLANK;
3049                            String previousReferencePackagePath = StringPool.BLANK;
3050    
3051                            List<Element> referenceElements = entityElement.elements(
3052                                    "reference");
3053    
3054                            for (Element referenceElement : referenceElements) {
3055                                    String referenceEntity = referenceElement.attributeValue(
3056                                            "entity");
3057                                    String referencePackagePath = referenceElement.attributeValue(
3058                                            "package-path");
3059    
3060                                    if (Validator.isNotNull(previousReferencePackagePath)) {
3061                                            if ((previousReferencePackagePath.compareToIgnoreCase(
3062                                                            referencePackagePath) > 0) ||
3063                                                    (previousReferencePackagePath.equals(
3064                                                            referencePackagePath) &&
3065                                                     (previousReferenceEntity.compareToIgnoreCase(
3066                                                             referenceEntity) > 0))) {
3067    
3068                                                    _processErrorMessage(
3069                                                            fileName,
3070                                                            "sort: " + fileName + " " + referencePackagePath);
3071                                            }
3072                                    }
3073    
3074                                    previousReferenceEntity = referenceEntity;
3075                                    previousReferencePackagePath = referencePackagePath;
3076                            }
3077    
3078                            previousEntityName = entityName;
3079                    }
3080    
3081                    Element exceptionsElement = rootElement.element("exceptions");
3082    
3083                    if (exceptionsElement == null) {
3084                            return;
3085                    }
3086    
3087                    List<Element> exceptionElements = exceptionsElement.elements(
3088                            "exception");
3089    
3090                    String previousException = StringPool.BLANK;
3091    
3092                    for (Element exceptionElement : exceptionElements) {
3093                            String exception = exceptionElement.getStringValue();
3094    
3095                            if (Validator.isNotNull(previousException) &&
3096                                    (previousException.compareToIgnoreCase(exception) > 0)) {
3097    
3098                                    _processErrorMessage(
3099                                            fileName, "sort: " + fileName + " " + exception);
3100                            }
3101    
3102                            previousException = exception;
3103                    }
3104            }
3105    
3106            private static void _formatSH() throws IOException {
3107                    _formatSH("ext/create.sh");
3108                    _formatSH("hooks/create.sh");
3109                    _formatSH("layouttpl/create.sh");
3110                    _formatSH("portlets/create.sh");
3111                    _formatSH("themes/create.sh");
3112            }
3113    
3114            private static void _formatSH(String fileName) throws IOException {
3115                    File file = new File(fileName);
3116    
3117                    if (!file.exists()) {
3118                            return;
3119                    }
3120    
3121                    String content = _fileUtil.read(new File(fileName), true);
3122    
3123                    if (content.contains("\r")) {
3124                            _processErrorMessage(fileName, "Invalid new line character");
3125    
3126                            content = StringUtil.replace(content, "\r", "");
3127    
3128                            _fileUtil.write(fileName, content);
3129                    }
3130            }
3131    
3132            private static void _formatSQL() throws IOException {
3133                    String basedir = "./";
3134    
3135                    DirectoryScanner directoryScanner = new DirectoryScanner();
3136    
3137                    directoryScanner.setBasedir(basedir);
3138                    directoryScanner.setExcludes(_excludes);
3139                    directoryScanner.setIncludes(new String[] {"**\\sql\\*.sql"});
3140    
3141                    List<String> fileNames = _sourceFormatterHelper.scanForFiles(
3142                            directoryScanner);
3143    
3144                    for (String fileName : fileNames) {
3145                            File file = new File(basedir + fileName);
3146    
3147                            String content = _fileUtil.read(file);
3148    
3149                            String newContent = _formatSQL(content);
3150    
3151                            if ((newContent != null) && !content.equals(newContent)) {
3152                                    _fileUtil.write(file, newContent);
3153    
3154                                    fileName = StringUtil.replace(
3155                                            fileName, StringPool.BACK_SLASH, StringPool.SLASH);
3156    
3157                                    _sourceFormatterHelper.printError(fileName, file);
3158                            }
3159                    }
3160            }
3161    
3162            private static String _formatSQL(String content) throws IOException {
3163                    StringBundler sb = new StringBundler();
3164    
3165                    UnsyncBufferedReader unsyncBufferedReader = new UnsyncBufferedReader(
3166                            new UnsyncStringReader(content));
3167    
3168                    String line = null;
3169    
3170                    String previousLineSqlCommand = StringPool.BLANK;
3171    
3172                    while ((line = unsyncBufferedReader.readLine()) != null) {
3173                            line = _trimLine(line, false);
3174    
3175                            if (Validator.isNotNull(line) && !line.startsWith(StringPool.TAB)) {
3176                                    String sqlCommand = StringUtil.split(line, CharPool.SPACE)[0];
3177    
3178                                    if (Validator.isNotNull(previousLineSqlCommand) &&
3179                                            !previousLineSqlCommand.equals(sqlCommand)) {
3180    
3181                                            sb.append("\n");
3182                                    }
3183    
3184                                    previousLineSqlCommand = sqlCommand;
3185                            }
3186                            else {
3187                                    previousLineSqlCommand = StringPool.BLANK;
3188                            }
3189    
3190                            sb.append(line);
3191                            sb.append("\n");
3192                    }
3193    
3194                    unsyncBufferedReader.close();
3195    
3196                    content = sb.toString();
3197    
3198                    if (content.endsWith("\n")) {
3199                            content = content.substring(0, content.length() - 1);
3200                    }
3201    
3202                    return content;
3203            }
3204    
3205            private static void _formatStrutsConfigXML()
3206                    throws DocumentException, IOException {
3207    
3208                    String basedir = "./";
3209    
3210                    if (!_portalSource) {
3211                            return;
3212                    }
3213    
3214                    String fileName = "portal-web/docroot/WEB-INF/struts-config.xml";
3215    
3216                    File file = new File(basedir + fileName);
3217    
3218                    String content = _fileUtil.read(file);
3219    
3220                    String newContent = _trimContent(content, false);
3221    
3222                    Document document = _saxReaderUtil.read(newContent);
3223    
3224                    Element rootElement = document.getRootElement();
3225    
3226                    Element actionMappingsElement = rootElement.element("action-mappings");
3227    
3228                    List<Element> actionElements = actionMappingsElement.elements("action");
3229    
3230                    String previousPath = StringPool.BLANK;
3231    
3232                    for (Element actionElement : actionElements) {
3233                            String path = actionElement.attributeValue("path");
3234    
3235                            if (Validator.isNotNull(previousPath) &&
3236                                    (previousPath.compareTo(path) > 0) &&
3237                                    (!previousPath.startsWith("/portal/") ||
3238                                     path.startsWith("/portal/"))) {
3239    
3240                                    _processErrorMessage(
3241                                            fileName, "sort: " + fileName + " " + path);
3242                            }
3243    
3244                            previousPath = path;
3245                    }
3246    
3247                    if ((newContent != null) && !content.equals(newContent)) {
3248                            _fileUtil.write(file, newContent);
3249    
3250                            _sourceFormatterHelper.printError(fileName, file);
3251                    }
3252            }
3253    
3254            private static String _formatTaglibQuotes(
3255                    String fileName, String content, String quoteType) {
3256    
3257                    String quoteFix = StringPool.APOSTROPHE;
3258    
3259                    if (quoteFix.equals(quoteType)) {
3260                            quoteFix = StringPool.QUOTE;
3261                    }
3262    
3263                    Pattern pattern = Pattern.compile(_getTaglibRegex(quoteType));
3264    
3265                    Matcher matcher = pattern.matcher(content);
3266    
3267                    while (matcher.find()) {
3268                            int x = content.indexOf(quoteType + "<%=", matcher.start());
3269                            int y = content.indexOf("%>" + quoteType, x);
3270    
3271                            while ((x != -1) && (y != -1)) {
3272                                    String result = content.substring(x + 1, y + 2);
3273    
3274                                    if (result.contains(quoteType)) {
3275                                            int lineCount = 1;
3276    
3277                                            char[] contentCharArray = content.toCharArray();
3278    
3279                                            for (int i = 0; i < x; i++) {
3280                                                    if (contentCharArray[i] == CharPool.NEW_LINE) {
3281                                                            lineCount++;
3282                                                    }
3283                                            }
3284    
3285                                            if (!result.contains(quoteFix)) {
3286                                                    StringBundler sb = new StringBundler(5);
3287    
3288                                                    sb.append(content.substring(0, x));
3289                                                    sb.append(quoteFix);
3290                                                    sb.append(result);
3291                                                    sb.append(quoteFix);
3292                                                    sb.append(content.substring(y + 3, content.length()));
3293    
3294                                                    content = sb.toString();
3295                                            }
3296                                            else {
3297                                                    _processErrorMessage(
3298                                                            fileName, "taglib: " + fileName + " " + lineCount);
3299                                            }
3300                                    }
3301    
3302                                    x = content.indexOf(quoteType + "<%=", y);
3303    
3304                                    if (x > matcher.end()) {
3305                                            break;
3306                                    }
3307    
3308                                    y = content.indexOf("%>" + quoteType, x);
3309                            }
3310                    }
3311    
3312                    return content;
3313            }
3314    
3315            private static void _formatTilesDefsXML()
3316                    throws DocumentException, IOException {
3317    
3318                    String basedir = "./";
3319    
3320                    if (!_portalSource) {
3321                            return;
3322                    }
3323    
3324                    String fileName = "portal-web/docroot/WEB-INF/tiles-defs.xml";
3325    
3326                    File file = new File(basedir + fileName);
3327    
3328                    String content = _fileUtil.read(file);
3329    
3330                    String newContent = _trimContent(content, false);
3331    
3332                    Document document = _saxReaderUtil.read(newContent);
3333    
3334                    Element rootElement = document.getRootElement();
3335    
3336                    List<Element> definitionElements = rootElement.elements("definition");
3337    
3338                    String previousName = StringPool.BLANK;
3339    
3340                    for (Element definitionElement : definitionElements) {
3341                            String name = definitionElement.attributeValue("name");
3342    
3343                            if (Validator.isNotNull(previousName) &&
3344                                    (previousName.compareTo(name) > 0) &&
3345                                    !previousName.equals("portlet")) {
3346    
3347                                    _processErrorMessage(
3348                                            fileName, "sort: " + fileName + " " + name);
3349    
3350                            }
3351    
3352                            previousName = name;
3353                    }
3354    
3355                    if ((newContent != null) && !content.equals(newContent)) {
3356                            _fileUtil.write(file, newContent);
3357    
3358                            _sourceFormatterHelper.printError(fileName, file);
3359                    }
3360            }
3361    
3362            private static void _formatTLD() throws IOException {
3363                    String basedir = "./";
3364    
3365                    DirectoryScanner directoryScanner = new DirectoryScanner();
3366    
3367                    directoryScanner.setBasedir(basedir);
3368    
3369                    String[] excludes = {
3370                            "**\\classes\\**", "**\\bin\\**", "**\\WEB-INF\\tld\\**"
3371                    };
3372    
3373                    excludes = ArrayUtil.append(excludes, _excludes);
3374    
3375                    directoryScanner.setExcludes(excludes);
3376    
3377                    directoryScanner.setIncludes(new String[] {"**\\*.tld"});
3378    
3379                    List<String> fileNames = _sourceFormatterHelper.scanForFiles(
3380                            directoryScanner);
3381    
3382                    for (String fileName : fileNames) {
3383                            File file = new File(basedir + fileName);
3384    
3385                            String content = _fileUtil.read(file);
3386    
3387                            String newContent = _trimContent(content, false);
3388    
3389                            if ((newContent != null) && !content.equals(newContent)) {
3390                                    _fileUtil.write(file, newContent);
3391    
3392                                    fileName = StringUtil.replace(
3393                                            fileName, StringPool.BACK_SLASH, StringPool.SLASH);
3394    
3395                                    _sourceFormatterHelper.printError(fileName, file);
3396                            }
3397                    }
3398            }
3399    
3400            private static void _formatWebXML() throws IOException {
3401                    String basedir = "./";
3402    
3403                    if (_portalSource) {
3404                            Properties properties = new Properties();
3405    
3406                            String propertiesContent = _fileUtil.read(
3407                                    basedir + "portal-impl/src/portal.properties");
3408    
3409                            PropertiesUtil.load(properties, propertiesContent);
3410    
3411                            String[] locales = StringUtil.split(
3412                                    properties.getProperty(PropsKeys.LOCALES));
3413    
3414                            Arrays.sort(locales);
3415    
3416                            Set<String> urlPatterns = new TreeSet<String>();
3417    
3418                            for (String locale : locales) {
3419                                    int pos = locale.indexOf(StringPool.UNDERLINE);
3420    
3421                                    String languageCode = locale.substring(0, pos);
3422    
3423                                    urlPatterns.add(languageCode);
3424                                    urlPatterns.add(locale);
3425                            }
3426    
3427                            StringBundler sb = new StringBundler();
3428    
3429                            for (String urlPattern : urlPatterns) {
3430                                    sb.append("\t<servlet-mapping>\n");
3431                                    sb.append("\t\t<servlet-name>I18n Servlet</servlet-name>\n");
3432                                    sb.append(
3433                                            "\t\t<url-pattern>/" + urlPattern +"/*</url-pattern>\n");
3434                                    sb.append("\t</servlet-mapping>\n");
3435                            }
3436    
3437                            File file = new File(
3438                                    basedir + "portal-web/docroot/WEB-INF/web.xml");
3439    
3440                            String content = _fileUtil.read(file);
3441    
3442                            String newContent = _trimContent(content, false);
3443    
3444                            int x = newContent.indexOf("<servlet-mapping>");
3445    
3446                            x = newContent.indexOf(
3447                                    "<servlet-name>I18n Servlet</servlet-name>", x);
3448    
3449                            x = newContent.lastIndexOf("<servlet-mapping>", x) - 1;
3450    
3451                            int y = newContent.lastIndexOf(
3452                                    "<servlet-name>I18n Servlet</servlet-name>");
3453    
3454                            y = newContent.indexOf("</servlet-mapping>", y) + 19;
3455    
3456                            newContent =
3457                                    newContent.substring(0, x) + sb.toString() +
3458                                            newContent.substring(y);
3459    
3460                            x = newContent.indexOf("<security-constraint>");
3461    
3462                            x = newContent.indexOf(
3463                                    "<web-resource-name>/c/portal/protected</web-resource-name>",
3464                                    x);
3465    
3466                            x = newContent.indexOf("<url-pattern>", x) - 3;
3467    
3468                            y = newContent.indexOf("<http-method>", x);
3469    
3470                            y = newContent.lastIndexOf("</url-pattern>", y) + 15;
3471    
3472                            sb = new StringBundler();
3473    
3474                            sb.append("\t\t\t<url-pattern>/c/portal/protected</url-pattern>\n");
3475    
3476                            for (String urlPattern : urlPatterns) {
3477                                    sb.append(
3478                                            "\t\t\t<url-pattern>/" + urlPattern +
3479                                                    "/c/portal/protected</url-pattern>\n");
3480                            }
3481    
3482                            newContent =
3483                                    newContent.substring(0, x) + sb.toString() +
3484                                            newContent.substring(y);
3485    
3486                            if ((newContent != null) && !content.equals(newContent)) {
3487                                    _fileUtil.write(file, newContent);
3488    
3489                                    System.out.println(file);
3490                            }
3491                    }
3492                    else {
3493                            String webXML = ContentUtil.get(
3494                                    "com/liferay/portal/deploy/dependencies/web.xml");
3495    
3496                            DirectoryScanner directoryScanner = new DirectoryScanner();
3497    
3498                            directoryScanner.setBasedir(basedir);
3499                            directoryScanner.setExcludes(_excludes);
3500                            directoryScanner.setIncludes(new String[] {"**\\web.xml"});
3501    
3502                            List<String> fileNames = _sourceFormatterHelper.scanForFiles(
3503                                    directoryScanner);
3504    
3505                            for (String fileName : fileNames) {
3506                                    String content = _fileUtil.read(basedir + fileName);
3507    
3508                                    if (content.equals(webXML)) {
3509                                            fileName = StringUtil.replace(
3510                                                    fileName, StringPool.BACK_SLASH, StringPool.SLASH);
3511    
3512                                            _processErrorMessage(fileName, fileName);
3513                                    }
3514                            }
3515                    }
3516            }
3517    
3518            private static String _getClassName(String line) {
3519                    int pos = line.indexOf(" implements ");
3520    
3521                    if (pos == -1) {
3522                            pos = line.indexOf(" extends ");
3523                    }
3524    
3525                    if (pos == -1) {
3526                            pos = line.indexOf(StringPool.OPEN_CURLY_BRACE);
3527                    }
3528    
3529                    if (pos != -1) {
3530                            line = line.substring(0, pos);
3531                    }
3532    
3533                    line = line.trim();
3534    
3535                    pos = line.lastIndexOf(StringPool.SPACE);
3536    
3537                    return line.substring(pos + 1);
3538            }
3539    
3540            private static Tuple _getCombinedLines(
3541                    String line, String previousLine, int lineTabCount,
3542                    int previousLineTabCount) {
3543    
3544                    if (Validator.isNull(line) || Validator.isNull(previousLine)) {
3545                            return null;
3546                    }
3547    
3548                    String trimmedPreviousLine = StringUtil.trimLeading(previousLine);
3549    
3550                    int previousLineLength = _getLineLength(previousLine);
3551    
3552                    if (line.startsWith("// ") || trimmedPreviousLine.startsWith("// ")) {
3553                            String linePart = line.substring(3);
3554    
3555                            if (!linePart.startsWith("PLACEHOLDER") &&
3556                                    !linePart.startsWith(StringPool.OPEN_BRACKET)) {
3557    
3558                                    int pos = linePart.indexOf(StringPool.SPACE);
3559    
3560                                    if (pos == -1) {
3561                                            pos = linePart.length();
3562                                    }
3563    
3564                                    if (previousLineLength + pos < 80) {
3565                                            if (linePart.contains(StringPool.SPACE)) {
3566                                                    return new Tuple(
3567                                                            previousLine + StringPool.SPACE,
3568                                                            linePart.substring(0, pos + 1), true);
3569                                            }
3570                                            else {
3571                                                    return new Tuple(
3572                                                            previousLine + StringPool.SPACE + linePart);
3573                                            }
3574                                    }
3575                            }
3576    
3577                            return null;
3578                    }
3579    
3580                    if (previousLine.endsWith(" extends")) {
3581                            return new Tuple(previousLine, "extends ", false);
3582                    }
3583    
3584                    if (previousLine.endsWith(" implements")) {
3585                            return new Tuple(previousLine, "implements ", false);
3586                    }
3587    
3588                    if (line.startsWith("+ ") || line.startsWith("- ") ||
3589                            line.startsWith("|| ") || line.startsWith("&& ")) {
3590    
3591                            int pos = line.indexOf(StringPool.SPACE);
3592    
3593                            String linePart = line.substring(0, pos);
3594    
3595                            return new Tuple(previousLine + StringPool.SPACE, linePart, true);
3596                    }
3597    
3598                    if ((line.length() + previousLineLength) < 80) {
3599                            if (trimmedPreviousLine.startsWith("for ") &&
3600                                    previousLine.endsWith(StringPool.COLON) &&
3601                                    line.endsWith(StringPool.OPEN_CURLY_BRACE)) {
3602    
3603                                    return new Tuple(previousLine + StringPool.SPACE + line);
3604                            }
3605    
3606                            if ((previousLine.endsWith(StringPool.EQUAL) ||
3607                                     previousLine.endsWith(StringPool.PERIOD) ||
3608                                     trimmedPreviousLine.equals("return")) &&
3609                                    line.endsWith(StringPool.SEMICOLON)) {
3610    
3611                                    return new Tuple(previousLine + StringPool.SPACE + line);
3612                            }
3613    
3614                            if ((trimmedPreviousLine.startsWith("if ") ||
3615                                     trimmedPreviousLine.startsWith("else ")) &&
3616                                    (previousLine.endsWith("||") || previousLine.endsWith("&&")) &&
3617                                    line.endsWith(StringPool.OPEN_CURLY_BRACE)) {
3618    
3619                                    return new Tuple(previousLine + StringPool.SPACE + line);
3620                            }
3621    
3622                            if ((line.startsWith("extends ") ||
3623                                     line.startsWith("implements ") ||
3624                                     line.startsWith("throws")) &&
3625                                    line.endsWith(StringPool.OPEN_CURLY_BRACE) &&
3626                                    (lineTabCount == (previousLineTabCount + 1))) {
3627    
3628                                    return new Tuple(previousLine + StringPool.SPACE + line);
3629                            }
3630                    }
3631    
3632                    if (previousLine.endsWith(StringPool.EQUAL) &&
3633                            line.endsWith(StringPool.SEMICOLON)) {
3634    
3635                            String tempLine = line;
3636    
3637                            for (int pos = 0;;) {
3638                                    pos = tempLine.indexOf(StringPool.DASH);
3639    
3640                                    if (pos == -1) {
3641                                            pos = tempLine.indexOf(StringPool.PLUS);
3642                                    }
3643    
3644                                    if (pos == -1) {
3645                                            pos = tempLine.indexOf(StringPool.SLASH);
3646                                    }
3647    
3648                                    if (pos == -1) {
3649                                            pos = tempLine.indexOf(StringPool.STAR);
3650                                    }
3651    
3652                                    if (pos == -1) {
3653                                            pos = tempLine.indexOf("||");
3654                                    }
3655    
3656                                    if (pos == -1) {
3657                                            pos = tempLine.indexOf("&&");
3658                                    }
3659    
3660                                    if (pos == -1) {
3661                                            break;
3662                                    }
3663    
3664                                    String linePart = tempLine.substring(0, pos);
3665    
3666                                    int openParenthesisCount = StringUtil.count(
3667                                            linePart, StringPool.OPEN_PARENTHESIS);
3668                                    int closeParenthesisCount = StringUtil.count(
3669                                            linePart, StringPool.CLOSE_PARENTHESIS);
3670    
3671                                    if (openParenthesisCount == closeParenthesisCount) {
3672                                            return null;
3673                                    }
3674    
3675                                    tempLine =
3676                                            tempLine.substring(0, pos) + tempLine.substring(pos + 1);
3677                            }
3678    
3679                            int x = line.indexOf(StringPool.OPEN_PARENTHESIS);
3680    
3681                            if (x == 0) {
3682                                    x = line.indexOf(StringPool.OPEN_PARENTHESIS, 1);
3683                            }
3684    
3685                            if (x != -1) {
3686                                    int y = line.indexOf(StringPool.CLOSE_PARENTHESIS, x);
3687                                    int z = line.indexOf(StringPool.QUOTE);
3688    
3689                                    if (((x + 1) != y) && ((z == -1) || (z > x))) {
3690                                            char previousChar = line.charAt(x - 1);
3691    
3692                                            if ((previousChar != CharPool.CLOSE_PARENTHESIS) &&
3693                                                    (previousChar != CharPool.OPEN_PARENTHESIS) &&
3694                                                    (previousChar != CharPool.SPACE) &&
3695                                                    (previousLineLength + 1 + x) < 80) {
3696    
3697                                                    String linePart = line.substring(0, x + 1);
3698    
3699                                                    if (linePart.startsWith(StringPool.OPEN_PARENTHESIS) &&
3700                                                            !linePart.contains(
3701                                                                     StringPool.CLOSE_PARENTHESIS)) {
3702    
3703                                                            return null;
3704                                                    }
3705    
3706                                                    return new Tuple(
3707                                                            previousLine + StringPool.SPACE, linePart, true);
3708                                            }
3709                                    }
3710                            }
3711                    }
3712    
3713                    if (previousLine.endsWith(StringPool.COMMA) &&
3714                            (previousLineTabCount == lineTabCount) &&
3715                            !previousLine.contains(StringPool.CLOSE_CURLY_BRACE)) {
3716    
3717                            int x = line.indexOf(StringPool.COMMA);
3718    
3719                            if (x != -1) {
3720                                    while ((previousLineLength + 1 + x) < 80) {
3721                                            String linePart = line.substring(0, x + 1);
3722    
3723                                            if (_isValidJavaParameter(linePart)) {
3724                                                    if (line.equals(linePart)) {
3725                                                            return new Tuple(
3726                                                                    previousLine + StringPool.SPACE + linePart);
3727                                                    }
3728                                                    else {
3729                                                            return new Tuple(
3730                                                                    previousLine + StringPool.SPACE,
3731                                                                    linePart + StringPool.SPACE, true);
3732                                                    }
3733                                            }
3734    
3735                                            String partAfterComma = line.substring(x + 1);
3736    
3737                                            int pos = partAfterComma.indexOf(StringPool.COMMA);
3738    
3739                                            if (pos == -1) {
3740                                                    break;
3741                                            }
3742    
3743                                            x = x + pos + 1;
3744                                    }
3745                            }
3746                            else if (!line.endsWith(StringPool.OPEN_PARENTHESIS) &&
3747                                             !line.endsWith(StringPool.PLUS) &&
3748                                             !line.endsWith(StringPool.PERIOD) &&
3749                                             (!line.startsWith("new ") ||
3750                                              !line.endsWith(StringPool.OPEN_CURLY_BRACE)) &&
3751                                             ((line.length() + previousLineLength) < 80)) {
3752    
3753                                    return new Tuple(previousLine + StringPool.SPACE + line);
3754                            }
3755                    }
3756    
3757                    if (!previousLine.endsWith(StringPool.OPEN_PARENTHESIS)) {
3758                            return null;
3759                    }
3760    
3761                    if (StringUtil.count(previousLine, StringPool.OPEN_PARENTHESIS) > 1) {
3762                            int pos = trimmedPreviousLine.lastIndexOf(
3763                                    StringPool.OPEN_PARENTHESIS, trimmedPreviousLine.length() - 2);
3764    
3765                            if ((pos > 0) &&
3766                                    Character.isLetterOrDigit(
3767                                            trimmedPreviousLine.charAt(pos -1 ))) {
3768    
3769                                    String filePart = trimmedPreviousLine.substring(pos + 1);
3770    
3771                                    if (!filePart.contains(StringPool.CLOSE_PARENTHESIS) &&
3772                                            !filePart.contains(StringPool.QUOTE)) {
3773    
3774                                            return new Tuple(previousLine, filePart, false);
3775                                    }
3776                            }
3777                    }
3778    
3779                    if ((line.length() + previousLineLength) > 80) {
3780                            return null;
3781                    }
3782    
3783                    if (line.endsWith(StringPool.SEMICOLON)) {
3784                            return new Tuple(previousLine + line);
3785                    }
3786    
3787                    if (((line.endsWith(StringPool.OPEN_CURLY_BRACE) &&
3788                              !line.startsWith("new ")) ||
3789                             line.endsWith(StringPool.CLOSE_PARENTHESIS)) &&
3790                            (trimmedPreviousLine.startsWith("else ") ||
3791                             trimmedPreviousLine.startsWith("if ") ||
3792                             trimmedPreviousLine.startsWith("private ") ||
3793                             trimmedPreviousLine.startsWith("protected ") ||
3794                             trimmedPreviousLine.startsWith("public "))) {
3795    
3796                            return new Tuple(previousLine + line);
3797                    }
3798    
3799                    return null;
3800            }
3801    
3802            private static String _getConstructorOrMethodName(String line, int pos) {
3803                    line = line.substring(0, pos);
3804    
3805                    int x = line.lastIndexOf(StringPool.SPACE);
3806    
3807                    return line.substring(x + 1);
3808            }
3809    
3810            private static String _getCopyright() throws IOException {
3811                    String copyright = _fileUtil.read("copyright.txt");
3812    
3813                    if (Validator.isNull(copyright)) {
3814                            copyright = _fileUtil.read("../copyright.txt");
3815                    }
3816    
3817                    if (Validator.isNull(copyright)) {
3818                            copyright = _fileUtil.read("../../copyright.txt");
3819                    }
3820    
3821                    return copyright;
3822            }
3823    
3824            private static String _getCustomCopyright(File file) throws IOException {
3825                    String absolutePath = _fileUtil.getAbsolutePath(file);
3826    
3827                    for (int x = absolutePath.length();;) {
3828                            x = absolutePath.lastIndexOf(StringPool.SLASH, x);
3829    
3830                            if (x == -1) {
3831                                    break;
3832                            }
3833    
3834                            String copyright = _fileUtil.read(
3835                                    absolutePath.substring(0, x + 1) + "copyright.txt");
3836    
3837                            if (Validator.isNotNull(copyright)) {
3838                                    return copyright;
3839                            }
3840    
3841                            x = x - 1;
3842                    }
3843    
3844                    return null;
3845            }
3846    
3847            private static Tuple _getJavaTermTuple(String line) {
3848                    int pos = line.indexOf(StringPool.OPEN_PARENTHESIS);
3849    
3850                    if (line.startsWith(StringPool.TAB + "public static final ") &&
3851                            (line.contains(StringPool.EQUAL) ||
3852                            (line.endsWith(StringPool.SEMICOLON) && (pos == -1)))) {
3853    
3854                            return new Tuple(
3855                                    _getVariableName(line), _TYPE_VARIABLE_PUBLIC_STATIC_FINAL);
3856                    }
3857                    else if (line.startsWith(StringPool.TAB + "public static ")) {
3858                            if (line.contains(StringPool.EQUAL) ||
3859                                    (line.endsWith(StringPool.SEMICOLON) && (pos == -1))) {
3860    
3861                                    return new Tuple(
3862                                            _getVariableName(line), _TYPE_VARIABLE_PUBLIC_STATIC);
3863                            }
3864    
3865                            if (pos != -1) {
3866                                    return new Tuple(
3867                                            _getConstructorOrMethodName(line, pos),
3868                                            _TYPE_METHOD_PUBLIC_STATIC);
3869                            }
3870    
3871                            if (line.startsWith(StringPool.TAB + "public static class ") ||
3872                                    line.startsWith(StringPool.TAB + "public static enum")) {
3873    
3874                                    return new Tuple(
3875                                            _getClassName(line), _TYPE_CLASS_PUBLIC_STATIC);
3876                            }
3877                    }
3878                    else if (line.startsWith(StringPool.TAB + "public ")) {
3879                            if (line.contains(StringPool.EQUAL) ||
3880                                    (line.endsWith(StringPool.SEMICOLON) && (pos == -1))) {
3881    
3882                                    return new Tuple(_getVariableName(line), _TYPE_VARIABLE_PUBLIC);
3883                            }
3884    
3885                            if (pos != -1) {
3886                                    int spaceCount = StringUtil.count(
3887                                            line.substring(0, pos), StringPool.SPACE);
3888    
3889                                    if (spaceCount == 1) {
3890                                            return new Tuple(
3891                                                    _getConstructorOrMethodName(line, pos),
3892                                                    _TYPE_CONSTRUCTOR_PUBLIC);
3893                                    }
3894    
3895                                    if (spaceCount > 1) {
3896                                            return new Tuple(
3897                                                    _getConstructorOrMethodName(line, pos),
3898                                                    _TYPE_METHOD_PUBLIC);
3899                                    }
3900                            }
3901                            else if (line.startsWith(StringPool.TAB + "public class ") ||
3902                                             line.startsWith(StringPool.TAB + "public enum")) {
3903    
3904                                    return new Tuple(_getClassName(line), _TYPE_CLASS_PUBLIC);
3905                            }
3906                    }
3907                    else if (line.startsWith(StringPool.TAB + "protected static final ")) {
3908                            if (line.contains(StringPool.EQUAL) ||
3909                                    (line.endsWith(StringPool.SEMICOLON) && (pos == -1))) {
3910    
3911                                    return new Tuple(
3912                                            _getVariableName(line),
3913                                            _TYPE_VARIABLE_PROTECTED_STATIC_FINAL);
3914                            }
3915                    }
3916                    else if (line.startsWith(StringPool.TAB + "protected static ")) {
3917                            if (line.contains(StringPool.EQUAL) ||
3918                                    (line.endsWith(StringPool.SEMICOLON) && (pos == -1))) {
3919    
3920                                    return new Tuple(
3921                                            _getVariableName(line), _TYPE_VARIABLE_PROTECTED_STATIC);
3922                            }
3923    
3924                            if (pos != -1) {
3925                                    return new Tuple(
3926                                            _getConstructorOrMethodName(line, pos),
3927                                            _TYPE_METHOD_PROTECTED_STATIC);
3928                            }
3929    
3930                            if (line.startsWith(StringPool.TAB + "protected static class ") ||
3931                                    line.startsWith(StringPool.TAB + "protected static enum ")) {
3932    
3933                                    return new Tuple(
3934                                            _getClassName(line), _TYPE_CLASS_PROTECTED_STATIC);
3935                            }
3936                    }
3937                    else if (line.startsWith(StringPool.TAB + "protected ")) {
3938                            if (pos != -1) {
3939                                    if (!line.contains(StringPool.EQUAL)) {
3940                                            int spaceCount = StringUtil.count(
3941                                                    line.substring(0, pos), StringPool.SPACE);
3942    
3943                                            if (spaceCount == 1) {
3944                                                    return new Tuple(
3945                                                            _getConstructorOrMethodName(line, pos),
3946                                                            _TYPE_CONSTRUCTOR_PROTECTED);
3947                                            }
3948    
3949                                            if (spaceCount > 1) {
3950                                                    return new Tuple(
3951                                                            _getConstructorOrMethodName(line, pos),
3952                                                            _TYPE_METHOD_PROTECTED);
3953                                            }
3954                                    }
3955                            }
3956                            else if (line.startsWith(StringPool.TAB + "protected class ") ||
3957                                             line.startsWith(StringPool.TAB + "protected enum ")) {
3958    
3959                                    return new Tuple(_getClassName(line), _TYPE_CLASS_PROTECTED);
3960                            }
3961    
3962                            return new Tuple(_getVariableName(line), _TYPE_VARIABLE_PROTECTED);
3963                    }
3964                    else if (line.startsWith(StringPool.TAB + "private static final ")) {
3965                            if (line.contains(StringPool.EQUAL) ||
3966                                    (line.endsWith(StringPool.SEMICOLON) && (pos == -1))) {
3967    
3968                                    return new Tuple(
3969                                            _getVariableName(line),
3970                                            _TYPE_VARIABLE_PRIVATE_STATIC_FINAL);
3971                            }
3972                    }
3973                    else if (line.startsWith(StringPool.TAB + "private static ")) {
3974                            if (line.contains(StringPool.EQUAL) ||
3975                                    (line.endsWith(StringPool.SEMICOLON) && (pos == -1))) {
3976    
3977                                    return new Tuple(
3978                                            _getVariableName(line), _TYPE_VARIABLE_PRIVATE_STATIC);
3979                            }
3980    
3981                            if (pos != -1) {
3982                                    return new Tuple(
3983                                            _getConstructorOrMethodName(line, pos),
3984                                            _TYPE_METHOD_PRIVATE_STATIC);
3985                            }
3986    
3987                            if (line.startsWith(StringPool.TAB + "private static class ") ||
3988                                    line.startsWith(StringPool.TAB + "private static enum ")) {
3989    
3990                                    return new Tuple(
3991                                            _getClassName(line), _TYPE_CLASS_PRIVATE_STATIC);
3992                            }
3993                    }
3994                    else if (line.startsWith(StringPool.TAB + "private ")) {
3995                            if (line.contains(StringPool.EQUAL) ||
3996                                    (line.endsWith(StringPool.SEMICOLON) && (pos == -1))) {
3997    
3998                                    return new Tuple(
3999                                            _getVariableName(line), _TYPE_VARIABLE_PRIVATE);
4000                            }
4001    
4002                            if (pos != -1) {
4003                                    int spaceCount = StringUtil.count(
4004                                            line.substring(0, pos), StringPool.SPACE);
4005    
4006                                    if (spaceCount == 1) {
4007                                            return new Tuple(
4008                                                    _getConstructorOrMethodName(line, pos),
4009                                                    _TYPE_CONSTRUCTOR_PRIVATE);
4010                                    }
4011    
4012                                    if (spaceCount > 1) {
4013                                            return new Tuple(
4014                                                    _getConstructorOrMethodName(line, pos),
4015                                                    _TYPE_METHOD_PRIVATE);
4016                                    }
4017                            }
4018                            else if (line.startsWith(StringPool.TAB + "private class ") ||
4019                                             line.startsWith(StringPool.TAB + "private enum ")) {
4020    
4021                                    return new Tuple(_getClassName(line), _TYPE_CLASS_PRIVATE);
4022                            }
4023                    }
4024    
4025                    return null;
4026            }
4027    
4028            private static List<String> _getJSPDuplicateImports(
4029                    String fileName, String content, List<String> importLines) {
4030    
4031                    List<String> duplicateImports = new ArrayList<String>();
4032    
4033                    for (String importLine : importLines) {
4034                            int x = content.indexOf("<%@ include file=");
4035    
4036                            if (x == -1) {
4037                                    continue;
4038                            }
4039    
4040                            int y = content.indexOf("<%@ page import=");
4041    
4042                            if (y == -1) {
4043                                    continue;
4044                            }
4045    
4046                            if ((x < y) && _isJSPDuplicateImport(fileName, importLine, false)) {
4047                                    duplicateImports.add(importLine);
4048                            }
4049                    }
4050    
4051                    return duplicateImports;
4052            }
4053    
4054            private static String[] _getLanguageKeys(Matcher matcher) {
4055                    if (matcher.groupCount() > 0) {
4056                            String languageKey = matcher.group(1);
4057    
4058                            if (Validator.isNotNull(languageKey)) {
4059                                    return new String[] {languageKey};
4060                            }
4061                    }
4062    
4063                    StringBundler sb = new StringBundler();
4064    
4065                    String match = matcher.group();
4066    
4067                    int count = 0;
4068    
4069                    for (int i = 0; i < match.length(); i++) {
4070                            char c = match.charAt(i);
4071    
4072                            switch (c) {
4073                                    case CharPool.CLOSE_PARENTHESIS:
4074                                            if (count <= 1) {
4075                                                    return new String[0];
4076                                            }
4077    
4078                                            count--;
4079    
4080                                            break;
4081    
4082                                    case CharPool.OPEN_PARENTHESIS:
4083                                            count++;
4084    
4085                                            break;
4086    
4087                                    case CharPool.QUOTE:
4088                                            if (count > 1) {
4089                                                    break;
4090                                            }
4091    
4092                                            while (i < match.length()) {
4093                                                    i++;
4094    
4095                                                    if (match.charAt(i) == CharPool.QUOTE) {
4096                                                            String languageKey = sb.toString();
4097    
4098                                                            if (match.startsWith("names")) {
4099                                                                    return StringUtil.split(languageKey);
4100                                                            }
4101                                                            else {
4102                                                                    return new String[] {languageKey};
4103                                                            }
4104    
4105                                                    }
4106    
4107                                                    sb.append(match.charAt(i));
4108                                            }
4109                            }
4110                    }
4111    
4112                    return new String[0];
4113            }
4114    
4115            private static int _getLeadingTabCount(String line) {
4116                    int leadingTabCount = 0;
4117    
4118                    while (line.startsWith(StringPool.TAB)) {
4119                            line = line.substring(1);
4120    
4121                            leadingTabCount++;
4122                    }
4123    
4124                    return leadingTabCount;
4125            }
4126    
4127            private static int _getLineLength(String line) {
4128                    int lineLength = 0;
4129    
4130                    int tabLength = 4;
4131    
4132                    for (char c : line.toCharArray()) {
4133                            if (c == CharPool.TAB) {
4134                                    for (int i = 0; i < tabLength; i++) {
4135                                            lineLength++;
4136                                    }
4137    
4138                                    tabLength = 4;
4139                            }
4140                            else {
4141                                    lineLength++;
4142    
4143                                    tabLength--;
4144    
4145                                    if (tabLength <= 0) {
4146                                            tabLength = 4;
4147                                    }
4148                            }
4149                    }
4150    
4151                    return lineLength;
4152            }
4153    
4154            private static String _getOldCopyright() throws IOException {
4155                    String copyright = _fileUtil.read("old-copyright.txt");
4156    
4157                    if (Validator.isNull(copyright)) {
4158                            copyright = _fileUtil.read("../old-copyright.txt");
4159                    }
4160    
4161                    if (Validator.isNull(copyright)) {
4162                            copyright = _fileUtil.read("../../old-copyright.txt");
4163                    }
4164    
4165                    return copyright;
4166            }
4167    
4168            private static Properties _getPluginExclusionsProperties(String fileName)
4169                    throws IOException {
4170    
4171                    FileInputStream fileInputStream = null;
4172    
4173                    int level = 0;
4174    
4175                    try {
4176                            fileInputStream = new FileInputStream(fileName);
4177                    }
4178                    catch (FileNotFoundException fnfe) {
4179                    }
4180    
4181                    if (fileInputStream == null) {
4182                            try {
4183                                    fileInputStream = new FileInputStream("../" + fileName);
4184    
4185                                    level = 1;
4186                            }
4187                            catch (FileNotFoundException fnfe) {
4188                            }
4189                    }
4190    
4191                    if (fileInputStream == null) {
4192                            try {
4193                                    fileInputStream = new FileInputStream("../../" + fileName);
4194    
4195                                    level = 2;
4196                            }
4197                            catch (FileNotFoundException fnfe) {
4198                                    return null;
4199                            }
4200                    }
4201    
4202                    Properties properties = new Properties();
4203    
4204                    properties.load(fileInputStream);
4205    
4206                    if (level > 0) {
4207                            properties = _stripTopLevelDirectories(properties, level);
4208                    }
4209    
4210                    return properties;
4211            }
4212    
4213            private static Collection<String> _getPluginJavaFiles() {
4214                    String basedir = "./";
4215    
4216                    Collection<String> fileNames = new TreeSet<String>();
4217    
4218                    DirectoryScanner directoryScanner = new DirectoryScanner();
4219    
4220                    directoryScanner.setBasedir(basedir);
4221    
4222                    String[] excludes = {
4223                            "**\\bin\\**", "**\\model\\*Clp.java",
4224                            "**\\model\\impl\\*BaseImpl.java", "**\\model\\impl\\*Model.java",
4225                            "**\\model\\impl\\*ModelImpl.java",
4226                            "**\\service\\**\\service\\*Service.java",
4227                            "**\\service\\**\\service\\*ServiceClp.java",
4228                            "**\\service\\**\\service\\*ServiceFactory.java",
4229                            "**\\service\\**\\service\\*ServiceUtil.java",
4230                            "**\\service\\**\\service\\*ServiceWrapper.java",
4231                            "**\\service\\**\\service\\ClpSerializer.java",
4232                            "**\\service\\**\\service\\messaging\\*ClpMessageListener.java",
4233                            "**\\service\\**\\service\\persistence\\*Finder.java",
4234                            "**\\service\\**\\service\\persistence\\*Persistence.java",
4235                            "**\\service\\**\\service\\persistence\\*Util.java",
4236                            "**\\service\\base\\*ServiceBaseImpl.java",
4237                            "**\\service\\base\\*ServiceClpInvoker.java",
4238                            "**\\service\\http\\*JSONSerializer.java",
4239                            "**\\service\\http\\*ServiceHttp.java",
4240                            "**\\service\\http\\*ServiceJSON.java",
4241                            "**\\service\\http\\*ServiceSoap.java",
4242                            "**\\service\\persistence\\*PersistenceImpl.java", "**\\tmp\\**"
4243                    };
4244    
4245                    excludes = ArrayUtil.append(excludes, _excludes);
4246    
4247                    directoryScanner.setExcludes(excludes);
4248    
4249                    directoryScanner.setIncludes(new String[] {"**\\*.java"});
4250    
4251                    fileNames.addAll(_sourceFormatterHelper.scanForFiles(directoryScanner));
4252    
4253                    return fileNames;
4254            }
4255    
4256            private static Properties _getPortalExclusionsProperties(String fileName)
4257                    throws IOException {
4258    
4259                    Properties properties = new Properties();
4260    
4261                    ClassLoader classLoader = SourceFormatter.class.getClassLoader();
4262    
4263                    String sourceFormatterExclusions = System.getProperty(
4264                            "source-formatter-exclusions",
4265                            "com/liferay/portal/tools/dependencies/" + fileName);
4266    
4267                    URL url = classLoader.getResource(sourceFormatterExclusions);
4268    
4269                    if (url == null) {
4270                            return null;
4271                    }
4272    
4273                    InputStream inputStream = url.openStream();
4274    
4275                    properties.load(inputStream);
4276    
4277                    inputStream.close();
4278    
4279                    return properties;
4280            }
4281    
4282            private static Collection<String> _getPortalJavaFiles() {
4283                    String basedir = "./";
4284    
4285                    Collection<String> fileNames = new TreeSet<String>();
4286    
4287                    DirectoryScanner directoryScanner = new DirectoryScanner();
4288    
4289                    directoryScanner.setBasedir(basedir);
4290    
4291                    String[] excludes = {
4292                            "**\\*_IW.java", "**\\PropsValues.java", "**\\bin\\**",
4293                            "**\\classes\\*", "**\\counter\\service\\**", "**\\jsp\\*",
4294                            "**\\model\\impl\\*BaseImpl.java", "**\\model\\impl\\*Model.java",
4295                            "**\\model\\impl\\*ModelImpl.java", "**\\portal\\service\\**",
4296                            "**\\portal-client\\**", "**\\portal-web\\classes\\**\\*.java",
4297                            "**\\portal-web\\test\\**\\*Test.java",
4298                            "**\\portal-web\\test\\**\\*Tests.java",
4299                            "**\\portlet\\**\\service\\**", "**\\test\\*-generated\\**",
4300                            "**\\tmp\\**", "**\\tools\\tck\\**"
4301                    };
4302    
4303                    excludes = ArrayUtil.append(excludes, _excludes);
4304    
4305                    directoryScanner.setExcludes(excludes);
4306    
4307                    directoryScanner.setIncludes(new String[] {"**\\*.java"});
4308    
4309                    fileNames.addAll(_sourceFormatterHelper.scanForFiles(directoryScanner));
4310    
4311                    directoryScanner = new DirectoryScanner();
4312    
4313                    directoryScanner.setBasedir(basedir);
4314    
4315                    excludes = new String[] {
4316                            "**\\bin\\**", "**\\portal-client\\**", "**\\tools\\ext_tmpl\\**",
4317                            "**\\*_IW.java", "**\\test\\**\\*PersistenceTest.java"
4318                    };
4319    
4320                    excludes = ArrayUtil.append(excludes, _excludes);
4321    
4322                    directoryScanner.setExcludes(excludes);
4323    
4324                    directoryScanner.setIncludes(
4325                            new String[] {
4326                                    "**\\com\\liferay\\portal\\service\\ServiceContext*.java",
4327                                    "**\\model\\BaseModel.java",
4328                                    "**\\model\\impl\\BaseModelImpl.java",
4329                                    "**\\service\\Base*.java",
4330                                    "**\\service\\PersistedModelLocalService*.java",
4331                                    "**\\service\\base\\PrincipalBean.java",
4332                                    "**\\service\\http\\*HttpTest.java",
4333                                    "**\\service\\http\\*SoapTest.java",
4334                                    "**\\service\\http\\TunnelUtil.java",
4335                                    "**\\service\\impl\\*.java", "**\\service\\jms\\*.java",
4336                                    "**\\service\\permission\\*.java",
4337                                    "**\\service\\persistence\\BasePersistence.java",
4338                                    "**\\service\\persistence\\BatchSession*.java",
4339                                    "**\\service\\persistence\\*FinderImpl.java",
4340                                    "**\\service\\persistence\\*Query.java",
4341                                    "**\\service\\persistence\\impl\\BasePersistenceImpl.java",
4342                                    "**\\portal-impl\\test\\**\\*.java",
4343                                    "**\\portal-service\\**\\liferay\\documentlibrary\\**.java",
4344                                    "**\\portal-service\\**\\liferay\\lock\\**.java",
4345                                    "**\\portal-service\\**\\liferay\\mail\\**.java",
4346                                    "**\\util-bridges\\**\\*.java"
4347                            });
4348    
4349                    fileNames.addAll(_sourceFormatterHelper.scanForFiles(directoryScanner));
4350    
4351                    return fileNames;
4352            }
4353    
4354            private static String _getTaglibRegex(String quoteType) {
4355                    StringBuilder sb = new StringBuilder();
4356    
4357                    sb.append("<(");
4358    
4359                    for (int i = 0; i < _TAG_LIBRARIES.length; i++) {
4360                            sb.append(_TAG_LIBRARIES[i]);
4361                            sb.append(StringPool.PIPE);
4362                    }
4363    
4364                    sb.deleteCharAt(sb.length() - 1);
4365                    sb.append("):([^>]|%>)*");
4366                    sb.append(quoteType);
4367                    sb.append("<%=.*");
4368                    sb.append(quoteType);
4369                    sb.append(".*%>");
4370                    sb.append(quoteType);
4371                    sb.append("([^>]|%>)*>");
4372    
4373                    return sb.toString();
4374            }
4375    
4376            private static String _getVariableName(String line) {
4377                    int x = line.indexOf(StringPool.EQUAL);
4378                    int y = line.lastIndexOf(StringPool.SPACE);
4379    
4380                    if (x != -1) {
4381                            line = line.substring(0, x);
4382                            line = StringUtil.trim(line);
4383    
4384                            y = line.lastIndexOf(StringPool.SPACE);
4385    
4386                            return line.substring(y + 1);
4387                    }
4388    
4389                    if (line.endsWith(StringPool.SEMICOLON)) {
4390                            return line.substring(y + 1, line.length() - 1);
4391                    }
4392    
4393                    return StringPool.BLANK;
4394            }
4395    
4396            private static boolean _hasAnnotationOrJavadoc(String s) {
4397                    if (s.startsWith(StringPool.TAB + StringPool.AT) ||
4398                            s.startsWith(StringPool.TAB + "/**")) {
4399    
4400                            return true;
4401                    }
4402                    else {
4403                            return false;
4404                    }
4405            }
4406    
4407            private static boolean _hasMissingParentheses(String s) {
4408                    if (Validator.isNull(s)) {
4409                            return false;
4410                    }
4411    
4412                    boolean containsAndOrOperator = (s.contains("&&") || s.contains("||"));
4413    
4414                    boolean containsCompareOperator =
4415                            (s.contains(" == ") || s.contains(" != ") || s.contains(" < ") ||
4416                             s.contains(" > ") || s.contains(" =< ") || s.contains(" => ") ||
4417                             s.contains(" <= ") || s.contains(" >= "));
4418    
4419                    boolean containsMathOperator =
4420                            (s.contains(" = ") || s.contains(" - ") || s.contains(" + ") ||
4421                             s.contains(" & ") || s.contains(" % ") || s.contains(" * ") ||
4422                             s.contains(" / "));
4423    
4424                    if (containsCompareOperator &&
4425                            (containsAndOrOperator ||
4426                             (containsMathOperator && !s.contains(StringPool.OPEN_BRACKET)))) {
4427    
4428                            return true;
4429                    }
4430                    else {
4431                            return false;
4432                    }
4433            }
4434    
4435            private static boolean _hasRedundantParentheses(String s) {
4436                    if (!s.contains("&&") && !s.contains("||")) {
4437                            for (int x = 0;;) {
4438                                    x = s.indexOf(StringPool.CLOSE_PARENTHESIS);
4439    
4440                                    if (x == -1) {
4441                                            break;
4442                                    }
4443    
4444                                    int y = s.substring(0, x).lastIndexOf(
4445                                            StringPool.OPEN_PARENTHESIS);
4446    
4447                                    if (y == -1) {
4448                                            break;
4449                                    }
4450    
4451                                    s = s.substring(0, y)  + s.substring(x + 1);
4452                            }
4453                    }
4454    
4455                    if (Validator.isNotNull(s) &&
4456                            !s.contains(StringPool.SPACE)) {
4457    
4458                            return true;
4459                    }
4460                    else {
4461                            return false;
4462                    }
4463            }
4464    
4465            private static boolean _isGenerated(String content) {
4466                    if (content.contains("* @generated") || content.contains("$ANTLR")) {
4467                            return true;
4468                    }
4469                    else {
4470                            return false;
4471                    }
4472            }
4473    
4474            private static boolean _isInJavaTermTypeGroup(
4475                    int javaTermType, int[] javaTermTypeGroup) {
4476    
4477                    for (int type : javaTermTypeGroup) {
4478                            if (javaTermType == type) {
4479                                    return true;
4480                            }
4481                    }
4482    
4483                    return false;
4484            }
4485    
4486            private static boolean _isJSPAttributName(String attributeName) {
4487                    if (Validator.isNull(attributeName)) {
4488                            return false;
4489                    }
4490    
4491                    Matcher matcher = _jspAttributeNamePattern.matcher(attributeName);
4492    
4493                    return matcher.matches();
4494            }
4495    
4496            private static boolean _isJSPDuplicateImport(
4497                    String fileName, String importLine, boolean checkFile) {
4498    
4499                    String content = _jspContents.get(fileName);
4500    
4501                    if (Validator.isNull(content)) {
4502                            return false;
4503                    }
4504    
4505                    int x = importLine.indexOf("page");
4506    
4507                    if (x == -1) {
4508                            return false;
4509                    }
4510    
4511                    if (checkFile && content.contains(importLine.substring(x))) {
4512                            return true;
4513                    }
4514    
4515                    int y = content.indexOf("<%@ include file=");
4516    
4517                    if (y == -1) {
4518                            return false;
4519                    }
4520    
4521                    y = content.indexOf(StringPool.QUOTE, y);
4522    
4523                    if (y == -1) {
4524                            return false;
4525                    }
4526    
4527                    int z = content.indexOf(StringPool.QUOTE, y + 1);
4528    
4529                    if (z == -1) {
4530                            return false;
4531                    }
4532    
4533                    String includeFileName = content.substring(y + 1, z);
4534    
4535                    String docrootPath = fileName.substring(
4536                            0, fileName.indexOf("docroot") + 7);
4537    
4538                    includeFileName = docrootPath + includeFileName;
4539    
4540                    return _isJSPDuplicateImport(includeFileName, importLine, true);
4541            }
4542    
4543            private static boolean _isJSPImportRequired(
4544                    String fileName, String className, Set<String> includeFileNames,
4545                    Set<String> checkedFileNames) {
4546    
4547                    if (checkedFileNames.contains(fileName)) {
4548                            return false;
4549                    }
4550    
4551                    checkedFileNames.add(fileName);
4552    
4553                    String content = _jspContents.get(fileName);
4554    
4555                    if (Validator.isNull(content)) {
4556                            return false;
4557                    }
4558    
4559                    Pattern pattern = Pattern.compile(
4560                            "[^A-Za-z0-9_]" + className + "[^A-Za-z0-9_\"]");
4561    
4562                    Matcher matcher = pattern.matcher(content);
4563    
4564                    if (matcher.find()) {
4565                            return true;
4566                    }
4567    
4568                    _addJSPIncludeFileNames(fileName, includeFileNames);
4569    
4570                    String docrootPath = fileName.substring(
4571                            0, fileName.indexOf("docroot") + 7);
4572    
4573                    fileName = fileName.replaceFirst(docrootPath, StringPool.BLANK);
4574    
4575                    if (fileName.endsWith("init.jsp") ||
4576                            fileName.contains("init-ext.jsp")) {
4577    
4578                            _addJSPReferenceFileNames(fileName, includeFileNames);
4579                    }
4580    
4581                    String[] includeFileNamesArray = includeFileNames.toArray(
4582                            new String[includeFileNames.size()]);
4583    
4584                    for (String includeFileName : includeFileNamesArray) {
4585                            if (!checkedFileNames.contains(includeFileName) &&
4586                                    _isJSPImportRequired(
4587                                            includeFileName, className, includeFileNames,
4588                                            checkedFileNames)) {
4589    
4590                                    return true;
4591                            }
4592                    }
4593    
4594                    return false;
4595            }
4596    
4597            private static boolean _isPortalSource() {
4598                    String basedir = "./";
4599    
4600                    if (_fileUtil.exists(basedir + "portal-impl")) {
4601                            return true;
4602                    }
4603                    else {
4604                            return false;
4605                    }
4606            }
4607    
4608            private static boolean _isValidJavaParameter(String javaParameter) {
4609                    int quoteCount = StringUtil.count(javaParameter, StringPool.QUOTE);
4610    
4611                    if ((quoteCount % 2) == 1) {
4612                            return false;
4613                    }
4614    
4615                    javaParameter = _stripQuotes(javaParameter, StringPool.QUOTE);
4616    
4617                    int openParenthesisCount = StringUtil.count(
4618                            javaParameter, StringPool.OPEN_PARENTHESIS);
4619                    int closeParenthesisCount = StringUtil.count(
4620                            javaParameter, StringPool.CLOSE_PARENTHESIS);
4621                    int lessThanCount = StringUtil.count(
4622                            javaParameter, StringPool.LESS_THAN);
4623                    int greaterThanCount = StringUtil.count(
4624                            javaParameter, StringPool.GREATER_THAN);
4625                    int openCurlyBraceCount = StringUtil.count(
4626                            javaParameter, StringPool.OPEN_CURLY_BRACE);
4627                    int closeCurlyBraceCount = StringUtil.count(
4628                            javaParameter, StringPool.CLOSE_CURLY_BRACE);
4629    
4630                    if ((openParenthesisCount == closeParenthesisCount) &&
4631                            (lessThanCount == greaterThanCount) &&
4632                            (openCurlyBraceCount == closeCurlyBraceCount)) {
4633    
4634                            return true;
4635                    }
4636    
4637                    return false;
4638            }
4639    
4640            private static void _processErrorMessage(String fileName, String message) {
4641                    if (_throwException) {
4642                            _errorMessages.add(message);
4643                    }
4644                    else {
4645                            _sourceFormatterHelper.printError(fileName, message);
4646                    }
4647            }
4648    
4649            private static String _replacePrimitiveWrapperInstantiation(
4650                    String fileName, String line, int lineCount) {
4651    
4652                    if (true) {
4653                            return line;
4654                    }
4655    
4656                    String newLine = StringUtil.replace(
4657                            line,
4658                            new String[] {
4659                                    "new Boolean(", "new Byte(", "new Character(", "new Integer(",
4660                                    "new Long(", "new Short("
4661                            },
4662                            new String[] {
4663                                    "Boolean.valueOf(", "Byte.valueOf(", "Character.valueOf(",
4664                                    "Integer.valueOf(", "Long.valueOf(", "Short.valueOf("
4665                            });
4666    
4667                    if (!line.equals(newLine)) {
4668                            _processErrorMessage(
4669                                    fileName, "> new Primitive(: " + fileName + " " + lineCount);
4670                    }
4671    
4672                    return newLine;
4673            }
4674    
4675            private static String _sortExceptions(String line) {
4676                    if (!line.endsWith(StringPool.OPEN_CURLY_BRACE) &&
4677                            !line.endsWith(StringPool.SEMICOLON)) {
4678    
4679                            return line;
4680                    }
4681    
4682                    int x = line.indexOf("throws ");
4683    
4684                    if (x == -1) {
4685                            return line;
4686                    }
4687    
4688                    String previousException = StringPool.BLANK;
4689    
4690                    String[] exceptions = StringUtil.split(
4691                            line.substring(x), CharPool.SPACE);
4692    
4693                    for (int i = 1; i < exceptions.length; i++) {
4694                            String exception = exceptions[i];
4695    
4696                            if (exception.equals(StringPool.OPEN_CURLY_BRACE)) {
4697                                    break;
4698                            }
4699    
4700                            if (exception.endsWith(StringPool.COMMA) ||
4701                                    exception.endsWith(StringPool.SEMICOLON)) {
4702    
4703                                    exception = exception.substring(0, exception.length() - 1);
4704                            }
4705    
4706                            if (Validator.isNotNull(previousException) &&
4707                                    (previousException.compareToIgnoreCase(exception) > 0)) {
4708    
4709                                    return StringUtil.replace(
4710                                            line, previousException + ", " + exception,
4711                                            exception + ", " + previousException);
4712                            }
4713    
4714                            previousException = exception;
4715                    }
4716    
4717                    return line;
4718            }
4719    
4720            private static String _sortJavaTerms(
4721                    String fileName, String content, Set<JavaTerm> javaTerms) {
4722    
4723                    String previousJavaTermContent = StringPool.BLANK;
4724                    int previousJavaTermLineCount = -1;
4725                    String previousJavaTermName = StringPool.BLANK;
4726                    int previousJavaTermType = -1;
4727    
4728                    Iterator<JavaTerm> itr = javaTerms.iterator();
4729    
4730                    while (itr.hasNext()) {
4731                            JavaTerm javaTerm = itr.next();
4732    
4733                            String javaTermContent = javaTerm.getContent();
4734                            int javaTermLineCount = javaTerm.getLineCount();
4735                            String javaTermName = javaTerm.getName();
4736                            int javaTermType = javaTerm.getType();
4737    
4738                            String excluded = null;
4739    
4740                            if (_javaTermSortExclusions != null) {
4741                                    excluded = _javaTermSortExclusions.getProperty(
4742                                            fileName + StringPool.AT + javaTermLineCount);
4743    
4744                                    if (excluded == null) {
4745                                            excluded = _javaTermSortExclusions.getProperty(
4746                                                    fileName + StringPool.AT + javaTermName);
4747                                    }
4748    
4749                                    if (excluded == null) {
4750                                            excluded = _javaTermSortExclusions.getProperty(fileName);
4751                                    }
4752                            }
4753    
4754                            if (excluded == null) {
4755                                    if (previousJavaTermLineCount > javaTermLineCount) {
4756                                            String javaTermNameLowerCase = javaTermName.toLowerCase();
4757                                            String previousJavaTermNameLowerCase =
4758                                                    previousJavaTermName.toLowerCase();
4759    
4760                                            if (fileName.contains("persistence") &&
4761                                                    ((previousJavaTermName.startsWith("doCount") &&
4762                                                      javaTermName.startsWith("doCount")) ||
4763                                                     (previousJavaTermName.startsWith("doFind") &&
4764                                                      javaTermName.startsWith("doFind")) ||
4765                                                     (previousJavaTermNameLowerCase.startsWith("count") &&
4766                                                      javaTermNameLowerCase.startsWith("count")) ||
4767                                                     (previousJavaTermNameLowerCase.startsWith("filter") &&
4768                                                      javaTermNameLowerCase.startsWith("filter")) ||
4769                                                     (previousJavaTermNameLowerCase.startsWith("find") &&
4770                                                      javaTermNameLowerCase.startsWith("find")) ||
4771                                                     (previousJavaTermNameLowerCase.startsWith("join") &&
4772                                                      javaTermNameLowerCase.startsWith("join")))) {
4773                                            }
4774                                            else {
4775                                                    content = StringUtil.replaceFirst(
4776                                                            content, javaTermContent, previousJavaTermContent);
4777                                                    content = StringUtil.replaceLast(
4778                                                            content, previousJavaTermContent, javaTermContent);
4779    
4780                                                    return content;
4781                                            }
4782                                    }
4783    
4784                                    if ((previousJavaTermType == javaTermType) &&
4785                                            ((javaTermType == _TYPE_VARIABLE_PRIVATE_STATIC) ||
4786                                             (javaTermType == _TYPE_VARIABLE_PRIVATE) ||
4787                                             (javaTermType == _TYPE_VARIABLE_PROTECTED_STATIC) ||
4788                                             (javaTermType == _TYPE_VARIABLE_PROTECTED)) &&
4789                                            (_hasAnnotationOrJavadoc(previousJavaTermContent) ||
4790                                             _hasAnnotationOrJavadoc(javaTermContent))) {
4791    
4792                                            if (!content.contains("\n\n" + javaTermContent)) {
4793                                                    return StringUtil.replace(
4794                                                            content, "\n" + javaTermContent,
4795                                                            "\n\n" + javaTermContent);
4796                                            }
4797                                    }
4798                            }
4799    
4800                            previousJavaTermContent = javaTermContent;
4801                            previousJavaTermLineCount = javaTermLineCount;
4802                            previousJavaTermName = javaTermName;
4803                            previousJavaTermType = javaTermType;
4804                    }
4805    
4806                    return content;
4807            }
4808    
4809            private static String _sortJSPAttributes(
4810                    String fileName, String line, int lineCount) {
4811    
4812                    String s = line;
4813    
4814                    int x = s.indexOf(StringPool.SPACE);
4815    
4816                    if (x == -1) {
4817                            return line;
4818                    }
4819    
4820                    s = s.substring(x + 1);
4821    
4822                    String previousAttribute = null;
4823                    String previousAttributeAndValue = null;
4824    
4825                    boolean wrongOrder = false;
4826    
4827                    for (x = 0;;) {
4828                            x = s.indexOf(StringPool.EQUAL);
4829    
4830                            if ((x == -1) || (s.length() <= (x + 1))) {
4831                                    return line;
4832                            }
4833    
4834                            String attribute = s.substring(0, x);
4835    
4836                            if (!_isJSPAttributName(attribute)) {
4837                                    return line;
4838                            }
4839    
4840                            if (Validator.isNotNull(previousAttribute) &&
4841                                    (previousAttribute.compareTo(attribute) > 0)) {
4842    
4843                                    wrongOrder = true;
4844                            }
4845    
4846                            s = s.substring(x + 1);
4847    
4848                            char delimeter = s.charAt(0);
4849    
4850                            if ((delimeter != CharPool.APOSTROPHE) &&
4851                                    (delimeter != CharPool.QUOTE)) {
4852    
4853                                    _processErrorMessage(
4854                                            fileName, "delimeter: " + fileName + " " + lineCount);
4855    
4856                                    return line;
4857                            }
4858    
4859                            s = s.substring(1);
4860    
4861                            String value = null;
4862    
4863                            int y = -1;
4864    
4865                            for (;;) {
4866                                    y = s.indexOf(delimeter, y + 1);
4867    
4868                                    if ((y == -1) || (s.length() <= (y + 1))) {
4869                                            return line;
4870                                    }
4871    
4872                                    value = s.substring(0, y);
4873    
4874                                    if (value.startsWith("<%")) {
4875                                            int endJavaCodeSignCount = StringUtil.count(value, "%>");
4876                                            int startJavaCodeSignCount = StringUtil.count(value, "<%");
4877    
4878                                            if (endJavaCodeSignCount == startJavaCodeSignCount) {
4879                                                    break;
4880                                            }
4881                                    }
4882                                    else {
4883                                            int greaterThanCount = StringUtil.count(
4884                                                    value, StringPool.GREATER_THAN);
4885                                            int lessThanCount = StringUtil.count(
4886                                                    value, StringPool.LESS_THAN);
4887    
4888                                            if (greaterThanCount == lessThanCount) {
4889                                                    break;
4890                                            }
4891                                    }
4892                            }
4893    
4894                            if ((delimeter == CharPool.APOSTROPHE) &&
4895                                    !value.contains(StringPool.QUOTE)) {
4896    
4897                                    return StringUtil.replace(
4898                                            line, StringPool.APOSTROPHE + value + StringPool.APOSTROPHE,
4899                                            StringPool.QUOTE + value + StringPool.QUOTE);
4900                            }
4901    
4902                            StringBundler sb = new StringBundler(5);
4903    
4904                            sb.append(attribute);
4905                            sb.append(StringPool.EQUAL);
4906                            sb.append(delimeter);
4907                            sb.append(value);
4908                            sb.append(delimeter);
4909    
4910                            String currentAttributeAndValue = sb.toString();
4911    
4912                            if (wrongOrder) {
4913                                    if ((StringUtil.count(line, currentAttributeAndValue) == 1) &&
4914                                            (StringUtil.count(line, previousAttributeAndValue) == 1)) {
4915    
4916                                            line = StringUtil.replaceFirst(
4917                                                    line, previousAttributeAndValue,
4918                                                    currentAttributeAndValue);
4919    
4920                                            line = StringUtil.replaceLast(
4921                                                    line, currentAttributeAndValue,
4922                                                    previousAttributeAndValue);
4923                                    }
4924    
4925                                    return line;
4926                            }
4927    
4928                            s = s.substring(y + 1);
4929    
4930                            s = StringUtil.trimLeading(s);
4931    
4932                            previousAttribute = attribute;
4933                            previousAttributeAndValue = currentAttributeAndValue;
4934                    }
4935            }
4936    
4937            private static String _stripJSPImports(String fileName, String content)
4938                    throws IOException {
4939    
4940                    fileName = fileName.replace(
4941                            CharPool.BACK_SLASH, CharPool.FORWARD_SLASH);
4942    
4943                    if (!fileName.contains("docroot") ||
4944                            fileName.endsWith("init-ext.jsp")) {
4945    
4946                            return content;
4947                    }
4948    
4949                    Matcher matcher = _jspImportPattern.matcher(content);
4950    
4951                    if (!matcher.find()) {
4952                            return content;
4953                    }
4954    
4955                    String imports = matcher.group();
4956    
4957                    imports = StringUtil.replace(
4958                            imports, new String[] {"%><%@\r\n", "%><%@\n"},
4959                            new String[] {"%>\r\n<%@ ", "%>\n<%@ "});
4960    
4961                    if (!fileName.endsWith("html/common/init.jsp") &&
4962                            !fileName.endsWith("html/portal/init.jsp")) {
4963    
4964                            List<String> importLines = new ArrayList<String>();
4965    
4966                            UnsyncBufferedReader unsyncBufferedReader =
4967                                    new UnsyncBufferedReader(new UnsyncStringReader(imports));
4968    
4969                            String line = null;
4970    
4971                            while ((line = unsyncBufferedReader.readLine()) != null) {
4972                                    if (line.contains("import=")) {
4973                                            importLines.add(line);
4974                                    }
4975                            }
4976    
4977                            List<String> unneededImports = _getJSPDuplicateImports(
4978                                    fileName, content, importLines);
4979    
4980                            _addJSPUnusedImports(fileName, importLines, unneededImports);
4981    
4982                            for (String unneededImport : unneededImports) {
4983                                    imports = StringUtil.replace(
4984                                            imports, unneededImport, StringPool.BLANK);
4985                            }
4986                    }
4987    
4988                    imports = _formatImports(imports, 17);
4989    
4990                    String beforeImports = content.substring(0, matcher.start());
4991    
4992                    if (Validator.isNull(imports)) {
4993                            beforeImports = StringUtil.replaceLast(
4994                                    beforeImports, "\n", StringPool.BLANK);
4995                    }
4996    
4997                    String afterImports = content.substring(matcher.end());
4998    
4999                    if (Validator.isNull(afterImports)) {
5000                            imports = StringUtil.replaceLast(imports, "\n", StringPool.BLANK);
5001    
5002                            content = beforeImports + imports;
5003    
5004                            return content;
5005                    }
5006    
5007                    content = beforeImports + imports + "\n" + afterImports;
5008    
5009                    return content;
5010            }
5011    
5012            private static String _stripQuotes(String s, String delimeter) {
5013                    String[] parts = StringUtil.split(s, delimeter);
5014    
5015                    int i = 1;
5016    
5017                    while (i < parts.length) {
5018                            s = StringUtil.replaceFirst(
5019                                    s, delimeter + parts[i] + delimeter, StringPool.BLANK);
5020    
5021                            i = i + 2;
5022                    }
5023    
5024                    return s;
5025            }
5026    
5027            private static String _stripRedundantParentheses(String s) {
5028                    for (int x = 0;;) {
5029                            x = s.indexOf(StringPool.OPEN_PARENTHESIS, x + 1);
5030                            int y = s.indexOf(StringPool.CLOSE_PARENTHESIS, x);
5031    
5032                            if ((x == -1) || (y == -1)) {
5033                                    return s;
5034                            }
5035    
5036                            String linePart = s.substring(x + 1, y);
5037    
5038                            linePart = StringUtil.replace(
5039                                    linePart, StringPool.COMMA, StringPool.BLANK);
5040    
5041                            if (Validator.isAlphanumericName(linePart) ||
5042                                    Validator.isNull(linePart)) {
5043    
5044                                    s = s.substring(0, x) + s.substring(y + 1);
5045                            }
5046                    }
5047            }
5048    
5049            private static Properties _stripTopLevelDirectories(
5050                            Properties properties, int level)
5051                    throws IOException {
5052    
5053                    File dir = new File(".");
5054    
5055                    String dirName = dir.getCanonicalPath();
5056    
5057                    dirName = StringUtil.replace(
5058                            dirName, StringPool.BACK_SLASH, StringPool.SLASH);
5059    
5060                    int pos = dirName.length();
5061    
5062                    for (int i = 0; i < level; i++) {
5063                            pos = dirName.lastIndexOf(StringPool.SLASH, pos - 1);
5064                    }
5065    
5066                    String topLevelDirNames = dirName.substring(pos + 1) + StringPool.SLASH;
5067    
5068                    Properties newProperties = new Properties();
5069    
5070                    for (Map.Entry<Object, Object> entry : properties.entrySet()) {
5071                            String key = (String)entry.getKey();
5072    
5073                            if (!key.startsWith(topLevelDirNames)) {
5074                                    continue;
5075                            }
5076    
5077                            key = StringUtil.replaceFirst(
5078                                    key, topLevelDirNames, StringPool.BLANK);
5079    
5080                            String value = (String)entry.getValue();
5081    
5082                            newProperties.setProperty(key, value);
5083                    }
5084    
5085                    return newProperties;
5086            }
5087    
5088            private static String _trimContent(
5089                            String content, boolean allowLeadingSpaces)
5090                    throws IOException {
5091    
5092                    StringBundler sb = new StringBundler();
5093    
5094                    UnsyncBufferedReader unsyncBufferedReader = new UnsyncBufferedReader(
5095                            new UnsyncStringReader(content));
5096    
5097                    String line = null;
5098    
5099                    while ((line = unsyncBufferedReader.readLine()) != null) {
5100                            sb.append(_trimLine(line, allowLeadingSpaces));
5101                            sb.append("\n");
5102                    }
5103    
5104                    unsyncBufferedReader.close();
5105    
5106                    content = sb.toString();
5107    
5108                    if (content.endsWith("\n")) {
5109                            content = content.substring(0, content.length() - 1);
5110                    }
5111    
5112                    return content;
5113            }
5114    
5115            private static String _trimLine(String line, boolean allowLeadingSpaces) {
5116                    if (line.trim().length() == 0) {
5117                            return StringPool.BLANK;
5118                    }
5119    
5120                    line = StringUtil.trimTrailing(line);
5121    
5122                    if (allowLeadingSpaces || !line.startsWith(StringPool.SPACE) ||
5123                            line.startsWith(" *")) {
5124    
5125                            return line;
5126                    }
5127    
5128                    if (!line.startsWith(StringPool.FOUR_SPACES)) {
5129                            while (line.startsWith(StringPool.SPACE)) {
5130                                    line = StringUtil.replaceFirst(
5131                                            line, StringPool.SPACE, StringPool.BLANK);
5132                            }
5133                    }
5134                    else {
5135                            int pos = 0;
5136    
5137                            String temp = line;
5138    
5139                            while (temp.startsWith(StringPool.FOUR_SPACES)) {
5140                                    line = StringUtil.replaceFirst(
5141                                            line, StringPool.FOUR_SPACES, StringPool.TAB);
5142    
5143                                    pos++;
5144    
5145                                    temp = line.substring(pos);
5146                            }
5147                    }
5148    
5149                    return line;
5150            }
5151    
5152            private static final String[] _TAG_LIBRARIES = new String[] {
5153                    "aui", "c", "html", "jsp", "liferay-portlet", "liferay-security",
5154                    "liferay-theme", "liferay-ui", "liferay-util", "portlet", "struts",
5155                    "tiles"
5156            };
5157    
5158            private static List<String> _errorMessages = new ArrayList<String>();
5159            private static String[] _excludes;
5160            private static FileImpl _fileUtil = FileImpl.getInstance();
5161            private static Pattern _javaImportPattern = Pattern.compile(
5162                    "(^[ \t]*import\\s+.*;\n+)+", Pattern.MULTILINE);
5163            private static Properties _javaTermSortExclusions;
5164            private static Pattern _jspAttributeNamePattern = Pattern.compile(
5165                    "[a-z]+[-_a-zA-Z0-9]*");
5166            private static Map<String, String> _jspContents =
5167                    new HashMap<String, String>();
5168            private static Pattern _jspImportPattern = Pattern.compile(
5169                    "(<.*\n*page.import=\".*>\n*)+", Pattern.MULTILINE);
5170            private static Pattern _jspIncludeFilePattern = Pattern.compile(
5171                    "/.*[.]jsp[f]?");
5172            private static Pattern _languageKeyPattern = Pattern.compile(
5173                    "LanguageUtil.(?:get|format)\\([^;%]+|Liferay.Language.get\\('([^']+)");
5174            private static Properties _lineLengthExclusions;
5175            private static Properties _portalLanguageKeysProperties;
5176            private static boolean _portalSource;
5177            private static SAXReaderImpl _saxReaderUtil = SAXReaderImpl.getInstance();
5178            private static Pattern _sessionKeyPattern = Pattern.compile(
5179                    "SessionErrors.(?:add|contains|get)\\([^;%&|!]+|".concat(
5180                            "SessionMessages.(?:add|contains|get)\\([^;%&|!]+"),
5181                    Pattern.MULTILINE);
5182            private static SourceFormatterHelper _sourceFormatterHelper;
5183            private static Pattern _taglibLanguageKeyPattern = Pattern.compile(
5184                    "(?:confirmation|label|(?:M|m)essage|message key|names|title)=\"[^A-Z" +
5185                            "<=%\\[\\s]+\"");
5186            private static Pattern _taglibSessionKeyPattern = Pattern.compile(
5187                    "<liferay-ui:error [^>]+>|<liferay-ui:success [^>]+>",
5188                    Pattern.MULTILINE);
5189            private static boolean _throwException;
5190            private static Pattern _xssPattern = Pattern.compile(
5191                    "String\\s+([^\\s]+)\\s*=\\s*(Bean)?ParamUtil\\.getString\\(");
5192    
5193    }