Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.liferay.source.formatter.XMLSourceProcessor 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.CharPool;
import com.liferay.portal.kernel.util.PropertiesUtil;
import com.liferay.portal.kernel.util.PropsKeys;
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.source.formatter.util.FileUtil;
import com.liferay.util.ContentUtil;
import com.liferay.util.xml.Dom4jUtil;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.concurrent.ConcurrentHashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.maven.artifact.versioning.ComparableVersion;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.Element;
/**
* @author Hugo Huijser
*/
public class XMLSourceProcessor extends BaseSourceProcessor {
public static String formatXML(String content) {
String newContent = StringUtil.replace(content, "\"/>\n", "\" />\n");
while (true) {
Matcher matcher = _commentPattern1.matcher(newContent);
if (matcher.find()) {
newContent = StringUtil.replaceFirst(
newContent, ">\n", ">\n\n", matcher.start());
continue;
}
matcher = _commentPattern2.matcher(newContent);
if (!matcher.find()) {
break;
}
newContent = StringUtil.replaceFirst(
newContent, "-->\n", "-->\n\n", matcher.start());
}
return newContent;
}
/**
* @deprecated As of 7.0.0, with no direct replacement
*/
@Deprecated
public static void sortAttributes(Element element, boolean recursive) {
Map attributesMap = new TreeMap<>();
List attributes = new ArrayList<>(element.attributes());
for (Attribute attribute : attributes) {
attribute.detach();
attributesMap.put(attribute.getName(), attribute);
}
for (Map.Entry entry : attributesMap.entrySet()) {
Attribute attribute = entry.getValue();
element.add(attribute);
}
if (!recursive) {
return;
}
List elements = element.elements();
for (Element curElement : elements) {
sortAttributes(curElement, recursive);
}
}
/**
* @deprecated As of 7.0.0, with no direct replacement
*/
@Deprecated
public static String sortAttributes(String content) throws Exception {
XMLSourceProcessor xmlSourceProcessor = new XMLSourceProcessor();
Document document = xmlSourceProcessor.readXML(content);
sortAttributes(document.getRootElement(), true);
return Dom4jUtil.toString(document);
}
public static void sortElementsByAttribute(
Element element, String elementName, String attributeName) {
Map elementsMap = new TreeMap<>();
List elements = element.elements();
for (Element curElement : elements) {
curElement.detach();
if (elementName.equals(curElement.getName())) {
String attributeValue = curElement.attributeValue(
attributeName);
elementsMap.put(attributeValue, curElement);
}
}
for (Element curElement : elements) {
if (elementName.equals(curElement.getName())) {
break;
}
element.add(curElement);
}
for (Map.Entry entry : elementsMap.entrySet()) {
Element curElement = entry.getValue();
element.add(curElement);
}
boolean foundLastElementWithElementName = false;
for (int i = 0; i < elements.size(); i++) {
Element curElement = elements.get(i);
if (!foundLastElementWithElementName) {
if (elementName.equals(curElement.getName()) &&
((i + 1) < elements.size())) {
Element nextElement = elements.get(i + 1);
if (!elementName.equals(nextElement.getName())) {
foundLastElementWithElementName = true;
}
}
}
else {
element.add(curElement);
}
}
}
public static void sortElementsByChildElement(
Element element, String elementName, String childElementName) {
Map elementsMap = new TreeMap<>();
List elements = element.elements();
for (Element curElement : elements) {
curElement.detach();
if (elementName.equals(curElement.getName())) {
String childElementValue = curElement.elementText(
childElementName);
elementsMap.put(childElementValue, curElement);
}
}
for (Element curElement : elements) {
if (elementName.equals(curElement.getName())) {
break;
}
element.add(curElement);
}
for (Map.Entry entry : elementsMap.entrySet()) {
Element curElement = entry.getValue();
element.add(curElement);
}
boolean foundLastElementWithElementName = false;
for (int i = 0; i < elements.size(); i++) {
Element curElement = elements.get(i);
if (!foundLastElementWithElementName) {
if (elementName.equals(curElement.getName()) &&
((i + 1) < elements.size())) {
Element nextElement = elements.get(i + 1);
if (!elementName.equals(nextElement.getName())) {
foundLastElementWithElementName = true;
}
}
}
else {
element.add(curElement);
}
}
}
@Override
public String[] getIncludes() {
return _INCLUDES;
}
protected void checkAntXMLProjectName(String fileName, Document document) {
Matcher matcher = _projectNamePattern.matcher(fileName);
if (!matcher.find()) {
return;
}
String expectedProjectName = matcher.group(1);
Element rootElement = document.getRootElement();
String projectName = rootElement.attributeValue("name");
if (!projectName.equals(expectedProjectName)) {
processMessage(fileName, "incorrect project name");
}
}
protected void checkImportFiles(String fileName, String content) {
Matcher matcher = _importFilePattern.matcher(content);
while (matcher.find()) {
String importFileName = fileName;
int pos = importFileName.lastIndexOf(StringPool.SLASH);
if (pos == -1) {
return;
}
importFileName = importFileName.substring(0, pos + 1);
importFileName = importFileName + matcher.group(1);
File file = new File(importFileName);
if (!file.exists()) {
processMessage(
fileName, "Incorrect import file: " + matcher.group(1));
}
}
}
protected void checkPoshiCharactersAfterDefinition(
String fileName, String content) {
if (content.contains("/definition>") &&
!content.endsWith("/definition>")) {
processMessage(
fileName, "Characters found after definition element");
}
}
protected void checkPoshiCharactersBeforeDefinition(
String fileName, String content) {
if (!content.startsWith(" targetNames = getTargetNames(
buildFileName, fileName, null, false);
if ((targetNames == null) || targetNames.contains(targetName)) {
return;
}
int x = targetName.lastIndexOf(CharPool.PERIOD);
if (x != -1) {
targetName = targetName.substring(x + 1);
}
if (!targetNames.contains(targetName)) {
processMessage(
fileName, "Target '" + targetName + "' does not exist");
}
}
protected void checkTargetNames(
String fileName, String absolutePath, String content)
throws Exception {
Document document = readXML(content);
Element rootElement = document.getRootElement();
List antCallElements = getElementsByName(
"antcall", rootElement, null);
for (Element antCallElement : antCallElements) {
String targetName = antCallElement.attributeValue("target");
if ((targetName == null) ||
targetName.contains(StringPool.OPEN_CURLY_BRACE)) {
continue;
}
checkTargetName(targetName, absolutePath, fileName);
}
String fileDirName = fileName.substring(
0, fileName.lastIndexOf(CharPool.SLASH) + 1);
List antElements = getElementsByName("ant", rootElement, null);
for (Element antElement : antElements) {
String targetName = antElement.attributeValue("target");
if ((targetName == null) ||
targetName.contains(StringPool.OPEN_CURLY_BRACE)) {
continue;
}
String fullDirName = fileDirName;
String dirName = antElement.attributeValue("dir");
if (dirName != null) {
if (dirName.contains(StringPool.OPEN_CURLY_BRACE)) {
continue;
}
fullDirName = fullDirName + dirName + StringPool.SLASH;
}
String antFileName = antElement.attributeValue("antfile");
if (antFileName == null) {
antFileName = "build.xml";
}
checkTargetName(targetName, fullDirName + antFileName, fileName);
}
}
@Override
protected String doFormat(
File file, String fileName, String absolutePath, String content)
throws Exception {
if (isExcludedPath(_xmlExcludes, absolutePath)) {
return content;
}
String newContent = content;
if (!fileName.startsWith(
sourceFormatterArgs.getBaseDirName() + "build") &&
!fileName.contains("/build")) {
newContent = trimContent(newContent, false);
}
if (fileName.startsWith(
sourceFormatterArgs.getBaseDirName() + "build") ||
(fileName.contains("/build") && !fileName.contains("/tools/"))) {
newContent = formatAntXML(fileName, absolutePath, newContent);
}
else if (fileName.contains("/custom-sql/")) {
formatCustomSQLXML(fileName, newContent);
}
else if (fileName.endsWith("structures.xml")) {
newContent = formatDDLStructuresXML(newContent);
}
else if (fileName.endsWith("routes.xml")) {
newContent = formatFriendlyURLRoutesXML(fileName, newContent);
}
else if (fileName.endsWith("-hbm.xml")) {
formatHBMXML(fileName, newContent);
}
else if (fileName.endsWith("-log4j.xml")) {
formatLog4jXML(fileName, newContent);
}
else if (fileName.endsWith("-model-hints.xml")) {
formatModelHintsXML(fileName, newContent);
}
else if (fileName.endsWith("portlet-preferences.xml")) {
formatPortletPreferencesXML(fileName, newContent);
}
else if (fileName.endsWith("/liferay-portlet.xml") ||
(portalSource && fileName.endsWith("/portlet-custom.xml")) ||
(!portalSource && fileName.endsWith("/portlet.xml"))) {
newContent = formatPortletXML(fileName, absolutePath, newContent);
}
else if (fileName.endsWith(".action") ||
fileName.endsWith(".function") ||
fileName.endsWith(".macro") ||
fileName.endsWith(".testcase")) {
newContent = formatPoshiXML(fileName, newContent);
}
else if (fileName.contains("/resource-actions/")) {
formatResourceActionXML(fileName, newContent);
}
else if (fileName.endsWith("/service.xml")) {
formatServiceXML(fileName, absolutePath, newContent);
}
else if (fileName.endsWith("/schema.xml") &&
absolutePath.contains("solr")) {
formatSolrSchema(fileName, newContent);
}
else if (portalSource && fileName.endsWith("/struts-config.xml")) {
formatStrutsConfigXML(fileName, newContent);
}
else if (portalSource &&
fileName.endsWith("/test-ignorable-error-lines.xml")) {
formatTestIgnorableErrorLinesXml(fileName, newContent);
}
else if (portalSource && fileName.endsWith("/tiles-defs.xml")) {
formatTilesDefsXML(fileName, newContent);
}
else if ((portalSource &&
fileName.endsWith("portal-web/docroot/WEB-INF/web.xml")) ||
(!portalSource && fileName.endsWith("/web.xml"))) {
newContent = formatWebXML(fileName, newContent);
}
newContent = sortAttributes(fileName, newContent);
newContent = fixEmptyLinesInNestedTags(newContent);
return formatXML(newContent);
}
@Override
protected List doGetFileNames() throws Exception {
String[] excludes = new String[] {
"**/.bnd/**", "**/.idea/**", "**/.ivy/**", "**/bin/**",
"**/javadocs-*.xml", "**/logs/**", "**/portal-impl/**/*.action",
"**/portal-impl/**/*.function", "**/portal-impl/**/*.macro",
"**/portal-impl/**/*.testcase", "**/src/test/**",
"**/test-classes/unit/**", "**/test-results/**", "**/test/unit/**",
"**/tools/node**"
};
return getFileNames(excludes, getIncludes());
}
protected String fixPoshiXMLElementWithNoChild(String content) {
Matcher matcher = _poshiElementWithNoChildPattern.matcher(content);
while (matcher.find()) {
content = StringUtil.replace(content, matcher.group(), "\" />");
}
return content;
}
protected 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;
}
protected 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;
}
protected 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;
}
protected String fixPoshiXMLNumberOfTabs(String content) {
Matcher matcher = _poshiTabsPattern.matcher(content);
int tabCount = 0;
boolean ignoredCdataBlock = false;
boolean ignoredCommentBlock = false;
while (matcher.find()) {
String statement = matcher.group();
Matcher quoteWithSlashMatcher = _poshiQuoteWithSlashPattern.matcher(
statement);
String fixedQuoteStatement = statement;
if (quoteWithSlashMatcher.find()) {
fixedQuoteStatement = StringUtil.replace(
statement, quoteWithSlashMatcher.group(), "\"\"");
}
Matcher closingTagMatcher = _poshiClosingTagPattern.matcher(
fixedQuoteStatement);
Matcher openingTagMatcher = _poshiOpeningTagPattern.matcher(
fixedQuoteStatement);
Matcher wholeTagMatcher = _poshiWholeTagPattern.matcher(
fixedQuoteStatement);
if (closingTagMatcher.find() && !openingTagMatcher.find() &&
!wholeTagMatcher.find() && !statement.contains("") &&
!statement.contains("")) {
tabCount--;
}
if (statement.contains("]]>")) {
ignoredCdataBlock = false;
}
else if (statement.contains("")) {
ignoredCommentBlock = false;
}
else if (statement.contains("") &&
!statement.contains("")) {
tabCount++;
}
}
return content;
}
protected String formatAntXML(
String fileName, String absolutePath, String content)
throws Exception {
String newContent = trimContent(content, true);
Document document = readXML(content);
checkAntXMLProjectName(fileName, document);
checkOrder(
fileName, document.getRootElement(), "macrodef", null,
new ElementComparator());
checkOrder(
fileName, document.getRootElement(), "target", null,
new ElementComparator());
int x = content.lastIndexOf("");
int y = content.indexOf(" y)) {
processMessage(fileName, "macrodefs go before process-ivy");
}
int z = content.indexOf("");
if ((z != -1) && (x > z)) {
processMessage(fileName, "macrodefs go before targets");
}
checkImportFiles(fileName, newContent);
checkTargetNames(fileName, absolutePath, content);
return newContent;
}
protected void formatCustomSQLXML(String fileName, String content)
throws Exception {
Document document = readXML(content);
checkOrder(
fileName, document.getRootElement(), "sql", null,
new CustomSQLElementComparator("id"));
Matcher matcher = _whereNotInSQLPattern.matcher(content);
if (!matcher.find()) {
return;
}
int x = content.lastIndexOf(" structureElements = rootElement.elements("structure");
for (Element structureElement : structureElements) {
Element structureRootElement = structureElement.element("root");
sortElementsByAttribute(
structureRootElement, "dynamic-element", "name");
List dynamicElementElements =
structureRootElement.elements("dynamic-element");
for (Element dynamicElementElement : dynamicElementElements) {
Element metaDataElement = dynamicElementElement.element(
"meta-data");
sortElementsByAttribute(metaDataElement, "entry", "name");
}
}
return Dom4jUtil.toString(document);
}
protected String formatFriendlyURLRoutesXML(String fileName, String content)
throws Exception {
Document document = readXML(content);
Element rootElement = document.getRootElement();
List routeElements = rootElement.elements("route");
ElementComparator elementComparator = new ElementComparator();
for (Element routeElement : routeElements) {
checkOrder(
fileName, routeElement, "ignored-parameter", null,
elementComparator);
checkOrder(
fileName, routeElement, "implicit-parameter", null,
elementComparator);
checkOrder(
fileName, routeElement, "overridden-parameter", null,
elementComparator);
}
int pos = content.indexOf("\n");
if (pos == -1) {
return content;
}
StringBundler sb = new StringBundler(9);
ComparableVersion mainReleaseComparableVersion =
getMainReleaseComparableVersion();
String mainReleaseVersion = mainReleaseComparableVersion.toString();
sb.append("\n");
sb.append("\n\n");
sb.append(content.substring(pos));
return sb.toString();
}
protected void formatHBMXML(String fileName, String content)
throws Exception {
Document document = readXML(content);
checkOrder(
fileName, document.getRootElement(), "import", null,
new ElementComparator("class"));
}
protected void formatLog4jXML(String fileName, String content)
throws Exception {
Document document = readXML(content);
checkOrder(
fileName, document.getRootElement(), "category", null,
new ElementComparator(true));
}
protected void formatModelHintsXML(String fileName, String content)
throws Exception {
Document document = readXML(content);
Element rootElement = document.getRootElement();
checkOrder(
fileName, rootElement, "hint-collection", null,
new ElementComparator());
checkOrder(
fileName, rootElement, "model", null, new ElementComparator());
}
protected void formatPortletPreferencesXML(String fileName, String content)
throws Exception {
Document document = readXML(content);
checkOrder(
fileName, document.getRootElement(), "preference", null,
new PortletPreferenceElementComparator());
Matcher matcher = _incorrectDefaultPreferencesFileName.matcher(
fileName);
if (matcher.find()) {
String correctFileName =
matcher.group(1) + "-default-portlet-preferences.xml";
processMessage(fileName, "Rename file to " + correctFileName);
}
}
protected String formatPortletXML(
String fileName, String absolutePath, String content)
throws Exception {
Document document = readXML(content);
Element rootElement = document.getRootElement();
boolean checkNumericalPortletNameElement = !isExcludedPath(
_numericalPortletNameElementExcludes, absolutePath);
List portletElements = rootElement.elements("portlet");
for (Element portletElement : portletElements) {
if (checkNumericalPortletNameElement) {
Element portletNameElement = portletElement.element(
"portlet-name");
String portletNameText = portletNameElement.getText();
if (!Validator.isNumber(portletNameText)) {
processMessage(
fileName,
"nonstandard portlet-name element " + portletNameText);
}
}
if (fileName.endsWith("/liferay-portlet.xml")) {
continue;
}
sortElementsByChildElement(portletElement, "init-param", "name");
Element portletPreferencesElement = portletElement.element(
"portlet-preferences");
if (portletPreferencesElement != null) {
sortElementsByChildElement(
portletPreferencesElement, "preference", "name");
}
}
return Dom4jUtil.toString(document);
}
protected String formatPoshiXML(String fileName, String content)
throws Exception {
checkPoshiCharactersAfterDefinition(fileName, content);
checkPoshiCharactersBeforeDefinition(fileName, content);
try {
Document document = readXML(content);
Element rootElement = document.getRootElement();
List commandElements = rootElement.elements("command");
for (Element commandElement : commandElements) {
checkOrder(
fileName, commandElement, "property", null,
new ElementComparator());
}
}
catch (Exception e) {
}
content = sortPoshiCommands(content);
content = sortPoshiVariables(content);
content = fixPoshiXMLElementWithNoChild(content);
content = fixPoshiXMLEndLinesAfterClosingElement(content);
content = fixPoshiXMLEndLinesBeforeClosingElement(content);
content = fixPoshiXMLEndLines(content);
return fixPoshiXMLNumberOfTabs(content);
}
protected void formatResourceActionXML(String fileName, String content)
throws Exception {
Document document = readXML(content);
Element rootElement = document.getRootElement();
List portletResourceElements = rootElement.elements(
"portlet-resource");
for (Element portletResourceElement : portletResourceElements) {
Element portletNameElement = portletResourceElement.element(
"portlet-name");
String portletName = portletNameElement.getText();
Element permissionsElement = portletResourceElement.element(
"permissions");
List permissionsChildElements =
permissionsElement.elements();
for (Element permissionsChildElement : permissionsChildElements) {
checkOrder(
fileName, permissionsChildElement, "action-key",
portletName,
new ResourceActionActionKeyElementComparator());
}
}
checkOrder(
fileName, rootElement, "portlet-resource", null,
new ResourceActionPortletResourceElementComparator());
}
protected void formatServiceXML(
String fileName, String absolutePath, String content)
throws Exception {
Document document = readXML(content);
Element rootElement = document.getRootElement();
List entityElements = rootElement.elements("entity");
ServiceReferenceElementComparator serviceReferenceElementComparator =
new ServiceReferenceElementComparator("entity");
for (Element entityElement : entityElements) {
String entityName = entityElement.attributeValue("name");
List columnNames = getColumnNames(
fileName, absolutePath, entityName);
checkOrder(
fileName, entityElement, "finder", entityName,
new ServiceFinderElementComparator(columnNames));
checkOrder(
fileName, entityElement, "reference", entityName,
serviceReferenceElementComparator);
}
checkOrder(
fileName, rootElement, "entity", null, new ElementComparator());
checkOrder(
fileName, rootElement.element("exceptions"), "exception", null,
new ServiceExceptionElementComparator());
}
protected void formatSolrSchema(String fileName, String content)
throws Exception {
Document document = readXML(content);
Element rootElement = document.getRootElement();
SolrElementComparator solrElementComparator =
new SolrElementComparator();
Element typesElement = rootElement.element("types");
_solrElementsContent = typesElement.asXML();
checkOrder(
fileName, typesElement, "fieldType", null, solrElementComparator);
Element fieldsElement = rootElement.element("fields");
_solrElementsContent = fieldsElement.asXML();
checkOrder(
fileName, fieldsElement, "field", null, solrElementComparator);
}
protected void formatStrutsConfigXML(String fileName, String content)
throws Exception {
Document document = readXML(content);
Element rootElement = document.getRootElement();
checkOrder(
fileName, rootElement.element("action-mappings"), "action", null,
new StrutsActionElementComparator("path"));
}
protected void formatTestIgnorableErrorLinesXml(
String fileName, String content)
throws Exception {
Document document = readXML(content);
Element rootElement = document.getRootElement();
List javascriptElements = rootElement.elements("javascript");
for (Element javascriptElement : javascriptElements) {
checkOrder(
fileName, javascriptElement, "ignore-error", null,
new ElementComparator("description"));
}
List logElements = rootElement.elements("log");
for (Element logElement : logElements) {
checkOrder(
fileName, logElement, "ignore-error", null,
new ElementComparator("description"));
}
}
protected void formatTilesDefsXML(String fileName, String content)
throws Exception {
Document document = readXML(content);
checkOrder(
fileName, document.getRootElement(), "definition", null,
new TilesDefinitionElementComparator());
}
protected String formatWebXML(String fileName, String content)
throws Exception {
if (!portalSource) {
String webXML = ContentUtil.get(
"com/liferay/portal/deploy/dependencies/web.xml");
if (content.equals(webXML)) {
processMessage(fileName, StringPool.BLANK);
}
return content;
}
Properties properties = new Properties();
File propertiesFile = new File(
sourceFormatterArgs.getBaseDirName(),
"portal-impl/src/portal.properties");
String propertiesContent = FileUtil.read(propertiesFile);
PropertiesUtil.load(properties, propertiesContent);
String[] locales = StringUtil.split(
properties.getProperty(PropsKeys.LOCALES));
Arrays.sort(locales);
Set urlPatterns = new TreeSet<>();
for (String locale : locales) {
int pos = locale.indexOf(CharPool.UNDERLINE);
String languageCode = locale.substring(0, pos);
urlPatterns.add(languageCode);
urlPatterns.add(locale);
}
StringBundler sb = new StringBundler(6 * urlPatterns.size());
for (String urlPattern : urlPatterns) {
sb.append("\t\n");
sb.append("\t\tI18n Servlet \n");
sb.append("\t\t/");
sb.append(urlPattern);
sb.append("/* \n");
sb.append("\t \n");
}
int x = content.indexOf("");
x = content.indexOf("I18n Servlet ", x);
x = content.lastIndexOf("", x) - 1;
int y = content.lastIndexOf(
"I18n Servlet ");
y = content.indexOf(" ", y) + 19;
String newContent =
content.substring(0, x) + sb.toString() + content.substring(y);
x = newContent.indexOf("");
x = newContent.indexOf("", x);
x = newContent.indexOf("", x) - 3;
y = newContent.indexOf(" ", x);
y = newContent.lastIndexOf("", y) + 15;
sb = new StringBundler(3 * urlPatterns.size() + 1);
sb.append("\t\t\t/c/portal/protected \n");
for (String urlPattern : urlPatterns) {
sb.append("\t\t\t/");
sb.append(urlPattern);
sb.append("/c/portal/protected \n");
}
return newContent.substring(0, x) + sb.toString() +
newContent.substring(y);
}
protected List getColumnNames(
String fileName, String absolutePath, String entityName)
throws Exception {
List columnNames = new ArrayList<>();
Pattern pattern = Pattern.compile(
"create table " + entityName + "_? \\(\n([\\s\\S]*?)\n\\);");
String tablesContent = getTablesContent(fileName, absolutePath);
if (tablesContent == null) {
return columnNames;
}
Matcher matcher = pattern.matcher(tablesContent);
if (!matcher.find()) {
return columnNames;
}
String tableContent = matcher.group(1);
UnsyncBufferedReader unsyncBufferedReader = new UnsyncBufferedReader(
new UnsyncStringReader(tableContent));
String line = null;
while ((line = unsyncBufferedReader.readLine()) != null) {
line = StringUtil.trim(line);
String columnName = line.substring(0, line.indexOf(CharPool.SPACE));
columnName = StringUtil.replace(
columnName, StringPool.UNDERLINE, StringPool.BLANK);
columnNames.add(columnName);
}
return columnNames;
}
protected List getElementsByName(
String name, Element element, List elements) {
if (elements == null) {
elements = new ArrayList<>();
}
List childElements = element.elements();
for (Element childElement : childElements) {
String elementName = childElement.getName();
if (elementName.equals(name)) {
elements.add(childElement);
}
elements = getElementsByName(name, childElement, elements);
}
return elements;
}
protected String getTablesContent(String fileName, String absolutePath)
throws Exception {
if (portalSource && !isModulesFile(absolutePath)) {
if (_tablesContent == null) {
String tablesContent = getContent(
"sql/portal-tables.sql", PORTAL_MAX_DIR_LEVEL);
_tablesContent = tablesContent;
}
return _tablesContent;
}
String tablesContent = _tablesContentMap.get(fileName);
if (tablesContent != null) {
return tablesContent;
}
int pos = fileName.lastIndexOf(CharPool.SLASH);
String moduleOrPluginFolder = fileName.substring(0, pos);
if (portalSource) {
tablesContent = FileUtil.read(
new File(
moduleOrPluginFolder +
"/src/main/resources/META-INF/sql/tables.sql"));
if (tablesContent == null) {
tablesContent = FileUtil.read(
new File(
moduleOrPluginFolder + "/src/META-INF/sql/tables.sql"));
}
}
else {
tablesContent = FileUtil.read(
new File(moduleOrPluginFolder + "/sql/tables.sql"));
}
if (tablesContent != null) {
_tablesContentMap.put(fileName, tablesContent);
}
return tablesContent;
}
protected List getTargetNames(
String buildfileName, String fileName, List targetNames,
boolean importFile)
throws Exception {
File file = new File(buildfileName);
if (!file.exists()) {
if (!importFile) {
processMessage(
fileName,
"ant element pointing to non-existing " + buildfileName);
}
return null;
}
Document document = readXML(FileUtil.read(file));
Element rootElement = document.getRootElement();
if (targetNames == null) {
targetNames = new ArrayList<>();
}
List targetElements = rootElement.elements("target");
for (Element targetElement : targetElements) {
targetNames.add(targetElement.attributeValue("name"));
}
List importElements = rootElement.elements("import");
for (Element importElement : importElements) {
String buildDirName = buildfileName.substring(
0, buildfileName.lastIndexOf(CharPool.SLASH) + 1);
String importFileName =
buildDirName + importElement.attributeValue("file");
targetNames = getTargetNames(
importFileName, fileName, targetNames, true);
}
return targetNames;
}
@Override
protected void preFormat() {
_numericalPortletNameElementExcludes = getPropertyList(
"numerical.portlet.name.element.excludes");
_xmlExcludes = getPropertyList("xml.excludes");
}
protected String sortAttributes(String fileName, String content)
throws Exception {
StringBundler sb = new StringBundler();
try (UnsyncBufferedReader unsyncBufferedReader =
new UnsyncBufferedReader(new UnsyncStringReader(content))) {
String line = null;
int lineCount = 0;
boolean sortAttributes = true;
while ((line = unsyncBufferedReader.readLine()) != null) {
lineCount++;
String trimmedLine = StringUtil.trimLeading(line);
if (sortAttributes) {
if (trimmedLine.startsWith(StringPool.LESS_THAN) &&
trimmedLine.endsWith(StringPool.GREATER_THAN) &&
!trimmedLine.startsWith("") &&
!trimmedLine.startsWith("<%") &&
!trimmedLine.startsWith(""))) {
line = formatAttributes(
fileName, line, trimmedLine, lineCount, true);
}
else if (trimmedLine.startsWith("")) {
sortAttributes = false;
}
}
else if (trimmedLine.endsWith("]]>")) {
sortAttributes = true;
}
sb.append(line);
sb.append("\n");
}
}
content = sb.toString();
if (content.endsWith("\n")) {
content = content.substring(0, content.length() - 1);
}
return content;
}
protected 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 = content.replace(setUpBlock, "");
sb.append(setUpBlock);
}
matcher = _poshiTearDownPattern.matcher(content);
if (matcher.find()) {
String tearDownBlock = matcher.group();
content = content.replace(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);
}
protected 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 String[] _INCLUDES = new String[] {
"**/*.action", "**/*.function", "**/*.macro", "**/*.testcase",
"**/*.xml"
};
private static final Pattern _commentPattern1 = Pattern.compile(
">\n\t+\n[\t<]");
private final Pattern _importFilePattern = Pattern.compile(
" _numericalPortletNameElementExcludes;
private final Pattern _poshiClosingTagPattern = Pattern.compile(
"[^>/]*>");
private final Pattern _poshiCommandsPattern = Pattern.compile(
"\\[\\s\\S]*?\\" +
"[\\n|\\t]*?(?:[^(?:/\\>)]*?--\\>)*+");
private final Pattern _poshiElementWithNoChildPattern = Pattern.compile(
"\\\"[\\s]*\\>[\\n\\s\\t]*\\[a-z\\-]+>");
private final Pattern _poshiEndLinesAfterClosingElementPattern =
Pattern.compile("(\\[a-z\\-]+>)(\\n+)\\t*\\<[a-z]+");
private final Pattern _poshiEndLinesBeforeClosingElementPattern =
Pattern.compile("(\\n+)(\\t*[a-z\\-]+>)");
private final Pattern _poshiEndLinesPattern = Pattern.compile(
"\\>\\n\\n\\n+(\\t*\\<)");
private final Pattern _poshiOpeningTagPattern = Pattern.compile(
"<[^/][^>]*[^/]>");
private final Pattern _poshiQuoteWithSlashPattern = Pattern.compile(
"\"[^\"]*\\>[^\"]*\"");
private final Pattern _poshiSetUpPattern = Pattern.compile(
"\\n[\\t]++\\([\\s\\S]*?)\\ " +
"[\\n|\\t]*?(?:[^(?:/\\>)]*?--\\>)*+\\n");
private final Pattern _poshiTabsPattern = Pattern.compile(
"\\n*([ \\t]*<).*");
private final Pattern _poshiTearDownPattern = Pattern.compile(
"\\n[\\t]++\\([\\s\\S]*?)\\ " +
"[\\n|\\t]*?(?:[^(?:/\\>)]*?--\\>)*+\\n");
private final Pattern _poshiVariableLinePattern = Pattern.compile(
"([\\t]*+)(\\" +
".*+(?:\\)??)");
private final Pattern _poshiVariablesBlockPattern = Pattern.compile(
"((?:[\\t]*+\\\\n[\\t]*+){2,}?)" +
"(?:(?:\\n){1,}+|\\)");
private final Pattern _poshiWholeTagPattern = Pattern.compile(
"<[^\\>^/]*\\/>");
private final Pattern _projectNamePattern = Pattern.compile(
"/(\\w*-(ext|hooks|layouttpl|portlet|theme|web))/build\\.xml$");
private String _solrElementsContent;
private String _tablesContent;
private final Map _tablesContentMap =
new ConcurrentHashMap<>();
private final Pattern _whereNotInSQLPattern = Pattern.compile(
"WHERE[ \t\n]+\\(*[a-zA-z0-9.]+ NOT IN");
private List _xmlExcludes;
private static class PortletPreferenceElementComparator
extends ElementComparator {
@Override
protected String getElementName(Element preferenceElement) {
Element nameElement = preferenceElement.element(getNameAttribute());
return nameElement.getStringValue();
}
}
private static class ResourceActionActionKeyElementComparator
extends ElementComparator {
@Override
protected String getElementName(Element actionKeyElement) {
return actionKeyElement.getStringValue();
}
}
private static class ResourceActionPortletResourceElementComparator
extends ElementComparator {
@Override
protected String getElementName(Element portletResourceElement) {
Element portletNameElement = portletResourceElement.element(
"portlet-name");
return portletNameElement.getText();
}
}
private static class ServiceExceptionElementComparator
extends ElementComparator {
@Override
protected String getElementName(Element exceptionElement) {
return exceptionElement.getStringValue();
}
}
private static class ServiceReferenceElementComparator
extends ElementComparator {
public ServiceReferenceElementComparator(String nameAttribute) {
super(nameAttribute);
}
@Override
public int compare(
Element referenceElement1, Element referenceElement2) {
String packagePath1 = referenceElement1.attributeValue(
"package-path");
String packagePath2 = referenceElement2.attributeValue(
"package-path");
if (!packagePath1.equals(packagePath2)) {
return packagePath1.compareToIgnoreCase(packagePath2);
}
String entityName1 = referenceElement1.attributeValue("entity");
String entityName2 = referenceElement2.attributeValue("entity");
return entityName1.compareToIgnoreCase(entityName2);
}
}
private static class StrutsActionElementComparator
extends ElementComparator {
public StrutsActionElementComparator(String nameAttribute) {
super(nameAttribute);
}
@Override
public int compare(Element actionElement1, Element actionElement2) {
String path1 = actionElement1.attributeValue("path");
String path2 = actionElement2.attributeValue("path");
if (!path1.startsWith("/portal/") && path2.startsWith("/portal/")) {
return 1;
}
if (path1.startsWith("/portal/") && !path2.startsWith("/portal/")) {
return -1;
}
return path1.compareTo(path2);
}
}
private static class TilesDefinitionElementComparator
extends ElementComparator {
@Override
public int compare(
Element definitionElement1, Element definitionElement2) {
String definitionName1 = getElementName(definitionElement1);
if (definitionName1.equals("portlet")) {
return -1;
}
return super.compare(definitionElement1, definitionElement2);
}
}
private class CustomSQLElementComparator extends ElementComparator {
public CustomSQLElementComparator(String nameAttribute) {
super(nameAttribute);
}
@Override
public int compare(Element sqlElement1, Element sqlElement2) {
String sqlElementName1 = getElementName(sqlElement1);
String sqlElementName2 = getElementName(sqlElement2);
if ((sqlElementName1 == null) || (sqlElementName2 == null)) {
return 0;
}
return sqlElementName1.compareToIgnoreCase(sqlElementName2);
}
@Override
protected String getElementName(Element element) {
String elementName = element.attributeValue(getNameAttribute());
if (Validator.isNull(elementName)) {
return null;
}
int pos = elementName.lastIndexOf(StringPool.PERIOD);
if (pos == -1) {
return null;
}
return elementName.substring(0, pos);
}
}
private class ServiceFinderElementComparator extends ElementComparator {
public ServiceFinderElementComparator(List columnNames) {
_columnNames = columnNames;
}
@Override
public int compare(Element finderElement1, Element finderElement2) {
List finderColumnElements1 = finderElement1.elements(
"finder-column");
List finderColumnElements2 = finderElement2.elements(
"finder-column");
int finderColumnCount1 = finderColumnElements1.size();
int finderColumnCount2 = finderColumnElements2.size();
if (finderColumnCount1 != finderColumnCount2) {
return finderColumnCount1 - finderColumnCount2;
}
for (int i = 0; i < finderColumnCount1; i++) {
Element finderColumnElement1 = finderColumnElements1.get(i);
Element finderColumnElement2 = finderColumnElements2.get(i);
String finderColumnName1 = finderColumnElement1.attributeValue(
"name");
String finderColumnName2 = finderColumnElement2.attributeValue(
"name");
int index1 = _columnNames.indexOf(finderColumnName1);
int index2 = _columnNames.indexOf(finderColumnName2);
if (index1 != index2) {
return index1 - index2;
}
}
String finderName1 = finderElement1.attributeValue("name");
String finderName2 = finderElement2.attributeValue("name");
int startsWithWeight = StringUtil.startsWithWeight(
finderName1, finderName2);
String strippedFinderName1 = finderName1.substring(
startsWithWeight);
String strippedFinderName2 = finderName2.substring(
startsWithWeight);
if (strippedFinderName1.startsWith("Gt") ||
strippedFinderName1.startsWith("Like") ||
strippedFinderName1.startsWith("Lt") ||
strippedFinderName1.startsWith("Not")) {
if (!strippedFinderName2.startsWith("Gt") &&
!strippedFinderName2.startsWith("Like") &&
!strippedFinderName2.startsWith("Lt") &&
!strippedFinderName2.startsWith("Not")) {
return 1;
}
else {
return strippedFinderName1.compareTo(strippedFinderName2);
}
}
return 0;
}
private final List _columnNames;
}
private class SolrElementComparator extends ElementComparator {
@Override
public int compare(Element solrElement1, Element solrElement2) {
int value = super.compare(solrElement1, solrElement2);
if (value <= 0) {
return value;
}
String solrElementContent1 = solrElement1.asXML();
String solrElementContent2 = solrElement2.asXML();
int x =
_solrElementsContent.indexOf(solrElementContent1) +
solrElementContent1.length();
int y = _solrElementsContent.indexOf(solrElementContent2);
if (x > y) {
return -1;
}
String betweenElementsContent = _solrElementsContent.substring(
x, y);
if (betweenElementsContent.contains("