/**
* 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.checks;
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.StringBundler;
import com.liferay.portal.kernel.util.StringPool;
import com.liferay.portal.kernel.util.StringUtil;
import com.liferay.portal.kernel.util.Validator;
import com.liferay.portal.tools.ToolsUtil;
import com.liferay.source.formatter.SourceFormatterMessage;
import com.liferay.source.formatter.checks.util.SourceUtil;
import com.liferay.source.formatter.util.FileUtil;
import com.liferay.source.formatter.util.SourceFormatterUtil;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.TreeSet;
import java.util.concurrent.ConcurrentHashMap;
/**
* @author Hugo Huijser
*/
public abstract class BaseSourceCheck implements SourceCheck {
@Override
public Set<SourceFormatterMessage> getSourceFormatterMessages(
String fileName) {
if (_sourceFormatterMessagesMap.containsKey(fileName)) {
return _sourceFormatterMessagesMap.get(fileName);
}
return Collections.emptySet();
}
@Override
public void init() throws Exception {
}
@Override
public boolean isModulesCheck() {
return false;
}
@Override
public boolean isPortalCheck() {
return false;
}
@Override
public void setAllFileNames(List<String> allFileNames) {
}
@Override
public void setBaseDirName(String baseDirName) {
_baseDirName = baseDirName;
}
@Override
public void setExcludes(String[] excludes) {
_excludes = excludes;
}
@Override
public void setMaxLineLength(int maxLineLength) {
_maxLineLength = maxLineLength;
}
@Override
public void setPluginsInsideModulesDirectoryNames(
List<String> pluginsInsideModulesDirectoryNames) {
_pluginsInsideModulesDirectoryNames =
pluginsInsideModulesDirectoryNames;
}
@Override
public void setPortalSource(boolean portalSource) {
_portalSource = portalSource;
}
@Override
public void setProperties(Properties properties) {
_properties = properties;
}
@Override
public void setSubrepository(boolean subrepository) {
_subrepository = subrepository;
}
protected void addMessage(String fileName, String message) {
addMessage(fileName, message, -1);
}
protected void addMessage(String fileName, String message, int lineCount) {
addMessage(fileName, message, null, lineCount);
}
protected void addMessage(
String fileName, String message, String markdownFileName) {
addMessage(fileName, message, markdownFileName, -1);
}
protected void addMessage(
String fileName, String message, String markdownFileName,
int lineCount) {
Set<SourceFormatterMessage> sourceFormatterMessages =
_sourceFormatterMessagesMap.get(fileName);
if (sourceFormatterMessages == null) {
sourceFormatterMessages = new TreeSet<>();
}
sourceFormatterMessages.add(
new SourceFormatterMessage(
fileName, message, markdownFileName, lineCount));
_sourceFormatterMessagesMap.put(fileName, sourceFormatterMessages);
}
protected void clearSourceFormatterMessages(String fileName) {
_sourceFormatterMessagesMap.remove(fileName);
}
protected String getBaseDirName() {
return _baseDirName;
}
protected Map<String, String> getCompatClassNamesMap() throws Exception {
Map<String, String> compatClassNamesMap = new HashMap<>();
String[] includes = new String[] {
"**/portal-compat-shared/src/com/liferay/compat/**/*.java"
};
String baseDirName = _baseDirName;
List<String> fileNames = new ArrayList<>();
for (int i = 0; i < ToolsUtil.PLUGINS_MAX_DIR_LEVEL; i++) {
File sharedDir = new File(baseDirName + "shared");
if (sharedDir.exists()) {
fileNames = getFileNames(baseDirName, new String[0], includes);
break;
}
baseDirName = baseDirName + "../";
}
for (String fileName : fileNames) {
File file = new File(fileName);
String content = FileUtil.read(file);
fileName = StringUtil.replace(
fileName, CharPool.BACK_SLASH, CharPool.SLASH);
fileName = StringUtil.replace(
fileName, CharPool.SLASH, CharPool.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);
}
}
return compatClassNamesMap;
}
protected String getContent(String fileName, int level) throws Exception {
File file = getFile(fileName, level);
if (file != null) {
String content = FileUtil.read(file);
if (Validator.isNotNull(content)) {
return content;
}
}
return StringPool.BLANK;
}
protected String[] getExcludes() {
return _excludes;
}
protected File getFile(String fileName, int level) {
for (int i = 0; i < level; i++) {
File file = new File(_baseDirName + fileName);
if (file.exists()) {
return file;
}
fileName = "../" + fileName;
}
return null;
}
protected List<String> getFileNames(
String basedir, String[] excludes, String[] includes)
throws Exception {
if (_excludes != null) {
excludes = ArrayUtil.append(excludes, _excludes);
}
return SourceFormatterUtil.scanForFiles(
basedir, excludes, includes, true);
}
protected int getLeadingTabCount(String line) {
int leadingTabCount = 0;
while (line.startsWith(StringPool.TAB)) {
line = line.substring(1);
leadingTabCount++;
}
return leadingTabCount;
}
protected int getLevel(String s) {
return SourceUtil.getLevel(s);
}
protected int getLevel(
String s, String increaseLevelString, String decreaseLevelString) {
return SourceUtil.getLevel(s, increaseLevelString, decreaseLevelString);
}
protected int getLevel(
String s, String[] increaseLevelStrings,
String[] decreaseLevelStrings) {
return SourceUtil.getLevel(
s, increaseLevelStrings, decreaseLevelStrings);
}
protected int getLevel(
String s, String[] increaseLevelStrings, String[] decreaseLevelStrings,
int startLevel) {
return SourceUtil.getLevel(
s, increaseLevelStrings, decreaseLevelStrings, startLevel);
}
protected int getLineCount(String content, int pos) {
return StringUtil.count(content, 0, pos, CharPool.NEW_LINE) + 1;
}
protected int getMaxLineLength() {
return _maxLineLength;
}
protected List<String> getPluginsInsideModulesDirectoryNames() {
return _pluginsInsideModulesDirectoryNames;
}
protected Properties getPortalLanguageProperties() throws Exception {
Properties portalLanguageProperties = new Properties();
File portalLanguagePropertiesFile = getFile(
"portal-impl/src/content/Language.properties",
ToolsUtil.PORTAL_MAX_DIR_LEVEL);
if (portalLanguagePropertiesFile != null) {
InputStream inputStream = new FileInputStream(
portalLanguagePropertiesFile);
portalLanguageProperties.load(inputStream);
}
return portalLanguageProperties;
}
protected String getProjectPathPrefix() throws Exception {
if (!_subrepository) {
return null;
}
File file = getFile(
"gradle.properties", ToolsUtil.PORTAL_MAX_DIR_LEVEL);
if (!file.exists()) {
return null;
}
Properties properties = new Properties();
properties.load(new FileInputStream(file));
return properties.getProperty("project.path.prefix");
}
protected String getProperty(String key) {
return GetterUtil.getString(_properties.getProperty(key));
}
protected List<String> getPropertyList(String key) {
return ListUtil.fromString(
GetterUtil.getString(_properties.getProperty(key)),
StringPool.COMMA);
}
protected boolean isExcludedPath(String key, String path) {
return isExcludedPath(key, path, -1);
}
protected boolean isExcludedPath(String key, String path, int lineCount) {
return isExcludedPath(key, path, lineCount, null);
}
protected boolean isExcludedPath(
String key, String path, int lineCount, String parameter) {
List<String> excludes = getPropertyList(key);
if (ListUtil.isEmpty(excludes)) {
return false;
}
String pathWithParameter = null;
if (Validator.isNotNull(parameter)) {
pathWithParameter = path + StringPool.AT + parameter;
}
String pathWithLineCount = null;
if (lineCount > 0) {
pathWithLineCount = path + StringPool.AT + lineCount;
}
for (String exclude : excludes) {
if (Validator.isNull(exclude)) {
continue;
}
if (exclude.startsWith("**")) {
exclude = exclude.substring(2);
}
if (exclude.endsWith("**")) {
exclude = exclude.substring(0, exclude.length() - 2);
if (path.contains(exclude)) {
return true;
}
continue;
}
if (path.endsWith(exclude) ||
((pathWithParameter != null) &&
pathWithParameter.endsWith(exclude)) ||
((pathWithLineCount != null) &&
pathWithLineCount.endsWith(exclude))) {
return true;
}
}
return false;
}
protected boolean isExcludedPath(
String key, String path, String parameter) {
return isExcludedPath(key, path, -1, parameter);
}
protected boolean isModulesApp(
String absolutePath, String projectPathPrefix, boolean privateOnly) {
if (absolutePath.contains("/modules/private/apps/") ||
(!privateOnly && absolutePath.contains("/modules/apps/"))) {
return true;
}
if (projectPathPrefix == null) {
return false;
}
if (projectPathPrefix.startsWith(":private:apps") ||
(!privateOnly && projectPathPrefix.startsWith(":apps:"))) {
return true;
}
return false;
}
protected boolean isModulesFile(String absolutePath) {
return isModulesFile(absolutePath, null);
}
protected boolean isModulesFile(
String absolutePath, List<String> pluginsInsideModulesDirectoryNames) {
if (_subrepository) {
return true;
}
if (pluginsInsideModulesDirectoryNames == null) {
return absolutePath.contains("/modules/");
}
try {
for (String directoryName : pluginsInsideModulesDirectoryNames) {
if (absolutePath.contains(directoryName)) {
return false;
}
}
}
catch (Exception e) {
}
return absolutePath.contains("/modules/");
}
protected boolean isPortalSource() {
return _portalSource;
}
protected boolean isSubrepository() {
return _subrepository;
}
protected String stripQuotes(String s) {
return stripQuotes(s, CharPool.APOSTROPHE, CharPool.QUOTE);
}
protected String stripQuotes(String s, char... delimeters) {
List<Character> delimetersList = ListUtil.toList(delimeters);
char delimeter = CharPool.SPACE;
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 (delimetersList.contains(c)) {
delimeter = c;
insideQuotes = true;
}
else {
sb.append(c);
}
}
return sb.toString();
}
private String _baseDirName;
private String[] _excludes;
private int _maxLineLength;
private List<String> _pluginsInsideModulesDirectoryNames;
private boolean _portalSource;
private Properties _properties;
private final Map<String, Set<SourceFormatterMessage>>
_sourceFormatterMessagesMap = new ConcurrentHashMap<>();
private boolean _subrepository;
}