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