< prev index next >

application/org.openjdk.jmc.flightrecorder.ui/src/main/java/org/openjdk/jmc/flightrecorder/ui/common/ThreadGraphLanes.java

Print this page

        

@@ -1,7 +1,8 @@
 /*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019, Red Hat Inc. All rights reserved.
  * 
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * The contents of this file are subject to the terms of either the Universal Permissive License
  * v 1.0 as shown at http://oss.oracle.com/licenses/upl

@@ -40,10 +41,11 @@
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 import java.util.function.Predicate;
 import java.util.function.Supplier;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
 

@@ -59,10 +61,11 @@
 import org.openjdk.jmc.common.item.IItem;
 import org.openjdk.jmc.common.item.IItemCollection;
 import org.openjdk.jmc.common.item.IItemFilter;
 import org.openjdk.jmc.common.item.IItemIterable;
 import org.openjdk.jmc.common.item.ItemFilters;
+import org.openjdk.jmc.common.item.ItemFilters.Types;
 import org.openjdk.jmc.common.unit.IQuantity;
 import org.openjdk.jmc.flightrecorder.JfrAttributes;
 import org.openjdk.jmc.flightrecorder.jdk.JdkFilters;
 import org.openjdk.jmc.flightrecorder.jdk.JdkTypeIDs;
 import org.openjdk.jmc.flightrecorder.ui.EventTypeFolderNode;

@@ -92,20 +95,29 @@
         private List<LaneDefinition> naLanes;
         private Supplier<StreamModel> dataSourceSupplier;
         private Runnable buildChart;
         private List<IAction> actions;
         private String tooltipTitle;
+        private EventTypeFolderNode typeTree;
+        private boolean quickFilterExist;
 
         public ThreadGraphLanes(Supplier<StreamModel> dataSourceSupplier, Runnable buildChart) {
                 this.dataSourceSupplier = dataSourceSupplier;
                 this.buildChart = buildChart;
                 this.actions = new ArrayList<>();
+                this.quickFilterExist = false;
+                this.typeTree = dataSourceSupplier.get().getTypeTree(ItemCollectionToolkit
+                                .stream(dataSourceSupplier.get().getItems()).filter(this::typeWithThreadAndDuration));
+        }
+
+        protected EventTypeFolderNode getTypeTree() {
+                return typeTree;
         }
 
         public void openEditLanesDialog(MCContextMenuManager mm, boolean isLegendMenu) {
                 // FIXME: Might there be other interesting events that don't really have duration?
-                EventTypeFolderNode typeTree = dataSourceSupplier.get().getTypeTree(ItemCollectionToolkit
+                typeTree = dataSourceSupplier.get().getTypeTree(ItemCollectionToolkit
                                 .stream(dataSourceSupplier.get().getItems()).filter(this::typeWithThreadAndDuration));
                 laneDefs = LaneEditor.openDialog(typeTree, laneDefs.stream().collect(Collectors.toList()),
                                 Messages.JavaApplicationPage_EDIT_THREAD_LANES_DIALOG_TITLE,
                                 Messages.JavaApplicationPage_EDIT_THREAD_LANES_DIALOG_MESSAGE);
                 updateContextMenu(mm, isLegendMenu);

@@ -125,10 +137,23 @@
                                 .filter((Predicate<? super LaneDefinition>) LaneDefinition::isEnabled).map(ld -> ld.getFilter())
                                 .collect(Collectors.toList());
                 return ItemFilters.or(laneFilters.toArray(new IItemFilter[laneFilters.size()]));
         }
 
+        /**
+         * Retrieves the set of lane names that are currently enabled.<br>
+         * Note: The "Rest lane" is of type ItemFilters$Composite, and cannot be cast to Types,
+         *     so it gets filtered out of the end result.
+         * @return the enabled lanes independent from the rest lane
+         */
+        public Set<String> getEnabledLanes() {
+                List<IItemFilter> laneFilters = laneDefs.stream()
+                                .filter((Predicate<? super LaneDefinition>) LaneDefinition::isEnabledAndNotRestLane).map(ld -> ld.getFilter())
+                                .collect(Collectors.toList());
+                return ((Types) ItemFilters.or(laneFilters.toArray(new IItemFilter[laneFilters.size()]))).getTypes();
+        }
+
         private void setTooltipTitle(String description) {
                 this.tooltipTitle = description;
         }
 
         private String getTooltipTitle() {

@@ -137,10 +162,41 @@
 
         private void resetTooltipTitle() {
                 this.tooltipTitle = null;
         }
 
+        /**
+         * Introduces a "Quick Filter" to the lane definitions which is controlled by the
+         * dropdown lane filter. Initially, the enabled activity lanes will be a copy of
+         * the currently enabled lanes. When initially used, the "Quick Filter" will be
+         * the only active lane definition in an attempt to preserve the lane activity of
+         * the existing lane definitions. The "Quick Filter" is meant for easy viewing of
+         * activities, and will not be persisted.
+         */
+        public void useDropdownFilter(LaneDefinition quickFilterDef) {
+                if (quickFilterExist) {
+                        for (int i = 0; i < laneDefs.size(); i++) {
+                                if (quickFilterDef.getName().equals(laneDefs.get(i).getName())) {
+                                        laneDefs.remove(laneDefs.get(i));
+                                        laneDefs.add(i, quickFilterDef);
+                                }
+                        }
+                } else {
+                        for (int i = 0; i < laneDefs.size(); i++) {
+                                setLaneDefinitionEnablement(laneDefs.get(i), i, false);
+                        }
+                        laneDefs.add(0, quickFilterDef);
+                        quickFilterExist = true;
+                }
+                buildChart.run();
+        }
+
+        private void setLaneDefinitionEnablement(LaneDefinition oldLd, int laneIndex, boolean isEnabled) {
+                LaneDefinition newLd = new LaneDefinition(oldLd.getName(), isEnabled, oldLd.getFilter(), oldLd.isRestLane());
+                laneDefs.set(laneIndex, newLd);
+        }
+
         public IXDataRenderer buildThreadRenderer(Object thread, IItemCollection items) {
                 this.resetTooltipTitle();
                 String threadName = thread == null ? "" : ((IMCThread) thread).getThreadName(); //$NON-NLS-1$
                 // FIXME: Workaround since this method can be called from super class constructor. Refactor to avoid this.
                 List<LaneDefinition> laneFilters = this.laneDefs == null ? Collections.emptyList() : this.laneDefs;

@@ -266,13 +322,11 @@
                         Action checkAction = new Action(ld.getName(), IAction.AS_CHECK_BOX) {
                                 int laneIndex = laneDefs.indexOf(ld);
 
                                 @Override
                                 public void run() {
-                                        LaneDefinition newLd = new LaneDefinition(ld.getName(), isChecked(), ld.getFilter(),
-                                                        ld.isRestLane());
-                                        laneDefs.set(laneIndex, newLd);
+                                        setLaneDefinitionEnablement(ld, laneIndex, isChecked());
                                         buildChart.run();
                                 }
                         };
                         String identifier = ld.getName() + checkAction.hashCode();
                         checkAction.setId(identifier);
< prev index next >