/* Index ECM Engine - A system for managing the capture (when created
* or received), classification (cataloguing), storage, retrieval,
* revision, sharing, reuse and disposition of documents.
*
* Copyright (C) 2008 Regione Piemonte
* Copyright (C) 2008 Provincia di Torino
* Copyright (C) 2008 Comune di Torino
*
* 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,
* 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*/
package it.doqui.index.ecmengine.business.personalization.multirepository;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.RandomAccessFile;
import java.nio.channels.Channels;
import java.nio.channels.WritableByteChannel;
import org.alfresco.repo.content.AbstractContentWriter;
import org.alfresco.repo.content.ContentStore;
import org.alfresco.service.cmr.repository.ContentIOException;
import org.alfresco.service.cmr.repository.ContentReader;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* Provides direct access to a local file.
* <p>
* This class does not provide remote access to the file.
*
* @author Derek Hulley
*/
public class FileContentWriterDynamic extends AbstractContentWriter
{
private static final Log logger = LogFactory.getLog(FileContentWriterDynamic.class);
private File file;
private String protocol;
private boolean allowRandomAccess;
/**
* Constructor that builds a URL based on the absolute path of the file.
*
* @param file the file for writing. This will most likely be directly
* related to the content URL.
*/
public FileContentWriterDynamic(File file, String protocol)
{
this(file, null, protocol);
}
/**
* Constructor that builds a URL based on the absolute path of the file.
*
* @param file the file for writing. This will most likely be directly
* related to the content URL.
* @param existingContentReader a reader of a previous version of this content
*/
public FileContentWriterDynamic(File file, ContentReader existingContentReader, String protocol)
{
this(
file,
protocol + ContentStore.PROTOCOL_DELIMITER + file.getAbsolutePath(),
existingContentReader,
protocol );
}
/**
* Constructor that explicitely sets the URL that the reader represents.
*
* @param file the file for writing. This will most likely be directly
* related to the content URL.
* @param url the relative url that the reader represents
* @param existingContentReader a reader of a previous version of this content
*/
public FileContentWriterDynamic(File file, String url, ContentReader existingContentReader, String protocol)
{
super(url, existingContentReader);
this.file = file;
this.protocol = protocol;
allowRandomAccess = true;
}
/* package */ void setAllowRandomAccess(boolean allow)
{
this.allowRandomAccess = allow;
}
/**
* @return Returns the file that this writer accesses
*/
public File getFile()
{
return file;
}
/**
* @return Returns the size of the underlying file or
*/
public long getSize()
{
if (file == null)
return 0L;
else if (!file.exists())
return 0L;
else
return file.length();
}
/**
* The URL of the write is known from the start and this method contract states
* that no consideration needs to be taken w.r.t. the stream state.
*/
@Override
protected ContentReader createReader() throws ContentIOException
{
FileContentReaderDynamic reader = new FileContentReaderDynamic(this.file, getContentUrl(),protocol);
reader.setAllowRandomAccess(this.allowRandomAccess);
return reader;
}
@Override
protected WritableByteChannel getDirectWritableChannel() throws ContentIOException
{
try
{
// we may not write to an existing file - EVER!!
if (file.exists() && file.length() > 0)
{
throw new IOException("File exists - overwriting not allowed");
}
// create the channel
WritableByteChannel channel = null;
if (allowRandomAccess)
{
RandomAccessFile randomAccessFile = new RandomAccessFile(file, "rw"); // will create it
channel = randomAccessFile.getChannel();
}
else
{
OutputStream os = new FileOutputStream(file);
channel = Channels.newChannel(os);
}
// done
if (logger.isDebugEnabled())
{
logger.debug("Opened write channel to file: \n" +
" file: " + file + "\n" +
" random-access: " + allowRandomAccess);
}
return channel;
}
catch (Throwable e)
{
throw new ContentIOException("Failed to open file channel: " + this, e);
}
}
/**
* @return Returns true always
*/
public boolean canWrite()
{
return true; // this is a writer
}
}