/**
* 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>
* Initial code contributed and copyrighted by<br>
* JGS goodsolutions GmbH, http://www.goodsolutions.ch
* <p>
*/
package org.olat.core.util.prefs.db;
import java.util.Iterator;
import java.util.List;
import org.olat.core.id.Identity;
import org.olat.core.logging.OLog;
import org.olat.core.logging.Tracing;
import org.olat.core.util.prefs.Preferences;
import org.olat.core.util.prefs.PreferencesStorage;
import org.olat.core.util.xml.XStreamHelper;
import org.olat.properties.Property;
import org.olat.properties.PropertyManager;
import com.thoughtworks.xstream.XStream;
/**
* Description:<br>
* <P>
* Initial Date: 21.06.2006 <br>
*
* @author Felix Jost
*/
public class DbStorage implements PreferencesStorage {
private static final OLog log = Tracing.createLoggerFor(DbStorage.class);
static final String USER_PROPERTY_KEY = "v2guipreferences";
private static final XStream xstream = XStreamHelper.createXStreamInstance();
static {
xstream.ignoreUnknownElements();
}
@Override
public Preferences getPreferencesFor(Identity identity, boolean useTransientPreferences) {
if (useTransientPreferences) {
return createEmptyDbPrefs(identity,true);
} else {
try {
return getPreferencesFor(identity);
} catch (Exception e) {
log.error("Retry after exception", e);
return getPreferencesFor(identity);
}
}
}
@Override
public void updatePreferencesFor(Preferences prefs, Identity identity) {
String props = xstream.toXML(prefs);
Property property = getPreferencesProperty(identity);
if (property == null) {
property = PropertyManager.getInstance().createPropertyInstance(identity, null, null, null, DbStorage.USER_PROPERTY_KEY, null, null,
null, props);
// also save the properties to db, here (strentini)
// fixes the "non-present gui preferences" for new users, or where guiproperties were manually deleted
PropertyManager.getInstance().saveProperty(property);
}else{
property.setTextValue(props);
PropertyManager.getInstance().updateProperty(property);
}
}
/**
* search x-stream serialization in properties table, create new if not found
* @param identity
* @return
*/
private DbPrefs getPreferencesFor(final Identity identity) {
Property guiProperty = getPreferencesProperty(identity);
if (guiProperty == null) {
return createEmptyDbPrefs(identity,false);
} else {
return getPreferencesForProperty(identity, guiProperty);
}
}
private Property getPreferencesProperty(Identity identity) {
Property guiProperty = null;
try {
guiProperty = PropertyManager.getInstance().findProperty(identity, null, null, null, USER_PROPERTY_KEY);
} catch (Exception e) {
// OLAT-6429 detect and delete multiple prefs objects, keep the first one only
List<Property> guiPropertyList = PropertyManager.getInstance().findProperties(identity, null, null, null, USER_PROPERTY_KEY);
if (guiPropertyList != null && guiPropertyList.size() > 0) {
log.warn("Found more than 1 entry for " + USER_PROPERTY_KEY + " in o_property table for user " + identity.getName() + ". Use first of them, deleting the others!", e);
Iterator<Property> iterator = guiPropertyList.iterator();
guiProperty = iterator.next();
while (iterator.hasNext()) {
Property property = iterator.next();
PropertyManager.getInstance().deleteProperty(property);
log.info("Will delete old property: " + property.getTextValue());
}
}
}
return guiProperty;
}
private DbPrefs getPreferencesForProperty(Identity identity, Property guiProperty) {
DbPrefs prefs;
try {
prefs = createDbPrefsFrom(identity, guiProperty.getTextValue());
} catch (Exception e) {
prefs = doGuiPrefsMigration( guiProperty, identity);
}
return prefs;
}
private DbPrefs createEmptyDbPrefs(Identity identity, boolean isTransient) {
DbPrefs prefs = new DbPrefs();
prefs.setIdentity(identity);
prefs.setTransient(isTransient);
return prefs;
}
private DbPrefs createDbPrefsFrom(Identity identity, String textValue) {
DbPrefs prefs = (DbPrefs) xstream.fromXML(textValue);
prefs.setIdentity(identity); // reset transient value
return prefs;
}
private DbPrefs doGuiPrefsMigration(Property guiProperty, Identity identity) {
String migratedTextValue = doCalendarRefactoringMigration(guiProperty.getTextValue());
// add new migration methode here
try {
return createDbPrefsFrom(identity, migratedTextValue);
} catch (Exception e) {
// Migration failed => return empty db-prefs
return createEmptyDbPrefs(identity,false);
}
}
/**
* Migration for 5.1.x to 5.2.0 because the calendar package was changed.
* Rename 'org.olat.core.commons.calendar.model.KalendarConfig' to 'org.olat.commons.calendar.model.KalendarConfig'.
* @param textValue
* @return Migrated textValue String
*/
private String doCalendarRefactoringMigration(String textValue) {
return textValue.replaceAll("org.olat.core.commons.calendar.model.KalendarConfig", "org.olat.commons.calendar.model.KalendarConfig");
}
}