/**
* 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.
*/
package org.olat.group.area;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.persistence.TypedQuery;
import org.olat.basesecurity.GroupRoles;
import org.olat.core.commons.persistence.DB;
import org.olat.core.commons.persistence.DBFactory;
import org.olat.core.id.Identity;
import org.olat.core.logging.OLATRuntimeException;
import org.olat.core.manager.BasicManager;
import org.olat.core.util.StringHelper;
import org.olat.core.util.coordinate.CoordinatorManager;
import org.olat.core.util.coordinate.SyncerCallback;
import org.olat.core.util.coordinate.SyncerExecutor;
import org.olat.group.BusinessGroup;
import org.olat.resource.OLATResource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* Description:<BR/> Implementation of the business group area manager <P/>
* Initial Date: Aug 24, 2004
*
* @author gnaegi
*/
@Service("areaManager")
public class BGAreaManagerImpl extends BasicManager implements BGAreaManager {
@Autowired
private DB dbInstance;
@Override
public BGArea loadArea(Long key) {
return dbInstance.getCurrentEntityManager().find(BGAreaImpl.class, key);
}
@Override
public List<BGArea> loadAreas(List<Long> keys) {
if(keys == null || keys.isEmpty()) return Collections.emptyList();
StringBuilder sb = new StringBuilder();
sb.append("select area from ").append(BGAreaImpl.class.getName()).append(" area ")
.append(" where area.key in (:keys)");
List<BGArea> areas = dbInstance.getCurrentEntityManager().createQuery(sb.toString(), BGArea.class)
.setParameter("keys", keys)
.getResultList();
return areas;
}
/**
* @see org.olat.group.area.BGAreaManager#findBGArea(java.lang.String,
* org.olat.group.context.BGContext)
*/
public BGArea findBGArea(String areaName, OLATResource resource) {
StringBuilder sb = new StringBuilder();
sb.append("select area from ").append(BGAreaImpl.class.getName()).append(" area ")
.append(" where area.name=:areaName and area.resource.key=:resourceKey");
List<BGArea> areas = dbInstance.getCurrentEntityManager().createQuery(sb.toString(), BGArea.class)
.setParameter("areaName", areaName)
.setParameter("resourceKey", resource.getKey())
.getResultList();
if (areas.isEmpty()) {
return null;
} else if (areas.size() > 1) {
throw new OLATRuntimeException(BGAreaManagerImpl.class, "findBGArea(" + areaName+ ") returned more than one row for BGContext with key " + resource.getKey(), null);
}
return areas.get(0);
}
/**
* @see org.olat.group.area.BGAreaManager#updateBGArea(org.olat.group.area.BGArea)
*/
//o_clusterOK by:cg synchronized
public BGArea updateBGArea(final BGArea area) {
// look if an area with such a name does already exist in this context
final OLATResource resource = area.getResource();
BGArea updatedBGArea =CoordinatorManager.getInstance().getCoordinator().getSyncer().doInSync(resource, new SyncerCallback<BGArea>(){
public BGArea execute() {
BGArea reloadArea = loadArea(area.getKey());
reloadArea.setName(area.getName());
reloadArea.setDescription(area.getDescription());
return dbInstance.getCurrentEntityManager().merge(reloadArea);
}
});
return updatedBGArea;
}
/**
* @see org.olat.group.area.BGAreaManager#deleteBGArea(org.olat.group.area.BGArea)
*/
@Override
public void deleteBGArea(final BGArea area) {
final OLATResource resource = area.getResource();
CoordinatorManager.getInstance().getCoordinator().getSyncer().doInSync(resource, new SyncerExecutor() {
@Override
public void execute() {
BGArea reloadArea = loadArea(area.getKey());
if (reloadArea != null) {
// 1) delete all area - group relations
deleteBGtoAreaRelations(reloadArea);
// 2) delete area - assessment mode relations
deleteAssessmentModeToAreaRelations(reloadArea);
// 3) delete area itself
dbInstance.deleteObject(reloadArea);
logAudit("Deleted Business Group Area", reloadArea.toString());
} else {
logAudit("Business Group Area was already deleted", area.toString());
}
}
});
}
/**
* Deletes all business group to area relations from the given business group
*
* @param group
*/
@Override
public void deleteBGtoAreaRelations(BusinessGroup group) {
StringBuilder sb = new StringBuilder();
sb.append(" delete from ").append(BGtoAreaRelationImpl.class.getName()).append(" as bgarel where bgarel.businessGroup.key=:groupKey");
dbInstance.getCurrentEntityManager().createQuery(sb.toString())
.setParameter("groupKey", group.getKey())
.executeUpdate();
}
/**
* @see org.olat.group.area.BGAreaManager#addBGToBGArea(org.olat.group.BusinessGroup,
* org.olat.group.area.BGArea)
*/
public void addBGToBGArea(BusinessGroup group, BGArea area) {
BGtoAreaRelation bgAreaRel = new BGtoAreaRelationImpl(area, group);
dbInstance.saveObject(bgAreaRel);
}
/**
* @see org.olat.group.area.BGAreaManager#removeBGFromArea(org.olat.group.BusinessGroup,
* org.olat.group.area.BGArea)
*/
public void removeBGFromArea(BusinessGroup group, BGArea area) {
removeBGFromArea(group.getKey(), area.getKey());
}
/**
* @see org.olat.group.area.BGAreaManager#findBusinessGroupsOfArea(org.olat.group.area.BGArea)
*/
public List<BusinessGroup> findBusinessGroupsOfArea(BGArea area) {
return findBusinessGroupsOfAreas(Collections.singletonList(area));
}
@Override
public List<BusinessGroup> findBusinessGroupsOfAreas(List<BGArea> areas) {
if(areas == null || areas.isEmpty()) return Collections.emptyList();
List<Long> areaKeys = new ArrayList<Long>();
for(BGArea area:areas) {
areaKeys.add(area.getKey());
}
return findBusinessGroupsOfAreaKeys(areaKeys);
}
@Override
public List<BusinessGroup> findBusinessGroupsOfAreaKeys(List<Long> areaKeys) {
if(areaKeys == null || areaKeys.isEmpty()) return Collections.emptyList();
StringBuilder sb = new StringBuilder();
sb.append("select distinct businessGroup from ").append(BGtoAreaRelationImpl.class.getName()).append(" as bgarel ")
.append(" inner join bgarel.businessGroup businessGroup ")
.append(" left join fetch businessGroup.resource resource")
.append(" where bgarel.groupArea.key in (:areaKeys)");
return DBFactory.getInstance().getCurrentEntityManager()
.createQuery(sb.toString(), BusinessGroup.class)
.setParameter("areaKeys", areaKeys)
.getResultList();
}
@Override
public List<Long> findBusinessGroupKeysOfAreaKeys(List<Long> areaKeys) {
if(areaKeys == null || areaKeys.isEmpty()) return Collections.emptyList();
StringBuilder sb = new StringBuilder();
sb.append("select distinct businessGroup.key from ").append(BGtoAreaRelationImpl.class.getName()).append(" as bgarel ")
.append(" inner join bgarel.businessGroup businessGroup ")
.append(" where bgarel.groupArea.key in (:areaKeys)");
return DBFactory.getInstance().getCurrentEntityManager()
.createQuery(sb.toString(), Long.class)
.setParameter("areaKeys", areaKeys)
.getResultList();
}
/**
* @see org.olat.group.area.BGAreaManager#findBusinessGroupsOfAreaAttendedBy(org.olat.core.id.Identity,
* java.lang.String, org.olat.group.context.BGContext)
*/
@Override
public List<BusinessGroup> findBusinessGroupsOfAreaAttendedBy(Identity identity, List<Long> areaKeys, OLATResource resource) {
StringBuilder sb = new StringBuilder();
sb.append("select distinct grp from ").append(BGtoAreaRelationImpl.class.getName()).append(" as bgarel")
.append(" inner join bgarel.businessGroup as grp")
.append(" inner join bgarel.groupArea as area")
.append(" inner join grp.baseGroup as baseGroup")
.append(" inner join baseGroup.members as membership")
.append(" where membership.identity.key=:identityKey and membership.role='").append(GroupRoles.participant.name()).append("'");
if(areaKeys != null && !areaKeys.isEmpty()) {
sb.append(" and area.key in (:areaKeys)");
}
if(resource != null) {
sb.append(" and area.resource.key=:resourceKey");
}
TypedQuery<BusinessGroup> query = dbInstance.getCurrentEntityManager().createQuery(sb.toString(), BusinessGroup.class)
.setParameter("identityKey", identity.getKey());
if(areaKeys != null && !areaKeys.isEmpty()) {
query.setParameter("areaKeys", areaKeys);
}
if(resource != null) {
query.setParameter("resourceKey", resource.getKey());
}
List<BusinessGroup> groups = query.getResultList();
return groups;
}
/**
* @see org.olat.group.area.BGAreaManager#findBGAreasOfBusinessGroup(org.olat.group.BusinessGroup)
*/
public List<BGArea> findBGAreasOfBusinessGroup(BusinessGroup group) {
return findBGAreasOfBusinessGroups(Collections.singletonList(group));
}
@Override
public List<BGArea> findBGAreasOfBusinessGroups(List<BusinessGroup> groups) {
if(groups == null || groups.isEmpty()) return Collections.emptyList();
StringBuilder sb = new StringBuilder();
sb.append("select distinct bgarel.groupArea from ").append(BGtoAreaRelationImpl.class.getName()).append(" as bgarel ")
.append("where bgarel.businessGroup.key in (:groupKeys)");
TypedQuery<BGArea> areaQuery = dbInstance.getCurrentEntityManager().createQuery(sb.toString(), BGArea.class);
List<Long> groupKeys = new ArrayList<Long>();
for(BusinessGroup group:groups) {
groupKeys.add(group.getKey());
}
areaQuery.setParameter("groupKeys", groupKeys);
return areaQuery.getResultList();
}
@Override
public int countBGAreasOfBusinessGroups(List<BusinessGroup> groups) {
if(groups == null || groups.isEmpty()) return 0;
StringBuilder sb = new StringBuilder();
sb.append("select count(distinct bgarel.groupArea.key) from ").append(BGtoAreaRelationImpl.class.getName()).append(" as bgarel ")
.append("where bgarel.businessGroup.key in (:groupKeys)");
TypedQuery<Number> areaQuery = dbInstance.getCurrentEntityManager().createQuery(sb.toString(), Number.class);
List<Long> groupKeys = new ArrayList<Long>();
for(BusinessGroup group:groups) {
groupKeys.add(group.getKey());
}
areaQuery.setParameter("groupKeys", groupKeys);
return areaQuery.getSingleResult().intValue();
}
/**
* @see org.olat.group.area.BGAreaManager#countBGAreasOfBGContext(org.olat.group.context.BGContext)
*/
@Override
public int countBGAreasInContext(OLATResource resource) {
StringBuilder sb = new StringBuilder();
sb.append("select count(area) from ").append(BGAreaImpl.class.getName()).append(" area where area.resource.key=:resourceKey");
Number count = dbInstance.getCurrentEntityManager().createQuery(sb.toString(), Number.class)
.setParameter("resourceKey", resource.getKey())
.setHint("org.hibernate.cacheable", Boolean.TRUE)
.getSingleResult();
return count.intValue();
}
/**
* @see org.olat.group.area.BGAreaManager#findBGAreasOfBGContext(org.olat.group.context.BGContext)
*/
@Override
public List<BGArea> findBGAreasInContext(OLATResource resource) {
StringBuilder sb = new StringBuilder();
sb.append("select area from ").append(BGAreaImpl.class.getName()).append(" area where area.resource.key=:resourceKey");
List<BGArea> areas = dbInstance.getCurrentEntityManager().createQuery(sb.toString(), BGArea.class)
.setParameter("resourceKey", resource.getKey())
.getResultList();
return areas;
}
/**
* @see org.olat.group.area.BGAreaManager#isIdentityInBGArea(org.olat.core.id.Identity,
* java.lang.String, org.olat.group.context.BGContext)
*/
public boolean isIdentityInBGArea(Identity identity, String areaName, Long areaKey, OLATResource resource) {
StringBuilder sb = new StringBuilder();
sb.append("select count(bgarel) from ").append(BGtoAreaRelationImpl.class.getName()).append(" as bgarel")
.append(" inner join bgarel.businessGroup as grp")
.append(" inner join bgarel.groupArea as area")
.append(" inner join grp.baseGroup as baseGroup")
.append(" inner join baseGroup.members as membership")
.append(" where area.resource.key=:resourceKey ")
.append(" and membership.identity.key=:identityKey and membership.role in ('").append(GroupRoles.coach.name()).append("','").append(GroupRoles.participant.name()).append("')");
if(StringHelper.containsNonWhitespace(areaName)) {
sb.append(" and area.name=:name ");
}
if(areaKey != null) {
sb.append(" and area.key=:areaKey ");
}
TypedQuery<Number> query = dbInstance.getCurrentEntityManager().createQuery(sb.toString(), Number.class)
.setParameter("identityKey", identity.getKey())
.setParameter("resourceKey", resource.getKey());
if(StringHelper.containsNonWhitespace(areaName)) {
query.setParameter("name", areaName);
}
if(areaKey != null) {
query.setParameter("areaKey", areaKey);
}
Number count = query
.setHint("org.hibernate.cacheable", Boolean.TRUE)
.getSingleResult();
return count.intValue() > 0;
}
/**
* @see org.olat.group.area.BGAreaManager#reloadArea(org.olat.group.area.BGArea)
*/
public BGArea reloadArea(BGArea area) {
return (BGArea) DBFactory.getInstance().loadObject(area);
}
@Override
public boolean existArea(String nameOrKey, OLATResource resource) {
Long key = null;
if(StringHelper.isLong(nameOrKey)) {
key = new Long(nameOrKey);
}
StringBuilder sb = new StringBuilder();
sb.append("select count(area) from ").append(BGAreaImpl.class.getName()).append(" area ")
.append(" where area.resource.key=:resourceKey and area.");
if(key == null) {
sb.append("name");
} else {
sb.append("key");
}
sb.append("=:nameOrKey");
Number count = dbInstance.getCurrentEntityManager().createQuery(sb.toString(), Number.class)
.setParameter("resourceKey", resource.getKey())
.setParameter("nameOrKey", key == null ? nameOrKey : key)
.setHint("org.hibernate.cacheable", Boolean.TRUE)
.getSingleResult();
return count.intValue() > 0;
}
@Override
public List<Long> toAreaKeys(String areaNames, OLATResource resource) {
if(!StringHelper.containsNonWhitespace(areaNames)) return Collections.emptyList();
String[] areaNameArr = areaNames.split(",");
List<String> areaNameList = new ArrayList<String>();
for(String areaName:areaNameArr) {
areaNameList.add(areaName.trim());
}
if(areaNameList.isEmpty()) return Collections.emptyList();
StringBuilder sb = new StringBuilder();
sb.append("select area.key from ").append(BGAreaImpl.class.getName()).append(" area")
.append(" where area.resource.key=:resourceKey and area.name in (:names)");
List<Long> keys = dbInstance.getCurrentEntityManager().createQuery(sb.toString(), Long.class)
.setParameter("resourceKey", resource.getKey())
.setParameter("names", areaNameList)
.setHint("org.hibernate.cacheable", Boolean.TRUE)
.getResultList();
return keys;
}
/**
* Creates an area object and persists the object in the database
*
* @param areaName The visible area name
* @param description The area description
* @param resource The resource of this area
* @return The new area
*/
@Override
public BGArea createAndPersistBGArea(String areaName, String description, OLATResource resource) {
BGArea area = new BGAreaImpl(areaName, description, resource);
dbInstance.getCurrentEntityManager().persist(area);
if (area != null) {
logAudit("Created Business Group Area", area.toString());
}
// else no area created, name duplicate
return area;
}
/**
* Remove a business group from a business group area. If no such relation
* exists, the method does nothing.
*
* @param businessGroupKey
* @param bgAreaKey
*/
private void removeBGFromArea(Long businessGroupKey, Long bgAreaKey) {
StringBuilder sb = new StringBuilder();
sb.append("delete from ").append(BGtoAreaRelationImpl.class.getName()).append(" as bgarel where bgarel.groupArea.key=:areaKey and bgarel.businessGroup.key=:groupKey");
dbInstance.getCurrentEntityManager().createQuery(sb.toString())
.setParameter("areaKey", bgAreaKey)
.setParameter("groupKey", businessGroupKey)
.executeUpdate();
}
/**
* Deletes all business group to area relations from the given business group
* area
*
* @param area
*/
private void deleteBGtoAreaRelations(BGArea area) {
StringBuilder sb = new StringBuilder();
sb.append("delete from ").append(BGtoAreaRelationImpl.class.getName()).append(" as bgarel where bgarel.groupArea.key=:areaKey");
dbInstance.getCurrentEntityManager().createQuery(sb.toString())
.setParameter("areaKey", area.getKey())
.executeUpdate();
}
private void deleteAssessmentModeToAreaRelations(BGArea area) {
StringBuilder sb = new StringBuilder();
sb.append("delete from courseassessmentmodetoarea as modearel where modearel.area.key=:areaKey");
dbInstance.getCurrentEntityManager().createQuery(sb.toString())
.setParameter("areaKey", area.getKey())
.executeUpdate();
}
}