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