/******************************************************************************* * Copyright (c) 2012 VMware Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * VMware Inc. - initial contribution *******************************************************************************/ package org.eclipse.virgo.kernel.deployer.core.internal; import org.eclipse.virgo.kernel.deployer.model.GCRoots; import org.eclipse.virgo.kernel.install.artifact.ArtifactIdentity; import org.eclipse.virgo.kernel.install.artifact.InstallArtifact; import org.eclipse.virgo.nano.serviceability.NonNull; import org.eclipse.virgo.util.common.GraphNode; import org.eclipse.virgo.util.common.GraphNode.DirectedAcyclicGraphVisitor; import org.eclipse.virgo.util.osgi.manifest.VersionRange; public final class ExistingNodeLocator implements DirectedAcyclicGraphVisitor<InstallArtifact> { private final String scopeName; private GraphNode<InstallArtifact> foundNode = null; private final String type; private final String name; private final VersionRange versionRange; /** * Searches the DAG from the given GC roots looking for an install artifact with the given identity and returns the * first one it finds or <code>null</code> if none are found. */ public static GraphNode<InstallArtifact> findSharedNode(GCRoots gcRoots, ArtifactIdentity artifactIdentity) { ExistingNodeLocator visitor = new ExistingNodeLocator(artifactIdentity.getType(), artifactIdentity.getName(), VersionRange.createExactRange(artifactIdentity.getVersion()), artifactIdentity.getScopeName()); for (InstallArtifact gcRoot : gcRoots) { gcRoot.getGraph().visit(visitor); } return visitor.getFoundNode(); } /** * Searches the DAG from the given GC roots looking for an install artifact with the given type, name, and scope * name and with version in the given version range and returns the first one it finds or <code>null</code> if none * are found. */ public static GraphNode<InstallArtifact> findSharedNode(GCRoots gcRoots, String type, String name, VersionRange versionRange, String scopeName) { ExistingNodeLocator visitor = new ExistingNodeLocator(type, name, versionRange, scopeName); for (InstallArtifact gcRoot : gcRoots) { gcRoot.getGraph().visit(visitor); } return visitor.getFoundNode(); } /** * Searches the DAG from the given GC roots looking for an install artifact that matches the given graph node and * returns the first one it finds or <code>null</code> if none are found. */ public static GraphNode<InstallArtifact> findSharedNode(GCRoots gcRoots, GraphNode<InstallArtifact> installGraph) { InstallArtifact installArtifact = installGraph.getValue(); ArtifactIdentity artifactIdentity = new ArtifactIdentity(installArtifact.getType(), installArtifact.getName(), installArtifact.getVersion(), installArtifact.getScopeName()); return findSharedNode(gcRoots, artifactIdentity); } ExistingNodeLocator(@NonNull String type, @NonNull String name, @NonNull VersionRange versionRange, String scopeName) { this.type = type; this.name = name; this.versionRange = versionRange; this.scopeName = scopeName; } @Override public boolean visit(GraphNode<InstallArtifact> node) { InstallArtifact candidate = node.getValue(); if (this.foundNode == null && matches(candidate)) { this.foundNode = node; } return this.foundNode == null; } private boolean matches(InstallArtifact candidate) { return candidate.getType().equals(this.type) && candidate.getName().equals(this.name) && (this.scopeName == null && candidate.getScopeName() == null || this.scopeName != null && this.scopeName.equals(candidate.getScopeName())) && this.versionRange.includes(candidate.getVersion()); } public GraphNode<InstallArtifact> getFoundNode() { return this.foundNode; } }