com.liferay.source.formatter.check.XMLPoshiFileCheck Maven / Gradle / Ivy
The newest version!
/**
* SPDX-FileCopyrightText: (c) 2000 Liferay, Inc. https://liferay.com
* SPDX-License-Identifier: LGPL-2.1-or-later OR LicenseRef-Liferay-DXP-EULA-2.0.0-2023-06
*/
package com.liferay.source.formatter.check;
import com.liferay.petra.string.StringBundler;
import com.liferay.petra.string.StringPool;
import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
import com.liferay.portal.kernel.util.StringUtil;
import com.liferay.source.formatter.check.comparator.ElementComparator;
import com.liferay.source.formatter.check.util.SourceUtil;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
/**
* @author Hugo Huijser
*/
public class XMLPoshiFileCheck extends BaseFileCheck {
@Override
protected String doProcess(
String fileName, String absolutePath, String content)
throws DocumentException {
if (fileName.endsWith(".action") || fileName.endsWith(".function") ||
fileName.endsWith(".macro") || fileName.endsWith(".testcase")) {
content = _formatPoshiXML(fileName, content);
}
return content;
}
private void _checkPoshiCharactersAfterDefinition(
String fileName, String content) {
if (content.contains("/definition>") &&
!content.endsWith("/definition>")) {
addMessage(fileName, "Characters found after definition element");
}
}
private void _checkPoshiCharactersBeforeDefinition(
String fileName, String content) {
if (!content.startsWith(" ");
}
return content;
}
private String _fixPoshiXMLEndLines(String content) {
Matcher matcher = _poshiEndLinesPattern.matcher(content);
while (matcher.find()) {
String statement = matcher.group();
String newStatement = StringUtil.replace(
statement, matcher.group(), ">\n\n" + matcher.group(1));
content = StringUtil.replace(content, statement, newStatement);
}
return content;
}
private String _fixPoshiXMLEndLinesAfterClosingElement(String content) {
Matcher matcher = _poshiEndLinesAfterClosingElementPattern.matcher(
content);
while (matcher.find()) {
String statement = matcher.group();
String closingElementName = matcher.group(1);
if (StringUtil.equalsIgnoreCase("", closingElementName) ||
StringUtil.equalsIgnoreCase("", closingElementName) ||
StringUtil.equalsIgnoreCase("", closingElementName) ||
StringUtil.equalsIgnoreCase("", closingElementName) ||
StringUtil.equalsIgnoreCase("", closingElementName)) {
String newStatement = StringUtil.replace(
statement, matcher.group(2), "\n");
content = StringUtil.replace(content, statement, newStatement);
}
else if (!StringUtil.equalsIgnoreCase(
"", closingElementName)) {
String newStatement = StringUtil.replace(
statement, matcher.group(2), "\n\n");
content = StringUtil.replace(content, statement, newStatement);
}
}
return content;
}
private String _fixPoshiXMLEndLinesBeforeClosingElement(String content) {
Matcher matcher = _poshiEndLinesBeforeClosingElementPattern.matcher(
content);
while (matcher.find()) {
String statement = matcher.group();
String newStatement = StringUtil.replace(
statement, matcher.group(1), "\n");
content = StringUtil.replace(content, statement, newStatement);
}
return content;
}
private String _formatPoshiXML(String fileName, String content) {
_checkPoshiCharactersAfterDefinition(fileName, content);
_checkPoshiCharactersBeforeDefinition(fileName, content);
try {
Document document = SourceUtil.readXML(content);
if (document == null) {
return content;
}
Element rootElement = document.getRootElement();
List commandElements = rootElement.elements("command");
for (Element commandElement : commandElements) {
checkElementOrder(
fileName, commandElement, "property", null,
new ElementComparator());
}
}
catch (Exception exception) {
if (_log.isDebugEnabled()) {
_log.debug(exception);
}
}
content = _sortPoshiCommands(content);
content = _sortPoshiVariables(content);
content = _fixPoshiXMLElementWithNoChild(content);
content = _fixPoshiXMLEndLinesAfterClosingElement(content);
content = _fixPoshiXMLEndLinesBeforeClosingElement(content);
return _fixPoshiXMLEndLines(content);
}
private String _sortPoshiCommands(String content) {
Matcher matcher = _poshiCommandsPattern.matcher(content);
Map commandBlocksMap = new TreeMap<>(
String.CASE_INSENSITIVE_ORDER);
String previousName = StringPool.BLANK;
boolean hasUnsortedCommands = false;
while (matcher.find()) {
String commandBlock = matcher.group();
String commandName = matcher.group(1);
commandBlocksMap.put(commandName, commandBlock);
if (!hasUnsortedCommands &&
(commandName.compareToIgnoreCase(previousName) < 0)) {
hasUnsortedCommands = true;
}
previousName = commandName;
}
if (!hasUnsortedCommands) {
return content;
}
StringBundler sb = new StringBundler();
matcher = _poshiSetUpPattern.matcher(content);
if (matcher.find()) {
String setUpBlock = matcher.group();
content = StringUtil.removeSubstring(content, setUpBlock);
sb.append(setUpBlock);
}
matcher = _poshiTearDownPattern.matcher(content);
if (matcher.find()) {
String tearDownBlock = matcher.group();
content = StringUtil.removeSubstring(content, tearDownBlock);
sb.append(tearDownBlock);
}
for (Map.Entry entry : commandBlocksMap.entrySet()) {
sb.append("\n\t");
sb.append(entry.getValue());
sb.append("\n");
}
int x = content.indexOf("");
String commandBlock = content.substring(x, y);
commandBlock = "\n\t" + commandBlock + " \n";
String newCommandBlock = sb.toString();
return StringUtil.replaceFirst(content, commandBlock, newCommandBlock);
}
private String _sortPoshiVariables(String content) {
Matcher matcher = _poshiVariablesBlockPattern.matcher(content);
while (matcher.find()) {
String previousName = StringPool.BLANK;
String tabs = StringPool.BLANK;
Map variableLinesMap = new TreeMap<>(
String.CASE_INSENSITIVE_ORDER);
String variableBlock = matcher.group(1);
variableBlock = variableBlock.trim();
Matcher variableLineMatcher = _poshiVariableLinePattern.matcher(
variableBlock);
boolean hasUnsortedVariables = false;
while (variableLineMatcher.find()) {
if (tabs.equals(StringPool.BLANK)) {
tabs = variableLineMatcher.group(1);
}
String variableLine = variableLineMatcher.group(2);
String variableName = variableLineMatcher.group(3);
variableLinesMap.put(variableName, variableLine);
if (!hasUnsortedVariables &&
(variableName.compareToIgnoreCase(previousName) < 0)) {
hasUnsortedVariables = true;
}
previousName = variableName;
}
if (!hasUnsortedVariables) {
continue;
}
StringBundler sb = new StringBundler();
for (Map.Entry entry :
variableLinesMap.entrySet()) {
sb.append(tabs);
sb.append(entry.getValue());
sb.append("\n");
}
String newVariableBlock = sb.toString();
newVariableBlock = newVariableBlock.trim();
content = StringUtil.replaceFirst(
content, variableBlock, newVariableBlock);
}
return content;
}
private static final Log _log = LogFactoryUtil.getLog(
XMLPoshiFileCheck.class);
private static final Pattern _poshiCommandsPattern = Pattern.compile(
"\\[\\s\\S]*?\\" +
"[\\n|\\t]*?(?:[^(?:/\\>)]*?--\\>)*+");
private static final Pattern _poshiElementWithNoChildPattern =
Pattern.compile("\\\"[\\s]*\\>[\\n\\s\\t]*\\[a-z\\-]+>");
private static final Pattern _poshiEndLinesAfterClosingElementPattern =
Pattern.compile("(\\[a-z\\-]+>)(\\n+)\\t*\\<[a-z]+");
private static final Pattern _poshiEndLinesBeforeClosingElementPattern =
Pattern.compile("(\\n+)(\\t*[a-z\\-]+>)");
private static final Pattern _poshiEndLinesPattern = Pattern.compile(
"\\>\\n\\n\\n+(\\t*\\<)");
private static final Pattern _poshiSetUpPattern = Pattern.compile(
"\\n[\\t]++\\([\\s\\S]*?)\\ " +
"[\\n|\\t]*?(?:[^(?:/\\>)]*?--\\>)*+\\n");
private static final Pattern _poshiTearDownPattern = Pattern.compile(
"\\n[\\t]++\\([\\s\\S]*?)\\ " +
"[\\n|\\t]*?(?:[^(?:/\\>)]*?--\\>)*+\\n");
private static final Pattern _poshiVariableLinePattern = Pattern.compile(
"([\\t]*+)(\\" +
".*+(?:\\)??)");
private static final Pattern _poshiVariablesBlockPattern = Pattern.compile(
"((?:[\\t]*+\\\\n[\\t]*+){2,}?)" +
"(?:(?:\\n){1,}+|\\)");
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy