Example usage for org.apache.maven.artifact.resolver ResolutionNode getDepth

List of usage examples for org.apache.maven.artifact.resolver ResolutionNode getDepth

Introduction

In this page you can find the example usage for org.apache.maven.artifact.resolver ResolutionNode getDepth.

Prototype

public int getDepth() 

Source Link

Usage

From source file:com.adviser.maven.GraphArtifactCollector.java

License:Apache License

private ResolutionNode checkPreviousNodes(ResolutionNode node, List listeners, List previousNodes)
        throws OverConstrainedVersionException {
    for (Iterator i = previousNodes.iterator(); i.hasNext();) {
        ResolutionNode previous = (ResolutionNode) i.next();
        if (previous.isActive()) {
            // Version mediation
            VersionRange previousRange = previous.getArtifact().getVersionRange();
            VersionRange currentRange = node.getArtifact().getVersionRange();
            // TODO: why do we force the version on it? what if they
            // don't match?
            if (previousRange == null) {
                // version was already resolved
                node.getArtifact().setVersion(previous.getArtifact().getVersion());
            } else if (currentRange == null) {
                // version was already resolved
                previous.getArtifact().setVersion(node.getArtifact().getVersion());
            } else {
                // TODO: shouldn't need to double up on this work, only
                // done for simplicity of handling recommended
                // version but the restriction is identical
                VersionRange newRange = previousRange.restrict(currentRange);
                // TODO: ick. this forces the OCE that should have come
                // from the previous call. It is still correct
                if (newRange.isSelectedVersionKnown(previous.getArtifact())) {
                    fireEvent(ResolutionListener.RESTRICT_RANGE, listeners, node, previous.getArtifact(),
                            newRange);//  www  . j a v  a 2  s  .  c  o  m
                }
                previous.getArtifact().setVersionRange(newRange);
                node.getArtifact().setVersionRange(currentRange.restrict(previousRange));

                // Select an appropriate available version from the (now
                // restricted) range
                // Note this version was selected before to get the
                // appropriate POM
                // But it was reset by the call to setVersionRange on
                // restricting the version
                ResolutionNode[] resetNodes = { previous, node };
                for (int j = 0; j < 2; j++) {
                    Artifact resetArtifact = resetNodes[j].getArtifact();
                    if (resetArtifact.getVersion() == null && resetArtifact.getVersionRange() != null
                            && resetArtifact.getAvailableVersions() != null) {

                        resetArtifact.selectVersion(resetArtifact.getVersionRange()
                                .matchVersion(resetArtifact.getAvailableVersions()).toString());
                        fireEvent(ResolutionListener.SELECT_VERSION_FROM_RANGE, listeners, resetNodes[j]);
                    }
                }
            }

            // Conflict Resolution
            // TODO: use as conflict resolver(s), chain

            // TODO: should this be part of mediation?
            // previous one is more dominant
            if (previous.getDepth() <= node.getDepth()) {
                checkScopeUpdate(node, previous, listeners);
            } else {
                checkScopeUpdate(previous, node, listeners);
            }

            if (previous.getDepth() <= node.getDepth()) {
                // previous was nearer
                fireEvent(ResolutionListener.OMIT_FOR_NEARER, listeners, node, previous.getArtifact());
                node.disable();
                node = previous;
            } else {
                fireEvent(ResolutionListener.OMIT_FOR_NEARER, listeners, previous, node.getArtifact());
                previous.disable();
            }
        }
    }
    return node;
}

From source file:com.adviser.maven.GraphArtifactCollector.java

License:Apache License

private void checkScopeUpdate(ResolutionNode farthest, ResolutionNode nearest, List listeners) {
    boolean updateScope = false;
    Artifact farthestArtifact = farthest.getArtifact();
    Artifact nearestArtifact = nearest.getArtifact();

    if (Artifact.SCOPE_RUNTIME.equals(farthestArtifact.getScope())
            && (Artifact.SCOPE_TEST.equals(nearestArtifact.getScope())
                    || Artifact.SCOPE_PROVIDED.equals(nearestArtifact.getScope()))) {
        updateScope = true;//from   ww  w.j  a v a2 s .com
    }

    if (Artifact.SCOPE_COMPILE.equals(farthestArtifact.getScope())
            && !Artifact.SCOPE_COMPILE.equals(nearestArtifact.getScope())) {
        updateScope = true;
    }

    // current POM rules all
    if (nearest.getDepth() < 2 && updateScope) {
        updateScope = false;

        fireEvent(ResolutionListener.UPDATE_SCOPE_CURRENT_POM, listeners, nearest, farthestArtifact);
    }

    if (updateScope) {
        fireEvent(ResolutionListener.UPDATE_SCOPE, listeners, nearest, farthestArtifact);

        // previously we cloned the artifact, but it is more effecient to
        // just update the scope
        // if problems are later discovered that the original object needs
        // its original scope value, cloning may
        // again be appropriate
        nearestArtifact.setScope(farthestArtifact.getScope());
    }
}

