public Stream getFlavors()

in application/org.openjdk.jmc.flightrecorder.ui/src/main/java/org/openjdk/jmc/flightrecorder/ui/JfrPropertySheet.java [132:242]


		public Stream<IItemStreamFlavor> getFlavors(
			IItemFilter dstFilter, IItemCollection items, List<IAttribute<?>> dstAttributes) {
			/*
			 * FIXME: Is this the desired behavior? Discuss and change if necessary.
			 * 
			 * This most likely need more thought and discussion, but the implemented order of
			 * flavors is currently:
			 * 
			 * For chart selections:
			 * 
			 * 1: The selected events if any of them appear on the destination page
			 * 
			 * 2: All events on the destination page in the selected range (if a range was selected)
			 * 
			 * 3-n: All events on the destination page filtered on any of the attributes common to
			 * all selected events (excluding the range attribute if a range was selected)
			 * 
			 * For histogram and list selections:
			 * 
			 * 1: The selected events if any of them appear on the destination page
			 * 
			 * 2-n: All events on the destination page filtered on any of the attributes common to
			 * all selected events (all will at least have (endTime))
			 * 
			 * For properties view selections:
			 * 
			 * 1: All events on the destination page filtered on the selected attribute:value if
			 * they all have the selected attribute
			 * 
			 * 2: All events on the destination page filtered on the selected value if they all have
			 * an attribute with the same content type
			 * 
			 * 3: All events on the destination page filtered on all common attributes with values
			 * from all events filtered on the selected attribute:value (see example)
			 * 
			 * 4: All events on the destination page filtered on the selected attribute:value if
			 * there are any events with the attribute (and the attribute is not common to all
			 * events in which case this flavor has already been added in (1))
			 * 
			 * Example of properties view selections (3):
			 * 
			 * ECID:1-2-3-4 was selected and the user navigates to Java Application. All events on
			 * Java Application share (thread) and (endTime), so all events on the page are filtered
			 * on those properties. The values to include are collected from all events with the
			 * ECID attribute having value 1-2-3-4. The threads will be put in a set, the timestamps
			 * will form a range.
			 */
			IItemCollection filteredDstItems = ItemCollectionToolkit.filterIfNotNull(items, dstFilter);
			IPropertyFlavor relatedFilterFlavor = IPropertyFlavor.build(row.attribute, row.value, filteredDstItems);
			LinkedList<IItemStreamFlavor> flavors = new LinkedList<>();

			boolean anyRelatedOnDst = relatedFilterFlavor.evaluate().hasItems();
			IPropertyFlavor selectedPropertyFlavor = IPropertyFlavor.build(row.attribute, row.value, items);
			if (anyRelatedOnDst) {
				// prio1(a): Items related to the selected attribute if there are any
				flavors.add(selectedPropertyFlavor);
				selectedPropertyFlavor = null;
			}
			IItemCollection itemsRelatedToSelection = items.apply(relatedFilterFlavor.getFilter());
			if (dstAttributes == null || dstAttributes.isEmpty()) {
				dstAttributes = commonAttributes(filteredDstItems.iterator()).collect(Collectors.toList());
			}
			Iterator<IAttribute<?>> commonDstAttr = dstAttributes.iterator();
			List<IPropertyFlavor> relatedProperties = new ArrayList<>();
			while (commonDstAttr.hasNext()) {
				IAttribute<?> dstAttribute = commonDstAttr.next();
				if (!dstAttribute.equals(JfrAttributes.EVENT_TYPE)
						&& (!(dstAttribute.getContentType() instanceof KindOfQuantity)
								|| dstAttribute.equals(JfrAttributes.END_TIME))) {
					// FIXME: Collect type or quantity values?
					if (dstAttribute.equals(row.attribute)) {
						if (!anyRelatedOnDst && selectedPropertyFlavor != null) {
							// prio1(b): Related to the selected attribute even though it's empty, since the attribute is shared by all
							flavors.push(selectedPropertyFlavor);
							selectedPropertyFlavor = null;
						}
						relatedProperties = null;
					} else if (!dstAttribute.equals(row.attribute)
							&& dstAttribute.getContentType().equals(row.attribute.getContentType())) {
						// prio2: Destination items with an attribute of the selected content type and which equals the selected value
						flavors.add(IPropertyFlavor.build(dstAttribute, row.value, items));
					}
					if (relatedProperties != null) {
						// Collect values from items related to selection (only items of types that has the attribute), and add as filter
						PropertySheetRow av = buildProperty(dstAttribute,
								ItemCollectionToolkit.stream(itemsRelatedToSelection)
										.filter(is -> dstAttribute.getAccessor(is.getType()) != null).iterator(),
								Integer.MAX_VALUE);
						if (av != null) {
							relatedProperties.add(IPropertyFlavor.build(av.attribute, av.value, items));
						}
					}
				}
			}
			if (relatedProperties != null) {
				if (relatedProperties.size() > 1) {
					// prio3: Destination items with properties shared with the items related to the selection
					flavors.add(IPropertyFlavor.combine(relatedProperties::stream, items));
				}

				// FIXME: Combinations with for example two properties if there are three properties in total shared?

				// prio4: Destination items with one property shared with the items related to the selection
				flavors.addAll(relatedProperties);
			}
			if (selectedPropertyFlavor != null) {
				// prio4: Items related to the selected attribute even if there aren't any
				flavors.add(selectedPropertyFlavor);
			}
			return flavors.stream();
		}