mirror of
				https://github.com/Alfresco/alfresco-community-repo.git
				synced 2025-10-29 15:21:53 +00:00 
			
		
		
		
	51903 to 54309 git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@54310 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
		
			
				
	
	
		
			925 lines
		
	
	
		
			29 KiB
		
	
	
	
		
			Java
		
	
	
	
	
	
			
		
		
	
	
			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);
 | |
|     }
 | |
| }
 |