From source file:com.alibaba.citrus.maven.eclipse.base.ide.AbstractIdeSupportMojo.java

License:Apache License

/**
 * Resolve project dependencies. Manual resolution is needed in order to avoid resolution of multiproject artifacts
 * (if projects will be linked each other an installed jar is not needed) and to avoid a failure when a jar is
 * missing./*from  w w w .  ja  va 2 s .  co  m*/
 *
 * @return resolved IDE dependencies, with attached jars for non-reactor dependencies
 * @throws MojoExecutionException if dependencies can't be resolved
 */
protected IdeDependency[] doDependencyResolution() throws MojoExecutionException {
    if (ideDeps == null) {
        if (resolveDependencies) {
            MavenProject project = getProject();
            ArtifactRepository localRepo = getLocalRepository();

            List deps = getProject().getDependencies();

            // Collect the list of resolved IdeDependencies.
            List dependencies = new ArrayList();

            if (deps != null) {
                Map managedVersions = createManagedVersionMap(getArtifactFactory(), project.getId(),
                        project.getDependencyManagement());

                ArtifactResolutionResult artifactResolutionResult = null;

                try {

                    List listeners = new ArrayList();

                    if (logger.isDebugEnabled()) {
                        listeners.add(new DebugResolutionListener(logger));
                    }

                    listeners.add(new WarningResolutionListener(logger));

                    artifactResolutionResult = artifactCollector.collect(getProjectArtifacts(),
                            project.getArtifact(), managedVersions, localRepo,
                            project.getRemoteArtifactRepositories(), getArtifactMetadataSource(), null,
                            listeners);
                } catch (ArtifactResolutionException e) {
                    getLog().debug(e.getMessage(), e);
                    getLog().error(
                            Messages.getString("AbstractIdeSupportMojo.artifactresolution", new Object[] { //$NON-NLS-1$
                                    e.getGroupId(), e.getArtifactId(), e.getVersion(), e.getMessage() }));

                    // if we are here artifactResolutionResult is null, create a project without dependencies but
                    // don't fail
                    // (this could be a reactor projects, we don't want to fail everything)
                    // Causes MECLIPSE-185. Not sure if it should be handled this way??
                    return new IdeDependency[0];
                }

                // keep track of added reactor projects in order to avoid duplicates
                Set emittedReactorProjectId = new HashSet();

                for (Iterator i = artifactResolutionResult.getArtifactResolutionNodes().iterator(); i
                        .hasNext();) {

                    ResolutionNode node = (ResolutionNode) i.next();
                    int dependencyDepth = node.getDepth();
                    Artifact art = node.getArtifact();
                    // don't resolve jars for reactor projects
                    if (hasToResolveJar(art)) {
                        try {
                            artifactResolver.resolve(art, node.getRemoteRepositories(), localRepository);
                        } catch (ArtifactNotFoundException e) {
                            getLog().debug(e.getMessage(), e);
                            getLog().warn(Messages.getString("AbstractIdeSupportMojo.artifactdownload", //$NON-NLS-1$
                                    new Object[] { e.getGroupId(), e.getArtifactId(), e.getVersion(),
                                            e.getMessage() }));
                        } catch (ArtifactResolutionException e) {
                            getLog().debug(e.getMessage(), e);
                            getLog().warn(Messages.getString("AbstractIdeSupportMojo.artifactresolution",
                                    new Object[] { //$NON-NLS-1$
                                            e.getGroupId(), e.getArtifactId(), e.getVersion(),
                                            e.getMessage() }));
                        }
                    }

                    boolean includeArtifact = true;
                    if (getExcludes() != null) {
                        String artifactFullId = art.getGroupId() + ":" + art.getArtifactId();
                        if (getExcludes().contains(artifactFullId)) {
                            getLog().info("excluded: " + artifactFullId);
                            includeArtifact = false;
                        }
                    }

                    if (includeArtifact && (!(getUseProjectReferences() && isAvailableAsAReactorProject(art))
                            || emittedReactorProjectId.add(art.getGroupId() + '-' + art.getArtifactId()))) {

                        // the following doesn't work: art.getArtifactHandler().getPackaging() always returns "jar"
                        // also
                        // if the packaging specified in pom.xml is different.

                        // osgi-bundle packaging is provided by the felix osgi plugin
                        // eclipse-plugin packaging is provided by this eclipse plugin
                        // String packaging = art.getArtifactHandler().getPackaging();
                        // boolean isOsgiBundle = "osgi-bundle".equals( packaging ) || "eclipse-plugin".equals(
                        // packaging );

                        // we need to check the manifest, if "Bundle-SymbolicName" is there the artifact can be
                        // considered
                        // an osgi bundle
                        boolean isOsgiBundle = false;
                        String osgiSymbolicName = null;
                        if (art.getFile() != null) {
                            JarFile jarFile = null;
                            try {
                                jarFile = new JarFile(art.getFile(), false, ZipFile.OPEN_READ);

                                Manifest manifest = jarFile.getManifest();
                                if (manifest != null) {
                                    osgiSymbolicName = manifest.getMainAttributes()
                                            .getValue(new Attributes.Name("Bundle-SymbolicName"));
                                }
                            } catch (IOException e) {
                                getLog().info("Unable to read jar manifest from " + art.getFile());
                            } finally {
                                if (jarFile != null) {
                                    try {
                                        jarFile.close();
                                    } catch (IOException e) {
                                        // ignore
                                    }
                                }
                            }
                        }

                        isOsgiBundle = osgiSymbolicName != null;

                        IdeDependency dep = new IdeDependency(art.getGroupId(), art.getArtifactId(),
                                art.getVersion(), art.getClassifier(), useProjectReference(art),
                                Artifact.SCOPE_TEST.equals(art.getScope()),
                                Artifact.SCOPE_SYSTEM.equals(art.getScope()),
                                Artifact.SCOPE_PROVIDED.equals(art.getScope()),
                                art.getArtifactHandler().isAddedToClasspath(), art.getFile(), art.getType(),
                                isOsgiBundle, osgiSymbolicName, dependencyDepth, getProjectNameForArifact(art));
                        // no duplicate entries allowed. System paths can cause this problem.
                        if (!dependencies.contains(dep)) {
                            dependencies.add(dep);
                        }
                    }
                }

                // @todo a final report with the list of
                // missingArtifacts?

            }

            ideDeps = (IdeDependency[]) dependencies.toArray(new IdeDependency[dependencies.size()]);
        } else {
            ideDeps = new IdeDependency[0];
        }
    }

    return ideDeps;
}

From source file:org.apache.tuscany.maven.plugin.eclipse.AbstractIdeSupportMojo.java

License:Apache License

/**
 * Resolve project dependencies. Manual resolution is needed in order to avoid resolution of multiproject artifacts
 * (if projects will be linked each other an installed jar is not needed) and to avoid a failure when a jar is
 * missing.//  w ww .j  ava 2 s. c o m
 *
 * @throws MojoExecutionException if dependencies can't be resolved
 * @return resolved IDE dependencies, with attached jars for non-reactor dependencies
 */
protected IdeDependency[] doDependencyResolution() throws MojoExecutionException {
    if (ideDeps == null) {
        if (resolveDependencies) {
            MavenProject project = getProject();
            Set<String> imported = Collections.emptySet();
            try {
                imported = BundleUtil.getImportedPackages(project.getBasedir());
            } catch (IOException e1) {
                throw new MojoExecutionException(e1.getMessage(), e1);
            }
            ArtifactRepository localRepo = getLocalRepository();

            List deps = getProject().getDependencies();

            // Collect the list of resolved IdeDependencies.
            List dependencies = new ArrayList();

            if (deps != null) {
                Map managedVersions = createManagedVersionMap(getArtifactFactory(), project.getId(),
                        project.getDependencyManagement());

                ArtifactResolutionResult artifactResolutionResult = null;

                try {

                    List listeners = new ArrayList();

                    if (logger.isDebugEnabled()) {
                        listeners.add(new DebugResolutionListener(logger));
                    }

                    listeners.add(new WarningResolutionListener(logger));

                    artifactResolutionResult = artifactCollector.collect(getProjectArtifacts(),
                            project.getArtifact(), managedVersions, localRepo,
                            project.getRemoteArtifactRepositories(), getArtifactMetadataSource(), null,
                            listeners);
                } catch (ArtifactResolutionException e) {
                    getLog().debug(e.getMessage(), e);
                    getLog().error(
                            Messages.getString("AbstractIdeSupportMojo.artifactresolution", new Object[] { //$NON-NLS-1$
                                    e.getGroupId(), e.getArtifactId(), e.getVersion(), e.getMessage() }));

                    // if we are here artifactResolutionResult is null, create a project without dependencies but
                    // don't fail
                    // (this could be a reactor projects, we don't want to fail everything)
                    // Causes MECLIPSE-185. Not sure if it should be handled this way??
                    return new IdeDependency[0];
                }

                // keep track of added reactor projects in order to avoid duplicates
                Set emittedReactorProjectId = new HashSet();

                for (Iterator i = artifactResolutionResult.getArtifactResolutionNodes().iterator(); i
                        .hasNext();) {

                    ResolutionNode node = (ResolutionNode) i.next();
                    int dependencyDepth = node.getDepth();
                    Artifact art = node.getArtifact();
                    // don't resolve jars for reactor projects
                    if (hasToResolveJar(art)) {
                        try {
                            artifactResolver.resolve(art, node.getRemoteRepositories(), localRepository);
                        } catch (ArtifactNotFoundException e) {
                            getLog().debug(e.getMessage(), e);
                            getLog().warn(Messages.getString("AbstractIdeSupportMojo.artifactdownload", //$NON-NLS-1$
                                    new Object[] { e.getGroupId(), e.getArtifactId(), e.getVersion(),
                                            e.getMessage() }));
                        } catch (ArtifactResolutionException e) {
                            getLog().debug(e.getMessage(), e);
                            getLog().warn(Messages.getString("AbstractIdeSupportMojo.artifactresolution", //$NON-NLS-1$
                                    new Object[] { e.getGroupId(), e.getArtifactId(), e.getVersion(),
                                            e.getMessage() }));
                        }
                    }

                    boolean includeArtifact = true;
                    if (getExcludes() != null) {
                        String artifactFullId = art.getGroupId() + ":" + art.getArtifactId();
                        if (getExcludes().contains(artifactFullId)) {
                            getLog().info("excluded: " + artifactFullId);
                            includeArtifact = false;
                        }
                    }

                    if (includeArtifact && (!(getUseProjectReferences() && isAvailableAsAReactorProject(art))
                            || emittedReactorProjectId.add(art.getGroupId() + '-' + art.getArtifactId()))) {

                        // the following doesn't work: art.getArtifactHandler().getPackaging() always returns "jar"
                        // also
                        // if the packaging specified in pom.xml is different.

                        // osgi-bundle packaging is provided by the felix osgi plugin
                        // eclipse-plugin packaging is provided by this eclipse plugin
                        // String packaging = art.getArtifactHandler().getPackaging();
                        // boolean isOsgiBundle = "osgi-bundle".equals( packaging ) || "eclipse-plugin".equals(
                        // packaging );

                        // we need to check the manifest, if "Bundle-SymbolicName" is there the artifact can be
                        // considered
                        // an osgi bundle
                        if ("pom".equals(art.getType())) {
                            continue;
                        }
                        File artifactFile = art.getFile();
                        MavenProject reactorProject = getReactorProject(art);
                        if (reactorProject != null) {
                            artifactFile = reactorProject.getBasedir();
                        }
                        boolean isOsgiBundle = false;
                        String osgiSymbolicName = null;
                        try {
                            osgiSymbolicName = BundleUtil.getBundleSymbolicName(artifactFile);
                        } catch (IOException e) {
                            getLog().error("Unable to read jar manifest from " + artifactFile, e);
                        }
                        isOsgiBundle = osgiSymbolicName != null;

                        IdeDependency dep = new IdeDependency(art.getGroupId(), art.getArtifactId(),
                                art.getVersion(), art.getClassifier(), useProjectReference(art),
                                Artifact.SCOPE_TEST.equals(art.getScope()),
                                Artifact.SCOPE_SYSTEM.equals(art.getScope()),
                                Artifact.SCOPE_PROVIDED.equals(art.getScope()),
                                art.getArtifactHandler().isAddedToClasspath(), art.getFile(), art.getType(),
                                isOsgiBundle, osgiSymbolicName, dependencyDepth, getProjectNameForArifact(art));
                        // no duplicate entries allowed. System paths can cause this problem.
                        if (!dependencies.contains(dep)) {
                            // [rfeng] Do not add compile/provided dependencies
                            if (!(pde && (Artifact.SCOPE_COMPILE.equals(art.getScope())
                                    || Artifact.SCOPE_PROVIDED.equals(art.getScope())))) {
                                dependencies.add(dep);
                            } else {
                                // Check this compile dependency is an OSGi package supplier
                                if (!imported.isEmpty()) {
                                    Set<String> exported = Collections.emptySet();
                                    try {
                                        exported = BundleUtil.getExportedPackages(artifactFile);
                                    } catch (IOException e) {
                                        getLog().error("Unable to read jar manifest from " + art.getFile(), e);
                                    }
                                    boolean matched = false;
                                    for (String p : imported) {
                                        if (exported.contains(p)) {
                                            matched = true;
                                            break;
                                        }
                                    }
                                    if (!matched) {
                                        dependencies.add(dep);
                                    } else {
                                        getLog().debug(
                                                "Compile dependency is skipped as it is added through OSGi dependency: "
                                                        + art);
                                    }
                                } else {
                                    dependencies.add(dep);
                                }
                            }
                        }
                    }

                }

                // @todo a final report with the list of
                // missingArtifacts?

            }

            ideDeps = (IdeDependency[]) dependencies.toArray(new IdeDependency[dependencies.size()]);
        } else {
            ideDeps = new IdeDependency[0];
        }
    }

    return ideDeps;
}

