diff --git a/source/java/org/alfresco/filesys/avm/AVMContext.java b/source/java/org/alfresco/filesys/avm/AVMContext.java index 7046fd2c8a..9f8f79061f 100644 --- a/source/java/org/alfresco/filesys/avm/AVMContext.java +++ b/source/java/org/alfresco/filesys/avm/AVMContext.java @@ -346,7 +346,7 @@ public class AVMContext extends AlfrescoContext // Update the file state modify time - rootState.setLastUpdated( System.currentTimeMillis()); + rootState.updateModifyDateTime(); // Send a change notification for the deleted folder diff --git a/source/java/org/alfresco/filesys/avm/AVMDiskDriver.java b/source/java/org/alfresco/filesys/avm/AVMDiskDriver.java index b56578aa10..539fced503 100644 --- a/source/java/org/alfresco/filesys/avm/AVMDiskDriver.java +++ b/source/java/org/alfresco/filesys/avm/AVMDiskDriver.java @@ -25,10 +25,8 @@ package org.alfresco.filesys.avm; import java.io.FileNotFoundException; import java.io.IOException; -import java.util.Iterator; import java.util.List; import java.util.Map; -import java.util.Set; import java.util.SortedMap; import java.util.StringTokenizer; @@ -41,7 +39,6 @@ import org.alfresco.jlan.server.SrvSession; import org.alfresco.jlan.server.auth.ClientInfo; import org.alfresco.jlan.server.core.DeviceContext; import org.alfresco.jlan.server.core.DeviceContextException; -import org.alfresco.jlan.server.core.DeviceInterface; import org.alfresco.jlan.server.filesys.AccessDeniedException; import org.alfresco.jlan.server.filesys.DirectoryNotEmptyException; import org.alfresco.jlan.server.filesys.DiskInterface; @@ -81,14 +78,9 @@ import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.MimetypeService; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeService; -import org.alfresco.service.cmr.repository.StoreRef; -import org.alfresco.service.cmr.search.ResultSet; -import org.alfresco.service.cmr.search.SearchService; import org.alfresco.service.cmr.security.AuthenticationService; -import org.alfresco.service.namespace.NamespaceService; import org.alfresco.service.namespace.QName; import org.alfresco.service.namespace.RegexQNamePattern; -import org.alfresco.service.transaction.TransactionService; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; diff --git a/source/java/org/alfresco/filesys/repo/BufferedWrite.java b/source/java/org/alfresco/filesys/repo/BufferedWrite.java new file mode 100644 index 0000000000..712753a1fe --- /dev/null +++ b/source/java/org/alfresco/filesys/repo/BufferedWrite.java @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2006-2008 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 + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + * As a special exception to the terms and conditions of version 2.0 of + * the GPL, you may redistribute this Program in connection with Free/Libre + * and Open Source Software ("FLOSS") applications as described in Alfresco's + * FLOSS exception. You should have recieved a copy of the text describing + * the FLOSS exception, and it is also available here: + * http://www.alfresco.com/legal/licensing" + */ + +package org.alfresco.filesys.repo; + +/** + * Buffered Write Class + * + *

