/**
* File ./src/main/java/de/lemo/dms/connectors/moodle_2_3/ExtractAndMap.java
* Lemo-Data-Management-Server for learning analytics.
* Copyright (C) 2013
* Leonard Kappe, Andreas Pursian, Sebastian Schwarzrock, Boris Wenzlaff
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
**/
/**
* File ./main/java/de/lemo/dms/connectors/moodle_2_3/ExtractAndMap.java
* Date 2013-01-24
* Project Lemo Learning Analytics
*/
package de.lemo.dms.connectors.moodle_2_3;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.log4j.Logger;
import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.criterion.ProjectionList;
import org.hibernate.criterion.Projections;
import de.lemo.dms.connectors.IConnector;
import de.lemo.dms.core.Clock;
import de.lemo.dms.core.config.ServerConfiguration;
import de.lemo.dms.db.DBConfigObject;
import de.lemo.dms.db.EQueryType;
import de.lemo.dms.db.IDBHandler;
import de.lemo.dms.db.mapping.AssignmentLogMining;
import de.lemo.dms.db.mapping.AssignmentMining;
import de.lemo.dms.db.mapping.ChatLogMining;
import de.lemo.dms.db.mapping.ChatMining;
import de.lemo.dms.db.mapping.ConfigMining;
import de.lemo.dms.db.mapping.CourseAssignmentMining;
import de.lemo.dms.db.mapping.CourseChatMining;
import de.lemo.dms.db.mapping.CourseForumMining;
import de.lemo.dms.db.mapping.CourseGroupMining;
import de.lemo.dms.db.mapping.CourseLogMining;
import de.lemo.dms.db.mapping.CourseMining;
import de.lemo.dms.db.mapping.CourseQuizMining;
import de.lemo.dms.db.mapping.CourseResourceMining;
import de.lemo.dms.db.mapping.CourseScormMining;
import de.lemo.dms.db.mapping.CourseUserMining;
import de.lemo.dms.db.mapping.CourseWikiMining;
import de.lemo.dms.db.mapping.ForumLogMining;
import de.lemo.dms.db.mapping.ForumMining;
import de.lemo.dms.db.mapping.GroupMining;
import de.lemo.dms.db.mapping.GroupUserMining;
import de.lemo.dms.db.mapping.LevelAssociationMining;
import de.lemo.dms.db.mapping.LevelCourseMining;
import de.lemo.dms.db.mapping.LevelMining;
import de.lemo.dms.db.mapping.PlatformMining;
import de.lemo.dms.db.mapping.QuestionLogMining;
import de.lemo.dms.db.mapping.QuestionMining;
import de.lemo.dms.db.mapping.QuizLogMining;
import de.lemo.dms.db.mapping.QuizMining;
import de.lemo.dms.db.mapping.QuizQuestionMining;
import de.lemo.dms.db.mapping.QuizUserMining;
import de.lemo.dms.db.mapping.ResourceLogMining;
import de.lemo.dms.db.mapping.ResourceMining;
import de.lemo.dms.db.mapping.RoleMining;
import de.lemo.dms.db.mapping.ScormLogMining;
import de.lemo.dms.db.mapping.ScormMining;
import de.lemo.dms.db.mapping.UserMining;
import de.lemo.dms.db.mapping.WikiLogMining;
import de.lemo.dms.db.mapping.WikiMining;
/**
* The main class of the extraction process.
* Inherit from this class to make an extract class for a specific LMS.
* Contains bundle of fields as container for LMS objects,
* which are used for linking the tables.
*/
public abstract class ExtractAndMap {
// lists of object tables which are new found in LMS DB
/** A List of new entries in the course table found in this run of the process. */
protected Map<Long, CourseMining> courseMining;
protected Map<Long, PlatformMining> platformMining;
/** A List of new entries in the quiz table found in this run of the process. */
protected Map<Long, QuizMining> quizMining;
/** A List of new entries in the assignment table found in this run of the process. */
protected Map<Long, AssignmentMining> assignmentMining;
/** A List of new entries in the assignment table found in this run of the process. */
protected Map<Long, ScormMining> scormMining;
/** A List of new entries in the forum table found in this run of the process. */
protected Map<Long, ForumMining> forumMining;
/** A List of new entries in the resource table found in this run of the process. */
protected Map<Long, ResourceMining> resourceMining;
/** A List of new entries in the user table found in this run of the process. */
protected Map<Long, UserMining> userMining;
/** A List of new entries in the wiki table found in this run of the process. */
protected Map<Long, WikiMining> wikiMining;
/** A List of new entries in the group table found in this run of the process. */
protected Map<Long, GroupMining> groupMining;
/** A List of entries in the new question table found in this run of the process. */
protected Map<Long, QuestionMining> questionMining;
/** A List of entries in the new question table found in this run of the process. */
protected Map<Long, QuizQuestionMining> quizQuestionMining;
/** A List of entries in the new level table found in this run of the process. */
protected Map<Long, LevelMining> levelMining;
protected Map<Long, CourseQuizMining> courseQuizMining;
/** A List of entries in the new role table found in this run of the process. */
protected Map<Long, RoleMining> roleMining;
/** The chat_mining. */
protected Map<Long, ChatMining> chatMining;
/** The chat_log_mining. */
protected Map<Long, ChatLogMining> chatLogMining;
protected Map<Long, PlatformMining> oldPlatformMining;
// lists of object tables which are already in the mining DB
/** A List of entries in the course table, needed for linking reasons in the process. */
protected Map<Long, CourseMining> oldCourseMining;
/** A List of entries in the quiz table, needed for linking reasons in the process. */
protected Map<Long, QuizMining> oldQuizMining;
/** A List of entries in the assignment table, needed for linking reasons in the process. */
protected Map<Long, AssignmentMining> oldAssignmentMining;
/** A List of entries in the scorm table, needed for linking reasons in the process. */
protected Map<Long, ScormMining> oldScormMining;
/** A List of entries in the forum table, needed for linking reasons in the process. */
protected Map<Long, ForumMining> oldForumMining;
/** A List of entries in the resource table, needed for linking reasons in the process. */
protected Map<Long, ResourceMining> oldResourceMining;
/** A List of entries in the user table, needed for linking reasons in the process. */
protected Map<Long, UserMining> oldUserMining;
/** A List of entries in the wiki table, needed for linking reasons in the process. */
protected Map<Long, WikiMining> oldWikiMining;
/** A List of entries in the group table, needed for linking reasons in the process. */
protected Map<Long, GroupMining> oldGroupMining;
/** A List of entries in the question table, needed for linking reasons in the process. */
protected Map<Long, QuestionMining> oldQuestionMining;
/** A List of entries in the role table, needed for linking reasons in the process. */
protected Map<Long, RoleMining> oldRoleMining;
/** The old_level_mining. */
protected Map<Long, LevelMining> oldLevelMining;
/** A List of entries in the quiz_question table, needed for linking reasons in the process. */
protected Map<Long, QuizQuestionMining> oldQuizQuestionMining;
/** A List of entries in the course_quiz table, needed for linking reasons in the process. */
protected Map<Long, CourseQuizMining> oldCourseQuizMining;
/** The old_chat_mining. */
protected Map<Long, ChatMining> oldChatMining;
/** The old_chat_log_mining. */
protected Map<Long, ChatLogMining> oldChatLogMining;
/** A list of objects used for submitting them to the DB. */
List<Collection<?>> updates;
/** A list of timestamps of the previous runs of the extractor. */
List<Timestamp> configMiningTimestamp;
/** Designates which entries should be read from the LMS Database during the process. */
private long starttime;
/** Database-handler **/
IDBHandler dbHandler;
private final Logger logger = Logger.getLogger(this.getClass());
private final IConnector connector;
Long questionLogMax;
public ExtractAndMap(final IConnector connector) {
this.connector = connector;
}
protected Long courseLogMax;
protected Long assignmentLogMax;
protected Long forumLogMax;
protected Long quizLogMax;
protected Long scormLogMax;
protected Long wikiLogMax;
protected Long chatLogMax;
protected Long resourceLogMax;
protected Long courseChatMax;
protected Long maxLog = 0L;
private Clock c;
/**
* Starts the extraction process by calling getLMS_tables() and saveMining_tables().
* A timestamp can be given as optional argument.
* When the argument is used the extraction begins after that timestamp.
* When no argument is given the program starts with the timestamp of the last run.
*
* @param args
* Optional arguments for the process. Used for the selection of the ExtractAndMap Implementation and
* timestamp when the extraction should start.
**/
public void start(final String[] args, final DBConfigObject sourceDBConf, List<Long> courses, List<String> logins) {
this.dbHandler = ServerConfiguration.getInstance().getMiningDbHandler();
this.c = new Clock();
this.starttime = System.currentTimeMillis() / 1000;
final Session session = this.dbHandler.getMiningSession();
// get the status of the mining DB; load timestamp of last update and objects needed for associations
long readingtimestamp = this.getMiningInitial();
this.dbHandler.saveToDB(session, new PlatformMining(this.connector.getPlatformId(), this.connector.getName(),
this.connector.getPlattformType().toString(), this.connector.getPrefix()));
logger.info("Initialized database in " + this.c.getAndReset());
// default call without parameter
if (args.length == 1)
{
// get the needed tables from LMS DB
this.c.reset();
this.getLMStables(sourceDBConf, readingtimestamp, courses, logins);
logger.info("Loaded data from source in " + this.c.getAndReset());
// create and write the mining database tables
this.saveMiningTables();
}
// call with parameter timestamp
else {
if (args[1].matches("[0-9]+"))
{
readingtimestamp = Long.parseLong(args[1]);
long readingtimestamp2 = Long.parseLong(args[1]) + 172800;
final long currenttimestamp = this.starttime;
this.logger.info("starttime:" + currenttimestamp);
this.logger.info("parameter:" + readingtimestamp);
// first read & save LMS DB tables from 0 to starttime for timestamps which are not set(which are 0)
if (this.configMiningTimestamp.get(0) == null) {
this.c.reset();
this.getLMStables(sourceDBConf, 0, readingtimestamp, courses, logins);
logger.info("Loaded data from source in " + this.c.getAndReset());
// create and write the mining database tables
this.saveMiningTables();
}
// read & save LMS DB in steps of 2 days
for (long looptimestamp = readingtimestamp - 1; looptimestamp < currenttimestamp;)
{
this.logger.info("looptimestamp:" + looptimestamp);
this.c.reset();
this.getLMStables(sourceDBConf, looptimestamp + 1, readingtimestamp2, courses, logins);
logger.info("Loaded data from source in " + this.c.getAndReset());
looptimestamp += 172800;
readingtimestamp2 += 172800;
this.logger.info("currenttimestamp:" + currenttimestamp);
this.saveMiningTables();
}
}
else {
// Fehlermeldung Datenformat
this.logger.info("wrong data format in parameter:" + args[1]);
}
}
// calculate running time of extract process
final long endtime = System.currentTimeMillis() / 1000;
final ConfigMining config = new ConfigMining();
config.setLastModifiedLong(System.currentTimeMillis());
config.setElapsedTime((endtime) - (this.starttime));
config.setDatabaseModel("1.3");
config.setPlatform(this.connector.getPlatformId());
config.setLatestTimestamp(maxLog);
this.dbHandler.saveToDB(session, config);
this.logger.info("Elapsed time: " + (endtime - this.starttime) + "s");
this.dbHandler.closeSession(session);
}
/**
* Reads the Mining Database.
* Initial informations needed to start the process of updating are collected here.
* The Timestamp of the last run of the extractor is read from the config table
* and the objects which might been needed to associate are read and saved here.
*
* @return The timestamp of the last run of the extractor. If this is the first run it will be set 0.
**/
public long getMiningInitial() {
final Session session = this.dbHandler.getMiningSession();
List<?> t;
Long readingtimestamp;
readingtimestamp = (Long) session.createQuery("Select max(latestTimestamp) from ConfigMining where platform=" + this.connector.getPlatformId()).uniqueResult();
if(readingtimestamp == null)
{
readingtimestamp = -1L;
}
// load objects which are already in Mining DB for associations
t = this.dbHandler.performQuery(session, EQueryType.HQL, "from CourseMining x where x.platform="
+ this.connector.getPlatformId() + " order by x.id asc");
this.oldCourseMining = new HashMap<Long, CourseMining>();
for (int i = 0; i < t.size(); i++) {
this.oldCourseMining.put(((CourseMining) (t.get(i))).getId(), (CourseMining) t.get(i));
}
logger.info("Loaded " + this.oldCourseMining.size() + " CourseMining objects from the mining database.");
t = this.dbHandler.performQuery(session, EQueryType.HQL,
"from QuizMining x where x.platform=" + this.connector.getPlatformId() + " order by x.id asc");
this.oldQuizMining = new HashMap<Long, QuizMining>();
for (int i = 0; i < t.size(); i++) {
this.oldQuizMining.put(((QuizMining) (t.get(i))).getId(), (QuizMining) t.get(i));
}
logger.info("Loaded " + this.oldQuizMining.size() + " QuizMining objects from the mining database.");
t = this.dbHandler.performQuery(session, EQueryType.HQL, "from AssignmentMining x where x.platform="
+ this.connector.getPlatformId() + " order by x.id asc");
this.oldAssignmentMining = new HashMap<Long, AssignmentMining>();
for (int i = 0; i < t.size(); i++) {
this.oldAssignmentMining.put(((AssignmentMining) (t.get(i))).getId(), (AssignmentMining) t.get(i));
}
logger.info("Loaded " + this.oldAssignmentMining.size()
+ " AssignmentMining objects from the mining database.");
t = this.dbHandler.performQuery(session, EQueryType.HQL, "from ScormMining x where x.platform="
+ this.connector.getPlatformId() + " order by x.id asc");
this.oldScormMining = new HashMap<Long, ScormMining>();
for (int i = 0; i < t.size(); i++) {
this.oldScormMining.put(((ScormMining) (t.get(i))).getId(), (ScormMining) t.get(i));
}
logger.info("Loaded " + this.oldScormMining.size() + " ScormMining objects from the mining database.");
t = this.dbHandler.performQuery(session, EQueryType.HQL, "from ForumMining x where x.platform="
+ this.connector.getPlatformId() + " order by x.id asc");
this.oldForumMining = new HashMap<Long, ForumMining>();
for (int i = 0; i < t.size(); i++) {
this.oldForumMining.put(((ForumMining) (t.get(i))).getId(), (ForumMining) t.get(i));
}
logger.info("Loaded " + this.oldForumMining.size() + " ForumMining objects from the mining database.");
t = this.dbHandler.performQuery(session, EQueryType.HQL, "from ResourceMining x where x.platform="
+ this.connector.getPlatformId() + " order by x.id asc");
this.oldResourceMining = new HashMap<Long, ResourceMining>();
for (int i = 0; i < t.size(); i++) {
this.oldResourceMining.put(((ResourceMining) (t.get(i))).getId(), (ResourceMining) t.get(i));
}
logger.info("Loaded " + this.oldResourceMining.size()
+ " ResourceMining objects from the mining database.");
t = this.dbHandler.performQuery(session, EQueryType.HQL,
"from UserMining x where x.platform=" + this.connector.getPlatformId() + " order by x.id asc");
this.oldUserMining = new HashMap<Long, UserMining>();
for (int i = 0; i < t.size(); i++) {
this.oldUserMining.put(((UserMining) (t.get(i))).getId(), (UserMining) t.get(i));
}
logger.info("Loaded " + this.oldUserMining.size() + " UserMining objects from the mining database.");
t = this.dbHandler.performQuery(session, EQueryType.HQL,
"from WikiMining x where x.platform=" + this.connector.getPlatformId() + " order by x.id asc");
this.oldWikiMining = new HashMap<Long, WikiMining>();
for (int i = 0; i < t.size(); i++) {
this.oldWikiMining.put(((WikiMining) (t.get(i))).getId(), (WikiMining) t.get(i));
}
logger.info("Loaded " + this.oldWikiMining.size() + " WikiMining objects from the mining database.");
t = this.dbHandler.performQuery(session, EQueryType.HQL, "from GroupMining x where x.platform="
+ this.connector.getPlatformId() + " order by x.id asc");
this.oldGroupMining = new HashMap<Long, GroupMining>();
for (int i = 0; i < t.size(); i++) {
this.oldGroupMining.put(((GroupMining) (t.get(i))).getId(), (GroupMining) t.get(i));
}
logger.info("Loaded " + this.oldGroupMining.size() + " GroupMining objects from the mining database.");
t = this.dbHandler.performQuery(session, EQueryType.HQL, "from QuestionMining x where x.platform="
+ this.connector.getPlatformId() + " order by x.id asc");
this.oldQuestionMining = new HashMap<Long, QuestionMining>();
for (int i = 0; i < t.size(); i++) {
this.oldQuestionMining.put(((QuestionMining) (t.get(i))).getId(), (QuestionMining) t.get(i));
}
logger.info("Loaded " + this.oldQuizMining.size() + " QuestionMining objects from the mining database.");
t = this.dbHandler.performQuery(session, EQueryType.HQL,
"from RoleMining x where x.platform=" + this.connector.getPlatformId() + " order by x.id asc");
this.oldRoleMining = new HashMap<Long, RoleMining>();
for (int i = 0; i < t.size(); i++) {
this.oldRoleMining.put(((RoleMining) (t.get(i))).getId(), (RoleMining) t.get(i));
}
logger.info("Loaded " + this.oldRoleMining.size() + " RoleMining objects from the mining database.");
t = this.dbHandler.performQuery(session, EQueryType.HQL, "from QuizQuestionMining x where x.platform="
+ this.connector.getPlatformId() + " order by x.id asc");
this.oldQuizQuestionMining = new HashMap<Long, QuizQuestionMining>();
for (int i = 0; i < t.size(); i++) {
this.oldQuizQuestionMining.put(((QuizQuestionMining) (t.get(i))).getQuestion().getId(),
(QuizQuestionMining) t.get(i));
}
logger.info("Loaded " + this.oldQuizQuestionMining.size()
+ " QuizQuestionMining objects from the mining database.");
t = this.dbHandler.performQuery(session, EQueryType.HQL, "from LevelMining x where x.platform="
+ this.connector.getPlatformId() + " order by x.id asc");
this.oldLevelMining = new HashMap<Long, LevelMining>();
for (int i = 0; i < t.size(); i++) {
this.oldLevelMining.put(((LevelMining) (t.get(i))).getId(), (LevelMining) t.get(i));
}
logger.info("Loaded " + this.oldLevelMining.size() + " LevelMining objects from the mining database.");
t = this.dbHandler.performQuery(session, EQueryType.HQL,
"from ChatMining x where x.platform=" + this.connector.getPlatformId() + " order by x.id asc");
this.oldChatMining = new HashMap<Long, ChatMining>();
for (int i = 0; i < t.size(); i++) {
this.oldChatMining.put(((ChatMining) (t.get(i))).getId(), (ChatMining) t.get(i));
}
logger.info("Loaded " + this.oldChatMining.size() + " ChatMining objects from the mining database.");
t = this.dbHandler.performQuery(session, EQueryType.HQL,
"from ChatMining x where x.platform=" + this.connector.getPlatformId() + " order by x.id asc");
this.oldChatMining = new HashMap<Long, ChatMining>();
for (int i = 0; i < t.size(); i++) {
this.oldChatMining.put(((ChatMining) (t.get(i))).getId(), (ChatMining) t.get(i));
}
logger.info("Loaded " + this.oldChatMining.size() + " ChatMining objects from the mining database.");
Criteria criteria = session.createCriteria(ResourceLogMining.class);
ProjectionList pl = Projections.projectionList();
pl.add(Projections.max("id"));
criteria.setProjection(pl);
this.resourceLogMax = (Long) criteria.list().get(0);
if (this.resourceLogMax == null) {
this.resourceLogMax = 0L;
}
criteria = session.createCriteria(CourseChatMining.class);
criteria.setProjection(pl);
this.courseChatMax = (Long) criteria.list().get(0);
if (this.courseChatMax == null) {
this.courseChatMax = 0L;
}
criteria = session.createCriteria(ChatLogMining.class);
criteria.setProjection(pl);
this.chatLogMax = (Long) criteria.list().get(0);
if (this.chatLogMax == null) {
this.chatLogMax = 0L;
}
criteria = session.createCriteria(AssignmentLogMining.class);
criteria.setProjection(pl);
this.assignmentLogMax = (Long) criteria.list().get(0);
if (this.assignmentLogMax == null) {
this.assignmentLogMax = 0L;
}
criteria = session.createCriteria(CourseLogMining.class);
criteria.setProjection(pl);
this.courseLogMax = (Long) criteria.list().get(0);
if (this.courseLogMax == null) {
this.courseLogMax = 0L;
}
criteria = session.createCriteria(ForumLogMining.class);
criteria.setProjection(pl);
this.forumLogMax = (Long) criteria.list().get(0);
if (this.forumLogMax == null) {
this.forumLogMax = 0L;
}
criteria = session.createCriteria(QuestionLogMining.class);
criteria.setProjection(pl);
this.questionLogMax = (Long) criteria.list().get(0);
if (this.questionLogMax == null) {
this.questionLogMax = 0L;
}
criteria = session.createCriteria(QuizLogMining.class);
criteria.setProjection(pl);
this.quizLogMax = (Long) criteria.list().get(0);
if (this.quizLogMax == null) {
this.quizLogMax = 0L;
}
criteria = session.createCriteria(ScormLogMining.class);
criteria.setProjection(pl);
this.scormLogMax = (Long) criteria.list().get(0);
if (this.scormLogMax == null) {
this.scormLogMax = 0L;
}
criteria = session.createCriteria(WikiLogMining.class);
criteria.setProjection(pl);
this.wikiLogMax = (Long) criteria.list().get(0);
if (this.wikiLogMax == null) {
this.wikiLogMax = 0L;
}
//this.dbHandler.closeSession(session);
return readingtimestamp;
}
/**
* Has to read the LMS Database.
* It starts reading elements with timestamp readingtimestamp and higher.
* It is supposed to be used for frequently and small updates.
* For a greater Mass of Data it is suggested to use getLMS_tables(long, long);
* If Hibernate is used to access the LMS DB too,
* it is suggested to write the found tables into lists of
* hibernate object model classes, which have to
* be created as global variables in this class.
* So they can be used in the generate methods of this class.
*
* @param readingfromtimestamp
* Only elements with timestamp readingtimestamp and higher are read here.
* *
* @return the lM stables
*/
public abstract void getLMStables(DBConfigObject dbConf, long readingfromtimestamp, List<Long> courses, List<String> logins);
/**
* Has to read the LMS Database.
* It reads elements with timestamp between readingfromtimestamp and readingtotimestamp.
* This method is used to read great DB in a step by step procedure.
* That is necessary for a great mass of Data when handeling an existing DB for example.
* If Hibernate is used to access the LMS DB too,
* it is suggested to write the found tables into lists of
* hibernate object model classes, which have to
* be created as global variables in this class.
* So they can be used in the generate methods of this class.
*
* @param readingfromtimestamp
* Only elements with timestamp readingfromtimestamp and higher are read here.
* @param readingtotimestamp
* Only elements with timestamp readingtotimestamp and lower are read here.
* *
* @return the lM stables
*/
public abstract void getLMStables(DBConfigObject dbConf, long readingfromtimestamp, long readingtotimestamp, List<Long> courses, List<String> logins);
/**
* Has to clear the lists of LMS tables*.
*/
public abstract void clearLMStables();
/**
* Clears the lists of mining tables.
**/
public void clearMiningTables() {
this.courseMining.clear();
this.quizMining.clear();
this.assignmentMining.clear();
this.scormMining.clear();
this.forumMining.clear();
this.resourceMining.clear();
this.userMining.clear();
this.wikiMining.clear();
this.groupMining.clear();
this.questionMining.clear();
this.roleMining.clear();
this.chatMining.clear();
this.chatMining.clear();
this.levelMining.clear();
}
/**
* Only for successive readings. This is meant to be done, when the gathered mining data has already
* been saved and before the mining tables are cleared for the next iteration.
*/
public void prepareMiningData()
{
this.oldCourseMining.putAll(this.courseMining);
this.oldQuizMining.putAll(this.quizMining);
this.oldAssignmentMining.putAll(this.assignmentMining);
this.oldScormMining.putAll(this.scormMining);
this.oldForumMining.putAll(this.forumMining);
this.oldResourceMining.putAll(this.resourceMining);
this.oldUserMining.putAll(this.userMining);
this.oldWikiMining.putAll(this.wikiMining);
this.oldGroupMining.putAll(this.groupMining);
this.oldQuestionMining.putAll(this.questionMining);
this.oldRoleMining.putAll(this.roleMining);
this.oldChatMining.putAll(this.chatMining);
this.oldQuizQuestionMining.putAll(this.quizQuestionMining);
this.oldCourseQuizMining.putAll(this.courseQuizMining);
this.oldLevelMining.putAll(this.levelMining);
}
/**
* Generates and save the new tables for the mining DB.
* We call the genereate-methods for each mining table to get the new entries.
* At last we create a Transaction and save the new entries to the DB.
**/
public void saveMiningTables() {
// generate & save new mining tables
this.updates = new ArrayList<Collection<?>>();
Long objects = 0L;
// generate mining tables
if (this.userMining == null) {
this.c.reset();
logger.info("\nObject tables:\n");
this.assignmentMining = this.generateAssignmentMining();
objects += this.assignmentMining.size();
logger.info("Generated " + this.assignmentMining.size() + " AssignmentMining entries in "
+ this.c.getAndReset() + " s. ");
this.updates.add(this.assignmentMining.values());
// Screwing up the alphabetical order, CourseMinings have to be calculated BEFORE ChatMinings due to the
// temporal foreign key "course" in ChatMining
this.courseMining = this.generateCourseMining();
objects += this.courseMining.size();
logger.info("Generated " + this.courseMining.size() + " CourseMining entries in "
+ this.c.getAndReset() + " s. ");
this.updates.add(this.courseMining.values());
this.chatMining = this.generateChatMining();
objects += this.chatMining.size();
this.updates.add(this.chatMining.values());
logger.info("Generated " + this.chatMining.size() + " ChatMining entries in " + this.c.getAndReset()
+ " s. ");
this.levelMining = this.generateLevelMining();
objects += this.levelMining.size();
logger.info("Generated " + this.levelMining.size() + " LevelMining entries in "
+ this.c.getAndReset() + " s. ");
this.updates.add(this.levelMining.values());
this.forumMining = this.generateForumMining();
objects += this.forumMining.size();
logger.info("Generated " + this.forumMining.size() + " ForumMining entries in "
+ this.c.getAndReset() + " s. ");
this.updates.add(this.forumMining.values());
this.groupMining = this.generateGroupMining();
objects += this.groupMining.size();
logger.info("Generated " + this.groupMining.size() + " GroupMining entries in "
+ this.c.getAndReset() + " s. ");
this.updates.add(this.groupMining.values());
this.questionMining = this.generateQuestionMining();
objects += this.questionMining.size();
logger.info("Generated " + this.questionMining.size() + " QuestionMining entries in "
+ this.c.getAndReset() + " s. ");
this.updates.add(this.questionMining.values());
this.quizMining = this.generateQuizMining();
objects += this.quizMining.size();
this.updates.add(this.quizMining.values());
logger.info("Generated " + this.quizMining.size() + " QuizMining entries in " + this.c.getAndReset()
+ " s. ");
this.resourceMining = this.generateResourceMining();
objects += this.resourceMining.size();
logger.info("Generated " + this.resourceMining.size() + " ResourceMining entries in "
+ this.c.getAndReset() + " s. ");
this.updates.add(this.resourceMining.values());
this.roleMining = this.generateRoleMining();
objects += this.roleMining.size();
logger.info("Generated " + this.roleMining.size() + " RoleMining entries in " + this.c.getAndReset()
+ " s. ");
this.updates.add(this.roleMining.values());
this.scormMining = this.generateScormMining();
objects += this.scormMining.size();
logger.info("Generated " + this.scormMining.size() + " ScormMining entries in "
+ this.c.getAndReset() + " s. ");
this.updates.add(this.scormMining.values());
this.userMining = this.generateUserMining();
objects += this.userMining.size();
logger.info("Generated " + this.userMining.size() + " UserMining entries in " + this.c.getAndReset()
+ " s. ");
this.updates.add(this.userMining.values());
this.wikiMining = this.generateWikiMining();
objects += this.wikiMining.size();
logger.info("Generated " + this.wikiMining.size() + " WikiMining entries in " + this.c.getAndReset()
+ " s. ");
this.updates.add(this.wikiMining.values());
this.updates.add(this.generateCourseAssignmentMining().values());
objects += this.updates.get(this.updates.size() - 1).size();
logger.info("Generated " + this.updates.get(this.updates.size() - 1).size()
+ " CourseAssignmentMining entries in " + this.c.getAndReset() + " s. ");
this.updates.add(this.generateCourseScormMining().values());
objects += this.updates.get(this.updates.size() - 1).size();
logger.info("Generated " + this.updates.get(this.updates.size() - 1).size()
+ " CourseScormMining entries in " + this.c.getAndReset() + " s. ");
this.updates.add(this.generateCourseChatMining().values());
objects += this.updates.get(this.updates.size() - 1).size();
logger.info("Generated " + this.updates.get(this.updates.size() - 1).size()
+ " CourseChatMining entries in " + this.c.getAndReset() + " s. ");
this.updates.add(this.generateLevelCourseMining().values());
objects += this.updates.get(this.updates.size() - 1).size();
logger.info("Generated " + this.updates.get(this.updates.size() - 1).size()
+ " LevelCourseMining entries in " + this.c.getAndReset() + " s. ");
this.updates.add(this.generateLevelAssociationMining().values());
objects += this.updates.get(this.updates.size() - 1).size();
logger.info("Generated " + this.updates.get(this.updates.size() - 1).size()
+ " LevelAssociationMining entries in " + this.c.getAndReset() + " s. ");
this.quizQuestionMining = this.generateQuizQuestionMining();
objects += this.quizQuestionMining.size();
logger.info("Generated " + this.quizQuestionMining.size() + " QuizQuestionMining entries in "
+ this.c.getAndReset() + " s. ");
this.updates.add(this.quizQuestionMining.values());
logger.info("\nAssociation tables:\n");
this.updates.add(this.generateCourseForumMining().values());
objects += this.updates.get(this.updates.size() - 1).size();
logger.info("Generated " + this.updates.get(this.updates.size() - 1).size()
+ " CourseForumMining entries in " + this.c.getAndReset() + " s. ");
this.updates.add(this.generateCourseGroupMining().values());
objects += this.updates.get(this.updates.size() - 1).size();
logger.info("Generated " + this.updates.get(this.updates.size() - 1).size()
+ " CourseGroupMining entries in " + this.c.getAndReset() + " s. ");
this.courseQuizMining = this.generateCourseQuizMining();
objects += this.courseQuizMining.size();
logger.info("Generated " + this.courseQuizMining.size() + " CourseQuizMining entries in "
+ this.c.getAndReset() + " s. ");
this.updates.add(this.courseQuizMining.values());
this.updates.add(this.generateCourseResourceMining().values());
objects += this.updates.get(this.updates.size() - 1).size();
logger.info("Generated " + this.updates.get(this.updates.size() - 1).size()
+ " CourseResourceMining entries in " + this.c.getAndReset() + " s. ");
this.updates.add(this.generateCourseWikiMining().values());
objects += this.updates.get(this.updates.size() - 1).size();
logger.info("Generated " + this.updates.get(this.updates.size() - 1).size()
+ " CourseWikiMining entries in " + this.c.getAndReset() + " s. ");
}
this.updates.add(this.generateCourseUserMining().values());
objects += this.updates.get(this.updates.size() - 1).size();
logger.info("Generated " + this.updates.get(this.updates.size() - 1).size()
+ " CourseUserMining entries in " + this.c.getAndReset() + " s. ");
this.updates.add(this.generateGroupUserMining().values());
objects += this.updates.get(this.updates.size() - 1).size();
logger.info("Generated " + this.updates.get(this.updates.size() - 1).size()
+ " GroupUserMining entries in " + this.c.getAndReset() + " s. ");
this.updates.add(this.generateQuizUserMining().values());
objects += this.updates.get(this.updates.size() - 1).size();
logger.info("Generated " + this.updates.get(this.updates.size() - 1).size()
+ " QuizUserMining entries in " + this.c.getAndReset() + " s. ");
logger.info("\nLog tables:\n");
this.updates.add(this.generateAssignmentLogMining().values());
objects += this.updates.get(this.updates.size() - 1).size();
logger.info("Generated " + this.updates.get(this.updates.size() - 1).size()
+ " AssignmentLogMining entries in " + this.c.getAndReset() + " s. ");
this.updates.add(this.generateChatLogMining().values());
objects += this.updates.get(this.updates.size() - 1).size();
logger.info("Generated " + this.updates.get(this.updates.size() - 1).size()
+ " ChatLogMining entries in " + this.c.getAndReset() + " s. ");
this.updates.add(this.generateCourseLogMining().values());
objects += this.updates.get(this.updates.size() - 1).size();
logger.info("Generated " + this.updates.get(this.updates.size() - 1).size()
+ " CourseLogMining entries in " + this.c.getAndReset() + " s. ");
this.updates.add(this.generateForumLogMining().values());
objects += this.updates.get(this.updates.size() - 1).size();
logger.info("Generated " + this.updates.get(this.updates.size() - 1).size()
+ " ForumLogMining entries in " + this.c.getAndReset() + " s. ");
this.updates.add(this.generateQuestionLogMining().values());
objects += this.updates.get(this.updates.size() - 1).size();
logger.info("Generated " + this.updates.get(this.updates.size() - 1).size()
+ " QuestionLogMining entries in " + this.c.getAndReset() + " s. ");
this.updates.add(this.generateQuizLogMining().values());
objects += this.updates.get(this.updates.size() - 1).size();
logger.info("Generated " + this.updates.get(this.updates.size() - 1).size()
+ " QuizLogMining entries in " + this.c.getAndReset() + " s. ");
this.updates.add(this.generateResourceLogMining().values());
objects += this.updates.get(this.updates.size() - 1).size();
logger.info("Generated " + this.updates.get(this.updates.size() - 1).size()
+ " ResourceLogMining entries in " + this.c.getAndReset() + " s. ");
this.updates.add(this.generateScormLogMining().values());
objects += this.updates.get(this.updates.size() - 1).size();
logger.info("Generated " + this.updates.get(this.updates.size() - 1).size()
+ " ScormLogMining entries in " + this.c.getAndReset() + " s. ");
this.updates.add(this.generateWikiLogMining().values());
objects += this.updates.get(this.updates.size() - 1).size();
logger.info("Generated " + this.updates.get(this.updates.size() - 1).size()
+ " WikiLogMining entries in " + this.c.getAndReset() + " s. ");
if (objects > 0)
{
final Session session = this.dbHandler.getMiningSession();
logger.info("Writing to DB");
this.dbHandler.saveCollectionToDB(session, this.updates);
}
this.clearLMStables();
this.updates.clear();
}
// methods for create and fill the mining-table instances
/**
* Has to create and fill the course_user table.
* This table describes which user is enrolled in which course in which timesspan.
* The attributes are described in the documentation of the course_user_mining class.
* Please use the getter and setter predefined in the course_user_mining class to fill the tables within this
* method.
*
* @return A list of instances of the course_user table representing class.
**/
abstract Map<Long, CourseUserMining> generateCourseUserMining();
/**
* Has to create and fill the course_forum table.
* This table describes which forum is used in which course.
* The attributes are described in the documentation of the course_forum_mining class.
* Please use the getter and setter predefined in the course_forum_mining class to fill the tables within this
* method.
*
* @return A list of instances of the course_forum table representing class.
**/
abstract Map<Long, CourseForumMining> generateCourseForumMining();
/**
* Has to create and fill the course table.
* This table describes the courses in the LMS.
* The attributes are described in the documentation of the course_mining class.
* Please use the getter and setter predefined in the course_mining class to fill the tables within this method.
*
* @return A list of instances of the course table representing class.
**/
abstract Map<Long, CourseMining> generateCourseMining();
/**
* Has to create and fill the course_group table.
* This table describes which groups are used in which courses.
* The attributes are described in the documentation of the course_group_mining class.
* Please use the getter and setter predefined in the course_group_mining class to fill the tables within this
* method.
*
* @return A list of instances of the course_group table representing class.
**/
abstract Map<Long, CourseGroupMining> generateCourseGroupMining();
/**
* Has to create and fill the course_quiz table.
* This table describes which quiz are used in which courses.
* The attributes are described in the documentation of the course_quiz_mining class.
* Please use the getter and setter predefined in the course_quiz_mining class to fill the tables within this
* method.
*
* @return A list of instances of the course_quiz table representing class.
**/
abstract Map<Long, CourseQuizMining> generateCourseQuizMining();
/**
* Has to create and fill the course_assignment table.
* This table describes which assignment are used in which courses.
* The attributes are described in the documentation of the course_assignment_mining class.
* Please use the getter and setter predefined in the course_assignment_mining class to fill the tables within this
* method.
*
* @return A list of instances of the course_assignment table representing class.
**/
abstract Map<Long, CourseAssignmentMining> generateCourseAssignmentMining();
/**
* Has to create and fill the course_scorm table.
* This table describes which scorm packages are used in which courses.
* The attributes are described in the documentation of the course_scorm_mining class.
* Please use the getter and setter predefined in the course_scorm_mining class to fill the tables within this
* method.
*
* @return A list of instances of the course_scorm table representing class.
**/
abstract Map<Long, CourseScormMining> generateCourseScormMining();
/**
* Has to create and fill the course_resource table.
* This table describes which resources are used in which courses.
* The attributes are described in the documentation of the course_resource_mining class.
* Please use the getter and setter predefined in the course_resource_mining class to fill the tables within this
* method.
*
* @return A list of instances of the course_resource table representing class.
**/
abstract Map<Long, CourseResourceMining> generateCourseResourceMining();
/**
* Has to create and fill the course_log table.
* This table contains the actions which are done on courses.
* The attributes are described in the documentation of the course_log_mining class.
* Please use the getter and setter predefined in the course_log_mining class to fill the tables within this method.
*
* @return A list of instances of the course_log table representing class.
**/
abstract Map<Long, CourseLogMining> generateCourseLogMining();
/**
* Has to create and fill the course_wiki table.
* This table describes which wikis are used in which courses.
* The attributes are described in the documentation of the course_wiki_mining class.
* Please use the getter and setter predefined in the course_wiki_mining class to fill the tables within this
* method.
*
* @return A list of instances of the course_wiki table representing class.
**/
abstract Map<Long, CourseWikiMining> generateCourseWikiMining();
/**
* Has to create and fill the course_chat table.
* This table describes which chats are used in which courses.
* The attributes are described in the documentation of the course_chat_mining class.
* Please use the getter and setter predefined in the course_chat_mining class to fill the tables within this
* method.
*
* @return A list of instances of the course_wiki table representing class.
**/
abstract Map<Long, CourseChatMining> generateCourseChatMining();
/**
* Has to create and fill the forum_log table.
* This table contains the actions which are done on forums.
* The attributes are described in the documentation of the forum_log_mining class.
* Please use the getter and setter predefined in the forum_log_mining class to fill the tables within this method.
*
* @return A list of instances of the forum_log table representing class.
**/
abstract Map<Long, ForumLogMining> generateForumLogMining();
/**
* Has to create and fill the forum table.
* This table describes the forums in the LMS.
* The attributes are described in the documentation of the forum_mining class.
* Please use the getter and setter predefined in the forum_mining class to fill the tables within this method.
*
* @return A list of instances of the forum table representing class.
**/
abstract Map<Long, ForumMining> generateForumMining();
/**
* Has to create and fill the group_user table.
* This table describes which user are in which groups.
* The attributes are described in the documentation of the group_user_mining class.
* Please use the getter and setter predefined in the group_user_mining class to fill the tables within this method.
*
* @return A list of instances of the group_user table representing class.
**/
abstract Map<Long, GroupUserMining> generateGroupUserMining();
/**
* Has to create and fill the group table.
* This table describes the groups in the LMS.
* The attributes are described in the documentation of the group_mining class.
* Please use the getter and setter predefined in the group_mining class to fill the tables within this method.
*
* @return A list of instances of the group table representing class.
**/
abstract Map<Long, GroupMining> generateGroupMining();
/**
* Has to create and fill the question_log table.
* This table contains the actions which are done on questions.
* The attributes are described in the documentation of the question_log_mining class.
* Please use the getter and setter predefined in the question_log_mining class to fill the tables within this
* method.
*
* @return A list of instances of the question_log table representing class.
**/
abstract Map<Long, QuestionLogMining> generateQuestionLogMining();
/**
* Has to create and fill the quiz_log table.
* This table contains the actions which are done on quiz.
* The attributes are described in the documentation of the quiz_log_mining class.
* Please use the getter and setter predefined in the quiz_log_mining class to fill the tables within this method.
*
* @return A list of instances of the quiz_log table representing class.
**/
abstract Map<Long, QuizLogMining> generateQuizLogMining();
/**
* Has to create and fill the assignment_log table.
* This table contains the actions which are done on assignment.
* The attributes are described in the documentation of the assignment_log_mining class.
* Please use the getter and setter predefined in the assignment_log_mining class to fill the tables within this
* method.
*
* @return A list of instances of the assignment_log table representing class.
**/
abstract Map<Long, AssignmentLogMining> generateAssignmentLogMining();
/**
* Has to create and fill the scorm_log table.
* This table contains the actions which are done on scorm.
* The attributes are described in the documentation of the scorm_log_mining class.
* Please use the getter and setter predefined in the scorm_log_mining class to fill the tables within this method.
*
* @return A list of instances of the scorm_log table representing class.
**/
abstract Map<Long, ScormLogMining> generateScormLogMining();
/**
* Has to create and fill the quiz_user table.
* This table describes which user gets which grade in which quiz.
* The attributes are described in the documentation of the quiz_user_mining class.
* Please use the getter and setter predefined in the quiz_user_mining class to fill the tables within this method.
*
* @return A list of instances of the quiz_user table representing class.
**/
abstract Map<Long, QuizUserMining> generateQuizUserMining();
/**
* Has to create and fill the quiz table.
* This table describes the quiz in the LMS.
* The attributes are described in the documentation of the quiz_mining class.
* Please use the getter and setter predefined in the quiz_mining class to fill the tables within this method.
*
* @return A list of instances of the quiz table representing class.
**/
abstract Map<Long, QuizMining> generateQuizMining();
/**
* Has to create and fill the assignment table.
* This table describes the assignment in the LMS.
* The attributes are described in the documentation of the assignment_mining class.
* Please use the getter and setter predefined in the assignment_mining class to fill the tables within this method.
*
* @return A list of instances of the assignment table representing class.
**/
abstract Map<Long, AssignmentMining> generateAssignmentMining();
/**
* Has to create and fill the scorm table.
* This table describes the scorm packages in the LMS.
* The attributes are described in the documentation of the scorm_mining class.
* Please use the getter and setter predefined in the scorm_mining class to fill the tables within this method.
*
* @return A list of instances of the scorm table representing class.
**/
abstract Map<Long, ScormMining> generateScormMining();
/**
* Has to create and fill the quiz_question table.
* This table describes which question is used in which quiz.
* The attributes are described in the documentation of the quiz_question_mining class.
* Please use the getter and setter predefined in the quiz_question_mining class to fill the tables within this
* method.
*
* @return A list of instances of the quiz_question table representing class.
**/
abstract Map<Long, QuizQuestionMining> generateQuizQuestionMining();
/**
* Has to create and fill the question table.
* This table describes the question in the LMS.
* The attributes are described in the documentation of the question_mining class.
* Please use the getter and setter predefined in the question_mining class to fill the tables within this method.
*
* @return A list of instances of the question table representing class.
**/
abstract Map<Long, QuestionMining> generateQuestionMining();
/**
* Has to create and fill the resource table.
* This table describes the resource in the LMS.
* The attributes are described in the documentation of the resource_mining class.
* Please use the getter and setter predefined in the resource_mining class to fill the tables within this method.
*
* @return A list of instances of the resource table representing class.
**/
abstract Map<Long, ResourceMining> generateResourceMining();
/**
* Has to create and fill the resource_log table.
* This table contains the actions which are done on resource.
* The attributes are described in the documentation of the resource_log_mining class.
* Please use the getter and setter predefined in the resource_log_mining class to fill the tables within this
* method.
*
* @return A list of instances of the resource_log table representing class.
**/
abstract Map<Long, ResourceLogMining> generateResourceLogMining();
/**
* Has to create and fill the user table.
* This table describes the user in the LMS.
* The attributes are described in the documentation of the user_mining class.
* Please use the getter and setter predefined in the user_mining class to fill the tables within this method.
*
* @return A list of instances of the user table representing class.
**/
abstract Map<Long, UserMining> generateUserMining();
/**
* Has to create and fill the wiki_log table.
* This table contains the actions which are done on wiki.
* The attributes are described in the documentation of the wiki_log_mining class.
* Please use the getter and setter predefined in the wiki_log_mining class to fill the tables within this method.
*
* @return A list of instances of the wiki_log table representing class.
**/
abstract Map<Long, WikiLogMining> generateWikiLogMining();
/**
* Has to create and fill the wiki table.
* This table describes the wiki in the LMS.
* The attributes are described in the documentation of the wiki_mining class.
* Please use the getter and setter predefined in the wiki_mining class to fill the tables within this method.
*
* @return A list of instances of the wiki table representing class.
**/
abstract Map<Long, WikiMining> generateWikiMining();
/**
* Has to create and fill the role table.
* This table describes the roles of users in the LMS.
* The attributes are described in the documentation of the role_mining class.
* Please use the getter and setter predefined in the role_mining class to fill the tables within this method.
*
* @return A list of instances of the role table representing class.
**/
abstract Map<Long, RoleMining> generateRoleMining();
/**
* Generate chat mining.
*
* @return the list
*/
abstract Map<Long, ChatMining> generateChatMining();
/**
* Generate chat log mining.
*
* @return the list
*/
abstract Map<Long, ChatLogMining> generateChatLogMining();
/**
* Generate level mining.
*
* @return the list
*/
abstract Map<Long, LevelMining> generateLevelMining();
/**
* Generate level association mining.
*
* @return the list
*/
abstract Map<Long, LevelAssociationMining> generateLevelAssociationMining();
/**
* Generate level course mining.
*
* @return the list
*/
abstract Map<Long, LevelCourseMining> generateLevelCourseMining();
}