public synchronized ResolutionContext startResolvingChildren(BOMNode node) throws CoreException { Resolution nodeRes = node.getResolution(); if (invalidateRun || nodeRes == null) return null; ComponentQuery cquery = node.getQuery(); ResolutionContext originalContext = query.getResolutionContext(); ResolutionContext context = originalContext; if (!(cquery == null || cquery.equals(context.getComponentQuery()))) context = new ResolutionContext(cquery, context); CSpec cspec = nodeRes.getCSpec(); Collection<Generator> generators = cspec.getGeneratorList(); if (generators.size() > 0) { if (context == originalContext) context = new ResolutionContext(originalContext.getComponentQuery(), originalContext); context.setGenerators(cspec, generators); } if (context != originalContext) query = context.getNodeQuery(query.getQualifiedDependency()); return context; }
public BOMNode collectNodes( Map<UUID, BOMNode> nodeMap, Stack<Resolution> circularDepTrap, boolean sameTop) throws CoreException { if (query.skipComponent()) return null; if (generatorNode != null) return generatorNode; if (resolution == null) return new UnresolvedNode(query.getQualifiedDependency()); UUID myID = resolution.getId(); BOMNode node = nodeMap.get(myID); if (node != null) return node; if (circularDepTrap.contains(resolution)) { if (query.allowCircularDependency()) return null; ArrayList<String> attrs = new ArrayList<String>(circularDepTrap.size()); for (Resolution res : circularDepTrap) attrs.add(res.getCSpec().getName()); attrs.add(resolution.getName()); throw new CircularDependencyException(attrs); } boolean transitive = true; if (IComponentType.OSGI_BUNDLE.equals(resolution.getComponentTypeId())) { // We don't traverse the children of source bundles since that // dependency is synthesized transitive = !resolution.getName().endsWith(".source"); // $NON-NLS-1$ } List<BOMNode> childNodes; int top = children.length; ComponentQuery cquery = query.getComponentQuery(); if (transitive && top > 0) { try { ArrayList<BOMNode> childNodeArr = new ArrayList<BOMNode>(top); circularDepTrap.push(resolution); for (ResolverNode child : children) { boolean sameChildTop = cquery.equals(child.query.getComponentQuery()); BOMNode childNode = child.collectNodes(nodeMap, circularDepTrap, sameChildTop); if (childNode == null) { // We encountered a skipped component or an allowed // circular dependency. This // means we must alter the resolution of this node // String depName = child.getQuery().getComponentRequest().getName(); CSpec cspec = resolution.getCSpec(); CSpecBuilder bld = new CSpecBuilder(); bld.initFrom(cspec); for (IAttribute attr : cspec.getAttributes().values()) { for (IPrerequisite pq : attr.getPrerequisites()) { if (depName.equals(pq.getComponentName())) ((TopLevelAttributeBuilder) bld.getAttribute(attr.getName())) .removePrerequisite(pq); } } bld.removeDependency(depName); cspec = bld.createCSpec(); resolution = new Resolution(cspec, resolution); } else childNodeArr.add(childNode); } circularDepTrap.pop(); childNodes = childNodeArr; } catch (CircularDependencyException e) { if (query.allowCircularDependency()) return null; throw e; } } else childNodes = Collections.emptyList(); node = new ResolvedNode(resolution, childNodes); if (!sameTop) node = BillOfMaterials.create(node, cquery); nodeMap.put(myID, node); return node; }