You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@servicemix.apache.org by js...@apache.org on 2008/03/14 18:17:09 UTC

svn commit: r637166 - in /servicemix/smx4/kernel/trunk/testing: ./ features-maven-plugin/ features-maven-plugin/src/ features-maven-plugin/src/main/ features-maven-plugin/src/main/java/ features-maven-plugin/src/main/java/org/ features-maven-plugin/src...

Author: jstrachan
Date: Fri Mar 14 10:17:06 2008
New Revision: 637166

URL: http://svn.apache.org/viewvc?rev=637166&view=rev
Log:
added a simple maven plugin to generate the features.xml file for a pom

Added:
    servicemix/smx4/kernel/trunk/testing/features-maven-plugin/
    servicemix/smx4/kernel/trunk/testing/features-maven-plugin/pom.xml   (with props)
    servicemix/smx4/kernel/trunk/testing/features-maven-plugin/src/
    servicemix/smx4/kernel/trunk/testing/features-maven-plugin/src/main/
    servicemix/smx4/kernel/trunk/testing/features-maven-plugin/src/main/java/
    servicemix/smx4/kernel/trunk/testing/features-maven-plugin/src/main/java/org/
    servicemix/smx4/kernel/trunk/testing/features-maven-plugin/src/main/java/org/apache/
    servicemix/smx4/kernel/trunk/testing/features-maven-plugin/src/main/java/org/apache/servicemix/
    servicemix/smx4/kernel/trunk/testing/features-maven-plugin/src/main/java/org/apache/servicemix/tooling/
    servicemix/smx4/kernel/trunk/testing/features-maven-plugin/src/main/java/org/apache/servicemix/tooling/features/
    servicemix/smx4/kernel/trunk/testing/features-maven-plugin/src/main/java/org/apache/servicemix/tooling/features/GenerateDependsFileMojo.java   (with props)
    servicemix/smx4/kernel/trunk/testing/features-maven-plugin/src/main/java/org/apache/servicemix/tooling/features/GenerateFeaturesFileMojo.java   (with props)
    servicemix/smx4/kernel/trunk/testing/features-maven-plugin/src/main/java/org/apache/servicemix/tooling/features/GraphArtifactCollector.java   (with props)
    servicemix/smx4/kernel/trunk/testing/features-maven-plugin/src/main/java/org/apache/servicemix/tooling/features/MojoSupport.java   (with props)
    servicemix/smx4/kernel/trunk/testing/features-maven-plugin/src/main/java/org/apache/servicemix/tooling/features/Node.java   (with props)
    servicemix/smx4/kernel/trunk/testing/features-maven-plugin/src/main/java/org/apache/servicemix/tooling/features/ResolutionListenerImpl.java   (with props)
Modified:
    servicemix/smx4/kernel/trunk/testing/pom.xml

Added: servicemix/smx4/kernel/trunk/testing/features-maven-plugin/pom.xml
URL: http://svn.apache.org/viewvc/servicemix/smx4/kernel/trunk/testing/features-maven-plugin/pom.xml?rev=637166&view=auto
==============================================================================
--- servicemix/smx4/kernel/trunk/testing/features-maven-plugin/pom.xml (added)
+++ servicemix/smx4/kernel/trunk/testing/features-maven-plugin/pom.xml Fri Mar 14 10:17:06 2008
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+    <!--
+
+        Licensed to the Apache Software Foundation (ASF) under one or more
+        contributor license agreements.  See the NOTICE file distributed with
+        this work for additional information regarding copyright ownership.
+        The ASF licenses this file to You under the Apache License, Version 2.0
+        (the "License"); you may not use this file except in compliance with
+        the License.  You may obtain a copy of the License at
+
+           http://www.apache.org/licenses/LICENSE-2.0
+
+        Unless required by applicable law or agreed to in writing, software
+        distributed under the License is distributed on an "AS IS" BASIS,
+        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+        See the License for the specific language governing permissions and
+        limitations under the License.
+    -->
+
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.apache.servicemix.kernel.testing</groupId>
+        <artifactId>testing</artifactId>
+        <version>1.0-m3-SNAPSHOT</version>
+    </parent>
+
+    <groupId>org.apache.servicemix.kernel.testing</groupId>
+    <artifactId>features-maven-plugin</artifactId>
+    <packaging>maven-plugin</packaging>
+    <version>1.0-m3-SNAPSHOT</version>
+    <name>ServiceMix Kernel :: Testing - Features plugin</name>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.maven</groupId>
+            <artifactId>maven-plugin-api</artifactId>
+            <version>2.0.8</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.maven</groupId>
+            <artifactId>maven-project</artifactId>
+            <version>2.0.8</version>
+        </dependency>
+    </dependencies>
+
+</project>

