/**
* OLAT - Online Learning and Training<br>
* http://www.olat.org
* <p>
* Licensed under the Apache License, Version 2.0 (the "License"); <br>
* you may not use this file except in compliance with the License.<br>
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing,<br>
* software distributed under the License is distributed on an "AS IS" BASIS, <br>
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
* See the License for the specific language governing permissions and <br>
* limitations under the License.
* <p>
* Copyright (c) since 2004 at Multimedia- & E-Learning Services (MELS),<br>
* University of Zurich, Switzerland.
* <hr>
* <a href="http://www.openolat.org">
* OpenOLAT - Online Learning and Training</a><br>
* This file has been modified by the OpenOLAT community. Changes are licensed
* under the Apache 2.0 license as the original file.
* <p>
*/
package org.olat.course.statistic.export;
import java.io.File;
import java.io.Writer;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.StandardOpenOption;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.TemporalType;
import javax.persistence.TypedQuery;
import org.olat.core.commons.persistence.DB;
import org.olat.core.logging.OLog;
import org.olat.core.logging.Tracing;
import org.olat.core.logging.activity.LoggingObject;
/**
*
* Description:<br>
* This class provides a simple log export from database.
* <p>
* Note that this will <b>not work with big tables</b> as you
* have with big installations. The reason being that when the resulting
* log set is big, it both requires a huge amount of memory plus the loop
* which happens in this class takes forever (minutes).
* <P>
* Initial Date: 09.12.2009 <br>
* @author bja
*/
public class SimpleLogExporter implements ICourseLogExporter {
private static final OLog log = Tracing.createLoggerFor(SimpleLogExporter.class);
private static final String LINE_SEPARATOR = System.getProperty("line.separator");
private DB dbInstance;
private LogLineConverter logLineConverter_;
private SimpleLogExporter() {
// this empty constructor is ok - instantiated via spring
}
/** injected by spring **/
public void setLogLineConverter(LogLineConverter logLineConverter) {
logLineConverter_ = logLineConverter;
}
public void setDbInstance(DB dbInstance) {
this.dbInstance = dbInstance;
}
@Override
public void exportCourseLog(File outFile, String charset, Long resourceableId, Date begin, Date end, boolean resourceAdminAction, boolean anonymize) {
String query = "select v from org.olat.core.logging.activity.LoggingObject v " + "where v.resourceAdminAction = :resAdminAction "
+ "AND ( "
+ "(v.targetResId = :resId) OR "
+ "(v.parentResId = :resId) OR "
+ "(v.grandParentResId = :resId) OR "
+ "(v.greatGrandParentResId = :resId) "
+ ")";
if (begin != null) {
query = query.concat(" AND (v.creationDate >= :createdAfter)");
}
if (end != null) {
query = query.concat(" AND (v.creationDate <= :createdBefore)");
}
EntityManager em = dbInstance.getCurrentEntityManager();
em.clear();
TypedQuery<LoggingObject> dbQuery = em.createQuery(query, LoggingObject.class)
.setParameter("resAdminAction", resourceAdminAction)
.setParameter("resId", Long.toString(resourceableId));
if (begin != null) {
dbQuery.setParameter("createdAfter", begin, TemporalType.DATE);
}
if (end != null) {
Calendar cal = Calendar.getInstance();
cal.setTime(end);
cal.add(Calendar.DAY_OF_MONTH, 1);
end = cal.getTime();
dbQuery.setParameter("createdBefore", end, TemporalType.DATE);
}
try(Writer out = Files.newBufferedWriter(outFile.toPath(), Charset.forName("UTF-8"), StandardOpenOption.CREATE_NEW)) {
out.append(logLineConverter_.getCSVHeader());
out.append(LINE_SEPARATOR);
int count = 0;
List<LoggingObject> queryResult = dbQuery.getResultList();
for (LoggingObject loggingObject : queryResult) {
out.append(logLineConverter_.getCSVRow(loggingObject, anonymize, resourceableId));
out.append(LINE_SEPARATOR);
if(count % 1000 == 0) {
out.flush();
em.clear();
}
}
} catch(Exception e) {
log.error("", e);
} finally {
em.clear();
dbInstance.commitAndCloseSession();
}
}
}