Package org.sonar.ide.intellij.utils

Source Code of org.sonar.ide.intellij.utils.SonarCache$ViolationsCache

package org.sonar.ide.intellij.utils;

import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import org.sonar.ide.intellij.listener.LoadingSonarFilesListener;
import org.sonar.ide.intellij.listener.RefreshListener;
import org.sonar.ide.intellij.worker.RefreshSonarFileWorker;
import org.sonar.ide.intellij.worker.RefreshSourceWorker;
import org.sonar.ide.intellij.worker.RefreshViolationsWorker;
import org.sonar.wsclient.services.Model;
import org.sonar.wsclient.services.Source;
import org.sonar.wsclient.services.Violation;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutionException;

public class SonarCache {
    private Cache<Violation> violationCache;
    private Cache<Source> sourceCache;

    private final Set<LoadingSonarFilesListener> loadingFilesListeners = new HashSet<LoadingSonarFilesListener>();

    public SonarCache(final Project project) {
        this.violationCache = new ViolationsCache(project);
        this.sourceCache = new SourceCache(project);
    }

    public List<Violation> getViolations(VirtualFile virtualFile) {
        return this.violationCache.get(virtualFile);
    }

    public void loadViolations(VirtualFile virtualFile, RefreshListener<Violation> listener) {
        this.violationCache.load(virtualFile, listener);
    }

    public void removeViolation(VirtualFile virtualFile, Violation violation) {
        violationCache.removeFromCache(virtualFile, violation);
    }

    public Source getSource(VirtualFile virtualFile) {
        List<Source> sources = sourceCache.get(virtualFile);
        if (sources == null || sources.isEmpty()) {
            return null;
        } else {
            return sources.get(0);
        }
    }

    public void loadSource(VirtualFile virtualFile, RefreshListener<Source> listener) {
        this.sourceCache.load(virtualFile, listener);
    }

    private void refreshLoadingSonarFiles() {
        Set<VirtualFile> currentlyLoadingFiles = new HashSet<VirtualFile>();
        currentlyLoadingFiles.addAll(this.violationCache.getCurrentlyLoadingFiles());
        currentlyLoadingFiles.addAll(this.sourceCache.getCurrentlyLoadingFiles());

        for (LoadingSonarFilesListener listener : this.loadingFilesListeners) {
            listener.loadingFiles(new ArrayList<VirtualFile>(currentlyLoadingFiles));
        }
    }

    public void addLoadingFileListener(LoadingSonarFilesListener listener) {
        this.loadingFilesListeners.add(listener);
    }

    public void clearCache() {
        this.violationCache.clear();
        this.sourceCache.clear();
    }

    private abstract class Cache<T extends Model> {

        private final Map<VirtualFile, List<T>> cache = new ConcurrentHashMap<VirtualFile, List<T>>();
        private final Map<VirtualFile, RefreshSonarFileWorker<T>> currentlyLoading = new ConcurrentHashMap<VirtualFile, RefreshSonarFileWorker<T>>();
        private final Map<VirtualFile, List<RefreshListener<T>>> loadListeners = new ConcurrentHashMap<VirtualFile, List<RefreshListener<T>>>();

        protected Project project;

        public Cache(Project project) {
            this.project = project;
        }

        public Set<VirtualFile> getCurrentlyLoadingFiles() {
            return currentlyLoading.keySet();
        }

        public void removeFromCache(VirtualFile virtualFile, T t) {
            this.cache.get(virtualFile).remove(t);
        }

        public List<T> get(VirtualFile virtualFile) {
            if (cache.containsKey(virtualFile)) {
                return cache.get(virtualFile);
            } else {
                RefreshSonarFileWorker<T> worker = createAndExecuteRefreshWorker(virtualFile);
                try {
                    return worker.get();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (ExecutionException e) {
                    e.printStackTrace();
                }
                return null;
            }
        }

        public void load(VirtualFile virtualFile, RefreshListener<T> listener) {
            if (this.cache.containsKey(virtualFile)) {
                listener.doneRefresh(virtualFile, this.cache.get(virtualFile));
            } else {
                if (!loadListeners.containsKey(virtualFile)) {
                    loadListeners.put(virtualFile, new ArrayList<RefreshListener<T>>());
                }

                loadListeners.get(virtualFile).add(listener);
                createAndExecuteRefreshWorker(virtualFile);
            }
        }

        protected abstract RefreshSonarFileWorker<T> createWorker(VirtualFile virtualFile);

        private RefreshSonarFileWorker<T> createAndExecuteRefreshWorker(VirtualFile virtualFile) {
            if (!this.currentlyLoading.containsKey(virtualFile)) {
                RefreshSonarFileWorker<T> worker = createWorker(virtualFile);

                this.currentlyLoading.put(virtualFile, worker);
                refreshLoadingSonarFiles();

                worker.addListener(new RefreshListener<T>() {
                    @Override
                    public void doneRefresh(VirtualFile virtualFile, List<T> ts) {
                        finishRefresh(virtualFile, ts);
                    }
                });
                worker.execute();

                return worker;
            } else {
                return currentlyLoading.get(virtualFile);
            }
        }

        private void finishRefresh(VirtualFile virtualFile, List<T> t) {
            this.cache.put(virtualFile, t);

            this.currentlyLoading.remove(virtualFile);

            if (this.loadListeners.containsKey(virtualFile)) {
                for (RefreshListener<T> listener : this.loadListeners.get(virtualFile)) {
                    listener.doneRefresh(virtualFile, t);
                }
                this.loadListeners.get(virtualFile).clear();
            }

            refreshLoadingSonarFiles();
        }

        public void clear() {
            this.cache.clear();
        }
    }

    private class ViolationsCache extends Cache<Violation> {
        private ViolationsCache(Project project) {
            super(project);
        }

        @Override
        protected RefreshSonarFileWorker<Violation> createWorker(VirtualFile virtualFile) {
            return new RefreshViolationsWorker(this.project, virtualFile);
        }
    }

    private class SourceCache extends Cache<Source> {
        private SourceCache(Project project) {
            super(project);
        }

        @Override
        protected RefreshSonarFileWorker<Source> createWorker(VirtualFile virtualFile) {
            return new RefreshSourceWorker(this.project, virtualFile);
        }
    }
}
TOP

Related Classes of org.sonar.ide.intellij.utils.SonarCache$ViolationsCache

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.