From 2905f5ab1a51e15ab010e01c199a4bc3ff0434e5 Mon Sep 17 00:00:00 2001 From: Kevin Roast Date: Mon, 5 Feb 2007 11:48:51 +0000 Subject: [PATCH] . Clipboard inter-store copy support - Inter-store copy between Workspace and AVM stores - Inter-store copy between AVM and Workspace stores . Added CrossRepositoryCopyService to ServiceRegistry git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@5034 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- .../web/bean/clipboard/AVMClipboardItem.java | 85 +++++++++++++++++- .../web/bean/clipboard/ClipboardBean.java | 35 ++++++-- .../web/bean/clipboard/ClipboardItem.java | 11 ++- .../clipboard/WorkspaceClipboardItem.java | 88 ++++++++++++++++++- 4 files changed, 202 insertions(+), 17 deletions(-) diff --git a/source/java/org/alfresco/web/bean/clipboard/AVMClipboardItem.java b/source/java/org/alfresco/web/bean/clipboard/AVMClipboardItem.java index aeaa651ff3..59b517e34c 100644 --- a/source/java/org/alfresco/web/bean/clipboard/AVMClipboardItem.java +++ b/source/java/org/alfresco/web/bean/clipboard/AVMClipboardItem.java @@ -24,9 +24,11 @@ import org.alfresco.service.cmr.avm.AVMExistsException; import org.alfresco.service.cmr.avm.AVMService; import org.alfresco.service.cmr.model.FileExistsException; import org.alfresco.service.cmr.model.FileFolderService; +import org.alfresco.service.cmr.repository.CrossRepositoryCopyService; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.web.app.Application; import org.alfresco.web.app.servlet.FacesHelper; +import org.alfresco.web.bean.NavigationBean; import org.alfresco.web.bean.repository.Repository; import org.alfresco.web.bean.wcm.AVMBrowseBean; @@ -38,6 +40,7 @@ import org.alfresco.web.bean.wcm.AVMBrowseBean; public class AVMClipboardItem extends AbstractClipboardItem { private static final String AVM_PASTE_VIEW_ID = "/jsp/wcm/browse-sandbox.jsp"; + private static final String WORKSPACE_PASTE_VIEW_ID = "/jsp/browse/browse.jsp"; /** * @param ref @@ -57,11 +60,18 @@ public class AVMClipboardItem extends AbstractClipboardItem } /** - * @see org.alfresco.web.bean.clipboard.ClipboardItem#canPasteToViewId(java.lang.String) + * @see org.alfresco.web.bean.clipboard.ClipboardItem#canCopyToViewId(java.lang.String) */ - public boolean canPasteToViewId(String viewId) + public boolean canCopyToViewId(String viewId) + { + return (AVM_PASTE_VIEW_ID.equals(viewId) || WORKSPACE_PASTE_VIEW_ID.equals(viewId)); + } + + /** + * @see org.alfresco.web.bean.clipboard.ClipboardItem#canMoveToViewId(java.lang.String) + */ + public boolean canMoveToViewId(String viewId) { - // TODO: add 'workspace' paste view when interstore copy/move is supported return (AVM_PASTE_VIEW_ID.equals(viewId)); } @@ -173,9 +183,76 @@ public class AVMClipboardItem extends AbstractClipboardItem } return operationComplete; } + else if (WORKSPACE_PASTE_VIEW_ID.equals(viewId)) + { + NavigationBean navigator = (NavigationBean)FacesHelper.getManagedBean(fc, NavigationBean.BEAN_NAME); + NodeRef destRef = new NodeRef(Repository.getStoreRef(), navigator.getCurrentNodeId()); + + CrossRepositoryCopyService crossRepoCopyService = getServiceRegistry().getCrossRepositoryCopyService(); + + // initial name to attempt the copy of the item with + String name = getName(); + + boolean operationComplete = false; + while (operationComplete == false) + { + UserTransaction tx = null; + try + { + // attempt each copy/paste in its own transaction + tx = Repository.getUserTransaction(fc); + tx.begin(); + if (getMode() == ClipboardStatus.COPY) + { + // COPY operation + if (logger.isDebugEnabled()) + logger.debug("Attempting to copy node: " + getNodeRef() + " into node ID: " + destRef.toString()); + + // inter-store copy operation + crossRepoCopyService.copy(getNodeRef(), destRef, name); + + // if we get here without an exception, the clipboard copy operation was successful + operationComplete = true; + } + else + { + // this should not occur as the canMoveToViewId() will return false + throw new Exception("Move operation not supported between stores."); + } + } + catch (FileExistsException fileExistsErr) + { + if (getMode() != ClipboardStatus.COPY) + { + // we should not rename an item when it is being moved - so exit + throw fileExistsErr; + } + } + catch (Throwable e) + { + // some other type of exception occured - rollback and exit + throw e; + } + finally + { + // rollback if the operation didn't complete + if (operationComplete == false) + { + try { if (tx != null) {tx.rollback();} } catch (Exception tex) {} + String copyOf = Application.getMessage(fc, MSG_COPY_OF); + name = copyOf + ' ' + name; + } + else + { + // commit the transaction + tx.commit(); + } + } + } + return operationComplete; + } else { - // TODO: support 'workspace' destination view... return false; } } diff --git a/source/java/org/alfresco/web/bean/clipboard/ClipboardBean.java b/source/java/org/alfresco/web/bean/clipboard/ClipboardBean.java index 8c0d32ab5c..08b8e01adb 100644 --- a/source/java/org/alfresco/web/bean/clipboard/ClipboardBean.java +++ b/source/java/org/alfresco/web/bean/clipboard/ClipboardBean.java @@ -189,20 +189,41 @@ public class ClipboardBean private boolean performClipboardOperation(ClipboardItem item, int action) throws Throwable { + boolean success = false; + FacesContext fc = FacesContext.getCurrentInstance(); // test the current JSF view to see if the clipboard item can paste to it if (logger.isDebugEnabled()) - logger.debug("Clipboard destintation View Id: " + fc.getViewRoot().getViewId()); - if (item.canPasteToViewId(fc.getViewRoot().getViewId()) == false) + logger.debug("Clipboard destination View Id: " + fc.getViewRoot().getViewId()); + if (item.getMode() == ClipboardStatus.CUT) { - // early exit if we cannot support this view as a paste location - if (logger.isDebugEnabled()) - logger.debug("Clipboard Item: " + item.getNodeRef() + " not suitable for paste to current View Id."); - return false; + if (item.canMoveToViewId(fc.getViewRoot().getViewId()) == true) + { + success = item.paste(fc, fc.getViewRoot().getViewId(), action); + } + else + { + // we cannot support this view as a Move paste location + if (logger.isDebugEnabled()) + logger.debug("Clipboard Item: " + item.getNodeRef() + " not suitable for Move paste to current View Id."); + } + } + else if (item.getMode() == ClipboardStatus.COPY) + { + if (item.canCopyToViewId(fc.getViewRoot().getViewId()) == true) + { + success = item.paste(fc, fc.getViewRoot().getViewId(), action); + } + else + { + // we cannot support this view as a Copy paste location + if (logger.isDebugEnabled()) + logger.debug("Clipboard Item: " + item.getNodeRef() + " not suitable for Copy paste to current View Id."); + } } - return item.paste(fc, fc.getViewRoot().getViewId(), action); + return success; } /** diff --git a/source/java/org/alfresco/web/bean/clipboard/ClipboardItem.java b/source/java/org/alfresco/web/bean/clipboard/ClipboardItem.java index 45130dff66..d3a1a3d576 100644 --- a/source/java/org/alfresco/web/bean/clipboard/ClipboardItem.java +++ b/source/java/org/alfresco/web/bean/clipboard/ClipboardItem.java @@ -61,9 +61,16 @@ public interface ClipboardItem /** * @param viewId JSF View Id to check against * - * @return true if the clipboard item can be pasted to the specified JSF view + * @return true if the clipboard item can be Copy pasted to the specified JSF view */ - public boolean canPasteToViewId(String viewId); + public boolean canCopyToViewId(String viewId); + + /** + * @param viewId JSF View Id to check against + * + * @return true if the clipboard item can be Move pasted to the specified JSF view + */ + public boolean canMoveToViewId(String viewId); /** * @param fc FacesContext diff --git a/source/java/org/alfresco/web/bean/clipboard/WorkspaceClipboardItem.java b/source/java/org/alfresco/web/bean/clipboard/WorkspaceClipboardItem.java index 17f49d205c..4a4eb58c61 100644 --- a/source/java/org/alfresco/web/bean/clipboard/WorkspaceClipboardItem.java +++ b/source/java/org/alfresco/web/bean/clipboard/WorkspaceClipboardItem.java @@ -25,11 +25,13 @@ import javax.transaction.UserTransaction; import org.alfresco.model.ApplicationModel; import org.alfresco.model.ContentModel; +import org.alfresco.repo.avm.AVMNodeConverter; import org.alfresco.service.cmr.dictionary.DictionaryService; import org.alfresco.service.cmr.model.FileExistsException; import org.alfresco.service.cmr.model.FileFolderService; import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.CopyService; +import org.alfresco.service.cmr.repository.CrossRepositoryCopyService; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeService; import org.alfresco.service.namespace.QName; @@ -37,6 +39,7 @@ import org.alfresco.web.app.Application; import org.alfresco.web.app.servlet.FacesHelper; import org.alfresco.web.bean.NavigationBean; import org.alfresco.web.bean.repository.Repository; +import org.alfresco.web.bean.wcm.AVMBrowseBean; import org.alfresco.web.ui.repo.component.shelf.UIClipboardShelfItem; /** @@ -47,6 +50,7 @@ import org.alfresco.web.ui.repo.component.shelf.UIClipboardShelfItem; public class WorkspaceClipboardItem extends AbstractClipboardItem { private static final String WORKSPACE_PASTE_VIEW_ID = "/jsp/browse/browse.jsp"; + private static final String AVM_PASTE_VIEW_ID = "/jsp/wcm/browse-sandbox.jsp"; private static final String MSG_LINK_TO = "link_to"; @@ -72,11 +76,18 @@ public class WorkspaceClipboardItem extends AbstractClipboardItem } /** - * @see org.alfresco.web.bean.clipboard.ClipboardItem#canPasteToViewId(java.lang.String) + * @see org.alfresco.web.bean.clipboard.ClipboardItem#canCopyToViewId(java.lang.String) */ - public boolean canPasteToViewId(String viewId) + public boolean canCopyToViewId(String viewId) + { + return (WORKSPACE_PASTE_VIEW_ID.equals(viewId) || AVM_PASTE_VIEW_ID.equals(viewId)); + } + + /** + * @see org.alfresco.web.bean.clipboard.ClipboardItem#canMoveToViewId(java.lang.String) + */ + public boolean canMoveToViewId(String viewId) { - // TODO: add 'avm' paste view when interstore copy/move is supported return (WORKSPACE_PASTE_VIEW_ID.equals(viewId)); } @@ -275,9 +286,78 @@ public class WorkspaceClipboardItem extends AbstractClipboardItem } return operationComplete; } + else if (AVM_PASTE_VIEW_ID.equals(viewId)) + { + AVMBrowseBean avmBrowseBean = (AVMBrowseBean)FacesHelper.getManagedBean(fc, AVMBrowseBean.BEAN_NAME); + + String destPath = avmBrowseBean.getCurrentPath(); + NodeRef destRef = AVMNodeConverter.ToNodeRef(-1, destPath); + + CrossRepositoryCopyService crossRepoCopyService = getServiceRegistry().getCrossRepositoryCopyService(); + + // initial name to attempt the copy of the item with + String name = getName(); + + boolean operationComplete = false; + while (operationComplete == false) + { + UserTransaction tx = null; + try + { + // attempt each copy/paste in its own transaction + tx = Repository.getUserTransaction(fc); + tx.begin(); + if (getMode() == ClipboardStatus.COPY) + { + // COPY operation + if (logger.isDebugEnabled()) + logger.debug("Attempting to copy node: " + getNodeRef() + " into node ID: " + destRef.toString()); + + // inter-store copy operation + crossRepoCopyService.copy(getNodeRef(), destRef, name); + + // if we get here without an exception, the clipboard copy operation was successful + operationComplete = true; + } + else + { + // this should not occur as the canMoveToViewId() will return false + throw new Exception("Move operation not supported between stores."); + } + } + catch (FileExistsException fileExistsErr) + { + if (getMode() != ClipboardStatus.COPY) + { + // we should not rename an item when it is being moved - so exit + throw fileExistsErr; + } + } + catch (Throwable e) + { + // some other type of exception occured - rollback and exit + throw e; + } + finally + { + // rollback if the operation didn't complete + if (operationComplete == false) + { + try { if (tx != null) {tx.rollback();} } catch (Exception tex) {} + String copyOf = Application.getMessage(fc, MSG_COPY_OF); + name = copyOf + ' ' + name; + } + else + { + // commit the transaction + tx.commit(); + } + } + } + return operationComplete; + } else { - // TODO: support 'avm' destination view... return false; } }