Derek Hulley cf86bf466c Merged V3.1 to HEAD
13077: Abstracted ContentStore MBean operations
   13099: Merge V3.0 to V3.1
      13096  Merged V2.2 to V3.0
         13071: Fix ETWOTWO-1058: Hibernate exception while concurrently submitting from and updating same user sandbox.
         13079: Fix ETWOTWO-1117: Misleading exceptions reported during AVM flatten and update
   13102: [no comment]
   13112: Merged V3.0 to V3.1
      13111: Merged V2.2 to V3.0
         13110: Fix 2.1 -> 2.2 upgrade on Postgres
   13114: Build/test fix (Enterprise Remote API project does not yet have any Java files to generate Javadoc)
   13117: DM Index Check - unit test improvements
   13123: *RECORD ONLY* Removed svn:mergeinfo fluff
   13124: Used newer, more efficient NodeService.addProperties method instead of many NodeService.setProperty calls
   13125: Added M2Binding for 'child-association': propagateTimestamps'
   13126: WCM unit tests - reduce build/test time to check (async) submits
   13127: Minor test fix - to allow it to run locally (on Mac OS X)
   13130: Support for 'maxRetries' of zero or less
   13131: Merged V3.0 to V3.1
      13025 *RECORD-ONLY*: Removed unnecessary svn:mergeinfo
      13026: Merged V2.2 to V3.0
         12964: Fixed ETWOTWO-968: Space rules are not run when saving from MS Word
         12993 *RECORD-ONLY*: added openoffice bootstrap context to sample-extensions
         13009 *RECORD-ONLY*: Avoid default OOo config from causing problems on zip/gz installs
   13132: Updated svn:mergeinfo
   13134: ETHREEOH-1202 - initial fix and unit tests
   ___________________________________________________________________
   Modified: svn:mergeinfo
      Merged /alfresco/BRANCHES/V3.0:r13005,13025-13026,13030,13039,13042,13050,13053,13096,13098,13111
      Merged /alfresco/BRANCHES/V2.2:r12964,12993,13009,13071,13079,13110
      Merged /alfresco/BRANCHES/V3.1:r13077,13099,13102,13112,13114,13117,13123-13127,13130-13132,13134


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@13564 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
2009-03-11 13:19:59 +00:00

1418 lines
57 KiB
Java

