/** * File ./src/main/java/de/lemo/dms/processing/questions/QCourseActivity.java * Lemo-Data-Management-Server for learning analytics. * Copyright (C) 2015 * 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/processing/questions/QCourseActivity.java * Date 2013-01-24 * Project Lemo Learning Analytics */ package de.lemo.dms.processing.questions; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import javax.ws.rs.FormParam; import javax.ws.rs.POST; import javax.ws.rs.Path; import org.hibernate.Criteria; import org.hibernate.Session; import org.hibernate.criterion.Restrictions; import de.lemo.dms.core.config.ServerConfiguration; import de.lemo.dms.db.IDBHandler; import de.lemo.dms.db.mapping.abstractions.ILog; import de.lemo.dms.processing.MetaParam; import de.lemo.dms.processing.Question; import de.lemo.dms.processing.StudentHelper; import de.lemo.dms.processing.resulttype.ResultListHashMapObject; import de.lemo.dms.processing.resulttype.ResultListLongObject; /** * Shows to the activities in the courses by objects * * @author Leonard Kappe * @author Sebastian Schwarzrock */ @Path("courseactivity") public class QCourseActivity extends Question { /** * Returns a list with the length of 'resolution'. Each entry holds the number of requests in the interval. * * @param courses * (Mandatory) Course-identifiers of the courses that should be processed. * @param roles * (Optional) Role-identifiers * @param startTime * (Mandatory) * @param endTime * (Mandatory) * @param resolution * (Mandatory) * @param resourceTypes * (Optional) * @return */ @POST public ResultListHashMapObject compute( @FormParam(MetaParam.COURSE_IDS) final List<Long> courses, @FormParam(MetaParam.USER_IDS) List<Long> users, @FormParam(MetaParam.START_TIME) final Long startTime, @FormParam(MetaParam.END_TIME) final Long endTime, @FormParam(MetaParam.RESOLUTION) final Long resolution, @FormParam(MetaParam.TYPES) final List<String> resourceTypes, @FormParam(MetaParam.GENDER) List<Long> gender, @FormParam(MetaParam.LEARNING_OBJ_IDS) List<Long> learningObjects){ validateTimestamps(startTime, endTime, resolution); final Map<Long, ResultListLongObject> result = new HashMap<Long, ResultListLongObject>(); Map<Long, Long> userMap = StudentHelper.getCourseStudentsAliasKeys(courses, gender); // Set up db-connection final IDBHandler dbHandler = ServerConfiguration.getInstance().getMiningDbHandler(); final Session session = dbHandler.getMiningSession(); if (users.isEmpty()) { users = new ArrayList<Long>(userMap.values()); if (users.isEmpty()) { // TODO no users in course, maybe send some http error this.logger.debug("No users found for course. Returning empty resultset."); return new ResultListHashMapObject(); } } else { List<Long> tmp = new ArrayList<Long>(); for(int i = 0; i < users.size(); i++) { tmp.add(userMap.get(users.get(i))); } users = tmp; } // Calculate size of time intervalls final double intervall = (endTime - startTime) / (resolution); final Map<Long, Long> idToAlias = StudentHelper.getCourseStudentsRealKeys(courses, gender); final Map<Long, HashMap<Integer, Set<Long>>> userPerResStep = new HashMap<Long, HashMap<Integer, Set<Long>>>(); // Create and initialize array for results for (int j = 0; j < courses.size(); j++) { final Long[] resArr = new Long[resolution.intValue()]; for (int i = 0; i < resArr.length; i++) { resArr[i] = 0L; } final List<Long> l = new ArrayList<Long>(); Collections.addAll(l, resArr); result.put(courses.get(j), new ResultListLongObject(l)); } for (final Long course : courses) { userPerResStep.put(course, new HashMap<Integer, Set<Long>>()); } for (String resourceType : resourceTypes) { this.logger.debug("Course Activity Request - CA Selection: " + resourceType); } if (resourceTypes.isEmpty()) { this.logger.debug("Course Activity Request - CA Selection: NO Items selected "); } final Criteria criteria = session.createCriteria(ILog.class, "log") .add(Restrictions.in("log.course.id", courses)) .add(Restrictions.between("log.timestamp", startTime, endTime)) .add(Restrictions.in("log.user.id", users)); if(!learningObjects.isEmpty()) { criteria.add(Restrictions.in("log.learning.id", learningObjects)); } @SuppressWarnings("unchecked") List<ILog> logs = criteria.list(); for (ILog log : logs) { boolean isInRT = false; if ((resourceTypes != null) && (resourceTypes.size() > 0) && resourceTypes.contains(log.getLearning().getLOType())) { isInRT = true; } if ((resourceTypes == null) || (resourceTypes.size() == 0) || isInRT) { Integer pos = new Double((log.getTimestamp() - startTime) / intervall).intValue(); if (pos > (resolution - 1)) { pos = resolution.intValue() - 1; } result.get(log.getCourse().getId()).getElements() .set(pos, result.get(log.getCourse().getId()).getElements().get(pos) + 1); if (userPerResStep.get(log.getCourse().getId()).get(pos) == null) { final Set<Long> s = new HashSet<Long>(); s.add(idToAlias.get(log.getUser().getId())); userPerResStep.get(log.getCourse().getId()).put(pos, s); } else { userPerResStep.get(log.getCourse().getId()).get(pos).add(idToAlias.get(log.getUser().getId())); } } } for (final Long c : courses) { for (int i = 0; i < resolution; i++) { if (userPerResStep.get(c).get(i) == null) { result.get(c).getElements().add(0L); } else { result.get(c).getElements().add(Long.valueOf(userPerResStep.get(c).get(i).size())); } } } final ResultListHashMapObject resultObject = new ResultListHashMapObject(result); if ((resultObject != null) && (resultObject.getElements() != null)) { final Set<Long> keySet = resultObject.getElements().keySet(); final Iterator<Long> it = keySet.iterator(); while (it.hasNext()) { final Long learnObjectTypeName = it.next(); this.logger.info("Result Course IDs: " + learnObjectTypeName); } } else { this.logger.info("Returning empty resultset."); } session.close(); return resultObject; } }