/**
* <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.io.File;
import java.nio.file.Paths;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.apache.commons.io.FileUtils;
import org.olat.admin.layout.LayoutModule;
import org.olat.basesecurity.BaseSecurity;
import org.olat.basesecurity.Constants;
import org.olat.basesecurity.Group;
import org.olat.basesecurity.GroupMembership;
import org.olat.basesecurity.GroupRoles;
import org.olat.basesecurity.Policy;
import org.olat.basesecurity.SecurityGroup;
import org.olat.basesecurity.SecurityGroupMembershipImpl;
import org.olat.basesecurity.manager.GroupDAO;
import org.olat.basesecurity.model.GroupImpl;
import org.olat.basesecurity.model.GroupMembershipImpl;
import org.olat.core.commons.persistence.DB;
import org.olat.core.util.StringHelper;
import org.olat.core.util.WebappHelper;
import org.olat.portfolio.manager.EPMapPolicy;
import org.olat.properties.Property;
import org.olat.properties.PropertyManager;
import org.olat.repository.manager.RepositoryEntryRelationDAO;
import org.olat.resource.OLATResource;
import org.olat.upgrade.model.BGResourceRelation;
import org.olat.upgrade.model.BusinessGroupUpgrade;
import org.olat.upgrade.model.EPMapUpgrade;
import org.olat.upgrade.model.EPMapUpgradeToGroupRelation;
import org.olat.upgrade.model.InvitationUpgrade;
import org.olat.upgrade.model.RepositoryEntryUpgrade;
import org.olat.upgrade.model.RepositoryEntryUpgradeToGroupRelation;
import org.springframework.beans.factory.annotation.Autowired;
/**
*
* Initial date: 27.02.2014<br>
* @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
*
*/
public class OLATUpgrade_10_0_0 extends OLATUpgrade {
private static final int BATCH_SIZE = 50;
private static final String TASK_BUSINESS_GROUPS = "Upgrade business groups";
private static final String TASK_REPOENTRIES = "Upgrade repository entries";
private static final String TASK_REPOENTRY_TO_BUSINESSGROUP = "Upgrade relation business groups to repository entries";
private static final String TASK_INVITATION = "Upgrade invitations";
private static final String TASK_UPGRADE_MAP = "Upgrade e-portfolio maps";
private static final String TASK_LOGO = "Upgrade custom logo";
private static final String VERSION = "OLAT_10.0.0";
private static String PROPERTY_CATEGORY = "_o3_";
private static String PNAME_LOGOURI = "customizing.img.uri";
private static String PNAME_LOGOALT = "customizing.img.alt";
private static String PNAME_LINKURI = "customizing.link.uri";
private static String PNAME_FOOTERLINE = "customizing.footer.text";
@Autowired
private DB dbInstance;
@Autowired
private BaseSecurity securityManager;
@Autowired
private GroupDAO groupDao;
@Autowired
private RepositoryEntryRelationDAO repositoryEntryToGroupDAO;
@Autowired
private PropertyManager propertyManager;
@Autowired
private LayoutModule layoutModule;
public OLATUpgrade_10_0_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 &= upgradeLogo(upgradeManager, uhd);
allOk &= upgradeBusinessGroups(upgradeManager, uhd);
allOk &= upgradeRepositoryEntries(upgradeManager, uhd);
allOk &= upgradeRelationsRepoToBusinessGroups(upgradeManager, uhd);
allOk &= upgradeInvitation(upgradeManager, uhd);
allOk &= upgradeEPMap(upgradeManager, uhd);
uhd.setInstallationComplete(allOk);
upgradeManager.setUpgradesHistory(uhd, VERSION);
if(allOk) {
log.audit("Finished OLATUpgrade_10_0_0 successfully!");
} else {
log.audit("OLATUpgrade_10_0_0 not finished, try to restart OpenOLAT!");
}
return allOk;
}
private boolean upgradeLogo(UpgradeManager upgradeManager, UpgradeHistoryData uhd) {
if (!uhd.getBooleanDataValue(TASK_LOGO)) {
try {
Property pLogoUri = propertyManager.findProperty(null, null, null, PROPERTY_CATEGORY, PNAME_LOGOURI);
if(pLogoUri != null && StringHelper.containsNonWhitespace(pLogoUri.getStringValue())) {
String filename = pLogoUri.getStringValue();
layoutModule.setLogoFilename(filename);
File currentFile = Paths.get(WebappHelper.getUserDataRoot(), "system", "logo", filename).toFile();
if(currentFile.exists()) {
File target = Paths.get(WebappHelper.getUserDataRoot(), "customizing", "logo", filename).toFile();
FileUtils.copyFile(currentFile, target);
}
}
Property pLogoAlt = propertyManager.findProperty(null, null, null, PROPERTY_CATEGORY, PNAME_LOGOALT);
if(pLogoAlt != null && StringHelper.containsNonWhitespace(pLogoAlt.getStringValue())) {
layoutModule.setLogoAlt(pLogoAlt.getStringValue());
}
Property pLinkUri = propertyManager.findProperty(null, null, null, PROPERTY_CATEGORY, PNAME_LINKURI);
if(pLinkUri != null && StringHelper.containsNonWhitespace(pLinkUri.getStringValue())) {
layoutModule.setLogoLinkUri(pLinkUri.getStringValue());
}
Property pFooterLine = propertyManager.findProperty(null, null, null, PROPERTY_CATEGORY, PNAME_FOOTERLINE);
if(pFooterLine != null && StringHelper.containsNonWhitespace(pFooterLine.getTextValue())) {
layoutModule.setFooterLine(pFooterLine.getTextValue());
}
uhd.setBooleanDataValue(TASK_LOGO, true);
upgradeManager.setUpgradesHistory(uhd, VERSION);
} catch (Exception e) {
log.error("", e);
return false;
}
}
return true;
}
private boolean upgradeBusinessGroups(UpgradeManager upgradeManager, UpgradeHistoryData uhd) {
if (!uhd.getBooleanDataValue(TASK_BUSINESS_GROUPS)) {
int counter = 0;
List<BusinessGroupUpgrade> businessGroups;
do {
businessGroups = findBusinessGroups(counter, BATCH_SIZE);
for(BusinessGroupUpgrade businessGroup:businessGroups) {
processBusinessGroup(businessGroup);
}
counter += businessGroups.size();
log.audit("Business groups processed: " + businessGroups.size() + ", total processed (" + counter + ")");
dbInstance.commitAndCloseSession();
} while(businessGroups.size() == BATCH_SIZE);
uhd.setBooleanDataValue(TASK_BUSINESS_GROUPS, true);
upgradeManager.setUpgradesHistory(uhd, VERSION);
}
return true;
}
private BusinessGroupUpgrade processBusinessGroup(BusinessGroupUpgrade businessGroup) {
Group baseGroup = businessGroup.getBaseGroup();
if(baseGroup != null && baseGroup.getKey() != null) {
return businessGroup;
}
Group group = groupDao.createGroup();
//update tutors
processSecurityGroup(group, GroupRoles.coach.name(), businessGroup.getOwnerGroup());
//update participants
processSecurityGroup(group, GroupRoles.participant.name(), businessGroup.getPartipiciantGroup());
//update waiting
processSecurityGroup(group, GroupRoles.waiting.name(), businessGroup.getWaitingGroup());
dbInstance.commit();
businessGroup.setBaseGroup(group);
businessGroup = dbInstance.getCurrentEntityManager().merge(businessGroup);
dbInstance.commit();
return businessGroup;
}
private boolean upgradeRepositoryEntries(UpgradeManager upgradeManager, UpgradeHistoryData uhd) {
if (!uhd.getBooleanDataValue(TASK_REPOENTRIES)) {
int counter = 0;
List<RepositoryEntryUpgrade> repoEntries;
do {
repoEntries = findRepositoryEntries(counter, BATCH_SIZE);
for(RepositoryEntryUpgrade repoEntry:repoEntries) {
processRepositoryEntry(repoEntry);
}
counter += repoEntries.size();
log.audit("Repository entries processed: " + repoEntries.size() + ", total processed (" + counter + ")");
dbInstance.commitAndCloseSession();
} while(repoEntries.size() == BATCH_SIZE);
uhd.setBooleanDataValue(TASK_REPOENTRIES, true);
upgradeManager.setUpgradesHistory(uhd, VERSION);
}
return true;
}
private void processRepositoryEntry(RepositoryEntryUpgrade repoEntry) {
if(isDefaultGroupOk(repoEntry)) return;
Group group = groupDao.createGroup();
//update owners
processSecurityGroup(group, GroupRoles.owner.name(), repoEntry.getOwnerGroup());
//update tutors
processSecurityGroup(group, GroupRoles.coach.name(), repoEntry.getTutorGroup());
//update participants
processSecurityGroup(group, GroupRoles.participant.name(), repoEntry.getParticipantGroup());
dbInstance.commit();
RepositoryEntryUpgradeToGroupRelation relation = create(repoEntry, group, true);
Set<RepositoryEntryUpgradeToGroupRelation> relations = new HashSet<>(2);
relations.add(relation);
repoEntry.setGroups(relations);
dbInstance.commit();
}
public RepositoryEntryUpgradeToGroupRelation create(RepositoryEntryUpgrade entry, Group group, boolean defaultRelation) {
RepositoryEntryUpgradeToGroupRelation rel = new RepositoryEntryUpgradeToGroupRelation();
rel.setCreationDate(new Date());
rel.setDefaultGroup(defaultRelation);
rel.setGroup(group);
rel.setEntry(entry);
dbInstance.getCurrentEntityManager().persist(rel);
return rel;
}
private boolean isDefaultGroupOk(RepositoryEntryUpgrade repoEntry) {
if(repoEntry.getGroups() == null || repoEntry.getGroups().isEmpty()) {
return false;
}
for(RepositoryEntryUpgradeToGroupRelation rel:repoEntry.getGroups()) {
if(rel.isDefaultGroup()) {
return true;
}
}
return false;
}
private boolean upgradeRelationsRepoToBusinessGroups(UpgradeManager upgradeManager, UpgradeHistoryData uhd) {
if (!uhd.getBooleanDataValue(TASK_REPOENTRY_TO_BUSINESSGROUP)) {
int counter = 0;
List<BusinessGroupUpgrade> businessGroups;
do {
businessGroups = findBusinessGroups(counter, BATCH_SIZE);
for(BusinessGroupUpgrade businessGroup:businessGroups) {
processRelationToRepo(businessGroup);
}
counter += businessGroups.size();
log.audit("Business groups relations processed: " + businessGroups.size() + ", total processed (" + counter + ")");
dbInstance.commitAndCloseSession();
} while(businessGroups.size() == BATCH_SIZE);
uhd.setBooleanDataValue(TASK_REPOENTRY_TO_BUSINESSGROUP, true);
upgradeManager.setUpgradesHistory(uhd, VERSION);
}
return true;
}
private void processRelationToRepo(BusinessGroupUpgrade businessGroup) {
try {
List<BGResourceRelation> relationsToRepo = findRelations(businessGroup);
if(relationsToRepo.size() > 0) {
Group refGroup = businessGroup.getBaseGroup();
for(BGResourceRelation relationToRepo:relationsToRepo) {
RepositoryEntryUpgrade entry = lookupRepositoryEntry(relationToRepo.getResource());
if(entry == null) {
continue;
}
boolean found = false;
Set<RepositoryEntryUpgradeToGroupRelation> groupRelations = entry.getGroups();
for(RepositoryEntryUpgradeToGroupRelation groupRelation:groupRelations) {
if(groupRelation.getGroup().equals(refGroup)) {
found = true;
}
}
if(!found) {
create(entry, refGroup, false);
}
}
}
dbInstance.commit();
} catch (Exception e) {
e.printStackTrace();
throw e;
}
}
private List<BGResourceRelation> findRelations(BusinessGroupUpgrade group) {
StringBuilder sb = new StringBuilder();
sb.append("select rel from ").append(BGResourceRelation.class.getName()).append(" as rel ")
.append(" where rel.group.key=:groupKey");
return dbInstance.getCurrentEntityManager().createQuery(sb.toString(), BGResourceRelation.class)
.setParameter("groupKey", group.getKey())
.getResultList();
}
private boolean upgradeInvitation(UpgradeManager upgradeManager, UpgradeHistoryData uhd) {
if (!uhd.getBooleanDataValue(TASK_INVITATION)) {
int counter = 0;
List<InvitationUpgrade> invitations;
do {
invitations = findInvitations(counter, BATCH_SIZE);
for(InvitationUpgrade invitation:invitations) {
if(invitation.getBaseGroup() == null) {
processInvitation(invitation);
}
}
counter += invitations.size();
log.audit("Invitations processed: " + invitations.size() + ", total processed (" + counter + ")");
dbInstance.commitAndCloseSession();
} while(invitations.size() == BATCH_SIZE);
uhd.setBooleanDataValue(TASK_INVITATION, true);
upgradeManager.setUpgradesHistory(uhd, VERSION);
}
return true;
}
private List<InvitationUpgrade> findInvitations(int firstResult, int maxResult) {
String sb = "select invitation from invitationupgrade as invitation order by invitation.key";
return dbInstance.getCurrentEntityManager()
.createQuery(sb, InvitationUpgrade.class)
.setFirstResult(firstResult)
.setMaxResults(maxResult)
.getResultList();
}
private void processInvitation(InvitationUpgrade invitation) {
if(invitation.getBaseGroup() == null) {
Group invitationGroup = groupDao.createGroup();
invitation.setBaseGroup(invitationGroup);
dbInstance.getCurrentEntityManager().merge(invitation);
}
}
private boolean upgradeEPMap(UpgradeManager upgradeManager, UpgradeHistoryData uhd) {
if (!uhd.getBooleanDataValue(TASK_UPGRADE_MAP)) {
int counter = 0;
List<EPMapUpgrade> businessGroups;
do {
businessGroups = findMaps(counter, BATCH_SIZE);
for(EPMapUpgrade businessGroup:businessGroups) {
processMap(businessGroup);
}
counter += businessGroups.size();
log.audit("Maps processed: " + businessGroups.size() + ", total processed (" + counter + ")");
dbInstance.commitAndCloseSession();
} while(businessGroups.size() == BATCH_SIZE);
uhd.setBooleanDataValue(TASK_UPGRADE_MAP, true);
upgradeManager.setUpgradesHistory(uhd, VERSION);
}
return true;
}
private void processMap(EPMapUpgrade map) {
if(hasGroupsRelations(map)) {
return;
}
Set<EPMapUpgradeToGroupRelation> relations = new HashSet<>();
SecurityGroup ownerGroup = map.getOwnerGroup();
if(ownerGroup != null) {
//create default group
RepositoryEntryUpgrade re = findMapRepoEntry(ownerGroup);
if(re != null) {
Group reGroup = repositoryEntryToGroupDAO.getDefaultGroup(re);
if(reGroup != null) {
relations.add(createDefaultGroup(map, reGroup));
}
}
if(relations.isEmpty()) {
Group group = groupDao.createGroup();
relations.add(createDefaultGroup(map, group));
processSecurityGroup(group, GroupRoles.owner.name(), ownerGroup);
}
//create policy -> relation
List<Policy> policies = securityManager.getPoliciesOfResource(map.getOlatResource(), null);
for(Policy policy:policies) {
if(policy.getPermission().contains(Constants.PERMISSION_READ)) {
EPMapUpgradeToGroupRelation policyRelation = processMapPolicy(policy, map);
if(policyRelation != null) {
relations.add(policyRelation);
}
}
}
for(EPMapUpgradeToGroupRelation relation:relations) {
dbInstance.getCurrentEntityManager().persist(relation);
}
}
}
private boolean hasGroupsRelations(EPMapUpgrade map) {
String sb = "select count(rel.key) from structureuptogroup as rel where rel.entry.key=:mapKey";
List<Number> counts = dbInstance.getCurrentEntityManager().createQuery(sb, Number.class)
.setParameter("mapKey", map.getKey())
.getResultList();
return counts != null && counts.size() > 0 && counts.get(0) != null && counts.get(0).intValue() > 0;
}
private EPMapUpgradeToGroupRelation processMapPolicy(Policy policy, EPMapUpgrade element) {
String permission = policy.getPermission();
SecurityGroup secGroup = policy.getSecurityGroup();
Group group;
String role;
if(permission.startsWith(EPMapPolicy.Type.user.name())) {
group = groupDao.createGroup();
processSecurityGroup(group, GroupRoles.participant.name(), secGroup);
role = EPMapPolicy.Type.user.name();
} else if (permission.startsWith(EPMapPolicy.Type.group.name())) {
group = findGroupOfBusinessGroup(secGroup);
role = EPMapPolicy.Type.group.name();
} else if (permission.startsWith(EPMapPolicy.Type.invitation.name())) {
InvitationUpgrade invitation = findInvitation(policy.getSecurityGroup());
if(invitation == null) {
return null;
}
group = invitation.getBaseGroup();
role = EPMapPolicy.Type.invitation.name();
} else if (permission.startsWith(EPMapPolicy.Type.allusers.name())) {
group = groupDao.createGroup(EPMapPolicy.Type.allusers.name());
role = EPMapPolicy.Type.allusers.name();
} else {
return null;
}
if(group == null) {
log.error("Group not resolve for policy of map: " + element.getKey() + " and policy: " + policy.getKey());
return null;
}
EPMapUpgradeToGroupRelation relation = new EPMapUpgradeToGroupRelation();
relation.setDefaultGroup(false);
relation.setCreationDate(new Date());
relation.setEntry(element);
relation.setValidTo(policy.getTo());
relation.setValidFrom(policy.getFrom());
relation.setGroup(group);
relation.setRole(role);
return relation;
}
private InvitationUpgrade findInvitation(SecurityGroup secGroup) {
String sb = "select invitation from invitationupgrade as invitation where invitation.securityGroup=:secGroup";
List<InvitationUpgrade> invitations = dbInstance.getCurrentEntityManager()
.createQuery(sb, InvitationUpgrade.class)
.setParameter("secGroup", secGroup)
.getResultList();
return invitations.isEmpty() ? null : invitations.get(0);
}
private EPMapUpgradeToGroupRelation createDefaultGroup(EPMapUpgrade element, Group group) {
EPMapUpgradeToGroupRelation relation = new EPMapUpgradeToGroupRelation();
relation.setDefaultGroup(true);
relation.setCreationDate(new Date());
relation.setGroup(group);
relation.setEntry(element);
return relation;
}
private Group findGroupOfBusinessGroup(SecurityGroup secGroup) {
StringBuilder sb = new StringBuilder();
sb.append("select bgi.baseGroup from ").append(BusinessGroupUpgrade.class.getName()).append(" as bgi ")
.append(" where (bgi.partipiciantGroup=:secGroup or bgi.ownerGroup=:secGroup or bgi.waitingGroup=:secGroup)");
List<Group> res = dbInstance.getCurrentEntityManager()
.createQuery(sb.toString(), Group.class)
.setParameter("secGroup", secGroup)
.getResultList();
if(res.isEmpty()) return null;
return res.get(0);
}
private RepositoryEntryUpgrade findMapRepoEntry(SecurityGroup ownerGroup) {
StringBuilder sb = new StringBuilder();
sb.append("select v from ").append(RepositoryEntryUpgrade.class.getName()).append(" as v")
.append(" where v.ownerGroup=:ownerGroup");
List<RepositoryEntryUpgrade> res = dbInstance.getCurrentEntityManager()
.createQuery(sb.toString(), RepositoryEntryUpgrade.class)
.setParameter("ownerGroup", ownerGroup)
.getResultList();
if(res.size() > 0) {
return res.get(0);
}
return null;
}
private List<EPMapUpgrade> findMaps(int firstResult, int maxResults) {
StringBuilder sb = new StringBuilder();
sb.append("select map from ").append(EPMapUpgrade.class.getName()).append(" map")
.append(" where map.ownerGroup is not null")
.append(" order by map.key");
return dbInstance.getCurrentEntityManager().createQuery(sb.toString(), EPMapUpgrade.class)
.setFirstResult(firstResult)
.setMaxResults(maxResults)
.getResultList();
}
private void processSecurityGroup(Group group, String role, SecurityGroup secGroup) {
if(secGroup == null) return;
List<SecurityGroupMembershipImpl> oldMemberships = getMembershipsOfSecurityGroup(secGroup);
for(SecurityGroupMembershipImpl oldMembership:oldMemberships) {
GroupMembershipImpl membership = new GroupMembershipImpl();
membership.setCreationDate(oldMembership.getCreationDate());
membership.setLastModified(oldMembership.getLastModified());
membership.setGroup(group);
membership.setIdentity(oldMembership.getIdentity());
membership.setRole(role);
dbInstance.getCurrentEntityManager().persist(membership);
Set<GroupMembership> members = ((GroupImpl)group).getMembers();
if(members == null) {
members = new HashSet<>();
((GroupImpl)group).setMembers(members);
}
members.add(membership);
}
}
private List<SecurityGroupMembershipImpl> getMembershipsOfSecurityGroup(SecurityGroup secGroup) {
StringBuilder sb = new StringBuilder();
sb.append("select membership from ").append(SecurityGroupMembershipImpl.class.getName()).append(" as membership")
.append(" where membership.securityGroup=:secGroup");
return dbInstance.getCurrentEntityManager()
.createQuery(sb.toString(), SecurityGroupMembershipImpl.class)
.setParameter("secGroup", secGroup)
.getResultList();
}
private List<BusinessGroupUpgrade> findBusinessGroups(int firstResult, int maxResults) {
StringBuilder sb = new StringBuilder();
sb.append("select businessgroup from ").append(BusinessGroupUpgrade.class.getName()).append(" businessgroup")
.append(" left join fetch businessgroup.baseGroup as baseGroup")
.append(" left join fetch businessgroup.ownerGroup as ownerGroup")
.append(" left join fetch businessgroup.partipiciantGroup as partipiciantGroup")
.append(" left join fetch businessgroup.waitingGroup as waitingGroup")
.append(" left join fetch businessgroup.resource as resource")
.append(" order by businessgroup.key");
return dbInstance.getCurrentEntityManager().createQuery(sb.toString(), BusinessGroupUpgrade.class)
.setFirstResult(firstResult)
.setMaxResults(maxResults)
.getResultList();
}
private List<RepositoryEntryUpgrade> findRepositoryEntries(int firstResult, int maxResults) {
StringBuilder sb = new StringBuilder();
sb.append("select v from ").append(RepositoryEntryUpgrade.class.getName()).append(" v")
.append(" inner join fetch v.olatResource as ores")
.append(" left join fetch v.ownerGroup as ownerGroup")
.append(" left join fetch v.participantGroup as participantGroup")
.append(" left join fetch v.tutorGroup as tutorGroup")
.append(" order by v.key");
return dbInstance.getCurrentEntityManager().createQuery(sb.toString(), RepositoryEntryUpgrade.class)
.setFirstResult(firstResult)
.setMaxResults(maxResults)
.getResultList();
}
private RepositoryEntryUpgrade lookupRepositoryEntry(OLATResource ores) {
StringBuilder sb = new StringBuilder();
sb.append("select v from ").append(RepositoryEntryUpgrade.class.getName()).append(" v ")
.append(" inner join fetch v.olatResource as ores")
.append(" left join fetch v.ownerGroup as ownerGroup")
.append(" left join fetch v.participantGroup as participantGroup")
.append(" left join fetch v.tutorGroup as tutorGroup")
.append(" where ores.key = :oreskey");
List<RepositoryEntryUpgrade> result = dbInstance.getCurrentEntityManager()
.createQuery(sb.toString(), RepositoryEntryUpgrade.class)
.setParameter("oreskey", ores.getKey())
.getResultList();
if(result.size() > 0) {
return result.get(0);
}
return null;
}
}