/** * 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.CharPool; 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 java.util.regex.Matcher; import java.util.regex.Pattern; /** * @author Hugo Huijser */ public abstract class TagAttributesCheck extends BaseFileCheck { protected String formatTagAttributes( String fileName, String line, String tag, int lineCount, boolean escapeQuotes) throws Exception { String s = tag; int y = s.indexOf(CharPool.SPACE); if (y == -1) { return line; } String tagName = s.substring(1, y); s = s.substring(y + 1); String previousAttribute = null; String previousAttributeAndValue = null; boolean wrongOrder = false; for (int x = 0;;) { x = s.indexOf(CharPool.EQUAL); if ((x == -1) || (s.length() <= (x + 1))) { return line; } String attribute = s.substring(0, x); String trimmedAttribute = StringUtil.trim(attribute); if (!_isAttributName(trimmedAttribute)) { return line; } if (!attribute.equals(trimmedAttribute)) { return StringUtil.replace( line, attribute + "=", trimmedAttribute + "="); } 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.SPACE) { return StringUtil.replace( line, attribute + "= ", attribute + "="); } if (delimeter != CharPool.AMPERSAND) { addMessage( fileName, "Incorrect delimeter '" + delimeter + "'", 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("<%")) { if (getLevel(value, "<%", "%>") == 0) { break; } } else if (getLevel( value, StringPool.LESS_THAN, StringPool.GREATER_THAN) == 0) { break; } } if (delimeter == CharPool.APOSTROPHE) { if (escapeQuotes) { String newValue = StringUtil.replace( value, CharPool.QUOTE, """); return StringUtil.replace( line, StringPool.APOSTROPHE + value + StringPool.APOSTROPHE, StringPool.QUOTE + newValue + StringPool.QUOTE); } if (!value.contains(StringPool.QUOTE) || !tagName.contains(StringPool.COLON)) { return StringUtil.replace( line, StringPool.APOSTROPHE + value + StringPool.APOSTROPHE, StringPool.QUOTE + value + StringPool.QUOTE); } } if ((delimeter == CharPool.QUOTE) && value.contains(StringPool.QUOTE) && tagName.contains(StringPool.COLON)) { return StringUtil.replace( line, StringPool.QUOTE + value + StringPool.QUOTE, StringPool.APOSTROPHE + value + StringPool.APOSTROPHE); } 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(); if (!tagName.equals("liferay-ui:tabs")) { String newLine = sortHTMLTagAttributes( line, value, currentAttributeAndValue); if (!newLine.equals(line)) { return newLine; } } String newLine = formatTagAttributeType( line, tagName, currentAttributeAndValue); if (!newLine.equals(line)) { return newLine; } if (wrongOrder) { if ((StringUtil.count(line, currentAttributeAndValue) == 1) && (StringUtil.count(line, previousAttributeAndValue) == 1)) { line = StringUtil.replaceFirst( line, previousAttributeAndValue, currentAttributeAndValue); return StringUtil.replaceLast( line, currentAttributeAndValue, previousAttributeAndValue); } return line; } s = s.substring(y + 1); if (s.startsWith(StringPool.GREATER_THAN)) { return line; } s = StringUtil.trimLeading(s); previousAttribute = attribute; previousAttributeAndValue = currentAttributeAndValue; } } protected String formatTagAttributeType( String line, String tagName, String attributeAndValue) throws Exception { return line; } protected String sortHTMLTagAttributes( String line, String value, String attributeAndValue) { return line; } private boolean _isAttributName(String attributeName) { if (Validator.isNull(attributeName)) { return false; } Matcher matcher = _attributeNamePattern.matcher(attributeName); return matcher.matches(); } private static final Pattern _attributeNamePattern = Pattern.compile( "[a-z]+[-_a-zA-Z0-9]*"); }