/**
* <a href="http://www.openolat.org">
* OpenOLAT - Online Learning and Training</a><br>
* <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 the
* <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a>
* <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>
* Initial code contributed and copyrighted by<br>
* frentix GmbH, http://www.frentix.com
* <p>
*/
package org.olat.upgrade;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
import org.olat.commons.calendar.CalendarManager;
import org.olat.commons.calendar.manager.CalendarUserConfigurationDAO;
import org.olat.commons.calendar.manager.ImportedCalendarDAO;
import org.olat.commons.calendar.manager.ImportedToCalendarDAO;
import org.olat.commons.calendar.model.CalendarUserConfiguration;
import org.olat.commons.calendar.model.ImportedCalendar;
import org.olat.commons.calendar.model.ImportedToCalendar;
import org.olat.commons.calendar.model.Kalendar;
import org.olat.core.commons.persistence.DB;
import org.olat.core.id.Identity;
import org.olat.core.util.StringHelper;
import org.olat.core.util.xml.XStreamHelper;
import org.olat.properties.Property;
import org.olat.upgrade.model.KalendarConfig;
import org.olat.upgrade.model.UpgradePreferences;
import org.springframework.beans.factory.annotation.Autowired;
import com.thoughtworks.xstream.XStream;
/**
*
* Initial date: 27.03.2015<br>
* @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
*
*/
public class OLATUpgrade_10_4_0 extends OLATUpgrade {
private static final int BATCH_SIZE = 1000;
private static final String CALENDAR_TOKENS = "Calendar tokens";
private static final String CALENDAR_USER_CONFIGS = "Calendar user configurations";
private static final String IMPORTED_CALENDARS = "Imported calendars";
private static final String IMPORTED_CALENDARS_URL = "Imported calendars url";
private static final String VERSION = "OLAT_10.4.0";
private static final XStream xstream = XStreamHelper.createXStreamInstance();
static {
xstream.ignoreUnknownElements();
xstream.alias("org.olat.preferences.DbPrefs", UpgradePreferences.class);
xstream.alias("org.olat.core.util.prefs.db.DbPrefs", UpgradePreferences.class);
xstream.alias("org.olat.commons.calendar.model.KalendarConfig", KalendarConfig.class);
}
private final static String KALENDAR_GUI_MARKER = "org.olat.commons.calendar.model.KalendarConfig::";
@Autowired
private DB dbInstance;
@Autowired
private CalendarManager calendarMgr;
@Autowired
private ImportedCalendarDAO importedCalendarDao;
@Autowired
private ImportedToCalendarDAO importedToCalendarDao;
@Autowired
private CalendarUserConfigurationDAO calendarUserConfigurationDao;
public OLATUpgrade_10_4_0() {
super();
}
@Override
public String getVersion() {
return VERSION;
}
@Override
public boolean doPreSystemInitUpgrade(UpgradeManager upgradeManager) {
return false;
}
@Override
public boolean doPostSystemInitUpgrade(UpgradeManager upgradeManager) {
UpgradeHistoryData uhd = upgradeManager.getUpgradesHistory(VERSION);
if (uhd == null) {
// has never been called, initialize
uhd = new UpgradeHistoryData();
} else if (uhd.isInstallationComplete()) {
return false;
}
boolean allOk = true;
allOk &= migrateImportedCalendars(upgradeManager, uhd);
allOk &= migrateImportedCalendarsTo(upgradeManager, uhd);
allOk &= migrateCalendarTokens(upgradeManager, uhd);
allOk &= migrateCalendarConfigurations(upgradeManager, uhd);
uhd.setInstallationComplete(allOk);
upgradeManager.setUpgradesHistory(uhd, VERSION);
if(allOk) {
log.audit("Finished OLATUpgrade_10_4_0 successfully!");
} else {
log.audit("OLATUpgrade_10_4_0 not finished, try to restart OpenOLAT!");
}
return allOk;
}
private boolean migrateCalendarTokens(UpgradeManager upgradeManager, UpgradeHistoryData uhd) {
if (!uhd.getBooleanDataValue(CALENDAR_TOKENS)) {
int counter = 0;
List<Property> properties;
do {
properties = findAllUserProperties(counter, BATCH_SIZE);
for(Property property:properties) {
processCalendarProperty(property);
if(counter % 20 == 0) {
dbInstance.commit();
}
}
dbInstance.commitAndCloseSession();
counter += properties.size();
} while(properties.size() == BATCH_SIZE);
uhd.setBooleanDataValue(CALENDAR_TOKENS, true);
upgradeManager.setUpgradesHistory(uhd, VERSION);
}
return true;
}
private void processCalendarProperty(Property property) {
String calendarId;
Identity identity = property.getIdentity();
String resourceType = property.getResourceTypeName();
if(StringHelper.containsNonWhitespace(resourceType) && property.getResourceTypeId() != null) {
calendarId = property.getResourceTypeId().toString();
} else {
resourceType = CalendarManager.TYPE_USER;
calendarId = identity.getName();
}
CalendarUserConfiguration config = calendarUserConfigurationDao
.getCalendarUserConfiguration(identity, calendarId, resourceType);
if(config == null) {
String token = property.getStringValue();
Kalendar mockCal = new Kalendar(calendarId, resourceType);
calendarUserConfigurationDao.createCalendarUserConfiguration(mockCal, identity, token, true, true);
}
}
private List<Property> findAllUserProperties(int firstResult, int maxResult) {
StringBuilder sb = new StringBuilder();
sb.append("select v from ").append(Property.class.getName()).append(" as v ")
.append(" inner join v.identity identity ")
.append(" where v.category='icalAuthToken' and v.name='authToken'")
.append(" order by v.key");
return dbInstance.getCurrentEntityManager()
.createQuery(sb.toString(), Property.class)
.setFirstResult(firstResult)
.setMaxResults(maxResult)
.getResultList();
}
private boolean migrateCalendarConfigurations(UpgradeManager upgradeManager, UpgradeHistoryData uhd) {
if (!uhd.getBooleanDataValue(CALENDAR_USER_CONFIGS)) {
int counter = 0;
List<Property> properties;
do {
properties = getUserGUIProperties(counter, BATCH_SIZE);
for(Property property:properties) {
processCalendarGUIProperty(property);
if(counter % 20 == 0) {
dbInstance.commit();
}
}
counter += properties.size();
log.audit("Calendar GUI properties processed: " + properties.size() + ", total processed (" + counter + ")");
dbInstance.commitAndCloseSession();
} while(properties.size() == BATCH_SIZE);
uhd.setBooleanDataValue(CALENDAR_USER_CONFIGS, true);
upgradeManager.setUpgradesHistory(uhd, VERSION);
}
return true;
}
private List<Property> getUserGUIProperties(int firstResult, int maxResult) {
StringBuilder sb = new StringBuilder();
sb.append("select v from ").append(Property.class.getName()).append(" as v ")
.append(" inner join v.identity identity ")
.append(" where v.name='v2guipreferences'")
.append(" order by v.key");
return dbInstance.getCurrentEntityManager()
.createQuery(sb.toString(), Property.class)
.setFirstResult(firstResult)
.setMaxResults(maxResult)
.getResultList();
}
private void processCalendarGUIProperty(Property property) {
String text = property.getTextValue();
if(StringHelper.containsNonWhitespace(text)) {
try {
UpgradePreferences prefs = (UpgradePreferences)xstream.fromXML(text);
if(prefs != null) {
Map<String,Object> preferenceMap = prefs.getPreferences();
for(Map.Entry<String,Object> entry:preferenceMap.entrySet()) {
String key = entry.getKey();
if(key.startsWith(KALENDAR_GUI_MARKER)) {
String calendarId = key.substring(KALENDAR_GUI_MARKER.length(), key.length());
KalendarConfig config = (KalendarConfig)entry.getValue();
processKalendarConfig(property.getIdentity(), calendarId, config);
}
}
}
} catch (Exception e) {
log.warn("Cannot read the preferences", e);
}
}
}
private void processKalendarConfig(Identity identity, String calendarId, KalendarConfig config) {
Kalendar cal;
CalendarUserConfiguration userConfig;
if(StringHelper.isLong(calendarId)) {
//guess if it's a course or a group calendar
if(calendarMgr.getCalendarFile(CalendarManager.TYPE_COURSE, calendarId) != null) {
cal = new Kalendar(calendarId, CalendarManager.TYPE_COURSE);
} else if(calendarMgr.getCalendarFile(CalendarManager.TYPE_GROUP, calendarId) != null) {
cal = new Kalendar(calendarId, CalendarManager.TYPE_GROUP);
} else {
return;
}
} else {
//personal calendar
cal = new Kalendar(calendarId, CalendarManager.TYPE_USER);
}
userConfig = calendarUserConfigurationDao
.getCalendarUserConfiguration(identity, cal.getCalendarID(), cal.getType());
if(userConfig == null) {
userConfig = calendarUserConfigurationDao.createCalendarUserConfiguration(cal, identity);
userConfig.setCssClass(config.getCss());
userConfig.setVisible(config.isVis());
userConfig = calendarUserConfigurationDao.update(userConfig);
}
}
private boolean migrateImportedCalendars(UpgradeManager upgradeManager, UpgradeHistoryData uhd) {
if (!uhd.getBooleanDataValue(IMPORTED_CALENDARS)) {
int counter = 0;
List<Property> properties;
do {
properties = getImportCalendarProperties(counter, BATCH_SIZE);
for(Property property:properties) {
processImportedCalendars(property);
if(counter % 20 == 0) {
dbInstance.commit();
}
}
dbInstance.commitAndCloseSession();
counter += properties.size();
} while(properties.size() == BATCH_SIZE);
uhd.setBooleanDataValue(IMPORTED_CALENDARS, true);
upgradeManager.setUpgradesHistory(uhd, VERSION);
}
return true;
}
private void processImportedCalendars(Property property) {
Identity identity = property.getIdentity();
String calendarPartialId = property.getName();
String calendarId = identity.getName() + "_" + calendarPartialId;
String url = property.getStringValue();
List<ImportedCalendar> currentCalendars = importedCalendarDao
.getImportedCalendar(identity, calendarId, CalendarManager.TYPE_USER);
if(currentCalendars.isEmpty()) {
Date importDate;
if(property.getLongValue() != null) {
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(property.getLongValue().longValue());
importDate = calendar.getTime();
} else {
importDate = new Date();
}
importedCalendarDao.createImportedCalendar(identity, calendarPartialId,
calendarId, CalendarManager.TYPE_USER, url, importDate);
}
}
private List<Property> getImportCalendarProperties(int firstResult, int maxResult) {
StringBuilder sb = new StringBuilder();
sb.append("select v from ").append(Property.class.getName()).append(" as v ")
.append(" inner join v.identity identity ")
.append(" where v.category='Imported-Calendar'")
.append(" order by v.key");
return dbInstance.getCurrentEntityManager()
.createQuery(sb.toString(), Property.class)
.setFirstResult(firstResult)
.setMaxResults(maxResult)
.getResultList();
}
private boolean migrateImportedCalendarsTo(UpgradeManager upgradeManager, UpgradeHistoryData uhd) {
if (!uhd.getBooleanDataValue(IMPORTED_CALENDARS_URL)) {
int counter = 0;
List<Property> properties;
do {
properties = getImportCalendarWithUrlProperties(counter, BATCH_SIZE);
for(Property property:properties) {
processImportedCalendarsTo(property);
if(counter % 20 == 0) {
dbInstance.commit();
}
}
dbInstance.commitAndCloseSession();
counter += properties.size();
} while(properties.size() == BATCH_SIZE);
uhd.setBooleanDataValue(IMPORTED_CALENDARS_URL, true);
upgradeManager.setUpgradesHistory(uhd, VERSION);
}
return true;
}
private void processImportedCalendarsTo(Property property) {
//the calendar are imported in an existent calendar
//urls are | separated
String calendarId = property.getName();
String type = property.getResourceTypeName();
if("user".equals(type)) {
return;//don't convert this, they have there own synchronization mechanism
}
String importUrls = property.getTextValue();
if(StringHelper.containsNonWhitespace(importUrls) && StringHelper.containsNonWhitespace(calendarId) && StringHelper.containsNonWhitespace(type)) {
for(StringTokenizer tokenizer = new StringTokenizer(importUrls, "|"); tokenizer.hasMoreTokens(); ) {
String importUrl = tokenizer.nextToken();
List<ImportedToCalendar> currentCalendars = importedToCalendarDao.getImportedToCalendars(calendarId, type, importUrl);
if(currentCalendars.isEmpty()) {
Date importDate;
if(property.getLongValue() != null) {
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(property.getLongValue().longValue());
importDate = calendar.getTime();
} else {
importDate = new Date();
}
importedToCalendarDao.createImportedToCalendar(calendarId, type, importUrl, importDate);
}
}
}
}
private List<Property> getImportCalendarWithUrlProperties(int firstResult, int maxResult) {
StringBuilder sb = new StringBuilder();
sb.append("select v from ").append(Property.class.getName()).append(" as v ")
.append(" where v.category='Imported-Calendar-To'")
.append(" order by v.key");
return dbInstance.getCurrentEntityManager()
.createQuery(sb.toString(), Property.class)
.setFirstResult(firstResult)
.setMaxResults(maxResult)
.getResultList();
}
}