All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.liferay.source.formatter.check.BaseJSPTermsCheck 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.CharPool;
import com.liferay.petra.string.StringBundler;
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.check.util.JSPSourceUtil;
import com.liferay.source.formatter.check.util.SourceUtil;
import com.liferay.source.formatter.util.SourceFormatterUtil;

import java.io.IOException;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author Hugo Huijser
 */
public abstract class BaseJSPTermsCheck extends BaseFileCheck {

	@Override
	public void setAllFileNames(List allFileNames) {
		_allFileNames = allFileNames;
	}

	protected Map getContentsMap() {
		return _contentsMap;
	}

	protected Set getMissingTaglibPrefixes(
		String fileName, Set taglibPrefixes) {

		List dependentfileNames = new ArrayList<>();

		dependentfileNames.add(fileName);

		Map contentsMap = getContentsMap();

		dependentfileNames = JSPSourceUtil.addIncludedAndReferencedFileNames(
			dependentfileNames, new HashSet(), contentsMap,
			".*\\.jspf");

		if (fileName.endsWith(".jspf") && (dependentfileNames.size() == 1)) {
			return Collections.emptySet();
		}

		for (String dependentfileName : dependentfileNames) {
			dependentfileName = StringUtil.replace(
				dependentfileName, CharPool.BACK_SLASH, CharPool.SLASH);

			String dependenFileContent = contentsMap.get(dependentfileName);

			if (dependenFileContent == null) {
				return Collections.emptySet();
			}

			Iterator iterator = taglibPrefixes.iterator();

			while (iterator.hasNext()) {
				String prefix = iterator.next();

				if (dependenFileContent.contains("prefix=\"" + prefix + "\"")) {
					iterator.remove();

					if (taglibPrefixes.isEmpty()) {
						return taglibPrefixes;
					}
				}
			}
		}

		return taglibPrefixes;
	}

	protected boolean hasUnusedJSPTerm(
		String fileName, String content, String regex, int lineNumber,
		String type, Set checkedForIncludesFileNames,
		Set includeFileNames, Map contentsMap) {

		includeFileNames.add(fileName);

		Set checkedForUnusedJSPTerm = new HashSet<>();

		return !_isJSPTermRequired(
			fileName, content, regex, lineNumber, type, checkedForUnusedJSPTerm,
			checkedForIncludesFileNames, includeFileNames, contentsMap);
	}

	protected boolean hasUnusedJSPTerm(
		String fileName, String content, String regex, String type,
		Set checkedForIncludesFileNames, Set includeFileNames,
		Map contentsMap) {

		return hasUnusedJSPTerm(
			fileName, content, regex, -1, type, checkedForIncludesFileNames,
			includeFileNames, contentsMap);
	}

	protected boolean hasVariableReference(
		String content, String value, int pos) {

		if (pos == -1) {
			return false;
		}

		pos = content.indexOf("\n", pos);

		Matcher methodCallMatcher = _methodCallPattern.matcher(value);

		while (methodCallMatcher.find()) {
			Pattern pattern = Pattern.compile(
				"\\b(? pos) {
					break;
				}

				String methodName = matcher.group(1);

				if (!methodName.startsWith("get") &&
					!methodName.startsWith("is")) {

					return true;
				}
			}
		}

