package cz.muni.fi.rtc.ISImporter;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.text.DateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;
import au.com.bytecode.opencsv.CSVReader;
import cz.muni.fi.rtc.teacherWorkbench.importer.ImporterConfiguration;
import cz.muni.fi.rtc.teacherWorkbench.importer.PasswordGenerator;
import cz.muni.fi.rtc.teacherWorkbench.importer.PeopleImporter;
import cz.muni.fi.rtc.teacherWorkbench.importer.ProjectImporter;
import cz.muni.fi.rtc.teacherWorkbench.importer.Utils;
import cz.muni.fi.rtc.teacherWorkbench.model.ImportedPerson;
import cz.muni.fi.rtc.teacherWorkbench.model.ImportedPersonImpl;
import cz.muni.fi.rtc.teacherWorkbench.model.Project;
import cz.muni.fi.rtc.teacherWorkbench.model.ProjectImpl;
/**
* Parses the CSV export from "IS MUNI, baliky". The format is given by the
* system. The package names must be unique. This class does not check it.
*
* Czech howto on exporting from the system: V zaznamniku ucitele
* "Export údajů o tématech přihlášených studentů" -> Vybrat pozadovany balik ->
* Typ vystupu: "Formát CSV pro Excel", Kodovani cestiny: "Kódování UTF-8"
*
* @author Jan Stastny
*
*/
public class ISProjectImporter {
private static final int ROW_UCO = 0;
private static final int ROW_FIRST = 3;
private static final int ROW_LAST = 2;
private static final int ROW_PROJECT_NAME = 9;
private static final int ROW_DESCRIPTION = 16;
private static final int ROW_TEACHER_UCO = 11;
private String processTemplate = "cz.muni.fi.pa165.imported.v4";
private String[] studentRoles = {"student_PA165"};
private String[] teacherRoles = {"vyucujici_PA165"};
/**
* Members of the projects. Without teachers
*/
private Map> projectMembers = new HashMap>();
/**
* Project teachers
*/
private Map projectTeachers = new HashMap();
/**
* Main method. 2 arguments expected. First is the path to the csv, second is path to the configuration
* @param args First is the path to the csv, second is path to the configuration
*/
public static void main(String[] args) {
if (args.length < 2) {
System.err.println("Incorrect call!");
System.err
.println("Usage: ISProjectImporter projects.csv conf.properties [1|0]");
System.exit(1);
}
String filename = args[0];
String confPath = args[1];
try {
ImporterConfiguration conf = Utils
.configurationFromProperties(confPath);
ISProjectImporter reader = new ISProjectImporter();
reader.parse(new File(filename));
// Import users if requested
// NOTICE -- this does not import teachers,
// because there is not enough information about them in the CSV export
if(args.length == 3 && args[2].equals("1")) {
PeopleImporter peopleImporter = new PeopleImporter(conf);
Set people = reader.getStudents();
PasswordGenerator.generatePasswordsForPeople(people);
peopleImporter.importUsers(people);
ISPersonImporter.sendEmails(conf, people);
}
ProjectImporter projectImporter = new ProjectImporter(conf);
Set projects = reader.getProjects();
// Import projects
projectImporter.importProjects(projects);
} catch (Exception e) {
e.printStackTrace();
}
}
private void parse(File file) {
CSVReader reader = null;
try {
reader = new CSVReader(new BufferedReader(new InputStreamReader(new FileInputStream(file), "WINDOWS-1250")),
';');
String[] line;
// Ignore first line -- it's header
reader.readNext();
while ((line = reader.readNext()) != null) {
ImportedPersonImpl person = new ImportedPersonImpl();
person.setUID(line[ROW_UCO]);
person.setFirstName(line[ROW_FIRST]);
person.setLastName(line[ROW_LAST]);
String projectName = line[ROW_PROJECT_NAME];
String description = line[ROW_DESCRIPTION];
ISProject isProject = new ISProject(projectName, description);
if (!projectMembers.containsKey(isProject)) {
projectMembers
.put(isProject, new HashSet());
}
projectMembers.get(isProject).add(person);
ImportedPersonImpl teacher = new ImportedPersonImpl();
teacher.setUID(line[ROW_TEACHER_UCO]);
projectTeachers.put(isProject, teacher);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
* Returns the list of the students in this file. Fields filled are:
*
* - UID -- UCO
*
- email -- UCO@mail.muni.cz
*
- first
*
- last
*
- description --
* "Batch imported user by IS Package reader at "
*
- rawPassword -- randomly generated
*
* First name, Last name, Email File has to be parsed first
*
* @return Set of students ready to be imported
*/
public Set getStudents() {
String timestamp = DateFormat.getDateTimeInstance().format(new Date());
String description = "Batch imported user by IS Package reader at "
+ timestamp;
// Speed things up and detect duplicates soon
Set doneUids = new HashSet();
Set result = new HashSet();
for (Entry> entry : projectMembers
.entrySet()) {
for (ImportedPerson p : entry.getValue()) {
if (!doneUids.contains(p.getUID())) {
ImportedPersonImpl pers = (ImportedPersonImpl) p;
pers.setDescription(description);
pers.setEmailAddress(pers.getUID() + "@mail.muni.cz");
result.add(pers);
}
}
}
return result;
}
/**
* Returns instances of project based on the imported file
*
* @return Set of projects ready to be put in the RTC
*/
public Set getProjects() {
Set result = new HashSet();
for (Entry> entry : projectMembers
.entrySet()) {
ProjectImpl project = new ProjectImpl();
String name = entry.getKey().name;
// Slash is not valid
name = name.replace('/', ' ');
project.setName(name);
project.setSummary("");
// Too long
//project.setSummary(entry.getKey().description);
// The longest description is left blank
project.setDescription("");
project.setMembers(entry.getValue());
// Set roles of the students
for (ImportedPerson student : entry.getValue()) {
for(String role: studentRoles) {
project.addRoleOfUser(student, role);
}
}
// Set role of the teacher
ImportedPerson teacher = projectTeachers.get(entry.getKey());
// Add teacher
project.addMember(teacher);
for(String role : teacherRoles) {
project.addRoleOfUser(teacher, role);
}
// Put teacher of the project to the root
project.addRootMember(teacher);
// Set the process template
project.setProcessTemplate(processTemplate);
result.add(project);
}
return result;
}
/**
* Dumb entity class for parsing
*
* @author Jan Stastny
*
*/
private class ISProject {
public String name;
@SuppressWarnings("unused")
public String description;
public ISProject(String name, String description) {
super();
this.name = name;
this.description = description;
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + getOuterType().hashCode();
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (!(obj instanceof ISProject)) {
return false;
}
ISProject other = (ISProject) obj;
if (!getOuterType().equals(other.getOuterType())) {
return false;
}
if (name == null) {
if (other.name != null) {
return false;
}
} else if (!name.equals(other.name)) {
return false;
}
return true;
}
@Override
public String toString() {
return name;
}
private ISProjectImporter getOuterType() {
return ISProjectImporter.this;
}
}
}