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

com.liferay.source.formatter.check.JavaMissingOverrideCheck Maven / Gradle / Ivy

There is a newer version: 1.0.1437
Show newest version
/**
 * 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.check;

import com.liferay.portal.kernel.json.JSONArray;
import com.liferay.portal.kernel.json.JSONObject;
import com.liferay.portal.kernel.util.StringUtil;
import com.liferay.source.formatter.parser.JavaClass;
import com.liferay.source.formatter.parser.JavaMethod;
import com.liferay.source.formatter.parser.JavaParameter;
import com.liferay.source.formatter.parser.JavaSignature;
import com.liferay.source.formatter.parser.JavaTerm;
import com.liferay.source.formatter.util.PortalJSONObjectUtil;

import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.TreeSet;

/**
 * @author Hugo Huijser
 */
public class JavaMissingOverrideCheck extends BaseJavaTermCheck {

	@Override
	public boolean isLiferaySourceCheck() {
		return true;
	}

	@Override
	protected String doProcess(
			String fileName, String absolutePath, JavaTerm javaTerm,
			String fileContent)
		throws Exception {

		JavaClass javaClass = (JavaClass)javaTerm;

		if (javaClass.hasAnnotation("Deprecated") ||
			(javaClass.getParentJavaClass() != null)) {

			return javaClass.getContent();
		}

		Set javaMethods = new TreeSet<>(
			new Comparator() {

				public int compare(JavaTerm javaTerm1, JavaTerm javaTerm2) {
					return javaTerm2.getLineNumber() -
						javaTerm1.getLineNumber();
				}

			});

		for (JavaTerm childJavaTerm : javaClass.getChildJavaTerms()) {
			if (childJavaTerm.isJavaMethod() && !childJavaTerm.isStatic() &&
				!childJavaTerm.hasAnnotation("Deprecated", "Override") &&
				!Objects.equals(childJavaTerm.getName(), "main") &&
				_hasSuperMethod(
					(JavaMethod)childJavaTerm, javaClass.getName(true),
					false)) {

				javaMethods.add((JavaMethod)childJavaTerm);
			}
		}

		return _fixMissingOverrideAnnotations(javaClass, javaMethods);
	}

	@Override
	protected String[] getCheckableJavaTermNames() {
		return new String[] {JAVA_CLASS};
	}

	private boolean _equals(
		JavaMethod javaMethod, JSONObject methodJSONObject) {

		if (!Objects.equals(
				javaMethod.getAccessModifier(),
				methodJSONObject.getString("accessModifier")) ||
			!Objects.equals(
				javaMethod.getName(), methodJSONObject.getString("name"))) {

			return false;
		}

		JavaSignature javaSignature = javaMethod.getSignature();

		if (!Objects.equals(
				javaSignature.getReturnType(true),
				methodJSONObject.getString("returnType"))) {

			return false;
		}

		List javaParameters = javaSignature.getParameters();
		JSONArray parametersJSONArray = methodJSONObject.getJSONArray(
			"parameters");

		if (parametersJSONArray == null) {
			return javaParameters.isEmpty();
		}

		if (javaParameters.size() != parametersJSONArray.length()) {
			return false;
		}

		Iterator iterator = parametersJSONArray.iterator();

		int i = 0;

		while (iterator.hasNext()) {
			JavaParameter javaParameter = javaParameters.get(i++);

			if (!Objects.equals(
					javaParameter.getParameterType(true), iterator.next())) {

				return false;
			}
		}

		return true;
	}

	private String _fixMissingOverrideAnnotations(
		JavaClass javaClass, Set javaMethods) {

		String content = javaClass.getContent();

		for (JavaMethod javaMethod : javaMethods) {
			int lineNumber =
				javaMethod.getLineNumber() - javaClass.getLineNumber();

			for (int i = lineNumber + 1;; i++) {
				String line = StringUtil.trim(getLine(content, i));

				if (line == null) {
					return content;
				}

				if (line.startsWith(javaMethod.getAccessModifier())) {
					content = StringUtil.replaceFirst(
						content, line, "@Override\n" + line,
						getLineStartPos(content, lineNumber));

					break;
				}
			}
		}

		return content;
	}

	private synchronized JSONObject _getJavaClassesJSONObject()
		throws Exception {

		if (_javaClassesJSONObject != null) {
			return _javaClassesJSONObject;
		}

		JSONObject portalJSONObject = PortalJSONObjectUtil.getPortalJSONObject(
			getBaseDirName(), getSourceFormatterExcludes(), getMaxLineLength());

		_javaClassesJSONObject = portalJSONObject.getJSONObject("javaClasses");

		return _javaClassesJSONObject;
	}

	private boolean _hasMethod(
		JSONObject classJSONObject, JavaMethod javaMethod) {

		JSONArray methodsJSONArray = classJSONObject.getJSONArray("methods");

		if (methodsJSONArray == null) {
			return false;
		}

		Iterator iterator = methodsJSONArray.iterator();

		while (iterator.hasNext()) {
			if (_equals(javaMethod, iterator.next())) {
				return true;
			}
		}

		return false;
	}

	private boolean _hasSuperMethod(
			JavaMethod javaMethod, JSONArray classNamesJSONArray)
		throws Exception {

		if (classNamesJSONArray == null) {
			return false;
		}

		Iterator iterator = classNamesJSONArray.iterator();

		while (iterator.hasNext()) {
			if (_hasSuperMethod(javaMethod, iterator.next(), true)) {
				return true;
			}
		}

		return false;
	}

	private boolean _hasSuperMethod(
			JavaMethod javaMethod, String className, boolean superClass)
		throws Exception {

		JSONObject javaClassesJSONObject = _getJavaClassesJSONObject();

		JSONObject classJSONObject = javaClassesJSONObject.getJSONObject(
			className);

		if (classJSONObject == null) {
			return false;
		}

		if ((superClass && _hasMethod(classJSONObject, javaMethod)) ||
			_hasSuperMethod(
				javaMethod,
				classJSONObject.getJSONArray("extendedClassNames")) ||
			_hasSuperMethod(
				javaMethod,
				classJSONObject.getJSONArray("implementedClassNames"))) {

			return true;
		}

		return false;
	}

	private JSONObject _javaClassesJSONObject;

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy