WCM Locking UI implementation and fixes.

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@6065 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Kevin Roast
2007-06-22 11:17:20 +00:00
parent 911327bda2
commit 86c9a9fc7e
6 changed files with 136 additions and 123 deletions

View File

@@ -31,6 +31,7 @@ import javax.faces.context.FacesContext;
import org.alfresco.model.WCMAppModel;
import org.alfresco.service.cmr.avm.AVMService;
import org.alfresco.service.cmr.avm.locking.AVMLockingService;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.namespace.RegexQNamePattern;
@@ -52,8 +53,12 @@ public class DeleteSandboxDialog extends BaseDialogBean
protected AVMService avmService;
protected AVMBrowseBean avmBrowseBean;
protected AVMLockingService avmLockingService;
// ------------------------------------------------------------------------------
// Bean property getters and setters
/**
* @param avmBrowseBean The avmBrowseBean to set.
*/
@@ -70,6 +75,14 @@ public class DeleteSandboxDialog extends BaseDialogBean
this.avmService = avmService;
}
/**
* @param avmLockingService The AVMLockingService to set
*/
public void setAvmLockingService(AVMLockingService avmLockingService)
{
this.avmLockingService = avmLockingService;
}
// ------------------------------------------------------------------------------
// Dialog implementation
@@ -118,17 +131,21 @@ public class DeleteSandboxDialog extends BaseDialogBean
// accessing a preview layer whose main layer has been torn
// out from under it.
AVMUtil.removeVServerWebapp(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
this.avmService.purgeStore(sandbox);
// remove any locks this user may have
this.avmLockingService.removeStoreLocks(sandbox);
// purge the user preview sandbox store from the system
sandbox = AVMUtil.buildUserPreviewStoreName(storeRoot, username);
this.avmService.purgeStore(sandbox);
// remove any locks this user may have
this.avmLockingService.removeStoreLocks(sandbox);
// remove the association to this web project user meta-data
this.nodeService.removeChild(website.getNodeRef(), ref.getChildRef());

View File

@@ -26,9 +26,7 @@ package org.alfresco.web.bean.wcm;
import java.io.Serializable;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.faces.context.FacesContext;
@@ -36,9 +34,6 @@ import javax.faces.context.FacesContext;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.avm.AVMNodeConverter;
import org.alfresco.service.cmr.avm.AVMService;
import org.alfresco.service.cmr.avm.locking.AVMLock;
import org.alfresco.service.cmr.avm.locking.AVMLockingException;
import org.alfresco.service.cmr.avm.locking.AVMLockingService;
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
import org.alfresco.service.cmr.dictionary.PropertyDefinition;
import org.alfresco.service.cmr.model.FileExistsException;
@@ -60,7 +55,7 @@ public class EditFilePropertiesDialog extends EditContentPropertiesDialog
{
protected AVMBrowseBean avmBrowseBean;
protected AVMService avmService;
protected AVMLockingService avmLockingService;
// ------------------------------------------------------------------------------
// Bean property getters and setters
@@ -81,14 +76,6 @@ public class EditFilePropertiesDialog extends EditContentPropertiesDialog
this.avmService = avmService;
}
/**
* @param avmLockingService The AVMLockingService to set
*/
public void setAvmLockingService(AVMLockingService avmLockingService)
{
this.avmLockingService = avmLockingService;
}
// ------------------------------------------------------------------------------
// Dialog implementation
@@ -106,106 +93,77 @@ public class EditFilePropertiesDialog extends EditContentPropertiesDialog
throws Exception
{
NodeRef nodeRef = this.editableNode.getNodeRef();
String webProjectId = this.avmBrowseBean.getWebProject().getStoreId();
String avmPath = AVMNodeConverter.ToAVMVersionPath(nodeRef).getSecond();
String[] storePath = avmPath.split(":");
String username = Application.getCurrentUser(context).getUserName();
Map<String, Object> editedProps = this.editableNode.getProperties();
try
// handle the name property separately, it is a special case for AVM nodes
String name = (String)editedProps.get(ContentModel.PROP_NAME);
if (name != null)
{
if (this.avmLockingService.hasAccess(webProjectId, avmPath, username) == false)
{
throw new AVMLockingException("avmlockservice.locked", new Object[]{avmPath});
}
else
editedProps.remove(ContentModel.PROP_NAME);
}
// we need to put all the properties from the editable bag back into
// the format expected by the repository
Map<QName, Serializable> repoProps = this.nodeService.getProperties(nodeRef);
// but first extract and deal with the special mimetype property for ContentData
String mimetype = (String)editedProps.get(TEMP_PROP_MIMETYPE);
if (mimetype != null)
{
// remove temporary prop from list so it isn't saved with the others
editedProps.remove(TEMP_PROP_MIMETYPE);
ContentData contentData = (ContentData)editedProps.get(ContentModel.PROP_CONTENT);
if (contentData != null)
{
if (this.avmLockingService.getLock(webProjectId, avmPath) == null)
{
List<String> owners = new ArrayList<String>(1);
owners.add(username);
AVMLock lock = new AVMLock(webProjectId, storePath[0], storePath[1], AVMLockingService.Type.DISCRETIONARY, owners);
this.avmLockingService.lockPath(lock);
}
}
Map<String, Object> editedProps = this.editableNode.getProperties();
// handle the name property separately, it is a special case for AVM nodes
String name = (String)editedProps.get(ContentModel.PROP_NAME);
if (name != null)
{
editedProps.remove(ContentModel.PROP_NAME);
}
// we need to put all the properties from the editable bag back into
// the format expected by the repository
Map<QName, Serializable> repoProps = this.nodeService.getProperties(nodeRef);
// but first extract and deal with the special mimetype property for ContentData
String mimetype = (String)editedProps.get(TEMP_PROP_MIMETYPE);
if (mimetype != null)
{
// remove temporary prop from list so it isn't saved with the others
editedProps.remove(TEMP_PROP_MIMETYPE);
ContentData contentData = (ContentData)editedProps.get(ContentModel.PROP_CONTENT);
if (contentData != null)
{
contentData = ContentData.setMimetype(contentData, mimetype);
editedProps.put(ContentModel.PROP_CONTENT.toString(), contentData);
}
}
// add the "titled" aspect if required, properties will get set below
if (this.nodeService.hasAspect(nodeRef, ContentModel.ASPECT_TITLED) == false)
{
this.nodeService.addAspect(nodeRef, ContentModel.ASPECT_TITLED, null);
}
// add the remaining properties
Iterator<String> iterProps = editedProps.keySet().iterator();
while (iterProps.hasNext())
{
String propName = iterProps.next();
QName qname = QName.createQName(propName);
// make sure the property is represented correctly
Serializable propValue = (Serializable)editedProps.get(propName);
// check for empty strings when using number types, set to null in this case
if ((propValue != null) && (propValue instanceof String) &&
(propValue.toString().length() == 0))
{
PropertyDefinition propDef = this.dictionaryService.getProperty(qname);
if (propDef != null)
{
if (propDef.getDataType().getName().equals(DataTypeDefinition.DOUBLE) ||
propDef.getDataType().getName().equals(DataTypeDefinition.FLOAT) ||
propDef.getDataType().getName().equals(DataTypeDefinition.INT) ||
propDef.getDataType().getName().equals(DataTypeDefinition.LONG))
{
propValue = null;
}
}
}
repoProps.put(qname, propValue);
}
// send the properties back to the repository
this.nodeService.setProperties(nodeRef, repoProps);
// perform the rename last as for an AVM it changes the NodeRef
if (name != null)
{
this.fileFolderService.rename(nodeRef, name);
editedProps.put(ContentModel.PROP_NAME.toString(), name);
contentData = ContentData.setMimetype(contentData, mimetype);
editedProps.put(ContentModel.PROP_CONTENT.toString(), contentData);
}
}
finally
// add the "titled" aspect if required, properties will get set below
if (this.nodeService.hasAspect(nodeRef, ContentModel.ASPECT_TITLED) == false)
{
if (this.avmLockingService.getLock(webProjectId, avmPath) != null)
nodeService.addAspect(nodeRef, ContentModel.ASPECT_TITLED, null);
}
// add the remaining properties
Iterator<String> iterProps = editedProps.keySet().iterator();
while (iterProps.hasNext())
{
String propName = iterProps.next();
QName qname = QName.createQName(propName);
// make sure the property is represented correctly
Serializable propValue = (Serializable)editedProps.get(propName);
// check for empty strings when using number types, set to null in this case
if ((propValue != null) && (propValue instanceof String) &&
(propValue.toString().length() == 0))
{
this.avmLockingService.removeLock(webProjectId, avmPath);
PropertyDefinition propDef = this.dictionaryService.getProperty(qname);
if (propDef != null)
{
if (propDef.getDataType().getName().equals(DataTypeDefinition.DOUBLE) ||
propDef.getDataType().getName().equals(DataTypeDefinition.FLOAT) ||
propDef.getDataType().getName().equals(DataTypeDefinition.INT) ||
propDef.getDataType().getName().equals(DataTypeDefinition.LONG))
{
propValue = null;
}
}
}
repoProps.put(qname, propValue);
}
// send the properties back to the repository
this.nodeService.setProperties(nodeRef, repoProps);
// perform the rename last as for an AVM it changes the NodeRef
if (name != null)
{
this.fileFolderService.rename(nodeRef, name);
editedProps.put(ContentModel.PROP_NAME.toString(), name);
}
return outcome;

View File

@@ -50,6 +50,7 @@ import org.alfresco.repo.domain.PropertyValue;
import org.alfresco.repo.workflow.WorkflowModel;
import org.alfresco.service.cmr.avm.AVMNodeDescriptor;
import org.alfresco.service.cmr.avm.AVMService;
import org.alfresco.service.cmr.avm.locking.AVMLockingService;
import org.alfresco.service.cmr.avmsync.AVMDifference;
import org.alfresco.service.cmr.avmsync.AVMSyncService;
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
@@ -122,6 +123,7 @@ public class SubmitDialog extends BaseDialogBean
protected AVMBrowseBean avmBrowseBean;
protected WorkflowService workflowService;
protected AVMSyncService avmSyncService;
protected AVMLockingService avmLockingService;
protected NameMatcher nameMatcher;
/** Current workflow for dialog context */
@@ -153,6 +155,14 @@ public class SubmitDialog extends BaseDialogBean
this.avmSyncService = avmSyncService;
}
/**
* @param avmLockingService The AVMLockingService to set
*/
public void setAvmLockingService(AVMLockingService avmLockingService)
{
this.avmLockingService = avmLockingService;
}
/**
* @param avmBrowseBean The AVM BrowseBean to set
*/
@@ -373,13 +383,14 @@ public class SubmitDialog extends BaseDialogBean
AVMDifference diff = new AVMDifference(-1, srcPath, -1, destPath, AVMDifference.NEWER);
diffs.add(diff);
// recursively remove locks from this item
recursivelyRemoveLocks(this.avmBrowseBean.getWebProject().getStoreId(), -1, srcPath);
// If nothing has required notifying the virtualization server
// so far, check to see if destPath forces a notification
// (e.g.: it might be a path to a jar file within WEB-INF/lib).
if ( (this.virtUpdatePath == null) &&
VirtServerUtils.requiresUpdateNotification( destPath )
)
VirtServerUtils.requiresUpdateNotification( destPath ) )
{
this.virtUpdatePath = destPath;
}
@@ -396,6 +407,27 @@ public class SubmitDialog extends BaseDialogBean
return outcome;
}
/**
* Recursively remove locks from a path. Walking child folders looking for files
* to remove locks from.
*/
private void recursivelyRemoveLocks(String webProject, int version, String path)
{
AVMNodeDescriptor desc = this.avmService.lookup(version, path, true);
if (desc.isFile() || desc.isDeletedFile())
{
this.avmLockingService.removeLock(webProject, path.substring(path.indexOf(":") + 1));
}
else
{
Map<String, AVMNodeDescriptor> list = avmService.getDirectoryListing(version, path, true);
for (AVMNodeDescriptor child : list.values())
{
recursivelyRemoveLocks(webProject, version, child.getPath());
}
}
}
/**
* Handle notification to the virtualization server

View File

@@ -48,6 +48,8 @@ import org.alfresco.web.ui.repo.component.UILockIcon;
*/
public class UIAVMLockIcon extends UILockIcon
{
public static final String ALFRESCO_FACES_AVMLOCKICON = "org.alfresco.faces.AVMLockIcon";
// ------------------------------------------------------------------------------
// Component implementation
@@ -56,7 +58,7 @@ public class UIAVMLockIcon extends UILockIcon
*/
public String getFamily()
{
return "org.alfresco.faces.AVMLockIcon";
return ALFRESCO_FACES_AVMLOCKICON;
}
@@ -77,7 +79,7 @@ public class UIAVMLockIcon extends UILockIcon
boolean locked = false;
boolean lockedOwner = false;
Object val = getValue();
List<String> lockUser = null;
List<String> lockUsers = null;
final String avmPath = (val instanceof NodeRef
? AVMNodeConverter.ToAVMVersionPath((NodeRef)val).getSecond()
: (val instanceof String
@@ -93,15 +95,14 @@ public class UIAVMLockIcon extends UILockIcon
{
locked = true;
final User currentUser = Application.getCurrentUser(context);
lockUser = lock.getOwners();
lockedOwner = (webProject.isManager(currentUser) ||
lockUser.contains(currentUser.getUserName()));
lockUsers = lock.getOwners();
lockedOwner = (lockUsers.contains(currentUser.getUserName()));
}
}
}
this.encodeBegin(context,
locked,
lockedOwner,
lockUser == null ? new String[0] : (String[])lockUser.toArray(new String[lockUser.size()]));
lockUsers == null ? new String[0] : (String[])lockUsers.toArray(new String[lockUsers.size()]));
}
}

View File

@@ -719,7 +719,8 @@ public class UIUserSandboxes extends SelfRenderingComponent
out.write("</a></td><td>");
out.write(linkPrefix);
out.write(name);
UIAVMLockIcon lockIcon = (UIAVMLockIcon)fc.getApplication().createComponent("org.alfresco.faces.AVMLockIcon");
UIAVMLockIcon lockIcon = (UIAVMLockIcon)fc.getApplication().createComponent(
UIAVMLockIcon.ALFRESCO_FACES_AVMLOCKICON);
lockIcon.setId("lock_" + FacesHelper.makeLegalId(name));
lockIcon.setValue(sourcePath);
Utils.encodeRecursive(fc, lockIcon);

View File

@@ -3054,6 +3054,10 @@
<property-name>avmService</property-name>
<value>#{AVMService}</value>
</managed-property>
<managed-property>
<property-name>avmLockingService</property-name>
<value>#{AVMLockingService}</value>
</managed-property>
<managed-property>
<property-name>avmBrowseBean</property-name>
<value>#{AVMBrowseBean}</value>
@@ -3196,10 +3200,6 @@
<property-name>avmService</property-name>
<value>#{AVMService}</value>
</managed-property>
<managed-property>
<property-name>avmLockingService</property-name>
<value>#{AVMLockingService}</value>
</managed-property>
<managed-property>
<property-name>fileFolderService</property-name>
<value>#{FileFolderService}</value>
@@ -3397,6 +3397,10 @@
<property-name>avmSyncService</property-name>
<value>#{AVMSyncService}</value>
</managed-property>
<managed-property>
<property-name>avmLockingService</property-name>
<value>#{AVMLockingService}</value>
</managed-property>
<managed-property>
<property-name>avmBrowseBean</property-name>
<value>#{AVMBrowseBean}</value>