package krasa.grepconsole.plugin; import com.intellij.execution.filters.TextConsoleBuilder; import com.intellij.execution.filters.TextConsoleBuilderFactory; import com.intellij.execution.ui.ConsoleView; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; import krasa.grepconsole.filter.*; import krasa.grepconsole.filter.support.Cache; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.lang.ref.WeakReference; import java.util.*; /** * @author Vojtech Krasa */ public class ServiceManager { private static final Logger log = Logger.getInstance(ServiceManager.class.getName()); private static final ServiceManager SERVICE_MANAGER = new ServiceManager(); /** for tracking settings change */ private List<WeakReference<GrepHighlightFilter>> highlightFilters = new ArrayList<>(); private List<WeakReference<GrepInputFilter>> inputFilters = new ArrayList<>(); /** to couple console with filters */ private WeakReference<GrepCopyingFilter> lastCopier; private WeakReference<GrepHighlightingInputFilter> lastGrepHighlightFilter; private long lastExecutionId; /** for providing attached filters for certain console */ private WeakHashMap<ConsoleView, GrepHighlightFilter> weakHighlightersMap = new WeakHashMap<>(); private WeakHashMap<ConsoleView, GrepCopyingFilter> weakCopiersMap = new WeakHashMap<>(); private boolean createInputFilter = true; public static ServiceManager getInstance() { return SERVICE_MANAGER; } public void resetSettings() { iterate(highlightFilters); iterate(inputFilters); iterate(weakCopiersMap.values()); // todo this may not work properly, regenerate GrepExpressionItem id Cache.reset(); } private void iterate(Collection<GrepCopyingFilter> values) { for (GrepCopyingFilter filter : values) { if (filter != null) { filter.onChange(); } } } private <T extends AbstractFilter> void iterate(final List<WeakReference<T>> filters) { Iterator<WeakReference<T>> iterator = filters.iterator(); while (iterator.hasNext()) { WeakReference<T> next = iterator.next(); T filter = next.get(); if (filter == null) { iterator.remove(); } else { filter.onChange(); } } } @Nullable public GrepInputFilter createInputFilter(Project project) { if (!createInputFilter) { return null; } GrepInputFilter lastInputFilter = new GrepInputFilter(project); inputFilters.add(new WeakReference<>(lastInputFilter)); return lastInputFilter; } public GrepHighlightingInputFilter createHighlightInputFilter(Project project) { GrepHighlightingInputFilter grepHighlightFilter = new GrepHighlightingInputFilter(project); grepHighlightFilter.setExecutionId(getLastExecutionId()); highlightFilters.add(new WeakReference<>(grepHighlightFilter)); lastGrepHighlightFilter = new WeakReference<>(grepHighlightFilter); return grepHighlightFilter; } public GrepHighlightFilter createHighlightFilter(@NotNull Project project, @Nullable ConsoleView consoleView) { final GrepHighlightFilter grepHighlightFilter = new GrepHighlightFilter(project); grepHighlightFilter.setExecutionId(getLastExecutionId()); highlightFilters.add(new WeakReference<>(grepHighlightFilter)); if (consoleView != null) { weakHighlightersMap.put(consoleView, grepHighlightFilter); } return grepHighlightFilter; } public GrepCopyingFilter createCopyingFilter(@NotNull Project project) { final GrepCopyingFilter grepInputFilter = new GrepCopyingFilter(project); lastCopier = new WeakReference<>(grepInputFilter); return grepInputFilter; } @Nullable public GrepHighlightFilter getHighlightFilter(@NotNull ConsoleView console) { GrepHighlightFilter grepHighlightFilter = weakHighlightersMap.get(console); if (grepHighlightFilter == null) { StringBuilder sb = new StringBuilder(); sb.append("Something is wrong. " + "GrepHighlightFilter" + " not found for ").append( System.identityHashCode(console)).append("-").append(console); sb.append(". Registered: ["); boolean i = false; for (Map.Entry<ConsoleView, GrepHighlightFilter> consoleViewGrepHighlightFilterEntry : weakHighlightersMap.entrySet()) { if (i) { sb.append(","); } sb.append(System.identityHashCode(console)).append("-").append( consoleViewGrepHighlightFilterEntry.getKey()); i = true; } sb.append("]"); log.warn(sb.toString()); return null; } return grepHighlightFilter; } @Nullable public GrepCopyingFilter getCopyingFilter(@NotNull ConsoleView console) { return weakCopiersMap.get(console); } public boolean isRegistered(@NotNull ConsoleView console) { return weakHighlightersMap.containsKey(console); } public long getLastExecutionId() { return lastExecutionId; } public void setLastExecutionId(long lastExecutionId) { this.lastExecutionId = lastExecutionId; } public void registerConsole(ConsoleView console) { GrepCopyingFilter lastCopier = getLastCopier(); if (lastCopier != null) { weakCopiersMap.put(console, lastCopier); this.lastCopier = null; } GrepHighlightingInputFilter lastGrepHighlightFilter = getLastGrepHighlightFilter(); if (lastGrepHighlightFilter != null) { weakHighlightersMap.put(console, lastGrepHighlightFilter); this.lastGrepHighlightFilter = null; } } @Nullable private GrepCopyingFilter getLastCopier() { if (lastCopier != null) { return lastCopier.get(); } else { return null; } } @Nullable private GrepHighlightingInputFilter getLastGrepHighlightFilter() { if (lastGrepHighlightFilter != null) { return lastGrepHighlightFilter.get(); } else { return null; } } public ConsoleView createConsoleWithoutInputFilter(Project project) { try { createInputFilter = false; TextConsoleBuilder consoleBuilder = TextConsoleBuilderFactory.getInstance().createBuilder(project); return consoleBuilder.getConsole(); } finally { createInputFilter = true; } } }