		return false;
	}

	protected synchronized void populateContentsMap(
			String fileName, String content)
		throws IOException {

		if (_contentsMap != null) {
			return;
		}

		List allJSPFileNames = SourceFormatterUtil.filterFileNames(
			_allFileNames, new String[] {"**/null.jsp", "**/tools/**"},
			new String[] {"**/*.jsp", "**/*.jspf", "**/*.tag"},
			getSourceFormatterExcludes(), true);

		_contentsMap = JSPSourceUtil.getContentsMap(allJSPFileNames);

		// When running tests, the contentsMap is empty, because the file
		// extension of the test files is *.testjsp

		if (_contentsMap.isEmpty()) {
			_contentsMap.put(fileName, content);
		}
	}

	protected void put(String fileName, String content) {
		_contentsMap.put(fileName, content);
	}

	private String _getRangeContent(String content, int lineNumber) {
		String line = getLine(content, lineNumber);

		String indent = SourceUtil.getIndent(line);

		if (indent.length() == 0) {
			return content;
		}

		int curLineNumber = lineNumber - 1;

		while (true) {
			if (curLineNumber == 0) {
				break;
			}

			String trimmedLine = StringUtil.trim(
				getLine(content, curLineNumber));

			if (trimmedLine.equals("<%")) {
				break;
			}

			if (trimmedLine.equals("<%!")) {
				return content;
			}

			curLineNumber--;
		}

		StringBundler sb = new StringBundler();

		sb.append("<%\n");
		sb.append(line);

		while (true) {
			lineNumber++;

			line = getLine(content, lineNumber);

			if (line == null) {
				if (indent.length() == 0) {
					return sb.toString();
				}

				return content;
			}

			if (Validator.isNotNull(line) && !line.startsWith(indent)) {
				String trimmedLine = StringUtil.trim(line);

				if (trimmedLine.startsWith("}")) {
					sb.append("%>/n");

					return sb.toString();
				}

				if (trimmedLine.matches("")) {
					return sb.toString();
				}

				if (trimmedLine.matches("")) {
					indent = indent.substring(1);
				}
			}

			sb.append(line);
			sb.append("\n");
		}
	}

	private boolean _isInsideComment(String content, int pos) {
		String s = content.substring(pos);

		int x = s.indexOf("*/");

		if (x == -1) {
			return false;
		}

		String trimmedLine = StringUtil.trim(
			getLine(
				content,
				getLineNumber(content, pos) + getLineNumber(s, x) - 1));

		if (!trimmedLine.endsWith("*/")) {
			return false;
		}

		s = s.substring(0, x);

		if (!s.contains("/*")) {
			return true;
		}

		return false;
	}

	private boolean _isJSPTermRequired(
		String fileName, String content, String regex, int lineNumber,
		String type, Set checkedForUnusedJSPTerm,
		Set checkedForIncludesFileNames, Set includeFileNames,
		Map contentsMap) {

		if (checkedForUnusedJSPTerm.contains(fileName)) {
			return false;
		}

		checkedForUnusedJSPTerm.add(fileName);

		if (content == null) {
			content = contentsMap.get(fileName);
		}

		if (Validator.isNull(content)) {
			return false;
		}

		if (lineNumber != -1) {
			content = _getRangeContent(content, lineNumber);
		}

		int count = 0;

		Pattern pattern = Pattern.compile(regex);

		Matcher matcher = pattern.matcher(content);

		while (matcher.find()) {
			if (type.equals("taglib")) {
				count++;

				continue;
			}

			int x = matcher.start() + 1;

			if (_isInsideComment(content, x)) {
				continue;
			}

			if (isJavaSource(content, x)) {
				if (!ToolsUtil.isInsideQuotes(content, x)) {
					count++;
				}

				continue;
			}

			String line = StringUtil.trim(
				getLine(content, getLineNumber(content, matcher.start())));

			if (line.startsWith("function ")) {
				continue;
			}

			int y = content.lastIndexOf("<%", x) + 2;
			int z = content.lastIndexOf("%>", x);

			if ((y == 1) || (z > y)) {
				continue;
			}

			z = content.indexOf("%>", x);

			if ((z == -1) ||
				(getLineNumber(content, y) != getLineNumber(content, z)) ||
				!ToolsUtil.isInsideQuotes(
					content.substring(y, z), x - y, false)) {

				count++;
			}
		}

		if ((count > 1) ||
			((count == 1) &&
			 (!type.equals("variable") ||
			  (checkedForUnusedJSPTerm.size() > 1)))) {

			return true;
		}

		if (!checkedForIncludesFileNames.contains(fileName)) {
			includeFileNames.addAll(
				JSPSourceUtil.getJSPIncludeFileNames(
					fileName, includeFileNames, contentsMap, false));
			includeFileNames.addAll(
				JSPSourceUtil.getJSPReferenceFileNames(
					fileName, includeFileNames, contentsMap,
					".*\\.(jsp|jspf|tag)"));
		}

		checkedForIncludesFileNames.add(fileName);

		String[] includeFileNamesArray = includeFileNames.toArray(
			new String[0]);

		for (String includeFileName : includeFileNamesArray) {
			if (!checkedForUnusedJSPTerm.contains(includeFileName) &&
				_isJSPTermRequired(
					includeFileName, null, regex, -1, type,
					checkedForUnusedJSPTerm, checkedForIncludesFileNames,
					includeFileNames, contentsMap)) {

				return true;
			}
		}

		return false;
	}

	private static final Pattern _methodCallPattern = Pattern.compile(
		"\\b(? _allFileNames;
	private Map _contentsMap;

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy