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

gr.uom.java.xmi.UMLOperation Maven / Gradle / Ivy

Go to download

RefactoringMiner is a library/API written in Java that can detect refactorings applied in the history of a Java project.

There is a newer version: 3.0.9
Show newest version
package gr.uom.java.xmi;

import gr.uom.java.xmi.decomposition.AbstractStatement;
import gr.uom.java.xmi.decomposition.AnonymousClassDeclarationObject;
import gr.uom.java.xmi.decomposition.CompositeStatementObject;
import gr.uom.java.xmi.decomposition.LambdaExpressionObject;
import gr.uom.java.xmi.decomposition.OperationBody;
import gr.uom.java.xmi.decomposition.OperationInvocation;
import gr.uom.java.xmi.decomposition.StatementObject;
import gr.uom.java.xmi.decomposition.VariableDeclaration;
import gr.uom.java.xmi.diff.CodeRange;
import gr.uom.java.xmi.diff.StringDistance;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.refactoringminer.util.AstUtils;

public class UMLOperation implements Comparable, Serializable, LocationInfoProvider {
	private LocationInfo locationInfo;
	private String name;
	private String visibility;
	private boolean isAbstract;
	private List parameters;
	private String className;
	private boolean isConstructor;
	private boolean isFinal;
	private boolean isStatic;
	private boolean emptyBody;
	private OperationBody operationBody;
	private List anonymousClassList;
	private List typeParameters;
	private UMLJavadoc javadoc;
	private List annotations;
	
	public UMLOperation(String name, LocationInfo locationInfo) {
		this.locationInfo = locationInfo;
        this.name = name;
        this.parameters = new ArrayList();
        this.anonymousClassList = new ArrayList();
        this.typeParameters = new ArrayList();
        this.annotations = new ArrayList();
    }

	public List getTypeParameters() {
		return typeParameters;
	}
	
	public void addTypeParameter(UMLTypeParameter typeParameter) {
		typeParameters.add(typeParameter);
	}

	public List getAnnotations() {
		return annotations;
	}

	public void addAnnotation(UMLAnnotation annotation) {
		annotations.add(annotation);
	}

	public LocationInfo getLocationInfo() {
		return locationInfo;
	}

	public String getName() {
		return name;
	}

	public String getVisibility() {
		return visibility;
	}

	public void setVisibility(String visibility) {
		this.visibility = visibility;
	}

	public boolean isAbstract() {
		return isAbstract;
	}

	public void setAbstract(boolean isAbstract) {
		this.isAbstract = isAbstract;
	}

	public boolean isConstructor() {
		return isConstructor;
	}

	public void setConstructor(boolean isConstructor) {
		this.isConstructor = isConstructor;
	}

	public boolean isFinal() {
		return isFinal;
	}

	public void setFinal(boolean isFinal) {
		this.isFinal = isFinal;
	}

	public boolean isStatic() {
		return isStatic;
	}

	public void setStatic(boolean isStatic) {
		this.isStatic = isStatic;
	}

	public boolean hasEmptyBody() {
		return emptyBody;
	}

	public void setEmptyBody(boolean emptyBody) {
		this.emptyBody = emptyBody;
	}

	public OperationBody getBody() {
		return operationBody;
	}

	public boolean hasTestAnnotation() {
		for(UMLAnnotation annotation : annotations) {
			if(annotation.getTypeName().equals("Test")) {
				return true;
			}
		}
		return false;
	}

	public UMLJavadoc getJavadoc() {
		return javadoc;
	}

	public void setJavadoc(UMLJavadoc javadoc) {
		this.javadoc = javadoc;
	}

	public List getAllOperationInvocations() {
		if(operationBody != null)
			return operationBody.getAllOperationInvocations();
		return new ArrayList();
	}

	public List getAllLambdas() {
		if(operationBody != null)
			return operationBody.getAllLambdas();
		return new ArrayList();
	}

	public List getAllVariables() {
		if(operationBody != null)
			return operationBody.getAllVariables();
		return new ArrayList();
	}

	public List getAllVariableDeclarations() {
		if(operationBody != null)
			return operationBody.getAllVariableDeclarations();
		return new ArrayList();
	}

	public List getVariableDeclarationsInScope(LocationInfo location) {
		if(operationBody != null)
			return operationBody.getVariableDeclarationsInScope(location);
		return new ArrayList();
	}

