blob: d730df5ce2eb345af8e74381ecb8c3a9b5251103 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* 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.apache.commons.vfs2.provider.ram;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.vfs2.FileObject;
import org.apache.commons.vfs2.FileSystemException;
import org.apache.commons.vfs2.FileSystemOptions;
import org.apache.commons.vfs2.FileType;
import org.apache.commons.vfs2.RandomAccessContent;
import org.apache.commons.vfs2.provider.AbstractFileName;
import org.apache.commons.vfs2.provider.AbstractFileObject;
import org.apache.commons.vfs2.util.FileObjectUtils;
import org.apache.commons.vfs2.util.RandomAccessMode;
/**
* A RAM File contains a single RAM FileData instance, it provides methods to access the data by implementing FileObject
* interface.
*/
public class RamFileObject extends AbstractFileObject<RamFileSystem> {
/**
* RAM File Object Data.
*/
private RamFileData data;
/**
* @param name The name of the file.
* @param fs The FileSystem.
*/
protected RamFileObject(final AbstractFileName name, final RamFileSystem fs) {
super(name, fs);
this.getAbstractFileSystem().attach(this);
}
private void save() throws FileSystemException {
this.getAbstractFileSystem().save(this);
}
/*
* (non-Javadoc)
*
* @see org.apache.commons.vfs2.provider.AbstractFileObject#doGetType()
*/
@Override
protected FileType doGetType() throws Exception {
return data.getType();
}
/*
* (non-Javadoc)
*
* @see org.apache.commons.vfs2.provider.AbstractFileObject#doListChildren()
*/
@Override
protected String[] doListChildren() throws Exception {
return this.getAbstractFileSystem().listChildren(this.getName());
}
/*
* (non-Javadoc)
*
* @see org.apache.commons.vfs2.provider.AbstractFileObject#doGetContentSize()
*/
@Override
protected long doGetContentSize() throws Exception {
return this.size();
}
/*
* (non-Javadoc)
*
* @see org.apache.commons.vfs2.provider.AbstractFileObject#doGetInputStream()
*/
@Override
protected InputStream doGetInputStream(final int bufferSize) throws Exception {
// VFS-210: ram allows to gather an input stream even from a directory. So we need to check the type anyway.
if (!getType().hasContent()) {
throw new FileSystemException("vfs.provider/read-not-file.error", getName());
}
return new ByteArrayInputStream(this.data.getContent());
}
/*
* (non-Javadoc)
*
* @see org.apache.commons.vfs2.provider.AbstractFileObject#doGetOutputStream(boolean)
*/
@Override
protected OutputStream doGetOutputStream(final boolean bAppend) throws Exception {
if (!bAppend) {
this.data.setContent(ArrayUtils.EMPTY_BYTE_ARRAY);
}
return new RamFileOutputStream(this);
}
/*
* (non-Javadoc)
*
* @see org.apache.commons.vfs2.provider.AbstractFileObject#doDelete()
*/
@Override
protected void doDelete() throws Exception {
if (this.isContentOpen()) {
throw new FileSystemException(this.getName() + " cannot be deleted while the file is openg");
}
getAbstractFileSystem().delete(this);
}
/*
* (non-Javadoc)
*
* @see org.apache.commons.vfs2.provider.AbstractFileObject#doGetLastModifiedTime()
*/
@Override
protected long doGetLastModifiedTime() throws Exception {
return data.getLastModified();
}
/*
* (non-Javadoc)
*
* @see org.apache.commons.vfs2.provider.AbstractFileObject#doSetLastModifiedTime(long)
*/
/** @since 2.0 */
@Override
protected boolean doSetLastModifiedTime(final long modtime) throws Exception {
data.setLastModified(modtime);
return true;
}
/*
* (non-Javadoc)
*
* @see org.apache.commons.vfs2.provider.AbstractFileObject#doCreateFolder()
*/
@Override
protected void doCreateFolder() throws Exception {
this.injectType(FileType.FOLDER);
this.save();
}
/*
* (non-Javadoc)
*
* @see org.apache.commons.vfs2.provider.AbstractFileObject#doRename(org.apache.commons.vfs2.FileObject)
*/
@Override
protected void doRename(final FileObject newFile) throws Exception {
final RamFileObject newRamFileObject = (RamFileObject) FileObjectUtils.getAbstractFileObject(newFile);
getAbstractFileSystem().rename(this, newRamFileObject);
}
/*
* (non-Javadoc)
*
* @see org.apache.commons.vfs2.provider.AbstractFileObject#doGetRandomAccessContent(
* org.apache.commons.vfs2.util.RandomAccessMode)
*/
@Override
protected RandomAccessContent doGetRandomAccessContent(final RandomAccessMode mode) throws Exception {
return new RamFileRandomAccessContent(this, mode);
}
/*
* (non-Javadoc)
*
* @see org.apache.commons.vfs2.provider.AbstractFileObject#doAttach()
*/
@Override
protected void doAttach() throws Exception {
this.getAbstractFileSystem().attach(this);
}
/**
* @return Returns the data.
*/
RamFileData getData() {
return data;
}
/**
* @param data The data to set.
*/
void setData(final RamFileData data) {
this.data = data;
}
/*
* (non-Javadoc)
*
* @see org.apache.commons.vfs2.provider.AbstractFileObject#injectType(org.apache.commons.vfs2.FileType)
*/
@Override
protected void injectType(final FileType fileType) {
this.data.setType(fileType);
super.injectType(fileType);
}
/*
* (non-Javadoc)
*
* @see org.apache.commons.vfs2.provider.AbstractFileObject#endOutput()
*/
@Override
protected void endOutput() throws Exception {
super.endOutput();
this.save();
}
/**
* @return Returns the size of the {@link RamFileData}.
*/
int size() {
return data == null ? 0 : data.size();
}
/**
* @param newSize The new buffer size.
* @throws IOException if the new size exceeds the limit
*/
synchronized void resize(final long newSize) throws IOException {
final RamFileSystem afs = getAbstractFileSystem();
final FileSystemOptions afsOptions = afs.getFileSystemOptions();
if (afsOptions != null) {
final long maxSize = RamFileSystemConfigBuilder.getInstance().getLongMaxSize(afsOptions);
if (afs.size() + newSize - this.size() > maxSize) {
throw new IOException("FileSystem capacity (" + maxSize + ") exceeded.");
}
}
this.data.resize(newSize);
}
}