Propchange: servicemix/smx4/kernel/trunk/testing/features-maven-plugin/pom.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Added: servicemix/smx4/kernel/trunk/testing/features-maven-plugin/src/main/java/org/apache/servicemix/tooling/features/GenerateDependsFileMojo.java
URL: http://svn.apache.org/viewvc/servicemix/smx4/kernel/trunk/testing/features-maven-plugin/src/main/java/org/apache/servicemix/tooling/features/GenerateDependsFileMojo.java?rev=637166&view=auto
==============================================================================
--- servicemix/smx4/kernel/trunk/testing/features-maven-plugin/src/main/java/org/apache/servicemix/tooling/features/GenerateDependsFileMojo.java (added)
+++ servicemix/smx4/kernel/trunk/testing/features-maven-plugin/src/main/java/org/apache/servicemix/tooling/features/GenerateDependsFileMojo.java Fri Mar 14 10:17:06 2008
@@ -0,0 +1,106 @@
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.servicemix.tooling.features;
+
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.util.Date;
+import java.util.Iterator;
+
+import org.apache.maven.model.Dependency;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+
+/**
+ * Generates the dependencies properties file
+ *
+ * @version $Revision: 1.1 $
+ * @goal generate-depends-file
+ * @phase generate-resources
+ * @requiresDependencyResolution runtime
+ * @description Generates the dependencies properties file
+ */
+public class GenerateDependsFileMojo extends MojoSupport {
+
+    protected static final String SEPARATOR = "/";
+
+    /**
+     * The file to generate
+     *
+     * @parameter default-value="${project.build.directory}/classes/META-INF/maven/dependencies.properties"
+     */
+
+    private File outputFile;
+
+    public void execute() throws MojoExecutionException, MojoFailureException {
+        OutputStream out = null;
+        try {
+            outputFile.getParentFile().mkdirs();
+            out = new FileOutputStream(outputFile);
+            PrintStream printer = new PrintStream(out);
+            populateProperties(printer);
+            getLog().info("Created: " + outputFile);
+
+        } catch (Exception e) {
+            throw new MojoExecutionException(
+                    "Unable to create dependencies file: " + e, e);
+        } finally {
+            if (out != null) {
+                try {
+                    out.close();
+                } catch (IOException e) {
+                    getLog().info("Failed to close: " + outputFile + ". Reason: " + e, e);
+                }
+            }
+        }
+    }
+
+    protected void populateProperties(PrintStream out) {
+        out.println("# Project dependencies generated by the Apache ServiceMix Maven Plugin");
+        out.println("# Generated at: " + new Date());
+        out.println();
+
+        out.println("groupId = " + project.getGroupId());
+        out.println("artifactId = " + project.getArtifactId());
+        out.println("version = " + project.getVersion());
+        out.println(project.getGroupId() + SEPARATOR + project.getArtifactId() + SEPARATOR + "version = " + project.getVersion());
+        out.println();
+        out.println("# dependencies");
+        out.println();
+
+        Iterator iterator = project.getDependencies().iterator();
+        while (iterator.hasNext()) {
+            Dependency dependency = (Dependency) iterator.next();
+            String prefix = dependency.getGroupId() + SEPARATOR + dependency.getArtifactId() + SEPARATOR;
+            out.println(prefix + "version = " + dependency.getVersion());
+            String classifier = dependency.getClassifier();
+            if (classifier != null) {
+                out.println(prefix + "classifier = " + classifier);
+            }
+            out.println(prefix + "type = " + dependency.getType());
+            out.println(prefix + "scope = " + dependency.getScope());
+            out.println();
+
+            getLog().debug("Dependency: " + dependency + " classifier: " + classifier + " type: " + dependency.getType());
+        }
+    }
+}
\ No newline at end of file

Propchange: servicemix/smx4/kernel/trunk/testing/features-maven-plugin/src/main/java/org/apache/servicemix/tooling/features/GenerateDependsFileMojo.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: servicemix/smx4/kernel/trunk/testing/features-maven-plugin/src/main/java/org/apache/servicemix/tooling/features/GenerateFeaturesFileMojo.java
URL: http://svn.apache.org/viewvc/servicemix/smx4/kernel/trunk/testing/features-maven-plugin/src/main/java/org/apache/servicemix/tooling/features/GenerateFeaturesFileMojo.java?rev=637166&view=auto
==============================================================================
--- servicemix/smx4/kernel/trunk/testing/features-maven-plugin/src/main/java/org/apache/servicemix/tooling/features/GenerateFeaturesFileMojo.java (added)
+++ servicemix/smx4/kernel/trunk/testing/features-maven-plugin/src/main/java/org/apache/servicemix/tooling/features/GenerateFeaturesFileMojo.java Fri Mar 14 10:17:06 2008
@@ -0,0 +1,118 @@
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.servicemix.tooling.features;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.util.Iterator;
+
+import org.apache.maven.model.Dependency;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+
+/**
+ * Generates the features XML file
+ *
+ * @version $Revision: 1.1 $
+ * @goal generate-features-file
+ * @phase generate-resources
+ * @requiresDependencyResolution runtime
+ * @description Generates the features XML file
+ */
+public class GenerateFeaturesFileMojo extends MojoSupport {
+    protected static final String SEPARATOR = "/";
+    /**
+     * The file to generate
+     *
+     * @parameter default-value="${project.build.directory}/classes/feature.xml"
+     */
+    private File outputFile;
+    /**
+     * The name of the feature, which defaults to the artifact ID if its not specified
+     *
+     * @parameter default-value="${project.artifactId}"
+     */
+    private String featureName;
+
+    public void execute() throws MojoExecutionException, MojoFailureException {
+        OutputStream out = null;
+        try {
+            outputFile.getParentFile().mkdirs();
+            out = new FileOutputStream(outputFile);
+            PrintStream printer = new PrintStream(out);
+            populateProperties(printer);
+            getLog().info("Created: " + outputFile);
+        }
+        catch (Exception e) {
+            throw new MojoExecutionException(
+                    "Unable to create dependencies file: " + e, e);
+        }
+        finally {
+            if (out != null) {
+                try {
+                    out.close();
+                }
+                catch (IOException e) {
+                    getLog().info("Failed to close: " + outputFile + ". Reason: " + e, e);
+                }
+            }
+        }
+    }
+
+    protected void populateProperties(PrintStream out) {
+        out.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
+        out.println("<features>");
+        out.println("  <feature name='" + featureName + "'>");
+
+
+        writeBundle(out, project.getGroupId(), project.getArtifactId(), project.getVersion());
+        out.println();
+
+        Iterator iterator = project.getDependencies().iterator();
+        while (iterator.hasNext()) {
+            Dependency dependency = (Dependency) iterator.next();
+
+            if (isValidDependency(dependency)) {
+                out.print("  ");
+                writeBundle(out, dependency.getGroupId(), dependency.getArtifactId(), dependency.getVersion());
+            }
+        }
+
+        out.println("  </feature>");
+        out.println("</features>");
+    }
+
+    protected boolean isValidDependency(Dependency dependency) {
+        // TODO filter out only compile time dependencies which are OSGi bundles?
+        return true;
+    }
+
+    protected void writeBundle(PrintStream out, String groupId, String artifactId, String version) {
+        out.print("  <bundle>mvn:");
+        out.print(groupId);
+        out.print("/");
+        out.print(artifactId);
+        out.print("/");
+        out.print(version);
+        out.print("</bundle>");
+        out.println();
+    }
+}
\ No newline at end of file

