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