/** * <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.restapi.repository.course; import static org.olat.restapi.security.RestSecurityHelper.isGroupManager; import java.util.List; import javax.servlet.http.HttpServletRequest; import javax.ws.rs.Consumes; import javax.ws.rs.DELETE; import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.PUT; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Request; import javax.ws.rs.core.Response; import javax.ws.rs.core.Response.Status; import org.olat.admin.quota.QuotaConstants; import org.olat.collaboration.CollaborationTools; import org.olat.collaboration.CollaborationToolsFactory; import org.olat.core.CoreSpringFactory; import org.olat.core.commons.modules.bc.vfs.OlatRootFolderImpl; import org.olat.core.commons.services.notifications.SubscriptionContext; import org.olat.core.gui.UserRequest; import org.olat.core.id.Identity; import org.olat.core.util.vfs.Quota; import org.olat.core.util.vfs.QuotaManager; import org.olat.core.util.vfs.restapi.VFSWebServiceSecurityCallback; import org.olat.core.util.vfs.restapi.VFSWebservice; import org.olat.group.BusinessGroup; import org.olat.group.BusinessGroupService; import org.olat.group.model.SearchBusinessGroupParams; import org.olat.modules.fo.Forum; import org.olat.modules.fo.restapi.ForumWebService; import org.olat.repository.RepositoryEntry; import org.olat.repository.RepositoryEntryRef; import org.olat.repository.RepositoryManager; import org.olat.resource.OLATResource; import org.olat.restapi.group.LearningGroupWebService; import org.olat.restapi.security.RestSecurityHelper; import org.olat.restapi.support.ObjectFactory; import org.olat.restapi.support.vo.GroupVO; /** * * Description:<br> * CourseGroupWebService * * <P> * Initial Date: 7 apr. 2010 <br> * @author srosse, stephane.rosse@frentix.com */ public class CourseGroupWebService { private static final String VERSION = "1.0"; private final OLATResource course; private final RepositoryEntryRef courseEntryRef; public CourseGroupWebService(RepositoryEntryRef courseEntryRef, OLATResource ores) { this.course = ores; this.courseEntryRef = courseEntryRef; } /** * Retrieves the version of the Course Group Web Service. * @response.representation.200.mediaType text/plain * @response.representation.200.doc The version of this specific Web Service * @response.representation.200.example 1.0 * @return */ @GET @Path("version") @Produces(MediaType.TEXT_PLAIN) public Response getVersion() { return Response.ok(VERSION).build(); } @Path("{groupKey}/folder") public VFSWebservice getFolder(@PathParam("groupKey") Long groupKey, @Context HttpServletRequest request) { BusinessGroupService bgs = CoreSpringFactory.getImpl(BusinessGroupService.class); BusinessGroup bg = bgs.loadBusinessGroup(groupKey); if(bg == null) { return null; } if(!isGroupManager(request)) { Identity identity = RestSecurityHelper.getIdentity(request); if(!bgs.isIdentityInBusinessGroup(identity, bg)) { return null; } } CollaborationTools collabTools = CollaborationToolsFactory.getInstance().getOrCreateCollaborationTools(bg); if(!collabTools.isToolEnabled(CollaborationTools.TOOL_FOLDER)) { return null; } String relPath = collabTools.getFolderRelPath(); QuotaManager qm = QuotaManager.getInstance(); Quota folderQuota = qm.getCustomQuota(relPath); if (folderQuota == null) { Quota defQuota = qm.getDefaultQuota(QuotaConstants.IDENTIFIER_DEFAULT_GROUPS); folderQuota = QuotaManager.getInstance().createQuota(relPath, defQuota.getQuotaKB(), defQuota.getUlLimitKB()); } SubscriptionContext subsContext = null; VFSWebServiceSecurityCallback secCallback = new VFSWebServiceSecurityCallback(true, true, true, folderQuota, subsContext); OlatRootFolderImpl rootContainer = new OlatRootFolderImpl(relPath, null); rootContainer.setLocalSecurityCallback(secCallback); return new VFSWebservice(rootContainer); } /** * Return the Forum web service * @param groupKey The key of the group * @param request The HTTP Request * @return */ @Path("{groupKey}/forum") public ForumWebService getForum(@PathParam("groupKey") Long groupKey, @Context HttpServletRequest request) { BusinessGroupService bgs = CoreSpringFactory.getImpl(BusinessGroupService.class); BusinessGroup bg = bgs.loadBusinessGroup(groupKey); if(bg == null) { return null; } if(!isGroupManager(request)) { Identity identity = RestSecurityHelper.getIdentity(request); if(!bgs.isIdentityInBusinessGroup(identity, bg)) { return null; } } CollaborationTools collabTools = CollaborationToolsFactory.getInstance().getOrCreateCollaborationTools(bg); if(collabTools.isToolEnabled(CollaborationTools.TOOL_FORUM)) { Forum forum = collabTools.getForum(); return new ForumWebService(forum); } return null; } /** * Lists all learn groups of the specified course. * @response.representation.200.qname {http://www.example.com}groupVO * @response.representation.200.mediaType application/xml, application/json * @response.representation.200.doc The list of all learning group of the course * @response.representation.200.example {@link org.olat.restapi.support.vo.Examples#SAMPLE_GROUPVOes} * @response.representation.404.doc The context of the group not found * @param request The HTTP request * @return */ @GET @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON}) public Response getGroupList() { BusinessGroupService bgs = CoreSpringFactory.getImpl(BusinessGroupService.class); SearchBusinessGroupParams params = new SearchBusinessGroupParams(); List<BusinessGroup> groups = bgs.findBusinessGroups(params, courseEntryRef, 0, -1); int count = 0; GroupVO[] vos = new GroupVO[groups.size()]; for(BusinessGroup group:groups) { vos[count++] = ObjectFactory.get(group); } return Response.ok(vos).build(); } /** * Creates a new group for the course. * @response.representation.qname {http://www.example.com}groupVO * @response.representation.mediaType application/xml, application/json * @response.representation.doc A group to save * @response.representation.example {@link org.olat.restapi.support.vo.Examples#SAMPLE_GROUPVO} * @response.representation.200.qname {http://www.example.com}groupVO * @response.representation.200.mediaType application/xml, application/json * @response.representation.200.doc The persisted group * @response.representation.200.example {@link org.olat.restapi.support.vo.Examples#SAMPLE_GROUPVO} * @response.representation.401.doc The roles of the authenticated user are not sufficient * @param group The group's metadatas * @param request The HTTP request * @return */ @PUT @Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON}) @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON}) public Response putNewGroup(GroupVO group, @Context HttpServletRequest request) { if(!RestSecurityHelper.isGroupManager(request)) { return Response.serverError().status(Status.UNAUTHORIZED).build(); } else if(course == null) { return Response.serverError().status(Status.NOT_FOUND).build(); } UserRequest ureq = RestSecurityHelper.getUserRequest(request); BusinessGroupService bgm = CoreSpringFactory.getImpl(BusinessGroupService.class); RepositoryEntry courseRe = RepositoryManager.getInstance().lookupRepositoryEntry(course, false); BusinessGroup bg; if(group.getKey() != null && group.getKey() > 0) { //group already exists bg = bgm.loadBusinessGroup(group.getKey()); bgm.addResourceTo(bg, courseRe); } else { Integer min = normalize(group.getMinParticipants()); Integer max = normalize(group.getMaxParticipants()); bg = bgm.createBusinessGroup(ureq.getIdentity(), group.getName(), group.getDescription(), group.getExternalId(), group.getManagedFlags(), min, max, false, false, courseRe); } GroupVO savedVO = ObjectFactory.get(bg); return Response.ok(savedVO).build(); } /** * Retrieves the metadata of the specified group. * @response.representation.200.qname {http://www.example.com}groupVO * @response.representation.200.mediaType application/xml, application/json * @response.representation.200.doc This is the list of all groups in OLAT system * @response.representation.200.example {@link org.olat.restapi.support.vo.Examples#SAMPLE_GROUPVO} * @response.representation.404.doc The business group cannot be found * @param groupKey The group's id * @param request The REST request * @param httpRequest The HTTP request * @return */ @GET @Path("{groupKey}") public Response getGroup(@PathParam("groupKey") Long groupKey, @Context Request request, @Context HttpServletRequest httpRequest) { //further security check: group is in the course return new LearningGroupWebService().findById(groupKey, request, httpRequest); } /** * Updates the metadata for the specified group. * @response.representation.qname {http://www.example.com}groupVO * @response.representation.mediaType application/xml, application/json * @response.representation.doc The group to update * @response.representation.example {@link org.olat.restapi.support.vo.Examples#SAMPLE_GROUPVO} * @response.representation.200.qname {http://www.example.com}groupVO * @response.representation.200.mediaType application/xml, application/json * @response.representation.200.doc The saved group * @response.representation.200.example {@link org.olat.restapi.support.vo.Examples#SAMPLE_GROUPVO} * @response.representation.401.doc The roles of the authenticated user are not sufficient * @response.representation.404.doc The business group cannot be found * @param groupKey The group's id * @param group The group metadatas * @param request The HTTP request * @return */ @POST @Path("{groupKey}") public Response updateGroup(@PathParam("groupKey") Long groupKey, GroupVO group, @Context HttpServletRequest request) { if(!isGroupManager(request)) { return Response.serverError().status(Status.UNAUTHORIZED).build(); } return new LearningGroupWebService().postGroup(groupKey, group, request); } /** * Deletes the business group specified by the key of the group. * @response.representation.200.doc The business group is deleted * @response.representation.401.doc The roles of the authenticated user are not sufficient * @response.representation.404.doc The business group cannot be found * @param groupKey The group id * @param request The HTTP request * @return */ @DELETE @Path("{groupKey}") public Response deleteGroup(@PathParam("groupKey") Long groupKey, @Context HttpServletRequest request) { if(!isGroupManager(request)) { return Response.serverError().status(Status.UNAUTHORIZED).build(); } return new LearningGroupWebService().deleteGroup(groupKey, request); } /** * @param integer * @return value bigger or equal than 0 */ private int normalize(Integer integer) { //fxdiff FXOLAT-122: course management if(integer == null) return -1; if(integer.intValue() < 0) return -1; return integer.intValue(); } }