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.TRUE);
}
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 = AlfrescoCollator.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)
{
// Please see GetAuthoritiesCannedQuery.AuthComparator for details.
// Get the value from the group
if (DISPLAY_NAME.equals(sortBy))
{
v = g.getAuthorityDisplayName();
}
else if (SHORT_NAME.equals(sortBy))
{
v = g.getShortName();
}
else
{
throw new InvalidArgumentException("Invalid sort field: " + sortBy);
}
if (v == null)
{
v = g.getAuthorityName();
}
// // Lower case it for case insensitive search
// v = v.toLowerCase();
// Cache it
nameCache.put(g, v);
}
return v;
}
}
public void delete(String groupId, Parameters parameters)
{
if (!isGroupAuthority(groupId))
{
throw new InvalidArgumentException("Invalid group id: " + groupId);
}
// Get cascade param - default false (if not provided).
boolean cascade = Boolean.valueOf(parameters.getParameter(PARAM_CASCADE));
try
{
authorityService.deleteAuthority(groupId, cascade);
}
catch (AuthorityException ae)
{
if (ae.getMsgId().equals("Trying to modify a fixed authority"))
{
throw new ConstraintViolatedException("Trying to modify a fixed authority");
}
else
{
throw ae;
}
}
}
public CollectionWithPagingInfo getGroupMembers(String groupId, final Parameters parameters)
{
validateGroupId(groupId, false);
Paging paging = parameters.getPaging();
// Retrieve sort column. This is limited for now to sort column due to
// v0 api implementation. Should be improved in the future.
Pair sortProp = getGroupsSortProp(parameters);
AuthorityType authorityType = null;
// Parse where clause properties.
Query q = parameters.getQuery();
if (q != null)
{
MapBasedQueryWalkerOrSupported propertyWalker = new MapBasedQueryWalkerOrSupported(LIST_GROUP_MEMBERS_QUERY_PROPERTIES, null);
QueryHelper.walk(q, propertyWalker);
String memberTypeStr = propertyWalker.getProperty(PARAM_MEMBER_TYPE, WhereClauseParser.EQUALS, String.class);
authorityType = getAuthorityType(memberTypeStr);
}
PagingResults pagingResult = getAuthoritiesInfo(authorityType, groupId, sortProp, paging);
// Create response.
final List page = pagingResult.getPage();
int totalItems = pagingResult.getTotalResultCount().getFirst();
List groupMembers = new AbstractList()
{
@Override
public GroupMember get(int index)
{
AuthorityInfo authorityInfo = page.get(index);
return getGroupMember(authorityInfo);
}
@Override
public int size()
{
return page.size();
}
};
return CollectionWithPagingInfo.asPaged(paging, groupMembers, pagingResult.hasMoreItems(), totalItems);
}
@Override
public GroupMember createGroupMember(String groupId, GroupMember groupMember)
{
validateGroupId(groupId, false);
validateGroupMember(groupMember);
AuthorityType authorityType = getAuthorityType(groupMember.getMemberType());
if (!authorityService.authorityExists(groupMember.getId()))
{
throw new EntityNotFoundException("Group member with id " + groupMember.getId() + " does not exists");
}
AuthorityType existingAuthorityType = AuthorityType.getAuthorityType(groupMember.getId());
if (existingAuthorityType != authorityType)
{
throw new IllegalArgumentException("Incorrect group member type, " + existingAuthorityType + " exists with the given id");
}
authorityService.addAuthority(groupId, groupMember.getId());
String authority = authorityService.getName(authorityType, groupMember.getId());
return getGroupMember(authority);
}
private AuthorityType getAuthorityType(String memberType)
{
AuthorityType authorityType = null;
if (memberType != null && !memberType.isEmpty())
{
switch (memberType)
{
case PARAM_MEMBER_TYPE_GROUP:
authorityType = AuthorityType.GROUP;
break;
case PARAM_MEMBER_TYPE_PERSON:
authorityType = AuthorityType.USER;
break;
default:
throw new InvalidArgumentException("MemberType is invalid (expected eg. GROUP, PERSON)");
}
}
return authorityType;
}
private PagingResults getAuthoritiesInfo(AuthorityType authorityType, String groupId, Pair sortProp, Paging paging)
{
Set authorities;
try
{
authorities = authorityService.findAuthorities(authorityType, groupId, true, null, null);
}
catch (UnknownAuthorityException e)
{
authorities = Collections.emptySet();
}
List authorityInfoList = new ArrayList<>(authorities.size());
authorityInfoList.addAll(authorities.stream().map(this::getAuthorityInfo).collect(Collectors.toList()));
// Post process sorting - this should be moved to service
// layer. It is done here because sorting is not supported at
// service layer.
AuthorityInfoComparator authorityComparator = new AuthorityInfoComparator(sortProp.getFirst(), sortProp.getSecond());
Collections.sort(authorityInfoList, authorityComparator);
// Post process paging - this should be moved to service layer.
return Util.wrapPagingResults(paging, authorityInfoList);
}
private GroupMember getGroupMember(AuthorityInfo authorityInfo)
{
if (authorityInfo == null)
{
return null;
}
GroupMember groupMember = new GroupMember();
groupMember.setId(authorityInfo.getAuthorityName());
String authorityDisplayName = authorityInfo.getAuthorityDisplayName();
if (authorityDisplayName == null || authorityDisplayName.isEmpty())
{
authorityDisplayName = authorityService.getAuthorityDisplayName(authorityInfo.getAuthorityName());
}
groupMember.setDisplayName(authorityDisplayName);
String memberType = null;
AuthorityType authorityType = AuthorityType.getAuthorityType(authorityInfo.getAuthorityName());
switch (authorityType)
{
case GROUP:
memberType = PARAM_MEMBER_TYPE_GROUP;
break;
case USER:
memberType = PARAM_MEMBER_TYPE_PERSON;
break;
default:
}
groupMember.setMemberType(memberType);
return groupMember;
}
private GroupMember getGroupMember(String authorityId)
{
AuthorityInfo authorityInfo = getAuthorityInfo(authorityId);
return getGroupMember(authorityInfo);
}
private void validateGroupId(String groupId, boolean inferPrefix)
{
if (groupId == null || groupId.isEmpty())
{
throw new InvalidArgumentException("groupId is null or empty");
}
if (!groupAuthorityExists(groupId, inferPrefix))
{
throw new EntityNotFoundException(groupId);
}
}
private void validateGroup(Group group, boolean isUpdate)
{
if (group == null)
{
throw new InvalidArgumentException("group is null");
}
if (!isUpdate)
{
if (group.getId() == null || group.getId().isEmpty())
{
throw new InvalidArgumentException("groupId is null or empty");
}
if (group.getId().indexOf('/') != -1)
{
throw new IllegalArgumentException("groupId contains characters that are not permitted.");
}
if (groupAuthorityExists(group.getId()))
{
throw new ConstraintViolatedException("Group '" + group.getId() + "' already exists.");
}
}
else
{
if (group.wasSet(Group.ID))
{
throw new InvalidArgumentException("Group update does not support field: id");
}
if (group.wasSet(Group.IS_ROOT))
{
throw new InvalidArgumentException("Group update does not support field: isRoot");
}
if (group.wasSet(Group.PARENT_IDS))
{
throw new InvalidArgumentException("Group update does not support field: parentIds");
}
if (group.wasSet(Group.ZONES))
{
throw new InvalidArgumentException("Group update does not support field: zones");
}
}
}
private void validateGroupMember(GroupMember groupMember)
{
if (groupMember == null)
{
throw new InvalidArgumentException("group member is null");
}
if (groupMember.getId() == null || groupMember.getId().isEmpty())
{
throw new InvalidArgumentException("group member Id is null or empty");
}
if (groupMember.getMemberType() == null || groupMember.getMemberType().isEmpty())
{
throw new InvalidArgumentException("group member type is null or empty");
}
}
private boolean groupAuthorityExists(String authorityName)
{
return groupAuthorityExists(authorityName, true);
}
private boolean groupAuthorityExists(String authorityName, boolean inferPrefix)
{
return authorityExists(AuthorityType.GROUP, authorityName, inferPrefix);
}
private boolean authorityExists(AuthorityType authorityType, String authorityName, boolean inferPrefix)
{
String name = inferPrefix ? authorityService.getName(authorityType, authorityName) : authorityName;
return (name != null && authorityService.authorityExists(name));
}
private boolean isGroupAuthority(String authorityName)
{
AuthorityType authorityType = AuthorityType.getAuthorityType(authorityName);
return AuthorityType.GROUP.equals(authorityType) || AuthorityType.EVERYONE.equals(authorityType);
}
}