	public VariableDeclaration getVariableDeclaration(String variableName) {
		if(operationBody != null)
			return operationBody.getVariableDeclaration(variableName);
		return null;
	}

	public Map variableTypeMap() {
		Map variableTypeMap = new LinkedHashMap();
		for(UMLParameter parameter : parameters) {
			if(!parameter.getKind().equals("return"))
				variableTypeMap.put(parameter.getName(), parameter.getType());
		}
		for(VariableDeclaration declaration : getAllVariableDeclarations()) {
			variableTypeMap.put(declaration.getVariableName(), declaration.getType());
		}
		return variableTypeMap;
	}

	public int statementCount() {
		if(operationBody != null)
			return operationBody.statementCount();
		return 0;
	}

	public void setBody(OperationBody body) {
		this.operationBody = body;
	}

	public String getNonQualifiedClassName() {
		return className.contains(".") ? className.substring(className.lastIndexOf(".")+1, className.length()) : className;
	}

	public String getClassName() {
		return className;
	}

	public void setClassName(String className) {
		this.className = className;
	}

	public void addParameter(UMLParameter parameter) {
		this.parameters.add(parameter);
	}

	public List getParameters() {
		return parameters;
	}

	public void addAnonymousClass(UMLAnonymousClass anonymous) {
		this.anonymousClassList.add(anonymous);
	}

	public List getAnonymousClassList() {
		return anonymousClassList;
	}

	public UMLParameter getReturnParameter() {
		for(UMLParameter parameter : parameters) {
			if(parameter.getKind().equals("return"))
				return parameter;
		}
		return null;
	}

	public boolean equalReturnParameter(UMLOperation operation) {
		UMLParameter thisReturnParameter = this.getReturnParameter();
		UMLParameter otherReturnParameter = operation.getReturnParameter();
		if(thisReturnParameter != null && otherReturnParameter != null)
			return thisReturnParameter.equals(otherReturnParameter);
		else if(thisReturnParameter == null && otherReturnParameter == null)
			return true;
		else
			return false;
	}

	public boolean equalQualifiedReturnParameter(UMLOperation operation) {
		UMLParameter thisReturnParameter = this.getReturnParameter();
		UMLParameter otherReturnParameter = operation.getReturnParameter();
		if(thisReturnParameter != null && otherReturnParameter != null)
			return thisReturnParameter.equalsQualified(otherReturnParameter);
		else if(thisReturnParameter == null && otherReturnParameter == null)
			return true;
		else
			return false;
	}