Propchange: servicemix/smx4/kernel/trunk/testing/features-maven-plugin/src/main/java/org/apache/servicemix/tooling/features/GenerateFeaturesFileMojo.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: servicemix/smx4/kernel/trunk/testing/features-maven-plugin/src/main/java/org/apache/servicemix/tooling/features/GraphArtifactCollector.java
URL: http://svn.apache.org/viewvc/servicemix/smx4/kernel/trunk/testing/features-maven-plugin/src/main/java/org/apache/servicemix/tooling/features/GraphArtifactCollector.java?rev=637166&view=auto
==============================================================================
--- servicemix/smx4/kernel/trunk/testing/features-maven-plugin/src/main/java/org/apache/servicemix/tooling/features/GraphArtifactCollector.java (added)
+++ servicemix/smx4/kernel/trunk/testing/features-maven-plugin/src/main/java/org/apache/servicemix/tooling/features/GraphArtifactCollector.java Fri Mar 14 10:17:06 2008
@@ -0,0 +1,435 @@
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.servicemix.tooling.features;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.metadata.ArtifactMetadataRetrievalException;
+import org.apache.maven.artifact.metadata.ArtifactMetadataSource;
+import org.apache.maven.artifact.metadata.ResolutionGroup;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.artifact.resolver.ArtifactCollector;
+import org.apache.maven.artifact.resolver.ArtifactResolutionException;
+import org.apache.maven.artifact.resolver.ArtifactResolutionResult;
+import org.apache.maven.artifact.resolver.CyclicDependencyException;
+import org.apache.maven.artifact.resolver.ResolutionListener;
+import org.apache.maven.artifact.resolver.ResolutionNode;
+import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
+import org.apache.maven.artifact.versioning.ArtifactVersion;
+import org.apache.maven.artifact.versioning.OverConstrainedVersionException;
+import org.apache.maven.artifact.versioning.VersionRange;
+
+/**
+ * @version $Revision: 1.1 $
+ */
+public class GraphArtifactCollector implements ArtifactCollector {
+    public ArtifactResolutionResult collect(
+            Set artifacts,
+            Artifact originatingArtifact,
+            ArtifactRepository localRepository,
+            List remoteRepositories,
+            ArtifactMetadataSource source,
+            ArtifactFilter filter,
+            List listeners) throws ArtifactResolutionException {
+        return collect(artifacts, originatingArtifact, Collections.EMPTY_MAP,
+                localRepository, remoteRepositories, source, filter, listeners);
+    }
+
+    public ArtifactResolutionResult collect(
+            Set artifacts,
+            Artifact originatingArtifact,
+            Map managedVersions,
+            ArtifactRepository localRepository,
+            List remoteRepositories,
+            ArtifactMetadataSource source,
+            ArtifactFilter filter,
+            List listeners) throws ArtifactResolutionException {
+        Map resolvedArtifacts = new HashMap();
+
+        ResolutionNode root = new ResolutionNode(originatingArtifact, remoteRepositories);
+        root.addDependencies(artifacts, remoteRepositories, filter);
+        recurse(root, resolvedArtifacts, managedVersions, localRepository,
+                remoteRepositories, source, filter, listeners);
+
+        Set set = new HashSet();
+        for (Iterator i = resolvedArtifacts.values().iterator(); i.hasNext();) {
+            List nodes = (List) i.next();
+            for (Iterator j = nodes.iterator(); j.hasNext();) {
+                ResolutionNode node = (ResolutionNode) j.next();
+                Artifact artifact = node.getArtifact();
+                if (!node.equals(root) && node.isActive() && node.filterTrail(filter)
+                        // If it was optional and not a direct dependency,
+                        // we don't add it or its children, just allow the
+                        // update of the version and scope
+                        && (node.isChildOfRootNode() || !artifact.isOptional())) {
+                    artifact.setDependencyTrail(node.getDependencyTrail());
+                    set.add(node);
+                }
+            }
+        }
+
+        ArtifactResolutionResult result = new ArtifactResolutionResult();
+        result.setArtifactResolutionNodes(set);
+        return result;
+    }
+
+    private void recurse(
+            ResolutionNode node,
+            Map resolvedArtifacts,
+            Map managedVersions,
+            ArtifactRepository localRepository,
+            List remoteRepositories,
+            ArtifactMetadataSource source,
+            ArtifactFilter filter,
+            List listeners) throws CyclicDependencyException, ArtifactResolutionException,
+            OverConstrainedVersionException {
+        fireEvent(ResolutionListener.TEST_ARTIFACT, listeners, node);
+
+        // TODO: use as a conflict resolver
+        Object key = node.getKey();
+        if (managedVersions.containsKey(key)) {
+            Artifact artifact = (Artifact) managedVersions.get(key);
+            fireEvent(ResolutionListener.MANAGE_ARTIFACT, listeners, node, artifact);
+            if (artifact.getVersion() != null) {
+                node.getArtifact().setVersion(artifact.getVersion());
+            }
+            if (artifact.getScope() != null) {
+                node.getArtifact().setScope(artifact.getScope());
+            }
+        }
+
+        List previousNodes = (List) resolvedArtifacts.get(key);
+        if (previousNodes != null) {
+            node = checkPreviousNodes(node, listeners, previousNodes);
+        }
+        else {
+            previousNodes = new ArrayList();
+            resolvedArtifacts.put(key, previousNodes);
+        }
+        previousNodes.add(node);
+
+        if (node.isActive()) {
+            fireEvent(ResolutionListener.INCLUDE_ARTIFACT, listeners, 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, listeners, node);
+            for (Iterator i = node.getChildrenIterator(); i.hasNext();) {
+                ResolutionNode child = (ResolutionNode) i.next();
+                // We leave in optional ones, but don't pick up its dependencies
+                if (!child.isResolved()
+                        && (!child.getArtifact().isOptional() || child.isChildOfRootNode())) {
+                    Artifact artifact = child.getArtifact();
+                    try {
+                        if (artifact.getVersion() == null) {
+                            // set the recommended version
+                            // TODO: maybe its better to just pass the range
+                            // through to retrieval and use a transformation?
+                            ArtifactVersion version;
+                            version = getArtifactVersion(localRepository, remoteRepositories, source, artifact);
+
+                            artifact.selectVersion(version.toString());
+                            fireEvent(ResolutionListener.SELECT_VERSION_FROM_RANGE,
+                                    listeners, child);
+                        }
+
+                        ResolutionGroup rGroup = source.retrieve(artifact,
+                                localRepository, remoteRepositories);
+
+                        // TODO might be better to have source.retreive() throw
+                        // a specific exception for this situation
+                        // and catch here rather than have it return null
+                        if (rGroup == null) {
+                            // relocated dependency artifact is declared
+                            // excluded, no need to add and recurse further
+                            continue;
+                        }
+
+                        child.addDependencies(rGroup.getArtifacts(),
+                                rGroup.getResolutionRepositories(), filter);
+                    }
+                    catch (CyclicDependencyException e) {
+                        // would like to throw this, but we have crappy stuff in
+                        // the repo
+
+                        fireEvent(ResolutionListener.OMIT_FOR_CYCLE, listeners,
+                                new ResolutionNode(e.getArtifact(), remoteRepositories, child));
+                    }
+                    catch (ArtifactMetadataRetrievalException e) {
+                        artifact.setDependencyTrail(node.getDependencyTrail());
+                        throw new ArtifactResolutionException(
+                                "Unable to get dependency information: "
+                                        + e.getMessage(), artifact, e);
+                    }
+
+                    recurse(child, resolvedArtifacts, managedVersions,
+                            localRepository, remoteRepositories, source,
+                            filter, listeners);
+                }
+            }
+            fireEvent(ResolutionListener.FINISH_PROCESSING_CHILDREN, listeners,
+                    node);
+        }
+    }
+
+    private ArtifactVersion getArtifactVersion(
+            ArtifactRepository localRepository,
+            List remoteRepositories,
+            ArtifactMetadataSource source,
+            Artifact artifact) throws OverConstrainedVersionException,
+            ArtifactMetadataRetrievalException {
+        ArtifactVersion version;
+        if (!artifact.isSelectedVersionKnown()) {
+            List versions = artifact.getAvailableVersions();
+            if (versions == null) {
+                versions = source.retrieveAvailableVersions(
+                        artifact, localRepository,
+                        remoteRepositories);
+                artifact.setAvailableVersions(versions);
+            }
+
+            VersionRange versionRange = artifact.getVersionRange();
+
+            version = versionRange.matchVersion(versions);
+
+            if (version == null) {
+                if (versions.isEmpty()) {
+                    throw new OverConstrainedVersionException(
+                            "No versions are present in the repository for the artifact with a range "
+                                    + versionRange, artifact, remoteRepositories);
+                }
+                else {
+                    throw new OverConstrainedVersionException(
+                            "Couldn't find a version in "
+                                    + versions
+                                    + " to match range "
+                                    + versionRange,
+                            artifact, remoteRepositories);
+                }
+            }
+        }
+        else {
+            version = artifact.getSelectedVersion();
+        }
+        return version;
+    }
+
+    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);
+                    }
+                    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;
+    }
+
+    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;
+        }
+
+        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());
+        }
+    }
+
+    private void fireEvent(int event, List listeners, ResolutionNode node) {
+        fireEvent(event, listeners, node, null);
+    }
+
+    private void fireEvent(int event, List listeners, ResolutionNode node,
+            Artifact replacement) {
+        fireEvent(event, listeners, node, replacement, null);
+    }
+
+    private void fireEvent(int event, List listeners, ResolutionNode node,
+            Artifact replacement, VersionRange newRange) {
+        for (Iterator i = listeners.iterator(); i.hasNext();) {
+            ResolutionListener listener = (ResolutionListener) i.next();
+
+            switch (event) {
+                case ResolutionListener.TEST_ARTIFACT:
+                    listener.testArtifact(node.getArtifact());
+                    break;
+                case ResolutionListener.PROCESS_CHILDREN:
+                    listener.startProcessChildren(node.getArtifact());
+                    break;
+                case ResolutionListener.FINISH_PROCESSING_CHILDREN:
+                    listener.endProcessChildren(node.getArtifact());
+                    break;
+                case ResolutionListener.INCLUDE_ARTIFACT:
+                    listener.includeArtifact(node.getArtifact());
+                    break;
+                case ResolutionListener.OMIT_FOR_NEARER:
+                    String version = node.getArtifact().getVersion();
+                    String replacementVersion = replacement.getVersion();
+                    if (version != null ? !version.equals(replacementVersion)
+                            : replacementVersion != null) {
+                        listener.omitForNearer(node.getArtifact(), replacement);
+                    }
+                    break;
+                case ResolutionListener.OMIT_FOR_CYCLE:
+                    listener.omitForCycle(node.getArtifact());
+                    break;
+                case ResolutionListener.UPDATE_SCOPE:
+                    listener
+                            .updateScope(node.getArtifact(), replacement.getScope());
+                    break;
+                case ResolutionListener.UPDATE_SCOPE_CURRENT_POM:
+                    listener.updateScopeCurrentPom(node.getArtifact(), replacement
+                            .getScope());
+                    break;
+                case ResolutionListener.MANAGE_ARTIFACT:
+                    listener.manageArtifact(node.getArtifact(), replacement);
+                    break;
+                case ResolutionListener.SELECT_VERSION_FROM_RANGE:
+                    listener.selectVersionFromRange(node.getArtifact());
+                    break;
+                case ResolutionListener.RESTRICT_RANGE:
+                    if (node.getArtifact().getVersionRange().hasRestrictions()
+                            || replacement.getVersionRange().hasRestrictions()) {
+                        listener.restrictRange(node.getArtifact(), replacement,
+                                newRange);
+                    }
+                    break;
+                default:
+                    throw new IllegalStateException("Unknown event: " + event);
+            }
+        }
+    }
+}

Propchange: servicemix/smx4/kernel/trunk/testing/features-maven-plugin/src/main/java/org/apache/servicemix/tooling/features/GraphArtifactCollector.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: servicemix/smx4/kernel/trunk/testing/features-maven-plugin/src/main/java/org/apache/servicemix/tooling/features/MojoSupport.java
URL: http://svn.apache.org/viewvc/servicemix/smx4/kernel/trunk/testing/features-maven-plugin/src/main/java/org/apache/servicemix/tooling/features/MojoSupport.java?rev=637166&view=auto
==============================================================================
--- servicemix/smx4/kernel/trunk/testing/features-maven-plugin/src/main/java/org/apache/servicemix/tooling/features/MojoSupport.java (added)
+++ servicemix/smx4/kernel/trunk/testing/features-maven-plugin/src/main/java/org/apache/servicemix/tooling/features/MojoSupport.java Fri Mar 14 10:17:06 2008
@@ -0,0 +1,299 @@
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.servicemix.tooling.features;
+
+
+import java.io.File;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.factory.ArtifactFactory;
+import org.apache.maven.artifact.metadata.ArtifactMetadataSource;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.artifact.resolver.ArtifactCollector;
+import org.apache.maven.artifact.resolver.ArtifactResolutionException;
+import org.apache.maven.artifact.resolver.ArtifactResolver;
+import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException;
+import org.apache.maven.artifact.versioning.VersionRange;
+import org.apache.maven.model.Dependency;
+import org.apache.maven.model.DependencyManagement;
+import org.apache.maven.plugin.AbstractMojo;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.project.MavenProject;
+import org.apache.maven.project.MavenProjectBuilder;
+import org.apache.maven.project.MavenProjectHelper;
+import org.apache.maven.project.ProjectBuildingException;
+
+/**
+ * @version $Revision: 1.1 $
+ */
+public abstract class MojoSupport extends AbstractMojo {
+
+    /**
+     * Maven ProjectHelper
+     *
+     * @component
+     */
+    protected MavenProjectHelper projectHelper;
+
+    /**
+     * The maven project.
+     *
+     * @parameter expression="${project}"
+     * @required
+     * @readonly
+     */
+    protected MavenProject project;
+
+    /**
+     * Directory that resources are copied to during the build.
+     *
+     * @parameter expression="${project.build.directory}/${project.artifactId}-${project.version}-installer"
+     * @required
+     */
+    protected File workDirectory;
+
+    /**
+     * @component
+     */
+    protected MavenProjectBuilder projectBuilder;
+
+    /**
+     * @parameter default-value="${localRepository}"
+     */
+    protected ArtifactRepository localRepo;
+
+    /**
+     * @parameter default-value="${project.remoteArtifactRepositories}"
+     */
+    protected List remoteRepos;
+
+    /**
+     * @component
+     */
+    protected ArtifactMetadataSource artifactMetadataSource;
+
+    /**
+     * @component
+     */
+    protected ArtifactResolver resolver;
+
+    protected ArtifactCollector collector = new GraphArtifactCollector();
+
+    /**
+     * @component
+     */
+    protected ArtifactFactory factory;
+
+    protected MavenProject getProject() {
+        return project;
+    }
+
+    protected File getWorkDirectory() {
+        return workDirectory;
+    }
+
+    public MavenProjectHelper getProjectHelper() {
+        return projectHelper;
+    }
+
+    protected void removeBranch(ResolutionListenerImpl listener,
+            Artifact artifact) {
+        Node n = listener.getNode(artifact);
+        if (n != null) {
+            for (Iterator it = n.getParents().iterator(); it.hasNext();) {
+                Node parent = (Node) it.next();
+                parent.getChildren().remove(n);
+            }
+        }
+    }
+
+    protected void removeChildren(ResolutionListenerImpl listener,
+            Artifact artifact) {
+        Node n = listener.getNode(artifact);
+        n.getChildren().clear();
+    }
+
+    protected Set getArtifacts(Node n, Set s) {
+        if (!s.contains(n.getArtifact())) {
+            s.add(n.getArtifact());
+            for (Iterator iter = n.getChildren().iterator(); iter.hasNext();) {
+                Node c = (Node) iter.next();
+                getArtifacts(c, s);
+            }
+        }
+        return s;
+    }
+
+    protected void excludeBranch(Node n, Set excludes) {
+        excludes.add(n);
+        for (Iterator iter = n.getChildren().iterator(); iter.hasNext();) {
+            Node c = (Node) iter.next();
+            excludeBranch(c, excludes);
+        }
+    }
+
+    protected void print(Node rootNode) {
+        for (Iterator iter = getArtifacts(rootNode, new HashSet()).iterator(); iter.hasNext();) {
+            Artifact a = (Artifact) iter.next();
+            getLog().info(" " + a);
+        }
+    }
+
+    protected Set retainArtifacts(Set includes, ResolutionListenerImpl listener) {
+        Set finalIncludes = new HashSet();
+        Set filteredArtifacts = getArtifacts(listener.getRootNode(),
+                new HashSet());
+        for (Iterator iter = includes.iterator(); iter.hasNext();) {
+            Artifact artifact = (Artifact) iter.next();
+            for (Iterator iter2 = filteredArtifacts.iterator(); iter2.hasNext();) {
+                Artifact filteredArtifact = (Artifact) iter2.next();
+                if (filteredArtifact.getArtifactId().equals(
+                        artifact.getArtifactId())
+                        && filteredArtifact.getType()
+                                .equals(artifact.getType())
+                        && filteredArtifact.getGroupId().equals(
+                                artifact.getGroupId())) {
+                    if (!filteredArtifact.getVersion().equals(
+                            artifact.getVersion())) {
+                        getLog()
+                                .warn(
+                                        "Resolved artifact "
+                                                + artifact
+                                                + " has a different version from that in dependency management "
+                                                + filteredArtifact
+                                                + ", overriding dependency management");
+                    }
+                    finalIncludes.add(artifact);
+                }
+            }
+
+        }
+
+        return finalIncludes;
+    }
+
+    protected ResolutionListenerImpl resolveProject() {
+        Map managedVersions = null;
+        try {
+            managedVersions = createManagedVersionMap(project.getId(), project
+                    .getDependencyManagement());
+        } catch (ProjectBuildingException e) {
+            getLog().error(
+                    "An error occurred while resolving project dependencies.",
+                    e);
+        }
+        ResolutionListenerImpl listener = new ResolutionListenerImpl();
+        listener.setLog(getLog());
+        try {
+            collector.collect(project.getDependencyArtifacts(), project
+                    .getArtifact(), managedVersions, localRepo, remoteRepos,
+                    artifactMetadataSource, null, Collections
+                            .singletonList(listener));
+        } catch (ArtifactResolutionException e) {
+            getLog().error(
+                    "An error occurred while resolving project dependencies.",
+                    e);
+        }
+        if (getLog().isDebugEnabled()) {
+            getLog().debug("Dependency graph");
+            getLog().debug("================");
+            print(listener.getRootNode());
+            getLog().debug("================");
+        }
+        return listener;
+    }
+
+    protected Map createManagedVersionMap(String projectId,
+            DependencyManagement dependencyManagement) throws ProjectBuildingException {
+        Map map;
+        if (dependencyManagement != null
+                && dependencyManagement.getDependencies() != null) {
+            map = new HashMap();
+            for (Iterator i = dependencyManagement.getDependencies().iterator(); i
+                    .hasNext();) {
+                Dependency d = (Dependency) i.next();
+
+                try {
+                    VersionRange versionRange = VersionRange
+                            .createFromVersionSpec(d.getVersion());
+                    Artifact artifact = factory.createDependencyArtifact(d
+                            .getGroupId(), d.getArtifactId(), versionRange, d
+                            .getType(), d.getClassifier(), d.getScope());
+                    map.put(d.getManagementKey(), artifact);
+                } catch (InvalidVersionSpecificationException e) {
+                    throw new ProjectBuildingException(projectId,
+                            "Unable to parse version '" + d.getVersion()
+                                    + "' for dependency '"
+                                    + d.getManagementKey() + "': "
+                                    + e.getMessage(), e);
+                }
+            }
+        } else {
+            map = Collections.EMPTY_MAP;
+        }
+        return map;
+    }
+
+    /**
+     * Set up a classloader for the execution of the main class.
+     *
+     * @return
+     * @throws MojoExecutionException
+     */
+    protected URLClassLoader getClassLoader() throws MojoExecutionException {
+        try {
+            Set urls = new HashSet();
+
+            URL mainClasses = new File(project.getBuild().getOutputDirectory())
+                    .toURL();
+            getLog().debug("Adding to classpath : " + mainClasses);
+            urls.add(mainClasses);
+
+            URL testClasses = new File(project.getBuild()
+                    .getTestOutputDirectory()).toURL();
+            getLog().debug("Adding to classpath : " + testClasses);
+            urls.add(testClasses);
+
+            Set dependencies = project.getArtifacts();
+            Iterator iter = dependencies.iterator();
+            while (iter.hasNext()) {
+                Artifact classPathElement = (Artifact) iter.next();
+                getLog().debug(
+                        "Adding artifact: " + classPathElement.getFile()
+                                + " to classpath");
+                urls.add(classPathElement.getFile().toURL());
+            }
+            URLClassLoader appClassloader = new URLClassLoader((URL[]) urls
+                    .toArray(new URL[urls.size()]), this.getClass().getClassLoader());
+            return appClassloader;
+        } catch (MalformedURLException e) {
+            throw new MojoExecutionException(
+                    "Error during setting up classpath", e);
+        }
+    }
+}

Propchange: servicemix/smx4/kernel/trunk/testing/features-maven-plugin/src/main/java/org/apache/servicemix/tooling/features/MojoSupport.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: servicemix/smx4/kernel/trunk/testing/features-maven-plugin/src/main/java/org/apache/servicemix/tooling/features/Node.java
URL: http://svn.apache.org/viewvc/servicemix/smx4/kernel/trunk/testing/features-maven-plugin/src/main/java/org/apache/servicemix/tooling/features/Node.java?rev=637166&view=auto
==============================================================================
--- servicemix/smx4/kernel/trunk/testing/features-maven-plugin/src/main/java/org/apache/servicemix/tooling/features/Node.java (added)
+++ servicemix/smx4/kernel/trunk/testing/features-maven-plugin/src/main/java/org/apache/servicemix/tooling/features/Node.java Fri Mar 14 10:17:06 2008
@@ -0,0 +1,56 @@
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.servicemix.tooling.features;
+
+import java.util.Set;
+import java.util.HashSet;
+
+import org.apache.maven.artifact.Artifact;
+
+/**
+ * @version $Revision: 1.1 $
+*/
+public class Node {
+    private Set children = new HashSet();
+    private Set parents = new HashSet();
+    private Artifact artifact;
+
+    public Set getChildren() {
+        return children;
+    }
+
+    public Artifact getArtifact() {
+        return artifact;
+    }
+
+    public Set getParents() {
+        return parents;
+    }
+
+    public void setChildren(Set children) {
+        this.children = children;
+    }
+
+    public void setParents(Set parents) {
+        this.parents = parents;
+    }
+
+    public void setArtifact(Artifact artifact) {
+        this.artifact = artifact;
+    }
+}

