/**
* 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.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.regex.Pattern;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import edu.illinois.codingspectator.efs.EFSFile;
import edu.illinois.codingspectator.refactorings.parser.CapturedRefactoringDescriptor;
import edu.illinois.codingspectator.refactorings.parser.RefactoringLog;
import edu.illinois.codingspectator.refactorings.parser.RefactoringLog.LogType;
import edu.illinois.codingtracker.helpers.ResourceHelper;
import edu.illinois.codingtracker.operations.OperationDeserializer;
import edu.illinois.codingtracker.operations.UserOperation;
/**
* @author Mohsen Vakilian
*
*/
public class CodingSpectatorDataExtractor {
private EFSFile rootDataFolder;
public CodingSpectatorDataExtractor(EFSFile rootDataFolder) {
this.rootDataFolder= rootDataFolder;
}
public Collection<Event> extractData() throws CoreException {
Collection<Event> operations= new ArrayList<Event>();
for (EFSFile usernameFolder : usersUnderStudy()) {
for (EFSFile workspaceFolder : CodingSpectatorDataExtractor.childrenExceptSVNFolders(usernameFolder)) {
for (EFSFile versionFolder : CodingSpectatorDataExtractor.versionsUnderStudy(workspaceFolder)) {
String username= usernameFolder.getPath().lastSegment();
String workspaceID= workspaceFolder.getPath().lastSegment();
IPath codingSpectatorVersionPath= versionFolder.getPath();
String codingspectatorVersion= codingSpectatorVersionPath.lastSegment();
IPath codingspectatorRefactoringsPath= codingSpectatorVersionPath.append("refactorings");
operations.addAll(CodingSpectatorDataExtractor.getRefactoringDescriptors(codingSpectatorVersionPath, LogType.ECLIPSE, username, workspaceID, codingspectatorVersion));
operations.addAll(CodingSpectatorDataExtractor.getRefactoringDescriptors(codingspectatorRefactoringsPath, LogType.CANCELLED, username, workspaceID, codingspectatorVersion));
operations.addAll(CodingSpectatorDataExtractor.getRefactoringDescriptors(codingspectatorRefactoringsPath, LogType.PERFORMED, username, workspaceID, codingspectatorVersion));
operations.addAll(CodingSpectatorDataExtractor.getRefactoringDescriptors(codingspectatorRefactoringsPath, LogType.UNAVAILABLE, username, workspaceID, codingspectatorVersion));
IPath codingtrackerPath= codingSpectatorVersionPath.append("codingtracker").append("codechanges.txt");
if (new EFSFile(codingtrackerPath).exists()) {
operations.addAll(CodingSpectatorDataExtractor.getUserOperations(codingtrackerPath, username, workspaceID, codingspectatorVersion));
} else {
System.err.println(String.format("CodingTracker's log at \"%s\" is missing.", codingtrackerPath.toOSString()));
}
}
}
}
return operations;
}
private List<EFSFile> usersUnderStudy() throws CoreException {
List<String> fileNames= rootDataFolder.childNames();
List<EFSFile> filteredFiles= new ArrayList<EFSFile>();
// String regex= "cs-\\d\\d\\d";
String regex= "cs-.*";
Pattern userUnderStudyPattern= Pattern.compile(regex);
for (String fileName : fileNames) {
if (userUnderStudyPattern.matcher(fileName).matches())
filteredFiles.add(rootDataFolder.append(fileName));
}
return filteredFiles;
}
private static Collection<Event> getUserOperations(IPath codingtrackerPath, String username, String workspaceID, String codingspectatorVersion) {
String operationsRecord= ResourceHelper.readFileContent(codingtrackerPath.toFile());
Collection<UserOperation> userOperations= new ArrayList<UserOperation>();
try {
userOperations= OperationDeserializer.getUserOperations(operationsRecord);
} catch (RuntimeException e) {
System.err.println(String.format("Failed to parse CodingTracker's log at \"%s\".", codingtrackerPath.toOSString()));
}
return CodingSpectatorDataExtractor.toUserOperationEvents(username, workspaceID, codingspectatorVersion, userOperations);
}
private static Collection<Event> toUserOperationEvents(String username, String workspaceID, String codingspectatorVersion, Collection<UserOperation> userOperations) {
Collection<Event> userOperationsWrapper= new ArrayList<Event>();
for (UserOperation userOperation : userOperations) {
UserOperationEvent userOperationMapWrapper= new UserOperationEvent(userOperation, username, workspaceID, codingspectatorVersion);
if (userOperationMapWrapper.shouldBeIncludedInCSV())
userOperationsWrapper.add(userOperationMapWrapper);
}
return userOperationsWrapper;
}
private static Collection<RefactoringEvent> getRefactoringDescriptors(IPath codingspectatorRefactoringsPath, LogType type, String username,
String workspaceID, String codingspectatorVersion) throws CoreException {
String refactoringHistoryFolder= type == LogType.ECLIPSE ? "eclipse-refactorings" : RefactoringLog.toString(type);
RefactoringLog refactoringLog= new RefactoringLog(codingspectatorRefactoringsPath.append(refactoringHistoryFolder));
Collection<CapturedRefactoringDescriptor> refactoringDescriptors= refactoringLog.getRefactoringDescriptors();
return CodingSpectatorDataExtractor.toRefactoringEvents(refactoringDescriptors, username, workspaceID, codingspectatorVersion, type);
}
static Collection<RefactoringEvent> toRefactoringEvents(Collection<CapturedRefactoringDescriptor> capturedRefactoringDescriptors, String username,
String workspaceID, String codingspectatorVersion, LogType refactoringKind) {
Collection<RefactoringEvent> refactoringEvents= new ArrayList<RefactoringEvent>();
for (CapturedRefactoringDescriptor capturedRefactoringDescriptor : capturedRefactoringDescriptors) {
refactoringEvents.add(new RefactoringEvent(capturedRefactoringDescriptor, username, workspaceID, codingspectatorVersion, refactoringKind));
}
return refactoringEvents;
}
private static List<EFSFile> versionsUnderStudy(EFSFile parentFolder) throws CoreException {
List<String> fileNames= new ArrayList<String>(parentFolder.childNames());
List<EFSFile> filteredFiles= new ArrayList<EFSFile>();
String match= ".svn";
fileNames.removeAll(Arrays.asList(match));
for (String fileName : fileNames) {
boolean hasValidVersionNumber= Pattern.compile("\\d\\.\\d\\.\\d\\.\\d*").matcher(fileName).matches();
//FIXME: See issue #244.
// boolean isNotTooOld= fileName.compareTo("1.0.0.201105300951") >= 0;
boolean isNotTooOld= true;
if (fileName.equals("1.0.0.qualifier") || (hasValidVersionNumber && isNotTooOld)) {
filteredFiles.add(parentFolder.append(fileName));
}
}
return filteredFiles;
}
private static List<EFSFile> childrenExceptSVNFolders(EFSFile parentFolder) throws CoreException {
List<String> fileNames= new ArrayList<String>(parentFolder.childNames());
List<EFSFile> filteredFiles= new ArrayList<EFSFile>();
String match= ".svn";
fileNames.removeAll(Arrays.asList(match));
for (String fileName : fileNames) {
filteredFiles.add(parentFolder.append(fileName));
}
return filteredFiles;
}
}