/**
* 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.
* <p>
*/
package org.olat.course.nodes.projectbroker.service;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.StringTokenizer;
import org.hibernate.Hibernate;
import org.hibernate.type.Type;
import org.olat.basesecurity.ManagerFactory;
import org.olat.basesecurity.SecurityGroup;
import org.olat.core.commons.modules.bc.vfs.OlatRootFolderImpl;
import org.olat.core.commons.persistence.DBFactory;
import org.olat.core.id.Identity;
import org.olat.core.id.OLATResourceable;
import org.olat.core.logging.OLog;
import org.olat.core.logging.Tracing;
import org.olat.core.util.FileUtils;
import org.olat.core.util.cache.n.CacheWrapper;
import org.olat.core.util.coordinate.CoordinatorManager;
import org.olat.core.util.coordinate.SyncerCallback;
import org.olat.core.util.coordinate.SyncerExecutor;
import org.olat.core.util.resource.OresHelper;
import org.olat.core.util.vfs.VFSContainer;
import org.olat.core.util.vfs.VFSItem;
import org.olat.core.util.vfs.VFSLeaf;
import org.olat.course.nodes.CourseNode;
import org.olat.course.nodes.ProjectBrokerCourseNode;
import org.olat.course.nodes.projectbroker.ProjectBrokerDropboxController;
import org.olat.course.nodes.projectbroker.ProjectBrokerNodeConfiguration;
import org.olat.course.nodes.projectbroker.ProjectBrokerReturnboxController;
import org.olat.course.nodes.projectbroker.datamodel.Project;
import org.olat.course.nodes.projectbroker.datamodel.ProjectBroker;
import org.olat.course.nodes.projectbroker.datamodel.ProjectBrokerImpl;
import org.olat.course.nodes.projectbroker.datamodel.ProjectEvent;
import org.olat.course.nodes.projectbroker.datamodel.ProjectImpl;
import org.olat.course.nodes.projectbroker.datamodel.Project.EventType;
import org.olat.course.properties.CoursePropertyManager;
import org.olat.course.run.environment.CourseEnvironment;
import org.olat.group.BusinessGroup;
import org.olat.group.BusinessGroupManagerImpl;
import org.olat.group.DeletableGroupData;
import org.olat.group.DeletableReference;
import org.olat.properties.Property;
import org.olat.testutils.codepoints.server.Codepoint;
/**
*
* @author guretzki
*/
public class ProjectBrokerManagerImpl implements ProjectBrokerManager, DeletableGroupData{
private static final String ATTACHEMENT_DIR_NAME = "projectbroker_attach";
private OLog log = Tracing.createLoggerFor(this.getClass());
private CacheWrapper projectCache;
protected ProjectBrokerManagerImpl() {
// cache name should not be too long e.g. 'projectbroker' is too long, use 'pb' instead.
projectCache = CoordinatorManager.getCoordinator().getCacher().getOrCreateCache(ProjectBrokerManagerImpl.class, "pb");
BusinessGroupManagerImpl.getInstance().registerDeletableGroupDataListener(this);
log.debug("ProjectBrokerManagerImpl created");
}
/**
* @param projectbroker_id
* @return List of projects for certain project-broker
*/
public List<Project> getProjectListBy(final Long projectBrokerId) {
log.debug("getProjectListBy for projectBroker=" + projectBrokerId);
long rstart = 0;
if(log.isDebug()){
rstart = System.currentTimeMillis();
}
OLATResourceable projectBrokerOres = OresHelper.createOLATResourceableInstance(this.getClass(),projectBrokerId);
List<Project> projectList = CoordinatorManager.getCoordinator().getSyncer().doInSync( projectBrokerOres, new SyncerCallback<List<Project>>() {
public List<Project> execute() {
ProjectBroker projectBroker = getOrLoadProjectBoker(projectBrokerId);
return projectBroker.getProjects();
}
});
if(log.isDebug()){
long rstop = System.currentTimeMillis();
log.debug("time to fetch project with projectbroker_id " + projectBrokerId + " :" + (rstop - rstart), null);
}
return projectList;
}
public ProjectBroker createAndSaveProjectBroker() {
ProjectBroker projectBroker = new ProjectBrokerImpl();
DBFactory.getInstance().saveObject(projectBroker);
return projectBroker;
}
public Project createAndSaveProjectFor(String title, String description, final Long projectBrokerId, BusinessGroup projectGroup) {
OLATResourceable projectBrokerOres = OresHelper.createOLATResourceableInstance(this.getClass(),projectBrokerId);
final Project project = new ProjectImpl(title, description, projectGroup, getProjectBroker(projectBrokerId));
CoordinatorManager.getCoordinator().getSyncer().doInSync( projectBrokerOres, new SyncerExecutor() {
public void execute() {
DBFactory.getInstance().saveObject(project);
ProjectBroker projectBroker = getOrLoadProjectBoker(projectBrokerId);
projectBroker.getProjects().add(project);
projectCache.update(projectBrokerId.toString(), projectBroker);
}
});
return project;
}
public int getSelectedPlaces(Project project) {
return ManagerFactory.getManager().countIdentitiesOfSecurityGroup(project.getProjectParticipantGroup()) +
ManagerFactory.getManager().countIdentitiesOfSecurityGroup(project.getCandidateGroup());
}
// TODO:cg/05.01.2010 Refactoring : move this method into ProjectGroupManager
public boolean isProjectManager(Identity identity, Project project) {
return ManagerFactory.getManager().isIdentityInSecurityGroup(identity, project.getProjectLeaderGroup());
}
public void updateProject(final Project project) {
final Long projectBrokerId = project.getProjectBroker().getKey();
OLATResourceable projectBrokerOres = OresHelper.createOLATResourceableInstance(this.getClass(),projectBrokerId);
CoordinatorManager.getCoordinator().getSyncer().doInSync( projectBrokerOres, new SyncerExecutor() {
public void execute() {
DBFactory.getInstance().updateObject(project);
// invalide with removing from cache
projectCache.remove(projectBrokerId.toString());
}
});
}
// TODO:cg/05.01.2010 Refactoring : move this method into ProjectGroupManager
public boolean isProjectParticipant(Identity identity, Project project) {
return ManagerFactory.getManager().isIdentityInSecurityGroup(identity, project.getProjectParticipantGroup());
}
// TODO:cg/05.01.2010 Refactoring : move this method into ProjectGroupManager
public boolean isProjectCandidate(Identity identity, Project project) {
return ManagerFactory.getManager().isIdentityInSecurityGroup(identity, project.getCandidateGroup());
}
public boolean enrollProjectParticipant(final Identity identity, final Project project, final ProjectBrokerModuleConfiguration moduleConfig, final int nbrSelectedProjects, final boolean isParticipantInAnyProject) {
OLATResourceable projectOres = OresHelper.createOLATResourceableInstance(Project.class, project.getKey());
log.debug("enrollProjectParticipant: start identity=" + identity + " project=" + project);
Codepoint.codepoint(ProjectBrokerManagerImpl.class, "beforeDoInSync");
Boolean result = CoordinatorManager.getCoordinator().getSyncer().doInSync(projectOres, new SyncerCallback<Boolean>(){
public Boolean execute() {
// For cluster-safe : reload project object here another node might have changed this in the meantime
Project reloadedProject = (Project) DBFactory.getInstance().loadObject(project, true);
log.debug("enrollProjectParticipant: project.getMaxMembers()=" + reloadedProject.getMaxMembers());
log.debug("enrollProjectParticipant: project.getSelectedPlaces()=" + reloadedProject.getSelectedPlaces());
if ( ProjectBrokerManagerFactory.getProjectBrokerManager().canBeProjectSelectedBy(identity, reloadedProject, moduleConfig, nbrSelectedProjects, isParticipantInAnyProject) ) {
if (moduleConfig.isAcceptSelectionManually() ) {
ManagerFactory.getManager().addIdentityToSecurityGroup(identity, reloadedProject.getCandidateGroup());
log.audit("ProjectBroker: Add as candidate identity=" + identity + " to project=" + reloadedProject);
} else {
ManagerFactory.getManager().addIdentityToSecurityGroup(identity, reloadedProject.getProjectParticipantGroup());
log.audit("ProjectBroker: Add as participant identity=" + identity + " to project=" + reloadedProject);
if ( (reloadedProject.getMaxMembers() != Project.MAX_MEMBERS_UNLIMITED) && (reloadedProject.getSelectedPlaces() >= reloadedProject.getMaxMembers()) ) {
reloadedProject.setState(Project.STATE_ASSIGNED);
DBFactory.getInstance().updateObject(reloadedProject);
}
}
return Boolean.TRUE;
} else {
log.debug("ProjectBroker: project-group was full for identity=" + identity + " , project=" + reloadedProject);
return Boolean.FALSE;
}
}
});// end of doInSync
Codepoint.codepoint(ProjectBrokerManagerImpl.class, "afterDoInSync");
return result.booleanValue();
}
public boolean cancelProjectEnrollmentOf(final Identity identity, final Project project, final ProjectBrokerModuleConfiguration moduleConfig) {
OLATResourceable projectOres = OresHelper.createOLATResourceableInstance(Project.class, project.getKey());
Codepoint.codepoint(ProjectBrokerManagerImpl.class, "beforeDoInSync");
Boolean result = CoordinatorManager.getCoordinator().getSyncer().doInSync(projectOres, new SyncerCallback<Boolean>(){
public Boolean execute() {
// For cluster-safe : reload project object here another node might have changed this in the meantime
Project reloadedProject = (Project) DBFactory.getInstance().loadObject(project, true);
// User can only cancel enrollment, when state is 'NOT_ASSIGNED'
if (canBeCancelEnrollmentBy(identity, project, moduleConfig)) {
ManagerFactory.getManager().removeIdentityFromSecurityGroup(identity, reloadedProject.getProjectParticipantGroup());
ManagerFactory.getManager().removeIdentityFromSecurityGroup(identity, reloadedProject.getCandidateGroup());
log.audit("ProjectBroker: Remove (as participant or waitinglist) identity=" + identity + " from project=" + project);
if ( (reloadedProject.getMaxMembers() != Project.MAX_MEMBERS_UNLIMITED) && (reloadedProject.getSelectedPlaces() < reloadedProject.getMaxMembers()) ) {
reloadedProject.setState(Project.STATE_NOT_ASSIGNED);
DBFactory.getInstance().updateObject(reloadedProject);
}
return Boolean.TRUE;
} else {
return Boolean.FALSE;
}
}
});// end of doInSync
Codepoint.codepoint(ProjectBrokerManagerImpl.class, "afterDoInSync");
return result.booleanValue();
}
/**
* Delete a project and delete project-groups related to this project.
* This method is cluster-save.
* @see org.olat.course.nodes.projectbroker.service.ProjectBrokerManager#deleteProject(org.olat.course.nodes.projectbroker.datamodel.Project)
*/
public void deleteProject(final Project project, final boolean deleteGroup, final CourseEnvironment courseEnv, final CourseNode cNode) {
log.debug("start deleteProject project=" + project);
final Long projectBrokerId = project.getProjectBroker().getKey();
OLATResourceable projectBrokerOres = OresHelper.createOLATResourceableInstance(this.getClass(),projectBrokerId);
CoordinatorManager.getCoordinator().getSyncer().doInSync( projectBrokerOres, new SyncerExecutor() {
public void execute() {
// delete first candidate-group, project-group will be deleted after deleting project
SecurityGroup candidateGroup = project.getCandidateGroup();
if ( (courseEnv != null) && (cNode != null) ) {
deleteAllAttachmentFilesOfProject(project, courseEnv, cNode);
deleteAllDropboxFilesOfProject(project, courseEnv, cNode);
deleteAllReturnboxFilesOfProject(project, courseEnv, cNode);
}
DBFactory.getInstance().deleteObject(project);
log.info("deleteSecurityGroup(project.getCandidateGroup())=" + candidateGroup.getKey());
ManagerFactory.getManager().deleteSecurityGroup(candidateGroup);
ProjectBroker projectBroker = getOrLoadProjectBoker(projectBrokerId);
projectBroker.getProjects().remove(project);
projectCache.update(projectBrokerId.toString(), projectBroker);
}
});
if (deleteGroup) {
log.debug("start deleteProjectGroupFor project=" + project);
ProjectBrokerManagerFactory.getProjectGroupManager().deleteProjectGroupFor(project);
}
log.debug("DONE deleteProjectGroupFor project=" + project);
}
public int getNbrSelectedProjects(Identity identity, List<Project> projectList) {
int selectedCounter = 0;
for (Iterator iterator = projectList.iterator(); iterator.hasNext();) {
Project project = (Project) iterator.next();
if (ManagerFactory.getManager().isIdentityInSecurityGroup(identity, project.getProjectParticipantGroup()) ||
ManagerFactory.getManager().isIdentityInSecurityGroup(identity, project.getCandidateGroup()) ) {
selectedCounter++;
}
}
return selectedCounter;
}
/**
* return true, when the project can be selected by the user.
* @see org.olat.course.nodes.projectbroker.datamodel.Project#canBeSelectedBy(org.olat.core.id.Identity)
*/
public boolean canBeProjectSelectedBy(Identity identity, Project project, ProjectBrokerModuleConfiguration moduleConfig, int nbrSelectedProjects, boolean isParticipantInAnyProject) {
log.debug("canBeSelectedBy: identity=" + identity + " project=" + project);
// 1. check if already enrolled
if (isProjectParticipant(identity, project) || isProjectCandidate(identity, project)) {
log.debug("canBeSelectedBy: return false because identity is already enrolled");
return false;
}
// 2. check number of max project members
int projectMembers = ManagerFactory.getManager().countIdentitiesOfSecurityGroup(project.getProjectParticipantGroup()) +
ManagerFactory.getManager().countIdentitiesOfSecurityGroup(project.getCandidateGroup());
if ( (project.getMaxMembers() != Project.MAX_MEMBERS_UNLIMITED) && (projectMembers >= project.getMaxMembers()) ) {
log.debug("canBeSelectedBy: return false because projectMembers >= getMaxMembers()");
return false;
}
// 3. number of selected topic per user
int nbrOfParticipantsPerTopicValue = moduleConfig.getNbrParticipantsPerTopic();
if ( (nbrOfParticipantsPerTopicValue != moduleConfig.NBR_PARTICIPANTS_UNLIMITED) &&
(nbrSelectedProjects >= nbrOfParticipantsPerTopicValue) ) {
log.debug("canBeSelectedBy: return false because number of selected topic per user is " + nbrOfParticipantsPerTopicValue);
return false;
}
// 4. accept is done manually
if (moduleConfig.isAcceptSelectionManually() ) {
// 4.1 and project-state is assigned
if (project.getState().equals(Project.STATE_ASSIGNED) ) {
log.debug("canBeSelectedBy: return false because accept is done manually and project-state is assigned, project.getState()=" + project.getState());
return false;
}
// 4.2. and user is already assigned in another project
if (moduleConfig.isAcceptSelectionManually() && moduleConfig.isAutoSignOut() && isParticipantInAnyProject ) {
log.debug("canBeSelectedBy: return false because accept is done manually and user is already participant in another project" );
return false;
}
}
// 5. date for enrollment ok
if (!isEnrollmentDateOk(project,moduleConfig) ){
log.debug("canBeSelectedBy: return false because enrollment date not valid =" + project.getProjectEvent(EventType.ENROLLMENT_EVENT));
return false;
}
log.debug("canBeSelectedBy: return true");
return true;
}
public boolean canBeCancelEnrollmentBy(Identity identity,Project project,ProjectBrokerModuleConfiguration moduleConfig) {
log.debug("canBeCancelEnrollmentBy: identity=" + identity + " project=" + project);
// 6. date for enrollemnt ok
if (!isEnrollmentDateOk(project,moduleConfig) ){
log.debug("canBeCancelEnrollmentBy: return false because isEnrollmentDateOk is false");
return false;
}
if (moduleConfig.isAcceptSelectionManually()) {
// could only cancel enrollment, when projectleader did not accept yet
boolean isProjectCandidate = isProjectCandidate(identity, project) && !project.getState().equals(Project.STATE_ASSIGNED);
log.debug("canBeCancelEnrollmentBy: isAcceptSelectionManually is true, returning isProjectCandidate="+isProjectCandidate);
return isProjectCandidate;
} else {
// could always cancel enrollment
boolean isProjectParticipant = isProjectParticipant(identity, project);
log.debug("canBeCancelEnrollmentBy: isAcceptSelectionManually is false, returning isProjectParticipant="+isProjectParticipant);
return isProjectParticipant;
}
}
public void signOutFormAllCandidateList(final List<Identity> chosenIdentities, final Long projectBrokerId) {
OLATResourceable projectBrokerOres = OresHelper.createOLATResourceableInstance(this.getClass(),projectBrokerId);
CoordinatorManager.getCoordinator().getSyncer().doInSync( projectBrokerOres, new SyncerExecutor() {
public void execute() {
ProjectBroker projectBroker = getOrLoadProjectBoker(projectBrokerId);
for (Iterator iterator = projectBroker.getProjects().iterator(); iterator.hasNext();) {
Project project = (Project) iterator.next();
// loop over all identities
for (Iterator iterator2 = chosenIdentities.iterator(); iterator2.hasNext();) {
Identity identity = (Identity) iterator2.next();
ManagerFactory.getManager().removeIdentityFromSecurityGroup(identity, project.getCandidateGroup());
log.audit("ProjectBroker: AutoSignOut: identity=" + identity + " from project=" + project);
}
}
}
});
}
public String getStateFor(Project project, Identity identity, ProjectBrokerModuleConfiguration moduleConfig) {
if (moduleConfig.isAcceptSelectionManually() ) {
// Accept manually : unterscheiden Betreuer | Teilnehmer
if (isProjectManager(identity, project)) {
// State Betreuer : Teilnehmer prüfen | Teilnemher akzeptiert
if (project.getState().equals(Project.STATE_ASSIGNED)) {
return Project.STATE_ASSIGNED_ACCOUNT_MANAGER;
} else {
if (ManagerFactory.getManager().countIdentitiesOfSecurityGroup(project.getCandidateGroup()) > 0) {
return Project.STATE_NOT_ASSIGNED_ACCOUNT_MANAGER;
} else {
return Project.STATE_NOT_ASSIGNED_ACCOUNT_MANAGER_NO_CANDIDATE;
}
}
} else {
// State Teilnehmer : prov. eingeschrieben | definitiv eingeschrieben | belegt | frei
if (isProjectParticipant(identity, project)) {
return Project.STATE_FINAL_ENROLLED;
} else if (isProjectCandidate(identity, project)){
return Project.STATE_PROV_ENROLLED;
} else {
if ( ((project.getMaxMembers() != Project.MAX_MEMBERS_UNLIMITED) && (project.getSelectedPlaces() >= project.getMaxMembers()))
|| project.getState().equals(Project.STATE_ASSIGNED)) {
return Project.STATE_COMPLETE;
} else {
return Project.STATE_NOT_ASSIGNED;
}
}
}
} else {
// Accept automatically => State : frei | belegt | eingeschrieben
if (isProjectParticipant(identity, project)) {
return Project.STATE_ENROLLED;
} else {
if ( (project.getMaxMembers() != Project.MAX_MEMBERS_UNLIMITED) && (project.getSelectedPlaces() >= project.getMaxMembers()) ) {
return Project.STATE_COMPLETE;
} else {
return Project.STATE_NOT_ASSIGNED;
}
}
}
}
public void deleteProjectBroker(Long projectBrokerId, CourseEnvironment courseEnvironment, CourseNode courseNode) {
log.debug("Start deleting projectBrokerId=" + projectBrokerId );
ProjectBroker projectBroker = getOrLoadProjectBoker(projectBrokerId);
// delete all projects of a project-broker
List<Project> deleteProjectList = new ArrayList<Project>();
deleteProjectList.addAll(projectBroker.getProjects());
for (Iterator iterator = deleteProjectList.iterator(); iterator.hasNext();) {
Project project = (Project) iterator.next();
deleteProject(project, true, courseEnvironment, courseNode);
log.audit("ProjectBroker: Deleted project=" + project );
}
log.debug("All projects are deleted for ProjectBroker=" + projectBroker);
ProjectBrokerManagerFactory.getProjectGroupManager().deleteAccountManagerGroup(courseEnvironment.getCoursePropertyManager(), courseNode);
DBFactory.getInstance().deleteObject(projectBroker);
log.audit("ProjectBroker: Deleted ProjectBroker=" + projectBroker);
}
public void saveAttachedFile(Project project, String fileName, VFSLeaf uploadedItem, CourseEnvironment courseEnv, CourseNode cNode) {
log.debug("saveAttachedFile file-name=" + uploadedItem.getName());
OlatRootFolderImpl uploadVFSContainer = new OlatRootFolderImpl(getAttamchmentRelativeRootPath(project,courseEnv,cNode), null);
log.debug("saveAttachedFile uploadVFSContainer.relPath=" + uploadVFSContainer.getRelPath());
// only one attachment, delete other file
for (Iterator<VFSItem> iterator = uploadVFSContainer.getItems().iterator(); iterator.hasNext();) {
VFSItem item = iterator.next();
// Project.getAttachmentFileName is the previous file-name, will not be deleted; student could have open detail-project page with previous attachemnt-link
if (!item.getName().equals(project.getAttachmentFileName())) {
item.delete();
}
}
VFSLeaf newFile = (VFSLeaf)uploadVFSContainer.resolve(fileName);
if (newFile == null) {
newFile = uploadVFSContainer.createChildLeaf(fileName);
}
BufferedInputStream in = new BufferedInputStream(uploadedItem.getInputStream());
BufferedOutputStream out = new BufferedOutputStream(newFile.getOutputStream(false));
boolean success = false;
if (in != null) {
success = FileUtils.copy(in, out);
}
FileUtils.closeSafely(in);
FileUtils.closeSafely(out);
log.debug("saveAttachedFile success=" + success);
}
public boolean isCustomFieldValueValid(String value, String valueList) {
StringTokenizer tok = new StringTokenizer(valueList,ProjectBrokerManager.CUSTOMFIELD_LIST_DELIMITER);
if (tok.hasMoreTokens()) {
// It is a list of values => check if value is one of them
while (tok.hasMoreTokens()) {
if (tok.nextToken().equalsIgnoreCase(value) ) {
return true;
}
}
return false;
} else {
// no value-list => value can be any value
return true;
}
}
public String getAttamchmentRelativeRootPath(Project project, CourseEnvironment courseEnv, CourseNode cNode) {
return getAttachmentBasePathRelToFolderRoot(courseEnv, cNode) + File.separator + project.getKey();
}
public String getAttachmentBasePathRelToFolderRoot(CourseEnvironment courseEnvironment, CourseNode courseNode) {
return courseEnvironment.getCourseBaseContainer().getRelPath() + File.separator + ATTACHEMENT_DIR_NAME + File.separator + courseNode.getIdent();
}
private void deleteAllAttachmentFilesOfProject(Project project, CourseEnvironment courseEnv, CourseNode cNode) {
VFSContainer attachmentDir = new OlatRootFolderImpl(getAttamchmentRelativeRootPath(project,courseEnv,cNode), null);
attachmentDir.delete();
log.debug("deleteAllAttachmentFilesOfProject path=" + attachmentDir);
}
private void deleteAllDropboxFilesOfProject(Project project, CourseEnvironment courseEnv, CourseNode cNode) {
VFSContainer dropboxDir = new OlatRootFolderImpl(ProjectBrokerDropboxController.getDropboxBasePathForProject(project,courseEnv,cNode), null);
dropboxDir.delete();
log.debug("deleteAllDropboxFilesOfProject path=" + dropboxDir);
}
private void deleteAllReturnboxFilesOfProject(Project project, CourseEnvironment courseEnv, CourseNode cNode) {
VFSContainer returnboxDir = new OlatRootFolderImpl(ProjectBrokerReturnboxController.getReturnboxBasePathForProject(project,courseEnv,cNode), null);
returnboxDir.delete();
log.debug("deleteAllReturnboxFilesOfProject path=" + returnboxDir);
}
///////////////////
// Private Methods
///////////////////
private ProjectBroker getOrLoadProjectBoker(final Long projectBrokerId) {
// 1. check if alreday a projectBroker is in the cache
ProjectBroker projectBroker = (ProjectBroker)projectCache.get(projectBrokerId.toString());
if (projectBroker == null) {
log.debug("find no projectBroker in the cache => create a new one projectBrokerId=" + projectBrokerId);
List projectList = DBFactory.getInstance().find(
"select project from org.olat.course.nodes.projectbroker.datamodel.ProjectImpl as project" +
" where project.projectBroker.key = ?", projectBrokerId, Hibernate.LONG);
projectBroker = getProjectBroker(projectBrokerId);
projectBroker.setProjects(projectList);
projectCache.put(projectBrokerId.toString(), projectBroker);
}
return projectBroker;
}
private ProjectBroker getProjectBroker(Long projectBrokerId) {
return (ProjectBroker) DBFactory.getInstance().loadObject(ProjectBrokerImpl.class, projectBrokerId);
}
private boolean isEnrollmentDateOk(Project project, ProjectBrokerModuleConfiguration moduleConfig) {
if (moduleConfig.isProjectEventEnabled(EventType.ENROLLMENT_EVENT)) {
ProjectEvent enrollmentEvent = project.getProjectEvent(EventType.ENROLLMENT_EVENT);
Date now = new Date();
if (enrollmentEvent.getStartDate() != null) {
if (now.before(enrollmentEvent.getStartDate())) {
return false;
}
}
if (enrollmentEvent.getEndDate() != null) {
if (now.after(enrollmentEvent.getEndDate())) {
return false;
}
}
if ( (enrollmentEvent.getStartDate() == null ) && (enrollmentEvent.getEndDate() == null) ) {
// no enrollment date define => access ok
return true;
}
}
return true;
}
/**
* return true, when identity is participant in any project of project-list.
* @param identity
* @param projectList
* @return
*/
public boolean isParticipantInAnyProject(Identity identity, List<Project> projectList) {
for (Iterator iterator = projectList.iterator(); iterator.hasNext();) {
Project project = (Project) iterator.next();
if ( ManagerFactory.getManager().isIdentityInSecurityGroup(identity, project.getProjectParticipantGroup()) ) {
return true;
}
}
return false;
}
//////////////////////////////////////////
// implements interface DeletableGroupData
//////////////////////////////////////////
public boolean deleteGroupDataFor(BusinessGroup group) {
log.debug("deleteAllProjectGroupEntiresFor started.. group=" + group);
List<Project> projectList = getProjectsWith(group);
if (projectList.isEmpty()) {
return false;
}
for (Project project : projectList) {
this.deleteProject(project,false, null, null); // no course-env, no course-node
log.debug("deleteProjectWith: group=" + group + " , project=" + project);
}
return true;
}
@Override
public DeletableReference checkIfReferenced(BusinessGroup group, Locale locale) {
StringBuilder buf = new StringBuilder();
List<Project> projectList = getProjectsWith(group);
if (projectList.isEmpty()) {
return DeletableReference.createNoDeletableReference();
}
buf.append(new ProjectBrokerNodeConfiguration().getLinkText(locale));
buf.append(":" );
for (Project project : projectList) {
buf.append(project.getTitle());
}
return DeletableReference.createDeletableReference(buf.toString());
}
@SuppressWarnings("unchecked")
private List<Project> getProjectsWith(BusinessGroup group) {
List<Project> projectList = DBFactory.getInstance().find(
"select project from org.olat.course.nodes.projectbroker.datamodel.ProjectImpl as project" +
" where project.projectGroup.key = ?", group.getKey(), Hibernate.LONG);
return projectList;
}
@Override
public void setProjectState(final Project project, final String state) {
final Long projectBrokerId = project.getProjectBroker().getKey();
OLATResourceable projectBrokerOres = OresHelper.createOLATResourceableInstance(this.getClass(),projectBrokerId);
CoordinatorManager.getCoordinator().getSyncer().doInSync( projectBrokerOres, new SyncerExecutor() {
public void execute() {
// For cluster-safe : reload project object here another node might have changed this in the meantime
Project reloadedProject = (Project) DBFactory.getInstance().loadObject(project, true);
reloadedProject.setState(state);
DBFactory.getInstance().updateObject(reloadedProject);
// invalide with removing from cache
projectCache.remove(projectBrokerId.toString());
}
});
}
public Long getProjectBrokerId(CoursePropertyManager cpm, CourseNode courseNode) {
Property projectBrokerKeyProperty = cpm.findCourseNodeProperty(courseNode, null, null, ProjectBrokerCourseNode.CONF_PROJECTBROKER_KEY);
// Check if forum-property exist
if (projectBrokerKeyProperty != null) {
Long projectBrokerId = projectBrokerKeyProperty.getLongValue();
return projectBrokerId;
}
return null;
}
public void saveProjectBrokerId(Long projectBrokerId, CoursePropertyManager cpm, CourseNode courseNode) {
Property projectBrokerKeyProperty = cpm.createCourseNodePropertyInstance(courseNode, null, null, ProjectBrokerCourseNode.CONF_PROJECTBROKER_KEY, null, projectBrokerId, null, null);
cpm.saveProperty(projectBrokerKeyProperty);
}
public boolean existProjectName(Long projectBrokerId, String newProjectTitle) {
List<Project> projectList = DBFactory.getInstance().find(
"select project from org.olat.course.nodes.projectbroker.datamodel.ProjectImpl as project" +
" where project.projectBroker = ? and project.title = ?",
new Object[] { projectBrokerId, newProjectTitle }, new Type[] { Hibernate.LONG, Hibernate.STRING });
log.debug("existProjectName projectList.size=" + projectList.size());
return !projectList.isEmpty();
}
}