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

gr.uom.java.xmi.diff.ExtractOperationRefactoring 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.diff;

import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

import org.apache.commons.lang3.tuple.ImmutablePair;
import org.refactoringminer.api.Refactoring;
import org.refactoringminer.api.RefactoringType;

import gr.uom.java.xmi.UMLOperation;
import gr.uom.java.xmi.decomposition.AbstractCodeFragment;
import gr.uom.java.xmi.decomposition.AbstractCodeMapping;
import gr.uom.java.xmi.decomposition.CompositeStatementObject;
import gr.uom.java.xmi.decomposition.OperationInvocation;
import gr.uom.java.xmi.decomposition.StatementObject;
import gr.uom.java.xmi.decomposition.UMLOperationBodyMapper;
import gr.uom.java.xmi.decomposition.replacement.Replacement;

public class ExtractOperationRefactoring implements Refactoring {
	private UMLOperation extractedOperation;
	private UMLOperation sourceOperationBeforeExtraction;
	private UMLOperation sourceOperationAfterExtraction;
	private List extractedOperationInvocations;
	private Set replacements;
	private Set extractedCodeFragmentsFromSourceOperation;
	private Set extractedCodeFragmentsToExtractedOperation;
	private UMLOperationBodyMapper bodyMapper;

	public ExtractOperationRefactoring(UMLOperationBodyMapper bodyMapper, UMLOperation sourceOperationAfterExtraction, List operationInvocations) {
		this.bodyMapper = bodyMapper;
		this.extractedOperation = bodyMapper.getOperation2();
		this.sourceOperationBeforeExtraction = bodyMapper.getOperation1();
		this.sourceOperationAfterExtraction = sourceOperationAfterExtraction;
		this.extractedOperationInvocations = operationInvocations;
		this.replacements = bodyMapper.getReplacements();
		this.extractedCodeFragmentsFromSourceOperation = new LinkedHashSet();
		this.extractedCodeFragmentsToExtractedOperation = new LinkedHashSet();
		for(AbstractCodeMapping mapping : bodyMapper.getMappings()) {
			this.extractedCodeFragmentsFromSourceOperation.add(mapping.getFragment1());
			this.extractedCodeFragmentsToExtractedOperation.add(mapping.getFragment2());
		}
	}

	public ExtractOperationRefactoring(UMLOperationBodyMapper bodyMapper, UMLOperation extractedOperation,
			UMLOperation sourceOperationBeforeExtraction, UMLOperation sourceOperationAfterExtraction, List operationInvocations) {
		this.bodyMapper = bodyMapper;
		this.extractedOperation = extractedOperation;
		this.sourceOperationBeforeExtraction = sourceOperationBeforeExtraction;
		this.sourceOperationAfterExtraction = sourceOperationAfterExtraction;
		this.extractedOperationInvocations = operationInvocations;
		this.replacements = bodyMapper.getReplacements();
		this.extractedCodeFragmentsFromSourceOperation = new LinkedHashSet();
		this.extractedCodeFragmentsToExtractedOperation = new LinkedHashSet();
		for(AbstractCodeMapping mapping : bodyMapper.getMappings()) {
			this.extractedCodeFragmentsFromSourceOperation.add(mapping.getFragment1());
			this.extractedCodeFragmentsToExtractedOperation.add(mapping.getFragment2());
		}
	}

	public String toString() {
		StringBuilder sb = new StringBuilder();
		sb.append(getName()).append("\t");
		sb.append(extractedOperation);
		sb.append(" extracted from ");
		sb.append(sourceOperationBeforeExtraction);
		sb.append(" in class ");
		sb.append(getClassName());
		if(getRefactoringType().equals(RefactoringType.EXTRACT_AND_MOVE_OPERATION)) {
			sb.append(" & moved to class ");
			sb.append(extractedOperation.getClassName());
		}
		return sb.toString();
	}

	private String getClassName() {
		if(getRefactoringType().equals(RefactoringType.EXTRACT_AND_MOVE_OPERATION)) {
			return getSourceOperationBeforeExtraction().getClassName();
		}
		String sourceClassName = getSourceOperationBeforeExtraction().getClassName();
		String targetClassName = getSourceOperationAfterExtraction().getClassName();
		return sourceClassName.equals(targetClassName) ? sourceClassName : targetClassName;
	}

	public UMLOperationBodyMapper getBodyMapper() {
		return bodyMapper;
	}

	public UMLOperation getExtractedOperation() {
		return extractedOperation;
	}

	public UMLOperation getSourceOperationBeforeExtraction() {
		return sourceOperationBeforeExtraction;
	}

	public UMLOperation getSourceOperationAfterExtraction() {
		return sourceOperationAfterExtraction;
	}

	public List getExtractedOperationInvocations() {
		return extractedOperationInvocations;
	}

	public Set getReplacements() {
		return replacements;
	}

	public Set getExtractedCodeFragmentsFromSourceOperation() {
		return extractedCodeFragmentsFromSourceOperation;
	}

	public Set getExtractedCodeFragmentsToExtractedOperation() {
		return extractedCodeFragmentsToExtractedOperation;
	}

	/**
	 * @return the code range of the source method in the parent commit
	 */
	public CodeRange getSourceOperationCodeRangeBeforeExtraction() {
		return sourceOperationBeforeExtraction.codeRange();
	}

	/**
	 * @return the code range of the source method in the child commit
	 */
	public CodeRange getSourceOperationCodeRangeAfterExtraction() {
		return sourceOperationAfterExtraction.codeRange();
	}

	/**
	 * @return the code range of the extracted method in the child commit
	 */
	public CodeRange getExtractedOperationCodeRange() {
		return extractedOperation.codeRange();
	}

	/**
	 * @return the code range of the extracted code fragment from the source method in the parent commit
	 */
	public CodeRange getExtractedCodeRangeFromSourceOperation() {
		return CodeRange.computeRange(extractedCodeFragmentsFromSourceOperation);
	}

	/**
	 * @return the code range of the extracted code fragment to the extracted method in the child commit
	 */
	public CodeRange getExtractedCodeRangeToExtractedOperation() {
		return CodeRange.computeRange(extractedCodeFragmentsToExtractedOperation);
	}

	/**
	 * @return the code range(s) of the invocation(s) to the extracted method inside the source method in the child commit
	 */
	public Set getExtractedOperationInvocationCodeRanges() {
		Set codeRanges = new LinkedHashSet();
		for(OperationInvocation invocation : extractedOperationInvocations) {
			codeRanges.add(invocation.codeRange());
		}
		return codeRanges;
	}

	public String getName() {
		return this.getRefactoringType().getDisplayName();
	}

	public RefactoringType getRefactoringType() {
		if(!getSourceOperationAfterExtraction().getClassName().equals(getExtractedOperation().getClassName()))
			return RefactoringType.EXTRACT_AND_MOVE_OPERATION;
		return RefactoringType.EXTRACT_OPERATION;
	}

	public Set> getInvolvedClassesBeforeRefactoring() {
		Set> pairs = new LinkedHashSet>();
		pairs.add(new ImmutablePair(getSourceOperationBeforeExtraction().getLocationInfo().getFilePath(), getSourceOperationBeforeExtraction().getClassName()));
		return pairs;
	}

	public Set> getInvolvedClassesAfterRefactoring() {
		Set> pairs = new LinkedHashSet>();
		pairs.add(new ImmutablePair(getSourceOperationAfterExtraction().getLocationInfo().getFilePath(), getSourceOperationAfterExtraction().getClassName()));
		pairs.add(new ImmutablePair(getExtractedOperation().getLocationInfo().getFilePath(), getExtractedOperation().getClassName()));
		return pairs;
	}

	@Override
	public List leftSide() {
		List ranges = new ArrayList();
		ranges.add(getSourceOperationCodeRangeBeforeExtraction()
				.setDescription("source method declaration before extraction")
				.setCodeElement(sourceOperationBeforeExtraction.toString()));
		for(AbstractCodeFragment extractedCodeFragment : extractedCodeFragmentsFromSourceOperation) {
			ranges.add(extractedCodeFragment.codeRange().setDescription("extracted code from source method declaration"));
		}
		/*
		CodeRange extractedCodeRangeFromSourceOperation = getExtractedCodeRangeFromSourceOperation();
		ranges.add(extractedCodeRangeFromSourceOperation.setDescription("extracted code from source method declaration"));
		for(StatementObject statement : bodyMapper.getNonMappedLeavesT1()) {
			if(extractedCodeRangeFromSourceOperation.subsumes(statement.codeRange())) {
				ranges.add(statement.codeRange().
						setDescription("deleted statement in source method declaration"));
			}
		}
		for(CompositeStatementObject statement : bodyMapper.getNonMappedInnerNodesT1()) {
			if(extractedCodeRangeFromSourceOperation.subsumes(statement.codeRange()) ||
					extractedCodeRangeFromSourceOperation.subsumes(statement.getLeaves())) {
				ranges.add(statement.codeRange().
						setDescription("deleted statement in source method declaration"));
			}
		}
		*/
		return ranges;
	}

	@Override
	public List rightSide() {
		List ranges = new ArrayList();
		ranges.add(getExtractedOperationCodeRange()
				.setDescription("extracted method declaration")
				.setCodeElement(extractedOperation.toString()));
		//ranges.add(getExtractedCodeRangeToExtractedOperation().setDescription("extracted code to extracted method declaration"));
		for(AbstractCodeFragment extractedCodeFragment : extractedCodeFragmentsToExtractedOperation) {
			ranges.add(extractedCodeFragment.codeRange().setDescription("extracted code to extracted method declaration"));
		}
		ranges.add(getSourceOperationCodeRangeAfterExtraction()
				.setDescription("source method declaration after extraction")
				.setCodeElement(sourceOperationAfterExtraction.toString()));
		for(OperationInvocation invocation : extractedOperationInvocations) {
			ranges.add(invocation.codeRange()
					.setDescription("extracted method invocation")
					.setCodeElement(invocation.actualString()));
		}
		for(StatementObject statement : bodyMapper.getNonMappedLeavesT2()) {
			ranges.add(statement.codeRange().
					setDescription("added statement in extracted method declaration"));
		}
		for(CompositeStatementObject statement : bodyMapper.getNonMappedInnerNodesT2()) {
			ranges.add(statement.codeRange().
					setDescription("added statement in extracted method declaration"));
		}
		return ranges;
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy