Package floobits.common.interfaces

Source Code of floobits.common.interfaces.IContext

package floobits.common.interfaces;

import com.intellij.openapi.editor.Editor;
import floobits.common.*;
import floobits.common.protocol.FlooUser;
import floobits.common.protocol.handlers.BaseHandler;
import floobits.common.protocol.handlers.CreateAccountHandler;
import floobits.common.protocol.handlers.FlooHandler;
import floobits.common.protocol.handlers.LinkEditorHandler;

import floobits.utilities.Flog;

import io.fletty.bootstrap.Bootstrap;
import io.fletty.channel.nio.NioEventLoopGroup;
import io.fletty.util.concurrent.ScheduledFuture;
import org.jetbrains.annotations.Nullable;

import java.io.File;
import java.net.MalformedURLException;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

public abstract class IContext {
    public final EditorScheduler editor;
    private final ReadWriteLock lock = new ReentrantReadWriteLock();
    public String colabDir;
    public volatile BaseHandler handler;
    public Date lastChatMessage;
    public IFactory iFactory;
    protected Ignore ignoreTree;
    protected volatile NioEventLoopGroup loopGroup;

    public IContext() {
        editor = new EditorScheduler(this);
    }

    public boolean addGroup(Bootstrap b) {
        boolean b1 = false;
        try {
            lock.readLock().lock();
            if (loopGroup != null) {
                b.group(loopGroup);
                b1 = true;
            }
        } finally {
            lock.readLock().unlock();
        }
        return b1;
    }

    public ScheduledFuture setTimeout(int time, final Runnable runnable) {
        ScheduledFuture schedule = null;
        try {
            lock.readLock().lock();
            if (loopGroup != null) {
                schedule = loopGroup.schedule(runnable, time, TimeUnit.MILLISECONDS);
            }
        } catch(Throwable e) {
            Flog.warn(e);
        } finally {
            lock.readLock().unlock();
        }
        return schedule;
    }

    private boolean changePerms(FlooUrl flooUrl, String[] newPerms) {
        HTTPWorkspaceRequest workspace = API.getWorkspace(flooUrl, this);
        if (workspace == null) {
            return false;
        }

        String[] anonPerms = workspace.perms.get("AnonymousUser");
        if (anonPerms == null) {
            anonPerms = new String[]{};
        }
        Arrays.sort(anonPerms);
        Arrays.sort(newPerms);
        if (!Arrays.equals(anonPerms, newPerms)) {
            workspace.perms.put("AnonymousUser", newPerms);
            return API.updateWorkspace(flooUrl, workspace, this);
        }
        return true;
    }

    public void shareProject(final boolean _private_, String projectPath) {


        FlooUrl flooUrl = DotFloo.read(projectPath);

        String[] newPerms = _private_ ? new String[]{} : new String[]{"view_room"};

        if (flooUrl != null && changePerms(flooUrl, newPerms)) {
            joinWorkspace(flooUrl, projectPath, true);
            return;
        }

        PersistentJson persistentJson = PersistentJson.getInstance();
        for (Map.Entry<String, Map<String, Workspace>> i : persistentJson.workspaces.entrySet()) {
            Map<String, Workspace> workspaces = i.getValue();
            for (Map.Entry<String, Workspace> j : workspaces.entrySet()) {
                Workspace w = j.getValue();
                if (Utils.isSamePath(w.path, projectPath)) {
                    try {
                        flooUrl = new FlooUrl(w.url);
                    } catch (MalformedURLException e) {
                        Flog.warn(e);
                        continue;
                    }
                    if (changePerms(flooUrl, newPerms)) {
                        joinWorkspace(flooUrl, w.path, true);
                        return;
                    }
                }
            }
        }

        String host;
        FloorcJson floorcJson;
        try {
            floorcJson = Settings.get();
        } catch (Throwable e) {
            Flog.log("Invalid .floorc.json");
            statusMessage("Invalid .floorc.json");
            return;
        }
        int size = floorcJson.auth.size();
        if (size <= 0) {
            Flog.log("No credentials.");
            return;
        }
        String[] keys = new String[size];
        floorcJson.auth.keySet().toArray(keys);

        if (keys.length == 1) {
            host = keys[0];
        } else {
            host = selectAccount(keys);
        }

        if (host == null) {
            return;
        }

        String owner = floorcJson.auth.get(host).get("username");
        final String name = new File(projectPath).getName();
        List<String> orgs = API.getOrgsCanAdmin(host, this);
        orgs.add(0, owner);
        shareProjectDialog(name, orgs, host, _private_, projectPath);
    }

    protected abstract void shareProjectDialog(String name, List<String> orgs, String host, boolean _private_, String projectPath);

    public void joinWorkspace(final FlooUrl flooUrl, final String path, final boolean upload) {
        FloorcJson floorcJson = null;
        try {
            floorcJson = Settings.get();
        } catch (Throwable e) {
            statusMessage("Invalid JSON in your .floorc.json.");
        }

        HashMap<String, String> auth = floorcJson != null ? floorcJson.auth.get(flooUrl.host) : null;
        if (auth == null) {
            setupHandler(new LinkEditorHandler(this, flooUrl.host, new Runnable() {
                @Override
                public void run() {
                    joinWorkspace(flooUrl, path, upload);
                }
            }));
            return;
        }

        if (!API.workspaceExists(flooUrl, this)) {
            errorMessage(String.format("The workspace %s does not exist!", flooUrl.toString()));
            return;
        }

        if (setupHandler(new FlooHandler(this, flooUrl, upload, path, auth))) {
            setListener(true);
            return;
        }

        String title = String.format("Really leave %s?", handler.url.workspace);
        String body = String.format("Leave %s and join %s ?", handler.url.toString(), handler.url.toString());

        dialog(title, body, new RunLater<Boolean>() {
            public void run(Boolean join) {
                if (!join) {
                    return;
                }
                shutdown();
                joinWorkspace(flooUrl, path, upload);
            }
        });
    }

    public void createAccount() {
        if (setupHandler(new CreateAccountHandler(this, Constants.defaultHost))) {
            return;
        }
        statusMessage("You already have an account and are connected with it.");
        shutdown();
    }

    public void linkEditor() {
        if (setupHandler(new LinkEditorHandler(this, Constants.defaultHost))) {
            return;
        }
        statusMessage("You already have an account and are connected with it.");
        shutdown();
    }

    private boolean setupHandler(BaseHandler handler) {
        if (isJoined()) {
            return false;
        }

        lock.writeLock().lock();
        this.handler = handler;
        loopGroup = new NioEventLoopGroup();
        lock.writeLock().unlock();
        handler.go();
        return true;
    }

    public boolean isJoined() {
        return handler != null && handler.isJoined;
    }

    public @Nullable
    FlooHandler getFlooHandler(){
        if (handler != null && handler instanceof FlooHandler)
            return (FlooHandler)handler;
        return null;
    }

    public void setColabDir(String colabDir) {
        this.colabDir = colabDir;
        Ignore.writeDefaultIgnores(this);
        refreshIgnores();
    }

    public void refreshIgnores() {
        IFile fileByIoFile = iFactory.findFileByIoFile(new File(colabDir));
        ignoreTree = Ignore.BuildIgnore(fileByIoFile);
    }

    public String absPath(String path) {
        return Utils.absPath(colabDir, path);
    }

    public Boolean isShared(String path) {
        return Utils.isShared(path, colabDir);
    }

    public String toProjectRelPath(String path) {
        return Utils.toProjectRelPath(path, colabDir);
    }

    public Boolean isIgnored(IFile f) {
        String path = f.getPath();

        if (!isShared(path)) {
            Flog.log("Ignoring %s because it isn't shared.", path);
            return true;
        }

        return ignoreTree.isIgnored(f, path, toProjectRelPath(path), f.isDirectory());
    }

    public synchronized void shutdown() {
        lock.writeLock().lock();
        try {
            if (handler != null) {
                handler.shutdown();
                editor.shutdown();
                statusMessage("Disconnecting.");
                handler = null;
            }
            if (iFactory != null) {
                iFactory.clearReadOnlyState();
            }

            if (loopGroup != null) {
                try {
                    loopGroup.shutdownGracefully(0, 500, TimeUnit.MILLISECONDS);
                } catch (Throwable e) {
                    Flog.warn(e);
                } finally {
                    loopGroup = null;
                }
            }
            ignoreTree = null;
        } finally {
            lock.writeLock().unlock();
        }
    }

    protected abstract String selectAccount(String[] keys);
    public Ignore getIgnoreTree() {
        return ignoreTree;
    }
    public abstract Object getActualContext();
    public abstract void loadChatManager();
    public abstract void flashMessage(String message);
    public abstract void warnMessage(String message);
    public abstract void statusMessage(String message);
    public abstract void errorMessage(String message);
    public abstract void chatStatusMessage(String message);
    public abstract void chatErrorMessage(String message);
    public abstract void chat(String username, String msg, Date messageDate);
    public abstract void openChat();
    public abstract void listenToEditor(EditorEventHandler editorEventHandler);
    public abstract void setUsers(Map<Integer, FlooUser> users);
    public abstract void setListener(boolean b);
    public abstract void mainThread(final Runnable runnable);
    public abstract void readThread(final Runnable runnable);
    public abstract void writeThread(final Runnable runnable);
    public abstract void dialog(String title, String body, RunLater<Boolean> runLater);
    public abstract void dialogDisconnect(int tooMuch, int howMany);
    public abstract void dialogPermsRequest(String username, RunLater<String> perms);
    public abstract boolean dialogTooBig(LinkedList<Ignore> tooBigIgnores);
    public abstract void dialogResolveConflicts(Runnable stompLocal, Runnable stompRemote, boolean readOnly,
                                                Runnable flee, String[] conflictedPathsArray,
                                                String [] connections);
}
TOP

Related Classes of floobits.common.interfaces.IContext

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.