sortCols = parameters.getSorting();
+
+ if ((sortCols != null) && (sortCols.size() > 0))
+ {
+ if (sortCols.size() > 1)
+ {
+ throw new InvalidArgumentException("Multiple sort fields not allowed.");
+ }
+
+ SortColumn sortCol = sortCols.get(0);
+
+ String sortPropName = SORT_PARAMS_TO_NAMES.get(sortCol.column);
+ if (sortPropName == null)
+ {
+ throw new InvalidArgumentException("Invalid sort field: " + sortCol.column);
+ }
+
+ sortProp = new Pair<>(sortPropName, (sortCol.asc ? Boolean.TRUE : Boolean.FALSE));
+ }
+ else
+ {
+ sortProp = getGroupsSortPropDefault();
+ }
+ return sortProp;
+ }
+
+ /**
+ *
+ * Returns the default sort order.
+ *
+ *
+ * @return The default Pair<QName, Boolean>
sort
+ * property.
+ */
+ private Pair getGroupsSortPropDefault()
+ {
+ return new Pair<>(DISPLAY_NAME, Boolean.FALSE);
+ }
+
+ private class AuthorityInfoComparator implements Comparator
+ {
+ private Map nameCache;
+ private String sortBy;
+ private Collator col;
+ private int orderMultiplier = 1;
+
+ private AuthorityInfoComparator(String sortBy, boolean sortAsc)
+ {
+ col = Collator.getInstance(I18NUtil.getLocale());
+ this.sortBy = sortBy;
+ this.nameCache = new HashMap<>();
+
+ if (!sortAsc)
+ {
+ orderMultiplier = -1;
+ }
+ }
+
+ @Override
+ public int compare(AuthorityInfo g1, AuthorityInfo g2)
+ {
+ return col.compare(get(g1), get(g2)) * orderMultiplier;
+ }
+
+ private String get(AuthorityInfo g)
+ {
+ String v = nameCache.get(g);
+ if (v == null)
+ {
+ // Get the value from the group
+ if (PARAM_DISPLAY_NAME.equals(sortBy))
+ {
+ v = g.getAuthorityDisplayName();
+ }
+ else if (PARAM_ID.equals(sortBy))
+ {
+ v = g.getAuthorityName();
+ }
+ else
+ {
+ throw new InvalidArgumentException("Invalid sort field: " + sortBy);
+ }
+
+ // Lower case it for case insensitive search
+ v = v.toLowerCase();
+
+ // Cache it
+ nameCache.put(g, v);
+ }
+ return v;
+ }
+ }
+}
diff --git a/source/java/org/alfresco/rest/api/model/Group.java b/source/java/org/alfresco/rest/api/model/Group.java
new file mode 100644
index 0000000000..320002d5f8
--- /dev/null
+++ b/source/java/org/alfresco/rest/api/model/Group.java
@@ -0,0 +1,144 @@
+/*
+ * #%L
+ * Alfresco Remote API
+ * %%
+ * Copyright (C) 2005 - 2016 Alfresco Software Limited
+ * %%
+ * This file is part of the Alfresco software.
+ * If the software was purchased under a paid Alfresco license, the terms of
+ * the paid license agreement will prevail. Otherwise, the software is
+ * provided under the following open source license terms:
+ *
+ * Alfresco is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Alfresco is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Alfresco. If not, see .
+ * #L%
+ */
+package org.alfresco.rest.api.model;
+
+import java.util.Set;
+
+import org.alfresco.rest.framework.resource.UniqueId;
+
+/**
+ * Represents a group.
+ *
+ * @author cturlica
+ *
+ */
+public class Group implements Comparable
+{
+
+ protected String id; // group id (aka authority name)
+ protected String displayName;
+ protected Boolean isRoot;
+ protected Set parentIds;
+ protected Set zones;
+
+ public Group()
+ {
+ }
+
+ @UniqueId
+ public String getId()
+ {
+ return id;
+ }
+
+ public void setId(String id)
+ {
+ this.id = id;
+ }
+
+ public String getDisplayName()
+ {
+ return displayName;
+ }
+
+ public void setDisplayName(String displayName)
+ {
+ this.displayName = displayName;
+ }
+
+ public Boolean getIsRoot()
+ {
+ return isRoot;
+ }
+
+ public void setIsRoot(Boolean isRoot)
+ {
+ this.isRoot = isRoot;
+ }
+
+ public Set getParentIds()
+ {
+ return parentIds;
+ }
+
+ public void setParentIds(Set parentIds)
+ {
+ this.parentIds = parentIds;
+ }
+
+ public Set getZones()
+ {
+ return zones;
+ }
+
+ public void setZones(Set zones)
+ {
+ this.zones = zones;
+ }
+
+ @Override
+ public boolean equals(Object obj)
+ {
+ if (this == obj)
+ {
+ return true;
+ }
+
+ if (obj == null)
+ {
+ return false;
+ }
+
+ if (getClass() != obj.getClass())
+ {
+ return false;
+ }
+
+ Group other = (Group) obj;
+ return id.equals(other.id);
+ }
+
+ @Override
+ public int compareTo(Group group)
+ {
+ return id.compareTo(group.getId());
+ }
+
+ @Override
+ public int hashCode()
+ {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((id == null) ? 0 : id.hashCode());
+ return result;
+ }
+
+ @Override
+ public String toString()
+ {
+ return "Group [id=" + id + ", displayName=" + displayName + ", isRoot=" + isRoot + "]";
+ }
+}
\ No newline at end of file
diff --git a/source/test-java/org/alfresco/rest/api/tests/ApiTest.java b/source/test-java/org/alfresco/rest/api/tests/ApiTest.java
index 5e65a23704..ff4549a3f5 100644
--- a/source/test-java/org/alfresco/rest/api/tests/ApiTest.java
+++ b/source/test-java/org/alfresco/rest/api/tests/ApiTest.java
@@ -57,7 +57,7 @@ import org.junit.runners.Suite;
AuthenticationsTest.class,
ModulePackagesApiTest.class,
WherePredicateApiTest.class,
- DiscoveryApiTest.class,
+ DiscoveryApiTest.class,
TestSites.class,
TestNodeComments.class,
TestFavouriteSites.class,
@@ -73,8 +73,8 @@ import org.junit.runners.Suite;
TestSiteMembershipRequests.class,
TestFavourites.class,
TestPublicApi128.class,
- TestPublicApiCaching.class
-
+ TestPublicApiCaching.class,
+ GroupsTest.class
})
public class ApiTest
{
diff --git a/source/test-java/org/alfresco/rest/api/tests/GroupsTest.java b/source/test-java/org/alfresco/rest/api/tests/GroupsTest.java
new file mode 100644
index 0000000000..815af94f11
--- /dev/null
+++ b/source/test-java/org/alfresco/rest/api/tests/GroupsTest.java
@@ -0,0 +1,380 @@
+/*
+ * #%L
+ * Alfresco Remote API
+ * %%
+ * Copyright (C) 2005 - 2016 Alfresco Software Limited
+ * %%
+ * This file is part of the Alfresco software.
+ * If the software was purchased under a paid Alfresco license, the terms of
+ * the paid license agreement will prevail. Otherwise, the software is
+ * provided under the following open source license terms:
+ *
+ * Alfresco is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Alfresco is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Alfresco. If not, see .
+ * #L%
+ */
+package org.alfresco.rest.api.tests;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletResponse;
+
+import org.alfresco.repo.security.authentication.AuthenticationUtil;
+import org.alfresco.rest.AbstractSingleNetworkSiteTest;
+import org.alfresco.rest.api.tests.client.PublicApiClient;
+import org.alfresco.rest.api.tests.client.PublicApiClient.Groups;
+import org.alfresco.rest.api.tests.client.PublicApiClient.ListResponse;
+import org.alfresco.rest.api.tests.client.PublicApiClient.Paging;
+import org.alfresco.rest.api.tests.client.data.Group;
+import org.alfresco.rest.framework.resource.parameters.SortColumn;
+import org.alfresco.service.cmr.security.AuthorityService;
+import org.alfresco.service.cmr.security.AuthorityType;
+import org.alfresco.util.GUID;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * V1 REST API tests for managing Groups
+ *
+ * @author cturlica
+ */
+public class GroupsTest extends AbstractSingleNetworkSiteTest
+{
+ protected AuthorityService authorityService;
+
+ private String rootGroupName = null;
+ private Group groupA = null;
+ private Group groupB = null;
+
+ @Before
+ public void setup() throws Exception
+ {
+ super.setup();
+
+ authorityService = (AuthorityService) applicationContext.getBean("AuthorityService");
+ }
+
+ @After
+ public void tearDown() throws Exception
+ {
+ super.tearDown();
+ }
+
+ @Test
+ public void testGetGroups() throws Exception
+ {
+ try
+ {
+ createAuthorityContext(user1);
+
+ setRequestContext(user1);
+
+ testGetGroupsSorting();
+ testGetGroupsWithInclude();
+ testGetGroupsSkipPaging();
+ testGetGroupsByIsRoot(true);
+ testGetGroupsByIsRoot(false);
+ }
+ finally
+ {
+ clearAuthorityContext();
+ }
+ }
+
+ private void testGetGroupsSkipPaging() throws Exception
+ {
+ // +ve: check skip count.
+ {
+ // Sort params
+ Map otherParams = new HashMap<>();
+ addOrderBy(otherParams, org.alfresco.rest.api.Groups.PARAM_DISPLAY_NAME, false);
+
+ // Paging and list groups
+
+ int skipCount = 0;
+ int maxItems = 4;
+ Paging paging = getPaging(skipCount, maxItems);
+
+ ListResponse resp = getGroups(paging, otherParams);
+
+ // Paging and list groups with skip count.
+
+ skipCount = 2;
+ maxItems = 2;
+ paging = getPaging(skipCount, maxItems);
+
+ ListResponse sublistResponse = getGroups(paging, otherParams);
+
+ List expectedSublist = sublist(resp.getList(), skipCount, maxItems);
+ checkList(expectedSublist, sublistResponse.getPaging(), sublistResponse);
+ }
+
+ // -ve: check skip count.
+ {
+ getGroups(getPaging(-1, null), null, "", HttpServletResponse.SC_BAD_REQUEST);
+ }
+ }
+
+ private void testGetGroupsSorting() throws Exception
+ {
+ // orderBy=sortColumn should be the same to orderBy=sortColumn ASC
+ {
+ // paging
+ Paging paging = getPaging(0, Integer.MAX_VALUE);
+
+ Map otherParams = new HashMap<>();
+
+ // Default order.
+ addOrderBy(otherParams, org.alfresco.rest.api.Groups.PARAM_DISPLAY_NAME, null);
+
+ ListResponse resp = getGroups(paging, otherParams);
+ List groups = resp.getList();
+ assertTrue("groups order not valid", groups.indexOf(groupA) < groups.indexOf(groupB));
+
+ // Ascending order.
+ addOrderBy(otherParams, org.alfresco.rest.api.Groups.PARAM_DISPLAY_NAME, true);
+
+ ListResponse respOrderAsc = getGroups(paging, otherParams);
+
+ checkList(respOrderAsc.getList(), resp.getPaging(), resp);
+ }
+
+ // Sorting should be the same regardless of implementation (canned query
+ // or postprocessing).
+ {
+ // paging
+ Paging paging = getPaging(0, Integer.MAX_VALUE);
+
+ Map otherParams = new HashMap<>();
+ addOrderBy(otherParams, org.alfresco.rest.api.Groups.PARAM_DISPLAY_NAME, null);
+
+ // Get and sort groups using canned query.
+ ListResponse respCannedQuery = getGroups(paging, otherParams);
+
+ // Get and sort groups using postprocessing.
+ otherParams.put("where", "(isRoot=true)");
+ ListResponse respPostProcess = getGroups(paging, otherParams);
+
+ List expected = respCannedQuery.getList();
+ expected.retainAll(respPostProcess.getList());
+
+ checkList(expected, respPostProcess.getPaging(), respPostProcess);
+ }
+
+ // Sort by displayName.
+ {
+ // paging
+ Paging paging = getPaging(0, Integer.MAX_VALUE);
+
+ Map otherParams = new HashMap<>();
+
+ // Default order.
+ addOrderBy(otherParams, org.alfresco.rest.api.Groups.PARAM_DISPLAY_NAME, true);
+
+ ListResponse resp = getGroups(paging, otherParams);
+ List groups = resp.getList();
+ assertTrue("groups order not valid", groups.indexOf(groupA) < groups.indexOf(groupB));
+ }
+
+ // Sort by id.
+ {
+ // paging
+ Paging paging = getPaging(0, Integer.MAX_VALUE);
+
+ Map otherParams = new HashMap<>();
+ addOrderBy(otherParams, org.alfresco.rest.api.Groups.PARAM_ID, false);
+
+ // list sites
+ ListResponse resp = getGroups(paging, otherParams);
+
+ List groups = resp.getList();
+ assertTrue("groups order not valid", groups.indexOf(groupB) < groups.indexOf(groupA));
+ }
+
+ // Multiple sort fields not allowed.
+ {
+ // paging
+ Paging paging = getPaging(0, Integer.MAX_VALUE);
+ Map otherParams = new HashMap<>();
+ otherParams.put("orderBy", org.alfresco.rest.api.Groups.PARAM_ID + " ASC," + org.alfresco.rest.api.Groups.PARAM_DISPLAY_NAME + " ASC");
+
+ getGroups(paging, otherParams, "", HttpServletResponse.SC_BAD_REQUEST);
+ }
+ }
+
+ private void testGetGroupsWithInclude() throws Exception
+ {
+ // paging
+ int maxItems = 2;
+ Paging paging = getPaging(0, maxItems);
+
+ Map otherParams = new HashMap<>();
+
+ // Validate that by default optionally fields aren't returned.
+ {
+ // list sites
+ ListResponse resp = getGroups(paging, null);
+
+ // check results
+ assertNotNull(resp);
+ assertNotNull(resp.getList());
+ assertFalse(resp.getList().isEmpty());
+
+ assertEquals(maxItems, resp.getList().size());
+
+ resp.getList().forEach(group -> validateGroupDefaultFields(group));
+ }
+
+ // Check include parent ids.
+ {
+ otherParams.put("include", org.alfresco.rest.api.Groups.PARAM_INCLUDE_PARENT_IDS);
+
+ // list sites
+ ListResponse resp = getGroups(paging, otherParams);
+
+ // check results
+ assertEquals(maxItems, resp.getList().size());
+
+ resp.getList().forEach(group ->
+ {
+ assertNotNull(group);
+
+ assertNotNull(group.getParentIds());
+ assertFalse(group.getParentIds().isEmpty());
+ });
+ }
+
+ // Check include zones.
+ {
+ otherParams.put("include", org.alfresco.rest.api.Groups.PARAM_INCLUDE_ZONES);
+
+ // list sites
+ ListResponse resp = getGroups(paging, otherParams);
+
+ // check results
+ assertEquals(maxItems, resp.getList().size());
+
+ resp.getList().forEach(group ->
+ {
+ assertNotNull(group);
+
+ assertNotNull(group.getZones());
+ assertFalse(group.getZones().isEmpty());
+ });
+ }
+ }
+
+ private void testGetGroupsByIsRoot(boolean isRoot) throws Exception
+ {
+ // Sort params
+ Map otherParams = new HashMap<>();
+ otherParams.put("where", "(isRoot=" + isRoot + ")");
+
+ // Paging
+ Paging paging = getPaging(0, 4);
+
+ ListResponse resp = getGroups(paging, otherParams);
+ resp.getList().forEach(group -> {
+ validateGroupDefaultFields(group);
+ assertEquals("isRoot was expected to be " + isRoot, isRoot, group.getIsRoot());
+ });
+ }
+
+ private ListResponse getGroups(final PublicApiClient.Paging paging, Map otherParams, String errorMessage, int expectedStatus) throws Exception
+ {
+ final Groups groupsProxy = publicApiClient.groups();
+ return groupsProxy.getGroups(createParams(paging, otherParams), errorMessage, expectedStatus);
+ }
+
+ private ListResponse getGroups(final PublicApiClient.Paging paging, Map otherParams) throws Exception
+ {
+ return getGroups(paging, otherParams, "Failed to get groups", HttpServletResponse.SC_OK);
+ }
+
+ private void addOrderBy(Map otherParams, String sortColumn, Boolean asc)
+ {
+ otherParams.put("orderBy", sortColumn + (asc != null ? " " + (asc ? SortColumn.ASCENDING : SortColumn.DESCENDING) : ""));
+ }
+
+ /**
+ * Creates authority context.
+ *
+ * @param userName
+ * The user to run as.
+ */
+ private void createAuthorityContext(String userName)
+ {
+ String groupName = "Group_ROOT" + GUID.generate();
+
+ AuthenticationUtil.setRunAsUser(userName);
+ if (rootGroupName == null)
+ {
+ rootGroupName = authorityService.getName(AuthorityType.GROUP, groupName);
+ }
+
+ if (!authorityService.authorityExists(rootGroupName))
+ {
+ AuthenticationUtil.setAdminUserAsFullyAuthenticatedUser();
+
+ rootGroupName = authorityService.createAuthority(AuthorityType.GROUP, groupName);
+
+ String groupBAuthorityName = authorityService.createAuthority(AuthorityType.GROUP, "Test_GroupB" + GUID.generate());
+ authorityService.addAuthority(rootGroupName, groupBAuthorityName);
+
+ String groupAAuthorityName = authorityService.createAuthority(AuthorityType.GROUP, "Test_GroupA" + GUID.generate());
+ authorityService.addAuthority(rootGroupName, groupAAuthorityName);
+
+ authorityService.addAuthority(groupAAuthorityName, user1);
+ authorityService.addAuthority(groupBAuthorityName, user2);
+
+ groupA = new Group();
+ groupA.setId(groupAAuthorityName);
+
+ groupB = new Group();
+ groupB.setId(groupBAuthorityName);
+ }
+ }
+
+ /**
+ * Clears authority context: removes root group and all child groups.
+ */
+ private void clearAuthorityContext()
+ {
+ if (authorityService.authorityExists(rootGroupName))
+ {
+ AuthenticationUtil.setAdminUserAsFullyAuthenticatedUser();
+ authorityService.deleteAuthority(rootGroupName, true);
+ }
+ }
+
+ private void validateGroupDefaultFields(Group group)
+ {
+ assertNotNull(group);
+ assertNotNull(group.getId());
+ assertNotNull(group.getDisplayName());
+ assertNotNull(group.getIsRoot());
+
+ // Optionally included.
+ assertNull(group.getParentIds());
+ assertNull(group.getZones());
+ }
+}
diff --git a/source/test-java/org/alfresco/rest/api/tests/client/PublicApiClient.java b/source/test-java/org/alfresco/rest/api/tests/client/PublicApiClient.java
index 1dd1d065fb..2b1ccef305 100644
--- a/source/test-java/org/alfresco/rest/api/tests/client/PublicApiClient.java
+++ b/source/test-java/org/alfresco/rest/api/tests/client/PublicApiClient.java
@@ -56,6 +56,7 @@ import org.alfresco.rest.api.tests.client.data.ContentData;
import org.alfresco.rest.api.tests.client.data.Favourite;
import org.alfresco.rest.api.tests.client.data.FavouriteSite;
import org.alfresco.rest.api.tests.client.data.FolderNode;
+import org.alfresco.rest.api.tests.client.data.Group;
import org.alfresco.rest.api.tests.client.data.JSONAble;
import org.alfresco.rest.api.tests.client.data.MemberOfSite;
import org.alfresco.rest.api.tests.client.data.NodeRating;
@@ -116,6 +117,7 @@ public class PublicApiClient
private People people;
private Favourites favourites;
private SiteMembershipRequests siteMembershipRequests;
+ private Groups groups;
private RawProxy rawProxy;
private ThreadLocal rc = new ThreadLocal();
@@ -137,6 +139,7 @@ public class PublicApiClient
people = new People();
favourites = new Favourites();
siteMembershipRequests = new SiteMembershipRequests();
+ groups = new Groups();
rawProxy = new RawProxy();
}
@@ -200,6 +203,11 @@ public class PublicApiClient
return comments;
}
+ public Groups groups()
+ {
+ return groups;
+ }
+
public CmisSession createPublicApiCMISSession(Binding binding, String version)
{
return createPublicApiCMISSession(binding, version, null);
@@ -2235,4 +2243,28 @@ public class PublicApiClient
return sb.toString();
}
}
+
+ public class Groups extends AbstractProxy
+ {
+
+ public ListResponse getGroups(Map params, String errorMessage, int expectedStatus) throws PublicApiException, ParseException
+ {
+ HttpResponse response = getAll("groups", null, null, null, params, errorMessage, expectedStatus);
+
+ if (response != null && response.getJsonResponse() != null)
+ {
+ JSONObject jsonList = (JSONObject) response.getJsonResponse().get("list");
+ if (jsonList != null)
+ {
+ return Group.parseGroups(response.getJsonResponse());
+ }
+ }
+ return null;
+ }
+
+ public ListResponse getGroups(Map params) throws PublicApiException, ParseException
+ {
+ return getGroups(params, "Failed to get groups", HttpServletResponse.SC_OK);
+ }
+ }
}
diff --git a/source/test-java/org/alfresco/rest/api/tests/client/data/Group.java b/source/test-java/org/alfresco/rest/api/tests/client/data/Group.java
new file mode 100644
index 0000000000..075a38ec89
--- /dev/null
+++ b/source/test-java/org/alfresco/rest/api/tests/client/data/Group.java
@@ -0,0 +1,127 @@
+/*
+ * #%L
+ * Alfresco Remote API
+ * %%
+ * Copyright (C) 2005 - 2016 Alfresco Software Limited
+ * %%
+ * This file is part of the Alfresco software.
+ * If the software was purchased under a paid Alfresco license, the terms of
+ * the paid license agreement will prevail. Otherwise, the software is
+ * provided under the following open source license terms:
+ *
+ * Alfresco is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Alfresco is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Alfresco. If not, see .
+ * #L%
+ */
+package org.alfresco.rest.api.tests.client.data;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.alfresco.rest.api.tests.client.PublicApiClient.ExpectedPaging;
+import org.alfresco.rest.api.tests.client.PublicApiClient.ListResponse;
+import org.json.simple.JSONArray;
+import org.json.simple.JSONObject;
+
+/**
+ * Represents a group.
+ *
+ * @author cturlica
+ *
+ */
+public class Group extends org.alfresco.rest.api.model.Group implements Serializable, ExpectedComparison
+{
+
+ private static final long serialVersionUID = -3580248429177260831L;
+
+ @Override
+ public void expected(Object o)
+ {
+ assertTrue("o is an instance of " + o.getClass(), o instanceof Group);
+
+ Group other = (Group) o;
+
+ AssertUtil.assertEquals("id", getId(), other.getId());
+ AssertUtil.assertEquals("displayName", getDisplayName(), other.getDisplayName());
+ AssertUtil.assertEquals("isRoot", getIsRoot(), other.getIsRoot());
+ AssertUtil.assertEquals("parentIds", getParentIds(), other.getParentIds());
+ AssertUtil.assertEquals("zones", getZones(), other.getZones());
+ }
+
+ public JSONObject toJSON()
+ {
+ JSONObject groupJson = new JSONObject();
+ groupJson.put("id", getId());
+ groupJson.put("displayName", getDisplayName());
+ groupJson.put("isRoot", getIsRoot());
+
+ if (getParentIds() != null)
+ {
+ groupJson.put("parentIds", getParentIds());
+ }
+
+ if (getZones() != null)
+ {
+ groupJson.put("zones", getZones());
+ }
+
+ return groupJson;
+ }
+
+ public static Group parseGroup(JSONObject jsonObject)
+ {
+ String id = (String) jsonObject.get("id");
+ String displayName = (String) jsonObject.get("displayName");
+ Boolean isRoot = (Boolean) jsonObject.get("isRoot");
+ List parentIds = (List) jsonObject.get("parentIds");
+ List zones = (List) jsonObject.get("zones");
+
+ Group group = new Group();
+ group.setId(id);
+ group.setDisplayName(displayName);
+ group.setIsRoot(isRoot);
+ group.setParentIds(parentIds != null ? new HashSet(parentIds) : null);
+ group.setZones(zones != null ? new HashSet(zones) : null);
+
+ return group;
+ }
+
+ public static ListResponse parseGroups(JSONObject jsonObject)
+ {
+ List groups = new ArrayList<>();
+
+ JSONObject jsonList = (JSONObject) jsonObject.get("list");
+ assertNotNull(jsonList);
+
+ JSONArray jsonEntries = (JSONArray) jsonList.get("entries");
+ assertNotNull(jsonEntries);
+
+ for (int i = 0; i < jsonEntries.size(); i++)
+ {
+ JSONObject jsonEntry = (JSONObject) jsonEntries.get(i);
+ JSONObject entry = (JSONObject) jsonEntry.get("entry");
+ groups.add(parseGroup(entry));
+ }
+
+ ExpectedPaging paging = ExpectedPaging.parsePagination(jsonList);
+ ListResponse resp = new ListResponse<>(paging, groups);
+ return resp;
+ }
+
+}