2013-08-20 17:17:31 +00:00

925 lines
29 KiB
Java

package org.alfresco.repo.favourites;
import java.io.Serializable;
import java.text.Collator;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.TreeMap;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.model.ContentModel;
import org.alfresco.query.PageDetails;
import org.alfresco.query.PagingRequest;
import org.alfresco.query.PagingResults;
import org.alfresco.repo.favourites.PersonFavourite.PersonFavouriteKey;
import org.alfresco.repo.policy.ClassPolicy;
import org.alfresco.repo.policy.ClassPolicyDelegate;
import org.alfresco.repo.policy.PolicyComponent;
import org.alfresco.repo.security.authentication.AuthenticationContext;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.security.permissions.AccessDeniedException;
import org.alfresco.repo.site.SiteModel;
import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.cmr.favourites.FavouritesService;
import org.alfresco.service.cmr.preference.PreferenceService;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.security.AccessStatus;
import org.alfresco.service.cmr.security.PermissionService;
import org.alfresco.service.cmr.security.PersonService;
import org.alfresco.service.cmr.site.SiteInfo;
import org.alfresco.service.cmr.site.SiteService;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName;
import org.alfresco.util.ISO8601DateFormat;
import org.alfresco.util.Pair;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.InitializingBean;
/**
* Favourites service implementation that uses the PreferencesService for persisting favourites.
*
* Unfortunately, we are tied to the PreferencesService and to the preference names and data structure because Share uses the PreferenceService directly.
*
* @author steveglover
*/
public class FavouritesServiceImpl implements FavouritesService, InitializingBean
{
private static final Log logger = LogFactory.getLog(FavouritesServiceImpl.class);
private Map<Type, PrefKeys> prefKeys;
private PreferenceService preferenceService;
private NodeService nodeService;
private DictionaryService dictionaryService;
private SiteService siteService;
private PolicyComponent policyComponent;
private PermissionService permissionService;
private PersonService personService;
/** Authentication Service */
private AuthenticationContext authenticationContext;
private ClassPolicyDelegate<OnAddFavouritePolicy> onAddFavouriteDelegate;
private ClassPolicyDelegate<OnRemoveFavouritePolicy> onRemoveFavouriteDelegate;
private Collator collator = Collator.getInstance();
public interface OnAddFavouritePolicy extends ClassPolicy
{
public static final QName QNAME = QName.createQName(NamespaceService.ALFRESCO_URI, "onAddfavourite");
/**
* Called after a node has been <b>favourited</b>
*
* @param userName the username of the person who favourited the node
* @param nodeRef the node which was favourited
*/
public void onAddFavourite(String userName, NodeRef nodeRef);
}
public interface OnRemoveFavouritePolicy extends ClassPolicy
{
public static final QName QNAME = QName.createQName(NamespaceService.ALFRESCO_URI, "onRemovefavourite");
/**
* Called after a <b>favourite</b> has been removed
*
* @param userName the username of the person who favourited the node
* @param nodeRef the node that was un-favourited
*/
public void onRemoveFavourite(String userName, NodeRef nodeRef);
}
public void setPermissionService(PermissionService permissionService)
{
this.permissionService = permissionService;
}
public void setPersonService(PersonService personService)
{
this.personService = personService;
}
public void setAuthenticationContext(AuthenticationContext authenticationContext)
{
this.authenticationContext = authenticationContext;
}
public void setPolicyComponent(PolicyComponent policyComponent)
{
this.policyComponent = policyComponent;
}
public void setSiteService(SiteService siteService)
{
this.siteService = siteService;
}
public void setNodeService(NodeService nodeService)
{
this.nodeService = nodeService;
}
public void setDictionaryService(DictionaryService dictionaryService)
{
this.dictionaryService = dictionaryService;
}
public void setPreferenceService(PreferenceService preferenceService)
{
this.preferenceService = preferenceService;
}
private static class PrefKeys
{
private String sharePrefKey;
private String alfrescoPrefKey;
public PrefKeys(String sharePrefKey, String alfrescoPrefKey)
{
super();
this.sharePrefKey = sharePrefKey;
this.alfrescoPrefKey = alfrescoPrefKey;
}
public String getSharePrefKey()
{
return sharePrefKey;
}
public String getAlfrescoPrefKey()
{
return alfrescoPrefKey;
}
}
@Override
public void afterPropertiesSet() throws Exception
{
this.prefKeys = new HashMap<Type, PrefKeys>();
this.prefKeys.put(Type.SITE, new PrefKeys("org.alfresco.share.sites.favourites.", "org.alfresco.ext.sites.favourites."));
this.prefKeys.put(Type.FILE, new PrefKeys("org.alfresco.share.documents.favourites", "org.alfresco.ext.documents.favourites."));
this.prefKeys.put(Type.FOLDER, new PrefKeys("org.alfresco.share.folders.favourites", "org.alfresco.ext.folders.favourites."));
}
public void init()
{
this.onAddFavouriteDelegate = policyComponent.registerClassPolicy(OnAddFavouritePolicy.class);
this.onRemoveFavouriteDelegate = policyComponent.registerClassPolicy(OnRemoveFavouritePolicy.class);
}
private PrefKeys getPrefKeys(Type type)
{
PrefKeys prefKey = prefKeys.get(type);
return prefKey;
}
private boolean removeFavouriteSite(String userName, NodeRef nodeRef)
{
PrefKeys prefKeys = getPrefKeys(Type.SITE);
boolean exists = false;
SiteInfo siteInfo = siteService.getSite(nodeRef);
if(siteInfo != null)
{
StringBuilder sitePrefKeyBuilder = new StringBuilder(prefKeys.getSharePrefKey());
sitePrefKeyBuilder.append(siteInfo.getShortName());
String sitePrefKey = sitePrefKeyBuilder.toString();
String siteFavouritedKey = siteFavouritedKey(siteInfo);
exists = preferenceService.getPreference(userName, siteFavouritedKey) != null;
preferenceService.clearPreferences(userName, sitePrefKey);
}
else
{
throw new IllegalArgumentException("NodeRef " + nodeRef + " is not a site");
}
return exists;
}
private String siteFavouritedKey(SiteInfo siteInfo)
{
PrefKeys prefKeys = getPrefKeys(Type.SITE);
StringBuilder sitePrefKeyBuilder = new StringBuilder(prefKeys.getSharePrefKey());
sitePrefKeyBuilder.append(siteInfo.getShortName());
String sitePrefKey = sitePrefKeyBuilder.toString();
String favouritedKey = sitePrefKey;
return favouritedKey;
}
private String siteCreatedAtKey(SiteInfo siteInfo)
{
PrefKeys prefKeys = getPrefKeys(Type.SITE);
StringBuilder sitePrefKeyBuilder = new StringBuilder(prefKeys.getAlfrescoPrefKey());
sitePrefKeyBuilder.append(siteInfo.getShortName());
String sitePrefKey = sitePrefKeyBuilder.toString();
StringBuilder createdAtKeyBuilder = new StringBuilder(sitePrefKey);
createdAtKeyBuilder.append(".createdAt");
String createdAtKey = createdAtKeyBuilder.toString();
return createdAtKey;
}
private Comparator<PersonFavouriteKey> getComparator(final List<Pair<FavouritesService.SortFields, Boolean>> sortProps)
{
Comparator<PersonFavouriteKey> comparator = new Comparator<PersonFavouriteKey>()
{
@Override
public int compare(PersonFavouriteKey o1, PersonFavouriteKey o2)
{
int ret = 0;
for(Pair<FavouritesService.SortFields, Boolean> sort : sortProps)
{
FavouritesService.SortFields field = sort.getFirst();
Boolean ascending = sort.getSecond();
if(field.equals(FavouritesService.SortFields.username))
{
if(ascending)
{
ret = collator.compare(o1.getUserName(), o2.getUserName());
}
else
{
ret = o2.getUserName().compareTo(o1.getUserName());
}
if(ret != 0)
{
break;
}
}
else if(field.equals(FavouritesService.SortFields.type))
{
if(ascending)
{
ret = o1.getType().compareTo(o2.getType());
}
else
{
ret = o2.getType().compareTo(o1.getType());
}
if(ret != 0)
{
break;
}
}
else if(field.equals(FavouritesService.SortFields.createdAt))
{
if(ascending)
{
if(o1.getCreatedAt() != null && o2.getCreatedAt() != null)
{
ret = o1.getCreatedAt().compareTo(o2.getCreatedAt());
}
}
else
{
if(o1.getCreatedAt() != null && o2.getCreatedAt() != null)
{
ret = o2.getCreatedAt().compareTo(o1.getCreatedAt());
}
}
if(ret != 0)
{
break;
}
}
else if(field.equals(FavouritesService.SortFields.title))
{
if(ascending)
{
if(o1.getTitle() != null && o2.getTitle() != null)
{
ret = collator.compare(o1.getTitle(), o2.getTitle());
}
}
else
{
if(o1.getTitle() != null && o2.getTitle() != null)
{
ret = collator.compare(o2.getTitle(), o1.getTitle());
}
}
if(ret != 0)
{
break;
}
}
}
if(ret == 0)
{
// some favourites may not have a createdAt value, rendering this comparator less selective.
// If the favourites are still regarded as the same, differentiate on nodeRef.
ret = o1.getNodeRef().toString().compareTo(o2.getNodeRef().toString());
}
return ret;
}
};
return comparator;
}
private PersonFavourite addFavouriteSite(String userName, NodeRef nodeRef)
{
PersonFavourite favourite = null;
SiteInfo siteInfo = siteService.getSite(nodeRef);
if(siteInfo != null)
{
favourite = getFavouriteSite(userName, siteInfo);
if(favourite == null)
{
Map<String, Serializable> preferences = new HashMap<String, Serializable>(1);
String siteFavouritedKey = siteFavouritedKey(siteInfo);
preferences.put(siteFavouritedKey, Boolean.TRUE);
// ISO8601 string format: PreferenceService works with strings only for dates it seems
String siteCreatedAtKey = siteCreatedAtKey(siteInfo);
Date createdAt = new Date();
String createdAtStr = ISO8601DateFormat.format(createdAt);
preferences.put(siteCreatedAtKey, createdAtStr);
preferenceService.setPreferences(userName, preferences);
favourite = new PersonFavourite(userName, siteInfo.getNodeRef(), Type.SITE, siteInfo.getTitle(), createdAt);
QName nodeClass = nodeService.getType(nodeRef);
OnAddFavouritePolicy policy = onAddFavouriteDelegate.get(nodeRef, nodeClass);
policy.onAddFavourite(userName, nodeRef);
}
}
else
{
// shouldn't happen, getType recognizes it as a site or subtype
logger.warn("Unable to get site for " + nodeRef);
}
return favourite;
}
private PersonFavourite getFavouriteSite(String userName, SiteInfo siteInfo)
{
PersonFavourite favourite = null;
String siteFavouritedKey = siteFavouritedKey(siteInfo);
String siteCreatedAtKey = siteCreatedAtKey(siteInfo);
Boolean isFavourited = false;
Serializable s = preferenceService.getPreference(userName, siteFavouritedKey);
if(s != null)
{
if(s instanceof String)
{
isFavourited = Boolean.valueOf((String)s);
}
else if(s instanceof Boolean)
{
isFavourited = (Boolean)s;
}
else
{
throw new AlfrescoRuntimeException("Unexpected favourites preference value");
}
}
if(isFavourited)
{
String createdAtStr = (String)preferenceService.getPreference(userName, siteCreatedAtKey);
Date createdAt = (createdAtStr == null ? null : ISO8601DateFormat.parse(createdAtStr));
favourite = new PersonFavourite(userName, siteInfo.getNodeRef(), Type.SITE, siteInfo.getTitle(), createdAt);
}
return favourite;
}
private boolean isFavouriteSite(String userName, NodeRef nodeRef)
{
Boolean isFavourited = Boolean.FALSE;
SiteInfo siteInfo = siteService.getSite(nodeRef);
if(siteInfo != null)
{
String favouritedPrefKey = siteFavouritedKey(siteInfo);
Serializable value = preferenceService.getPreference(userName, favouritedPrefKey);
if(value != null)
{
if(value instanceof String)
{
isFavourited = Boolean.valueOf((String)value);
}
else if(value instanceof String)
{
isFavourited = (Boolean)value;
}
else
{
throw new AlfrescoRuntimeException("Unexpected favourites preference value");
}
}
}
else
{
throw new IllegalArgumentException("NodeRef " + nodeRef + " is not a site");
}
return isFavourited.booleanValue();
}
private void updateFavouriteNodes(String userName, Type type, Map<PersonFavouriteKey, PersonFavourite> favouriteNodes)
{
PrefKeys prefKeys = getPrefKeys(type);
Map<String, Serializable> preferences = new HashMap<String, Serializable>(1);
StringBuilder values = new StringBuilder();
for(PersonFavourite node : favouriteNodes.values())
{
NodeRef nodeRef = node.getNodeRef();
values.append(nodeRef.toString());
values.append(",");
// ISO8601 string format: PreferenceService works with strings only for dates it seems
StringBuilder sb = new StringBuilder(prefKeys.getAlfrescoPrefKey());
sb.append(nodeRef.toString());
sb.append(".createdAt");
String createdAtKey = sb.toString();
Date createdAt = node.getCreatedAt();
if(createdAt != null)
{
String createdAtStr = ISO8601DateFormat.format(createdAt);
preferences.put(createdAtKey, createdAtStr);
}
}
if(values.length() > 1)
{
values.delete(values.length() - 1, values.length());
}
preferences.put(prefKeys.getSharePrefKey(), values.toString());
preferenceService.setPreferences(userName, preferences);
}
private Map<PersonFavouriteKey, PersonFavourite> getFavouriteNodes(String userName, Type type)
{
PrefKeys prefKeys = getPrefKeys(type);
Map<PersonFavouriteKey, PersonFavourite> favouriteNodes = Collections.emptyMap();
Map<String, Serializable> prefs = preferenceService.getPreferences(userName, prefKeys.getSharePrefKey());
String nodes = (String)prefs.get(prefKeys.getSharePrefKey());
if(nodes != null)
{
favouriteNodes = extractFavouriteNodes(userName, type, nodes);
}
else
{
favouriteNodes = new HashMap<PersonFavouriteKey, PersonFavourite>();
}
return favouriteNodes;
}
/*
* Extract favourite nodes of the given type from the comma-separated list in "nodes".
*/
private Map<PersonFavouriteKey, PersonFavourite> extractFavouriteNodes(String userName, Type type, String nodes)
{
PrefKeys prefKeys = getPrefKeys(type);
Map<PersonFavouriteKey, PersonFavourite> favouriteNodes = new HashMap<PersonFavouriteKey, PersonFavourite>();
StringTokenizer st = new StringTokenizer(nodes, ",");
while(st.hasMoreTokens())
{
String nodeRefStr = st.nextToken();
nodeRefStr = nodeRefStr.trim();
if(!NodeRef.isNodeRef((String)nodeRefStr))
{
continue;
}
NodeRef nodeRef = new NodeRef((String)nodeRefStr);
if(!nodeService.exists(nodeRef))
{
continue;
}
if(permissionService.hasPermission(nodeRef, PermissionService.READ_PROPERTIES) == AccessStatus.DENIED)
{
continue;
}
// get createdAt for this favourited node
// use ISO8601
StringBuilder builder = new StringBuilder(prefKeys.getAlfrescoPrefKey());
builder.append(nodeRef.toString());
builder.append(".createdAt");
String prefKey = builder.toString();
String createdAtStr = (String)preferenceService.getPreference(userName, prefKey);
Date createdAt = (createdAtStr != null ? ISO8601DateFormat.parse(createdAtStr): null);
String name = (String)nodeService.getProperty(nodeRef, ContentModel.PROP_NAME);
PersonFavourite personFavourite = new PersonFavourite(userName, nodeRef, type, name, createdAt);
PersonFavouriteKey key = personFavourite.getKey();
favouriteNodes.put(key, personFavourite);
}
return favouriteNodes;
}
private void extractFavouriteSite(String userName, Type type, Map<PersonFavouriteKey, PersonFavourite> sortedFavouriteNodes, Map<String, Serializable> preferences, String key)
{
// preference value indicates whether the site has been favourited
Serializable pref = preferences.get(key);
Boolean isFavourite = (Boolean)pref;
if(isFavourite)
{
PrefKeys sitePrefKeys = getPrefKeys(Type.SITE);
int length = sitePrefKeys.getSharePrefKey().length();
String siteId = key.substring(length);
try
{
SiteInfo siteInfo = siteService.getSite(siteId);
if(siteInfo != null)
{
StringBuilder builder = new StringBuilder(sitePrefKeys.getAlfrescoPrefKey());
builder.append(siteId);
builder.append(".createdAt");
String createdAtPrefKey = builder.toString();
String createdAtStr = (String)preferences.get(createdAtPrefKey);
Date createdAt = null;
if(createdAtStr != null)
{
createdAt = (createdAtStr != null ? ISO8601DateFormat.parse(createdAtStr): null);
}
PersonFavourite personFavourite = new PersonFavourite(userName, siteInfo.getNodeRef(), Type.SITE, siteId, createdAt);
sortedFavouriteNodes.put(personFavourite.getKey(), personFavourite);
}
}
catch(AccessDeniedException ex)
{
// the user no longer has access to this site, skip over the favourite
// TODO remove the favourite preference
return;
}
}
}
private PersonFavourite getFavouriteDocumentOrFolder(String userName, Type type, NodeRef nodeRef)
{
PersonFavourite favourite = null;
PrefKeys prefKeys = getPrefKeys(type);
Map<String, Serializable> preferences = preferenceService.getPreferences(userName, prefKeys.getSharePrefKey());
String nodes = (String)preferences.get(prefKeys.getSharePrefKey());
if(nodes != null)
{
Map<PersonFavouriteKey, PersonFavourite> favouriteNodes = extractFavouriteNodes(userName, type, nodes);
String title = (String)nodeService.getProperty(nodeRef, ContentModel.PROP_TITLE);
PersonFavouriteKey key = new PersonFavouriteKey(userName, title, type, nodeRef);
favourite = favouriteNodes.get(key);
}
return favourite;
}
private PersonFavourite getPersonFavourite(String userName, Type type, NodeRef nodeRef)
{
PersonFavourite ret = null;
if(type.equals(Type.SITE))
{
SiteInfo siteInfo = siteService.getSite(nodeRef);
if(siteInfo != null)
{
ret = getFavouriteSite(userName, siteInfo);
}
else
{
// shouldn't happen, getType recognizes it as a site or subtype
logger.warn("Unable to get site for " + nodeRef);
}
}
else if(type.equals(Type.FILE))
{
ret = getFavouriteDocumentOrFolder(userName, type, nodeRef);
}
else if(type.equals(Type.FOLDER))
{
ret = getFavouriteDocumentOrFolder(userName, type, nodeRef);
}
else
{
// shouldn't happen
throw new AlfrescoRuntimeException("Unexpected favourite type");
}
return ret;
}
private PersonFavourite addFavouriteDocumentOrFolder(String userName, Type type, NodeRef nodeRef)
{
Map<PersonFavouriteKey, PersonFavourite> personFavourites = getFavouriteNodes(userName, type);
PersonFavourite personFavourite = getPersonFavourite(userName, type, nodeRef);
if(personFavourite == null)
{
Date createdAt = new Date();
String name = (String)nodeService.getProperty(nodeRef, ContentModel.PROP_NAME);
personFavourite = new PersonFavourite(userName, nodeRef, type, name, createdAt);
personFavourites.put(personFavourite.getKey(), personFavourite);
updateFavouriteNodes(userName, type, personFavourites);
QName nodeClass = nodeService.getType(nodeRef);
OnAddFavouritePolicy policy = onAddFavouriteDelegate.get(nodeRef, nodeClass);
policy.onAddFavourite(userName, nodeRef);
}
return personFavourite;
}
private boolean isFavouriteNode(String userName, Type type, NodeRef nodeRef)
{
Map<PersonFavouriteKey, PersonFavourite> personFavourites = getFavouriteNodes(userName, type);
PersonFavouriteKey personFavouriteKey = new PersonFavouriteKey(userName, null, type, nodeRef);
boolean isFavourite = personFavourites.containsKey(personFavouriteKey);
return isFavourite;
}
public Type getType(NodeRef nodeRef)
{
Type favouriteType = null;
QName type = nodeService.getType(nodeRef);
boolean isSite = dictionaryService.isSubClass(type, SiteModel.TYPE_SITE);
if(isSite)
{
favouriteType = Type.SITE;
}
else
{
boolean isContainer = (dictionaryService.isSubClass(type, ContentModel.TYPE_FOLDER) &&
!dictionaryService.isSubClass(type, ContentModel.TYPE_SYSTEM_FOLDER));
if(isContainer)
{
favouriteType = Type.FOLDER;
}
else
{
boolean isFile = dictionaryService.isSubClass(type, ContentModel.TYPE_CONTENT);
if(isFile)
{
favouriteType = Type.FILE;
}
}
}
return favouriteType;
}
private boolean removeFavouriteNode(String userName, Type type, NodeRef nodeRef)
{
boolean exists = false;
Map<PersonFavouriteKey, PersonFavourite> personFavourites = getFavouriteNodes(userName, type);
PersonFavouriteKey personFavouriteKey = new PersonFavouriteKey(userName, null, type, nodeRef);
PersonFavourite personFavourite = personFavourites.remove(personFavouriteKey);
exists = personFavourite != null;
updateFavouriteNodes(userName, type, personFavourites);
QName nodeClass = nodeService.getType(nodeRef);
OnRemoveFavouritePolicy policy = onRemoveFavouriteDelegate.get(nodeRef, nodeClass);
policy.onRemoveFavourite(userName, nodeRef);
return exists;
}
@Override
public PersonFavourite addFavourite(String userName, NodeRef nodeRef)
{
PersonFavourite personFavourite = null;
Type type = getType(nodeRef);
if(type == null)
{
throw new IllegalArgumentException("Cannot favourite this node");
}
else if(type.equals(Type.FILE))
{
personFavourite = addFavouriteDocumentOrFolder(userName, Type.FILE, nodeRef);
}
else if(type.equals(Type.FOLDER))
{
personFavourite = addFavouriteDocumentOrFolder(userName, Type.FOLDER, nodeRef);
}
else if(type.equals(Type.SITE))
{
personFavourite = addFavouriteSite(userName, nodeRef);
}
else
{
throw new IllegalArgumentException("Cannot favourite this node");
}
return personFavourite;
}
@Override
public boolean removeFavourite(String userName, NodeRef nodeRef)
{
boolean exists = false;
Type type = getType(nodeRef);
if(type == null)
{
throw new IllegalArgumentException("Cannot un-favourite this node");
}
else if(type.equals(Type.FILE))
{
exists = removeFavouriteNode(userName, type, nodeRef);
}
else if(type.equals(Type.FOLDER))
{
exists = removeFavouriteNode(userName, type, nodeRef);
}
else if(type.equals(Type.SITE))
{
exists = removeFavouriteSite(userName, nodeRef);
}
else
{
throw new IllegalArgumentException("Cannot un-favourite this node");
}
return exists;
}
@Override
public boolean isFavourite(String userName, NodeRef nodeRef)
{
boolean isFavourite = false;
Type type = getType(nodeRef);
if(type == null)
{
throw new IllegalArgumentException("Unsupported node type");
}
else if(type.equals(Type.FILE))
{
isFavourite = isFavouriteNode(userName, type, nodeRef);
}
else if(type.equals(Type.FOLDER))
{
isFavourite = isFavouriteNode(userName, type, nodeRef);
}
else if(type.equals(Type.SITE))
{
isFavourite = isFavouriteSite(userName, nodeRef);
}
else
{
throw new IllegalArgumentException("Unsupported node type");
}
return isFavourite;
}
@Override
public PagingResults<PersonFavourite> getPagedFavourites(String userName, Set<Type> types,
List<Pair<FavouritesService.SortFields, Boolean>> sortProps, PagingRequest pagingRequest)
{
// Get the user node reference
final NodeRef personNodeRef = personService.getPerson(userName);
if(personNodeRef == null)
{
throw new AlfrescoRuntimeException("Can not get preferences for " + userName + " because he/she does not exist.");
}
boolean includeFiles = types.contains(Type.FILE);
boolean includeFolders = types.contains(Type.FOLDER);
boolean includeSites = types.contains(Type.SITE);
String currentUserName = AuthenticationUtil.getFullyAuthenticatedUser();
if (authenticationContext.isSystemUserName(currentUserName) == true ||
permissionService.hasPermission(personNodeRef, PermissionService.WRITE) == AccessStatus.ALLOWED ||
userName.equals(currentUserName) == true)
{
// we may have more than one favourite that is considered the same w.r.t. the PersonFavourite comparator
final Map<PersonFavouriteKey, PersonFavourite> sortedFavouriteNodes = new TreeMap<PersonFavouriteKey, PersonFavourite>(getComparator(sortProps));
PrefKeys sitePrefKeys = getPrefKeys(Type.SITE);
PrefKeys documentsPrefKeys = getPrefKeys(Type.FILE);
PrefKeys foldersPrefKeys = getPrefKeys(Type.FOLDER);
Map<String, Serializable> preferences = preferenceService.getPreferences(userName);
for(String key : preferences.keySet())
{
if(includeFiles && key.startsWith(documentsPrefKeys.sharePrefKey))
{
String nodes = (String)preferences.get(key);
if(nodes != null)
{
sortedFavouriteNodes.putAll(extractFavouriteNodes(userName, Type.FILE, nodes));
}
}
else if(includeFolders && key.startsWith(foldersPrefKeys.sharePrefKey))
{
String nodes = (String)preferences.get(key);
if(nodes != null)
{
sortedFavouriteNodes.putAll(extractFavouriteNodes(userName, Type.FOLDER, nodes));
}
}
else if(includeSites && key.startsWith(sitePrefKeys.getSharePrefKey()) && !key.endsWith(".createdAt"))
{
// key is either of the form org.alfresco.share.sites.favourites.<siteId>.favourited or
// org.alfresco.share.sites.favourites.<siteId>
extractFavouriteSite(userName, Type.SITE, sortedFavouriteNodes, preferences, key);
}
}
int totalSize = sortedFavouriteNodes.size();
final PageDetails pageDetails = PageDetails.getPageDetails(pagingRequest, totalSize);
final List<PersonFavourite> page = new ArrayList<PersonFavourite>(pageDetails.getPageSize());
Iterator<PersonFavourite> it = sortedFavouriteNodes.values().iterator();
for(int counter = 0; counter < pageDetails.getEnd() && it.hasNext(); counter++)
{
PersonFavourite favouriteNode = it.next();
if(counter < pageDetails.getSkipCount())
{
continue;
}
if(counter > pageDetails.getEnd() - 1)
{
break;
}
page.add(favouriteNode);
}
return new PagingResults<PersonFavourite>()
{
@Override
public List<PersonFavourite> getPage()
{
return page;
}
@Override
public boolean hasMoreItems()
{
return pageDetails.hasMoreItems();
}
@Override
public Pair<Integer, Integer> getTotalResultCount()
{
Integer total = Integer.valueOf(sortedFavouriteNodes.size());
return new Pair<Integer, Integer>(total, total);
}
@Override
public String getQueryExecutionId()
{
return null;
}
};
}
else
{
// The current user does not have sufficient permissions to update the preferences for this user
throw new AccessDeniedException("The current user " + currentUserName + " does not have sufficient permissions to get the favourites of the user " + userName);
}
}
public PersonFavourite getFavourite(String userName, NodeRef nodeRef)
{
Type type = getType(nodeRef);
return getPersonFavourite(userName, type, nodeRef);
}
}