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.sourceformatter;
016    
017    import com.liferay.portal.kernel.io.unsync.UnsyncBufferedReader;
018    import com.liferay.portal.kernel.io.unsync.UnsyncStringReader;
019    import com.liferay.portal.kernel.util.CharPool;
020    import com.liferay.portal.kernel.util.ClassUtil;
021    import com.liferay.portal.kernel.util.GetterUtil;
022    import com.liferay.portal.kernel.util.StringBundler;
023    import com.liferay.portal.kernel.util.StringPool;
024    import com.liferay.portal.kernel.util.StringUtil;
025    import com.liferay.portal.kernel.util.Tuple;
026    import com.liferay.portal.kernel.util.Validator;
027    
028    import com.thoughtworks.qdox.JavaDocBuilder;
029    import com.thoughtworks.qdox.model.JavaClass;
030    import com.thoughtworks.qdox.model.JavaSource;
031    
032    import java.io.File;
033    import java.io.IOException;
034    
035    import java.util.ArrayList;
036    import java.util.Collection;
037    import java.util.Iterator;
038    import java.util.List;
039    import java.util.Properties;
040    import java.util.Set;
041    import java.util.TreeSet;
042    import java.util.regex.Matcher;
043    import java.util.regex.Pattern;
044    
045    /**
046     * @author Hugo Huijser
047     */
048    public class JavaSourceProcessor extends BaseSourceProcessor {
049    
050            public static final int TYPE_CLASS_PRIVATE = 24;
051    
052            public static final int TYPE_CLASS_PRIVATE_STATIC = 23;
053    
054            public static final int TYPE_CLASS_PROTECTED = 16;
055    
056            public static final int TYPE_CLASS_PROTECTED_STATIC = 15;
057    
058            public static final int TYPE_CLASS_PUBLIC = 8;
059    
060            public static final int TYPE_CLASS_PUBLIC_STATIC = 7;
061    
062            public static final int[] TYPE_CONSTRUCTOR = {
063                    JavaSourceProcessor.TYPE_CONSTRUCTOR_PRIVATE,
064                    JavaSourceProcessor.TYPE_CONSTRUCTOR_PROTECTED,
065                    JavaSourceProcessor.TYPE_CONSTRUCTOR_PUBLIC
066            };
067    
068            public static final int TYPE_CONSTRUCTOR_PRIVATE = 18;
069    
070            public static final int TYPE_CONSTRUCTOR_PROTECTED = 10;
071    
072            public static final int TYPE_CONSTRUCTOR_PUBLIC = 4;
073    
074            public static final int[] TYPE_METHOD = {
075                    JavaSourceProcessor.TYPE_METHOD_PRIVATE,
076                    JavaSourceProcessor.TYPE_METHOD_PRIVATE_STATIC,
077                    JavaSourceProcessor.TYPE_METHOD_PROTECTED,
078                    JavaSourceProcessor.TYPE_METHOD_PROTECTED_STATIC,
079                    JavaSourceProcessor.TYPE_METHOD_PUBLIC,
080                    JavaSourceProcessor.TYPE_METHOD_PUBLIC_STATIC
081            };
082    
083            public static final int TYPE_METHOD_PRIVATE = 19;
084    
085            public static final int TYPE_METHOD_PRIVATE_STATIC = 17;
086    
087            public static final int TYPE_METHOD_PROTECTED = 11;
088    
089            public static final int TYPE_METHOD_PROTECTED_STATIC = 9;
090    
091            public static final int TYPE_METHOD_PUBLIC = 5;
092    
093            public static final int TYPE_METHOD_PUBLIC_STATIC = 3;
094    
095            public static final int[] TYPE_VARIABLE = {
096                    JavaSourceProcessor.TYPE_VARIABLE_PRIVATE,
097                    JavaSourceProcessor.TYPE_VARIABLE_PRIVATE_STATIC,
098                    JavaSourceProcessor.TYPE_VARIABLE_PRIVATE_STATIC_FINAL,
099                    JavaSourceProcessor.TYPE_VARIABLE_PROTECTED,
100                    JavaSourceProcessor.TYPE_VARIABLE_PROTECTED_STATIC,
101                    JavaSourceProcessor.TYPE_VARIABLE_PROTECTED_STATIC_FINAL,
102                    JavaSourceProcessor.TYPE_VARIABLE_PUBLIC,
103                    JavaSourceProcessor.TYPE_VARIABLE_PUBLIC_STATIC,
104                    JavaSourceProcessor.TYPE_VARIABLE_PUBLIC_STATIC_FINAL
105            };
106    
107            public static final int TYPE_VARIABLE_PRIVATE = 22;
108    
109            public static final int TYPE_VARIABLE_PRIVATE_STATIC = 21;
110    
111            public static final int TYPE_VARIABLE_PRIVATE_STATIC_FINAL = 20;
112    
113            public static final int TYPE_VARIABLE_PROTECTED = 14;
114    
115            public static final int TYPE_VARIABLE_PROTECTED_STATIC = 13;
116    
117            public static final int TYPE_VARIABLE_PROTECTED_STATIC_FINAL = 12;
118    
119            public static final int TYPE_VARIABLE_PUBLIC = 6;
120    
121            public static final int TYPE_VARIABLE_PUBLIC_STATIC = 2;
122    
123            public static final int TYPE_VARIABLE_PUBLIC_STATIC_FINAL = 1;
124    
125            public static String stripJavaImports(
126                            String content, String packageDir, String className)
127                    throws IOException {
128    
129                    Pattern pattern = Pattern.compile(
130                            "(^[ \t]*import\\s+.*;\n+)+", Pattern.MULTILINE);
131    
132                    Matcher matcher = pattern.matcher(content);
133    
134                    if (!matcher.find()) {
135                            return content;
136                    }
137    
138                    String imports = matcher.group();
139    
140                    Set<String> classes = ClassUtil.getClasses(
141                            new UnsyncStringReader(content), className);
142    
143                    StringBundler sb = new StringBundler();
144    
145                    UnsyncBufferedReader unsyncBufferedReader = new UnsyncBufferedReader(
146                            new UnsyncStringReader(imports));
147    
148                    String line = null;
149    
150                    while ((line = unsyncBufferedReader.readLine()) != null) {
151                            if (!line.contains("import ")) {
152                                    continue;
153                            }
154    
155                            int importX = line.indexOf(" ");
156                            int importY = line.lastIndexOf(".");
157    
158                            String importPackage = line.substring(importX + 1, importY);
159    
160                            if (importPackage.equals(packageDir) ||
161                                    importPackage.equals("java.lang")) {
162    
163                                    continue;
164                            }
165    
166                            String importClass = line.substring(importY + 1, line.length() - 1);
167    
168                            if (importClass.equals("*") || classes.contains(importClass)) {
169                                    sb.append(line);
170                                    sb.append("\n");
171                            }
172                    }
173    
174                    imports = formatImports(sb.toString(), 7);
175    
176                    content =
177                            content.substring(0, matcher.start()) + imports +
178                                    content.substring(matcher.end());
179    
180                    // Ensure a blank line exists between the package and the first import
181    
182                    content = content.replaceFirst(
183                            "(?m)^[ \t]*(package .*;)\\s*^[ \t]*import", "$1\n\nimport");
184    
185                    // Ensure a blank line exists between the last import (or package if
186                    // there are no imports) and the class comment
187    
188                    content = content.replaceFirst(
189                            "(?m)^[ \t]*((?:package|import) .*;)\\s*^[ \t]*/\\*\\*",
190                            "$1\n\n/**");
191    
192                    return content;
193            }
194    
195            protected List<String> addParameterTypes(
196                    String line, List<String> parameterTypes) {
197    
198                    int x = line.indexOf(StringPool.OPEN_PARENTHESIS);
199    
200                    if (x != -1) {
201                            line = line.substring(x + 1);
202    
203                            if (Validator.isNull(line) ||
204                                    line.startsWith(StringPool.CLOSE_PARENTHESIS)) {
205    
206                                    return parameterTypes;
207                            }
208                    }
209    
210                    for (x = 0;;) {
211                            x = line.indexOf(StringPool.SPACE);
212    
213                            if (x == -1) {
214                                    return parameterTypes;
215                            }
216    
217                            String parameterType = line.substring(0, x);
218    
219                            if (parameterType.equals("throws")) {
220                                    return parameterTypes;
221                            }
222    
223                            parameterTypes.add(parameterType);
224    
225                            int y = line.indexOf(StringPool.COMMA);
226                            int z = line.indexOf(StringPool.CLOSE_PARENTHESIS);
227    
228                            if ((y == -1) || ((z != -1) && (z < y))) {
229                                    return parameterTypes;
230                            }
231    
232                            line = line.substring(y + 1);
233                            line = line.trim();
234                    }
235            }
236    
237            protected void checkAnnotationForMethod(
238                    JavaTerm javaTerm, String annotation, String requiredMethodNameRegex,
239                    int requiredMethodType, String fileName) {
240    
241                    String methodContent = javaTerm.getContent();
242                    String methodName = javaTerm.getName();
243    
244                    Pattern pattern = Pattern.compile(requiredMethodNameRegex);
245    
246                    Matcher matcher = pattern.matcher(methodName);
247    
248                    if (methodContent.contains(
249                                    StringPool.TAB + StringPool.AT + annotation + "\n") ||
250                            methodContent.contains(
251                                    StringPool.TAB + StringPool.AT + annotation +
252                                            StringPool.OPEN_PARENTHESIS)) {
253    
254                            if (!matcher.find()) {
255                                    processErrorMessage(
256                                            fileName,
257                                            "LPS-36303: Incorrect method name: " + methodName + " " +
258                                                    fileName);
259                            }
260                            else if (javaTerm.getType() != requiredMethodType) {
261                                    processErrorMessage(
262                                            fileName,
263                                            "LPS-36303: Incorrect method type for " + methodName + " " +
264                                                    fileName);
265                            }
266                    }
267                    else if (matcher.find() &&
268                                     !methodContent.contains(StringPool.TAB + "@Override")) {
269    
270                            processErrorMessage(
271                                    fileName,
272                                    "Annotation @" + annotation + " required for " + methodName +
273                                            " " + fileName);
274                    }
275            }
276    
277            protected String checkIfClause(
278                            String ifClause, String fileName, int lineCount)
279                    throws IOException {
280    
281                    String ifClauseSingleLine = StringUtil.replace(
282                            ifClause,
283                            new String[] {
284                                    StringPool.TAB + StringPool.SPACE, StringPool.TAB,
285                                    StringPool.OPEN_PARENTHESIS + StringPool.NEW_LINE,
286                                    StringPool.NEW_LINE
287                            },
288                            new String[] {
289                                    StringPool.TAB, StringPool.BLANK, StringPool.OPEN_PARENTHESIS,
290                                    StringPool.SPACE
291                            });
292    
293                    checkIfClauseParentheses(ifClauseSingleLine, fileName, lineCount);
294    
295                    return checkIfClauseTabsAndSpaces(ifClause);
296            }
297    
298            protected String checkIfClauseTabsAndSpaces(String ifClause)
299                    throws IOException {
300    
301                    if (ifClause.contains("!(") ||
302                            ifClause.contains(StringPool.TAB + "//")) {
303    
304                            return ifClause;
305                    }
306    
307                    UnsyncBufferedReader unsyncBufferedReader = new UnsyncBufferedReader(
308                            new UnsyncStringReader(ifClause));
309    
310                    String line = null;
311    
312                    String previousLine = null;
313                    int previousLineLeadingWhiteSpace = 0;
314    
315                    int lastCriteriumLineLeadingWhiteSpace = 0;
316    
317                    int closeParenthesesCount = 0;
318                    int openParenthesesCount = 0;
319    
320                    while ((line = unsyncBufferedReader.readLine()) != null) {
321                            String originalLine = line;
322    
323                            line = StringUtil.replace(
324                                    line, StringPool.TAB, StringPool.FOUR_SPACES);
325    
326                            int leadingWhiteSpace =
327                                    line.length() - StringUtil.trimLeading(line).length();
328    
329                            if (Validator.isNull(previousLine)) {
330                                    lastCriteriumLineLeadingWhiteSpace = line.indexOf(
331                                            StringPool.OPEN_PARENTHESIS);
332                            }
333                            else if (previousLine.endsWith("|") || previousLine.endsWith("&") ||
334                                             previousLine.endsWith("^")) {
335    
336                                    int expectedLeadingWhiteSpace =
337                                            lastCriteriumLineLeadingWhiteSpace +
338                                                    openParenthesesCount - closeParenthesesCount;
339    
340                                    if (leadingWhiteSpace != expectedLeadingWhiteSpace) {
341                                            return fixIfClause(
342                                                    ifClause, originalLine,
343                                                    leadingWhiteSpace - expectedLeadingWhiteSpace);
344                                    }
345    
346                                    lastCriteriumLineLeadingWhiteSpace = leadingWhiteSpace;
347    
348                                    closeParenthesesCount = 0;
349                                    openParenthesesCount = 0;
350                            }
351                            else {
352                                    int expectedLeadingWhiteSpace = 0;
353    
354                                    if (previousLine.contains(StringPool.TAB + "if (")) {
355                                            expectedLeadingWhiteSpace =
356                                                    previousLineLeadingWhiteSpace + 8;
357                                    }
358                                    else if (previousLine.contains(StringPool.TAB + "else if (") ||
359                                                     previousLine.contains(StringPool.TAB + "while (")) {
360    
361                                            expectedLeadingWhiteSpace =
362                                                    previousLineLeadingWhiteSpace + 12;
363                                    }
364    
365                                    if ((expectedLeadingWhiteSpace != 0) &&
366                                            (leadingWhiteSpace != expectedLeadingWhiteSpace)) {
367    
368                                            return fixIfClause(
369                                                    ifClause, originalLine,
370                                                    leadingWhiteSpace - expectedLeadingWhiteSpace);
371                                    }
372                            }
373    
374                            if (line.endsWith(") {")) {
375                                    return ifClause;
376                            }
377    
378                            line = stripQuotes(line, StringPool.QUOTE);
379                            line = stripQuotes(line, StringPool.APOSTROPHE);
380    
381                            closeParenthesesCount += StringUtil.count(
382                                    line, StringPool.CLOSE_PARENTHESIS);
383                            openParenthesesCount += StringUtil.count(
384                                    line, StringPool.OPEN_PARENTHESIS);
385    
386                            previousLine = originalLine;
387                            previousLineLeadingWhiteSpace = leadingWhiteSpace;
388                    }
389    
390                    return ifClause;
391            }
392    
393            protected void checkTestAnnotations(JavaTerm javaTerm, String fileName) {
394                    int methodType = javaTerm.getType();
395    
396                    if ((methodType != TYPE_METHOD_PUBLIC) &&
397                            (methodType != TYPE_METHOD_PUBLIC_STATIC)) {
398    
399                            return;
400                    }
401    
402                    checkAnnotationForMethod(
403                            javaTerm, "After", "^.*tearDown\\z", TYPE_METHOD_PUBLIC, fileName);
404                    checkAnnotationForMethod(
405                            javaTerm, "AfterClass", "^.*tearDownClass\\z",
406                            TYPE_METHOD_PUBLIC_STATIC, fileName);
407                    checkAnnotationForMethod(
408                            javaTerm, "Before", "^.*setUp\\z", TYPE_METHOD_PUBLIC, fileName);
409                    checkAnnotationForMethod(
410                            javaTerm, "BeforeClass", "^.*setUpClass\\z",
411                            TYPE_METHOD_PUBLIC_STATIC, fileName);
412                    checkAnnotationForMethod(
413                            javaTerm, "Test", "^.*test", TYPE_METHOD_PUBLIC, fileName);
414            }
415    
416            protected void checkUnprocessedExceptions(
417                            String content, File file, String packagePath, String fileName)
418                    throws IOException {
419    
420                    List<String> importedExceptionClassNames = null;
421                    JavaDocBuilder javaDocBuilder = null;
422    
423                    Pattern catchExceptionPattern = Pattern.compile(
424                            "\n(\t+)catch \\((.+Exception) (.+)\\) \\{\n");
425    
426                    for (int lineCount = 1;;) {
427                            Matcher catchExceptionMatcher = catchExceptionPattern.matcher(
428                                    content);
429    
430                            if (!catchExceptionMatcher.find()) {
431                                    return;
432                            }
433    
434                            String beforeCatchCode = content.substring(
435                                    0, catchExceptionMatcher.start());
436    
437                            lineCount = lineCount + StringUtil.count(beforeCatchCode, "\n") + 1;
438    
439                            String exceptionClassName = catchExceptionMatcher.group(2);
440                            String exceptionVariableName = catchExceptionMatcher.group(3);
441                            String tabs = catchExceptionMatcher.group(1);
442    
443                            int pos = content.indexOf(
444                                    "\n" + tabs + StringPool.CLOSE_CURLY_BRACE,
445                                    catchExceptionMatcher.end() - 1);
446    
447                            String insideCatchCode = content.substring(
448                                    catchExceptionMatcher.end(), pos + 1);
449    
450                            Pattern exceptionVariablePattern = Pattern.compile(
451                                    "\\W" + exceptionVariableName + "\\W");
452    
453                            Matcher exceptionVariableMatcher = exceptionVariablePattern.matcher(
454                                    insideCatchCode);
455    
456                            if (exceptionVariableMatcher.find()) {
457                                    content = content.substring(catchExceptionMatcher.start() + 1);
458    
459                                    continue;
460                            }
461    
462                            if (javaDocBuilder == null) {
463                                    javaDocBuilder = new JavaDocBuilder();
464    
465                                    javaDocBuilder.addSource(file);
466                            }
467    
468                            if (importedExceptionClassNames == null) {
469                                    importedExceptionClassNames = getImportedExceptionClassNames(
470                                            javaDocBuilder);
471                            }
472    
473                            String originalExceptionClassName = exceptionClassName;
474    
475                            if (!exceptionClassName.contains(StringPool.PERIOD)) {
476                                    for (String exceptionClass : importedExceptionClassNames) {
477                                            if (exceptionClass.endsWith(
478                                                            StringPool.PERIOD + exceptionClassName)) {
479    
480                                                    exceptionClassName = exceptionClass;
481    
482                                                    break;
483                                            }
484                                    }
485                            }
486    
487                            if (!exceptionClassName.contains(StringPool.PERIOD)) {
488                                    exceptionClassName =
489                                            packagePath + StringPool.PERIOD + exceptionClassName;
490                            }
491    
492                            JavaClass exceptionClass = javaDocBuilder.getClassByName(
493                                    exceptionClassName);
494    
495                            while (true) {
496                                    String packageName = exceptionClass.getPackageName();
497    
498                                    if (!packageName.contains("com.liferay")) {
499                                            break;
500                                    }
501    
502                                    exceptionClassName = exceptionClass.getName();
503    
504                                    if (exceptionClassName.equals("PortalException") ||
505                                            exceptionClassName.equals("SystemException")) {
506    
507                                            processErrorMessage(
508                                                    fileName,
509                                                    "Unprocessed " + originalExceptionClassName + ": " +
510                                                            fileName + " " + lineCount);
511    
512                                            break;
513                                    }
514    
515                                    JavaClass exceptionSuperClass =
516                                            exceptionClass.getSuperJavaClass();
517    
518                                    if (exceptionSuperClass == null) {
519                                            break;
520                                    }
521    
522                                    exceptionClass = exceptionSuperClass;
523                            }
524    
525                            content = content.substring(catchExceptionMatcher.start() + 1);
526                    }
527            }
528    
529            @Override
530            protected void doFormat() throws Exception {
531                    String copyright = getCopyright();
532                    String oldCopyright = getOldCopyright();
533    
534                    boolean portalJavaFiles = true;
535    
536                    Collection<String> fileNames = null;
537    
538                    if (portalSource) {
539                            fileNames = getPortalJavaFiles();
540    
541                            _checkUnprocessedExceptions = GetterUtil.getBoolean(
542                                    System.getProperty(
543                                            "source.formatter.check.unprocessed.exceptions"));
544                    }
545                    else {
546                            portalJavaFiles = false;
547    
548                            fileNames = getPluginJavaFiles();
549                    }
550    
551                    _javaTermSortExclusions = getExclusionsProperties(
552                            "source_formatter_javaterm_sort_exclusions.properties");
553                    _lineLengthExclusions = getExclusionsProperties(
554                            "source_formatter_line_length_exclusions.properties");
555                    Properties staticLogVariableExclusions = getExclusionsProperties(
556                            "source_formatter_static_log_exclusions.properties");
557                    Properties upgradeServiceUtilExclusions = getExclusionsProperties(
558                            "source_formatter_upgrade_service_util_exclusions.properties");
559    
560                    for (String fileName : fileNames) {
561                            if (fileName.endsWith("SourceProcessor.java")) {
562                                    continue;
563                            }
564    
565                            File file = new File(BASEDIR + fileName);
566    
567                            fileName = StringUtil.replace(
568                                    fileName, StringPool.BACK_SLASH, StringPool.SLASH);
569    
570                            String content = fileUtil.read(file);
571    
572                            if (isGenerated(content) &&
573                                    !fileName.endsWith("JavadocFormatter.java")) {
574    
575                                    continue;
576                            }
577    
578                            String className = file.getName();
579    
580                            className = className.substring(0, className.length() - 5);
581    
582                            String packagePath = fileName;
583    
584                            int packagePathX = packagePath.indexOf("/src/");
585                            int packagePathY = packagePath.lastIndexOf(StringPool.SLASH);
586    
587                            if ((packagePathX + 5) >= packagePathY) {
588                                    packagePath = StringPool.BLANK;
589                            }
590                            else {
591                                    packagePath = packagePath.substring(
592                                            packagePathX + 5, packagePathY);
593                            }
594    
595                            packagePath = StringUtil.replace(
596                                    packagePath, StringPool.SLASH, StringPool.PERIOD);
597    
598                            if (packagePath.endsWith(".model")) {
599                                    if (content.contains("extends " + className + "Model")) {
600                                            continue;
601                                    }
602                            }
603    
604                            String newContent = content;
605    
606                            if (newContent.contains("$\n */")) {
607                                    processErrorMessage(fileName, "*: " + fileName);
608    
609                                    newContent = StringUtil.replace(
610                                            newContent, "$\n */", "$\n *\n */");
611                            }
612    
613                            newContent = fixCopyright(
614                                    newContent, copyright, oldCopyright, file, fileName);
615    
616                            if (newContent.contains(className + ".java.html")) {
617                                    processErrorMessage(fileName, "Java2HTML: " + fileName);
618                            }
619    
620                            if (newContent.contains(" * @author Raymond Aug") &&
621                                    !newContent.contains(" * @author Raymond Aug\u00e9")) {
622    
623                                    newContent = newContent.replaceFirst(
624                                            "Raymond Aug.++", "Raymond Aug\u00e9");
625    
626                                    processErrorMessage(fileName, "UTF-8: " + fileName);
627                            }
628    
629                            newContent = fixDataAccessConnection(className, newContent);
630                            newContent = fixSessionKey(fileName, newContent, sessionKeyPattern);
631    
632                            newContent = StringUtil.replace(
633                                    newContent,
634                                    new String[] {
635                                            "com.liferay.portal.PortalException",
636                                            "com.liferay.portal.SystemException",
637                                            "com.liferay.util.LocalizationUtil",
638                                            "private static final Log _log"
639                                    },
640                                    new String[] {
641                                            "com.liferay.portal.kernel.exception.PortalException",
642                                            "com.liferay.portal.kernel.exception.SystemException",
643                                            "com.liferay.portal.kernel.util.LocalizationUtil",
644                                            "private static Log _log"
645                                    });
646    
647                            newContent = fixCompatClassImports(fileName, newContent);
648    
649                            newContent = stripJavaImports(newContent, packagePath, className);
650    
651                            newContent = StringUtil.replace(
652                                    newContent,
653                                    new String[] {
654                                            ";\n/**", "\t/*\n\t *", "catch(", "else{", "if(", "for(",
655                                            "while(", "List <", "){\n", "]{\n"
656                                    },
657                                    new String[] {
658                                            ";\n\n/**", "\t/**\n\t *", "catch (", "else {", "if (",
659                                            "for (", "while (", "List<", ") {\n", "] {\n"
660                                    });
661    
662                            Pattern pattern = Pattern.compile(
663                                    "\t(catch |else |finally |for |if |try |while ).*\\{\n\n" +
664                                            "\t+\\w");
665    
666                            for (;;) {
667                                    Matcher matcher = pattern.matcher(newContent);
668    
669                                    if (!matcher.find()) {
670                                            break;
671                                    }
672    
673                                    String match = matcher.group();
674    
675                                    String replacement = StringUtil.replaceFirst(
676                                            match, StringPool.NEW_LINE, StringPool.BLANK);
677    
678                                    newContent = StringUtil.replaceFirst(
679                                            newContent, match, replacement);
680                            }
681    
682                            pattern = Pattern.compile(
683                                    "Log _log = LogFactoryUtil.getLog\\(\n*\t*(.+)\\.class\\)");
684    
685                            Matcher matcher = pattern.matcher(newContent);
686    
687                            if (matcher.find()) {
688                                    String logClassName = matcher.group(1);
689    
690                                    if (!logClassName.equals(className)) {
691                                            newContent = StringUtil.replaceLast(
692                                                    newContent, logClassName + ".class)",
693                                                    className + ".class)");
694                                    }
695                            }
696    
697                            String excluded = null;
698    
699                            if (staticLogVariableExclusions != null) {
700                                    excluded = staticLogVariableExclusions.getProperty(fileName);
701                            }
702    
703                            if (excluded == null) {
704                                    newContent = StringUtil.replace(
705                                            newContent, "private Log _log", "private static Log _log");
706                            }
707    
708                            if (newContent.contains("*/\npackage ")) {
709                                    processErrorMessage(fileName, "package: " + fileName);
710                            }
711    
712                            if (!newContent.endsWith("\n\n}") && !newContent.endsWith("{\n}")) {
713                                    processErrorMessage(fileName, "}: " + fileName);
714                            }
715    
716                            if (portalJavaFiles && !className.equals("BaseServiceImpl") &&
717                                    className.endsWith("ServiceImpl") &&
718                                    newContent.contains("ServiceUtil.")) {
719    
720                                    processErrorMessage(fileName, "ServiceUtil: " + fileName);
721                            }
722    
723                            // LPS-34911
724    
725                            excluded = null;
726    
727                            if (upgradeServiceUtilExclusions != null) {
728                                    excluded = upgradeServiceUtilExclusions.getProperty(fileName);
729                            }
730    
731                            if ((excluded == null) && portalJavaFiles &&
732                                    fileName.contains("/portal/upgrade/") &&
733                                    !fileName.contains("/test/") &&
734                                    newContent.contains("ServiceUtil.")) {
735    
736                                    processErrorMessage(fileName, "ServiceUtil: " + fileName);
737                            }
738    
739                            if (!className.equals("DeepNamedValueScanner") &&
740                                    !className.equals("ProxyUtil") &&
741                                    newContent.contains("import java.lang.reflect.Proxy;")) {
742    
743                                    processErrorMessage(fileName, "Proxy: " + fileName);
744                            }
745    
746                            if (newContent.contains("import edu.emory.mathcs.backport.java")) {
747                                    processErrorMessage(
748                                            fileName, "edu.emory.mathcs.backport.java: " + fileName);
749                            }
750    
751                            // LPS-28266
752    
753                            for (int pos1 = -1;;) {
754                                    pos1 = newContent.indexOf(StringPool.TAB + "try {", pos1 + 1);
755    
756                                    if (pos1 == -1) {
757                                            break;
758                                    }
759    
760                                    int pos2 = newContent.indexOf(
761                                            StringPool.TAB + "try {", pos1 + 1);
762                                    int pos3 = newContent.indexOf("\"select count(", pos1);
763    
764                                    if ((pos2 != -1) && (pos3 != -1) && (pos2 < pos3)) {
765                                            continue;
766                                    }
767    
768                                    int pos4 = newContent.indexOf("rs.getLong(1)", pos1);
769                                    int pos5 = newContent.indexOf(
770                                            StringPool.TAB + "finally {", pos1);
771    
772                                    if ((pos3 == -1) || (pos4 == -1) || (pos5 == -1)) {
773                                            break;
774                                    }
775    
776                                    if ((pos3 < pos4) && (pos4 < pos5)) {
777                                            processErrorMessage(
778                                                    fileName, "Use getInt(1) for count: " + fileName);
779                                    }
780                            }
781    
782                            // LPS-33070
783    
784                            if (content.contains("implements ProcessCallable") &&
785                                    !content.contains(
786                                            "private static final long serialVersionUID")) {
787    
788                                    processErrorMessage(
789                                            fileName,
790                                            "Assign ProcessCallable implementation a " +
791                                                    "serialVersionUID: " + fileName);
792                            }
793    
794                            checkLanguageKeys(fileName, newContent, languageKeyPattern);
795    
796                            // LPS-36174
797    
798                            if (_checkUnprocessedExceptions && !fileName.contains("/test/")) {
799                                    checkUnprocessedExceptions(
800                                            newContent, file, packagePath, fileName);
801                            }
802    
803                            String oldContent = newContent;
804    
805                            for (;;) {
806                                    newContent = formatJava(fileName, oldContent);
807    
808                                    newContent = StringUtil.replace(newContent, "\n\n\n", "\n\n");
809    
810                                    if (oldContent.equals(newContent)) {
811                                            break;
812                                    }
813    
814                                    oldContent = newContent;
815                            }
816    
817                            if ((newContent != null) && !content.equals(newContent)) {
818                                    fileUtil.write(file, newContent);
819    
820                                    sourceFormatterHelper.printError(fileName, file);
821                            }
822                    }
823            }
824    
825            protected String fixDataAccessConnection(String className, String content) {
826                    int x = content.indexOf("package ");
827    
828                    int y = content.indexOf(CharPool.SEMICOLON, x);
829    
830                    if ((x == -1) || (y == -1)) {
831                            return content;
832                    }
833    
834                    String packageName = content.substring(x + 8, y);
835    
836                    if (!packageName.startsWith("com.liferay.portal.kernel.upgrade") &&
837                            !packageName.startsWith("com.liferay.portal.kernel.verify") &&
838                            !packageName.startsWith("com.liferay.portal.upgrade") &&
839                            !packageName.startsWith("com.liferay.portal.verify")) {
840    
841                            return content;
842                    }
843    
844                    content = StringUtil.replace(
845                            content, "DataAccess.getConnection",
846                            "DataAccess.getUpgradeOptimizedConnection");
847    
848                    return content;
849            }
850    
851            protected String fixIfClause(String ifClause, String line, int delta) {
852                    String newLine = line;
853    
854                    String whiteSpace = StringPool.BLANK;
855                    int whiteSpaceLength = Math.abs(delta);
856    
857                    while (whiteSpaceLength > 0) {
858                            if (whiteSpaceLength >= 4) {
859                                    whiteSpace += StringPool.TAB;
860    
861                                    whiteSpaceLength -= 4;
862                            }
863                            else {
864                                    whiteSpace += StringPool.SPACE;
865    
866                                    whiteSpaceLength -= 1;
867                            }
868                    }
869    
870                    if (delta > 0) {
871                            if (!line.contains(StringPool.TAB + whiteSpace)) {
872                                    newLine = StringUtil.replaceLast(
873                                            newLine, StringPool.TAB, StringPool.FOUR_SPACES);
874                            }
875    
876                            newLine = StringUtil.replaceLast(
877                                    newLine, StringPool.TAB + whiteSpace, StringPool.TAB);
878                    }
879                    else {
880                            newLine = StringUtil.replaceLast(
881                                    newLine, StringPool.TAB, StringPool.TAB + whiteSpace);
882                    }
883    
884                    return StringUtil.replace(ifClause, line, newLine);
885            }
886    
887            protected String fixJavaTermsDividers(
888                    String fileName, String content, Set<JavaTerm> javaTerms) {
889    
890                    JavaTerm previousJavaTerm = null;
891    
892                    Iterator<JavaTerm> itr = javaTerms.iterator();
893    
894                    while (itr.hasNext()) {
895                            JavaTerm javaTerm = itr.next();
896    
897                            if (previousJavaTerm == null) {
898                                    previousJavaTerm = javaTerm;
899    
900                                    continue;
901                            }
902    
903                            String javaTermContent = javaTerm.getContent();
904    
905                            if (javaTermContent.startsWith(StringPool.TAB + "//") ||
906                                    javaTermContent.contains(StringPool.TAB + "static {")) {
907    
908                                    previousJavaTerm = javaTerm;
909    
910                                    continue;
911                            }
912    
913                            String previousJavaTermContent = previousJavaTerm.getContent();
914    
915                            if (previousJavaTermContent.startsWith(StringPool.TAB + "//") ||
916                                    previousJavaTermContent.contains(StringPool.TAB + "static {")) {
917    
918                                    previousJavaTerm = javaTerm;
919    
920                                    continue;
921                            }
922    
923                            String javaTermName = javaTerm.getName();
924    
925                            String excluded = null;
926    
927                            if (_javaTermSortExclusions != null) {
928                                    excluded = _javaTermSortExclusions.getProperty(
929                                            fileName + StringPool.AT + javaTerm.getLineCount());
930    
931                                    if (excluded == null) {
932                                            excluded = _javaTermSortExclusions.getProperty(
933                                                    fileName + StringPool.AT + javaTermName);
934                                    }
935    
936                                    if (excluded == null) {
937                                            excluded = _javaTermSortExclusions.getProperty(fileName);
938                                    }
939                            }
940    
941                            if (excluded != null) {
942                                    previousJavaTerm = javaTerm;
943    
944                                    continue;
945                            }
946    
947                            String previousJavaTermName = previousJavaTerm.getName();
948    
949                            boolean requiresEmptyLine = false;
950    
951                            if (previousJavaTerm.getType() != javaTerm.getType()) {
952                                    requiresEmptyLine = true;
953                            }
954                            else if (!isInJavaTermTypeGroup(
955                                                    javaTerm.getType(), TYPE_VARIABLE)) {
956    
957                                    requiresEmptyLine = true;
958                            }
959                            else if (previousJavaTermName.equals(
960                                                    previousJavaTermName.toUpperCase()) ||
961                                             javaTermName.equals(javaTermName.toUpperCase())) {
962    
963                                    requiresEmptyLine = true;
964                            }
965                            else if (hasAnnotationCommentOrJavadoc(javaTermContent) ||
966                                             hasAnnotationCommentOrJavadoc(previousJavaTermContent)) {
967    
968                                    requiresEmptyLine = true;
969                            }
970                            else if ((previousJavaTerm.getType() ==
971                                                    TYPE_VARIABLE_PRIVATE_STATIC) &&
972                                             (previousJavaTermName.equals("_log") ||
973                                              previousJavaTermName.equals("_instance"))) {
974    
975                                    requiresEmptyLine = true;
976                            }
977                            else if (previousJavaTermContent.contains("\n\n\t") ||
978                                             javaTermContent.contains("\n\n\t")) {
979    
980                                    requiresEmptyLine = true;
981                            }
982    
983                            if (requiresEmptyLine) {
984                                    if (!content.contains("\n\n" + javaTermContent)) {
985                                            return StringUtil.replace(
986                                                    content,
987                                                    "\n" + javaTermContent, "\n\n" + javaTermContent);
988                                    }
989                            }
990                            else if (content.contains("\n\n" + javaTermContent)) {
991                                    return StringUtil.replace(
992                                            content, "\n\n" + javaTermContent, "\n" + javaTermContent);
993                            }
994    
995                            previousJavaTerm = javaTerm;
996                    }
997    
998                    return content;
999            }
1000    
1001            protected String formatAnnotations(
1002                            String fileName, String content, Set<JavaTerm> javaTerms)
1003                    throws IOException {
1004    
1005                    Iterator<JavaTerm> itr = javaTerms.iterator();
1006    
1007                    while (itr.hasNext()) {
1008                            JavaTerm javaTerm = itr.next();
1009    
1010                            if (fileName.contains("/test/") &&
1011                                    !fileName.endsWith("TestBean.java") &&
1012                                    !fileName.endsWith("TestCase.java")) {
1013    
1014                                    checkTestAnnotations(javaTerm, fileName);
1015                            }
1016    
1017                            for (;;) {
1018                                    String javaTermContent = javaTerm.getContent();
1019    
1020                                    javaTerm.sortAnnotations();
1021    
1022                                    String newJavaTermContent = javaTerm.getContent();
1023    
1024                                    if (javaTermContent.equals(newJavaTermContent)) {
1025                                            break;
1026                                    }
1027    
1028                                    content = content.replace(javaTermContent, newJavaTermContent);
1029                            }
1030                    }
1031    
1032                    return content;
1033            }
1034    
1035            protected String formatJava(String fileName, String content)
1036                    throws IOException {
1037    
1038                    StringBundler sb = new StringBundler();
1039    
1040                    UnsyncBufferedReader unsyncBufferedReader = new UnsyncBufferedReader(
1041                            new UnsyncStringReader(content));
1042    
1043                    int index = 0;
1044                    int lineCount = 0;
1045    
1046                    String line = null;
1047    
1048                    String previousLine = StringPool.BLANK;
1049    
1050                    int lineToSkipIfEmpty = 0;
1051    
1052                    Set<JavaTerm> javaTerms = new TreeSet<JavaTerm>(
1053                            new JavaTermComparator());
1054    
1055                    JavaTerm javaTerm = null;
1056    
1057                    String javaTermName = null;
1058                    int javaTermLineCount = -1;
1059                    int javaTermStartPosition = -1;
1060                    int javaTermType = -1;
1061    
1062                    boolean readParameterTypes = false;
1063                    List<String> parameterTypes = new ArrayList<String>();
1064    
1065                    int lastCommentOrAnnotationPos = -1;
1066    
1067                    String ifClause = StringPool.BLANK;
1068    
1069                    String packageName = StringPool.BLANK;
1070    
1071                    while ((line = unsyncBufferedReader.readLine()) != null) {
1072                            lineCount++;
1073    
1074                            line = trimLine(line, false);
1075    
1076                            if (line.startsWith("package ")) {
1077                                    packageName = line.substring(8, line.length() - 1);
1078                            }
1079    
1080                            if (line.startsWith("import ")) {
1081                                    if (line.endsWith(".*;")) {
1082                                            processErrorMessage(
1083                                                    fileName, "import: " + fileName + " " + lineCount);
1084                                    }
1085    
1086                                    int pos = line.lastIndexOf(StringPool.PERIOD);
1087    
1088                                    if (pos != -1) {
1089                                            String importPackageName = line.substring(7, pos);
1090    
1091                                            if (importPackageName.equals(packageName)) {
1092                                                    continue;
1093                                            }
1094                                    }
1095                            }
1096    
1097                            if (line.contains(StringPool.TAB + "for (") && line.contains(":") &&
1098                                    !line.contains(" :")) {
1099    
1100                                    line = StringUtil.replace(line, ":" , " :");
1101                            }
1102    
1103                            line = replacePrimitiveWrapperInstantiation(
1104                                    fileName, line, lineCount);
1105    
1106                            String trimmedLine = StringUtil.trimLeading(line);
1107    
1108                            if (trimmedLine.startsWith("* @deprecated") &&
1109                                    mainReleaseVersion.equals(MAIN_RELEASE_VERSION_6_2_0)) {
1110    
1111                                    if (!trimmedLine.startsWith("* @deprecated As of ")) {
1112                                            line = StringUtil.replace(
1113                                                    line, "* @deprecated",
1114                                                    "* @deprecated As of " + MAIN_RELEASE_VERSION_6_2_0);
1115                                    }
1116                                    else {
1117                                            String version = trimmedLine.substring(20);
1118    
1119                                            version = StringUtil.split(version, StringPool.SPACE)[0];
1120    
1121                                            version = StringUtil.replace(
1122                                                    version, StringPool.COMMA, StringPool.BLANK);
1123    
1124                                            if (StringUtil.count(version, StringPool.PERIOD) == 1) {
1125                                                    line = StringUtil.replaceFirst(
1126                                                            line, version, version + ".0");
1127                                            }
1128                                    }
1129                            }
1130    
1131                            if (trimmedLine.startsWith(StringPool.EQUAL)) {
1132                                    processErrorMessage(
1133                                            fileName, "equal: " + fileName + " " + lineCount);
1134                            }
1135    
1136                            if (line.contains("ActionForm form")) {
1137                                    processErrorMessage(
1138                                            fileName,
1139                                            "Rename form to actionForm: " + fileName + " " + lineCount);
1140                            }
1141    
1142                            if (line.contains("ActionMapping mapping")) {
1143                                    processErrorMessage(
1144                                            fileName,
1145                                            "Rename mapping to ActionMapping: " + fileName + " " +
1146                                                    lineCount);
1147                            }
1148    
1149                            if (!trimmedLine.equals("{") && line.endsWith("{") &&
1150                                    !line.endsWith(" {")) {
1151    
1152                                    line = StringUtil.replaceLast(line, "{", " {");
1153                            }
1154    
1155                            line = sortExceptions(line);
1156    
1157                            if (trimmedLine.startsWith("if (") ||
1158                                    trimmedLine.startsWith("else if (") ||
1159                                    trimmedLine.startsWith("while (") ||
1160                                    Validator.isNotNull(ifClause)) {
1161    
1162                                    ifClause = ifClause + line + StringPool.NEW_LINE;
1163    
1164                                    if (line.endsWith(") {")) {
1165                                            String newIfClause = checkIfClause(
1166                                                    ifClause, fileName, lineCount);
1167    
1168                                            if (!ifClause.equals(newIfClause)) {
1169                                                    return StringUtil.replace(
1170                                                            content, ifClause, newIfClause);
1171                                            }
1172    
1173                                            ifClause = StringPool.BLANK;
1174                                    }
1175                                    else if (line.endsWith(StringPool.SEMICOLON)) {
1176                                            ifClause = StringPool.BLANK;
1177                                    }
1178                            }
1179    
1180                            String excluded = null;
1181    
1182                            if (line.startsWith(StringPool.TAB + "private ") ||
1183                                    line.startsWith(StringPool.TAB + "protected ") ||
1184                                    line.startsWith(StringPool.TAB + "public ")) {
1185    
1186                                    Tuple tuple = getJavaTermTuple(line, content, index, 1, 3);
1187    
1188                                    if (tuple != null) {
1189                                            int javaTermEndPosition = 0;
1190    
1191                                            if (lastCommentOrAnnotationPos == -1) {
1192                                                    javaTermEndPosition = index;
1193                                            }
1194                                            else {
1195                                                    javaTermEndPosition = lastCommentOrAnnotationPos;
1196                                            }
1197    
1198                                            if ((javaTermStartPosition != -1) &&
1199                                                    (javaTermEndPosition < content.length())) {
1200    
1201                                                    String javaTermContent = content.substring(
1202                                                            javaTermStartPosition, javaTermEndPosition);
1203    
1204                                                    if (Validator.isNotNull(javaTermName)) {
1205                                                            javaTerm = new JavaTerm(
1206                                                                    javaTermName, javaTermType, parameterTypes,
1207                                                                    javaTermContent, javaTermLineCount);
1208    
1209                                                            javaTerms.add(javaTerm);
1210                                                    }
1211                                            }
1212    
1213                                            javaTermLineCount = lineCount;
1214                                            javaTermName = (String)tuple.getObject(0);
1215                                            javaTermStartPosition = javaTermEndPosition;
1216                                            javaTermType = (Integer)tuple.getObject(1);
1217    
1218                                            if (Validator.isNotNull(javaTermName)) {
1219                                                    if (isInJavaTermTypeGroup(
1220                                                                    javaTermType, TYPE_CONSTRUCTOR) ||
1221                                                            isInJavaTermTypeGroup(
1222                                                                    javaTermType, TYPE_METHOD)) {
1223    
1224                                                            readParameterTypes = true;
1225    
1226                                                            parameterTypes = new ArrayList<String>();
1227                                                    }
1228                                            }
1229                                    }
1230    
1231                                    lastCommentOrAnnotationPos = -1;
1232                            }
1233                            else if (hasAnnotationCommentOrJavadoc(line)) {
1234                                    if (lastCommentOrAnnotationPos == -1) {
1235                                            lastCommentOrAnnotationPos = index;
1236                                    }
1237                            }
1238    
1239                            if (readParameterTypes) {
1240                                    parameterTypes = addParameterTypes(trimmedLine, parameterTypes);
1241    
1242                                    if (trimmedLine.contains(StringPool.CLOSE_PARENTHESIS)) {
1243                                            readParameterTypes = false;
1244                                    }
1245                            }
1246    
1247                            if (!trimmedLine.contains(StringPool.DOUBLE_SLASH) &&
1248                                    !trimmedLine.startsWith(StringPool.STAR)) {
1249    
1250                                    while (trimmedLine.contains(StringPool.TAB)) {
1251                                            line = StringUtil.replaceLast(
1252                                                    line, StringPool.TAB, StringPool.SPACE);
1253    
1254                                            trimmedLine = StringUtil.replaceLast(
1255                                                    trimmedLine, StringPool.TAB, StringPool.SPACE);
1256                                    }
1257    
1258                                    if (line.contains(StringPool.TAB + StringPool.SPACE) &&
1259                                            !previousLine.endsWith("&&") &&
1260                                            !previousLine.endsWith("||") &&
1261                                            !previousLine.contains(StringPool.TAB + "((") &&
1262                                            !previousLine.contains(StringPool.TAB + StringPool.SPACE) &&
1263                                            !previousLine.contains(StringPool.TAB + "implements ") &&
1264                                            !previousLine.contains(StringPool.TAB + "throws ")) {
1265    
1266                                            line = StringUtil.replace(
1267                                                    line, StringPool.TAB + StringPool.SPACE,
1268                                                    StringPool.TAB);
1269                                    }
1270    
1271                                    while (trimmedLine.contains(StringPool.DOUBLE_SPACE) &&
1272                                               !trimmedLine.contains(
1273                                                       StringPool.QUOTE + StringPool.DOUBLE_SPACE) &&
1274                                               !fileName.contains("Test")) {
1275    
1276                                            line = StringUtil.replaceLast(
1277                                                    line, StringPool.DOUBLE_SPACE, StringPool.SPACE);
1278    
1279                                            trimmedLine = StringUtil.replaceLast(
1280                                                    trimmedLine, StringPool.DOUBLE_SPACE, StringPool.SPACE);
1281                                    }
1282    
1283                                    if (!line.contains(StringPool.QUOTE)) {
1284                                            int pos = line.indexOf(") ");
1285    
1286                                            if (pos != -1) {
1287                                                    String linePart = line.substring(pos + 2);
1288    
1289                                                    if (Character.isLetter(linePart.charAt(0)) &&
1290                                                            !linePart.startsWith("default") &&
1291                                                            !linePart.startsWith("instanceof") &&
1292                                                            !linePart.startsWith("throws")) {
1293    
1294                                                            line = StringUtil.replaceLast(
1295                                                                    line, StringPool.SPACE + linePart, linePart);
1296                                                    }
1297                                            }
1298    
1299                                            if ((trimmedLine.startsWith("private ") ||
1300                                                     trimmedLine.startsWith("protected ") ||
1301                                                     trimmedLine.startsWith("public ")) &&
1302                                                    line.contains(" (")) {
1303    
1304                                                    line = StringUtil.replace(line, " (", "(");
1305                                            }
1306    
1307                                            if (line.contains(" [")) {
1308                                                    line = StringUtil.replace(line, " [", "[");
1309                                            }
1310    
1311                                            for (int x = -1;;) {
1312                                                    int posComma = line.indexOf(StringPool.COMMA, x + 1);
1313                                                    int posSemicolon = line.indexOf(
1314                                                            StringPool.SEMICOLON, x + 1);
1315    
1316                                                    if ((posComma == -1) && (posSemicolon == -1)) {
1317                                                            break;
1318                                                    }
1319    
1320                                                    x = Math.min(posComma, posSemicolon);
1321    
1322                                                    if (x == -1) {
1323                                                            x = Math.max(posComma, posSemicolon);
1324                                                    }
1325    
1326                                                    if (line.length() > (x + 1)) {
1327                                                            char nextChar = line.charAt(x + 1);
1328    
1329                                                            if ((nextChar != CharPool.APOSTROPHE) &&
1330                                                                    (nextChar != CharPool.CLOSE_PARENTHESIS) &&
1331                                                                    (nextChar != CharPool.SPACE) &&
1332                                                                    (nextChar != CharPool.STAR)) {
1333    
1334                                                                    line = StringUtil.insert(
1335                                                                            line, StringPool.SPACE, x + 1);
1336                                                            }
1337                                                    }
1338    
1339                                                    if (x > 0) {
1340                                                            char previousChar = line.charAt(x - 1);
1341    
1342                                                            if (previousChar == CharPool.SPACE) {
1343                                                                    line = line.substring(0, x - 1).concat(
1344                                                                            line.substring(x));
1345                                                            }
1346                                                    }
1347                                            }
1348                                    }
1349    
1350                                    if ((line.contains(" && ") || line.contains(" || ")) &&
1351                                            line.endsWith(StringPool.OPEN_PARENTHESIS)) {
1352    
1353                                            processErrorMessage(
1354                                                    fileName, "line break: " + fileName + " " + lineCount);
1355                                    }
1356    
1357                                    if (trimmedLine.endsWith(StringPool.PLUS) &&
1358                                            !trimmedLine.startsWith(StringPool.OPEN_PARENTHESIS)) {
1359    
1360                                            String strippedQuotesLine = stripQuotes(
1361                                                    trimmedLine, StringPool.QUOTE);
1362    
1363                                            int closeParenthesisCount = StringUtil.count(
1364                                                    strippedQuotesLine, StringPool.CLOSE_PARENTHESIS);
1365                                            int openParenthesisCount = StringUtil.count(
1366                                                    strippedQuotesLine, StringPool.OPEN_PARENTHESIS);
1367    
1368                                            if (openParenthesisCount > closeParenthesisCount) {
1369                                                    processErrorMessage(
1370                                                            fileName,
1371                                                            "line break: " + fileName + " " + lineCount);
1372                                            }
1373                                    }
1374    
1375                                    if (line.contains(StringPool.COMMA) &&
1376                                            !line.contains(StringPool.CLOSE_PARENTHESIS) &&
1377                                            !line.contains(StringPool.GREATER_THAN) &&
1378                                            !line.contains(StringPool.QUOTE) &&
1379                                            line.endsWith(StringPool.OPEN_PARENTHESIS)) {
1380    
1381                                            processErrorMessage(
1382                                                    fileName, "line break: " + fileName + " " + lineCount);
1383                                    }
1384    
1385                                    if (line.endsWith(" +") || line.endsWith(" -") ||
1386                                            line.endsWith(" *") || line.endsWith(" /")) {
1387    
1388                                            int x = line.indexOf(" = ");
1389    
1390                                            if (x != -1) {
1391                                                    int y = line.indexOf(StringPool.QUOTE);
1392    
1393                                                    if ((y == -1) || (x < y)) {
1394                                                            processErrorMessage(
1395                                                                    fileName,
1396                                                                    "line break: " + fileName + " " + lineCount);
1397                                                    }
1398                                            }
1399                                    }
1400    
1401                                    if (line.endsWith(" throws") ||
1402                                            (previousLine.endsWith(
1403                                                    StringPool.OPEN_PARENTHESIS) &&
1404                                             line.contains(" throws " ) &&
1405                                             line.endsWith(StringPool.OPEN_CURLY_BRACE))) {
1406    
1407                                            processErrorMessage(
1408                                                    fileName, "line break: " + fileName + " " + lineCount);
1409                                    }
1410    
1411                                    if (trimmedLine.startsWith(StringPool.PERIOD) ||
1412                                            (line.endsWith(StringPool.PERIOD) &&
1413                                             line.contains(StringPool.EQUAL))) {
1414    
1415                                            processErrorMessage(
1416                                                    fileName, "line break: " + fileName + " " + lineCount);
1417                                    }
1418    
1419                                    if (trimmedLine.startsWith(StringPool.CLOSE_CURLY_BRACE) &&
1420                                            line.endsWith(StringPool.OPEN_CURLY_BRACE)) {
1421    
1422                                            processErrorMessage(
1423                                                    fileName, "line break: " + fileName + " " + lineCount);
1424                                    }
1425                            }
1426    
1427                            if (line.contains("    ") && !line.matches("\\s*\\*.*")) {
1428                                    if (!fileName.endsWith("StringPool.java")) {
1429                                            processErrorMessage(
1430                                                    fileName, "tab: " + fileName + " " + lineCount);
1431                                    }
1432                            }
1433    
1434                            if (line.contains("  {") && !line.matches("\\s*\\*.*")) {
1435                                    processErrorMessage(
1436                                            fileName, "{:" + fileName + " " + lineCount);
1437                            }
1438    
1439                            excluded = null;
1440    
1441                            if (_lineLengthExclusions != null) {
1442                                    excluded = _lineLengthExclusions.getProperty(
1443                                            fileName + StringPool.AT + lineCount);
1444    
1445                                    if (excluded == null) {
1446                                            excluded = _lineLengthExclusions.getProperty(fileName);
1447                                    }
1448                            }
1449    
1450                            Tuple combinedLines = null;
1451                            int lineLength = getLineLength(line);
1452    
1453                            if ((excluded == null) &&
1454                                    !line.startsWith("import ") && !line.startsWith("package ") &&
1455                                    !line.matches("\\s*\\*.*")) {
1456    
1457                                    if (fileName.endsWith("Table.java") &&
1458                                            line.contains("String TABLE_SQL_CREATE = ")) {
1459                                    }
1460                                    else if (fileName.endsWith("Table.java") &&
1461                                                     line.contains("String TABLE_SQL_DROP = ")) {
1462                                    }
1463                                    else if (fileName.endsWith("Table.java") &&
1464                                                     line.contains(" index IX_")) {
1465                                    }
1466                                    else if (lineLength > 80) {
1467                                            processErrorMessage(
1468                                                    fileName, "> 80: " + fileName + " " + lineCount);
1469                                    }
1470                                    else {
1471                                            int lineLeadingTabCount = getLeadingTabCount(line);
1472                                            int previousLineLeadingTabCount = getLeadingTabCount(
1473                                                    previousLine);
1474    
1475                                            if (!trimmedLine.startsWith("//")) {
1476                                                    if (previousLine.endsWith(StringPool.COMMA) &&
1477                                                            previousLine.contains(
1478                                                                    StringPool.OPEN_PARENTHESIS) &&
1479                                                            !previousLine.contains("for (") &&
1480                                                            (lineLeadingTabCount >
1481                                                                    previousLineLeadingTabCount)) {
1482    
1483                                                            processErrorMessage(
1484                                                                    fileName,
1485                                                                    "line break: " + fileName + " " + lineCount);
1486                                                    }
1487    
1488                                                    if (Validator.isNotNull(trimmedLine)) {
1489                                                            if (((previousLine.endsWith(StringPool.COLON) &&
1490                                                                      previousLine.contains(
1491                                                                              StringPool.TAB + "for ")) ||
1492                                                                     (previousLine.endsWith(
1493                                                                             StringPool.OPEN_PARENTHESIS) &&
1494                                                                      previousLine.contains(
1495                                                                              StringPool.TAB + "if "))) &&
1496                                                                    ((previousLineLeadingTabCount + 2) !=
1497                                                                            lineLeadingTabCount)) {
1498    
1499                                                            processErrorMessage(
1500                                                                    fileName,
1501                                                                    "line break: " + fileName + " " + lineCount);
1502                                                            }
1503    
1504                                                            if (previousLine.endsWith(
1505                                                                            StringPool.OPEN_CURLY_BRACE) &&
1506                                                                    !trimmedLine.startsWith(
1507                                                                            StringPool.CLOSE_CURLY_BRACE) &&
1508                                                                    ((previousLineLeadingTabCount + 1) !=
1509                                                                            lineLeadingTabCount)) {
1510    
1511                                                                    processErrorMessage(
1512                                                                            fileName,
1513                                                                            "tab: " + fileName + " " + lineCount);
1514                                                            }
1515                                                    }
1516    
1517                                                    if (previousLine.endsWith(StringPool.PERIOD)) {
1518                                                            int x = trimmedLine.indexOf(
1519                                                                    StringPool.OPEN_PARENTHESIS);
1520    
1521                                                            if ((x != -1) &&
1522                                                                    ((getLineLength(previousLine) + x) < 80) &&
1523                                                                    (trimmedLine.endsWith(
1524                                                                            StringPool.OPEN_PARENTHESIS) ||
1525                                                                     (trimmedLine.charAt(x + 1) !=
1526                                                                             CharPool.CLOSE_PARENTHESIS))) {
1527    
1528                                                                    processErrorMessage(
1529                                                                            fileName,
1530                                                                            "line break: " + fileName + " " +
1531                                                                                    lineCount);
1532                                                            }
1533                                                    }
1534    
1535                                                    if (trimmedLine.startsWith("throws ") &&
1536                                                            (lineLeadingTabCount ==
1537                                                                    previousLineLeadingTabCount)) {
1538    
1539                                                            processErrorMessage(
1540                                                                    fileName, "tab: " + fileName + " " + lineCount);
1541                                                    }
1542    
1543                                                    if ((previousLine.contains(" class " ) ||
1544                                                             previousLine.contains(" enum ")) &&
1545                                                            previousLine.endsWith(
1546                                                                    StringPool.OPEN_CURLY_BRACE) &&
1547                                                            Validator.isNotNull(line) &&
1548                                                            !trimmedLine.startsWith(
1549                                                                    StringPool.CLOSE_CURLY_BRACE)) {
1550    
1551                                                            processErrorMessage(
1552                                                                    fileName,
1553                                                                    "new line: " + fileName + " " + lineCount);
1554                                                    }
1555                                            }
1556    
1557                                            combinedLines = getCombinedLines(
1558                                                    trimmedLine, previousLine, lineLeadingTabCount,
1559                                                    previousLineLeadingTabCount);
1560                                    }
1561                            }
1562    
1563                            if (combinedLines != null) {
1564                                    previousLine = (String)combinedLines.getObject(0);
1565    
1566                                    if (combinedLines.getSize() > 1) {
1567                                            String linePart = (String)combinedLines.getObject(1);
1568                                            boolean addToPreviousLine =
1569                                                    (Boolean)combinedLines.getObject(2);
1570    
1571                                            if (addToPreviousLine) {
1572                                                    previousLine = previousLine + linePart;
1573                                                    line = StringUtil.replaceFirst(
1574                                                            line, linePart, StringPool.BLANK);
1575                                            }
1576                                            else {
1577                                                    if (((linePart.length() + lineLength) <= 80) &&
1578                                                            (line.endsWith(StringPool.OPEN_CURLY_BRACE) ||
1579                                                             line.endsWith(StringPool.SEMICOLON))) {
1580    
1581                                                            previousLine = StringUtil.replaceLast(
1582                                                                    previousLine, StringUtil.trim(linePart),
1583                                                                    StringPool.BLANK);
1584    
1585                                                            line = StringUtil.replaceLast(
1586                                                                    line, StringPool.TAB,
1587                                                                    StringPool.TAB + linePart);
1588                                                    }
1589                                                    else {
1590                                                            processErrorMessage(
1591                                                                    fileName,
1592                                                                    "line break: " + fileName + " " + lineCount);
1593                                                    }
1594                                            }
1595    
1596                                            sb.append(previousLine);
1597                                            sb.append("\n");
1598    
1599                                            previousLine = line;
1600                                    }
1601                                    else if (line.endsWith(StringPool.OPEN_CURLY_BRACE) &&
1602                                                     !previousLine.contains(" class ")) {
1603    
1604                                            lineToSkipIfEmpty = lineCount + 1;
1605                                    }
1606                            }
1607                            else {
1608                                    if ((lineCount > 1) &&
1609                                            (Validator.isNotNull(previousLine) ||
1610                                             (lineToSkipIfEmpty != (lineCount - 1)))) {
1611    
1612                                            sb.append(previousLine);
1613    
1614                                            if (Validator.isNotNull(previousLine) &&
1615                                                    Validator.isNotNull(trimmedLine) &&
1616                                                    !previousLine.contains("/*") &&
1617                                                    !previousLine.endsWith("*/")) {
1618    
1619                                                    String trimmedPreviousLine = StringUtil.trimLeading(
1620                                                            previousLine);
1621    
1622                                                    if ((trimmedPreviousLine.startsWith("// ") &&
1623                                                             !trimmedLine.startsWith("// ")) ||
1624                                                            (!trimmedPreviousLine.startsWith("// ") &&
1625                                                             trimmedLine.startsWith("// "))) {
1626    
1627                                                            sb.append("\n");
1628                                                    }
1629                                                    else if (!trimmedPreviousLine.endsWith(
1630                                                                            StringPool.OPEN_CURLY_BRACE) &&
1631                                                                     !trimmedPreviousLine.endsWith(
1632                                                                            StringPool.COLON) &&
1633                                                                     (trimmedLine.startsWith("for (") ||
1634                                                                      trimmedLine.startsWith("if ("))) {
1635    
1636                                                            sb.append("\n");
1637                                                    }
1638                                                    else if (previousLine.endsWith(
1639                                                                            StringPool.TAB +
1640                                                                                    StringPool.CLOSE_CURLY_BRACE) &&
1641                                                                     !trimmedLine.startsWith(
1642                                                                             StringPool.CLOSE_CURLY_BRACE) &&
1643                                                                     !trimmedLine.startsWith(
1644                                                                             StringPool.CLOSE_PARENTHESIS) &&
1645                                                                     !trimmedLine.startsWith(
1646                                                                             StringPool.DOUBLE_SLASH) &&
1647                                                                     !trimmedLine.startsWith("catch ") &&
1648                                                                     !trimmedLine.startsWith("else ") &&
1649                                                                     !trimmedLine.startsWith("finally ") &&
1650                                                                     !trimmedLine.startsWith("while ")) {
1651    
1652                                                            sb.append("\n");
1653                                                    }
1654                                            }
1655    
1656                                            sb.append("\n");
1657                                    }
1658    
1659                                    previousLine = line;
1660                            }
1661    
1662                            index = index + line.length() + 1;
1663                    }
1664    
1665                    sb.append(previousLine);
1666    
1667                    unsyncBufferedReader.close();
1668    
1669                    String newContent = sb.toString();
1670    
1671                    if (newContent.endsWith("\n")) {
1672                            newContent = newContent.substring(0, newContent.length() - 1);
1673                    }
1674    
1675                    if (content.equals(newContent)) {
1676                            if (javaTermStartPosition != -1) {
1677                                    int javaTermEndPosition = content.length() - 2;
1678    
1679                                    String javaTermContent = content.substring(
1680                                            javaTermStartPosition, javaTermEndPosition);
1681    
1682                                    javaTerm = new JavaTerm(
1683                                            javaTermName, javaTermType, parameterTypes, javaTermContent,
1684                                            javaTermLineCount);
1685    
1686                                    javaTerms.add(javaTerm);
1687                            }
1688    
1689                            newContent = sortJavaTerms(fileName, content, javaTerms);
1690                    }
1691    
1692                    if (content.equals(newContent)) {
1693                            newContent = fixJavaTermsDividers(fileName, content, javaTerms);
1694                    }
1695    
1696                    if (content.equals(newContent)) {
1697                            newContent = formatAnnotations(fileName, content, javaTerms);
1698                    }
1699    
1700                    return newContent;
1701            }
1702    
1703            protected String getClassName(String line) {
1704                    int pos = line.indexOf(" implements ");
1705    
1706                    if (pos == -1) {
1707                            pos = line.indexOf(" extends ");
1708                    }
1709    
1710                    if (pos == -1) {
1711                            pos = line.indexOf(StringPool.OPEN_CURLY_BRACE);
1712                    }
1713    
1714                    if (pos != -1) {
1715                            line = line.substring(0, pos);
1716                    }
1717    
1718                    line = line.trim();
1719    
1720                    pos = line.lastIndexOf(StringPool.SPACE);
1721    
1722                    return line.substring(pos + 1);
1723            }
1724    
1725            protected Tuple getCombinedLines(
1726                    String line, String previousLine, int lineTabCount,
1727                    int previousLineTabCount) {
1728    
1729                    if (Validator.isNull(line) || Validator.isNull(previousLine)) {
1730                            return null;
1731                    }
1732    
1733                    String trimmedPreviousLine = StringUtil.trimLeading(previousLine);
1734    
1735                    int previousLineLength = getLineLength(previousLine);
1736    
1737                    if (line.startsWith("// ") && trimmedPreviousLine.startsWith("// ")) {
1738                            String linePart = line.substring(3);
1739    
1740                            if (!linePart.startsWith("PLACEHOLDER") &&
1741                                    !linePart.startsWith(StringPool.OPEN_BRACKET)) {
1742    
1743                                    int pos = linePart.indexOf(StringPool.SPACE);
1744    
1745                                    if (pos == -1) {
1746                                            pos = linePart.length();
1747                                    }
1748    
1749                                    if (previousLineLength + pos < 80) {
1750                                            if (linePart.contains(StringPool.SPACE)) {
1751                                                    return new Tuple(
1752                                                            previousLine + StringPool.SPACE,
1753                                                            linePart.substring(0, pos + 1), true);
1754                                            }
1755                                            else {
1756                                                    return new Tuple(
1757                                                            previousLine + StringPool.SPACE + linePart);
1758                                            }
1759                                    }
1760                            }
1761    
1762                            return null;
1763                    }
1764                    else if (line.startsWith("// ") ||
1765                                     trimmedPreviousLine.startsWith("// ")) {
1766    
1767                            return null;
1768                    }
1769    
1770                    if (previousLine.endsWith(" extends")) {
1771                            return new Tuple(previousLine, "extends ", false);
1772                    }
1773    
1774                    if (previousLine.endsWith(" implements")) {
1775                            return new Tuple(previousLine, "implements ", false);
1776                    }
1777    
1778                    if (line.startsWith("+ ") || line.startsWith("- ") ||
1779                            line.startsWith("|| ") || line.startsWith("&& ")) {
1780    
1781                            int pos = line.indexOf(StringPool.SPACE);
1782    
1783                            String linePart = line.substring(0, pos);
1784    
1785                            return new Tuple(previousLine + StringPool.SPACE, linePart, true);
1786                    }
1787    
1788                    if ((line.length() + previousLineLength) < 80) {
1789                            if (trimmedPreviousLine.startsWith("for ") &&
1790                                    previousLine.endsWith(StringPool.COLON) &&
1791                                    line.endsWith(StringPool.OPEN_CURLY_BRACE)) {
1792    
1793                                    return new Tuple(previousLine + StringPool.SPACE + line);
1794                            }
1795    
1796                            if ((previousLine.endsWith(StringPool.EQUAL) ||
1797                                     previousLine.endsWith(StringPool.PERIOD) ||
1798                                     trimmedPreviousLine.equals("return")) &&
1799                                    line.endsWith(StringPool.SEMICOLON)) {
1800    
1801                                    return new Tuple(previousLine + StringPool.SPACE + line);
1802                            }
1803    
1804                            if ((trimmedPreviousLine.startsWith("if ") ||
1805                                     trimmedPreviousLine.startsWith("else ")) &&
1806                                    (previousLine.endsWith("||") || previousLine.endsWith("&&")) &&
1807                                    line.endsWith(StringPool.OPEN_CURLY_BRACE)) {
1808    
1809                                    return new Tuple(previousLine + StringPool.SPACE + line);
1810                            }
1811    
1812                            if ((line.startsWith("extends ") ||
1813                                     line.startsWith("implements ") ||
1814                                     line.startsWith("throws")) &&
1815                                    line.endsWith(StringPool.OPEN_CURLY_BRACE) &&
1816                                    (lineTabCount == (previousLineTabCount + 1))) {
1817    
1818                                    return new Tuple(previousLine + StringPool.SPACE + line);
1819                            }
1820                    }
1821    
1822                    if (previousLine.endsWith(StringPool.EQUAL) &&
1823                            line.endsWith(StringPool.SEMICOLON)) {
1824    
1825                            String tempLine = line;
1826    
1827                            for (int pos = 0;;) {
1828                                    pos = tempLine.indexOf(StringPool.DASH);
1829    
1830                                    if (pos == -1) {
1831                                            pos = tempLine.indexOf(StringPool.PLUS);
1832                                    }
1833    
1834                                    if (pos == -1) {
1835                                            pos = tempLine.indexOf(StringPool.SLASH);
1836                                    }
1837    
1838                                    if (pos == -1) {
1839                                            pos = tempLine.indexOf(StringPool.STAR);
1840                                    }
1841    
1842                                    if (pos == -1) {
1843                                            pos = tempLine.indexOf("||");
1844                                    }
1845    
1846                                    if (pos == -1) {
1847                                            pos = tempLine.indexOf("&&");
1848                                    }
1849    
1850                                    if (pos == -1) {
1851                                            break;
1852                                    }
1853    
1854                                    String linePart = tempLine.substring(0, pos);
1855    
1856                                    int openParenthesisCount = StringUtil.count(
1857                                            linePart, StringPool.OPEN_PARENTHESIS);
1858                                    int closeParenthesisCount = StringUtil.count(
1859                                            linePart, StringPool.CLOSE_PARENTHESIS);
1860    
1861                                    if (openParenthesisCount == closeParenthesisCount) {
1862                                            return null;
1863                                    }
1864    
1865                                    tempLine =
1866                                            tempLine.substring(0, pos) + tempLine.substring(pos + 1);
1867                            }
1868    
1869                            int x = line.indexOf(StringPool.OPEN_PARENTHESIS);
1870    
1871                            if (x == 0) {
1872                                    x = line.indexOf(StringPool.OPEN_PARENTHESIS, 1);
1873                            }
1874    
1875                            if (x != -1) {
1876                                    int y = line.indexOf(StringPool.CLOSE_PARENTHESIS, x);
1877                                    int z = line.indexOf(StringPool.QUOTE);
1878    
1879                                    if (((x + 1) != y) && ((z == -1) || (z > x))) {
1880                                            char previousChar = line.charAt(x - 1);
1881    
1882                                            if ((previousChar != CharPool.CLOSE_PARENTHESIS) &&
1883                                                    (previousChar != CharPool.OPEN_PARENTHESIS) &&
1884                                                    (previousChar != CharPool.SPACE) &&
1885                                                    (previousLineLength + 1 + x) < 80) {
1886    
1887                                                    String linePart = line.substring(0, x + 1);
1888    
1889                                                    if (linePart.startsWith(StringPool.OPEN_PARENTHESIS) &&
1890                                                            !linePart.contains(
1891                                                                    StringPool.CLOSE_PARENTHESIS)) {
1892    
1893                                                            return null;
1894                                                    }
1895    
1896                                                    return new Tuple(
1897                                                            previousLine + StringPool.SPACE, linePart, true);
1898                                            }
1899                                    }
1900                            }
1901                    }
1902    
1903                    if (previousLine.endsWith(StringPool.COMMA) &&
1904                            (previousLineTabCount == lineTabCount) &&
1905                            !previousLine.contains(StringPool.CLOSE_CURLY_BRACE)) {
1906    
1907                            int x = line.indexOf(StringPool.COMMA);
1908    
1909                            if (x != -1) {
1910                                    while ((previousLineLength + 1 + x) < 80) {
1911                                            String linePart = line.substring(0, x + 1);
1912    
1913                                            if (isValidJavaParameter(linePart)) {
1914                                                    if (line.equals(linePart)) {
1915                                                            return new Tuple(
1916                                                                    previousLine + StringPool.SPACE + linePart);
1917                                                    }
1918                                                    else {
1919                                                            return new Tuple(
1920                                                                    previousLine + StringPool.SPACE,
1921                                                                    linePart + StringPool.SPACE, true);
1922                                                    }
1923                                            }
1924    
1925                                            String partAfterComma = line.substring(x + 1);
1926    
1927                                            int pos = partAfterComma.indexOf(StringPool.COMMA);
1928    
1929                                            if (pos == -1) {
1930                                                    break;
1931                                            }
1932    
1933                                            x = x + pos + 1;
1934                                    }
1935                            }
1936                            else if (!line.endsWith(StringPool.OPEN_PARENTHESIS) &&
1937                                             !line.endsWith(StringPool.PLUS) &&
1938                                             !line.endsWith(StringPool.PERIOD) &&
1939                                             (!line.startsWith("new ") ||
1940                                              !line.endsWith(StringPool.OPEN_CURLY_BRACE)) &&
1941                                             ((line.length() + previousLineLength) < 80)) {
1942    
1943                                    return new Tuple(previousLine + StringPool.SPACE + line);
1944                            }
1945                    }
1946    
1947                    if (!previousLine.endsWith(StringPool.OPEN_PARENTHESIS)) {
1948                            return null;
1949                    }
1950    
1951                    if (StringUtil.count(previousLine, StringPool.OPEN_PARENTHESIS) > 1) {
1952                            int pos = trimmedPreviousLine.lastIndexOf(
1953                                    StringPool.OPEN_PARENTHESIS, trimmedPreviousLine.length() - 2);
1954    
1955                            if ((pos > 0) &&
1956                                    Character.isLetterOrDigit(
1957                                            trimmedPreviousLine.charAt(pos -1 ))) {
1958    
1959                                    String filePart = trimmedPreviousLine.substring(pos + 1);
1960    
1961                                    if (!filePart.contains(StringPool.CLOSE_PARENTHESIS) &&
1962                                            !filePart.contains(StringPool.QUOTE)) {
1963    
1964                                            return new Tuple(previousLine, filePart, false);
1965                                    }
1966                            }
1967                    }
1968    
1969                    if ((line.length() + previousLineLength) > 80) {
1970                            return null;
1971                    }
1972    
1973                    if (line.endsWith(StringPool.SEMICOLON)) {
1974                            return new Tuple(previousLine + line);
1975                    }
1976    
1977                    if (((line.endsWith(StringPool.OPEN_CURLY_BRACE) &&
1978                              !line.startsWith("new ")) ||
1979                             line.endsWith(StringPool.CLOSE_PARENTHESIS)) &&
1980                            (trimmedPreviousLine.startsWith("else ") ||
1981                             trimmedPreviousLine.startsWith("if ") ||
1982                             trimmedPreviousLine.startsWith("private ") ||
1983                             trimmedPreviousLine.startsWith("protected ") ||
1984                             trimmedPreviousLine.startsWith("public "))) {
1985    
1986                            return new Tuple(previousLine + line);
1987                    }
1988    
1989                    return null;
1990            }
1991    
1992            protected String getConstructorOrMethodName(String line, int pos) {
1993                    line = line.substring(0, pos);
1994    
1995                    int x = line.lastIndexOf(StringPool.SPACE);
1996    
1997                    return line.substring(x + 1);
1998            }
1999    
2000            protected List<String> getImportedExceptionClassNames(
2001                    JavaDocBuilder javaDocBuilder) {
2002    
2003                    List<String> exceptionClassNames = new ArrayList<String>();
2004    
2005                    JavaSource javaSource = javaDocBuilder.getSources()[0];
2006    
2007                    for (String importClassName : javaSource.getImports()) {
2008                            if (importClassName.endsWith("Exception") &&
2009                                    !exceptionClassNames.contains(importClassName)) {
2010    
2011                                    exceptionClassNames.add(importClassName);
2012                            }
2013                    }
2014    
2015                    return exceptionClassNames;
2016            }
2017    
2018            protected Tuple getJavaTermTuple(
2019                    String line, String content, int index, int numLines, int maxLines) {
2020    
2021                    int pos = line.indexOf(StringPool.OPEN_PARENTHESIS);
2022    
2023                    if (line.startsWith(StringPool.TAB + "public static final ") &&
2024                            (line.contains(StringPool.EQUAL) ||
2025                             (line.endsWith(StringPool.SEMICOLON) && (pos == -1)))) {
2026    
2027                            return new Tuple(
2028                                    getVariableName(line), TYPE_VARIABLE_PUBLIC_STATIC_FINAL);
2029                    }
2030                    else if (line.startsWith(StringPool.TAB + "public static ")) {
2031                            if (line.contains(StringPool.EQUAL) ||
2032                                    (line.endsWith(StringPool.SEMICOLON) && (pos == -1))) {
2033    
2034                                    return new Tuple(
2035                                            getVariableName(line), TYPE_VARIABLE_PUBLIC_STATIC);
2036                            }
2037    
2038                            if (pos != -1) {
2039                                    return new Tuple(
2040                                            getConstructorOrMethodName(line, pos),
2041                                            TYPE_METHOD_PUBLIC_STATIC);
2042                            }
2043    
2044                            if (line.startsWith(StringPool.TAB + "public static class ") ||
2045                                    line.startsWith(StringPool.TAB + "public static enum")) {
2046    
2047                                    return new Tuple(getClassName(line), TYPE_CLASS_PUBLIC_STATIC);
2048                            }
2049                    }
2050                    else if (line.startsWith(StringPool.TAB + "public ")) {
2051                            if (line.contains(StringPool.EQUAL) ||
2052                                    (line.endsWith(StringPool.SEMICOLON) && (pos == -1))) {
2053    
2054                                    return new Tuple(getVariableName(line), TYPE_VARIABLE_PUBLIC);
2055                            }
2056    
2057                            if (pos != -1) {
2058                                    int spaceCount = StringUtil.count(
2059                                            line.substring(0, pos), StringPool.SPACE);
2060    
2061                                    if (spaceCount == 1) {
2062                                            return new Tuple(
2063                                                    getConstructorOrMethodName(line, pos),
2064                                                    TYPE_CONSTRUCTOR_PUBLIC);
2065                                    }
2066    
2067                                    if (spaceCount > 1) {
2068                                            return new Tuple(
2069                                                    getConstructorOrMethodName(line, pos),
2070                                                    TYPE_METHOD_PUBLIC);
2071                                    }
2072                            }
2073                            else if (line.startsWith(
2074                                                    StringPool.TAB + "public abstract class ") ||
2075                                             line.startsWith(StringPool.TAB + "public class ") ||
2076                                             line.startsWith(StringPool.TAB + "public enum ")) {
2077    
2078                                    return new Tuple(getClassName(line), TYPE_CLASS_PUBLIC);
2079                            }
2080                    }
2081                    else if (line.startsWith(StringPool.TAB + "protected static final ")) {
2082                            if (line.contains(StringPool.EQUAL) ||
2083                                    (line.endsWith(StringPool.SEMICOLON) && (pos == -1))) {
2084    
2085                                    return new Tuple(
2086                                            getVariableName(line),
2087                                            TYPE_VARIABLE_PROTECTED_STATIC_FINAL);
2088                            }
2089                    }
2090                    else if (line.startsWith(StringPool.TAB + "protected static ")) {
2091                            if (line.contains(StringPool.EQUAL) ||
2092                                    (line.endsWith(StringPool.SEMICOLON) && (pos == -1))) {
2093    
2094                                    return new Tuple(
2095                                            getVariableName(line), TYPE_VARIABLE_PROTECTED_STATIC);
2096                            }
2097    
2098                            if (pos != -1) {
2099                                    return new Tuple(
2100                                            getConstructorOrMethodName(line, pos),
2101                                            TYPE_METHOD_PROTECTED_STATIC);
2102                            }
2103    
2104                            if (line.startsWith(StringPool.TAB + "protected static class ") ||
2105                                    line.startsWith(StringPool.TAB + "protected static enum ")) {
2106    
2107                                    return new Tuple(
2108                                            getClassName(line), TYPE_CLASS_PROTECTED_STATIC);
2109                            }
2110                    }
2111                    else if (line.startsWith(StringPool.TAB + "protected ")) {
2112                            if (pos != -1) {
2113                                    if (!line.contains(StringPool.EQUAL)) {
2114                                            int spaceCount = StringUtil.count(
2115                                                    line.substring(0, pos), StringPool.SPACE);
2116    
2117                                            if (spaceCount == 1) {
2118                                                    return new Tuple(
2119                                                            getConstructorOrMethodName(line, pos),
2120                                                            TYPE_CONSTRUCTOR_PROTECTED);
2121                                            }
2122    
2123                                            if (spaceCount > 1) {
2124                                                    return new Tuple(
2125                                                            getConstructorOrMethodName(line, pos),
2126                                                            TYPE_METHOD_PROTECTED);
2127                                            }
2128                                    }
2129                            }
2130                            else if (line.startsWith(
2131                                                    StringPool.TAB + "protected abstract class ") ||
2132                                             line.startsWith(StringPool.TAB + "protected class ") ||
2133                                             line.startsWith(StringPool.TAB + "protected enum ")) {
2134    
2135                                    return new Tuple(getClassName(line), TYPE_CLASS_PROTECTED);
2136                            }
2137    
2138                            return new Tuple(getVariableName(line), TYPE_VARIABLE_PROTECTED);
2139                    }
2140                    else if (line.startsWith(StringPool.TAB + "private static final ")) {
2141                            if (line.contains(StringPool.EQUAL) ||
2142                                    (line.endsWith(StringPool.SEMICOLON) && (pos == -1))) {
2143    
2144                                    return new Tuple(
2145                                            getVariableName(line), TYPE_VARIABLE_PRIVATE_STATIC_FINAL);
2146                            }
2147                    }
2148                    else if (line.startsWith(StringPool.TAB + "private static ")) {
2149                            if (line.contains(StringPool.EQUAL) ||
2150                                    (line.endsWith(StringPool.SEMICOLON) && (pos == -1))) {
2151    
2152                                    return new Tuple(
2153                                            getVariableName(line), TYPE_VARIABLE_PRIVATE_STATIC);
2154                            }
2155    
2156                            if (pos != -1) {
2157                                    return new Tuple(
2158                                            getConstructorOrMethodName(line, pos),
2159                                            TYPE_METHOD_PRIVATE_STATIC);
2160                            }
2161    
2162                            if (line.startsWith(StringPool.TAB + "private static class ") ||
2163                                    line.startsWith(StringPool.TAB + "private static enum ")) {
2164    
2165                                    return new Tuple(getClassName(line), TYPE_CLASS_PRIVATE_STATIC);
2166                            }
2167                    }
2168                    else if (line.startsWith(StringPool.TAB + "private ")) {
2169                            if (line.contains(StringPool.EQUAL) ||
2170                                    (line.endsWith(StringPool.SEMICOLON) && (pos == -1))) {
2171    
2172                                    return new Tuple(getVariableName(line), TYPE_VARIABLE_PRIVATE);
2173                            }
2174    
2175                            if (pos != -1) {
2176                                    int spaceCount = StringUtil.count(
2177                                            line.substring(0, pos), StringPool.SPACE);
2178    
2179                                    if (spaceCount == 1) {
2180                                            return new Tuple(
2181                                                    getConstructorOrMethodName(line, pos),
2182                                                    TYPE_CONSTRUCTOR_PRIVATE);
2183                                    }
2184    
2185                                    if (spaceCount > 1) {
2186                                            return new Tuple(
2187                                                    getConstructorOrMethodName(line, pos),
2188                                                    TYPE_METHOD_PRIVATE);
2189                                    }
2190                            }
2191                            else if (line.startsWith(
2192                                                    StringPool.TAB + "private abstract class ") ||
2193                                             line.startsWith(StringPool.TAB + "private class ") ||
2194                                             line.startsWith(StringPool.TAB + "private enum ")) {
2195    
2196                                    return new Tuple(getClassName(line), TYPE_CLASS_PRIVATE);
2197                            }
2198                    }
2199    
2200                    if (numLines < maxLines) {
2201                            int posStartNextLine =
2202                                    content.indexOf(StringPool.NEW_LINE, index) + 1;
2203    
2204                            int posEndNextline = content.indexOf(
2205                                    StringPool.NEW_LINE, posStartNextLine);
2206    
2207                            String nextLine = content.substring(
2208                                    posStartNextLine, posEndNextline);
2209    
2210                            if (Validator.isNull(nextLine)) {
2211                                    return null;
2212                            }
2213    
2214                            nextLine = StringUtil.trimLeading(nextLine);
2215    
2216                            return getJavaTermTuple(
2217                                    line + StringPool.SPACE + nextLine, content, posStartNextLine,
2218                                    numLines + 1, maxLines);
2219                    }
2220                    else {
2221                            return null;
2222                    }
2223            }
2224    
2225            protected int getLeadingTabCount(String line) {
2226                    int leadingTabCount = 0;
2227    
2228                    while (line.startsWith(StringPool.TAB)) {
2229                            line = line.substring(1);
2230    
2231                            leadingTabCount++;
2232                    }
2233    
2234                    return leadingTabCount;
2235            }
2236    
2237            protected int getLineLength(String line) {
2238                    int lineLength = 0;
2239    
2240                    int tabLength = 4;
2241    
2242                    for (char c : line.toCharArray()) {
2243                            if (c == CharPool.TAB) {
2244                                    for (int i = 0; i < tabLength; i++) {
2245                                            lineLength++;
2246                                    }
2247    
2248                                    tabLength = 4;
2249                            }
2250                            else {
2251                                    lineLength++;
2252    
2253                                    tabLength--;
2254    
2255                                    if (tabLength <= 0) {
2256                                            tabLength = 4;
2257                                    }
2258                            }
2259                    }
2260    
2261                    return lineLength;
2262            }
2263    
2264            protected Collection<String> getPluginJavaFiles() {
2265                    Collection<String> fileNames = new TreeSet<String>();
2266    
2267                    String[] excludes = new String[] {
2268                            "**\\bin\\**", "**\\model\\*Clp.java",
2269                            "**\\model\\impl\\*BaseImpl.java", "**\\model\\impl\\*Model.java",
2270                            "**\\model\\impl\\*ModelImpl.java",
2271                            "**\\service\\**\\service\\*Service.java",
2272                            "**\\service\\**\\service\\*ServiceClp.java",
2273                            "**\\service\\**\\service\\*ServiceFactory.java",
2274                            "**\\service\\**\\service\\*ServiceUtil.java",
2275                            "**\\service\\**\\service\\*ServiceWrapper.java",
2276                            "**\\service\\**\\service\\ClpSerializer.java",
2277                            "**\\service\\**\\service\\messaging\\*ClpMessageListener.java",
2278                            "**\\service\\**\\service\\persistence\\*Finder.java",
2279                            "**\\service\\**\\service\\persistence\\*Util.java",
2280                            "**\\service\\base\\*ServiceBaseImpl.java",
2281                            "**\\service\\base\\*ServiceClpInvoker.java",
2282                            "**\\service\\http\\*JSONSerializer.java",
2283                            "**\\service\\http\\*ServiceHttp.java",
2284                            "**\\service\\http\\*ServiceJSON.java",
2285                            "**\\service\\http\\*ServiceSoap.java", "**\\tmp\\**"
2286                    };
2287                    String[] includes = new String[] {"**\\*.java"};
2288    
2289                    fileNames.addAll(getFileNames(excludes, includes));
2290    
2291                    return fileNames;
2292            }
2293    
2294            protected Collection<String> getPortalJavaFiles() {
2295                    Collection<String> fileNames = new TreeSet<String>();
2296    
2297                    String[] excludes = new String[] {
2298                            "**\\*_IW.java", "**\\PropsValues.java", "**\\bin\\**",
2299                            "**\\classes\\*", "**\\counter\\service\\**", "**\\jsp\\*",
2300                            "**\\model\\impl\\*BaseImpl.java", "**\\model\\impl\\*Model.java",
2301                            "**\\model\\impl\\*ModelImpl.java", "**\\portal\\service\\**",
2302                            "**\\portal-client\\**", "**\\portal-web\\classes\\**\\*.java",
2303                            "**\\portal-web\\test\\**\\*Test.java",
2304                            "**\\portal-web\\test\\**\\*Tests.java",
2305                            "**\\portlet\\**\\service\\**", "**\\test\\*-generated\\**",
2306                            "**\\tmp\\**", "**\\tools\\tck\\**"
2307                    };
2308                    String[] includes = new String[] {"**\\*.java"};
2309    
2310                    fileNames.addAll(getFileNames(excludes, includes));
2311    
2312                    excludes = new String[] {
2313                            "**\\bin\\**", "**\\portal-client\\**", "**\\tools\\ext_tmpl\\**",
2314                            "**\\*_IW.java", "**\\test\\**\\*PersistenceTest.java"
2315                    };
2316                    includes = new String[] {
2317                            "**\\com\\liferay\\portal\\service\\ServiceContext*.java",
2318                            "**\\model\\BaseModel.java", "**\\model\\impl\\BaseModelImpl.java",
2319                            "**\\service\\Base*.java",
2320                            "**\\service\\PersistedModelLocalService*.java",
2321                            "**\\service\\base\\PrincipalBean.java",
2322                            "**\\service\\http\\*HttpTest.java",
2323                            "**\\service\\http\\*SoapTest.java",
2324                            "**\\service\\http\\TunnelUtil.java", "**\\service\\impl\\*.java",
2325                            "**\\service\\jms\\*.java", "**\\service\\permission\\*.java",
2326                            "**\\service\\persistence\\BasePersistence.java",
2327                            "**\\service\\persistence\\BatchSession*.java",
2328                            "**\\service\\persistence\\*FinderImpl.java",
2329                            "**\\service\\persistence\\*Query.java",
2330                            "**\\service\\persistence\\impl\\BasePersistenceImpl.java",
2331                            "**\\portal-impl\\test\\**\\*.java",
2332                            "**\\portal-service\\**\\liferay\\documentlibrary\\**.java",
2333                            "**\\portal-service\\**\\liferay\\lock\\**.java",
2334                            "**\\portal-service\\**\\liferay\\mail\\**.java",
2335                            "**\\util-bridges\\**\\*.java"
2336                    };
2337    
2338                    fileNames.addAll(getFileNames(excludes, includes));
2339    
2340                    return fileNames;
2341            }
2342    
2343            protected String getVariableName(String line) {
2344                    int x = line.indexOf(StringPool.EQUAL);
2345                    int y = line.lastIndexOf(StringPool.SPACE);
2346    
2347                    if (x != -1) {
2348                            line = line.substring(0, x);
2349                            line = StringUtil.trim(line);
2350    
2351                            y = line.lastIndexOf(StringPool.SPACE);
2352    
2353                            return line.substring(y + 1);
2354                    }
2355    
2356                    if (line.endsWith(StringPool.SEMICOLON)) {
2357                            return line.substring(y + 1, line.length() - 1);
2358                    }
2359    
2360                    return StringPool.BLANK;
2361            }
2362    
2363            protected boolean hasAnnotationCommentOrJavadoc(String s) {
2364                    if (s.startsWith(StringPool.TAB + StringPool.AT) ||
2365                            s.startsWith(StringPool.TAB + "/**") ||
2366                            s.startsWith(StringPool.TAB + "//")) {
2367    
2368                            return true;
2369                    }
2370                    else {
2371                            return false;
2372                    }
2373            }
2374    
2375            protected boolean isGenerated(String content) {
2376                    if (content.contains("* @generated") || content.contains("$ANTLR")) {
2377                            return true;
2378                    }
2379                    else {
2380                            return false;
2381                    }
2382            }
2383    
2384            protected boolean isInJavaTermTypeGroup(
2385                    int javaTermType, int[] javaTermTypeGroup) {
2386    
2387                    for (int type : javaTermTypeGroup) {
2388                            if (javaTermType == type) {
2389                                    return true;
2390                            }
2391                    }
2392    
2393                    return false;
2394            }
2395    
2396            protected boolean isValidJavaParameter(String javaParameter) {
2397                    int quoteCount = StringUtil.count(javaParameter, StringPool.QUOTE);
2398    
2399                    if ((quoteCount % 2) == 1) {
2400                            return false;
2401                    }
2402    
2403                    javaParameter = stripQuotes(javaParameter, StringPool.QUOTE);
2404    
2405                    int openParenthesisCount = StringUtil.count(
2406                            javaParameter, StringPool.OPEN_PARENTHESIS);
2407                    int closeParenthesisCount = StringUtil.count(
2408                            javaParameter, StringPool.CLOSE_PARENTHESIS);
2409                    int lessThanCount = StringUtil.count(
2410                            javaParameter, StringPool.LESS_THAN);
2411                    int greaterThanCount = StringUtil.count(
2412                            javaParameter, StringPool.GREATER_THAN);
2413                    int openCurlyBraceCount = StringUtil.count(
2414                            javaParameter, StringPool.OPEN_CURLY_BRACE);
2415                    int closeCurlyBraceCount = StringUtil.count(
2416                            javaParameter, StringPool.CLOSE_CURLY_BRACE);
2417    
2418                    if ((openParenthesisCount == closeParenthesisCount) &&
2419                            (lessThanCount == greaterThanCount) &&
2420                            (openCurlyBraceCount == closeCurlyBraceCount)) {
2421    
2422                            return true;
2423                    }
2424    
2425                    return false;
2426            }
2427    
2428            protected String sortExceptions(String line) {
2429                    if (!line.endsWith(StringPool.OPEN_CURLY_BRACE) &&
2430                            !line.endsWith(StringPool.SEMICOLON)) {
2431    
2432                            return line;
2433                    }
2434    
2435                    int x = line.indexOf("throws ");
2436    
2437                    if (x == -1) {
2438                            return line;
2439                    }
2440    
2441                    String previousException = StringPool.BLANK;
2442    
2443                    String[] exceptions = StringUtil.split(
2444                            line.substring(x), CharPool.SPACE);
2445    
2446                    for (int i = 1; i < exceptions.length; i++) {
2447                            String exception = exceptions[i];
2448    
2449                            if (exception.equals(StringPool.OPEN_CURLY_BRACE)) {
2450                                    break;
2451                            }
2452    
2453                            if (exception.endsWith(StringPool.COMMA) ||
2454                                    exception.endsWith(StringPool.SEMICOLON)) {
2455    
2456                                    exception = exception.substring(0, exception.length() - 1);
2457                            }
2458    
2459                            if (Validator.isNotNull(previousException) &&
2460                                    (previousException.compareToIgnoreCase(exception) > 0)) {
2461    
2462                                    return StringUtil.replace(
2463                                            line, previousException + ", " + exception,
2464                                            exception + ", " + previousException);
2465                            }
2466    
2467                            previousException = exception;
2468                    }
2469    
2470                    return line;
2471            }
2472    
2473            protected String sortJavaTerms(
2474                    String fileName, String content, Set<JavaTerm> javaTerms) {
2475    
2476                    JavaTerm previousJavaTerm = null;
2477    
2478                    Iterator<JavaTerm> itr = javaTerms.iterator();
2479    
2480                    while (itr.hasNext()) {
2481                            JavaTerm javaTerm = itr.next();
2482    
2483                            if (previousJavaTerm == null) {
2484                                    previousJavaTerm = javaTerm;
2485    
2486                                    continue;
2487                            }
2488    
2489                            int javaTermLineCount = javaTerm.getLineCount();
2490                            String javaTermName = javaTerm.getName();
2491    
2492                            String excluded = null;
2493    
2494                            if (_javaTermSortExclusions != null) {
2495                                    excluded = _javaTermSortExclusions.getProperty(
2496                                            fileName + StringPool.AT + javaTermLineCount);
2497    
2498                                    if (excluded == null) {
2499                                            excluded = _javaTermSortExclusions.getProperty(
2500                                                    fileName + StringPool.AT + javaTermName);
2501                                    }
2502    
2503                                    if (excluded == null) {
2504                                            excluded = _javaTermSortExclusions.getProperty(fileName);
2505                                    }
2506                            }
2507    
2508                            if (excluded != null) {
2509                                    previousJavaTerm = javaTerm;
2510    
2511                                    continue;
2512                            }
2513    
2514                            String javaTermContent = javaTerm.getContent();
2515                            String previousJavaTermContent = previousJavaTerm.getContent();
2516    
2517                            if (previousJavaTerm.getLineCount() > javaTermLineCount) {
2518                                    String previousJavaTermName = previousJavaTerm.getName();
2519    
2520                                    String javaTermNameLowerCase = javaTermName.toLowerCase();
2521                                    String previousJavaTermNameLowerCase =
2522                                            previousJavaTermName.toLowerCase();
2523    
2524                                    if (fileName.contains("persistence") &&
2525                                            ((previousJavaTermName.startsWith("doCount") &&
2526                                              javaTermName.startsWith("doCount")) ||
2527                                             (previousJavaTermName.startsWith("doFind") &&
2528                                              javaTermName.startsWith("doFind")) ||
2529                                             (previousJavaTermNameLowerCase.startsWith("count") &&
2530                                              javaTermNameLowerCase.startsWith("count")) ||
2531                                             (previousJavaTermNameLowerCase.startsWith("filter") &&
2532                                              javaTermNameLowerCase.startsWith("filter")) ||
2533                                             (previousJavaTermNameLowerCase.startsWith("find") &&
2534                                              javaTermNameLowerCase.startsWith("find")) ||
2535                                             (previousJavaTermNameLowerCase.startsWith("join") &&
2536                                              javaTermNameLowerCase.startsWith("join")))) {
2537                                    }
2538                                    else {
2539                                            content = StringUtil.replaceFirst(
2540                                                    content, javaTermContent, previousJavaTermContent);
2541                                            content = StringUtil.replaceLast(
2542                                                    content, previousJavaTermContent, javaTermContent);
2543    
2544                                            return content;
2545                                    }
2546                            }
2547    
2548                            previousJavaTerm = javaTerm;
2549                    }
2550    
2551                    return content;
2552            }
2553    
2554            private boolean _checkUnprocessedExceptions;
2555            private Properties _javaTermSortExclusions;
2556            private Properties _lineLengthExclusions;
2557    
2558    }