From source file:org.codehaus.mojo.pomtools.helpers.TransitiveDependencyInfo.java

License:Apache License

/** Adds a resolution node to the list. If the artifact version 
 * from the new node differs from the artifact version of the "selectedNode",
 * this object is noted as having conflicting versions.
 * <p>//  www  . j a va  2  s  .  c  o m
 * If the version strings do not match literally,
 * A version range is created and the item being added is
 * tested to see if it's range includes the "selectedNode" version.
 * If so, it is not considered a conflict. 
 * 
 * @param pathNode
 */
public void addResolutionNode(ResolutionNode pathNode) {
    // If the pathNode isn't a direct project dependency, and it is optional, it will
    // never get included into the build so ignore it.
    if (pathNode.getDepth() > 1 && pathNode.getArtifact().isOptional()) {
        return;
    }

    resolutionNodes.add(pathNode);

    if (!StringUtils.equals(selectedNode.getArtifact().getVersion(), pathNode.getArtifact().getVersion())) {
        ModelVersionRange newRange = new ModelVersionRange(pathNode.getArtifact().getVersionRange());

        if (newRange.hasRestrictions()) {
            hasConflicts = hasConflicts || !newRange.containsVersion(selectedNode.getArtifact().getVersion());
        } else {
            // The newly added version isn't a range, so see if it is a snapshot build
            // Snapshots have their fully qualified build numbers appended to them at this point,
            // So 2 different snapshots can have different string equality, but still represent the same version. 
            // If it is a snapshot, then compare the release version of the string to the release version 
            // of the selectedNode.
            VersionInfo selectVersion = new DefaultVersionInfo(selectedNode.getArtifact().getVersion());
            VersionInfo newVersion = new DefaultVersionInfo(pathNode.getArtifact().getVersion());

            if (selectVersion.isParsed() && newVersion.isParsed()) {
                if (selectVersion.isSnapshot() && newVersion.isSnapshot()) {
                    hasConflicts = hasConflicts || !StringUtils.equals(selectVersion.getReleaseVersionString(),
                            newVersion.getReleaseVersionString());
                } else {
                    hasConflicts = true;
                }
            } else {
                hasConflicts = true;
            }
        }
    }
}

From source file:org.universAAL.maven.treebuilder.DependencyTreeBuilder.java

License:Apache License

/**
 * Checks if scope update related to conflict or duplication of two given
 * artifacts (farthest - lower in the subtree, nearest - higher in the
 * subtree) is needed. And if so, updates the scope of nearest artifact to
 * the scope of farthest artifact.//w w  w.  ja v a 2  s.c  om
 * 
 * @param farthest
 *            artifact lower in the subtree (or the one occuring as second
 *            if both artifacts are on the same level of the subtree)
 * @param nearest
 *            artifact higher in the subtree (or the one occuring as first
 *            if both artifacts are on the same level of the subtree).
 * @param listener
 * @return Returns true if scope was updated.
 */
private boolean checkScopeUpdate(final ResolutionNode farthest, final ResolutionNode nearest) {
    boolean updateScope = false;
    Artifact farthestArtifact = farthest.getArtifact();
    Artifact nearestArtifact = nearest.getArtifact();

    /* farthest is runtime and nearest has lower priority, change to runtime */
    if (Artifact.SCOPE_RUNTIME.equals(farthestArtifact.getScope())
            && (Artifact.SCOPE_TEST.equals(nearestArtifact.getScope())
                    || Artifact.SCOPE_PROVIDED.equals(nearestArtifact.getScope()))) {
        updateScope = true;
    }

    /*
     * farthest is compile and nearest is not (has lower priority), change
     * to compile
     */
    if (Artifact.SCOPE_COMPILE.equals(farthestArtifact.getScope())
            && !Artifact.SCOPE_COMPILE.equals(nearestArtifact.getScope())) {
        updateScope = true;
    }

    /*
     * current POM rules all, if nearest is in current pom, do not update
     * its scope
     */
    if (nearest.getDepth() < 2 && updateScope) {
        updateScope = false;
    }

    if (updateScope) {
        // previously we cloned the artifact, but it is more effecient to
        // just update the scope
        // if problems are later discovered that the original object needs
        // its original scope value, cloning may
        // again be appropriate
        nearestArtifact.setScope(farthestArtifact.getScope());
    }

    return updateScope;
}

From source file:org.universAAL.maven.treebuilder.DependencyTreeBuilder.java

License:Apache License

/**
 * The heart of the tree builder. Recursively resolves provided artifact.
 * Output is passed to listeners, passed as argument, which are notified
 * about all dependencies detected in the tree. Resolving of each child node
 * is delegated to resolveChildNode method.
 * //from   www  .  jav a2s.  co  m
 * @param originatingArtifact
 *            Rootnode of recursed subtree.
 * @param node
 *            Current node which is resolved.
 * @param resolvedArtifacts
 *            Map which is used for remembering already resolved artifacts.
 *            Artifacts are indexed by a key which calculation algorithm is
 *            the same as the one present in calculateDepKey method. Thanks
 *            to this map, duplicates and conflicts are detected and
 *            resolved.
 * @param managedVersions
 *            Information about dependency management extracted from the
 *            subtree rootnode - a maven project.
 * @param localRepository
 *            Local maven repository.
 * @param remoteRepositories
 *            Remote repositories provided by maven.
 * @param source
 *            ArtifactMetadataSource provided by maven.
 * @param filter
 *            Filter used for unfiltering artifacts which should not be
 *            included in the dependency tree.
 * @param listener
 *            Listener used for providing the output of the resolve process.
 * @param transitive
 *            If this parameter is false than the children of current node
 *            are not resolved.
 * 
 * @throws CyclicDependencyException
 *             Exception thrown when cyclic dependency detected.
 * @throws ArtifactResolutionException
 *             Exception thrown when a problem with artifact resolution
 *             occurs.
 * @throws OverConstrainedVersionException
 *             Occurs when ranges exclude each other and no valid value
 *             remains.
 * @throws ArtifactMetadataRetrievalException
 *             Error while retrieving repository metadata from the
 *             repository.
 * @throws NoSuchFieldException
 *             Signals that the class doesn't have a field of a specified
 *             name.
 * @throws SecurityException
 *             Thrown by the security manager to indicate a security
 *             violation.
 * @throws IllegalAccessException
 *             When illegal access is performed in the curse of java
 *             reflection operations.
 * @throws IllegalArgumentException
 *             Thrown to indicate that an illegal or inappropriate argument
 *             has been passed.
 */
