mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-07 17:49:17 +00:00
Merged V3.1 to HEAD
13065: SiteService - listSites() "nameFilter" and "sizeFilter" now implemented. Optimization to retrieve the Site Root noderef and cache it within the SiteService. git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@13556 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -64,13 +64,15 @@
|
|||||||
<property name="fileFolderService" ref="FileFolderService"/>
|
<property name="fileFolderService" ref="FileFolderService"/>
|
||||||
<property name="searchService" ref="SearchService"/>
|
<property name="searchService" ref="SearchService"/>
|
||||||
<property name="namespaceService" ref="NamespaceService"/>
|
<property name="namespaceService" ref="NamespaceService"/>
|
||||||
<property name="permissionService" ref="PermissionService" />
|
<property name="permissionService" ref="PermissionService"/>
|
||||||
<property name="authenticationComponent" ref="authenticationComponent"/>
|
<property name="authenticationComponent" ref="authenticationComponent"/>
|
||||||
<property name="personService" ref="PersonService"/>
|
<property name="personService" ref="PersonService"/>
|
||||||
<property name="activityService" ref="activityService"/>
|
<property name="activityService" ref="activityService"/>
|
||||||
<property name="taggingService" ref="TaggingService"/>
|
<property name="taggingService" ref="TaggingService"/>
|
||||||
<property name="authorityService" ref="authorityService"/>
|
<property name="authorityService" ref="authorityService"/>
|
||||||
<property name="dictionaryService" ref="DictionaryService"/>
|
<property name="dictionaryService" ref="DictionaryService"/>
|
||||||
|
<property name="tenantAdminService" ref="tenantAdminService"/>
|
||||||
|
<property name="transactionHelper" ref="retryingTransactionHelper"/>
|
||||||
<property name="sitesXPath">
|
<property name="sitesXPath">
|
||||||
<value>./${spaces.company_home.childname}/st:sites</value>
|
<value>./${spaces.company_home.childname}/st:sites</value>
|
||||||
</property>
|
</property>
|
||||||
|
@@ -27,17 +27,23 @@ package org.alfresco.repo.site;
|
|||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
import org.alfresco.model.ContentModel;
|
import org.alfresco.model.ContentModel;
|
||||||
import org.alfresco.repo.activities.ActivityType;
|
import org.alfresco.repo.activities.ActivityType;
|
||||||
|
import org.alfresco.repo.search.QueryParameterDefImpl;
|
||||||
import org.alfresco.repo.security.authentication.AuthenticationComponent;
|
import org.alfresco.repo.security.authentication.AuthenticationComponent;
|
||||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||||
|
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
|
||||||
|
import org.alfresco.repo.tenant.TenantAdminService;
|
||||||
import org.alfresco.repo.tenant.TenantService;
|
import org.alfresco.repo.tenant.TenantService;
|
||||||
|
import org.alfresco.repo.transaction.RetryingTransactionHelper;
|
||||||
|
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
|
||||||
import org.alfresco.service.cmr.activities.ActivityService;
|
import org.alfresco.service.cmr.activities.ActivityService;
|
||||||
|
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
|
||||||
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
||||||
import org.alfresco.service.cmr.model.FileFolderService;
|
import org.alfresco.service.cmr.model.FileFolderService;
|
||||||
import org.alfresco.service.cmr.model.FileInfo;
|
import org.alfresco.service.cmr.model.FileInfo;
|
||||||
@@ -46,6 +52,8 @@ import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
|||||||
import org.alfresco.service.cmr.repository.NodeRef;
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
import org.alfresco.service.cmr.repository.NodeService;
|
import org.alfresco.service.cmr.repository.NodeService;
|
||||||
import org.alfresco.service.cmr.repository.StoreRef;
|
import org.alfresco.service.cmr.repository.StoreRef;
|
||||||
|
import org.alfresco.service.cmr.search.QueryParameterDefinition;
|
||||||
|
import org.alfresco.service.cmr.search.ResultSet;
|
||||||
import org.alfresco.service.cmr.search.SearchService;
|
import org.alfresco.service.cmr.search.SearchService;
|
||||||
import org.alfresco.service.cmr.security.AccessPermission;
|
import org.alfresco.service.cmr.security.AccessPermission;
|
||||||
import org.alfresco.service.cmr.security.AccessStatus;
|
import org.alfresco.service.cmr.security.AccessStatus;
|
||||||
@@ -75,11 +83,11 @@ import org.json.JSONObject;
|
|||||||
*/
|
*/
|
||||||
public class SiteServiceImpl implements SiteService, SiteModel
|
public class SiteServiceImpl implements SiteService, SiteModel
|
||||||
{
|
{
|
||||||
private static final String GROUP_SITE_PREFIX = PermissionService.GROUP_PREFIX + "site_";
|
|
||||||
|
|
||||||
/** Logger */
|
/** Logger */
|
||||||
private static Log logger = LogFactory.getLog(SiteServiceImpl.class);
|
private static Log logger = LogFactory.getLog(SiteServiceImpl.class);
|
||||||
|
|
||||||
|
private static final String GROUP_SITE_PREFIX = PermissionService.GROUP_PREFIX + "site_";
|
||||||
|
|
||||||
/** The DM store where site's are kept */
|
/** The DM store where site's are kept */
|
||||||
public static final StoreRef SITE_STORE = new StoreRef("workspace://SpacesStore");
|
public static final StoreRef SITE_STORE = new StoreRef("workspace://SpacesStore");
|
||||||
|
|
||||||
@@ -88,6 +96,9 @@ public class SiteServiceImpl implements SiteService, SiteModel
|
|||||||
|
|
||||||
private static final String SITE_PREFIX = "site_";
|
private static final String SITE_PREFIX = "site_";
|
||||||
private static final int GROUP_PREFIX_LENGTH = SITE_PREFIX.length() + PermissionService.GROUP_PREFIX.length();
|
private static final int GROUP_PREFIX_LENGTH = SITE_PREFIX.length() + PermissionService.GROUP_PREFIX.length();
|
||||||
|
|
||||||
|
/** Site home ref cache (Tennant aware) */
|
||||||
|
private Map<String, NodeRef> siteHomeRefs = new ConcurrentHashMap<String, NodeRef>(4);
|
||||||
|
|
||||||
private String sitesXPath;
|
private String sitesXPath;
|
||||||
|
|
||||||
@@ -115,6 +126,9 @@ public class SiteServiceImpl implements SiteService, SiteModel
|
|||||||
private AuthorityService authorityService;
|
private AuthorityService authorityService;
|
||||||
private DictionaryService dictionaryService;
|
private DictionaryService dictionaryService;
|
||||||
private TenantService tenantService;
|
private TenantService tenantService;
|
||||||
|
private TenantAdminService tenantAdminService;
|
||||||
|
private RetryingTransactionHelper retryingTransactionHelper;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the path to the location of the sites root folder. For example:
|
* Set the path to the location of the sites root folder. For example:
|
||||||
@@ -229,6 +243,22 @@ public class SiteServiceImpl implements SiteService, SiteModel
|
|||||||
this.tenantService = tenantService;
|
this.tenantService = tenantService;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the tenant admin service
|
||||||
|
*/
|
||||||
|
public void setTenantAdminService(TenantAdminService tenantAdminService)
|
||||||
|
{
|
||||||
|
this.tenantAdminService = tenantAdminService;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets helper that provides transaction callbacks
|
||||||
|
*/
|
||||||
|
public void setTransactionHelper(RetryingTransactionHelper retryingTransactionHelper)
|
||||||
|
{
|
||||||
|
this.retryingTransactionHelper = retryingTransactionHelper;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks that all necessary properties and services have been provided.
|
* Checks that all necessary properties and services have been provided.
|
||||||
*/
|
*/
|
||||||
@@ -465,8 +495,7 @@ public class SiteServiceImpl implements SiteService, SiteModel
|
|||||||
{
|
{
|
||||||
// TODO
|
// TODO
|
||||||
// For now just return the site root, later we may build folder
|
// For now just return the site root, later we may build folder
|
||||||
// structure based on the shortname to
|
// structure based on the shortname to spread the sites about
|
||||||
// spread the sites about
|
|
||||||
return getSiteRoot();
|
return getSiteRoot();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -477,57 +506,128 @@ public class SiteServiceImpl implements SiteService, SiteModel
|
|||||||
*/
|
*/
|
||||||
private NodeRef getSiteRoot()
|
private NodeRef getSiteRoot()
|
||||||
{
|
{
|
||||||
// Get the root 'sites' folder
|
String tenantDomain = tenantAdminService.getCurrentUserDomain();
|
||||||
NodeRef rootNodeRef = this.nodeService.getRootNode(SITE_STORE);
|
NodeRef siteHomeRef = siteHomeRefs.get(tenantDomain);
|
||||||
List<NodeRef> results = this.searchService.selectNodes(
|
if (siteHomeRef == null)
|
||||||
rootNodeRef,
|
{
|
||||||
sitesXPath,
|
siteHomeRef = AuthenticationUtil.runAs(new RunAsWork<NodeRef>()
|
||||||
null,
|
{
|
||||||
namespaceService,
|
public NodeRef doWork() throws Exception
|
||||||
false,
|
{
|
||||||
SearchService.LANGUAGE_XPATH);
|
return retryingTransactionHelper.doInTransaction(new RetryingTransactionCallback<NodeRef>()
|
||||||
if (results.size() == 0)
|
{
|
||||||
{
|
public NodeRef execute() throws Exception
|
||||||
// No root site folder exists
|
{
|
||||||
throw new SiteServiceException("No root sites folder exists");
|
// Get the root 'sites' folder
|
||||||
|
NodeRef rootNodeRef = nodeService.getRootNode(SITE_STORE);
|
||||||
|
List<NodeRef> results = searchService.selectNodes(
|
||||||
|
rootNodeRef,
|
||||||
|
sitesXPath,
|
||||||
|
null,
|
||||||
|
namespaceService,
|
||||||
|
false,
|
||||||
|
SearchService.LANGUAGE_XPATH);
|
||||||
|
if (results.size() == 0)
|
||||||
|
{
|
||||||
|
// No root site folder exists
|
||||||
|
throw new SiteServiceException("No root sites folder exists");
|
||||||
|
}
|
||||||
|
else if (results.size() != 1)
|
||||||
|
{
|
||||||
|
// More than one root site folder exits
|
||||||
|
logger.warn("More than one root sites folder exists: \n" + results);
|
||||||
|
}
|
||||||
|
|
||||||
|
return results.get(0);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, AuthenticationUtil.getSystemUserName());
|
||||||
|
|
||||||
|
siteHomeRefs.put(tenantDomain, siteHomeRef);
|
||||||
}
|
}
|
||||||
else if (results.size() != 1)
|
return siteHomeRef;
|
||||||
{
|
|
||||||
// More than one root site folder exits
|
|
||||||
logger.warn("More than one root sites folder exists: \n" + results);
|
|
||||||
}
|
|
||||||
|
|
||||||
return results.get(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see org.alfresco.service.cmr.site.SiteService#listSites(java.lang.String,
|
* @see org.alfresco.service.cmr.site.SiteService#listSites(java.lang.String, java.lang.String)
|
||||||
* java.lang.String)
|
|
||||||
*/
|
*/
|
||||||
public List<SiteInfo> listSites(String nameFilter, String sitePresetFilter)
|
public List<SiteInfo> listSites(String nameFilter, String sitePresetFilter)
|
||||||
{
|
{
|
||||||
// TODO
|
return listSites(nameFilter, sitePresetFilter, 0);
|
||||||
// - take into consideration the filters set
|
}
|
||||||
// - take into consideration that the sites may not just be in a flat
|
|
||||||
// list under the site root
|
|
||||||
|
|
||||||
// For now just return the list of sites present under the site root
|
/**
|
||||||
|
* @see org.alfresco.service.cmr.site.SiteService#listSites(java.lang.String, java.lang.String, int)
|
||||||
|
*/
|
||||||
|
public List<SiteInfo> listSites(String nameFilter, String sitePresetFilter, int size)
|
||||||
|
{
|
||||||
|
List<SiteInfo> result;
|
||||||
|
|
||||||
|
// TODO: take into consideration the sitePresetFilter
|
||||||
|
|
||||||
NodeRef siteRoot = getSiteRoot();
|
NodeRef siteRoot = getSiteRoot();
|
||||||
List<ChildAssociationRef> assocs = this.nodeService.getChildAssocs(
|
if (nameFilter != null && nameFilter.length() != 0)
|
||||||
siteRoot, ContentModel.ASSOC_CONTAINS,
|
|
||||||
RegexQNamePattern.MATCH_ALL);
|
|
||||||
List<SiteInfo> result = new ArrayList<SiteInfo>(assocs.size());
|
|
||||||
for (ChildAssociationRef assoc : assocs)
|
|
||||||
{
|
{
|
||||||
// Ignore any node that is not a "site"
|
// Perform a Lucene search under the Site parent node using *name* search query
|
||||||
NodeRef site = assoc.getChildRef();
|
QueryParameterDefinition[] params = new QueryParameterDefinition[1];
|
||||||
QName siteClassName = this.nodeService.getType(site);
|
params[0] = new QueryParameterDefImpl(
|
||||||
if (this.dictionaryService.isSubClass(siteClassName, SiteModel.TYPE_SITE) == true)
|
ContentModel.PROP_NAME,
|
||||||
{
|
dictionaryService.getDataType(
|
||||||
result.add(createSiteInfo(site));
|
DataTypeDefinition.TEXT),
|
||||||
|
true,
|
||||||
|
nameFilter);
|
||||||
|
|
||||||
|
// get the sites that match the specified names
|
||||||
|
StringBuilder query = new StringBuilder(128);
|
||||||
|
query.append("+PARENT:\"").append(siteRoot.toString())
|
||||||
|
.append("\" +@cm\\:name:\"*").append(nameFilter).append("*\"");
|
||||||
|
ResultSet results = this.searchService.query(
|
||||||
|
siteRoot.getStoreRef(),
|
||||||
|
SearchService.LANGUAGE_LUCENE,
|
||||||
|
query.toString(),
|
||||||
|
params);
|
||||||
|
result = new ArrayList<SiteInfo>(results.length());
|
||||||
|
try
|
||||||
|
{
|
||||||
|
for (NodeRef site : results.getNodeRefs())
|
||||||
|
{
|
||||||
|
// Ignore any node type that is not a "site"
|
||||||
|
QName siteClassName = this.nodeService.getType(site);
|
||||||
|
if (this.dictionaryService.isSubClass(siteClassName, SiteModel.TYPE_SITE) == true)
|
||||||
|
{
|
||||||
|
result.add(createSiteInfo(site));
|
||||||
|
// break on max size limit reached
|
||||||
|
if (result.size() == size) break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
results.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Get ALL sites - this may be a very slow operation if there are many sites...
|
||||||
|
List<ChildAssociationRef> assocs = this.nodeService.getChildAssocs(
|
||||||
|
siteRoot, ContentModel.ASSOC_CONTAINS,
|
||||||
|
RegexQNamePattern.MATCH_ALL);
|
||||||
|
result = new ArrayList<SiteInfo>(assocs.size());
|
||||||
|
for (ChildAssociationRef assoc : assocs)
|
||||||
|
{
|
||||||
|
// Ignore any node type that is not a "site"
|
||||||
|
NodeRef site = assoc.getChildRef();
|
||||||
|
QName siteClassName = this.nodeService.getType(site);
|
||||||
|
if (this.dictionaryService.isSubClass(siteClassName, SiteModel.TYPE_SITE) == true)
|
||||||
|
{
|
||||||
|
result.add(createSiteInfo(site));
|
||||||
|
// break on max size limit reached
|
||||||
|
if (result.size() == size) break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -122,14 +122,31 @@ public class ScriptSiteService extends BaseScopableProcessorExtension
|
|||||||
*/
|
*/
|
||||||
public Site[] listSites(String nameFilter, String sitePresetFilter)
|
public Site[] listSites(String nameFilter, String sitePresetFilter)
|
||||||
{
|
{
|
||||||
List<SiteInfo> siteInfos = this.siteService.listSites(nameFilter, sitePresetFilter);
|
return listSites(nameFilter, sitePresetFilter, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List the sites available in the repository. The returned list can optionally be filtered by name and site
|
||||||
|
* preset.
|
||||||
|
* <p>
|
||||||
|
* If no filters are specified then all the available sites are returned.
|
||||||
|
*
|
||||||
|
* @param nameFilter name filter
|
||||||
|
* @param sitePresetFilter site preset filter
|
||||||
|
* @param size max results size crop if >0
|
||||||
|
*
|
||||||
|
* @return Site[] a list of the site filtered as appropriate
|
||||||
|
*/
|
||||||
|
public Site[] listSites(String nameFilter, String sitePresetFilter, int size)
|
||||||
|
{
|
||||||
|
List<SiteInfo> siteInfos = this.siteService.listSites(nameFilter, sitePresetFilter, size);
|
||||||
List<Site> sites = new ArrayList<Site>(siteInfos.size());
|
List<Site> sites = new ArrayList<Site>(siteInfos.size());
|
||||||
for (SiteInfo siteInfo : siteInfos)
|
for (SiteInfo siteInfo : siteInfos)
|
||||||
{
|
{
|
||||||
sites.add(new Site(siteInfo, this.serviceRegistry, this.siteService, getScope()));
|
sites.add(new Site(siteInfo, this.serviceRegistry, this.siteService, getScope()));
|
||||||
}
|
}
|
||||||
return (Site[])sites.toArray(new Site[sites.size()]);
|
return (Site[])sites.toArray(new Site[sites.size()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* List all the sites that the specified user has an explicit membership to.
|
* List all the sites that the specified user has an explicit membership to.
|
||||||
|
@@ -41,6 +41,16 @@ public interface SiteService
|
|||||||
*/
|
*/
|
||||||
SiteInfo createSite(String sitePreset, String shortName, String title, String description, SiteVisibility visibility);
|
SiteInfo createSite(String sitePreset, String shortName, String title, String description, SiteVisibility visibility);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List the available sites. This list can optionally be filtered by site name and/or site preset.
|
||||||
|
*
|
||||||
|
* @param nameFilter name filter
|
||||||
|
* @param sitePresetFilter site preset filter
|
||||||
|
* @param size list maximum size or zero for all
|
||||||
|
* @return List<SiteInfo> list of site information
|
||||||
|
*/
|
||||||
|
List<SiteInfo> listSites(String nameFilter, String sitePresetFilter, int size);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* List the available sites. This list can optionally be filtered by site name and/or site preset.
|
* List the available sites. This list can optionally be filtered by site name and/or site preset.
|
||||||
*
|
*
|
||||||
|
Reference in New Issue
Block a user