Skip to content

Commit

Permalink
chore: Track all relevant locations for creating and attaching (#20292)…
Browse files Browse the repository at this point in the history
… (#20474)

Co-authored-by: Artur <[email protected]>
  • Loading branch information
vaadin-bot and Artur- authored Nov 14, 2024
1 parent 5f4114b commit 2587d49
Showing 1 changed file with 59 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

import java.io.File;
import java.io.Serializable;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
Expand Down Expand Up @@ -47,6 +48,10 @@ public class ComponentTracker {
.synchronizedMap(new WeakHashMap<>());
private static Map<Component, Location> attachLocation = Collections
.synchronizedMap(new WeakHashMap<>());
private static Map<Component, Location[]> createLocations = Collections
.synchronizedMap(new WeakHashMap<>());
private static Map<Component, Location[]> attachLocations = Collections
.synchronizedMap(new WeakHashMap<>());

private static Boolean disabled = null;
private static String[] prefixesToSkip = new String[] {
Expand Down Expand Up @@ -190,6 +195,18 @@ public static Location findCreate(Component component) {
return createLocation.get(component);
}

/**
* Finds the locations related to where the given component instance was
* created.
*
* @param component
* the component to find
* @return the locations involved in creating the component
*/
public static Location[] findCreateLocations(Component component) {
return createLocations.get(component);
}

/**
* Tracks the location where the component was created. This should be
* called from the Component constructor so that the creation location can
Expand All @@ -203,12 +220,14 @@ public static void trackCreate(Component component) {
return;
}
StackTraceElement[] stack = Thread.currentThread().getStackTrace();
Location location = findRelevantLocation(component.getClass(), stack,
null);
Location[] relevantLocations = findRelevantLocations(stack);
Location location = findRelevantLocation(component.getClass(),
relevantLocations, null);
if (isNavigatorCreate(location)) {
location = findRelevantLocation(null, stack, null);
location = findRelevantLocation(null, relevantLocations, null);
}
createLocation.put(component, location);
createLocations.put(component, relevantLocations);
}

/**
Expand All @@ -223,6 +242,18 @@ public static Location findAttach(Component component) {
return attachLocation.get(component);
}

/**
* Finds the locations related to where the given component instance was
* attached to a parent.
*
* @param component
* the component to find
* @return the locations involved in creating the component
*/
public static Location[] findAttachLocations(Component component) {
return attachLocations.get(component);
}

/**
* Tracks the location where the component was attached. This should be
* called from the Component attach logic so that the creation location can
Expand All @@ -239,14 +270,16 @@ public static void trackAttach(Component component) {

// In most cases the interesting attach call is found in the same class
// where the component was created and not in a generic layout class
Location location = findRelevantLocation(component.getClass(), stack,
findCreate(component));
Location[] relevantLocations = findRelevantLocations(stack);
Location location = findRelevantLocation(component.getClass(),
relevantLocations, findCreate(component));
if (isNavigatorCreate(location)) {
// For routes, we can just show the init location as we have nothing
// better
location = createLocation.get(component);
}
attachLocation.put(component, location);
attachLocations.put(component, relevantLocations);
}

/**
Expand Down Expand Up @@ -283,30 +316,41 @@ private static boolean isNavigatorCreate(Location location) {
.equals(AbstractNavigationStateRenderer.class.getName());
}

private static Location[] findRelevantLocations(StackTraceElement[] stack) {
return Stream.of(stack).filter(e -> {
for (String prefixToSkip : prefixesToSkip) {
if (e.getClassName().startsWith(prefixToSkip)) {
return false;
}
}
return true;
}).map(ComponentTracker::toLocation).toArray(Location[]::new);
}

private static Location findRelevantLocation(
Class<? extends Component> excludeClass, StackTraceElement[] stack,
Class<? extends Component> excludeClass, Location[] locations,
Location preferredClass) {
List<StackTraceElement> candidates = Stream.of(stack)
.filter(e -> excludeClass == null
|| !e.getClassName().equals(excludeClass.getName()))
.filter(e -> {
List<Location> candidates = Arrays.stream(locations)
.filter(location -> excludeClass == null
|| !location.className().equals(excludeClass.getName()))
.filter(location -> {
for (String prefixToSkip : prefixesToSkip) {
if (e.getClassName().startsWith(prefixToSkip)) {
if (location.className().startsWith(prefixToSkip)) {
return false;
}
}
return true;
}).collect(Collectors.toList());
if (preferredClass != null) {
Optional<StackTraceElement> preferredCandidate = candidates.stream()
.filter(e -> e.getClassName()
Optional<Location> preferredCandidate = candidates.stream()
.filter(location -> location.className()
.equals(preferredClass.className()))
.findFirst();
if (preferredCandidate.isPresent()) {
return toLocation(preferredCandidate.get());
return preferredCandidate.get();
}
}
return toLocation(candidates.stream().findFirst().orElse(null));
return candidates.isEmpty() ? null : candidates.get(0);
}

/**
Expand Down

0 comments on commit 2587d49

Please sign in to comment.