/*
 * Copyright 2009 New Atlanta Communications, LLC
 *
 * 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.newatlanta.commons.vfs.provider.gae;

import java.io.IOException;

import org.apache.commons.vfs.FileObject;

/**
 * Creates and initializes a GaeFileSystemManager.
 * 
 * IMPORTANT! You must set the path to the webapp root directory via the
 * GaeVFS.setRootPath() method before invoking GaeVFS.getManager().
 * 
 * IMPORTANT! You must clear the ThreadLocal cache at the end of every request
 * via the GaeVFS.clearFilesCache() method. See additional comments within the
 * GaeMemcacheFilesCache class.
 *
 * @author Vince Bonfanti <vbonfanti@gmail.com>
 */
public class GaeVFS {

    private static final int DEFAULT_BLOCK_SIZE = 1024 * 32; // max 1024 x 1023
    
    static {
        // GAE doesn't set these values; Commons VFS will fail to
        // initialize if they're not set
        System.setProperty( "os.arch", "" );
        System.setProperty( "os.version", "" );
    }

    private static GaeFileSystemManager fsManager;
    private static String rootPath;
    private static int blockSize = DEFAULT_BLOCK_SIZE;

    public static GaeFileSystemManager getManager() throws IOException {
        if ( fsManager == null ) {
            if ( rootPath == null ) {
                throw new IOException( "root path not defined" );
            }
            fsManager = new GaeFileSystemManager();
            fsManager.init( rootPath );
        }
        return fsManager;
    }
    
    public static void setRootPath( String _rootPath ) {
        rootPath = _rootPath;
    }
    
    public static int getBlockSize() {
        return blockSize;
    }
    
    public void setBlockSize( int size ) {
        if ( size <= 0 ) {
            throw new IllegalArgumentException( "invalid block size: " + size );
        }
        blockSize = Math.min( size, 1023 ) * 1024; // max size is 1023 * 1024
    }
    
    public static void setBlockSize( FileObject fileObject, int size ) throws IOException {
        if ( size <= 0 ) {
            throw new IllegalArgumentException( "invalid block size: " + size );
        }
        if ( fileObject instanceof GaeFileObject ) {
            ((GaeFileObject)fileObject).setBlockSize( Math.min( size, 1023 ) * 1024 );
        }
    }

    public static FileObject resolveFile( String name ) throws IOException {
        return getManager().resolveFile( name );
    }

    public static void clearFilesCache() {
        if ( fsManager != null ) {
            fsManager.clearFilesCache();
        }
    }

    public static void close() {
        if ( fsManager != null ) {
            fsManager.close();
            fsManager = null;
        }
    }
}
@@ -671,24 +671,63 @@
 der.gae;%0D%0A%0D%0A
+import java.io.FileNotFoundException;%0D%0A
 import java.
@@ -787,16 +787,227 @@
 Object;%0D
+%0Aimport org.apache.commons.vfs.FileSystemException;%0D%0Aimport org.apache.commons.vfs.RandomAccessContent;%0D%0Aimport org.apache.commons.vfs.util.FileObjectUtils;%0D%0Aimport org.apache.commons.vfs.util.RandomAccessMode;%0D
 %0A%0D%0A/**%0D%0A
@@ -2833,34 +2833,42 @@
 t size ) throws 
-IO
+FileSystem
 Exception %7B%0D%0A   
@@ -3273,32 +3273,1296 @@
  name );%0D%0A    %7D%0D
+%0A    %0D%0A    public static RandomAccessContent getRandomAccessContent( String name, String mode )%0D%0A            throws IOException %7B%0D%0A        return getRandomAccessContent( resolveFile( name ), mode );%0D%0A    %7D%0D%0A%0D%0A    public static RandomAccessContent getRandomAccessContent( FileObject fileObject, String mode )%0D%0A            throws IOException %7B%0D%0A        RandomAccessMode raMode;%0D%0A        if ( mode.equals( %22r%22 ) ) %7B%0D%0A            raMode = RandomAccessMode.READ;%0D%0A        // TODO: support %22rws%22 and %22rwd%22 modes as described for RandomAccessFile?%0D%0A        %7D else if ( mode.equals( %22rw%22 ) ) %7B // %7C%7C mode.equals( %22rws%22 ) %7C%7C mode.equals( %22rwd%22 ) ) %7B%0D%0A            raMode = RandomAccessMode.READWRITE;%0D%0A        %7D else %7B%0D%0A            throw new IllegalArgumentException( %22invalid mode: %22 + mode );%0D%0A        %7D%0D%0A        if ( !fileObject.exists() ) %7B%0D%0A            // if opening for read/write and the file doesn't exist, try to create it%0D%0A            if ( raMode == RandomAccessMode.READWRITE ) %7B%0D%0A                fileObject.createFile();%0D%0A            %7D else %7B%0D%0A                throw new FileNotFoundException( fileObject.getName().getPath() );%0D%0A            %7D%0D%0A        %7D%0D%0A        return FileObjectUtils.getAbstractFileObject( fileObject ).getRandomAccessContent( raMode );%0D%0A    %7D%0D
 %0A%0D%0A    public st

add getRandomAccessContent() methods