]> source.dussan.org Git - archiva.git/commitdiff
[MRM-1411] project information is missing if a POM could not be read correctly
authorMaria Odea B. Ching <oching@apache.org>
Wed, 15 Jun 2011 09:36:05 +0000 (09:36 +0000)
committerMaria Odea B. Ching <oching@apache.org>
Wed, 15 Jun 2011 09:36:05 +0000 (09:36 +0000)
o proxy parent POM if not found in the repo when building the effective POM when creating metadata (also applied the same in dependency tree builder)
o added unit tests
o moved out wagonfactory classes into separate module so it can be used by maven2-repository w/o depending on archiva-proxy module (as it inroduces cyclic dependency)

git-svn-id: https://svn.apache.org/repos/asf/archiva/trunk@1135978 13f79535-47bb-0310-9956-ffa450edef68

46 files changed:
archiva-modules/archiva-base/archiva-common/pom.xml
archiva-modules/archiva-base/archiva-common/src/main/java/org/apache/maven/archiva/common/utils/FileUtil.java [new file with mode: 0644]
archiva-modules/archiva-base/archiva-configuration/src/main/mdo/configuration.mdo
archiva-modules/archiva-base/archiva-proxy-common/pom.xml [new file with mode: 0644]
archiva-modules/archiva-base/archiva-proxy-common/src/main/java/org/apache/archiva/proxy/common/DefaultWagonFactory.java [new file with mode: 0755]
archiva-modules/archiva-base/archiva-proxy-common/src/main/java/org/apache/archiva/proxy/common/WagonFactory.java [new file with mode: 0644]
archiva-modules/archiva-base/archiva-proxy-common/src/main/java/org/apache/archiva/proxy/common/WagonFactoryException.java [new file with mode: 0755]
archiva-modules/archiva-base/archiva-proxy-common/src/main/resources/META-INF/spring-context.xml [new file with mode: 0644]
archiva-modules/archiva-base/archiva-proxy-common/src/test/java/org/apache/archiva/proxy/common/WagonFactoryTest.java [new file with mode: 0644]
archiva-modules/archiva-base/archiva-proxy-common/src/test/resources/META-INF/spring-context.xml [new file with mode: 0644]
archiva-modules/archiva-base/archiva-proxy/pom.xml
archiva-modules/archiva-base/archiva-proxy/src/main/java/org/apache/maven/archiva/proxy/DefaultRepositoryProxyConnectors.java
archiva-modules/archiva-base/archiva-proxy/src/main/java/org/apache/maven/archiva/proxy/DefaultWagonFactory.java [deleted file]
archiva-modules/archiva-base/archiva-proxy/src/main/java/org/apache/maven/archiva/proxy/WagonFactory.java [deleted file]
archiva-modules/archiva-base/archiva-proxy/src/main/java/org/apache/maven/archiva/proxy/WagonFactoryException.java [deleted file]
archiva-modules/archiva-base/archiva-proxy/src/test/java/org/apache/maven/archiva/proxy/WagonFactoryTest.java [deleted file]
archiva-modules/archiva-base/archiva-proxy/src/test/resources/org/apache/maven/archiva/proxy/CacheFailuresTransferTest.xml
archiva-modules/archiva-base/archiva-proxy/src/test/resources/org/apache/maven/archiva/proxy/ChecksumTransferTest.xml
archiva-modules/archiva-base/archiva-proxy/src/test/resources/org/apache/maven/archiva/proxy/ErrorHandlingTest.xml
archiva-modules/archiva-base/archiva-proxy/src/test/resources/org/apache/maven/archiva/proxy/HttpProxyTransferTest.xml
archiva-modules/archiva-base/archiva-proxy/src/test/resources/org/apache/maven/archiva/proxy/ManagedDefaultTransferTest.xml
archiva-modules/archiva-base/archiva-proxy/src/test/resources/org/apache/maven/archiva/proxy/ManagedLegacyTransferTest.xml
archiva-modules/archiva-base/archiva-proxy/src/test/resources/org/apache/maven/archiva/proxy/MetadataTransferTest.xml
archiva-modules/archiva-base/archiva-proxy/src/test/resources/org/apache/maven/archiva/proxy/RelocateTransferTest.xml
archiva-modules/archiva-base/archiva-proxy/src/test/resources/org/apache/maven/archiva/proxy/SnapshotTransferTest.xml
archiva-modules/archiva-base/pom.xml
archiva-modules/metadata/test-repository/src/main/resources/com/example/test/missing-parent/1.1/missing-parent-1.1.pom [new file with mode: 0644]
archiva-modules/plugins/maven2-repository/pom.xml
archiva-modules/plugins/maven2-repository/src/main/java/org/apache/archiva/dependency/tree/maven2/DefaultDependencyTreeBuilder.java
archiva-modules/plugins/maven2-repository/src/main/java/org/apache/archiva/metadata/repository/storage/maven2/Maven2RepositoryStorage.java
archiva-modules/plugins/maven2-repository/src/main/java/org/apache/archiva/metadata/repository/storage/maven2/RepositoryModelResolver.java
archiva-modules/plugins/maven2-repository/src/test/java/org/apache/archiva/metadata/repository/storage/maven2/Maven2RepositoryMetadataResolverTest.java
archiva-modules/plugins/maven2-repository/src/test/java/org/apache/archiva/metadata/repository/storage/maven2/MockWagon.java [new file with mode: 0644]
archiva-modules/plugins/maven2-repository/src/test/resources/com/example/test/test-artifact-module-a/1.0/test-artifact-module-a-1.0.jar [new file with mode: 0644]
archiva-modules/plugins/maven2-repository/src/test/resources/com/example/test/test-artifact-module-a/1.0/test-artifact-module-a-1.0.jar.md5 [new file with mode: 0644]
archiva-modules/plugins/maven2-repository/src/test/resources/com/example/test/test-artifact-module-a/1.0/test-artifact-module-a-1.0.jar.sha1 [new file with mode: 0644]
archiva-modules/plugins/maven2-repository/src/test/resources/com/example/test/test-artifact-module-a/1.0/test-artifact-module-a-1.0.pom [new file with mode: 0644]
archiva-modules/plugins/maven2-repository/src/test/resources/com/example/test/test-artifact-module-a/1.0/test-artifact-module-a-1.0.pom.md5 [new file with mode: 0644]
archiva-modules/plugins/maven2-repository/src/test/resources/com/example/test/test-artifact-module-a/1.0/test-artifact-module-a-1.0.pom.sha1 [new file with mode: 0644]
archiva-modules/plugins/maven2-repository/src/test/resources/com/example/test/test-artifact-parent/1/test-artifact-parent-1.pom [new file with mode: 0644]
archiva-modules/plugins/maven2-repository/src/test/resources/com/example/test/test-artifact-parent/1/test-artifact-parent-1.pom.md5 [new file with mode: 0644]
archiva-modules/plugins/maven2-repository/src/test/resources/com/example/test/test-artifact-parent/1/test-artifact-parent-1.pom.sha1 [new file with mode: 0644]
archiva-modules/plugins/maven2-repository/src/test/resources/com/example/test/test-artifact-root/1.0/test-artifact-root-1.0.pom [new file with mode: 0644]
archiva-modules/plugins/maven2-repository/src/test/resources/com/example/test/test-artifact-root/1.0/test-artifact-root-1.0.pom.md5 [new file with mode: 0644]
archiva-modules/plugins/maven2-repository/src/test/resources/com/example/test/test-artifact-root/1.0/test-artifact-root-1.0.pom.sha1 [new file with mode: 0644]
pom.xml

index dd92dfed944329e8ac111a6df652f51d3b308cf0..32ea5a0f1a0ef1acfa8fa57dbe95a9dafc7a7d80 100644 (file)
       <artifactId>sisu-inject-plexus</artifactId>
       <scope>compile</scope>
     </dependency>
-    <dependency>
-      <groupId>dom4j</groupId>
-      <artifactId>dom4j</artifactId>
-      <version>1.6.1</version>
-      <scope>test</scope>
-    </dependency>
     <dependency>
       <groupId>org.sonatype.nexus</groupId>
       <artifactId>nexus-indexer</artifactId>
       <groupId>javax.inject</groupId>
       <artifactId>javax.inject</artifactId>
     </dependency>
+    <dependency>
+      <groupId>dom4j</groupId>
+      <artifactId>dom4j</artifactId>
+      <version>1.6.1</version>
+      <scope>test</scope>
+    </dependency>
   </dependencies>
 </project>
diff --git a/archiva-modules/archiva-base/archiva-common/src/main/java/org/apache/maven/archiva/common/utils/FileUtil.java b/archiva-modules/archiva-base/archiva-common/src/main/java/org/apache/maven/archiva/common/utils/FileUtil.java
new file mode 100644 (file)
index 0000000..8c451dc
--- /dev/null
@@ -0,0 +1,36 @@
+package org.apache.maven.archiva.common.utils;
+
+/*
+ * 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.
+ */
+
+import java.io.File;
+
+public class FileUtil
+{
+    public static String getBasedir()
+    {
+        String basedir = System.getProperty( "basedir" );
+        if ( basedir == null )
+        {
+            basedir = new File( "" ).getAbsolutePath();
+        }
+
+        return basedir;
+    }
+}
\ No newline at end of file
index bf7c0f7dc1c59035ef0c377ca7fffc2f4a7a8bf6..f37faf4b15291b70b0cb740849a3166e4271a938 100644 (file)
         java.util.Map<String, java.util.List<ProxyConnectorConfiguration>> proxyConnectorMap =
             new java.util.HashMap<String, java.util.List<ProxyConnectorConfiguration>>();
 
