mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-07 17:49:17 +00:00
ALF-10052 - Channel Exception when reading file
git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@30470 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -68,26 +68,20 @@ public class ContentNetworkFile extends NodeRefNetworkFile
|
||||
private static final Log logger = LogFactory.getLog(ContentNetworkFile.class);
|
||||
|
||||
// Services
|
||||
|
||||
private NodeService nodeService;
|
||||
private ContentService contentService;
|
||||
private MimetypeService mimetypeService;
|
||||
|
||||
// File channel to file content
|
||||
|
||||
private FileChannel channel;
|
||||
private FileChannel channel; // File channel to file content
|
||||
private ContentAccessor content; // content
|
||||
|
||||
// File content
|
||||
|
||||
private ContentAccessor content;
|
||||
private String preUpdateContentURL;
|
||||
|
||||
// Indicate if file has been written to or truncated/resized
|
||||
|
||||
private boolean modified;
|
||||
|
||||
// Flag to indicate if the file channel is writable
|
||||
|
||||
private boolean writableChannel;
|
||||
|
||||
/**
|
||||
@@ -265,6 +259,8 @@ public class ContentNetworkFile extends NodeRefNetworkFile
|
||||
/**
|
||||
* Opens the channel for reading or writing depending on the access mode.
|
||||
* <p>
|
||||
* Side effect: sets fileSize
|
||||
* <p>
|
||||
* If the channel is already open, it is left.
|
||||
*
|
||||
* @param write true if the channel must be writable
|
||||
@@ -277,19 +273,31 @@ public class ContentNetworkFile extends NodeRefNetworkFile
|
||||
* @see NetworkFile#WRITEONLY
|
||||
* @see NetworkFile#READWRITE
|
||||
*/
|
||||
protected void openContent(boolean write, boolean trunc)
|
||||
public void openContent(boolean write, boolean trunc)
|
||||
throws AccessDeniedException, AlfrescoRuntimeException
|
||||
{
|
||||
// Check if the file is a directory
|
||||
|
||||
if (isDirectory())
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Unable to open channel for a directory network file: " + this);
|
||||
throw new AlfrescoRuntimeException("Unable to open content for a directory network file: " + this);
|
||||
}
|
||||
|
||||
if(channel != null && !write)
|
||||
{
|
||||
if(logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("channel is already open for read-only");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if write access is required and the current channel is read-only
|
||||
|
||||
else if ( write && writableChannel == false && channel != null)
|
||||
// update of channel and content member variables need to be serialized
|
||||
synchronized(this)
|
||||
{
|
||||
if ( write && writableChannel == false && channel != null)
|
||||
{
|
||||
// Close the existing read-only channel
|
||||
|
||||
@@ -297,6 +305,7 @@ public class ContentNetworkFile extends NodeRefNetworkFile
|
||||
{
|
||||
channel.close();
|
||||
channel = null;
|
||||
content = null;
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
@@ -306,12 +315,13 @@ public class ContentNetworkFile extends NodeRefNetworkFile
|
||||
// Debug
|
||||
|
||||
if ( logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("Switching to writable channel for " + getName());
|
||||
}
|
||||
}
|
||||
else if (channel != null)
|
||||
{
|
||||
// Already have channel open
|
||||
|
||||
// Already have read/write channel open
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -322,14 +332,15 @@ public class ContentNetworkFile extends NodeRefNetworkFile
|
||||
throw new AccessDeniedException("The network file was created for read-only: " + this);
|
||||
}
|
||||
|
||||
content = null;
|
||||
preUpdateContentURL = null;
|
||||
|
||||
// Need to open content for write
|
||||
if (write)
|
||||
{
|
||||
// Get a writeable channel to the content, along with the original content
|
||||
if(logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("get writer for content property");
|
||||
logger.debug("open writer for content property");
|
||||
}
|
||||
|
||||
content = contentService.getWriter( getNodeRef(), ContentModel.PROP_CONTENT, false);
|
||||
@@ -347,7 +358,6 @@ public class ContentNetworkFile extends NodeRefNetworkFile
|
||||
writableChannel = true;
|
||||
|
||||
// Get the writable channel, do not copy existing content data if the file is to be truncated
|
||||
|
||||
channel = ((ContentWriter) content).getFileChannel( trunc);
|
||||
}
|
||||
else
|
||||
@@ -355,7 +365,7 @@ public class ContentNetworkFile extends NodeRefNetworkFile
|
||||
// Get a read-only channel to the content
|
||||
if(logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("get reader for content property");
|
||||
logger.debug("open reader for content property");
|
||||
}
|
||||
|
||||
content = contentService.getReader( getNodeRef(), ContentModel.PROP_CONTENT);
|
||||
@@ -393,6 +403,7 @@ public class ContentNetworkFile extends NodeRefNetworkFile
|
||||
|
||||
setClosed( false);
|
||||
}
|
||||
} // release lock
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -420,9 +431,8 @@ public class ContentNetworkFile extends NodeRefNetworkFile
|
||||
setClosed( true);
|
||||
return;
|
||||
}
|
||||
else if (!hasContent())
|
||||
{
|
||||
// File was not read/written so channel was not opened
|
||||
else if (!hasContent()) {
|
||||
// File was not read/written so content was not opened
|
||||
if(logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("no content to write - nothing to do");
|
||||
@@ -434,6 +444,10 @@ public class ContentNetworkFile extends NodeRefNetworkFile
|
||||
|
||||
// Check if the file has been modified
|
||||
|
||||
// update of channel and content member variables need to be serialized
|
||||
synchronized(this)
|
||||
{
|
||||
|
||||
if (modified)
|
||||
{
|
||||
if(logger.isDebugEnabled())
|
||||
@@ -446,6 +460,11 @@ public class ContentNetworkFile extends NodeRefNetworkFile
|
||||
// We may be in a retry block, in which case this section will already have executed and channel will be null
|
||||
if (channel != null)
|
||||
{
|
||||
// Close the channel
|
||||
channel.close();
|
||||
channel = null;
|
||||
}
|
||||
|
||||
// Do we need the mimetype guessing for us when we're done?
|
||||
if (content.getMimetype() == null || content.getMimetype().equals(MimetypeMap.MIMETYPE_BINARY) )
|
||||
{
|
||||
@@ -456,11 +475,6 @@ public class ContentNetworkFile extends NodeRefNetworkFile
|
||||
// We always want the encoding guessing
|
||||
writer.guessEncoding();
|
||||
|
||||
// Close the channel
|
||||
channel.close();
|
||||
channel = null;
|
||||
}
|
||||
|
||||
// Retrieve the content data and stop the content URL from being 'eagerly deleted', in case we need to
|
||||
// retry the transaction
|
||||
|
||||
@@ -496,6 +510,8 @@ public class ContentNetworkFile extends NodeRefNetworkFile
|
||||
}
|
||||
catch (ContentQuotaException qe)
|
||||
{
|
||||
content = null;
|
||||
setClosed( true);
|
||||
throw new DiskFullException(qe.getMessage());
|
||||
}
|
||||
}
|
||||
@@ -505,12 +521,18 @@ public class ContentNetworkFile extends NodeRefNetworkFile
|
||||
{
|
||||
@Override
|
||||
public void afterCommit()
|
||||
{
|
||||
synchronized(this)
|
||||
{
|
||||
if(channel == null)
|
||||
{
|
||||
content = null;
|
||||
preUpdateContentURL = null;
|
||||
|
||||
setClosed( true);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
else if (channel != null)
|
||||
@@ -523,6 +545,9 @@ public class ContentNetworkFile extends NodeRefNetworkFile
|
||||
|
||||
channel.close();
|
||||
channel = null;
|
||||
content = null;
|
||||
setClosed(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -601,9 +626,9 @@ public class ContentNetworkFile extends NodeRefNetworkFile
|
||||
public void writeFile(byte[] buffer, int length, int position, long fileOffset)
|
||||
throws IOException
|
||||
{
|
||||
try {
|
||||
try
|
||||
{
|
||||
// Open the channel for writing
|
||||
|
||||
openContent(true, false);
|
||||
}
|
||||
catch ( ContentIOException ex) {
|
||||
@@ -842,4 +867,5 @@ public class ContentNetworkFile extends NodeRefNetworkFile
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user