Package com.adito.vfs

Source Code of com.adito.vfs.VFSOutputStream

/* ========================================================================== *
* Copyright (C) 2004-2005 Pier Fumagalli <http://www.betaversion.org/~pier/> *
*                            All rights reserved.                            *
* ========================================================================== *
*                                                                            *
* Licensed 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 com.adito.vfs;

import java.io.File;
import java.io.IOException;
import java.io.OutputStream;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.vfs.FileObject;
import org.apache.commons.vfs.FileSystemException;

import com.adito.vfs.webdav.DAVException;
import com.adito.vfs.webdav.DAVListener;


/**
* <p>A specialized {@link OutputStream} to write to {@link VFSResource}s.</p>
*
* <p>When writing to this {@link OutputStream} the data will be written to
* a temporary file. This temporary file will be moved to its final destination
* (the original file identifying the resource) when the {@link #close()}
* method is called.</p>
*
* <p>This specialized {@link OutputStream} never throws {@link IOException}s,
* but rather relies on the unchecked {@link DAVException} to notify the
* framework of the correct DAV errors.</p>
*
* @author <a href="http://www.betaversion.org/~pier/">Pier Fumagalli</a>
*/
public class VFSOutputStream extends OutputStream {

    final static Log log = LogFactory.getLog(VFSOutputStream.class);
   
    /** <p>The index of the temporary file.</p> */
    private static int tmpno = (int)( Math.random() * 100000 );
    /** <p>The original resource {@link File}.</p> */
    private FileObject temporary = null;
    /** <p>The {@link OutputStream} of the temporary {@link File}. </p> */
    private OutputStream output = null;
    /** <p>The {@link VFSResource} associated with this instance. </p> */
    private VFSResource resource = null;

    /**
     * <p>Create a new {@link VFSOutputStream} instance.</p>
     */
    protected VFSOutputStream(VFSResource resource) {
        if (resource == null) throw new NullPointerException();
        this.resource = resource;

        try {
            if(resource instanceof FileObjectVFSResource) {
              // LDP - changed to get the parent using the FileObject rather than
              // the DAVResource beause we may have a null parent if the resource
              // is located at the root of a mount.
              this.temporary = resource.getFile().getParent();
              this.temporary = this.temporary.resolveFile(
                              VFSResource.PREFIX + ( tmpno++) + VFSResource.SUFFIX);
              this.output = this.temporary.getContent().getOutputStream();
            }
            else {
                throw new IOException("DAV resource is not a true file.");
            }
        } catch (IOException e) {
            String message = VfsUtils.maskSensitiveArguments("Unable to create temporary file. " + e.getMessage());
            throw new DAVException(507, message, resource);
        }
    }

    /**
     * <p>Rename the temporary {@link File} to the original one.</p>
     */
    protected void rename(FileObject temporary, FileObject original)
    throws IOException {
        if ((original.exists()) && (!original.delete())) {
            throw new IOException("Unable to delete original file");
        }
        temporary.moveTo(original);
    }

    /**
     * <p>Abort any data written to the temporary file and delete it.</p>
     */
    public void abort() {
        try {
            if (this.temporary.exists())
              this.temporary.delete();
        } catch (FileSystemException e) {
            log.error(e);           
        }
        if (this.output != null) try {
            this.output.close();
        } catch (IOException exception) {
            // Swallow the IOException on close
        } finally {
            this.output = null;
        }
    }

    /**
     * <p>Close this {@link OutputStream} {@link #rename(File,File) renaming}
     * the temporary file to the {@link VFSResource#getFile() original} one.</p>
     */
    public void close() {
        if (this.output == null) return;
        try {
            /* What kind of event should this invocation trigger? */
            int event = ((FileObjectVFSResource)this.resource).getFile().exists() ?
                        DAVListener.RESOURCE_MODIFIED:
                        DAVListener.RESOURCE_CREATED;

            /* Make sure that everything is closed and named properly */
            this.output.close();
            this.output = null;
            this.rename(this.temporary, ((FileObjectVFSResource)this.resource).getFile());

            /* Send notifications to all listeners of the repository */
            this.resource.getMount().getStore().getRepository().notify(this.resource, event);

        } catch (IOException e) {
            String message = "Error processing temporary file";
            throw new DAVException(507, message, e, this.resource);
        } finally {
            this.abort();
        }
    }

    /**
     * <p>Flush any unwritten data to the disk.</p>
     */
    public void flush() {
        if (this.output == null) throw new IllegalStateException("Closed");
        try {
            this.output.flush();
        } catch (IOException e) {
            this.abort();
            String message = "Unable to flush buffers";
            throw new DAVException(507, message, e, this.resource);
        }
    }

    /**
     * <p>Write data to this {@link OutputStream}.</p>
     */
    public void write(int b) {
        if (this.output == null) throw new IllegalStateException("Closed");
        try {
            this.output.write(b);
        } catch (IOException e) {
            this.abort();
            String message = "Unable to write data";
            throw new DAVException(507, message, e, this.resource);
        }
    }
   
    /**
     * <p>Write data to this {@link OutputStream}.</p>
     */
    public void write(byte b[]) {
        if (this.output == null) throw new IllegalStateException("Closed");
        try {
            this.output.write(b);
        } catch (IOException e) {
            this.abort();
            String message = "Unable to write data";
            throw new DAVException(507, message, e, this.resource);
        }
    }
   
    /**
     * <p>Write data to this {@link OutputStream}.</p>
     */
    public void write(byte b[], int o, int l) {
        if (this.output == null) throw new IllegalStateException("Closed");
        try {
            this.output.write(b, o, l);
        } catch (IOException e) {
            this.abort();
            String message = "Unable to write data";
            throw new DAVException(507, message, e, this.resource);
        }
    }
   
    /**
     * <p>Finalize this {@link VFSOutputStream} instance.</p>
     */
    public void finalize() {
        this.abort();
    }
}
TOP

Related Classes of com.adito.vfs.VFSOutputStream

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.