-        java.util.Iterator<ProxyConnectorConfiguration> it = proxyConnectors.iterator();
-        while ( it.hasNext() )
+        if( proxyConnectors != null )
         {
-            ProxyConnectorConfiguration proxyConfig = it.next();
-            String key = proxyConfig.getSourceRepoId();
-
-            java.util.List<ProxyConnectorConfiguration> connectors = proxyConnectorMap.get( key );
-            if ( connectors == null )
+            java.util.Iterator<ProxyConnectorConfiguration> it = proxyConnectors.iterator();
+            while ( it.hasNext() )
             {
-                connectors = new java.util.ArrayList<ProxyConnectorConfiguration>();
-                proxyConnectorMap.put( key, connectors );
-            }
+                ProxyConnectorConfiguration proxyConfig = it.next();
+                String key = proxyConfig.getSourceRepoId();
+
+                java.util.List<ProxyConnectorConfiguration> connectors = proxyConnectorMap.get( key );
+                if ( connectors == null )
+                {
+                    connectors = new java.util.ArrayList<ProxyConnectorConfiguration>();
+                    proxyConnectorMap.put( key, connectors );
+                }
 
-            connectors.add( proxyConfig );
-            java.util.Collections.sort( connectors,
-                org.apache.maven.archiva.configuration.functors.ProxyConnectorConfigurationOrderComparator.getInstance() );
+                connectors.add( proxyConfig );
+                java.util.Collections.sort( connectors,
+                    org.apache.maven.archiva.configuration.functors.ProxyConnectorConfigurationOrderComparator.getInstance() );
+            }
         }
 
         return proxyConnectorMap;
diff --git a/archiva-modules/archiva-base/archiva-proxy-common/pom.xml b/archiva-modules/archiva-base/archiva-proxy-common/pom.xml
new file mode 100644 (file)
index 0000000..8c9e396
--- /dev/null
@@ -0,0 +1,44 @@
+<?xml version="1.0"?>
+<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <artifactId>archiva-base</artifactId>
+    <groupId>org.apache.archiva</groupId>
+    <version>1.4-SNAPSHOT</version>
+  </parent>
+  <artifactId>archiva-proxy-common</artifactId>
+  <name>Archiva Base :: Proxy Common</name>
+  <properties>
+    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+  </properties>
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.archiva</groupId>
+      <artifactId>archiva-plexus-bridge</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.maven.wagon</groupId>
+      <artifactId>wagon-provider-api</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.maven.wagon</groupId>
+      <artifactId>wagon-file</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.maven.wagon</groupId>
+      <artifactId>wagon-http-lightweight</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>commons-logging</groupId>
+      <artifactId>commons-logging-api</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.springframework</groupId>
+      <artifactId>spring-test</artifactId>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+</project>
diff --git a/archiva-modules/archiva-base/archiva-proxy-common/src/main/java/org/apache/archiva/proxy/common/DefaultWagonFactory.java b/archiva-modules/archiva-base/archiva-proxy-common/src/main/java/org/apache/archiva/proxy/common/DefaultWagonFactory.java
new file mode 100755 (executable)
index 0000000..f2631c0
--- /dev/null
@@ -0,0 +1,62 @@
+package org.apache.archiva.proxy.common;
+
+/*
+ * 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.
+ */
+
+import org.apache.archiva.common.plexusbridge.PlexusSisuBridge;
+import org.apache.archiva.common.plexusbridge.PlexusSisuBridgeException;
+import org.apache.commons.lang.StringUtils;
+import org.apache.maven.wagon.Wagon;
+import org.springframework.stereotype.Service;
+
+import javax.inject.Inject;
+
+/**
+ * @author Olivier Lamy
+ * @since 1.4
+ */
+@Service( "wagonFactory" )
+public class DefaultWagonFactory
+    implements WagonFactory
+{
+
+    private PlexusSisuBridge plexusSisuBridge;
+
+    @Inject
+    public DefaultWagonFactory( PlexusSisuBridge plexusSisuBridge )
+    {
+        this.plexusSisuBridge = plexusSisuBridge;
+    }
+
+    public Wagon getWagon( String protocol )
+        throws WagonFactoryException
+    {
+        try
+        {
+            // with sisu inject bridge hint is file or http
+            // so remove wagon#
+            protocol = StringUtils.remove( protocol, "wagon#" );
+            return plexusSisuBridge.lookup( Wagon.class, protocol );
+        }
+        catch ( PlexusSisuBridgeException e )
+        {
+            throw new WagonFactoryException( e.getMessage(), e );
+        }
+    }
+}
diff --git a/archiva-modules/archiva-base/archiva-proxy-common/src/main/java/org/apache/archiva/proxy/common/WagonFactory.java b/archiva-modules/archiva-base/archiva-proxy-common/src/main/java/org/apache/archiva/proxy/common/WagonFactory.java
new file mode 100644 (file)
index 0000000..3768f8e
--- /dev/null
@@ -0,0 +1,38 @@
+package org.apache.archiva.proxy.common;
+
+/*
+ * 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.
+ */
+
+import org.apache.maven.wagon.Wagon;
+
+/**
+ * Create a Wagon instance for the given protocol.
+ */
+public interface WagonFactory
+{
+    /**
+     * Create a new Wagon instance for the given protocol.
+     *
+     * @param protocol the protocol to find the Wagon for, which must be prefixed with <code>wagon#</code>, for example
+     *                 <code>wagon#http</code>.
+     * @return the Wagon instance
+     */
+    Wagon getWagon( String protocol )
+        throws WagonFactoryException;
+}
diff --git a/archiva-modules/archiva-base/archiva-proxy-common/src/main/java/org/apache/archiva/proxy/common/WagonFactoryException.java b/archiva-modules/archiva-base/archiva-proxy-common/src/main/java/org/apache/archiva/proxy/common/WagonFactoryException.java
new file mode 100755 (executable)
index 0000000..aba311c
--- /dev/null
@@ -0,0 +1,33 @@
+package org.apache.archiva.proxy.common;
+
+/*
+ * 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.
+ */
+
+/**
+ * @author Olivier Lamy
+ * @since 1.4
+ */
+public class WagonFactoryException
+    extends Exception
+{
+    public WagonFactoryException( String message, Throwable e )
+    {
+        super( message, e );
+    }
+}
diff --git a/archiva-modules/archiva-base/archiva-proxy-common/src/main/resources/META-INF/spring-context.xml b/archiva-modules/archiva-base/archiva-proxy-common/src/main/resources/META-INF/spring-context.xml
new file mode 100644 (file)
index 0000000..eaf7b41
--- /dev/null
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ 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.
+  -->
+
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xmlns:context="http://www.springframework.org/schema/context"
+       xsi:schemaLocation="http://www.springframework.org/schema/beans
+           http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
+           http://www.springframework.org/schema/context
+           http://www.springframework.org/schema/context/spring-context-3.0.xsd"
+       default-lazy-init="true">
+
+  <context:annotation-config/>
+  <context:component-scan base-package="org.apache.archiva.proxy.common"/>
+
+
+</beans>
\ No newline at end of file
diff --git a/archiva-modules/archiva-base/archiva-proxy-common/src/test/java/org/apache/archiva/proxy/common/WagonFactoryTest.java b/archiva-modules/archiva-base/archiva-proxy-common/src/test/java/org/apache/archiva/proxy/common/WagonFactoryTest.java
new file mode 100644 (file)
index 0000000..85dc8d2
--- /dev/null
@@ -0,0 +1,60 @@
+package org.apache.archiva.proxy.common;
+
+/*
+ * 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.
+ */
+
+import junit.framework.TestCase;
+import org.apache.maven.wagon.Wagon;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import javax.inject.Inject;
+
+/**
+ * Test the WagonFactory works through Spring to be bound into the RepositoryProxyConnectors implementation.
+ * 
+ */
+@RunWith( SpringJUnit4ClassRunner.class )
+@ContextConfiguration( locations = { "classpath*:/META-INF/spring-context.xml" } )
+public class WagonFactoryTest
+    extends TestCase
+{
+
+    @Inject
+    WagonFactory factory;
+
+    @Test
+    public void testLookupSuccessiveWagons()
+        throws Exception
+    {
+
+        Wagon first = factory.getWagon( "wagon#file" );
+        
+        Wagon second = factory.getWagon( "wagon#file" );
+
+        // ensure we support only protocol name too
+        Wagon third = factory.getWagon( "file" );
+        
+        assertNotSame( first, second );
+
+        assertNotSame( first, third );
+    }
+}
diff --git a/archiva-modules/archiva-base/archiva-proxy-common/src/test/resources/META-INF/spring-context.xml b/archiva-modules/archiva-base/archiva-proxy-common/src/test/resources/META-INF/spring-context.xml
new file mode 100644 (file)
index 0000000..011f375
--- /dev/null
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ 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.
+  -->
+
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xmlns:context="http://www.springframework.org/schema/context"
+       xsi:schemaLocation="http://www.springframework.org/schema/beans
+           http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
+           http://www.springframework.org/schema/context
+           http://www.springframework.org/schema/context/spring-context-3.0.xsd"
+       default-lazy-init="true">
+
+</beans>
\ No newline at end of file
index 7e2b2552ab80637256196512bfb45dd202a208d6..7ab1457fc529149aea8e8720bd3b88c3206c8870 100644 (file)
       <groupId>org.apache.archiva</groupId>
       <artifactId>archiva-scheduler-repository</artifactId>
     </dependency>
+    <dependency>
+      <groupId>org.apache.archiva</groupId>
+      <artifactId>archiva-proxy-common</artifactId>
+    </dependency>
     <dependency>
       <groupId>commons-io</groupId>
       <artifactId>commons-io</artifactId>
index 9d9091159bad12bb4589a52e0ec2b00dd266921b..ec50428190a80097454b8f241e25dd0391333583 100644 (file)
@@ -20,6 +20,8 @@ package org.apache.maven.archiva.proxy;
  */
 
 import com.google.common.collect.Lists;
+import org.apache.archiva.proxy.common.WagonFactory;
+import org.apache.archiva.proxy.common.WagonFactoryException;
 import org.apache.archiva.scheduler.ArchivaTaskScheduler;
 import org.apache.archiva.scheduler.repository.RepositoryTask;
 import org.apache.commons.collections.CollectionUtils;
diff --git a/archiva-modules/archiva-base/archiva-proxy/src/main/java/org/apache/maven/archiva/proxy/DefaultWagonFactory.java b/archiva-modules/archiva-base/archiva-proxy/src/main/java/org/apache/maven/archiva/proxy/DefaultWagonFactory.java
deleted file mode 100755 (executable)
index 04d2e8c..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-package org.apache.maven.archiva.proxy;
-
-/*
- * 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.
- */
-
-import org.apache.archiva.common.plexusbridge.PlexusSisuBridge;
-import org.apache.archiva.common.plexusbridge.PlexusSisuBridgeException;
-import org.apache.commons.lang.StringUtils;
-import org.apache.maven.wagon.Wagon;
-import org.springframework.stereotype.Service;
-
-import javax.inject.Inject;
-
-/**
- * @author Olivier Lamy
- * @since 1.4
- */
-@Service( "wagonFactory" )
-public class DefaultWagonFactory
-    implements WagonFactory
-{
-
-    private PlexusSisuBridge plexusSisuBridge;
-
-    @Inject
-    public DefaultWagonFactory( PlexusSisuBridge plexusSisuBridge )
-    {
-        this.plexusSisuBridge = plexusSisuBridge;
-    }
-
-    public Wagon getWagon( String protocol )
-        throws WagonFactoryException
-    {
-        try
-        {
-            // with sisu inject bridge hint is file or http
-            // so remove wagon#
-            protocol = StringUtils.remove( protocol, "wagon#" );
-            return plexusSisuBridge.lookup( Wagon.class, protocol );
-        }
-        catch ( PlexusSisuBridgeException e )
-        {
-            throw new WagonFactoryException( e.getMessage(), e );
-        }
-    }
-}
diff --git a/archiva-modules/archiva-base/archiva-proxy/src/main/java/org/apache/maven/archiva/proxy/WagonFactory.java b/archiva-modules/archiva-base/archiva-proxy/src/main/java/org/apache/maven/archiva/proxy/WagonFactory.java
deleted file mode 100644 (file)
index 965d2cf..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-package org.apache.maven.archiva.proxy;
-
-/*
- * 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.
- */
-
-import org.apache.maven.wagon.Wagon;
-
-/**
- * Create a Wagon instance for the given protocol.
- */
-public interface WagonFactory
-{
-    /**
-     * Create a new Wagon instance for the given protocol.
-     *
-     * @param protocol the protocol to find the Wagon for, which must be prefixed with <code>wagon#</code>, for example
-     *                 <code>wagon#http</code>.
-     * @return the Wagon instance
-     */
-    Wagon getWagon( String protocol )
-        throws WagonFactoryException;
-}
diff --git a/archiva-modules/archiva-base/archiva-proxy/src/main/java/org/apache/maven/archiva/proxy/WagonFactoryException.java b/archiva-modules/archiva-base/archiva-proxy/src/main/java/org/apache/maven/archiva/proxy/WagonFactoryException.java
deleted file mode 100755 (executable)
index e88dc94..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-package org.apache.maven.archiva.proxy;
-
-/*
- * 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.
- */
-
-/**
- * @author Olivier Lamy
- * @since 1.4
- */
-public class WagonFactoryException
-    extends Exception
-{
-    public WagonFactoryException( String message, Throwable e )
-    {
-        super( message, e );
-    }
-}
diff --git a/archiva-modules/archiva-base/archiva-proxy/src/test/java/org/apache/maven/archiva/proxy/WagonFactoryTest.java b/archiva-modules/archiva-base/archiva-proxy/src/test/java/org/apache/maven/archiva/proxy/WagonFactoryTest.java
deleted file mode 100644 (file)
index 0c7e9fb..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-package org.apache.maven.archiva.proxy;
-
-/*
- * 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.
- */
-
-import junit.framework.TestCase;
-import org.apache.archiva.common.plexusbridge.PlexusSisuBridge;
-import org.apache.maven.wagon.Wagon;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.springframework.test.context.ContextConfiguration;
-import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
-
-import javax.inject.Inject;
-
-/**
- * Test the WagonFactory works through Spring to be bound into the RepositoryProxyConnectors implementation.
- * 
- */
-@RunWith( SpringJUnit4ClassRunner.class )
-@ContextConfiguration( locations = {"classpath*:/META-INF/spring-context.xml","classpath:/spring-context.xml"} )
-public class WagonFactoryTest
-    extends TestCase
-{
-
-    @Inject
-    WagonFactory factory;
-
-    @Test
-    public void testLookupSuccessiveWagons()
-        throws Exception
-    {
-
-        Wagon first = factory.getWagon( "wagon#file" );
-        
-        Wagon second = factory.getWagon( "wagon#file" );
-
-        // ensure we support only protocol name too
-        Wagon third = factory.getWagon( "file" );
-        
-        assertNotSame( first, second );
-
-        assertNotSame( first, third );
-    }
-}
index 8f7c85414a06c5beb9e8b405242257a661091d89..5f332f09c247bf61943bef7ce15e0354f3f45228 100644 (file)
@@ -54,7 +54,7 @@
           <field-name>archivaConfiguration</field-name>
         </requirement>
         <requirement>
-          <role>org.apache.maven.archiva.proxy.WagonFactory</role>
+          <role>org.apache.archiva.proxy.common.WagonFactory</role>
         </requirement>
         <requirement>
           <role>org.apache.maven.archiva.repository.RepositoryContentFactory</role>
index d6e12306b1931385ff33d4ef740791a3b47e1c8b..b624eaf52fe801d44244b37a5c504465c3d46909 100644 (file)
@@ -54,7 +54,7 @@
           <field-name>archivaConfiguration</field-name>
         </requirement>
         <requirement>
-          <role>org.apache.maven.archiva.proxy.WagonFactory</role>
+          <role>org.apache.archiva.proxy.common.WagonFactory</role>
         </requirement>
         <requirement>
           <role>org.apache.maven.archiva.repository.RepositoryContentFactory</role>
index fdd2414d506ac1e504edc9b33c74a524dee0b853..997eb03cdb146d462f2a744315c0119872b7f823 100644 (file)
@@ -54,7 +54,7 @@
           <field-name>archivaConfiguration</field-name>
         </requirement>
         <requirement>
-          <role>org.apache.maven.archiva.proxy.WagonFactory</role>
+          <role>org.apache.archiva.proxy.common.WagonFactory</role>
         </requirement>
         <requirement>
           <role>org.apache.maven.archiva.repository.RepositoryContentFactory</role>
index 6913522ede28b298ef66f6e6b6b988e049959962..78705b6b20ee73fe548d843569d0f790a176ff24 100644 (file)
@@ -68,7 +68,7 @@
           <field-name>urlFailureCache</field-name>
         </requirement>
         <requirement>
-          <role>org.apache.maven.archiva.proxy.WagonFactory</role>
+          <role>org.apache.archiva.proxy.common.WagonFactory</role>
           <role-hint>default</role-hint>
         </requirement>
         <requirement>
index d6e12306b1931385ff33d4ef740791a3b47e1c8b..b624eaf52fe801d44244b37a5c504465c3d46909 100644 (file)
@@ -54,7 +54,7 @@
           <field-name>archivaConfiguration</field-name>
         </requirement>
         <requirement>
-          <role>org.apache.maven.archiva.proxy.WagonFactory</role>
+          <role>org.apache.archiva.proxy.common.WagonFactory</role>
         </requirement>
         <requirement>
           <role>org.apache.maven.archiva.repository.RepositoryContentFactory</role>
index d6e12306b1931385ff33d4ef740791a3b47e1c8b..b624eaf52fe801d44244b37a5c504465c3d46909 100644 (file)
@@ -54,7 +54,7 @@
           <field-name>archivaConfiguration</field-name>
         </requirement>
         <requirement>
-          <role>org.apache.maven.archiva.proxy.WagonFactory</role>
+          <role>org.apache.archiva.proxy.common.WagonFactory</role>
         </requirement>
         <requirement>
           <role>org.apache.maven.archiva.repository.RepositoryContentFactory</role>
index 6830d1ee46c4fd5935d50e29a30370a0eb88094f..c51bd9e093f5f83ae05540ad89bcb266bad775c3 100644 (file)
@@ -74,7 +74,7 @@
           <field-name>archivaConfiguration</field-name>
         </requirement>
         <requirement>
-          <role>org.apache.maven.archiva.proxy.WagonFactory</role>
+          <role>org.apache.archiva.proxy.common.WagonFactory</role>
         </requirement>
         <requirement>
           <role>org.apache.maven.archiva.repository.RepositoryContentFactory</role>
index d6e12306b1931385ff33d4ef740791a3b47e1c8b..b624eaf52fe801d44244b37a5c504465c3d46909 100644 (file)
@@ -54,7 +54,7 @@
           <field-name>archivaConfiguration</field-name>
         </requirement>
         <requirement>
-          <role>org.apache.maven.archiva.proxy.WagonFactory</role>
+          <role>org.apache.archiva.proxy.common.WagonFactory</role>
         </requirement>
         <requirement>
           <role>org.apache.maven.archiva.repository.RepositoryContentFactory</role>
index d6e12306b1931385ff33d4ef740791a3b47e1c8b..b624eaf52fe801d44244b37a5c504465c3d46909 100644 (file)
@@ -54,7 +54,7 @@
           <field-name>archivaConfiguration</field-name>
         </requirement>
         <requirement>
-          <role>org.apache.maven.archiva.proxy.WagonFactory</role>
+          <role>org.apache.archiva.proxy.common.WagonFactory</role>
         </requirement>
         <requirement>
           <role>org.apache.maven.archiva.repository.RepositoryContentFactory</role>
index 1a599ad77fb490cb393c3b90f10ad1f0e5019837..53805ead02ba871a6d73072843cfb780950d9365 100644 (file)
@@ -17,7 +17,6 @@
   ~ specific language governing permissions and limitations
   ~ under the License.
   -->
-
 <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">
   <modelVersion>4.0.0</modelVersion>
   <parent>
@@ -46,5 +45,6 @@
     <module>archiva-artifact-converter</module>
     <module>archiva-converter</module>
     <module>archiva-repository-scanner</module>
+    <module>archiva-proxy-common</module>
   </modules>
-</project>
+</project>
\ No newline at end of file
diff --git a/archiva-modules/metadata/test-repository/src/main/resources/com/example/test/missing-parent/1.1/missing-parent-1.1.pom b/archiva-modules/metadata/test-repository/src/main/resources/com/example/test/missing-parent/1.1/missing-parent-1.1.pom
new file mode 100644 (file)
index 0000000..a2f1ecf
--- /dev/null
@@ -0,0 +1,20 @@
+<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">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>com.example.test</groupId>
+    <artifactId>missing-parent-pom</artifactId>
+    <version>1</version>
+  </parent>
+  <artifactId>missing-parent</artifactId>
+  <packaging>jar</packaging>
+  <version>1.1</version>
+  <name>Test Artifact :: Missing Parent POM</name>
+  <dependencies>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+</project>
index 94eacf6f5141bbd708d4f06aede143b0e5db4f46..0344dbb49b3b22d419a470f1dd985ee5196ee688 100644 (file)
       <groupId>org.apache.archiva</groupId>
       <artifactId>metadata-repository-api</artifactId>
     </dependency>
+    <dependency>
+      <groupId>org.apache.archiva</groupId>
+      <artifactId>archiva-proxy-common</artifactId>
+    </dependency>
     <dependency>
       <groupId>org.sonatype.sisu</groupId>
       <artifactId>sisu-inject-plexus</artifactId>
       <groupId>org.apache.archiva</groupId>
       <artifactId>archiva-configuration</artifactId>
     </dependency>
+    <dependency>
+      <groupId>org.apache.maven.wagon</groupId>
+      <artifactId>wagon-provider-api</artifactId>
+    </dependency>
     <!-- TODO: aim to remove this dependency -->
     <dependency>
       <groupId>org.apache.archiva</groupId>
       <artifactId>slf4j-simple</artifactId>
       <scope>test</scope>
     </dependency>
+    <dependency>
+      <groupId>org.mockito</groupId>
+      <artifactId>mockito-all</artifactId>
+      <scope>test</scope>
+    </dependency>
   </dependencies>
   <build>
     <plugins>
index 3336ab1efa9b648702139c96d5aaf47687e2008b..4ab685160f6ef6c175b9de8e67b7d7ff126441db 100644 (file)
@@ -27,10 +27,14 @@ import org.apache.archiva.metadata.repository.RepositorySession;
 import org.apache.archiva.metadata.repository.RepositorySessionFactory;
 import org.apache.archiva.metadata.repository.storage.RepositoryPathTranslator;
 import org.apache.archiva.metadata.repository.storage.maven2.RepositoryModelResolver;
+import org.apache.archiva.proxy.common.WagonFactory;
 import org.apache.commons.lang.StringUtils;
 import org.apache.maven.archiva.common.utils.Slf4JPlexusLogger;
 import org.apache.maven.archiva.configuration.ArchivaConfiguration;
 import org.apache.maven.archiva.configuration.ManagedRepositoryConfiguration;
+import org.apache.maven.archiva.configuration.NetworkProxyConfiguration;
+import org.apache.maven.archiva.configuration.ProxyConnectorConfiguration;
+import org.apache.maven.archiva.configuration.RemoteRepositoryConfiguration;
 import org.apache.maven.artifact.Artifact;
 import org.apache.maven.artifact.factory.ArtifactFactory;
 import org.apache.maven.artifact.metadata.ArtifactMetadataRetrievalException;
@@ -69,6 +73,7 @@ import org.apache.maven.shared.dependency.tree.traversal.BuildingDependencyNodeV
 import org.apache.maven.shared.dependency.tree.traversal.CollectingDependencyNodeVisitor;
 import org.apache.maven.shared.dependency.tree.traversal.DependencyNodeVisitor;
 import org.apache.maven.shared.dependency.tree.traversal.FilteringDependencyNodeVisitor;
+import org.apache.maven.wagon.proxy.ProxyInfo;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.stereotype.Service;
@@ -80,6 +85,7 @@ import java.io.File;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.LinkedHashSet;
 import java.util.List;
@@ -140,6 +146,9 @@ public class DefaultDependencyTreeBuilder
     @Inject
     private PlexusSisuBridge plexusSisuBridge;
 
+    @Inject
+    private WagonFactory wagonFactory;
+
     @PostConstruct
     public void initialize()
         throws PlexusSisuBridgeException
@@ -160,18 +169,50 @@ public class DefaultDependencyTreeBuilder
             new DependencyTreeResolutionListener( new Slf4JPlexusLogger( getClass() ) );
 
         Artifact projectArtifact = factory.createProjectArtifact( groupId, artifactId, version );
-        File basedir = findArtifactInRepositories( repositoryIds, projectArtifact );
+        ManagedRepositoryConfiguration repository = findArtifactInRepositories( repositoryIds, projectArtifact );
 
-        if ( basedir == null )
+        if ( repository == null )
         {
             // metadata could not be resolved
             return;
         }
 
+        File basedir = new File( repository.getLocation() );
+
         try
         {
-            Model model =
-                buildProject( new RepositoryModelResolver( basedir, pathTranslator ), groupId, artifactId, version );
+            // MRM-1411
+            List< RemoteRepositoryConfiguration > remoteRepositories = new ArrayList<RemoteRepositoryConfiguration>();
+            Map<String, ProxyInfo > networkProxies = new HashMap<String, ProxyInfo>();
+
+            Map<String, List< ProxyConnectorConfiguration >> proxyConnectorsMap = archivaConfiguration.getConfiguration().getProxyConnectorAsMap();
+            List<ProxyConnectorConfiguration> proxyConnectors = proxyConnectorsMap.get( repository.getId() );
+            if( proxyConnectors != null )
+            {
+                for( ProxyConnectorConfiguration proxyConnector : proxyConnectors )
+                {
+                    remoteRepositories.add( archivaConfiguration.getConfiguration().findRemoteRepositoryById( proxyConnector.getTargetRepoId() ) );
+
+                    NetworkProxyConfiguration networkProxyConfig = archivaConfiguration.getConfiguration().getNetworkProxiesAsMap().get(
+                        proxyConnector.getProxyId() );
+
+                    if( networkProxyConfig != null )
+                    {
+                        ProxyInfo proxy = new ProxyInfo();
+                        proxy.setType( networkProxyConfig.getProtocol() );
+                        proxy.setHost( networkProxyConfig.getHost() );
+                        proxy.setPort( networkProxyConfig.getPort() );
+                        proxy.setUserName( networkProxyConfig.getUsername() );
+                        proxy.setPassword( networkProxyConfig.getPassword() );
+
+                        // key/value: remote repo ID/proxy info
+                        networkProxies.put( proxyConnector.getTargetRepoId(), proxy );
+                    }
+                }
+            }
+
+            Model model = buildProject( new RepositoryModelResolver( basedir, pathTranslator, wagonFactory, remoteRepositories,
+                                         networkProxies, repository ), groupId, artifactId, version );
 
             Map managedVersions = createManagedVersionMap( model );
 
@@ -237,7 +278,7 @@ public class DefaultDependencyTreeBuilder
         }
     }
 
