/**
* This file is licensed under the University of Illinois/NCSA Open Source License. See LICENSE.TXT for details.
*/
package edu.illinois.codingtracker.operations.refactorings;
import java.util.HashSet;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.TreeMap;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.ltk.core.refactoring.IUndoManager;
import org.eclipse.ltk.core.refactoring.RefactoringContribution;
import org.eclipse.ltk.core.refactoring.RefactoringCore;
import org.eclipse.ltk.core.refactoring.RefactoringDescriptor;
import org.eclipse.ltk.internal.core.refactoring.history.DefaultRefactoringDescriptor;
import org.eclipse.ltk.internal.core.refactoring.history.RefactoringContributionManager;
import edu.illinois.codingtracker.helpers.Debugger;
import edu.illinois.codingtracker.operations.OperationLexer;
import edu.illinois.codingtracker.operations.OperationTextChunk;
import edu.illinois.codingtracker.operations.UserOperation;
/**
* Concrete implementations of this operation are no longer recorded.
*
* {@see NewStartedRefactoringOperation, FinishedRefactoringOperation}.
*
* @author Stas Negara
*
*/
@SuppressWarnings({ "rawtypes", "restriction" })
public abstract class RefactoringOperation extends UserOperation {
protected static Set<Long> unperformedRefactorings= new HashSet<Long>();
private String id;
private String project;
private int flags;
//TreeMap is required for the deterministic behavior that is expected by the tests
private final Map<String, String> arguments= new TreeMap<String, String>();
public RefactoringOperation() {
super();
}
public RefactoringOperation(RefactoringDescriptor refactoringDescriptor) {
super(refactoringDescriptor.getTimeStamp());
id= refactoringDescriptor.getID();
project= refactoringDescriptor.getProject();
flags= refactoringDescriptor.getFlags();
initializeArguments(getRefactoringArguments(refactoringDescriptor));
}
public String getID() {
return id;
}
public String getProject() {
return project;
}
public int getFlags() {
return flags;
}
/**
* Note that returning a reference to a private collection breaks incapsulation. But considering
* that this is a deprecated class, and this method is used only for its update to the replacing
* class, it should be OK.
*
* @return
*/
public Map<String, String> getArguments() {
return arguments;
}
private Map getRefactoringArguments(RefactoringDescriptor refactoringDescriptor) {
Map arguments= null;
RefactoringContribution refactoringContribution=
RefactoringContributionManager.getInstance().getRefactoringContribution(refactoringDescriptor.getID());
if (refactoringContribution != null)
arguments= refactoringContribution.retrieveArgumentMap(refactoringDescriptor);
else if (refactoringDescriptor instanceof DefaultRefactoringDescriptor)
arguments= ((DefaultRefactoringDescriptor)refactoringDescriptor).getArguments();
return arguments;
}
private void initializeArguments(Map refactoringArguments) {
if (refactoringArguments != null) {
for (Object key : refactoringArguments.keySet()) {
Object value= refactoringArguments.get(key);
arguments.put(key.toString(), value.toString());
}
}
}
protected IUndoManager getRefactoringUndoManager() {
return RefactoringCore.getUndoManager();
}
@Override
protected void populateTextChunk(OperationTextChunk textChunk) {
textChunk.append(id);
textChunk.append(project);
textChunk.append(flags);
textChunk.append(arguments.size());
for (Entry<String, String> argumentEntry : arguments.entrySet()) {
textChunk.append(argumentEntry.getKey());
textChunk.append(argumentEntry.getValue());
}
}
@Override
protected void initializeFrom(OperationLexer operationLexer) {
id= operationLexer.readString();
project= operationLexer.readString();
flags= operationLexer.readInt();
int argumentsCount= operationLexer.readInt();
for (int i= 0; i < argumentsCount; i++) {
arguments.put(operationLexer.readString(), operationLexer.readString());
}
}
@Override
public void replay() throws CoreException {
isReplayedRefactoring= false;
RefactoringContribution refactoringContribution= RefactoringCore.getRefactoringContribution(id);
if (refactoringContribution == null) {
Debugger.debugWarning("Failed to get refactoring contribution for id: " + id);
return;
}
RefactoringDescriptor refactoringDescriptor= refactoringContribution.createDescriptor(id, project.isEmpty() ? null : project, "Recorded refactoring", "", arguments, flags);
replayRefactoring(refactoringDescriptor);
}
@Override
public String toString() {
StringBuffer sb= new StringBuffer();
sb.append("ID: " + id + "\n");
sb.append("Project: " + project + "\n");
sb.append("Flags: " + flags + "\n");
sb.append("Arguments count: " + arguments.size() + "\n");
for (Entry<String, String> argumentEntry : arguments.entrySet()) {
sb.append("Key: " + argumentEntry.getKey() + "\n");
sb.append("Value: " + argumentEntry.getValue() + "\n");
}
sb.append(super.toString());
return sb.toString();
}
protected abstract void replayRefactoring(RefactoringDescriptor refactoringDescriptor) throws CoreException;
}