Package org.uberfire.backend.server.io.watch

Source Code of org.uberfire.backend.server.io.watch.IOWatchServiceExecutorImpl

package org.uberfire.backend.server.io.watch;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.ejb.Singleton;
import javax.ejb.Startup;
import javax.ejb.TransactionAttribute;
import javax.enterprise.event.Event;
import javax.inject.Inject;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.uberfire.backend.server.util.Filter;
import org.uberfire.backend.vfs.Path;
import org.uberfire.commons.data.Pair;
import org.uberfire.java.nio.base.WatchContext;
import org.uberfire.java.nio.file.StandardWatchEventKind;
import org.uberfire.java.nio.file.WatchEvent;
import org.uberfire.java.nio.file.WatchKey;
import org.uberfire.rpc.SessionInfo;
import org.uberfire.rpc.impl.SessionInfoImpl;
import org.uberfire.security.impl.IdentityImpl;
import org.uberfire.workbench.events.ResourceAdded;
import org.uberfire.workbench.events.ResourceAddedEvent;
import org.uberfire.workbench.events.ResourceBatchChangesEvent;
import org.uberfire.workbench.events.ResourceChange;
import org.uberfire.workbench.events.ResourceDeleted;
import org.uberfire.workbench.events.ResourceDeletedEvent;
import org.uberfire.workbench.events.ResourceEvent;
import org.uberfire.workbench.events.ResourceRenamed;
import org.uberfire.workbench.events.ResourceRenamedEvent;
import org.uberfire.workbench.events.ResourceUpdated;
import org.uberfire.workbench.events.ResourceUpdatedEvent;

import static javax.ejb.TransactionAttributeType.*;
import static org.uberfire.backend.server.util.Paths.*;

@Singleton
@Startup
@TransactionAttribute(NOT_SUPPORTED)
public class IOWatchServiceExecutorImpl implements IOWatchServiceExecutor {

    private static final Logger LOGGER = LoggerFactory.getLogger( IOWatchServiceExecutorImpl.class );

    @Inject
    private Event<ResourceBatchChangesEvent> resourceBatchChanges;

    @Inject
    private Event<ResourceUpdatedEvent> resourceUpdatedEvent;

    @Inject
    private Event<ResourceRenamedEvent> resourceRenamedEvent;

    @Inject
    private Event<ResourceDeletedEvent> resourceDeletedEvent;

    @Inject
    private Event<ResourceAddedEvent> resourceAddedEvent;

    public void setEvents( final Event<ResourceBatchChangesEvent> resourceBatchChanges,
                           final Event<ResourceUpdatedEvent> resourceUpdatedEvent,
                           final Event<ResourceRenamedEvent> resourceRenamedEvent,
                           final Event<ResourceDeletedEvent> resourceDeletedEvent,
                           final Event<ResourceAddedEvent> resourceAddedEvent ) {
        this.resourceBatchChanges = resourceBatchChanges;
        this.resourceUpdatedEvent = resourceUpdatedEvent;
        this.resourceRenamedEvent = resourceRenamedEvent;
        this.resourceDeletedEvent = resourceDeletedEvent;
        this.resourceAddedEvent = resourceAddedEvent;
    }

    public void execute( final WatchKey wk,
                         final Filter<WatchEvent<?>> filter ) {
        final List<WatchEvent<?>> events = wk.pollEvents();
        WatchContext firstContext = null;

        if ( events.size() > 1 ) {
            final Map<Path, Collection<ResourceChange>> changes = new HashMap<Path, Collection<ResourceChange>>();
            for ( final WatchEvent event : events ) {
                if ( !filter.doFilter( event ) ) {
                    if ( firstContext == null ) {
                        firstContext = (WatchContext) event.context();
                    }
                    final Pair<Path, ResourceChange> result = buildChange( event );
                    if ( result != null ) {
                        if ( !changes.containsKey( result.getK1() ) ) {
                            changes.put( result.getK1(), new ArrayList<ResourceChange>() );
                        }
                        changes.get( result.getK1() ).add( result.getK2() );
                    }
                }
            }
            if ( changes.size() == 1 && changes.values().size() == 1 ) {
                final ResourceChange _event = changes.values().iterator().next().iterator().next();
                if ( _event instanceof ResourceUpdated ) {
                    resourceUpdatedEvent.fire( (ResourceUpdatedEvent) toEvent( changes.keySet().iterator().next(), _event, firstContext ) );
                } else if ( _event instanceof ResourceAdded ) {
                    resourceAddedEvent.fire( (ResourceAddedEvent) toEvent( changes.keySet().iterator().next(), _event, firstContext ) );
                } else if ( _event instanceof ResourceRenamed ) {
                    resourceRenamedEvent.fire( (ResourceRenamedEvent) toEvent( changes.keySet().iterator().next(), _event, firstContext ) );
                } else if ( _event instanceof ResourceDeleted ) {
                    resourceDeletedEvent.fire( (ResourceDeletedEvent) toEvent( changes.keySet().iterator().next(), _event, firstContext ) );
                }
            } else if ( changes.size() > 1 ) {
                resourceBatchChanges.fire( new ResourceBatchChangesEvent( changes, message( firstContext ), sessionInfo( firstContext ) ) );
            }
        } else if ( events.size() == 1 ) {
            try {
                final WatchEvent<?> event = events.get( 0 );
                if ( !filter.doFilter( event ) ) {
                    if ( event.kind().equals( StandardWatchEventKind.ENTRY_MODIFY ) ) {
                        resourceUpdatedEvent.fire( buildEvent( ResourceUpdatedEvent.class, event ).getK2() );
                    } else if ( event.kind().equals( StandardWatchEventKind.ENTRY_CREATE ) ) {
                        resourceAddedEvent.fire( buildEvent( ResourceAddedEvent.class, event ).getK2() );
                    } else if ( event.kind().equals( StandardWatchEventKind.ENTRY_RENAME ) ) {
                        resourceRenamedEvent.fire( buildEvent( ResourceRenamedEvent.class, event ).getK2() );
                    } else if ( event.kind().equals( StandardWatchEventKind.ENTRY_DELETE ) ) {
                        resourceDeletedEvent.fire( buildEvent( ResourceDeletedEvent.class, event ).getK2() );
                    }
                }
            } catch ( final Exception ex ) {
                LOGGER.error( "Unexpected error during WatchService events fire.", ex );
            }
        }
    }

    private String message( final WatchContext context ) {
        if ( context == null ) {
            return null;
        }
        return context.getMessage();
    }

    private <T extends ResourceEvent> Pair<Path, T> buildEvent( final Class<T> clazz,
                                                                final WatchEvent<?> event ) {
        final WatchContext context = (WatchContext) event.context();

        final Path _affectedPath;
        final T result;
        if ( event.kind().equals( StandardWatchEventKind.ENTRY_MODIFY ) ) {
            _affectedPath = convert( context.getOldPath() );
            result = (T) new ResourceUpdatedEvent( _affectedPath, context.getMessage(), sessionInfo( context ) );
        } else if ( event.kind().equals( StandardWatchEventKind.ENTRY_CREATE ) ) {
            _affectedPath = convert( context.getPath() );
            result = (T) new ResourceAddedEvent( _affectedPath, context.getMessage(), sessionInfo( context ) );
        } else if ( event.kind().equals( StandardWatchEventKind.ENTRY_RENAME ) ) {
            _affectedPath = convert( context.getOldPath() );
            result = (T) new ResourceRenamedEvent( _affectedPath, convert( context.getPath() ), context.getMessage(), sessionInfo( context ) );
        } else if ( event.kind().equals( StandardWatchEventKind.ENTRY_DELETE ) ) {
            _affectedPath = convert( context.getOldPath() );
            result = (T) new ResourceDeletedEvent( _affectedPath, context.getMessage(), sessionInfo( context ) );
        } else {
            _affectedPath = null;
            result = null;
        }
        if ( _affectedPath == null ) {
            return null;
        }

        return Pair.newPair( _affectedPath, result );
    }

    private Pair<Path, ResourceChange> buildChange( final WatchEvent<?> event ) {
        final WatchContext context = (WatchContext) event.context();

        final Path _affectedPath;
        final ResourceChange result;
        if ( event.kind().equals( StandardWatchEventKind.ENTRY_MODIFY ) ) {
            _affectedPath = convert( context.getOldPath() );
            result = new ResourceUpdated();
        } else if ( event.kind().equals( StandardWatchEventKind.ENTRY_CREATE ) ) {
            _affectedPath = convert( context.getPath() );
            result = new ResourceAdded();
        } else if ( event.kind().equals( StandardWatchEventKind.ENTRY_RENAME ) ) {
            _affectedPath = convert( context.getOldPath() );
            result = new ResourceRenamed( convert( context.getPath() ), context.getMessage() );
        } else if ( event.kind().equals( StandardWatchEventKind.ENTRY_DELETE ) ) {
            _affectedPath = convert( context.getOldPath() );
            result = new ResourceDeleted();
        } else {
            _affectedPath = null;
            result = null;
        }
        if ( _affectedPath == null ) {
            return null;
        }

        return Pair.newPair( _affectedPath, result );
    }

    private ResourceEvent toEvent( final Path path,
                                   final ResourceChange change,
                                   final WatchContext context ) {
        if ( change instanceof ResourceUpdated ) {
            return new ResourceUpdatedEvent( path, context.getMessage(), sessionInfo( context ) );
        } else if ( change instanceof ResourceAdded ) {
            return new ResourceAddedEvent( path, context.getMessage(), sessionInfo( context ) );
        } else if ( change instanceof ResourceRenamed ) {
            return new ResourceRenamedEvent( path, ( (ResourceRenamed) change ).getDestinationPath(), context.getMessage(), sessionInfo( context ) );
        } else if ( change instanceof ResourceDeleted ) {
            return new ResourceDeletedEvent( path, context.getMessage(), sessionInfo( context ) );
        }
        return null;
    }

    private SessionInfo sessionInfo( final WatchContext context ) {
        final String sessionId;
        final String user;
        if ( context.getSessionId() == null ) {
            sessionId = "<system>";
        } else {
            sessionId = context.getSessionId();
        }
        if ( context.getUser() == null ) {
            user = "<system>";
        } else {
            user = context.getUser();
        }

        return new SessionInfoImpl( sessionId, new IdentityImpl( user ) );
    }

}
TOP

Related Classes of org.uberfire.backend.server.io.watch.IOWatchServiceExecutorImpl

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.