-    private File findArtifactInRepositories( List<String> repositoryIds, Artifact projectArtifact )
+    private ManagedRepositoryConfiguration findArtifactInRepositories( List<String> repositoryIds, Artifact projectArtifact )
     {
         for ( String repoId : repositoryIds )
         {
@@ -252,7 +293,7 @@ public class DefaultDependencyTreeBuilder
 
             if ( file.exists() )
             {
-                return repoDir;
+                return repositoryConfiguration;
             }
         }
         return null;
@@ -426,11 +467,13 @@ public class DefaultDependencyTreeBuilder
                 factory.createProjectArtifact( artifact.getGroupId(), artifact.getArtifactId(), artifact.getVersion(),
                                                artifact.getScope() );
 
-            File basedir = findArtifactInRepositories( repositoryIds, pomArtifact );
+            ManagedRepositoryConfiguration repository = findArtifactInRepositories( repositoryIds, pomArtifact );
 
             Model project = null;
-            if ( !Artifact.SCOPE_SYSTEM.equals( artifact.getScope() ) && basedir != null )
+            if ( !Artifact.SCOPE_SYSTEM.equals( artifact.getScope() ) && repository != null )
             {
+                File basedir = new File( repository.getLocation() );
+
                 try
                 {
                     project =
index 5eaa390f8c204683d801abce9b0e387ae5d6b6df..f4291eca3b73346379ddcf703b82ced686c2797b 100644 (file)
@@ -29,9 +29,13 @@ import org.apache.archiva.metadata.repository.storage.RepositoryPathTranslator;
 import org.apache.archiva.metadata.repository.storage.RepositoryStorage;
 import org.apache.archiva.metadata.repository.storage.RepositoryStorageMetadataInvalidException;
 import org.apache.archiva.metadata.repository.storage.RepositoryStorageMetadataNotFoundException;
+import org.apache.archiva.proxy.common.WagonFactory;
 import org.apache.maven.archiva.common.utils.VersionUtil;
 import org.apache.maven.archiva.configuration.ArchivaConfiguration;
 import org.apache.maven.archiva.configuration.ManagedRepositoryConfiguration;
+import org.apache.maven.archiva.configuration.NetworkProxyConfiguration;
+import org.apache.maven.archiva.configuration.ProxyConnectorConfiguration;
+import org.apache.maven.archiva.configuration.RemoteRepositoryConfiguration;
 import org.apache.maven.archiva.xml.XMLException;
 import org.apache.maven.model.CiManagement;
 import org.apache.maven.model.Dependency;
@@ -46,6 +50,8 @@ import org.apache.maven.model.building.DefaultModelBuildingRequest;
 import org.apache.maven.model.building.ModelBuilder;
 import org.apache.maven.model.building.ModelBuildingException;
 import org.apache.maven.model.building.ModelBuildingRequest;
+import org.apache.maven.model.building.ModelProblem;
+import org.apache.maven.wagon.proxy.ProxyInfo;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.stereotype.Service;
@@ -54,6 +60,7 @@ import javax.annotation.PostConstruct;
 import javax.inject.Inject;
 import javax.inject.Named;
 import java.io.File;
+import java.io.FileNotFoundException;
 import java.io.FilenameFilter;
 import java.io.IOException;
 import java.util.ArrayList;
@@ -61,7 +68,9 @@ import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Date;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
 /**
  * Maven 2 repository format storage implementation. This class currently takes parameters to indicate the repository to
@@ -97,6 +106,9 @@ public class Maven2RepositoryStorage
     @Named( value = "repositoryPathTranslator#maven2" )
     private RepositoryPathTranslator pathTranslator;
 
+    @Inject
+    private WagonFactory wagonFactory;
+
     private final static Logger log = LoggerFactory.getLogger( Maven2RepositoryStorage.class );
 
     private static final String METADATA_FILENAME = "maven-metadata.xml";
@@ -161,10 +173,48 @@ public class Maven2RepositoryStorage
                 "The artifact's POM file '" + file.getAbsolutePath() + "' was missing" );
         }
 
+        List<RemoteRepositoryConfiguration> remoteRepositories = new ArrayList<RemoteRepositoryConfiguration>();
+        Map<String, ProxyInfo> networkProxies = new HashMap<String, ProxyInfo>();
+
+        Map<String, List<ProxyConnectorConfiguration>> proxyConnectorsMap = archivaConfiguration.getConfiguration().getProxyConnectorAsMap();
+        List<ProxyConnectorConfiguration> proxyConnectors = proxyConnectorsMap.get( repoId );
+        if( proxyConnectors != null )
+        {
+            for( ProxyConnectorConfiguration proxyConnector : proxyConnectors )
+            {
+                RemoteRepositoryConfiguration remoteRepoConfig = archivaConfiguration.getConfiguration().findRemoteRepositoryById(
+                    proxyConnector.getTargetRepoId() );
+
+                if( remoteRepoConfig != null )
+                {
+                    remoteRepositories.add( remoteRepoConfig );
+
+                    NetworkProxyConfiguration networkProxyConfig = archivaConfiguration.getConfiguration().getNetworkProxiesAsMap().get(
+                        proxyConnector.getProxyId() );
+
+                    if( networkProxyConfig != null )
+                    {
+                        ProxyInfo proxy = new ProxyInfo();
+                        proxy.setType( networkProxyConfig.getProtocol() );
+                        proxy.setHost( networkProxyConfig.getHost() );
+                        proxy.setPort( networkProxyConfig.getPort() );
+                        proxy.setUserName( networkProxyConfig.getUsername() );
+                        proxy.setPassword( networkProxyConfig.getPassword() );
+
+                        // key/value: remote repo ID/proxy info
+                        networkProxies.put( proxyConnector.getTargetRepoId(), proxy );
+                    }
+                }
+            }
+        }
+
         ModelBuildingRequest req = new DefaultModelBuildingRequest();
         req.setProcessPlugins( false );
         req.setPomFile( file );
-        req.setModelResolver( new RepositoryModelResolver( basedir, pathTranslator ) );
+
+        // MRM-1411
+        req.setModelResolver( new RepositoryModelResolver( basedir, pathTranslator, wagonFactory, remoteRepositories,
+                                                           networkProxies, repositoryConfiguration ) );
         req.setValidationLevel( ModelBuildingRequest.VALIDATION_LEVEL_MINIMAL );
 
         Model model;
@@ -176,6 +226,30 @@ public class Maven2RepositoryStorage
         {
             String msg = "The artifact's POM file '" + file + "' was invalid: " + e.getMessage();
 
+            List<ModelProblem> modelProblems = e.getProblems();
+            for( ModelProblem problem : modelProblems )
+            {
+                // MRM-1411, related to MRM-1335
+                // this means that the problem was that the parent wasn't resolved!
+                if( problem.getException() instanceof FileNotFoundException && e.getModelId() != null &&
+                    !e.getModelId().equals( problem.getModelId() ) )
+                {
+                    log.warn( "The artifact's parent POM file '" + file + "' cannot be resolved. " +
+                        "Using defaults for project version metadata.." );
+
+                    ProjectVersionMetadata metadata = new ProjectVersionMetadata();
+                    metadata.setId( projectVersion );
+
+                    MavenProjectFacet facet = new MavenProjectFacet();
+                    facet.setGroupId( namespace );
+                    facet.setArtifactId( projectId );
+                    facet.setPackaging( "jar" );
+                    metadata.addFacet( facet );
+
+                    return metadata;
+                }
+            }
+
             throw new RepositoryStorageMetadataInvalidException( "invalid-pom", msg, e );
         }
 
@@ -232,6 +306,11 @@ public class Maven2RepositoryStorage
         return metadata;
     }
 
+    public void setWagonFactory( WagonFactory wagonFactory )
+    {
+        this.wagonFactory = wagonFactory;
+    }
+
     private List<org.apache.archiva.metadata.model.Dependency> convertDependencies( List<Dependency> dependencies )
     {
         List<org.apache.archiva.metadata.model.Dependency> l =
index b76d8740db1539990a58d97c891cf9379597745b..28a86a67b0ee0edb07d27005ed165e6b5357e164 100644 (file)
@@ -20,14 +20,33 @@ package org.apache.archiva.metadata.repository.storage.maven2;
  */
 
 import java.io.File;
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
 
 import org.apache.archiva.metadata.repository.storage.RepositoryPathTranslator;
+import org.apache.archiva.proxy.common.WagonFactory;
+import org.apache.archiva.proxy.common.WagonFactoryException;
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.lang.StringUtils;
+import org.apache.maven.archiva.configuration.ManagedRepositoryConfiguration;
+import org.apache.maven.archiva.configuration.RemoteRepositoryConfiguration;
 import org.apache.maven.model.Repository;
 import org.apache.maven.model.building.FileModelSource;
 import org.apache.maven.model.building.ModelSource;
 import org.apache.maven.model.resolution.InvalidRepositoryException;
 import org.apache.maven.model.resolution.ModelResolver;
 import org.apache.maven.model.resolution.UnresolvableModelException;
+import org.apache.maven.wagon.ConnectionException;
+import org.apache.maven.wagon.ResourceDoesNotExistException;
+import org.apache.maven.wagon.TransferFailedException;
+import org.apache.maven.wagon.Wagon;
+import org.apache.maven.wagon.authentication.AuthenticationException;
+import org.apache.maven.wagon.authentication.AuthenticationInfo;
+import org.apache.maven.wagon.authorization.AuthorizationException;
+import org.apache.maven.wagon.proxy.ProxyInfo;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 public class RepositoryModelResolver
     implements ModelResolver
@@ -36,6 +55,17 @@ public class RepositoryModelResolver
 
     private RepositoryPathTranslator pathTranslator;
 
+    private WagonFactory wagonFactory;
+
+    private List<RemoteRepositoryConfiguration> remoteRepositories;
+
+    private ManagedRepositoryConfiguration targetRepository;
+
+    private static final Logger log = LoggerFactory.getLogger( RepositoryModelResolver.class );
+
+    // key/value: remote repo ID/network proxy
+    Map<String, ProxyInfo> networkProxyMap;
+
     public RepositoryModelResolver( File basedir, RepositoryPathTranslator pathTranslator )
     {
         this.basedir = basedir;
@@ -43,12 +73,53 @@ public class RepositoryModelResolver
         this.pathTranslator = pathTranslator;
     }
 
+    public RepositoryModelResolver( File basedir, RepositoryPathTranslator pathTranslator,
+                                    WagonFactory wagonFactory, List<RemoteRepositoryConfiguration> remoteRepositories,
+                                    Map<String, ProxyInfo> networkProxiesMap, ManagedRepositoryConfiguration targetRepository )
+    {
+        this( basedir, pathTranslator );
+
+        this.wagonFactory = wagonFactory;
+
+        this.remoteRepositories = remoteRepositories;
+
+        this.networkProxyMap = networkProxiesMap;
+
+        this.targetRepository = targetRepository;
+    }
+
     public ModelSource resolveModel( String groupId, String artifactId, String version )
         throws UnresolvableModelException
     {
         String filename = artifactId + "-" + version + ".pom";
         // TODO: we need to convert 1.0-20091120.112233-1 type paths to baseVersion for the below call - add a test
-        return new FileModelSource( pathTranslator.toFile( basedir, groupId, artifactId, version, filename ) );
+
+        File model = pathTranslator.toFile( basedir, groupId, artifactId, version, filename );
+
+        if( !model.exists() )
+        {
+            for( RemoteRepositoryConfiguration remoteRepository : remoteRepositories )
+            {
+                try
+                {
+                    boolean success = getModelFromProxy( remoteRepository, groupId, artifactId, version, filename );
+                    if( success && model.exists() )
+                    {
+                        log.info( "Model '" + model.getAbsolutePath() + "' successfully retrieved from remote repository '"
+                            + remoteRepository.getId() + "'" );
+                        break;
+                    }
+                }
+                catch( Exception e )
+                {
+                    log.warn( "An exception was caught while attempting to retrieve model '" + model.getAbsolutePath()
+                        + "' from remote repository '" + remoteRepository.getId() + "'.", e );
+                    continue;
+                }
+            }
+        }
+
+        return new FileModelSource( model );
     }
 
     public void addRepository( Repository repository )
@@ -63,4 +134,232 @@ public class RepositoryModelResolver
     {
         return new RepositoryModelResolver( basedir, pathTranslator );
     }
-}
+
+    // TODO: we need to do some refactoring, we cannot re-use the proxy components of archiva-proxy in maven2-repository
+    // because it's causing a cyclic dependency
+    private boolean getModelFromProxy( RemoteRepositoryConfiguration remoteRepository, String groupId,
+                                    String artifactId, String version, String filename )
+        throws AuthorizationException, TransferFailedException, ResourceDoesNotExistException, WagonFactoryException
+    {
+        boolean success = false;
+        File tmpMd5 = null;
+        File tmpSha1 = null;
+        File tmpResource = null;
+        String artifactPath = pathTranslator.toPath( groupId, artifactId, version, filename );
+        File resource = new File( targetRepository.getLocation(), artifactPath );
+
+        File workingDirectory = createWorkingDirectory( targetRepository.getLocation() );
+        try
+        {
+            Wagon wagon = null;
+            try
+            {
+                String protocol = getProtocol( remoteRepository.getUrl() );
+
+                wagon = wagonFactory.getWagon( "wagon#" + protocol );
+                if ( wagon == null )
+                {
+                    throw new RuntimeException( "Unsupported remote repository protocol: " + protocol );
+                }
+
+                boolean connected = connectToRepository( wagon, remoteRepository );
+                if ( connected )
+                {
+                    tmpResource = new File( workingDirectory, filename );
+
+                    log.info( "Retrieving " + artifactPath + " from " + remoteRepository.getName() );
+                    
+                    wagon.get( artifactPath, tmpResource );
+
+                    log.debug( "Downloaded successfully." );
+
+                    tmpSha1 =
+                        transferChecksum( wagon, remoteRepository, artifactPath, tmpResource, workingDirectory, ".sha1" );
+                    tmpMd5 =
+                        transferChecksum( wagon, remoteRepository, artifactPath, tmpResource, workingDirectory, ".md5" );
+                }
+            }
+            finally
+            {
+                if ( wagon != null )
+                {
+                    try
+                    {
+                        wagon.disconnect();
+                    }
+                    catch ( ConnectionException e )
+                    {
+                        log.warn( "Unable to disconnect wagon.", e );
+                    }
+                }
+            }
+
+            if ( resource != null )
+            {
+                synchronized ( resource.getAbsolutePath().intern() )
+                {
+                    File directory = resource.getParentFile();
+                    moveFileIfExists( tmpMd5, directory );
+                    moveFileIfExists( tmpSha1, directory );
+                    moveFileIfExists( tmpResource, directory );
+                    success = true;
+                }
+            }
+        }
+        finally
+        {
+            FileUtils.deleteQuietly( workingDirectory );
+        }
+
+        // do we still need to execute the consumers?
+
+        return success;
+    }
+
+    /**
+     * Using wagon, connect to the remote repository.
+     *
+     * @param wagon the wagon instance to establish the connection on.
+     * @return true if the connection was successful. false if not connected.
+     */
+    private boolean connectToRepository( Wagon wagon, RemoteRepositoryConfiguration remoteRepository )
+    {
+        boolean connected;
+
+        final ProxyInfo networkProxy;
+        networkProxy = this.networkProxyMap.get( remoteRepository.getId() );
+
+        if ( networkProxy != null )
+        {
+            String msg =
+                "Using network proxy " + networkProxy.getHost() + ":" + networkProxy.getPort()
+                    + " to connect to remote repository " + remoteRepository.getUrl();
+            if ( networkProxy.getNonProxyHosts() != null )
+            {
+                msg += "; excluding hosts: " + networkProxy.getNonProxyHosts();
+            }
+
+            if ( StringUtils.isNotBlank( networkProxy.getUserName() ) )
+            {
+                msg += "; as user: " + networkProxy.getUserName();
+            }
+
+            log.debug( msg );
+        }
+
+        AuthenticationInfo authInfo = null;
+        String username = remoteRepository.getUsername();
+        String password = remoteRepository.getPassword();
+
+        if ( StringUtils.isNotBlank( username ) && StringUtils.isNotBlank( password ) )
+        {
+            log.debug( "Using username " + username + " to connect to remote repository " + remoteRepository.getUrl() );
+            authInfo = new AuthenticationInfo();
+            authInfo.setUserName( username );
+            authInfo.setPassword( password );
+        }
+
+        // Convert seconds to milliseconds
+        int timeoutInMilliseconds = remoteRepository.getTimeout() * 1000;
+
+        // Set timeout
+        wagon.setTimeout( timeoutInMilliseconds );
+
+        try
+        {
+            org.apache.maven.wagon.repository.Repository wagonRepository =
+                new org.apache.maven.wagon.repository.Repository( remoteRepository.getId(), remoteRepository.getUrl() );
+            wagon.connect( wagonRepository, authInfo, networkProxy );
+            connected = true;
+        }
+        catch ( ConnectionException e )
+        {
+            log.error( "Could not connect to " + remoteRepository.getName() + ": " + e.getMessage() );
+            connected = false;
+        }
+        catch ( AuthenticationException e )
+        {
+            log.error( "Could not connect to " + remoteRepository.getName() + ": " + e.getMessage() );
+            connected = false;
+        }
+
+        return connected;
+    }
+
+    private File transferChecksum( Wagon wagon, RemoteRepositoryConfiguration remoteRepository, String remotePath,
+                                   File resource, File tmpDirectory, String ext )
+        throws AuthorizationException, TransferFailedException, ResourceDoesNotExistException
+    {
+        File destFile = new File( tmpDirectory, resource.getName() + ext );
+
+        log.info( "Retrieving " + remotePath + " from " + remoteRepository.getName() );
+
+        wagon.get( remotePath, destFile );
+
+        log.debug( "Downloaded successfully." );
+
+        return destFile;
+    }
+
+    private String getProtocol( String url )
+    {
+        String protocol = StringUtils.substringBefore( url, ":" );
+
+        return protocol;
+    }
+
+    private File createWorkingDirectory( String targetRepository )
+    {
+        try
+        {
+            File tmpDir = File.createTempFile( ".workingdirectory", null, new File( targetRepository ) );
+            tmpDir.delete();
+            tmpDir.mkdirs();
+            return tmpDir;
+        }
+        catch ( IOException e )
+        {
+            throw new RuntimeException( "Could not create working directory for this request", e );
+        }
+    }
+
+    private void moveFileIfExists( File fileToMove, File directory )
+    {
+        if ( fileToMove != null && fileToMove.exists() )
+        {
+            File newLocation = new File( directory, fileToMove.getName() );
+            if ( newLocation.exists() && !newLocation.delete() )
+            {
+                throw new RuntimeException( "Unable to overwrite existing target file: " + newLocation.getAbsolutePath() );
+            }
+
+            newLocation.getParentFile().mkdirs();
+            if ( !fileToMove.renameTo( newLocation ) )
+            {
+                log.warn( "Unable to rename tmp file to its final name... resorting to copy command." );
+
+                try
+                {
+                    FileUtils.copyFile( fileToMove, newLocation );
+                }
+                catch ( IOException e )
+                {
+                    if ( newLocation.exists() )
+                    {
+                        log.error( "Tried to copy file " + fileToMove.getName() + " to " + newLocation.getAbsolutePath()
+                            + " but file with this name already exists." );
+                    }
+                    else
+                    {
+                        throw new RuntimeException( "Cannot copy tmp file " + fileToMove.getAbsolutePath()
+                            + " to its final location", e );
+                    }
+                }
+                finally
+                {
+                    FileUtils.deleteQuietly( fileToMove );
+                }
+            }
+        }
+    }
+}
\ No newline at end of file
index 65002297eb8ee58a2ead4ac517903dc6b603340e..03b8dd5a8be47c9c89082b480f6d716f6a5f0ae6 100644 (file)
@@ -30,18 +30,28 @@ import org.apache.archiva.metadata.repository.filter.ExcludesFilter;
 import org.apache.archiva.metadata.repository.filter.Filter;
 import org.apache.archiva.metadata.repository.storage.RepositoryStorageMetadataInvalidException;
 import org.apache.archiva.metadata.repository.storage.RepositoryStorageMetadataNotFoundException;
+import org.apache.archiva.proxy.common.WagonFactory;
+import org.apache.commons.io.FileUtils;
+import org.apache.maven.archiva.common.utils.FileUtil;
 import org.apache.maven.archiva.configuration.ArchivaConfiguration;
 import org.apache.maven.archiva.configuration.Configuration;
 import org.apache.maven.archiva.configuration.ManagedRepositoryConfiguration;
+import org.apache.maven.archiva.configuration.ProxyConnectorConfiguration;
+import org.apache.maven.archiva.configuration.RemoteRepositoryConfiguration;
+import org.apache.maven.wagon.Wagon;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.springframework.test.context.ContextConfiguration;
 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
 
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
 import javax.inject.Inject;
 import javax.inject.Named;
 import java.io.File;
+import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
@@ -62,12 +72,20 @@ public class Maven2RepositoryMetadataResolverTest
 
     private static final String TEST_REPO_ID = "test";
 
+    private static final String TEST_REMOTE_REPO_ID = "central";
+
     private static final String ASF_SCM_CONN_BASE = "scm:svn:http://svn.apache.org/repos/asf/";
 
     private static final String ASF_SCM_DEV_CONN_BASE = "scm:svn:https://svn.apache.org/repos/asf/";
 
     private static final String ASF_SCM_VIEWVC_BASE = "http://svn.apache.org/viewvc/";
 
+    private static final String TEST_SCM_CONN_BASE = "scm:svn:http://svn.example.com/repos/";
+
+    private static final String TEST_SCM_DEV_CONN_BASE = "scm:svn:https://svn.example.com/repos/";
+
+    private static final String TEST_SCM_URL_BASE = "http://svn.example.com/repos/";
+
     private static final String EMPTY_MD5 = "d41d8cd98f00b204e9800998ecf8427e";
 
     private static final String EMPTY_SHA1 = "da39a3ee5e6b4b0d3255bfef95601890afd80709";
@@ -75,6 +93,8 @@ public class Maven2RepositoryMetadataResolverTest
     @Inject
     private ArchivaConfiguration configuration;
 
+    private WagonFactory wagonFactory;
+
     @Before
     public void setUp()
         throws Exception
@@ -87,8 +107,29 @@ public class Maven2RepositoryMetadataResolverTest
         testRepo.setId( TEST_REPO_ID );
         testRepo.setLocation( new File( "target/test-repository" ).getAbsolutePath() );
         c.addManagedRepository( testRepo );
+
+        RemoteRepositoryConfiguration testRemoteRepo = new RemoteRepositoryConfiguration();
+        testRemoteRepo.setId( TEST_REMOTE_REPO_ID );
+        testRemoteRepo.setLayout( "default" );
+        testRemoteRepo.setName( "Central Repository" );
+        testRemoteRepo.setUrl( "http://central.repo.com/maven2" );
+        testRemoteRepo.setTimeout( 10 );
+        c.addRemoteRepository( testRemoteRepo );
+
+        ProxyConnectorConfiguration proxyConnector = new ProxyConnectorConfiguration();
+        proxyConnector.setSourceRepoId( TEST_REPO_ID );
+        proxyConnector.setTargetRepoId( TEST_REMOTE_REPO_ID );
+        proxyConnector.setDisabled( false );
+        c.addProxyConnector( proxyConnector );
+
         configuration.save( c );
 
+        wagonFactory = mock( WagonFactory.class );
+
+        storage.setWagonFactory( wagonFactory );
+
+        Wagon wagon = new MockWagon();
+        when( wagonFactory.getWagon( "wagon#http" ) ).thenReturn( wagon );
         //storage = (Maven2RepositoryStorage) lookup( RepositoryStorage.class, "maven2" );
     }
 
