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