/*
* #%L
* Alfresco Remote API
* %%
* Copyright (C) 2005 - 2016 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see .
* #L%
*/
package org.alfresco.rest.api.tests;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.io.Serializable;
import java.sql.SQLException;
import java.text.Collator;
import java.util.ArrayList;
import java.util.Collection;
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.Random;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
import org.alfresco.model.ContentModel;
import org.alfresco.opencmis.CMISConnector;
import org.alfresco.opencmis.CMISNodeInfoImpl;
import org.alfresco.query.PageDetails;
import org.alfresco.query.PagingRequest;
import org.alfresco.query.PagingResults;
import org.alfresco.repo.activities.feed.FeedGenerator;
import org.alfresco.repo.activities.feed.cleanup.FeedCleaner;
import org.alfresco.repo.activities.post.lookup.PostLookup;
import org.alfresco.repo.content.MimetypeMap;
import org.alfresco.repo.content.cleanup.ContentStoreCleaner;
import org.alfresco.repo.domain.activities.ActivityFeedEntity;
import org.alfresco.repo.domain.activities.ActivityPostDAO;
import org.alfresco.repo.forum.CommentService;
import org.alfresco.repo.invitation.InvitationSearchCriteriaImpl;
import org.alfresco.repo.management.subsystems.ChildApplicationContextFactory;
import org.alfresco.repo.model.filefolder.HiddenAspect;
import org.alfresco.repo.model.filefolder.HiddenAspect.Visibility;
import org.alfresco.repo.node.index.NodeIndexer;
import org.alfresco.repo.security.authentication.AuthenticationException;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
import org.alfresco.repo.site.SiteDoesNotExistException;
import org.alfresco.repo.tenant.Network;
import org.alfresco.repo.tenant.NetworksService;
import org.alfresco.repo.tenant.TenantAdminService;
import org.alfresco.repo.tenant.TenantService;
import org.alfresco.repo.tenant.TenantUtil;
import org.alfresco.repo.tenant.TenantUtil.TenantRunAsWork;
import org.alfresco.repo.transaction.RetryingTransactionHelper;
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
import org.alfresco.repo.version.VersionModel;
import org.alfresco.repo.web.scripts.invitation.InvitationWebScriptTest;
import org.alfresco.rest.api.Activities;
import org.alfresco.rest.api.impl.node.ratings.RatingScheme;
import org.alfresco.rest.api.tests.client.data.Activity;
import org.alfresco.rest.api.tests.client.data.Comment;
import org.alfresco.rest.api.tests.client.data.Company;
import org.alfresco.rest.api.tests.client.data.FavouriteDocument;
import org.alfresco.rest.api.tests.client.data.FavouriteFolder;
import org.alfresco.rest.api.tests.client.data.FavouriteSite;
import org.alfresco.rest.api.tests.client.data.MemberOfSite;
import org.alfresco.rest.api.tests.client.data.NetworkImpl;
import org.alfresco.rest.api.tests.client.data.NodeRating;
import org.alfresco.rest.api.tests.client.data.NodeRating.Aggregate;
import org.alfresco.rest.api.tests.client.data.Person;
import org.alfresco.rest.api.tests.client.data.PersonNetwork;
import org.alfresco.rest.api.tests.client.data.SiteContainer;
import org.alfresco.rest.api.tests.client.data.SiteImpl;
import org.alfresco.rest.api.tests.client.data.SiteMember;
import org.alfresco.rest.api.tests.client.data.SiteRole;
import org.alfresco.rest.api.tests.client.data.Tag;
import org.alfresco.service.cmr.activities.ActivityService;
import org.alfresco.service.cmr.coci.CheckOutCheckInService;
import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.cmr.favourites.FavouritesService;
import org.alfresco.service.cmr.invitation.Invitation;
import org.alfresco.service.cmr.invitation.InvitationSearchCriteria.InvitationType;
import org.alfresco.service.cmr.invitation.InvitationService;
import org.alfresco.service.cmr.lock.LockService;
import org.alfresco.service.cmr.lock.LockType;
import org.alfresco.service.cmr.model.FileExistsException;
import org.alfresco.service.cmr.model.FileFolderService;
import org.alfresco.service.cmr.model.FileInfo;
import org.alfresco.service.cmr.model.FileNotFoundException;
import org.alfresco.service.cmr.preference.PreferenceService;
import org.alfresco.service.cmr.rating.Rating;
import org.alfresco.service.cmr.rating.RatingService;
import org.alfresco.service.cmr.repository.AssociationRef;
import org.alfresco.service.cmr.repository.ContentReader;
import org.alfresco.service.cmr.repository.ContentService;
import org.alfresco.service.cmr.repository.ContentWriter;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.security.MutableAuthenticationService;
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.cmr.site.SiteVisibility;
import org.alfresco.service.cmr.tagging.TaggingService;
import org.alfresco.service.cmr.version.Version;
import org.alfresco.service.cmr.version.VersionHistory;
import org.alfresco.service.cmr.version.VersionService;
import org.alfresco.service.cmr.version.VersionType;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName;
import org.alfresco.util.FileFilterMode.Client;
import org.alfresco.util.GUID;
import org.alfresco.util.Pair;
import org.alfresco.util.registry.NamedObjectRegistry;
import org.apache.chemistry.opencmis.commons.data.CmisExtensionElement;
import org.apache.chemistry.opencmis.commons.data.Properties;
import org.apache.chemistry.opencmis.commons.data.PropertyData;
import org.apache.chemistry.opencmis.commons.impl.dataobjects.PropertyStringImpl;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.json.JSONException;
import org.json.simple.JSONObject;
import org.json.simple.JSONValue;
import org.quartz.JobExecutionException;
import org.quartz.Scheduler;
import org.springframework.context.ApplicationContext;
import org.springframework.scheduling.quartz.JobDetailBean;
import com.google.common.collect.AbstractIterator;
/**
* A convenient proxy into the repository services to support the tests.
*
* @author steveglover
*
*/
public class RepoService
{
private static final Log logger = LogFactory.getLog(RepoService.class);
protected static final String TEST_SITE_PRESET = "testSitePreset";
private static final String FAVOURITE_SITES_PREFIX = "org.alfresco.share.sites.favourites.";
private static final int FAVOURITE_SITES_PREFIX_LENGTH = FAVOURITE_SITES_PREFIX.length();
protected ApplicationContext applicationContext;
protected MutableAuthenticationService authenticationService;
protected DictionaryService dictionaryService;
protected SiteService siteService;
protected ActivityService activityService;
protected PostLookup postLookup;
protected FeedGenerator feedGenerator;
protected FileFolderService fileFolderService;
protected ContentService contentService;
protected CommentService commentService;
protected NodeService nodeService;
protected PreferenceService preferenceService;
protected TaggingService taggingService;
protected RatingService ratingService;
protected TenantService tenantService;
protected TenantAdminService tenantAdminService;
protected ActivityPostDAO postDAO;
protected JobDetailBean feedGeneratorJobDetail;
protected JobDetailBean postLookupJobDetail;
protected JobDetailBean feedCleanerJobDetail;
protected JobDetailBean postCleanerJobDetail;
protected JobDetailBean feedNotifierJobDetail;
protected ContentStoreCleaner contentStoreCleaner;
protected FeedCleaner feedCleaner;
protected PersonService personService;
protected NamedObjectRegistry nodeRatingSchemeRegistry;
protected VersionService versionService;
protected CheckOutCheckInService cociService;
protected FavouritesService favouritesService;
protected InvitationService invitationService;
protected LockService lockService;
protected CMISConnector cmisConnector;
protected NodeIndexer nodeIndexer;
protected HiddenAspect hiddenAspect;
protected NetworksService networksService;
protected NamespaceService namespaceService;
protected RetryingTransactionHelper transactionHelper;
protected Activities activities;
protected PublicApiTestContext publicApiContext;
protected Random random = new Random(System.currentTimeMillis());
protected static int numNetworks = 0;
/*
* Represents the "system" tenant/network
*/
protected TestNetwork systemNetwork;
/*
* A map of user names (stored in the map in lower case) and TestPersons
*/
protected Map allPeople = new HashMap();
// Needed for CGLIB to create proxy, see CloudRepoService
public RepoService()
{
}
@SuppressWarnings("unchecked")
public RepoService(ApplicationContext applicationContext) throws Exception
{
this.applicationContext = applicationContext;
this.publicApiContext = new PublicApiTestContext(applicationContext);
this.authenticationService = (MutableAuthenticationService)applicationContext.getBean("AuthenticationService");
this.siteService = (SiteService)applicationContext.getBean("SiteService");
this.activityService = (ActivityService)applicationContext.getBean("activityService");
this.fileFolderService = (FileFolderService)applicationContext.getBean("FileFolderService");
this.contentService = (ContentService)applicationContext.getBean("ContentService");
this.commentService = (CommentService)applicationContext.getBean("CommentService");
this.nodeService = (NodeService)applicationContext.getBean("NodeService");
this.preferenceService = (PreferenceService)applicationContext.getBean("PreferenceService");
this.taggingService = (TaggingService)applicationContext.getBean("TaggingService");
this.ratingService = (RatingService)applicationContext.getBean("RatingService");
this.tenantService = (TenantService)applicationContext.getBean("tenantService");
this.tenantAdminService = (TenantAdminService)applicationContext.getBean("tenantAdminService");
this.personService = (PersonService)applicationContext.getBean("PersonService");
this.contentStoreCleaner = (ContentStoreCleaner)applicationContext.getBean("contentStoreCleaner");
this.postDAO = (ActivityPostDAO)applicationContext.getBean("postDAO");
this.nodeRatingSchemeRegistry = (NamedObjectRegistry)applicationContext.getBean("nodeRatingSchemeRegistry");
this.cociService = (CheckOutCheckInService)applicationContext.getBean("CheckoutCheckinService");
this.favouritesService = (FavouritesService)applicationContext.getBean("FavouritesService");
this.dictionaryService = (DictionaryService)applicationContext.getBean("dictionaryService");
this.invitationService = (InvitationService)applicationContext.getBean("InvitationService");
this.lockService = (LockService)applicationContext.getBean("LockService");
this.cmisConnector = (CMISConnector)applicationContext.getBean("CMISConnector");
this.nodeIndexer = (NodeIndexer)applicationContext.getBean("nodeIndexer");
this.activities = (Activities)applicationContext.getBean("activities");
this.hiddenAspect = (HiddenAspect)applicationContext.getBean("hiddenAspect");
this.networksService = (NetworksService)applicationContext.getBean("networksService");
this.namespaceService = (NamespaceService)applicationContext.getBean("namespaceService");
this.transactionHelper = (RetryingTransactionHelper)applicationContext.getBean("retryingTransactionHelper");
Scheduler scheduler = (Scheduler)applicationContext.getBean("schedulerFactory");
JobDetailBean contentStoreCleanerJobDetail = (JobDetailBean)applicationContext.getBean("contentStoreCleanerJobDetail");
scheduler.pauseJob(contentStoreCleanerJobDetail.getName(), contentStoreCleanerJobDetail.getGroup());
ChildApplicationContextFactory activitiesFeed = (ChildApplicationContextFactory)applicationContext.getBean("ActivitiesFeed");
ApplicationContext activitiesFeedCtx = activitiesFeed.getApplicationContext();
this.postLookup = (PostLookup)activitiesFeedCtx.getBean("postLookup");
this.feedGenerator = (FeedGenerator)activitiesFeedCtx.getBean("feedGenerator");
this.feedGeneratorJobDetail = (JobDetailBean)activitiesFeedCtx.getBean("feedGeneratorJobDetail");
this.postLookupJobDetail = (JobDetailBean)activitiesFeedCtx.getBean("postLookupJobDetail");
this.feedCleanerJobDetail = (JobDetailBean)activitiesFeedCtx.getBean("feedCleanerJobDetail");
this.postCleanerJobDetail = (JobDetailBean)activitiesFeedCtx.getBean("postCleanerJobDetail");
this.feedNotifierJobDetail = (JobDetailBean)activitiesFeedCtx.getBean("feedNotifierJobDetail");
this.feedCleaner = (FeedCleaner)activitiesFeedCtx.getBean("feedCleaner");
// Pause activities jobs so that we aren't competing with their scheduled versions
scheduler.pauseJob(feedGeneratorJobDetail.getName(), feedGeneratorJobDetail.getGroup());
scheduler.pauseJob(postLookupJobDetail.getName(), postLookupJobDetail.getGroup());
scheduler.pauseJob(feedCleanerJobDetail.getName(), feedCleanerJobDetail.getGroup());
scheduler.pauseJob(postCleanerJobDetail.getName(), postCleanerJobDetail.getGroup());
scheduler.pauseJob(feedNotifierJobDetail.getName(), feedNotifierJobDetail.getGroup());
this.systemNetwork = new TestNetwork(TenantService.DEFAULT_DOMAIN, true);
}
public TestNetwork getSystemNetwork()
{
return systemNetwork;
}
public PublicApiTestContext getPublicApiContext()
{
return publicApiContext;
}
public void addPerson(TestPerson person)
{
allPeople.put(person.getId().toLowerCase(), person);
}
public NodeService getNodeService()
{
return nodeService;
}
public TestPerson getPerson(String username)
{
return allPeople.get(username.toLowerCase());
}
public void disableInTxnIndexing()
{
nodeIndexer.setDisabled(true);
}
public int getClientVisibilityMask(Client client, Visibility visibility)
{
return hiddenAspect.getClientVisibilityMask(client, visibility);
}
public ApplicationContext getApplicationContext()
{
return applicationContext;
}
public AssociationRef createAssociation(NodeRef sourceRef, NodeRef targetRef, QName assocTypeQName)
{
return nodeService.createAssociation(sourceRef, targetRef, assocTypeQName);
}
public String toPrefixString(QName qname)
{
return qname.toPrefixString(namespaceService);
}
public Invitation approveSiteInvitation(String personId, String siteId)
{
Invitation ret = null;
List invitations = invitationService.listPendingInvitationsForInvitee(personId);
for(Invitation invitation : invitations)
{
if(invitation.getResourceName().equals(siteId))
{
ret = invitationService.approve(invitation.getInviteId(), "I accept you");
}
}
return ret;
}
public void moveNode(NodeRef nodeToMoveRef, NodeRef newParentNodeRef) throws FileExistsException, FileNotFoundException
{
fileFolderService.move(nodeToMoveRef, newParentNodeRef, GUID.generate());
}
public void deleteNode(NodeRef nodeRef)
{
nodeService.deleteNode(nodeRef);
}
public void lockNode(NodeRef nodeRef)
{
lockService.lock(nodeRef, LockType.NODE_LOCK);
}
public void unlockNode(NodeRef nodeRef)
{
lockService.unlock(nodeRef);
}
public NodeRef addUserDescription(final String personId, final TestNetwork network, final String personDescription)
{
return AuthenticationUtil.runAsSystem(new RunAsWork()
{
//@Override
public NodeRef doWork() throws Exception
{
NodeRef userRef = personService.getPersonOrNull(personId);
if (userRef == null)
{
throw new AuthenticationException("User name does not exist: " + personId);
}
ContentWriter writer = contentService.getWriter(userRef, ContentModel.PROP_PERSONDESC, true);
writer.setMimetype(MimetypeMap.MIMETYPE_HTML);
writer.putContent(personDescription);
log("Updated person description " + personId + (network != null ? " in network " + network : ""));
return userRef;
}
});
}
public TestPerson createUser(final PersonInfo personInfo, final String username, final TestNetwork network)
{
return getOrCreateUser(personInfo, username, network, true);
}
public TestPerson getOrCreateUser(final PersonInfo personInfo, final String username, final TestNetwork network)
{
return getOrCreateUser(personInfo, username, network, false);
}
public final static String DEFAULT_ADMIN = "admin";
public final static String DEFAULT_ADMIN_PWD = "admin";
// TODO improve admin-related API tests (including ST vs MT)
private boolean isDefaultAdmin(String username, TestNetwork network)
{
if ((network == null) || (TenantService.DEFAULT_DOMAIN.equals(network.getId())))
{
return (DEFAULT_ADMIN.equalsIgnoreCase(username));
}
else
{
return ((DEFAULT_ADMIN+"@"+network.getId()).equalsIgnoreCase(username));
}
}
// TODO review delete person
public TestPerson getOrCreateUser(final PersonInfo personInfo, final String username, final TestNetwork network, final boolean deletePerson)
{
return AuthenticationUtil.runAsSystem(new RunAsWork()
{
@Override
public TestPerson doWork() throws Exception
{
final TestPerson testPerson = new TestPerson(personInfo.getFirstName(), personInfo.getLastName(), username, personInfo.getPassword(),
personInfo.getCompany(), network, personInfo.getSkype(), personInfo.getLocation(), personInfo.getTel(),
personInfo.getMob(), personInfo.getInstantmsg(), personInfo.getGoogle());
final Map props = testPerson.getProperties();
// short-circuit for default/tenant "admin"
if (! isDefaultAdmin(username, network))
{
NodeRef personNodeRef = personService.getPersonOrNull(username);
if ((personNodeRef != null) && deletePerson)
{
AuthenticationUtil.runAsSystem(new RunAsWork()
{
@Override
public Void doWork() throws Exception
{
personService.deletePerson(testPerson.getId());
return null;
}
});
}
if (personNodeRef == null)
{
personNodeRef = personService.createPerson(props);
// create authentication to represent user
authenticationService.createAuthentication(username, personInfo.getPassword().toCharArray());
if (EnterpriseTestFixture.WITH_AVATAR.equals(personInfo.getInstantmsg()))
{
InvitationWebScriptTest.makeAvatar(nodeService, personNodeRef);
log("Made avatar for " + testPerson.getId() + (network != null ? " in network " + network : ""));
}
}
}
log("Username " + testPerson.getId() + (network != null ? " in network " + network : ""));
publicApiContext.addUser(testPerson.getId());
addPerson(testPerson);
return testPerson;
}
});
}
protected void deleteUser(final String username, final TestNetwork network)
{
AuthenticationUtil.runAsSystem(new RunAsWork()
{
@Override
public TestPerson doWork() throws Exception
{
if (personService.personExists(username))
{
authenticationService.deleteAuthentication(username);
personService.deletePerson(username);
}
return null;
}
});
}
public TestSite createSite(TestNetwork network, final SiteInformation site)
{
SiteInfo siteInfo = null;
if(siteService.hasSite(site.getShortName()))
{
AuthenticationUtil.runAsSystem(new RunAsWork()
{
@Override
public Void doWork() throws Exception
{
siteService.deleteSite(site.getShortName());
return null;
}
});
}
siteInfo = siteService.createSite(TEST_SITE_PRESET, site.getShortName(), site.getTitle(), site.getDescription(), site.getSiteVisibility());
siteService.createContainer(site.getShortName(), "documentLibrary", ContentModel.TYPE_FOLDER, null);
final TestSite testSite = new TestSite(network, siteInfo);
log("Created site " + testSite + (network != null ? " in network " + network : ""));
return testSite;
}
public Invitation rejectSiteInvitation(String personId, String siteId)
{
Invitation ret = null;
List invitations = invitationService.listPendingInvitationsForInvitee(personId);
for(Invitation invitation : invitations)
{
if(invitation.getResourceName().equals(siteId))
{
ret = invitationService.reject(invitation.getInviteId(), "I reject you");
}
}
return ret;
}
public List getModeratedSiteInvitations(String networkId, String runAsUserId, final String inviteeId, final String siteId)
{
List invitations = TenantUtil.runAsUserTenant(new TenantRunAsWork>()
{
@Override
public List doWork() throws Exception
{
InvitationSearchCriteriaImpl searchCriteria = new InvitationSearchCriteriaImpl();
searchCriteria.setInvitee(inviteeId);
if(siteId != null)
{
searchCriteria.setResourceName(siteId);
}
searchCriteria.setResourceType(Invitation.ResourceType.WEB_SITE);
searchCriteria.setInvitationType(InvitationType.MODERATED);
List invitations = invitationService.searchInvitation(searchCriteria);
return invitations;
}
}, runAsUserId, networkId);
return invitations;
}
public Version getCurrentVersion(NodeRef nodeRef)
{
return versionService.getCurrentVersion(nodeRef);
}
protected void log(String msg)
{
if(logger.isDebugEnabled())
{
logger.debug(msg);
}
}
public SiteInfo getSiteInfo(String siteId)
{
return siteService.getSite(siteId);
}
public boolean isCheckedOut(NodeRef nodeRef)
{
return cociService.isCheckedOut(nodeRef);
}
public Serializable getProperty(NodeRef nodeRef, QName propertyName)
{
Serializable value = nodeService.getProperty(nodeRef, propertyName);
return value;
}
public Set getAspects(NodeRef nodeRef)
{
Set aspects = nodeService.getAspects(nodeRef);
return aspects;
}
public ContentReader getContent(NodeRef nodeRef, QName propertyQName)
{
ContentReader reader = contentService.getReader(nodeRef, propertyQName);
return reader;
}
private void cleanupContent()
{
// eagerCleaner.setEagerOrphanCleanup(false);
log("Cleaning up feeds...");
// fire the cleaner
feedCleaner.setMaxAgeMins(1);
feedCleaner.setMaxFeedSize(1);
try
{
feedCleaner.execute();
}
catch(JobExecutionException e)
{
// TODO
}
log("...done");
log("Cleaning up content...");
// fire the cleaner
contentStoreCleaner.setProtectDays(0);
contentStoreCleaner.execute();
log("...done");
}
public void shutdown()
{
cleanupContent();
publicApiContext.cleanup();
}
public Version createVersion(NodeRef nodeRef, String history, boolean majorVersion)
{
Map props = new HashMap(2, 1.0f);
props.put(Version.PROP_DESCRIPTION, history);
props.put(VersionModel.PROP_VERSION_TYPE, majorVersion ? VersionType.MAJOR : VersionType.MINOR);
return versionService.createVersion(nodeRef, props);
}
public VersionHistory getVersionHistory(NodeRef nodeRef)
{
return versionService.getVersionHistory(nodeRef);
}
public Pair splitSiteNetwork(String siteNetwork)
{
int idx = siteNetwork.indexOf("@");
String siteId = siteNetwork;
String networkId = null;
if(idx > -1)
{
siteId = siteNetwork.substring(0, idx - 1);
networkId = siteNetwork.substring(idx + 1);
}
return new Pair(siteId, networkId);
}
private Map parseActivitySummary(ActivityFeedEntity entity)
{
String activityType = entity.getActivityType();
String activitySummary = entity.getActivitySummary();
JSONObject json = (JSONObject)JSONValue.parse(activitySummary);
return Activity.getActivitySummary(json, activityType);
}
public List getActivities(String personId, String siteId, boolean excludeUser, boolean excludeOthers)
{
List feedEntities = activityService.getUserFeedEntries(personId, siteId, excludeUser, excludeOthers, 0);
List activities = new ArrayList(feedEntities.size());
for(ActivityFeedEntity entity : feedEntities)
{
String siteNetwork = entity.getSiteNetwork();
Pair pair = splitSiteNetwork(siteNetwork);
siteId = pair.getFirst();
String networkId = pair.getSecond();
String postDateStr = PublicApiDateFormat.getDateFormat().format(entity.getPostDate());
Activity activity = new Activity(entity.getId(), networkId, siteId, entity.getFeedUserId(), entity.getPostUserId(), postDateStr, entity.getActivityType(), parseActivitySummary(entity));
activities.add(activity);
}
return activities;
}
public Rating getRating(NodeRef targetNode, String scheme)
{
return ratingService.getRatingByCurrentUser(targetNode, scheme);
}
public List getRatings(NodeRef targetNode)
{
return ratingService.getRatingsByCurrentUser(targetNode);
}
public RatingScheme getApiRatingScheme(String ratingSchemeName)
{
return nodeRatingSchemeRegistry.getNamedObject(ratingSchemeName);
}
@SuppressWarnings("unchecked")
public Map getActivitySummary(ActivityFeedEntity entity) throws JSONException
{
Map activitySummary = activities.getActivitySummary(entity);
JSONObject json = new JSONObject();
for(String key : activitySummary.keySet())
{
Object value = activitySummary.get(key);
if(value instanceof NodeRef)
{
value = ((NodeRef)value).getId();
}
json.put(key, value);
}
return json;
}
public void checkSiteMember(final TestPerson person, final TestSite site, SiteRole siteRole) throws Exception
{
assertTrue(siteService.isMember(site.getSiteId(), person.getId()));
assertEquals(siteRole.toString(), siteService.getMembersRole(site.getSiteId(), person.getId()));
}
public void addFavouriteSite(final String username, final String siteShortName)
{
SiteInfo siteInfo = siteService.getSite(siteShortName);
if(siteInfo != null)
{
favouritesService.addFavourite(username, siteInfo.getNodeRef());
}
else
{
throw new SiteDoesNotExistException(siteShortName);
}
}
private PagingResults getFavouriteSites(String userName, PagingRequest pagingRequest)
{
final Collator collator = Collator.getInstance();
final Set sortedFavouriteSites = new TreeSet(new Comparator()
{
@Override
public int compare(SiteInfo o1, SiteInfo o2)
{
return collator.compare(o1.getTitle(), o2.getTitle());
}
});
Map prefs = preferenceService.getPreferences(userName, FAVOURITE_SITES_PREFIX);
for(String key : prefs.keySet())
{
boolean isFavourite = false;
Serializable s = prefs.get(key);
if(s instanceof Boolean)
{
isFavourite = (Boolean)s;
}
if(isFavourite)
{
String siteShortName = key.substring(FAVOURITE_SITES_PREFIX_LENGTH);
SiteInfo siteInfo = siteService.getSite(siteShortName);
if(siteInfo != null)
{
sortedFavouriteSites.add(siteInfo);
}
}
}
int totalSize = sortedFavouriteSites.size();
final PageDetails pageDetails = PageDetails.getPageDetails(pagingRequest, totalSize);
final List page = new ArrayList(pageDetails.getPageSize());
Iterator it = sortedFavouriteSites.iterator();
for(int counter = 0; counter < pageDetails.getEnd() && it.hasNext(); counter++)
{
SiteInfo favouriteSite = it.next();
if(counter < pageDetails.getSkipCount())
{
continue;
}
if(counter > pageDetails.getEnd() - 1)
{
break;
}
page.add(favouriteSite);
}
return new PagingResults()
{
@Override
public List getPage()
{
return page;
}
@Override
public boolean hasMoreItems()
{
return pageDetails.hasMoreItems();
}
@Override
public Pair getTotalResultCount()
{
Integer total = Integer.valueOf(sortedFavouriteSites.size());
return new Pair(total, total);
}
@Override
public String getQueryExecutionId()
{
return null;
}
};
}
public List getFavouriteSites(TestPerson user)
{
List favouriteSites = new ArrayList();
PagingResults pagingResults = getFavouriteSites(user.getId(), new PagingRequest(0, Integer.MAX_VALUE));
for(SiteInfo siteInfo : pagingResults.getPage())
{
String siteId = siteInfo.getShortName();
String siteGuid = siteInfo.getNodeRef().getId();
TestSite site = user.getDefaultAccount().getSite(siteId);
FavouriteSite favouriteSite = null;
if(site.isMember(user.getId()))
{
favouriteSite = new FavouriteSite(site);
}
else
{
favouriteSite = new FavouriteSite(null, siteId, siteGuid, null, null, null, null, null);
}
favouriteSites.add(favouriteSite);
}
return favouriteSites;
}
public void addPreference(final String username, final String Key, final Serializable value)
{
Map preferences = new HashMap(1);
preferences.put(Key, value);
preferenceService.setPreferences(username, preferences);
}
public List getSiteMemberships(String personId)
{
List sites = siteService.listSites(personId);
List memberships = new ArrayList();
for(SiteInfo siteInfo : sites)
{
String roleStr = siteService.getMembersRole(siteInfo.getShortName(), personId);
SiteRole role = SiteRole.valueOf(roleStr);
SiteImpl site = new SiteImpl(siteInfo, role, true);
memberships.add(new MemberOfSite(site, role));
}
return memberships;
}
public void generateFeed() throws JobExecutionException, SQLException
{
// process all outstanding activity posts
transactionHelper.doInTransaction(new RetryingTransactionCallback()
{
@Override
public Void execute() throws Throwable
{
postLookup.execute();
return null;
}
}, false, true);
Long maxSequence = getMaxActivitySeq();
while(maxSequence != null)
{
feedGenerator.execute();
maxSequence = getMaxActivitySeq();
}
}
private Long getMaxActivitySeq() throws SQLException
{
Long maxSequence = transactionHelper.doInTransaction(new RetryingTransactionCallback()
{
@Override
public Long execute() throws Throwable
{
return postDAO.getMaxActivitySeq();
}
}, true, true);
return maxSequence;
}
public Tag addTag(NodeRef nodeRef, String tag)
{
NodeRef tagNodeRef = taggingService.addTag(nodeRef, tag);
return new Tag(nodeRef.getId(), tagNodeRef.getId(), tag);
}
public List getTags()
{
Set tags = new TreeSet();
for(String tag : taggingService.getTags(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE))
{
tags.add(new Tag(null, taggingService.getTagNodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, tag).getId(), tag));
}
return new ArrayList(tags);
}
public List getTags(NodeRef nodeRef)
{
Set tags = new TreeSet();
for(String tag : taggingService.getTags(nodeRef))
{
tags.add(new Tag(null, taggingService.getTagNodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, tag).getId(), tag));
}
return new ArrayList(tags);
}
/*
* Get (CMIS) node properties
*/
private Properties getProperties(NodeRef nodeRef)
{
CMISNodeInfoImpl nodeInfo = cmisConnector.createNodeInfo(nodeRef);
final Properties properties = cmisConnector.getNodeProperties(nodeInfo, null);
// fake the title property, which CMIS doesn't give us
String title = (String)nodeService.getProperty(nodeRef, ContentModel.PROP_TITLE);
final PropertyStringImpl titleProp = new PropertyStringImpl(ContentModel.PROP_TITLE.toString(), title);
Properties wrapProperties = new Properties()
{
@Override
public List getExtensions()
{
return properties.getExtensions();
}
@Override
public void setExtensions(List extensions)
{
properties.setExtensions(extensions);
}
@Override
public Map> getProperties()
{
Map> updatedProperties = new HashMap>(properties.getProperties());
updatedProperties.put(titleProp.getId(), titleProp);
return updatedProperties;
}
@Override
public List> getPropertyList()
{
List> propertyList = new ArrayList>(properties.getPropertyList());
propertyList.add(titleProp);
return propertyList;
}
};
return wrapProperties;
}
public FavouriteDocument getDocument(String networkId, final NodeRef nodeRef)
{
return TenantUtil.runAsSystemTenant(new TenantRunAsWork()
{
@Override
public FavouriteDocument doWork() throws Exception
{
FavouriteDocument document = null;
QName type = nodeService.getType(nodeRef);
if(dictionaryService.isSubClass(type, ContentModel.TYPE_CONTENT))
{
Properties properties = getProperties(nodeRef);
document = FavouriteDocument.getDocument(nodeRef.getId(), nodeRef.getId(), properties);
}
else
{
throw new IllegalArgumentException("Not a document node");
}
return document;
}
}, networkId);
}
public FavouriteFolder getFolder(String networkId, final NodeRef nodeRef)
{
return TenantUtil.runAsSystemTenant(new TenantRunAsWork()
{
@Override
public FavouriteFolder doWork() throws Exception
{
FavouriteFolder folder = null;
QName type = nodeService.getType(nodeRef);
if(dictionaryService.isSubClass(type, ContentModel.TYPE_FOLDER))
{
Properties properties = getProperties(nodeRef);
folder = FavouriteFolder.getFolder(nodeRef.getId(), nodeRef.getId(), properties);
}
else
{
throw new IllegalArgumentException("Not a folder node");
}
return folder;
}
}, networkId);
}
public List getNodeRatings(String personId, String networkId, final NodeRef nodeRef)
{
List ratings = TenantUtil.runAsUserTenant(new TenantRunAsWork>()
{
@Override
public List doWork() throws Exception
{
List ratings = new ArrayList();
{
Rating likesRating = ratingService.getRatingByCurrentUser(nodeRef, "likesRatingScheme");
Object myRating = null;
String ratedAt = null;
if(likesRating != null)
{
myRating = likesRating.getScore() == 1.0f ? Boolean.TRUE : Boolean.FALSE;
Date rateTime = likesRating.getAppliedAt();
ratedAt = PublicApiDateFormat.getDateFormat().format(rateTime);
}
int ratingsCount = ratingService.getRatingsCount(nodeRef, "likesRatingScheme");
Aggregate aggregate = new Aggregate(ratingsCount, null);
ratings.add(new NodeRating(nodeRef.getId(), "likes", ratedAt, myRating, aggregate));
}
{
Rating fiveStarRating = ratingService.getRatingByCurrentUser(nodeRef, "fiveStarRatingScheme");
Object myRating = null;
String ratedAt = null;
if(fiveStarRating != null)
{
myRating = fiveStarRating.getScore();
Date rateTime = fiveStarRating.getAppliedAt();
ratedAt = PublicApiDateFormat.getDateFormat().format(rateTime);
}
int ratingsCount = ratingService.getRatingsCount(nodeRef, "fiveStarRatingScheme");
float averageRating = ratingService.getAverageRating(nodeRef, "fiveStarRatingScheme");
Aggregate aggregate = new Aggregate(ratingsCount, averageRating == -1 ? null : averageRating);
ratings.add(new NodeRating(nodeRef.getId(), "fiveStar", ratedAt, myRating, aggregate));
}
return ratings;
}
}, personId, networkId);
Collections.sort(ratings);
return ratings;
}
public int numRatingSchemes()
{
return ratingService.getRatingSchemes().size();
}
public NodeRef addToDocumentLibrary(TestSite site, String name, QName type)
{
NodeRef documentLibraryContainerNodeRef = siteService.getContainer(site.getSiteId(), "documentLibrary");
NodeRef nodeRef = fileFolderService.create(documentLibraryContainerNodeRef, name, type).getNodeRef();
return nodeRef;
}
public String getSiteNetwork(final String siteShortName, String tenantDomain)
{
return TenantUtil.runAsTenant(new TenantRunAsWork()
{
@Override
public String doWork() throws Exception
{
return tenantService.getName(siteShortName);
}
}, tenantDomain);
}
public void postActivity(final String activityType, final String siteId, final JSONObject activityData) throws JobExecutionException
{
activityService.postActivity(activityType, siteId, "documentlibrary", activityData.toString());
}
public NodeRef createDocument(final NodeRef parentNodeRef, final String name, final String content)
{
NodeRef nodeRef = fileFolderService.create(parentNodeRef, name, ContentModel.TYPE_CONTENT).getNodeRef();
ContentWriter writer = contentService.getWriter(nodeRef, ContentModel.PROP_CONTENT, true);
writer.putContent(content);
return nodeRef;
}
public NodeRef createDocument(final NodeRef parentNodeRef, final String name, final String title, final String description, final String content)
{
NodeRef nodeRef = fileFolderService.create(parentNodeRef, name, ContentModel.TYPE_CONTENT).getNodeRef();
ContentWriter writer = contentService.getWriter(nodeRef, ContentModel.PROP_CONTENT, true);
writer.putContent(content);
nodeService.setProperty(nodeRef, ContentModel.PROP_TITLE, title);
nodeService.setProperty(nodeRef, ContentModel.PROP_DESCRIPTION, description);
return nodeRef;
}
public NodeRef createFolder(final NodeRef parentNodeRef, final String name)
{
NodeRef nodeRef = fileFolderService.create(parentNodeRef, name, ContentModel.TYPE_FOLDER).getNodeRef();
return nodeRef;
}
public NodeRef createFolder(final NodeRef parentNodeRef, final String name, final String title, final String description)
{
NodeRef nodeRef = fileFolderService.create(parentNodeRef, name, ContentModel.TYPE_FOLDER).getNodeRef();
nodeService.setProperty(nodeRef, ContentModel.PROP_TITLE, title);
nodeService.setProperty(nodeRef, ContentModel.PROP_DESCRIPTION, description);
return nodeRef;
}
public NodeRef createCmObject(final NodeRef parentNodeRef, final String name)
{
QName assocQName = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, QName.createValidLocalName(name));
NodeRef nodeRef = nodeService.createNode(parentNodeRef, ContentModel.ASSOC_CONTAINS, assocQName, ContentModel.TYPE_CMOBJECT).getChildRef();
return nodeRef;
}
public NodeRef createObjectOfCustomType(final NodeRef parentNodeRef, final String name, final String typeName)
{
QName assocQName = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, QName.createValidLocalName(name));
QName typeQName = QName.createQName(typeName);
NodeRef nodeRef = nodeService.createNode(parentNodeRef, ContentModel.ASSOC_CONTAINS, assocQName, typeQName).getChildRef();
return nodeRef;
}
public Visibility getVisibility(Client client, NodeRef nodeRef)
{
return hiddenAspect.getVisibility(client, nodeRef);
}
public void addAspect(NodeRef nodeRef, QName aspectTypeQName, Map aspectProperties)
{
nodeService.addAspect(nodeRef, aspectTypeQName, aspectProperties);
}
public NodeRef createComment(NodeRef nodeRef, final Comment comment)
{
NodeRef commentNodeRef = commentService.createComment(nodeRef, comment.getTitle(), comment.getContent(), false);
comment.setId(commentNodeRef.getId());
Date created = (Date)nodeService.getProperty(commentNodeRef, ContentModel.PROP_CREATED);
comment.setCreatedAt(PublicApiDateFormat.getDateFormat().format(created));
TestPerson person = getPerson((String)nodeService.getProperty(commentNodeRef, ContentModel.PROP_CREATOR));
comment.setCreatedBy(person);
return commentNodeRef;
}
public TestNetwork createNetworkWithAlias(String alias, boolean enabled)
{
String networkId = alias + "-" + System.currentTimeMillis();
TestNetwork network = new TestNetwork(networkId, enabled);
return network;
}
public TestNetwork createNetwork(String networkId, boolean enabled)
{
TestNetwork network = new TestNetwork(networkId, enabled);
return network;
}
public class TestSite extends SiteImpl
{
private static final long serialVersionUID = 5317623044880374281L;
private TestNetwork account;
private SiteInfo siteInfo;
public TestSite(TestNetwork account, SiteInfo siteInfo)
{
this(account, siteInfo.getShortName(), siteInfo.getNodeRef().getId(), siteInfo.getTitle(), siteInfo.getDescription(), siteInfo.getVisibility());
this.account = account;
this.siteInfo = siteInfo;
}
public TestSite(TestNetwork account, String siteId, String guid, String title, String description, SiteVisibility siteVisibility)
{
super((account == null ? null : account.getId()), siteId, guid);
setTitle(title);
setDescription(description);
setVisibility(siteVisibility.toString());
this.siteInfo = siteService.getSite(siteId);
}
public SiteInfo getSiteInfo()
{
return siteInfo;
}
public NodeRef getContainerNodeRef(String containerId)
{
return siteService.getContainer(siteId, containerId);
}
public NodeRef createContainer(String containerName)
{
return siteService.createContainer(getSiteId(), containerName, ContentModel.TYPE_FOLDER, null);
}
public void inviteToSite(final String toInvite, final SiteRole siteRole)
{
siteService.setMembership(getSiteId(), toInvite, siteRole.toString());
log(toInvite + " invited to site " + getSiteId());
}
public TestNetwork getAccount()
{
return account;
}
public Map getMembers(final String roleFilter)
{
Map members = TenantUtil.runAsSystemTenant(new TenantRunAsWork