@@ -404,6 +445,91 @@ public class Maven2RepositoryMetadataResolverTest
         }
     }
 
+    // Tests for MRM-1411 - START
+    @Test
+    public void testGetProjectVersionMetadataWithParentSuccessful()
+        throws Exception
+    {
+        copyTestArtifactWithParent();
+
+        ProjectVersionMetadata metadata = storage.readProjectVersionMetadata( TEST_REPO_ID, "com.example.test",
+                                                                               "test-artifact-module-a", "1.0" );
+
+        MavenProjectFacet facet = (MavenProjectFacet) metadata.getFacet( MavenProjectFacet.FACET_ID );
+        assertEquals( "jar", facet.getPackaging() );
+        assertEquals( "http://maven.apache.org", metadata.getUrl() );
+        assertEquals( "com.example.test", facet.getParent().getGroupId() );
+        assertEquals( "test-artifact-root", facet.getParent().getArtifactId() );
+        assertEquals( "1.0", facet.getParent().getVersion() );
+        assertEquals( "test-artifact-module-a", facet.getArtifactId() );
+        assertEquals( "com.example.test", facet.getGroupId() );
+        assertNull( metadata.getCiManagement() );
+        assertNotNull( metadata.getDescription() );
+
+        checkApacheLicense( metadata );
+
+        assertEquals( "1.0", metadata.getId() );
+        assertEquals( "Test Artifact :: Module A", metadata.getName() );
+        String path = "test-artifact/trunk/test-artifact-module-a";
+        assertEquals( TEST_SCM_CONN_BASE + path, metadata.getScm().getConnection() );
+        assertEquals( TEST_SCM_DEV_CONN_BASE + path, metadata.getScm().getDeveloperConnection() );
+        assertEquals( TEST_SCM_URL_BASE + path, metadata.getScm().getUrl() );
+
+        List<Dependency> dependencies = metadata.getDependencies();
+        assertEquals( 2, dependencies.size() );
+        assertDependency( dependencies.get( 0 ), "commons-io", "commons-io", "1.4" );
+        assertDependency( dependencies.get( 1 ), "junit", "junit", "3.8.1", "test" );
+
+        deleteTestArtifactWithParent();
+    }
+
+    @Test
+    public void testGetProjectVersionMetadataWithParentNoRemoteReposConfigured()
+         throws Exception
+    {
+       // remove configuration
+        Configuration config = configuration.getConfiguration();
+        RemoteRepositoryConfiguration remoteRepo = config.findRemoteRepositoryById( TEST_REMOTE_REPO_ID );
+        config.removeRemoteRepository( remoteRepo );
+
+        configuration.save( config );
+
+        copyTestArtifactWithParent();
+
+        ProjectVersionMetadata metadata =  storage.readProjectVersionMetadata( TEST_REPO_ID, "com.example.test",
+                                                                "test-artifact-module-a", "1.0" );
+        assertEquals( "1.0", metadata.getId() );
+
+        MavenProjectFacet facet = ( MavenProjectFacet ) metadata.getFacet( MavenProjectFacet.FACET_ID );
+        assertNotNull( facet );
+        assertEquals( "com.example.test", facet.getGroupId() );
+        assertEquals( "test-artifact-module-a", facet.getArtifactId() );
+        assertEquals( "jar", facet.getPackaging() );
+
+        deleteTestArtifactWithParent();
+    }
+
+    @Test
+    public void testGetProjectVersionMetadataWithParentNotInAnyRemoteRepo()
+         throws Exception
+    {
+        copyTestArtifactWithParent();
+
+        ProjectVersionMetadata metadata = storage.readProjectVersionMetadata( TEST_REPO_ID, "com.example.test", "missing-parent", "1.1" );
+
+        assertEquals( "1.1", metadata.getId() );
+
+        MavenProjectFacet facet = ( MavenProjectFacet ) metadata.getFacet( MavenProjectFacet.FACET_ID );
+        assertNotNull( facet );
+        assertEquals( "com.example.test", facet.getGroupId() );
+        assertEquals( "missing-parent", facet.getArtifactId() );
+        assertEquals( "jar", facet.getPackaging() );
+
+        deleteTestArtifactWithParent();
+    }
+
+    // Tests for MRM-1411 - END
+
     @Test
     public void testGetRootNamespaces()
     {
@@ -440,7 +566,7 @@ public class Maven2RepositoryMetadataResolverTest
         assertEquals( Collections.<String>emptyList(), storage.listProjects( TEST_REPO_ID, "com", ALL ) );
         assertEquals( Collections.<String>emptyList(), storage.listProjects( TEST_REPO_ID, "com.example", ALL ) );
         assertEquals( Arrays.asList( "incomplete-metadata", "invalid-pom", "malformed-metadata", "mislocated-pom",
-                                     "missing-metadata", "test-artifact" ), storage.listProjects( TEST_REPO_ID,
+                                     "missing-metadata", "missing-parent", "test-artifact" ), storage.listProjects( TEST_REPO_ID,
                                                                                                   "com.example.test",
                                                                                                   ALL ) );
 
@@ -608,4 +734,32 @@ public class Maven2RepositoryMetadataResolverTest
         assertEquals( "The Apache Software Foundation", metadata.getOrganization().getName() );
         assertEquals( "http://www.apache.org/", metadata.getOrganization().getUrl() );
     }
