mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-08-24 08:44:01 +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;
|
package org.eclipse.dd.dsf.datamodel;
|
||||||
|
|
||||||
|
import java.lang.reflect.Array;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.LinkedHashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import org.eclipse.dd.dsf.concurrent.ThreadSafe;
|
import org.eclipse.dd.dsf.concurrent.ThreadSafe;
|
||||||
|
|
||||||
|
@ -26,10 +30,15 @@ public class DMContexts {
|
||||||
* Convenience constant.
|
* Convenience constant.
|
||||||
*/
|
*/
|
||||||
public static final IDMContext[] EMPTY_CONTEXTS_ARRAY = new IDMContext[0];
|
public static final IDMContext[] EMPTY_CONTEXTS_ARRAY = new IDMContext[0];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Finds a data model context of given type among ancestors of the
|
* 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 ctx DMC to search.
|
||||||
* @param ancestorType Class type of the desired DMC ancestor.
|
* @param ancestorType Class type of the desired DMC ancestor.
|
||||||
* @return Returns the ancestor if found, null otherwise.
|
* @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) {
|
public static <V extends IDMContext> V getAncestorOfType(IDMContext ctx, Class<V> ancestorType) {
|
||||||
if(ctx == null)
|
if(ctx == null)
|
||||||
return null;
|
return null;
|
||||||
|
// Check the first context here for efficiency
|
||||||
if (ancestorType.isAssignableFrom(ctx.getClass())) {
|
if (ancestorType.isAssignableFrom(ctx.getClass())) {
|
||||||
return (V)ctx;
|
return (V)ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (IDMContext parent : ctx.getParents()) {
|
// Use a LinkedHashSet to avoid duplicates and preserver insertion-order
|
||||||
if (ancestorType.isAssignableFrom(parent.getClass())) {
|
Set<IDMContext> nodes = new LinkedHashSet<IDMContext>();
|
||||||
return (V)parent;
|
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()) {
|
nodes.addAll(Arrays.asList(parent.getParents()));
|
||||||
V ancestor = getAncestorOfType(parent, ancestorType);
|
}
|
||||||
if (ancestor != null) return ancestor;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
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
|
* Checks all ancestors for a given context to see if the given
|
||||||
|
|
Loading…
Add table
Reference in a new issue