Contains the details and data for a buffered write. + * + * @author gkspencer + */ +public class BufferedWrite { + + // Write details + + private long m_offset; + private byte[] m_data; + + /** + * Class constructor + * + * @param buf byte[] + * @param offset long + */ + public BufferedWrite( byte[] buf, long offset) { + m_data = buf; + m_offset = offset; + } + + /** + * Return the file offset + * + * @return long + */ + public final long getOffset() { + return m_offset; + } + + /** + * Return the write data + * + * @return byte[] + */ + public final byte[] getData() { + return m_data; + } + + /** + * Return the data length + * + * @return int + */ + public final int getDataLength() { + return m_data != null ? m_data.length : 0; + } + + /** + * Return the buffered write details as a string + * + * @return String + */ + public String toString() { + StringBuilder str = new StringBuilder(); + + str.append("[Data len="); + str.append(m_data.length); + str.append(",Offset="); + str.append(m_offset); + str.append("]"); + + return str.toString(); + } +} diff --git a/source/java/org/alfresco/filesys/repo/CifsHelper.java b/source/java/org/alfresco/filesys/repo/CifsHelper.java index 8ed44a7d52..1e15df2925 100644 --- a/source/java/org/alfresco/filesys/repo/CifsHelper.java +++ b/source/java/org/alfresco/filesys/repo/CifsHelper.java @@ -636,10 +636,6 @@ public class CifsHelper { try { - // Check if the new file name is a temporary file name - if ( newName.endsWith(".tmp") || newName.endsWith(".temp")) - nodeService.addAspect(nodeToRenameRef, ContentModel.ASPECT_TEMPORARY, null); - fileFolderService.rename(nodeToRenameRef, newName); } catch (org.alfresco.service.cmr.model.FileExistsException e) diff --git a/source/java/org/alfresco/filesys/repo/ContentDiskDriver.java b/source/java/org/alfresco/filesys/repo/ContentDiskDriver.java index 99a76931a4..53b3e24711 100644 --- a/source/java/org/alfresco/filesys/repo/ContentDiskDriver.java +++ b/source/java/org/alfresco/filesys/repo/ContentDiskDriver.java @@ -27,6 +27,7 @@ package org.alfresco.filesys.repo; import java.io.FileNotFoundException; import java.io.IOException; import java.net.InetAddress; +import java.util.Date; import java.util.List; import javax.transaction.UserTransaction; @@ -606,8 +607,8 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa // Debug - if ( logger.isInfoEnabled()) - logger.info( "Added file state for pseudo files folder (getinfo) - " + paths[0]); + if ( logger.isDebugEnabled()) + logger.debug( "Added file state for pseudo files folder (getinfo) - " + paths[0]); } else if ( fstate.hasPseudoFiles() == false) { @@ -626,8 +627,8 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa // Debug - if ( logger.isInfoEnabled()) - logger.info( "Added pseudo files for folder (exists) - " + paths[0]); + if ( logger.isDebugEnabled()) + logger.debug( "Added pseudo files for folder (exists) - " + paths[0]); } @@ -657,6 +658,7 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa // Get the node ref for the path, chances are there is a file state in the cache NodeRef nodeRef = getNodeForPath(tree, infoPath); + if ( nodeRef != null) { // Get the file information for the node @@ -665,7 +667,7 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa // DEBUG - if ( logger.isInfoEnabled()) + if ( logger.isDebugEnabled()) logger.debug("getInfo using cached noderef for path " + path); } @@ -689,7 +691,7 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa // DEBUG - if ( logger.isInfoEnabled()) + if ( logger.isDebugEnabled()) logger.debug("getInfo using cached noderef for parent " + path); } } @@ -710,9 +712,25 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa // Set the file id for the file using the relative path - if ( finfo != null) + if ( finfo != null) { + + // Set the file id + finfo.setFileId( path.hashCode()); + // Copy cached timestamps, if available + + FileState fstate = getStateForPath(tree, infoPath); + if ( fstate != null) { + if ( fstate.hasAccessDateTime()) + finfo.setAccessDateTime(fstate.getAccessDateTime()); + if ( fstate.hasChangeDateTime()) + finfo.setChangeDateTime(fstate.getChangeDateTime()); + if ( fstate.hasModifyDateTime()) + finfo.setModifyDateTime(fstate.getModifyDateTime()); + } + } + // Return the file information return finfo; @@ -1019,8 +1037,8 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa // Debug - if ( logger.isInfoEnabled()) - logger.info( "Added file state for pseudo files folder (exists) - " + paths[0]); + if ( logger.isDebugEnabled()) + logger.debug( "Added file state for pseudo files folder (exists) - " + paths[0]); } } else if ( fstate.hasPseudoFiles() == false) @@ -1044,8 +1062,8 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa // Debug - if ( logger.isInfoEnabled()) - logger.info( "Added pseudo files for folder (exists) - " + paths[0]); + if ( logger.isDebugEnabled()) + logger.debug( "Added pseudo files for folder (exists) - " + paths[0]); } // Check if the path is to a pseudo file @@ -1061,8 +1079,8 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa { // Failed to find pseudo file - if ( logger.isInfoEnabled()) - logger.info( "Failed to find pseudo file (exists) - " + name); + if ( logger.isDebugEnabled()) + logger.debug( "Failed to find pseudo file (exists) - " + name); } } } @@ -1167,8 +1185,8 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa // Debug - if ( logger.isInfoEnabled()) - logger.info( "Added file state for pseudo files folder (open) - " + paths[0]); + if ( logger.isDebugEnabled()) + logger.debug( "Added file state for pseudo files folder (open) - " + paths[0]); } } else if ( fstate.hasPseudoFiles() == false) @@ -1179,8 +1197,8 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa // Debug - if ( logger.isInfoEnabled()) - logger.info( "Added pseudo files for folder (open) - " + paths[0]); + if ( logger.isDebugEnabled()) + logger.debug( "Added pseudo files for folder (open) - " + paths[0]); } // Check if the path is to a pseudo file @@ -1196,8 +1214,8 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa { // Failed to find pseudo file - if ( logger.isInfoEnabled()) - logger.info( "Failed to find pseudo file (open) - " + params.getPath()); + if ( logger.isDebugEnabled()) + logger.debug( "Failed to find pseudo file (open) - " + params.getPath()); } } } @@ -1439,7 +1457,7 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa // DEBUG - if ( logger.isInfoEnabled()) + if ( logger.isDebugEnabled()) logger.debug("Create file using cached noderef for path " + paths[0]); } } @@ -2019,9 +2037,46 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa if ( sameFolder == true) { + // Check if the new file name is a temporary file name + + String newNameNorm = newName.toLowerCase(); + boolean isTempFile = false; + + if ( newNameNorm.endsWith(".tmp") || newNameNorm.endsWith(".temp")) { + + // Add the temporary aspect, also prevents versioning + + nodeService.addAspect(nodeToMoveRef, ContentModel.ASPECT_TEMPORARY, null); + + // Indicate that the new file is a temporary file + + isTempFile = true; + + // DEBUG + + if ( logger.isDebugEnabled()) + logger.debug("Added Temporary aspect to renamed file " + newName); + } + // Rename the file/folder cifsHelper.rename(nodeToMoveRef, name); + + // Check if the temporary aspect should be removed from the renamed file + + String oldNameNorm = oldName.toLowerCase(); + + if ( isTempFile == false && (oldNameNorm.endsWith(".tmp") || oldNameNorm.endsWith(".temp"))) { + + // Remove the temporary aspect + + nodeService.removeAspect(nodeToMoveRef, ContentModel.ASPECT_TEMPORARY); + + // DEBUG + + if ( logger.isDebugEnabled()) + logger.debug("Removed Temporary aspect from renamed file " + newName); + } // DEBUG @@ -2151,6 +2206,7 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa // Get the file/folder node NodeRef nodeRef = getNodeForPath(tree, name); + FileState fstate = getStateForPath(tree, name); // Check permissions on the file/folder node @@ -2164,6 +2220,10 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa if ( info.hasSetFlag(FileInfo.SetDeleteOnClose) && info.hasDeleteOnClose()) { + // Start a transaction + + beginReadTransaction( sess); + // Check if the node is locked if ( nodeService.hasAspect( nodeRef, ContentModel.ASPECT_LOCKABLE)) @@ -2175,6 +2235,64 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa if ( lockTypeStr != null) throw new AccessDeniedException("Node locked, cannot mark for delete"); } + + // Update the change date/time + + if ( fstate != null) + fstate.updateChangeDateTime(); + + // DEBUG + + if ( logger.isDebugEnabled()) + logger.debug("Set deleteOnClose=true file=" + name); + } + + // Set the creation date/time + + if ( info.hasSetFlag(FileInfo.SetCreationDate)) { + + // Create the transaction + + beginWriteTransaction( sess); + + // Set the creation date on the file/folder node + + Date createDate = new Date( info.getCreationDateTime()); + nodeService.setProperty( nodeRef, ContentModel.PROP_CREATED, createDate); + + // Update the change date/time + + if ( fstate != null) + fstate.updateChangeDateTime(); + + // DEBUG + + if ( logger.isDebugEnabled()) + logger.debug("Set creationDate=" + createDate + " file=" + name); + } + + // Set the modification date/time + + if ( info.hasSetFlag(FileInfo.SetModifyDate)) { + + // Create the transaction + + beginWriteTransaction( sess); + + // Set the creation date on the file/folder node + + Date modifyDate = new Date( info.getModifyDateTime()); + nodeService.setProperty( nodeRef, ContentModel.PROP_MODIFIED, modifyDate); + + // Update the change date/time + + if ( fstate != null) + fstate.updateChangeDateTime(); + + // DEBUG + + if ( logger.isDebugEnabled()) + logger.debug("Set modifyDate=" + modifyDate + " file=" + name); } } catch (org.alfresco.repo.security.permissions.AccessDeniedException ex) diff --git a/source/java/org/alfresco/filesys/repo/ContentNetworkFile.java b/source/java/org/alfresco/filesys/repo/ContentNetworkFile.java index 53f6487e22..4d6671b618 100644 --- a/source/java/org/alfresco/filesys/repo/ContentNetworkFile.java +++ b/source/java/org/alfresco/filesys/repo/ContentNetworkFile.java @@ -69,6 +69,8 @@ public class ContentNetworkFile extends NodeRefNetworkFile { private static final Log logger = LogFactory.getLog(ContentNetworkFile.class); + // Services + private NodeService nodeService; private ContentService contentService; private MimetypeService mimetypeService; @@ -107,7 +109,20 @@ public class ContentNetworkFile extends NodeRefNetworkFile // Create the file - ContentNetworkFile netFile = new ContentNetworkFile(nodeService, contentService, mimetypeService, nodeRef, path); + ContentNetworkFile netFile = null; + + if ( isMSOfficeSpecialFile(path)) { + + // Create a file for special processing + + netFile = new MSOfficeContentNetworkFile( nodeService, contentService, mimetypeService, nodeRef, path); + } + else { + + // Create a normal content file + + netFile = new ContentNetworkFile(nodeService, contentService, mimetypeService, nodeRef, path); + } // Set relevant parameters @@ -182,7 +197,7 @@ public class ContentNetworkFile extends NodeRefNetworkFile * @param nodeRef NodeRef * @param name String */ - private ContentNetworkFile( + protected ContentNetworkFile( NodeService nodeService, ContentService contentService, MimetypeService mimetypeService, @@ -439,6 +454,11 @@ public class ContentNetworkFile extends NodeRefNetworkFile setFileSize( size); + // Update the modification date/time + + if ( getFileState() != null) + getFileState().updateModifyDateTime(); + // DEBUG if (logger.isDebugEnabled()) @@ -475,6 +495,11 @@ public class ContentNetworkFile extends NodeRefNetworkFile setFileSize(channel.size()); + // Update the modification date/time + + if ( getFileState() != null) + getFileState().updateModifyDateTime(); + // DEBUG if (logger.isDebugEnabled()) @@ -507,6 +532,11 @@ public class ContentNetworkFile extends NodeRefNetworkFile count = 0; // doesn't obey the same rules, i.e. just returns the bytes read } + // Update the access date/time + + if ( getFileState() != null) + getFileState().updateAccessDateTime(); + // DEBUG if (logger.isDebugEnabled()) @@ -574,6 +604,11 @@ public class ContentNetworkFile extends NodeRefNetworkFile break; } + // Update the access date/time + + if ( getFileState() != null) + getFileState().updateAccessDateTime(); + // DEBUG if (logger.isDebugEnabled()) @@ -601,9 +636,31 @@ public class ContentNetworkFile extends NodeRefNetworkFile channel.force(false); + // Update the access date/time + + if ( getFileState() != null) + getFileState().updateAccessDateTime(); + // DEBUG if (logger.isDebugEnabled()) logger.debug("Flush file=" + this); } + + /** + * Check if the file is an MS Office document type that needs special processing + * + * @param path String + * @return boolean + */ + private static final boolean isMSOfficeSpecialFile(String path) { + + // Check if the file extension indicates a problem MS Office format + + path = path.toLowerCase(); + + if ( path.endsWith( ".xls")) + return true; + return false; + } } diff --git a/source/java/org/alfresco/filesys/repo/MSOfficeContentNetworkFile.java b/source/java/org/alfresco/filesys/repo/MSOfficeContentNetworkFile.java new file mode 100644 index 0000000000..ce21966123 --- /dev/null +++ b/source/java/org/alfresco/filesys/repo/MSOfficeContentNetworkFile.java @@ -0,0 +1,213 @@ +/* + * Copyright (C) 2006-2008 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 + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + * As a special exception to the terms and conditions of version 2.0 of + * the GPL, you may redistribute this Program in connection with Free/Libre + * and Open Source Software ("FLOSS") applications as described in Alfresco's + * FLOSS exception. You should have recieved a copy of the text describing + * the FLOSS exception, and it is also available here: + * http://www.alfresco.com/legal/licensing" + */ + +package org.alfresco.filesys.repo; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import org.alfresco.service.cmr.repository.ContentService; +import org.alfresco.service.cmr.repository.MimetypeService; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.repository.NodeService; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * Ms Office Content Network File Class + * + *

Provides special handling for MS Office files that are written to by the app even though the user does not + * change the file. + * + * @author gkspencer + */ +public class MSOfficeContentNetworkFile extends ContentNetworkFile { + + private static final Log logger = LogFactory.getLog(MSOfficeContentNetworkFile.class); + + // Count of file reads + + private int m_readCnt; + + // Buffered write list + + private List m_writeList; + + /** + * Class constructor + * + * @param transactionService TransactionService + * @param nodeService NodeService + * @param contentService ContentService + * @param nodeRef NodeRef + * @param name String + */ + protected MSOfficeContentNetworkFile( + NodeService nodeService, + ContentService contentService, + MimetypeService mimetypeService, + NodeRef nodeRef, + String name) + { + super(nodeService, contentService, mimetypeService, nodeRef, name); + + // Create the buffered write list + + m_writeList = new ArrayList(); + } + + /** + * Return the file read count + * + * @return int + */ + public final int getReadCount() { + return m_readCnt; + } + + /** + * 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[] buffer, int length, int position, long fileOffset) + throws IOException + { + // Update the read count + + m_readCnt++; + + // Chain to the standard read + + return super.readFile( buffer, length, position, fileOffset); + } + + /** + * Write a block of data to the file. + * + * @param buf byte[] + * @param len int + * @param pos int + * @param fileOff long + * @exception IOException + */ + public void writeFile(byte[] buffer, int length, int position, long fileOffset) + throws IOException + { + // Check if writes are being buffered + + if ( m_writeList != null) { + + // Check if the write should be buffered + + if ( getReadCount() > 0 && m_writeList.size() < 2) { + + // Buffer the write, looks like a file open update. Do not buffer zero length writes. + + if ( length == 0) { + byte[] data = new byte[ length]; + System.arraycopy(buffer, position, data, 0, length); + + BufferedWrite bufWrite = new BufferedWrite( data, fileOffset); + m_writeList.add( bufWrite); + + // DEBUG + + if ( logger.isDebugEnabled()) + logger.debug("MSOfficeFile: Buffered write=" + bufWrite + ", cnt=" + m_writeList.size() + ", readCnt=" + getReadCount()); + } + else if ( logger.isDebugEnabled()) + logger.debug("MSOfficeFile: Ignored zero length write"); + + return; + } + + // Check if there are any buffered writes to be flushed + + if ( m_writeList.size() > 0) { + + // Write out the buffered writes first + + while ( m_writeList.size() > 0) { + + // Get the current buffered write + + BufferedWrite bufWrite = m_writeList.remove( 0); + + try { + + // Write the buffered data to the file + + super.writeFile( bufWrite.getData(), bufWrite.getDataLength(), 0, bufWrite.getOffset()); + } + catch ( Exception ex) { + + // DEBUG + + if ( logger.isDebugEnabled()) + logger.debug("MSOfficeFile: Buffered write error, " + ex.getMessage()); + } + } + + // DEBUG + + if ( logger.isDebugEnabled()) + logger.debug("MSOfficeFile: Buffered writes flushed"); + + // Disable any more buffered writes + + m_writeList = null; + } + } + + // Now do the current write + + super.writeFile(buffer, length, position, fileOffset); + } + + /** + * Close the file + * + * @exception IOException + */ + public void closeFile() + throws IOException + { + // DEBUG + + if ( logger.isDebugEnabled() && m_writeList != null) + logger.debug("MSOfficeFile: Discarded buffered writes - " + m_writeList.size()); + + // Chain to the standard close + + super.closeFile(); + } +} diff --git a/source/java/org/alfresco/filesys/state/FileState.java b/source/java/org/alfresco/filesys/state/FileState.java index 983bb5425d..fdbdace1e1 100644 --- a/source/java/org/alfresco/filesys/state/FileState.java +++ b/source/java/org/alfresco/filesys/state/FileState.java @@ -95,9 +95,11 @@ public class FileState private PseudoFileList m_pseudoFiles; - // Last updated time + // File timestamps updated only whilst file is open - private long m_lastUpdate; + private long m_accessDate; + private long m_modifyDate; + private long m_changeDate; /** * Class constructor @@ -442,26 +444,6 @@ public class FileState m_path = normalizePath(path); } - /** - * Return the last updated time - * - * @return long - */ - public final long getLastUpdated() - { - return m_lastUpdate; - } - - /** - * Set the last updated time - * - * @param updateTime long - */ - public final void setLastUpdated(long updateTime) - { - m_lastUpdate = updateTime; - } - /** * Return the count of active locks on this file * @@ -544,6 +526,91 @@ public class FileState } } + /** + * Check if the access date/time has been set + * + * @return boolean + */ + public final boolean hasAccessDateTime() { + return m_accessDate != 0L ? true : false; + } + + /** + * Return the access date/time + * + * @return long + */ + public final long getAccessDateTime() { + return m_accessDate; + } + + /** + * Update the access date/time + */ + public final void updateAccessDateTime() { + m_accessDate = System.currentTimeMillis(); + } + + /** + * Check if the change date/time has been set + * + * @return boolean + */ + public final boolean hasChangeDateTime() { + return m_changeDate != 0L ? true : false; + } + + /** + * Return the change date/time + * + * @return long + */ + public final long getChangeDateTime() { + return m_changeDate; + } + + /** + * Update the change date/time + */ + public final void updateChangeDateTime() { + m_changeDate = System.currentTimeMillis(); + } + + /** + * Check if the modification date/time has been set + * + * @return boolean + */ + public final boolean hasModifyDateTime() { + return m_modifyDate != 0L ? true : false; + } + + /** + * Return the modify date/time + * + * @return long + */ + public final long getModifyDateTime() { + return m_modifyDate; + } + + /** + * Update the modify date/time + */ + public final void updateModifyDateTime() { + m_modifyDate = System.currentTimeMillis(); + m_accessDate = m_modifyDate; + } + + /** + * Update the modify date/time + * + * @param modTime long + */ + public final void updateModifyDateTime( long modTime) { + m_modifyDate = modTime; + } + /** * Check if the file is readable for the specified section of the file and process id * diff --git a/source/java/org/alfresco/filesys/state/FileStateTable.java b/source/java/org/alfresco/filesys/state/FileStateTable.java index 958a4c8b3a..9f9f5fb577 100644 --- a/source/java/org/alfresco/filesys/state/FileStateTable.java +++ b/source/java/org/alfresco/filesys/state/FileStateTable.java @@ -127,7 +127,12 @@ public class FileStateTable */ public final synchronized FileState findFileState(String path) { - return m_stateTable.get(FileState.normalizePath(path)); + FileState fstate = m_stateTable.get(FileState.normalizePath(path)); + + if ( fstate != null) + fstate.updateAccessDateTime(); + + return fstate; } /** @@ -168,6 +173,11 @@ public class FileStateTable } } + // Update the access date/time if valid + + if ( state != null) + state.updateAccessDateTime(); + // Return the file state return state; @@ -182,7 +192,6 @@ public class FileStateTable */ public final synchronized FileState updateFileState(String oldName, String newName) { - // Find the current file state FileState state = m_stateTable.remove(FileState.normalizePath(oldName)); @@ -193,6 +202,10 @@ public class FileStateTable { state.setPath(newName); addFileState(state); + + // Update the access date/time + + state.updateAccessDateTime(); } // Return the updated file state @@ -246,6 +259,10 @@ public class FileStateTable state.setPath(FileState.normalizePath(newPath)); m_stateTable.put(state.getPath(), state); + + // Updaet the access date/time + + state.updateAccessDateTime(); } /** diff --git a/source/java/org/alfresco/repo/version/VersionableAspect.java b/source/java/org/alfresco/repo/version/VersionableAspect.java index e9f155b311..2757f12d3b 100644 --- a/source/java/org/alfresco/repo/version/VersionableAspect.java +++ b/source/java/org/alfresco/repo/version/VersionableAspect.java @@ -228,8 +228,9 @@ public class VersionableAspect implements ContentServicePolicies.OnContentUpdate @SuppressWarnings("unchecked") public void onContentUpdate(NodeRef nodeRef, boolean newContent) { - if (this.nodeService.exists(nodeRef) == true && this.nodeService.hasAspect(nodeRef, ContentModel.ASPECT_VERSIONABLE) == true) - { + if (this.nodeService.exists(nodeRef) == true && this.nodeService.hasAspect(nodeRef, ContentModel.ASPECT_VERSIONABLE) == true + && this.nodeService.hasAspect(nodeRef, ContentModel.ASPECT_TEMPORARY) == false) + { Map versionedNodeRefs = (Map)AlfrescoTransactionSupport.getResource(KEY_VERSIONED_NODEREFS); if (versionedNodeRefs == null || versionedNodeRefs.containsKey(nodeRef) == false) {