+
+    private void deleteTestArtifactWithParent()
+         throws IOException
+    {
+        File dest = new File( FileUtil.getBasedir(), "target/test-repository/com/example/test/test-artifact-module-a" );
+        File parentPom = new File( FileUtil.getBasedir(), "target/test-repository/com/example/test/test-artifact-parent" );
+        File rootPom = new File( FileUtil.getBasedir(), "target/test-repository/com/example/test/test-artifact-root" );
+
+        FileUtils.deleteDirectory( dest );
+        FileUtils.deleteDirectory( parentPom );
+        FileUtils.deleteDirectory( rootPom );
+
+        assertFalse( dest.exists() );
+        assertFalse( parentPom.exists() );
+        assertFalse( rootPom.exists() );
+    }
+
+    private File copyTestArtifactWithParent()
+         throws IOException
+    {
+        File src = new File( FileUtil.getBasedir(), "target/test-classes/com/example/test/test-artifact-module-a" );
+        File dest = new File( FileUtil.getBasedir(), "target/test-repository/com/example/test/test-artifact-module-a" );
+
+        FileUtils.copyDirectory( src, dest );
+        assertTrue( dest.exists() );
+        return dest;
+    }
+
 }
diff --git a/archiva-modules/plugins/maven2-repository/src/test/java/org/apache/archiva/metadata/repository/storage/maven2/MockWagon.java b/archiva-modules/plugins/maven2-repository/src/test/java/org/apache/archiva/metadata/repository/storage/maven2/MockWagon.java
new file mode 100644 (file)
index 0000000..cea007c
--- /dev/null
@@ -0,0 +1,190 @@
+package org.apache.archiva.metadata.repository.storage.maven2;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.maven.wagon.ConnectionException;
+import org.apache.maven.wagon.ResourceDoesNotExistException;
+import org.apache.maven.wagon.TransferFailedException;
+import org.apache.maven.wagon.Wagon;
+import org.apache.maven.wagon.authentication.AuthenticationException;
+import org.apache.maven.wagon.authentication.AuthenticationInfo;
+import org.apache.maven.wagon.authorization.AuthorizationException;
+import org.apache.maven.wagon.events.SessionListener;
+import org.apache.maven.wagon.events.TransferListener;
+import org.apache.maven.wagon.proxy.ProxyInfo;
+import org.apache.maven.wagon.proxy.ProxyInfoProvider;
+import org.apache.maven.wagon.repository.Repository;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+
+public class MockWagon
+    implements Wagon
+{
+    public void get( String s, File file )
+        throws TransferFailedException, ResourceDoesNotExistException, AuthorizationException
+    {
+        String sourceFile = getBasedir() + "/target/test-classes/" + s;
+
+        try
+        {
+            FileUtils.copyFile( new File( sourceFile ), file );
+            assert( file.exists() );
+        }
+        catch( IOException e )
+        {
+            throw new ResourceDoesNotExistException( e.getMessage() );            
+        }
+    }
+
+    public boolean getIfNewer( String s, File file, long l )
+        throws TransferFailedException, ResourceDoesNotExistException, AuthorizationException
+    {
+        return false;
+    }
+
+    public void put( File file, String s )
+        throws TransferFailedException, ResourceDoesNotExistException, AuthorizationException
+    {
+        
+    }
+
+    public void putDirectory( File file, String s )
+        throws TransferFailedException, ResourceDoesNotExistException, AuthorizationException
+    {
+
+    }
+
+    public boolean resourceExists( String s )
+        throws TransferFailedException, AuthorizationException
+    {
+        return false;
+    }
+
+    public List getFileList( String s )
+        throws TransferFailedException, ResourceDoesNotExistException, AuthorizationException
+    {
+        return null;
+    }
+
+    public boolean supportsDirectoryCopy()
+    {
+        return false;
+    }
+
+    public Repository getRepository()
+    {
+        return null;
+    }
+
+    public void connect( Repository repository )
+        throws ConnectionException, AuthenticationException
+    {
+
+    }
+
+    public void connect( Repository repository, ProxyInfo proxyInfo )
+        throws ConnectionException, AuthenticationException
+    {
+
+    }
+
+    public void connect( Repository repository, ProxyInfoProvider proxyInfoProvider )
+        throws ConnectionException, AuthenticationException
+    {
+
+    }
+
+    public void connect( Repository repository, AuthenticationInfo authenticationInfo )
+        throws ConnectionException, AuthenticationException
+    {
+
+    }
+
+    public void connect( Repository repository, AuthenticationInfo authenticationInfo, ProxyInfo proxyInfo )
+        throws ConnectionException, AuthenticationException
+    {
+
+    }
+
+    public void connect( Repository repository, AuthenticationInfo authenticationInfo,
+                         ProxyInfoProvider proxyInfoProvider )
+        throws ConnectionException, AuthenticationException
+    {
+
+    }
+
+    public void openConnection()
+        throws ConnectionException, AuthenticationException
+    {
+
+    }
+
+    public void disconnect()
+        throws ConnectionException
+    {
+
+    }
+
+    public void setTimeout( int i )
+    {
+
+    }
+
+    public int getTimeout()
+    {
+        return 0;
+    }
+
+    public void addSessionListener( SessionListener sessionListener )
+    {
+
+    }
+
+    public void removeSessionListener( SessionListener sessionListener )
+    {
+
+    }
+
+    public boolean hasSessionListener( SessionListener sessionListener )
+    {
+        return false;
+    }
+
+    public void addTransferListener( TransferListener transferListener )
+    {
+
+    }
+
+    public void removeTransferListener( TransferListener transferListener )
+    {
+
+    }
+
+    public boolean hasTransferListener( TransferListener transferListener )
+    {
+        return false;
+    }
+
+    public boolean isInteractive()
+    {
+        return false;
+    }
+
+    public void setInteractive( boolean b )
+    {
+
+    }
+
+    public String getBasedir()
+    {
+        String basedir = System.getProperty( "basedir" );
+
+        if ( basedir == null )
+        {
+            basedir = new File( "" ).getAbsolutePath();
+        }
+
+        return basedir;
+    }
+}
diff --git a/archiva-modules/plugins/maven2-repository/src/test/resources/com/example/test/test-artifact-module-a/1.0/test-artifact-module-a-1.0.jar b/archiva-modules/plugins/maven2-repository/src/test/resources/com/example/test/test-artifact-module-a/1.0/test-artifact-module-a-1.0.jar
new file mode 100644 (file)
index 0000000..3176aff
Binary files /dev/null and b/archiva-modules/plugins/maven2-repository/src/test/resources/com/example/test/test-artifact-module-a/1.0/test-artifact-module-a-1.0.jar differ
diff --git a/archiva-modules/plugins/maven2-repository/src/test/resources/com/example/test/test-artifact-module-a/1.0/test-artifact-module-a-1.0.jar.md5 b/archiva-modules/plugins/maven2-repository/src/test/resources/com/example/test/test-artifact-module-a/1.0/test-artifact-module-a-1.0.jar.md5
new file mode 100644 (file)
index 0000000..877b697
--- /dev/null
@@ -0,0 +1 @@
+37786de9e272ed6db8541855e0e2d5dc
diff --git a/archiva-modules/plugins/maven2-repository/src/test/resources/com/example/test/test-artifact-module-a/1.0/test-artifact-module-a-1.0.jar.sha1 b/archiva-modules/plugins/maven2-repository/src/test/resources/com/example/test/test-artifact-module-a/1.0/test-artifact-module-a-1.0.jar.sha1
new file mode 100644 (file)
index 0000000..7f1a38e
--- /dev/null
@@ -0,0 +1 @@
+bb1ca7834422926d0cb79ef303b715bc17f41661
diff --git a/archiva-modules/plugins/maven2-repository/src/test/resources/com/example/test/test-artifact-module-a/1.0/test-artifact-module-a-1.0.pom b/archiva-modules/plugins/maven2-repository/src/test/resources/com/example/test/test-artifact-module-a/1.0/test-artifact-module-a-1.0.pom
new file mode 100644 (file)
index 0000000..c8db3fb
--- /dev/null
@@ -0,0 +1,19 @@
+<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">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>com.example.test</groupId>
+    <artifactId>test-artifact-root</artifactId>
+    <version>1.0</version>
+  </parent>
+  <artifactId>test-artifact-module-a</artifactId>
+  <packaging>jar</packaging>
+  <name>Test Artifact :: Module A</name>
+  <url>http://maven.apache.org</url>
+  <dependencies>
+    <dependency>
+      <groupId>commons-io</groupId>
+      <artifactId>commons-io</artifactId>
+    </dependency>
+  </dependencies>
+</project>
diff --git a/archiva-modules/plugins/maven2-repository/src/test/resources/com/example/test/test-artifact-module-a/1.0/test-artifact-module-a-1.0.pom.md5 b/archiva-modules/plugins/maven2-repository/src/test/resources/com/example/test/test-artifact-module-a/1.0/test-artifact-module-a-1.0.pom.md5
new file mode 100644 (file)
index 0000000..0a2d5c3
--- /dev/null
@@ -0,0 +1 @@
+61a4d030260fc6bee0681cf99ba54674
diff --git a/archiva-modules/plugins/maven2-repository/src/test/resources/com/example/test/test-artifact-module-a/1.0/test-artifact-module-a-1.0.pom.sha1 b/archiva-modules/plugins/maven2-repository/src/test/resources/com/example/test/test-artifact-module-a/1.0/test-artifact-module-a-1.0.pom.sha1
new file mode 100644 (file)
index 0000000..9b05237
--- /dev/null
@@ -0,0 +1 @@
+6f54bc4223bc39d7880420f66baa3a24d7f9c181
diff --git a/archiva-modules/plugins/maven2-repository/src/test/resources/com/example/test/test-artifact-parent/1/test-artifact-parent-1.pom b/archiva-modules/plugins/maven2-repository/src/test/resources/com/example/test/test-artifact-parent/1/test-artifact-parent-1.pom
new file mode 100644 (file)
index 0000000..4a3ebef
--- /dev/null
@@ -0,0 +1,41 @@
+<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">
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>com.example.test</groupId>
+  <artifactId>test-artifact-parent</artifactId>
+  <version>1</version>
+  <packaging>pom</packaging>
+  <name>Test Artifact :: Parent</name>
+  <description>This is the uber parent POM.</description>
+  <url>http://test.com</url>
+  <scm>
+    <connection>scm:svn:http://svn.example.com/repos/test-artifact-parent/trunk</connection>
+    <developerConnection>scm:svn:https://svn.example.com/repos/test-artifact-parent/trunk</developerConnection>
+    <url>http://svn.example.com/repos/test-artifact-parent/trunk</url>
+  </scm>
+  <distributionManagement>
+    <repository>
+      <id>releases</id>
+      <name>Releases Repository</name>
+      <url>http://repo.test.com/archiva/repository/releases</url>
+    </repository>
+    <snapshotRepository>
+      <id>snapshots</id>
+      <name>Snapshots Repository</name>
+      <url>http://repo.test.com/archiva/repository/snapshots</url>
+    </snapshotRepository>
+  </distributionManagement>
+  <developers>
+    <developer>
+      <id>jsmith</id>
+      <name>John Smith</name>
+      <email>jsmith@mail.com</email>
+    </developer>
+  </developers>
+  <licenses>
+    <license>
+      <name>The Apache Software License, Version 2.0</name>
+      <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
+    </license>
+  </licenses>
+</project>
diff --git a/archiva-modules/plugins/maven2-repository/src/test/resources/com/example/test/test-artifact-parent/1/test-artifact-parent-1.pom.md5 b/archiva-modules/plugins/maven2-repository/src/test/resources/com/example/test/test-artifact-parent/1/test-artifact-parent-1.pom.md5
new file mode 100644 (file)
index 0000000..61e2b6b
--- /dev/null
@@ -0,0 +1 @@
+92c60efe85e23fe5afd8a854cea87209
diff --git a/archiva-modules/plugins/maven2-repository/src/test/resources/com/example/test/test-artifact-parent/1/test-artifact-parent-1.pom.sha1 b/archiva-modules/plugins/maven2-repository/src/test/resources/com/example/test/test-artifact-parent/1/test-artifact-parent-1.pom.sha1
new file mode 100644 (file)
index 0000000..6eae228
--- /dev/null
@@ -0,0 +1 @@
+6eca3509acf66023c29e2bc17f73e79d1d1a341a
diff --git a/archiva-modules/plugins/maven2-repository/src/test/resources/com/example/test/test-artifact-root/1.0/test-artifact-root-1.0.pom b/archiva-modules/plugins/maven2-repository/src/test/resources/com/example/test/test-artifact-root/1.0/test-artifact-root-1.0.pom
new file mode 100644 (file)
index 0000000..6fe5449
--- /dev/null
@@ -0,0 +1,40 @@
+<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">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>com.example.test</groupId>
+    <artifactId>test-artifact-parent</artifactId>
+    <version>1</version>
+  </parent>
+  <artifactId>test-artifact-root</artifactId>
+  <version>1.0</version>
+  <packaging>pom</packaging>
+  <name>Test Artifact :: Root</name>
+  <description>This is the Test project.</description>
+  <modules>
+    <module>test-artifact-module-a</module>
+    <module>test-artifact-module-b</module>
+  </modules>
+  <scm>
+    <connection>scm:svn:http://svn.example.com/repos/test-artifact/trunk</connection>
+    <developerConnection>scm:svn:https://svn.example.com/repos/test-artifact/trunk</developerConnection>
+    <url>http://svn.example.com/repos/test-artifact/trunk</url>
+  </scm>
+  <dependencyManagement>
+    <dependencies>
+      <dependency>
+        <groupId>commons-io</groupId>
+        <artifactId>commons-io</artifactId>
+        <version>1.4</version>
+      </dependency>
+    </dependencies>
+  </dependencyManagement>
+  <dependencies>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>3.8.1</version>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+</project>
diff --git a/archiva-modules/plugins/maven2-repository/src/test/resources/com/example/test/test-artifact-root/1.0/test-artifact-root-1.0.pom.md5 b/archiva-modules/plugins/maven2-repository/src/test/resources/com/example/test/test-artifact-root/1.0/test-artifact-root-1.0.pom.md5
new file mode 100644 (file)
index 0000000..809d19e
--- /dev/null
@@ -0,0 +1 @@
+034449f8696981edce2485b841a02a47
diff --git a/archiva-modules/plugins/maven2-repository/src/test/resources/com/example/test/test-artifact-root/1.0/test-artifact-root-1.0.pom.sha1 b/archiva-modules/plugins/maven2-repository/src/test/resources/com/example/test/test-artifact-root/1.0/test-artifact-root-1.0.pom.sha1
new file mode 100644 (file)
index 0000000..0de5db2
--- /dev/null
@@ -0,0 +1 @@
+bef26aec1a0714cec7fa56cdbb7ebcdb452295eb
diff --git a/pom.xml b/pom.xml
index 9413fdd920c0601db821c92839f0bf6078358ae7..bddfbe50e2b590996ef5e57c25166beaeaf53670 100644 (file)
--- a/pom.xml
+++ b/pom.xml
       <dependency>
         <groupId>org.apache.archiva</groupId>
         <artifactId>archiva-plexus-bridge</artifactId>
-        <version>${project.version}</version>
+        <version>1.4-SNAPSHOT</version>
       </dependency>
       <dependency>
         <groupId>org.apache.archiva</groupId>
         <artifactId>archiva-proxy</artifactId>
         <version>1.4-SNAPSHOT</version>
       </dependency>
+      <dependency>
+        <groupId>org.apache.archiva</groupId>
+        <artifactId>archiva-proxy-common</artifactId>
+        <version>1.4-SNAPSHOT</version>
+      </dependency>
       <dependency>
         <groupId>org.apache.archiva</groupId>
         <artifactId>archiva-repository-layer</artifactId>