private void recurse(final Artifact originatingArtifact, final ResolutionNode node, final Map resolvedArtifacts,
        final ManagedVersionMap managedVersions, final ArtifactRepository localRepository,
        final List remoteRepositories, final ArtifactMetadataSource source, final ArtifactFilter filter,
        final DependencyTreeResolutionListener listener, final boolean transitive,
        final Set<String> separatedGroupIds) throws CyclicDependencyException, ArtifactResolutionException,
        OverConstrainedVersionException, ArtifactMetadataRetrievalException, SecurityException,
        NoSuchFieldException, IllegalArgumentException, IllegalAccessException {
    try {

        fireEvent(ResolutionListener.TEST_ARTIFACT, listener, node);
        Object key = node.getKey();

        // TODO: Does this check need to happen here? Had to add the same
        // call
        // below when we iterate on child nodes -- will that suffice?
        if (managedVersions.containsKey(key)) {
            manageArtifact(node, managedVersions);
        }

        List previousNodes = (List) resolvedArtifacts.get(key);
        if (previousNodes != null) {
            for (Iterator i = previousNodes.iterator(); i.hasNext();) {
                ResolutionNode previous = (ResolutionNode) i.next();

                if (previous.isActive()) {
                    // Version mediation
                    VersionRange previousRange = previous.getArtifact().getVersionRange();
                    VersionRange currentRange = node.getArtifact().getVersionRange();

                    if (previousRange != null && currentRange != null) {
                        // TODO: shouldn't need to double up on this work,
                        // only
                        // done for simplicity of handling recommended
                        // version but the restriction is identical
                        VersionRange newRange = previousRange.restrict(currentRange);
                        // TODO: ick. this forces the OCE that should have
                        // come
                        // from the previous call. It is still correct
                        if (newRange.isSelectedVersionKnown(previous.getArtifact())) {
                            fireEvent(ResolutionListener.RESTRICT_RANGE, listener, node, previous, newRange);
                        }
                        previous.getArtifact().setVersionRange(newRange);
                        node.getArtifact().setVersionRange(currentRange.restrict(previousRange));

                        // Select an appropriate available version from the
                        // (now
                        // restricted) range
                        // Note this version was selected before to get the
                        // appropriate POM
                        // But it was reset by the call to setVersionRange
                        // on
                        // restricting the version
                        ResolutionNode[] resetNodes = { previous, node };
                        for (int j = 0; j < 2; j++) {
                            Artifact resetArtifact = resetNodes[j].getArtifact();

                            // MNG-2123: if the previous node was not a
                            // range,
                            // then it wouldn't have any available
                            // versions. We just clobbered the selected
                            // version
                            // above. (why? i have no idea.)
                            // So since we are here and this is ranges we
                            // must
                            // go figure out the version (for a third
                            // time...)
                            if (resetArtifact.getVersion() == null && resetArtifact.getVersionRange() != null) {

                                // go find the version. This is a total
                                // hack.
                                // See previous comment.
                                List versions = resetArtifact.getAvailableVersions();
                                if (versions == null) {
                                    try {
                                        versions = source.retrieveAvailableVersions(resetArtifact,
                                                localRepository, remoteRepositories);
                                        resetArtifact.setAvailableVersions(versions);
                                    } catch (ArtifactMetadataRetrievalException e) {
                                        resetArtifact.setDependencyTrail(node.getDependencyTrail());
                                        throw e;
                                    }
                                }
                                // end hack

                                // MNG-2861: match version can return null
                                ArtifactVersion selectedVersion = resetArtifact.getVersionRange()
                                        .matchVersion(resetArtifact.getAvailableVersions());
                                if (selectedVersion != null) {
                                    resetArtifact.selectVersion(selectedVersion.toString());
                                } else {
                                    throw new OverConstrainedVersionException(
                                            " Unable to find a version in "
                                                    + resetArtifact.getAvailableVersions()
                                                    + " to match the range " + resetArtifact.getVersionRange(),
                                            resetArtifact);
                                }
                                fireEvent(ResolutionListener.SELECT_VERSION_FROM_RANGE, listener,
                                        resetNodes[j]);
                            }
                        }
                    }

                    // Conflict Resolution
                    // TODO: use as conflict resolver(s), chain

                    // TODO: should this be part of mediation?
                    // previous one is more dominant
                    ResolutionNode nearest;
                    ResolutionNode farthest;
                    if (previous.getDepth() <= node.getDepth()) {
                        nearest = previous;
                        farthest = node;
                    } else {
                        nearest = node;
                        farthest = previous;
                    }

                    if (checkScopeUpdate(farthest, nearest)) {
                        // if we need to update scope of nearest to use
                        // farthest
                        // scope, use the nearest version, but farthest
                        // scope
                        nearest.disable();
                        farthest.getArtifact().setVersion(nearest.getArtifact().getVersion());
                        fireEvent(ResolutionListener.OMIT_FOR_NEARER, listener, nearest, farthest);
                    } else {
                        farthest.disable();
                        fireEvent(ResolutionListener.OMIT_FOR_NEARER, listener, farthest, nearest);
                    }
                }
            }
        } else {
            previousNodes = new ArrayList();
            resolvedArtifacts.put(key, previousNodes);
        }
        previousNodes.add(node);

        if (node.isActive()) {
            fireEvent(ResolutionListener.INCLUDE_ARTIFACT, listener, node);
        }

        // don't pull in the transitive deps of a system-scoped dependency.
        if (node.isActive() && !Artifact.SCOPE_SYSTEM.equals(node.getArtifact().getScope())) {
            fireEvent(ResolutionListener.PROCESS_CHILDREN, listener, node);
            if (transitive) {
                Artifact parentArtifact = node.getArtifact();
                for (Iterator i = node.getChildrenIterator(); i.hasNext();) {
                    ResolutionNode child = (ResolutionNode) i.next();
                    if (!filter.include(child.getArtifact())) {
                        continue;
                    }
                    /*
                     * rotgier: In case of regular dependencies provided
                     * scope is simply ignored (artifact versions specified
                     * there conflict with the ones of runtime deps)
                     */
                    if (Artifact.SCOPE_PROVIDED.equals(child.getArtifact().getScope())) {
                        continue;
                    }
                    changeArtifactCoreToOsgi(node, child, separatedGroupIds, listener);
                    boolean isContinue = resolveChildNode(node, child, filter, managedVersions, listener,
                            source, parentArtifact);
                    if (isContinue) {
                        continue;
                    }
                    List<String> extractedSeparatedGroupIds = extractSeparatedGroupIds(child.getArtifact(),
                            remoteRepositories);
                    Set<String> combinedSeparatedGroupIds = new HashSet<String>(separatedGroupIds);
                    combinedSeparatedGroupIds.addAll(extractedSeparatedGroupIds);
                    recurse(originatingArtifact, child, resolvedArtifacts, managedVersions, localRepository,
                            child.getRemoteRepositories(), source, filter, listener, true,
                            combinedSeparatedGroupIds);
                }
                List runtimeDeps = getRuntimeDeps(node.getArtifact(), managedVersions, remoteRepositories);
                Field childrenField = node.getClass().getDeclaredField("children");
                childrenField.setAccessible(true);
                List nodesChildren = (List) childrenField.get(node);
                /* nodesChildren can be empty when dealing with parent POMs */
                if (nodesChildren == Collections.EMPTY_LIST) {
                    nodesChildren = new ArrayList();
                    childrenField.set(node, nodesChildren);
                }
                for (Object runtimeDepObj : runtimeDeps) {
                    DependencyNode runtimeDep = (DependencyNode) runtimeDepObj;
                    Artifact artifact = runtimeDep.getArtifact();
                    ResolutionNode childRuntime = new ResolutionNode(artifact, node.getRemoteRepositories(),
                            node);
                    /*
                     * rotgier: In case of runtime dependencies provided
                     * scope should be allowed
                     */
                    if (!filter.include(childRuntime.getArtifact())) {

                        if (!Artifact.SCOPE_PROVIDED.equals(artifact.getScope())) {
                            continue;
                        }
                    }
                    changeArtifactCoreToOsgi(node, childRuntime, separatedGroupIds, listener);
                    boolean isContinue = resolveChildNode(node, childRuntime, filter, managedVersions, listener,
                            source, parentArtifact);
                    if (isContinue) {
                        continue;
                    }
                    List<String> extractedSeparatedGroupIds = extractSeparatedGroupIds(
                            childRuntime.getArtifact(), remoteRepositories);
                    Set<String> combinedSeparatedGroupIds = new HashSet<String>(separatedGroupIds);
                    combinedSeparatedGroupIds.addAll(extractedSeparatedGroupIds);
                    recurse(originatingArtifact, childRuntime, resolvedArtifacts, managedVersions,
                            localRepository, childRuntime.getRemoteRepositories(), source, filter, listener,
                            true, combinedSeparatedGroupIds);
                    nodesChildren.add(childRuntime);
                }
            }
            fireEvent(ResolutionListener.FINISH_PROCESSING_CHILDREN, listener, node);
        }
    } catch (Exception ex) {
        StringBuilder msg = new StringBuilder();
        msg.append(String.format("\nUnpredicted exception during dependency tree recursion at node %s",
                FilteringVisitorSupport.stringify(node.getArtifact())));
        msg.append("\nNode's parent tree:\n");
        msg.append(printNodeParentsTree(node));
        throw new IllegalStateException(msg.toString(), ex);
    }
}