mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-08-24 00:33:48 +02:00
Bug 239050
Makes getAncestorOfType() return the closest ancestor in terms of depth. Also adds a new method, getAllAncestorsOfType(), which returns all the ancestors of the specified type in an array.
This commit is contained in:
parent
0006e4ba15
commit
963ba7e067
1 changed files with 62 additions and 10 deletions
|
@ -11,8 +11,12 @@
|
|||
*******************************************************************************/
|
||||
package org.eclipse.dd.dsf.datamodel;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.eclipse.dd.dsf.concurrent.ThreadSafe;
|
||||
|
||||
|
@ -26,10 +30,15 @@ public class DMContexts {
|
|||
* Convenience constant.
|
||||
*/
|
||||
public static final IDMContext[] EMPTY_CONTEXTS_ARRAY = new IDMContext[0];
|
||||
|
||||
|
||||
/**
|
||||
* Finds a data model context of given type among ancestors of the
|
||||
* specified context.
|
||||
* specified context. The returned ancestor is the one closest to the
|
||||
* specified context, in terms of depth.
|
||||
*
|
||||
* Note that for efficiency, this method does not re-use getAllAncestorsOfType()
|
||||
* to avoid the unnecessary creation of an array.
|
||||
*
|
||||
* @param ctx DMC to search.
|
||||
* @param ancestorType Class type of the desired DMC ancestor.
|
||||
* @return Returns the ancestor if found, null otherwise.
|
||||
|
@ -39,22 +48,65 @@ public class DMContexts {
|
|||
public static <V extends IDMContext> V getAncestorOfType(IDMContext ctx, Class<V> ancestorType) {
|
||||
if(ctx == null)
|
||||
return null;
|
||||
// Check the first context here for efficiency
|
||||
if (ancestorType.isAssignableFrom(ctx.getClass())) {
|
||||
return (V)ctx;
|
||||
}
|
||||
|
||||
for (IDMContext parent : ctx.getParents()) {
|
||||
if (ancestorType.isAssignableFrom(parent.getClass())) {
|
||||
return (V)parent;
|
||||
}
|
||||
}
|
||||
// Use a LinkedHashSet to avoid duplicates and preserver insertion-order
|
||||
Set<IDMContext> nodes = new LinkedHashSet<IDMContext>();
|
||||
nodes.addAll(Arrays.asList(ctx.getParents()));
|
||||
while (nodes.isEmpty() == false) {
|
||||
Set<IDMContext> parents = nodes;
|
||||
nodes = new LinkedHashSet<IDMContext>();
|
||||
for (IDMContext parent : parents) {
|
||||
if (ancestorType.isAssignableFrom(parent.getClass())) {
|
||||
return (V)parent;
|
||||
}
|
||||
|
||||
for (IDMContext parent : ctx.getParents()) {
|
||||
V ancestor = getAncestorOfType(parent, ancestorType);
|
||||
if (ancestor != null) return ancestor;
|
||||
nodes.addAll(Arrays.asList(parent.getParents()));
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds all data model contexts of given type among ancestors of the
|
||||
* specified context. Ancestors are returned in order of closest to farthest,
|
||||
* in terms of depth.
|
||||
* @param ctx DMC to search.
|
||||
* @param ancestorType Class type of the desired DMC ancestor.
|
||||
* @return Returns all ancestors found, null if none.
|
||||
*/
|
||||
@ThreadSafe
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <V extends IDMContext> V[] getAllAncestorsOfType(IDMContext ctx, Class<V> ancestorType) {
|
||||
if(ctx == null)
|
||||
return null;
|
||||
|
||||
// Use a LinkedHashSet to avoid duplicates and preserver insertion-order
|
||||
Set<V> requestedAncestors = new LinkedHashSet<V>();
|
||||
Set<IDMContext> nodes = new LinkedHashSet<IDMContext>();
|
||||
nodes.add(ctx);
|
||||
while (nodes.isEmpty() == false) {
|
||||
Set<IDMContext> parents = nodes;
|
||||
nodes = new LinkedHashSet<IDMContext>();
|
||||
for (IDMContext parent : parents) {
|
||||
if (ancestorType.isAssignableFrom(parent.getClass())) {
|
||||
requestedAncestors.add((V)parent);
|
||||
}
|
||||
|
||||
nodes.addAll(Arrays.asList(parent.getParents()));
|
||||
}
|
||||
}
|
||||
|
||||
if (requestedAncestors.isEmpty()) return null;
|
||||
else {
|
||||
V[] v = (V[])Array.newInstance(ancestorType, 0);
|
||||
return requestedAncestors.toArray(v);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks all ancestors for a given context to see if the given
|
||||
|
|
Loading…
Add table
Reference in a new issue