/** * <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.getIdentity; import static org.olat.restapi.security.RestSecurityHelper.getRoles; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import javax.servlet.http.HttpServletRequest; import javax.ws.rs.DefaultValue; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; 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.core.CoreSpringFactory; import org.olat.core.commons.services.notifications.NotificationsManager; import org.olat.core.commons.services.notifications.Subscriber; import org.olat.core.id.Identity; import org.olat.core.id.IdentityEnvironment; import org.olat.core.id.Roles; import org.olat.core.logging.OLog; import org.olat.core.logging.Tracing; import org.olat.core.util.nodes.INode; import org.olat.core.util.tree.Visitor; import org.olat.course.CourseFactory; import org.olat.course.CourseModule; import org.olat.course.ICourse; import org.olat.course.nodes.BCCourseNode; import org.olat.course.nodes.FOCourseNode; import org.olat.course.nodes.bc.BCWebService; import org.olat.course.run.userview.CourseTreeVisitor; import org.olat.course.run.userview.VisibleTreeFilter; import org.olat.modules.fo.restapi.ForumCourseNodeWebService; import org.olat.modules.fo.restapi.ForumVO; import org.olat.repository.RepositoryEntry; import org.olat.repository.RepositoryManager; import org.olat.repository.model.SearchRepositoryEntryParameters; import org.olat.resource.accesscontrol.ACService; import org.olat.resource.accesscontrol.AccessResult; import org.olat.restapi.support.MediaTypeVariants; import org.olat.restapi.support.vo.CourseInfoVO; import org.olat.restapi.support.vo.CourseInfoVOes; import org.olat.restapi.support.vo.FolderVO; /** * * Description:<br> * * <P> * Initial Date: 7 févr. 2012 <br> * * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com */ @Path("repo/courses/infos") public class CoursesInfosWebService { private static final OLog log = Tracing.createLoggerFor(CoursesInfosWebService.class); /** * Get courses informations viewable by the authenticated user * @response.representation.200.qname {http://www.example.com}courseVO * @response.representation.200.mediaType application/xml, application/json, application/json;pagingspec=1.0 * @response.representation.200.doc List of visible courses * @response.representation.200.example {@link org.olat.restapi.support.vo.Examples#SAMPLE_COURSEINFOVOes} * @param start * @param limit * @param httpRequest The HTTP request * @param request The REST request * @return */ @GET @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON}) public Response getCourseInfoList(@QueryParam("start") @DefaultValue("0") Integer start, @QueryParam("limit") @DefaultValue("25") Integer limit, @Context HttpServletRequest httpRequest, @Context Request request) { RepositoryManager rm = RepositoryManager.getInstance(); //fxdiff VCRP-1,2: access control of resources Roles roles = getRoles(httpRequest); Identity identity = getIdentity(httpRequest); SearchRepositoryEntryParameters params = new SearchRepositoryEntryParameters(identity, roles, CourseModule.getCourseTypeName()); if(MediaTypeVariants.isPaged(httpRequest, request)) { int totalCount = rm.countGenericANDQueryWithRolesRestriction(params); List<RepositoryEntry> repoEntries = rm.genericANDQueryWithRolesRestriction(params, start, limit, true); List<CourseInfoVO> infos = new ArrayList<CourseInfoVO>(); final Set<Long> forumNotified = new HashSet<Long>(); final Map<Long,Set<String>> courseNotified = new HashMap<Long,Set<String>>(); collectSubscriptions(identity, forumNotified, courseNotified); for(RepositoryEntry entry:repoEntries) { CourseInfoVO info = collect(identity, roles, entry, forumNotified, courseNotified); if(info != null) { infos.add(info); } } CourseInfoVO[] vos = infos.toArray(new CourseInfoVO[infos.size()]); CourseInfoVOes voes = new CourseInfoVOes(); voes.setInfos(vos); voes.setTotalCount(totalCount); return Response.ok(voes).build(); } else { return Response.serverError().status(Status.FORBIDDEN).build(); } } /** * Get course informations viewable by the authenticated user * @response.representation.200.qname {http://www.example.com}courseVO * @response.representation.200.mediaType application/xml, application/json * @response.representation.200.doc Course informations * @response.representation.200.example {@link org.olat.restapi.support.vo.Examples#SAMPLE_COURSEINFOVO} * @param courseId The course id * @param httpRequest The HTTP request * @return */ @GET @Path("{courseId}") @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON}) public Response getCourseInfo(@PathParam("courseId") Long courseId, @Context HttpServletRequest httpRequest) { Roles roles = getRoles(httpRequest); Identity identity = getIdentity(httpRequest); if(identity != null && roles != null) { Set<Long> forumNotified = new HashSet<Long>(); Map<Long,Set<String>> courseNotified = new HashMap<Long,Set<String>>(); collectSubscriptions(identity, forumNotified, courseNotified); ICourse course = CourseFactory.loadCourse(courseId); RepositoryEntry entry = RepositoryManager.getInstance().lookupRepositoryEntry(course, true); CourseInfoVO info = collect(identity, roles, entry, forumNotified, courseNotified); return Response.ok(info).build(); } else { return Response.serverError().status(Status.FORBIDDEN).build(); } } private void collectSubscriptions(Identity identity, Set<Long> forumNotified, Map<Long,Set<String>> courseNotified) { NotificationsManager man = NotificationsManager.getInstance(); {//collect subscriptions List<String> notiTypes = new ArrayList<String>(); notiTypes.add("FolderModule"); notiTypes.add("Forum"); List<Subscriber> subs = man.getSubscribers(identity, notiTypes); for(Subscriber sub:subs) { String publisherType = sub.getPublisher().getType(); String resName = sub.getPublisher().getResName(); if("CourseModule".equals(resName)) { if("FolderModule".equals(publisherType)) { Long courseKey = sub.getPublisher().getResId(); if(!courseNotified.containsKey(courseKey)) { courseNotified.put(courseKey,new HashSet<String>()); } courseNotified.get(courseKey).add(sub.getPublisher().getSubidentifier()); } else if ("Forum".equals(publisherType)) { Long forumKey = Long.parseLong(sub.getPublisher().getData()); forumNotified.add(forumKey); } } } } } private CourseInfoVO collect(final Identity identity, final Roles roles, final RepositoryEntry entry, final Set<Long> forumNotified, final Map<Long,Set<String>> courseNotified) { CourseInfoVO info = new CourseInfoVO(); info.setRepoEntryKey(entry.getKey()); info.setSoftKey(entry.getSoftkey()); info.setDisplayName(entry.getDisplayname()); ACService acManager = CoreSpringFactory.getImpl(ACService.class); AccessResult result = acManager.isAccessible(entry, identity, false); if(result.isAccessible()) { try { final ICourse course = CourseFactory.loadCourse(entry); final List<FolderVO> folders = new ArrayList<FolderVO>(); final List<ForumVO> forums = new ArrayList<ForumVO>(); final IdentityEnvironment ienv = new IdentityEnvironment(identity, roles); new CourseTreeVisitor(course, ienv).visit(new Visitor() { @Override public void visit(INode node) { if(node instanceof BCCourseNode) { BCCourseNode bcNode = (BCCourseNode)node; folders.add(BCWebService.createFolderVO(ienv, course, bcNode, courseNotified.get(course.getResourceableId()))); } else if (node instanceof FOCourseNode) { FOCourseNode forumNode = (FOCourseNode)node; forums.add(ForumCourseNodeWebService.createForumVO(course, forumNode, forumNotified)); } } }, new VisibleTreeFilter()); info.setKey(course.getResourceableId()); info.setTitle(course.getCourseTitle()); info.setFolders(folders.toArray(new FolderVO[folders.size()])); info.setForums(forums.toArray(new ForumVO[forums.size()])); } catch (Exception e) { log.error("", e); } } return info; } }