From b4d2db1017ecb1531d04189088b2c2906e8ebcab Mon Sep 17 00:00:00 2001 From: Gary Spencer Date: Fri, 27 Jan 2006 15:36:32 +0000 Subject: [PATCH] Added URL link pseudo files support. Split pseudo file classes to allow local filesystem and in memory pseudo files. Drag/drop and URL link pseudo files now only appear when using CIFS. git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@2229 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- .../filesys/smb/mailslot/HostAnnouncer.java | 9 + .../smb/server/repo/ContentContext.java | 57 ++++ .../smb/server/repo/ContentDiskDriver.java | 116 +++++++- .../smb/server/repo/ContentSearchContext.java | 89 +----- .../repo/pseudo/ContentPseudoFileImpl.java | 51 +++- .../server/repo/pseudo/LocalPseudoFile.java | 110 ++++++++ .../server/repo/pseudo/MemoryNetworkFile.java | 261 ++++++++++++++++++ .../server/repo/pseudo/MemoryPseudoFile.java | 95 +++++++ .../smb/server/repo/pseudo/PseudoFile.java | 78 ++---- 9 files changed, 703 insertions(+), 163 deletions(-) create mode 100644 source/java/org/alfresco/filesys/smb/server/repo/pseudo/LocalPseudoFile.java create mode 100644 source/java/org/alfresco/filesys/smb/server/repo/pseudo/MemoryNetworkFile.java create mode 100644 source/java/org/alfresco/filesys/smb/server/repo/pseudo/MemoryPseudoFile.java diff --git a/source/java/org/alfresco/filesys/smb/mailslot/HostAnnouncer.java b/source/java/org/alfresco/filesys/smb/mailslot/HostAnnouncer.java index 117cc44a20..aa832c43da 100644 --- a/source/java/org/alfresco/filesys/smb/mailslot/HostAnnouncer.java +++ b/source/java/org/alfresco/filesys/smb/mailslot/HostAnnouncer.java @@ -19,6 +19,7 @@ package org.alfresco.filesys.smb.mailslot; import java.io.IOException; import org.alfresco.filesys.netbios.NetBIOSName; +import org.alfresco.filesys.netbios.win32.WinsockNetBIOSException; import org.alfresco.filesys.smb.ServerType; import org.alfresco.filesys.smb.TransactionNames; import org.alfresco.filesys.util.StringList; @@ -323,6 +324,14 @@ public abstract class HostAnnouncer extends Thread sleepTime = sleepNormal; } } + catch (WinsockNetBIOSException ex) + { + // Debug + + if (m_shutdown == false) + logger.error("HostAnnouncer error", ex); + m_shutdown = true; + } catch ( IOException ex) { // Debug diff --git a/source/java/org/alfresco/filesys/smb/server/repo/ContentContext.java b/source/java/org/alfresco/filesys/smb/server/repo/ContentContext.java index 4658f4f29a..b024f5233c 100644 --- a/source/java/org/alfresco/filesys/smb/server/repo/ContentContext.java +++ b/source/java/org/alfresco/filesys/smb/server/repo/ContentContext.java @@ -46,6 +46,11 @@ public class ContentContext extends DiskDeviceContext private PseudoFile m_dragAndDropApp; + // URL pseudo file web path prefix (server/port/webapp) and link file name + + private String m_urlPathPrefix; + private String m_urlFileName; + /** * Class constructor * @@ -159,6 +164,38 @@ public class ContentContext extends DiskDeviceContext { return m_dragAndDropApp; } + + /** + * Determine if the URL pseudo file is enabled + * + * @return boolean + */ + public final boolean hasURLFile() + { + if ( m_urlPathPrefix != null && m_urlFileName != null) + return true; + return false; + } + + /** + * Return the URL pseudo file path prefix + * + * @return String + */ + public final String getURLPrefix() + { + return m_urlPathPrefix; + } + + /** + * Return the URL pseudo file name + * + * @return String + */ + public final String getURLFileName() + { + return m_urlFileName; + } /** * Set the drag and drop application details @@ -169,4 +206,24 @@ public class ContentContext extends DiskDeviceContext { m_dragAndDropApp = dragDropApp; } + + /** + * Set the URL path prefix + * + * @param urlPrefix String + */ + public final void setURLPrefix(String urlPrefix) + { + m_urlPathPrefix = urlPrefix; + } + + /** + * Set the URL pseudo file name + * + * @param urlFileName String + */ + public final void setURLFileName(String urlFileName) + { + m_urlFileName = urlFileName; + } } diff --git a/source/java/org/alfresco/filesys/smb/server/repo/ContentDiskDriver.java b/source/java/org/alfresco/filesys/smb/server/repo/ContentDiskDriver.java index 728f43c6a9..320c5be061 100644 --- a/source/java/org/alfresco/filesys/smb/server/repo/ContentDiskDriver.java +++ b/source/java/org/alfresco/filesys/smb/server/repo/ContentDiskDriver.java @@ -47,12 +47,15 @@ import org.alfresco.filesys.server.filesys.TreeConnection; import org.alfresco.filesys.smb.SMBException; import org.alfresco.filesys.smb.SMBStatus; import org.alfresco.filesys.smb.SharingMode; +import org.alfresco.filesys.smb.server.SMBSrvSession; import org.alfresco.filesys.smb.server.repo.FileState.FileStateStatus; import org.alfresco.filesys.smb.server.repo.pseudo.ContentPseudoFileImpl; +import org.alfresco.filesys.smb.server.repo.pseudo.LocalPseudoFile; import org.alfresco.filesys.smb.server.repo.pseudo.PseudoFile; import org.alfresco.filesys.smb.server.repo.pseudo.PseudoFileInterface; -import org.alfresco.filesys.smb.server.repo.pseudo.PseudoNetworkFile; +import org.alfresco.filesys.smb.server.repo.pseudo.PseudoFileList; import org.alfresco.filesys.util.DataBuffer; +import org.alfresco.filesys.util.WildCard; import org.alfresco.model.ContentModel; import org.alfresco.repo.security.authentication.AuthenticationComponent; import org.alfresco.service.cmr.coci.CheckOutCheckInService; @@ -371,12 +374,8 @@ public class ContentDiskDriver implements DiskInterface, IOCtlInterface // Create the pseudo file for the drag and drop application - PseudoFile dragDropPseudo = new PseudoFile( pseudoName.getValue(), appFile.getAbsolutePath()); + PseudoFile dragDropPseudo = new LocalPseudoFile( pseudoName.getValue(), appFile.getAbsolutePath()); context.setDragAndDropApp( dragDropPseudo); - - // Enable pseudo file support - - m_pseudoFiles = new ContentPseudoFileImpl(); } } } @@ -386,6 +385,45 @@ public class ContentDiskDriver implements DiskInterface, IOCtlInterface if ( logger.isDebugEnabled()) logger.debug("No I/O control handler available"); } + + // Check if URL link files are enabled + + ConfigElement urlFileElem = cfg.getChild( "urlFile"); + if ( urlFileElem != null) + { + // Get the pseudo file name and web prefix path + + ConfigElement pseudoName = urlFileElem.getChild( "filename"); + ConfigElement webPath = urlFileElem.getChild( "webpath"); + + if ( pseudoName != null && webPath != null) + { + // Make sure the web prefix has a trailing slash + + String path = webPath.getValue(); + if ( path.endsWith("/") == false) + path = path + "/"; + + // URL file name must end with .url + + if ( pseudoName.getValue().endsWith(".url") == false) + throw new DeviceContextException("URL link file must end with .url, " + pseudoName.getValue()); + + // Set the URL link file name and web path + + context.setURLFileName( pseudoName.getValue()); + context.setURLPrefix( path); + } + } + + // Enable pseudo file support if the drag and drop app and/or URL link files are enabled + + if ( context.hasDragAndDropApp() || context.hasURLFile()) + { + // Create the pseudo file handler + + m_pseudoFiles = new ContentPseudoFileImpl(); + } // Check if locked files should be marked as offline @@ -603,12 +641,14 @@ public class ContentDiskDriver implements DiskInterface, IOCtlInterface // If the state table is available see if we can speed up the search using either cached // file information or find the folder node to be searched without having to walk the path - + + String[] paths = null; + if ( ctx.hasStateTable()) { // See if the folder to be searched has a file state, we can avoid having to walk the path - String[] paths = FileName.splitPath(searchPath); + paths = FileName.splitPath(searchPath); if ( paths[0] != null && paths[0].length() > 1) { // Get the file state for the folder being searched @@ -631,6 +671,10 @@ public class ContentDiskDriver implements DiskInterface, IOCtlInterface searchRootNodeRef = nodeRef; searchFileSpec = paths[1]; + // Make sure the node ref is stored in the file state + + searchFolderState.setNodeRef( nodeRef); + // DEBUG if ( logger.isDebugEnabled()) @@ -639,12 +683,51 @@ public class ContentDiskDriver implements DiskInterface, IOCtlInterface } } - // Start the search + // Perform the search - SearchContext searchCtx = ContentSearchContext.search(cifsHelper, searchRootNodeRef, - searchFileSpec, attributes, searchFolderState); + List results = cifsHelper.getNodeRefs(searchRootNodeRef, searchFileSpec); + + // Check if there are any pseudo files for the folder being searched, for CIFS only - // done + PseudoFileList pseudoList = null; + + if ( sess instanceof SMBSrvSession && searchFolderState != null && searchFolderState.hasPseudoFiles()) + { + // If it is a wildcard search use all pseudo files + + if ( WildCard.containsWildcards(searchFileSpec)) + { + // Check if the folder has any associated pseudo files + + pseudoList = searchFolderState.getPseudoFileList(); + } + else if ( results == null || results.size() == 0) + { + // Check if the required file is in the pseudo file list + + String fname = paths[1]; + + if ( fname != null) + { + // Search for a matching pseudo file + + PseudoFile pfile = searchFolderState.getPseudoFileList().findFile( fname, true); + if ( pfile != null) + { + // Create a file list with the required file + + pseudoList = new PseudoFileList(); + pseudoList.addFile( pfile); + } + } + } + } + + // Build the search context to store the results + + SearchContext searchCtx = new ContentSearchContext(cifsHelper, results, searchFileSpec, pseudoList); + + // Debug if (logger.isDebugEnabled()) { @@ -792,7 +875,7 @@ public class ContentDiskDriver implements DiskInterface, IOCtlInterface { // Create a network file to access the pseudo file data - return new PseudoNetworkFile( pfile.getFileName(), pfile.getFilePath(), params.getPath()); + return pfile.getFile( params.getPath()); } } @@ -1641,6 +1724,13 @@ public class ContentDiskDriver implements DiskInterface, IOCtlInterface int count = file.readFile(buffer, size, bufferPosition, fileOffset); + if ( count == -1) + { + // Read count of -1 indicates a read past the end of file + + count = 0; + } + // done if (logger.isDebugEnabled()) { diff --git a/source/java/org/alfresco/filesys/smb/server/repo/ContentSearchContext.java b/source/java/org/alfresco/filesys/smb/server/repo/ContentSearchContext.java index 2504c249a6..20c76de882 100644 --- a/source/java/org/alfresco/filesys/smb/server/repo/ContentSearchContext.java +++ b/source/java/org/alfresco/filesys/smb/server/repo/ContentSearchContext.java @@ -20,11 +20,9 @@ import java.io.FileNotFoundException; import java.util.List; import org.alfresco.filesys.server.filesys.FileInfo; -import org.alfresco.filesys.server.filesys.FileName; import org.alfresco.filesys.server.filesys.SearchContext; import org.alfresco.filesys.smb.server.repo.pseudo.PseudoFile; import org.alfresco.filesys.smb.server.repo.pseudo.PseudoFileList; -import org.alfresco.filesys.util.WildCard; import org.alfresco.service.cmr.repository.NodeRef; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -54,89 +52,14 @@ public class ContentSearchContext extends SearchContext private int resumeId; /** - * Performs a search against the direct children of the given node. - *

- * Wildcard characters are acceptable, and the search may either be for - * a specific file or directory, or any file or directory. + * Class constructor * - * @param serviceRegistry used to gain access the the repository - * @param cifsHelper caches path query results - * @param searchRootNodeRef the node whos children are to be searched - * @param searchStr the search string relative to the search root node - * @param attributes the search attributes, e.g. searching for folders, etc - * @param searchFolderState File state of the folder being searched - * @return Returns a search context with the results of the search + * @param cifsHelper Filesystem helper class + * @param results List of file/folder nodes that match the search pattern + * @param searchStr Search path + * @param pseudoList List of pseudo files to be blended into the returned list of files */ - public static ContentSearchContext search( - CifsHelper cifsHelper, - NodeRef searchRootNodeRef, - String searchStr, - int attributes, - FileState searchFolderState) - { - // Perform the search - - List results = cifsHelper.getNodeRefs(searchRootNodeRef, searchStr); - - // Check if there are any pseudo files for the folder being searched. - - PseudoFileList pseudoList = null; - - if ( searchFolderState != null && searchFolderState.hasPseudoFiles()) - { - // If it is a wildcard search use all pseudo files - - if ( WildCard.containsWildcards(searchStr)) - { - // Check if the folder has any associated pseudo files - - pseudoList = searchFolderState.getPseudoFileList(); - } - else if ( results == null || results.size() == 0) - { - // Check if the required file is in the pseudo file list - - String fname = searchStr; - if ( fname.indexOf(FileName.DOS_SEPERATOR) != -1) - { - String[] paths = FileName.splitPath( searchStr); - fname = paths[1]; - } - - if ( fname != null) - { - // Search for a matching pseudo file - - PseudoFile pfile = searchFolderState.getPseudoFileList().findFile( fname, true); - if ( pfile != null) - { - // Create a file list with the required file - - pseudoList = new PseudoFileList(); - pseudoList.addFile( pfile); - } - } - } - } - - // Build the search context to store the results - - ContentSearchContext searchCtx = new ContentSearchContext(cifsHelper, results, searchStr, pseudoList); - - // done - if (logger.isDebugEnabled()) - { - logger.debug("Search context created: \n" + - " search root: " + searchRootNodeRef + "\n" + - " search context: " + searchCtx); - } - return searchCtx; - } - - /** - * @see ContentSearchContext#search(FilePathCache, NodeRef, String, int) - */ - private ContentSearchContext( + protected ContentSearchContext( CifsHelper cifsHelper, List results, String searchStr, diff --git a/source/java/org/alfresco/filesys/smb/server/repo/pseudo/ContentPseudoFileImpl.java b/source/java/org/alfresco/filesys/smb/server/repo/pseudo/ContentPseudoFileImpl.java index 206d970c38..3a6be32bee 100644 --- a/source/java/org/alfresco/filesys/smb/server/repo/pseudo/ContentPseudoFileImpl.java +++ b/source/java/org/alfresco/filesys/smb/server/repo/pseudo/ContentPseudoFileImpl.java @@ -18,12 +18,10 @@ package org.alfresco.filesys.smb.server.repo.pseudo; import org.alfresco.filesys.server.SrvSession; -import org.alfresco.filesys.server.filesys.DiskDeviceContext; -import org.alfresco.filesys.server.filesys.DiskInterface; import org.alfresco.filesys.server.filesys.FileName; import org.alfresco.filesys.server.filesys.TreeConnection; +import org.alfresco.filesys.smb.server.SMBSrvSession; import org.alfresco.filesys.smb.server.repo.ContentContext; -import org.alfresco.filesys.smb.server.repo.ContentDiskDriver; import org.alfresco.filesys.smb.server.repo.FileState; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -118,12 +116,23 @@ public class ContentPseudoFileImpl implements PseudoFileInterface int pseudoCnt = 0; ContentContext ctx = (ContentContext) tree.getContext(); + FileState fstate = getStateForPath( ctx, path); + + // Check if pseudo files have already been added for this folder - if ( ctx.hasDragAndDropApp()) + if ( fstate.hasPseudoFiles()) + return 0; + + // Check if this is a CIFS session + + boolean isCIFS = sess instanceof SMBSrvSession; + + // Add the drag and drop pseudo file, if enabled + + if ( isCIFS && ctx.hasDragAndDropApp()) { // If the file state is null create a file state for the path - FileState fstate = getStateForPath( ctx, path); if ( fstate == null) ctx.getStateTable().findFileState( path, true, true); @@ -149,6 +158,38 @@ public class ContentPseudoFileImpl implements PseudoFileInterface logger.info("Added drag/drop pseudo file for " + path); } } + + // Add the URL link pseudo file, if enabled + + if ( isCIFS && ctx.hasURLFile() && fstate.getNodeRef() != null) + { + // Build the URL file data + + StringBuilder urlStr = new StringBuilder(); + + urlStr.append("[InternetShortcut]\r\n"); + urlStr.append("URL="); + urlStr.append(ctx.getURLPrefix()); + urlStr.append("navigate/browse/workspace/SpaceStore/"); + urlStr.append( fstate.getNodeRef().getId()); + urlStr.append("\r\n"); + + // Create the in memory pseudo file for the URL link + + byte[] urlData = urlStr.toString().getBytes(); + + MemoryPseudoFile urlFile = new MemoryPseudoFile( ctx.getURLFileName(), urlData); + fstate.addPseudoFile( urlFile); + + // Update the count of files added + + pseudoCnt++; + + // DEBUG + + if ( logger.isInfoEnabled()) + logger.info("Added URL link pseudo file for " + path); + } // Return the count of pseudo files added diff --git a/source/java/org/alfresco/filesys/smb/server/repo/pseudo/LocalPseudoFile.java b/source/java/org/alfresco/filesys/smb/server/repo/pseudo/LocalPseudoFile.java new file mode 100644 index 0000000000..11a0d99370 --- /dev/null +++ b/source/java/org/alfresco/filesys/smb/server/repo/pseudo/LocalPseudoFile.java @@ -0,0 +1,110 @@ +/* + * Copyright (C) 2005 Alfresco, Inc. + * + * Licensed under the Mozilla Public License version 1.1 + * with a permitted attribution clause. You may obtain a + * copy of the License at + * + * http://www.alfresco.org/legal/license.txt + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + */ + +package org.alfresco.filesys.smb.server.repo.pseudo; + +import java.io.File; + +import org.alfresco.filesys.server.filesys.FileInfo; +import org.alfresco.filesys.server.filesys.NetworkFile; + +/** + * Local Pseudo File Class + * + *

Pseudo file class that uses a file on the local filesystem. + * + * @author gkspencer + */ +public class LocalPseudoFile extends PseudoFile +{ + // Path to the file on the local filesystem + + private String m_path; + + /** + * Class constructor + * + * @param name String + * @param path String + */ + public LocalPseudoFile(String name, String path) + { + super(name); + + m_path = path; + } + + /** + * Return the path to the file on the local filesystem + * + * @return String + */ + public final String getFilePath() + { + return m_path; + } + + /** + * Return the file information for the pseudo file + * + * @return FileInfo + */ + public FileInfo getFileInfo() + { + // Check if the file information is valid + + if ( m_fileInfo == null) { + + // Get the file details + + File localFile = new File( getFilePath()); + if ( localFile.exists()) + { + // Create the file information + + m_fileInfo = new FileInfo( getFileName(), localFile.length(), getAttributes()); + + // Set the file creation/modification times + + m_fileInfo.setModifyDateTime( localFile.lastModified()); + m_fileInfo.setCreationDateTime( _creationDateTime); + m_fileInfo.setChangeDateTime( _creationDateTime); + + // Set the allocation size, round up the actual length + + m_fileInfo.setAllocationSize(( localFile.length() + 512L) & 0xFFFFFFFFFFFFFE00L); + } + } + + // Return the file information + + return m_fileInfo; + } + + /** + * Return a network file for reading/writing the pseudo file + * + * @param netPath String + * @return NetworkFile + */ + public NetworkFile getFile(String netPath) + { + // Create a pseudo file mapped to a file in the local filesystem + + return new PseudoNetworkFile( getFileName(), getFilePath(), netPath); + } +} diff --git a/source/java/org/alfresco/filesys/smb/server/repo/pseudo/MemoryNetworkFile.java b/source/java/org/alfresco/filesys/smb/server/repo/pseudo/MemoryNetworkFile.java new file mode 100644 index 0000000000..4a40d62866 --- /dev/null +++ b/source/java/org/alfresco/filesys/smb/server/repo/pseudo/MemoryNetworkFile.java @@ -0,0 +1,261 @@ +/* + * Copyright (C) 2005 Alfresco, Inc. + * + * Licensed under the Mozilla Public License version 1.1 + * with a permitted attribution clause. You may obtain a + * copy of the License at + * + * http://www.alfresco.org/legal/license.txt + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + */ + +package org.alfresco.filesys.smb.server.repo.pseudo; + +import java.io.File; +import java.io.IOException; +import java.io.RandomAccessFile; + +import org.alfresco.filesys.server.filesys.AccessDeniedException; +import org.alfresco.filesys.server.filesys.FileInfo; +import org.alfresco.filesys.server.filesys.NetworkFile; +import org.alfresco.filesys.smb.SeekType; + +/** + * In Memory Network File Class + * + *

In memory network file implementation that uses a memory buffer for the file data. + * + * @author gkspencer + */ +public class MemoryNetworkFile extends NetworkFile +{ + // Current file position + + private long m_filePos; + + // File data + + private byte[] m_data; + + // End of file flag + + private boolean m_eof; + + /** + * Class constructor. + * + * @param name String + * @param localPath String + * @param finfo FileInfo + */ + public MemoryNetworkFile(String name, byte[] data, FileInfo finfo) + { + super( name); + + // Set the file data + + m_data = data; + if ( m_data == null) + m_data = new byte[0]; + + // Set the file size + + setFileSize( m_data.length); + m_eof = false; + + // Set the creation and modification date/times + + setModifyDate( finfo.getModifyDateTime()); + setCreationDate( finfo.getCreationDateTime()); + + // Set the file id and relative path + + if ( finfo.getPath() != null) + { + setFileId( finfo.getPath().hashCode()); + setFullName( finfo.getPath()); + } + } + + /** + * Close the network file. + */ + public void closeFile() throws java.io.IOException + { + // Nothing to do + } + + /** + * Return the current file position. + * + * @return long + */ + public long currentPosition() + { + return m_filePos; + } + + /** + * Flush the file. + * + * @exception IOException + */ + public void flushFile() throws IOException + { + // Nothing to do + } + + /** + * Determine if the end of file has been reached. + * + * @return boolean + */ + public boolean isEndOfFile() throws java.io.IOException + { + // Check if we reached end of file + + if ( m_filePos == m_data.length) + return true; + return false; + } + + /** + * Open the file. + * + * @param createFlag boolean + * @exception IOException + */ + public void openFile(boolean createFlag) throws java.io.IOException + { + // Indicate that the file is open + + setClosed(false); + } + + /** + * Read from the file. + * + * @param buf byte[] + * @param len int + * @param pos int + * @param fileOff long + * @return Length of data read. + * @exception IOException + */ + public int readFile(byte[] buf, int len, int pos, long fileOff) throws java.io.IOException + { + // Check if the read is within the file data range + + long fileLen = (long) m_data.length; + + if ( fileOff >= fileLen) + return 0; + + // Calculate the actual read length + + if (( fileOff + len) > fileLen) + len = (int) ( fileLen - fileOff); + + // Copy the data to the user buffer + + System.arraycopy( m_data, (int) fileOff, buf, pos, len); + + // Update the current file position + + m_filePos = fileOff + len; + + // Return the actual length of data read + + return len; + } + + /** + * Seek to the specified file position. + * + * @param pos long + * @param typ int + * @return long + * @exception IOException + */ + public long seekFile(long pos, int typ) throws IOException + { + // Seek to the required file position + + switch (typ) + { + // From start of file + + case SeekType.StartOfFile: + if (currentPosition() != pos) + m_filePos = pos; + break; + + // From current position + + case SeekType.CurrentPos: + m_filePos += pos; + break; + + // From end of file + + case SeekType.EndOfFile: + m_filePos += pos; + if ( m_filePos < 0) + m_filePos = 0L; + break; + } + + // Return the new file position + + return currentPosition(); + } + + /** + * Truncate the file + * + * @param siz long + * @exception IOException + */ + public void truncateFile(long siz) throws IOException + { + // Do not allow the file to be written to + + throw new AccessDeniedException("Cannot truncate pseudo file"); + } + + /** + * Write a block of data to the file. + * + * @param buf byte[] + * @param len int + * @exception IOException + */ + public void writeFile(byte[] buf, int len, int pos) throws java.io.IOException + { + // Do not allow the file to be written to + + throw new AccessDeniedException("Cannot write to pseudo file"); + } + + /** + * Write a block of data to the file. + * + * @param buf byte[] + * @param len int + * @param pos int + * @param offset long + * @exception IOException + */ + public void writeFile(byte[] buf, int len, int pos, long offset) throws java.io.IOException + { + // Do not allow the file to be written to + + throw new AccessDeniedException("Cannot write to pseudo file"); + } +} diff --git a/source/java/org/alfresco/filesys/smb/server/repo/pseudo/MemoryPseudoFile.java b/source/java/org/alfresco/filesys/smb/server/repo/pseudo/MemoryPseudoFile.java new file mode 100644 index 0000000000..c1733e71f2 --- /dev/null +++ b/source/java/org/alfresco/filesys/smb/server/repo/pseudo/MemoryPseudoFile.java @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2005 Alfresco, Inc. + * + * Licensed under the Mozilla Public License version 1.1 + * with a permitted attribution clause. You may obtain a + * copy of the License at + * + * http://www.alfresco.org/legal/license.txt + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + */ + +package org.alfresco.filesys.smb.server.repo.pseudo; + +import org.alfresco.filesys.server.filesys.FileInfo; +import org.alfresco.filesys.server.filesys.NetworkFile; + +/** + * In Memory Pseudo File Class + * + *

Pseudo file class that uses an in memory buffer for the file data. + * + * @author gkspencer + */ +public class MemoryPseudoFile extends PseudoFile +{ + // File data buffer + + private byte[] m_data; + + /** + * Class constructor + * + * @param name String + * @param data byte[] + */ + public MemoryPseudoFile(String name, byte[] data) + { + super( name); + + m_data = data; + } + + /** + * Return the file information for the pseudo file + * + * @return FileInfo + */ + public FileInfo getFileInfo() + { + // Check if the file information is valid + + if ( m_fileInfo == null) { + + // Create the file information + + m_fileInfo = new FileInfo( getFileName(), m_data != null ? m_data.length : 0, getAttributes()); + + // Set the file creation/modification times + + m_fileInfo.setCreationDateTime( _creationDateTime); + m_fileInfo.setModifyDateTime( _creationDateTime); + m_fileInfo.setChangeDateTime( _creationDateTime); + + // Set the allocation size, round up the actual length + + m_fileInfo.setAllocationSize(( m_fileInfo.getSize() + 512L) & 0xFFFFFFFFFFFFFE00L); + } + + // Return the file information + + return m_fileInfo; + } + + /** + * Return a network file for reading/writing the pseudo file + * + * @param netPath String + * @return NetworkFile + */ + public NetworkFile getFile(String netPath) + { + // Create a pseudo file mapped to the in memory file data + + FileInfo finfo = getFileInfo(); + finfo.setPath( netPath); + + return new MemoryNetworkFile( getFileName(), m_data, finfo); + } +} diff --git a/source/java/org/alfresco/filesys/smb/server/repo/pseudo/PseudoFile.java b/source/java/org/alfresco/filesys/smb/server/repo/pseudo/PseudoFile.java index e194293422..7ce7d11a05 100644 --- a/source/java/org/alfresco/filesys/smb/server/repo/pseudo/PseudoFile.java +++ b/source/java/org/alfresco/filesys/smb/server/repo/pseudo/PseudoFile.java @@ -21,6 +21,7 @@ import java.io.File; import org.alfresco.filesys.server.filesys.FileAttribute; import org.alfresco.filesys.server.filesys.FileInfo; +import org.alfresco.filesys.server.filesys.NetworkFile; /** * Pseudo File Class @@ -30,11 +31,11 @@ import org.alfresco.filesys.server.filesys.FileInfo; * * @author gkspencer */ -public class PseudoFile +public abstract class PseudoFile { // Dummy creation date/time to use for pseudo files - private static long _creationDateTime = System.currentTimeMillis(); + protected static long _creationDateTime = System.currentTimeMillis(); // File name for pseudo file @@ -44,38 +45,29 @@ public class PseudoFile private int m_fileFlags = FileAttribute.ReadOnly; - // Path to the file data in the local filesystem - - private String m_filePath; - // File information, used for file information/folder searches - private FileInfo m_fileInfo; + protected FileInfo m_fileInfo; /** * Class constructor * * @param name String - * @param path String */ - public PseudoFile(String name, String path) + protected PseudoFile(String name) { m_fileName = name; - m_filePath = path; } /** * Class constructor * * @param name String - * @param path String * @param flags int */ - public PseudoFile(String name, String path, int flags) + protected PseudoFile(String name, int flags) { m_fileName = name; - m_filePath = path; - m_fileFlags = flags; } @@ -89,16 +81,6 @@ public class PseudoFile return m_fileName; } - /** - * Return the path to the file data on the local filesystem - * - * @return String - */ - public final String getFilePath() - { - return m_filePath; - } - /** * Return the standard file attributes * @@ -114,37 +96,15 @@ public class PseudoFile * * @return FileInfo */ - public final FileInfo getFileInfo() - { - // Check if the file information is valid - - if ( m_fileInfo == null) { - - // Get the file details - - File localFile = new File( getFilePath()); - if ( localFile.exists()) - { - // Create the file information - - m_fileInfo = new FileInfo( getFileName(), localFile.length(), getAttributes()); - - // Set the file creation/modification times - - m_fileInfo.setModifyDateTime( localFile.lastModified()); - m_fileInfo.setCreationDateTime( _creationDateTime); - m_fileInfo.setChangeDateTime( _creationDateTime); - - // Set the allocation size, round up the actual length - - m_fileInfo.setAllocationSize(( localFile.length() + 512L) & 0xFFFFFFFFFFFFFE00L); - } - } - - // Return the file information - - return m_fileInfo; - } + public abstract FileInfo getFileInfo(); + + /** + * Return a network file for reading/writing the pseudo file + * + * @param netPath String + * @return NetworkFile + */ + public abstract NetworkFile getFile(String netPath); /** * Return the pseudo file as a string @@ -158,13 +118,7 @@ public class PseudoFile str.append("["); str.append(getFileName()); str.append(","); - str.append(getFilePath()); - str.append(":"); - - if ( m_fileInfo != null) - str.append( m_fileInfo.toString()); - else - str.append("Null"); + str.append(getFileInfo()); str.append("]"); return str.toString();