/**
* This file is licensed under the University of Illinois/NCSA Open Source License. See LICENSE.TXT for details.
*/
package edu.illinois.codingspectator.logstocsv;
import java.util.Date;
import java.util.Iterator;
import java.util.Map;
import org.eclipse.ltk.core.refactoring.codingspectator.NavigationHistory;
import org.eclipse.ltk.core.refactoring.codingspectator.NavigationHistory.ParseException;
import org.eclipse.ltk.core.refactoring.codingspectator.NavigationHistoryItem;
import edu.illinois.codingspectator.refactorings.parser.CapturedRefactoringDescriptor;
import edu.illinois.codingspectator.refactorings.parser.RefactoringLog.LogType;
/**
*
* @author Mohsen Vakilian
* @author nchen
*
*/
public class RefactoringEvent extends Event {
private CapturedRefactoringDescriptor capturedRefactoringDescriptor;
private LogType refactoringKind;
public RefactoringEvent(CapturedRefactoringDescriptor capturedRefactoringDescriptor, String username, String workspaceID, String codingspectatorVersion, LogType refactoringKind) {
super(username, workspaceID, codingspectatorVersion);
this.capturedRefactoringDescriptor= capturedRefactoringDescriptor;
this.refactoringKind= refactoringKind;
}
@Override
@SuppressWarnings("unchecked")
public Map<String, String> toMap() {
Map<String, String> map= super.toMap();
String comment= capturedRefactoringDescriptor.getComment();
map.put("comment", truncateString(comment));
map.put("description", capturedRefactoringDescriptor.getDescription());
map.put("flags", String.valueOf(capturedRefactoringDescriptor.getFlags()));
map.put("id", getRefactoringID());
map.put("project", capturedRefactoringDescriptor.getProject());
map.put("timestamp", String.valueOf(getTimestamp()));
Date timestampDate= new Date(getTimestamp());
map.put("human-readable timestamp", timestampDate.toString());
map.putAll(capturedRefactoringDescriptor.getArguments());
switch (getRefactoringKind()) {
case ECLIPSE:
map.put("refactoring kind", "PERFORMED");
map.put("recorder", "ECLIPSE");
break;
case PERFORMED:
map.put("refactoring kind", "PERFORMED");
map.put("recorder", "CODINGSPECTATOR");
break;
case CANCELLED:
map.put("refactoring kind", "CANCELLED");
map.put("recorder", "CODINGSPECTATOR");
break;
case UNAVAILABLE:
map.put("refactoring kind", "UNAVAILABLE");
map.put("recorder", "CODINGSPECTATOR");
break;
default:
break;
}
map.put("severity level", String.valueOf(getSeverityLevel(capturedRefactoringDescriptor.getAttribute("status"))));
map.put("navigation duration", getNavigationDurationString(capturedRefactoringDescriptor.getAttribute("navigation-history")));
if (capturedRefactoringDescriptor.getCodeSnippet() != null && capturedRefactoringDescriptor.getSelectionInCodeSnippet() != null) {
map.put("code-snippet-with-selection-markers", getCodesnippetWithSelectionMarkers());
}
return map;
}
public String getRefactoringID() {
return capturedRefactoringDescriptor.getID();
}
private String truncateString(String comment) {
if (comment.length() == 0)
return "";
int maxLength= comment.length() > ATTRIBUTE_LENGTH_LIMIT ? ATTRIBUTE_LENGTH_LIMIT : comment.length();
return comment.substring(0, maxLength);
}
@Override
public long getTimestamp() {
return capturedRefactoringDescriptor.getTimestamp();
}
public LogType getRefactoringKind() {
return refactoringKind;
}
/**
*
* @param status
* @return
*/
private int getSeverityLevel(String status) {
if (status == null) {
return 0;
}
if (status.startsWith("<OK")) {
return 1;
} else if (status.startsWith("<INFO")) {
return 2;
} else if (status.startsWith("<WARNING")) {
return 3;
} else if (status.startsWith("<ERROR")) {
return 4;
} else if (status.startsWith("<FATALERROR")) {
return 5;
}
return 6;
}
private String getNavigationDurationString(String navigationHistoryString) {
if (navigationHistoryString == null) {
return "";
} else {
long navigationDuration;
try {
navigationDuration= getNavigationDuration(navigationHistoryString);
} catch (ParseException e) {
System.err.println(e.getMessage());
return "";
}
return String.valueOf(navigationDuration);
}
}
private boolean hasNavigationDuration(String navigationHistoryString) throws ParseException {
NavigationHistory navigationHistory= NavigationHistory.parse(navigationHistoryString);
int numberOfNavigationHistoryItems= navigationHistory.getNavigationHistoryItems().size();
return numberOfNavigationHistoryItems >= 2;
}
private long getNavigationDuration(String navigationHistoryString) throws NavigationHistory.ParseException {
if (!hasNavigationDuration(navigationHistoryString)) {
throw new NavigationHistory.ParseException("Expected at least two items in the navigation history (" + navigationHistoryString + ") of a " + getRefactoringKind() + " "
+ getRefactoringID() + " refactoring, which was " + (capturedRefactoringDescriptor.isInvokedByQuickAssist() ? "" : "not ")
+ "invoked by Quick Assist (username=" + username + ", workspace ID=" + workspaceID + ", CodingSpectator version=" + codingspectatorVersion + ", timestamp=" + getTimestamp()
+ ").");
}
NavigationHistory navigationHistory= NavigationHistory.parse(navigationHistoryString);
@SuppressWarnings("rawtypes")
Iterator iterator= navigationHistory.getNavigationHistoryItems().iterator();
NavigationHistoryItem currentNavigationHistoryItem= (NavigationHistoryItem)iterator.next();
long firstTimestamp= currentNavigationHistoryItem.getTimestamp();
while (iterator.hasNext()) {
currentNavigationHistoryItem= (NavigationHistoryItem)iterator.next();
}
long lastTimestamp= currentNavigationHistoryItem.getTimestamp();
return lastTimestamp - firstTimestamp;
}
private String getCodesnippetWithSelectionMarkers() {
String codeSnippet= capturedRefactoringDescriptor.getCodeSnippet();
String selectionInCodeSnippet= capturedRefactoringDescriptor.getSelectionInCodeSnippet();
int selectionBeginningOffset= Integer.valueOf(selectionInCodeSnippet.split(" ")[0]);
int selectionLength= Integer.valueOf(selectionInCodeSnippet.split(" ")[1]);
String selectionStartMarker= "/* CODINGSPECTATOR: SELECTION BEGINS */";
String selectionEndMarker= "/* CODINGSPECTATOR: SELECTION ENDS */";
String codeSnippetWithSelectionMarkers= codeSnippet.substring(0, selectionBeginningOffset) + selectionStartMarker
+ codeSnippet.subSequence(selectionBeginningOffset, selectionBeginningOffset + selectionLength) + selectionEndMarker
+ codeSnippet.substring(selectionBeginningOffset + selectionLength);
return codeSnippetWithSelectionMarkers;
}
}