Propchange: servicemix/smx4/kernel/trunk/testing/features-maven-plugin/src/main/java/org/apache/servicemix/tooling/features/Node.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: servicemix/smx4/kernel/trunk/testing/features-maven-plugin/src/main/java/org/apache/servicemix/tooling/features/ResolutionListenerImpl.java
URL: http://svn.apache.org/viewvc/servicemix/smx4/kernel/trunk/testing/features-maven-plugin/src/main/java/org/apache/servicemix/tooling/features/ResolutionListenerImpl.java?rev=637166&view=auto
==============================================================================
--- servicemix/smx4/kernel/trunk/testing/features-maven-plugin/src/main/java/org/apache/servicemix/tooling/features/ResolutionListenerImpl.java (added)
+++ servicemix/smx4/kernel/trunk/testing/features-maven-plugin/src/main/java/org/apache/servicemix/tooling/features/ResolutionListenerImpl.java Fri Mar 14 10:17:06 2008
@@ -0,0 +1,161 @@
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.servicemix.tooling.features;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Stack;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.resolver.ResolutionListener;
+import org.apache.maven.artifact.versioning.VersionRange;
+import org.apache.maven.plugin.logging.Log;
+
+/**
+ * @author Edwin Punzalan
+ * @version $Revision: 1.1 $
+ */
+public class ResolutionListenerImpl implements ResolutionListener {
+    private Stack parents = new Stack();
+    private Map artifacts = new HashMap();
+    private Node rootNode;
+    private Log log;
+
+    public void setLog(Log log) {
+        this.log = log;
+    }
+
+    public Log getLog() {
+        return log;
+    }
+
+    public void testArtifact(Artifact artifact) {
+        // getLog().debug("testArtifact: " + artifact);
+        // intentionally blank
+    }
+
+    public void startProcessChildren(Artifact artifact) {
+        // getLog().debug("startProcessChildren: " + artifact);
+        Node node = (Node) artifacts.get(artifact.getDependencyConflictId());
+        if (parents.isEmpty()) {
+            rootNode = node;
+        }
+        parents.push(node);
+    }
+
+    public void endProcessChildren(Artifact artifact) {
+        // getLog().debug("endProcessChildren: " + artifact);
+        Node check = (Node) parents.pop();
+        assert artifact.equals(check.getArtifact());
+    }
+
+    public void omitForNearer(Artifact omitted, Artifact kept) {
+        // getLog().debug("omitForNearer: omitted=" + omitted + ", kept=" +
+        // kept);
+        assert omitted.getDependencyConflictId().equals(
+                kept.getDependencyConflictId());
+        Node node = (Node) artifacts.get(omitted.getDependencyConflictId());
+        assert node != null;
+        node.setArtifact(kept);
+    }
+
+    public void omitForCycle(Artifact artifact) {
+        // getLog().debug("omitForCycle: " + artifact);
+        // intentionally blank
+    }
+
+    public void includeArtifact(Artifact artifact) {
+        // getLog().debug("includeArtifact: " + artifact);
+        Node node = (Node) artifacts.get(artifact.getDependencyConflictId());
+        if (node == null) {
+            node = new Node();
+            artifacts.put(artifact.getDependencyConflictId(), node);
+        }
+        node.setArtifact(artifact);
+        if (!parents.isEmpty()) {
+            Node parent = (Node) parents.peek();
+            parent.getChildren().add(node);
+            node.getParents().add(parent);
+        }
+        if (rootNode != null) {
+            // print(rootNode, "");
+        }
+    }
+
+    protected void print(Node node, String string) {
+        // getLog().debug(string + rootNode.getArtifact());
+        for (Iterator iter = node.getChildren().iterator(); iter.hasNext();) {
+            Node n = (Node) iter.next();
+            print(n, string + "  ");
+        }
+    }
+
+    public void updateScope(Artifact artifact, String scope) {
+        // getLog().debug("updateScope: " + artifact);
+        Node node = (Node) artifacts.get(artifact.getDependencyConflictId());
+
+        node.getArtifact().setScope(scope);
+    }
+
+    public void manageArtifact(Artifact artifact, Artifact replacement) {
+        // getLog().debug("manageArtifact: artifact=" + artifact + ",
+        // replacement=" + replacement);
+        Node node = (Node) artifacts.get(artifact.getDependencyConflictId());
+        if (node != null) {
+            if (replacement.getVersion() != null) {
+                node.getArtifact().setVersion(replacement.getVersion());
+            }
+            if (replacement.getScope() != null) {
+                node.getArtifact().setScope(replacement.getScope());
+            }
+        }
+    }
+
+    public void updateScopeCurrentPom(Artifact artifact, String key) {
+
+        getLog().debug("updateScopeCurrentPom: " + artifact);
+        // intentionally blank
+    }
+
+    public void selectVersionFromRange(Artifact artifact) {
+
+        getLog().debug("selectVersionFromRange: " + artifact);
+        // intentionally blank
+    }
+
+    public void restrictRange(Artifact artifact, Artifact artifact1,
+            VersionRange versionRange) {
+
+        getLog().debug("restrictRange: " + artifact);
+        // intentionally blank
+    }
+
+    public Node getNode(Artifact artifact) {
+        return (Node) artifacts.get(artifact.getDependencyConflictId());
+    }
+
+    public Collection getArtifacts() {
+        return artifacts.values();
+    }
+
+    public Node getRootNode() {
+        return rootNode;
+    }
+}

Propchange: servicemix/smx4/kernel/trunk/testing/features-maven-plugin/src/main/java/org/apache/servicemix/tooling/features/ResolutionListenerImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: servicemix/smx4/kernel/trunk/testing/pom.xml
URL: http://svn.apache.org/viewvc/servicemix/smx4/kernel/trunk/testing/pom.xml?rev=637166&r1=637165&r2=637166&view=diff
==============================================================================
--- servicemix/smx4/kernel/trunk/testing/pom.xml (original)
+++ servicemix/smx4/kernel/trunk/testing/pom.xml Fri Mar 14 10:17:06 2008
@@ -35,6 +35,7 @@
 
     <modules>
         <module>depends-maven-plugin</module>
+        <module>features-maven-plugin</module>
         <module>support</module>
     </modules>