gr.uom.java.xmi.UMLAbstractClass Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of refactoring-miner Show documentation
Show all versions of refactoring-miner Show documentation
RefactoringMiner is a library/API written in Java that can detect refactorings applied in the history of a Java project.
package gr.uom.java.xmi;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import org.refactoringminer.util.PrefixSuffixUtils;
import gr.uom.java.xmi.diff.CodeRange;
import gr.uom.java.xmi.diff.RenamePattern;
import gr.uom.java.xmi.diff.StringDistance;
public abstract class UMLAbstractClass {
protected LocationInfo locationInfo;
protected String packageName;
protected String name;
protected List operations;
protected List attributes;
public UMLAbstractClass() {
this.operations = new ArrayList();
this.attributes = new ArrayList();
}
public LocationInfo getLocationInfo() {
return locationInfo;
}
public void addOperation(UMLOperation operation) {
this.operations.add(operation);
}
public void addAttribute(UMLAttribute attribute) {
this.attributes.add(attribute);
}
public List getOperations() {
return operations;
}
public List getAttributes() {
return attributes;
}
public UMLOperation operationWithTheSameSignature(UMLOperation operation) {
for(UMLOperation originalOperation : operations) {
if(originalOperation.equalSignature(operation))
return originalOperation;
}
return null;
}
public boolean containsOperationWithTheSameSignature(UMLOperation operation) {
for(UMLOperation originalOperation : operations) {
if(originalOperation.equalSignature(operation))
return true;
}
return false;
}
public UMLOperation operationWithTheSameSignatureIgnoringChangedTypes(UMLOperation operation) {
List matchingOperations = new ArrayList();
for(UMLOperation originalOperation : operations) {
boolean matchesOperation = isInterface() ?
originalOperation.equalSignatureIgnoringChangedTypes(operation) :
originalOperation.equalSignatureWithIdenticalNameIgnoringChangedTypes(operation);
if(matchesOperation) {
boolean originalOperationEmptyBody = originalOperation.getBody() == null || originalOperation.hasEmptyBody();
boolean operationEmptyBody = operation.getBody() == null || operation.hasEmptyBody();
if(originalOperationEmptyBody == operationEmptyBody)
matchingOperations.add(originalOperation);
}
}
if(matchingOperations.size() == 1) {
return matchingOperations.get(0);
}
else if(matchingOperations.size() > 1) {
int minDistance = StringDistance.editDistance(matchingOperations.get(0).toString(), operation.toString());
UMLOperation matchingOperation = matchingOperations.get(0);
for(int i=1; i commonOperations = new LinkedHashSet();
int totalOperations = 0;
for(UMLOperation operation : operations) {
if(!operation.isConstructor() && !operation.overridesObject()) {
totalOperations++;
if(umlClass.containsOperationWithTheSameName(operation)) {
commonOperations.add(operation);
}
}
}
for(UMLOperation operation : umlClass.operations) {
if(!operation.isConstructor() && !operation.overridesObject()) {
totalOperations++;
if(this.containsOperationWithTheSameName(operation)) {
commonOperations.add(operation);
}
}
}
Set commonAttributes = new LinkedHashSet();
int totalAttributes = 0;
for(UMLAttribute attribute : attributes) {
totalAttributes++;
if(umlClass.containsAttributeWithTheSameName(attribute)) {
commonAttributes.add(attribute);
}
}
for(UMLAttribute attribute : umlClass.attributes) {
totalAttributes++;
if(this.containsAttributeWithTheSameName(attribute)) {
commonAttributes.add(attribute);
}
}
if(this.isTestClass() && umlClass.isTestClass()) {
return commonOperations.size() > Math.floor(totalOperations/2.0) || commonOperations.containsAll(this.operations);
}
if(this.isSingleAbstractMethodInterface() && umlClass.isSingleAbstractMethodInterface()) {
return commonOperations.size() == totalOperations;
}
return (commonOperations.size() >= Math.floor(totalOperations/2.0) && (commonAttributes.size() > 2 || totalAttributes == 0)) ||
(commonAttributes.size() >= Math.floor(totalAttributes/2.0) && (commonOperations.size() > 2 || totalOperations == 0)) ||
(commonOperations.size() == totalOperations && commonOperations.size() > 2 && this.attributes.size() == umlClass.attributes.size()) ||
(commonOperations.size() == totalOperations && commonOperations.size() > 2 && totalAttributes == 1);
}
public boolean hasCommonAttributesAndOperations(UMLAbstractClass umlClass) {
String commonPrefix = PrefixSuffixUtils.longestCommonPrefix(this.name, umlClass.name);
String commonSuffix = PrefixSuffixUtils.longestCommonSuffix(this.name, umlClass.name);
RenamePattern pattern = null;
if(!commonPrefix.isEmpty() && !commonSuffix.isEmpty()) {
int beginIndexS1 = this.name.indexOf(commonPrefix) + commonPrefix.length();
int endIndexS1 = this.name.lastIndexOf(commonSuffix);
String diff1 = beginIndexS1 > endIndexS1 ? "" : this.name.substring(beginIndexS1, endIndexS1);
int beginIndexS2 = umlClass.name.indexOf(commonPrefix) + commonPrefix.length();
int endIndexS2 = umlClass.name.lastIndexOf(commonSuffix);
String diff2 = beginIndexS2 > endIndexS2 ? "" : umlClass.name.substring(beginIndexS2, endIndexS2);
pattern = new RenamePattern(diff1, diff2);
}
Set commonOperations = new LinkedHashSet();
int totalOperations = 0;
for(UMLOperation operation : operations) {
if(!operation.isConstructor() && !operation.overridesObject()) {
totalOperations++;
if(umlClass.containsOperationWithTheSameSignatureIgnoringChangedTypes(operation) ||
(pattern != null && umlClass.containsOperationWithTheSameRenamePattern(operation, pattern.reverse()))) {
commonOperations.add(operation);
}
}
}
for(UMLOperation operation : umlClass.operations) {
if(!operation.isConstructor() && !operation.overridesObject()) {
totalOperations++;
if(this.containsOperationWithTheSameSignatureIgnoringChangedTypes(operation) ||
(pattern != null && this.containsOperationWithTheSameRenamePattern(operation, pattern))) {
commonOperations.add(operation);
}
}
}
Set commonAttributes = new LinkedHashSet();
int totalAttributes = 0;
for(UMLAttribute attribute : attributes) {
totalAttributes++;
if(umlClass.containsAttributeWithTheSameNameIgnoringChangedType(attribute) ||
(pattern != null && umlClass.containsAttributeWithTheSameRenamePattern(attribute, pattern.reverse()))) {
commonAttributes.add(attribute);
}
}
for(UMLAttribute attribute : umlClass.attributes) {
totalAttributes++;
if(this.containsAttributeWithTheSameNameIgnoringChangedType(attribute) ||
(pattern != null && this.containsAttributeWithTheSameRenamePattern(attribute, pattern))) {
commonAttributes.add(attribute);
}
}
if(this.isTestClass() && umlClass.isTestClass()) {
return commonOperations.size() > Math.floor(totalOperations/2.0) || commonOperations.containsAll(this.operations);
}
if(this.isSingleAbstractMethodInterface() && umlClass.isSingleAbstractMethodInterface()) {
return commonOperations.size() == totalOperations;
}
return (commonOperations.size() > Math.floor(totalOperations/2.0) && (commonAttributes.size() > 2 || totalAttributes == 0)) ||
(commonOperations.size() > Math.floor(totalOperations/3.0*2.0) && (commonAttributes.size() >= 2 || totalAttributes == 0)) ||
(commonAttributes.size() > Math.floor(totalAttributes/2.0) && (commonOperations.size() > 2 || totalOperations == 0)) ||
(commonOperations.size() == totalOperations && commonOperations.size() > 2 && this.attributes.size() == umlClass.attributes.size()) ||
(commonOperations.size() == totalOperations && commonOperations.size() > 2 && totalAttributes == 1);
}
public boolean hasSameAttributesAndOperations(UMLAbstractClass umlClass) {
if(this.attributes.size() != umlClass.attributes.size())
return false;
if(this.operations.size() != umlClass.operations.size())
return false;
for(UMLOperation operation : operations) {
if(!umlClass.containsOperationWithTheSameSignatureIgnoringChangedTypes(operation)) {
return false;
}
}
for(UMLOperation operation : umlClass.operations) {
if(!this.containsOperationWithTheSameSignatureIgnoringChangedTypes(operation)) {
return false;
}
}
for(UMLAttribute attribute : attributes) {
if(!umlClass.containsAttributeWithTheSameNameIgnoringChangedType(attribute)) {
return false;
}
}
for(UMLAttribute attribute : umlClass.attributes) {
if(!this.containsAttributeWithTheSameNameIgnoringChangedType(attribute)) {
return false;
}
}
return true;
}
public boolean isTestClass() {
for(UMLOperation operation : operations) {
if(operation.hasTestAnnotation()) {
return true;
}
}
return false;
}
public List attributesOfType(String targetClass) {
List attributesOfType = new ArrayList();
for(UMLAttribute attribute : attributes) {
if(targetClass.endsWith("." + attribute.getType().getClassType()) ||
targetClass.equals(attribute.getType().getClassType())) {
attributesOfType.add(attribute);
}
}
return attributesOfType;
}
public abstract boolean isSingleAbstractMethodInterface();
public abstract boolean isInterface();
public String getSourceFile() {
return locationInfo.getFilePath();
}
public CodeRange codeRange() {
return locationInfo.codeRange();
}
}