Java tutorial
/* * #%L * Alfresco Repository * %% * 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 <http://www.gnu.org/licenses/>. * #L% */ 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.events.types.ActivityEvent; import org.alfresco.events.types.Event; import org.alfresco.model.ContentModel; import org.alfresco.query.PageDetails; import org.alfresco.query.PagingRequest; import org.alfresco.query.PagingResults; import org.alfresco.repo.Client; import org.alfresco.repo.Client.ClientType; import org.alfresco.repo.events.EventPreparator; import org.alfresco.repo.events.EventPublisher; 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; private EventPublisher eventPublisher; /** 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 Boolean) { 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(); final 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); final String finalRef = nodeRef.getId(); final QName nodeType = nodeClass; eventPublisher.publishEvent(new EventPreparator() { @Override public Event prepareEvent(String user, String networkId, String transactionId) { return new ActivityEvent("favorite.added", transactionId, networkId, user, finalRef, null, nodeType == null ? null : nodeType.toString(), Client.asType(ClientType.script), null, name, null, 0l, null); } }); 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); final String finalRef = nodeRef.getId(); final QName nodeType = nodeClass; eventPublisher.publishEvent(new EventPreparator() { @Override public Event prepareEvent(String user, String networkId, String transactionId) { return new ActivityEvent("favorite.removed", transactionId, networkId, user, finalRef, null, nodeType == null ? null : nodeType.toString(), Client.asType(ClientType.script), null, null, null, 0l, null); } }); 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); } public void setEventPublisher(EventPublisher eventPublisher) { this.eventPublisher = eventPublisher; } }