package com.instructure.canvasapi.api;
import android.content.Context;
import com.instructure.canvasapi.model.Favorite;
import com.instructure.canvasapi.model.Group;
import com.instructure.canvasapi.model.User;
import com.instructure.canvasapi.utilities.APIHelpers;
import com.instructure.canvasapi.utilities.CanvasCallback;
import com.instructure.canvasapi.utilities.ExhaustiveBridgeCallback;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import retrofit.client.Response;
import retrofit.http.Body;
import retrofit.http.DELETE;
import retrofit.http.GET;
import retrofit.http.POST;
import retrofit.http.Path;
import retrofit.http.Query;
/**
* Copyright (c) 2015 Instructure. All rights reserved.
*/
public class GroupAPI extends BuildInterfaceAPI {
interface GroupsInterface {
@GET("/users/self/groups?include[]=favorites")
void getFirstPageGroups(CanvasCallback<Group[]> callback);
@GET("/courses/{courseid}/groups?include[]=favorites")
void getFirstPageGroupsInCourse(@Path("courseid") long courseId, CanvasCallback<Group[]> callback);
@GET("/{next}?include[]=favorites")
void getNextPageGroups(@Path(value = "next", encode = false)String nextURL, CanvasCallback<Group[]> callback);
@GET("/groups/{groupid}?include[]=permissions&include[]=favorites")
void getDetailedGroup(@Path("groupid") long groupId, CanvasCallback<Group> callback);
@GET("/groups/{groupid}/users")
void getGroupUsers(@Path("groupid") long groupId, CanvasCallback<User[]> callback);
@GET("/groups/{groupid}/users?include[]=avatar_url")
void getGroupUsersWithAvatars(@Path("groupid") long groupId, CanvasCallback<User[]> callback);
@GET("/{next}?[]=favorites")
void getNextPageGroupUsers(@Path(value = "next", encode = false) String nextURL, CanvasCallback<User[]> callback);
@POST("/groups?[]=favorites")
void createGroup(@Query("name") String name, @Query("is_public") boolean isPublic, @Body String body, CanvasCallback<Group> callback);
@DELETE("/groups/{groupid}")
void deleteGroup(@Path("groupid") long groupId, CanvasCallback<Response> callback);
@POST("/groups/{groupid}/memberships")
void createMembership(@Path("groupid") long groupId, @Query("user_id") String userId, @Body String body, CanvasCallback<Response> callback);
@POST("/group_categories/{group_category_id}/groups")
void createGroupWithCategory(@Path("group_category_id") long groupCategoryId, @Query("name") String name, @Query("is_public") boolean isPublic, @Body String body, CanvasCallback<Group> callback);
@GET("/users/self/favorites/groups?[]=favorites")
void getFavoriteGroups(CanvasCallback<Group[]> callback);
@POST("/users/self/favorites/groups/{groupId}")
void addGroupToFavorites(@Path("groupId") long groupId, @Body String body, CanvasCallback<Favorite> callback);
@DELETE("/users/self/favorites/groups/{groupId}")
void removeGroupFromFavorites(@Path("groupId") long groupId, CanvasCallback<Favorite> callback);
/////////////////////////////////////////////////////////////////////////////
// Synchronous
/////////////////////////////////////////////////////////////////////////////
@GET("/users/self/groups")
Group[] getGroupsSynchronous(@Query("page") int page);
}
/////////////////////////////////////////////////////////////////////////
// API Calls
/////////////////////////////////////////////////////////////////////////
public static void getAllGroups(final CanvasCallback<Group[]> callback){
if(APIHelpers.paramIsNull(callback)) return;
CanvasCallback<Group[]> bridge = new ExhaustiveBridgeCallback<>(Group.class, callback, new ExhaustiveBridgeCallback.ExhaustiveBridgeEvents() {
@Override
public void performApiCallWithExhaustiveCallback(CanvasCallback bridgeCallback, String nextURL, boolean isCached) {
if(callback.isCancelled()) { return; }
getNextPageGroupsChained(nextURL, bridgeCallback, isCached);
}
});
buildCacheInterface(GroupsInterface.class, callback).getFirstPageGroups(bridge);
buildInterface(GroupsInterface.class, callback).getFirstPageGroups(bridge);
}
public static void getAllGroupsInCourse(long courseID, final CanvasCallback<Group[]> callback) {
if (APIHelpers.paramIsNull(callback)) return;
CanvasCallback<Group[]> bridge = new ExhaustiveBridgeCallback<>(Group.class, callback, new ExhaustiveBridgeCallback.ExhaustiveBridgeEvents() {
@Override
public void performApiCallWithExhaustiveCallback(CanvasCallback bridgeCallback, String nextURL, boolean isCached) {
if(callback.isCancelled()) { return; }
getNextPageGroupsChained(nextURL, bridgeCallback, isCached);
}
});
buildCacheInterface(GroupsInterface.class, callback).getFirstPageGroupsInCourse(courseID, bridge);
buildInterface(GroupsInterface.class, callback).getFirstPageGroupsInCourse(courseID, bridge);
}
public static void getGroupsForUserChained(final CanvasCallback<Group[]> callback, boolean isCached) {
if (APIHelpers.paramIsNull(callback)) return;
CanvasCallback<Group[]> bridge = new ExhaustiveBridgeCallback<>(Group.class, callback, new ExhaustiveBridgeCallback.ExhaustiveBridgeEvents() {
@Override
public void performApiCallWithExhaustiveCallback(CanvasCallback bridgeCallback, String nextURL, boolean isCached) {
if(callback.isCancelled()) { return; }
getNextPageGroupsChained(nextURL, bridgeCallback, isCached);
}
});
if (isCached) {
buildCacheInterface(GroupsInterface.class, callback).getFirstPageGroups(bridge);
} else {
buildInterface(GroupsInterface.class, callback).getFirstPageGroups(bridge);
}
}
public static void getGroupsForUser(final CanvasCallback<Group[]> callback) {
if (APIHelpers.paramIsNull(callback)) return;
CanvasCallback<Group[]> bridge = new ExhaustiveBridgeCallback<>(Group.class, callback, new ExhaustiveBridgeCallback.ExhaustiveBridgeEvents() {
@Override
public void performApiCallWithExhaustiveCallback(CanvasCallback bridgeCallback, String nextURL, boolean isCached) {
if(callback.isCancelled()) { return; }
getNextPageGroupsChained(nextURL, bridgeCallback, isCached);
}
});
buildCacheInterface(GroupsInterface.class, callback).getFirstPageGroups(bridge);
buildInterface(GroupsInterface.class, callback).getFirstPageGroups(bridge);
}
public static void getNextPageGroups(String nextURL, CanvasCallback<Group[]> callback) {
if (APIHelpers.paramIsNull(callback, nextURL)) return;
callback.setIsNextPage(true);
buildCacheInterface(GroupsInterface.class, callback, false).getNextPageGroups(nextURL, callback);
buildInterface(GroupsInterface.class, callback, false).getNextPageGroups(nextURL, callback);
}
public static void getNextPageGroupsChained(String nextURL, CanvasCallback<Group[]> callback, boolean isCached) {
if (APIHelpers.paramIsNull(callback, nextURL)) return;
callback.setIsNextPage(true);
if (isCached) {
buildCacheInterface(GroupsInterface.class, callback, false).getNextPageGroups(nextURL, callback);
} else {
buildInterface(GroupsInterface.class, callback, false).getNextPageGroups(nextURL, callback);
}
}
public static void getDetailedGroup(long groupId, CanvasCallback<Group> callback) {
if (APIHelpers.paramIsNull(callback)) return;
buildCacheInterface(GroupsInterface.class, callback).getDetailedGroup(groupId, callback);
buildInterface(GroupsInterface.class, callback).getDetailedGroup(groupId, callback);
}
public static void getGroupUsers(long groupId, CanvasCallback<User[]> callback) {
if (APIHelpers.paramIsNull(groupId, callback)) return;
buildCacheInterface(GroupsInterface.class, callback).getGroupUsers(groupId, callback);
buildInterface(GroupsInterface.class, callback).getGroupUsers(groupId, callback);
}
public static void getGroupUsersWithAvatars(long groupId, CanvasCallback<User[]> callback) {
if (APIHelpers.paramIsNull(groupId, callback)) return;
buildCacheInterface(GroupsInterface.class, callback).getGroupUsersWithAvatars(groupId, callback);
buildInterface(GroupsInterface.class, callback).getGroupUsersWithAvatars(groupId, callback);
}
public static void getNextPageGroupUsers(String nextURL, CanvasCallback<User[]> callback) {
if (APIHelpers.paramIsNull(callback, nextURL)) return;
callback.setIsNextPage(true);
buildCacheInterface(GroupsInterface.class, callback, false).getNextPageGroupUsers(nextURL, callback);
buildInterface(GroupsInterface.class, callback, false).getNextPageGroupUsers(nextURL, callback);
}
public static void createGroup(String name, boolean isPublic, CanvasCallback<Group> callback) {
if (APIHelpers.paramIsNull(name, callback)) return;
buildInterface(GroupsInterface.class, callback).createGroup(name, isPublic, "", callback);
}
public static void createGroupWithCategory(long categoryId, String name, boolean isPublic, CanvasCallback<Group> callback) {
if (APIHelpers.paramIsNull(name, callback)) return;
buildInterface(GroupsInterface.class, callback).createGroupWithCategory(categoryId, name, isPublic, "", callback);
}
public static void deleteGroup(long groupId, CanvasCallback<Response>responseCanvasCallback){
if(APIHelpers.paramIsNull(responseCanvasCallback)){return;}
buildInterface(GroupsInterface.class, responseCanvasCallback).deleteGroup(groupId, responseCanvasCallback);
}
public static void createMembership(long groupId, String userId, CanvasCallback<Response> callback) {
if (APIHelpers.paramIsNull(userId, callback)) return;
buildInterface(GroupsInterface.class, callback).createMembership(groupId, userId, "", callback);
}
public static void addGroupToFavorites(final long groupId, final CanvasCallback<Favorite> callback) {
if (APIHelpers.paramIsNull(callback)) return;
buildInterface(GroupsInterface.class, callback).addGroupToFavorites(groupId, "", callback);
}
public static void removeGroupFromFavorites(final long groupId, final CanvasCallback<Favorite> callback) {
if (APIHelpers.paramIsNull(callback)) return;
buildInterface(GroupsInterface.class, callback).removeGroupFromFavorites(groupId, callback);
}
public static void getNextPageGroupsChained(CanvasCallback<Group[]> callback, String nextURL, boolean isCached) {
if (APIHelpers.paramIsNull(callback, nextURL)) return;
callback.setIsNextPage(true);
if (isCached) {
buildCacheInterface(GroupsInterface.class, callback).getNextPageGroups(nextURL, callback);
} else {
buildInterface(GroupsInterface.class, callback).getNextPageGroups(nextURL, callback);
}
}
public static void getAllFavoriteGroupsChained(final CanvasCallback<Group[]> callback, boolean isCached) {
if (APIHelpers.paramIsNull(callback)) return;
CanvasCallback<Group[]> bridge = new ExhaustiveBridgeCallback<>(Group.class, callback, new ExhaustiveBridgeCallback.ExhaustiveBridgeEvents() {
@Override
public void performApiCallWithExhaustiveCallback(CanvasCallback bridgeCallback, String nextURL, boolean isCached) {
if(callback.isCancelled()) { return; }
GroupAPI.getNextPageGroupsChained(bridgeCallback, nextURL, isCached);
}
});
if (isCached) {
buildCacheInterface(GroupsInterface.class, callback).getFavoriteGroups(bridge);
} else {
buildInterface(GroupsInterface.class, callback).getFavoriteGroups(bridge);
}
}
public static void getAllFavoriteGroups(final CanvasCallback<Group[]> callback) {
if (APIHelpers.paramIsNull(callback)) return;
CanvasCallback<Group[]> bridge = new ExhaustiveBridgeCallback<>(Group.class, callback, new ExhaustiveBridgeCallback.ExhaustiveBridgeEvents() {
@Override
public void performApiCallWithExhaustiveCallback(CanvasCallback bridgeCallback, String nextURL, boolean isCached) {
if(callback.isCancelled()) { return; }
GroupAPI.getNextPageGroupsChained(bridgeCallback, nextURL, isCached);
}
});
buildCacheInterface(GroupsInterface.class, callback).getFavoriteGroups(bridge);
buildInterface(GroupsInterface.class, callback).getFavoriteGroups(bridge);
}
/////////////////////////////////////////////////////////////////////////////
// Helper Methods
////////////////////////////////////////////////////////////////////////////
public static Map<Long, Group> createGroupMap(Group[] groups) {
Map<Long, Group> groupMap = new HashMap<Long, Group>();
for (Group group : groups) {
groupMap.put(group.getId(), group);
}
return groupMap;
}
/////////////////////////////////////////////////////////////////////////////
// Synchronous
//
// If Retrofit is unable to parse (no network for example) Synchronous calls
// will throw a nullPointer exception. All synchronous calls need to be in a
// try catch block.
/////////////////////////////////////////////////////////////////////////////
public static Group[] getAllGroupsSynchronous(Context context) {
try {
ArrayList<Group> allGroups = new ArrayList<Group>();
int page = 1;
long firstItemId = -1;
//for(ever) loop. break once we've run outta stuff;
for(;;){
Group[] groups = buildInterface(GroupsInterface.class, context).getGroupsSynchronous(page);
page++;
//This is all or nothing. We don't want partial data.
if(groups == null){
return null;
} else if(groups.length == 0){
break;
} else if(groups[0].getId() == firstItemId){
break;
} else{
firstItemId = groups[0].getId();
Collections.addAll(allGroups, groups);
}
}
return allGroups.toArray(new Group[allGroups.size()]);
} catch (Exception E) {
return null;
}
}
}