/**
* <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.List;
import org.olat.core.commons.persistence.DB;
import org.olat.core.commons.services.notifications.Publisher;
import org.olat.core.id.OLATResourceable;
import org.olat.core.util.resource.OresHelper;
import org.olat.group.BusinessGroup;
import org.olat.group.BusinessGroupImpl;
import org.olat.properties.Property;
import org.olat.properties.PropertyManager;
import org.olat.repository.RepositoryEntry;
import org.olat.repository.RepositoryManager;
import org.springframework.beans.factory.annotation.Autowired;
/**
*
* Initial date: 23.01.2014<br>
* @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
*
*/
public class OLATUpgrade_9_4_0 extends OLATUpgrade {
private static final int BATCH_SIZE = 50;
private static final String TASK_DISPLAY_MEMBERS = "Upgrade display members";
private static final String FIX_PUBLISHER_BUSINESSPATH = "Fix publishers business path";
private static final String VERSION = "OLAT_9.4.0";
private static final String PROP_NAME = "displayMembers";
private static final String OLATRESOURCE_CONFIGURATION = "config";
@Autowired
private DB dbInstance;
@Autowired
private PropertyManager propertyManager;
@Autowired
private RepositoryManager repositoryManager;
public OLATUpgrade_9_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 = upgradeDisplayMembers(upgradeManager, uhd);
allOk &= fixBusinessPathPublisher(upgradeManager, uhd);
uhd.setInstallationComplete(allOk);
upgradeManager.setUpgradesHistory(uhd, VERSION);
if(allOk) {
log.audit("Finished OLATUpgrade_9_4_0 successfully!");
} else {
log.audit("OLATUpgrade_9_4_0 not finished, try to restart OpenOLAT!");
}
return allOk;
}
private boolean fixBusinessPathPublisher(UpgradeManager upgradeManager, UpgradeHistoryData uhd) {
if (!uhd.getBooleanDataValue(FIX_PUBLISHER_BUSINESSPATH)) {
List<Publisher> publishers = getPublishers();
int count = 0;
int updates = 0;
for(Publisher publisher:publishers) {
boolean updated = processPublisher(publisher);
if(count % 10 == 0) {
dbInstance.commit();
}
if(updated) updates++;
}
dbInstance.commit();
log.audit("Update " + updates + " publisher with partial business path.");
uhd.setBooleanDataValue(FIX_PUBLISHER_BUSINESSPATH, true);
upgradeManager.setUpgradesHistory(uhd, VERSION);
}
return true;
}
private boolean processPublisher(Publisher publisher) {
OLATResourceable ores = OresHelper.createOLATResourceableInstance(publisher.getResName(), publisher.getResId());
RepositoryEntry re = repositoryManager.lookupRepositoryEntry(ores, false);
if(re != null) {
String businessPath = publisher.getBusinessPath();
String newPath = "[RepositoryEntry:" + re.getKey() + "]" + businessPath;
publisher.setBusinessPath(newPath);
StringBuilder sb = new StringBuilder();
sb.append("update notipublisher pub set pub.businessPath=:newPath ")
.append("where pub.key=:pubKey");
int rows = dbInstance.getCurrentEntityManager().createQuery(sb.toString())
.setParameter("newPath", newPath)
.setParameter("pubKey", publisher.getKey())
.executeUpdate();
if(rows != 1) {
log.error("Cannot update publisher with key: " + publisher.getKey());
}
return rows == 1;
} else {
log.error("Cannot update publisher with key: " + publisher.getKey() + " don't find an according repository entry");
return false;
}
}
private List<Publisher> getPublishers() {
String q = "select pub from notipublisher pub where pub.businessPath like '[CourseNode:%'";
return dbInstance.getCurrentEntityManager().createQuery(q, Publisher.class)
.getResultList();
}
private static final int showOwnersVal = 1;// 0x..0001
private static final int showPartipsVal = 2;// 0x..0010
private static final int showWaitingListVal = 4;// 0x..0100
private boolean upgradeDisplayMembers(UpgradeManager upgradeManager, UpgradeHistoryData uhd) {
if (!uhd.getBooleanDataValue(TASK_DISPLAY_MEMBERS)) {
int counter = 0;
List<BusinessGroupImpl> groups;
do {
groups = findGroups(counter, BATCH_SIZE);
for(BusinessGroupImpl group:groups) {
Property prop = findProperty(group);
if(prop != null) {
boolean changed = false;
Long internValue = prop.getLongValue();
if(internValue != null && internValue.longValue() > 0) {
long value = internValue.longValue();
boolean owners = (value & showOwnersVal) == showOwnersVal;
boolean participants = (value & showPartipsVal) == showPartipsVal;
boolean waiting = (value & showWaitingListVal) == showWaitingListVal;
group.setOwnersVisibleIntern(owners);
group.setParticipantsVisibleIntern(participants);
group.setWaitingListVisibleIntern(waiting);
changed = true;
}
String publicValue = prop.getStringValue();
if(publicValue != null && publicValue.length() > 0
&& Character.isDigit(publicValue.toCharArray()[0])) {
try {
int value = Integer.parseInt(publicValue);
boolean owners = (value & showOwnersVal) == showOwnersVal;
boolean participants = (value & showPartipsVal) == showPartipsVal;
boolean waiting = (value & showWaitingListVal) == showWaitingListVal;
group.setOwnersVisiblePublic(owners);
group.setParticipantsVisiblePublic(participants);
group.setWaitingListVisiblePublic(waiting);
} catch (NumberFormatException e) {
log.error("", e);
}
changed = true;
}
Float downloadValue = prop.getFloatValue();
if(downloadValue != null && downloadValue != 0.0f) {
float value = downloadValue.floatValue();
//paranoid check
if(value > 0.9 && value < 1.1) {
group.setDownloadMembersLists(true);
changed = true;
} else if(value < -0.9 && value > -1.1) {
group.setDownloadMembersLists(true);
changed = true;
}
}
if(changed) {
prop.setCategory("configMoved");
dbInstance.getCurrentEntityManager().merge(group);
}
}
}
counter += groups.size();
log.audit("Business groups processed: " + groups.size());
dbInstance.commitAndCloseSession();
} while(groups.size() == BATCH_SIZE);
uhd.setBooleanDataValue(TASK_DISPLAY_MEMBERS, true);
upgradeManager.setUpgradesHistory(uhd, VERSION);
}
return true;
}
private List<BusinessGroupImpl> findGroups(int firstResult, int maxResults) {
StringBuilder sb = new StringBuilder();
sb.append("select grp from businessgroup grp order by key");
return dbInstance.getCurrentEntityManager().createQuery(sb.toString(), BusinessGroupImpl.class)
.setFirstResult(firstResult)
.setMaxResults(maxResults)
.getResultList();
}
public Property findProperty(BusinessGroup group) {
Property prop = propertyManager.findProperty(null, group, group, OLATRESOURCE_CONFIGURATION, PROP_NAME);
return prop;
}
}