diff options
Diffstat (limited to 'dcaedt_validator/checker/src/main/java/org/onap/sdc/dcae/checker/Catalog.java')
-rw-r--r-- | dcaedt_validator/checker/src/main/java/org/onap/sdc/dcae/checker/Catalog.java | 722 |
1 files changed, 360 insertions, 362 deletions
diff --git a/dcaedt_validator/checker/src/main/java/org/onap/sdc/dcae/checker/Catalog.java b/dcaedt_validator/checker/src/main/java/org/onap/sdc/dcae/checker/Catalog.java index 1512e56..bdddce3 100644 --- a/dcaedt_validator/checker/src/main/java/org/onap/sdc/dcae/checker/Catalog.java +++ b/dcaedt_validator/checker/src/main/java/org/onap/sdc/dcae/checker/Catalog.java @@ -23,7 +23,6 @@ import com.google.common.collect.Iterators; import com.google.common.collect.Table; import com.google.common.collect.HashBasedTable; import org.onap.sdc.common.onaplog.OnapLoggerDebug; -import org.onap.sdc.common.onaplog.OnapLoggerError; import org.onap.sdc.common.onaplog.Enums.LogLevel; /* @@ -33,250 +32,249 @@ import org.onap.sdc.common.onaplog.Enums.LogLevel; */ public class Catalog { - private static OnapLoggerError errLogger = OnapLoggerError.getInstance(); - private static OnapLoggerDebug debugLogger = OnapLoggerDebug.getInstance(); + private static final String DERIVED_FROM = "derived_from"; + private static OnapLoggerDebug debugLogger = OnapLoggerDebug.getInstance(); - /* Type hierarchies are stored as maps from a type name to its definition + + /* tracks imports, i.e.targets */ + private LinkedHashMap<URI, Target> targets = + new LinkedHashMap<>(); + /* tracks dependencies between targets, i.e. the 'adjency' matrix defined by + * the 'import' relationship */ + private Table<Target,Target,Boolean> imports = HashBasedTable.create(); + + + /* Type hierarchies are stored as maps from a type name to its definition * Not the best but easy to follow hierarchies towards their root .. */ private EnumMap<Construct, Map<String,Map>> types = - new EnumMap<Construct, Map<String,Map>>(Construct.class); - /* track templates: we track templates (tye instances) first per target then per contruct. - * This allows us to share the catalog among multiple templates sharign the same type set + new EnumMap<>(Construct.class); + /* track templates: we track templates (tye instances) first per target then per contruct. + * This allows us to share the catalog among multiple templates sharign the same type set */ private Map<Target, EnumMap<Construct, Map<String,Map>>> templates = - new HashMap<Target, EnumMap<Construct, Map<String,Map>>>(); - - private Catalog parent; - - public Catalog(Catalog theParent) { - this.parent = theParent; - /* there are no requirement types, they are the same as capability types */ - types.put(Construct.Data, new LinkedHashMap<String, Map>()); - types.put(Construct.Capability, new LinkedHashMap<String, Map>()); - types.put(Construct.Relationship, new LinkedHashMap<String, Map>()); - types.put(Construct.Artifact, new LinkedHashMap<String, Map>()); - types.put(Construct.Interface, new LinkedHashMap<String, Map>()); - types.put(Construct.Node, new LinkedHashMap<String, Map>()); - types.put(Construct.Group, new LinkedHashMap<String, Map>()); - types.put(Construct.Policy, new LinkedHashMap<String, Map>()); + new HashMap<>(); + + private Catalog parent; + + public Catalog(Catalog theParent) { + this.parent = theParent; + /* there are no requirement types, they are the same as capability types */ + types.put(Construct.Data, new LinkedHashMap<>()); + types.put(Construct.Capability, new LinkedHashMap<>()); + types.put(Construct.Relationship, new LinkedHashMap<>()); + types.put(Construct.Artifact, new LinkedHashMap<>()); + types.put(Construct.Interface, new LinkedHashMap<>()); + types.put(Construct.Node, new LinkedHashMap<>()); + types.put(Construct.Group, new LinkedHashMap<>()); + types.put(Construct.Policy, new LinkedHashMap<>()); - } - - public Catalog() { - this(null); - } - - public boolean addType(Construct theConstruct, String theName, Map theDef) { - if (hasType(theConstruct, theName)) { - return false; - } - getConstructTypes(theConstruct).put(theName, theDef); - return true; + } + + public Catalog() { + this(null); + } + + public boolean addType(Construct theConstruct, String theName, Map theDef) { + if (hasType(theConstruct, theName)) { + return false; + } + getConstructTypes(theConstruct).put(theName, theDef); + return true; } - public Map getTypeDefinition(Construct theConstruct, String theName) { - Map<String, Map> constructTypes = getConstructTypes(theConstruct); - Map typeDef = constructTypes.get(theName); - if (typeDef == null && this.parent != null) { - return this.parent.getTypeDefinition(theConstruct, theName); - } - return typeDef; - } + public Map getTypeDefinition(Construct theConstruct, String theName) { + Map<String, Map> constructTypes = getConstructTypes(theConstruct); + Map typeDef = constructTypes.get(theName); + if (typeDef == null && this.parent != null) { + return this.parent.getTypeDefinition(theConstruct, theName); + } + return typeDef; + } public boolean hasType(Construct theConstruct, String theName) { - Map<String, Map> constructTypes = getConstructTypes(theConstruct); - boolean res = constructTypes.containsKey(theName); - if (!res && this.parent != null) { - res = this.parent.hasType(theConstruct, theName); - } - return res; - } - - protected Map<String, Map> getConstructTypes(Construct theConstruct) { - Map<String, Map> constructTypes = this.types.get(theConstruct); - if (null == constructTypes) { - throw new RuntimeException("Something worse is cooking here!", - new CatalogException("No types for construct " + theConstruct)); - } - return constructTypes; - } - - protected Iterator<Map.Entry<String,Map>> - typesIterator(Construct theConstruct) { - List<Map.Entry<String,Map>> constructTypes = - new ArrayList<Map.Entry<String,Map>>( - this.types.get(theConstruct).entrySet()); - Collections.reverse(constructTypes); - return (this.parent == null) - ? constructTypes.iterator() - : Iterators.concat(constructTypes.iterator(), - this.parent.typesIterator(theConstruct)); - } - - /* this will iterate through the type hierarchy for the given type, included. - */ - public Iterator<Map.Entry<String,Map>> - hierarchy(Construct theConstruct, final String theName) { - return Iterators.filter(typesIterator(theConstruct), + Map<String, Map> constructTypes = getConstructTypes(theConstruct); + boolean res = constructTypes.containsKey(theName); + if (!res && this.parent != null) { + res = this.parent.hasType(theConstruct, theName); + } + return res; + } + + protected Map<String, Map> getConstructTypes(Construct theConstruct) { + Map<String, Map> constructTypes = this.types.get(theConstruct); + if (null == constructTypes) { + throw new RuntimeException("Something worse is cooking here!", + new CatalogException("No types for construct " + theConstruct)); + } + return constructTypes; + } + + private Iterator<Map.Entry<String,Map>> + typesIterator(Construct theConstruct) { + List<Map.Entry<String,Map>> constructTypes = + new ArrayList<>( + this.types.get(theConstruct).entrySet()); + Collections.reverse(constructTypes); + return (this.parent == null) + ? constructTypes.iterator() + : Iterators.concat(constructTypes.iterator(), + this.parent.typesIterator(theConstruct)); + } + + + // this will iterate through the type hierarchy for the given type, included. + public Iterator<Map.Entry<String,Map>> + hierarchy(Construct theConstruct, final String theName) { + return Iterators.filter(typesIterator(theConstruct), new Predicate<Map.Entry<String,Map>>() { Object next = theName; public boolean apply(Map.Entry<String,Map> theEntry) { if (next != null && next.equals(theEntry.getKey())) { - next = theEntry.getValue().get("derived_from"); + next = theEntry.getValue().get(DERIVED_FROM); return true; + } else { + return false; } - else - return false; } }); } - public boolean isDerivedFrom(Construct theConstruct, String theType, String theBaseType) { - - Iterator<Map.Entry<String,Map>> hierachyIterator = - hierarchy(theConstruct, theType); - while (hierachyIterator.hasNext()) { - Map.Entry<String,Map> typeDef = hierachyIterator.next(); - - if (typeDef.getKey().equals(theBaseType)) { - return true; - } - } - return false; - } - - /* We go over the type hierarchy and retain only an iterator over the - * elements of the given facet for each type in the hierarchy. - * We concatenate these iterators and filter out duplicates. - * TODO: cannot just filter out duplicates - a redefinition can refine the one in the base construct so we - * should merge them! - */ - public Iterator<Map.Entry> facets(Construct theConstruct, - final Facet theFacet, - final String theName) { - return - Iterators.filter( - Iterators.concat( - Iterators.transform( - hierarchy(theConstruct, theName), - new Function<Map.Entry<String,Map>, Iterator<Map.Entry>>() { - public Iterator<Map.Entry> apply(Map.Entry<String,Map> theEntry) { - Map m = (Map)theEntry.getValue().get(theFacet.name()); - return m == null - ? Collections.emptyIterator() - : m.entrySet().iterator(); - } - } - ) - ), + public boolean isDerivedFrom(Construct theConstruct, String theType, String theBaseType) { + + Iterator<Map.Entry<String,Map>> hierachyIterator = + hierarchy(theConstruct, theType); + while (hierachyIterator.hasNext()) { + Map.Entry<String,Map> typeDef = hierachyIterator.next(); + + if (typeDef.getKey().equals(theBaseType)) { + return true; + } + } + return false; + } + + /* We go over the type hierarchy and retain only an iterator over the + * elements of the given facet for each type in the hierarchy. + * We concatenate these iterators and filter out duplicates. + * TODO: cannot just filter out duplicates - a redefinition can refine the one in the base construct so we + * should merge them! + */ + public Iterator<Map.Entry> facets(Construct theConstruct, final Facet theFacet, final String theName) { + return + Iterators.filter( + Iterators.concat( + Iterators.transform( + hierarchy(theConstruct, theName), + (Function<Map.Entry<String, Map>, Iterator<Map.Entry>>) theEntry -> { + Map m = (Map)theEntry.getValue().get(theFacet.name()); + return m == null + ? Collections.emptyIterator() + : m.entrySet().iterator(); + } + ) + ), new Predicate<Map.Entry>() { - Set insts = new HashSet(); - public boolean apply(Map.Entry theEntry) { - return !insts.contains(theEntry.getKey()); - } - } - ); - } - - //no need to specify a construct, only nodes can have requirements - public Iterator<Map.Entry> requirements(final String theName) { - return - Iterators.concat( - Iterators.transform( - hierarchy(Construct.Node, theName), - new Function<Map.Entry<String,Map>, Iterator<Map.Entry>>() { - public Iterator<Map.Entry> apply(Map.Entry<String,Map> theEntry) { - List<Map> l = (List<Map>)theEntry.getValue().get("requirements"); - return l == null - ? Collections.emptyIterator() - : Iterators.concat( - Iterators.transform( - l.iterator(), - new Function<Map, Iterator<Map.Entry>> () { - public Iterator<Map.Entry> apply(Map theEntry) { - return theEntry.entrySet().iterator(); - } - } - ) - ); - } - } - ) - ); - } - - /* Example: find the definition of property 'port' of the node type - * tosca.nodes.Database (properties being a facet of the node construct) - * - * Note: the definition of a facet is cumulative, i.e. more specialized - * definitions contribute (by overwriting) to the - */ - public Map getFacetDefinition(Construct theConstruct, - String theConstructTypeName, - Facet theFacet, - String theName) { - Map def = null; - Iterator<Map.Entry<String,Map>> ti = hierarchy(theConstruct, theConstructTypeName); - while (ti.hasNext()) { - //this is where requirements would yield a List .. - Map<String,Map> fset = (Map<String,Map>)ti.next().getValue().get(theFacet.name()); - if (fset != null) { - def = def == null ? fset.get(theName) - : mergeDefinitions(def, fset.get(theName)); - } - } - return def; - } - - public Map getRequirementDefinition(Construct theConstruct, - String theConstructTypeName, - String theName) { - Iterator<Map.Entry<String,Map>> ti = hierarchy(theConstruct, theConstructTypeName); - while (ti.hasNext()) { - //this is where requirements yield a List .. - List<Map> reqs = (List<Map>)ti.next().getValue().get("requirements"); - - if(reqs!=null){ - for (Map req: reqs) { - Map.Entry reqe = (Map.Entry)req.entrySet().iterator().next(); - if (theName.equals(reqe.getKey())) { - return (Map)reqe.getValue(); - } - } - }else{ - debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Avoiding adding requirment block since it doesn't exists on the template...."); - } - } - return null; - } + Set insts = new HashSet(); + public boolean apply(Map.Entry theEntry) { + return !insts.contains(theEntry.getKey()); + } + } + ); + } + + //no need to specify a construct, only nodes can have requirements + public Iterator<Map.Entry> requirements(final String theName) { + return + Iterators.concat( + Iterators.transform( + hierarchy(Construct.Node, theName), + theEntry -> { + List<Map> l = (List<Map>)theEntry.getValue().get("requirements"); + return l == null + ? Collections.emptyIterator() + : Iterators.concat( + Iterators.transform( + l.iterator(), + (Function<Map, Iterator<Map.Entry>>) theEntry1 -> theEntry1.entrySet().iterator() + ) + ); + } + ) + ); + } + + /* Example: find the definition of property 'port' of the node type + * tosca.nodes.Database (properties being a facet of the node construct) + * + * Note: the definition of a facet is cumulative, i.e. more specialized + * definitions contribute (by overwriting) to the + */ + public Map getFacetDefinition(Construct theConstruct, + String theConstructTypeName, + Facet theFacet, + String theName) { + Map def = null; + Iterator<Map.Entry<String,Map>> ti = hierarchy(theConstruct, theConstructTypeName); + while (ti.hasNext()) { + //this is where requirements would yield a List .. + Map<String,Map> fset = (Map<String,Map>)ti.next().getValue().get(theFacet.name()); + if (fset != null) { + def = def == null ? fset.get(theName) + : mergeDefinitions(def, fset.get(theName)); + } + } + return def; + } + + public Map getRequirementDefinition(Construct theConstruct, + String theConstructTypeName, + String theName) { + Iterator<Map.Entry<String,Map>> ti = hierarchy(theConstruct, theConstructTypeName); + while (ti.hasNext()) { + //this is where requirements yield a List .. + List<Map> reqs = (List<Map>)ti.next().getValue().get("requirements"); + + if(reqs!=null) { + for (Map req: reqs) { + Map.Entry reqe = (Map.Entry)req.entrySet().iterator().next(); + if (theName.equals(reqe.getKey())) { + return (Map)reqe.getValue(); + } + } + } else { + debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Avoiding adding requirment block since it doesn't exists on the template...."); + } + } + return null; + } /* */ private EnumMap<Construct,Map<String,Map>> getTemplates(Target theTarget) { - EnumMap<Construct, Map<String,Map>> targetTemplates = templates.get(theTarget); - if (targetTemplates == null) { - targetTemplates = new EnumMap<Construct,Map<String,Map>>(Construct.class); - targetTemplates.put(Construct.Data, new LinkedHashMap<String, Map>()); - targetTemplates.put(Construct.Relationship, new LinkedHashMap<String, Map>()); - targetTemplates.put(Construct.Node, new LinkedHashMap<String, Map>()); - targetTemplates.put(Construct.Group, new LinkedHashMap<String, Map>()); - targetTemplates.put(Construct.Policy, new LinkedHashMap<String, Map>()); - - templates.put(theTarget, targetTemplates); - } - return targetTemplates; - } - - public Map<String,Map> getTargetTemplates(Target theTarget, Construct theConstruct) { - return getTemplates(theTarget).get(theConstruct); - } - - public void addTemplate(Target theTarget, Construct theConstruct, String theName, Map theDef) - throws CatalogException { - Map<String, Map> constructTemplates = getTargetTemplates(theTarget, theConstruct); - if (null == constructTemplates) { + EnumMap<Construct, Map<String,Map>> targetTemplates = templates.get(theTarget); + if (targetTemplates == null) { + targetTemplates = new EnumMap<>(Construct.class); + targetTemplates.put(Construct.Data, new LinkedHashMap<>()); + targetTemplates.put(Construct.Relationship, new LinkedHashMap<>()); + targetTemplates.put(Construct.Node, new LinkedHashMap<>()); + targetTemplates.put(Construct.Group, new LinkedHashMap<>()); + targetTemplates.put(Construct.Policy, new LinkedHashMap<>()); + + templates.put(theTarget, targetTemplates); + } + return targetTemplates; + } + + public Map<String,Map> getTargetTemplates(Target theTarget, Construct theConstruct) { + return getTemplates(theTarget).get(theConstruct); + } + + public void addTemplate(Target theTarget, Construct theConstruct, String theName, Map theDef) + throws CatalogException { + Map<String, Map> constructTemplates = getTargetTemplates(theTarget, theConstruct); + if (null == constructTemplates) { throw new CatalogException("No such thing as " + theConstruct + " templates"); - } + } if (constructTemplates.containsKey(theName)) { throw new CatalogException(theConstruct + " template '" + theName + "' re-declaration"); } @@ -286,159 +284,159 @@ public class Catalog { public boolean hasTemplate(Target theTarget, Construct theConstruct, String theName) { Map<String, Map> constructTemplates = getTargetTemplates(theTarget, theConstruct); return constructTemplates != null && - constructTemplates.containsKey(theName); + constructTemplates.containsKey(theName); } public Map getTemplate(Target theTarget, Construct theConstruct, String theName) { Map<String, Map> constructTemplates = getTargetTemplates(theTarget, theConstruct); - if (constructTemplates != null) - return constructTemplates.get(theName); - else - return null; + if (constructTemplates != null) { + return constructTemplates.get(theName); + } else { + return null; + } } - public static Map mergeDefinitions(Map theAggregate, Map theIncrement) { - if (theIncrement == null) - return theAggregate; - - for(Map.Entry e: (Set<Map.Entry>)theIncrement.entrySet()) { - theAggregate.putIfAbsent(e.getKey(), e.getValue()); - } - return theAggregate; - } + public static Map mergeDefinitions(Map theAggregate, Map theIncrement) { + if (theIncrement == null) { + return theAggregate; + } - /* tracks imports, i.e.targets */ - private LinkedHashMap<URI, Target> targets = - new LinkedHashMap<URI, Target>(); - /* tracks dependencies between targets, i.e. the 'adjency' matrix defined by - * the 'import' relationship */ - private Table<Target,Target,Boolean> imports = HashBasedTable.create(); + for(Map.Entry e: (Set<Map.Entry>)theIncrement.entrySet()) { + theAggregate.putIfAbsent(e.getKey(), e.getValue()); + } + return theAggregate; + } - /* + /* * theParent contains an 'include/import' statement pointing to the Target */ - public boolean addTarget(Target theTarget, Target theParent) { - boolean cataloged = targets.containsKey(theTarget.getLocation()); - - if(!cataloged) { - targets.put(theTarget.getLocation(), theTarget); - } - - if (theParent != null) { - imports.put(theParent, theTarget, Boolean.TRUE); - } - - return !cataloged; - } - - public Target getTarget(URI theLocation) { - return targets.get(theLocation); - } - - public Collection<Target> targets() { - return targets.values(); - } - - /* Targets that no other targets depend on */ - public Collection<Target> topTargets() { - return targets.values() - .stream() - .filter(t -> !imports.containsColumn(t)) - .collect(Collectors.toList()); - - } - - public String importString(Target theTarget) { - return importString(theTarget, " "); - } - - private String importString(Target theTarget, String thePrefix) { - StringBuilder sb = new StringBuilder(""); - Map<Target,Boolean> parents = imports.column(theTarget); - if (parents != null) { - for (Target p: parents.keySet()) { - sb.append(thePrefix) - .append("from ") - .append(p.getLocation()) - .append("\n") - .append(importString(p, thePrefix + " ")); - } - //we only keep the positive relationships - } - return sb.toString(); - } - - /* */ - private class TargetComparator implements Comparator<Target> { - - /* @return 1 if there is a dependency path from TargetOne to TargetTwo, -1 otherwise */ - public int compare(Target theTargetOne, Target theTargetTwo) { - if (hasPath(theTargetTwo, theTargetOne)) - return -1; - - if (hasPath(theTargetOne, theTargetTwo)) - return 1; - - return 0; - } - - public boolean hasPath(Target theStart, Target theEnd) { - Map<Target,Boolean> deps = imports.row(theStart); - if (deps.containsKey(theEnd)) - return true; - for (Target dep: deps.keySet()) { - if (hasPath(dep, theEnd)) - return true; - } - return false; - } - } - - public Collection<Target> sortedTargets() { - List keys = new ArrayList(this.targets.values()); - Collections.sort(keys, new TargetComparator()); - return keys; - } - - public static void main(String[] theArgs) throws Exception { - - Catalog cat = new Catalog(); - - Target a = new Target("a", new URI("a")), - b = new Target("b", new URI("b")), - c = new Target("c", new URI("c")), - d = new Target("d", new URI("d")); - - cat.addTarget(a, null); - cat.addTarget(b, null); - cat.addTarget(c, null); - cat.addTarget(d, null); - - cat.addTarget(b, c); - cat.addTarget(a, c); - cat.addTarget(c, d); - cat.addTarget(a, b); - - for (Target t: cat.sortedTargets()) - debugLogger.log(LogLevel.DEBUG, Catalog.class.getName(), t.toString()); - - Catalog root = new Catalog(); - root.addType(Construct.Node, "_a", Collections.emptyMap()); - root.addType(Construct.Node, "__a", Collections.singletonMap("derived_from", "_a")); - root.addType(Construct.Node, "___a", Collections.singletonMap("derived_from", "_a")); - - Catalog base = new Catalog(root); - base.addType(Construct.Node, "_b", Collections.singletonMap("derived_from", "__a")); - base.addType(Construct.Node, "__b", Collections.singletonMap("derived_from", "_b")); - base.addType(Construct.Node, "__b_", Collections.singletonMap("derived_from", "_a")); - - if (theArgs.length > 0) { - Iterator<Map.Entry<String, Map>> ti = - base.hierarchy(Construct.Node, theArgs[0]); - while (ti.hasNext()) { + public boolean addTarget(Target theTarget, Target theParent) { + boolean cataloged = targets.containsKey(theTarget.getLocation()); + + if(!cataloged) { + targets.put(theTarget.getLocation(), theTarget); + } + + if (theParent != null) { + imports.put(theParent, theTarget, Boolean.TRUE); + } + + return !cataloged; + } + + public Target getTarget(URI theLocation) { + return targets.get(theLocation); + } + + public Collection<Target> targets() { + return targets.values(); + } + + /* Targets that no other targets depend on */ + public Collection<Target> topTargets() { + return targets.values() + .stream() + .filter(t -> !imports.containsColumn(t)) + .collect(Collectors.toList()); + + } + + public String importString(Target theTarget) { + return importString(theTarget, " "); + } + + private String importString(Target theTarget, String thePrefix) { + StringBuilder sb = new StringBuilder(""); + Map<Target,Boolean> parents = imports.column(theTarget); + if (parents != null) { + for (Target p: parents.keySet()) { + sb.append(thePrefix) + .append("from ") + .append(p.getLocation()) + .append("\n") + .append(importString(p, thePrefix + " ")); + } + //we only keep the positive relationships + } + return sb.toString(); + } + + /* */ + private class TargetComparator implements Comparator<Target> { + + /* @return 1 if there is a dependency path from TargetOne to TargetTwo, -1 otherwise */ + public int compare(Target theTargetOne, Target theTargetTwo) { + if (hasPath(theTargetTwo, theTargetOne)) { + return -1; + } + + if (hasPath(theTargetOne, theTargetTwo)) { + return 1; + } + + return 0; + } + + boolean hasPath(Target theStart, Target theEnd) { + Map<Target,Boolean> deps = imports.row(theStart); + if (deps.containsKey(theEnd)) { + return true; + } + for (Target dep: deps.keySet()) { + if (hasPath(dep, theEnd)) { + return true; + } + } + return false; + } + } + + public Collection<Target> sortedTargets() { + List keys = new ArrayList(this.targets.values()); + Collections.sort(keys, new TargetComparator()); + return keys; + } + + public static void main(String[] theArgs) throws Exception { + + Catalog cat = new Catalog(); + + Target a = new Target("a", new URI("a")), + b = new Target("b", new URI("b")), + c = new Target("c", new URI("c")), + d = new Target("d", new URI("d")); + + cat.addTarget(a, null); + cat.addTarget(b, null); + cat.addTarget(c, null); + cat.addTarget(d, null); + + cat.addTarget(b, c); + cat.addTarget(a, c); + cat.addTarget(c, d); + cat.addTarget(a, b); + + for (Target t: cat.sortedTargets()) { + debugLogger.log(LogLevel.DEBUG, Catalog.class.getName(), t.toString()); + } + + Catalog root = new Catalog(); + root.addType(Construct.Node, "_a", Collections.emptyMap()); + root.addType(Construct.Node, "__a", Collections.singletonMap(DERIVED_FROM, "_a")); + root.addType(Construct.Node, "___a", Collections.singletonMap(DERIVED_FROM, "_a")); + + Catalog base = new Catalog(root); + base.addType(Construct.Node, "_b", Collections.singletonMap(DERIVED_FROM, "__a")); + base.addType(Construct.Node, "__b", Collections.singletonMap(DERIVED_FROM, "_b")); + base.addType(Construct.Node, "__b_", Collections.singletonMap(DERIVED_FROM, "_a")); + + if (theArgs.length > 0) { + Iterator<Map.Entry<String, Map>> ti = + base.hierarchy(Construct.Node, theArgs[0]); + while (ti.hasNext()) { debugLogger.log(LogLevel.DEBUG, Catalog.class.getName(), "> {}", ti.next().getKey()); - } - } - } + } + } + } } |