/*
* Copyright (C) 2005-2008 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program 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 General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing"
*/
package org.alfresco.wcm.webproject;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.mbeans.VirtServerRegistry;
import org.alfresco.model.ApplicationModel;
import org.alfresco.model.ContentModel;
import org.alfresco.model.WCMAppModel;
import org.alfresco.repo.avm.AVMNodeConverter;
import org.alfresco.repo.domain.PropertyValue;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
import org.alfresco.repo.security.permissions.AccessDeniedException;
import org.alfresco.repo.transaction.AlfrescoTransactionSupport;
import org.alfresco.repo.transaction.TransactionListenerAdapter;
import org.alfresco.service.cmr.avm.AVMNodeDescriptor;
import org.alfresco.service.cmr.avm.AVMService;
import org.alfresco.service.cmr.avm.locking.AVMLockingService;
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.InvalidNodeRefException;
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.search.ResultSet;
import org.alfresco.service.cmr.search.SearchService;
import org.alfresco.service.cmr.security.AccessStatus;
import org.alfresco.service.cmr.security.AuthorityService;
import org.alfresco.service.cmr.security.AuthorityType;
import org.alfresco.service.cmr.security.PermissionService;
import org.alfresco.service.cmr.security.PersonService;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName;
import org.alfresco.service.namespace.RegexQNamePattern;
import org.alfresco.util.DNSNameMangler;
import org.alfresco.util.ParameterCheck;
import org.alfresco.wcm.sandbox.SandboxFactory;
import org.alfresco.wcm.sandbox.SandboxInfo;
import org.alfresco.wcm.sandbox.SandboxFactory.UserRoleWrapper;
import org.alfresco.wcm.util.WCMUtil;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* Web Project Service Implementation
*
* @author janv
*/
public class WebProjectServiceImpl extends WCMUtil implements WebProjectService
{
/** Logger */
private static Log logger = LogFactory.getLog(WebProjectServiceImpl.class);
/** The DM store where web projects are kept */
public static final StoreRef WEBPROJECT_STORE = new StoreRef("workspace://SpacesStore");
/** The web projects root node reference */
private NodeRef webProjectsRootNodeRef; // note: WCM is not currently MT-enabled (so this is OK)
/** Services */
private NodeService nodeService;
private SearchService searchService;
private AVMService avmService;
private AVMLockingService avmLockingService;
private AuthorityService authorityService;
private PermissionService permissionService;
private PersonService personService;
private SandboxFactory sandboxFactory;
private VirtServerRegistry virtServerRegistry;
public void setNodeService(NodeService nodeService)
{
this.nodeService = nodeService;
}
public void setSearchService(SearchService searchService)
{
this.searchService = searchService;
}
public void setAvmService(AVMService avmService)
{
this.avmService = avmService;
}
public void setAvmLockingService(AVMLockingService avmLockingService)
{
this.avmLockingService = avmLockingService;
}
public void setAuthorityService(AuthorityService authorityService)
{
this.authorityService = authorityService;
}
public void setPermissionService(PermissionService permissionService)
{
this.permissionService = permissionService;
}
public void setPersonService(PersonService personService)
{
this.personService = personService;
}
public void setSandboxFactory(SandboxFactory sandboxFactory)
{
this.sandboxFactory = sandboxFactory;
}
public void setVirtServerRegistry(VirtServerRegistry virtServerRegistry)
{
this.virtServerRegistry = virtServerRegistry;
}
/* (non-Javadoc)
* @see org.alfresco.wcm.WebProjectService#createWebProject(java.lang.String, java.lang.String, java.lang.String, java.lang.String)
*/
public WebProjectInfo createWebProject(String dnsName, String name, String title, String description)
{
return createWebProject(dnsName, name, title, description, null, false, null);
}
/* (non-Javadoc)
* @see org.alfresco.wcm.WebProjectService#createWebProject(java.lang.String, java.lang.String, java.lang.String, java.lang.String, org.alfresco.service.cmr.repository.NodeRef)
*/
public WebProjectInfo createWebProject(String dnsName, String name, String title, String description, NodeRef sourceNodeRef)
{
return createWebProject(dnsName, name, title, description, null, false, sourceNodeRef);
}
/* (non-Javadoc)
* @see org.alfresco.wcm.WebProjectService#createWebProject(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, boolean, org.alfresco.service.cmr.repository.NodeRef)
*/
public WebProjectInfo createWebProject(String dnsName, String name, String title, String description, String defaultWebApp, boolean useAsTemplate, NodeRef sourceNodeRef)
{
// Generate web project store id (an AVM store name)
String wpStoreId = DNSNameMangler.MakeDNSName(dnsName);
if (wpStoreId.indexOf(WCMUtil.STORE_SEPARATOR) != -1)
{
throw new IllegalArgumentException("Unexpected store id '"+wpStoreId+"' - should not contain '"+WCMUtil.STORE_SEPARATOR+"'");
}
if (wpStoreId.indexOf(WCMUtil.AVM_STORE_SEPARATOR) != -1)
{
throw new IllegalArgumentException("Unexpected store id '"+wpStoreId+"' - should not contain '"+WCMUtil.AVM_STORE_SEPARATOR+"'");
}
// create the website space in the correct parent folder
Map<QName, Serializable> props = new HashMap<QName, Serializable>(1);
props.put(ContentModel.PROP_NAME, name);
ChildAssociationRef childAssocRef = nodeService.createNode(
getWebProjectsRoot(),
ContentModel.ASSOC_CONTAINS,
QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, QName.createValidLocalName(name)),
WCMAppModel.TYPE_AVMWEBFOLDER,
props);
NodeRef wpNodeRef = childAssocRef.getChildRef();
// apply the uifacets aspect - icon, title and description props
Map<QName, Serializable> uiFacetsProps = new HashMap<QName, Serializable>(4);
uiFacetsProps.put(ApplicationModel.PROP_ICON, WCMUtil.SPACE_ICON_WEBSITE);
uiFacetsProps.put(ContentModel.PROP_TITLE, title);
uiFacetsProps.put(ContentModel.PROP_DESCRIPTION, description);
nodeService.addAspect(wpNodeRef, ApplicationModel.ASPECT_UIFACETS, uiFacetsProps);
// use as template source flag
nodeService.setProperty(wpNodeRef, WCMAppModel.PROP_ISSOURCE, useAsTemplate);
// set the default webapp name for the project
defaultWebApp = (defaultWebApp != null && defaultWebApp.length() != 0) ? defaultWebApp : WCMUtil.DIR_ROOT;
nodeService.setProperty(wpNodeRef, WCMAppModel.PROP_DEFAULTWEBAPP, defaultWebApp);
// set the property on the node to reference the root AVM store
nodeService.setProperty(wpNodeRef, WCMAppModel.PROP_AVMSTORE, wpStoreId);
// branch from source web project, if supplied
String branchStoreId = null;
if (sourceNodeRef != null)
{
branchStoreId = (String)nodeService.getProperty(sourceNodeRef, WCMAppModel.PROP_AVMSTORE);
}
// create the AVM staging store to represent the newly created location website
sandboxFactory.createStagingSandbox(wpStoreId, wpNodeRef, branchStoreId); // ignore return, fails if web project already exists
// create the default webapp folder under the hidden system folders
if (branchStoreId == null)
{
String stagingStore = WCMUtil.buildStagingStoreName(wpStoreId);
String stagingStoreRoot = WCMUtil.buildSandboxRootPath(stagingStore);
avmService.createDirectory(stagingStoreRoot, defaultWebApp);
avmService.addAspect(AVMNodeConverter.ExtendAVMPath(stagingStoreRoot, defaultWebApp), WCMAppModel.ASPECT_WEBAPP);
}
// now the sandbox is created set the permissions masks for the store
sandboxFactory.setStagingPermissionMasks(wpStoreId);
// set the property on the node to reference the root AVM store
nodeService.setProperty(wpNodeRef, WCMAppModel.PROP_AVMSTORE, wpStoreId);
// inform the locking service about this new instance
avmLockingService.addWebProject(wpStoreId);
// Snapshot the store with the empty webapp
avmService.createSnapshot(wpStoreId, null, null);
// break the permissions inheritance on the web project node so that only assigned users can access it
permissionService.setInheritParentPermissions(wpNodeRef, false);
// TODO: Currently auto-creates author sandbox for creator of web project (eg. an admin or a DM contributor to web projects root space)
// NOTE: JSF client does not yet allow explicit creation of author sandboxes
inviteWebUser(wpNodeRef, AuthenticationUtil.getRunAsUser(), WCMUtil.ROLE_CONTENT_MANAGER, true);
// Bind the post-commit transaction listener with data required for virtualization server notification
CreateWebProjectTransactionListener tl = new CreateWebProjectTransactionListener(wpStoreId);
AlfrescoTransactionSupport.bindListener(tl);
if (logger.isInfoEnabled())
{
logger.info("Created web project: " + wpNodeRef + " (store id: " + wpStoreId + ")");
}
// Return created web project info
WebProjectInfo wpInfo = new WebProjectInfoImpl(name, title, description, wpStoreId, defaultWebApp, useAsTemplate, wpNodeRef);
return wpInfo;
}
/* (non-Javadoc)
* @see org.alfresco.wcm.webproject.WebProjectService#createWebApp(java.lang.String, java.lang.String, java.lang.String)
*/
public void createWebApp(String wpStoreId, String webAppName, String webAppDescription)
{
createWebApp(getWebProjectNodeFromStore(wpStoreId), webAppName, webAppDescription);
}
/* (non-Javadoc)
* @see org.alfresco.wcm.webproject.WebProjectService#createWebApp(org.alfresco.service.cmr.repository.NodeRef, java.lang.String, java.lang.String)
*/
public void createWebApp(NodeRef wpNodeRef, final String webAppName, final String webAppDescription)
{
WebProjectInfo wpInfo = getWebProject(wpNodeRef);
if (isContentManager(wpNodeRef))
{
// get AVM store name of the staging sandbox
final String stagingStoreId = wpInfo.getStagingStoreName();
AuthenticationUtil.runAs(new RunAsWork<Object>()
{
public Object doWork() throws Exception
{
final String parent = WCMUtil.buildSandboxRootPath(stagingStoreId);
avmService.createDirectory(parent, webAppName);
String path = AVMNodeConverter.ExtendAVMPath(parent, webAppName);
avmService.addAspect(path, ApplicationModel.ASPECT_UIFACETS);
avmService.addAspect(path, WCMAppModel.ASPECT_WEBAPP);
if (webAppDescription != null && webAppDescription.length() != 0)
{
avmService.setNodeProperty(path,
ContentModel.PROP_DESCRIPTION,
new PropertyValue(DataTypeDefinition.TEXT,
webAppDescription));
}
// Snapshot the store with the empty webapp
avmService.createSnapshot(stagingStoreId, null, null);
return null;
}
}, AuthenticationUtil.getSystemUserName());
if (logger.isInfoEnabled())
{
logger.info("Created web app: "+webAppName+" (store id: "+wpInfo.getStoreId()+")");
}
}
else
{
throw new AccessDeniedException("Only content managers may create new webapp '"+webAppName+"' (store id: "+wpInfo.getStoreId()+")");
}
}
/* (non-Javadoc)
* @see org.alfresco.wcm.webproject.WebProjectService#listWebApps(java.lang.String)
*/
public List<String> listWebApps(String wpStoreId)
{
return listWebApps(getWebProjectNodeFromStore(wpStoreId));
}
/* (non-Javadoc)
* @see org.alfresco.wcm.webproject.WebProjectService#listWebApps(org.alfresco.service.cmr.repository.NodeRef)
*/
public List<String> listWebApps(NodeRef wpNodeRef)
{
WebProjectInfo wpInfo = getWebProject(wpNodeRef);
String path = WCMUtil.buildSandboxRootPath(wpInfo.getStagingStoreName());
Map<String, AVMNodeDescriptor> folders = avmService.getDirectoryListing(-1, path);
List<String> webAppNames = new ArrayList<String>(folders.size());
webAppNames.addAll(folders.keySet());
return webAppNames;
}
/* (non-Javadoc)
* @see org.alfresco.wcm.webproject.WebProjectService#deleteWebApp(java.lang.String, java.lang.String)
*/
public void deleteWebApp(String wpStoreId, String webAppName)
{
deleteWebApp(getWebProjectNodeFromStore(wpStoreId), webAppName);
}
/* (non-Javadoc)
* @see org.alfresco.wcm.webproject.WebProjectService#deleteWebApp(org.alfresco.service.cmr.repository.NodeRef, java.lang.String)
*/
public void deleteWebApp(NodeRef wpNodeRef, final String webAppName)
{
ParameterCheck.mandatoryString("webAppName", webAppName);
WebProjectInfo wpInfo = getWebProject(wpNodeRef);
if (webAppName.equals(wpInfo.getDefaultWebApp()))
{
throw new AlfrescoRuntimeException("Cannot delete default webapp '"+webAppName+"' (store id: "+wpInfo.getStoreId()+")");
}
else if (isContentManager(wpInfo.getNodeRef()))
{
// get AVM store name of the staging sandbox
final String wpStoreId = wpInfo.getStoreId();
AuthenticationUtil.runAs(new RunAsWork<Object>()
{
public Object doWork() throws Exception
{
final String parent = WCMUtil.buildSandboxRootPath(wpStoreId);
avmService.removeNode(parent, webAppName);
// Snapshot the store with the webapp removed
avmService.createSnapshot(wpStoreId, null, null);
return null;
}
}, AuthenticationUtil.getSystemUserName());
if (logger.isInfoEnabled())
{
logger.info("Deleted web app: "+webAppName+" (store id: "+wpStoreId+")");
}
}
else
{
throw new AccessDeniedException("Only content managers may delete webapp '"+webAppName+"' (web project: "+wpNodeRef+")");
}
}
/**
* Get the node reference that is the web projects root
*
* @return NodeRef node reference
*/
public NodeRef getWebProjectsRoot()
{
if (this.webProjectsRootNodeRef == null)
{
// Get the root 'web projects' folder
ResultSet resultSet = null;
try
{
resultSet = this.searchService.query(WEBPROJECT_STORE, SearchService.LANGUAGE_LUCENE, "PATH:\""+getWebProjectsPath()+"\"");
if (resultSet.length() == 0)
{
// No root web projects folder exists
throw new AlfrescoRuntimeException("No root 'Web Projects' folder exists (is WCM enabled ?)");
}
else if (resultSet.length() != 1)
{
// More than one root web projects folder exits
throw new AlfrescoRuntimeException("More than one root 'Web Projects' folder exists");
}
}
finally
{
if (resultSet != null)
{
resultSet.close();
}
}
this.webProjectsRootNodeRef = resultSet.getNodeRef(0);
}
return this.webProjectsRootNodeRef;
}
/* (non-Javadoc)
* @see org.alfresco.wcm.webproject.WebProjectService#listWebProjects()
*/
public List<WebProjectInfo> listWebProjects()
{
NodeRef wpRoot = getWebProjectsRoot();
Set<QName> nodeTypeQNames = new HashSet<QName>(1);
nodeTypeQNames.add(WCMAppModel.TYPE_AVMWEBFOLDER);
List<ChildAssociationRef> webProjects = nodeService.getChildAssocs(wpRoot, nodeTypeQNames);
List<WebProjectInfo> result = new ArrayList<WebProjectInfo>(webProjects.size());
for (ChildAssociationRef childAssocRefs : webProjects)
{
result.add(getWebProject(childAssocRefs.getChildRef()));
}
return result;
}
/* (non-Javadoc)
* @see org.alfresco.wcm.webproject.WebProjectService#listWebProjects(java.lang.String)
*/
public List<WebProjectInfo> listWebProjects(String userName)
{
List<WebProjectInfo> webProjects = listWebProjects();
List<WebProjectInfo> result = new ArrayList<WebProjectInfo>(webProjects.size());
for (WebProjectInfo webProject : webProjects)
{
if (isWebUser(webProject.getNodeRef(), userName) == true)
{
result.add(webProject);
}
}
return result;
}
/* (non-Javadoc)
* @see org.alfresco.wcm.webproject.WebProjectService#isWebProject(java.lang.String)
*/
public boolean isWebProject(String wpStoreId)
{
NodeRef wpNodeRef = getWebProjectNodeFromStore(wpStoreId);
if (wpNodeRef == null)
{
return false;
}
return isWebProject(wpNodeRef);
}
/* (non-Javadoc)
* @see org.alfresco.wcm.webproject.WebProjectService#isWebProject(org.alfresco.service.cmr.repository.NodeRef)
*/
public boolean isWebProject(NodeRef wpNodeRef)
{
if (wpNodeRef == null)
{
return false;
}
try
{
return (WCMAppModel.TYPE_AVMWEBFOLDER.equals(nodeService.getType(wpNodeRef)));
}
catch (InvalidNodeRefException e)
{
return false;
}
}
/* (non-Javadoc)
* @see org.alfresco.wcm.webproject.WebProjectService#getWebProject(java.lang.String)
*/
public WebProjectInfo getWebProject(String wpStoreId)
{
WebProjectInfo result = null;
// Get the web project node
NodeRef wpNodeRef = getWebProjectNodeFromStore(wpStoreId);
if (wpNodeRef != null)
{
// Create the web project info
result = getWebProject(wpNodeRef);
}
// Return the web project info
return result;
}
/* (non-Javadoc)
* @see org.alfresco.wcm.webproject.WebProjectService#getWebProject(org.alfresco.service.cmr.repository.NodeRef)
*/
public WebProjectInfo getWebProject(NodeRef wpNodeRef)
{
if (! isWebProject(wpNodeRef))
{
throw new IllegalArgumentException(wpNodeRef + " is not a web project");
}
// Get the properties
Map<QName, Serializable> properties = this.nodeService.getProperties(wpNodeRef);
String name = (String)properties.get(ContentModel.PROP_NAME);
String title = (String)properties.get(ContentModel.PROP_TITLE);
String description = (String)properties.get(ContentModel.PROP_DESCRIPTION);
String wpStoreId = (String)properties.get(WCMAppModel.PROP_AVMSTORE);
String defaultWebApp = (String)properties.get(WCMAppModel.PROP_DEFAULTWEBAPP);
Boolean useAsTemplate = (Boolean)properties.get(WCMAppModel.PROP_ISSOURCE);
// Create and return the web project info
WebProjectInfo wpInfo = new WebProjectInfoImpl(name, title, description, wpStoreId, defaultWebApp, useAsTemplate, wpNodeRef);
return wpInfo;
}
/* (non-Javadoc)
* @see org.alfresco.wcm.webproject.WebProjectService#updateWebProject(org.alfresco.wcm.webproject.WebProjectInfo)
*/
public void updateWebProject(WebProjectInfo wpInfo)
{
NodeRef wpNodeRef = getWebProjectNodeFromStore(wpInfo.getStoreId());
if (wpNodeRef == null)
{
throw new AlfrescoRuntimeException("Cannot update web project '" + wpInfo.getStoreId() + "' because it does not exist.");
}
// Note: the site preset and short name can not be updated
// Update the properties of the site - note: cannot change storeId or wpNodeRef
Map<QName, Serializable> properties = this.nodeService.getProperties(wpNodeRef);
properties.put(ContentModel.PROP_NAME, wpInfo.getName());
properties.put(ContentModel.PROP_TITLE, wpInfo.getTitle());
properties.put(ContentModel.PROP_DESCRIPTION, wpInfo.getDescription());
properties.put(WCMAppModel.PROP_DEFAULTWEBAPP, wpInfo.getDefaultWebApp());
properties.put(WCMAppModel.PROP_ISSOURCE, wpInfo.isTemplate());
this.nodeService.setProperties(wpNodeRef, properties);
if (logger.isDebugEnabled())
{
logger.debug("Updated web project: " + wpNodeRef + " (store id: " + wpInfo.getStoreId() + ")");
}
}
/* (non-Javadoc)
* @see org.alfresco.wcm.webproject.WebProjectService#deleteWebProject(java.lang.String)
*/
public void deleteWebProject(String wpStoreId)
{
NodeRef wpNodeRef = getWebProjectNodeFromStore(wpStoreId);
if (wpNodeRef != null)
{
deleteWebProject(wpNodeRef);
}
else
{
// by definition, the current user is not a content manager since the web project does not exist (or is not visible)
throw new AccessDeniedException("Only content managers may delete a web project");
}
}
/* (non-Javadoc)
* @see org.alfresco.wcm.webproject.WebProjectService#deleteWebProject(org.alfresco.service.cmr.repository.NodeRef)
*/
public void deleteWebProject(final NodeRef wpNodeRef)
{
if (! isContentManager(wpNodeRef))
{
// the current user is not a content manager since the web project does not exist (or is not visible)
throw new AccessDeniedException("Only content managers may delete web project");
}
// delete all attached website sandboxes in reverse order to the layering
final String wpStoreId = (String)nodeService.getProperty(wpNodeRef, WCMAppModel.PROP_AVMSTORE);
if (wpStoreId != null)
{
// Notifiy virtualization server about removing this website
//
// Implementation note:
//
// Because the removal of virtual webapps in the virtualization
// server is recursive, it only needs to be given the name of
// the main staging store.
//
// This notification must occur *prior* to purging content
// within the AVM because the virtualization server must list
// the avm_webapps dir in each store to discover which
// virtual webapps must be unloaded. The virtualization
// server traverses the sandbox's stores in most-to-least
// dependent order, so clients don't have to worry about
// accessing a preview layer whose main layer has been torn
// out from under it.
//
// It does not matter what webapp name we give here, so "/ROOT"
// is as sensible as anything else. It's all going away.
String sandbox = WCMUtil.buildStagingStoreName(wpStoreId);
String path = WCMUtil.buildStoreWebappPath(sandbox, "/ROOT");
WCMUtil.removeAllVServerWebapps(virtServerRegistry, path, true);
AuthenticationUtil.runAs(new RunAsWork<Object>()
{
public Object doWork() throws Exception
{
List<SandboxInfo> sbInfos = sandboxFactory.listAllSandboxes(wpStoreId);
for (SandboxInfo sbInfo : sbInfos)
{
// delete sandbox
sandboxFactory.deleteSandbox(sbInfo.getSandboxId());
}
// TODO delete workflow sandboxes !
// delete the web project node itself
nodeService.deleteNode(wpNodeRef);
return null;
}
}, AuthenticationUtil.getSystemUserName());
if (logger.isInfoEnabled())
{
logger.info("Deleted web project: " + wpNodeRef + " (store id: " + wpStoreId + ")");
}
}
}
/* (non-Javadoc)
* @see org.alfresco.wcm.webproject.WebProjectService#isContentManager(java.lang.String)
*/
public boolean isContentManager(String storeName)
{
return isContentManager(storeName, AuthenticationUtil.getRunAsUser());
}
/* (non-Javadoc)
* @see org.alfresco.wcm.WebProjectService#isContentManager(java.lang.String, java.lang.String)
*/
public boolean isContentManager(String wpStoreId, String userName)
{
return isContentManager(getWebProjectNodeFromStore(wpStoreId), userName);
}
/* (non-Javadoc)
* @see org.alfresco.wcm.webproject.WebProjectService#isContentManager(org.alfresco.service.cmr.repository.NodeRef)
*/
public boolean isContentManager(NodeRef wpNodeRef)
{
return isContentManager(wpNodeRef, AuthenticationUtil.getRunAsUser());
}
/* (non-Javadoc)
* @see org.alfresco.wcm.webproject.WebProjectService#isContentManager(org.alfresco.service.cmr.repository.NodeRef, java.lang.String)
*/
public boolean isContentManager(NodeRef wpNodeRef, String userName)
{
String userRole = getWebUserRole(wpNodeRef, userName);
return WCMUtil.ROLE_CONTENT_MANAGER.equals(userRole);
}
/* (non-Javadoc)
* @see org.alfresco.wcm.webproject.WebProjectService#isWebUser(java.lang.String)
*/
public boolean isWebUser(String wpStoreId)
{
return isWebUser(getWebProjectNodeFromStore(wpStoreId));
}
/* (non-Javadoc)
* @see org.alfresco.wcm.webproject.WebProjectService#isWebUser(org.alfresco.service.cmr.repository.NodeRef)
*/
public boolean isWebUser(NodeRef wpNodeRef)
{
// note: admin is an implied web user (content manager) although will not appear in listWebUsers unless explicitly invited
return (permissionService.hasPermission(wpNodeRef, PermissionService.READ) == AccessStatus.ALLOWED);
}
/* (non-Javadoc)
* @see org.alfresco.wcm.webproject.WebProjectService#isWebUser(java.lang.String, java.lang.String)
*/
public boolean isWebUser(String wpStoreId, String username)
{
return isWebUser(getWebProjectNodeFromStore(wpStoreId), username);
}
/* (non-Javadoc)
* @see org.alfresco.wcm.webproject.WebProjectService#isWebUser(org.alfresco.service.cmr.repository.NodeRef, java.lang.String)
*/
public boolean isWebUser(final NodeRef wpNodeRef, String userName)
{
return AuthenticationUtil.runAs(new RunAsWork<Boolean>()
{
public Boolean doWork() throws Exception
{
return isWebUser(wpNodeRef);
}
}, userName);
}
/* (non-Javadoc)
* @see org.alfresco.wcm.webproject.WebProjectService#getWebUserCount(org.alfresco.service.cmr.repository.NodeRef)
*/
public int getWebUserCount(NodeRef wpNodeRef)
{
return WCMUtil.listWebUsers(nodeService, wpNodeRef).size();
}
/* (non-Javadoc)
* @see org.alfresco.wcm.webproject.WebProjectService#listWebUsers(java.lang.String)
*/
public Map<String, String> listWebUsers(String wpStoreId)
{
return listWebUsers(getWebProjectNodeFromStore(wpStoreId));
}
/* (non-Javadoc)
* @see org.alfresco.wcm.webproject.WebProjectService#listWebUsers(org.alfresco.service.cmr.repository.NodeRef)
*/
public Map<String, String> listWebUsers(NodeRef wpNodeRef)
{
// special case: allow System - eg. to allow user to create their own sandbox on-demand (createAuthorSandbox)
if (isContentManager(wpNodeRef)
|| (AuthenticationUtil.getRunAsUser().equals(AuthenticationUtil.getSystemUserName())
|| (permissionService.hasPermission(wpNodeRef, PermissionService.ADD_CHILDREN) == AccessStatus.ALLOWED)))
{
return WCMUtil.listWebUsers(nodeService, wpNodeRef);
}
else
{
throw new AccessDeniedException("Only content managers may list users in a web project");
}
}
/* (non-Javadoc)
* @see org.alfresco.wcm.webproject.WebProjectService#getWebUserRole(java.lang.String, java.lang.String)
*/
public String getWebUserRole(String wpStoreId, String userName)
{
return getWebUserRole(getWebProjectNodeFromStore(wpStoreId), userName);
}
/* (non-Javadoc)
* @see org.alfresco.wcm.webproject.WebProjectService#getWebUserRole(org.alfresco.service.cmr.repository.NodeRef, java.lang.String)
*/
public String getWebUserRole(NodeRef wpNodeRef, String userName)
{
ParameterCheck.mandatoryString("userName", userName);
String userRole = null;
if (! isWebProject(wpNodeRef))
{
logger.warn(wpNodeRef + " is not a web project");
return null;
}
if (authorityService.isAdminAuthority(userName))
{
// fake the Content Manager role for an admin user
userRole = WCMUtil.ROLE_CONTENT_MANAGER;
}
else
{
userRole = getWebUserRoleImpl(wpNodeRef, userName);
}
return userRole;
}
private String getWebUserRoleImpl(NodeRef wpNodeRef, String userName)
{
NodeRef userRef = getWebUserRef(wpNodeRef, userName);
String userRole = null;
if (userRef != null)
{
userRole = (String)nodeService.getProperty(userRef, WCMAppModel.PROP_WEBUSERROLE);
}
return userRole;
}
private NodeRef getWebUserRef(NodeRef wpNodeRef, String userName)
{
StringBuilder query = new StringBuilder(128);
query.append("+PARENT:\"").append(wpNodeRef).append("\" ");
query.append("+TYPE:\"").append(WCMAppModel.TYPE_WEBUSER).append("\" ");
query.append("+@").append(NamespaceService.WCMAPP_MODEL_PREFIX).append("\\:username:\"");
query.append(userName);
query.append("\"");
ResultSet resultSet = null;
List<NodeRef> nodes = null;
try
{
resultSet = searchService.query(
WEBPROJECT_STORE,
SearchService.LANGUAGE_LUCENE,
query.toString());
nodes = resultSet.getNodeRefs();
}
finally
{
if (resultSet != null)
{
resultSet.close();
}
}
if (nodes.size() == 1)
{
return nodes.get(0);
}
else if (nodes.size() == 0)
{
if (logger.isTraceEnabled())
{
logger.trace("getWebUserRef: web user ("+userName+") not found in web project: "+wpNodeRef);
}
}
else
{
logger.error("getWebUserRef: more than one web user ("+userName+") found in web project: "+wpNodeRef);
}
return null;
}
/* (non-Javadoc)
* @see org.alfresco.wcm.webproject.WebProjectService#findWebProjectNodeFromPath(java.lang.String)
*/
public NodeRef getWebProjectNodeFromPath(String absoluteAVMPath)
{
return getWebProjectNodeFromStore(WCMUtil.getWebProjectStoreIdFromPath(absoluteAVMPath));
}
/*(non-Javadoc)
* @see org.alfresco.wcm.webproject.WebProjectService#getWebProjectNodeFromStore(java.lang.String)
*/
public NodeRef getWebProjectNodeFromStore(String wpStoreId)
{
ParameterCheck.mandatoryString("wpStoreId", wpStoreId);
return WCMUtil.getWebProjectNodeFromWebProjectStore(avmService, wpStoreId);
}
/* (non-Javadoc)
* @see org.alfresco.wcm.webproject.WebProjectService#inviteWebUsersGroups(java.lang.String, java.util.Map)
*/
public void inviteWebUsersGroups(String wpStoreId, Map<String, String> userGroupRoles)
{
inviteWebUsersGroups(getWebProjectNodeFromStore(wpStoreId), userGroupRoles, false);
}
/* (non-Javadoc)
* @see org.alfresco.wcm.webproject.WebProjectService#inviteWebUsersGroups(java.lang.String, java.util.Map, boolean)
*/
public void inviteWebUsersGroups(String wpStoreId, Map<String, String> userGroupRoles, boolean autoCreateAuthorSandbox)
{
inviteWebUsersGroups(getWebProjectNodeFromStore(wpStoreId), userGroupRoles, autoCreateAuthorSandbox);
}
public void inviteWebUsersGroups(NodeRef wpNodeRef, Map<String, String> userGroupRoles, boolean autoCreateAuthorSandbox)
{
if (! (isContentManager(wpNodeRef) ||
permissionService.hasPermission(wpNodeRef, PermissionService.ADD_CHILDREN) == AccessStatus.ALLOWED))
{
throw new AccessDeniedException("Only content managers may invite web users");
}
WebProjectInfo wpInfo = getWebProject(wpNodeRef);
String wpStoreId = wpInfo.getStoreId();
// build a list of managers who will have full permissions on ALL staging areas
List<String> managers = new ArrayList<String>(4);
Map<String, NodeRef> webSiteUsers = new HashMap<String, NodeRef>(8);
List<String> managersToRemove = new LinkedList<String>();
List<UserRoleWrapper> usersToUpdate = new LinkedList<UserRoleWrapper>();
// retrieve the list of managers from the existing users
for (Map.Entry<String, String> userRole : userGroupRoles.entrySet())
{
String authority = userRole.getKey();
String role = userRole.getValue();
for (String userAuth : findNestedUserAuthorities(authority))
{
if (WCMUtil.ROLE_CONTENT_MANAGER.equals(role))
{
managers.add(userAuth);
}
}
}
List<ChildAssociationRef> userInfoRefs = nodeService.getChildAssocs(wpNodeRef, WCMAppModel.ASSOC_WEBUSER, RegexQNamePattern.MATCH_ALL);
for (ChildAssociationRef ref : userInfoRefs)
{
NodeRef userInfoRef = ref.getChildRef();
String username = (String)nodeService.getProperty(userInfoRef, WCMAppModel.PROP_WEBUSERNAME);
String userrole = (String)nodeService.getProperty(userInfoRef, WCMAppModel.PROP_WEBUSERROLE);
if (WCMUtil.ROLE_CONTENT_MANAGER.equals(userrole) && managers.contains(username) == false)
{
managers.add(username);
}
// add each existing user to the map which will be rechecked for update changed user permissions
webSiteUsers.put(username, userInfoRef);
}
List<SandboxInfo> sandboxInfoList = new LinkedList<SandboxInfo>();
int invitedCount = 0;
boolean managersUpdateRequired = false;
for (Map.Entry<String, String> userRole : userGroupRoles.entrySet())
{
String authority = userRole.getKey();
String role = userRole.getValue();
for (String userAuth : findNestedUserAuthorities(authority))
{
if (webSiteUsers.keySet().contains(userAuth) == false)
{
if (autoCreateAuthorSandbox)
{
// create a sandbox for the user with permissions based on role
SandboxInfo sbInfo = sandboxFactory.createUserSandbox(wpStoreId, managers, userAuth, role);
sandboxInfoList.add(sbInfo);
}
sandboxFactory.addStagingAreaUser(wpStoreId, userAuth, role);
// create an app:webuser instance for each authority and assoc to the web project node
createWebUser(wpNodeRef, userAuth, role);
// if this new user is a manager, we'll need to update the manager permissions applied
// to each existing user sandbox - to ensure that new managers have access to them
managersUpdateRequired |= (WCMUtil.ROLE_CONTENT_MANAGER.equals(role));
invitedCount++;
}
else
{
// TODO - split out into separate 'change role'
// if user role have been changed then update required properties etc.
NodeRef userRef = webSiteUsers.get(userAuth);
String oldUserRole = (String)nodeService.getProperty(userRef, WCMAppModel.PROP_WEBUSERROLE);
if (!role.equals(oldUserRole))
{
// change in role
Map<QName, Serializable> props = nodeService.getProperties(userRef);
props.put(WCMAppModel.PROP_WEBUSERNAME, userAuth);
props.put(WCMAppModel.PROP_WEBUSERROLE, role);
nodeService.setProperties(userRef, props);
if (WCMUtil.ROLE_CONTENT_MANAGER.equals(role))
{
managersUpdateRequired = true;
}
else if (WCMUtil.ROLE_CONTENT_MANAGER.equals(oldUserRole))
{
managersToRemove.add(userAuth);
}
usersToUpdate.add(sandboxFactory.new UserRoleWrapper(userAuth, oldUserRole, role));
if (logger.isDebugEnabled())
{
logger.debug(userAuth +"'s role has been changed from '" + oldUserRole +
"' to '" + role + "'");
}
}
}
}
}
// Bind the post-commit transaction listener with data required for virtualization server notification
CreateSandboxTransactionListener tl = new CreateSandboxTransactionListener(sandboxInfoList, listWebApps(wpNodeRef));
AlfrescoTransactionSupport.bindListener(tl);
if (managersUpdateRequired == true)
{
sandboxFactory.updateSandboxManagers(wpStoreId, managers);
}
// TODO - split out into separate 'change role'
// remove ex-managers from sandboxes
if (managersToRemove.size() != 0)
{
sandboxFactory.removeSandboxManagers(wpStoreId, managersToRemove);
}
// get permissions and roles for a web project folder type
Set<String> perms = permissionService.getSettablePermissions(WCMAppModel.TYPE_AVMWEBFOLDER);
// set permissions for each user
for (Map.Entry<String, String> userRole : userGroupRoles.entrySet())
{
String authority = userRole.getKey();
String role = userRole.getValue();
for (String permission : perms)
{
if (role.equals(permission))
{
permissionService.setPermission(wpNodeRef,
authority,
permission,
true);
break;
}
}
}
// TODO - split out into separate 'change role'
// update user's roles
if (usersToUpdate.size() != 0)
{
sandboxFactory.updateSandboxRoles(wpStoreId, usersToUpdate, perms);
}
if (logger.isInfoEnabled())
{
logger.info("Invited "+invitedCount+" web users (store id: "+wpStoreId+")");
}
}
/* (non-Javadoc)
* @see org.alfresco.wcm.webproject.WebProjectService#inviteWebUser(java.lang.String, java.lang.String, java.lang.String)
*/
public void inviteWebUser(String wpStoreId, String userAuth, String role)
{
inviteWebUser(getWebProjectNodeFromStore(wpStoreId), userAuth, role, false);
}
/* (non-Javadoc)
* @see org.alfresco.wcm.webproject.WebProjectService#inviteWebUser(java.lang.String, java.lang.String, java.lang.String, boolean)
*/
public void inviteWebUser(String wpStoreId, String userAuth, String role, boolean autoCreateAuthorSandbox)
{
inviteWebUser(getWebProjectNodeFromStore(wpStoreId), userAuth, role, autoCreateAuthorSandbox);
}
/* (non-Javadoc)
* @see org.alfresco.wcm.webproject.WebProjectService#inviteWebUser(org.alfresco.service.cmr.repository.NodeRef, java.lang.String, java.lang.String, boolean)
*/
public void inviteWebUser(NodeRef wpNodeRef, String userAuth, String role, boolean autoCreateAuthorSandbox)
{
if (! (isContentManager(wpNodeRef) ||
permissionService.hasPermission(wpNodeRef, PermissionService.ADD_CHILDREN) == AccessStatus.ALLOWED))
{
throw new AccessDeniedException("Only content managers may invite web user");
}
WebProjectInfo wpInfo = getWebProject(wpNodeRef);
final String wpStoreId = wpInfo.getStoreId();
// build a list of managers who will have full permissions on ALL staging areas
List<String> managers = new ArrayList<String>(4);
// retrieve the list of managers from the existing users
Map<String, String> existingUserRoles = listWebUsers(wpNodeRef);
for (Map.Entry<String, String> userRole : existingUserRoles.entrySet())
{
String username = userRole.getKey();
String userrole = userRole.getValue();
if (WCMUtil.ROLE_CONTENT_MANAGER.equals(userrole) && managers.contains(username) == false)
{
managers.add(username);
}
}
// get permissions and roles for a web project folder type
Set<String> perms = permissionService.getSettablePermissions(WCMAppModel.TYPE_AVMWEBFOLDER);
NodeRef userRef = getWebUserRef(wpNodeRef, userAuth);
if (userRef != null)
{
// TODO - split out into separate 'change role'
// if user role has been changed then update required properties etc.
String oldUserRole = (String)nodeService.getProperty(userRef, WCMAppModel.PROP_WEBUSERROLE);
if (!role.equals(oldUserRole))
{
// change in role
Map<QName, Serializable> props = nodeService.getProperties(userRef);
props.put(WCMAppModel.PROP_WEBUSERNAME, userAuth);
props.put(WCMAppModel.PROP_WEBUSERROLE, role);
nodeService.setProperties(userRef, props);
if (WCMUtil.ROLE_CONTENT_MANAGER.equals(role))
{
managers.add(userAuth);
sandboxFactory.updateSandboxManagers(wpStoreId, managers);
}
else if (WCMUtil.ROLE_CONTENT_MANAGER.equals(oldUserRole))
{
List<String> managersToRemove = new LinkedList<String>();
managersToRemove.add(userAuth);
sandboxFactory.removeSandboxManagers(wpStoreId, managersToRemove);
}
List<UserRoleWrapper> usersToUpdate = new LinkedList<UserRoleWrapper>();
usersToUpdate.add(sandboxFactory.new UserRoleWrapper(userAuth, oldUserRole, role));
sandboxFactory.updateSandboxRoles(wpStoreId, usersToUpdate, perms);
if (logger.isInfoEnabled())
{
logger.info("Web user "+userAuth +"'s role has been changed from '" + oldUserRole + "' to '" + role + "' (store id: "+wpStoreId+")");
}
}
}
else
{
if (autoCreateAuthorSandbox)
{
// create a sandbox for the user with permissions based on role
SandboxInfo sbInfo = sandboxFactory.createUserSandbox(wpStoreId, managers, userAuth, role);
List<SandboxInfo> sandboxInfoList = new LinkedList<SandboxInfo>();
sandboxInfoList.add(sbInfo);
// Bind the post-commit transaction listener with data required for virtualization server notification
CreateSandboxTransactionListener tl = new CreateSandboxTransactionListener(sandboxInfoList, listWebApps(wpNodeRef));
AlfrescoTransactionSupport.bindListener(tl);
}
// if this new user is a manager, we'll need to update the manager permissions applied
// to each existing user sandbox - to ensure that new user has access to them
if (WCMUtil.ROLE_CONTENT_MANAGER.equals(role))
{
managers.add(userAuth);
sandboxFactory.updateSandboxManagers(wpStoreId, managers);
}
sandboxFactory.addStagingAreaUser(wpStoreId, userAuth, role);
// create an app:webuser instance for the user and assoc to the web project node
createWebUser(wpNodeRef, userAuth, role);
// set permissions for the user
for (String permission : perms)
{
if (role.equals(permission))
{
permissionService.setPermission(wpNodeRef,
userAuth,
permission,
true);
break;
}
}
if (logger.isInfoEnabled())
{
logger.info("Invited web user: "+userAuth+" (store id: "+wpStoreId+")");
}
}
}
private void createWebUser(NodeRef wpNodeRef, String userName, String userRole)
{
// create an app:webuser instance for the user and assoc to the web project node
Map<QName, Serializable> props = new HashMap<QName, Serializable>(2, 1.0f);
props.put(WCMAppModel.PROP_WEBUSERNAME, userName);
props.put(WCMAppModel.PROP_WEBUSERROLE, userRole);
nodeService.createNode(wpNodeRef,
WCMAppModel.ASSOC_WEBUSER,
WCMAppModel.ASSOC_WEBUSER,
WCMAppModel.TYPE_WEBUSER,
props);
}
/* (non-Javadoc)
* @see org.alfresco.wcm.webproject.WebProjectService#uninviteWebUser(java.lang.String, java.lang.String)
*/
public void uninviteWebUser(String wpStoreId, String userAuth)
{
uninviteWebUser(getWebProjectNodeFromStore(wpStoreId), userAuth, false);
}
/* (non-Javadoc)
* @see org.alfresco.wcm.webproject.WebProjectService#uninviteWebUser(java.lang.String, java.lang.String, boolean)
*/
public void uninviteWebUser(String wpStoreId, String userAuth, boolean autoDeleteAuthorSandbox)
{
uninviteWebUser(getWebProjectNodeFromStore(wpStoreId), userAuth, autoDeleteAuthorSandbox);
}
/* (non-Javadoc)
* @see org.alfresco.wcm.webproject.WebProjectService#uninviteWebUser(org.alfresco.service.cmr.repository.NodeRef, java.lang.String, boolean)
*/
public void uninviteWebUser(NodeRef wpNodeRef, String userAuth, boolean autoDeleteAuthorSandbox)
{
if (! isContentManager(wpNodeRef))
{
throw new AccessDeniedException("Only content managers may uninvite web user '"+userAuth+"' from web project: "+wpNodeRef);
}
ParameterCheck.mandatory("wpNodeRef", wpNodeRef);
ParameterCheck.mandatoryString("userAuth", userAuth);
WebProjectInfo wpInfo = getWebProject(wpNodeRef);
String wpStoreId = wpInfo.getStoreId();
String userMainStore = WCMUtil.buildUserMainStoreName(wpStoreId, userAuth);
if (autoDeleteAuthorSandbox)
{
sandboxFactory.deleteSandbox(userMainStore);
}
// remove the store reference from the website folder meta-data (see also WCMUtil.listWebUsers)
List<ChildAssociationRef> userInfoRefs = nodeService.getChildAssocs(wpNodeRef, WCMAppModel.ASSOC_WEBUSER, RegexQNamePattern.MATCH_ALL);
// retrieve the list of managers from the existing users
List<String> managers = new ArrayList<String>(4);
for (ChildAssociationRef ref : userInfoRefs)
{
NodeRef userInfoRef = ref.getChildRef();
String username = (String)nodeService.getProperty(userInfoRef, WCMAppModel.PROP_WEBUSERNAME);
String userrole = (String)nodeService.getProperty(userInfoRef, WCMAppModel.PROP_WEBUSERROLE);
if (WCMUtil.ROLE_CONTENT_MANAGER.equals(userrole) && managers.contains(username) == false)
{
managers.add(username);
}
}
for (ChildAssociationRef ref : userInfoRefs)
{
NodeRef userInfoRef = ref.getChildRef();
String user = (String)nodeService.getProperty(userInfoRef, WCMAppModel.PROP_WEBUSERNAME);
if (userAuth.equals(user))
{
// remove the association to this web project user meta-data
nodeService.removeChild(wpNodeRef, ref.getChildRef());
// remove permission for the user (also fixes ETWOONE-338)
permissionService.clearPermission(wpNodeRef, userAuth);
if (logger.isInfoEnabled())
{
logger.info("Uninvited web user: "+userAuth+" (store id: "+wpStoreId+")");
}
break; // for loop
}
}
}
/**
* Find all nested user authorities contained with an authority
*
* @param authority The authority to search, USER authorities are returned immediately, GROUP authorites
* are recursively scanned for contained USER authorities.
*
* @return a Set of USER authorities
*/
private Set<String> findNestedUserAuthorities(String authority)
{
Set<String> users;
AuthorityType authType = AuthorityType.getAuthorityType(authority);
if (authType.equals(AuthorityType.USER))
{
users = new HashSet<String>(1, 1.0f);
if (personService.personExists(authority) == true)
{
users.add(authority);
}
}
else if (authType.equals(AuthorityType.GROUP))
{
// walk each member of the group
users = authorityService.getContainedAuthorities(AuthorityType.USER, authority, false);
for (String userAuth : users)
{
if (personService.personExists(userAuth) == false)
{
users.remove(authType);
}
}
}
else
{
users = Collections.<String>emptySet();
}
return users;
}
private String getWebProjectsPath()
{
return "/"+SPACES_COMPANY_HOME_CHILDNAME+"/"+SPACES_WCM_CHILDNAME;
}
private static final String SPACES_COMPANY_HOME_CHILDNAME = "app:company_home"; // should match repository property: spaces.company_home.childname
private static final String SPACES_WCM_CHILDNAME = "app:wcm"; // should match repository property: spaces.wcm.childname
/**
* Transaction listener - invoked after commit
*/
private class CreateWebProjectTransactionListener extends TransactionListenerAdapter
{
private String wpStoreId;
public CreateWebProjectTransactionListener(String wpStoreId)
{
this.wpStoreId = wpStoreId;
}
/**
* @see org.alfresco.repo.transaction.TransactionListenerAdapter#afterCommit()
*/
@Override
public void afterCommit()
{
// post-commit
if (wpStoreId != null)
{
// update the virtualisation server with the default ROOT webapp path
// performed after the main txn has committed successfully
String newStoreName = WCMUtil.buildStagingStoreName(wpStoreId);
String path = WCMUtil.buildStoreWebappPath(newStoreName, WCMUtil.DIR_ROOT);
WCMUtil.updateVServerWebapp(virtServerRegistry, path, true);
}
}
}
/**
* Create Sandbox Transaction listener - invoked after commit
*/
private class CreateSandboxTransactionListener extends TransactionListenerAdapter
{
private List<SandboxInfo> sandboxInfoList;
private List<String> webAppNames;
public CreateSandboxTransactionListener(List<SandboxInfo> sandboxInfoList, List<String> webAppNames)
{
this.sandboxInfoList = sandboxInfoList;
this.webAppNames = webAppNames;
}
/**
* @see org.alfresco.repo.transaction.TransactionListenerAdapter#afterCommit()
*/
@Override
public void afterCommit()
{
// Handle notification to the virtualization server
// (this needs to occur after the sandboxes are created in the main txn)
// reload virtualisation server for webapp(s) in this web project
for (SandboxInfo sandboxInfo : this.sandboxInfoList)
{
String newlyInvitedStoreName = WCMUtil.buildStagingStoreName(sandboxInfo.getMainStoreName());
for (String webAppName : webAppNames)
{
String path = WCMUtil.buildStoreWebappPath(newlyInvitedStoreName, webAppName);
WCMUtil.updateVServerWebapp(virtServerRegistry, path, true);
}
}
}
}
}