mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-07 17:49:17 +00:00
Merge WCM_SERVICES into HEAD 11697, 11698, 11702, 11751, 11801, 11924, 12023, 12073
git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@12076 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -332,6 +332,9 @@
|
||||
<property name="searchService">
|
||||
<ref bean="SearchService" />
|
||||
</property>
|
||||
<property name="sandboxFactory">
|
||||
<ref bean="sandboxFactory" />
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<!-- AVM Locking. -->
|
||||
|
@@ -147,9 +147,6 @@
|
||||
<property name="serviceRegistry">
|
||||
<ref bean="ServiceRegistry"/>
|
||||
</property>
|
||||
<property name="nameMatcher">
|
||||
<ref bean="globalPathExcluder"/>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean id="crossCopyScript" parent="baseJavaScriptExtension" class="org.alfresco.repo.jscript.CrossRepositoryCopy">
|
||||
|
@@ -46,9 +46,6 @@
|
||||
<property name="serviceRegistry">
|
||||
<ref bean="ServiceRegistry"/>
|
||||
</property>
|
||||
<property name="nameMatcher">
|
||||
<ref bean="globalPathExcluder"/>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean id="sessionTemplateExtension" parent="baseTemplateImplementation" class="org.alfresco.repo.template.Session">
|
||||
|
@@ -3,6 +3,8 @@
|
||||
|
||||
<beans>
|
||||
|
||||
<!-- Web Project Service -->
|
||||
|
||||
<!-- Web Project service bean -->
|
||||
<bean id="WebProjectService" class="org.springframework.aop.framework.ProxyFactoryBean">
|
||||
<property name="proxyInterfaces">
|
||||
@@ -49,22 +51,90 @@
|
||||
<property name="authorityService" ref="AuthorityService"/>
|
||||
<property name="permissionService" ref="PermissionService"/>
|
||||
<property name="personService" ref="PersonService"/>
|
||||
<property name="virtServerRegistry" ref="VirtServerRegistry"/>
|
||||
<property name="sandboxFactory" ref="sandboxFactory"/>
|
||||
<property name="virtServerRegistry" ref="VirtServerRegistry"/>
|
||||
</bean>
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- Sandbox service bean -->
|
||||
<bean id="SandboxService" class="org.springframework.aop.framework.ProxyFactoryBean">
|
||||
<property name="proxyInterfaces">
|
||||
<value>org.alfresco.wcm.sandbox.SandboxService</value>
|
||||
</property>
|
||||
<property name="target">
|
||||
<ref bean="sandboxService"/>
|
||||
</property>
|
||||
<property name="interceptorNames">
|
||||
<list>
|
||||
<idref local="SandboxService_transaction"/>
|
||||
<idref bean="AuditMethodInterceptor"/>
|
||||
<idref bean="exceptionTranslator"/>
|
||||
<idref local="SandboxService_security"/>
|
||||
</list>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<!-- Sandbox service transaction bean -->
|
||||
<bean id="SandboxService_transaction" class="org.springframework.transaction.interceptor.TransactionInterceptor">
|
||||
<property name="transactionManager">
|
||||
<ref bean="transactionManager"/>
|
||||
</property>
|
||||
<property name="transactionAttributes">
|
||||
<props>
|
||||
<prop key="get*">${server.transaction.mode.readOnly}</prop>
|
||||
<prop key="list*">${server.transaction.mode.readOnly}</prop>
|
||||
<prop key="is*">${server.transaction.mode.readOnly}</prop>
|
||||
<prop key="find*">${server.transaction.mode.readOnly}</prop>
|
||||
<prop key="*">${server.transaction.mode.default}</prop>
|
||||
</props>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<!-- Sandbox service security bean -->
|
||||
<bean id="SandboxService_security" class="org.alfresco.repo.security.permissions.impl.AlwaysProceedMethodInterceptor" />
|
||||
|
||||
|
||||
<bean id="sandboxService" class="org.alfresco.wcm.sandbox.SandboxServiceImpl">
|
||||
<property name="webProjectService" ref="WebProjectService"/>
|
||||
<property name="sandboxFactory" ref="sandboxFactory"/>
|
||||
<property name="avmService" ref="AVMService"/>
|
||||
<property name="avmSyncService" ref="AVMSyncService"/>
|
||||
<property name="nameMatcher" ref="globalPathExcluder"/>
|
||||
<property name="virtServerRegistry" ref="VirtServerRegistry"/>
|
||||
<property name="avmLockingService" ref="AVMLockingService"/>
|
||||
<property name="actionService" ref="ActionService"/>
|
||||
<property name="workflowService" ref="WorkflowService"/>
|
||||
</bean>
|
||||
|
||||
<!--
|
||||
<bean id="sandboxScript" parent="baseJavaScriptExtension" class="org.alfresco.wcm.sandbox.script.Sandboxes">
|
||||
<property name="extensionName">
|
||||
<value>sandboxes</value>
|
||||
</property>
|
||||
<property name="serviceRegistry" ref="ServiceRegistry"/>
|
||||
<property name="sandboxService" ref="SandboxService"/>
|
||||
</bean>
|
||||
-->
|
||||
|
||||
<bean id="sandboxFactory" class="org.alfresco.wcm.sandbox.SandboxFactory">
|
||||
<property name="nodeService" ref="NodeService"/>
|
||||
<property name="permissionService" ref="PermissionService"/>
|
||||
<property name="avmService" ref="AVMService"/>
|
||||
<property name="avmLockingService" ref="AVMLockingService"/>
|
||||
<property name="virtServerRegistry" ref="VirtServerRegistry"/>
|
||||
</bean>
|
||||
|
||||
|
||||
<!-- Java script API ROOT Scopeable object for WCM -->
|
||||
<bean id="webProjectsScript" parent="baseJavaScriptExtension" class="org.alfresco.wcm.webproject.script.WebProjects">
|
||||
<property name="extensionName">
|
||||
<value>webprojects</value>
|
||||
</property>
|
||||
<property name="serviceRegistry" ref="ServiceRegistry"/>
|
||||
<property name="webProjectService" ref="WebProjectService"/>
|
||||
</bean>
|
||||
|
||||
<bean id="sandboxFactory" class="org.alfresco.wcm.sandbox.SandboxFactory">
|
||||
<property name="nodeService" ref="NodeService"/>
|
||||
<property name="permissionService" ref="PermissionService"/>
|
||||
<property name="avmService" ref="AVMService"/>
|
||||
<property name="sandboxService" ref="SandboxService"/>
|
||||
</bean>
|
||||
|
||||
</beans>
|
||||
|
@@ -44,7 +44,7 @@ import org.alfresco.repo.domain.PropertyValue;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
|
||||
import org.alfresco.repo.workflow.WorkflowModel;
|
||||
import org.alfresco.sandbox.SandboxConstants;
|
||||
import org.alfresco.wcm.sandbox.SandboxConstants;
|
||||
import org.alfresco.service.cmr.avm.AVMNodeDescriptor;
|
||||
import org.alfresco.service.cmr.avm.AVMService;
|
||||
import org.alfresco.service.cmr.avm.AVMStoreDescriptor;
|
||||
@@ -66,9 +66,8 @@ import org.alfresco.service.cmr.workflow.WorkflowTask;
|
||||
import org.alfresco.service.cmr.workflow.WorkflowTaskState;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.service.transaction.TransactionService;
|
||||
import org.alfresco.util.DNSNameMangler;
|
||||
import org.alfresco.util.GUID;
|
||||
import org.alfresco.util.Pair;
|
||||
import org.alfresco.wcm.sandbox.SandboxFactory;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
@@ -97,6 +96,7 @@ public class AVMExpiredContentProcessor
|
||||
protected TransactionService transactionService;
|
||||
protected VirtServerRegistry virtServerRegistry;
|
||||
protected SearchService searchService;
|
||||
private SandboxFactory sandboxFactory;
|
||||
|
||||
private static Log logger = LogFactory.getLog(AVMExpiredContentProcessor.class);
|
||||
|
||||
@@ -172,6 +172,11 @@ public class AVMExpiredContentProcessor
|
||||
this.avmLockingAwareService = avmLockingAwareService;
|
||||
}
|
||||
|
||||
public void setSandboxFactory(SandboxFactory sandboxFactory)
|
||||
{
|
||||
this.sandboxFactory = sandboxFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the expired content processor.
|
||||
* The work is performed within a transaction running as the system user.
|
||||
@@ -425,7 +430,7 @@ public class AVMExpiredContentProcessor
|
||||
NodeRef assignee = this.personService.getPerson(userName);
|
||||
|
||||
// create a workflow store layered over the users store
|
||||
String workflowStoreName = createUserWorkflowSandbox(storeName, userStore);
|
||||
String workflowStoreName = sandboxFactory.createUserWorkflowSandbox(storeName, userStore);
|
||||
|
||||
// create a workflow package with all the expired items
|
||||
NodeRef workflowPackage = setupWorkflowPackage(workflowStoreName, expiredContent);
|
||||
@@ -454,124 +459,6 @@ public class AVMExpiredContentProcessor
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a workflow sandbox for the given user store. This will create a
|
||||
* workflow sandbox layered over the user's main store.
|
||||
*
|
||||
* @param stagingStore The name of the staging store the user sandbox is layered over
|
||||
* @param userStore The name of the user store to create the workflow for
|
||||
* @return The store name of the main store in the workflow sandbox
|
||||
*/
|
||||
private String createUserWorkflowSandbox(String stagingStore, String userStore)
|
||||
{
|
||||
// create the workflow 'main' store
|
||||
String packageName = "workflow-" + GUID.generate();
|
||||
String workflowStoreName = userStore + STORE_SEPARATOR + packageName;
|
||||
|
||||
this.avmService.createStore(workflowStoreName);
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Created user workflow sandbox store: " + workflowStoreName);
|
||||
|
||||
// create a layered directory pointing to 'www' in the users store
|
||||
this.avmService.createLayeredDirectory(
|
||||
userStore + ":/" + JNDIConstants.DIR_DEFAULT_WWW,
|
||||
workflowStoreName + ":/", JNDIConstants.DIR_DEFAULT_WWW);
|
||||
|
||||
// tag the store with the store type
|
||||
this.avmService.setStoreProperty(workflowStoreName,
|
||||
SandboxConstants.PROP_SANDBOX_AUTHOR_WORKFLOW_MAIN,
|
||||
new PropertyValue(DataTypeDefinition.TEXT, null));
|
||||
|
||||
// tag the store with the name of the author's store this one is layered over
|
||||
this.avmService.setStoreProperty(workflowStoreName,
|
||||
SandboxConstants.PROP_AUTHOR_NAME,
|
||||
new PropertyValue(DataTypeDefinition.TEXT, userStore));
|
||||
|
||||
// tag the store, oddly enough, with its own store name for querying.
|
||||
this.avmService.setStoreProperty(workflowStoreName,
|
||||
QName.createQName(null, SandboxConstants.PROP_SANDBOX_STORE_PREFIX + workflowStoreName),
|
||||
new PropertyValue(DataTypeDefinition.TEXT, null));
|
||||
|
||||
// tag the store with the DNS name property
|
||||
String path = workflowStoreName + ":/" + JNDIConstants.DIR_DEFAULT_WWW +
|
||||
"/" + JNDIConstants.DIR_DEFAULT_APPBASE;
|
||||
// DNS name mangle the property name - can only contain value DNS characters!
|
||||
String dnsProp = SandboxConstants.PROP_DNS + DNSNameMangler.MakeDNSName(stagingStore, packageName);
|
||||
this.avmService.setStoreProperty(workflowStoreName, QName.createQName(null, dnsProp),
|
||||
new PropertyValue(DataTypeDefinition.TEXT, path));
|
||||
|
||||
// the main workflow store depends on the main user store (dist=1)
|
||||
String prop_key = SandboxConstants.PROP_BACKGROUND_LAYER + userStore;
|
||||
this.avmService.setStoreProperty(workflowStoreName, QName.createQName(null, prop_key),
|
||||
new PropertyValue(DataTypeDefinition.INT, 1));
|
||||
|
||||
// The main workflow store depends on the main staging store (dist=2)
|
||||
prop_key = SandboxConstants.PROP_BACKGROUND_LAYER + stagingStore;
|
||||
this.avmService.setStoreProperty(workflowStoreName, QName.createQName(null, prop_key),
|
||||
new PropertyValue(DataTypeDefinition.INT, 2));
|
||||
|
||||
// snapshot the store
|
||||
this.avmService.createSnapshot(workflowStoreName, null, null);
|
||||
|
||||
// create the workflow 'preview' store
|
||||
String previewStoreName = workflowStoreName + STORE_SEPARATOR + "preview";
|
||||
this.avmService.createStore(previewStoreName);
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Created user workflow sandbox preview store: " + previewStoreName);
|
||||
|
||||
// create a layered directory pointing to 'www' in the workflow 'main' store
|
||||
this.avmService.createLayeredDirectory(
|
||||
workflowStoreName + ":/" + JNDIConstants.DIR_DEFAULT_WWW,
|
||||
previewStoreName + ":/", JNDIConstants.DIR_DEFAULT_WWW);
|
||||
|
||||
// tag the store with the store type
|
||||
this.avmService.setStoreProperty(previewStoreName, SandboxConstants.PROP_SANDBOX_WORKFLOW_PREVIEW,
|
||||
new PropertyValue(DataTypeDefinition.TEXT, null));
|
||||
|
||||
// tag the store with its own store name for querying.
|
||||
avmService.setStoreProperty(previewStoreName,
|
||||
QName.createQName(null, SandboxConstants.PROP_SANDBOX_STORE_PREFIX + previewStoreName),
|
||||
new PropertyValue(DataTypeDefinition.TEXT, null));
|
||||
|
||||
// tag the store with the DNS name property
|
||||
path = previewStoreName + ":/" + JNDIConstants.DIR_DEFAULT_WWW +
|
||||
"/" + JNDIConstants.DIR_DEFAULT_APPBASE;
|
||||
// DNS name mangle the property name - can only contain value DNS characters!
|
||||
dnsProp = SandboxConstants.PROP_DNS + DNSNameMangler.MakeDNSName(userStore, packageName, "preview");
|
||||
this.avmService.setStoreProperty(previewStoreName, QName.createQName(null, dnsProp),
|
||||
new PropertyValue(DataTypeDefinition.TEXT, path));
|
||||
|
||||
// The preview worfkflow store depends on the main workflow store (dist=1)
|
||||
prop_key = SandboxConstants.PROP_BACKGROUND_LAYER + workflowStoreName;
|
||||
this.avmService.setStoreProperty(previewStoreName, QName.createQName(null, prop_key),
|
||||
new PropertyValue(DataTypeDefinition.INT, 1));
|
||||
|
||||
// The preview workflow store depends on the main user store (dist=2)
|
||||
prop_key = SandboxConstants.PROP_BACKGROUND_LAYER + userStore;
|
||||
this.avmService.setStoreProperty(previewStoreName, QName.createQName(null, prop_key),
|
||||
new PropertyValue(DataTypeDefinition.INT, 2));
|
||||
|
||||
// The preview workflow store depends on the main staging store (dist=3)
|
||||
prop_key = SandboxConstants.PROP_BACKGROUND_LAYER + stagingStore;
|
||||
this.avmService.setStoreProperty(previewStoreName, QName.createQName(null, prop_key),
|
||||
new PropertyValue(DataTypeDefinition.INT, 3));
|
||||
|
||||
// snapshot the store
|
||||
this.avmService.createSnapshot(previewStoreName, null, null);
|
||||
|
||||
// tag all related stores to indicate that they are part of a single sandbox
|
||||
QName sandboxIdProp = QName.createQName(SandboxConstants.PROP_SANDBOXID + GUID.generate());
|
||||
this.avmService.setStoreProperty(workflowStoreName, sandboxIdProp,
|
||||
new PropertyValue(DataTypeDefinition.TEXT, null));
|
||||
this.avmService.setStoreProperty(previewStoreName, sandboxIdProp,
|
||||
new PropertyValue(DataTypeDefinition.TEXT, null));
|
||||
|
||||
// return the main workflow store name
|
||||
return workflowStoreName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up a workflow package from the given main workflow store and applies
|
||||
* the list of paths as modified items within the main workflow store.
|
||||
|
@@ -24,22 +24,17 @@
|
||||
*/
|
||||
package org.alfresco.repo.jscript;
|
||||
|
||||
import java.text.MessageFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.alfresco.config.JNDIConstants;
|
||||
import org.alfresco.repo.avm.AVMNodeConverter;
|
||||
import org.alfresco.repo.domain.PropertyValue;
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
import org.alfresco.service.cmr.avm.AVMNodeDescriptor;
|
||||
import org.alfresco.service.cmr.avm.AVMService;
|
||||
import org.alfresco.service.cmr.avm.AVMStoreDescriptor;
|
||||
import org.alfresco.service.cmr.avmsync.AVMDifference;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.util.NameMatcher;
|
||||
import org.alfresco.util.ParameterCheck;
|
||||
import org.alfresco.wcm.sandbox.SandboxService;
|
||||
import org.alfresco.wcm.util.WCMUtil;
|
||||
import org.mozilla.javascript.Context;
|
||||
import org.mozilla.javascript.Scriptable;
|
||||
|
||||
@@ -53,8 +48,6 @@ public final class AVM extends BaseScopableProcessorExtension
|
||||
/** Repository Service Registry */
|
||||
private ServiceRegistry services;
|
||||
|
||||
private NameMatcher matcher;
|
||||
|
||||
/**
|
||||
* Set the service registry
|
||||
*
|
||||
@@ -65,11 +58,6 @@ public final class AVM extends BaseScopableProcessorExtension
|
||||
this.services = serviceRegistry;
|
||||
}
|
||||
|
||||
public void setNameMatcher(NameMatcher matcher)
|
||||
{
|
||||
this.matcher = matcher;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a array of all AVM stores in the system
|
||||
*/
|
||||
@@ -163,29 +151,18 @@ public final class AVM extends BaseScopableProcessorExtension
|
||||
ParameterCheck.mandatoryString("Username", username);
|
||||
ParameterCheck.mandatoryString("Webapp", webapp);
|
||||
|
||||
List<AVMNode> items;
|
||||
SandboxService sbService = this.services.getSandboxService();
|
||||
|
||||
AVMService avmService = this.services.getAVMService();
|
||||
// get modified items - not including deleted
|
||||
List<AVMNodeDescriptor> nodes = sbService.listChangedItemsWebApp(storeId, webapp, false);
|
||||
|
||||
// build the paths to the stores to compare - filter by current webapp
|
||||
String userStore = userSandboxStore(storeId, username);
|
||||
String userStorePath = getStoreRootWebappPath(userStore, webapp);
|
||||
String stagingStore = stagingStore(storeId);
|
||||
String stagingStorePath = getStoreRootWebappPath(stagingStore, webapp);
|
||||
List<AVMNode> items = new ArrayList<AVMNode>(nodes.size());
|
||||
|
||||
List<AVMDifference> diffs = this.services.getAVMSyncService().compare(
|
||||
-1, userStorePath, -1, stagingStorePath, this.matcher);
|
||||
items = new ArrayList<AVMNode>(diffs.size());
|
||||
for (AVMDifference diff : diffs)
|
||||
{
|
||||
// convert each diff record into an AVM Node template wrapper
|
||||
String sourcePath = diff.getSourcePath();
|
||||
AVMNodeDescriptor node = avmService.lookup(-1, sourcePath);
|
||||
if (node != null)
|
||||
for (AVMNodeDescriptor node : nodes)
|
||||
{
|
||||
// convert each diff/node record into an AVM Node wrapper
|
||||
items.add(new AVMNode(node.getPath(), -1, this.services, getScope()));
|
||||
}
|
||||
}
|
||||
|
||||
return items;
|
||||
}
|
||||
@@ -197,8 +174,7 @@ public final class AVM extends BaseScopableProcessorExtension
|
||||
*/
|
||||
public static String stagingStore(String storeId)
|
||||
{
|
||||
ParameterCheck.mandatoryString("Store ID", storeId);
|
||||
return storeId;
|
||||
return WCMUtil.buildStagingStoreName(storeId);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -209,9 +185,7 @@ public final class AVM extends BaseScopableProcessorExtension
|
||||
*/
|
||||
public static String userSandboxStore(String storeId, String username)
|
||||
{
|
||||
ParameterCheck.mandatoryString("Store ID", storeId);
|
||||
ParameterCheck.mandatoryString("Username", username);
|
||||
return storeId + "--" + username;
|
||||
return WCMUtil.buildUserMainStoreName(storeId, username);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -221,9 +195,7 @@ public final class AVM extends BaseScopableProcessorExtension
|
||||
*/
|
||||
public String websiteStagingUrl(String storeId)
|
||||
{
|
||||
ParameterCheck.mandatoryString("Store ID", storeId);
|
||||
return MessageFormat.format(JNDIConstants.PREVIEW_SANDBOX_URL,
|
||||
lookupStoreDNS(storeId), getVServerDomain(), getVServerPort());
|
||||
return WCMUtil.buildStoreUrl(this.services.getAVMService(), storeId, getVServerDomain(), getVServerPort());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -247,25 +219,7 @@ public final class AVM extends BaseScopableProcessorExtension
|
||||
*/
|
||||
public String assetUrl(String store, String assetPath)
|
||||
{
|
||||
ParameterCheck.mandatoryString("Store", store);
|
||||
ParameterCheck.mandatoryString("Asset Path", assetPath);
|
||||
|
||||
if (assetPath.startsWith('/' + JNDIConstants.DIR_DEFAULT_WWW +
|
||||
'/' + JNDIConstants.DIR_DEFAULT_APPBASE))
|
||||
{
|
||||
assetPath = assetPath.substring(('/' + JNDIConstants.DIR_DEFAULT_WWW +
|
||||
'/' + JNDIConstants.DIR_DEFAULT_APPBASE).length());
|
||||
}
|
||||
if (assetPath.startsWith("/ROOT"))
|
||||
{
|
||||
assetPath = assetPath.substring(("/ROOT").length());
|
||||
}
|
||||
if (assetPath.length() == 0 || assetPath.charAt(0) != '/')
|
||||
{
|
||||
assetPath = '/' + assetPath;
|
||||
}
|
||||
return MessageFormat.format(JNDIConstants.PREVIEW_ASSET_URL,
|
||||
lookupStoreDNS(store), getVServerDomain(), getVServerPort(), assetPath);
|
||||
return WCMUtil.buildAssetUrl(assetPath, getVServerDomain(), getVServerPort(), WCMUtil.lookupStoreDNS(this.services.getAVMService(), store));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -315,27 +269,6 @@ public final class AVM extends BaseScopableProcessorExtension
|
||||
*/
|
||||
public static String getWebappsFolderPath()
|
||||
{
|
||||
return '/' + JNDIConstants.DIR_DEFAULT_WWW +
|
||||
'/' + JNDIConstants.DIR_DEFAULT_APPBASE;
|
||||
return JNDIConstants.DIR_DEFAULT_WWW_APPBASE;
|
||||
}
|
||||
|
||||
private static String getStoreRootPath(String store)
|
||||
{
|
||||
return store + ":" + getWebappsFolderPath();
|
||||
}
|
||||
|
||||
private static String getStoreRootWebappPath(String store, String webapp)
|
||||
{
|
||||
return getStoreRootPath(store) + '/' + webapp;
|
||||
}
|
||||
|
||||
private String lookupStoreDNS(String store)
|
||||
{
|
||||
Map<QName, PropertyValue> props =
|
||||
this.services.getAVMService().queryStorePropertyKey(store, QName.createQName(null, PROP_DNS + '%'));
|
||||
return (props.size() == 1
|
||||
? props.keySet().iterator().next().getLocalName().substring(PROP_DNS.length()) : null);
|
||||
}
|
||||
|
||||
private final static String PROP_DNS = ".dns.";
|
||||
}
|
||||
|
@@ -69,6 +69,7 @@ import org.alfresco.service.descriptor.DescriptorService;
|
||||
import org.alfresco.service.namespace.NamespaceService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.service.transaction.TransactionService;
|
||||
import org.alfresco.wcm.sandbox.SandboxService;
|
||||
import org.alfresco.wcm.webproject.WebProjectService;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
@@ -468,4 +469,11 @@ public class ServiceDescriptorRegistry
|
||||
public WebProjectService getWebProjectService() {
|
||||
return (WebProjectService)getService(WEBPROJECT_SERVICE);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.service.ServiceRegistry#getSandboxService()
|
||||
*/
|
||||
public SandboxService getSandboxService() {
|
||||
return (SandboxService)getService(SANDBOX_SERVICE);
|
||||
}
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2007 Alfresco Software Limited.
|
||||
* 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
|
||||
@@ -24,21 +24,16 @@
|
||||
*/
|
||||
package org.alfresco.repo.template;
|
||||
|
||||
import java.text.MessageFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.alfresco.config.JNDIConstants;
|
||||
import org.alfresco.repo.domain.PropertyValue;
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
import org.alfresco.service.cmr.avm.AVMNodeDescriptor;
|
||||
import org.alfresco.service.cmr.avm.AVMService;
|
||||
import org.alfresco.service.cmr.avm.AVMStoreDescriptor;
|
||||
import org.alfresco.service.cmr.avmsync.AVMDifference;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.util.NameMatcher;
|
||||
import org.alfresco.util.ParameterCheck;
|
||||
import org.alfresco.wcm.sandbox.SandboxService;
|
||||
import org.alfresco.wcm.util.WCMUtil;
|
||||
|
||||
/**
|
||||
* AVM root object access for a template model.
|
||||
@@ -48,7 +43,6 @@ import org.alfresco.util.ParameterCheck;
|
||||
public class AVM extends BaseTemplateProcessorExtension
|
||||
{
|
||||
private ServiceRegistry services;
|
||||
private NameMatcher matcher;
|
||||
|
||||
/**
|
||||
* Sets the service registry
|
||||
@@ -60,11 +54,6 @@ public class AVM extends BaseTemplateProcessorExtension
|
||||
this.services = services;
|
||||
}
|
||||
|
||||
public void setNameMatcher(NameMatcher matcher)
|
||||
{
|
||||
this.matcher = matcher;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a list of all AVM stores in the system
|
||||
*/
|
||||
@@ -152,29 +141,18 @@ public class AVM extends BaseTemplateProcessorExtension
|
||||
ParameterCheck.mandatoryString("Username", username);
|
||||
ParameterCheck.mandatoryString("Webapp", webapp);
|
||||
|
||||
List<AVMTemplateNode> items;
|
||||
SandboxService sbService = this.services.getSandboxService();
|
||||
|
||||
AVMService avmService = this.services.getAVMService();
|
||||
// get modified items - not including deleted
|
||||
List<AVMNodeDescriptor> nodes = sbService.listChangedItemsWebApp(storeId, webapp, false);
|
||||
|
||||
// build the paths to the stores to compare - filter by current webapp
|
||||
String userStore = userSandboxStore(storeId, username);
|
||||
String userStorePath = getStoreRootWebappPath(userStore, webapp);
|
||||
String stagingStore = stagingStore(storeId);
|
||||
String stagingStorePath = getStoreRootWebappPath(stagingStore, webapp);
|
||||
List<AVMTemplateNode> items = new ArrayList<AVMTemplateNode>(nodes.size());
|
||||
|
||||
List<AVMDifference> diffs = this.services.getAVMSyncService().compare(
|
||||
-1, userStorePath, -1, stagingStorePath, this.matcher);
|
||||
items = new ArrayList<AVMTemplateNode>(diffs.size());
|
||||
for (AVMDifference diff : diffs)
|
||||
{
|
||||
// convert each diff record into an AVM Node template wrapper
|
||||
String sourcePath = diff.getSourcePath();
|
||||
AVMNodeDescriptor node = avmService.lookup(-1, sourcePath);
|
||||
if (node != null)
|
||||
for (AVMNodeDescriptor node : nodes)
|
||||
{
|
||||
// convert each diff/node record into an AVM Node template wrapper
|
||||
items.add(new AVMTemplateNode(node, this.services, getTemplateImageResolver()));
|
||||
}
|
||||
}
|
||||
|
||||
return items;
|
||||
}
|
||||
@@ -186,8 +164,7 @@ public class AVM extends BaseTemplateProcessorExtension
|
||||
*/
|
||||
public static String stagingStore(String storeId)
|
||||
{
|
||||
ParameterCheck.mandatoryString("Store ID", storeId);
|
||||
return storeId;
|
||||
return WCMUtil.buildStagingStoreName(storeId);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -198,9 +175,7 @@ public class AVM extends BaseTemplateProcessorExtension
|
||||
*/
|
||||
public static String userSandboxStore(String storeId, String username)
|
||||
{
|
||||
ParameterCheck.mandatoryString("Store ID", storeId);
|
||||
ParameterCheck.mandatoryString("Username", username);
|
||||
return storeId + "--" + username;
|
||||
return WCMUtil.buildUserMainStoreName(storeId, username);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -210,9 +185,7 @@ public class AVM extends BaseTemplateProcessorExtension
|
||||
*/
|
||||
public String websiteStagingUrl(String storeId)
|
||||
{
|
||||
ParameterCheck.mandatoryString("Store ID", storeId);
|
||||
return MessageFormat.format(JNDIConstants.PREVIEW_SANDBOX_URL,
|
||||
lookupStoreDNS(storeId), getVServerDomain(), getVServerPort());
|
||||
return WCMUtil.buildStoreUrl(this.services.getAVMService(), storeId, getVServerDomain(), getVServerPort());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -236,25 +209,7 @@ public class AVM extends BaseTemplateProcessorExtension
|
||||
*/
|
||||
public String assetUrl(String store, String assetPath)
|
||||
{
|
||||
ParameterCheck.mandatoryString("Store", store);
|
||||
ParameterCheck.mandatoryString("Asset Path", assetPath);
|
||||
|
||||
if (assetPath.startsWith('/' + JNDIConstants.DIR_DEFAULT_WWW +
|
||||
'/' + JNDIConstants.DIR_DEFAULT_APPBASE))
|
||||
{
|
||||
assetPath = assetPath.substring(('/' + JNDIConstants.DIR_DEFAULT_WWW +
|
||||
'/' + JNDIConstants.DIR_DEFAULT_APPBASE).length());
|
||||
}
|
||||
if (assetPath.startsWith("/ROOT"))
|
||||
{
|
||||
assetPath = assetPath.substring(("/ROOT").length());
|
||||
}
|
||||
if (assetPath.length() == 0 || assetPath.charAt(0) != '/')
|
||||
{
|
||||
assetPath = '/' + assetPath;
|
||||
}
|
||||
return MessageFormat.format(JNDIConstants.PREVIEW_ASSET_URL,
|
||||
lookupStoreDNS(store), getVServerDomain(), getVServerPort(), assetPath);
|
||||
return WCMUtil.buildAssetUrl(assetPath, getVServerDomain(), getVServerPort(), WCMUtil.lookupStoreDNS(this.services.getAVMService(), store));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -304,27 +259,6 @@ public class AVM extends BaseTemplateProcessorExtension
|
||||
*/
|
||||
public static String getWebappsFolderPath()
|
||||
{
|
||||
return '/' + JNDIConstants.DIR_DEFAULT_WWW +
|
||||
'/' + JNDIConstants.DIR_DEFAULT_APPBASE;
|
||||
return JNDIConstants.DIR_DEFAULT_WWW_APPBASE;
|
||||
}
|
||||
|
||||
private static String getStoreRootPath(String store)
|
||||
{
|
||||
return store + ":" + getWebappsFolderPath();
|
||||
}
|
||||
|
||||
private static String getStoreRootWebappPath(String store, String webapp)
|
||||
{
|
||||
return getStoreRootPath(store) + '/' + webapp;
|
||||
}
|
||||
|
||||
private String lookupStoreDNS(String store)
|
||||
{
|
||||
Map<QName, PropertyValue> props =
|
||||
this.services.getAVMService().queryStorePropertyKey(store, QName.createQName(null, PROP_DNS + '%'));
|
||||
return (props.size() == 1
|
||||
? props.keySet().iterator().next().getLocalName().substring(PROP_DNS.length()) : null);
|
||||
}
|
||||
|
||||
private final static String PROP_DNS = ".dns.";
|
||||
}
|
||||
|
@@ -33,6 +33,7 @@ import org.alfresco.service.cmr.action.ActionService;
|
||||
import org.alfresco.service.cmr.attributes.AttributeService;
|
||||
import org.alfresco.service.cmr.audit.AuditService;
|
||||
import org.alfresco.service.cmr.avm.AVMService;
|
||||
import org.alfresco.service.cmr.avm.deploy.DeploymentService;
|
||||
import org.alfresco.service.cmr.avm.locking.AVMLockingService;
|
||||
import org.alfresco.service.cmr.avmsync.AVMSyncService;
|
||||
import org.alfresco.service.cmr.coci.CheckOutCheckInService;
|
||||
@@ -62,12 +63,12 @@ import org.alfresco.service.cmr.thumbnail.ThumbnailService;
|
||||
import org.alfresco.service.cmr.version.VersionService;
|
||||
import org.alfresco.service.cmr.view.ExporterService;
|
||||
import org.alfresco.service.cmr.view.ImporterService;
|
||||
import org.alfresco.service.cmr.avm.deploy.DeploymentService;
|
||||
import org.alfresco.service.cmr.workflow.WorkflowService;
|
||||
import org.alfresco.service.descriptor.DescriptorService;
|
||||
import org.alfresco.service.namespace.NamespaceService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.service.transaction.TransactionService;
|
||||
import org.alfresco.wcm.sandbox.SandboxService;
|
||||
import org.alfresco.wcm.webproject.WebProjectService;
|
||||
|
||||
|
||||
@@ -129,6 +130,7 @@ public interface ServiceRegistry
|
||||
static final QName TAGGING_SERVICE = QName.createQName(NamespaceService.ALFRESCO_URI, "TaggingService");
|
||||
static final QName DEPLOYMENT_SERVICE = QName.createQName(NamespaceService.ALFRESCO_URI, "DeploymentService");
|
||||
static final QName WEBPROJECT_SERVICE = QName.createQName(NamespaceService.ALFRESCO_URI, "WebProjectService");
|
||||
static final QName SANDBOX_SERVICE = QName.createQName(NamespaceService.ALFRESCO_URI, "SandboxService");
|
||||
|
||||
/**
|
||||
* Get the list of services provided by the Repository
|
||||
@@ -429,4 +431,11 @@ public interface ServiceRegistry
|
||||
*/
|
||||
@NotAuditable
|
||||
WebProjectService getWebProjectService();
|
||||
|
||||
/**
|
||||
* Get the Sandbox Service
|
||||
* @return
|
||||
*/
|
||||
@NotAuditable
|
||||
SandboxService getSandboxService();
|
||||
}
|
||||
|
54
source/java/org/alfresco/wcm/WCMTestSuite.java
Normal file
54
source/java/org/alfresco/wcm/WCMTestSuite.java
Normal file
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import junit.framework.Test;
|
||||
import junit.framework.TestSuite;
|
||||
|
||||
import org.alfresco.wcm.sandbox.SandboxServiceImplTest;
|
||||
import org.alfresco.wcm.webproject.WebProjectServiceImplTest;
|
||||
|
||||
/**
|
||||
* WCM test suite
|
||||
*
|
||||
* @author janv
|
||||
*/
|
||||
public class WCMTestSuite extends TestSuite
|
||||
{
|
||||
/**
|
||||
* Creates the test suite
|
||||
*
|
||||
* @return the test suite
|
||||
*/
|
||||
public static Test suite()
|
||||
{
|
||||
TestSuite suite = new TestSuite();
|
||||
|
||||
suite.addTestSuite(WebProjectServiceImplTest.class);
|
||||
suite.addTestSuite(SandboxServiceImplTest.class);
|
||||
|
||||
return suite;
|
||||
}
|
||||
}
|
@@ -43,6 +43,7 @@ public class SandboxConstants
|
||||
public final static String PROP_DNS = ".dns.";
|
||||
public final static String PROP_SANDBOX_STORE_PREFIX = ".sandbox.store.";
|
||||
|
||||
// sandbox type
|
||||
public final static QName PROP_SANDBOX_STAGING_MAIN = QName.createQName(null, ".sandbox.staging.main");
|
||||
public final static QName PROP_SANDBOX_STAGING_PREVIEW = QName.createQName(null, ".sandbox.staging.preview");
|
||||
public final static QName PROP_SANDBOX_AUTHOR_MAIN = QName.createQName(null, ".sandbox.author.main");
|
||||
@@ -51,6 +52,7 @@ public class SandboxConstants
|
||||
public final static QName PROP_SANDBOX_WORKFLOW_PREVIEW = QName.createQName(null, ".sandbox.workflow.preview");
|
||||
public final static QName PROP_SANDBOX_AUTHOR_WORKFLOW_MAIN = QName.createQName(null, ".sandbox.author.workflow.main");
|
||||
public final static QName PROP_SANDBOX_AUTHOR_WORKFLOW_PREVIEW = QName.createQName(null, ".sandbox.author.workflow.preview");
|
||||
|
||||
public final static QName PROP_WEBSITE_NAME = QName.createQName(null, ".website.name");
|
||||
public final static QName PROP_AUTHOR_NAME = QName.createQName(null, ".author.name");
|
||||
public final static QName PROP_WEB_PROJECT_NODE_REF = QName.createQName(null, ".web_project.noderef");
|
||||
|
@@ -24,24 +24,29 @@
|
||||
*/
|
||||
package org.alfresco.wcm.sandbox;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.alfresco.config.JNDIConstants;
|
||||
import org.alfresco.model.WCMAppModel;
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.mbeans.VirtServerRegistry;
|
||||
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.service.cmr.avm.AVMService;
|
||||
import org.alfresco.service.cmr.avm.AVMStoreDescriptor;
|
||||
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.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.cmr.security.PermissionService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.service.namespace.RegexQNamePattern;
|
||||
import org.alfresco.util.DNSNameMangler;
|
||||
import org.alfresco.util.GUID;
|
||||
import org.alfresco.util.ParameterCheck;
|
||||
import org.alfresco.wcm.util.WCMUtil;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
@@ -57,9 +62,11 @@ public final class SandboxFactory extends WCMUtil
|
||||
private static Log logger = LogFactory.getLog(SandboxFactory.class);
|
||||
|
||||
/** Services */
|
||||
private NodeService nodeService;
|
||||
private PermissionService permissionService;
|
||||
private AVMService avmService;
|
||||
private NodeService nodeService;
|
||||
private AVMLockingService avmLockingService;
|
||||
private VirtServerRegistry virtServerRegistry;
|
||||
|
||||
public void setNodeService(NodeService nodeService)
|
||||
{
|
||||
@@ -76,6 +83,17 @@ public final class SandboxFactory extends WCMUtil
|
||||
this.avmService = avmService;
|
||||
}
|
||||
|
||||
public void setAvmLockingService(AVMLockingService avmLockingService)
|
||||
{
|
||||
this.avmLockingService = avmLockingService;
|
||||
}
|
||||
|
||||
public void setVirtServerRegistry(VirtServerRegistry virtServerRegistry)
|
||||
{
|
||||
this.virtServerRegistry = virtServerRegistry;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Private constructor
|
||||
*/
|
||||
@@ -109,7 +127,7 @@ public final class SandboxFactory extends WCMUtil
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("Created staging sandbox store: " + stagingStoreName);
|
||||
logger.debug("Created staging sandbox: " + stagingStoreName);
|
||||
}
|
||||
|
||||
// we can either branch from an existing staging store or create a new structure
|
||||
@@ -200,24 +218,97 @@ public final class SandboxFactory extends WCMUtil
|
||||
dumpStoreProperties(avmService, previewStoreName);
|
||||
}
|
||||
|
||||
return new SandboxInfo( new String[] { stagingStoreName, previewStoreName } );
|
||||
return getSandbox(stagingStoreName);
|
||||
}
|
||||
|
||||
protected void setStagingPermissions(String storeId, NodeRef webProjectNodeRef)
|
||||
/**
|
||||
* Get sandbox info for given sandbox store id
|
||||
*
|
||||
* @param sandboxId
|
||||
* @return SandboxInfo returns sandbox info or null if sandbox does not exist or is not visible
|
||||
*/
|
||||
public SandboxInfo getSandbox(String sandboxId)
|
||||
{
|
||||
AVMStoreDescriptor storeDesc = avmService.getStore(sandboxId);
|
||||
if (storeDesc == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
String wpStoreId = WCMUtil.getWebProjectStoreId(sandboxId);
|
||||
|
||||
String[] storeNames = null;
|
||||
|
||||
// Check sandbox type
|
||||
Map<QName, PropertyValue> props = avmService.getStoreProperties(sandboxId);
|
||||
QName sandboxType = null;
|
||||
|
||||
// derive name for now
|
||||
String name = null;
|
||||
|
||||
if (props.containsKey(SandboxConstants.PROP_SANDBOX_STAGING_MAIN))
|
||||
{
|
||||
sandboxType = SandboxConstants.PROP_SANDBOX_STAGING_MAIN;
|
||||
name = sandboxId;
|
||||
storeNames = new String[] {sandboxId, WCMUtil.getCorrespondingPreviewStoreName(sandboxId)};
|
||||
}
|
||||
else if ( props.containsKey( SandboxConstants.PROP_SANDBOX_STAGING_PREVIEW))
|
||||
{
|
||||
sandboxType = SandboxConstants.PROP_SANDBOX_STAGING_PREVIEW;
|
||||
storeNames = new String[] {WCMUtil.getCorrespondingMainStoreName(sandboxId), sandboxId};
|
||||
}
|
||||
else if (props.containsKey(SandboxConstants.PROP_SANDBOX_AUTHOR_MAIN))
|
||||
{
|
||||
sandboxType = SandboxConstants.PROP_SANDBOX_AUTHOR_MAIN;
|
||||
name = WCMUtil.getUserName(sandboxId);
|
||||
storeNames = new String[] {sandboxId, WCMUtil.getCorrespondingPreviewStoreName(sandboxId)};
|
||||
}
|
||||
else if (props.containsKey(SandboxConstants.PROP_SANDBOX_AUTHOR_PREVIEW))
|
||||
{
|
||||
sandboxType = SandboxConstants.PROP_SANDBOX_AUTHOR_PREVIEW;
|
||||
name = WCMUtil.getUserName(sandboxId);
|
||||
storeNames = new String[] {WCMUtil.getCorrespondingMainStoreName(sandboxId), sandboxId};
|
||||
}
|
||||
else if (props.containsKey(SandboxConstants.PROP_SANDBOX_WORKFLOW_MAIN))
|
||||
{
|
||||
sandboxType = SandboxConstants.PROP_SANDBOX_WORKFLOW_MAIN;
|
||||
name = WCMUtil.getWorkflowId(sandboxId);
|
||||
storeNames = new String[] {sandboxId, WCMUtil.getCorrespondingPreviewStoreName(sandboxId)};
|
||||
}
|
||||
else if (props.containsKey(SandboxConstants.PROP_SANDBOX_WORKFLOW_PREVIEW))
|
||||
{
|
||||
sandboxType = SandboxConstants.PROP_SANDBOX_WORKFLOW_PREVIEW;
|
||||
name = WCMUtil.getWorkflowId(sandboxId);
|
||||
storeNames = new String[] {WCMUtil.getCorrespondingMainStoreName(sandboxId), sandboxId};
|
||||
}
|
||||
|
||||
if ((storeNames == null) || (storeNames.length == 0))
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Must have at least one store");
|
||||
}
|
||||
|
||||
if ((storeNames.length == 1) && (! sandboxType.equals(SandboxConstants.PROP_SANDBOX_STAGING_MAIN)))
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Main store must be of type: " + SandboxConstants.PROP_SANDBOX_STAGING_MAIN);
|
||||
}
|
||||
|
||||
return new SandboxInfoImpl(wpStoreId, sandboxId, sandboxType, name, storeNames, new Date(storeDesc.getCreateDate()), storeDesc.getCreator());
|
||||
}
|
||||
|
||||
protected void setStagingPermissions(String storeId, NodeRef wpNodeRef)
|
||||
{
|
||||
String storeName = WCMUtil.buildStagingStoreName(storeId);
|
||||
NodeRef dirRef = AVMNodeConverter.ToNodeRef(-1, WCMUtil.buildStoreRootPath(storeName));
|
||||
|
||||
// Apply sepcific user permissions as set on the web project
|
||||
// Apply specific user permissions as set on the web project
|
||||
// All these will be masked out
|
||||
List<ChildAssociationRef> userInfoRefs = nodeService.getChildAssocs(
|
||||
webProjectNodeRef, WCMAppModel.ASSOC_WEBUSER, RegexQNamePattern.MATCH_ALL);
|
||||
|
||||
for (ChildAssociationRef ref : userInfoRefs)
|
||||
Map<String, String> userRoles = WCMUtil.listWebUsers(nodeService, wpNodeRef);
|
||||
|
||||
for (Map.Entry<String, String> userRole : userRoles.entrySet())
|
||||
{
|
||||
NodeRef userInfoRef = ref.getChildRef();
|
||||
String username = (String)nodeService.getProperty(userInfoRef, WCMAppModel.PROP_WEBUSERNAME);
|
||||
String userrole = (String)nodeService.getProperty(userInfoRef, WCMAppModel.PROP_WEBUSERROLE);
|
||||
String username = userRole.getKey();
|
||||
String userrole = userRole.getValue();
|
||||
|
||||
permissionService.setPermission(dirRef, username, userrole, true);
|
||||
}
|
||||
@@ -238,7 +329,7 @@ public final class SandboxFactory extends WCMUtil
|
||||
permissionService.setPermission(dirRef, PermissionService.ALL_AUTHORITIES, PermissionService.READ, true);
|
||||
}
|
||||
|
||||
public void updateStagingAreaManagers(String storeId, NodeRef webProjectNodeRef, final List<String> managers)
|
||||
private void updateStagingAreaManagers(String storeId, NodeRef webProjectNodeRef, final List<String> managers)
|
||||
{
|
||||
// The stores have the mask set in updateSandboxManagers
|
||||
String storeName = WCMUtil.buildStagingStoreName(storeId);
|
||||
@@ -256,10 +347,10 @@ public final class SandboxFactory extends WCMUtil
|
||||
}
|
||||
}
|
||||
|
||||
public void addStagingAreaUser(String storeId, String authority, String role)
|
||||
public void addStagingAreaUser(String wpStoreId, String authority, String role)
|
||||
{
|
||||
// The stores have the mask set in updateSandboxManagers
|
||||
String storeName = WCMUtil.buildStagingStoreName(storeId);
|
||||
String storeName = WCMUtil.buildStagingStoreName(wpStoreId);
|
||||
|
||||
NodeRef dirRef = AVMNodeConverter.ToNodeRef(-1, WCMUtil.buildStoreRootPath(storeName));
|
||||
permissionService.setPermission(dirRef, authority, role, true);
|
||||
@@ -293,20 +384,23 @@ public final class SandboxFactory extends WCMUtil
|
||||
String userStoreName = WCMUtil.buildUserMainStoreName(storeId, username);
|
||||
String previewStoreName = WCMUtil.buildUserPreviewStoreName(storeId, username);
|
||||
|
||||
if (avmService.getStore(userStoreName) != null)
|
||||
SandboxInfo userSandboxInfo = getSandbox(userStoreName);
|
||||
if (userSandboxInfo != null)
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("Not creating as store already exists: " + userStoreName);
|
||||
logger.debug("Not creating author sandbox as it already exists: " + userStoreName);
|
||||
}
|
||||
return new SandboxInfo( new String[] { userStoreName, previewStoreName } );
|
||||
return userSandboxInfo;
|
||||
}
|
||||
|
||||
avmService.createStore(userStoreName);
|
||||
String stagingStoreName = WCMUtil.buildStagingStoreName(storeId);
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Created user sandbox store: " + userStoreName +
|
||||
" above staging store " + stagingStoreName);
|
||||
{
|
||||
logger.debug("Created user sandbox: " + userStoreName + " above staging store " + stagingStoreName);
|
||||
}
|
||||
|
||||
// create a layered directory pointing to 'www' in the staging area
|
||||
avmService.createLayeredDirectory(WCMUtil.buildStoreRootPath(stagingStoreName),
|
||||
@@ -417,7 +511,8 @@ public final class SandboxFactory extends WCMUtil
|
||||
dumpStoreProperties(avmService, userStoreName);
|
||||
dumpStoreProperties(avmService, previewStoreName);
|
||||
}
|
||||
return new SandboxInfo( new String[] { userStoreName, previewStoreName } );
|
||||
|
||||
return getSandbox(userStoreName);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -533,7 +628,232 @@ public final class SandboxFactory extends WCMUtil
|
||||
dumpStoreProperties(avmService, mainStoreName);
|
||||
dumpStoreProperties(avmService, previewStoreName);
|
||||
}
|
||||
return new SandboxInfo( new String[] { mainStoreName, previewStoreName } );
|
||||
|
||||
return getSandbox(mainStoreName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a workflow sandbox for the given user store. This will create a
|
||||
* workflow sandbox layered over the user's main store.
|
||||
*
|
||||
* @param stagingStore The name of the staging store the user sandbox is layered over
|
||||
* @param userStore The name of the user store to create the workflow for
|
||||
* @return The store name of the main store in the workflow sandbox
|
||||
*/
|
||||
// TODO refactor AVMExpiredContentProcessor ...
|
||||
public String createUserWorkflowSandbox(String stagingStore, String userStore)
|
||||
{
|
||||
// create the workflow 'main' store
|
||||
String packageName = "workflow-" + GUID.generate();
|
||||
String workflowStoreName = userStore + STORE_SEPARATOR + packageName;
|
||||
|
||||
this.avmService.createStore(workflowStoreName);
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Created user workflow sandbox store: " + workflowStoreName);
|
||||
|
||||
// create a layered directory pointing to 'www' in the users store
|
||||
this.avmService.createLayeredDirectory(
|
||||
userStore + ":/" + JNDIConstants.DIR_DEFAULT_WWW,
|
||||
workflowStoreName + ":/", JNDIConstants.DIR_DEFAULT_WWW);
|
||||
|
||||
// tag the store with the store type
|
||||
this.avmService.setStoreProperty(workflowStoreName,
|
||||
SandboxConstants.PROP_SANDBOX_AUTHOR_WORKFLOW_MAIN,
|
||||
new PropertyValue(DataTypeDefinition.TEXT, null));
|
||||
|
||||
// tag the store with the name of the author's store this one is layered over
|
||||
this.avmService.setStoreProperty(workflowStoreName,
|
||||
SandboxConstants.PROP_AUTHOR_NAME,
|
||||
new PropertyValue(DataTypeDefinition.TEXT, userStore));
|
||||
|
||||
// tag the store, oddly enough, with its own store name for querying.
|
||||
this.avmService.setStoreProperty(workflowStoreName,
|
||||
QName.createQName(null, SandboxConstants.PROP_SANDBOX_STORE_PREFIX + workflowStoreName),
|
||||
new PropertyValue(DataTypeDefinition.TEXT, null));
|
||||
|
||||
// tag the store with the DNS name property
|
||||
String path = workflowStoreName + ":/" + JNDIConstants.DIR_DEFAULT_WWW +
|
||||
"/" + JNDIConstants.DIR_DEFAULT_APPBASE;
|
||||
// DNS name mangle the property name - can only contain value DNS characters!
|
||||
String dnsProp = SandboxConstants.PROP_DNS + DNSNameMangler.MakeDNSName(stagingStore, packageName);
|
||||
this.avmService.setStoreProperty(workflowStoreName, QName.createQName(null, dnsProp),
|
||||
new PropertyValue(DataTypeDefinition.TEXT, path));
|
||||
|
||||
// the main workflow store depends on the main user store (dist=1)
|
||||
String prop_key = SandboxConstants.PROP_BACKGROUND_LAYER + userStore;
|
||||
this.avmService.setStoreProperty(workflowStoreName, QName.createQName(null, prop_key),
|
||||
new PropertyValue(DataTypeDefinition.INT, 1));
|
||||
|
||||
// The main workflow store depends on the main staging store (dist=2)
|
||||
prop_key = SandboxConstants.PROP_BACKGROUND_LAYER + stagingStore;
|
||||
this.avmService.setStoreProperty(workflowStoreName, QName.createQName(null, prop_key),
|
||||
new PropertyValue(DataTypeDefinition.INT, 2));
|
||||
|
||||
// snapshot the store
|
||||
this.avmService.createSnapshot(workflowStoreName, null, null);
|
||||
|
||||
// create the workflow 'preview' store
|
||||
String previewStoreName = workflowStoreName + STORE_SEPARATOR + "preview";
|
||||
this.avmService.createStore(previewStoreName);
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Created user workflow sandbox preview store: " + previewStoreName);
|
||||
|
||||
// create a layered directory pointing to 'www' in the workflow 'main' store
|
||||
this.avmService.createLayeredDirectory(
|
||||
workflowStoreName + ":/" + JNDIConstants.DIR_DEFAULT_WWW,
|
||||
previewStoreName + ":/", JNDIConstants.DIR_DEFAULT_WWW);
|
||||
|
||||
// tag the store with the store type
|
||||
this.avmService.setStoreProperty(previewStoreName, SandboxConstants.PROP_SANDBOX_WORKFLOW_PREVIEW,
|
||||
new PropertyValue(DataTypeDefinition.TEXT, null));
|
||||
|
||||
// tag the store with its own store name for querying.
|
||||
avmService.setStoreProperty(previewStoreName,
|
||||
QName.createQName(null, SandboxConstants.PROP_SANDBOX_STORE_PREFIX + previewStoreName),
|
||||
new PropertyValue(DataTypeDefinition.TEXT, null));
|
||||
|
||||
// tag the store with the DNS name property
|
||||
path = previewStoreName + ":/" + JNDIConstants.DIR_DEFAULT_WWW +
|
||||
"/" + JNDIConstants.DIR_DEFAULT_APPBASE;
|
||||
// DNS name mangle the property name - can only contain value DNS characters!
|
||||
dnsProp = SandboxConstants.PROP_DNS + DNSNameMangler.MakeDNSName(userStore, packageName, "preview");
|
||||
this.avmService.setStoreProperty(previewStoreName, QName.createQName(null, dnsProp),
|
||||
new PropertyValue(DataTypeDefinition.TEXT, path));
|
||||
|
||||
// The preview worfkflow store depends on the main workflow store (dist=1)
|
||||
prop_key = SandboxConstants.PROP_BACKGROUND_LAYER + workflowStoreName;
|
||||
this.avmService.setStoreProperty(previewStoreName, QName.createQName(null, prop_key),
|
||||
new PropertyValue(DataTypeDefinition.INT, 1));
|
||||
|
||||
// The preview workflow store depends on the main user store (dist=2)
|
||||
prop_key = SandboxConstants.PROP_BACKGROUND_LAYER + userStore;
|
||||
this.avmService.setStoreProperty(previewStoreName, QName.createQName(null, prop_key),
|
||||
new PropertyValue(DataTypeDefinition.INT, 2));
|
||||
|
||||
// The preview workflow store depends on the main staging store (dist=3)
|
||||
prop_key = SandboxConstants.PROP_BACKGROUND_LAYER + stagingStore;
|
||||
this.avmService.setStoreProperty(previewStoreName, QName.createQName(null, prop_key),
|
||||
new PropertyValue(DataTypeDefinition.INT, 3));
|
||||
|
||||
// snapshot the store
|
||||
this.avmService.createSnapshot(previewStoreName, null, null);
|
||||
|
||||
// tag all related stores to indicate that they are part of a single sandbox
|
||||
QName sandboxIdProp = QName.createQName(SandboxConstants.PROP_SANDBOXID + GUID.generate());
|
||||
this.avmService.setStoreProperty(workflowStoreName, sandboxIdProp,
|
||||
new PropertyValue(DataTypeDefinition.TEXT, null));
|
||||
this.avmService.setStoreProperty(previewStoreName, sandboxIdProp,
|
||||
new PropertyValue(DataTypeDefinition.TEXT, null));
|
||||
|
||||
// return the main workflow store name
|
||||
return workflowStoreName;
|
||||
}
|
||||
|
||||
public List<SandboxInfo> listSandboxes(final String wpStoreId, String userName)
|
||||
{
|
||||
ParameterCheck.mandatoryString("wpStoreId", wpStoreId);
|
||||
ParameterCheck.mandatoryString("userName", userName);
|
||||
|
||||
return AuthenticationUtil.runAs(new AuthenticationUtil.RunAsWork<List<SandboxInfo>>()
|
||||
{
|
||||
public List<SandboxInfo> doWork() throws Exception
|
||||
{
|
||||
List<AVMStoreDescriptor> stores = avmService.getStores();
|
||||
|
||||
List<SandboxInfo> sbInfos = new ArrayList<SandboxInfo>();
|
||||
for (AVMStoreDescriptor store : stores)
|
||||
{
|
||||
String storeName = store.getName();
|
||||
|
||||
// list main stores - not preview stores or workflow stores
|
||||
if ((storeName.startsWith(wpStoreId)) &&
|
||||
(! WCMUtil.isPreviewStore(storeName)) &&
|
||||
(! WCMUtil.isWorkflowStore(storeName)))
|
||||
{
|
||||
sbInfos.add(getSandbox(storeName));
|
||||
}
|
||||
}
|
||||
|
||||
return sbInfos;
|
||||
}
|
||||
}, userName);
|
||||
}
|
||||
|
||||
public void deleteSandbox(String sbStoreId)
|
||||
{
|
||||
SandboxInfo sbInfo = getSandbox(sbStoreId);
|
||||
|
||||
if (sbInfo != null)
|
||||
{
|
||||
String mainSandboxStore = sbInfo.getMainStoreName();
|
||||
|
||||
// found the sandbox to remove - remove the main store (eg. user main store, staging main store, workflow main store)
|
||||
String path = WCMUtil.buildSandboxRootPath(mainSandboxStore);
|
||||
|
||||
// Notify virtualisation server about removing this sandbox.
|
||||
//
|
||||
// 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 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.
|
||||
|
||||
WCMUtil.removeAllVServerWebapps(virtServerRegistry, path, true);
|
||||
|
||||
// TODO: Use the .sandbox-id. property to delete all sandboxes,
|
||||
// rather than assume a sandbox always had a single preview
|
||||
// layer attached.
|
||||
|
||||
// purge stores, eg. main store followed by preview store
|
||||
String[] avmStoreNames = sbInfo.getStoreNames();
|
||||
|
||||
for (String avmStoreName : avmStoreNames)
|
||||
{
|
||||
// check it exists before we try to remove it
|
||||
if (avmService.getStore(avmStoreName) != null)
|
||||
{
|
||||
// purge store from the system
|
||||
avmService.purgeStore(avmStoreName);
|
||||
}
|
||||
|
||||
// remove any locks this user may have
|
||||
avmLockingService.removeStoreLocks(avmStoreName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void updateSandboxManagers(final String wpStoreId, NodeRef wpNodeRef, List<String> managers)
|
||||
{
|
||||
// walk existing user sandboxes and reapply manager permissions to include new manager user
|
||||
List<SandboxInfo> sbInfos = AuthenticationUtil.runAs(new RunAsWork<List<SandboxInfo>>()
|
||||
{
|
||||
public List<SandboxInfo> doWork() throws Exception
|
||||
{
|
||||
return listSandboxes(wpStoreId, AuthenticationUtil.getSystemUserName());
|
||||
}
|
||||
}, AuthenticationUtil.getSystemUserName());
|
||||
|
||||
for (SandboxInfo sbInfo : sbInfos)
|
||||
{
|
||||
if (sbInfo.getSandboxType().equals(SandboxConstants.PROP_SANDBOX_AUTHOR_MAIN))
|
||||
{
|
||||
String username = sbInfo.getName();
|
||||
updateUserSandboxManagers(wpStoreId, managers, username);
|
||||
}
|
||||
}
|
||||
|
||||
updateStagingAreaManagers(wpStoreId, wpNodeRef, managers);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -545,7 +865,7 @@ public final class SandboxFactory extends WCMUtil
|
||||
* @param managers The list of authorities who have ContentManager role in the web project
|
||||
* @param username Username of the user sandbox to update
|
||||
*/
|
||||
public void updateSandboxManagers(final String storeId, final List<String> managers, final String username)
|
||||
private void updateUserSandboxManagers(final String storeId, final List<String> managers, final String username)
|
||||
{
|
||||
final String userStoreName = WCMUtil.buildUserMainStoreName(storeId, username);
|
||||
final String previewStoreName = WCMUtil.buildUserPreviewStoreName(storeId, username);
|
||||
|
@@ -24,23 +24,43 @@
|
||||
*/
|
||||
package org.alfresco.wcm.sandbox;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
import org.alfresco.service.namespace.QName;
|
||||
|
||||
/**
|
||||
* Provides information about a WCM sandbox created by SandboxFactory.
|
||||
*/
|
||||
public final class SandboxInfo implements Serializable
|
||||
public interface SandboxInfo
|
||||
{
|
||||
private static final long serialVersionUID = 3615436375385857404L;
|
||||
|
||||
String [] store_names_;
|
||||
public SandboxInfo(String [] store_names)
|
||||
{
|
||||
store_names_ = store_names;
|
||||
}
|
||||
/**
|
||||
* Get the name
|
||||
*
|
||||
* @return String name
|
||||
*/
|
||||
public String getName();
|
||||
|
||||
/**
|
||||
* A list of names of the stores within this sandbox.
|
||||
* The sandbox store id
|
||||
*/
|
||||
public String getSandboxId();
|
||||
|
||||
/**
|
||||
* The web project store id
|
||||
*/
|
||||
public String getWebProjectId();
|
||||
|
||||
/**
|
||||
* The sandbox type ... for now a QName, based on existing SandboxConstants
|
||||
*/
|
||||
public QName getSandboxType();
|
||||
|
||||
public Date getCreatedDate();
|
||||
|
||||
public String getCreator();
|
||||
|
||||
/**
|
||||
* A list of ids of the stores within this sandbox.
|
||||
* The "main" store should come first in this list;
|
||||
* any other stores should appear in the order that
|
||||
* they are overlaid on "main" (e.g.: any "preview"
|
||||
@@ -48,10 +68,10 @@ public final class SandboxInfo implements Serializable
|
||||
* <p>
|
||||
* Note: all sandboxes must have a "main" layer.
|
||||
*/
|
||||
public String [] getStoreNames() { return store_names_; }
|
||||
public String[] getStoreNames();
|
||||
|
||||
/**
|
||||
* The name of the "main" store within this sandbox.
|
||||
* The id of the "main" store within this sandbox.
|
||||
*/
|
||||
public String getMainStoreName() { return store_names_[0]; }
|
||||
public String getMainStoreName();
|
||||
}
|
||||
|
104
source/java/org/alfresco/wcm/sandbox/SandboxInfoImpl.java
Normal file
104
source/java/org/alfresco/wcm/sandbox/SandboxInfoImpl.java
Normal file
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* 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.sandbox;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import org.alfresco.service.namespace.QName;
|
||||
|
||||
/**
|
||||
* Provides information about a WCM sandbox created by Sandbox Service/Factory
|
||||
*/
|
||||
public class SandboxInfoImpl implements SandboxInfo
|
||||
{
|
||||
private String wpStoreId;
|
||||
private String sbStoreId;
|
||||
private QName sandboxType;
|
||||
private String name;
|
||||
private String[] storeNames;
|
||||
private Date createdDate;
|
||||
private String creator;
|
||||
|
||||
/* package */ SandboxInfoImpl(String wpStoreId, String sbStoreId, QName sandboxType, String name, String[] storeNames, Date createdDate, String creator)
|
||||
{
|
||||
this.wpStoreId = wpStoreId;
|
||||
this.sbStoreId = sbStoreId;
|
||||
this.sandboxType = sandboxType;
|
||||
this.name = name;
|
||||
this.storeNames = storeNames;
|
||||
this.createdDate = createdDate;
|
||||
this.creator = creator;
|
||||
}
|
||||
|
||||
// note: currently derived - for author sandbox this is the username, for staging sandbox this is the sandbox id
|
||||
public String getName()
|
||||
{
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public String getWebProjectId()
|
||||
{
|
||||
return this.wpStoreId;
|
||||
}
|
||||
|
||||
public String getSandboxId()
|
||||
{
|
||||
return this.sbStoreId;
|
||||
}
|
||||
|
||||
public QName getSandboxType()
|
||||
{
|
||||
return this.sandboxType;
|
||||
}
|
||||
|
||||
public Date getCreatedDate()
|
||||
{
|
||||
return this.createdDate;
|
||||
}
|
||||
|
||||
public String getCreator()
|
||||
{
|
||||
return this.creator;
|
||||
}
|
||||
|
||||
/**
|
||||
* A list of names of the stores within this sandbox.
|
||||
* The "main" store should come first in this list;
|
||||
* any other stores should appear in the order that
|
||||
* they are overlaid on "main" (e.g.: any "preview"
|
||||
* layers should come afterward, in "lowest first" order).
|
||||
* <p>
|
||||
* Note: all sandboxes must have a "main" layer.
|
||||
*/
|
||||
public String [] getStoreNames() { return storeNames; }
|
||||
|
||||
/**
|
||||
* The name of the "main" store within this sandbox.
|
||||
*/
|
||||
public String getMainStoreName()
|
||||
{
|
||||
return storeNames[0];
|
||||
}
|
||||
}
|
308
source/java/org/alfresco/wcm/sandbox/SandboxService.java
Normal file
308
source/java/org/alfresco/wcm/sandbox/SandboxService.java
Normal file
@@ -0,0 +1,308 @@
|
||||
/*
|
||||
* 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.sandbox;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.alfresco.service.cmr.avm.AVMNodeDescriptor;
|
||||
import org.alfresco.service.cmr.avm.VersionDescriptor;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
|
||||
|
||||
/**
|
||||
* Sandbox Service fundamental API.
|
||||
* <p>
|
||||
* This service API is designed to support the public facing Sandbox APIs.
|
||||
*
|
||||
* @author janv
|
||||
*/
|
||||
public interface SandboxService
|
||||
{
|
||||
/**
|
||||
* Create author/user sandbox within a web project for the current user
|
||||
* <p>
|
||||
* If the author sandbox already exists for this web project then it will be returned
|
||||
*
|
||||
* @param wpStoreId web project store id
|
||||
* @return SandboxInfo the created user sandbox info
|
||||
*/
|
||||
public SandboxInfo createAuthorSandbox(String wpStoreId);
|
||||
|
||||
/**
|
||||
* Create author/user sandbox within a web project for the given user
|
||||
* <p>
|
||||
* If the author sandbox already exists for this web project then it will be returned
|
||||
* <p>
|
||||
* Current user must be a content manager for the web project
|
||||
*
|
||||
* @param wpStoreId web project store id
|
||||
* @param userName user name
|
||||
* @return SandboxInfo the created user sandbox info
|
||||
*/
|
||||
public SandboxInfo createAuthorSandbox(String wpStoreId, String userName);
|
||||
|
||||
/**
|
||||
* List the available sandboxes for the current user and given web project
|
||||
*
|
||||
* @param wpStoreId web project store id
|
||||
* @return List<SandboxInfo> list of sandbox info
|
||||
*/
|
||||
public List<SandboxInfo> listSandboxes(String wpStoreId);
|
||||
|
||||
/**
|
||||
* List the available sandboxes for the given user and web project
|
||||
* <p>
|
||||
* Current user must be a content manager for the web project
|
||||
*
|
||||
* @param wpStoreId web project store id
|
||||
* @param userName user name
|
||||
* @return List<SandboxInfo> list of sandbox info
|
||||
*/
|
||||
public List<SandboxInfo> listSandboxes(String wpStoreId, String userName);
|
||||
|
||||
/**
|
||||
* Return true if sandbox is visible to user and is of given type
|
||||
* <p>
|
||||
* eg. isSandboxType("test123--myusername", SandboxConstants.PROP_SANDBOX_AUTHOR_MAIN)
|
||||
*
|
||||
* @param sbStoreId sandbox store id
|
||||
* @param sandboxType sandbox type (see SandboxConstants)
|
||||
* @return boolean true, if sandbox exists with given type
|
||||
*/
|
||||
public boolean isSandboxType(String sbStoreId, QName sandboxType);
|
||||
|
||||
/**
|
||||
* Get sandbox info
|
||||
*
|
||||
* @param sbStoreId sandbox store id
|
||||
* @return SandboxInfo null if sandbox does not exist or is not visible to the current user
|
||||
*/
|
||||
public SandboxInfo getSandbox(String sbStoreId);
|
||||
|
||||
/**
|
||||
* Gets author/user sandbox info for the current user
|
||||
* <p>
|
||||
* Returns null if the author sandbox can not be found
|
||||
*
|
||||
* @param wpStoreId web project store id
|
||||
* @return SandboxInfo author sandbox info
|
||||
*/
|
||||
public SandboxInfo getAuthorSandbox(String wpStoreId);
|
||||
|
||||
/**
|
||||
* Gets author/user sandbox info for the given user
|
||||
* <p>
|
||||
* Returns null if the user sandbox can not be found
|
||||
* <p>
|
||||
* Current user must be a content manager for the web project
|
||||
*
|
||||
* @param wpStoreId web project store id
|
||||
* @param userName userName
|
||||
* @return SandboxInfo author sandbox info
|
||||
*/
|
||||
public SandboxInfo getAuthorSandbox(String wpStoreId, String userName);
|
||||
|
||||
/**
|
||||
* Gets staging sandbox info
|
||||
* <p>
|
||||
* Returns null if the staging sandbox can not be found
|
||||
*
|
||||
* @param wpStoreId web project store id
|
||||
* @return SandboxInfo staging sandbox info
|
||||
*/
|
||||
public SandboxInfo getStagingSandbox(String wpStoreId);
|
||||
|
||||
/**
|
||||
* Delete the sandbox
|
||||
* <p>
|
||||
* If the sandbox does not exist, will log a warning and succeed
|
||||
* <p>
|
||||
* Current user must be a content manager for the web project (associated with the sandbox)
|
||||
*
|
||||
* @param sbStoreId sandbox store id
|
||||
*/
|
||||
public void deleteSandbox(String sbStoreId);
|
||||
|
||||
/**
|
||||
* List changed items for given sandbox (eg. for user sandbox compared to staging sandbox)
|
||||
* <p>
|
||||
* Note: This will list new/modified/deleted items from the root directory and below, including all web apps
|
||||
*
|
||||
* @param sbStoreId sandbox store id
|
||||
* @param includeDeleted if true, include deleted items as well as new/modified items
|
||||
* @return List<AVMNodeDescriptor> list of changed items
|
||||
*/
|
||||
public List<AVMNodeDescriptor> listChangedItems(String sbStoreId, boolean includeDeleted);
|
||||
|
||||
/**
|
||||
* List changed items for given sandbox and web app (eg. in user sandbox)
|
||||
* <p>
|
||||
* Note: This will list new/modified/deleted items for the given web app
|
||||
*
|
||||
* @param sbStoreId sandbox store id
|
||||
* @param webApp web app to filter by
|
||||
* @param includeDeleted if true, include deleted items as well as new/modified items
|
||||
* @return List<AVMNodeDescriptor> list of changed items
|
||||
*/
|
||||
public List<AVMNodeDescriptor> listChangedItemsWebApp(String sbStoreId, String webApp, boolean includeDeleted);
|
||||
|
||||
/**
|
||||
* List changed items for given sandbox path (eg. between user sandbox and staging sandbox)
|
||||
* <p>
|
||||
* Note: This will list new/modified/deleted items from the directory and below. The destination path will be dervied.
|
||||
*
|
||||
* @param avmSrcPath source sandbox path (an AVM path)
|
||||
* @param includeDeleted if true, include deleted items as well as new/modified items
|
||||
* @return List<AVMNodeDescriptor> list of changed items
|
||||
*/
|
||||
public List<AVMNodeDescriptor> listChangedItemsDir(String avmSrcPath, boolean includeDeleted);
|
||||
|
||||
/**
|
||||
* List changed (new/modified/deleted) items between any two sandbox paths
|
||||
*
|
||||
* @param avmSrcPath source sandbox path (an AVM path)
|
||||
* @param avmDstPath destination sandbox path (an AVM path)
|
||||
* @param includeDeleted if true, include deleted items as well as new/modified items
|
||||
* @return List<AVMNodeDescriptor> list of changed items
|
||||
*/
|
||||
public List<AVMNodeDescriptor> listChangedItems(String avmSrcPath, String avmDstPath, boolean includeDeleted);
|
||||
|
||||
/**
|
||||
* Submit all changed items for given sandbox (eg. from user sandbox to staging sandbox)
|
||||
* <p>
|
||||
* Note: This will submit new/modified/deleted items from the root directory and below, including all web apps
|
||||
* <p>
|
||||
* @param sbStoreId sandbox store id
|
||||
*/
|
||||
public void submitAll(String sbStoreId, String submitLabel, String submitComment);
|
||||
|
||||
/**
|
||||
* Submit all changed items for given sandbox and web app (eg. in user sandbox)
|
||||
* <p>
|
||||
* Note: This will submit new/modified/deleted items for the given web app
|
||||
*
|
||||
* @param sbStoreId sandbox store id
|
||||
* @param webApp web app to filter by
|
||||
*/
|
||||
public void submitAllWebApp(String sbStoreId, String webApp, String submitLabel, String submitComment);
|
||||
|
||||
/**
|
||||
* Submit all changed items for given sandbox path (eg. in user sandbox)
|
||||
* <p>
|
||||
* Note: This will submit new/modified/deleted items from the directory and below
|
||||
*
|
||||
* @param avmDirectoryPath path to filter by
|
||||
*/
|
||||
public void submitAllDir(String avmDirectoryPath, String submitLabel, String submitComment);
|
||||
|
||||
/**
|
||||
* Submit list of changed items for given sandbox (eg. from user sandbox to staging sandbox)
|
||||
*
|
||||
* @param sbStoreId sandbox store id
|
||||
* @param items list of AVM node descriptors
|
||||
*/
|
||||
public void submitList(String sbStoreId, List<AVMNodeDescriptor> items, String submitLabel, String submitComment);
|
||||
|
||||
/**
|
||||
* Submit list of changed items for given sandbox (eg. from user sandbox to staging sandbox)
|
||||
*
|
||||
* @param sbStoreId sandbox store id
|
||||
* @param items list of AVM node descriptors
|
||||
* @param expirationDates map of <path, date> for those items set with an expiration date, or can be null (if no expiration dates)
|
||||
*/
|
||||
public void submitList(String sbStoreId, List<AVMNodeDescriptor> items, Map<String, Date> expirationDates, final String submitLabel, final String submitComment);
|
||||
|
||||
/**
|
||||
* Revert all changed items for given sandbox (eg. in user sandbox)
|
||||
* <p>
|
||||
* Note: This will revert new/modified/deleted items from the root directory and below, including all web apps
|
||||
*
|
||||
* @param sbStoreId sandbox store id
|
||||
*/
|
||||
public void revertAll(String sbStoreId);
|
||||
|
||||
/**
|
||||
* Revert all changed items for given sandbox and web app (eg. in user sandbox)
|
||||
* <p>
|
||||
* Note: This will revert new/modified/deleted items for the given web app
|
||||
*
|
||||
* @param sbStoreId sandbox store id
|
||||
* @param webApp web app to filter by
|
||||
*/
|
||||
public void revertAllWebApp(String sbStoreId, String webApp);
|
||||
|
||||
/**
|
||||
* Revert all changed items for given sandbox path (eg. in user sandbox)
|
||||
* <p>
|
||||
* Note: This will revert new/modified/deleted items from the directory and below
|
||||
*
|
||||
* @param avmDirectoryPath path to filter by
|
||||
*/
|
||||
public void revertAllDir(String avmDirectoryPath);
|
||||
|
||||
/**
|
||||
* Revert list of changed items for given sandbox (eg. in user sandbox)
|
||||
*
|
||||
* @param items list of AVM node descriptors
|
||||
*/
|
||||
public void revertList(String sbStoreId, List<AVMNodeDescriptor> items);
|
||||
|
||||
/**
|
||||
* Revert sandbox to a specific snapshot version ID (ie. for staging sandbox)
|
||||
* <p>
|
||||
* Current user must be a content manager for the web project
|
||||
*
|
||||
* @param sbStoreId staging sandbox store id
|
||||
* @param version version
|
||||
*/
|
||||
public void revertSnapshot(String sbStoreId, int version);
|
||||
|
||||
/**
|
||||
* List all snapshots (sandbox versions) for the given sandbox (ie. for staging sandbox)
|
||||
* <p>
|
||||
* Current user must be a content manager for the web project
|
||||
*
|
||||
* @param sbStoreId staging sandbox store id
|
||||
* @param includeSystemGenerated if false will ignore system generated snapshots else true to get all snapshots
|
||||
* @return List<VersionDescriptor> list of AVM version descriptors
|
||||
*/
|
||||
public List<VersionDescriptor> listSnapshots(String sbStoreId, boolean includeSystemGenerated);
|
||||
|
||||
/**
|
||||
* List snapshots (sandbox versions) for the given sandbox between given dates (ie. for staging sandbox)
|
||||
* <p>
|
||||
* Current user must be a content manager for the web project
|
||||
*
|
||||
* @param sbStoreId staging sandbox store id
|
||||
* @param from from date
|
||||
* @param to to date
|
||||
* @param includeSystemGenerated if false will ignore system generated snapshots else true to get all snapshots
|
||||
* @return List<VersionDescriptor> list of AVM version descriptors
|
||||
*/
|
||||
public List<VersionDescriptor> listSnapshots(String sbStoreId, Date from, Date to, boolean includeSystemGenerated);
|
||||
|
||||
}
|
858
source/java/org/alfresco/wcm/sandbox/SandboxServiceImpl.java
Normal file
858
source/java/org/alfresco/wcm/sandbox/SandboxServiceImpl.java
Normal file
@@ -0,0 +1,858 @@
|
||||
/*
|
||||
* 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.sandbox;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.mbeans.VirtServerRegistry;
|
||||
import org.alfresco.model.WCMAppModel;
|
||||
import org.alfresco.repo.avm.AVMDAOs;
|
||||
import org.alfresco.repo.avm.AVMNodeConverter;
|
||||
import org.alfresco.repo.avm.actions.AVMRevertStoreAction;
|
||||
import org.alfresco.repo.avm.actions.AVMUndoSandboxListAction;
|
||||
import org.alfresco.repo.domain.PropertyValue;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||
import org.alfresco.repo.security.permissions.AccessDeniedException;
|
||||
import org.alfresco.repo.transaction.AlfrescoTransactionSupport;
|
||||
import org.alfresco.repo.transaction.TransactionListenerAdapter;
|
||||
import org.alfresco.service.cmr.action.Action;
|
||||
import org.alfresco.service.cmr.action.ActionService;
|
||||
import org.alfresco.service.cmr.avm.AVMNodeDescriptor;
|
||||
import org.alfresco.service.cmr.avm.AVMService;
|
||||
import org.alfresco.service.cmr.avm.VersionDescriptor;
|
||||
import org.alfresco.service.cmr.avm.locking.AVMLockingService;
|
||||
import org.alfresco.service.cmr.avmsync.AVMDifference;
|
||||
import org.alfresco.service.cmr.avmsync.AVMSyncService;
|
||||
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.workflow.WorkflowService;
|
||||
import org.alfresco.service.cmr.workflow.WorkflowTask;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.util.NameMatcher;
|
||||
import org.alfresco.util.Pair;
|
||||
import org.alfresco.util.ParameterCheck;
|
||||
import org.alfresco.util.VirtServerUtils;
|
||||
import org.alfresco.wcm.util.WCMUtil;
|
||||
import org.alfresco.wcm.util.WCMWorkflowUtil;
|
||||
import org.alfresco.wcm.webproject.WebProjectInfo;
|
||||
import org.alfresco.wcm.webproject.WebProjectService;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
|
||||
/**
|
||||
* Sandbox Service fundamental API.
|
||||
* <p>
|
||||
* This service API is designed to support the public facing Sandbox APIs.
|
||||
*
|
||||
* @author janv
|
||||
*/
|
||||
public class SandboxServiceImpl extends WCMUtil implements SandboxService
|
||||
{
|
||||
/** Logger */
|
||||
private static Log logger = LogFactory.getLog(SandboxServiceImpl.class);
|
||||
|
||||
private WebProjectService wpService;
|
||||
private SandboxFactory sandboxFactory;
|
||||
private AVMService avmService;
|
||||
private AVMLockingService avmLockingService;
|
||||
private AVMSyncService avmSyncService;
|
||||
private NameMatcher nameMatcher;
|
||||
private VirtServerRegistry virtServerRegistry;
|
||||
private ActionService actionService;
|
||||
private WorkflowService workflowService;
|
||||
|
||||
public void setWebProjectService(WebProjectService wpService)
|
||||
{
|
||||
this.wpService = wpService;
|
||||
}
|
||||
|
||||
public void setSandboxFactory(SandboxFactory sandboxFactory)
|
||||
{
|
||||
this.sandboxFactory = sandboxFactory;
|
||||
}
|
||||
|
||||
public void setAvmService(AVMService avmService)
|
||||
{
|
||||
this.avmService = avmService;
|
||||
}
|
||||
|
||||
public void setAvmLockingService(AVMLockingService avmLockingService)
|
||||
{
|
||||
this.avmLockingService = avmLockingService;
|
||||
}
|
||||
|
||||
public void setAvmSyncService(AVMSyncService avmSyncService)
|
||||
{
|
||||
this.avmSyncService = avmSyncService;
|
||||
}
|
||||
|
||||
public void setNameMatcher(NameMatcher nameMatcher)
|
||||
{
|
||||
this.nameMatcher = nameMatcher;
|
||||
}
|
||||
|
||||
public void setVirtServerRegistry(VirtServerRegistry virtServerRegistry)
|
||||
{
|
||||
this.virtServerRegistry = virtServerRegistry;
|
||||
}
|
||||
|
||||
public void setActionService(ActionService actionService)
|
||||
{
|
||||
this.actionService = actionService;
|
||||
}
|
||||
|
||||
public void setWorkflowService(WorkflowService workflowService)
|
||||
{
|
||||
this.workflowService = workflowService;
|
||||
}
|
||||
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.wcm.sandbox.SandboxService#createAuthorSandbox(java.lang.String)
|
||||
*/
|
||||
public SandboxInfo createAuthorSandbox(String wpStoreId)
|
||||
{
|
||||
ParameterCheck.mandatoryString("wpStoreId", wpStoreId);
|
||||
|
||||
String currentUserName = AuthenticationUtil.getCurrentEffectiveUserName();
|
||||
SandboxInfo sbInfo = null;
|
||||
|
||||
if (! wpService.isWebUser(wpStoreId, currentUserName))
|
||||
{
|
||||
throw new AccessDeniedException("Only web project users may create their own (author) sandbox for '"+currentUserName+"' (store id: "+wpStoreId+")");
|
||||
}
|
||||
else
|
||||
{
|
||||
sbInfo = createAuthorSandboxImpl(wpStoreId, currentUserName);
|
||||
}
|
||||
|
||||
return sbInfo;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.wcm.sandbox.SandboxService#createAuthorSandbox(java.lang.String, java.lang.String)
|
||||
*/
|
||||
public SandboxInfo createAuthorSandbox(String wpStoreId, String userName)
|
||||
{
|
||||
ParameterCheck.mandatoryString("wpStoreId", wpStoreId);
|
||||
ParameterCheck.mandatoryString("userName", userName);
|
||||
|
||||
// is the current user a content manager for this web project ?
|
||||
if (! wpService.isContentManager(wpStoreId))
|
||||
{
|
||||
throw new AccessDeniedException("Only content managers may create author sandbox for '"+userName+"' (store id: "+wpStoreId+")");
|
||||
}
|
||||
|
||||
return createAuthorSandboxImpl(wpStoreId, userName);
|
||||
}
|
||||
|
||||
private SandboxInfo createAuthorSandboxImpl(String wpStoreId, String userName)
|
||||
{
|
||||
WebProjectInfo wpInfo = wpService.getWebProject(wpStoreId);
|
||||
|
||||
final NodeRef wpNodeRef = wpInfo.getNodeRef();
|
||||
final List<String> managers = new ArrayList<String>(4);
|
||||
|
||||
AuthenticationUtil.runAs(new AuthenticationUtil.RunAsWork<Object>()
|
||||
{
|
||||
public Object doWork() throws Exception
|
||||
{
|
||||
// retrieve the list of managers from the existing users
|
||||
Map<String, String> existingUserRoles = wpService.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);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}, AuthenticationUtil.getSystemUserName());
|
||||
|
||||
String role = wpService.getWebUserRole(wpNodeRef, userName);
|
||||
SandboxInfo sbInfo = sandboxFactory.createUserSandbox(wpStoreId, managers, userName, 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, wpService.listWebApps(wpNodeRef));
|
||||
AlfrescoTransactionSupport.bindListener(tl);
|
||||
|
||||
if (logger.isInfoEnabled())
|
||||
{
|
||||
logger.info("Created author sandbox: " + sbInfo.getSandboxId() + " (web project id: " + wpStoreId + ")");
|
||||
}
|
||||
|
||||
return sbInfo;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.wcm.sandbox.SandboxService#listSandboxes(java.lang.String)
|
||||
*/
|
||||
public List<SandboxInfo> listSandboxes(String wpStoreId)
|
||||
{
|
||||
ParameterCheck.mandatoryString("wpStoreId", wpStoreId);
|
||||
|
||||
return sandboxFactory.listSandboxes(wpStoreId, AuthenticationUtil.getCurrentEffectiveUserName());
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.wcm.sandbox.SandboxService#listSandboxes(java.lang.String, java.lang.String)
|
||||
*/
|
||||
public List<SandboxInfo> listSandboxes(final String wpStoreId, String userName)
|
||||
{
|
||||
ParameterCheck.mandatoryString("wpStoreId", wpStoreId);
|
||||
ParameterCheck.mandatoryString("userName", userName);
|
||||
|
||||
if (! wpService.isContentManager(wpStoreId))
|
||||
{
|
||||
throw new AccessDeniedException("Only content managers may list sandboxes for '"+userName+"' (web project id: "+wpStoreId+")");
|
||||
}
|
||||
|
||||
return sandboxFactory.listSandboxes(wpStoreId, userName);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.wcm.sandbox.SandboxService#isSandboxType(java.lang.String, org.alfresco.service.namespace.QName)
|
||||
*/
|
||||
public boolean isSandboxType(String sbStoreId, QName sandboxType)
|
||||
{
|
||||
ParameterCheck.mandatoryString("sbStoreId", sbStoreId);
|
||||
ParameterCheck.mandatory("sandboxType", sandboxType);
|
||||
|
||||
SandboxInfo sbInfo = sandboxFactory.getSandbox(sbStoreId);
|
||||
if (sbInfo != null)
|
||||
{
|
||||
return sbInfo.getSandboxType().equals(sandboxType);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.wcm.sandbox.SandboxService#getSandbox(java.lang.String)
|
||||
*/
|
||||
public SandboxInfo getSandbox(String sbStoreId)
|
||||
{
|
||||
ParameterCheck.mandatoryString("sbStoreId", sbStoreId);
|
||||
|
||||
return sandboxFactory.getSandbox(sbStoreId);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.wcm.sandbox.SandboxService#getAuthorSandbox(java.lang.String)
|
||||
*/
|
||||
public SandboxInfo getAuthorSandbox(String wpStoreId)
|
||||
{
|
||||
ParameterCheck.mandatoryString("wpStoreId", wpStoreId);
|
||||
|
||||
String currentUserName = AuthenticationUtil.getCurrentEffectiveUserName();
|
||||
return getSandbox(WCMUtil.buildUserMainStoreName(WCMUtil.buildStagingStoreName(wpStoreId), currentUserName));
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.wcm.sandbox.SandboxService#getUserSandbox(java.lang.String, java.lang.String)
|
||||
*/
|
||||
public SandboxInfo getAuthorSandbox(String wpStoreId, String userName)
|
||||
{
|
||||
ParameterCheck.mandatoryString("wpStoreId", wpStoreId);
|
||||
ParameterCheck.mandatoryString("userName", userName);
|
||||
|
||||
if (! wpService.isContentManager(wpStoreId))
|
||||
{
|
||||
throw new AccessDeniedException("Only content managers may get author sandbox for '"+userName+"' (web project id: "+wpStoreId+")");
|
||||
}
|
||||
|
||||
return getSandbox(WCMUtil.buildUserMainStoreName(WCMUtil.buildStagingStoreName(wpStoreId), userName));
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.wcm.sandbox.SandboxService#getStagingSandbox(java.lang.String)
|
||||
*/
|
||||
public SandboxInfo getStagingSandbox(String wpStoreId)
|
||||
{
|
||||
ParameterCheck.mandatoryString("wpStoreId", wpStoreId);
|
||||
|
||||
return getSandbox(WCMUtil.buildStagingStoreName(wpStoreId));
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.wcm.sandbox.SandboxService#deleteSandbox(java.lang.String)
|
||||
*/
|
||||
public void deleteSandbox(String sbStoreId)
|
||||
{
|
||||
ParameterCheck.mandatoryString("sbStoreId", sbStoreId);
|
||||
|
||||
String wpStoreId = WCMUtil.getWebProjectStoreId(sbStoreId);
|
||||
|
||||
String currentUserName = AuthenticationUtil.getCurrentEffectiveUserName();
|
||||
if (sbStoreId.equals(WCMUtil.buildUserMainStoreName(wpStoreId, currentUserName)))
|
||||
{
|
||||
// author may delete their own sandbox
|
||||
sandboxFactory.deleteSandbox(sbStoreId);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (! wpService.isContentManager(wpStoreId))
|
||||
{
|
||||
throw new AccessDeniedException("Only content managers may delete sandbox '"+sbStoreId+"' (web project id: "+wpStoreId+")");
|
||||
}
|
||||
|
||||
if (sbStoreId.equals(wpStoreId))
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Cannot delete staging sandbox '"+sbStoreId+"' (web project id: "+wpStoreId+")");
|
||||
}
|
||||
|
||||
// content manager may delete sandboxes, except staging sandbox
|
||||
sandboxFactory.deleteSandbox(sbStoreId);
|
||||
}
|
||||
|
||||
if (logger.isInfoEnabled())
|
||||
{
|
||||
logger.info("Deleted sandbox: " + sbStoreId + " (web project id: " + wpStoreId + ")");
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.wcm.sandbox.SandboxService#listChangedItems(java.lang.String, boolean)
|
||||
*/
|
||||
public List<AVMNodeDescriptor> listChangedItems(String sbStoreId, boolean includeDeleted)
|
||||
{
|
||||
ParameterCheck.mandatoryString("sbStoreId", sbStoreId);
|
||||
|
||||
// no filtering
|
||||
String avmDirectoryPath = sbStoreId+":/";
|
||||
return listChangedItemsDir(avmDirectoryPath, includeDeleted);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.wcm.sandbox.SandboxService#listChangedItemsWebApp(java.lang.String, java.lang.String, boolean)
|
||||
*/
|
||||
public List<AVMNodeDescriptor> listChangedItemsWebApp(String sbStoreId, String webApp, boolean includeDeleted)
|
||||
{
|
||||
ParameterCheck.mandatoryString("sbStoreId", sbStoreId);
|
||||
ParameterCheck.mandatoryString("webApp", webApp);
|
||||
|
||||
// filter by current webapp
|
||||
String avmDirectoryPath = WCMUtil.buildStoreWebappPath(sbStoreId, webApp);
|
||||
return listChangedItemsDir(avmDirectoryPath, includeDeleted);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.wcm.sandbox.SandboxService#listChangedItemsDir(java.lang.String, boolean)
|
||||
*/
|
||||
public List<AVMNodeDescriptor> listChangedItemsDir(String avmDirectoryPath, boolean includeDeleted)
|
||||
{
|
||||
ParameterCheck.mandatoryString("avmDirectoryPath", avmDirectoryPath);
|
||||
|
||||
String sandboxId = WCMUtil.getSandboxStoreId(avmDirectoryPath);
|
||||
|
||||
// TODO - allow list for any sandbox
|
||||
if (! WCMUtil.isUserStore(sandboxId))
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Not an author sandbox: "+sandboxId);
|
||||
}
|
||||
|
||||
// build the paths to the stores to compare - filter by given directory path
|
||||
String wpStoreId = WCMUtil.getWebProjectStoreId(sandboxId);
|
||||
String stagingSandboxId = WCMUtil.buildStagingStoreName(wpStoreId);
|
||||
|
||||
String relativePath = WCMUtil.getStoreRelativePath(avmDirectoryPath);
|
||||
|
||||
String srcPath = sandboxId + AVM_STORE_SEPARATOR + relativePath;
|
||||
String dstPath = stagingSandboxId + AVM_STORE_SEPARATOR + relativePath;
|
||||
|
||||
return listChangedItems(srcPath, dstPath, includeDeleted);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.wcm.sandbox.SandboxService#listChangedItems(java.lang.String, java.lang.String, boolean)
|
||||
*/
|
||||
public List<AVMNodeDescriptor> listChangedItems(String avmSrcPath, String avmDstPath, boolean includeDeleted)
|
||||
{
|
||||
return listChangedItems(-1, avmSrcPath, -1, avmDstPath, includeDeleted);
|
||||
}
|
||||
|
||||
private List<AVMNodeDescriptor> listChangedItems(int srcVersion, String srcPath, int dstVersion, String dstPath, boolean includeDeleted)
|
||||
{
|
||||
ParameterCheck.mandatoryString("srcPath", srcPath);
|
||||
ParameterCheck.mandatoryString("dstPath", dstPath);
|
||||
|
||||
long start = System.currentTimeMillis();
|
||||
|
||||
List<AVMDifference> diffs = avmSyncService.compare(srcVersion, srcPath, dstVersion, dstPath, nameMatcher);
|
||||
|
||||
List<AVMNodeDescriptor> items = new ArrayList<AVMNodeDescriptor>(diffs.size());
|
||||
|
||||
for (AVMDifference diff : diffs)
|
||||
{
|
||||
// convert each diff record into an AVM node descriptor
|
||||
String sourcePath = diff.getSourcePath();
|
||||
AVMNodeDescriptor node = avmService.lookup(-1, sourcePath, includeDeleted);
|
||||
if (node != null)
|
||||
{
|
||||
items.add(node);
|
||||
}
|
||||
}
|
||||
|
||||
if (logger.isTraceEnabled())
|
||||
{
|
||||
logger.trace("listModifiedItems: "+items.size()+" items in "+(System.currentTimeMillis()-start)+" ms (between "+srcVersion+","+srcPath+" and "+dstVersion+","+dstPath);
|
||||
}
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.wcm.sandbox.SandboxService#submitAll(java.lang.String, java.lang.String, java.lang.String)
|
||||
*/
|
||||
public void submitAll(String sbStoreId, String submitLabel, String submitComment)
|
||||
{
|
||||
ParameterCheck.mandatoryString("sbStoreId", sbStoreId);
|
||||
|
||||
String avmDirectoryPath = sbStoreId+":/";
|
||||
submitAllDir(avmDirectoryPath, submitLabel, submitComment);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.wcm.sandbox.SandboxService#submitAllWebApp(java.lang.String, java.lang.String, java.lang.String, java.lang.String)
|
||||
*/
|
||||
public void submitAllWebApp(String sbStoreId, String webApp, String submitLabel, String submitComment)
|
||||
{
|
||||
ParameterCheck.mandatoryString("sbStoreId", sbStoreId);
|
||||
ParameterCheck.mandatoryString("webApp", webApp);
|
||||
|
||||
String avmDirectoryPath = WCMUtil.buildStoreWebappPath(sbStoreId, webApp);
|
||||
submitAllDir(avmDirectoryPath, submitLabel, submitComment);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.wcm.sandbox.SandboxService#submitAllDir(java.lang.String, java.lang.String, java.lang.String)
|
||||
*/
|
||||
public void submitAllDir(String avmDirectoryPath, String submitLabel, String submitComment)
|
||||
{
|
||||
ParameterCheck.mandatoryString("avmDirectoryPath", avmDirectoryPath);
|
||||
|
||||
String sbStoreId = WCMUtil.getSandboxStoreId(avmDirectoryPath);
|
||||
|
||||
List<AVMNodeDescriptor> items = listChangedItemsDir(avmDirectoryPath, true);
|
||||
|
||||
submitList(sbStoreId, items, submitLabel, submitComment);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.wcm.sandbox.SandboxService#submitList(java.lang.String, java.util.List, java.lang.String, java.lang.String)
|
||||
*/
|
||||
public void submitList(String sbStoreId, List<AVMNodeDescriptor> items, final String submitLabel, final String submitComment)
|
||||
{
|
||||
submitList(sbStoreId, items, null, submitLabel, submitComment);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.wcm.sandbox.SandboxService#submitList(java.lang.String, java.util.List, java.util.Map, java.lang.String, java.lang.String)
|
||||
*/
|
||||
public void submitList(String sbStoreId, List<AVMNodeDescriptor> items, Map<String, Date> expirationDates, final String submitLabel, final String submitComment)
|
||||
{
|
||||
ParameterCheck.mandatoryString("sbStoreId", sbStoreId);
|
||||
|
||||
// direct submit to the staging area (without workflow)
|
||||
|
||||
// TODO - consider submit to higher-level sandbox, not just to staging
|
||||
if (! WCMUtil.isUserStore(sbStoreId))
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Not an author sandbox: "+sbStoreId);
|
||||
}
|
||||
|
||||
// construct diffs for selected items for submission
|
||||
String wpStoreId = WCMUtil.getWebProjectStoreId(sbStoreId);
|
||||
String stagingSandboxId = WCMUtil.buildStagingStoreName(wpStoreId);
|
||||
|
||||
final List<AVMDifference> diffs = new ArrayList<AVMDifference>(items.size());
|
||||
|
||||
for (AVMNodeDescriptor item : items)
|
||||
{
|
||||
String relativePath = WCMUtil.getStoreRelativePath(item.getPath());
|
||||
|
||||
String srcPath = sbStoreId + AVM_STORE_SEPARATOR + relativePath;
|
||||
String dstPath = stagingSandboxId + AVM_STORE_SEPARATOR + relativePath;
|
||||
|
||||
AVMDifference diff = new AVMDifference(-1, srcPath, -1, dstPath, AVMDifference.NEWER);
|
||||
diffs.add(diff);
|
||||
|
||||
if (expirationDates != null)
|
||||
{
|
||||
// process the expiration date (if any)
|
||||
processExpirationDate(srcPath, expirationDates);
|
||||
}
|
||||
|
||||
// recursively remove locks from this item
|
||||
recursivelyRemoveLocks(wpStoreId, -1, avmService.lookup(-1, srcPath, true), srcPath);
|
||||
|
||||
// check to see if destPath forces a notification of the virtualization server
|
||||
// (e.g.: it might be a path to a jar file within WEB-INF/lib).
|
||||
if (VirtServerUtils.requiresUpdateNotification(dstPath))
|
||||
{
|
||||
// Bind the post-commit transaction listener with data required for virtualization server notification
|
||||
UpdateSandboxTransactionListener tl = new UpdateSandboxTransactionListener(dstPath);
|
||||
AlfrescoTransactionSupport.bindListener(tl);
|
||||
}
|
||||
}
|
||||
|
||||
// write changes to layer so files are marked as modified
|
||||
|
||||
// Submit is done as system as the staging store is read only
|
||||
// We could add support to runIgnoringStoreACls
|
||||
|
||||
// TODO review flatten - assumes webapps, hence currently flattens at /www/avm_webapps level
|
||||
// also review flatten for SimpleAVMSubmitAction and AVMSubmitAction
|
||||
final String sandboxPath = WCMUtil.buildSandboxRootPath(sbStoreId);
|
||||
final String stagingPath = WCMUtil.buildSandboxRootPath(stagingSandboxId);
|
||||
|
||||
AuthenticationUtil.runAs(new AuthenticationUtil.RunAsWork<Object>()
|
||||
{
|
||||
public Object doWork() throws Exception
|
||||
{
|
||||
avmSyncService.update(diffs, null, true, true, false, false, submitLabel, submitComment);
|
||||
AVMDAOs.Instance().fAVMNodeDAO.flush();
|
||||
avmSyncService.flatten(sandboxPath, stagingPath);
|
||||
return null;
|
||||
}
|
||||
}, AuthenticationUtil.getSystemUserName());
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.wcm.sandbox.SandboxService#revertAll(java.lang.String, java.lang.String)
|
||||
*/
|
||||
public void revertAll(String sbStoreId)
|
||||
{
|
||||
ParameterCheck.mandatoryString("sbStoreId", sbStoreId);
|
||||
|
||||
String avmDirectoryPath = sbStoreId+":/";
|
||||
revertAllDir(avmDirectoryPath);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.wcm.sandbox.SandboxService#revertAll(java.lang.String, java.lang.String)
|
||||
*/
|
||||
public void revertAllWebApp(String sbStoreId, String webApp)
|
||||
{
|
||||
ParameterCheck.mandatoryString("sbStoreId", sbStoreId);
|
||||
ParameterCheck.mandatoryString("webApp", webApp);
|
||||
|
||||
String avmDirectoryPath = WCMUtil.buildStoreWebappPath(sbStoreId, webApp);
|
||||
revertAllDir(avmDirectoryPath);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.wcm.sandbox.SandboxService#revertAll(java.lang.String)
|
||||
*/
|
||||
public void revertAllDir(String avmDirectoryPath)
|
||||
{
|
||||
ParameterCheck.mandatoryString("avmDirectoryPath", avmDirectoryPath);
|
||||
|
||||
String sbStoreId = WCMUtil.getSandboxStoreId(avmDirectoryPath);
|
||||
|
||||
List<AVMNodeDescriptor> items = listChangedItemsDir(avmDirectoryPath, true);
|
||||
|
||||
revertList(sbStoreId, items);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.wcm.sandbox.SandboxService#revertList(java.lang.String, java.lang.String, java.util.List)
|
||||
*/
|
||||
public void revertList(String sbStoreId, List<AVMNodeDescriptor> items)
|
||||
{
|
||||
ParameterCheck.mandatoryString("sbStoreId", sbStoreId);
|
||||
|
||||
List<Pair<Integer, String>> versionPaths = new ArrayList<Pair<Integer, String>>(items.size());
|
||||
|
||||
List<WorkflowTask> tasks = null;
|
||||
for (AVMNodeDescriptor node : items)
|
||||
{
|
||||
if (tasks == null)
|
||||
{
|
||||
tasks = WCMWorkflowUtil.getAssociatedTasksForSandbox(workflowService, WCMUtil.getSandboxStoreId(node.getPath()));
|
||||
}
|
||||
if (WCMWorkflowUtil.getAssociatedTasksForNode(avmService, node, tasks).size() == 0)
|
||||
{
|
||||
String revertPath = node.getPath();
|
||||
versionPaths.add(new Pair<Integer, String>(-1, revertPath));
|
||||
|
||||
if (VirtServerUtils.requiresUpdateNotification(revertPath))
|
||||
{
|
||||
// Bind the post-commit transaction listener with data required for virtualization server notification
|
||||
UpdateSandboxTransactionListener tl = new UpdateSandboxTransactionListener(revertPath);
|
||||
AlfrescoTransactionSupport.bindListener(tl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Map<String, Serializable> args = new HashMap<String, Serializable>(1, 1.0f);
|
||||
args.put(AVMUndoSandboxListAction.PARAM_NODE_LIST, (Serializable)versionPaths);
|
||||
Action action = actionService.createAction(AVMUndoSandboxListAction.NAME, args);
|
||||
actionService.executeAction(action, null); // dummy action ref, list passed as action arg
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.wcm.sandbox.SandboxService#listSnapshots(java.lang.String, boolean)
|
||||
*/
|
||||
public List<VersionDescriptor> listSnapshots(String sbStoreId, boolean includeSystemGenerated)
|
||||
{
|
||||
ParameterCheck.mandatoryString("sbStoreId", sbStoreId);
|
||||
|
||||
String wpStoreId = WCMUtil.getWebProjectStoreId(sbStoreId);
|
||||
if (! wpService.isContentManager(wpStoreId))
|
||||
{
|
||||
throw new AccessDeniedException("Only content managers may list snapshots '"+sbStoreId+"' (web project id: "+wpStoreId+")");
|
||||
}
|
||||
|
||||
List<VersionDescriptor> allVersions = avmService.getStoreVersions(sbStoreId);
|
||||
return listSnapshots(allVersions, includeSystemGenerated);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.wcm.sandbox.SandboxService#listSnapshots(java.lang.String, java.util.Date, java.util.Date, boolean)
|
||||
*/
|
||||
public List<VersionDescriptor> listSnapshots(String sbStoreId, Date from, Date to, boolean includeSystemGenerated)
|
||||
{
|
||||
ParameterCheck.mandatoryString("sbStoreId", sbStoreId);
|
||||
|
||||
String wpStoreId = WCMUtil.getWebProjectStoreId(sbStoreId);
|
||||
if (! wpService.isContentManager(wpStoreId))
|
||||
{
|
||||
throw new AccessDeniedException("Only content managers may list snapshots '"+sbStoreId+"' (web project id: "+wpStoreId+")");
|
||||
}
|
||||
|
||||
List<VersionDescriptor> versionsToFilter = avmService.getStoreVersions(sbStoreId, from, to);
|
||||
return listSnapshots(versionsToFilter, includeSystemGenerated);
|
||||
}
|
||||
|
||||
private List<VersionDescriptor> listSnapshots(List<VersionDescriptor> versionsToFilter, boolean includeSystemGenerated)
|
||||
{
|
||||
List<VersionDescriptor> versions = new ArrayList<VersionDescriptor>(versionsToFilter.size());
|
||||
|
||||
for (int i = versionsToFilter.size() - 1; i >= 0; i--) // reverse order
|
||||
{
|
||||
VersionDescriptor item = versionsToFilter.get(i);
|
||||
|
||||
// only display snapshots with a valid tag - others are system generated snapshots
|
||||
if ((includeSystemGenerated == true) || ((item.getTag() != null) && (item.getVersionID() != 0)))
|
||||
{
|
||||
versions.add(item);
|
||||
}
|
||||
}
|
||||
|
||||
return versions;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.wcm.sandbox.SandboxService#revertSnapshot(java.lang.String, int)
|
||||
*/
|
||||
public void revertSnapshot(final String sbStoreId, final int version)
|
||||
{
|
||||
ParameterCheck.mandatoryString("sbStoreId", sbStoreId);
|
||||
|
||||
String wpStoreId = WCMUtil.getWebProjectStoreId(sbStoreId);
|
||||
if (! wpService.isContentManager(wpStoreId))
|
||||
{
|
||||
throw new AccessDeniedException("Only content managers may revert staging sandbox '"+sbStoreId+"' (web project id: "+wpStoreId+")");
|
||||
}
|
||||
|
||||
// do this as system as the staging area has restricted access (and content manager may not have permission to delete children, for example)
|
||||
List<AVMDifference> diffs = AuthenticationUtil.runAs(new AuthenticationUtil.RunAsWork<List<AVMDifference>>()
|
||||
{
|
||||
public List<AVMDifference> doWork() throws Exception
|
||||
{
|
||||
String sandboxPath = WCMUtil.buildSandboxRootPath(sbStoreId);
|
||||
|
||||
List<AVMDifference> diffs = avmSyncService.compare(-1, sandboxPath, version, sandboxPath, null);
|
||||
|
||||
Map<String, Serializable> args = new HashMap<String, Serializable>(1, 1.0f);
|
||||
args.put(AVMRevertStoreAction.PARAM_VERSION, version);
|
||||
Action action = actionService.createAction(AVMRevertStoreAction.NAME, args);
|
||||
actionService.executeAction(action, AVMNodeConverter.ToNodeRef(-1, sbStoreId + AVM_STORE_SEPARATOR + "/"));
|
||||
return diffs;
|
||||
}
|
||||
}, AuthenticationUtil.getSystemUserName());
|
||||
|
||||
// See if any of the files being reverted require notification of the virt server, to update the webapp
|
||||
for (AVMDifference diff : diffs)
|
||||
{
|
||||
if (VirtServerUtils.requiresUpdateNotification(diff.getSourcePath()))
|
||||
{
|
||||
// Bind the post-commit transaction listener with data required for virtualization server notification
|
||||
UpdateSandboxTransactionListener tl = new UpdateSandboxTransactionListener(diff.getSourcePath());
|
||||
AlfrescoTransactionSupport.bindListener(tl);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up the expiration date for the given source path
|
||||
*
|
||||
* @param srcPath The path to set the expiration date for
|
||||
*/
|
||||
private void processExpirationDate(String srcPath, Map<String, Date> expirationDates)
|
||||
{
|
||||
// if an expiration date has been set for this item we need to
|
||||
// add the expires aspect and the date supplied
|
||||
Date expirationDate = expirationDates.get(srcPath);
|
||||
if (expirationDate == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// make sure the aspect is present
|
||||
if (avmService.hasAspect(-1, srcPath, WCMAppModel.ASPECT_EXPIRES) == false)
|
||||
{
|
||||
avmService.addAspect(srcPath, WCMAppModel.ASPECT_EXPIRES);
|
||||
}
|
||||
|
||||
// set the expiration date
|
||||
avmService.setNodeProperty(srcPath, WCMAppModel.PROP_EXPIRATIONDATE,
|
||||
new PropertyValue(DataTypeDefinition.DATETIME, expirationDate));
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("Set expiration date of " + expirationDate + " for " + srcPath);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively remove locks from a path. Walking child folders looking for files
|
||||
* to remove locks from.
|
||||
*/
|
||||
private void recursivelyRemoveLocks(String wpStoreId, int version, AVMNodeDescriptor desc, String absoluteAVMPath)
|
||||
{
|
||||
if (desc.isFile() || desc.isDeletedFile())
|
||||
{
|
||||
avmLockingService.removeLock(wpStoreId, WCMUtil.getStoreRelativePath(absoluteAVMPath));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (desc.isDeletedDirectory())
|
||||
{
|
||||
// lookup the previous child and get its contents
|
||||
final List<AVMNodeDescriptor> history = avmService.getHistory(desc, 2);
|
||||
if (history.size() <= 1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
desc = history.get(1);
|
||||
}
|
||||
|
||||
Map<String, AVMNodeDescriptor> list = avmService.getDirectoryListingDirect(desc, true);
|
||||
for (Map.Entry<String, AVMNodeDescriptor> child : list.entrySet())
|
||||
{
|
||||
String name = child.getKey();
|
||||
AVMNodeDescriptor childDesc = child.getValue();
|
||||
recursivelyRemoveLocks(wpStoreId, version, childDesc, absoluteAVMPath + "/" + name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update Sandbox Transaction listener - invoked after submit or revert
|
||||
*/
|
||||
private class UpdateSandboxTransactionListener extends TransactionListenerAdapter
|
||||
{
|
||||
private String virtUpdatePath;
|
||||
|
||||
public UpdateSandboxTransactionListener(String virtUpdatePath)
|
||||
{
|
||||
this.virtUpdatePath = virtUpdatePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.repo.transaction.TransactionListenerAdapter#afterCommit()
|
||||
*/
|
||||
@Override
|
||||
public void afterCommit()
|
||||
{
|
||||
// The virtualization server might need to be notified
|
||||
// because one or more of the files submitted / reverted could alter
|
||||
// the behavior the virtual webapp in the target of the submit.
|
||||
// For example, the user might be submitting a new jar or web.xml file.
|
||||
//
|
||||
// This must take place after the transaction has been completed;
|
||||
|
||||
// force an update of the virt server if necessary
|
||||
if (this.virtUpdatePath != null)
|
||||
{
|
||||
WCMUtil.updateVServerWebapp(virtServerRegistry, this.virtUpdatePath, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
1523
source/java/org/alfresco/wcm/sandbox/SandboxServiceImplTest.java
Normal file
1523
source/java/org/alfresco/wcm/sandbox/SandboxServiceImplTest.java
Normal file
File diff suppressed because it is too large
Load Diff
116
source/java/org/alfresco/wcm/sandbox/script/Asset.java
Normal file
116
source/java/org/alfresco/wcm/sandbox/script/Asset.java
Normal file
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2007 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.sandbox.script;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import org.alfresco.service.cmr.avm.AVMNodeDescriptor;
|
||||
import org.alfresco.util.ISO8601DateFormat;
|
||||
|
||||
/**
|
||||
* Asset in a sandbox exposed over Java Script API.
|
||||
* @author mrogers
|
||||
*
|
||||
*/
|
||||
public class Asset
|
||||
{
|
||||
private AVMNodeDescriptor desc;
|
||||
private Sandbox sandbox;
|
||||
|
||||
public Asset(Sandbox sandbox, AVMNodeDescriptor desc)
|
||||
{
|
||||
this.sandbox = sandbox;
|
||||
this.desc = desc;
|
||||
}
|
||||
|
||||
public String getCreator()
|
||||
{
|
||||
return desc.getCreator();
|
||||
}
|
||||
|
||||
public Date getCreatedDate()
|
||||
{
|
||||
return new Date(desc.getCreateDate());
|
||||
}
|
||||
|
||||
public String getCreatedDateAsISO8601()
|
||||
{
|
||||
return ISO8601DateFormat.format(getCreatedDate());
|
||||
}
|
||||
|
||||
public String getModifier()
|
||||
{
|
||||
return desc.getLastModifier();
|
||||
}
|
||||
|
||||
public Date getModifiedDate()
|
||||
{
|
||||
return new Date(desc.getModDate());
|
||||
}
|
||||
|
||||
public String getModifiedDateAsISO8601()
|
||||
{
|
||||
return ISO8601DateFormat.format(getModifiedDate());
|
||||
}
|
||||
|
||||
public String getAssetRef()
|
||||
{
|
||||
return desc.getGuid();
|
||||
}
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return desc.getName();
|
||||
}
|
||||
|
||||
public String getPath()
|
||||
{
|
||||
return desc.getPath();
|
||||
}
|
||||
|
||||
public boolean isFile()
|
||||
{
|
||||
return desc.isFile();
|
||||
}
|
||||
|
||||
public boolean isDirectory()
|
||||
{
|
||||
return desc.isDirectory();
|
||||
}
|
||||
|
||||
public boolean isDeleted()
|
||||
{
|
||||
return desc.isDeleted();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the parent sandbox which contains this asset
|
||||
* @return the parent sandbox which contains this asset
|
||||
*/
|
||||
public Sandbox getSandbox()
|
||||
{
|
||||
return this.sandbox;
|
||||
}
|
||||
}
|
232
source/java/org/alfresco/wcm/sandbox/script/Sandbox.java
Normal file
232
source/java/org/alfresco/wcm/sandbox/script/Sandbox.java
Normal file
@@ -0,0 +1,232 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2007 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.sandbox.script;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import org.alfresco.repo.jscript.ScriptableHashMap;
|
||||
import org.alfresco.service.cmr.avm.AVMNodeDescriptor;
|
||||
import org.alfresco.util.ISO8601DateFormat;
|
||||
import org.alfresco.wcm.sandbox.SandboxInfo;
|
||||
import org.alfresco.wcm.sandbox.SandboxService;
|
||||
import org.alfresco.wcm.webproject.script.WebProject;
|
||||
|
||||
/**
|
||||
* Sandbox object to expose via JavaScript
|
||||
* @author mrogers
|
||||
*
|
||||
*/
|
||||
public class Sandbox implements Serializable
|
||||
{
|
||||
/**
|
||||
* serial version id
|
||||
*/
|
||||
private static final long serialVersionUID = -9176488061624800911L;
|
||||
|
||||
private SandboxInfo si;
|
||||
private WebProject webproject;
|
||||
|
||||
/*
|
||||
* Constructor from a SandboxInfo
|
||||
*/
|
||||
public Sandbox(WebProject webproject, SandboxInfo si)
|
||||
{
|
||||
this.webproject = webproject;
|
||||
this.si = si;
|
||||
}
|
||||
|
||||
public void setName(String name)
|
||||
{
|
||||
// read only
|
||||
}
|
||||
|
||||
/**
|
||||
* Display name for the sandbox
|
||||
* @return the name of the sandbox
|
||||
*/
|
||||
public String getName()
|
||||
{
|
||||
return si.getName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the unique reference for this sandbox - no-op, read only
|
||||
* @param sandboxRef
|
||||
*/
|
||||
public void setSandboxRef(String sandboxRef)
|
||||
{
|
||||
// read only
|
||||
}
|
||||
|
||||
/**
|
||||
* Submit the modified contents of this sandbox
|
||||
*/
|
||||
public void submitAll(String submitLabel, String submitComment)
|
||||
{
|
||||
getSandboxService().submitAll(getSandboxRef(), submitLabel, submitComment);
|
||||
}
|
||||
|
||||
/**
|
||||
* Submit the modified contents of the webapp within this sandbox
|
||||
*/
|
||||
public void submitAllWebApp(String webApp, String submitLabel, String submitComment)
|
||||
{
|
||||
getSandboxService().submitAllWebApp(getSandboxRef(), webApp, submitLabel, submitComment);
|
||||
}
|
||||
|
||||
/**
|
||||
* Revert all modified contents within this sandbox
|
||||
*/
|
||||
public void revertAll()
|
||||
{
|
||||
getSandboxService().revertAll(getSandboxRef());
|
||||
}
|
||||
|
||||
/**
|
||||
* Revert all modified contents within this sandbox
|
||||
*/
|
||||
public void revertAllWebApp(String webApp)
|
||||
{
|
||||
getSandboxService().revertAllWebApp(getSandboxRef(), webApp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the snapshots
|
||||
* @param includeSystemGenerated
|
||||
*/
|
||||
public void getSnapshots(boolean includeSystemGenerated)
|
||||
{
|
||||
getSandboxService().listSnapshots(getSandboxRef(), includeSystemGenerated);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the unique reference for this sandbox
|
||||
*/
|
||||
public String getSandboxRef()
|
||||
{
|
||||
return si.getSandboxId();
|
||||
}
|
||||
|
||||
public String getCreator()
|
||||
{
|
||||
return si.getCreator();
|
||||
}
|
||||
|
||||
public Date getCreatedDate()
|
||||
{
|
||||
return si.getCreatedDate();
|
||||
}
|
||||
|
||||
public String getCreatedDateAsISO8601()
|
||||
{
|
||||
return ISO8601DateFormat.format(si.getCreatedDate());
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete this sandbox
|
||||
*/
|
||||
public void deleteSandbox()
|
||||
{
|
||||
getSandboxService().deleteSandbox(getSandboxRef());
|
||||
}
|
||||
|
||||
/*
|
||||
* Save the updates to this sandbox
|
||||
*/
|
||||
public void save()
|
||||
{
|
||||
// no read-write params yet ...
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the store names
|
||||
* @return the list of store names with the "main" store first.
|
||||
*/
|
||||
public String[] getStoreNames()
|
||||
{
|
||||
return si.getStoreNames();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the modified assets within this sandbox
|
||||
* @return the list of changed assets
|
||||
*/
|
||||
public List<Asset> getModifiedAssets()
|
||||
{
|
||||
List<AVMNodeDescriptor> items = getSandboxService().listChangedItems(getSandboxRef(), true);
|
||||
ArrayList<Asset> ret = new ArrayList<Asset>(items.size());
|
||||
|
||||
for(AVMNodeDescriptor item : items)
|
||||
{
|
||||
Asset a = new Asset(this, item);
|
||||
ret.add(a);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the modified assets within this sandbox
|
||||
* @return the list of changed assets
|
||||
*/
|
||||
public List<Asset> getModifiedAssetsWebApp(String webApp)
|
||||
{
|
||||
List<AVMNodeDescriptor> items = getSandboxService().listChangedItems(getSandboxRef(), webApp, true);
|
||||
ArrayList<Asset> ret = new ArrayList<Asset>(items.size());
|
||||
|
||||
for(AVMNodeDescriptor item : items)
|
||||
{
|
||||
Asset a = new Asset(this, item);
|
||||
ret.add(a);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Submit a list of files
|
||||
*/
|
||||
public void submitList(List<String> toSubmit, String submitLabel, String submitComment)
|
||||
{
|
||||
// TODO - Interface will add string list
|
||||
//ss.submitList(sbStoreId, items, submitLabel, submitComment)
|
||||
}
|
||||
|
||||
public List<Asset> getAssets(String path)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public WebProject getWebproject()
|
||||
{
|
||||
return this.webproject;
|
||||
}
|
||||
|
||||
private SandboxService getSandboxService()
|
||||
{
|
||||
return webproject.getWebProjects().getSandboxService();
|
||||
}
|
||||
}
|
@@ -25,15 +25,22 @@
|
||||
package org.alfresco.wcm.util;
|
||||
|
||||
import java.text.MessageFormat;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.alfresco.config.JNDIConstants;
|
||||
import org.alfresco.mbeans.VirtServerRegistry;
|
||||
import org.alfresco.model.WCMAppModel;
|
||||
import org.alfresco.repo.domain.PropertyValue;
|
||||
import org.alfresco.service.cmr.avm.AVMService;
|
||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.service.namespace.RegexQNamePattern;
|
||||
import org.alfresco.util.ParameterCheck;
|
||||
import org.alfresco.util.VirtServerUtils;
|
||||
import org.alfresco.wcm.sandbox.SandboxConstants;
|
||||
@@ -50,15 +57,15 @@ import org.alfresco.wcm.sandbox.SandboxConstants;
|
||||
public class WCMUtil
|
||||
{
|
||||
/**
|
||||
* Extracts the store name from the avm path
|
||||
* Extracts the sandbox store id from the avm path
|
||||
*
|
||||
* @param avmPath an absolute avm path
|
||||
*
|
||||
* @return the store name
|
||||
* @return the sandbox store id
|
||||
*/
|
||||
protected static String getStoreName(final String avmPath)
|
||||
protected static String getSandboxStoreId(final String avmPath)
|
||||
{
|
||||
final int i = avmPath.indexOf(':');
|
||||
final int i = avmPath.indexOf(AVM_STORE_SEPARATOR);
|
||||
if (i == -1)
|
||||
{
|
||||
throw new IllegalArgumentException("path " + avmPath + " does not contain a store");
|
||||
@@ -78,7 +85,7 @@ public class WCMUtil
|
||||
*
|
||||
* @return the web project store id
|
||||
*/
|
||||
protected static String getStoreId(final String storeName)
|
||||
protected static String getWebProjectStoreId(final String storeName)
|
||||
{
|
||||
final int index = storeName.indexOf(WCMUtil.STORE_SEPARATOR);
|
||||
return (index == -1
|
||||
@@ -87,17 +94,17 @@ public class WCMUtil
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts the store id from the avm path
|
||||
* Extracts the web project store id from the avm path
|
||||
*
|
||||
* For example, if the avm path is: teststore--admin:/www/ROOT then the store id is: teststore
|
||||
* For example, if the avm path is: teststore--admin:/www/ROOT then the web project id is: teststore
|
||||
*
|
||||
* @param avmPath an absolute avm path
|
||||
*
|
||||
* @return the store id.
|
||||
* @return the web project store id.
|
||||
*/
|
||||
protected static String getStoreIdFromPath(final String avmPath)
|
||||
protected static String getWebProjectStoreIdFromPath(final String avmPath)
|
||||
{
|
||||
return getStoreId(getStoreName(avmPath));
|
||||
return getWebProjectStoreId(getSandboxStoreId(avmPath));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -109,7 +116,7 @@ public class WCMUtil
|
||||
*/
|
||||
protected static boolean isPreviewStore(final String storeName)
|
||||
{
|
||||
return storeName.endsWith(WCMUtil.STORE_SEPARATOR + WCMUtil.STORE_PREVIEW);
|
||||
return ((storeName != null) && (storeName.endsWith(WCMUtil.STORE_SEPARATOR + WCMUtil.STORE_PREVIEW)));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -126,7 +133,7 @@ public class WCMUtil
|
||||
storeName = WCMUtil.getCorrespondingMainStoreName(storeName);
|
||||
}
|
||||
|
||||
return storeName.indexOf(STORE_SEPARATOR + STORE_WORKFLOW) != -1;
|
||||
return ((storeName != null) && (storeName.indexOf(STORE_SEPARATOR + STORE_WORKFLOW) != -1));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -142,19 +149,19 @@ public class WCMUtil
|
||||
{
|
||||
storeName = WCMUtil.getCorrespondingMainStoreName(storeName);
|
||||
}
|
||||
return storeName.indexOf(WCMUtil.STORE_SEPARATOR) != -1;
|
||||
return ((storeName != null) && (storeName.indexOf(WCMUtil.STORE_SEPARATOR) != -1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether the store name describes a main store.
|
||||
* Indicates whether the store name describes a staging store.
|
||||
*
|
||||
* @param storeName the store name
|
||||
*
|
||||
* @return <tt>true</tt> if the store is a main store, <tt>false</tt> otherwise.
|
||||
*/
|
||||
protected static boolean isMainStore(String storeName)
|
||||
protected static boolean isStagingStore(String storeName)
|
||||
{
|
||||
return (storeName.indexOf(WCMUtil.STORE_SEPARATOR) == -1);
|
||||
return ((storeName != null) && (storeName.indexOf(WCMUtil.STORE_SEPARATOR) == -1));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -164,7 +171,7 @@ public class WCMUtil
|
||||
*
|
||||
* @return the username associated or <tt>null</tt> if this is a staging store.
|
||||
*/
|
||||
protected static String getUserName(String storeName)
|
||||
public static String getUserName(String storeName)
|
||||
{
|
||||
if (WCMUtil.isPreviewStore(storeName))
|
||||
{
|
||||
@@ -176,6 +183,24 @@ public class WCMUtil
|
||||
: storeName.substring(index + WCMUtil.STORE_SEPARATOR.length()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts the workflow id
|
||||
*
|
||||
* @param storeName
|
||||
* @return
|
||||
*/
|
||||
public static String getWorkflowId(String storeName)
|
||||
{
|
||||
if (WCMUtil.isPreviewStore(storeName))
|
||||
{
|
||||
storeName = WCMUtil.getCorrespondingMainStoreName(storeName);
|
||||
}
|
||||
final int index = storeName.indexOf(STORE_SEPARATOR + STORE_WORKFLOW);
|
||||
return (index == -1
|
||||
? null
|
||||
: storeName.substring(index + WCMUtil.STORE_SEPARATOR.length()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the corresponding main store name if this is a preview store name.
|
||||
*
|
||||
@@ -226,7 +251,7 @@ public class WCMUtil
|
||||
*/
|
||||
protected static String getCorrespondingPathInMainStore(final String avmPath)
|
||||
{
|
||||
String storeName = WCMUtil.getStoreName(avmPath);
|
||||
String storeName = WCMUtil.getSandboxStoreId(avmPath);
|
||||
storeName = WCMUtil.getCorrespondingMainStoreName(storeName);
|
||||
return WCMUtil.getCorrespondingPath(avmPath, storeName);
|
||||
}
|
||||
@@ -243,7 +268,7 @@ public class WCMUtil
|
||||
*/
|
||||
protected static String getCorrespondingPathInPreviewStore(final String avmPath)
|
||||
{
|
||||
String storeName = WCMUtil.getStoreName(avmPath);
|
||||
String storeName = WCMUtil.getSandboxStoreId(avmPath);
|
||||
storeName = WCMUtil.getCorrespondingPreviewStoreName(storeName);
|
||||
return WCMUtil.getCorrespondingPath(avmPath, storeName);
|
||||
}
|
||||
@@ -258,20 +283,19 @@ public class WCMUtil
|
||||
*/
|
||||
protected static String getCorrespondingPath(final String avmPath, final String otherStore)
|
||||
{
|
||||
return (otherStore + ':' + WCMUtil.getStoreRelativePath(avmPath));
|
||||
return (otherStore + AVM_STORE_SEPARATOR + WCMUtil.getStoreRelativePath(avmPath));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the main staging store name for the specified store id.
|
||||
* Returns the main staging store name for the specified web project
|
||||
*
|
||||
* @param storeId store id to build staging store name for
|
||||
*
|
||||
* @return main staging store name for the specified store id
|
||||
* @param wpStoreId web project store id to build staging store name for
|
||||
* @return String main staging store name for the specified web project store id
|
||||
*/
|
||||
protected static String buildStagingStoreName(final String storeId)
|
||||
public static String buildStagingStoreName(final String wpStoreId)
|
||||
{
|
||||
ParameterCheck.mandatoryString("storeId", storeId);
|
||||
return storeId;
|
||||
ParameterCheck.mandatoryString("wpStoreId", wpStoreId);
|
||||
return wpStoreId;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -295,7 +319,7 @@ public class WCMUtil
|
||||
*
|
||||
* @return the main store for the specified user and store id
|
||||
*/
|
||||
protected static String buildUserMainStoreName(final String storeId,
|
||||
public static String buildUserMainStoreName(final String storeId,
|
||||
final String userName)
|
||||
{
|
||||
ParameterCheck.mandatoryString("userName", userName);
|
||||
@@ -361,7 +385,7 @@ public class WCMUtil
|
||||
protected static String buildStoreRootPath(final String storeName)
|
||||
{
|
||||
ParameterCheck.mandatoryString("storeName", storeName);
|
||||
return storeName + ":/" + JNDIConstants.DIR_DEFAULT_WWW;
|
||||
return storeName + AVM_STORE_SEPARATOR + "/" + JNDIConstants.DIR_DEFAULT_WWW;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -376,7 +400,7 @@ public class WCMUtil
|
||||
protected static String buildSandboxRootPath(final String storeName)
|
||||
{
|
||||
ParameterCheck.mandatoryString("storeName", storeName);
|
||||
return storeName + ":/" + JNDIConstants.DIR_DEFAULT_WWW_APPBASE;
|
||||
return storeName + AVM_STORE_SEPARATOR + JNDIConstants.DIR_DEFAULT_WWW_APPBASE;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -393,9 +417,7 @@ public class WCMUtil
|
||||
return WCMUtil.buildSandboxRootPath(storeName) + '/' + webApp;
|
||||
}
|
||||
|
||||
// TODO refactor ...
|
||||
// assume for now that it is a store name rather than a path - eg. main rather than main:/
|
||||
protected static String buildStoreUrl(AVMService avmService, String storeName, String domain, String port)
|
||||
public static String buildStoreUrl(AVMService avmService, String storeName, String domain, String port)
|
||||
{
|
||||
ParameterCheck.mandatoryString("storeName", storeName);
|
||||
|
||||
@@ -418,7 +440,7 @@ public class WCMUtil
|
||||
: buildStoreUrl(avmService, storeName, domain, port) + '/' + webApp);
|
||||
}
|
||||
|
||||
protected static String buildAssetUrl(String assetPath, String domain, String port, String dns)
|
||||
public static String buildAssetUrl(String assetPath, String domain, String port, String dns)
|
||||
{
|
||||
ParameterCheck.mandatoryString("assetPath", assetPath);
|
||||
|
||||
@@ -443,7 +465,7 @@ public class WCMUtil
|
||||
return MessageFormat.format(JNDIConstants.PREVIEW_ASSET_URL, dns, domain, port, assetPath);
|
||||
}
|
||||
|
||||
protected static String lookupStoreDNS(AVMService avmService, String store)
|
||||
public static String lookupStoreDNS(AVMService avmService, String store)
|
||||
{
|
||||
ParameterCheck.mandatoryString("store", store);
|
||||
|
||||
@@ -502,8 +524,8 @@ public class WCMUtil
|
||||
*/
|
||||
protected static String getStoreRelativePath(final String absoluteAVMPath)
|
||||
{
|
||||
final Matcher m = STORE_RELATIVE_PATH_PATTERN.matcher(absoluteAVMPath);
|
||||
return m.matches() && m.group(1).length() != 0 ? m.group(1) : null;
|
||||
ParameterCheck.mandatoryString("absoluteAVMPath", absoluteAVMPath);
|
||||
return absoluteAVMPath.substring(absoluteAVMPath.indexOf(AVM_STORE_SEPARATOR) + 1);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -571,6 +593,24 @@ public class WCMUtil
|
||||
return m.matches() && m.group(1).length() != 0 ? m.group(1) : null;
|
||||
}
|
||||
|
||||
protected static Map<String, String> listWebUsers(NodeService nodeService, NodeRef wpNodeRef)
|
||||
{
|
||||
List<ChildAssociationRef> userInfoRefs = nodeService.getChildAssocs(wpNodeRef, WCMAppModel.ASSOC_WEBUSER, RegexQNamePattern.MATCH_ALL);
|
||||
|
||||
Map<String, String> webUsers = new HashMap<String, String>(23);
|
||||
|
||||
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);
|
||||
|
||||
webUsers.put(userName, userRole);
|
||||
}
|
||||
|
||||
return webUsers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates all directories for a path if they do not already exist.
|
||||
*/
|
||||
@@ -685,6 +725,8 @@ public class WCMUtil
|
||||
// Component Separator.
|
||||
protected static final String STORE_SEPARATOR = "--";
|
||||
|
||||
protected static final char AVM_STORE_SEPARATOR = ':';
|
||||
|
||||
// names of the stores representing the layers for an AVM website
|
||||
//XXXarielb this should be private
|
||||
protected final static String STORE_WORKFLOW = "workflow";
|
||||
@@ -702,10 +744,6 @@ public class WCMUtil
|
||||
public static final String ROLE_CONTENT_REVIEWER = "ContentReviewer";
|
||||
public static final String ROLE_CONTENT_CONTRIBUTOR = "ContentContributor";
|
||||
|
||||
// pattern for absolute AVM Path
|
||||
private final static Pattern STORE_RELATIVE_PATH_PATTERN =
|
||||
Pattern.compile("[^:]+:(.+)");
|
||||
|
||||
private final static Pattern WEBAPP_RELATIVE_PATH_PATTERN =
|
||||
Pattern.compile("([^:]+:/" + JNDIConstants.DIR_DEFAULT_WWW +
|
||||
"/" + JNDIConstants.DIR_DEFAULT_APPBASE + "/([^/]+))(.*)");
|
||||
|
121
source/java/org/alfresco/wcm/util/WCMWorkflowUtil.java
Normal file
121
source/java/org/alfresco/wcm/util/WCMWorkflowUtil.java
Normal file
@@ -0,0 +1,121 @@
|
||||
/*
|
||||
* 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.util;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import org.alfresco.model.WCMWorkflowModel;
|
||||
import org.alfresco.service.cmr.avm.AVMNodeDescriptor;
|
||||
import org.alfresco.service.cmr.avm.AVMNotFoundException;
|
||||
import org.alfresco.service.cmr.avm.AVMService;
|
||||
import org.alfresco.service.cmr.avm.LayeringDescriptor;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.workflow.WorkflowService;
|
||||
import org.alfresco.service.cmr.workflow.WorkflowTask;
|
||||
import org.alfresco.service.cmr.workflow.WorkflowTaskQuery;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
/**
|
||||
* WCM Specific workflow related helper methods.
|
||||
*
|
||||
* @author Ariel Backenroth
|
||||
* @author Kevin Roast
|
||||
* @author janv
|
||||
*/
|
||||
public class WCMWorkflowUtil
|
||||
{
|
||||
private static final Log logger = LogFactory.getLog(WCMWorkflowUtil.class);
|
||||
|
||||
public static List<WorkflowTask> getAssociatedTasksForSandbox(WorkflowService workflowService, final String storeName)
|
||||
{
|
||||
String fromPath = WCMUtil.buildStoreRootPath(storeName);
|
||||
WorkflowTaskQuery query = new WorkflowTaskQuery();
|
||||
|
||||
HashMap<QName, Object> props = new HashMap<QName, Object>(1, 1.0f);
|
||||
|
||||
props.put(WCMWorkflowModel.PROP_FROM_PATH, fromPath);
|
||||
query.setProcessCustomProps(props);
|
||||
query.setActive(true);
|
||||
|
||||
List<WorkflowTask> tasks = workflowService.queryTasks(query);
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("found " + tasks.size() + " tasks originating user sandbox " + fromPath);
|
||||
}
|
||||
|
||||
return tasks;
|
||||
}
|
||||
|
||||
public static List<WorkflowTask> getAssociatedTasksForNode(AVMService avmService, AVMNodeDescriptor node, List<WorkflowTask> tasks)
|
||||
{
|
||||
List<WorkflowTask> result = new LinkedList<WorkflowTask>();
|
||||
|
||||
for (WorkflowTask task : tasks)
|
||||
{
|
||||
final NodeRef ref = task.path.instance.workflowPackage;
|
||||
final String path = WCMUtil.getCorrespondingPath(node.getPath(), ref.getStoreRef().getIdentifier());
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("checking store " + ref.getStoreRef().getIdentifier() +
|
||||
" for " + node.getPath() + " (" + path + ")");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
final LayeringDescriptor ld = avmService.getLayeringInfo(-1, path);
|
||||
if (!ld.isBackground())
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug(path + " is in the foreground. workflow active");
|
||||
}
|
||||
|
||||
result.add(task);
|
||||
}
|
||||
}
|
||||
catch (final AVMNotFoundException avmnfe)
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug(path + " not found");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static List<WorkflowTask> getAssociatedTasksForNode(WorkflowService workflowService, AVMService avmService, AVMNodeDescriptor node)
|
||||
{
|
||||
final List<WorkflowTask> tasks = WCMWorkflowUtil.getAssociatedTasksForSandbox(workflowService, WCMUtil.getSandboxStoreId(node.getPath()));
|
||||
return getAssociatedTasksForNode(avmService, node, tasks);
|
||||
}
|
||||
}
|
@@ -32,7 +32,7 @@ import org.alfresco.wcm.util.WCMUtil;
|
||||
*
|
||||
* @author janv
|
||||
*/
|
||||
public class WebProjectInfoImpl extends WCMUtil implements WebProjectInfo
|
||||
public class WebProjectInfoImpl implements WebProjectInfo
|
||||
{
|
||||
/** Web Project node reference */
|
||||
private NodeRef nodeRef;
|
||||
|
@@ -347,12 +347,25 @@ public interface WebProjectService
|
||||
* Invite users/groups to web project
|
||||
* <p>
|
||||
* Note: authority name can be user or group, although a group is flattened into a set of users
|
||||
* <p>
|
||||
* Note: author sandbox will NOT be auto created for each invited user
|
||||
*
|
||||
* @param wpStoreId web project store id
|
||||
* @param userGroupRoles map of <authority name, role name> pairs
|
||||
*/
|
||||
public void inviteWebUsersGroups(String wpStoreId, Map<String, String> userGroupRoles);
|
||||
|
||||
/**
|
||||
* Invite users/groups to web project
|
||||
* <p>
|
||||
* Note: authority name can be user or group, although a group is flattened into a set of users
|
||||
*
|
||||
* @param wpStoreId web project store id
|
||||
* @param userGroupRoles map of <authority name, role name> pairs
|
||||
* @param autoCreateAuthorSandbox if <tt>true</tt> then auto create an author sandbox for each invited user
|
||||
*/
|
||||
public void inviteWebUsersGroups(String wpStoreId, Map<String, String> userGroupRoles, boolean autoCreateAuthorSandbox);
|
||||
|
||||
/**
|
||||
* Invite users/groups to web project
|
||||
* <p>
|
||||
@@ -360,11 +373,14 @@ public interface WebProjectService
|
||||
*
|
||||
* @param wpNodeRef web project node ref
|
||||
* @param userGroupRoles map of <authority name, role name> pairs
|
||||
* @param autoCreateAuthorSandbox if <tt>true</tt> then auto create the author sandbox for each invited user
|
||||
*/
|
||||
public void inviteWebUsersGroups(NodeRef wpNodeRef, Map<String, String> userGroupRoles);
|
||||
public void inviteWebUsersGroups(NodeRef wpNodeRef, Map<String, String> userGroupRoles, boolean autoCreateAuthorSandbox);
|
||||
|
||||
/**
|
||||
* Invite user to web project
|
||||
* <p>
|
||||
* Note: author sandbox will NOT be auto created for each invited user
|
||||
*
|
||||
* @param wpStoreId web project store id
|
||||
* @param userName user name (not a group)
|
||||
@@ -372,19 +388,30 @@ public interface WebProjectService
|
||||
*/
|
||||
public void inviteWebUser(String wpStoreId, String userName, String userRole);
|
||||
|
||||
/**
|
||||
* Invite user to web project
|
||||
*
|
||||
* @param wpStoreId web project store id
|
||||
* @param userName user name (not a group)
|
||||
* @param userRole web project role
|
||||
* @param autoCreateAuthorSandbox if <tt>true</tt> then auto create the author sandbox for each invited user
|
||||
*/
|
||||
public void inviteWebUser(String wpStoreId, String userName, String userRole, boolean autoCreateAuthorSandbox);
|
||||
|
||||
/**
|
||||
* Invite user to web project
|
||||
*
|
||||
* @param wpNodeRef web project node ref
|
||||
* @param userName user name (not a group)
|
||||
* @param userRole web project role
|
||||
* @param autoCreateAuthorSandbox if <tt>true</tt> then auto create the author sandbox for each invited user
|
||||
*/
|
||||
public void inviteWebUser(NodeRef wpNodeRef, String userName, String userRole);
|
||||
public void inviteWebUser(NodeRef wpNodeRef, String userName, String userRole, boolean autoCreateAuthorSandbox);
|
||||
|
||||
/**
|
||||
* Uninvite user from a web project
|
||||
* <p>
|
||||
* Note: this will cascade delete the user's sandboxes without warning (even if there are modified items)
|
||||
* Note: author sandbox will NOT be auto deleted
|
||||
*
|
||||
* @param wpStoreId web project store id
|
||||
* @param userName user name
|
||||
@@ -394,10 +421,22 @@ public interface WebProjectService
|
||||
/**
|
||||
* Uninvite user from a web project
|
||||
* <p>
|
||||
* Note: this will cascade delete the user's sandboxes without warning (even if there are modified items)
|
||||
* Note: if author sandbox is auto deleted then this will cascade delete without warning (even if there are changed items)
|
||||
*
|
||||
* @param wpStoreId web project store id
|
||||
* @param userName user name
|
||||
* @param autoDeleteAuthorSandbox if <tt>true</tt> then auto delete the author sandbox
|
||||
*/
|
||||
public void uninviteWebUser(String wpStoreId, String userName, boolean autoDeleteAuthorSandbox);
|
||||
|
||||
/**
|
||||
* Uninvite user from a web project
|
||||
* <p>
|
||||
* Note: if author sandbox is auto deleted then this will cascade delete without warning (even if there are changed items)
|
||||
*
|
||||
* @param wpNodeRef web project node ref
|
||||
* @param userName user name
|
||||
* @param autoDeleteAuthorSandbox if <tt>true</tt> then auto delete the author sandbox
|
||||
*/
|
||||
public void uninviteWebUser(NodeRef wpNodeRef, String userName);
|
||||
public void uninviteWebUser(NodeRef wpNodeRef, String userName, boolean autoDeleteAuthorSandbox);
|
||||
}
|
||||
|
@@ -53,8 +53,8 @@ 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.repository.NodeService;
|
||||
import org.alfresco.service.cmr.search.ResultSet;
|
||||
import org.alfresco.service.cmr.search.SearchService;
|
||||
import org.alfresco.service.cmr.security.AuthorityService;
|
||||
@@ -220,7 +220,7 @@ public class WebProjectServiceImpl extends WCMUtil implements WebProjectService
|
||||
}
|
||||
|
||||
// create the AVM staging store to represent the newly created location website
|
||||
sandboxFactory.createStagingSandbox(wpStoreId, wpNodeRef, branchStoreId); // ignore return
|
||||
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)
|
||||
@@ -246,7 +246,9 @@ public class WebProjectServiceImpl extends WCMUtil implements WebProjectService
|
||||
// break the permissions inheritance on the web project node so that only assigned users can access it
|
||||
permissionService.setInheritParentPermissions(wpNodeRef, false);
|
||||
|
||||
inviteWebUser(wpNodeRef, AuthenticationUtil.getCurrentEffectiveUserName(), WCMUtil.ROLE_CONTENT_MANAGER);
|
||||
// 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.getCurrentEffectiveUserName(), WCMUtil.ROLE_CONTENT_MANAGER, true);
|
||||
|
||||
// Bind the post-commit transaction listener with data required for virtualization server notification
|
||||
CreateWebProjectTransactionListener tl = new CreateWebProjectTransactionListener(wpStoreId);
|
||||
@@ -624,27 +626,19 @@ public class WebProjectServiceImpl extends WCMUtil implements WebProjectService
|
||||
|
||||
WCMUtil.removeAllVServerWebapps(virtServerRegistry, path, true);
|
||||
|
||||
// get the list of users who have a sandbox in the website
|
||||
final Map<String, String> existingUserRoles = listWebUsers(wpNodeRef);
|
||||
|
||||
AuthenticationUtil.runAs(new RunAsWork<Object>()
|
||||
{
|
||||
public Object doWork() throws Exception
|
||||
{
|
||||
for (Map.Entry<String, String> userRole : existingUserRoles.entrySet())
|
||||
List<SandboxInfo> sbInfos = sandboxFactory.listSandboxes(wpStoreId, AuthenticationUtil.getSystemUserName());
|
||||
|
||||
for (SandboxInfo sbInfo : sbInfos)
|
||||
{
|
||||
String username = userRole.getKey();
|
||||
|
||||
// delete the preview store for this user
|
||||
deleteStore(WCMUtil.buildUserPreviewStoreName(wpStoreId, username));
|
||||
|
||||
// delete the main store for this user
|
||||
deleteStore(WCMUtil.buildUserMainStoreName(wpStoreId, username));
|
||||
// delete sandbox
|
||||
sandboxFactory.deleteSandbox(sbInfo.getSandboxId());
|
||||
}
|
||||
|
||||
// remove the main staging and preview stores
|
||||
deleteStore(WCMUtil.buildStagingPreviewStoreName(wpStoreId));
|
||||
deleteStore(WCMUtil.buildStagingStoreName(wpStoreId));
|
||||
// TODO delete workflow sandboxes !
|
||||
|
||||
// delete the web project node itself
|
||||
nodeService.deleteNode(wpNodeRef);
|
||||
@@ -660,20 +654,6 @@ public class WebProjectServiceImpl extends WCMUtil implements WebProjectService
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a store, checking for its existence first.
|
||||
*
|
||||
* @param store
|
||||
*/
|
||||
private void deleteStore(final String store)
|
||||
{
|
||||
// check it exists before we try to remove it
|
||||
if (avmService.getStore(store) != null)
|
||||
{
|
||||
avmService.purgeStore(store);
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.wcm.webproject.WebProjectService#isContentManager(java.lang.String)
|
||||
*/
|
||||
@@ -687,7 +667,7 @@ public class WebProjectServiceImpl extends WCMUtil implements WebProjectService
|
||||
*/
|
||||
public boolean isContentManager(String storeName, String userName)
|
||||
{
|
||||
String wpStoreId = WCMUtil.getStoreId(storeName);
|
||||
String wpStoreId = WCMUtil.getWebProjectStoreId(storeName);
|
||||
PropertyValue pValue = avmService.getStoreProperty(wpStoreId, SandboxConstants.PROP_WEB_PROJECT_NODE_REF);
|
||||
|
||||
if (pValue != null)
|
||||
@@ -723,7 +703,7 @@ public class WebProjectServiceImpl extends WCMUtil implements WebProjectService
|
||||
*/
|
||||
public boolean isWebUser(String storeName, String username)
|
||||
{
|
||||
String wpStoreId = WCMUtil.getStoreId(storeName);
|
||||
String wpStoreId = WCMUtil.getWebProjectStoreId(storeName);
|
||||
PropertyValue pValue = avmService.getStoreProperty(wpStoreId, SandboxConstants.PROP_WEB_PROJECT_NODE_REF);
|
||||
|
||||
if (pValue != null)
|
||||
@@ -742,7 +722,7 @@ public class WebProjectServiceImpl extends WCMUtil implements WebProjectService
|
||||
*/
|
||||
public boolean isWebUser(NodeRef wpNodeRef, String userName)
|
||||
{
|
||||
String userRole = getWebUserRole(wpNodeRef, userName);
|
||||
String userRole = getWebUserRoleImpl(wpNodeRef, userName);
|
||||
return (userRole != null);
|
||||
}
|
||||
|
||||
@@ -751,7 +731,7 @@ public class WebProjectServiceImpl extends WCMUtil implements WebProjectService
|
||||
*/
|
||||
public int getWebUserCount(NodeRef wpNodeRef)
|
||||
{
|
||||
return listWebUserRefs(wpNodeRef).size();
|
||||
return WCMUtil.listWebUsers(nodeService, wpNodeRef).size();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
@@ -767,22 +747,10 @@ public class WebProjectServiceImpl extends WCMUtil implements WebProjectService
|
||||
*/
|
||||
public Map<String, String> listWebUsers(NodeRef wpNodeRef)
|
||||
{
|
||||
if (isContentManager(wpNodeRef))
|
||||
// special case: allow System - eg. to allow user to create their own sandbox on-demand (createAuthorSandbox)
|
||||
if (isContentManager(wpNodeRef) || (AuthenticationUtil.getCurrentEffectiveUserName().equals(AuthenticationUtil.getSystemUserName())))
|
||||
{
|
||||
List<ChildAssociationRef> userInfoRefs = listWebUserRefs(wpNodeRef);
|
||||
|
||||
Map<String, String> webUsers = new HashMap<String, String>(23);
|
||||
|
||||
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);
|
||||
|
||||
webUsers.put(userName, userRole);
|
||||
}
|
||||
|
||||
return webUsers;
|
||||
return WCMUtil.listWebUsers(nodeService, wpNodeRef);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -790,11 +758,6 @@ public class WebProjectServiceImpl extends WCMUtil implements WebProjectService
|
||||
}
|
||||
}
|
||||
|
||||
private List<ChildAssociationRef> listWebUserRefs(NodeRef wpNodeRef)
|
||||
{
|
||||
return nodeService.getChildAssocs(wpNodeRef, WCMAppModel.ASSOC_WEBUSER, RegexQNamePattern.MATCH_ALL);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.wcm.webproject.WebProjectService#getWebUserRole(java.lang.String, java.lang.String)
|
||||
*/
|
||||
@@ -808,7 +771,6 @@ public class WebProjectServiceImpl extends WCMUtil implements WebProjectService
|
||||
*/
|
||||
public String getWebUserRole(NodeRef wpNodeRef, String userName)
|
||||
{
|
||||
long start = System.currentTimeMillis();
|
||||
String userRole = null;
|
||||
|
||||
if (! isWebProject(wpNodeRef))
|
||||
@@ -824,6 +786,17 @@ public class WebProjectServiceImpl extends WCMUtil implements WebProjectService
|
||||
}
|
||||
else
|
||||
{
|
||||
userRole = getWebUserRoleImpl(wpNodeRef, userName);
|
||||
}
|
||||
|
||||
return userRole;
|
||||
}
|
||||
|
||||
private String getWebUserRoleImpl(NodeRef wpNodeRef, String userName)
|
||||
{
|
||||
long start = System.currentTimeMillis();
|
||||
String userRole = null;
|
||||
|
||||
StringBuilder query = new StringBuilder(128);
|
||||
query.append("+PARENT:\"").append(wpNodeRef).append("\" ");
|
||||
query.append("+TYPE:\"").append(WCMAppModel.TYPE_WEBUSER).append("\" ");
|
||||
@@ -852,7 +825,6 @@ public class WebProjectServiceImpl extends WCMUtil implements WebProjectService
|
||||
{
|
||||
logger.warn("getWebProjectUserRole: more than one user role found for " + userName);
|
||||
}
|
||||
}
|
||||
|
||||
if (logger.isTraceEnabled())
|
||||
{
|
||||
@@ -867,7 +839,7 @@ public class WebProjectServiceImpl extends WCMUtil implements WebProjectService
|
||||
*/
|
||||
public NodeRef findWebProjectNodeFromPath(String absoluteAVMPath)
|
||||
{
|
||||
return findWebProjectNodeFromStore(WCMUtil.getStoreIdFromPath(absoluteAVMPath));
|
||||
return findWebProjectNodeFromStore(WCMUtil.getWebProjectStoreIdFromPath(absoluteAVMPath));
|
||||
}
|
||||
|
||||
/*(non-Javadoc)
|
||||
@@ -938,13 +910,18 @@ public class WebProjectServiceImpl extends WCMUtil implements WebProjectService
|
||||
*/
|
||||
public void inviteWebUsersGroups(String wpStoreId, Map<String, String> userGroupRoles)
|
||||
{
|
||||
inviteWebUsersGroups(findWebProjectNodeFromStore(wpStoreId), userGroupRoles);
|
||||
inviteWebUsersGroups(findWebProjectNodeFromStore(wpStoreId), userGroupRoles, false);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.wcm.webproject.WebProjectService#inviteWebUsers(org.alfresco.service.cmr.repository.NodeRef, java.util.Map)
|
||||
* @see org.alfresco.wcm.webproject.WebProjectService#inviteWebUsersGroups(java.lang.String, java.util.Map, boolean)
|
||||
*/
|
||||
public void inviteWebUsersGroups(NodeRef wpNodeRef, Map<String, String> userGroupRoles)
|
||||
public void inviteWebUsersGroups(String wpStoreId, Map<String, String> userGroupRoles, boolean autoCreateAuthorSandbox)
|
||||
{
|
||||
inviteWebUsersGroups(findWebProjectNodeFromStore(wpStoreId), userGroupRoles, autoCreateAuthorSandbox);
|
||||
}
|
||||
|
||||
public void inviteWebUsersGroups(NodeRef wpNodeRef, Map<String, String> userGroupRoles, boolean autoCreateAuthorSandbox)
|
||||
{
|
||||
if (! isContentManager(wpNodeRef))
|
||||
{
|
||||
@@ -954,13 +931,11 @@ public class WebProjectServiceImpl extends WCMUtil implements WebProjectService
|
||||
WebProjectInfo wpInfo = getWebProject(wpNodeRef);
|
||||
String wpStoreId = wpInfo.getStoreId();
|
||||
|
||||
// create a sandbox for each user appropriately with permissions based on role
|
||||
// build a list of managers who will have full permissions on ALL staging areas
|
||||
List<String> managers = new ArrayList<String>(4);
|
||||
Set<String> existingUsers = new HashSet<String>(8);
|
||||
|
||||
// website already exists - we are only adding to the existing sandboxes
|
||||
// so retrieve the list of managers from the existing users and the selected invitees
|
||||
// retrieve the list of managers from the existing users
|
||||
for (Map.Entry<String, String> userRole : userGroupRoles.entrySet())
|
||||
{
|
||||
String authority = userRole.getKey();
|
||||
@@ -990,9 +965,6 @@ public class WebProjectServiceImpl extends WCMUtil implements WebProjectService
|
||||
existingUsers.add(username);
|
||||
}
|
||||
|
||||
// build the sandboxes now we have the manager list and complete user list
|
||||
// and create an association to a node to represent each invited user
|
||||
|
||||
List<SandboxInfo> sandboxInfoList = new LinkedList<SandboxInfo>();
|
||||
|
||||
int invitedCount = 0;
|
||||
@@ -1005,11 +977,14 @@ public class WebProjectServiceImpl extends WCMUtil implements WebProjectService
|
||||
|
||||
for (String userAuth : findNestedUserAuthorities(authority))
|
||||
{
|
||||
// create the sandbox if the invited user does not already have one
|
||||
if (existingUsers.contains(userAuth) == false)
|
||||
{
|
||||
SandboxInfo info = sandboxFactory.createUserSandbox(wpStoreId, managers, userAuth, role);
|
||||
sandboxInfoList.add(info);
|
||||
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);
|
||||
|
||||
@@ -1029,19 +1004,13 @@ public class WebProjectServiceImpl extends WCMUtil implements WebProjectService
|
||||
}
|
||||
}
|
||||
|
||||
// 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)
|
||||
{
|
||||
// walk existing sandboxes and reapply manager permissions to include any new manager users
|
||||
for (Map.Entry<String, String> userRole : existingUserRoles.entrySet())
|
||||
{
|
||||
String username = userRole.getKey();
|
||||
if (existingUsers.contains(username))
|
||||
{
|
||||
// only need to modify the sandboxes we haven't just created
|
||||
sandboxFactory.updateSandboxManagers(wpStoreId, managers, username);
|
||||
}
|
||||
}
|
||||
sandboxFactory.updateStagingAreaManagers(wpStoreId, wpNodeRef, managers);
|
||||
sandboxFactory.updateSandboxManagers(wpStoreId, wpNodeRef, managers);
|
||||
}
|
||||
|
||||
// get permissions and roles for a web project folder type
|
||||
@@ -1066,10 +1035,6 @@ public class WebProjectServiceImpl extends WCMUtil implements WebProjectService
|
||||
}
|
||||
}
|
||||
|
||||
// Bind the post-commit transaction listener with data required for virtualization server notification
|
||||
InviteWebUsersTransactionListener tl = new InviteWebUsersTransactionListener(sandboxInfoList, listWebApps(wpNodeRef));
|
||||
AlfrescoTransactionSupport.bindListener(tl);
|
||||
|
||||
if (logger.isInfoEnabled())
|
||||
{
|
||||
logger.info("Invited "+invitedCount+" web users (store id: "+wpStoreId+")");
|
||||
@@ -1081,13 +1046,21 @@ public class WebProjectServiceImpl extends WCMUtil implements WebProjectService
|
||||
*/
|
||||
public void inviteWebUser(String wpStoreId, String userAuth, String role)
|
||||
{
|
||||
inviteWebUser(findWebProjectNodeFromStore(wpStoreId), userAuth, role);
|
||||
inviteWebUser(findWebProjectNodeFromStore(wpStoreId), userAuth, role, false);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.wcm.webproject.WebProjectService#inviteWebUser(org.alfresco.service.cmr.repository.NodeRef, java.lang.String, java.lang.String)
|
||||
* @see org.alfresco.wcm.webproject.WebProjectService#inviteWebUser(java.lang.String, java.lang.String, java.lang.String, boolean)
|
||||
*/
|
||||
public void inviteWebUser(NodeRef wpNodeRef, String userAuth, String role)
|
||||
public void inviteWebUser(String wpStoreId, String userAuth, String role, boolean autoCreateAuthorSandbox)
|
||||
{
|
||||
inviteWebUser(findWebProjectNodeFromStore(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))
|
||||
{
|
||||
@@ -1095,11 +1068,15 @@ public class WebProjectServiceImpl extends WCMUtil implements WebProjectService
|
||||
}
|
||||
|
||||
WebProjectInfo wpInfo = getWebProject(wpNodeRef);
|
||||
String wpStoreId = wpInfo.getStoreId();
|
||||
final String wpStoreId = wpInfo.getStoreId();
|
||||
|
||||
boolean existingUser = false;
|
||||
|
||||
// create a sandbox for the user with permissions based on role
|
||||
if (isWebUser(wpNodeRef, userAuth))
|
||||
{
|
||||
logger.warn("User '"+userAuth+"' already invited to web project: "+wpNodeRef+" (store id: "+wpStoreId+")");
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
// build a list of managers who will have full permissions on ALL staging areas
|
||||
List<String> managers = new ArrayList<String>(4);
|
||||
|
||||
@@ -1114,43 +1091,28 @@ public class WebProjectServiceImpl extends WCMUtil implements WebProjectService
|
||||
{
|
||||
managers.add(username);
|
||||
}
|
||||
|
||||
if (username.equals(userAuth))
|
||||
{
|
||||
existingUser = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (existingUser)
|
||||
if (autoCreateAuthorSandbox)
|
||||
{
|
||||
logger.warn("User '"+userAuth+"' already invited to web project: "+wpNodeRef+" (store id: "+wpStoreId+")");
|
||||
return;
|
||||
// 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);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
// 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);
|
||||
|
||||
// walk existing sandboxes and reapply manager permissions to include new manager user
|
||||
for (Map.Entry<String, String> userRole : existingUserRoles.entrySet())
|
||||
{
|
||||
String username = userRole.getKey();
|
||||
sandboxFactory.updateSandboxManagers(wpStoreId, managers, username);
|
||||
sandboxFactory.updateSandboxManagers(wpStoreId, wpNodeRef, managers);
|
||||
}
|
||||
sandboxFactory.updateStagingAreaManagers(wpStoreId, wpNodeRef, managers);
|
||||
}
|
||||
|
||||
// build the user sandboxes now we have the manager list
|
||||
// and create an association to a node to represent invited user
|
||||
|
||||
List<SandboxInfo> sandboxInfoList = new LinkedList<SandboxInfo>();
|
||||
|
||||
SandboxInfo info = sandboxFactory.createUserSandbox(wpStoreId, managers, userAuth, role);
|
||||
sandboxInfoList.add(info);
|
||||
|
||||
sandboxFactory.addStagingAreaUser(wpStoreId, userAuth, role);
|
||||
|
||||
@@ -1173,10 +1135,6 @@ public class WebProjectServiceImpl extends WCMUtil implements WebProjectService
|
||||
}
|
||||
}
|
||||
|
||||
// Bind the post-commit transaction listener with data required for virtualization server notification
|
||||
InviteWebUsersTransactionListener tl = new InviteWebUsersTransactionListener(sandboxInfoList, listWebApps(wpNodeRef));
|
||||
AlfrescoTransactionSupport.bindListener(tl);
|
||||
|
||||
if (logger.isInfoEnabled())
|
||||
{
|
||||
logger.info("Invited web user: "+userAuth+" (store id: "+wpStoreId+")");
|
||||
@@ -1202,13 +1160,21 @@ public class WebProjectServiceImpl extends WCMUtil implements WebProjectService
|
||||
*/
|
||||
public void uninviteWebUser(String wpStoreId, String userAuth)
|
||||
{
|
||||
uninviteWebUser(findWebProjectNodeFromStore(wpStoreId), userAuth);
|
||||
uninviteWebUser(findWebProjectNodeFromStore(wpStoreId), userAuth, false);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.wcm.webproject.WebProjectService#uninviteWebUser(org.alfresco.service.cmr.repository.NodeRef, java.lang.String)
|
||||
* @see org.alfresco.wcm.webproject.WebProjectService#uninviteWebUser(java.lang.String, java.lang.String, boolean)
|
||||
*/
|
||||
public void uninviteWebUser(NodeRef wpNodeRef, String userAuth)
|
||||
public void uninviteWebUser(String wpStoreId, String userAuth, boolean autoDeleteAuthorSandbox)
|
||||
{
|
||||
uninviteWebUser(findWebProjectNodeFromStore(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))
|
||||
{
|
||||
@@ -1222,8 +1188,13 @@ public class WebProjectServiceImpl extends WCMUtil implements WebProjectService
|
||||
String wpStoreId = wpInfo.getStoreId();
|
||||
String userMainStore = WCMUtil.buildUserMainStoreName(wpStoreId, userAuth);
|
||||
|
||||
// remove the store reference from the website folder meta-data
|
||||
List<ChildAssociationRef> userInfoRefs = listWebUserRefs(wpNodeRef);
|
||||
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);
|
||||
@@ -1246,49 +1217,10 @@ public class WebProjectServiceImpl extends WCMUtil implements WebProjectService
|
||||
|
||||
if (userAuth.equals(user))
|
||||
{
|
||||
// found the sandbox to remove
|
||||
String path = WCMUtil.buildSandboxRootPath(userMainStore);
|
||||
|
||||
// Notify virtualisation server about removing this sandbox.
|
||||
//
|
||||
// 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 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.
|
||||
|
||||
WCMUtil.removeAllVServerWebapps(virtServerRegistry, path, true);
|
||||
|
||||
// TODO: Use the .sandbox-id. property to delete all sandboxes,
|
||||
// rather than assume a sandbox always had a single preview
|
||||
// layer attached.
|
||||
|
||||
// purge the user main sandbox store from the system
|
||||
avmService.purgeStore(userMainStore);
|
||||
|
||||
// remove any locks this user may have
|
||||
avmLockingService.removeStoreLocks(userMainStore);
|
||||
|
||||
// purge the user preview sandbox store from the system
|
||||
String userPreviewStore = WCMUtil.buildUserPreviewStoreName(wpStoreId, userAuth);
|
||||
avmService.purgeStore(userPreviewStore);
|
||||
|
||||
// remove any locks this user may have
|
||||
avmLockingService.removeStoreLocks(userPreviewStore);
|
||||
|
||||
// remove the association to this web project user meta-data
|
||||
nodeService.removeChild(wpNodeRef, ref.getChildRef());
|
||||
|
||||
// remove permission for the user (also fixes ETWOONE-338 - also need to ensure that last content manager does not uninvite themselves)
|
||||
// remove permission for the user (also fixes ETWOONE-338)
|
||||
permissionService.clearPermission(wpNodeRef, userAuth);
|
||||
|
||||
if (logger.isInfoEnabled())
|
||||
@@ -1375,14 +1307,14 @@ public class WebProjectServiceImpl extends WCMUtil implements WebProjectService
|
||||
}
|
||||
|
||||
/**
|
||||
* Invite Web Users Transaction listener - invoked after commit
|
||||
* Create Sandbox Transaction listener - invoked after commit
|
||||
*/
|
||||
private class InviteWebUsersTransactionListener extends TransactionListenerAdapter
|
||||
private class CreateSandboxTransactionListener extends TransactionListenerAdapter
|
||||
{
|
||||
private List<SandboxInfo> sandboxInfoList;
|
||||
private List<String> webAppNames;
|
||||
|
||||
public InviteWebUsersTransactionListener(List<SandboxInfo> sandboxInfoList, List<String> webAppNames)
|
||||
public CreateSandboxTransactionListener(List<SandboxInfo> sandboxInfoList, List<String> webAppNames)
|
||||
{
|
||||
this.sandboxInfoList = sandboxInfoList;
|
||||
this.webAppNames = webAppNames;
|
||||
|
@@ -241,6 +241,30 @@ public class WebProjectServiceImplTest extends TestCase
|
||||
WebProjectInfo wpInfo = wpService.createWebProject(TEST_WEBPROJ_DNS+"-create", TEST_WEBPROJ_NAME+"-create", TEST_TITLE, TEST_DESCRIPTION, TEST_DEFAULT_WEBAPP, TEST_USE_AS_TEMPLATE, null);
|
||||
checkWebProjectInfo(wpInfo, TEST_WEBPROJ_DNS+"-create", TEST_WEBPROJ_NAME+"-create", TEST_TITLE, TEST_DESCRIPTION, TEST_DEFAULT_WEBAPP, TEST_USE_AS_TEMPLATE);
|
||||
|
||||
// Duplicate web project dns/store name
|
||||
try
|
||||
{
|
||||
// Try to create duplicate web project dns/store (-ve test)
|
||||
wpService.createWebProject(TEST_WEBPROJ_DNS+"-create", TEST_WEBPROJ_NAME+"-x", TEST_TITLE+"x", TEST_DESCRIPTION+"x", TEST_DEFAULT_WEBAPP+"x", TEST_USE_AS_TEMPLATE, null);
|
||||
fail("Shouldn't allow duplicate web project dns/store name");
|
||||
}
|
||||
catch (AlfrescoRuntimeException exception)
|
||||
{
|
||||
// Expected
|
||||
}
|
||||
|
||||
// Duplicate web project folder/name
|
||||
try
|
||||
{
|
||||
// Try to create duplicate web project folder/name (-ve test)
|
||||
wpService.createWebProject(TEST_WEBPROJ_DNS+"x", TEST_WEBPROJ_NAME+"-create", TEST_TITLE+"x", TEST_DESCRIPTION+"x", TEST_DEFAULT_WEBAPP+"x", TEST_USE_AS_TEMPLATE, null);
|
||||
fail("Shouldn't allow duplicate web project folder/name");
|
||||
}
|
||||
catch (DuplicateChildNodeNameException exception)
|
||||
{
|
||||
// Expected
|
||||
}
|
||||
|
||||
// Mangled case
|
||||
String dnsName = TEST_WEBPROJ_DNS+"some.unexpected.chars";
|
||||
String name = dnsName + " name";
|
||||
@@ -289,30 +313,6 @@ public class WebProjectServiceImplTest extends TestCase
|
||||
{
|
||||
// Expected
|
||||
}
|
||||
|
||||
// Duplicate web project dns/store name
|
||||
try
|
||||
{
|
||||
// Try to create duplicate web project dns/store (-ve test)
|
||||
wpService.createWebProject(TEST_WEBPROJ_DNS+"-create", TEST_WEBPROJ_NAME+"-x", TEST_TITLE+"x", TEST_DESCRIPTION+"x", TEST_DEFAULT_WEBAPP+"x", TEST_USE_AS_TEMPLATE, null);
|
||||
fail("Shouldn't allow duplicate web project dns/store name");
|
||||
}
|
||||
catch (AlfrescoRuntimeException exception)
|
||||
{
|
||||
// Expected
|
||||
}
|
||||
|
||||
// Duplicate web project folder/name
|
||||
try
|
||||
{
|
||||
// Try to create duplicate web project folder/name (-ve test)
|
||||
wpService.createWebProject(TEST_WEBPROJ_DNS+"x", TEST_WEBPROJ_NAME+"-create", TEST_TITLE+"x", TEST_DESCRIPTION+"x", TEST_DEFAULT_WEBAPP+"x", TEST_USE_AS_TEMPLATE, null);
|
||||
fail("Shouldn't allow duplicate web project folder/name");
|
||||
}
|
||||
catch (DuplicateChildNodeNameException exception)
|
||||
{
|
||||
// Expected
|
||||
}
|
||||
}
|
||||
|
||||
private void checkWebProjectInfo(WebProjectInfo wpInfo, String expectedStoreId, String expectedName, String expectedTitle,
|
||||
@@ -525,7 +525,7 @@ public class WebProjectServiceImplTest extends TestCase
|
||||
wpInfo = wpService.createWebProject(TEST_WEBPROJ_DNS+"-delete2", TEST_WEBPROJ_NAME+"-delete2", TEST_TITLE, TEST_DESCRIPTION, TEST_DEFAULT_WEBAPP, true, null);
|
||||
assertNotNull(wpService.getWebProject(wpInfo.getStoreId()));
|
||||
|
||||
wpService.inviteWebUser(wpInfo.getNodeRef(), USER_ONE, WCMUtil.ROLE_CONTENT_MANAGER);
|
||||
wpService.inviteWebUser(wpInfo.getNodeRef(), USER_ONE, WCMUtil.ROLE_CONTENT_MANAGER, false);
|
||||
|
||||
// Switch to USER_TWO
|
||||
AuthenticationUtil.setCurrentUser(USER_TWO);
|
||||
@@ -749,7 +749,7 @@ public class WebProjectServiceImplTest extends TestCase
|
||||
userGroupRoles.put(USER_THREE, WCMUtil.ROLE_CONTENT_REVIEWER);
|
||||
|
||||
// Invite web users - test using wpNodeRef
|
||||
wpService.inviteWebUsersGroups(wpNodeRef, userGroupRoles);
|
||||
wpService.inviteWebUsersGroups(wpNodeRef, userGroupRoles, false);
|
||||
|
||||
assertEquals(4, wpService.listWebUsers(wpNodeRef).size());
|
||||
assertEquals(WCMUtil.ROLE_CONTENT_MANAGER, wpService.listWebUsers(wpNodeRef).get(USER_ADMIN));
|
||||
@@ -763,11 +763,15 @@ public class WebProjectServiceImplTest extends TestCase
|
||||
webProjects = wpService.listWebProjects();
|
||||
assertEquals(userOneWebProjectCount+1, webProjects.size());
|
||||
|
||||
// Start: Test fix ETWOTWO-567
|
||||
|
||||
// Test newly invited content manager can invite other
|
||||
userGroupRoles = new HashMap<String, String>();
|
||||
userGroupRoles.put(USER_FIVE, WCMUtil.ROLE_CONTENT_CONTRIBUTOR);
|
||||
|
||||
wpService.inviteWebUsersGroups(wpNodeRef, userGroupRoles);
|
||||
wpService.inviteWebUsersGroups(wpNodeRef, userGroupRoles, false);
|
||||
|
||||
// Finish: Test fix ETWOTWO-567
|
||||
|
||||
// Switch back to admin
|
||||
AuthenticationUtil.setCurrentUser(USER_ADMIN);
|
||||
@@ -818,7 +822,7 @@ public class WebProjectServiceImplTest extends TestCase
|
||||
wpService.inviteWebUser(wpInfo.getStoreId(), USER_ONE, WCMUtil.ROLE_CONTENT_PUBLISHER);
|
||||
|
||||
// Invite one web user - test using wpNodeRef
|
||||
wpService.inviteWebUser(wpNodeRef, USER_TWO, WCMUtil.ROLE_CONTENT_MANAGER);
|
||||
wpService.inviteWebUser(wpNodeRef, USER_TWO, WCMUtil.ROLE_CONTENT_MANAGER, true);
|
||||
|
||||
assertEquals(3, wpService.listWebUsers(wpNodeRef).size());
|
||||
assertEquals(WCMUtil.ROLE_CONTENT_PUBLISHER, wpService.listWebUsers(wpNodeRef).get(USER_ONE));
|
||||
@@ -831,8 +835,8 @@ public class WebProjectServiceImplTest extends TestCase
|
||||
assertEquals(1, wpService.listWebUsers(wpNodeRef2).size());
|
||||
assertEquals(WCMUtil.ROLE_CONTENT_MANAGER, wpService.listWebUsers(wpNodeRef2).get(USER_ADMIN));
|
||||
|
||||
wpService.inviteWebUser(wpNodeRef2, USER_TWO, WCMUtil.ROLE_CONTENT_PUBLISHER);
|
||||
wpService.inviteWebUser(wpNodeRef2, USER_ONE, WCMUtil.ROLE_CONTENT_MANAGER);
|
||||
wpService.inviteWebUser(wpNodeRef2, USER_TWO, WCMUtil.ROLE_CONTENT_PUBLISHER, false);
|
||||
wpService.inviteWebUser(wpNodeRef2, USER_ONE, WCMUtil.ROLE_CONTENT_MANAGER, false);
|
||||
|
||||
assertEquals(3, wpService.listWebUsers(wpNodeRef2).size());
|
||||
assertEquals(WCMUtil.ROLE_CONTENT_PUBLISHER, wpService.listWebUsers(wpNodeRef2).get(USER_TWO));
|
||||
@@ -850,7 +854,7 @@ public class WebProjectServiceImplTest extends TestCase
|
||||
try
|
||||
{
|
||||
// Try to invite web user as a non-content-manager (-ve test)
|
||||
wpService.inviteWebUser(wpNodeRef2, USER_THREE, WCMUtil.ROLE_CONTENT_REVIEWER);
|
||||
wpService.inviteWebUser(wpNodeRef2, USER_THREE, WCMUtil.ROLE_CONTENT_REVIEWER, false);
|
||||
fail("Shouldn't be able to invite web user since not a content manager");
|
||||
}
|
||||
catch (AccessDeniedException exception)
|
||||
@@ -864,7 +868,7 @@ public class WebProjectServiceImplTest extends TestCase
|
||||
try
|
||||
{
|
||||
// Try to invite web user as a non-content-manager (such as System) (-ve test)
|
||||
wpService.inviteWebUser(wpNodeRef2, USER_THREE, WCMUtil.ROLE_CONTENT_REVIEWER);
|
||||
wpService.inviteWebUser(wpNodeRef2, USER_THREE, WCMUtil.ROLE_CONTENT_REVIEWER, false);
|
||||
fail("Shouldn't be able to invite web user since not a content manager");
|
||||
}
|
||||
catch (AccessDeniedException exception)
|
||||
@@ -878,7 +882,7 @@ public class WebProjectServiceImplTest extends TestCase
|
||||
AuthenticationUtil.setCurrentUser(USER_ONE);
|
||||
|
||||
// Invite web user
|
||||
wpService.inviteWebUser(wpNodeRef2, USER_THREE, WCMUtil.ROLE_CONTENT_REVIEWER);
|
||||
wpService.inviteWebUser(wpNodeRef2, USER_THREE, WCMUtil.ROLE_CONTENT_REVIEWER, false);
|
||||
|
||||
// Switch back to admin
|
||||
AuthenticationUtil.setCurrentUser(USER_ADMIN);
|
||||
@@ -909,12 +913,12 @@ public class WebProjectServiceImplTest extends TestCase
|
||||
assertEquals(1, wpService.listWebUsers(wpNodeRef).size());
|
||||
assertEquals(WCMUtil.ROLE_CONTENT_MANAGER, wpService.listWebUsers(wpNodeRef).get(USER_ADMIN));
|
||||
|
||||
wpService.inviteWebUser(wpNodeRef, USER_FOUR, WCMUtil.ROLE_CONTENT_CONTRIBUTOR);
|
||||
wpService.inviteWebUser(wpNodeRef, USER_FOUR, WCMUtil.ROLE_CONTENT_CONTRIBUTOR, false);
|
||||
|
||||
assertEquals(2, wpService.listWebUsers(wpNodeRef).size());
|
||||
assertEquals(WCMUtil.ROLE_CONTENT_CONTRIBUTOR, wpService.listWebUsers(wpNodeRef).get(USER_FOUR));
|
||||
|
||||
wpService.inviteWebUser(wpNodeRef, USER_ONE, WCMUtil.ROLE_CONTENT_MANAGER);
|
||||
wpService.inviteWebUser(wpNodeRef, USER_ONE, WCMUtil.ROLE_CONTENT_MANAGER, false);
|
||||
|
||||
assertEquals(3, wpService.listWebUsers(wpNodeRef).size());
|
||||
assertEquals(WCMUtil.ROLE_CONTENT_MANAGER, wpService.listWebUsers(wpNodeRef).get(USER_ONE));
|
||||
@@ -931,7 +935,7 @@ public class WebProjectServiceImplTest extends TestCase
|
||||
try
|
||||
{
|
||||
// Try to uninvite web user as a non-content-manager (-ve test)
|
||||
wpService.uninviteWebUser(wpNodeRef, USER_FOUR);
|
||||
wpService.uninviteWebUser(wpNodeRef, USER_FOUR, false);
|
||||
fail("Shouldn't be able to uninvite web user since not a content manager");
|
||||
}
|
||||
catch (AccessDeniedException exception)
|
||||
@@ -945,7 +949,7 @@ public class WebProjectServiceImplTest extends TestCase
|
||||
try
|
||||
{
|
||||
// Try to uninvite web user as a non-content-manager (such as System) (-ve test)
|
||||
wpService.uninviteWebUser(wpNodeRef, USER_FOUR);
|
||||
wpService.uninviteWebUser(wpNodeRef, USER_FOUR, false);
|
||||
fail("Shouldn't be able to uninvite web user since not a content manager");
|
||||
}
|
||||
catch (AccessDeniedException exception)
|
||||
@@ -973,7 +977,7 @@ public class WebProjectServiceImplTest extends TestCase
|
||||
|
||||
// Content manager can uninvite themself
|
||||
// Uninvite web user - test using wpNodeRef
|
||||
wpService.uninviteWebUser(wpNodeRef, USER_ADMIN);
|
||||
wpService.uninviteWebUser(wpNodeRef, USER_ADMIN, false);
|
||||
|
||||
assertEquals(1, wpService.listWebUsers(wpNodeRef).size());
|
||||
assertEquals(null, wpService.listWebUsers(wpNodeRef).get(USER_ADMIN));
|
||||
@@ -985,7 +989,7 @@ public class WebProjectServiceImplTest extends TestCase
|
||||
assertEquals(WCMUtil.ROLE_CONTENT_MANAGER, wpService.listWebUsers(wpNodeRef).get(USER_ONE));
|
||||
|
||||
// Delete user (in this case, last invited content manager)
|
||||
wpService.uninviteWebUser(wpNodeRef, USER_ONE);
|
||||
wpService.uninviteWebUser(wpNodeRef, USER_ONE, false);
|
||||
|
||||
try
|
||||
{
|
||||
@@ -1055,7 +1059,7 @@ public class WebProjectServiceImplTest extends TestCase
|
||||
{
|
||||
userRoles.put(TEST_USER+"-"+j, WCMUtil.ROLE_CONTENT_MANAGER);
|
||||
}
|
||||
wpService.inviteWebUsersGroups(wpInfo.getNodeRef(), userRoles);
|
||||
wpService.inviteWebUsersGroups(wpInfo.getNodeRef(), userRoles, false);
|
||||
}
|
||||
|
||||
System.out.println("testPseudoScaleTest: invited "+SCALE_USERS+" content managers to each of "+SCALE_WEBPROJECTS+" web projects in "+(System.currentTimeMillis()-split)+" msecs");
|
||||
@@ -1064,7 +1068,7 @@ public class WebProjectServiceImplTest extends TestCase
|
||||
|
||||
for (int i = 1; i <= SCALE_USERS; i++)
|
||||
{
|
||||
wpService.listWebProjects(TEST_USER+"-"+i); // ignore return
|
||||
assertEquals(SCALE_WEBPROJECTS, wpService.listWebProjects(TEST_USER+"-"+i).size());
|
||||
}
|
||||
|
||||
System.out.println("testPseudoScaleTest: list web projects for "+SCALE_USERS+" content managers in "+(System.currentTimeMillis()-split)+" msecs");
|
||||
|
@@ -0,0 +1,73 @@
|
||||
package org.alfresco.wcm.webproject.script;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.jscript.ClasspathScriptLocation;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationComponent;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.cmr.repository.ScriptLocation;
|
||||
import org.alfresco.service.cmr.repository.ScriptService;
|
||||
import org.alfresco.service.cmr.security.AuthenticationService;
|
||||
import org.alfresco.service.cmr.security.PersonService;
|
||||
import org.alfresco.util.BaseAlfrescoSpringTest;
|
||||
import org.alfresco.util.PropertyMap;
|
||||
|
||||
public class ScriptWebProjectsTest extends BaseAlfrescoSpringTest {
|
||||
|
||||
|
||||
private static final String USER_ONE = "WebProjectTestOne";
|
||||
private static final String USER_TWO = "WebProjectTestTwo";
|
||||
private static final String USER_THREE = "WebProjectTestThree";
|
||||
|
||||
private static final String URL_WEB_PROJECTS = "/api/wcm/webprojects";
|
||||
private AuthenticationService authenticationService;
|
||||
private PersonService personService;
|
||||
private ScriptService scriptService;
|
||||
private AuthenticationComponent authenticationComponent;
|
||||
|
||||
private void createUser(String userName)
|
||||
{
|
||||
if (this.authenticationService.authenticationExists(userName) == false)
|
||||
{
|
||||
this.authenticationService.createAuthentication(userName, "PWD".toCharArray());
|
||||
|
||||
PropertyMap ppOne = new PropertyMap(4);
|
||||
ppOne.put(ContentModel.PROP_USERNAME, userName);
|
||||
ppOne.put(ContentModel.PROP_FIRSTNAME, "firstName");
|
||||
ppOne.put(ContentModel.PROP_LASTNAME, "lastName");
|
||||
ppOne.put(ContentModel.PROP_EMAIL, "email@email.com");
|
||||
ppOne.put(ContentModel.PROP_JOBTITLE, "jobTitle");
|
||||
|
||||
this.personService.createPerson(ppOne);
|
||||
}
|
||||
}
|
||||
|
||||
protected void onSetUpInTransaction() throws Exception
|
||||
{
|
||||
super.onSetUpInTransaction();
|
||||
this.scriptService = (ScriptService)this.applicationContext.getBean("ScriptService");
|
||||
|
||||
this.authenticationService = (AuthenticationService)this.applicationContext.getBean("AuthenticationService");
|
||||
this.authenticationComponent = (AuthenticationComponent)this.applicationContext.getBean("authenticationComponent");
|
||||
this.personService = (PersonService)this.applicationContext.getBean("PersonService");
|
||||
|
||||
// Create users
|
||||
createUser(USER_ONE);
|
||||
createUser(USER_TWO);
|
||||
createUser(USER_THREE);
|
||||
|
||||
// Do tests as user one
|
||||
this.authenticationComponent.setCurrentUser(USER_ONE);
|
||||
|
||||
}
|
||||
|
||||
public void testJSAPI() throws Exception
|
||||
{
|
||||
this.authenticationComponent.setCurrentUser("admin");
|
||||
|
||||
ScriptLocation location = new ClasspathScriptLocation("org/alfresco/wcm/webproject/script/test_WebProjectService.js");
|
||||
this.scriptService.executeScript(location, new HashMap<String, Object>(0));
|
||||
}
|
||||
|
||||
}
|
@@ -25,18 +25,21 @@
|
||||
package org.alfresco.wcm.webproject.script;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.alfresco.repo.jscript.ScriptNode;
|
||||
import org.alfresco.repo.jscript.ScriptableHashMap;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.wcm.webproject.WebProjectInfo;
|
||||
import org.alfresco.wcm.webproject.WebProjectService;
|
||||
|
||||
import com.sun.corba.se.spi.orbutil.fsm.Guard.Result;
|
||||
import org.alfresco.wcm.sandbox.SandboxInfo;
|
||||
import org.alfresco.wcm.sandbox.SandboxService;
|
||||
import org.alfresco.wcm.sandbox.script.Sandbox;
|
||||
|
||||
|
||||
/**
|
||||
* WebProject object to expose via JavaScript
|
||||
*
|
||||
*/
|
||||
public class WebProject implements Serializable
|
||||
{
|
||||
@@ -50,8 +53,6 @@ public class WebProject implements Serializable
|
||||
*/
|
||||
private static final long serialVersionUID = -2194205151549790079L;
|
||||
|
||||
WebProjectService service;
|
||||
|
||||
WebProjectInfo info;
|
||||
|
||||
private String name;
|
||||
@@ -59,11 +60,12 @@ public class WebProject implements Serializable
|
||||
private String description;
|
||||
private boolean isTemplate;
|
||||
private String webProjectRef;
|
||||
private WebProjects webprojects;
|
||||
|
||||
/*
|
||||
* Constructor for Outbound WebProjects
|
||||
*/
|
||||
public WebProject(WebProjectInfo info, WebProjectService service)
|
||||
public WebProject(WebProjects webprojects, WebProjectInfo info)
|
||||
{
|
||||
this.info = info;
|
||||
this.name = info.getName();
|
||||
@@ -71,7 +73,7 @@ public class WebProject implements Serializable
|
||||
this.description = info.getDescription();
|
||||
this.isTemplate = info.isTemplate();
|
||||
this.webProjectRef = info.getStoreId();
|
||||
this.service = service;
|
||||
this.webprojects = webprojects;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
@@ -123,16 +125,23 @@ public class WebProject implements Serializable
|
||||
}
|
||||
|
||||
//
|
||||
public String getWebProjectRef() {
|
||||
public String getWebProjectRef()
|
||||
{
|
||||
return webProjectRef;
|
||||
}
|
||||
|
||||
// read-only property
|
||||
public NodeRef getNodeRef()
|
||||
{
|
||||
return info.getNodeRef();
|
||||
}
|
||||
|
||||
/**
|
||||
* delete this web project
|
||||
*/
|
||||
public void deleteWebProject()
|
||||
{
|
||||
service.deleteWebProject(webProjectRef);
|
||||
getWebProjectService().deleteWebProject(webProjectRef);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -140,7 +149,74 @@ public class WebProject implements Serializable
|
||||
*/
|
||||
public void save()
|
||||
{
|
||||
service.updateWebProject(info);
|
||||
getWebProjectService().updateWebProject(info);
|
||||
}
|
||||
|
||||
/**
|
||||
* getSandboxes
|
||||
* @param userName
|
||||
* @return the sandboxes or an empty map if there are none.
|
||||
*/
|
||||
public ScriptableHashMap<String, Sandbox> getSandboxes(String userName)
|
||||
{
|
||||
ScriptableHashMap<String, Sandbox> result = new ScriptableHashMap<String, Sandbox>();
|
||||
|
||||
// TODO at the moment the user can only have one sandbox - this will change in future
|
||||
SandboxInfo si = getSandboxService().getAuthorSandbox(webProjectRef, userName);
|
||||
if(si != null)
|
||||
{
|
||||
Sandbox sandbox = new Sandbox(this, si);
|
||||
result.put(userName, sandbox);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a user sandbox, if the user already has a sandbox does nothing.
|
||||
* @param userName
|
||||
* @return the newly created sandbox details
|
||||
*/
|
||||
public Sandbox createSandbox(String userName)
|
||||
{
|
||||
SandboxInfo si = getSandboxService().createAuthorSandbox(webProjectRef, userName);
|
||||
Sandbox sandbox = new Sandbox(this, si);
|
||||
return sandbox;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a single sandbox by its unique reference
|
||||
* @param sandboxRef
|
||||
* @return the sandbox or null if it is not found.
|
||||
*/
|
||||
public Sandbox getSandbox(String sandboxRef)
|
||||
{
|
||||
SandboxInfo si = getSandboxService().getSandbox(sandboxRef);
|
||||
if(si != null)
|
||||
{
|
||||
Sandbox sandbox = new Sandbox(this, si);
|
||||
return sandbox;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* getSandboxes for this web project
|
||||
* @return the sandboxes
|
||||
*/
|
||||
public ScriptableHashMap<String, Sandbox> getSandboxes()
|
||||
{
|
||||
List<SandboxInfo> si = getSandboxService().listSandboxes(webProjectRef);
|
||||
|
||||
ScriptableHashMap<String, Sandbox> result = new ScriptableHashMap<String, Sandbox>();
|
||||
|
||||
for(SandboxInfo s : si)
|
||||
{
|
||||
Sandbox b = new Sandbox(this, s);
|
||||
result.put(b.getSandboxRef(), b);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -153,7 +229,7 @@ public class WebProject implements Serializable
|
||||
*/
|
||||
public String getMembersRole(String userName)
|
||||
{
|
||||
return service.getWebUserRole(webProjectRef, userName);
|
||||
return getWebProjectService().getWebUserRole(webProjectRef, userName);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -170,7 +246,7 @@ public class WebProject implements Serializable
|
||||
*/
|
||||
public void addMembership(String userName, String role)
|
||||
{
|
||||
service.inviteWebUser(webProjectRef, userName, role);
|
||||
getWebProjectService().inviteWebUser(webProjectRef, userName, role);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -183,7 +259,7 @@ public class WebProject implements Serializable
|
||||
*/
|
||||
public void removeMembership(String userName)
|
||||
{
|
||||
service.uninviteWebUser(webProjectRef, userName);
|
||||
getWebProjectService().uninviteWebUser(webProjectRef, userName);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -193,7 +269,7 @@ public class WebProject implements Serializable
|
||||
*/
|
||||
public ScriptableHashMap<String, String> listMembers()
|
||||
{
|
||||
Map<String, String> members = service.listWebUsers(webProjectRef);
|
||||
Map<String, String> members = getWebProjectService().listWebUsers(webProjectRef);
|
||||
|
||||
ScriptableHashMap<String, String> result = new ScriptableHashMap<String, String>();
|
||||
result.putAll(members);
|
||||
@@ -203,12 +279,36 @@ public class WebProject implements Serializable
|
||||
|
||||
/**
|
||||
* List the role (name) for a WCM project
|
||||
* @return the roles for a WCM project
|
||||
* @return a map of roles for a WCM project (value, name)
|
||||
*/
|
||||
public ScriptableHashMap<String, String> getRoles()
|
||||
{
|
||||
// TODO Not yet implemented.
|
||||
//TODO Role names should be I811N from webclient.properties
|
||||
//ContentManager=Content Manager
|
||||
//ContentPublisher=Content Publisher
|
||||
//ContentContributor=Content Contributor
|
||||
//ContentReviewer=Content Reviewer
|
||||
ScriptableHashMap<String, String> result = new ScriptableHashMap<String, String>();
|
||||
result.put(ROLE_CONTENT_MANAGER, "Content Manager");
|
||||
result.put(ROLE_CONTENT_PUBLISHER, "Content Publisher");
|
||||
result.put(ROLE_CONTENT_REVIEWER, "Content Reviewer");
|
||||
result.put(ROLE_CONTENT_CONTRIBUTOR, "Content Contributor");
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public WebProjects getWebProjects()
|
||||
{
|
||||
return this.webprojects;
|
||||
}
|
||||
|
||||
public SandboxService getSandboxService()
|
||||
{
|
||||
return getWebProjects().getSandboxService();
|
||||
}
|
||||
|
||||
public WebProjectService getWebProjectService()
|
||||
{
|
||||
return getWebProjects().getWebProjectService();
|
||||
}
|
||||
}
|
||||
|
@@ -30,6 +30,7 @@ import org.alfresco.repo.jscript.BaseScopableProcessorExtension;
|
||||
import org.alfresco.repo.model.Repository;
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.wcm.sandbox.SandboxService;
|
||||
import org.alfresco.wcm.webproject.WebProjectInfo;
|
||||
import org.alfresco.wcm.webproject.WebProjectService;
|
||||
|
||||
@@ -44,9 +45,12 @@ public class WebProjects extends BaseScopableProcessorExtension
|
||||
/** Service Registry */
|
||||
private ServiceRegistry serviceRegistry;
|
||||
|
||||
/** The site service */
|
||||
/** The web projects service */
|
||||
private WebProjectService webProjectService;
|
||||
|
||||
/** The sandbox service */
|
||||
private SandboxService sandboxService;
|
||||
|
||||
/**
|
||||
* Sets the Service Registry
|
||||
*
|
||||
@@ -67,6 +71,26 @@ public class WebProjects extends BaseScopableProcessorExtension
|
||||
this.webProjectService = webProjectService;
|
||||
}
|
||||
|
||||
public WebProjectService getWebProjectService()
|
||||
{
|
||||
return this.webProjectService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the wcm sandbox service
|
||||
*
|
||||
* @param webProjectService the wcm web project service
|
||||
*/
|
||||
public void setSandboxService(SandboxService sandboxService)
|
||||
{
|
||||
this.sandboxService = sandboxService;
|
||||
}
|
||||
|
||||
public SandboxService getSandboxService()
|
||||
{
|
||||
return this.sandboxService;
|
||||
}
|
||||
|
||||
/**
|
||||
* create web project
|
||||
* @param name
|
||||
@@ -77,7 +101,7 @@ public class WebProjects extends BaseScopableProcessorExtension
|
||||
public WebProject createWebProject(String dnsName, String name, String title, String description )
|
||||
{
|
||||
WebProjectInfo info = webProjectService.createWebProject(dnsName, name, title, description);
|
||||
return new WebProject(info, webProjectService);
|
||||
return new WebProject(this, info);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -90,7 +114,7 @@ public class WebProjects extends BaseScopableProcessorExtension
|
||||
WebProjectInfo info = webProjectService.getWebProject(webProjectRef);
|
||||
|
||||
if(info != null){
|
||||
WebProject retVal = new WebProject(info, webProjectService);
|
||||
WebProject retVal = new WebProject(this, info);
|
||||
return retVal;
|
||||
}
|
||||
return null;
|
||||
@@ -109,7 +133,7 @@ public class WebProjects extends BaseScopableProcessorExtension
|
||||
int i= 0;
|
||||
for(WebProjectInfo info : projects)
|
||||
{
|
||||
ret[i++] = new WebProject(info, webProjectService);
|
||||
ret[i++] = new WebProject(this, info);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@@ -127,7 +151,7 @@ public class WebProjects extends BaseScopableProcessorExtension
|
||||
int i= 0;
|
||||
for(WebProjectInfo info : projects)
|
||||
{
|
||||
ret[i++] = new WebProject(info, webProjectService);
|
||||
ret[i++] = new WebProject(this, info);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
@@ -0,0 +1,45 @@
|
||||
/**
|
||||
* Test WCM Web Project Java Script Interface
|
||||
*/
|
||||
|
||||
function testListWebProjects()
|
||||
{
|
||||
var service = webprojects;
|
||||
test.assertNotNull(service, "Service is null.");
|
||||
|
||||
var list1 = service.listWebProjects();
|
||||
var length = list1.length;
|
||||
|
||||
var newProjA = service.createWebProject("TestA", "test a website", "description", "jsTestA");
|
||||
var newProjB = service.createWebProject("TestB", "test b website", "description", "jsTestB");
|
||||
var newProjC = service.createWebProject("TestC", "test c website", "description", "jsTestC");
|
||||
|
||||
var list2 = service.listWebProjects();
|
||||
test.assertNotNull(list2, "list2 is null.");
|
||||
test.assertTrue(list2.length >= 3 + length, "list too small");
|
||||
|
||||
newProjA.deleteWebProject();
|
||||
newProjB.deleteWebProject();
|
||||
newProjC.deleteWebProject();
|
||||
|
||||
}
|
||||
|
||||
function testCRUD()
|
||||
{
|
||||
var service = webprojects;
|
||||
test.assertNotNull(service, "Service is null.");
|
||||
|
||||
// Try and get a web project that doesn't exist.
|
||||
var newProj = service.createWebProject("name", "title", "description", "jsTest");
|
||||
|
||||
var node = newProj.getNodeRef();
|
||||
|
||||
test.assertNotNull(node.id, "node.id is null.");
|
||||
|
||||
newProj.deleteWebProject();
|
||||
}
|
||||
|
||||
|
||||
// Execute test's
|
||||
testCRUD();
|
||||
testListWebProjects();
|
Reference in New Issue
Block a user