diff --git a/config/alfresco/subsystems/fileServers/default/file-servers-context.xml b/config/alfresco/subsystems/fileServers/default/file-servers-context.xml index 55bd006d7e..12f7a59527 100644 --- a/config/alfresco/subsystems/fileServers/default/file-servers-context.xml +++ b/config/alfresco/subsystems/fileServers/default/file-servers-context.xml @@ -386,10 +386,7 @@ ${filesystem.renameShufflePattern} - - - __Alfresco.url - + true @@ -399,6 +396,27 @@ + + + + ${cifs.pseudoFiles.enabled} + + + + + ${cifs.pseudoFiles.explorerURL.enabled} + + + ${cifs.pseudoFiles.explorerURL.fileName} + + + + + ${cifs.pseudoFiles.shareURL.enabled} + + + ${cifs.pseudoFiles.shareURL.fileName} + @@ -468,6 +486,8 @@ Write --> + + diff --git a/config/alfresco/subsystems/fileServers/default/file-servers.properties b/config/alfresco/subsystems/fileServers/default/file-servers.properties index 20df2642a2..2b6802f1ba 100644 --- a/config/alfresco/subsystems/fileServers/default/file-servers.properties +++ b/config/alfresco/subsystems/fileServers/default/file-servers.properties @@ -49,6 +49,17 @@ cifs.WINS.secondary=5.6.7.8 # PKTSTATS, THREADPOOL, BENCHMARK cifs.sessionDebug= +# Big Switch, are the Desktop Actions and URL shortcuts shown for CIFS ? +cifs.pseudoFiles.enabled=true + +# CIFS URL for alfresco explorer +cifs.pseudoFiles.explorerURL.enabled=true +cifs.pseudoFiles.explorerURL.fileName=__Alfresco.url + +# Cifs URL for alfresco share +cifs.pseudoFiles.shareURL.enabled=false +cifs.pseudoFiles.shareURL.fileName=__Share.url + ### FTP Server Configuration ### ftp.enabled=true ftp.port=21 diff --git a/source/java/org/alfresco/filesys/alfresco/AlfrescoContext.java b/source/java/org/alfresco/filesys/alfresco/AlfrescoContext.java index 0892cb3684..9c005e9554 100644 --- a/source/java/org/alfresco/filesys/alfresco/AlfrescoContext.java +++ b/source/java/org/alfresco/filesys/alfresco/AlfrescoContext.java @@ -54,6 +54,10 @@ import org.springframework.extensions.config.element.GenericConfigElement; public abstract class AlfrescoContext extends DiskDeviceContext { private SysAdminParams sysAdminParams; + + private boolean pseudoFilesEnabled = false; + private boolean isAlfrescoURLEnabled = false; + private boolean isShareURLEnabled = false; // Debug levels @@ -72,6 +76,7 @@ public abstract class AlfrescoContext extends DiskDeviceContext // URL pseudo file web path prefix (server/port/webapp) and link file name private String m_urlFileName; + private String m_shareUrlFileName; // Pseudo file interface @@ -233,20 +238,21 @@ public abstract class AlfrescoContext extends DiskDeviceContext } - /** - * Determine if the URL pseudo file is enabled - * - * @return boolean - */ - public final boolean hasURLFile() - { - if (m_urlFileName != null) - return true; - return false; - } - +// /** +// * Determine if the URL pseudo file is enabled +// * +// * @return boolean +// */ +// public final boolean hasURLFile() +// { +// if (m_urlFileName != null) +// return true; +// return false; +// } +// /** * Return the URL pseudo file path prefix + * @deprecated - does not know about share * * @return String */ @@ -265,6 +271,17 @@ public abstract class AlfrescoContext extends DiskDeviceContext return m_urlFileName; } + /** + * Return the Share URL pseudo file name + * + * @return String + */ + public final String getShareURLFileName() + { + return m_shareUrlFileName; + } + + /** * Set the URL pseudo file name * @@ -283,6 +300,25 @@ public abstract class AlfrescoContext extends DiskDeviceContext enabledPseudoFileInterface(); } } + + /** + * Set the Share URL pseudo file name + * + * @param urlFileName String + */ + public final void setShareURLFileName(String urlFileName) + { + m_shareUrlFileName = urlFileName; + + // URL file name must end with .url + if (urlFileName != null) + { + if (!urlFileName.endsWith(".url")) + throw new AlfrescoRuntimeException("URL Share link file must end with .url, " + urlFileName); + + enabledPseudoFileInterface(); + } + } /** * Set the desktop actions @@ -444,4 +480,34 @@ public abstract class AlfrescoContext extends DiskDeviceContext this.opLockManager = opLockManager; } + public void setPseudoFilesEnabled(boolean enablePseudoFiles) + { + this.pseudoFilesEnabled = enablePseudoFiles; + } + + public boolean isPseudoFilesEnabled() + { + return pseudoFilesEnabled; + } + + public void setAlfrescoURLEnabled(boolean isAlfrescoURLEnabled) + { + this.isAlfrescoURLEnabled = isAlfrescoURLEnabled; + } + + public boolean isAlfrescoURLEnabled() + { + return isAlfrescoURLEnabled; + } + + public void setShareURLEnabled(boolean isShareURLEnabled) + { + this.isShareURLEnabled = isShareURLEnabled; + } + + public boolean isShareURLEnabled() + { + return isShareURLEnabled; + } + } diff --git a/source/java/org/alfresco/filesys/alfresco/PseudoFileImpl.java b/source/java/org/alfresco/filesys/alfresco/PseudoFileImpl.java index 14e58bfc0c..5c16a2fe50 100644 --- a/source/java/org/alfresco/filesys/alfresco/PseudoFileImpl.java +++ b/source/java/org/alfresco/filesys/alfresco/PseudoFileImpl.java @@ -93,7 +93,7 @@ public class PseudoFileImpl implements PseudoFileInterface // Check if the URL file is enabled - if ( isPseudo == false && ctx.hasURLFile()) + if ( isPseudo == false && ctx.isAlfrescoURLEnabled()) { // Check if it is the URL file name @@ -204,7 +204,7 @@ public class PseudoFileImpl implements PseudoFileInterface // Add the URL link pseudo file, if enabled - if ( isCIFS && ctx.hasURLFile()) + if ( isCIFS && ctx.isAlfrescoURLEnabled()) { // Make sure the state has the associated node details diff --git a/source/java/org/alfresco/filesys/alfresco/PseudoFileOverlayImpl.java b/source/java/org/alfresco/filesys/alfresco/PseudoFileOverlayImpl.java index 86a7dc8c00..3210c6ee2a 100644 --- a/source/java/org/alfresco/filesys/alfresco/PseudoFileOverlayImpl.java +++ b/source/java/org/alfresco/filesys/alfresco/PseudoFileOverlayImpl.java @@ -26,6 +26,9 @@ import org.alfresco.jlan.server.filesys.pseudo.MemoryPseudoFile; import org.alfresco.jlan.server.filesys.pseudo.PseudoFile; import org.alfresco.jlan.server.filesys.pseudo.PseudoFileList; import org.alfresco.jlan.util.WildCard; +import org.alfresco.model.ContentModel; +import org.alfresco.repo.admin.SysAdminParams; +import org.alfresco.repo.site.SiteModel; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeService; import org.alfresco.util.PropertyCheck; @@ -41,6 +44,7 @@ import org.apache.commons.logging.LogFactory; * */ public class PseudoFileOverlayImpl implements PseudoFileOverlay { + private SysAdminParams sysAdminParams; private AlfrescoContext context; private NodeService nodeService; @@ -52,6 +56,7 @@ public class PseudoFileOverlayImpl implements PseudoFileOverlay { PropertyCheck.mandatory(this, "nodeService", getNodeService()); PropertyCheck.mandatory(this, "context", context); + PropertyCheck.mandatory(this, "sysAdminParams", sysAdminParams); DesktopActionTable actions = context.getDesktopActions(); @@ -76,9 +81,9 @@ public class PseudoFileOverlayImpl implements PseudoFileOverlay } } - private PseudoFile generateURLShortcut(NodeRef nodeRef) + private PseudoFile generateAlfrescoURLShortcut(NodeRef nodeRef) { - if ( context.hasURLFile()) + if ( context.isAlfrescoURLEnabled()) { // Make sure the state has the associated node details @@ -88,7 +93,7 @@ public class PseudoFileOverlayImpl implements PseudoFileOverlay urlStr.append("[InternetShortcut]\r\n"); urlStr.append("URL="); - urlStr.append(context.getURLPrefix()); + urlStr.append(getAlfrescoURLPrefix()); urlStr.append("navigate/browse/workspace/SpacesStore/"); urlStr.append( nodeRef.getId()); urlStr.append("\r\n"); @@ -102,6 +107,109 @@ public class PseudoFileOverlayImpl implements PseudoFileOverlay } return null; } + + /** + * Return the site name if the node ref is in a document library + * Return null if the document is not in a site + */ + // MER URRGH - copied from IMAP service - I don't like it there either! + private String getSiteForNode(NodeRef nodeRef) + { + if(logger.isDebugEnabled()) + { + logger.debug("get site for node:" + nodeRef); + } + boolean isInDocLibrary = false; + + NodeRef parent = nodeService.getPrimaryParent(nodeRef).getParentRef(); + + while (parent != null && !nodeService.getType(parent).equals(SiteModel.TYPE_SITE)) + { + String parentName = (String) nodeService.getProperty(parent, ContentModel.PROP_NAME); + if (parentName.equalsIgnoreCase("documentlibrary")) + { + isInDocLibrary = true; + } + + parent = nodeService.getPrimaryParent(parent).getParentRef(); + } + + if (parent == null) + { + logger.debug("folder is not in a site"); + return null; + } + else + { + if(isInDocLibrary) + { + if(nodeService.getType(parent).equals(SiteModel.TYPE_SITE)) + { + String siteName = (String)nodeService.getProperty(parent, ContentModel.PROP_NAME); + if(logger.isDebugEnabled()) + { + logger.debug("got a site:" + siteName); + } + return siteName; + } + } + logger.debug("folder is not in doc library"); + + return null; + } + + } + + private PseudoFile generateShareURLShortcut(NodeRef nodeRef) + { + if(logger.isDebugEnabled()) + { + logger.debug("generateShareURLShortcut nodeRef" + nodeRef); + } + if ( context.isShareURLEnabled()) + { +// try +// { + String site = getSiteForNode(nodeRef); +// String site = "wibble"; + if(site != null) + { + // Make sure the state has the associated node details + // Build the URL file data + + StringBuilder urlStr = new StringBuilder(); + + urlStr.append("[InternetShortcut]\r\n"); + urlStr.append("URL="); + urlStr.append(getShareURLPrefix()); + urlStr.append("page/site/"); + urlStr.append(site + "/folder-details?nodeRef="); + urlStr.append(nodeRef.getStoreRef() + "/"); + urlStr.append( nodeRef.getId()); + urlStr.append("\r\n"); + + // Create the in memory pseudo file for the URL link + if(logger.isDebugEnabled()) + { + logger.debug("generateShareURLShortcut url as string:" + urlStr); + } +// + byte[] urlData = urlStr.toString().getBytes(); +// + MemoryPseudoFile urlFile = new MemoryPseudoFile( context.getShareURLFileName(), urlData); + return urlFile; +// } + } +// catch (Throwable t) +// { +// logger.error("unexpected exception ", t); +// return null; +// } + + } + return null; + } + /** * @@ -112,6 +220,22 @@ public class PseudoFileOverlayImpl implements PseudoFileOverlay { return false; } + + if(context.isAlfrescoURLEnabled()) + { + if(context.getURLFileName().equals(name)) + { + return true; + } + } + + if(context.isShareURLEnabled()) + { + if(context.getShareURLFileName().equals(name)) + { + return true; + } + } if(getPseudoFile(parentDir, name) != null) { @@ -136,7 +260,7 @@ public class PseudoFileOverlayImpl implements PseudoFileOverlay return null; } - if(context.hasURLFile()) + if(context.isAlfrescoURLEnabled()) { if(context.getURLFileName().equals(fname)) { @@ -144,7 +268,19 @@ public class PseudoFileOverlayImpl implements PseudoFileOverlay { logger.debug("returning URL pseudo file"); } - return generateURLShortcut(parentDir); + return generateAlfrescoURLShortcut(parentDir); + } + } + + if(context.isShareURLEnabled()) + { + if(context.getShareURLFileName().equals(fname)) + { + if(logger.isDebugEnabled()) + { + logger.debug("returning Share URL pseudo file"); + } + return generateShareURLShortcut(parentDir); } } @@ -194,9 +330,19 @@ public class PseudoFileOverlayImpl implements PseudoFileOverlay } // The URL file is dependent upon the parent dir - if(context.hasURLFile()) + if(context.isAlfrescoURLEnabled()) { - filterList.addFile(generateURLShortcut(parentDir)); + filterList.addFile(generateAlfrescoURLShortcut(parentDir)); + } + + if(context.isShareURLEnabled()) + { + PseudoFile sharePseudoFile = generateShareURLShortcut(parentDir); + + if(sharePseudoFile != null) + { + filterList.addFile(sharePseudoFile); + } } return filterList; @@ -219,11 +365,24 @@ public class PseudoFileOverlayImpl implements PseudoFileOverlay } // The URL file is dependent upon the parent dir - if(context.hasURLFile()) + if(context.isAlfrescoURLEnabled()) { if(wildCard.matchesPattern(context.getURLFileName())) { - filterList.addFile(generateURLShortcut(parentDir)); + filterList.addFile(generateAlfrescoURLShortcut(parentDir)); + } + } + + if(context.isShareURLEnabled()) + { + if(wildCard.matchesPattern(context.getShareURLFileName())) + { + PseudoFile sharePseudoFile = generateShareURLShortcut(parentDir); + + if(sharePseudoFile != null) + { + filterList.addFile(sharePseudoFile); + } } } @@ -266,4 +425,23 @@ public class PseudoFileOverlayImpl implements PseudoFileOverlay { return context; } + + private final String getAlfrescoURLPrefix() + { + return sysAdminParams.getAlfrescoProtocol() + "://" + sysAdminParams.getAlfrescoHost() + ":" + sysAdminParams.getAlfrescoPort() + "/" + sysAdminParams.getAlfrescoContext() + "/"; + } + private final String getShareURLPrefix() + { + return sysAdminParams.getShareProtocol() + "://" + sysAdminParams.getShareHost() + ":" + sysAdminParams.getSharePort() + "/" + sysAdminParams.getShareContext() + "/"; + } + + public void setSysAdminParams(SysAdminParams sysAdminParams) + { + this.sysAdminParams = sysAdminParams; + } + + public SysAdminParams getSysAdminParams() + { + return sysAdminParams; + } } diff --git a/source/java/org/alfresco/filesys/repo/ContentDiskDriver2.java b/source/java/org/alfresco/filesys/repo/ContentDiskDriver2.java index 5c0e078daa..174eec1873 100644 --- a/source/java/org/alfresco/filesys/repo/ContentDiskDriver2.java +++ b/source/java/org/alfresco/filesys/repo/ContentDiskDriver2.java @@ -601,6 +601,7 @@ public class ContentDiskDriver2 extends AlfrescoDiskDriver implements ExtendedD PseudoFileOverlayImpl ps = new PseudoFileOverlayImpl(); ps.setContext(context); ps.setNodeService(nodeService); + ps.setSysAdminParams(context.getSysAdminParams()); context.setPseudoFileOverlay(ps); ps.init(); } @@ -651,7 +652,7 @@ public class ContentDiskDriver2 extends AlfrescoDiskDriver implements ExtendedD FileInfo finfo = null; // Is the node a pseudo file ? - if(session.isPseudoFilesEnabled()) + if(session.isPseudoFilesEnabled() && ctx.isPseudoFilesEnabled()) { String[] paths = FileName.splitPath(path); // lookup parent directory @@ -798,7 +799,7 @@ public class ContentDiskDriver2 extends AlfrescoDiskDriver implements ExtendedD * Search pseudo files if they are enabled */ PseudoFileList pseudoList = null; - if(session.isPseudoFilesEnabled()) + if(session.isPseudoFilesEnabled() && ctx.isPseudoFilesEnabled()) { logger.debug("search pseudo files"); pseudoList = ctx.getPseudoFileOverlay().searchPseudoFiles(dirNodeRef, searchFileSpec); @@ -829,11 +830,11 @@ public class ContentDiskDriver2 extends AlfrescoDiskDriver implements ExtendedD } catch (AlfrescoRuntimeException ex) { - // Debug + // This is an error even though we "handle" it here. - if ( logger.isDebugEnabled()) + if ( logger.isErrorEnabled()) { - logger.debug("Exception in Start search", ex); + logger.error("Exception in Start search", ex); } // Convert to a file not found status @@ -862,7 +863,7 @@ public class ContentDiskDriver2 extends AlfrescoDiskDriver implements ExtendedD int status = FileStatus.Unknown; try { - if(session.isPseudoFilesEnabled()) + if(session.isPseudoFilesEnabled() && ctx.isPseudoFilesEnabled()) { String[] paths = FileName.splitPath(name); // lookup parent directory @@ -945,7 +946,7 @@ public class ContentDiskDriver2 extends AlfrescoDiskDriver implements ExtendedD { String name = params.getPath(); - if(session.isPseudoFilesEnabled()) + if(session.isPseudoFilesEnabled() && ctx.isPseudoFilesEnabled()) { String[] paths = FileName.splitPath(name); // lookup parent directory @@ -1683,7 +1684,7 @@ public class ContentDiskDriver2 extends AlfrescoDiskDriver implements ExtendedD try { - if(session.isPseudoFilesEnabled()) + if(session.isPseudoFilesEnabled() && ctx.isPseudoFilesEnabled()) { String[] paths = FileName.splitPath(name); // lookup parent directory @@ -1919,7 +1920,7 @@ public class ContentDiskDriver2 extends AlfrescoDiskDriver implements ExtendedD try { - if(sess.isPseudoFilesEnabled()) + if(sess.isPseudoFilesEnabled() && ctx.isPseudoFilesEnabled()) { String[] paths = FileName.splitPath(name); // lookup parent directory