	public boolean equalSignature(UMLOperation operation) {
		boolean equalParameterTypes = this.getParameterTypeList().equals(operation.getParameterTypeList());
		boolean compatibleParameterTypes = false;
		if(!equalParameterTypes) {
			List thisParameterTypeList = this.getParameterTypeList();
			List otherParameterTypeList = operation.getParameterTypeList();
			if(thisParameterTypeList.size() == otherParameterTypeList.size()) {
				int compatibleTypes = 0;
				int equalTypes = 0;
				for(int i=0; i 0 && operation2.getParametersWithoutReturnType().size() > 0;
		if(operation1.name.startsWith(operation2.name) && !operation2.name.equals("get") && !operation2.name.equals("set") && !operation2.name.equals("print")) {
			String suffix1 = operation1.name.substring(operation2.name.length(), operation1.name.length());
			String className2 = operation2.className.contains(".") ? operation2.className.substring(operation2.className.lastIndexOf(".")+1, operation2.className.length()) : operation2.className;
			return operation2.name.length() > operation1.name.length() - operation2.name.length() || equalReturn || className2.contains(suffix1);
		}
		return false;
	}

	public List getParametersWithoutReturnType() {
		List params = new ArrayList();
		for(UMLParameter parameter : parameters) {
			if(!parameter.getKind().equals("return"))
				params.add(parameter);
		}
		return params;
	}

	public List commonParameterTypes(UMLOperation operation) {
		List commonParameterTypes = new ArrayList();
		List thisParameterTypeList = getParameterTypeList();
		List otherParameterTypeList = operation.getParameterTypeList();
		int min = Math.min(thisParameterTypeList.size(), otherParameterTypeList.size());
		for(int i=0; i getParameterTypeList() {
		List parameterTypeList = new ArrayList();
		for(UMLParameter parameter : parameters) {
			if(!parameter.getKind().equals("return"))
				parameterTypeList.add(parameter.getType());
		}
		return parameterTypeList;
	}

	public List getParameterNameList() {
		List parameterNameList = new ArrayList();
		for(UMLParameter parameter : parameters) {
			if(!parameter.getKind().equals("return"))
				parameterNameList.add(parameter.getName());
		}
		return parameterNameList;
	}

	public int getNumberOfNonVarargsParameters() {
		int counter = 0;
		for(UMLParameter parameter : parameters) {
			if(!parameter.getKind().equals("return") && !parameter.isVarargs()) {
				counter++;
			}
		}
		return counter;
	}

	public boolean hasVarargsParameter() {
		for(UMLParameter parameter : parameters) {
			if(!parameter.getKind().equals("return") && parameter.isVarargs()) {
				return true;
			}
		}
		return false;
	}

	public OperationInvocation isDelegate() {
		if(getBody() != null) {
			List statements = getBody().getCompositeStatement().getStatements();
			if(statements.size() == 1 && statements.get(0) instanceof StatementObject) {
				StatementObject statement = (StatementObject)statements.get(0);
				Map> operationInvocationMap = statement.getMethodInvocationMap();
				for(String key : operationInvocationMap.keySet()) {
					List operationInvocations = operationInvocationMap.get(key);
					for(OperationInvocation operationInvocation : operationInvocations) {
						if(operationInvocation.matchesOperation(this, this.variableTypeMap(), null) || operationInvocation.getMethodName().equals(this.getName())) {
							return operationInvocation;
						}
					}
				}
			}
		}
		return null;
	}

	public boolean isGetter() {
		if(getBody() != null) {
			List statements = getBody().getCompositeStatement().getStatements();
			List parameters = getParametersWithoutReturnType();
			if(statements.size() == 1 && statements.get(0) instanceof StatementObject) {
				StatementObject statement = (StatementObject)statements.get(0);
				if(statement.getString().startsWith("return ")) {
					for(String variable : statement.getVariables()) {
						if(statement.getString().equals("return " + variable + ";\n") && parameters.size() == 0) {
							return true;
						}
						else if(statement.getString().equals("return " + variable + ".keySet()" + ";\n") && parameters.size() == 0) {
							return true;
						}
						else if(statement.getString().equals("return " + variable + ".values()" + ";\n") && parameters.size() == 0) {
							return true;
						}
					}
					UMLParameter returnParameter = getReturnParameter();
					if((name.startsWith("is") || name.startsWith("has")) && parameters.size() == 0 &&
							returnParameter != null && returnParameter.getType().getClassType().equals("boolean")) {
						return true;
					}
					if(statement.getString().equals("return null;\n")) {
						return true;
					}
				}
			}
		}
		return false;
	}

	public boolean isSetter() {
		List parameterNames = getParameterNameList();
		if(getBody() != null && parameterNames.size() == 1) {
			List statements = getBody().getCompositeStatement().getStatements();
			if(statements.size() == 1 && statements.get(0) instanceof StatementObject) {
				StatementObject statement = (StatementObject)statements.get(0);
				for(String variable : statement.getVariables()) {
					if(statement.getString().equals(variable + "=" + parameterNames.get(0) + ";\n")) {
						return true;
					}
				}
			}
		}
		return false;
	}

	public boolean equalsIgnoringVisibility(UMLOperation operation) {
		boolean thisEmptyBody = this.getBody() == null || this.hasEmptyBody();
		boolean otherEmptyBody = operation.getBody() == null || operation.hasEmptyBody();
		return this.className.equals(operation.className) &&
				this.name.equals(operation.name) &&
				this.isAbstract == operation.isAbstract &&
				thisEmptyBody == otherEmptyBody &&
				equalReturnParameter(operation) &&
				this.getParameterTypeList().equals(operation.getParameterTypeList()) &&
				equalTypeParameters(operation);
	}

	public boolean equalsIgnoringNameCase(UMLOperation operation) {
		boolean thisEmptyBody = this.getBody() == null || this.hasEmptyBody();
		boolean otherEmptyBody = operation.getBody() == null || operation.hasEmptyBody();
		return this.className.equals(operation.className) &&
				this.name.equalsIgnoreCase(operation.name) &&
				this.visibility.equals(operation.visibility) &&
				this.isAbstract == operation.isAbstract &&
				thisEmptyBody == otherEmptyBody &&
				equalReturnParameter(operation) &&
				this.getParameterTypeList().equals(operation.getParameterTypeList()) &&
				equalTypeParameters(operation);
	}

	public boolean equals(Object o) {
		if(this == o) {
            return true;
        }
		
		if(o instanceof UMLOperation) {
			UMLOperation operation = (UMLOperation)o;
			boolean thisEmptyBody = this.getBody() == null || this.hasEmptyBody();
			boolean otherEmptyBody = operation.getBody() == null || operation.hasEmptyBody();
			return this.className.equals(operation.className) &&
				this.name.equals(operation.name) &&
				this.visibility.equals(operation.visibility) &&
				this.isAbstract == operation.isAbstract &&
				thisEmptyBody == otherEmptyBody &&
				this.getParameterTypeList().equals(operation.getParameterTypeList()) &&
				equalTypeParameters(operation);
		}
		return false;
	}

	public boolean equalsQualified(UMLOperation operation) {
		if(this.className.equals(operation.className) &&
				this.name.equals(operation.name) &&
				this.visibility.equals(operation.visibility) &&
				this.isAbstract == operation.isAbstract &&
				equalTypeParameters(operation)) {
			UMLParameter thisReturnParameter = this.getReturnParameter();
			UMLParameter otherReturnParameter = operation.getReturnParameter();
			if(thisReturnParameter != null && otherReturnParameter != null) {
				if(!thisReturnParameter.getType().equalsQualified(otherReturnParameter.getType())) {
					return false;
				}
			}
			List thisParameterTypeList = this.getParameterTypeList();
			List otherParameterTypeList = operation.getParameterTypeList();
			if(thisParameterTypeList.size() != otherParameterTypeList.size()) {
				return false;
			}
			for(int i=0; i parameters = new ArrayList(this.parameters);
		parameters.remove(returnParameter);
		sb.append("(");
		for(int i=0; i parameters = new ArrayList(this.parameters);
		parameters.remove(returnParameter);
		sb.append("(");
		for(int i=0; i parameters = new ArrayList(this.parameters);
		parameters.remove(returnParameter);
		sb.append("(");
		for (int i = 0; i < parameters.size(); i++) {
			UMLParameter parameter = parameters.get(i);
			if(parameter.getKind().equals("in")) {
				sb.append(AstUtils.stripTypeParamsFromTypeName(parameter.getType().toString()));
				if(i < parameters.size() - 1)
					sb.append(", ");
			}
		}
		sb.append(")");
		return sb.toString();
	}
	
	public int compareTo(UMLOperation operation) {
		return this.toString().compareTo(operation.toString());
	}

	public double normalizedNameDistance(UMLOperation operation) {
		String s1 = getName().toLowerCase();
		String s2 = operation.getName().toLowerCase();
		int distance = StringDistance.editDistance(s1, s2);
		double normalized = (double)distance/(double)Math.max(s1.length(), s2.length());
		return normalized;
	}

	public boolean equalParameters(UMLOperation operation) {
		return this.equalReturnParameter(operation) && this.getParameters().equals(operation.getParameters());
	}

	public boolean equalParameterTypes(UMLOperation operation) {
		return this.equalReturnParameter(operation) && this.getParameterTypeList().equals(operation.getParameterTypeList()) && equalTypeParameters(operation);
	}

	private boolean equalTypeParameters(UMLOperation operation) {
		return this.typeParameters.equals(operation.typeParameters);
	}

	public boolean equalParameterNames(UMLOperation operation) {
		return this.equalReturnParameter(operation) && this.getParameterNameList().equals(operation.getParameterNameList());
	}

	public boolean overloadedParameters(UMLOperation operation) {
		return this.equalReturnParameter(operation) &&
				(this.getParameters().containsAll(operation.getParameters()) || operation.getParameters().containsAll(this.getParameters()));
	}

	public boolean overloadedParameterTypes(UMLOperation operation) {
		return this.equalReturnParameter(operation) &&
				(this.getParameterTypeList().containsAll(operation.getParameterTypeList()) || operation.getParameterTypeList().containsAll(this.getParameterTypeList()));
	}
	
	public boolean replacedParameterTypes(UMLOperation operation) {
		List thisParameterTypes = this.getParameterTypeList();
		List otherParameterTypes = operation.getParameterTypeList();
		
		if(thisParameterTypes.size() == otherParameterTypes.size() && thisParameterTypes.size() > 0) {
			int commonParameterTypes = 0;
			int differentParameterTypes = 0;
			for(int i=0; i= differentParameterTypes && commonParameterTypes > 0;
		}
		else if(thisParameterTypes.size() > otherParameterTypes.size() && thisParameterTypes.size() > 0) {
			int commonParameterTypes = 0;
			int differentParameterTypes = 0;
			for(int i=0; i= differentParameterTypes && commonParameterTypes > 0;
		}
		else if(otherParameterTypes.size() > thisParameterTypes.size() && thisParameterTypes.size() > 0) {
			int commonParameterTypes = 0;
			int differentParameterTypes = 0;
			for(int i=0; i= differentParameterTypes && commonParameterTypes > 0;
		}
		return false;
	}

	public List getOperationsInsideAnonymousClass(List allAddedAnonymousClasses) {
		List operationsInsideAnonymousClass = new ArrayList();
		if(this.operationBody != null) {
			List anonymousClassDeclarations = this.operationBody.getAllAnonymousClassDeclarations();
			for(AnonymousClassDeclarationObject anonymousClassDeclaration : anonymousClassDeclarations) {
				for(UMLAnonymousClass anonymousClass : allAddedAnonymousClasses) {
					if(anonymousClass.getLocationInfo().equals(anonymousClassDeclaration.getLocationInfo())) {
						operationsInsideAnonymousClass.addAll(anonymousClass.getOperations());
					}
				}
			}
		}
		return operationsInsideAnonymousClass;
	}

	public CodeRange codeRange() {
		return locationInfo.codeRange();
	}

	public boolean overridesObject() {
		return isEquals() || isHashCode() || isToString() || isClone() || isCompareTo();
	}

	private boolean isEquals() {
		List parameterTypeList = getParameterTypeList();
		return getName().equals("equals") && getReturnParameter().getType().getClassType().equals("boolean") &&
				parameterTypeList.size() == 1 && parameterTypeList.get(0).getClassType().equals("Object");
	}

	private boolean isHashCode() {
		List parameterTypeList = getParameterTypeList();
		return getName().equals("hashCode") && getReturnParameter().getType().getClassType().equals("int") && parameterTypeList.size() == 0;
	}

	private boolean isToString() {
		List parameterTypeList = getParameterTypeList();
		return getName().equals("toString") && getReturnParameter().getType().getClassType().equals("String") && parameterTypeList.size() == 0;
	}

	private boolean isClone() {
		List parameterTypeList = getParameterTypeList();
		return getName().equals("clone") && getReturnParameter().getType().getClassType().equals("Object") && parameterTypeList.size() == 0;
	}

	private boolean isCompareTo() {
		List parameterTypeList = getParameterTypeList();
		return getName().equals("compareTo") && getReturnParameter().getType().getClassType().equals("int") && parameterTypeList.size() == 1;
	}

	public boolean compatibleSignature(UMLOperation removedOperation) {
		return equalParameterTypes(removedOperation) || overloadedParameterTypes(removedOperation) || replacedParameterTypes(removedOperation) || equalParameterNames(removedOperation);
	}

	public boolean hasTwoParametersWithTheSameType() {
		List parameterTypes = getParameterTypeList();
		if(parameterTypes.size() == 2) {
			if(parameterTypes.get(0).equals(parameterTypes.get(1))) {
				return true;
			}
		}
		return false;
	}

	public Map> aliasedAttributes() {
		if(operationBody != null && isConstructor) {
			List parameterNames = getParameterNameList();
			Map> map = operationBody.aliasedAttributes();
			Set keysToBeRemoved = new LinkedHashSet();
			for(String key : map.keySet()) {
				if(!parameterNames.contains(key)) {
					keysToBeRemoved.add(key);
				}
			}
			for(String key : keysToBeRemoved) {
				map.remove(key);
			}
			return map;
		}
		return new LinkedHashMap>();
	}

	public CompositeStatementObject loopWithVariables(String currentElementName, String collectionName) {
		if(operationBody != null) {
			return operationBody.loopWithVariables(currentElementName, collectionName);
		}
		return null;
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy