diff --git a/source/java/org/alfresco/web/bean/wcm/AVMBrowseBean.java b/source/java/org/alfresco/web/bean/wcm/AVMBrowseBean.java index 2056a59bda..e9147f95c6 100644 --- a/source/java/org/alfresco/web/bean/wcm/AVMBrowseBean.java +++ b/source/java/org/alfresco/web/bean/wcm/AVMBrowseBean.java @@ -1329,7 +1329,7 @@ public class AVMBrowseBean implements IContextListener String type = ""; if (avmRef.getType() == AVMNodeType.LAYERED_DIRECTORY && avmRef.isPrimary()) { - if (getAvmService().lookup(avmRef.getIndirectionVersion(), avmRef.getIndirection()) != null) + if ((getAvmService().lookup(avmRef.getIndirectionVersion(), avmRef.getIndirection()) != null) || (avmRef.getOpacity())) { type = Application.getMessage(FacesContext.getCurrentInstance(), "shared_folder"); } @@ -1348,9 +1348,9 @@ public class AVMBrowseBean implements IContextListener } else { - String type = "file"; - if (avmRef.isLayeredFile()) - { + String type = ""; + if (avmRef.isLayeredFile()) + { if (getAvmService().lookup(avmRef.getIndirectionVersion(), avmRef.getIndirection()) != null) { type = Application.getMessage(FacesContext.getCurrentInstance(), "shared_file"); @@ -1359,12 +1359,17 @@ public class AVMBrowseBean implements IContextListener { type = Application.getMessage(FacesContext.getCurrentInstance(), "stale_shared_file"); } - } - - node.getProperties().put("fileType", type); + } + else + { + type = Application.getMessage(FacesContext.getCurrentInstance(), "file"); + } + + node.getProperties().put("fileType", type); node.getProperties().put("fileType16", FileTypeImageUtils.getFileTypeImage(avmRef.getName(), true)); node.getProperties().put("url", DownloadContentServlet.generateBrowserURL( AVMNodeConverter.ToNodeRef(-1, avmRef.getPath()), avmRef.getName())); + this.files.add(node); } @@ -1430,7 +1435,10 @@ public class AVMBrowseBean implements IContextListener String path = params.get("id"); AVMNodeDescriptor avmNode = getAvmService().lookup(-1, path); - if (avmNode.isLayeredDirectory() && avmNode.isPrimary() && (getAvmService().lookup(avmNode.getIndirectionVersion(), avmNode.getIndirection()) == null)) + if (avmNode.isLayeredDirectory() && avmNode.isPrimary() && + (getAvmService().lookup(avmNode.getIndirectionVersion(), avmNode.getIndirection()) == null) && + (! avmNode.getOpacity()) && + getAvmService().getDirectoryListingDirect(avmNode, false).isEmpty()) { String pattern = Application.getMessage(FacesContext.getCurrentInstance(), MSG_TARGET_IS_DELETED); String folderName = path.substring(path.lastIndexOf("/") + 1); diff --git a/source/java/org/alfresco/web/forms/FormImpl.java b/source/java/org/alfresco/web/forms/FormImpl.java index 31c10e6cb0..16cb5d8e85 100644 --- a/source/java/org/alfresco/web/forms/FormImpl.java +++ b/source/java/org/alfresco/web/forms/FormImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005-2007 Alfresco Software Limited. + * Copyright (C) 2005-2009 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 @@ -38,7 +38,6 @@ import javax.faces.context.FacesContext; import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.model.ContentModel; import org.alfresco.model.WCMAppModel; -import org.alfresco.repo.avm.AVMNodeConverter; import org.alfresco.service.ServiceRegistry; import org.alfresco.service.cmr.repository.AssociationRef; import org.alfresco.service.cmr.repository.ChildAssociationRef; @@ -213,7 +212,7 @@ public class FormImpl implements Form result = AVMUtil.buildPath(parentAVMPath, result, AVMUtil.PathRelation.SANDBOX_RELATIVE); - result = AVMNodeConverter.NormalizePath(result); + result = AVMUtil.normalizePath(result); LOGGER.debug("processed pattern " + outputPathPattern + " as " + result); return result; } diff --git a/source/java/org/alfresco/web/ui/wcm/component/UIAVMLockIcon.java b/source/java/org/alfresco/web/ui/wcm/component/UIAVMLockIcon.java index 5c58939a88..2b881e9a1d 100644 --- a/source/java/org/alfresco/web/ui/wcm/component/UIAVMLockIcon.java +++ b/source/java/org/alfresco/web/ui/wcm/component/UIAVMLockIcon.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005-2007 Alfresco Software Limited. + * Copyright (C) 2005-2009 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 @@ -25,21 +25,20 @@ package org.alfresco.web.ui.wcm.component; import java.io.IOException; +import java.util.ArrayList; import java.util.List; import javax.faces.context.FacesContext; import org.alfresco.repo.avm.AVMNodeConverter; -import org.alfresco.service.cmr.avm.AVMService; +import org.alfresco.service.cmr.avm.AVMNotFoundException; import org.alfresco.service.cmr.avm.locking.AVMLock; import org.alfresco.service.cmr.avm.locking.AVMLockingService; import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.wcm.asset.AssetInfo; +import org.alfresco.wcm.util.WCMUtil; import org.alfresco.web.app.Application; -import org.alfresco.web.app.servlet.FacesHelper; import org.alfresco.web.bean.repository.Repository; -import org.alfresco.web.bean.wcm.AVMBrowseBean; -import org.alfresco.web.bean.wcm.AVMUtil; -import org.alfresco.web.bean.wcm.WebProject; import org.alfresco.web.ui.repo.component.UILockIcon; /** @@ -70,45 +69,69 @@ public class UIAVMLockIcon extends UILockIcon return; } - // get the value and see if the image is locked - final AVMService avmService = Repository.getServiceRegistry(context).getAVMService(); - final AVMLockingService avmLockingService = Repository.getServiceRegistry(context).getAVMLockingService(); - final AVMBrowseBean avmBrowseBean = (AVMBrowseBean)FacesHelper.getManagedBean(context, AVMBrowseBean.BEAN_NAME); - boolean locked = false; boolean lockedOwner = false; Object val = getValue(); List lockUsers = null; - final String avmPath = (val instanceof NodeRef - ? AVMNodeConverter.ToAVMVersionPath((NodeRef)val).getSecond() - : (val instanceof String - ? (String)val - : null)); - if (avmPath != null) + + if (val != null) { - if (avmService.lookup(-1, avmPath) != null) + if (val instanceof AssetInfo) { - // optimization to reuse the current WebProject object if it represents the - // same webproject that the lock item path is contained within - this ensures - // we do not perform slow store property lookups for every UIAVMLockIcon instance - String stagingStore = AVMUtil.buildStagingStoreName(AVMUtil.getStoreId(AVMUtil.getStoreName(avmPath))); - WebProject webProject = avmBrowseBean.getWebProject(); - if (webProject == null || !webProject.getStagingStore().equals(stagingStore)) + // via UIUserSandboxes.renderUserFiles() + + AssetInfo asset = (AssetInfo)val; + + locked = asset.isLocked(); + + String assetLockOwner = asset.getLockOwner(); + if (assetLockOwner != null) { - webProject = new WebProject(avmPath); - } - AVMLock lock = avmLockingService.getLock(webProject.getStoreId(), avmPath.substring(avmPath.indexOf("/"))); - if (lock != null) - { - locked = true; - lockUsers = lock.getOwners(); - lockedOwner = (lockUsers.contains(Application.getCurrentUser(context).getUserName())); + lockUsers = new ArrayList(1); + lockUsers.add(assetLockOwner); + lockedOwner = assetLockOwner.equals(Application.getCurrentUser(context).getUserName()); } } + else + { + // TODO eventually refactor out + + // via browse-sandbox.jsp -> AVMBrowseBean (getFolders/getFiles - directory listing or search) + + // get the value and see if the image is locked + final AVMLockingService avmLockingService = Repository.getServiceRegistry(context).getAVMLockingService(); + + // NodeRef or String + final String avmPath = (val instanceof NodeRef + ? AVMNodeConverter.ToAVMVersionPath((NodeRef)val).getSecond() + : (val instanceof String + ? (String)val + : null)); + if (avmPath != null) + { + String[] pathParts = WCMUtil.splitPath(avmPath); + AVMLock lock = null; + try + { + lock = avmLockingService.getLock(WCMUtil.getWebProjectStoreId(pathParts[0]), pathParts[1]); + } + catch (AVMNotFoundException nfe) + { + // ignore + } + if (lock != null) + { + locked = true; + lockUsers = lock.getOwners(); + lockedOwner = (lockUsers.contains(Application.getCurrentUser(context).getUserName())); + } + } + } + + this.encodeBegin(context, + locked, + lockedOwner, + lockUsers == null ? new String[0] : (String[])lockUsers.toArray(new String[lockUsers.size()])); } - this.encodeBegin(context, - locked, - lockedOwner, - lockUsers == null ? new String[0] : (String[])lockUsers.toArray(new String[lockUsers.size()])); } } diff --git a/source/java/org/alfresco/web/ui/wcm/component/UIUserSandboxes.java b/source/java/org/alfresco/web/ui/wcm/component/UIUserSandboxes.java index 5d7c6d46ed..87231cc855 100644 --- a/source/java/org/alfresco/web/ui/wcm/component/UIUserSandboxes.java +++ b/source/java/org/alfresco/web/ui/wcm/component/UIUserSandboxes.java @@ -734,10 +734,19 @@ public class UIUserSandboxes extends SelfRenderingComponent implements Serializa String stagingStore = AVMUtil.buildStagingStoreName(storeRoot); String stagingStorePath = AVMUtil.buildStoreWebappPath(stagingStore, getWebapp()); + long start = System.currentTimeMillis(); + List assets = sandboxService.listChangedWebApp(userStore, getWebapp(), true); + if (logger.isDebugEnabled()) + { + logger.debug("List "+assets.size()+" changes webapp in "+(System.currentTimeMillis()-start)+" msecs"); + } + if (assets.size() != 0) { + start = System.currentTimeMillis(); + // output confict header, only if conflicts exist int diffCount = 0; for (AssetInfo asset : assets) @@ -891,7 +900,7 @@ public class UIUserSandboxes extends SelfRenderingComponent implements Serializa out.write(""); UIAVMLockIcon lockIcon = (UIAVMLockIcon)fc.getApplication().createComponent(UIAVMLockIcon.ALFRESCO_FACES_AVMLOCKICON); lockIcon.setId("avmlock_" + Integer.toString(rowIndex)); - lockIcon.setValue(sourcePath); + lockIcon.setValue(node); Utils.encodeRecursive(fc, lockIcon); out.write(""); out.write(linkPrefix); @@ -993,6 +1002,11 @@ public class UIUserSandboxes extends SelfRenderingComponent implements Serializa // end table out.write(""); + + if (logger.isDebugEnabled()) + { + logger.debug("Wrote table in "+(System.currentTimeMillis()-start)+" msecs"); + } } else { diff --git a/source/java/org/alfresco/web/ui/wcm/renderer/AVMListRenderer.java b/source/java/org/alfresco/web/ui/wcm/renderer/AVMListRenderer.java index 9fe96e712e..15ad2d37e6 100644 --- a/source/java/org/alfresco/web/ui/wcm/renderer/AVMListRenderer.java +++ b/source/java/org/alfresco/web/ui/wcm/renderer/AVMListRenderer.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005-2007 Alfresco Software Limited. + * Copyright (C) 2005-2009 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 @@ -67,7 +67,8 @@ public class AVMListRenderer extends RichListRenderer if ((avmRef.isLayeredDirectory() && avmRef.isPrimary()) || avmRef.isLayeredFile()) { AVMService avmService = Repository.getServiceRegistry(context).getAVMService(); - if (avmService.lookup(avmRef.getIndirectionVersion(), avmRef.getIndirection()) == null) + if ((avmService.lookup(avmRef.getIndirectionVersion(), avmRef.getIndirection()) == null) && + (! avmRef.getOpacity())) { rowStyle = STALE_CSS; } diff --git a/source/web/jsp/admin/avm-console-help.txt b/source/web/jsp/admin/avm-console-help.txt index 89e5c64d10..950712286d 100644 --- a/source/web/jsp/admin/avm-console-help.txt +++ b/source/web/jsp/admin/avm-console-help.txt @@ -15,6 +15,8 @@ To quit / exit, close this window or tab (and logout from Alfresco Explorer or c Individual Commands: +------ + ls - Lists the contents of the given directory. ls, avmpath, #versionnumber# @@ -49,8 +51,12 @@ lsrep lsver - Lists the versions in a given store. lsver, storename +lsver, storename, fromDate +lsver, storename, fromDate, toDate -storename is the name of the store (alphanumeric). +storename - name of the store (alphanumeric). + +fromDate, toDate in ISO 8601 format (eg. 'YYYY-MM-DDThh:mm:ss.sss' where = 'Z' or '+hh:mm' or '-hh:mm') ------ @@ -58,7 +64,7 @@ mkrep - Create a new store. mkrep, storename -storename as above. +storename - as above. ------ @@ -66,6 +72,8 @@ setstoreproperty - Set the value of store property. setstoreproperty, storename, qname, value +storename - as above. + value - the new property value - the type will be auto-detected. At present only TEXT and INT types are suppored as well as collections of these types. Collections can be specified using a comma seperated list enclosed in square brackets. @@ -78,6 +86,8 @@ setstorepermission - Set a permission mask on a store. setstorepermission, storename, authority, permission +storename - as above. + authority - the user or group identifier. permission - the permission name to set. @@ -88,6 +98,8 @@ clearstorepermission - Clears a permission mask on a store for a given authority clearstorepermission, storename, authority +storename - as above. + authority - the user or group identifier. ------ @@ -133,6 +145,16 @@ name is a valid path component name. ------ +setopacity - Set layered directory to be opaque (or not) to its indirection + +setopacity, avmpath, bool + +avmpath is avmpath to the layered directory + +bool is "true" (opaque) or "false" (not opaque) + +------ + rename - Renames a node from one place to another. rename, srcdiravmpath, srcname, dstdiravmpath, dstname @@ -191,22 +213,32 @@ to remove. rmrep - Purges a store, i.e. makes it truly go away. -rmrep, name +rmrep, storename -name is the name of the store to purge. +storename - as above. ------ rmver - Purges a particular version of a store. -rmver, name, #versionnumber# +rmver, storename, #versionnumber# -name is the name of the store. +storename - as above. #versionnmber# is the version to purge. ------ +rmvers - Purges versions of a store between two dates (inclusive). + +rmvers, storename, fromDate, toDate + +storename - as above. + +fromDate, toDate in ISO 8601 format (eg. 'YYYY-MM-DDThh:mm:ss.sss' where = 'Z' or '+hh:mm' or '-hh:mm') + +------ + write - Writes content to an existing file. write, avmpath