
com.liferay.source.formatter.BaseSourceProcessor Maven / Gradle / Ivy
/**
* Copyright (c) 2000-present Liferay, Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*/
package com.liferay.source.formatter;
import com.liferay.portal.kernel.io.unsync.UnsyncBufferedReader;
import com.liferay.portal.kernel.io.unsync.UnsyncStringReader;
import com.liferay.portal.kernel.util.ArrayUtil;
import com.liferay.portal.kernel.util.CharPool;
import com.liferay.portal.kernel.util.GetterUtil;
import com.liferay.portal.kernel.util.ListUtil;
import com.liferay.portal.kernel.util.ReflectionUtil;
import com.liferay.portal.kernel.util.ReleaseInfo;
import com.liferay.portal.kernel.util.SetUtil;
import com.liferay.portal.kernel.util.StringBundler;
import com.liferay.portal.kernel.util.StringPool;
import com.liferay.portal.kernel.util.StringUtil;
import com.liferay.portal.kernel.util.TextFormatter;
import com.liferay.portal.kernel.util.Validator;
import com.liferay.portal.tools.ToolsUtil;
import com.liferay.source.formatter.util.FileUtil;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.io.FilenameUtils;
import org.apache.tools.ant.types.selectors.SelectorUtils;
/**
* @author Brian Wing Shun Chan
* @author Igor Spasic
* @author Wesley Gong
* @author Hugo Huijser
*/
public abstract class BaseSourceProcessor implements SourceProcessor {
public static final int PORTAL_MAX_DIR_LEVEL = 5;
public BaseSourceProcessor() {
portalSource = _isPortalSource();
try {
_properties = _getProperties();
}
catch (Exception e) {
ReflectionUtil.throwException(e);
}
}
@Override
public final void format() throws Exception {
for (String fileName : getFileNames()) {
try {
format(fileName);
}
catch (Exception e) {
throw new RuntimeException("Unable to format " + fileName, e);
}
}
postFormat();
_sourceFormatterHelper.close();
}
@Override
public List getErrorMessages() {
List errorMessages = new ArrayList<>();
for (Map.Entry> entry :
_errorMessagesMap.entrySet()) {
errorMessages.addAll(entry.getValue());
}
return errorMessages;
}
public final List getFileNames() throws Exception {
List fileNames = sourceFormatterArgs.getFileNames();
if (fileNames != null) {
return fileNames;
}
return doGetFileNames();
}
@Override
public SourceMismatchException getFirstSourceMismatchException() {
return _firstSourceMismatchException;
}
@Override
public List getModifiedFileNames() {
return _modifiedFileNames;
}
@Override
public void setSourceFormatterArgs(
SourceFormatterArgs sourceFormatterArgs) {
this.sourceFormatterArgs = sourceFormatterArgs;
_init();
}
protected static int getLeadingTabCount(String line) {
int leadingTabCount = 0;
while (line.startsWith(StringPool.TAB)) {
line = line.substring(1);
leadingTabCount++;
}
return leadingTabCount;
}
protected static boolean isExcludedFile(
List exclusionFiles, String absolutePath) {
return isExcludedFile(exclusionFiles, absolutePath, -1);
}
protected static boolean isExcludedFile(
List exclusionFiles, String absolutePath, int lineCount) {
return isExcludedFile(exclusionFiles, absolutePath, lineCount, null);
}
protected static boolean isExcludedFile(
List exclusionFiles, String absolutePath, int lineCount,
String javaTermName) {
if (ListUtil.isEmpty(exclusionFiles)) {
return false;
}
String absolutePathWithJavaTermName = null;
if (Validator.isNotNull(javaTermName)) {
absolutePathWithJavaTermName =
absolutePath + StringPool.AT + javaTermName;
}
String absolutePathWithLineCount = null;
if (lineCount > 0) {
absolutePathWithLineCount =
absolutePath + StringPool.AT + lineCount;
}
for (String exclusionFile : exclusionFiles) {
if (absolutePath.endsWith(exclusionFile) ||
((absolutePathWithJavaTermName != null) &&
absolutePathWithJavaTermName.endsWith(exclusionFile)) ||
((absolutePathWithLineCount != null) &&
absolutePathWithLineCount.endsWith(exclusionFile))) {
return true;
}
}
return false;
}
protected static boolean isExcludedPath(
List exclusionPaths, String absolutePath) {
if (ListUtil.isEmpty(exclusionPaths)) {
return false;
}
for (String exclusionPath : exclusionPaths) {
if (absolutePath.contains(exclusionPath)) {
return true;
}
}
return false;
}
protected static String stripQuotes(String s, char delimeter) {
boolean insideQuotes = false;
StringBundler sb = new StringBundler();
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (insideQuotes) {
if (c == delimeter) {
int precedingBackSlashCount = 0;
for (int j = (i - 1); j >= 0; j--) {
if (s.charAt(j) == CharPool.BACK_SLASH) {
precedingBackSlashCount += 1;
}
else {
break;
}
}
if ((precedingBackSlashCount == 0) ||
((precedingBackSlashCount % 2) == 0)) {
insideQuotes = false;
}
}
}
else if (c == delimeter) {
insideQuotes = true;
}
else {
sb.append(c);
}
}
return sb.toString();
}
protected void checkEmptyCollection(
String line, String fileName, int lineCount) {
// LPS-46028
Matcher matcher = emptyCollectionPattern.matcher(line);
if (matcher.find()) {
String collectionType = TextFormatter.format(
matcher.group(1), TextFormatter.J);
processErrorMessage(
fileName,
"Use Collections.empty" + collectionType + "(): " + fileName +
" " + lineCount);
}
}
protected void checkIfClauseParentheses(
String ifClause, String fileName, int lineCount) {
int quoteCount = StringUtil.count(ifClause, StringPool.QUOTE);
if ((quoteCount % 2) == 1) {
return;
}
ifClause = stripQuotes(ifClause, CharPool.QUOTE);
ifClause = stripQuotes(ifClause, CharPool.APOSTROPHE);
if (ifClause.contains(StringPool.DOUBLE_SLASH) ||
ifClause.contains("/*") || ifClause.contains("*/")) {
return;
}
if (hasRedundantParentheses(ifClause, "||", "&&") ||
hasRedundantParentheses(ifClause, "&&", "||")) {
processErrorMessage(
fileName,
"redundant parentheses: " + fileName + " " + lineCount);
}
ifClause = stripRedundantParentheses(ifClause);
int level = 0;
int max = StringUtil.count(ifClause, StringPool.OPEN_PARENTHESIS);
int previousParenthesisPos = -1;
int[] levels = new int[max];
for (int i = 0; i < ifClause.length(); i++) {
char c = ifClause.charAt(i);
if ((c == CharPool.OPEN_PARENTHESIS) ||
(c == CharPool.CLOSE_PARENTHESIS)) {
if (previousParenthesisPos != -1) {
String s = ifClause.substring(
previousParenthesisPos + 1, i);
if (hasMissingParentheses(s)) {
processErrorMessage(
fileName,
"missing parentheses: " + fileName + " " +
lineCount);
}
}
previousParenthesisPos = i;
if (c == CharPool.OPEN_PARENTHESIS) {
levels[level] = i;
level += 1;
}
else {
int posOpenParenthesis = levels[level - 1];
if (level > 1) {
char nextChar = ifClause.charAt(i + 1);
char previousChar = ifClause.charAt(
posOpenParenthesis - 1);
if (!Character.isLetterOrDigit(nextChar) &&
(nextChar != CharPool.PERIOD) &&
!Character.isLetterOrDigit(previousChar)) {
String s = ifClause.substring(
posOpenParenthesis + 1, i);
if (hasRedundantParentheses(s)) {
processErrorMessage(
fileName,
"redundant parentheses: " + fileName + " " +
lineCount);
}
}
if ((previousChar == CharPool.OPEN_PARENTHESIS) &&
(nextChar == CharPool.CLOSE_PARENTHESIS)) {
processErrorMessage(
fileName,
"redundant parentheses: " + fileName + " " +
lineCount);
}
}
level -= 1;
}
}
}
}
protected void checkInefficientStringMethods(
String line, String fileName, String absolutePath, int lineCount) {
if (isExcludedPath(getRunOutsidePortalExclusionPaths(), absolutePath) ||
fileName.endsWith("GetterUtil.java")) {
return;
}
String methodName = "toLowerCase";
int pos = line.indexOf(".toLowerCase()");
if (pos == -1) {
methodName = "toUpperCase";
pos = line.indexOf(".toUpperCase()");
}
if ((pos == -1) && !line.contains("StringUtil.equalsIgnoreCase(")) {
methodName = "equalsIgnoreCase";
pos = line.indexOf(".equalsIgnoreCase(");
}
if (pos != -1) {
processErrorMessage(
fileName,
"Use StringUtil." + methodName + ": " + fileName + " " +
lineCount);
}
}
protected void checkLanguageKeys(
String fileName, String content, Pattern pattern)
throws Exception {
String fileExtension = FilenameUtils.getExtension(fileName);
if (!portalSource || fileExtension.equals("vm")) {
return;
}
if (_portalLanguageProperties == null) {
_portalLanguageProperties = new Properties();
File portalLanguagePropertiesFile = new File(
getFile("portal-impl", PORTAL_MAX_DIR_LEVEL),
"src/content/Language.properties");
InputStream inputStream = new FileInputStream(
portalLanguagePropertiesFile);
_portalLanguageProperties.load(inputStream);
}
Matcher matcher = pattern.matcher(content);
while (matcher.find()) {
String[] languageKeys = getLanguageKeys(matcher);
for (String languageKey : languageKeys) {
if (Validator.isNumber(languageKey) ||
languageKey.endsWith(StringPool.DASH) ||
languageKey.endsWith(StringPool.OPEN_BRACKET) ||
languageKey.endsWith(StringPool.PERIOD) ||
languageKey.endsWith(StringPool.UNDERLINE) ||
languageKey.startsWith(StringPool.DASH) ||
languageKey.startsWith(StringPool.OPEN_BRACKET) ||
languageKey.startsWith(StringPool.OPEN_CURLY_BRACE) ||
languageKey.startsWith(StringPool.PERIOD) ||
languageKey.startsWith(StringPool.UNDERLINE) ||
_portalLanguageProperties.containsKey(languageKey)) {
continue;
}
Properties moduleLanguageProperties =
getModuleLanguageProperties(fileName);
if ((moduleLanguageProperties != null) &&
moduleLanguageProperties.containsKey(languageKey)) {
continue;
}
Properties bndFileLanguageProperties =
getBNDFileLanguageProperties(fileName);
if ((bndFileLanguageProperties == null) ||
!bndFileLanguageProperties.containsKey(languageKey)) {
processErrorMessage(
fileName,
"missing language key: " + languageKey +
StringPool.SPACE + fileName);
}
}
}
}
protected String checkPrincipalException(String content) {
String newContent = content;
Matcher matcher = principalExceptionPattern.matcher(content);
while (matcher.find()) {
String match = matcher.group();
String replacement = StringUtil.replace(
match, "class.getName", "getNestedClasses");
newContent = StringUtil.replace(newContent, match, replacement);
}
return newContent;
}
protected void checkResourceUtil(
String line, String fileName, int lineCount) {
if (!portalSource || fileName.endsWith("ResourceBundleUtil.java")) {
return;
}
if (line.contains("ResourceBundle.getBundle(")) {
processErrorMessage(
fileName,
"Use ResourceBundleUtil.getBundle instead of " +
"ResourceBundle.getBundle: " + fileName + " " + lineCount);
}
if (line.contains("resourceBundle.getString(")) {
processErrorMessage(
fileName,
"Use ResourceBundleUtil.getString instead of " +
"resourceBundle.getString: " + fileName + " " + lineCount);
}
}
protected void checkStringBundler(
String line, String fileName, int lineCount) {
if ((!line.startsWith("sb.append(") && !line.contains("SB.append(")) ||
!line.endsWith(");")) {
return;
}
int pos = line.indexOf(".append(");
line = line.substring(pos + 8, line.length() - 2);
line = stripQuotes(line, CharPool.QUOTE);
if (!line.contains(" + ")) {
return;
}
String[] lineParts = StringUtil.split(line, " + ");
for (String linePart : lineParts) {
int closeParenthesesCount = StringUtil.count(
linePart, StringPool.CLOSE_PARENTHESIS);
int openParenthesesCount = StringUtil.count(
linePart, StringPool.OPEN_PARENTHESIS);
if (closeParenthesesCount != openParenthesesCount) {
return;
}
if (Validator.isNumber(linePart)) {
return;
}
}
processErrorMessage(fileName, "plus: " + fileName + " " + lineCount);
}
protected abstract String doFormat(
File file, String fileName, String absolutePath, String content)
throws Exception;
protected abstract List doGetFileNames() throws Exception;
protected String fixCompatClassImports(String absolutePath, String content)
throws Exception {
if (portalSource || !_usePortalCompatImport ||
absolutePath.contains("/ext-") ||
absolutePath.contains("/portal-compat-shared/")) {
return content;
}
Map compatClassNamesMap = getCompatClassNamesMap();
String newContent = content;
for (Map.Entry entry : compatClassNamesMap.entrySet()) {
String compatClassName = entry.getKey();
String extendedClassName = entry.getValue();
Pattern pattern = Pattern.compile(extendedClassName + "\\W");
while (true) {
Matcher matcher = pattern.matcher(newContent);
if (!matcher.find()) {
break;
}
newContent =
newContent.substring(0, matcher.start()) + compatClassName +
newContent.substring(matcher.end() - 1);
}
}
return newContent;
}
protected String fixCopyright(
String content, String absolutePath, String fileName)
throws IOException {
if (_copyright == null) {
_copyright = getContent(
sourceFormatterArgs.getCopyrightFileName(),
PORTAL_MAX_DIR_LEVEL);
}
String copyright = _copyright;
if (fileName.endsWith(".vm") || Validator.isNull(copyright)) {
return content;
}
if (_oldCopyright == null) {
_oldCopyright = getContent(
"old-copyright.txt", PORTAL_MAX_DIR_LEVEL);
}
if (Validator.isNotNull(_oldCopyright) &&
content.contains(_oldCopyright)) {
content = StringUtil.replace(content, _oldCopyright, copyright);
processErrorMessage(fileName, "old (c): " + fileName);
}
if (!content.contains(copyright)) {
String customCopyright = getCustomCopyright(absolutePath);
if (Validator.isNotNull(customCopyright)) {
copyright = customCopyright;
}
if (!content.contains(copyright)) {
processErrorMessage(fileName, "(c): " + fileName);
}
}
if (fileName.endsWith(".jsp") || fileName.endsWith(".jspf")) {
content = StringUtil.replace(
content, "<%\n" + copyright + "\n%>",
"<%--\n" + copyright + "\n--%>");
}
int x = content.indexOf("* Copyright (c) 2000-");
if (x == -1) {
return content;
}
int y = content.indexOf("Liferay", x);
String contentCopyrightYear = content.substring(x, y);
x = copyright.indexOf("* Copyright (c) 2000-");
if (x == -1) {
return content;
}
y = copyright.indexOf("Liferay", x);
String copyrightYear = copyright.substring(x, y);
return StringUtil.replace(content, contentCopyrightYear, copyrightYear);
}
protected String fixIncorrectParameterTypeForLanguageUtil(
String content, boolean autoFix, String fileName) {
if (portalSource) {
return content;
}
String expectedParameter = getProperty(
"languageutil.expected.parameter");
String incorrectParameter = getProperty(
"languageutil.incorrect.parameter");
if (!content.contains(
"LanguageUtil.format(" + incorrectParameter + ", ") &&
!content.contains(
"LanguageUtil.get(" + incorrectParameter + ", ")) {
return content;
}
if (autoFix) {
content = StringUtil.replace(
content,
new String[] {
"LanguageUtil.format(" + incorrectParameter + ", ",
"LanguageUtil.get(" + incorrectParameter + ", "
},
new String[] {
"LanguageUtil.format(" + expectedParameter + ", ",
"LanguageUtil.get(" + expectedParameter + ", "
});
}
else {
processErrorMessage(
fileName,
"(Unicode)LanguageUtil.format/get methods require " +
expectedParameter + " parameter instead of " +
incorrectParameter + " " + fileName);
}
return content;
}
protected String fixSessionKey(
String fileName, String content, Pattern pattern) {
Matcher matcher = pattern.matcher(content);
if (!matcher.find()) {
return content;
}
String newContent = content;
do {
String match = matcher.group();
String s = null;
if (pattern.equals(sessionKeyPattern)) {
s = StringPool.COMMA;
}
else if (pattern.equals(taglibSessionKeyPattern)) {
s = "key=";
}
int x = match.indexOf(s);
if (x == -1) {
continue;
}
x = x + s.length();
String substring = match.substring(x).trim();
String quote = StringPool.BLANK;
if (substring.startsWith(StringPool.APOSTROPHE)) {
quote = StringPool.APOSTROPHE;
}
else if (substring.startsWith(StringPool.QUOTE)) {
quote = StringPool.QUOTE;
}
else {
continue;
}
int y = match.indexOf(quote, x);
int z = match.indexOf(quote, y + 1);
if ((y == -1) || (z == -1)) {
continue;
}
String prefix = match.substring(0, y + 1);
String suffix = match.substring(z);
String oldKey = match.substring(y + 1, z);
boolean alphaNumericKey = true;
for (char c : oldKey.toCharArray()) {
if (!Validator.isChar(c) && !Validator.isDigit(c) &&
(c != CharPool.DASH) && (c != CharPool.UNDERLINE)) {
alphaNumericKey = false;
}
}
if (!alphaNumericKey) {
continue;
}
String newKey = TextFormatter.format(oldKey, TextFormatter.O);
newKey = TextFormatter.format(newKey, TextFormatter.M);
if (newKey.equals(oldKey)) {
continue;
}
String oldSub = prefix.concat(oldKey).concat(suffix);
String newSub = prefix.concat(newKey).concat(suffix);
newContent = StringUtil.replaceFirst(newContent, oldSub, newSub);
}
while (matcher.find());
return newContent;
}
protected final String format(
File file, String fileName, String absolutePath, String content)
throws Exception {
_errorMessagesMap.remove(fileName);
String newContent = doFormat(file, fileName, absolutePath, content);
newContent = StringUtil.replace(
newContent, StringPool.RETURN, StringPool.BLANK);
if (content.equals(newContent)) {
return content;
}
return format(file, fileName, absolutePath, newContent);
}
protected final void format(String fileName) throws Exception {
if (!_isMatchPath(fileName)) {
return;
}
fileName = StringUtil.replace(
fileName, StringPool.BACK_SLASH, StringPool.SLASH);
File file = new File(fileName);
String absolutePath = getAbsolutePath(file);
String content = FileUtil.read(file);
String newContent = format(file, fileName, absolutePath, content);
processFormattedFile(file, fileName, content, newContent);
}
protected String formatIncorrectSyntax(
String line, String incorrectSyntax, String correctSyntax,
boolean lineStart) {
if (lineStart) {
if (line.startsWith(incorrectSyntax)) {
line = StringUtil.replaceFirst(
line, incorrectSyntax, correctSyntax);
}
return line;
}
for (int x = -1;;) {
x = line.indexOf(incorrectSyntax, x + 1);
if (x == -1) {
return line;
}
if (!ToolsUtil.isInsideQuotes(line, x)) {
line = StringUtil.replaceFirst(
line, incorrectSyntax, correctSyntax, x);
}
}
}
protected String formatJavaTerms(
String javaClassName, String packagePath, File file,
String fileName, String absolutePath, String content,
String javaClassContent, int javaClassLineCount,
List checkJavaFieldTypesExclusionFiles,
List javaTermAccessLevelModifierExclusionFiles,
List javaTermSortExclusionFiles,
List testAnnotationsExclusionFiles)
throws Exception {
JavaSourceProcessor javaSourceProcessor = null;
if (this instanceof JavaSourceProcessor) {
javaSourceProcessor = (JavaSourceProcessor)this;
}
else {
javaSourceProcessor = new JavaSourceProcessor();
javaSourceProcessor.setSourceFormatterArgs(sourceFormatterArgs);
}
JavaClass javaClass = new JavaClass(
javaClassName, packagePath, file, fileName, absolutePath,
javaClassContent, javaClassLineCount, StringPool.TAB, null,
javaTermAccessLevelModifierExclusionFiles, javaSourceProcessor);
String newJavaClassContent = javaClass.formatJavaTerms(
getAnnotationsExclusions(), getImmutableFieldTypes(),
checkJavaFieldTypesExclusionFiles, javaTermSortExclusionFiles,
testAnnotationsExclusionFiles);
if (!javaClassContent.equals(newJavaClassContent)) {
return StringUtil.replaceFirst(
content, javaClassContent, newJavaClassContent);
}
return content;
}
protected String formatTagAttributeType(
String line, String tag, String attributeAndValue)
throws Exception {
return line;
}
protected String formatWhitespace(String line, String linePart) {
String originalLinePart = linePart;
linePart = formatIncorrectSyntax(linePart, "catch(", "catch (", true);
linePart = formatIncorrectSyntax(linePart, "else{", "else {", true);
linePart = formatIncorrectSyntax(linePart, "for(", "for (", true);
linePart = formatIncorrectSyntax(linePart, "if(", "if (", true);
linePart = formatIncorrectSyntax(linePart, "while(", "while (", true);
linePart = formatIncorrectSyntax(linePart, "List <", "List<", false);
linePart = formatIncorrectSyntax(linePart, "){", ") {", false);
linePart = formatIncorrectSyntax(linePart, "]{", "] {", false);
linePart = formatIncorrectSyntax(linePart, " [", "[", false);
for (int x = 0;;) {
x = linePart.indexOf(CharPool.EQUAL, x + 1);
if (x == -1) {
break;
}
if (ToolsUtil.isInsideQuotes(linePart, x)) {
continue;
}
char c = linePart.charAt(x - 1);
if (Character.isLetterOrDigit(c)) {
linePart = StringUtil.replaceFirst(linePart, "=", " =", x);
break;
}
if (x == (linePart.length() - 1)) {
break;
}
c = linePart.charAt(x + 1);
if (Character.isLetterOrDigit(c)) {
linePart = StringUtil.replaceFirst(linePart, "=", "= ", x);
break;
}
}
if (!line.contains(StringPool.DOUBLE_SLASH)) {
while (linePart.contains(StringPool.TAB)) {
linePart = StringUtil.replaceLast(
linePart, StringPool.TAB, StringPool.SPACE);
}
}
for (int x = 0;;) {
x = linePart.indexOf(StringPool.DOUBLE_SPACE, x + 1);
if (x == -1) {
break;
}
if (ToolsUtil.isInsideQuotes(linePart, x)) {
continue;
}
linePart = StringUtil.replaceFirst(
linePart, StringPool.DOUBLE_SPACE, StringPool.SPACE, x);
}
if (line.contains(StringPool.DOUBLE_SLASH)) {
line = StringUtil.replace(line, originalLinePart, linePart);
return formatIncorrectSyntax(
line, StringPool.SPACE + StringPool.TAB, StringPool.TAB, false);
}
int pos = linePart.indexOf(") ");
if ((pos != -1) && ((pos + 2) < linePart.length()) &&
!linePart.contains(StringPool.AT) &&
!ToolsUtil.isInsideQuotes(linePart, pos)) {
String linePart2 = linePart.substring(pos + 2);
if (Character.isLetter(linePart2.charAt(0)) &&
!linePart2.startsWith("default") &&
!linePart2.startsWith("instanceof") &&
!linePart2.startsWith("throws")) {
linePart = StringUtil.replaceFirst(
linePart, StringPool.SPACE, StringPool.BLANK, pos);
}
}
pos = linePart.indexOf(" (");
if ((pos != -1) && !linePart.contains(StringPool.EQUAL) &&
!ToolsUtil.isInsideQuotes(linePart, pos) &&
(linePart.startsWith("private ") ||
linePart.startsWith("protected ") ||
linePart.startsWith("public "))) {
linePart = StringUtil.replaceFirst(linePart, " (", "(", pos);
}
for (int x = -1;;) {
int posComma = linePart.indexOf(CharPool.COMMA, x + 1);
int posSemicolon = linePart.indexOf(CharPool.SEMICOLON, x + 1);
if ((posComma == -1) && (posSemicolon == -1)) {
break;
}
x = Math.min(posComma, posSemicolon);
if (x == -1) {
x = Math.max(posComma, posSemicolon);
}
if (ToolsUtil.isInsideQuotes(linePart, x)) {
continue;
}
if (linePart.length() > (x + 1)) {
char nextChar = linePart.charAt(x + 1);
if ((nextChar != CharPool.APOSTROPHE) &&
(nextChar != CharPool.CLOSE_PARENTHESIS) &&
(nextChar != CharPool.SPACE) &&
(nextChar != CharPool.STAR)) {
linePart = StringUtil.insert(
linePart, StringPool.SPACE, x + 1);
}
}
if (x > 0) {
char previousChar = linePart.charAt(x - 1);
if (previousChar == CharPool.SPACE) {
linePart = linePart.substring(0, x - 1).concat(
linePart.substring(x));
}
}
}
line = StringUtil.replace(line, originalLinePart, linePart);
return formatIncorrectSyntax(
line, StringPool.SPACE + StringPool.TAB, StringPool.TAB, false);
}
protected String formatWhitespace(
String line, String trimmedLine, boolean javaSource) {
if (javaSource) {
return formatWhitespace(line, trimmedLine);
}
Matcher matcher = javaSourceInsideJSPTagPattern.matcher(line);
while (matcher.find()) {
String linePart = matcher.group(1);
if (!linePart.startsWith(StringPool.SPACE)) {
return StringUtil.replace(
line, matcher.group(), "<%= " + linePart + "%>");
}
if (!linePart.endsWith(StringPool.SPACE)) {
return StringUtil.replace(
line, matcher.group(), "<%=" + linePart + " %>");
}
line = formatWhitespace(line, linePart);
}
return line;
}
protected String getAbsolutePath(File file) throws Exception {
String absolutePath = file.getCanonicalPath();
absolutePath = StringUtil.replace(
absolutePath, CharPool.BACK_SLASH, CharPool.SLASH);
return StringUtil.replace(absolutePath, "/./", StringPool.SLASH);
}
protected Set getAnnotationsExclusions() {
if (_annotationsExclusions != null) {
return _annotationsExclusions;
}
_annotationsExclusions = SetUtil.fromArray(
new String[] {
"ArquillianResource", "BeanReference", "Inject", "Mock",
"SuppressWarnings"
});
return _annotationsExclusions;
}
protected Properties getBNDFileLanguageProperties(String fileName)
throws Exception {
Properties properties = _bndFileLanguageProperties.get(fileName);
if (properties != null) {
return properties;
}
String bndContent = null;
String bndFileLocation = fileName;
while (true) {
int pos = bndFileLocation.lastIndexOf(StringPool.SLASH);
if (pos == -1) {
return null;
}
bndFileLocation = bndFileLocation.substring(0, pos + 1);
File file = new File(bndFileLocation + "bnd.bnd");
if (file.exists()) {
bndContent = FileUtil.read(file);
break;
}
bndFileLocation = StringUtil.replaceLast(
bndFileLocation, StringPool.SLASH, StringPool.BLANK);
}
Matcher matcher = bndContentDirPattern.matcher(bndContent);
if (matcher.find()) {
File file = new File(
bndFileLocation + matcher.group(1) + "/Language.properties");
if (!file.exists()) {
return null;
}
properties = new Properties();
InputStream inputStream = new FileInputStream(file);
properties.load(inputStream);
_bndFileLanguageProperties.put(fileName, properties);
return properties;
}
return null;
}
protected Map getCompatClassNamesMap() throws Exception {
if (_compatClassNamesMap != null) {
return _compatClassNamesMap;
}
Map compatClassNamesMap = new HashMap<>();
String[] includes = new String[] {
"**/portal-compat-shared/src/com/liferay/compat/**/*.java"
};
String basedir = sourceFormatterArgs.getBaseDirName();
List fileNames = new ArrayList<>();
for (int i = 0; i < 3; i++) {
fileNames = getFileNames(basedir, new String[0], includes);
if (!fileNames.isEmpty()) {
break;
}
basedir = "../" + basedir;
}
for (String fileName : fileNames) {
if (!fileName.startsWith(
sourceFormatterArgs.getBaseDirName() + "shared")) {
break;
}
File file = new File(basedir + fileName);
String content = FileUtil.read(file);
fileName = StringUtil.replace(
fileName, StringPool.BACK_SLASH, StringPool.SLASH);
fileName = StringUtil.replace(
fileName, StringPool.SLASH, StringPool.PERIOD);
int pos = fileName.indexOf("com.");
String compatClassName = fileName.substring(pos);
compatClassName = compatClassName.substring(
0, compatClassName.length() - 5);
String extendedClassName = StringUtil.replace(
compatClassName, "compat.", StringPool.BLANK);
if (content.contains("extends " + extendedClassName)) {
compatClassNamesMap.put(compatClassName, extendedClassName);
}
}
_compatClassNamesMap = compatClassNamesMap;
return _compatClassNamesMap;
}
protected String getContent(String fileName, int level) throws IOException {
File file = getFile(fileName, level);
if (file != null) {
String content = FileUtil.read(file);
if (Validator.isNotNull(content)) {
return content;
}
}
return StringPool.BLANK;
}
protected String getCustomCopyright(String absolutePath)
throws IOException {
for (int x = absolutePath.length();;) {
x = absolutePath.lastIndexOf(CharPool.SLASH, x);
if (x == -1) {
break;
}
String copyright = FileUtil.read(
new File(absolutePath.substring(0, x + 1) + "copyright.txt"));
if (Validator.isNotNull(copyright)) {
return copyright;
}
x = x - 1;
}
return null;
}
protected File getFile(String fileName, int level) {
for (int i = 0; i < level; i++) {
File file = new File(fileName);
if (file.exists()) {
return file;
}
fileName = "../" + fileName;
}
return null;
}
protected List getFileNames(
String basedir, List recentChangesFileNames,
String[] excludes, String[] includes)
throws Exception {
if (_excludes != null) {
excludes = ArrayUtil.append(excludes, _excludes);
}
return _sourceFormatterHelper.getFileNames(
basedir, recentChangesFileNames, excludes, includes);
}
protected List getFileNames(
String basedir, String[] excludes, String[] includes)
throws Exception {
return getFileNames(
basedir, sourceFormatterArgs.getRecentChangesFileNames(), excludes,
includes);
}
protected List getFileNames(String[] excludes, String[] includes)
throws Exception {
return getFileNames(
sourceFormatterArgs.getBaseDirName(), excludes, includes);
}
protected Set getImmutableFieldTypes() {
if (_immutableFieldTypes != null) {
return _immutableFieldTypes;
}
Set immutableFieldTypes = SetUtil.fromArray(
new String[] {
"boolean", "byte", "char", "double", "float", "int", "long",
"short", "Boolean", "Byte", "Character", "Class", "Double",
"Float", "Int", "Long", "Number", "Short", "String"
});
immutableFieldTypes.addAll(getPropertyList("immutable.field.types"));
_immutableFieldTypes = immutableFieldTypes;
return _immutableFieldTypes;
}
protected String[] getLanguageKeys(Matcher matcher) {
int groupCount = matcher.groupCount();
if (groupCount == 1) {
String languageKey = matcher.group(1);
if (Validator.isNotNull(languageKey)) {
return new String[] {languageKey};
}
}
else if (groupCount == 2) {
String languageKey = matcher.group(2);
languageKey = TextFormatter.format(languageKey, TextFormatter.P);
return new String[] {languageKey};
}
StringBundler sb = new StringBundler();
String match = matcher.group();
int count = 0;
for (int i = 0; i < match.length(); i++) {
char c = match.charAt(i);
switch (c) {
case CharPool.CLOSE_PARENTHESIS:
if (count <= 1) {
return new String[0];
}
count--;
break;
case CharPool.OPEN_PARENTHESIS:
count++;
break;
case CharPool.QUOTE:
if (count > 1) {
break;
}
while (i < match.length()) {
i++;
if (match.charAt(i) == CharPool.QUOTE) {
String languageKey = sb.toString();
if (match.startsWith("names")) {
return StringUtil.split(languageKey);
}
else {
return new String[] {languageKey};
}
}
sb.append(match.charAt(i));
}
}
}
return new String[0];
}
protected String getMainReleaseVersion() {
if (_mainReleaseVersion != null) {
return _mainReleaseVersion;
}
String releaseVersion = ReleaseInfo.getVersion();
int pos = releaseVersion.lastIndexOf(CharPool.PERIOD);
_mainReleaseVersion = releaseVersion.substring(0, pos) + ".0";
return _mainReleaseVersion;
}
protected Properties getModuleLanguageProperties(String fileName) {
Properties properties = _moduleLanguageProperties.get(fileName);
if (properties != null) {
return properties;
}
StringBundler sb = new StringBundler(3);
int pos = fileName.indexOf("/docroot/");
if (pos != -1) {
sb.append(fileName.substring(0, pos + 9));
sb.append("WEB-INF/src/");
}
else {
pos = fileName.indexOf("src/");
if (pos == -1) {
return null;
}
sb.append(fileName.substring(0, pos + 4));
if (fileName.contains("src/main/")) {
sb.append("main/resources/");
}
}
sb.append("content/Language.properties");
try {
properties = new Properties();
InputStream inputStream = new FileInputStream(sb.toString());
properties.load(inputStream);
_moduleLanguageProperties.put(fileName, properties);
return properties;
}
catch (Exception e) {
}
return null;
}
protected String getProperty(String key) {
return _properties.getProperty(key);
}
protected List getPropertyList(String key) {
return ListUtil.fromString(
GetterUtil.getString(getProperty(key)), StringPool.COMMA);
}
protected List getRunOutsidePortalExclusionPaths() {
if (_runOutsidePortalExclusionPaths != null) {
return _runOutsidePortalExclusionPaths;
}
List runOutsidePortalExclusionPaths = getPropertyList(
"run.outside.portal.excludes.paths");
_runOutsidePortalExclusionPaths = runOutsidePortalExclusionPaths;
return _runOutsidePortalExclusionPaths;
}
protected boolean hasMissingParentheses(String s) {
if (Validator.isNull(s)) {
return false;
}
boolean containsAndOperator = s.contains("&&");
boolean containsOrOperator = s.contains("||");
if (containsAndOperator && containsOrOperator) {
return true;
}
boolean containsCompareOperator =
(s.contains(" == ") || s.contains(" != ") || s.contains(" < ") ||
s.contains(" > ") || s.contains(" =< ") || s.contains(" => ") ||
s.contains(" <= ") || s.contains(" >= "));
boolean containsMathOperator =
(s.contains(" = ") || s.contains(" - ") || s.contains(" + ") ||
s.contains(" & ") || s.contains(" % ") || s.contains(" * ") ||
s.contains(" / "));
if (containsCompareOperator &&
(containsAndOperator || containsOrOperator ||
(containsMathOperator && !s.contains(StringPool.OPEN_BRACKET)))) {
return true;
}
return false;
}
protected boolean hasRedundantParentheses(String s) {
if (!s.contains("&&") && !s.contains("||")) {
for (int x = 0;;) {
x = s.indexOf(CharPool.CLOSE_PARENTHESIS);
if (x == -1) {
break;
}
int y = s.substring(0, x).lastIndexOf(
CharPool.OPEN_PARENTHESIS);
if (y == -1) {
break;
}
s = s.substring(0, y) + s.substring(x + 1);
}
}
if (Validator.isNotNull(s) && !s.contains(StringPool.SPACE)) {
return true;
}
else {
return false;
}
}
protected boolean hasRedundantParentheses(
String s, String operator1, String operator2) {
String[] parts = StringUtil.split(s, operator1);
if (parts.length < 3) {
return false;
}
for (int i = 1; i < (parts.length - 1); i++) {
String part = parts[i];
if (part.contains(operator2) || part.contains("!(")) {
continue;
}
int closeParenthesesCount = StringUtil.count(
part, StringPool.CLOSE_PARENTHESIS);
int openParenthesesCount = StringUtil.count(
part, StringPool.OPEN_PARENTHESIS);
if (Math.abs(closeParenthesesCount - openParenthesesCount) == 1) {
return true;
}
}
return false;
}
protected boolean isAttributName(String attributeName) {
if (Validator.isNull(attributeName)) {
return false;
}
Matcher matcher = attributeNamePattern.matcher(attributeName);
return matcher.matches();
}
protected boolean isModulesFile(String absolutePath) {
return absolutePath.contains("/modules/");
}
protected void postFormat() throws Exception {
}
protected void processErrorMessage(String fileName, String message) {
List errorMessages = _errorMessagesMap.get(fileName);
if (errorMessages == null) {
errorMessages = new ArrayList<>();
}
errorMessages.add(message);
_errorMessagesMap.put(fileName, errorMessages);
}
protected void processFormattedFile(
File file, String fileName, String content, String newContent)
throws IOException {
if (sourceFormatterArgs.isPrintErrors()) {
List errorMessages = _errorMessagesMap.get(fileName);
if (errorMessages != null) {
for (String errorMessage : errorMessages) {
_sourceFormatterHelper.printError(fileName, errorMessage);
}
}
}
_modifiedFileNames.add(file.getAbsolutePath());
if (content.equals(newContent)) {
return;
}
if (sourceFormatterArgs.isAutoFix()) {
FileUtil.write(file, newContent);
}
else if (_firstSourceMismatchException == null) {
_firstSourceMismatchException = new SourceMismatchException(
fileName, content, newContent);
}
if (sourceFormatterArgs.isPrintErrors()) {
_sourceFormatterHelper.printError(fileName, file);
}
}
protected String replacePrimitiveWrapperInstantiation(String line) {
return StringUtil.replace(
line,
new String[] {
"new Boolean(", "new Byte(", "new Character(", "new Double(",
"new Float(", "new Integer(", "new Long(", "new Short("
},
new String[] {
"Boolean.valueOf(", "Byte.valueOf(", "Character.valueOf(",
"Double.valueOf(", "Float.valueOf(", "Integer.valueOf(",
"Long.valueOf(", "Short.valueOf("
});
}
protected String sortAttributes(
String fileName, String line, int lineCount,
boolean allowApostropheDelimeter)
throws Exception {
String s = line;
int x = s.indexOf(CharPool.LESS_THAN);
int y = s.indexOf(CharPool.SPACE);
if ((x == -1) || (x >= y)) {
return line;
}
String tag = s.substring(x + 1, y);
s = s.substring(y + 1);
String previousAttribute = null;
String previousAttributeAndValue = null;
boolean wrongOrder = false;
for (x = 0;;) {
x = s.indexOf(CharPool.EQUAL);
if ((x == -1) || (s.length() <= (x + 1))) {
return line;
}
String attribute = s.substring(0, x);
if (!isAttributName(attribute)) {
return line;
}
if (Validator.isNotNull(previousAttribute) &&
(previousAttribute.compareToIgnoreCase(attribute) > 0)) {
wrongOrder = true;
}
s = s.substring(x + 1);
char delimeter = s.charAt(0);
if ((delimeter != CharPool.APOSTROPHE) &&
(delimeter != CharPool.QUOTE)) {
if (delimeter != CharPool.AMPERSAND) {
processErrorMessage(
fileName, "delimeter: " + fileName + " " + lineCount);
}
return line;
}
s = s.substring(1);
String value = null;
y = -1;
while (true) {
y = s.indexOf(delimeter, y + 1);
if ((y == -1) || (s.length() <= (y + 1))) {
return line;
}
value = s.substring(0, y);
if (value.startsWith("<%")) {
int endJavaCodeSignCount = StringUtil.count(value, "%>");
int startJavaCodeSignCount = StringUtil.count(value, "<%");
if (endJavaCodeSignCount == startJavaCodeSignCount) {
break;
}
}
else {
int greaterThanCount = StringUtil.count(
value, StringPool.GREATER_THAN);
int lessThanCount = StringUtil.count(
value, StringPool.LESS_THAN);
if (greaterThanCount == lessThanCount) {
break;
}
}
}
if (delimeter == CharPool.APOSTROPHE) {
if (!value.contains(StringPool.QUOTE)) {
line = StringUtil.replace(
line,
StringPool.APOSTROPHE + value + StringPool.APOSTROPHE,
StringPool.QUOTE + value + StringPool.QUOTE);
return sortAttributes(
fileName, line, lineCount, allowApostropheDelimeter);
}
else if (!allowApostropheDelimeter) {
String newValue = StringUtil.replace(
value, StringPool.QUOTE, """);
line = StringUtil.replace(
line,
StringPool.APOSTROPHE + value + StringPool.APOSTROPHE,
StringPool.QUOTE + newValue + StringPool.QUOTE);
return sortAttributes(
fileName, line, lineCount, allowApostropheDelimeter);
}
}
StringBundler sb = new StringBundler(5);
sb.append(attribute);
sb.append(StringPool.EQUAL);
sb.append(delimeter);
sb.append(value);
sb.append(delimeter);
String currentAttributeAndValue = sb.toString();
String newLine = sortHTMLAttributes(
line, value, currentAttributeAndValue);
if (!newLine.equals(line)) {
return sortAttributes(
fileName, newLine, lineCount, allowApostropheDelimeter);
}
newLine = formatTagAttributeType(
line, tag, currentAttributeAndValue);
if (!newLine.equals(line)) {
return sortAttributes(
fileName, newLine, lineCount, allowApostropheDelimeter);
}
if (wrongOrder) {
if ((StringUtil.count(line, currentAttributeAndValue) == 1) &&
(StringUtil.count(line, previousAttributeAndValue) == 1)) {
line = StringUtil.replaceFirst(
line, previousAttributeAndValue,
currentAttributeAndValue);
line = StringUtil.replaceLast(
line, currentAttributeAndValue,
previousAttributeAndValue);
return sortAttributes(
fileName, line, lineCount, allowApostropheDelimeter);
}
return line;
}
s = s.substring(y + 1);
if (s.startsWith(StringPool.GREATER_THAN)) {
x = s.indexOf(CharPool.SPACE);
if (x == -1) {
return line;
}
s = s.substring(x + 1);
previousAttribute = null;
previousAttributeAndValue = null;
}
else {
s = StringUtil.trimLeading(s);
previousAttribute = attribute;
previousAttributeAndValue = currentAttributeAndValue;
}
}
}
protected String sortHTMLAttributes(
String line, String value, String attributeAndValue) {
return line;
}
protected String stripRedundantParentheses(String s) {
for (int x = 0;;) {
x = s.indexOf(CharPool.OPEN_PARENTHESIS, x + 1);
int y = s.indexOf(CharPool.CLOSE_PARENTHESIS, x);
if ((x == -1) || (y == -1)) {
return s;
}
String linePart = s.substring(x + 1, y);
linePart = StringUtil.replace(
linePart, StringPool.COMMA, StringPool.BLANK);
if (Validator.isAlphanumericName(linePart) ||
Validator.isNull(linePart)) {
s = s.substring(0, x) + s.substring(y + 1);
}
}
}
protected String trimContent(String content, boolean allowLeadingSpaces)
throws IOException {
StringBundler sb = new StringBundler();
try (UnsyncBufferedReader unsyncBufferedReader =
new UnsyncBufferedReader(new UnsyncStringReader(content))) {
String line = null;
while ((line = unsyncBufferedReader.readLine()) != null) {
sb.append(trimLine(line, allowLeadingSpaces));
sb.append("\n");
}
}
content = sb.toString();
if (content.endsWith("\n")) {
content = content.substring(0, content.length() - 1);
}
return content;
}
protected String trimLine(String line, boolean allowLeadingSpaces) {
if (line.trim().length() == 0) {
return StringPool.BLANK;
}
line = StringUtil.trimTrailing(line);
if (allowLeadingSpaces || !line.startsWith(StringPool.SPACE) ||
line.startsWith(" *")) {
return line;
}
if (!line.startsWith(StringPool.FOUR_SPACES)) {
while (line.startsWith(StringPool.SPACE)) {
line = StringUtil.replaceFirst(
line, StringPool.SPACE, StringPool.BLANK);
}
}
else {
int pos = 0;
String temp = line;
while (temp.startsWith(StringPool.FOUR_SPACES)) {
line = StringUtil.replaceFirst(
line, StringPool.FOUR_SPACES, StringPool.TAB);
pos++;
temp = line.substring(pos);
}
}
return line;
}
protected static Pattern attributeNamePattern = Pattern.compile(
"[a-z]+[-_a-zA-Z0-9]*");
protected static Pattern bndContentDirPattern = Pattern.compile(
"\tcontent=(.*?)(,\\\\|\n)");
protected static Pattern emptyCollectionPattern = Pattern.compile(
"Collections\\.EMPTY_(LIST|MAP|SET)");
protected static Pattern javaSourceInsideJSPTagPattern = Pattern.compile(
"<%=(.+?)%>");
protected static Pattern languageKeyPattern = Pattern.compile(
"LanguageUtil.(?:get|format)\\([^;%]+|Liferay.Language.get\\('([^']+)");
protected static boolean portalSource;
protected static Pattern principalExceptionPattern = Pattern.compile(
"SessionErrors\\.contains\\(\n?\t*(renderR|r)equest, " +
"PrincipalException\\.class\\.getName\\(\\)");
protected static Pattern sessionKeyPattern = Pattern.compile(
"SessionErrors.(?:add|contains|get)\\([^;%&|!]+|".concat(
"SessionMessages.(?:add|contains|get)\\([^;%&|!]+"),
Pattern.MULTILINE);
protected static Pattern taglibSessionKeyPattern = Pattern.compile(
"]+>|]+>",
Pattern.MULTILINE);
protected SourceFormatterArgs sourceFormatterArgs;
private String[] _getExcludes() {
if (sourceFormatterArgs.getFileNames() != null) {
return new String[0];
}
List excludesList = ListUtil.fromString(
GetterUtil.getString(
System.getProperty("source.formatter.excludes")));
excludesList.addAll(getPropertyList("source.formatter.excludes"));
return excludesList.toArray(new String[excludesList.size()]);
}
private Properties _getProperties() throws Exception {
String fileName = "source-formatter.properties";
Properties properties = new Properties();
List propertiesList = new ArrayList<>();
int level = 2;
if (portalSource) {
level = PORTAL_MAX_DIR_LEVEL;
}
for (int i = 0; i <= level; i++) {
try {
InputStream inputStream = new FileInputStream(fileName);
Properties props = new Properties();
props.load(inputStream);
propertiesList.add(props);
}
catch (FileNotFoundException fnfe) {
}
fileName = "../" + fileName;
}
if (propertiesList.isEmpty()) {
return properties;
}
properties = propertiesList.get(0);
if (propertiesList.size() == 1) {
return properties;
}
for (int i = 1; i < propertiesList.size(); i++) {
Properties props = propertiesList.get(i);
Enumeration enu =
(Enumeration)props.propertyNames();
while (enu.hasMoreElements()) {
String key = enu.nextElement();
String value = props.getProperty(key);
if (Validator.isNull(value)) {
continue;
}
if (key.contains("excludes")) {
String existingValue = properties.getProperty(key);
if (Validator.isNotNull(existingValue)) {
value = existingValue + StringPool.COMMA + value;
}
properties.put(key, value);
}
else if (!properties.containsKey(key)) {
properties.put(key, value);
}
}
}
return properties;
}
private void _init() {
_errorMessagesMap = new HashMap<>();
_sourceFormatterHelper = new SourceFormatterHelper(
sourceFormatterArgs.isUseProperties());
try {
_sourceFormatterHelper.init();
}
catch (IOException ioe) {
ReflectionUtil.throwException(ioe);
}
_excludes = _getExcludes();
_usePortalCompatImport = GetterUtil.getBoolean(
getProperty("use.portal.compat.import"));
}
private boolean _isMatchPath(String fileName) {
for (String pattern : getIncludes()) {
if (SelectorUtils.matchPath(_normalizePattern(pattern), fileName)) {
return true;
}
}
return false;
}
private boolean _isPortalSource() {
if (getFile("portal-impl", PORTAL_MAX_DIR_LEVEL) != null) {
return true;
}
else {
return false;
}
}
private String _normalizePattern(String originalPattern) {
String pattern = originalPattern.replace(
CharPool.SLASH, File.separatorChar);
pattern = pattern.replace(CharPool.BACK_SLASH, File.separatorChar);
if (pattern.endsWith(File.separator)) {
pattern += SelectorUtils.DEEP_TREE_MATCH;
}
return pattern;
}
private Set _annotationsExclusions;
private Map _bndFileLanguageProperties =
new HashMap<>();
private Map _compatClassNamesMap;
private String _copyright;
private Map> _errorMessagesMap = new HashMap<>();
private String[] _excludes;
private SourceMismatchException _firstSourceMismatchException;
private Set _immutableFieldTypes;
private String _mainReleaseVersion;
private final List _modifiedFileNames = new ArrayList<>();
private Map _moduleLanguageProperties = new HashMap<>();
private String _oldCopyright;
private Properties _portalLanguageProperties;
private Properties _properties;
private List _runOutsidePortalExclusionPaths;
private SourceFormatterHelper _sourceFormatterHelper;
private boolean _usePortalCompatImport;
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy