All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.kie.commons.io.impl.cluster.IOServiceClusterImpl Maven / Gradle / Ivy

There is a newer version: 6.0.0.CR5
Show newest version
package org.kie.commons.io.impl.cluster;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
import java.util.concurrent.atomic.AtomicBoolean;

import org.kie.commons.cluster.ClusterService;
import org.kie.commons.cluster.ClusterServiceFactory;
import org.kie.commons.cluster.LockExecuteNotifySyncReleaseTemplate;
import org.kie.commons.data.Pair;
import org.kie.commons.io.FileSystemType;
import org.kie.commons.io.IOService;
import org.kie.commons.java.nio.IOException;
import org.kie.commons.java.nio.base.FileSystemId;
import org.kie.commons.java.nio.base.SeekableByteChannelWrapperImpl;
import org.kie.commons.java.nio.channels.SeekableByteChannel;
import org.kie.commons.java.nio.file.AtomicMoveNotSupportedException;
import org.kie.commons.java.nio.file.CopyOption;
import org.kie.commons.java.nio.file.DirectoryNotEmptyException;
import org.kie.commons.java.nio.file.DirectoryStream;
import org.kie.commons.java.nio.file.FileAlreadyExistsException;
import org.kie.commons.java.nio.file.FileSystem;
import org.kie.commons.java.nio.file.FileSystemAlreadyExistsException;
import org.kie.commons.java.nio.file.FileSystemNotFoundException;
import org.kie.commons.java.nio.file.NoSuchFileException;
import org.kie.commons.java.nio.file.NotDirectoryException;
import org.kie.commons.java.nio.file.OpenOption;
import org.kie.commons.java.nio.file.Option;
import org.kie.commons.java.nio.file.Path;
import org.kie.commons.java.nio.file.ProviderNotFoundException;
import org.kie.commons.java.nio.file.attribute.FileAttribute;
import org.kie.commons.java.nio.file.attribute.FileAttributeView;
import org.kie.commons.java.nio.file.attribute.FileTime;
import org.kie.commons.lock.LockExecuteReleaseTemplate;
import org.kie.commons.message.AsyncCallback;
import org.kie.commons.message.MessageHandler;
import org.kie.commons.message.MessageHandlerResolver;
import org.kie.commons.message.MessageType;

import static org.kie.commons.io.impl.cluster.ClusterMessageType.*;
import static org.kie.commons.validation.Preconditions.*;

public class IOServiceClusterImpl implements IOService {

    private final IOService service;
    private final ClusterService clusterService;
    private NewFileSystemListener newFileSystemListener = null;

    public IOServiceClusterImpl( final IOService service,
                                 final ClusterServiceFactory clusterServiceFactory ) {
        checkNotNull( "clusterServiceFactory", clusterServiceFactory );
        this.service = checkNotNull( "service", service );

        this.clusterService = clusterServiceFactory.build( new MessageHandlerResolver() {

            final MessageHandler newFs = new NewFileSystemMessageHandler();
            final MessageHandler syncFs = new SyncFileSystemMessageHandler();
            final MessageHandler queryFs = new QueryFileSystemMessageHandler();

            @Override
            public MessageHandler resolveHandler( final MessageType type ) {
                if ( NEW_FS.equals( type ) ) {
                    return newFs;
                } else if ( SYNC_FS.equals( type ) ) {
                    return syncFs;
                } else if ( QUERY_FOR_FS.equals( type ) ) {
                    return queryFs;
                }

                return null;
            }
        } );

        //New cluster members are executed within locked
        new LockExecuteReleaseTemplate().execute( clusterService, new FutureTask( new Callable() {
            @Override
            public Void call() throws Exception {

                // 10 seconds
                int timeout = 10000;
                final AtomicBoolean msgAnsweredOrTimedout = new AtomicBoolean( false );
                final AtomicBoolean onSync = new AtomicBoolean( false );

                final Map fileSystems = new HashMap();

                clusterService.broadcastAndWait( QUERY_FOR_FS, Collections.emptyMap(), timeout, new AsyncCallback() {
                    @Override
                    public void onTimeOut() {
                        msgAnsweredOrTimedout.set( true );
                    }

                    @Override
                    public void onReply( final MessageType type,
                                         final Map content ) {
                        if ( msgAnsweredOrTimedout.get() || onSync.get() ) {
                            return;
                        }

                        onSync.set( true );

                        new Thread() {
                            @Override
                            public void run() {
                                for ( final Map.Entry entry : content.entrySet() ) {
                                    if ( entry.getKey().startsWith( "fs_" ) ) {
                                        int index = Integer.valueOf( entry.getKey().substring( entry.getKey().lastIndexOf( "_" ) + 1 ) );
                                        if ( !fileSystems.containsKey( index ) ) {
                                            fileSystems.put( index, new FileSystemInfo() );
                                        }
                                        final FileSystemInfo fsInfo = fileSystems.get( index );
                                        if ( entry.getKey().startsWith( "fs_id_" ) ) {
                                            fsInfo.setId( entry.getValue() );
                                        } else if ( entry.getKey().startsWith( "fs_scheme_" ) ) {
                                            fsInfo.setScheme( entry.getValue() );
                                        } else if ( entry.getKey().startsWith( "fs_uri_" ) ) {
                                            fsInfo.setUri( entry.getValue() );
                                        }
                                    }
                                }

                                for ( final FileSystemInfo fileSystemInfo : fileSystems.values() ) {
                                    try {
                                        final URI newFS = URI.create( fileSystemInfo.getScheme() + "://" + fileSystemInfo.getId() );
                                        service.newFileSystem( newFS, Collections.emptyMap() );
                                    } catch ( FileSystemAlreadyExistsException ex ) {
                                    }

                                    final URI fs = URI.create( fileSystemInfo.getScheme() + "://" + fileSystemInfo.getId() + "?sync=" + fileSystemInfo.getUri() + "&force" );
                                    service.getFileSystem( fs );
                                }

                                msgAnsweredOrTimedout.set( true );
                            }
                        }.start();
                    }
                } );

                while ( !msgAnsweredOrTimedout.get() ) {
                    try {
                        Thread.sleep( 100 );
                    } catch ( InterruptedException e ) {
                    }
                }

                return null;
            }
        } ) );
    }

    @Override
    public void dispose() {
        service.dispose();
    }

    @Override
    public void startBatch( final Option... options ) {
        clusterService.lock();
    }

    @Override
    public void endBatch( final Option... options ) {
        clusterService.unlock();
    }

    @Override
    public FileAttribute[] convert( final Map attrs ) {
        return service.convert( attrs );
    }

    @Override
    public Path get( final String first,
                     final String... more ) throws IllegalArgumentException {
        return service.get( first, more );
    }

    @Override
    public Path get( final URI uri ) throws IllegalArgumentException, FileSystemNotFoundException, SecurityException {
        return service.get( uri );
    }

    @Override
    public Iterable getFileSystems() {
        return service.getFileSystems();
    }

    @Override
    public Iterable getFileSystems( final FileSystemType type ) {
        return service.getFileSystems( type );
    }

    @Override
    public FileSystem getFileSystem( final URI uri ) throws IllegalArgumentException, FileSystemNotFoundException, ProviderNotFoundException, SecurityException {
        return service.getFileSystem( uri );
    }

    @Override
    public FileSystem newFileSystem( final URI uri,
                                     final Map env ) throws IllegalArgumentException, FileSystemAlreadyExistsException, ProviderNotFoundException, IOException, SecurityException {
        return new LockExecuteNotifySyncReleaseTemplate() {

            @Override
            public MessageType getMessageType() {
                return NEW_FS;
            }

            @Override
            public Map buildContent() {
                return new HashMap() {{
                    put( "uri", uri.toString() );
                    for ( final Map.Entry entry : env.entrySet() ) {
                        put( entry.getKey(), entry.getValue().toString() );
                    }
                }};
            }

            @Override
            public int timeOut() {
                return 3000;
            }
        }.execute( clusterService, new FutureTask( new Callable() {
            @Override
            public FileSystem call() throws Exception {
                return service.newFileSystem( uri, new HashMap( env ) {{
                    put( "clusterService", clusterService );
                }} );
            }
        } ) );
    }

    @Override
    public FileSystem newFileSystem( final URI uri,
                                     final Map env,
                                     final FileSystemType type ) throws IllegalArgumentException, FileSystemAlreadyExistsException, ProviderNotFoundException, IOException, SecurityException {
        return new LockExecuteNotifySyncReleaseTemplate() {

            @Override
            public MessageType getMessageType() {
                return NEW_FS;
            }

            @Override
            public Map buildContent() {
                return new HashMap() {{
                    put( "uri", uri.toString() );
                    put( "type", type.toString() );
                    for ( final Map.Entry entry : env.entrySet() ) {
                        put( entry.getKey(), entry.getValue().toString() );
                    }
                }};
            }

            @Override
            public int timeOut() {
                return 300;
            }
        }.execute( clusterService, new FutureTask( new Callable() {
            @Override
            public FileSystem call() throws Exception {
                return service.newFileSystem( uri, new HashMap( env ) {{
                    put( "clusterService", clusterService );
                }}, type );

            }
        } ) );

    }

    @Override
    public void onNewFileSystem( NewFileSystemListener listener ) {
        this.newFileSystemListener = listener;
    }

    @Override
    public InputStream newInputStream( final Path path,
                                       final OpenOption... options ) throws IllegalArgumentException, NoSuchFileException, UnsupportedOperationException, IOException, SecurityException {
        return service.newInputStream( path, options );
    }

    @Override
    public DirectoryStream newDirectoryStream( final Path dir ) throws IllegalArgumentException, NotDirectoryException, IOException, SecurityException {
        return service.newDirectoryStream( dir );
    }

    @Override
    public DirectoryStream newDirectoryStream( final Path dir,
                                                     final DirectoryStream.Filter filter ) throws IllegalArgumentException, NotDirectoryException, IOException, SecurityException {
        return service.newDirectoryStream( dir, filter );
    }

    @Override
    public Path createFile( final Path path,
                            final FileAttribute... attrs ) throws IllegalArgumentException, UnsupportedOperationException, FileAlreadyExistsException, IOException, SecurityException {
        return new FileSystemSyncLock( path.getFileSystem() ).execute( clusterService, new FutureTask( new Callable() {
            @Override
            public Path call() throws Exception {
                return service.createFile( path, attrs );
            }
        } ) );
    }

    @Override
    public Path createDirectory( final Path dir,
                                 final FileAttribute... attrs ) throws IllegalArgumentException, UnsupportedOperationException, FileAlreadyExistsException, IOException, SecurityException {
        return new FileSystemSyncLock( dir.getFileSystem() ).execute( clusterService, new FutureTask( new Callable() {
            @Override
            public Path call() throws Exception {
                return service.createDirectory( dir, attrs );
            }
        } ) );
    }

    @Override
    public Path createDirectories( final Path dir,
                                   final FileAttribute... attrs ) throws UnsupportedOperationException, FileAlreadyExistsException, IOException, SecurityException {
        return new FileSystemSyncLock( dir.getFileSystem() ).execute( clusterService, new FutureTask( new Callable() {
            @Override
            public Path call() throws Exception {
                return service.createDirectories( dir, attrs );
            }
        } ) );
    }

    @Override
    public Path createDirectory( final Path dir,
                                 final Map attrs ) throws IllegalArgumentException, UnsupportedOperationException, FileAlreadyExistsException, IOException, SecurityException {
        return new FileSystemSyncLock( dir.getFileSystem() ).execute( clusterService, new FutureTask( new Callable() {
            @Override
            public Path call() throws Exception {
                return service.createDirectory( dir, attrs );
            }
        } ) );
    }

    @Override
    public Path createDirectories( final Path dir,
                                   final Map attrs ) throws UnsupportedOperationException, FileAlreadyExistsException, IOException, SecurityException {
        return new FileSystemSyncLock( dir.getFileSystem() ).execute( clusterService, new FutureTask( new Callable() {
            @Override
            public Path call() throws Exception {
                return service.createDirectories( dir, attrs );
            }
        } ) );
    }

    @Override
    public void delete( final Path path ) throws IllegalArgumentException, NoSuchFileException, DirectoryNotEmptyException, IOException, SecurityException {
        new FileSystemSyncLock( path.getFileSystem() ).execute( clusterService, new FutureTask( new Callable() {
            @Override
            public Void call() throws Exception {
                service.delete( path );
                return null;
            }
        } ) );
    }

    @Override
    public boolean deleteIfExists( final Path path ) throws IllegalArgumentException, DirectoryNotEmptyException, IOException, SecurityException {
        return new FileSystemSyncLock( path.getFileSystem() ).execute( clusterService, new FutureTask( new Callable() {
            @Override
            public Boolean call() throws Exception {
                return service.deleteIfExists( path );
            }
        } ) );
    }

    @Override
    public Path createTempFile( final String prefix,
                                final String suffix,
                                final FileAttribute... attrs ) throws IllegalArgumentException, UnsupportedOperationException, IOException, SecurityException {
        return service.createTempFile( prefix, suffix, attrs );
    }

    @Override
    public Path createTempFile( final Path dir,
                                final String prefix,
                                final String suffix,
                                final FileAttribute... attrs ) throws IllegalArgumentException, UnsupportedOperationException, IOException, SecurityException {
        return service.createTempFile( dir, prefix, suffix, attrs );
    }

    @Override
    public Path createTempDirectory( final String prefix,
                                     final FileAttribute... attrs ) throws IllegalArgumentException, UnsupportedOperationException, IOException, SecurityException {
        return service.createTempDirectory( prefix, attrs );
    }

    @Override
    public Path createTempDirectory( final Path dir,
                                     final String prefix,
                                     final FileAttribute... attrs ) throws IllegalArgumentException, UnsupportedOperationException, IOException, SecurityException {
        return service.createTempDirectory( dir, prefix, attrs );
    }

    @Override
    public Path copy( final Path source,
                      final Path target,
                      final CopyOption... options ) throws UnsupportedOperationException, FileAlreadyExistsException, DirectoryNotEmptyException, IOException, SecurityException {
        return new FileSystemSyncLock( target.getFileSystem() ).execute( clusterService, new FutureTask( new Callable() {
            @Override
            public Path call() throws Exception {
                return service.copy( source, target, options );
            }
        } ) );
    }

    @Override
    public long copy( final InputStream in,
                      final Path target,
                      final CopyOption... options ) throws IOException, FileAlreadyExistsException, DirectoryNotEmptyException, UnsupportedOperationException, SecurityException {
        return new FileSystemSyncLock( target.getFileSystem() ).execute( clusterService, new FutureTask( new Callable() {
            @Override
            public Long call() throws Exception {
                return service.copy( in, target, options );
            }
        } ) );
    }

    @Override
    public long copy( final Path source,
                      final OutputStream out ) throws IOException, SecurityException {
        return service.copy( source, out );
    }

    @Override
    public Path move( final Path source,
                      final Path target,
                      final CopyOption... options ) throws UnsupportedOperationException, FileAlreadyExistsException, DirectoryNotEmptyException, AtomicMoveNotSupportedException, IOException, SecurityException {
        return new FileSystemSyncLock( source.getFileSystem() ).execute( clusterService, new FutureTask( new Callable() {
            @Override
            public Path call() throws Exception {
                return new FileSystemSyncLock( target.getFileSystem() ).execute( clusterService, new FutureTask( new Callable() {
                    @Override
                    public Path call() throws Exception {
                        return service.move( source, target, options );
                    }
                } ) );
            }
        } ) );
    }

    @Override
    public  V getFileAttributeView( final Path path,
                                                                 final Class type ) throws IllegalArgumentException {
        return service.getFileAttributeView( path, type );
    }

    @Override
    public Map readAttributes( final Path path ) throws UnsupportedOperationException, NoSuchFileException, IllegalArgumentException, IOException, SecurityException {
        return service.readAttributes( path );
    }

    @Override
    public Map readAttributes( final Path path,
                                               final String attributes ) throws UnsupportedOperationException, NoSuchFileException, IllegalArgumentException, IOException, SecurityException {
        return service.readAttributes( path, attributes );
    }

    @Override
    public Path setAttributes( final Path path,
                               final FileAttribute... attrs ) throws UnsupportedOperationException, IllegalArgumentException, ClassCastException, IOException, SecurityException {
        return new FileSystemSyncLock( path.getFileSystem() ).execute( clusterService, new FutureTask( new Callable() {
            @Override
            public Path call() throws Exception {
                return service.setAttributes( path, attrs );
            }
        } ) );
    }

    @Override
    public Path setAttributes( final Path path,
                               final Map attrs ) throws UnsupportedOperationException, IllegalArgumentException, ClassCastException, IOException, SecurityException {
        return new FileSystemSyncLock( path.getFileSystem() ).execute( clusterService, new FutureTask( new Callable() {
            @Override
            public Path call() throws Exception {
                return service.setAttributes( path, attrs );
            }
        } ) );
    }

    @Override
    public Path setAttribute( final Path path,
                              final String attribute,
                              final Object value ) throws UnsupportedOperationException, IllegalArgumentException, ClassCastException, IOException, SecurityException {
        return new FileSystemSyncLock( path.getFileSystem() ).execute( clusterService, new FutureTask( new Callable() {
            @Override
            public Path call() throws Exception {
                return service.setAttribute( path, attribute, value );
            }
        } ) );
    }

    @Override
    public Object getAttribute( final Path path,
                                final String attribute ) throws UnsupportedOperationException, IllegalArgumentException, IOException, SecurityException {
        return service.getAttribute( path, attribute );
    }

    @Override
    public FileTime getLastModifiedTime( final Path path ) throws IllegalArgumentException, IOException, SecurityException {
        return service.getLastModifiedTime( path );
    }

    @Override
    public long size( final Path path ) throws IllegalArgumentException, IOException, SecurityException {
        return service.size( path );
    }

    @Override
    public boolean exists( final Path path ) throws IllegalArgumentException, SecurityException {
        return service.exists( path );
    }

    @Override
    public boolean notExists( final Path path ) throws IllegalArgumentException, SecurityException {
        return service.notExists( path );
    }

    @Override
    public boolean isSameFile( final Path path,
                               final Path path2 ) throws IllegalArgumentException, IOException, SecurityException {
        return service.isSameFile( path, path2 );
    }

    @Override
    public BufferedReader newBufferedReader( final Path path,
                                             final Charset cs ) throws IllegalArgumentException, NoSuchFileException, IOException, SecurityException {
        return service.newBufferedReader( path, cs );
    }

    @Override
    public byte[] readAllBytes( final Path path ) throws IOException, OutOfMemoryError, SecurityException {
        return service.readAllBytes( path );
    }

    @Override
    public List readAllLines( final Path path ) throws IllegalArgumentException, NoSuchFileException, IOException, SecurityException {
        return service.readAllLines( path );
    }

    @Override
    public List readAllLines( final Path path,
                                      final Charset cs ) throws IllegalArgumentException, NoSuchFileException, IOException, SecurityException {
        return service.readAllLines( path, cs );
    }

    @Override
    public String readAllString( final Path path,
                                 final Charset cs ) throws IllegalArgumentException, NoSuchFileException, IOException {
        return service.readAllString( path, cs );
    }

    @Override
    public String readAllString( final Path path ) throws IllegalArgumentException, NoSuchFileException, IOException {
        return service.readAllString( path );
    }

    @Override
    public Path write( final Path path,
                       final byte[] bytes,
                       final OpenOption... options ) throws IOException, UnsupportedOperationException, SecurityException {
        return new FileSystemSyncLock( path.getFileSystem() ).execute( clusterService, new FutureTask( new Callable() {
            @Override
            public Path call() throws Exception {
                return service.write( path, bytes, options );
            }
        } ) );
    }

    @Override
    public Path write( final Path path,
                       final byte[] bytes,
                       final Map attrs,
                       final OpenOption... options ) throws IOException, UnsupportedOperationException, SecurityException {
        return new FileSystemSyncLock( path.getFileSystem() ).execute( clusterService, new FutureTask( new Callable() {
            @Override
            public Path call() throws Exception {
                return service.write( path, bytes, attrs, options );
            }
        } ) );
    }

    @Override
    public Path write( final Path path,
                       final byte[] bytes,
                       final Set options,
                       final FileAttribute... attrs ) throws IllegalArgumentException, IOException, UnsupportedOperationException {
        return new FileSystemSyncLock( path.getFileSystem() ).execute( clusterService, new FutureTask( new Callable() {
            @Override
            public Path call() throws Exception {
                return service.write( path, bytes, options, attrs );
            }
        } ) );
    }

    @Override
    public Path write( final Path path,
                       final Iterable lines,
                       final Charset cs,
                       final OpenOption... options ) throws IllegalArgumentException, IOException, UnsupportedOperationException, SecurityException {
        return new FileSystemSyncLock( path.getFileSystem() ).execute( clusterService, new FutureTask( new Callable() {
            @Override
            public Path call() throws Exception {
                return service.write( path, lines, cs, options );
            }
        } ) );
    }

    @Override
    public Path write( final Path path,
                       final String content,
                       final OpenOption... options ) throws IllegalArgumentException, IOException, UnsupportedOperationException {
        return new FileSystemSyncLock( path.getFileSystem() ).execute( clusterService, new FutureTask( new Callable() {
            @Override
            public Path call() throws Exception {
                return service.write( path, content, options );
            }
        } ) );
    }

    @Override
    public Path write( final Path path,
                       final String content,
                       final Charset cs,
                       final OpenOption... options ) throws IllegalArgumentException, IOException, UnsupportedOperationException {
        return new FileSystemSyncLock( path.getFileSystem() ).execute( clusterService, new FutureTask( new Callable() {
            @Override
            public Path call() throws Exception {
                return service.write( path, content, cs, options );
            }
        } ) );
    }

    @Override
    public Path write( final Path path,
                       final String content,
                       final Set options,
                       final FileAttribute... attrs ) throws IllegalArgumentException, IOException, UnsupportedOperationException {
        return new FileSystemSyncLock( path.getFileSystem() ).execute( clusterService, new FutureTask( new Callable() {
            @Override
            public Path call() throws Exception {
                return service.write( path, content, options, attrs );
            }
        } ) );
    }

    @Override
    public Path write( final Path path,
                       final String content,
                       final Charset cs,
                       final Set options,
                       final FileAttribute... attrs ) throws IllegalArgumentException, IOException, UnsupportedOperationException {
        return new FileSystemSyncLock( path.getFileSystem() ).execute( clusterService, new FutureTask( new Callable() {
            @Override
            public Path call() throws Exception {
                return service.write( path, content, cs, options, attrs );
            }
        } ) );
    }

    @Override
    public Path write( final Path path,
                       final String content,
                       final Map attrs,
                       final OpenOption... options ) throws IllegalArgumentException, IOException, UnsupportedOperationException {
        return new FileSystemSyncLock( path.getFileSystem() ).execute( clusterService, new FutureTask( new Callable() {
            @Override
            public Path call() throws Exception {
                return service.write( path, content, attrs, options );
            }
        } ) );
    }

    @Override
    public Path write( final Path path,
                       final String content,
                       final Charset cs,
                       final Map attrs,
                       final OpenOption... options ) throws IllegalArgumentException, IOException, UnsupportedOperationException {
        return new FileSystemSyncLock( path.getFileSystem() ).execute( clusterService, new FutureTask( new Callable() {
            @Override
            public Path call() throws Exception {
                return service.write( path, content, cs, attrs, options );
            }
        } ) );
    }

    @Override
    public OutputStream newOutputStream( final Path path,
                                         final OpenOption... options ) throws IllegalArgumentException, UnsupportedOperationException, IOException, SecurityException {
        final OutputStream out = service.newOutputStream( path, options );
        return new OutputStream() {
            @Override
            public void write( final int b ) throws java.io.IOException {
                out.write( b );
            }

            @Override
            public void close() throws java.io.IOException {
                new FileSystemSyncLock( path.getFileSystem() ).execute( clusterService, new FutureTask( new Callable() {
                    @Override
                    public Void call() throws Exception {
                        out.close();
                        return null;
                    }
                } ) );
            }
        };
    }

    @Override
    public SeekableByteChannel newByteChannel( final Path path,
                                               final OpenOption... options ) throws IllegalArgumentException, UnsupportedOperationException, FileAlreadyExistsException, IOException, SecurityException {
        final SeekableByteChannel sbc = service.newByteChannel( path, options );

        return new SeekableByteChannelWrapperImpl( sbc ) {
            @Override
            public void close() throws java.io.IOException {
                new FileSystemSyncLock( path.getFileSystem() ).execute( clusterService, new FutureTask( new Callable() {
                    @Override
                    public Void call() throws Exception {
                        sbc.close();
                        return null;
                    }
                } ) );
            }
        };
    }

    @Override
    public SeekableByteChannel newByteChannel( final Path path,
                                               final Set options,
                                               final FileAttribute... attrs ) throws IllegalArgumentException, UnsupportedOperationException, FileAlreadyExistsException, IOException, SecurityException {
        final SeekableByteChannel sbc = service.newByteChannel( path, options, attrs );

        return new SeekableByteChannelWrapperImpl( sbc ) {
            @Override
            public void close() throws java.io.IOException {
                new FileSystemSyncLock( path.getFileSystem() ).execute( clusterService, new FutureTask( new Callable() {
                    @Override
                    public Void call() throws Exception {
                        sbc.close();
                        return null;
                    }
                } ) );
            }
        };
    }

    @Override
    public BufferedWriter newBufferedWriter( final Path path,
                                             final Charset cs,
                                             final OpenOption... options ) throws IllegalArgumentException, IOException, UnsupportedOperationException, SecurityException {
        return new BufferedWriter( service.newBufferedWriter( path, cs, options ) ) {
            @Override
            public void close() throws java.io.IOException {
                new FileSystemSyncLock( path.getFileSystem() ).execute( clusterService, new FutureTask( new Callable() {
                    @Override
                    public Void call() throws Exception {
                        superClose();
                        return null;
                    }
                } ) );
            }

            private void superClose() {
                try {
                    super.close();
                } catch ( java.io.IOException e ) {
                    throw new RuntimeException( e );
                }
            }
        };
    }

    class NewFileSystemMessageHandler implements MessageHandler {

        @Override
        public Pair> handleMessage( final MessageType type,
                                                                     final Map content ) {
            if ( NEW_FS.equals( type ) ) {
                final String _uri = content.get( "uri" );
                final String fsType = content.get( "type" );
                final Map env = new HashMap();

                for ( final Map.Entry entry : content.entrySet() ) {
                    if ( !( entry.getKey().equals( "uri" ) || entry.getKey().equals( "type" ) ) ) {
                        env.put( entry.getKey(), entry.getValue() );
                    }
                }

                final URI uri = URI.create( _uri );
                final FileSystem fs;
                if ( fsType != null ) {
                    fs = service.newFileSystem( uri, env, new FileSystemType() {
                        public String toString() {
                            return fsType;
                        }

                        public int hashCode() {
                            return fsType.hashCode();
                        }
                    } );
                } else {
                    fs = service.newFileSystem( uri, env );
                }

                newFileSystemListener.execute( fs, uri.getScheme(), ( (FileSystemId) fs ).id(), env );
            }
            return null;
        }
    }

    class SyncFileSystemMessageHandler implements MessageHandler {

        @Override
        public Pair> handleMessage( final MessageType type,
                                                                     final Map content ) {
            if ( SYNC_FS.equals( type ) ) {
                final String scheme = content.get( "fs_scheme" );
                final String id = content.get( "fs_id" );

                String origin;
                try {
                    origin = URLEncoder.encode( content.get( "fs_uri" ), "UTF-8" );
                } catch ( UnsupportedEncodingException e ) {
                    origin = content.get( "fs_uri" );
                }

                if ( origin != null ) {
                    final URI fs = URI.create( scheme + "://" + id + "?sync=" + origin + "&force" );

                    service.getFileSystem( fs );
                }
            }

            return null;
        }
    }

    class QueryFileSystemMessageHandler implements MessageHandler {

        @Override
        public Pair> handleMessage( final MessageType type,
                                                                     final Map content ) {
            if ( QUERY_FOR_FS.equals( type ) ) {
                Map replyContent = new HashMap();
                int i = 0;
                for ( FileSystem fs : service.getFileSystems() ) {
                    replyContent.put( "fs_scheme_" + i, fs.getRootDirectories().iterator().next().toUri().getScheme() );
                    replyContent.put( "fs_id_" + i, ( (FileSystemId) fs ).id() );
                    replyContent.put( "fs_uri_" + i, fs.toString() );
                    i++;
                }
                return new Pair>( QUERY_FOR_FS_RESULT, replyContent );
            }
            return null;
        }
    }

    static class FileSystemInfo {

        private String id;
        private String scheme;
        private String uri;

        FileSystemInfo() {

        }

        FileSystemInfo( String id,
                        String scheme,
                        String uri ) {
            this.id = id;
            this.scheme = scheme;
            this.uri = uri;
        }

        String getId() {
            return id;
        }

        void setId( String id ) {
            this.id = id;
        }

        String getScheme() {
            return scheme;
        }

        void setScheme( String scheme ) {
            this.scheme = scheme;
        }

        String getUri() {
            return uri;
        }

        void setUri( String uri ) {
            this.uri = uri;
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy